29 #include "../../idlib/precompiled.h"
32 #include "../Game_local.h"
34 #define MAX_SECTOR_DEPTH 12
35 #define MAX_SECTORS ((1<<(MAX_SECTOR_DEPTH+1))-1)
83 traceModelHash.
Free();
105 for ( i = traceModelHash.
First( hashKey ); i >= 0; i = traceModelHash.
Next( i ) ) {
106 if ( traceModelCache[i]->trm == trm ) {
107 traceModelCache[
i]->refCount++;
117 traceModelIndex = traceModelCache.
Append( entry );
118 traceModelHash.
Add( hashKey, traceModelIndex );
128 if ( traceModelIndex < 0 || traceModelIndex >= traceModelCache.
Num() || traceModelCache[
traceModelIndex]->refCount <= 0 ) {
129 gameLocal.
Warning(
"idClipModel::FreeTraceModel: tried to free uncached trace model" );
163 for ( i = 0; i < traceModelCache.
Num(); i++ ) {
184 traceModelCache.
SetNum( num );
186 for ( i = 0; i <
num; i++ ) {
196 traceModelCache[
i] = entry;
255 if ( renderModelHandle != -1 ) {
257 if ( renderEntity ) {
402 idStr collisionModelName;
416 if ( collisionModelName.
Length() ) {
481 mass = entry->
volume * density;
504 clipLinkAllocator.
Free( link );
516 while( node->
axis != -1 ) {
527 link = clipLinkAllocator.
Alloc();
588 this->
axis = newAxis;
589 if ( renderModelHandle != -1 ) {
592 if ( renderEntity ) {
649 for ( i = 0; i < 3; i++ ) {
650 if ( bounds[1][i] - bounds[0][i] > maxSector[i] ) {
651 maxSector[
i] = bounds[1][
i] - bounds[0][
i];
657 size = bounds[1] - bounds[0];
658 if ( size[0] >= size[1] && size[0] >= size[2] ) {
660 }
else if ( size[1] >= size[0] && size[1] >= size[2] ) {
666 anode->
dist = 0.5f * ( bounds[1][anode->
axis] + bounds[0][anode->
axis] );
671 front[0][anode->
axis] = back[1][anode->
axis] = anode->
dist;
700 gameLocal.
Printf(
"map bounds are (%1.1f, %1.1f, %1.1f)\n", size[0], size[1], size[2] );
701 gameLocal.
Printf(
"max clip sector is (%1.1f, %1.1f, %1.1f)\n", maxSector[0], maxSector[1], maxSector[2] );
749 while( node->
axis != -1 ) {
807 if ( bounds[0][0] > bounds[1][0] ||
808 bounds[0][1] > bounds[1][1] ||
809 bounds[0][2] > bounds[1][2] ) {
818 parms.
list = clipModelList;
839 for ( i = 0; i <
count; i++ ) {
841 for ( j = 0; j < entCount; j++ ) {
842 if ( entityList[j] == clipModelList[i]->entity ) {
846 if ( j >= entCount ) {
847 if ( entCount >= maxCount ) {
851 entityList[entCount] = clipModelList[
i]->
entity;
887 for ( i = 0; i <
num; i++ ) {
889 cm = clipModelList[
i];
892 if ( cm->
entity == passEntity ) {
893 clipModelList[
i] =
NULL;
894 }
else if ( cm->
entity == passOwner ) {
895 clipModelList[
i] =
NULL;
896 }
else if ( cm->
owner ) {
897 if ( cm->
owner == passEntity ) {
898 clipModelList[
i] =
NULL;
899 }
else if ( cm->
owner == passOwner ) {
900 clipModelList[
i] =
NULL;
952 gameLocal.
Error(
"TraceModelForClipModel: clip model %d is not a trace model\n", mdl->
GetId() );
977 memset( &results.
c, 0,
sizeof( results.
c ) );
1024 for ( i = 0; i <
num; i++ ) {
1025 touch = clipModelList[
i];
1043 results.
c.
id = touch->
id;
1080 memset( &results, 0,
sizeof( results ) );
1096 for ( i = 0; i <
num; i++ ) {
1097 touch = clipModelList[
i];
1115 results.
c.
id = touch->
id;
1122 return ( results.
fraction < 1.0f );
1149 memset( &results, 0,
sizeof( results ) );
1163 for ( i = 0; i <
num; i++ ) {
1164 touch = clipModelList[
i];
1182 results.
c.
id = touch->
id;
1189 return ( results.
fraction < 1.0f );
1204 trace_t translationalTrace, rotationalTrace, trace;
1216 if ( start == end ) {
1218 return Rotation( results, start, rotation, mdl, trmAxis, contentMask, passEntity );
1220 }
else if ( start != end ) {
1222 return Translation( results, start, end, mdl, trmAxis, contentMask, passEntity );
1241 memset( &translationalTrace, 0,
sizeof( translationalTrace ) );
1242 translationalTrace.
fraction = 1.0f;
1244 translationalTrace.
endAxis = trmAxis;
1247 if ( translationalTrace.
fraction != 0.0f ) {
1251 for ( i = 0; i < 3; i++ ) {
1252 if ( dir[i] < 0.0
f ) {
1253 traceBounds[0][
i] += dir[
i];
1256 traceBounds[1][
i] += dir[
i];
1262 for ( i = 0; i <
num; i++ ) {
1263 touch = clipModelList[
i];
1279 translationalTrace = trace;
1281 translationalTrace.
c.
id = touch->
id;
1282 if ( translationalTrace.
fraction == 0.0f ) {
1291 endPosition = translationalTrace.
endpos;
1292 endRotation = rotation;
1301 memset( &rotationalTrace, 0,
sizeof( rotationalTrace ) );
1303 rotationalTrace.
endpos = endPosition;
1307 if ( rotationalTrace.
fraction != 0.0f ) {
1314 for ( i = 0; i <
num; i++ ) {
1315 touch = clipModelList[
i];
1331 rotationalTrace = trace;
1333 rotationalTrace.
c.
id = touch->
id;
1334 if ( rotationalTrace.
fraction == 0.0f ) {
1341 if ( rotationalTrace.
fraction < 1.0f ) {
1342 results = rotationalTrace;
1344 results = translationalTrace;
1350 return ( translationalTrace.
fraction < 1.0f || rotationalTrace.
fraction < 1.0f );
1370 numContacts =
collisionModelManager->
Contacts( contacts, maxContacts, start, dir, depth, trm, trmAxis, contentMask, 0,
vec3_origin,
mat3_default );
1380 if ( numContacts >= maxContacts ) {
1393 for ( i = 0; i <
num; i++ ) {
1394 touch = clipModelList[
i];
1407 start, dir, depth, trm, trmAxis, contentMask,
1410 for ( j = 0; j <
n; j++ ) {
1416 if ( numContacts >= maxContacts ) {
1430 int i,
num, contents;
1446 traceBounds[0] =
start;
1447 traceBounds[1] =
start;
1457 for ( i = 0; i <
num; i++ ) {
1458 touch = clipModelList[
i];
1470 if ( ( touch->
contents & contentMask ) == 0 ) {
1481 contents |= ( touch->
contents & contentMask );
1524 return collisionModelManager->
Contacts( contacts, maxContacts, start, dir, depth, trm, trmAxis, contentMask, model, modelOrigin, modelAxis );
1553 if ( clipModel ==
NULL ) {
1557 winding += contact.
point;
1567 if ( handle != -1 ) {
1568 switch( contact.
type ) {
1593 winding[
i].ToVec3() *= clipModel->
axis;
1594 winding[
i].ToVec3() += clipModel->
origin;
1607 gameLocal.
Printf(
"t = %-3d, r = %-3d, m = %-3d, render = %-3d, contents = %-3d, contacts = %-3d\n",
1627 for ( i = 0; i <
num; i++ ) {
1628 clipModel = clipModelList[
i];
1629 if ( clipModel->
GetEntity() == passEntity ) {
int ClipModelsTouchingBounds(const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount) const
idEntity * GetEntity(void) const
idMat3 ToMat3(void) const
void WriteString(const char *string)
void DrawClipModels(const idVec3 &eye, const float radius, const idEntity *passEntity)
assert(prefInfo.fullscreenBtn)
static void ClearTraceModelCache(void)
virtual bool GetModelContents(cmHandle_t model, int &contents) const =0
void ReadMaterial(const idMaterial *&material)
void WriteObject(const idClass *obj)
int Next(const int index) const
void Printf(const char *fmt,...) const id_attribute((format(printf
int Contacts(contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity)
void SetNum(int newnum, bool resize=true)
bool GetModelContactFeature(const contactInfo_t &contact, const idClipModel *clipModel, idFixedWinding &winding) const
void FromPointRotation(const idVec3 &point, const idRotation &rotation)
ID_INLINE T Max(T x, T y)
const float * ToFloatPtr(void) const
void void void void void Error(const char *fmt,...) const id_attribute((format(printf
static int TraceModelCacheSize(void)
const idMaterial * material
const idMat3 & GetAxis(void) const
static void FreeTraceModel(int traceModelIndex)
virtual int GetNumClipModels(void) const =0
virtual void Translation(trace_t *results, const idVec3 &start, const idVec3 &end, const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis)=0
struct clipLink_s * nextInSector
static int FloatHash(const float *array, const int numFloats)
#define CM_MAX_TRACE_DIST
ID_INLINE bool TestHugeTranslation(trace_t &results, const idClipModel *mdl, const idVec3 &start, const idVec3 &end, const idMat3 &trmAxis)
const char * GetName(void) const
void ReadBool(bool &value)
GLint GLint GLsizei GLsizei GLsizei depth
struct clipSector_s * sector
struct trmCache_s trmCache_t
void ReadTraceModel(idTraceModel &trace)
const idVec3 & GetOrigin(void) const
virtual const char * GetModelName(cmHandle_t model) const =0
virtual int Contents(const idVec3 &start, const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis)=0
float GetRadius(void) const
virtual int Contacts(contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis)=0
virtual void DrawModel(cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis, const idVec3 &viewOrigin, const float radius)=0
bool IsRotated(void) const
void GetMassProperties(const float density, float &mass, idVec3 ¢erOfMass, idMat3 &inertiaTensor) const
struct clipLink_s * nextLink
void FromBoundsRotation(const idBounds &bounds, const idVec3 &origin, const idMat3 &axis, const idRotation &rotation)
void WriteVec3(const idVec3 &vec)
const idTraceModel * TraceModelForClipModel(const idClipModel *mdl) const
void WriteMaterial(const idMaterial *material)
struct listParms_s listParms_t
int EntitiesTouchingBounds(const idBounds &bounds, int contentMask, idEntity **entityList, int maxCount) const
virtual bool GetModelVertex(cmHandle_t model, int vertexNum, idVec3 &vertex) const =0
int First(const int key) const
void WriteBool(const bool value)
int GetTraceClipModels(const idBounds &bounds, int contentMask, const idEntity *passEntity, idClipModel **clipModelList) const
void void void Warning(const char *fmt,...) const id_attribute((format(printf
idClipModel temporaryClipModel
void FromBoundsTranslation(const idBounds &bounds, const idVec3 &origin, const idMat3 &axis, const idVec3 &translation)
idBlockAlloc< clipLink_t, 1024 > clipLinkAllocator
float GetAngle(void) const
GLuint GLuint GLsizei count
idClipModel defaultClipModel
virtual cmHandle_t LoadModel(const char *modelName, const bool precache)=0
idPhysics * GetPhysics(void) const
virtual void DebugLine(const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifetime=0, const bool depthTest=false)=0
void GetMassProperties(const float density, float &mass, idVec3 ¢erOfMass, idMat3 &inertiaTensor) const
int GetNumPoints(void) const
void ReadFloat(float &value)
static void RestoreTraceModels(idRestoreGame *savefile)
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
struct clipSector_s * clipSectors
virtual bool GetModelPolygon(cmHandle_t model, int polygonNum, idFixedWinding &winding) const =0
void FromPointTranslation(const idVec3 &point, const idVec3 &translation)
void WriteFloat(const float value)
virtual void Rotation(trace_t *results, const idVec3 &start, const idRotation &rotation, const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis)=0
virtual bool GetModelEdge(cmHandle_t model, int edgeNum, idVec3 &start, idVec3 &end) const =0
cmHandle_t Handle(void) const
idEntity * GetOwner(void) const
const int GetContentFlags(void) const
static int AllocTraceModel(const idTraceModel &trm)
struct clipLink_s * clipLinks
int ContactsModel(contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis)
static void SaveTraceModels(idSaveGame *savefile)
void PrintStatistics(void)
bool IsTraceModel(void) const
void Save(idSaveGame *savefile) const
void DeleteContents(bool clear)
void TraceRenderModel(trace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, const idMat3 &axis, idClipModel *touch) const
struct clipLink_s * clipLinks
void Link_r(struct clipSector_s *node)
virtual void DrawText(const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align=1, const int lifetime=0, bool depthTest=false)=0
void FromTransformedBounds(const idBounds &bounds, const idVec3 &origin, const idMat3 &axis)
idVec3 vec3_boxEpsilon(CM_BOX_EPSILON, CM_BOX_EPSILON, CM_BOX_EPSILON)
struct clipLink_s clipLink_t
idBounds Expand(const float d) const
void ReadBounds(idBounds &bounds)
virtual idClipModel * GetClipModel(int id=0) const =0
void WriteInt(const int value)
void WriteMat3(const idMat3 &mat)
const idVec3 & GetVec(void) const
void ReadMat3(idMat3 &mat)
struct clipSector_s * CreateClipSectors_r(const int depth, const idBounds &bounds, idVec3 &maxSector)
int Append(const type &obj)
void ClipModelsTouchingBounds_r(const struct clipSector_s *node, struct listParms_s &parms) const
bool LineIntersection(const idVec3 &start, const idVec3 &end) const
bool DrawModelContactFeature(const contactInfo_t &contact, const idClipModel *clipModel, int lifetime) const
void SetOrigin(const idVec3 &rotationOrigin)
bool IsCleared(void) const
bool LoadModel(const char *name)
const idMat3 & ToMat3(void) const
const idMaterial * material
bool Rotation(trace_t &results, const idVec3 &start, const idRotation &rotation, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity)
idVec3 GetCenter(void) const
int Contents(const idVec3 &start, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity)
void RotationModel(trace_t &results, const idVec3 &start, const idRotation &rotation, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis)
int ContentsModel(const idVec3 &start, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis)
void WriteTraceModel(const idTraceModel &trace)
struct clipLink_s * prevInSector
const char * GetName(void) const
void ReadVec3(idVec3 &vec)
const char * c_str(void) const
cmHandle_t collisionModelHandle
void TranslationModel(trace_t &results, const idVec3 &start, const idVec3 &end, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis)
void TranslationEntities(trace_t &results, const idVec3 &start, const idVec3 &end, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity)
void WriteBounds(const idBounds &bounds)
const idVec3 & GetOrigin(void) const
const idBounds & GetAbsBounds(void) const
void Add(const int key, const int index)
virtual cmHandle_t SetupTrmModel(const idTraceModel &trm, const idMaterial *material)=0
static cmHandle_t CheckModel(const char *name)
idBounds & ExpandSelf(const float d)
virtual void DebugBounds(const idVec4 &color, const idBounds &bounds, const idVec3 &org=vec3_origin, const int lifetime=0)=0
struct clipSector_s clipSector_t
idRenderWorld * gameRenderWorld
virtual bool ModelTrace(modelTrace_t &trace, qhandle_t entityHandle, const idVec3 &start, const idVec3 &end, const float radius) const =0
bool Translation(trace_t &results, const idVec3 &start, const idVec3 &end, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity)
int GetDimension(void) const
static idTraceModel * GetCachedTraceModel(int traceModelIndex)
struct clipSector_s * children[2]
virtual bool GetModelBounds(cmHandle_t model, idBounds &bounds) const =0
void Restore(idRestoreGame *savefile)
void ReadString(idStr &string)
#define JOINT_HANDLE_TO_CLIPMODEL_ID(id)
void SetPosition(const idVec3 &newOrigin, const idMat3 &newAxis)
idCollisionModelManager * collisionModelManager
virtual const renderEntity_t * GetRenderEntity(qhandle_t entityHandle) const =0
bool Motion(trace_t &results, const idVec3 &start, const idVec3 &end, const idRotation &rotation, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity)
void ReadObject(idClass *&obj)
static int GetTraceModelHashKey(const idTraceModel &trm)