📄 model.java
字号:
/* * Model.java * Copyright (C) 2003 * * $Id: Model.java,v 1.12 2005/05/15 16:06:15 cawe Exp $ *//* 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 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. 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.util.Math3D;import jake2.util.Vargs;import java.nio.*;import java.util.Arrays;import java.util.Vector;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.length() == 0) 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.length() == 0) 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.length() == 0) 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) { if ((l.filelen % qfiles.dmodel_t.SIZE) != 0) Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name); int i, j; int count = l.filelen / qfiles.dmodel_t.SIZE; // out = Hunk_Alloc ( count*sizeof(*out)); mmodel_t out; mmodel_t[] outs = new mmodel_t[count]; for (i = 0; i < count; i++) { outs[i] = new mmodel_t(); } loadmodel.submodels = outs; loadmodel.numsubmodels = count; ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen); bb.order(ByteOrder.LITTLE_ENDIAN); qfiles.dmodel_t in; for (i = 0; i < count; i++) { in = new qfiles.dmodel_t(bb); out = outs[i]; for (j = 0; j < 3; j++) { // spread the mins / maxs by a // pixel out.mins[j] = in.mins[j] - 1; out.maxs[j] = in.maxs[j] + 1; out.origin[j] = in.origin[j]; } out.radius = RadiusFromBounds(out.mins, out.maxs); out.headnode = in.headnode; out.firstface = in.firstface; out.numfaces = in.numfaces; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -