29 #include "../idlib/precompiled.h"
114 totalBytes +=
sizeof( *this );
115 totalBytes +=
name.DynamicMemoryUsed();
116 totalBytes +=
surfaces.MemoryUsed();
247 AddCubeFace( tri,
idVec3(-1, 1, 1),
idVec3(1, 1, 1),
idVec3(1, -1, 1),
idVec3(-1, -1, 1) );
248 AddCubeFace( tri,
idVec3(-1, 1, -1),
idVec3(-1, -1, -1),
idVec3(1, -1, -1),
idVec3(1, 1, -1) );
250 AddCubeFace( tri,
idVec3(1, -1, 1),
idVec3(1, 1, 1),
idVec3(1, 1, -1),
idVec3(1, -1, -1) );
251 AddCubeFace( tri,
idVec3(-1, -1, 1),
idVec3(-1, -1, -1),
idVec3(-1, 1, -1),
idVec3(-1, 1, 1) );
253 AddCubeFace( tri,
idVec3(-1, -1, 1),
idVec3(1, -1, 1),
idVec3(1, -1, -1),
idVec3(-1, -1, -1) );
254 AddCubeFace( tri,
idVec3(-1, 1, 1),
idVec3(-1, 1, -1),
idVec3(1, 1, -1),
idVec3(1, 1, 1) );
285 name.ExtractFileExtension( extension );
287 if ( extension.
Icmp(
"ase" ) == 0 ) {
290 }
else if ( extension.
Icmp(
"lwo" ) == 0 ) {
293 }
else if ( extension.
Icmp(
"flt" ) == 0 ) {
296 }
else if ( extension.
Icmp(
"ma" ) == 0 ) {
300 common->
Warning(
"idRenderModelStatic::InitFromFile: unknown type for model: \'%s\'",
name.c_str() );
493 common->
Error(
"InstantiateDynamicModel called on static model '%s'",
name.c_str() );
582 int totalVerts, totalIndexes;
596 for ( i = 0 ; i <
surfaces.Num() ; i++ ) {
611 int numOriginalSurfaces =
surfaces.Num();
614 for ( i = 0 ; i < numOriginalSurfaces ; i++ ) {
633 for ( i = 0 ; i < numOriginalSurfaces ; i++ ) {
652 for ( i = 0 ; i <
surfaces.Num() ; i++ ) {
663 for ( i = 0 ; i <
surfaces.Num() ; i++ ) {
679 for ( i = 0 ; i <
surfaces.Num() ; i++ ) {
691 float radius = ( tri->
bounds[0] - mid ).Length();
694 tri->
bounds[0][0] = mid[0] - radius;
695 tri->
bounds[0][1] = mid[1] - radius;
696 tri->
bounds[0][2] = mid[2] - radius;
698 tri->
bounds[1][0] = mid[0] + radius;
699 tri->
bounds[1][1] = mid[1] + radius;
700 tri->
bounds[1][2] = mid[2] + radius;
738 float uOffset, vOffset, textureSin, textureCos;
739 float uTiling, vTiling;
742 static byte identityColor[4] = { 255, 255, 255, 255 };
757 mergeTo = (
int *)_alloca( ase->
objects.
Num() *
sizeof( *mergeTo ) );
764 for ( i = 0 ; i < ase->
objects.
Num() ; i++ ) {
769 for ( i = 0 ; i < ase->
objects.
Num() ; i++ ) {
772 material = ase->
materials[
object->materialRef];
779 for ( i = 0 ; i < ase->
objects.
Num() ; i++ ) {
781 material = ase->
materials[
object->materialRef];
811 for ( objectNum = 0 ; objectNum < ase->
objects.
Num() ; objectNum++ ) {
812 object = ase->
objects[objectNum];
813 mesh = &
object->mesh;
814 material = ase->
materials[
object->materialRef];
823 normalsParsed =
false;
841 float expand = 2 * 32 * vertexEpsilon;
845 mins -=
idVec3( expand, expand, expand );
846 maxs +=
idVec3( expand, expand, expand );
847 vertexSubset.
Init( mins, maxs, 32, 1024 );
862 float expand = 2 * 32 * texCoordEpsilon;
866 mins -=
idVec2( expand, expand );
867 maxs +=
idVec2( expand, expand );
868 texCoordSubset.
Init( mins, maxs, 32, 1024 );
892 color = identityColor;
897 for ( j = 0; j < mesh->
numFaces; j++ ) {
898 for ( k = 0; k < 3; k++ ) {
902 common->
Error(
"ConvertASEToModelSurfaces: bad vertex index in ASE file %s",
name.c_str() );
912 common->
Error(
"ConvertASEToModelSurfaces: bad tex coord index in ASE file %s",
name.c_str() );
919 if ( normalsParsed ) {
929 for ( lastmv =
NULL, mv = mvHash[v]; mv !=
NULL; lastmv = mv, mv = mv->
next ) {
930 if ( mv->tv != tv ) {
933 if ( *(
unsigned *)mv->color != *(
unsigned *)color ) {
936 if ( !normalsParsed ) {
941 if ( mv->normal * normal > normalEpsilon ) {
951 *(
unsigned *)mv->color = *(
unsigned *)
color;
971 common->
FatalError(
"ConvertASEToModelSurfaces: vertex miscount in ASE file %s",
name.c_str() );
976 uOffset = vOffset = 0.0f;
977 uTiling = vTiling = 1.0f;
981 material = ase->
materials[
object->materialRef];
992 for ( j = 0; j < tri->
numVerts; j++ ) {
1000 float u = tv.
x * uTiling + uOffset;
1001 float v = tv.
y * vTiling + vOffset;
1002 tri->
verts[
j ].
st[0] = u * textureCos + v * textureSin;
1003 tri->
verts[
j ].
st[1] = u * -textureSin + v * textureCos;
1013 modelSurf = &this->
surfaces[mergeTo[ objectNum ]];
1063 for ( lwoSurf = lwo->
surf; lwoSurf; lwoSurf = lwoSurf->
next ) {
1069 mergeTo = (
int *)_alloca( i *
sizeof( mergeTo[0] ) );
1070 memset( &surf, 0,
sizeof( surf ) );
1074 for ( lwoSurf = lwo->
surf, i = 0; lwoSurf; lwoSurf = lwoSurf->
next, i++ ) {
1082 for ( lwoSurf = lwo->
surf, i = 0; lwoSurf; lwoSurf = lwoSurf->
next, i++ ) {
1116 common->
Warning(
"ConvertLWOToModelSurfaces: model \'%s\' has bad or missing vertex data",
name.c_str() );
1132 if ( vm->type ==
LWID_(
'T',
'X',
'U',
'V') ) {
1133 numTVertexes += vm->nverts;
1138 if ( numTVertexes ) {
1142 if ( vm->type ==
LWID_(
'T',
'X',
'U',
'V') ) {
1144 for ( k = 0; k < vm->nverts; k++ ) {
1145 tvList[k +
offset].
x = vm->val[k][0];
1146 tvList[k +
offset].
y = 1.0f - vm->val[k][1];
1148 offset += vm->nverts;
1152 common->
Warning(
"ConvertLWOToModelSurfaces: model \'%s\' has bad or missing uv data",
name.c_str() );
1172 float expand = 2 * 32 * vertexEpsilon;
1176 mins -=
idVec3( expand, expand, expand );
1177 maxs +=
idVec3( expand, expand, expand );
1178 vertexSubset.
Init( mins, maxs, 32, 1024 );
1180 vRemap[
j] = vertexSubset.
FindVector( vList, j, vertexEpsilon );
1184 tvRemap = (
int *)
R_StaticAlloc( numTVertexes *
sizeof( tvRemap[0] ) );
1188 for ( j = 0; j < numTVertexes; j++ ) {
1193 float expand = 2 * 32 * texCoordEpsilon;
1197 mins -=
idVec2( expand, expand );
1198 maxs +=
idVec2( expand, expand );
1199 texCoordSubset.
Init( mins, maxs, 32, 1024 );
1200 for ( j = 0; j < numTVertexes; j++ ) {
1201 tvRemap[
j] = texCoordSubset.
FindVector( tvList, j, texCoordEpsilon );
1206 for ( lwoSurf = lwo->
surf, i = 0; lwoSurf; lwoSurf = lwoSurf->
next, i++ ) {
1209 bool normalsParsed =
true;
1214 if ( rb && rb[0] ) {
1215 normalsParsed =
false;
1234 float normalEpsilon;
1236 normalEpsilon = 1.0f;
1243 if ( poly->
surf != lwoSurf ) {
1247 if ( poly->
nverts != 3 ) {
1248 common->
Warning(
"ConvertLWOToModelSurfaces: model %s has too many verts for a poly! Make sure you triplet it down",
name.c_str() );
1252 for ( k = 0; k < 3; k++ ) {
1254 v = vRemap[poly->
v[k].
index];
1256 normal.
x = poly->
v[k].
norm[0];
1257 normal.
y = poly->
v[k].
norm[2];
1258 normal.
z = poly->
v[k].
norm[1];
1265 color[0] = lwoSurf->
color.
rgb[0] * 255;
1266 color[1] = lwoSurf->
color.
rgb[1] * 255;
1267 color[2] = lwoSurf->
color.
rgb[2] * 255;
1273 for ( nvm = 0; nvm < pt->
nvmaps; nvm++ ) {
1280 for (
int chan = 0; chan < 4; chan++ ) {
1287 for ( nvm = 0; nvm < poly->
v[k].
nvmaps; nvm++ ) {
1294 for (
int chan = 0; chan < 4; chan++ ) {
1301 for ( lastmv =
NULL, mv = mvHash[v]; mv !=
NULL; lastmv = mv, mv = mv->
next ) {
1302 if ( mv->tv != tv ) {
1305 if ( *(
unsigned *)mv->color != *(
unsigned *)color ) {
1308 if ( !normalsParsed ) {
1313 if ( mv->normal * normal > normalEpsilon ) {
1323 *(
unsigned *)mv->color = *(
unsigned *)
color;
1340 common->
FatalError(
"ConvertLWOToModelSurfaces: index miscount in LWO file %s",
name.c_str() );
1343 common->
FatalError(
"ConvertLWOToModelSurfaces: vertex miscount in LWO file %s",
name.c_str() );
1348 for ( j = 0; j < tri->
numVerts; j++ ) {
1361 modelSurf = &this->
surfaces[mergeTo[
i ]];
1398 int materialRef = 0;
1403 strcpy( mat->
name, surf->name );
1411 object->materialRef = materialRef++;
1425 common->
Warning(
"ConvertLWOToASE: model \'%s\' has bad or missing vertex data",
name.c_str() );
1439 if ( vm->type ==
LWID_(
'T',
'X',
'U',
'V') ) {
1449 if ( vm->type ==
LWID_(
'T',
'X',
'U',
'V') ) {
1451 for ( k = 0; k < vm->nverts; k++ ) {
1455 offset += vm->nverts;
1459 common->
Warning(
"ConvertLWOToASE: model \'%s\' has bad or missing uv data", fileName );
1472 if ( poly->
surf != surf ) {
1476 if ( poly->
nverts != 3 ) {
1477 common->
Warning(
"ConvertLWOToASE: model %s has too many verts for a poly! Make sure you triplet it down", fileName );
1485 for ( k = 0; k < 3; k++ ) {
1504 for ( nvm = 0; nvm < pt->
nvmaps; nvm++ ) {
1511 for (
int chan = 0; chan < 4; chan++ ) {
1518 for ( nvm = 0; nvm < poly->
v[k].
nvmaps; nvm++ ) {
1525 for (
int chan = 0; chan < 4; chan++ ) {
1541 mesh->
faces = newFaces;
1570 float uOffset, vOffset, textureSin, textureCos;
1571 float uTiling, vTiling;
1574 static byte identityColor[4] = { 255, 255, 255, 255 };
1589 mergeTo = (
int *)_alloca( ma->
objects.
Num() *
sizeof( *mergeTo ) );
1597 for ( i = 0 ; i < ma->
objects.
Num() ; i++ ) {
1602 for ( i = 0 ; i < ma->
objects.
Num() ; i++ ) {
1606 material = ma->
materials[
object->materialRef];
1616 for ( i = 0 ; i < ma->
objects.
Num() ; i++ ) {
1619 material = ma->
materials[
object->materialRef];
1652 for ( objectNum = 0 ; objectNum < ma->
objects.
Num() ; objectNum++ ) {
1653 object = ma->
objects[objectNum];
1654 mesh = &
object->mesh;
1656 material = ma->
materials[
object->materialRef];
1667 if ( rb && rb[0] ) {
1668 normalsParsed =
false;
1686 float expand = 2 * 32 * vertexEpsilon;
1690 mins -=
idVec3( expand, expand, expand );
1691 maxs +=
idVec3( expand, expand, expand );
1692 vertexSubset.
Init( mins, maxs, 32, 1024 );
1707 float expand = 2 * 32 * texCoordEpsilon;
1711 mins -=
idVec2( expand, expand );
1712 maxs +=
idVec2( expand, expand );
1713 texCoordSubset.
Init( mins, maxs, 32, 1024 );
1737 color = identityColor;
1742 for ( j = 0; j < mesh->
numFaces; j++ ) {
1743 for ( k = 0; k < 3; k++ ) {
1747 common->
Error(
"ConvertMAToModelSurfaces: bad vertex index in MA file %s",
name.c_str() );
1757 common->
Error(
"ConvertMAToModelSurfaces: bad tex coord index in MA file %s",
name.c_str() );
1764 if ( normalsParsed ) {
1776 for ( lastmv =
NULL, mv = mvHash[v]; mv !=
NULL; lastmv = mv, mv = mv->
next ) {
1777 if ( mv->tv != tv ) {
1780 if ( *(
unsigned *)mv->color != *(
unsigned *)color ) {
1783 if ( !normalsParsed ) {
1788 if ( mv->normal * normal > normalEpsilon ) {
1797 mv->normal = normal;
1798 *(
unsigned *)mv->color = *(
unsigned *)
color;
1824 uOffset = vOffset = 0.0f;
1825 uTiling = vTiling = 1.0f;
1840 for ( j = 0; j < tri->
numVerts; j++ ) {
1848 float u = tv.
x * uTiling + uOffset;
1849 float v = tv.
y * vTiling + vOffset;
1850 tri->
verts[
j ].
st[0] = u * textureCos + v * textureSin;
1851 tri->
verts[
j ].
st[1] = u * -textureSin + v * textureCos;
1861 modelSurf = &this->
surfaces[mergeTo[ objectNum ]];
1884 if ( ase ==
NULL ) {
1901 unsigned int failID;
1906 if ( lwo ==
NULL ) {
1952 int size = sqrt( len / 4.0
f );
1955 float min = 9999999;
1956 float max = -9999999;
1957 for (
int i = 0 ;
i < len/4 ;
i++ ) {
1959 if ( data[i] == -9999 ) {
1963 if ( data[i] < min ) {
1966 if ( data[i] > max ) {
1974 for (
int i = 0 ;
i < len/4 ;
i++ ) {
1975 float v = ( data[
i] -
min ) / ( max - min );
1978 image_p[2] = v * 255;
1982 idStr tgaName = fileName;
1991 int minX, maxX, minY, maxY;
1994 for ( minX = 0 ; minX <
size ; minX++ ) {
1995 for ( i = 0 ; i <
size ; i++ ) {
1996 if ( data[i*size + minX] > 1.0 ) {
2005 for ( maxX = size-1 ; maxX > 0 ; maxX-- ) {
2006 for ( i = 0 ; i <
size ; i++ ) {
2007 if ( data[i*size + maxX] > 1.0 ) {
2016 for ( minY = 0 ; minY <
size ; minY++ ) {
2017 for ( i = 0 ; i <
size ; i++ ) {
2018 if ( data[minY*size + i] > 1.0 ) {
2027 for ( maxY = size-1 ; maxY <
size ; maxY-- ) {
2028 for ( i = 0 ; i <
size ; i++ ) {
2029 if ( data[maxY*size + i] > 1.0 ) {
2039 int width = maxX - minX + 1;
2040 int height = maxY - minY + 1;
2046 tri->
numIndexes = (width-1) * (height-1) * 6;
2054 for (
int j = 0;
j <
width ;
j++ ) {
2055 int v =
i * width +
j;
2059 tri->
verts[
v ].
xyz[2] = data[(minY+
i)*size+minX+j];
2065 for (
int i = 0 ;
i < height-1 ;
i++ ) {
2066 for (
int j = 0;
j < width-1 ;
j++ ) {
2067 int v = (
i * (width-1) +
j ) * 6;
2070 tri->
indexes[ v + 1 ] = (
i+1) * width + j;
2071 tri->
indexes[ v + 2 ] = (
i+1) * width + j + 1;
2073 tri->
indexes[ v + 4 ] = (
i+1) * width + j + 1;
2074 tri->
indexes[ v + 5 ] =
i * width + j + 1;
2077 tri->
indexes[ v + 1 ] =
i * width + j + 1;
2078 tri->
indexes[ v + 2 ] = (
i+1) * width + j + 1;
2080 tri->
indexes[ v + 4 ] = (
i+1) * width + j + 1;
2081 tri->
indexes[ v + 5 ] = (
i+1) * width + j;
2111 for ( i = 0 ; i <
surfaces.Num() ; i++ ) {
2158 int i,
j, numSurfaces;
2161 for ( i = 0 ; i < numSurfaces ; i++ ) {
2212 for ( i = 0 ; i <
surfaces.Num() ; i++ ) {
2286 for ( i = 0; i <
surfaces.Num(); i++ ) {
2304 for ( i = 0; i <
surfaces.Num(); i++ ) {
2321 for ( i = 0; i <
surfaces.Num(); i++ ) {
struct st_lwSurface * next
bool SurfaceCastsShadow(void) const
virtual int NumJoints(void) const
virtual ~idRenderModelStatic()
virtual const char * Name() const
virtual int ReadUnsignedChar(unsigned char &value)
virtual int WriteUnsignedChar(const unsigned char value)
virtual const char * GetJointName(jointHandle_t handle) const
bool AddBounds(const idBounds &a)
maModel_t * MA_Load(const char *fileName)
bool FindSurfaceWithId(int id, int &surfaceNum)
idList< modelSurface_t > surfaces
virtual jointHandle_t GetJointHandle(const char *name) const
virtual int virtual int ReadInt(int &value)
#define LWID_(a, b, c, d)
virtual const idMD5Joint * GetJoints(void) const
srfTriangles_t * R_MergeTriangles(const srfTriangles_t *tri1, const srfTriangles_t *tri2)
virtual int Memory() const
bool ConvertASEToModelSurfaces(const struct aseModel_s *ase)
virtual void InitFromFile(const char *fileName)
virtual void List() const
virtual bool IsReloadable() const
float GetFloat(void) const
bool ConvertLWOToModelSurfaces(const struct st_lwObject *lwo)
virtual void PartialInitFromFile(const char *fileName)
virtual int ReadFile(const char *relativePath, void **buffer, ID_TIME_T *timestamp=NULL)=0
struct matchVert_s * next
virtual idRenderModel * InstantiateDynamicModel(const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel)
virtual srfTriangles_t * AllocSurfaceTriangles(int numVerts, int numIndexes) const
virtual const modelSurface_t * Surface(int surfaceNum) const
bool LoadMA(const char *filename)
idFileSystem * fileSystem
virtual void SetLevelLoadReferenced(bool referenced)
const idMaterial * shader
void ASE_Free(aseModel_t *ase)
deform_t Deform(void) const
bool ConvertMAToModelSurfaces(const struct maModel_s *ma)
const char * GetName(void) const
virtual dynamicModel_t IsDynamicModel() const
GLenum GLsizei GLenum GLenum const GLvoid * image
virtual bool IsStaticWorldModel() const
virtual const idMaterial * FindMaterial(const char *name, bool makeDefault=true)=0
idList< aseMaterial_t * > materials
srfTriangles_t * R_AllocStaticTriSurf(void)
bool DeleteSurfaceWithId(int id)
idList< aseObject_t * > objects
virtual void WriteToDemoFile(class idDemoFile *f)
virtual int WriteVec2(const idVec2 &vec)
struct vertCache_s * ambientCache
virtual void FreeFile(void *buffer)=0
int Cmpn(const char *text, int n) const
static idCVar r_slopTexCoord
srfTriangles_t * R_CopyStaticTriSurf(const srfTriangles_t *tri)
int Icmp(const char *text) const
virtual void ReadFromDemoFile(class idDemoFile *f)
idList< maObject_t * > objects
GLfloat GLfloat GLfloat v2
virtual void VPCALL MinMax(float &min, float &max, const float *src, const int count)=0
virtual void InitEmpty(const char *name)
virtual int WriteInt(const int value)
const char * GetRenderBump() const
idStr & StripFileExtension(void)
virtual void FinishSurfaces()
void DeleteSurfacesWithNegativeId(void)
static float Sin(float a)
virtual int ReadVec2(idVec2 &vec)
void R_CleanupTriangles(srfTriangles_t *tri, bool createNormals, bool identifySilEdges, bool useUnsmoothedTangents)
static float TriangleArea(const idVec3 &a, const idVec3 &b, const idVec3 &c)
srfTriangles_t * geometry
virtual int ReadVec3(idVec3 &vec)
GLsizei GLsizei GLenum GLenum const GLvoid * data
struct aseModel_s * ConvertLWOToASE(const struct st_lwObject *obj, const char *fileName)
virtual void virtual void FatalError(const char *fmt,...) id_attribute((format(printf
void R_FreeStaticTriSurf(srfTriangles_t *tri)
void R_WriteTGA(const char *filename, const byte *data, int width, int height, bool flipVertical=false)
struct matchVert_s matchVert_t
virtual ID_TIME_T Timestamp() const
virtual const idJointQuat * GetDefaultPose(void) const
void R_ReverseTriangles(srfTriangles_t *tri)
struct vertCache_s * shadowCache
virtual int NumBaseSurfaces() const
GLubyte GLubyte GLubyte a
virtual void Printf(const char *fmt,...) id_attribute((format(printf
void R_BoundTriSurf(srfTriangles_t *tri)
struct aseModel_s aseModel_t
bool FixDegenerateNormal(void)
void MA_Free(maModel_t *ma)
bool UseUnsmoothedTangents(void) const
virtual void FreeVertexCache()
bool LoadASE(const char *fileName)
idList< maMaterial_t * > materials
GLenum GLsizei GLsizei height
int FindVector(const type *vectorList, const int vectorNum, const float epsilon)
virtual bool IsDefaultModel() const
virtual idBounds Bounds(const struct renderEntity_s *ent) const
idDeclManager * declManager
GLfloat GLfloat GLfloat GLfloat v3
int Append(const type &obj)
virtual float DepthHack() const
void * R_ClearedStaticAlloc(int bytes)
void * R_StaticAlloc(int bytes)
bool ShouldCreateBackSides(void) const
static idCVar r_slopNormal
virtual void Print() const
virtual void FreeSurfaceTriangles(srfTriangles_t *tris) const
void * Mem_ClearedAlloc(const int size)
const char * c_str(void) const
idVertexCache vertexCache
virtual int NumSurfaces() const
lwObject * lwGetObject(const char *filename, unsigned int *failID, int *failpos)
virtual void PurgeModel()
const char * ReadHashString()
void R_AllocStaticTriSurfIndexes(srfTriangles_t *tri, int numIndexes)
void * Mem_Alloc(const int size)
void Free(vertCache_t *buffer)
virtual bool IsLevelLoadReferenced()
void Init(const type &mins, const type &maxs, const int boxHashSize, const int initialSize)
static idCVar r_mergeModelSurfaces
void lwFreeObject(lwObject *object)
void R_StaticFree(void *data)
bool LoadFLT(const char *fileName)
virtual void Error(const char *fmt,...) id_attribute((format(printf
static idCVar r_slopVertex
bool IsDiscrete(void) const
virtual srfTriangles_t * ShadowHull() const
int R_TriSurfMemory(const srfTriangles_t *tri)
srfTriangles_t * shadowHull
void R_AllocStaticTriSurfVerts(srfTriangles_t *tri, int numVerts)
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
virtual int WriteVec3(const idVec3 &vec)
const idMaterial * defaultMaterial
aseModel_t * ASE_Load(const char *fileName)
bool LoadLWO(const char *fileName)
virtual int NearestJoint(int surfaceNum, int a, int b, int c) const
virtual void AddSurface(modelSurface_t surface)
static float Cos(float a)
void WriteHashString(const char *str)
idSIMDProcessor * SIMDProcessor