⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cm.java

📁 JAKE2用JAVA写的queck2的3D游戏开发引擎
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
        if (t1 < -offset && t2 < -offset) {            CM_RecursiveHullCheck(node.children[1], p1f, p2f, p1, p2);            return;        }        // put the crosspoint DIST_EPSILON pixels on the near side        if (t1 < t2) {            idist = 1.0f / (t1 - t2);            side = 1;            frac2 = (t1 + offset + DIST_EPSILON) * idist;            frac = (t1 - offset + DIST_EPSILON) * idist;        } else if (t1 > t2) {            idist = 1.0f / (t1 - t2);            side = 0;            frac2 = (t1 - offset - DIST_EPSILON) * idist;            frac = (t1 + offset + DIST_EPSILON) * idist;        } else {            side = 0;            frac = 1;            frac2 = 0;        }        // move up to the node        if (frac < 0)            frac = 0;        if (frac > 1)            frac = 1;        midf = p1f + (p2f - p1f) * frac;        float[] mid = Vec3Cache.get();        for (i = 0; i < 3; i++)            mid[i] = p1[i] + frac * (p2[i] - p1[i]);        CM_RecursiveHullCheck(node.children[side], p1f, midf, p1, mid);        // go past the node        if (frac2 < 0)            frac2 = 0;        if (frac2 > 1)            frac2 = 1;        midf = p1f + (p2f - p1f) * frac2;        for (i = 0; i < 3; i++)            mid[i] = p1[i] + frac2 * (p2[i] - p1[i]);        CM_RecursiveHullCheck(node.children[side ^ 1], midf, p2f, mid, p2);        Vec3Cache.release();    }    //======================================================================    /*     * ================== CM_BoxTrace ==================     */    public static trace_t BoxTrace(float[] start, float[] end, float[] mins,            float[] maxs, int headnode, int brushmask) {        // for multi-check avoidance        checkcount++;        // for statistics, may be zeroed        Globals.c_traces++;        // fill in a default trace        //was: memset(& trace_trace, 0, sizeof(trace_trace));        trace_trace = new trace_t();        trace_trace.fraction = 1;        trace_trace.surface = nullsurface.c;        if (numnodes == 0) {            // map not loaded            return trace_trace;        }        trace_contents = brushmask;        Math3D.VectorCopy(start, trace_start);        Math3D.VectorCopy(end, trace_end);        Math3D.VectorCopy(mins, trace_mins);        Math3D.VectorCopy(maxs, trace_maxs);        //        // check for position test special case        //        if (start[0] == end[0] && start[1] == end[1] && start[2] == end[2]) {            int leafs[] = new int[1024];            int i, numleafs;            float[] c1 = { 0, 0, 0 }, c2 = { 0, 0, 0 };            int topnode = 0;            Math3D.VectorAdd(start, mins, c1);            Math3D.VectorAdd(start, maxs, c2);            for (i = 0; i < 3; i++) {                c1[i] -= 1;                c2[i] += 1;            }            int tn[] = { topnode };            numleafs = CM_BoxLeafnums_headnode(c1, c2, leafs, 1024, headnode,                    tn);            topnode = tn[0];            for (i = 0; i < numleafs; i++) {                CM_TestInLeaf(leafs[i]);                if (trace_trace.allsolid)                    break;            }            Math3D.VectorCopy(start, trace_trace.endpos);            return trace_trace;        }        //        // check for point special case        //        if (mins[0] == 0 && mins[1] == 0 && mins[2] == 0 && maxs[0] == 0                && maxs[1] == 0 && maxs[2] == 0) {            trace_ispoint = true;            Math3D.VectorClear(trace_extents);        } else {            trace_ispoint = false;            trace_extents[0] = -mins[0] > maxs[0] ? -mins[0] : maxs[0];            trace_extents[1] = -mins[1] > maxs[1] ? -mins[1] : maxs[1];            trace_extents[2] = -mins[2] > maxs[2] ? -mins[2] : maxs[2];        }        //        // general sweeping through world        //        CM_RecursiveHullCheck(headnode, 0, 1, start, end);        if (trace_trace.fraction == 1) {            Math3D.VectorCopy(end, trace_trace.endpos);        } else {            for (int i = 0; i < 3; i++)                trace_trace.endpos[i] = start[i] + trace_trace.fraction                        * (end[i] - start[i]);        }        return trace_trace;    }    /*     * ================== CM_TransformedBoxTrace     *      * Handles offseting and rotation of the end points for moving and rotating     * entities ==================     */    public static trace_t TransformedBoxTrace(float[] start, float[] end,            float[] mins, float[] maxs, int headnode, int brushmask,            float[] origin, float[] angles) {        trace_t trace;        float[] start_l = { 0, 0, 0 }, end_l = { 0, 0, 0 };        float[] a = { 0, 0, 0 };        float[] forward = { 0, 0, 0 }, right = { 0, 0, 0 }, up = { 0, 0, 0 };        float[] temp = { 0, 0, 0 };        boolean rotated;        // subtract origin offset        Math3D.VectorSubtract(start, origin, start_l);        Math3D.VectorSubtract(end, origin, end_l);        // rotate start and end into the models frame of reference        if (headnode != box_headnode                && (angles[0] != 0 || angles[1] != 0 || angles[2] != 0))            rotated = true;        else            rotated = false;        if (rotated) {            Math3D.AngleVectors(angles, forward, right, up);            Math3D.VectorCopy(start_l, temp);            start_l[0] = Math3D.DotProduct(temp, forward);            start_l[1] = -Math3D.DotProduct(temp, right);            start_l[2] = Math3D.DotProduct(temp, up);            Math3D.VectorCopy(end_l, temp);            end_l[0] = Math3D.DotProduct(temp, forward);            end_l[1] = -Math3D.DotProduct(temp, right);            end_l[2] = Math3D.DotProduct(temp, up);        }        // sweep the box through the model        trace = BoxTrace(start_l, end_l, mins, maxs, headnode, brushmask);        if (rotated && trace.fraction != 1.0) {            // FIXME: figure out how to do this with existing angles            Math3D.VectorNegate(angles, a);            Math3D.AngleVectors(a, forward, right, up);            Math3D.VectorCopy(trace.plane.normal, temp);            trace.plane.normal[0] = Math3D.DotProduct(temp, forward);            trace.plane.normal[1] = -Math3D.DotProduct(temp, right);            trace.plane.normal[2] = Math3D.DotProduct(temp, up);        }        trace.endpos[0] = start[0] + trace.fraction * (end[0] - start[0]);        trace.endpos[1] = start[1] + trace.fraction * (end[1] - start[1]);        trace.endpos[2] = start[2] + trace.fraction * (end[2] - start[2]);        return trace;    }    /*     * ===============================================================================     * PVS / PHS     * ===============================================================================     */    /*     * =================== CM_DecompressVis ===================     */    public static void CM_DecompressVis(byte in[], int offset, byte out[]) {        int c;        int row;        row = (numclusters + 7) >> 3;        int outp = 0;        int inp = offset;        if (in == null || numvisibility == 0) { // no vis info, so make all                                                // visible            while (row != 0) {                out[outp++] = (byte) 0xFF;                row--;            }            return;        }        do {            if (in[inp] != 0) {                out[outp++] = in[inp++];                continue;            }            c = in[inp + 1] & 0xFF;            inp += 2;            if (outp + c > row) {                c = row - (outp);                Com.DPrintf("warning: Vis decompression overrun\n");            }            while (c != 0) {                out[outp++] = 0;                c--;            }        } while (outp < row);    }    public static byte pvsrow[] = new byte[Defines.MAX_MAP_LEAFS / 8];    public static byte phsrow[] = new byte[Defines.MAX_MAP_LEAFS / 8];    public static byte[] CM_ClusterPVS(int cluster) {        if (cluster == -1)            Arrays.fill(pvsrow, 0, (numclusters + 7) >> 3, (byte) 0);        else            CM_DecompressVis(map_visibility,                    map_vis.bitofs[cluster][Defines.DVIS_PVS], pvsrow);        return pvsrow;    }    public static byte[] CM_ClusterPHS(int cluster) {        if (cluster == -1)            Arrays.fill(phsrow, 0, (numclusters + 7) >> 3, (byte) 0);        else            CM_DecompressVis(map_visibility,                    map_vis.bitofs[cluster][Defines.DVIS_PHS], phsrow);        return phsrow;    }    /*     * ===============================================================================     * AREAPORTALS     * ===============================================================================     */    public static void FloodArea_r(carea_t area, int floodnum) {        //Com.Printf("FloodArea_r(" + floodnum + ")...\n");        int i;        qfiles.dareaportal_t p;        if (area.floodvalid == floodvalid) {            if (area.floodnum == floodnum)                return;            Com.Error(Defines.ERR_DROP, "FloodArea_r: reflooded");        }        area.floodnum = floodnum;        area.floodvalid = floodvalid;        for (i = 0; i < area.numareaportals; i++) {            p = map_areaportals[area.firstareaportal + i];            if (portalopen[p.portalnum])                FloodArea_r(map_areas[p.otherarea], floodnum);        }    }    /*     * ==================== FloodAreaConnections ====================     */    public static void FloodAreaConnections() {        Com.DPrintf("FloodAreaConnections...\n");        int i;        carea_t area;        int floodnum;        // all current floods are now invalid        floodvalid++;        floodnum = 0;        // area 0 is not used        for (i = 1; i < numareas; i++) {            area = map_areas[i];            if (area.floodvalid == floodvalid)                continue; // already flooded into            floodnum++;            FloodArea_r(area, floodnum);        }    }    /*     * ================= CM_SetAreaPortalState =================     */    public static void CM_SetAreaPortalState(int portalnum, boolean open) {        if (portalnum > numareaportals)            Com.Error(Defines.ERR_DROP, "areaportal > numareaportals");        portalopen[portalnum] = open;        FloodAreaConnections();    }    /*     * ================= CM_AreasConnected =================     */    public static boolean CM_AreasConnected(int area1, int area2) {        if (map_noareas.value != 0)            return true;        if (area1 > numareas || area2 > numareas)            Com.Error(Defines.ERR_DROP, "area > numareas");        if (map_areas[area1].floodnum == map_areas[area2].floodnum)            return true;        return false;    }    /*     * ================= CM_WriteAreaBits     *      * Writes a length byte followed by a bit vector of all the areas that area     * in the same flood as the area parameter     *      * This is used by the client refreshes to cull visibility =================     */    public static int CM_WriteAreaBits(byte buffer[], int area) {        int i;        int floodnum;        int bytes;        bytes = (numareas + 7) >> 3;        if (map_noareas.value != 0) { // for debugging, send everything            Arrays.fill(buffer, 0, bytes, (byte) 255);        } else {            Arrays.fill(buffer, 0, bytes, (byte) 0);            floodnum = map_areas[area].floodnum;            for (i = 0; i < numareas; i++) {                if (map_areas[i].floodnum == floodnum || area == 0)                    buffer[i >> 3] |= 1 << (i & 7);            }        }        return bytes;    }    /*     * =================== CM_WritePortalState     *      * Writes the portal state to a savegame file ===================     */    public static void CM_WritePortalState(RandomAccessFile os) {        //was: fwrite(portalopen, sizeof(portalopen), 1, f);        try {            for (int n = 0; n < portalopen.length; n++)                if (portalopen[n])                    os.writeInt(1);                else                    os.writeInt(0);        } catch (Exception e) {            Com.Printf("ERROR:" + e);            e.printStackTrace();        }    }    /*     * =================== CM_ReadPortalState     *      * Reads the portal state from a savegame file and recalculates the area     * connections ===================     */    public static void CM_ReadPortalState(RandomAccessFile f) {        //was: FS_Read(portalopen, sizeof(portalopen), f);        int len = portalopen.length * 4;        byte buf[] = new byte[len];        FS.Read(buf, len, f);        ByteBuffer bb = ByteBuffer.wrap(buf);        IntBuffer ib = bb.asIntBuffer();        for (int n = 0; n < portalopen.length; n++)            portalopen[n] = ib.get() != 0;        FloodAreaConnections();    }    /*     * ============= CM_HeadnodeVisible     *      * Returns true if any leaf under headnode has a cluster that is potentially     * visible =============     */    public static boolean CM_HeadnodeVisible(int nodenum, byte visbits[]) {        int leafnum;        int cluster;        cnode_t node;        if (nodenum < 0) {            leafnum = -1 - nodenum;            cluster = map_leafs[leafnum].cluster;            if (cluster == -1)                return false;            if (0 != (visbits[cluster >>> 3] & (1 << (cluster & 7))))                return true;            return false;        }        node = map_nodes[nodenum];        if (CM_HeadnodeVisible(node.children[0], visbits))            return true;        return CM_HeadnodeVisible(node.children[1], visbits);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -