aboutsummaryrefslogtreecommitdiffstats
path: root/src/jake2/render/fastjogl/Model.java
diff options
context:
space:
mode:
authorRene Stoeckel <[email protected]>2004-09-22 19:22:16 +0000
committerRene Stoeckel <[email protected]>2004-09-22 19:22:16 +0000
commitc4fcffe436fbfb5b0f3b7be2e5ee103ec74932f7 (patch)
tree7c9439ab1d9f5a4fd61bd57c755069007b23e0b6 /src/jake2/render/fastjogl/Model.java
parentbcb4ac6eefb425d5b0a90009da506361d5739e75 (diff)
major refactoring in game, server and client package
Diffstat (limited to 'src/jake2/render/fastjogl/Model.java')
-rw-r--r--src/jake2/render/fastjogl/Model.java2558
1 files changed, 1237 insertions, 1321 deletions
diff --git a/src/jake2/render/fastjogl/Model.java b/src/jake2/render/fastjogl/Model.java
index 90cb7c9..080f6dd 100644
--- a/src/jake2/render/fastjogl/Model.java
+++ b/src/jake2/render/fastjogl/Model.java
@@ -2,39 +2,54 @@
* Model.java
* Copyright (C) 2003
*
- * $Id: Model.java,v 1.4 2004-07-19 19:39:57 hzi Exp $
+ * $Id: Model.java,v 1.5 2004-09-22 19:22:10 salomo Exp $
*/
/*
-Copyright (C) 1997-2001 Id Software, Inc.
+ Copyright (C) 1997-2001 Id Software, Inc.
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-See the GNU General Public License for more details.
+ See the GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
+ */
package jake2.render.fastjogl;
import jake2.Defines;
import jake2.client.VID;
import jake2.game.cplane_t;
import jake2.game.cvar_t;
-import jake2.qcommon.*;
-import jake2.render.*;
+import jake2.qcommon.Com;
+import jake2.qcommon.Cvar;
+import jake2.qcommon.FS;
+import jake2.qcommon.lump_t;
+import jake2.qcommon.qfiles;
+import jake2.qcommon.texinfo_t;
+import jake2.render.medge_t;
+import jake2.render.mleaf_t;
+import jake2.render.mmodel_t;
+import jake2.render.mnode_t;
+import jake2.render.model_t;
+import jake2.render.msurface_t;
+import jake2.render.mtexinfo_t;
+import jake2.render.mvertex_t;
import jake2.util.Math3D;
import jake2.util.Vargs;
-import java.nio.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
import java.util.Arrays;
import java.util.Vector;
@@ -42,1310 +57,1211 @@ import net.java.games.jogl.util.BufferUtils;
/**
* Model
- *
+ *
* @author cwei
*/
public abstract class Model extends Surf {
-
- // models.c -- model loading and caching
-
- model_t loadmodel;
- int modfilelen;
-
- byte[] mod_novis = new byte[Defines.MAX_MAP_LEAFS/8];
-
- static final int MAX_MOD_KNOWN = 512;
- model_t[] mod_known = new model_t[MAX_MOD_KNOWN];
- int mod_numknown;
-
- // the inline * models from the current map are kept seperate
- model_t[] mod_inline = new model_t[MAX_MOD_KNOWN];
-
- abstract void GL_SubdivideSurface(msurface_t surface); // Warp.java
-
- /*
- ===============
- Mod_PointInLeaf
- ===============
- */
- mleaf_t Mod_PointInLeaf(float[] p, model_t model)
- {
- mnode_t node;
- float d;
- cplane_t plane;
-
- if (model == null || model.nodes == null)
- Com.Error (Defines.ERR_DROP, "Mod_PointInLeaf: bad model");
-
- node = model.nodes[0]; // root node
- while (true)
- {
- if (node.contents != -1)
- return (mleaf_t)node;
-
- plane = node.plane;
- d = Math3D.DotProduct(p, plane.normal) - plane.dist;
- if (d > 0)
- node = node.children[0];
- else
- node = node.children[1];
- }
- // never reached
- }
-
-
- byte[] decompressed = new byte[Defines.MAX_MAP_LEAFS / 8];
- byte[] model_visibility = new byte[Defines.MAX_MAP_VISIBILITY];
-
- /*
- ===================
- Mod_DecompressVis
- ===================
- */
- byte[] Mod_DecompressVis(byte[] in, int offset, model_t model)
- {
- int c;
- byte[] out;
- int outp, inp;
- int row;
-
- row = (model.vis.numclusters+7)>>3;
- out = decompressed;
- outp = 0;
- inp = offset;
-
- if (in == null)
- { // no vis info, so make all visible
- while (row != 0)
- {
- out[outp++] = (byte)0xFF;
- row--;
- }
- return decompressed;
- }
-
- do
- {
- if (in[inp] != 0)
- {
- out[outp++] = in[inp++];
- continue;
- }
-
- c = in[inp + 1] & 0xFF;
- inp += 2;
- while (c != 0)
- {
- out[outp++] = 0;
- c--;
- }
- } while (outp < row);
-
- return decompressed;
- }
-
- /*
- ==============
- Mod_ClusterPVS
- ==============
- */
- byte[] Mod_ClusterPVS(int cluster, model_t model)
- {
- if (cluster == -1 || model.vis == null)
- return mod_novis;
- //return Mod_DecompressVis( (byte *)model.vis + model.vis.bitofs[cluster][Defines.DVIS_PVS], model);
- return Mod_DecompressVis(model_visibility, model.vis.bitofs[cluster][Defines.DVIS_PVS], model);
- }
-
-
-// ===============================================================================
-
- /*
- ================
- Mod_Modellist_f
- ================
- */
- void Mod_Modellist_f()
- {
- int i;
- model_t mod;
- int total;
-
- total = 0;
- VID.Printf(Defines.PRINT_ALL,"Loaded models:\n");
- for (i=0; i < mod_numknown ; i++)
- {
- mod = mod_known[i];
- if (mod.name == "")
- continue;
-
- VID.Printf (Defines.PRINT_ALL, "%8i : %s\n", new Vargs(2).add(mod.extradatasize).add(mod.name));
- total += mod.extradatasize;
- }
- VID.Printf (Defines.PRINT_ALL, "Total resident: " + total +'\n');
- }
-
- /*
- ===============
- Mod_Init
- ===============
- */
- void Mod_Init()
- {
- // init mod_known
- for (int i=0; i < MAX_MOD_KNOWN; i++) {
- mod_known[i] = new model_t();
- }
- Arrays.fill(mod_novis, (byte)0xff);
- }
-
- byte[] fileBuffer;
-
- /*
- ==================
- Mod_ForName
-
- Loads in a model for the given name
- ==================
- */
- model_t Mod_ForName(String name, boolean crash)
- {
- model_t mod = null;
- int i;
-
- if (name == null || name.length() == 0)
- Com.Error(Defines.ERR_DROP, "Mod_ForName: NULL name");
-
- //
- // inline models are grabbed only from worldmodel
- //
- if (name.charAt(0) == '*')
- {
- i = Integer.parseInt(name.substring(1));
- if (i < 1 || r_worldmodel == null || i >= r_worldmodel.numsubmodels)
- Com.Error (Defines.ERR_DROP, "bad inline model number");
- return mod_inline[i];
- }
-
- //
- // search the currently loaded models
- //
- for (i=0; i<mod_numknown ; i++)
- {
- mod = mod_known[i];
-
- if (mod.name == "")
- continue;
- if (mod.name.equals(name) )
- return mod;
- }
-
- //
- // find a free model slot spot
- //
- for (i=0; i<mod_numknown ; i++)
- {
- mod = mod_known[i];
-
- if (mod.name == "")
- break; // free spot
- }
- if (i == mod_numknown)
- {
- if (mod_numknown == MAX_MOD_KNOWN)
- Com.Error (Defines.ERR_DROP, "mod_numknown == MAX_MOD_KNOWN");
- mod_numknown++;
- mod = mod_known[i];
- }
-
- mod.name = name;
-
- //
- // load the file
- //
- fileBuffer = FS.LoadFile(name);
-
- if (fileBuffer == null)
- {
- if (crash)
- Com.Error(Defines.ERR_DROP, "Mod_NumForName: " + mod.name + " not found");
-
- mod.name = "";
- return null;
- }
-
- modfilelen = fileBuffer.length;
-
- loadmodel = mod;
-
- //
- // fill it in
- //
- ByteBuffer bb = ByteBuffer.wrap(fileBuffer);
- bb.order(ByteOrder.LITTLE_ENDIAN);
-
- // call the apropriate loader
-
- bb.mark();
- int ident = bb.getInt();
-
- bb.reset();
-
- switch (ident)
- {
- case qfiles.IDALIASHEADER:
- Mod_LoadAliasModel(mod, bb);
- break;
- case qfiles.IDSPRITEHEADER:
- Mod_LoadSpriteModel(mod, bb);
- break;
- case qfiles.IDBSPHEADER:
- Mod_LoadBrushModel(mod, bb);
- break;
- default:
- Com.Error(Defines.ERR_DROP,"Mod_NumForName: unknown fileid for " + mod.name);
- break;
- }
-
- this.fileBuffer = null; // free it for garbage collection
- return mod;
- }
-
- /*
- ===============================================================================
-
- BRUSHMODEL LOADING
-
- ===============================================================================
- */
-
- byte[] mod_base;
-
-
- /*
- =================
- Mod_LoadLighting
- =================
- */
- void Mod_LoadLighting(lump_t l)
- {
- if (l.filelen == 0)
- {
- loadmodel.lightdata = null;
- return;
- }
- // memcpy (loadmodel.lightdata, mod_base + l.fileofs, l.filelen);
- loadmodel.lightdata = new byte[l.filelen];
- System.arraycopy(mod_base, l.fileofs, loadmodel.lightdata, 0, l.filelen);
- }
-
-
- /*
- =================
- Mod_LoadVisibility
- =================
- */
- void Mod_LoadVisibility(lump_t l)
- {
- int i;
-
- if (l.filelen == 0)
- {
- loadmodel.vis = null;
- return;
- }
-
- System.arraycopy(mod_base, l.fileofs, model_visibility, 0, l.filelen);
-
- ByteBuffer bb = ByteBuffer.wrap(model_visibility, 0, l.filelen);
-
- loadmodel.vis = new qfiles.dvis_t(bb.order(ByteOrder.LITTLE_ENDIAN));
-
- /* done:
- memcpy (loadmodel.vis, mod_base + l.fileofs, l.filelen);
-
- loadmodel.vis.numclusters = LittleLong (loadmodel.vis.numclusters);
- for (i=0 ; i<loadmodel.vis.numclusters ; i++)
- {
- loadmodel.vis.bitofs[i][0] = LittleLong (loadmodel.vis.bitofs[i][0]);
- loadmodel.vis.bitofs[i][1] = LittleLong (loadmodel.vis.bitofs[i][1]);
- }
- */
- }
-
-
- /*
- =================
- Mod_LoadVertexes
- =================
- */
- void Mod_LoadVertexes(lump_t l)
- {
- mvertex_t[] vertexes;
- int i, count;
-
- if ( (l.filelen % mvertex_t.DISK_SIZE) != 0)
- Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
-
- count = l.filelen / mvertex_t.DISK_SIZE;
-
- vertexes = new mvertex_t[count];
-
- loadmodel.vertexes = vertexes;
- loadmodel.numvertexes = count;
-
- ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
- bb.order(ByteOrder.LITTLE_ENDIAN);
-
- for ( i=0 ; i<count ; i++)
- {
- vertexes[i] = new mvertex_t(bb);
- }
- }
-
- /*
- =================
- RadiusFromBounds
- =================
- */
- float RadiusFromBounds(float[] mins, float[] maxs)
- {
- float[] corner = {0, 0, 0};
-
- for (int i=0 ; i<3 ; i++)
- {
- corner[i] = Math.abs(mins[i]) > Math.abs(maxs[i]) ? Math.abs(mins[i]) : Math.abs(maxs[i]);
- }
- return Math3D.VectorLength(corner);
- }
-
-
- /*
- =================
- Mod_LoadSubmodels
- =================
- */
- void Mod_LoadSubmodels(lump_t l)
- {
- qfiles.dmodel_t in;
- mmodel_t[] out;
- int i, j, count;
-
- if ((l.filelen % qfiles.dmodel_t.SIZE) != 0)
- Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
-
- count = l.filelen / qfiles.dmodel_t.SIZE;
- // out = Hunk_Alloc ( count*sizeof(*out));
- out = new mmodel_t[count];
-
- loadmodel.submodels = out;
- loadmodel.numsubmodels = count;
-
- ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
- bb.order(ByteOrder.LITTLE_ENDIAN);
-
- for ( i=0 ; i<count ; i++)
- {
- in = new qfiles.dmodel_t(bb);
- out[i] = new mmodel_t();
- for (j=0 ; j<3 ; j++)
- { // spread the mins / maxs by a pixel
- out[i].mins[j] = in.mins[j] - 1;
- out[i].maxs[j] = in.maxs[j] + 1;
- out[i].origin[j] = in.origin[j];
- }
- out[i].radius = RadiusFromBounds(out[i].mins, out[i].maxs);
- out[i].headnode = in.headnode;
- out[i].firstface = in.firstface;
- out[i].numfaces = in.numfaces;
- }
- }
-
- /*
- =================
- Mod_LoadEdges
- =================
- */
- void Mod_LoadEdges (lump_t l)
- {
- medge_t[] edges;
- int i, count;
-
- if ( (l.filelen % medge_t.DISK_SIZE) != 0)
- Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
-
- count = l.filelen / medge_t.DISK_SIZE;
- // out = Hunk_Alloc ( (count + 1) * sizeof(*out));
- edges = new medge_t[count + 1];
-
- loadmodel.edges = edges;
- loadmodel.numedges = count;
-
- ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
- bb.order(ByteOrder.LITTLE_ENDIAN);
-
- for ( i=0 ; i<count ; i++)
- {
- edges[i] = new medge_t(bb);
- }
- }
-
- /*
- =================
- Mod_LoadTexinfo
- =================
- */
- void Mod_LoadTexinfo(lump_t l)
- {
- texinfo_t in;
- mtexinfo_t[] out;
- mtexinfo_t step;
- int i, j, count;
- int next;
- String name;
-
- if ((l.filelen % texinfo_t.SIZE) != 0)
- Com.Error (Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
-
- count = l.filelen / texinfo_t.SIZE;
- // out = Hunk_Alloc ( count*sizeof(*out));
- out = new mtexinfo_t[count];
- for ( i=0 ; i<count ; i++) {
- out[i] = new mtexinfo_t();
- }
-
- loadmodel.texinfo = out;
- loadmodel.numtexinfo = count;
-
- ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
- bb.order(ByteOrder.LITTLE_ENDIAN);
-
- for ( i=0 ; i<count ; i++) {
-
- in = new texinfo_t(bb);
- out[i].vecs = in.vecs;
- out[i].flags = in.flags;
- next = in.nexttexinfo;
- if (next > 0)
- out[i].next = loadmodel.texinfo[next];
- else
- out[i].next = null;
-
- name = "textures/" + in.texture + ".wal";
-
- out[i].image = GL_FindImage(name, it_wall);
- if (out[i].image == null) {
- VID.Printf(Defines.PRINT_ALL, "Couldn't load " + name + '\n');
- out[i].image = r_notexture;
- }
- }
-
- // count animation frames
- for (i=0 ; i<count ; i++) {
- out[i].numframes = 1;
- for (step = out[i].next ; (step != null) && (step != out[i]) ; step=step.next)
- out[i].numframes++;
- }
- }
-
- /*
- ================
- CalcSurfaceExtents
-
- Fills in s.texturemins[] and s.extents[]
- ================
- */
- void CalcSurfaceExtents(msurface_t s)
- {
- float[] mins = {0, 0};
- float[] maxs = {0, 0};
- float val;
-
- int j, e;
- mvertex_t v;
- int[] bmins = {0, 0};
- int[] bmaxs = {0, 0};
-
- mins[0] = mins[1] = 999999;
- maxs[0] = maxs[1] = -99999;
-
- mtexinfo_t tex = s.texinfo;
-
- for (int i=0 ; i<s.numedges ; i++)
- {
- e = loadmodel.surfedges[s.firstedge+i];
- if (e >= 0)
- v = loadmodel.vertexes[loadmodel.edges[e].v[0]];
- else
- v = loadmodel.vertexes[loadmodel.edges[-e].v[1]];
-
- for (j=0 ; j<2 ; j++)
- {
- val = v.position[0] * tex.vecs[j][0] +
- v.position[1] * tex.vecs[j][1] +
- v.position[2] * tex.vecs[j][2] +
- tex.vecs[j][3];
- if (val < mins[j])
- mins[j] = val;
- if (val > maxs[j])
- maxs[j] = val;
- }
- }
-
- for (int i=0 ; i<2 ; i++)
- {
- bmins[i] = (int)Math.floor(mins[i]/16);
- bmaxs[i] = (int)Math.ceil(maxs[i]/16);
-
- s.texturemins[i] = (short)(bmins[i] * 16);
- s.extents[i] = (short)((bmaxs[i] - bmins[i]) * 16);
-
- }
- }
-
- /*
- =================
- Mod_LoadFaces
- =================
- */
- void Mod_LoadFaces (lump_t l)
- {
- qfiles.dface_t in;
- msurface_t[] out;
- int i, count, surfnum;
- int planenum, side;
- int ti;
-
- if ((l.filelen % qfiles.dface_t.SIZE) != 0)
- Com.Error (Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
-
- count = l.filelen / qfiles.dface_t.SIZE;
- // out = Hunk_Alloc ( count*sizeof(*out));
- out = new msurface_t[count];
-
- loadmodel.surfaces = out;
- loadmodel.numsurfaces = count;
-
- ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
- bb.order(ByteOrder.LITTLE_ENDIAN);
-
- currentmodel = loadmodel;
-
- GL_BeginBuildingLightmaps(loadmodel);
-
- for ( surfnum=0 ; surfnum<count ; surfnum++)
- {
- in = new qfiles.dface_t(bb);
- out[surfnum] = new msurface_t();
- out[surfnum].firstedge = in.firstedge;
- out[surfnum].numedges = in.numedges;
- out[surfnum].flags = 0;
- out[surfnum].polys = null;
-
- planenum = in.planenum;
- side = in.side;
- if (side != 0)
- out[surfnum].flags |= Defines.SURF_PLANEBACK;
-
- out[surfnum].plane = loadmodel.planes[planenum];
-
- ti = in.texinfo;
- if (ti < 0 || ti >= loadmodel.numtexinfo)
- Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: bad texinfo number");
-
- out[surfnum].texinfo = loadmodel.texinfo[ti];
-
- CalcSurfaceExtents(out[surfnum]);
-
- // lighting info
-
- for (i=0 ; i<Defines.MAXLIGHTMAPS ; i++)
- out[surfnum].styles[i] = in.styles[i];
-
- i = in.lightofs;
- if (i == -1)
- out[surfnum].samples = null;
- else {
- ByteBuffer pointer = ByteBuffer.wrap(loadmodel.lightdata);
- pointer.position(i);
- pointer = pointer.slice();
- pointer.mark();
- out[surfnum].samples = pointer; // subarray
- }
-
- // set the drawing flags
-
- if ((out[surfnum].texinfo.flags & Defines.SURF_WARP) != 0)
- {
- out[surfnum].flags |= Defines.SURF_DRAWTURB;
- for (i=0 ; i<2 ; i++)
- {
- out[surfnum].extents[i] = 16384;
- out[surfnum].texturemins[i] = -8192;
- }
- GL_SubdivideSurface(out[surfnum]); // cut up polygon for warps
- }
-
- // create lightmaps and polygons
- if ((out[surfnum].texinfo.flags & (Defines.SURF_SKY | Defines.SURF_TRANS33 | Defines.SURF_TRANS66 | Defines.SURF_WARP)) == 0)
- GL_CreateSurfaceLightmap(out[surfnum]);
-
- if ((out[surfnum].texinfo.flags & Defines.SURF_WARP) == 0)
- GL_BuildPolygonFromSurface(out[surfnum]);
-
- }
- GL_EndBuildingLightmaps ();
- }
-
-
- /*
- =================
- Mod_SetParent
- =================
- */
- void Mod_SetParent(mnode_t node, mnode_t parent)
- {
- node.parent = parent;
- if (node.contents != -1) return;
- Mod_SetParent(node.children[0], node);
- Mod_SetParent(node.children[1], node);
- }
-
- /*
- =================
- Mod_LoadNodes
- =================
- */
- void Mod_LoadNodes(lump_t l)
- {
- int i, j, count, p;
- qfiles.dnode_t in;
- mnode_t[] out;
-
- if ((l.filelen % qfiles.dnode_t.SIZE) != 0)
- Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
-
- count = l.filelen / qfiles.dnode_t.SIZE;
- // out = Hunk_Alloc ( count*sizeof(*out));
- out = new mnode_t[count];
-
- loadmodel.nodes = out;
- loadmodel.numnodes = count;
-
- ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
- bb.order(ByteOrder.LITTLE_ENDIAN);
-
- // initialize the tree array
- for ( i=0 ; i<count ; i++) out[i] = new mnode_t(); // do first before linking
-
- // fill and link the nodes
- for ( i=0 ; i<count ; i++)
- {
- in = new qfiles.dnode_t(bb);
- for (j=0 ; j<3 ; j++)
- {
- out[i].mins[j] = in.mins[j];
- out[i].maxs[j] = in.maxs[j];
- }
-
- p = in.planenum;
- out[i].plane = loadmodel.planes[p];
-
- out[i].firstsurface = in.firstface;
- out[i].numsurfaces = in.numfaces;
- out[i].contents = -1; // differentiate from leafs
-
- for (j=0 ; j<2 ; j++)
- {
- p = in.children[j];
- if (p >= 0)
- out[i].children[j] = loadmodel.nodes[p];
- else
- out[i].children[j] = loadmodel.leafs[-1 - p]; // mleaf_t extends mnode_t
- }
- }
-
- Mod_SetParent(loadmodel.nodes[0], null); // sets nodes and leafs
- }
-
- /*
- =================
- Mod_LoadLeafs
- =================
- */
- void Mod_LoadLeafs(lump_t l)
- {
- qfiles.dleaf_t in;
- mleaf_t[] out;
- int i, j, count, p;
-
- if ((l.filelen % qfiles.dleaf_t.SIZE) != 0)
- Com.Error (Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
-
- count = l.filelen / qfiles.dleaf_t.SIZE;
- // out = Hunk_Alloc ( count*sizeof(*out));
- out = new mleaf_t[count];
-
- loadmodel.leafs = out;
- loadmodel.numleafs = count;
-
- ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
- bb.order(ByteOrder.LITTLE_ENDIAN);
-
- for ( i=0 ; i<count ; i++)
- {
- in = new qfiles.dleaf_t(bb);
- out[i] = new mleaf_t();
- for (j=0 ; j<3 ; j++)
- {
- out[i].mins[j] = in.mins[j];
- out[i].maxs[j] = in.maxs[j];
-
- }
-
- out[i].contents = in.contents;
- out[i].cluster = in.cluster;
- out[i].area = in.area;
-
- out[i].setMarkSurface(in.firstleafface, loadmodel.marksurfaces);
- out[i].nummarksurfaces = in.numleaffaces;
- }
- }
-
-
- /*
- =================
- Mod_LoadMarksurfaces
- =================
- */
- void Mod_LoadMarksurfaces(lump_t l)
- {
- int i, j, count;
-
- msurface_t[] out;
-
- if ((l.filelen % Defines.SIZE_OF_SHORT) != 0)
- Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
- count = l.filelen / Defines.SIZE_OF_SHORT;
- // out = Hunk_Alloc ( count*sizeof(*out));
- out = new msurface_t[count];
-
- loadmodel.marksurfaces = out;
- loadmodel.nummarksurfaces = count;
-
- ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
- bb.order(ByteOrder.LITTLE_ENDIAN);
-
- for ( i=0 ; i<count ; i++)
- {
- j = bb.getShort();
- if (j < 0 || j >= loadmodel.numsurfaces)
- Com.Error(Defines.ERR_DROP, "Mod_ParseMarksurfaces: bad surface number");
-
- out[i] = loadmodel.surfaces[j];
- }
- }
-
-
- /*
- =================
- Mod_LoadSurfedges
- =================
- */
- void Mod_LoadSurfedges(lump_t l)
- {
- int i, count;
- int[] offsets;
-
- if ( (l.filelen % Defines.SIZE_OF_INT) != 0)
- Com.Error (Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
-
- count = l.filelen / Defines.SIZE_OF_INT;
- if (count < 1 || count >= Defines.MAX_MAP_SURFEDGES)
- Com.Error (Defines.ERR_DROP, "MOD_LoadBmodel: bad surfedges count in " + loadmodel.name + ": " + count);
-
- offsets = new int[count];
-
- loadmodel.surfedges = offsets;
- loadmodel.numsurfedges = count;
-
- ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
- bb.order(ByteOrder.LITTLE_ENDIAN);
-
- for ( i=0 ; i<count ; i++) offsets[i] = bb.getInt();
- }
-
-
- /*
- =================
- Mod_LoadPlanes
- =================
- */
- void Mod_LoadPlanes(lump_t l)
- {
- int i, j;
- cplane_t[] out;
- qfiles.dplane_t in;
- int count;
- int bits;
-
- if ((l.filelen % qfiles.dplane_t.SIZE) != 0)
- Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
-
- count = l.filelen / qfiles.dplane_t.SIZE;
- // out = Hunk_Alloc ( count*2*sizeof(*out));
- out = new cplane_t[count * 2];
-
- loadmodel.planes = out;
- loadmodel.numplanes = count;
-
- ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
- bb.order(ByteOrder.LITTLE_ENDIAN);
-
- for ( i=0 ; i<count ; i++)
- {
- bits = 0;
- in = new qfiles.dplane_t(bb);
- out[i] = new cplane_t();
- for (j=0 ; j<3 ; j++)
- {
- out[i].normal[j] = in.normal[j];
- if (out[i].normal[j] < 0)
- bits |= (1<<j);
- }
-
- out[i].dist = in.dist;
- out[i].type = (byte)in.type;
- out[i].signbits = (byte)bits;
- }
- }
-
- /*
- =================
- Mod_LoadBrushModel
- =================
- */
- void Mod_LoadBrushModel(model_t mod, ByteBuffer buffer)
- {
- int i;
- qfiles.dheader_t header;
- mmodel_t bm;
-
- loadmodel.type = mod_brush;
- if (loadmodel != mod_known[0])
- Com.Error(Defines.ERR_DROP, "Loaded a brush model after the world");
-
- header = new qfiles.dheader_t(buffer);
-
- i = header.version;
- if (i != Defines.BSPVERSION)
- Com.Error (Defines.ERR_DROP, "Mod_LoadBrushModel: " + mod.name + " has wrong version number (" + i + " should be " + Defines.BSPVERSION + ")");
-
- mod_base = fileBuffer; //(byte *)header;
-
- // load into heap
- Mod_LoadVertexes(header.lumps[Defines.LUMP_VERTEXES]); // ok
- Mod_LoadEdges(header.lumps[Defines.LUMP_EDGES]); // ok
- Mod_LoadSurfedges(header.lumps[Defines.LUMP_SURFEDGES]); // ok
- Mod_LoadLighting(header.lumps[Defines.LUMP_LIGHTING]); // ok
- Mod_LoadPlanes(header.lumps[Defines.LUMP_PLANES]); // ok
- Mod_LoadTexinfo(header.lumps[Defines.LUMP_TEXINFO]); // ok
- Mod_LoadFaces(header.lumps[Defines.LUMP_FACES]); // ok
- Mod_LoadMarksurfaces(header.lumps[Defines.LUMP_LEAFFACES]);
- Mod_LoadVisibility(header.lumps[Defines.LUMP_VISIBILITY]); // ok
- Mod_LoadLeafs(header.lumps[Defines.LUMP_LEAFS]); // ok
- Mod_LoadNodes(header.lumps[Defines.LUMP_NODES]); // ok
- Mod_LoadSubmodels(header.lumps[Defines.LUMP_MODELS]);
- mod.numframes = 2; // regular and alternate animation
-
- //
- // set up the submodels
- //
- model_t starmod;
-
- for (i=0 ; i<mod.numsubmodels ; i++)
- {
-
- bm = mod.submodels[i];
- starmod = mod_inline[i] = loadmodel.copy();
-
- starmod.firstmodelsurface = bm.firstface;
- starmod.nummodelsurfaces = bm.numfaces;
- starmod.firstnode = bm.headnode;
- if (starmod.firstnode >= loadmodel.numnodes)
- Com.Error(Defines.ERR_DROP, "Inline model " + i + " has bad firstnode");
-
- Math3D.VectorCopy(bm.maxs, starmod.maxs);
- Math3D.VectorCopy(bm.mins, starmod.mins);
- starmod.radius = bm.radius;
-
- if (i == 0)
- loadmodel = starmod.copy();
-
- starmod.numleafs = bm.visleafs;
- }
- }
-
- /*
- ==============================================================================
-
- ALIAS MODELS
-
- ==============================================================================
- */
-
- /*
- =================
- Mod_LoadAliasModel
- =================
- */
- void Mod_LoadAliasModel (model_t mod, ByteBuffer buffer)
- {
- int i, j;
- qfiles.dmdl_t pheader;
- qfiles.dstvert_t[] poutst;
- qfiles.dtriangle_t[] pouttri;
- qfiles.daliasframe_t[] poutframe;
- int[] poutcmd;
-
- pheader = new qfiles.dmdl_t(buffer);
-
- if (pheader.version != qfiles.ALIAS_VERSION)
- Com.Error(Defines.ERR_DROP, "%s has wrong version number (%i should be %i)",
- new Vargs(3).add(mod.name).add(pheader.version).add(qfiles.ALIAS_VERSION));
-
- if (pheader.skinheight > MAX_LBM_HEIGHT)
- Com.Error(Defines.ERR_DROP, "model "+ mod.name +" has a skin taller than " + MAX_LBM_HEIGHT);
-
- if (pheader.num_xyz <= 0)
- Com.Error(Defines.ERR_DROP, "model " + mod.name + " has no vertices");
-
- if (pheader.num_xyz > qfiles.MAX_VERTS)
- Com.Error(Defines.ERR_DROP, "model " + mod.name +" has too many vertices");
-
- if (pheader.num_st <= 0)
- Com.Error(Defines.ERR_DROP, "model " + mod.name + " has no st vertices");
-
- if (pheader.num_tris <= 0)
- Com.Error(Defines.ERR_DROP, "model " + mod.name + " has no triangles");
-
- if (pheader.num_frames <= 0)
- Com.Error(Defines.ERR_DROP, "model " + mod.name + " has no frames");
-
- //
- // load base s and t vertices (not used in gl version)
- //
- poutst = new qfiles.dstvert_t[pheader.num_st];
- buffer.position(pheader.ofs_st);
- for (i=0 ; i<pheader.num_st ; i++)
- {
- poutst[i] = new qfiles.dstvert_t(buffer);
- }
-
- //
- // load triangle lists
- //
- pouttri = new qfiles.dtriangle_t[pheader.num_tris];
- buffer.position(pheader.ofs_tris);
- for (i=0 ; i<pheader.num_tris ; i++)
- {
- pouttri[i] = new qfiles.dtriangle_t(buffer);
- }
-
- //
- // load the frames
- //
- poutframe = new qfiles.daliasframe_t[pheader.num_frames];
- buffer.position(pheader.ofs_frames);
- for (i=0 ; i<pheader.num_frames ; i++)
- {
- poutframe[i] = new qfiles.daliasframe_t(buffer);
- // verts are all 8 bit, so no swapping needed
- poutframe[i].verts = new qfiles.dtrivertx_t[pheader.num_xyz];
- for (int k=0; k < pheader.num_xyz; k++) {
- poutframe[i].verts[k] = new qfiles.dtrivertx_t(buffer);
- }
- }
-
- mod.type = mod_alias;
-
- //
- // load the glcmds
- //
- poutcmd = new int[pheader.num_glcmds];
- buffer.position(pheader.ofs_glcmds);
- for (i=0 ; i<pheader.num_glcmds ; i++)
- poutcmd[i] = buffer.getInt(); // LittleLong (pincmd[i]);
-
- // register all skins
- String[] skinNames = new String[pheader.num_skins];
- byte[] nameBuf = new byte[qfiles.MAX_SKINNAME];
- buffer.position(pheader.ofs_skins);
- for (i=0 ; i<pheader.num_skins ; i++)
- {
- buffer.get(nameBuf);
- skinNames[i] = new String(nameBuf);
- int n = skinNames[i].indexOf('\0');
- if (n > -1) {
- skinNames[i] = skinNames[i].substring(0, n);
- }
- mod.skins[i] = GL_FindImage(skinNames[i], it_skin);
- }
-
- // set the model arrays
- pheader.skinNames = skinNames; // skin names
- pheader.stVerts = poutst; // textur koordinaten
- pheader.triAngles = pouttri; // dreiecke
- pheader.glCmds = poutcmd; // STRIP or FAN
- pheader.aliasFrames = poutframe; // frames mit vertex array
-
- mod.extradata = pheader;
-
- mod.mins[0] = -32;
- mod.mins[1] = -32;
- mod.mins[2] = -32;
- mod.maxs[0] = 32;
- mod.maxs[1] = 32;
- mod.maxs[2] = 32;
-
- precompileGLCmds(pheader);
- }
-
- /*
- ==============================================================================
-
- SPRITE MODELS
-
- ==============================================================================
- */
-
- /*
- =================
- Mod_LoadSpriteModel
- =================
- */
- void Mod_LoadSpriteModel(model_t mod, ByteBuffer buffer)
- {
- qfiles.dsprite_t sprout = new qfiles.dsprite_t(buffer);
-
- if (sprout.version != qfiles.SPRITE_VERSION)
- Com.Error(Defines.ERR_DROP, "%s has wrong version number (%i should be %i)",
- new Vargs(3).add(mod.name).add(sprout.version).add(qfiles.SPRITE_VERSION));
-
- if (sprout.numframes > qfiles.MAX_MD2SKINS)
- Com.Error(Defines.ERR_DROP, "%s has too many frames (%i > %i)",
- new Vargs(3).add(mod.name).add(sprout.numframes).add(qfiles.MAX_MD2SKINS));
-
- for (int i=0 ; i<sprout.numframes ; i++)
- {
- mod.skins[i] = GL_FindImage(sprout.frames[i].name, it_sprite);
- }
-
- mod.type = mod_sprite;
- mod.extradata = sprout;
- }
-
-// =============================================================================
-
- /*
- @@@@@@@@@@@@@@@@@@@@@
- R_BeginRegistration
-
- Specifies the model that will be used as the world
- @@@@@@@@@@@@@@@@@@@@@
- */
- protected void R_BeginRegistration(String model)
- {
- resetModelArrays();
- resetPolygonArrays();
-
- cvar_t flushmap;
-
- registration_sequence++;
- r_oldviewcluster = -1; // force markleafs
-
- String fullname = "maps/" + model + ".bsp";
-
- // explicitly free the old map if different
- // this guarantees that mod_known[0] is the world map
- flushmap = Cvar.Get("flushmap", "0", 0);
- if ( !mod_known[0].name.equals(fullname) || flushmap.value != 0.0f)
- Mod_Free(mod_known[0]);
- r_worldmodel = Mod_ForName(fullname, true);
-
- r_viewcluster = -1;
- }
-
-
- /*
- @@@@@@@@@@@@@@@@@@@@@
- R_RegisterModel
-
- @@@@@@@@@@@@@@@@@@@@@
- */
- protected model_t R_RegisterModel(String name)
- {
- model_t mod = null;
- int i;
- qfiles.dsprite_t sprout;
- qfiles.dmdl_t pheader;
-
- mod = Mod_ForName(name, false);
- if (mod != null)
- {
- mod.registration_sequence = registration_sequence;
-
- // register any images used by the models
- if (mod.type == mod_sprite)
- {
- sprout = (qfiles.dsprite_t)mod.extradata;
- for (i=0 ; i<sprout.numframes ; i++)
- mod.skins[i] = GL_FindImage(sprout.frames[i].name, it_sprite);
- }
- else if (mod.type == mod_alias)
- {
- pheader = (qfiles.dmdl_t)mod.extradata;
- for (i=0 ; i<pheader.num_skins ; i++)
- mod.skins[i] = GL_FindImage(pheader.skinNames[i], it_skin);
- // PGM
- mod.numframes = pheader.num_frames;
- // PGM
- }
- else if (mod.type == mod_brush)
- {
- for (i=0 ; i<mod.numtexinfo ; i++)
- mod.texinfo[i].image.registration_sequence = registration_sequence;
- }
- }
- return mod;
- }
-
-
- /*
- @@@@@@@@@@@@@@@@@@@@@
- R_EndRegistration
-
- @@@@@@@@@@@@@@@@@@@@@
- */
- protected void R_EndRegistration()
- {
- model_t mod;
-
- for (int i=0; i<mod_numknown ; i++)
- {
- mod = mod_known[i];
- if (mod.name == "")
- continue;
- if (mod.registration_sequence != registration_sequence)
- { // don't need this model
- Mod_Free(mod);
- } else {
- // precompile AliasModels
- if (mod.type == mod_alias)
- precompileGLCmds((qfiles.dmdl_t)mod.extradata);
- }
- }
- GL_FreeUnusedImages();
-
- //modelMemoryUsage();
- }
-
-
-// =============================================================================
-
-
- /*
- ================
- Mod_Free
- ================
- */
- void Mod_Free (model_t mod)
- {
- mod.clear();
- }
-
- /*
- ================
- Mod_FreeAll
- ================
- */
- void Mod_FreeAll()
- {
- for (int i=0 ; i<mod_numknown ; i++)
- {
- if (mod_known[i].extradata != null)
- Mod_Free(mod_known[i]);
- }
- }
-
- /*
- * new functions for vertex array handling
- */
- static final int MODEL_BUFFER_SIZE = 50000;
- static FloatBuffer globalModelTextureCoordBuf = BufferUtils.newFloatBuffer(MODEL_BUFFER_SIZE * 2);
- static IntBuffer globalModelVertexIndexBuf = BufferUtils.newIntBuffer(MODEL_BUFFER_SIZE);
-
- void precompileGLCmds(qfiles.dmdl_t model) {
- model.textureCoordBuf = globalModelTextureCoordBuf.slice();
- model.vertexIndexBuf = globalModelVertexIndexBuf.slice();
- Vector tmp = new Vector();
-
- int count = 0;
- int[] order = model.glCmds;
- int orderIndex = 0;
- while (true)
- {
- // get the vertex count and primitive type
- count = order[orderIndex++];
- if (count == 0)
- break; // done
-
- tmp.addElement(new Integer(count));
-
- if (count < 0)
- {
- count = -count;
- //gl.glBegin (GL.GL_TRIANGLE_FAN);
- }
- else
- {
- //gl.glBegin (GL.GL_TRIANGLE_STRIP);
- }
-
- do {
- // texture coordinates come from the draw list
- globalModelTextureCoordBuf.put(Float.intBitsToFloat(order[orderIndex + 0]));
- globalModelTextureCoordBuf.put(Float.intBitsToFloat(order[orderIndex + 1]));
- globalModelVertexIndexBuf.put(order[orderIndex + 2]);
-
- orderIndex += 3;
- } while (--count != 0);
- }
-
- int size = tmp.size();
-
- model.counts = new int[size];
- model.indexElements = new IntBuffer[size];
-
- count = 0;
- int pos = 0;
- for (int i = 0; i < model.counts.length; i++) {
- count = ((Integer)tmp.get(i)).intValue();
- model.counts[i] = count;
-
- count = (count < 0) ? -count : count;
- model.vertexIndexBuf.position(pos);
- model.indexElements[i] = model.vertexIndexBuf.slice();
- pos += count;
- }
- }
-
- static void resetModelArrays() {
- globalModelTextureCoordBuf.rewind();
- globalModelVertexIndexBuf.rewind();
- }
-
- static void modelMemoryUsage() {
- System.out.println("AliasModels: globalVertexBuffer size " + globalModelVertexIndexBuf.position());
- }
-}
+
+ // models.c -- model loading and caching
+
+ model_t loadmodel;
+
+ int modfilelen;
+
+ byte[] mod_novis = new byte[Defines.MAX_MAP_LEAFS / 8];
+
+ static final int MAX_MOD_KNOWN = 512;
+
+ model_t[] mod_known = new model_t[MAX_MOD_KNOWN];
+
+ int mod_numknown;
+
+ // the inline * models from the current map are kept seperate
+ model_t[] mod_inline = new model_t[MAX_MOD_KNOWN];
+
+ abstract void GL_SubdivideSurface(msurface_t surface); // Warp.java
+
+ /*
+ * =============== Mod_PointInLeaf ===============
+ */
+ mleaf_t Mod_PointInLeaf(float[] p, model_t model) {
+ mnode_t node;
+ float d;
+ cplane_t plane;
+
+ if (model == null || model.nodes == null)
+ Com.Error(Defines.ERR_DROP, "Mod_PointInLeaf: bad model");
+
+ node = model.nodes[0]; // root node
+ while (true) {
+ if (node.contents != -1)
+ return (mleaf_t) node;
+
+ plane = node.plane;
+ d = Math3D.DotProduct(p, plane.normal) - plane.dist;
+ if (d > 0)
+ node = node.children[0];
+ else
+ node = node.children[1];
+ }
+ // never reached
+ }
+
+ byte[] decompressed = new byte[Defines.MAX_MAP_LEAFS / 8];
+
+ byte[] model_visibility = new byte[Defines.MAX_MAP_VISIBILITY];
+
+ /*
+ * =================== Mod_DecompressVis ===================
+ */
+ byte[] Mod_DecompressVis(byte[] in, int offset, model_t model) {
+ int c;
+ byte[] out;
+ int outp, inp;
+ int row;
+
+ row = (model.vis.numclusters + 7) >> 3;
+ out = decompressed;
+ outp = 0;
+ inp = offset;
+
+ if (in == null) { // no vis info, so make all visible
+ while (row != 0) {
+ out[outp++] = (byte) 0xFF;
+ row--;
+ }
+ return decompressed;
+ }
+
+ do {
+ if (in[inp] != 0) {
+ out[outp++] = in[inp++];
+ continue;
+ }
+
+ c = in[inp + 1] & 0xFF;
+ inp += 2;
+ while (c != 0) {
+ out[outp++] = 0;
+ c--;
+ }
+ } while (outp < row);
+
+ return decompressed;
+ }
+
+ /*
+ * ============== Mod_ClusterPVS ==============
+ */
+ byte[] Mod_ClusterPVS(int cluster, model_t model) {
+ if (cluster == -1 || model.vis == null)
+ return mod_novis;
+ //return Mod_DecompressVis( (byte *)model.vis +
+ // model.vis.bitofs[cluster][Defines.DVIS_PVS], model);
+ return Mod_DecompressVis(model_visibility,
+ model.vis.bitofs[cluster][Defines.DVIS_PVS], model);
+ }
+
+ // ===============================================================================
+
+ /*
+ * ================ Mod_Modellist_f ================
+ */
+ void Mod_Modellist_f() {
+ int i;
+ model_t mod;
+ int total;
+
+ total = 0;
+ VID.Printf(Defines.PRINT_ALL, "Loaded models:\n");
+ for (i = 0; i < mod_numknown; i++) {
+ mod = mod_known[i];
+ if (mod.name == "")
+ continue;
+
+ VID.Printf(Defines.PRINT_ALL, "%8i : %s\n", new Vargs(2).add(
+ mod.extradatasize).add(mod.name));
+ total += mod.extradatasize;
+ }
+ VID.Printf(Defines.PRINT_ALL, "Total resident: " + total + '\n');
+ }
+
+ /*
+ * =============== Mod_Init ===============
+ */
+ void Mod_Init() {
+ // init mod_known
+ for (int i = 0; i < MAX_MOD_KNOWN; i++) {
+ mod_known[i] = new model_t();
+ }
+ Arrays.fill(mod_novis, (byte) 0xff);
+ }
+
+ byte[] fileBuffer;
+
+ /*
+ * ================== Mod_ForName
+ *
+ * Loads in a model for the given name ==================
+ */
+ model_t Mod_ForName(String name, boolean crash) {
+ model_t mod = null;
+ int i;
+
+ if (name == null || name.length() == 0)
+ Com.Error(Defines.ERR_DROP, "Mod_ForName: NULL name");
+
+ //
+ // inline models are grabbed only from worldmodel
+ //
+ if (name.charAt(0) == '*') {
+ i = Integer.parseInt(name.substring(1));
+ if (i < 1 || r_worldmodel == null || i >= r_worldmodel.numsubmodels)
+ Com.Error(Defines.ERR_DROP, "bad inline model number");
+ return mod_inline[i];
+ }
+
+ //
+ // search the currently loaded models
+ //
+ for (i = 0; i < mod_numknown; i++) {
+ mod = mod_known[i];
+
+ if (mod.name == "")
+ continue;
+ if (mod.name.equals(name))
+ return mod;
+ }
+
+ //
+ // find a free model slot spot
+ //
+ for (i = 0; i < mod_numknown; i++) {
+ mod = mod_known[i];
+
+ if (mod.name == "")
+ break; // free spot
+ }
+ if (i == mod_numknown) {
+ if (mod_numknown == MAX_MOD_KNOWN)
+ Com.Error(Defines.ERR_DROP, "mod_numknown == MAX_MOD_KNOWN");
+ mod_numknown++;
+ mod = mod_known[i];
+ }
+
+ mod.name = name;
+
+ //
+ // load the file
+ //
+ fileBuffer = FS.LoadFile(name);
+
+ if (fileBuffer == null) {
+ if (crash)
+ Com.Error(Defines.ERR_DROP, "Mod_NumForName: " + mod.name
+ + " not found");
+
+ mod.name = "";
+ return null;
+ }
+
+ modfilelen = fileBuffer.length;
+
+ loadmodel = mod;
+
+ //
+ // fill it in
+ //
+ ByteBuffer bb = ByteBuffer.wrap(fileBuffer);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ // call the apropriate loader
+
+ bb.mark();
+ int ident = bb.getInt();
+
+ bb.reset();
+
+ switch (ident) {
+ case qfiles.IDALIASHEADER:
+ Mod_LoadAliasModel(mod, bb);
+ break;
+ case qfiles.IDSPRITEHEADER:
+ Mod_LoadSpriteModel(mod, bb);
+ break;
+ case qfiles.IDBSPHEADER:
+ Mod_LoadBrushModel(mod, bb);
+ break;
+ default:
+ Com.Error(Defines.ERR_DROP, "Mod_NumForName: unknown fileid for "
+ + mod.name);
+ break;
+ }
+
+ this.fileBuffer = null; // free it for garbage collection
+ return mod;
+ }
+
+ /*
+ * ===============================================================================
+ *
+ * BRUSHMODEL LOADING
+ *
+ * ===============================================================================
+ */
+
+ byte[] mod_base;
+
+ /*
+ * ================= Mod_LoadLighting =================
+ */
+ void Mod_LoadLighting(lump_t l) {
+ if (l.filelen == 0) {
+ loadmodel.lightdata = null;
+ return;
+ }
+ // memcpy (loadmodel.lightdata, mod_base + l.fileofs, l.filelen);
+ loadmodel.lightdata = new byte[l.filelen];
+ System
+ .arraycopy(mod_base, l.fileofs, loadmodel.lightdata, 0,
+ l.filelen);
+ }
+
+ /*
+ * ================= Mod_LoadVisibility =================
+ */
+ void Mod_LoadVisibility(lump_t l) {
+ int i;
+
+ if (l.filelen == 0) {
+ loadmodel.vis = null;
+ return;
+ }
+
+ System.arraycopy(mod_base, l.fileofs, model_visibility, 0, l.filelen);
+
+ ByteBuffer bb = ByteBuffer.wrap(model_visibility, 0, l.filelen);
+
+ loadmodel.vis = new qfiles.dvis_t(bb.order(ByteOrder.LITTLE_ENDIAN));
+
+ /*
+ * done: memcpy (loadmodel.vis, mod_base + l.fileofs, l.filelen);
+ *
+ * loadmodel.vis.numclusters = LittleLong (loadmodel.vis.numclusters);
+ * for (i=0 ; i <loadmodel.vis.numclusters ; i++) {
+ * loadmodel.vis.bitofs[i][0] = LittleLong (loadmodel.vis.bitofs[i][0]);
+ * loadmodel.vis.bitofs[i][1] = LittleLong (loadmodel.vis.bitofs[i][1]); }
+ */
+ }
+
+ /*
+ * ================= Mod_LoadVertexes =================
+ */
+ void Mod_LoadVertexes(lump_t l) {
+ mvertex_t[] vertexes;
+ int i, count;
+
+ if ((l.filelen % mvertex_t.DISK_SIZE) != 0)
+ Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in "
+ + loadmodel.name);
+
+ count = l.filelen / mvertex_t.DISK_SIZE;
+
+ vertexes = new mvertex_t[count];
+
+ loadmodel.vertexes = vertexes;
+ loadmodel.numvertexes = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for (i = 0; i < count; i++) {
+ vertexes[i] = new mvertex_t(bb);
+ }
+ }
+
+ /*
+ * ================= RadiusFromBounds =================
+ */
+ float RadiusFromBounds(float[] mins, float[] maxs) {
+ float[] corner = { 0, 0, 0 };
+
+ for (int i = 0; i < 3; i++) {
+ corner[i] = Math.abs(mins[i]) > Math.abs(maxs[i]) ? Math
+ .abs(mins[i]) : Math.abs(maxs[i]);
+ }
+ return Math3D.VectorLength(corner);
+ }
+
+ /*
+ * ================= Mod_LoadSubmodels =================
+ */
+ void Mod_LoadSubmodels(lump_t l) {
+ qfiles.dmodel_t in;
+ mmodel_t[] out;
+ int i, j, count;
+
+ if ((l.filelen % qfiles.dmodel_t.SIZE) != 0)
+ Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in "
+ + loadmodel.name);
+
+ count = l.filelen / qfiles.dmodel_t.SIZE;
+ // out = Hunk_Alloc ( count*sizeof(*out));
+ out = new mmodel_t[count];
+
+ loadmodel.submodels = out;
+ loadmodel.numsubmodels = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for (i = 0; i < count; i++) {
+ in = new qfiles.dmodel_t(bb);
+ out[i] = new mmodel_t();
+ for (j = 0; j < 3; j++) { // spread the mins / maxs by a pixel
+ out[i].mins[j] = in.mins[j] - 1;
+ out[i].maxs[j] = in.maxs[j] + 1;
+ out[i].origin[j] = in.origin[j];
+ }
+ out[i].radius = RadiusFromBounds(out[i].mins, out[i].maxs);
+ out[i].headnode = in.headnode;
+ out[i].firstface = in.firstface;
+ out[i].numfaces = in.numfaces;
+ }
+ }
+
+ /*
+ * ================= Mod_LoadEdges =================
+ */
+ void Mod_LoadEdges(lump_t l) {
+ medge_t[] edges;
+ int i, count;
+
+ if ((l.filelen % medge_t.DISK_SIZE) != 0)
+ Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in "
+ + loadmodel.name);
+
+ count = l.filelen / medge_t.DISK_SIZE;
+ // out = Hunk_Alloc ( (count + 1) * sizeof(*out));
+ edges = new medge_t[count + 1];
+
+ loadmodel.edges = edges;
+ loadmodel.numedges = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for (i = 0; i < count; i++) {
+ edges[i] = new medge_t(bb);
+ }
+ }
+
+ /*
+ * ================= Mod_LoadTexinfo =================
+ */
+ void Mod_LoadTexinfo(lump_t l) {
+ texinfo_t in;
+ mtexinfo_t[] out;
+ mtexinfo_t step;
+ int i, j, count;
+ int next;
+ String name;
+
+ if ((l.filelen % texinfo_t.SIZE) != 0)
+ Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in "
+ + loadmodel.name);
+
+ count = l.filelen / texinfo_t.SIZE;
+ // out = Hunk_Alloc ( count*sizeof(*out));
+ out = new mtexinfo_t[count];
+ for (i = 0; i < count; i++) {
+ out[i] = new mtexinfo_t();
+ }
+
+ loadmodel.texinfo = out;
+ loadmodel.numtexinfo = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for (i = 0; i < count; i++) {
+
+ in = new texinfo_t(bb);
+ out[i].vecs = in.vecs;
+ out[i].flags = in.flags;
+ next = in.nexttexinfo;
+ if (next > 0)
+ out[i].next = loadmodel.texinfo[next];
+ else
+ out[i].next = null;
+
+ name = "textures/" + in.texture + ".wal";
+
+ out[i].image = GL_FindImage(name, it_wall);
+ if (out[i].image == null) {
+ VID.Printf(Defines.PRINT_ALL, "Couldn't load " + name + '\n');
+ out[i].image = r_notexture;
+ }
+ }
+
+ // count animation frames
+ for (i = 0; i < count; i++) {
+ out[i].numframes = 1;
+ for (step = out[i].next; (step != null) && (step != out[i]); step = step.next)
+ out[i].numframes++;
+ }
+ }
+
+ /*
+ * ================ CalcSurfaceExtents
+ *
+ * Fills in s.texturemins[] and s.extents[] ================
+ */
+ void CalcSurfaceExtents(msurface_t s) {
+ float[] mins = { 0, 0 };
+ float[] maxs = { 0, 0 };
+ float val;
+
+ int j, e;
+ mvertex_t v;
+ int[] bmins = { 0, 0 };
+ int[] bmaxs = { 0, 0 };
+
+ mins[0] = mins[1] = 999999;
+ maxs[0] = maxs[1] = -99999;
+
+ mtexinfo_t tex = s.texinfo;
+
+ for (int i = 0; i < s.numedges; i++) {
+ e = loadmodel.surfedges[s.firstedge + i];
+ if (e >= 0)
+ v = loadmodel.vertexes[loadmodel.edges[e].v[0]];
+ else
+ v = loadmodel.vertexes[loadmodel.edges[-e].v[1]];
+
+ for (j = 0; j < 2; j++) {
+ val = v.position[0] * tex.vecs[j][0] + v.position[1]
+ * tex.vecs[j][1] + v.position[2] * tex.vecs[j][2]
+ + tex.vecs[j][3];
+ if (val < mins[j])
+ mins[j] = val;
+ if (val > maxs[j])
+ maxs[j] = val;
+ }
+ }
+
+ for (int i = 0; i < 2; i++) {
+ bmins[i] = (int) Math.floor(mins[i] / 16);
+ bmaxs[i] = (int) Math.ceil(maxs[i] / 16);
+
+ s.texturemins[i] = (short) (bmins[i] * 16);
+ s.extents[i] = (short) ((bmaxs[i] - bmins[i]) * 16);
+
+ }
+ }
+
+ /*
+ * ================= Mod_LoadFaces =================
+ */
+ void Mod_LoadFaces(lump_t l) {
+ qfiles.dface_t in;
+ msurface_t[] out;
+ int i, count, surfnum;
+ int planenum, side;
+ int ti;
+
+ if ((l.filelen % qfiles.dface_t.SIZE) != 0)
+ Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in "
+ + loadmodel.name);
+
+ count = l.filelen / qfiles.dface_t.SIZE;
+ // out = Hunk_Alloc ( count*sizeof(*out));
+ out = new msurface_t[count];
+
+ loadmodel.surfaces = out;
+ loadmodel.numsurfaces = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ currentmodel = loadmodel;
+
+ GL_BeginBuildingLightmaps(loadmodel);
+
+ for (surfnum = 0; surfnum < count; surfnum++) {
+ in = new qfiles.dface_t(bb);
+ out[surfnum] = new msurface_t();
+ out[surfnum].firstedge = in.firstedge;
+ out[surfnum].numedges = in.numedges;
+ out[surfnum].flags = 0;
+ out[surfnum].polys = null;
+
+ planenum = in.planenum;
+ side = in.side;
+ if (side != 0)
+ out[surfnum].flags |= Defines.SURF_PLANEBACK;
+
+ out[surfnum].plane = loadmodel.planes[planenum];
+
+ ti = in.texinfo;
+ if (ti < 0 || ti >= loadmodel.numtexinfo)
+ Com.Error(Defines.ERR_DROP,
+ "MOD_LoadBmodel: bad texinfo number");
+
+ out[surfnum].texinfo = loadmodel.texinfo[ti];
+
+ CalcSurfaceExtents(out[surfnum]);
+
+ // lighting info
+
+ for (i = 0; i < Defines.MAXLIGHTMAPS; i++)
+ out[surfnum].styles[i] = in.styles[i];
+
+ i = in.lightofs;
+ if (i == -1)
+ out[surfnum].samples = null;
+ else {
+ ByteBuffer pointer = ByteBuffer.wrap(loadmodel.lightdata);
+ pointer.position(i);
+ pointer = pointer.slice();
+ pointer.mark();
+ out[surfnum].samples = pointer; // subarray
+ }
+
+ // set the drawing flags
+
+ if ((out[surfnum].texinfo.flags & Defines.SURF_WARP) != 0) {
+ out[surfnum].flags |= Defines.SURF_DRAWTURB;
+ for (i = 0; i < 2; i++) {
+ out[surfnum].extents[i] = 16384;
+ out[surfnum].texturemins[i] = -8192;
+ }
+ GL_SubdivideSurface(out[surfnum]); // cut up polygon for warps
+ }
+
+ // create lightmaps and polygons
+ if ((out[surfnum].texinfo.flags & (Defines.SURF_SKY
+ | Defines.SURF_TRANS33 | Defines.SURF_TRANS66 | Defines.SURF_WARP)) == 0)
+ GL_CreateSurfaceLightmap(out[surfnum]);
+
+ if ((out[surfnum].texinfo.flags & Defines.SURF_WARP) == 0)
+ GL_BuildPolygonFromSurface(out[surfnum]);
+
+ }
+ GL_EndBuildingLightmaps();
+ }
+
+ /*
+ * ================= Mod_SetParent =================
+ */
+ void Mod_SetParent(mnode_t node, mnode_t parent) {
+ node.parent = parent;
+ if (node.contents != -1)
+ return;
+ Mod_SetParent(node.children[0], node);
+ Mod_SetParent(node.children[1], node);
+ }
+
+ /*
+ * ================= Mod_LoadNodes =================
+ */
+ void Mod_LoadNodes(lump_t l) {
+ int i, j, count, p;
+ qfiles.dnode_t in;
+ mnode_t[] out;
+
+ if ((l.filelen % qfiles.dnode_t.SIZE) != 0)
+ Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in "
+ + loadmodel.name);
+
+ count = l.filelen / qfiles.dnode_t.SIZE;
+ // out = Hunk_Alloc ( count*sizeof(*out));
+ out = new mnode_t[count];
+
+ loadmodel.nodes = out;
+ loadmodel.numnodes = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ // initialize the tree array
+ for (i = 0; i < count; i++)
+ out[i] = new mnode_t(); // do first before linking
+
+ // fill and link the nodes
+ for (i = 0; i < count; i++) {
+ in = new qfiles.dnode_t(bb);
+ for (j = 0; j < 3; j++) {
+ out[i].mins[j] = in.mins[j];
+ out[i].maxs[j] = in.maxs[j];
+ }
+
+ p = in.planenum;
+ out[i].plane = loadmodel.planes[p];
+
+ out[i].firstsurface = in.firstface;
+ out[i].numsurfaces = in.numfaces;
+ out[i].contents = -1; // differentiate from leafs
+
+ for (j = 0; j < 2; j++) {
+ p = in.children[j];
+ if (p >= 0)
+ out[i].children[j] = loadmodel.nodes[p];
+ else
+ out[i].children[j] = loadmodel.leafs[-1 - p]; // mleaf_t
+ // extends
+ // mnode_t
+ }
+ }
+
+ Mod_SetParent(loadmodel.nodes[0], null); // sets nodes and leafs
+ }
+
+ /*
+ * ================= Mod_LoadLeafs =================
+ */
+ void Mod_LoadLeafs(lump_t l) {
+ qfiles.dleaf_t in;
+ mleaf_t[] out;
+ int i, j, count, p;
+
+ if ((l.filelen % qfiles.dleaf_t.SIZE) != 0)
+ Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in "
+ + loadmodel.name);
+
+ count = l.filelen / qfiles.dleaf_t.SIZE;
+ // out = Hunk_Alloc ( count*sizeof(*out));
+ out = new mleaf_t[count];
+
+ loadmodel.leafs = out;
+ loadmodel.numleafs = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for (i = 0; i < count; i++) {
+ in = new qfiles.dleaf_t(bb);
+ out[i] = new mleaf_t();
+ for (j = 0; j < 3; j++) {
+ out[i].mins[j] = in.mins[j];
+ out[i].maxs[j] = in.maxs[j];
+
+ }
+
+ out[i].contents = in.contents;
+ out[i].cluster = in.cluster;
+ out[i].area = in.area;
+
+ out[i].setMarkSurface(in.firstleafface, loadmodel.marksurfaces);
+ out[i].nummarksurfaces = in.numleaffaces;
+ }
+ }
+
+ /*
+ * ================= Mod_LoadMarksurfaces =================
+ */
+ void Mod_LoadMarksurfaces(lump_t l) {
+ int i, j, count;
+
+ msurface_t[] out;
+
+ if ((l.filelen % Defines.SIZE_OF_SHORT) != 0)
+ Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in "
+ + loadmodel.name);
+ count = l.filelen / Defines.SIZE_OF_SHORT;
+ // out = Hunk_Alloc ( count*sizeof(*out));
+ out = new msurface_t[count];
+
+ loadmodel.marksurfaces = out;
+ loadmodel.nummarksurfaces = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for (i = 0; i < count; i++) {
+ j = bb.getShort();
+ if (j < 0 || j >= loadmodel.numsurfaces)
+ Com.Error(Defines.ERR_DROP,
+ "Mod_ParseMarksurfaces: bad surface number");
+
+ out[i] = loadmodel.surfaces[j];
+ }
+ }
+
+ /*
+ * ================= Mod_LoadSurfedges =================
+ */
+ void Mod_LoadSurfedges(lump_t l) {
+ int i, count;
+ int[] offsets;
+
+ if ((l.filelen % Defines.SIZE_OF_INT) != 0)
+ Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in "
+ + loadmodel.name);
+
+ count = l.filelen / Defines.SIZE_OF_INT;
+ if (count < 1 || count >= Defines.MAX_MAP_SURFEDGES)
+ Com.Error(Defines.ERR_DROP,
+ "MOD_LoadBmodel: bad surfedges count in " + loadmodel.name
+ + ": " + count);
+
+ offsets = new int[count];
+
+ loadmodel.surfedges = offsets;
+ loadmodel.numsurfedges = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for (i = 0; i < count; i++)
+ offsets[i] = bb.getInt();
+ }
+
+ /*
+ * ================= Mod_LoadPlanes =================
+ */
+ void Mod_LoadPlanes(lump_t l) {
+ int i, j;
+ cplane_t[] out;
+ qfiles.dplane_t in;
+ int count;
+ int bits;
+
+ if ((l.filelen % qfiles.dplane_t.SIZE) != 0)
+ Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in "
+ + loadmodel.name);
+
+ count = l.filelen / qfiles.dplane_t.SIZE;
+ // out = Hunk_Alloc ( count*2*sizeof(*out));
+ out = new cplane_t[count * 2];
+
+ loadmodel.planes = out;
+ loadmodel.numplanes = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for (i = 0; i < count; i++) {
+ bits = 0;
+ in = new qfiles.dplane_t(bb);
+ out[i] = new cplane_t();
+ for (j = 0; j < 3; j++) {
+ out[i].normal[j] = in.normal[j];
+ if (out[i].normal[j] < 0)
+ bits |= (1 << j);
+ }
+
+ out[i].dist = in.dist;
+ out[i].type = (byte) in.type;
+ out[i].signbits = (byte) bits;
+ }
+ }
+
+ /*
+ * ================= Mod_LoadBrushModel =================
+ */
+ void Mod_LoadBrushModel(model_t mod, ByteBuffer buffer) {
+ int i;
+ qfiles.dheader_t header;
+ mmodel_t bm;
+
+ loadmodel.type = mod_brush;
+ if (loadmodel != mod_known[0])
+ Com.Error(Defines.ERR_DROP, "Loaded a brush model after the world");
+
+ header = new qfiles.dheader_t(buffer);
+
+ i = header.version;
+ if (i != Defines.BSPVERSION)
+ Com.Error(Defines.ERR_DROP, "Mod_LoadBrushModel: " + mod.name
+ + " has wrong version number (" + i + " should be "
+ + Defines.BSPVERSION + ")");
+
+ mod_base = fileBuffer; //(byte *)header;
+
+ // load into heap
+ Mod_LoadVertexes(header.lumps[Defines.LUMP_VERTEXES]); // ok
+ Mod_LoadEdges(header.lumps[Defines.LUMP_EDGES]); // ok
+ Mod_LoadSurfedges(header.lumps[Defines.LUMP_SURFEDGES]); // ok
+ Mod_LoadLighting(header.lumps[Defines.LUMP_LIGHTING]); // ok
+ Mod_LoadPlanes(header.lumps[Defines.LUMP_PLANES]); // ok
+ Mod_LoadTexinfo(header.lumps[Defines.LUMP_TEXINFO]); // ok
+ Mod_LoadFaces(header.lumps[Defines.LUMP_FACES]); // ok
+ Mod_LoadMarksurfaces(header.lumps[Defines.LUMP_LEAFFACES]);
+ Mod_LoadVisibility(header.lumps[Defines.LUMP_VISIBILITY]); // ok
+ Mod_LoadLeafs(header.lumps[Defines.LUMP_LEAFS]); // ok
+ Mod_LoadNodes(header.lumps[Defines.LUMP_NODES]); // ok
+ Mod_LoadSubmodels(header.lumps[Defines.LUMP_MODELS]);
+ mod.numframes = 2; // regular and alternate animation
+
+ //
+ // set up the submodels
+ //
+ model_t starmod;
+
+ for (i = 0; i < mod.numsubmodels; i++) {
+
+ bm = mod.submodels[i];
+ starmod = mod_inline[i] = loadmodel.copy();
+
+ starmod.firstmodelsurface = bm.firstface;
+ starmod.nummodelsurfaces = bm.numfaces;
+ starmod.firstnode = bm.headnode;
+ if (starmod.firstnode >= loadmodel.numnodes)
+ Com.Error(Defines.ERR_DROP, "Inline model " + i
+ + " has bad firstnode");
+
+ Math3D.VectorCopy(bm.maxs, starmod.maxs);
+ Math3D.VectorCopy(bm.mins, starmod.mins);
+ starmod.radius = bm.radius;
+
+ if (i == 0)
+ loadmodel = starmod.copy();
+
+ starmod.numleafs = bm.visleafs;
+ }
+ }
+
+ /*
+ * ==============================================================================
+ *
+ * ALIAS MODELS
+ *
+ * ==============================================================================
+ */
+
+ /*
+ * ================= Mod_LoadAliasModel =================
+ */
+ void Mod_LoadAliasModel(model_t mod, ByteBuffer buffer) {
+ int i, j;
+ qfiles.dmdl_t pheader;
+ qfiles.dstvert_t[] poutst;
+ qfiles.dtriangle_t[] pouttri;
+ qfiles.daliasframe_t[] poutframe;
+ int[] poutcmd;
+
+ pheader = new qfiles.dmdl_t(buffer);
+
+ if (pheader.version != qfiles.ALIAS_VERSION)
+ Com.Error(Defines.ERR_DROP,
+ "%s has wrong version number (%i should be %i)", new Vargs(
+ 3).add(mod.name).add(pheader.version).add(
+ qfiles.ALIAS_VERSION));
+
+ if (pheader.skinheight > MAX_LBM_HEIGHT)
+ Com.Error(Defines.ERR_DROP, "model " + mod.name
+ + " has a skin taller than " + MAX_LBM_HEIGHT);
+
+ if (pheader.num_xyz <= 0)
+ Com.Error(Defines.ERR_DROP, "model " + mod.name
+ + " has no vertices");
+
+ if (pheader.num_xyz > qfiles.MAX_VERTS)
+ Com.Error(Defines.ERR_DROP, "model " + mod.name
+ + " has too many vertices");
+
+ if (pheader.num_st <= 0)
+ Com.Error(Defines.ERR_DROP, "model " + mod.name
+ + " has no st vertices");
+
+ if (pheader.num_tris <= 0)
+ Com.Error(Defines.ERR_DROP, "model " + mod.name
+ + " has no triangles");
+
+ if (pheader.num_frames <= 0)
+ Com.Error(Defines.ERR_DROP, "model " + mod.name + " has no frames");
+
+ //
+ // load base s and t vertices (not used in gl version)
+ //
+ poutst = new qfiles.dstvert_t[pheader.num_st];
+ buffer.position(pheader.ofs_st);
+ for (i = 0; i < pheader.num_st; i++) {
+ poutst[i] = new qfiles.dstvert_t(buffer);
+ }
+
+ //
+ // load triangle lists
+ //
+ pouttri = new qfiles.dtriangle_t[pheader.num_tris];
+ buffer.position(pheader.ofs_tris);
+ for (i = 0; i < pheader.num_tris; i++) {
+ pouttri[i] = new qfiles.dtriangle_t(buffer);
+ }
+
+ //
+ // load the frames
+ //
+ poutframe = new qfiles.daliasframe_t[pheader.num_frames];
+ buffer.position(pheader.ofs_frames);
+ for (i = 0; i < pheader.num_frames; i++) {
+ poutframe[i] = new qfiles.daliasframe_t(buffer);
+ // verts are all 8 bit, so no swapping needed
+ poutframe[i].verts = new qfiles.dtrivertx_t[pheader.num_xyz];
+ for (int k = 0; k < pheader.num_xyz; k++) {
+ poutframe[i].verts[k] = new qfiles.dtrivertx_t(buffer);
+ }
+ }
+
+ mod.type = mod_alias;
+
+ //
+ // load the glcmds
+ //
+ poutcmd = new int[pheader.num_glcmds];
+ buffer.position(pheader.ofs_glcmds);
+ for (i = 0; i < pheader.num_glcmds; i++)
+ poutcmd[i] = buffer.getInt(); // LittleLong (pincmd[i]);
+
+ // register all skins
+ String[] skinNames = new String[pheader.num_skins];
+ byte[] nameBuf = new byte[qfiles.MAX_SKINNAME];
+ buffer.position(pheader.ofs_skins);
+ for (i = 0; i < pheader.num_skins; i++) {
+ buffer.get(nameBuf);
+ skinNames[i] = new String(nameBuf);
+ int n = skinNames[i].indexOf('\0');
+ if (n > -1) {
+ skinNames[i] = skinNames[i].substring(0, n);
+ }
+ mod.skins[i] = GL_FindImage(skinNames[i], it_skin);
+ }
+
+ // set the model arrays
+ pheader.skinNames = skinNames; // skin names
+ pheader.stVerts = poutst; // textur koordinaten
+ pheader.triAngles = pouttri; // dreiecke
+ pheader.glCmds = poutcmd; // STRIP or FAN
+ pheader.aliasFrames = poutframe; // frames mit vertex array
+
+ mod.extradata = pheader;
+
+ mod.mins[0] = -32;
+ mod.mins[1] = -32;
+ mod.mins[2] = -32;
+ mod.maxs[0] = 32;
+ mod.maxs[1] = 32;
+ mod.maxs[2] = 32;
+
+ precompileGLCmds(pheader);
+ }
+
+ /*
+ * ==============================================================================
+ *
+ * SPRITE MODELS
+ *
+ * ==============================================================================
+ */
+
+ /*
+ * ================= Mod_LoadSpriteModel =================
+ */
+ void Mod_LoadSpriteModel(model_t mod, ByteBuffer buffer) {
+ qfiles.dsprite_t sprout = new qfiles.dsprite_t(buffer);
+
+ if (sprout.version != qfiles.SPRITE_VERSION)
+ Com.Error(Defines.ERR_DROP,
+ "%s has wrong version number (%i should be %i)", new Vargs(
+ 3).add(mod.name).add(sprout.version).add(
+ qfiles.SPRITE_VERSION));
+
+ if (sprout.numframes > qfiles.MAX_MD2SKINS)
+ Com.Error(Defines.ERR_DROP, "%s has too many frames (%i > %i)",
+ new Vargs(3).add(mod.name).add(sprout.numframes).add(
+ qfiles.MAX_MD2SKINS));
+
+ for (int i = 0; i < sprout.numframes; i++) {
+ mod.skins[i] = GL_FindImage(sprout.frames[i].name, it_sprite);
+ }
+
+ mod.type = mod_sprite;
+ mod.extradata = sprout;
+ }
+
+ // =============================================================================
+
+ /*
+ * @@@@@@@@@@@@@@@@@@@@@ R_BeginRegistration
+ *
+ * Specifies the model that will be used as the world @@@@@@@@@@@@@@@@@@@@@
+ */
+ protected void R_BeginRegistration(String model) {
+ resetModelArrays();
+ resetPolygonArrays();
+
+ cvar_t flushmap;
+
+ registration_sequence++;
+ r_oldviewcluster = -1; // force markleafs
+
+ String fullname = "maps/" + model + ".bsp";
+
+ // explicitly free the old map if different
+ // this guarantees that mod_known[0] is the world map
+ flushmap = Cvar.Get("flushmap", "0", 0);
+ if (!mod_known[0].name.equals(fullname) || flushmap.value != 0.0f)
+ Mod_Free(mod_known[0]);
+ r_worldmodel = Mod_ForName(fullname, true);
+
+ r_viewcluster = -1;
+ }
+
+ /*
+ * @@@@@@@@@@@@@@@@@@@@@ R_RegisterModel
+ *
+ * @@@@@@@@@@@@@@@@@@@@@
+ */
+ protected model_t R_RegisterModel(String name) {
+ model_t mod = null;
+ int i;
+ qfiles.dsprite_t sprout;
+ qfiles.dmdl_t pheader;
+
+ mod = Mod_ForName(name, false);
+ if (mod != null) {
+ mod.registration_sequence = registration_sequence;
+
+ // register any images used by the models
+ if (mod.type == mod_sprite) {
+ sprout = (qfiles.dsprite_t) mod.extradata;
+ for (i = 0; i < sprout.numframes; i++)
+ mod.skins[i] = GL_FindImage(sprout.frames[i].name,
+ it_sprite);
+ } else if (mod.type == mod_alias) {
+ pheader = (qfiles.dmdl_t) mod.extradata;
+ for (i = 0; i < pheader.num_skins; i++)
+ mod.skins[i] = GL_FindImage(pheader.skinNames[i], it_skin);
+ // PGM
+ mod.numframes = pheader.num_frames;
+ // PGM
+ } else if (mod.type == mod_brush) {
+ for (i = 0; i < mod.numtexinfo; i++)
+ mod.texinfo[i].image.registration_sequence = registration_sequence;
+ }
+ }
+ return mod;
+ }
+
+ /*
+ * @@@@@@@@@@@@@@@@@@@@@ R_EndRegistration
+ *
+ * @@@@@@@@@@@@@@@@@@@@@
+ */
+ protected void R_EndRegistration() {
+ model_t mod;
+
+ for (int i = 0; i < mod_numknown; i++) {
+ mod = mod_known[i];
+ if (mod.name == "")
+ continue;
+ if (mod.registration_sequence != registration_sequence) { // don't
+ // need
+ // this
+ // model
+ Mod_Free(mod);
+ } else {
+ // precompile AliasModels
+ if (mod.type == mod_alias)
+ precompileGLCmds((qfiles.dmdl_t) mod.extradata);
+ }
+ }
+ GL_FreeUnusedImages();
+
+ //modelMemoryUsage();
+ }
+
+ // =============================================================================
+
+ /*
+ * ================ Mod_Free ================
+ */
+ void Mod_Free(model_t mod) {
+ mod.clear();
+ }
+
+ /*
+ * ================ Mod_FreeAll ================
+ */
+ void Mod_FreeAll() {
+ for (int i = 0; i < mod_numknown; i++) {
+ if (mod_known[i].extradata != null)
+ Mod_Free(mod_known[i]);
+ }
+ }
+
+ /*
+ * new functions for vertex array handling
+ */
+ static final int MODEL_BUFFER_SIZE = 50000;
+
+ static FloatBuffer globalModelTextureCoordBuf = BufferUtils
+ .newFloatBuffer(MODEL_BUFFER_SIZE * 2);
+
+ static IntBuffer globalModelVertexIndexBuf = BufferUtils
+ .newIntBuffer(MODEL_BUFFER_SIZE);
+
+ void precompileGLCmds(qfiles.dmdl_t model) {
+ model.textureCoordBuf = globalModelTextureCoordBuf.slice();
+ model.vertexIndexBuf = globalModelVertexIndexBuf.slice();
+ Vector tmp = new Vector();
+
+ int count = 0;
+ int[] order = model.glCmds;
+ int orderIndex = 0;
+ while (true) {
+ // get the vertex count and primitive type
+ count = order[orderIndex++];
+ if (count == 0)
+ break; // done
+
+ tmp.addElement(new Integer(count));
+
+ if (count < 0) {
+ count = -count;
+ //gl.glBegin (GL.GL_TRIANGLE_FAN);
+ } else {
+ //gl.glBegin (GL.GL_TRIANGLE_STRIP);
+ }
+
+ do {
+ // texture coordinates come from the draw list
+ globalModelTextureCoordBuf.put(Float
+ .intBitsToFloat(order[orderIndex + 0]));
+ globalModelTextureCoordBuf.put(Float
+ .intBitsToFloat(order[orderIndex + 1]));
+ globalModelVertexIndexBuf.put(order[orderIndex + 2]);
+
+ orderIndex += 3;
+ } while (--count != 0);
+ }
+
+ int size = tmp.size();
+
+ model.counts = new int[size];
+ model.indexElements = new IntBuffer[size];
+
+ count = 0;
+ int pos = 0;
+ for (int i = 0; i < model.counts.length; i++) {
+ count = ((Integer) tmp.get(i)).intValue();
+ model.counts[i] = count;
+
+ count = (count < 0) ? -count : count;
+ model.vertexIndexBuf.position(pos);
+ model.indexElements[i] = model.vertexIndexBuf.slice();
+ pos += count;
+ }
+ }
+
+ static void resetModelArrays() {
+ globalModelTextureCoordBuf.rewind();
+ globalModelVertexIndexBuf.rewind();
+ }
+
+ static void modelMemoryUsage() {
+ System.out.println("AliasModels: globalVertexBuffer size "
+ + globalModelVertexIndexBuf.position());
+ }
+} \ No newline at end of file