Initial commit.
This commit is contained in:
40
codemp/ghoul2/g2.h
Normal file
40
codemp/ghoul2/g2.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#if defined (_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
#if !defined(G2_H_INC)
|
||||
#define G2_H_INC
|
||||
|
||||
|
||||
#define BONE_ANGLES_PREMULT 0x0001
|
||||
#define BONE_ANGLES_POSTMULT 0x0002
|
||||
#define BONE_ANGLES_REPLACE 0x0004
|
||||
|
||||
//rww - RAGDOLL_BEGIN
|
||||
#define BONE_ANGLES_RAGDOLL 0x2000 // the rag flags give more details
|
||||
//rww - RAGDOLL_END
|
||||
#define BONE_ANGLES_IK 0x4000 // the rag flags give more details
|
||||
|
||||
#define BONE_ANGLES_TOTAL ( BONE_ANGLES_PREMULT | BONE_ANGLES_POSTMULT | BONE_ANGLES_REPLACE )
|
||||
#define BONE_ANIM_OVERRIDE 0x0008
|
||||
#define BONE_ANIM_OVERRIDE_LOOP 0x0010
|
||||
#define BONE_ANIM_OVERRIDE_FREEZE ( 0x0040 + BONE_ANIM_OVERRIDE )
|
||||
#define BONE_ANIM_BLEND 0x0080
|
||||
#define BONE_ANIM_TOTAL ( BONE_ANIM_OVERRIDE | BONE_ANIM_OVERRIDE_LOOP | BONE_ANIM_OVERRIDE_FREEZE | BONE_ANIM_BLEND)
|
||||
|
||||
|
||||
// defines to setup the
|
||||
#define ENTITY_WIDTH 12
|
||||
#define MODEL_WIDTH 10
|
||||
#define BOLT_WIDTH 10
|
||||
|
||||
#define MODEL_AND ((1<<MODEL_WIDTH)-1)
|
||||
#define BOLT_AND ((1<<BOLT_WIDTH)-1)
|
||||
#define ENTITY_AND ((1<<ENTITY_WIDTH)-1)
|
||||
|
||||
#define BOLT_SHIFT 0
|
||||
#define MODEL_SHIFT (BOLT_SHIFT + BOLT_WIDTH)
|
||||
#define ENTITY_SHIFT (MODEL_SHIFT + MODEL_WIDTH)
|
||||
|
||||
|
||||
#endif // G2_H_INC
|
||||
|
||||
2698
codemp/ghoul2/g2_api.cpp
Normal file
2698
codemp/ghoul2/g2_api.cpp
Normal file
File diff suppressed because it is too large
Load Diff
331
codemp/ghoul2/g2_bolts.cpp
Normal file
331
codemp/ghoul2/g2_bolts.cpp
Normal file
@@ -0,0 +1,331 @@
|
||||
// leave this as first line for PCH reasons...
|
||||
//
|
||||
|
||||
|
||||
//Anything above this #include will be ignored by the compiler
|
||||
#include "../qcommon/exe_headers.h"
|
||||
|
||||
#if !defined(TR_LOCAL_H)
|
||||
#include "../renderer/tr_local.h"
|
||||
#endif
|
||||
|
||||
#if !defined(G2_H_INC)
|
||||
#include "G2.h"
|
||||
#endif
|
||||
#include "G2_local.h"
|
||||
|
||||
//=====================================================================================================================
|
||||
// Bolt List handling routines - so entities can attach themselves to any part of the model in question
|
||||
|
||||
// Given a bone number, see if that bone is already in our bone list
|
||||
int G2_Find_Bolt_Bone_Num(boltInfo_v &bltlist, const int boneNum)
|
||||
{
|
||||
int i;
|
||||
|
||||
// look through entire list
|
||||
for(i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// if this bone entry has no info in it, bounce over it
|
||||
if (bltlist[i].boneNumber == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bltlist[i].boneNumber == boneNum)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// didn't find it
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Given a bone number, see if that surface is already in our surfacelist list
|
||||
int G2_Find_Bolt_Surface_Num(boltInfo_v &bltlist, const int surfaceNum, const int flags)
|
||||
{
|
||||
int i;
|
||||
|
||||
// look through entire list
|
||||
for(i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// if this bone entry has no info in it, bounce over it
|
||||
if (bltlist[i].surfaceNumber == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((bltlist[i].surfaceNumber == surfaceNum) && ((bltlist[i].surfaceType & flags) == flags))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// didn't find it
|
||||
return -1;
|
||||
}
|
||||
|
||||
//=========================================================================================
|
||||
//// Public Bolt Routines
|
||||
int G2_Add_Bolt_Surf_Num(CGhoul2Info *ghlInfo, boltInfo_v &bltlist, surfaceInfo_v &slist, const int surfNum)
|
||||
{
|
||||
assert(ghlInfo && ghlInfo->mValid);
|
||||
boltInfo_t tempBolt;
|
||||
int i;
|
||||
|
||||
// first up, make sure have a surface first
|
||||
if (surfNum >= slist.size())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// look through entire list - see if it's already there first
|
||||
for(i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// already there??
|
||||
if (bltlist[i].surfaceNumber == surfNum)
|
||||
{
|
||||
// increment the usage count
|
||||
bltlist[i].boltUsed++;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// we have a surface
|
||||
// look through entire list - see if it's already there first
|
||||
for(i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// if this surface entry has info in it, bounce over it
|
||||
if (bltlist[i].boneNumber == -1 && bltlist[i].surfaceNumber == -1)
|
||||
{
|
||||
// if we found an entry that had a -1 for the bone / surface number, then we hit a surface / bone slot that was empty
|
||||
bltlist[i].surfaceNumber = surfNum;
|
||||
bltlist[i].surfaceType = G2SURFACEFLAG_GENERATED;
|
||||
bltlist[i].boltUsed = 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// ok, we didn't find an existing surface of that name, or an empty slot. Lets add an entry
|
||||
tempBolt.surfaceNumber = surfNum;
|
||||
tempBolt.surfaceType = G2SURFACEFLAG_GENERATED;
|
||||
tempBolt.boneNumber = -1;
|
||||
tempBolt.boltUsed = 1;
|
||||
bltlist.push_back(tempBolt);
|
||||
return bltlist.size()-1;
|
||||
|
||||
}
|
||||
|
||||
int G2_Add_Bolt(CGhoul2Info *ghlInfo, boltInfo_v &bltlist, surfaceInfo_v &slist, const char *boneName)
|
||||
{
|
||||
assert(ghlInfo && ghlInfo->mValid);
|
||||
model_t *mod_m = (model_t *)ghlInfo->currentModel;
|
||||
model_t *mod_a = (model_t *)ghlInfo->animModel;
|
||||
int i, x, surfNum = -1;
|
||||
mdxaSkel_t *skel;
|
||||
mdxaSkelOffsets_t *offsets;
|
||||
mdxmHierarchyOffsets_t *surfOffsets;
|
||||
boltInfo_t tempBolt;
|
||||
int flags;
|
||||
|
||||
surfOffsets = (mdxmHierarchyOffsets_t *)((byte*)mod_m->mdxm + sizeof(mdxmHeader_t));
|
||||
// first up, we'll search for that which this bolt names in all the surfaces
|
||||
surfNum = G2_IsSurfaceLegal((void*)mod_m, boneName, &flags);
|
||||
|
||||
// did we find it as a surface?
|
||||
if (surfNum != -1)
|
||||
{
|
||||
// look through entire list - see if it's already there first
|
||||
for(i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// already there??
|
||||
if (bltlist[i].surfaceNumber == surfNum)
|
||||
{
|
||||
// increment the usage count
|
||||
bltlist[i].boltUsed++;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// look through entire list - see if we can re-use one
|
||||
for(i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// if this surface entry has info in it, bounce over it
|
||||
if (bltlist[i].boneNumber == -1 && bltlist[i].surfaceNumber == -1)
|
||||
{
|
||||
// if we found an entry that had a -1 for the bone / surface number, then we hit a surface / bone slot that was empty
|
||||
bltlist[i].surfaceNumber = surfNum;
|
||||
bltlist[i].boltUsed = 1;
|
||||
bltlist[i].surfaceType = 0;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// ok, we didn't find an existing surface of that name, or an empty slot. Lets add an entry
|
||||
tempBolt.surfaceNumber = surfNum;
|
||||
tempBolt.boneNumber = -1;
|
||||
tempBolt.boltUsed = 1;
|
||||
tempBolt.surfaceType = 0;
|
||||
bltlist.push_back(tempBolt);
|
||||
return bltlist.size()-1;
|
||||
}
|
||||
|
||||
// no, check to see if it's a bone then
|
||||
|
||||
offsets = (mdxaSkelOffsets_t *)((byte *)mod_a->mdxa + sizeof(mdxaHeader_t));
|
||||
|
||||
// walk the entire list of bones in the gla file for this model and see if any match the name of the bone we want to find
|
||||
for (x=0; x< mod_a->mdxa->numBones; x++)
|
||||
{
|
||||
skel = (mdxaSkel_t *)((byte *)mod_a->mdxa + sizeof(mdxaHeader_t) + offsets->offsets[x]);
|
||||
// if name is the same, we found it
|
||||
if (!stricmp(skel->name, boneName))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check to see we did actually make a match with a bone in the model
|
||||
if (x == mod_a->mdxa->numBones)
|
||||
{
|
||||
// didn't find it? Error
|
||||
//assert(0&&x == mod_a->mdxa->numBones);
|
||||
#ifdef _DEBUG
|
||||
// Com_Printf("WARNING: %s not found on skeleton\n", boneName);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
// look through entire list - see if it's already there first
|
||||
for(i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// already there??
|
||||
if (bltlist[i].boneNumber == x)
|
||||
{
|
||||
// increment the usage count
|
||||
bltlist[i].boltUsed++;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// look through entire list - see if we can re-use it
|
||||
for(i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// if this bone entry has info in it, bounce over it
|
||||
if (bltlist[i].boneNumber == -1 && bltlist[i].surfaceNumber == -1)
|
||||
{
|
||||
// if we found an entry that had a -1 for the bonenumber, then we hit a bone slot that was empty
|
||||
bltlist[i].boneNumber = x;
|
||||
bltlist[i].boltUsed = 1;
|
||||
bltlist[i].surfaceType = 0;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// ok, we didn't find an existing bone of that name, or an empty slot. Lets add an entry
|
||||
tempBolt.boneNumber = x;
|
||||
tempBolt.surfaceNumber = -1;
|
||||
tempBolt.boltUsed = 1;
|
||||
tempBolt.surfaceType = 0;
|
||||
bltlist.push_back(tempBolt);
|
||||
return bltlist.size()-1;
|
||||
|
||||
}
|
||||
|
||||
// Given a model handle, and a bone name, we want to remove this bone from the bone override list
|
||||
qboolean G2_Remove_Bolt (boltInfo_v &bltlist, int index)
|
||||
{
|
||||
// did we find it?
|
||||
if (index != -1)
|
||||
{
|
||||
bltlist[index].boltUsed--;
|
||||
if (!bltlist[index].boltUsed)
|
||||
{
|
||||
// set this bone to not used
|
||||
bltlist[index].boneNumber = -1;
|
||||
bltlist[index].surfaceNumber = -1;
|
||||
|
||||
unsigned int newSize = bltlist.size();
|
||||
// now look through the list from the back and see if there is a block of -1's we can resize off the end of the list
|
||||
for (int i=bltlist.size()-1; i>-1; i--)
|
||||
{
|
||||
if ((bltlist[i].surfaceNumber == -1) && (bltlist[i].boneNumber == -1))
|
||||
{
|
||||
newSize = i;
|
||||
}
|
||||
// once we hit one that isn't a -1, we are done.
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
// do we need to resize?
|
||||
if (newSize != bltlist.size())
|
||||
{
|
||||
// yes, so lets do it
|
||||
bltlist.resize(newSize);
|
||||
}
|
||||
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
|
||||
// no
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// set the bolt list to all unused so the bone transformation routine ignores it.
|
||||
void G2_Init_Bolt_List(boltInfo_v &bltlist)
|
||||
{
|
||||
bltlist.clear();
|
||||
}
|
||||
|
||||
// remove any bolts that reference original surfaces, generated surfaces, or bones that aren't active anymore
|
||||
void G2_RemoveRedundantBolts(boltInfo_v &bltlist, surfaceInfo_v &slist, int *activeSurfaces, int *activeBones)
|
||||
{
|
||||
// walk the bolt list
|
||||
for (int i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// are we using this bolt?
|
||||
if ((bltlist[i].surfaceNumber != -1) || (bltlist[i].boneNumber != -1))
|
||||
{
|
||||
// is this referenceing a surface?
|
||||
if (bltlist[i].surfaceNumber != -1)
|
||||
{
|
||||
// is this bolt looking at a generated surface?
|
||||
if (bltlist[i].surfaceType)
|
||||
{
|
||||
// yes, so look for it in the surface list
|
||||
if (!G2_FindOverrideSurface(bltlist[i].surfaceNumber, slist))
|
||||
{
|
||||
// no - we want to remove this bolt, regardless of how many people are using it
|
||||
bltlist[i].boltUsed = 1;
|
||||
G2_Remove_Bolt(bltlist, i);
|
||||
}
|
||||
}
|
||||
// no, it's an original, so look for it in the active surfaces list
|
||||
{
|
||||
if (!activeSurfaces[bltlist[i].surfaceNumber])
|
||||
{
|
||||
// no - we want to remove this bolt, regardless of how many people are using it
|
||||
bltlist[i].boltUsed = 1;
|
||||
G2_Remove_Bolt(bltlist, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
// no, must be looking at a bone then
|
||||
else
|
||||
{
|
||||
// is that bone active then?
|
||||
if (!activeBones[bltlist[i].boneNumber])
|
||||
{
|
||||
// no - we want to remove this bolt, regardless of how many people are using it
|
||||
bltlist[i].boltUsed = 1;
|
||||
G2_Remove_Bolt(bltlist, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
4905
codemp/ghoul2/g2_bones.cpp
Normal file
4905
codemp/ghoul2/g2_bones.cpp
Normal file
File diff suppressed because it is too large
Load Diff
201
codemp/ghoul2/g2_gore.h
Normal file
201
codemp/ghoul2/g2_gore.h
Normal file
@@ -0,0 +1,201 @@
|
||||
#if defined (_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
#if !defined(G2_GORE_H_INC)
|
||||
#define G2_GORE_H_INC
|
||||
|
||||
#ifdef _G2_GORE
|
||||
|
||||
#define MAX_LODS (8)
|
||||
struct GoreTextureCoordinates
|
||||
{
|
||||
float *tex[MAX_LODS];
|
||||
|
||||
GoreTextureCoordinates()
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<MAX_LODS;i++)
|
||||
{
|
||||
tex[i]=0;
|
||||
}
|
||||
}
|
||||
~GoreTextureCoordinates()
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<MAX_LODS;i++)
|
||||
{
|
||||
if ( tex[i] )
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
extern int g_goreTexAllocs;
|
||||
g_goreTexAllocs--;
|
||||
#endif
|
||||
Z_Free(tex[i]);
|
||||
tex[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int AllocGoreRecord();
|
||||
GoreTextureCoordinates *FindGoreRecord(int tag);
|
||||
void DeleteGoreRecord(int tag);
|
||||
|
||||
struct SGoreSurface
|
||||
{
|
||||
int shader;
|
||||
int mGoreTag;
|
||||
int mDeleteTime;
|
||||
int mFadeTime;
|
||||
bool mFadeRGB;
|
||||
|
||||
int mGoreGrowStartTime;
|
||||
int mGoreGrowEndTime; // set this to -1 to disable growing
|
||||
//curscale = (curtime-mGoreGrowStartTime)*mGoreGrowFactor + mGoreGrowOffset;
|
||||
float mGoreGrowFactor;
|
||||
float mGoreGrowOffset;
|
||||
};
|
||||
|
||||
class CGoreSet
|
||||
{
|
||||
public:
|
||||
int mMyGoreSetTag;
|
||||
unsigned char mRefCount;
|
||||
multimap<int,SGoreSurface> mGoreRecords; // a map from surface index
|
||||
CGoreSet(int tag) : mMyGoreSetTag(tag), mRefCount(0) {}
|
||||
~CGoreSet();
|
||||
};
|
||||
|
||||
CGoreSet *FindGoreSet(int goreSetTag);
|
||||
CGoreSet *NewGoreSet();
|
||||
void DeleteGoreSet(int goreSetTag);
|
||||
|
||||
#endif // _G2_GORE
|
||||
|
||||
//rww - RAGDOLL_BEGIN
|
||||
|
||||
/// ragdoll stuff
|
||||
|
||||
#pragma warning(disable: 4512)
|
||||
|
||||
struct SRagDollEffectorCollision
|
||||
{
|
||||
vec3_t effectorPosition;
|
||||
const trace_t &tr;
|
||||
bool useTracePlane;
|
||||
SRagDollEffectorCollision(const vec3_t effectorPos,const trace_t &t) :
|
||||
tr(t),
|
||||
useTracePlane(false)
|
||||
{
|
||||
VectorCopy(effectorPos,effectorPosition);
|
||||
}
|
||||
};
|
||||
|
||||
class CRagDollUpdateParams
|
||||
{
|
||||
public:
|
||||
vec3_t angles;
|
||||
vec3_t position;
|
||||
vec3_t scale;
|
||||
vec3_t velocity;
|
||||
//CServerEntity *me;
|
||||
int me; //index!
|
||||
int settleFrame;
|
||||
|
||||
//at some point I'll want to make VM callbacks in here. For now I am just doing nothing.
|
||||
virtual void EffectorCollision(const SRagDollEffectorCollision &data)
|
||||
{
|
||||
// assert(0); // you probably meant to override this
|
||||
}
|
||||
virtual void RagDollBegin()
|
||||
{
|
||||
// assert(0); // you probably meant to override this
|
||||
}
|
||||
virtual void RagDollSettled()
|
||||
{
|
||||
// assert(0); // you probably meant to override this
|
||||
}
|
||||
|
||||
virtual void Collision()
|
||||
{
|
||||
// assert(0); // you probably meant to override this
|
||||
// we had a collision, uhh I guess call SetRagDoll RP_DEATH_COLLISION
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
virtual void DebugLine(const vec3_t p1,const vec3_t p2,bool bbox) {assert(0);}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
class CRagDollParams
|
||||
{
|
||||
public:
|
||||
|
||||
enum ERagPhase
|
||||
{
|
||||
RP_START_DEATH_ANIM,
|
||||
RP_END_DEATH_ANIM,
|
||||
RP_DEATH_COLLISION,
|
||||
RP_CORPSE_SHOT,
|
||||
RP_GET_PELVIS_OFFSET, // this actually does nothing but set the pelvisAnglesOffset, and pelvisPositionOffset
|
||||
RP_SET_PELVIS_OFFSET, // this actually does nothing but set the pelvisAnglesOffset, and pelvisPositionOffset
|
||||
RP_DISABLE_EFFECTORS // this removes effectors given by the effectorsToTurnOff member
|
||||
};
|
||||
vec3_t angles;
|
||||
vec3_t position;
|
||||
vec3_t scale;
|
||||
vec3_t pelvisAnglesOffset; // always set on return, an argument for RP_SET_PELVIS_OFFSET
|
||||
vec3_t pelvisPositionOffset; // always set on return, an argument for RP_SET_PELVIS_OFFSET
|
||||
|
||||
float fImpactStrength; //should be applicable when RagPhase is RP_DEATH_COLLISION
|
||||
float fShotStrength; //should be applicable for setting velocity of corpse on shot (probably only on RP_CORPSE_SHOT)
|
||||
//CServerEntity *me;
|
||||
int me;
|
||||
|
||||
//rww - we have convenient animation/frame access in the game, so just send this info over from there.
|
||||
int startFrame;
|
||||
int endFrame;
|
||||
|
||||
int collisionType; // 1 = from a fall, 0 from effectors, this will be going away soon, hence no enum
|
||||
|
||||
qboolean CallRagDollBegin; // a return value, means that we are now begininng ragdoll and the NPC stuff needs to happen
|
||||
|
||||
ERagPhase RagPhase;
|
||||
|
||||
// effector control, used for RP_DISABLE_EFFECTORS call
|
||||
|
||||
enum ERagEffector
|
||||
{
|
||||
RE_MODEL_ROOT= 0x00000001, //"model_root"
|
||||
RE_PELVIS= 0x00000002, //"pelvis"
|
||||
RE_LOWER_LUMBAR= 0x00000004, //"lower_lumbar"
|
||||
RE_UPPER_LUMBAR= 0x00000008, //"upper_lumbar"
|
||||
RE_THORACIC= 0x00000010, //"thoracic"
|
||||
RE_CRANIUM= 0x00000020, //"cranium"
|
||||
RE_RHUMEROUS= 0x00000040, //"rhumerus"
|
||||
RE_LHUMEROUS= 0x00000080, //"lhumerus"
|
||||
RE_RRADIUS= 0x00000100, //"rradius"
|
||||
RE_LRADIUS= 0x00000200, //"lradius"
|
||||
RE_RFEMURYZ= 0x00000400, //"rfemurYZ"
|
||||
RE_LFEMURYZ= 0x00000800, //"lfemurYZ"
|
||||
RE_RTIBIA= 0x00001000, //"rtibia"
|
||||
RE_LTIBIA= 0x00002000, //"ltibia"
|
||||
RE_RHAND= 0x00004000, //"rhand"
|
||||
RE_LHAND= 0x00008000, //"lhand"
|
||||
RE_RTARSAL= 0x00010000, //"rtarsal"
|
||||
RE_LTARSAL= 0x00020000, //"ltarsal"
|
||||
RE_RTALUS= 0x00040000, //"rtalus"
|
||||
RE_LTALUS= 0x00080000, //"ltalus"
|
||||
RE_RRADIUSX= 0x00100000, //"rradiusX"
|
||||
RE_LRADIUSX= 0x00200000, //"lradiusX"
|
||||
RE_RFEMURX= 0x00400000, //"rfemurX"
|
||||
RE_LFEMURX= 0x00800000, //"lfemurX"
|
||||
RE_CEYEBROW= 0x01000000 //"ceyebrow"
|
||||
};
|
||||
|
||||
ERagEffector effectorsToTurnOff; // set this to an | of the above flags for a RP_DISABLE_EFFECTORS
|
||||
|
||||
};
|
||||
#endif //G2_GORE_H_INC
|
||||
//rww - RAGDOLL_END
|
||||
226
codemp/ghoul2/g2_local.h
Normal file
226
codemp/ghoul2/g2_local.h
Normal file
@@ -0,0 +1,226 @@
|
||||
// defines to setup the
|
||||
|
||||
#include "ghoul2_shared.h"
|
||||
|
||||
|
||||
//rww - RAGDOLL_BEGIN
|
||||
class CRagDollUpdateParams;
|
||||
//rww - RAGDOLL_END
|
||||
|
||||
class CMiniHeap;
|
||||
|
||||
#define GHOUL2_CRAZY_SMOOTH 0x2000 //hack for smoothing during ugly situations. forgive me.
|
||||
|
||||
|
||||
// internal surface calls G2_surfaces.cpp
|
||||
qboolean G2_SetSurfaceOnOff (CGhoul2Info *ghlInfo, surfaceInfo_v &slist, const char *surfaceName, const int offFlags);
|
||||
int G2_IsSurfaceOff (CGhoul2Info *ghlInfo, surfaceInfo_v &slist, const char *surfaceName);
|
||||
qboolean G2_SetRootSurface( CGhoul2Info_v &ghoul2, const int modelIndex, const char *surfaceName);
|
||||
int G2_AddSurface(CGhoul2Info *ghoul2, int surfaceNumber, int polyNumber, float BarycentricI, float BarycentricJ, int lod );
|
||||
qboolean G2_RemoveSurface(surfaceInfo_v &slist, const int index);
|
||||
surfaceInfo_t *G2_FindOverrideSurface(int surfaceNum, surfaceInfo_v &surfaceList);
|
||||
int G2_IsSurfaceLegal(void *mod, const char *surfaceName, int *flags);
|
||||
int G2_GetParentSurface(CGhoul2Info *ghlInfo, const int index);
|
||||
int G2_GetSurfaceIndex(CGhoul2Info *ghlInfo, const char *surfaceName);
|
||||
int G2_IsSurfaceRendered(CGhoul2Info *ghlInfo, const char *surfaceName, surfaceInfo_v &slist);
|
||||
|
||||
// internal bone calls - G2_Bones.cpp
|
||||
qboolean G2_Set_Bone_Angles(CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName, const float *angles, const int flags,
|
||||
const Eorientations up, const Eorientations left, const Eorientations forward, qhandle_t *modelList,
|
||||
const int modelIndex, const int blendTime, const int currentTime);
|
||||
qboolean G2_Remove_Bone (CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName);
|
||||
qboolean G2_Set_Bone_Anim(CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName, const int startFrame,
|
||||
const int endFrame, const int flags, const float animSpeed, const int currentTime, const float setFrame, const int blendTime);
|
||||
qboolean G2_Get_Bone_Anim(CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName, const int currentTime,
|
||||
float *currentFrame, int *startFrame, int *endFrame, int *flags, float *retAnimSpeed, qhandle_t *modelList, int modelIndex);
|
||||
qboolean G2_Get_Bone_Anim_Range(CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName, int *startFrame, int *endFrame);
|
||||
qboolean G2_Pause_Bone_Anim(CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName, const int currentTime );
|
||||
qboolean G2_IsPaused(const char *fileName, boneInfo_v &blist, const char *boneName);
|
||||
qboolean G2_Stop_Bone_Anim(const char *fileName, boneInfo_v &blist, const char *boneName);
|
||||
qboolean G2_Stop_Bone_Angles(const char *fileName, boneInfo_v &blist, const char *boneName);
|
||||
//rww - RAGDOLL_BEGIN
|
||||
void G2_Animate_Bone_List(CGhoul2Info_v &ghoul2, const int currentTime, const int index,CRagDollUpdateParams *params);
|
||||
//rww - RAGDOLL_END
|
||||
void G2_Init_Bone_List(boneInfo_v &blist);
|
||||
int G2_Find_Bone_In_List(boneInfo_v &blist, const int boneNum);
|
||||
void G2_RemoveRedundantBoneOverrides(boneInfo_v &blist, int *activeBones);
|
||||
qboolean G2_Set_Bone_Angles_Matrix(const char *fileName, boneInfo_v &blist, const char *boneName, const mdxaBone_t &matrix,
|
||||
const int flags, qhandle_t *modelList, const int modelIndex, const int blendTime, const int currentTime);
|
||||
int G2_Get_Bone_Index(CGhoul2Info *ghoul2, const char *boneName);
|
||||
qboolean G2_Set_Bone_Angles_Index(boneInfo_v &blist, const int index,
|
||||
const float *angles, const int flags, const Eorientations yaw,
|
||||
const Eorientations pitch, const Eorientations roll, qhandle_t *modelList,
|
||||
const int modelIndex, const int blendTime, const int currentTime);
|
||||
qboolean G2_Set_Bone_Angles_Matrix_Index(boneInfo_v &blist, const int index,
|
||||
const mdxaBone_t &matrix, const int flags, qhandle_t *modelList,
|
||||
const int modelIndex, const int blendTime, const int currentTime);
|
||||
qboolean G2_Stop_Bone_Anim_Index(boneInfo_v &blist, const int index);
|
||||
qboolean G2_Stop_Bone_Angles_Index(boneInfo_v &blist, const int index);
|
||||
qboolean G2_Set_Bone_Anim_Index(boneInfo_v &blist, const int index, const int startFrame,
|
||||
const int endFrame, const int flags, const float animSpeed, const int currentTime, const float setFrame, const int blendTime, const int numFrames);
|
||||
qboolean G2_Get_Bone_Anim_Index( boneInfo_v &blist, const int index, const int currentTime,
|
||||
float *currentFrame, int *startFrame, int *endFrame, int *flags, float *retAnimSpeed, qhandle_t *modelList, int modelIndex);
|
||||
|
||||
// misc functions G2_misc.cpp
|
||||
void G2_List_Model_Surfaces(const char *fileName);
|
||||
void G2_List_Model_Bones(const char *fileName, int frame);
|
||||
qboolean G2_GetAnimFileName(const char *fileName, char **filename);
|
||||
#ifdef _G2_GORE
|
||||
void G2_TraceModels(CGhoul2Info_v &ghoul2, vec3_t rayStart, vec3_t rayEnd, CollisionRecord_t *collRecMap, int entNum, int traceFlags, int useLod, float fRadius, float ssize,float tsize,float theta,int shader, SSkinGoreData *gore);
|
||||
#else
|
||||
void G2_TraceModels(CGhoul2Info_v &ghoul2, vec3_t rayStart, vec3_t rayEnd, CollisionRecord_t *collRecMap, int entNum, int traceFlags, int useLod, float fRadius);
|
||||
#endif
|
||||
void TransformAndTranslatePoint (const vec3_t in, vec3_t out, mdxaBone_t *mat);
|
||||
#ifdef _G2_GORE
|
||||
void G2_TransformModel(CGhoul2Info_v &ghoul2, const int frameNum, vec3_t scale, CMiniHeap *G2VertSpace, int useLod, bool ApplyGore);
|
||||
#else
|
||||
void G2_TransformModel(CGhoul2Info_v &ghoul2, const int frameNum, vec3_t scale, CMiniHeap *G2VertSpace, int useLod);
|
||||
#endif
|
||||
void G2_GenerateWorldMatrix(const vec3_t angles, const vec3_t origin);
|
||||
void TransformPoint (const vec3_t in, vec3_t out, mdxaBone_t *mat);
|
||||
void Inverse_Matrix(mdxaBone_t *src, mdxaBone_t *dest);
|
||||
void *G2_FindSurface(void *mod, int index, int lod);
|
||||
qboolean G2_SaveGhoul2Models(CGhoul2Info_v &ghoul2, char **buffer, int *size);
|
||||
void G2_LoadGhoul2Model(CGhoul2Info_v &ghoul2, char *buffer);
|
||||
|
||||
// internal bolt calls. G2_bolts.cpp
|
||||
int G2_Add_Bolt(CGhoul2Info *ghlInfo, boltInfo_v &bltlist, surfaceInfo_v &slist, const char *boneName);
|
||||
qboolean G2_Remove_Bolt (boltInfo_v &bltlist, int index);
|
||||
void G2_Init_Bolt_List(boltInfo_v &bltlist);
|
||||
int G2_Find_Bolt_Bone_Num(boltInfo_v &bltlist, const int boneNum);
|
||||
int G2_Find_Bolt_Surface_Num(boltInfo_v &bltlist, const int surfaceNum, const int flags);
|
||||
int G2_Add_Bolt_Surf_Num(CGhoul2Info *ghlInfo, boltInfo_v &bltlist, surfaceInfo_v &slist, const int surfNum);
|
||||
void G2_RemoveRedundantBolts(boltInfo_v &bltlist, surfaceInfo_v &slist, int *activeSurfaces, int *activeBones);
|
||||
|
||||
|
||||
// API calls - G2_API.cpp
|
||||
void G2API_GetModelName(CGhoul2Info_v &ghoul2, const int modelIndex,
|
||||
const char **modelName);
|
||||
void G2API_SetTime(int currentTime, int clock);
|
||||
int G2API_GetTime(int argTime);
|
||||
|
||||
qhandle_t G2API_PrecacheGhoul2Model(const char *fileName);
|
||||
|
||||
int G2API_InitGhoul2Model(CGhoul2Info_v **ghoul2Ptr, const char *fileName, int modelIndex, qhandle_t customSkin = NULL,
|
||||
qhandle_t customShader = NULL, int modelFlags = 0, int lodBias = 0);
|
||||
qboolean G2API_SetLodBias(CGhoul2Info *ghlInfo, int lodBias);
|
||||
qboolean G2API_SetSkin(CGhoul2Info *ghlInfo, qhandle_t customSkin, qhandle_t renderSkin);
|
||||
qboolean G2API_SetShader(CGhoul2Info *ghlInfo, qhandle_t customShader);
|
||||
qboolean G2API_HasGhoul2ModelOnIndex(CGhoul2Info_v **ghlRemove, const int modelIndex);
|
||||
qboolean G2API_RemoveGhoul2Model(CGhoul2Info_v **ghlRemove, const int modelIndex);
|
||||
qboolean G2API_RemoveGhoul2Models(CGhoul2Info_v **ghlRemove);
|
||||
qboolean G2API_SetSurfaceOnOff(CGhoul2Info_v &ghoul2, const char *surfaceName, const int flags);
|
||||
int G2API_GetSurfaceOnOff(CGhoul2Info *ghlInfo, const char *surfaceName);
|
||||
qboolean G2API_SetRootSurface(CGhoul2Info_v &ghoul2, const int modelIndex, const char *surfaceName);
|
||||
qboolean G2API_RemoveSurface(CGhoul2Info *ghlInfo, const int index);
|
||||
int G2API_AddSurface(CGhoul2Info *ghlInfo, int surfaceNumber, int polyNumber, float BarycentricI, float BarycentricJ, int lod );
|
||||
qboolean G2API_SetBoneAnim(CGhoul2Info_v &ghoul2, const int modelIndex, const char *boneName, const int startFrame, const int endFrame,
|
||||
const int flags, const float animSpeed, const int currentTime, const float setFrame = -1, const int blendTime = -1);
|
||||
qboolean G2API_GetBoneAnim(CGhoul2Info *ghlInfo, const char *boneName, const int currentTime, float *currentFrame,
|
||||
int *startFrame, int *endFrame, int *flags, float *animSpeed, qhandle_t *modelList);
|
||||
qboolean G2API_GetAnimRange(CGhoul2Info *ghlInfo, const char *boneName, int *startFrame, int *endFrame);
|
||||
qboolean G2API_PauseBoneAnim(CGhoul2Info *ghlInfo, const char *boneName, const int currentTime);
|
||||
qboolean G2API_IsPaused(CGhoul2Info *ghlInfo, const char *boneName);
|
||||
qboolean G2API_StopBoneAnim(CGhoul2Info *ghlInfo, const char *boneName);
|
||||
|
||||
|
||||
qboolean G2API_SetBoneAngles(CGhoul2Info_v &ghoul2, const int modelIndex, const char *boneName, const vec3_t angles, const int flags,
|
||||
const Eorientations up, const Eorientations left, const Eorientations forward,
|
||||
qhandle_t *modelList, int blendTime, int currentTime );
|
||||
|
||||
qboolean G2API_StopBoneAngles(CGhoul2Info *ghlInfo, const char *boneName);
|
||||
qboolean G2API_RemoveBone(CGhoul2Info *ghlInfo, const char *boneName);
|
||||
void G2API_AnimateG2Models(CGhoul2Info_v &ghoul2, float speedVar);
|
||||
qboolean G2API_RemoveBolt(CGhoul2Info *ghlInfo, const int index);
|
||||
int G2API_AddBolt(CGhoul2Info_v &ghoul2, const int modelIndex, const char *boneName);
|
||||
int G2API_AddBoltSurfNum(CGhoul2Info *ghlInfo, const int surfIndex);
|
||||
void G2API_SetBoltInfo(CGhoul2Info_v &ghoul2, int modelIndex, int boltInfo);
|
||||
qboolean G2API_AttachG2Model(CGhoul2Info_v &ghoul2From, int modelFrom, CGhoul2Info_v &ghoul2To, int toBoltIndex, int toModel);
|
||||
qboolean G2API_DetachG2Model(CGhoul2Info *ghlInfo);
|
||||
qboolean G2API_AttachEnt(int *boltInfo, CGhoul2Info *ghlInfoTo, int toBoltIndex, int entNum, int toModelNum);
|
||||
void G2API_DetachEnt(int *boltInfo);
|
||||
|
||||
qboolean G2API_GetBoltMatrix(CGhoul2Info_v &ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix,
|
||||
const vec3_t angles, const vec3_t position, const int frameNum, qhandle_t *modelList, vec3_t scale);
|
||||
|
||||
void G2API_ListSurfaces(CGhoul2Info *ghlInfo);
|
||||
void G2API_ListBones(CGhoul2Info *ghlInfo, int frame);
|
||||
qboolean G2API_HaveWeGhoul2Models(CGhoul2Info_v &ghoul2);
|
||||
void G2API_SetGhoul2ModelIndexes(CGhoul2Info_v &ghoul2, qhandle_t *modelList, qhandle_t *skinList);
|
||||
qboolean G2API_SetGhoul2ModelFlags(CGhoul2Info *ghlInfo, const int flags);
|
||||
int G2API_GetGhoul2ModelFlags(CGhoul2Info *ghlInfo);
|
||||
|
||||
qboolean G2API_GetAnimFileName(CGhoul2Info *ghlInfo, char **filename);
|
||||
void G2API_CollisionDetect(CollisionRecord_t *collRecMap, CGhoul2Info_v &ghoul2, const vec3_t angles, const vec3_t position,
|
||||
int frameNumber, int entNum, vec3_t rayStart, vec3_t rayEnd, vec3_t scale, CMiniHeap *G2VertSpace, int traceFlags, int useLod, float fRadius);
|
||||
|
||||
void G2API_GiveMeVectorFromMatrix(mdxaBone_t *boltMatrix, Eorientations flags, vec3_t vec);
|
||||
int G2API_CopyGhoul2Instance(CGhoul2Info_v &g2From, CGhoul2Info_v &g2To, int modelIndex);
|
||||
void G2API_CleanGhoul2Models(CGhoul2Info_v **ghoul2Ptr);
|
||||
int G2API_GetParentSurface(CGhoul2Info *ghlInfo, const int index);
|
||||
int G2API_GetSurfaceIndex(CGhoul2Info *ghlInfo, const char *surfaceName);
|
||||
char *G2API_GetSurfaceName(CGhoul2Info *ghlInfo, int surfNumber);
|
||||
char *G2API_GetGLAName(CGhoul2Info_v &ghoul2, int modelIndex);
|
||||
char *G2API_GetGLMName(void *pGhoul2, int modelIndex);
|
||||
qboolean G2API_SetBoneAnglesMatrix(CGhoul2Info *ghlInfo, const char *boneName, const mdxaBone_t &matrix, const int flags,
|
||||
qhandle_t *modelList, int blendTime = 0, int currentTime = 0);
|
||||
qboolean G2API_SetNewOrigin(CGhoul2Info_v &ghoul2, const int boltIndex);
|
||||
int G2API_GetBoneIndex(CGhoul2Info *ghlInfo, const char *boneName);
|
||||
qboolean G2API_StopBoneAnglesIndex(CGhoul2Info *ghlInfo, const int index);
|
||||
qboolean G2API_StopBoneAnimIndex(CGhoul2Info *ghlInfo, const int index);
|
||||
qboolean G2API_SetBoneAnglesIndex(CGhoul2Info *ghlInfo, const int index, const vec3_t angles, const int flags,
|
||||
const int yaw, const int pitch, const int roll,
|
||||
qhandle_t *modelList, int blendTime, int currentTime);
|
||||
qboolean G2API_SetBoneAnglesMatrixIndex(CGhoul2Info *ghlInfo, const int index, const mdxaBone_t &matrix,
|
||||
const int flags, qhandle_t *modelList, int blendTime, int currentTime);
|
||||
qboolean G2API_DoesBoneExist(CGhoul2Info *ghlInfo, const char *boneName);
|
||||
qboolean G2API_SetBoneAnimIndex(CGhoul2Info *ghlInfo, const int index, const int startFrame, const int endFrame, const int flags, const float animSpeed, const int currentTime, const float setFrame, const int blendTime);
|
||||
qboolean G2API_SaveGhoul2Models(CGhoul2Info_v &ghoul2, char **buffer, int *size);
|
||||
void G2API_LoadGhoul2Models(CGhoul2Info_v &ghoul2, char *buffer);
|
||||
void G2API_LoadSaveCodeDestructGhoul2Info(CGhoul2Info_v &ghoul2);
|
||||
void G2API_FreeSaveBuffer(char *buffer);
|
||||
char *G2API_GetAnimFileNameIndex(qhandle_t modelIndex);
|
||||
int G2API_GetSurfaceRenderStatus(CGhoul2Info *ghlInfo, const char *surfaceName);
|
||||
void G2API_CopySpecificG2Model(CGhoul2Info_v &ghoul2From, int modelFrom, CGhoul2Info_v &ghoul2To, int modelTo);
|
||||
void G2API_DuplicateGhoul2Instance(CGhoul2Info_v &g2From, CGhoul2Info_v **g2To);
|
||||
void G2API_SetBoltInfo(CGhoul2Info_v &ghoul2, int modelIndex, int boltInfo);
|
||||
|
||||
class CRagDollUpdateParams;
|
||||
class CRagDollParams;
|
||||
|
||||
void G2API_AbsurdSmoothing(CGhoul2Info_v &ghoul2, qboolean status);
|
||||
|
||||
void G2API_SetRagDoll(CGhoul2Info_v &ghoul2,CRagDollParams *parms);
|
||||
void G2API_ResetRagDoll(CGhoul2Info_v &ghoul2);
|
||||
void G2API_AnimateG2Models(CGhoul2Info_v &ghoul2, int AcurrentTime,CRagDollUpdateParams *params);
|
||||
|
||||
qboolean G2API_RagPCJConstraint(CGhoul2Info_v &ghoul2, const char *boneName, vec3_t min, vec3_t max);
|
||||
qboolean G2API_RagPCJGradientSpeed(CGhoul2Info_v &ghoul2, const char *boneName, const float speed);
|
||||
qboolean G2API_RagEffectorGoal(CGhoul2Info_v &ghoul2, const char *boneName, vec3_t pos);
|
||||
qboolean G2API_GetRagBonePos(CGhoul2Info_v &ghoul2, const char *boneName, vec3_t pos, vec3_t entAngles, vec3_t entPos, vec3_t entScale);
|
||||
qboolean G2API_RagEffectorKick(CGhoul2Info_v &ghoul2, const char *boneName, vec3_t velocity);
|
||||
qboolean G2API_RagForceSolve(CGhoul2Info_v &ghoul2, qboolean force);
|
||||
|
||||
qboolean G2API_SetBoneIKState(CGhoul2Info_v &ghoul2, int time, const char *boneName, int ikState, sharedSetBoneIKStateParams_t *params);
|
||||
qboolean G2API_IKMove(CGhoul2Info_v &ghoul2, int time, sharedIKMoveParams_t *params);
|
||||
|
||||
void G2API_AttachInstanceToEntNum(CGhoul2Info_v &ghoul2, int entityNum, qboolean server);
|
||||
void G2API_ClearAttachedInstance(int entityNum);
|
||||
void G2API_CleanEntAttachments(void);
|
||||
qboolean G2API_OverrideServerWithClientData(CGhoul2Info *serverInstance);
|
||||
|
||||
extern qboolean gG2_GBMNoReconstruct;
|
||||
extern qboolean gG2_GBMUseSPMethod;
|
||||
// From tr_ghoul2.cpp
|
||||
void G2_ConstructGhoulSkeleton( CGhoul2Info_v &ghoul2,const int frameNum,bool checkForNewOrigin,const vec3_t scale);
|
||||
|
||||
qboolean G2API_SkinlessModel(CGhoul2Info *g2);
|
||||
|
||||
#ifdef _G2_GORE
|
||||
int G2API_GetNumGoreMarks(CGhoul2Info *g2);
|
||||
void G2API_AddSkinGore(CGhoul2Info_v &ghoul2,SSkinGoreData &gore);
|
||||
void G2API_ClearSkinGore ( CGhoul2Info_v &ghoul2 );
|
||||
#endif // _SOF2
|
||||
|
||||
int G2API_Ghoul2Size ( CGhoul2Info_v &ghoul2 );
|
||||
|
||||
1926
codemp/ghoul2/g2_misc.cpp
Normal file
1926
codemp/ghoul2/g2_misc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
677
codemp/ghoul2/g2_surfaces.cpp
Normal file
677
codemp/ghoul2/g2_surfaces.cpp
Normal file
@@ -0,0 +1,677 @@
|
||||
// leave this as first line for PCH reasons...
|
||||
//
|
||||
|
||||
//Anything above this #include will be ignored by the compiler
|
||||
#include "../qcommon/exe_headers.h"
|
||||
|
||||
|
||||
#if !defined(TR_LOCAL_H)
|
||||
#include "../renderer/tr_local.h"
|
||||
#endif
|
||||
|
||||
#if !defined(G2_H_INC)
|
||||
#include "G2.h"
|
||||
#endif
|
||||
#include "G2_local.h"
|
||||
#pragma warning(disable : 4512) //assignment op could not be genereated
|
||||
|
||||
class CConstructBoneList
|
||||
{
|
||||
public:
|
||||
int surfaceNum;
|
||||
int *boneUsedList;
|
||||
surfaceInfo_v &rootSList;
|
||||
model_t *currentModel;
|
||||
boneInfo_v &boneList;
|
||||
|
||||
CConstructBoneList(
|
||||
int initsurfaceNum,
|
||||
int *initboneUsedList,
|
||||
surfaceInfo_v &initrootSList,
|
||||
model_t *initcurrentModel,
|
||||
boneInfo_v &initboneList):
|
||||
|
||||
surfaceNum(initsurfaceNum),
|
||||
boneUsedList(initboneUsedList),
|
||||
rootSList(initrootSList),
|
||||
currentModel(initcurrentModel),
|
||||
boneList(initboneList) { }
|
||||
};
|
||||
|
||||
extern void G2_ConstructUsedBoneList(CConstructBoneList &CBL);
|
||||
|
||||
|
||||
//=====================================================================================================================
|
||||
// Surface List handling routines - so entities can determine what surfaces attached to a model are operational or not.
|
||||
|
||||
// find a particular surface in the surface override list
|
||||
surfaceInfo_t *G2_FindOverrideSurface(int surfaceNum, surfaceInfo_v &surfaceList)
|
||||
{
|
||||
int i;
|
||||
|
||||
// look through entire list
|
||||
for(i=0; i<surfaceList.size(); i++)
|
||||
{
|
||||
if (surfaceList[i].surface == surfaceNum)
|
||||
{
|
||||
return &surfaceList[i];
|
||||
}
|
||||
}
|
||||
// didn't find it.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// given a surface name, lets see if it's legal in the model
|
||||
int G2_IsSurfaceLegal(void *mod, const char *surfaceName, int *flags)
|
||||
{
|
||||
// damn include file dependancies
|
||||
mdxmSurfHierarchy_t *surf;
|
||||
model_t *mod_m = (model_t *)mod;
|
||||
surf = (mdxmSurfHierarchy_t *) ( (byte *)mod_m->mdxm + mod_m->mdxm->ofsSurfHierarchy );
|
||||
|
||||
for ( int i = 0 ; i < mod_m->mdxm->numSurfaces ; i++)
|
||||
{
|
||||
if (!stricmp(surfaceName, surf->name))
|
||||
{
|
||||
*flags = surf->flags;
|
||||
return i;
|
||||
}
|
||||
// find the next surface
|
||||
surf = (mdxmSurfHierarchy_t *)( (byte *)surf + (int)( &((mdxmSurfHierarchy_t *)0)->childIndexes[ surf->numChildren ] ));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* G2_FindSurface
|
||||
* find a surface in a ghoul2 surface override list based on it's name
|
||||
*
|
||||
* Input
|
||||
* filename of model, surface list of model instance, name of surface, int to be filled in
|
||||
* with the index of this surface (defaults to NULL)
|
||||
*
|
||||
* Output
|
||||
* pointer to surface if successful, false otherwise
|
||||
*
|
||||
************************************************************************************************/
|
||||
mdxmSurface_t *G2_FindSurface(CGhoul2Info *ghlInfo, surfaceInfo_v &slist, const char *surfaceName,
|
||||
int *surfIndex/*NULL*/)
|
||||
{
|
||||
int i = 0;
|
||||
// find the model we want
|
||||
model_t *mod = (model_t *)ghlInfo->currentModel;
|
||||
mdxmHierarchyOffsets_t *surfIndexes = (mdxmHierarchyOffsets_t *)((byte *)mod->mdxm + sizeof(mdxmHeader_t));
|
||||
mdxmSurfHierarchy_t *surfInfo;
|
||||
|
||||
// did we find a ghoul 2 model or not?
|
||||
if (!mod->mdxm)
|
||||
{
|
||||
assert(0);
|
||||
if (surfIndex)
|
||||
{
|
||||
*surfIndex = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// first find if we already have this surface in the list
|
||||
for (i = slist.size() - 1; i >= 0; i--)
|
||||
{
|
||||
if ((slist[i].surface != 10000) && (slist[i].surface != -1))
|
||||
{
|
||||
mdxmSurface_t *surf = (mdxmSurface_t *)G2_FindSurface((void *)mod, slist[i].surface, 0);
|
||||
// back track and get the surfinfo struct for this surface
|
||||
surfInfo = (mdxmSurfHierarchy_t *)((byte *)surfIndexes + surfIndexes->offsets[surf->thisSurfaceIndex]);
|
||||
|
||||
// are these the droids we're looking for?
|
||||
if (!stricmp (surfInfo->name, surfaceName))
|
||||
{
|
||||
// yup
|
||||
if (surfIndex)
|
||||
{
|
||||
*surfIndex = i;
|
||||
}
|
||||
return surf;
|
||||
}
|
||||
}
|
||||
}
|
||||
// didn't find it
|
||||
if (surfIndex)
|
||||
{
|
||||
*surfIndex = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set a named surface offFlags - if it doesn't find a surface with this name in the list then it will add one.
|
||||
qboolean G2_SetSurfaceOnOff (CGhoul2Info *ghlInfo, surfaceInfo_v &slist, const char *surfaceName, const int offFlags)
|
||||
{
|
||||
int surfIndex = -1;
|
||||
surfaceInfo_t temp_slist_entry;
|
||||
mdxmSurface_t *surf;
|
||||
// find the model we want
|
||||
model_t *mod = (model_t *)ghlInfo->currentModel;
|
||||
|
||||
// did we find a ghoul 2 model or not?
|
||||
if (!mod->mdxm)
|
||||
{
|
||||
assert(0);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// first find if we already have this surface in the list
|
||||
surf = G2_FindSurface(ghlInfo, slist, surfaceName, &surfIndex);
|
||||
if (surf)
|
||||
{
|
||||
// set descendants value
|
||||
|
||||
// slist[surfIndex].offFlags = offFlags;
|
||||
// seems to me that we shouldn't overwrite the other flags.
|
||||
// the only bit we really care about in the incoming flags is the off bit
|
||||
slist[surfIndex].offFlags &= ~(G2SURFACEFLAG_OFF | G2SURFACEFLAG_NODESCENDANTS);
|
||||
slist[surfIndex].offFlags |= offFlags & (G2SURFACEFLAG_OFF | G2SURFACEFLAG_NODESCENDANTS);
|
||||
return qtrue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ok, not in the list already - in that case, lets verify this surface exists in the model mesh
|
||||
int flags;
|
||||
int surfaceNum = G2_IsSurfaceLegal((void*)mod, surfaceName, &flags);
|
||||
if (surfaceNum != -1)
|
||||
{
|
||||
int newflags = flags;
|
||||
// the only bit we really care about in the incoming flags is the off bit
|
||||
newflags &= ~(G2SURFACEFLAG_OFF | G2SURFACEFLAG_NODESCENDANTS);
|
||||
newflags |= offFlags & (G2SURFACEFLAG_OFF | G2SURFACEFLAG_NODESCENDANTS);
|
||||
|
||||
if (newflags != flags)
|
||||
{ // insert here then because it changed, no need to add an override otherwise
|
||||
temp_slist_entry.offFlags = newflags;
|
||||
temp_slist_entry.surface = surfaceNum;
|
||||
|
||||
slist.push_back(temp_slist_entry);
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void G2_SetSurfaceOnOffFromSkin (CGhoul2Info *ghlInfo, qhandle_t renderSkin)
|
||||
{
|
||||
int j;
|
||||
const skin_t *skin = R_GetSkinByHandle( renderSkin );
|
||||
|
||||
ghlInfo->mSlist.clear(); //remove any overrides we had before.
|
||||
ghlInfo->mMeshFrameNum = 0;
|
||||
|
||||
for ( j = 0 ; j < skin->numSurfaces ; j++ )
|
||||
{
|
||||
// the names have both been lowercased
|
||||
if ( !strcmp( skin->surfaces[j]->shader->name , "*off") )
|
||||
{
|
||||
G2_SetSurfaceOnOff(ghlInfo, ghlInfo->mSlist, skin->surfaces[j]->name, G2SURFACEFLAG_OFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
int flags;
|
||||
int surfaceNum = G2_IsSurfaceLegal((void *)ghlInfo->currentModel, skin->surfaces[j]->name, &flags);
|
||||
if ( (surfaceNum != -1) && (!(flags&G2SURFACEFLAG_OFF)) ) //only turn on if it's not an "_off" surface
|
||||
{
|
||||
G2_SetSurfaceOnOff(ghlInfo, ghlInfo->mSlist, skin->surfaces[j]->name, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return a named surfaces off flags - should tell you if this surface is on or off.
|
||||
int G2_IsSurfaceOff (CGhoul2Info *ghlInfo, surfaceInfo_v &slist, const char *surfaceName)
|
||||
{
|
||||
model_t *mod = (model_t *)ghlInfo->currentModel;
|
||||
int surfIndex = -1;
|
||||
mdxmSurface_t *surf = 0;
|
||||
|
||||
// did we find a ghoul 2 model or not?
|
||||
if (!mod->mdxm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// first find if we already have this surface in the list
|
||||
surf = G2_FindSurface(ghlInfo, slist, surfaceName, &surfIndex);
|
||||
if (surf)
|
||||
{
|
||||
// set descendants value
|
||||
return slist[surfIndex].offFlags;
|
||||
}
|
||||
// ok, we didn't find it in the surface list. Lets look at the original surface then.
|
||||
|
||||
mdxmSurfHierarchy_t *surface = (mdxmSurfHierarchy_t *) ( (byte *)mod->mdxm + mod->mdxm->ofsSurfHierarchy );
|
||||
|
||||
for ( int i = 0 ; i < mod->mdxm->numSurfaces ; i++)
|
||||
{
|
||||
if (!stricmp(surfaceName, surface->name))
|
||||
{
|
||||
return surface->flags;
|
||||
}
|
||||
// find the next surface
|
||||
surface = (mdxmSurfHierarchy_t *)( (byte *)surface + (int)( &((mdxmSurfHierarchy_t *)0)->childIndexes[ surface->numChildren ] ));
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void G2_FindRecursiveSurface(model_t *currentModel, int surfaceNum, surfaceInfo_v &rootList, int *activeSurfaces)
|
||||
{
|
||||
int i;
|
||||
mdxmSurface_t *surface = (mdxmSurface_t *)G2_FindSurface((void *)currentModel, surfaceNum, 0);
|
||||
mdxmHierarchyOffsets_t *surfIndexes = (mdxmHierarchyOffsets_t *)((byte *)currentModel->mdxm + sizeof(mdxmHeader_t));
|
||||
mdxmSurfHierarchy_t *surfInfo = (mdxmSurfHierarchy_t *)((byte *)surfIndexes + surfIndexes->offsets[surface->thisSurfaceIndex]);
|
||||
|
||||
// see if we have an override surface in the surface list
|
||||
surfaceInfo_t *surfOverride = G2_FindOverrideSurface(surfaceNum, rootList);
|
||||
|
||||
// really, we should use the default flags for this surface unless it's been overriden
|
||||
int offFlags = surfInfo->flags;
|
||||
|
||||
// set the off flags if we have some
|
||||
if (surfOverride)
|
||||
{
|
||||
offFlags = surfOverride->offFlags;
|
||||
}
|
||||
|
||||
// if this surface is not off, indicate as such in the active surface list
|
||||
if (!(offFlags & G2SURFACEFLAG_OFF))
|
||||
{
|
||||
activeSurfaces[surfaceNum] = 1;
|
||||
}
|
||||
else
|
||||
// if we are turning off all descendants, then stop this recursion now
|
||||
if (offFlags & G2SURFACEFLAG_NODESCENDANTS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// now recursively call for the children
|
||||
for (i=0; i< surfInfo->numChildren; i++)
|
||||
{
|
||||
surfaceNum = surfInfo->childIndexes[i];
|
||||
G2_FindRecursiveSurface(currentModel, surfaceNum, rootList, activeSurfaces);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void G2_RemoveRedundantGeneratedSurfaces(surfaceInfo_v &slist, int *activeSurfaces)
|
||||
{
|
||||
int i;
|
||||
|
||||
// walk the surface list, removing surface overrides or generated surfaces that are pointing at surfaces that aren't active anymore
|
||||
for (i=0; i<slist.size(); i++)
|
||||
{
|
||||
if (slist[i].surface != -1)
|
||||
{
|
||||
// is this a generated surface?
|
||||
if (slist[i].offFlags & G2SURFACEFLAG_GENERATED)
|
||||
{
|
||||
// if it's not in the list, remove it
|
||||
if (!activeSurfaces[slist[i].genPolySurfaceIndex & 0xffff])
|
||||
{
|
||||
G2_RemoveSurface(slist, i);
|
||||
}
|
||||
}
|
||||
// no, so it does point back at a legal surface
|
||||
else
|
||||
{
|
||||
// if it's not in the list, remove it
|
||||
if (!activeSurfaces[slist[i].surface])
|
||||
{
|
||||
G2_RemoveSurface(slist, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qboolean G2_SetRootSurface(CGhoul2Info_v &ghoul2, const int modelIndex, const char *surfaceName)
|
||||
{
|
||||
int surf;
|
||||
int flags;
|
||||
int *activeSurfaces, *activeBones;
|
||||
|
||||
assert(ghoul2[modelIndex].currentModel && ghoul2[modelIndex].animModel);
|
||||
|
||||
model_t *mod_m = (model_t *)ghoul2[modelIndex].currentModel;
|
||||
model_t *mod_a = (model_t *)ghoul2[modelIndex].animModel;
|
||||
|
||||
// did we find a ghoul 2 model or not?
|
||||
if (!mod_m->mdxm)
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// first find if we already have this surface in the list
|
||||
surf = G2_IsSurfaceLegal(mod_m, surfaceName, &flags);
|
||||
if (surf != -1)
|
||||
{
|
||||
// first see if this ghoul2 model already has this as a root surface
|
||||
if (ghoul2[modelIndex].mSurfaceRoot == surf)
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
// set the root surface
|
||||
ghoul2[modelIndex].mSurfaceRoot = surf;
|
||||
|
||||
// ok, now the tricky bits.
|
||||
// firstly, generate a list of active / on surfaces below the root point
|
||||
|
||||
// gimme some space to put this list into
|
||||
activeSurfaces = (int *)Z_Malloc(mod_m->mdxm->numSurfaces * 4, TAG_GHOUL2, qtrue);
|
||||
memset(activeSurfaces, 0, (mod_m->mdxm->numSurfaces * 4));
|
||||
activeBones = (int *)Z_Malloc(mod_a->mdxa->numBones * 4, TAG_GHOUL2, qtrue);
|
||||
memset(activeBones, 0, (mod_a->mdxa->numBones * 4));
|
||||
|
||||
G2_FindRecursiveSurface(mod_m, surf, ghoul2[modelIndex].mSlist, activeSurfaces);
|
||||
|
||||
// now generate the used bone list
|
||||
CConstructBoneList CBL(ghoul2[modelIndex].mSurfaceRoot,
|
||||
activeBones,
|
||||
ghoul2[modelIndex].mSlist,
|
||||
mod_m,
|
||||
ghoul2[modelIndex].mBlist);
|
||||
|
||||
G2_ConstructUsedBoneList(CBL);
|
||||
|
||||
// now remove all procedural or override surfaces that refer to surfaces that arent on this list
|
||||
G2_RemoveRedundantGeneratedSurfaces(ghoul2[modelIndex].mSlist, activeSurfaces);
|
||||
|
||||
// now remove all bones that are pointing at bones that aren't active
|
||||
G2_RemoveRedundantBoneOverrides(ghoul2[modelIndex].mBlist, activeBones);
|
||||
|
||||
// then remove all bolts that point at surfaces or bones that *arent* active.
|
||||
G2_RemoveRedundantBolts(ghoul2[modelIndex].mBltlist, ghoul2[modelIndex].mSlist, activeSurfaces, activeBones);
|
||||
|
||||
// then remove all models on this ghoul2 instance that use those bolts that are being removed.
|
||||
for (int i=0; i<ghoul2.size(); i++)
|
||||
{
|
||||
// are we even bolted to anything?
|
||||
if (ghoul2[i].mModelBoltLink != -1)
|
||||
{
|
||||
int boltMod = (ghoul2[i].mModelBoltLink >> MODEL_SHIFT) & MODEL_AND;
|
||||
int boltNum = (ghoul2[i].mModelBoltLink >> BOLT_SHIFT) & BOLT_AND;
|
||||
// if either the bolt list is too small, or the bolt we are pointing at references nothing, remove this model
|
||||
if ((ghoul2[boltMod].mBltlist.size() <= boltNum) ||
|
||||
((ghoul2[boltMod].mBltlist[boltNum].boneNumber == -1) &&
|
||||
(ghoul2[boltMod].mBltlist[boltNum].surfaceNumber == -1)))
|
||||
{
|
||||
CGhoul2Info_v *g2i = &ghoul2;
|
||||
G2API_RemoveGhoul2Model((CGhoul2Info_v **)&g2i, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
//No support for this, for now.
|
||||
|
||||
// remember to free what we used
|
||||
Z_Free(activeSurfaces);
|
||||
Z_Free(activeBones);
|
||||
|
||||
return (qtrue);
|
||||
}
|
||||
/*
|
||||
//g2r if (entstate->ghoul2)
|
||||
{
|
||||
CGhoul2Info_v &ghoul2 = *((CGhoul2Info_v *)entstate->ghoul2);
|
||||
model_t *mod_m = R_GetModelByHandle(RE_RegisterModel(ghoul2[modelIndex].mFileName));
|
||||
model_t *mod_a = R_GetModelByHandle(mod_m->mdxm->animIndex);
|
||||
int surf;
|
||||
int flags;
|
||||
int *activeSurfaces, *activeBones;
|
||||
|
||||
// did we find a ghoul 2 model or not?
|
||||
if (!mod_m->mdxm)
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// first find if we already have this surface in the list
|
||||
surf = G2_IsSurfaceLegal(mod_m, surfaceName, &flags);
|
||||
if (surf != -1)
|
||||
{
|
||||
// first see if this ghoul2 model already has this as a root surface
|
||||
if (ghoul2[modelIndex].mSurfaceRoot == surf)
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
// set the root surface
|
||||
ghoul2[modelIndex].mSurfaceRoot = surf;
|
||||
|
||||
// ok, now the tricky bits.
|
||||
// firstly, generate a list of active / on surfaces below the root point
|
||||
|
||||
// gimme some space to put this list into
|
||||
activeSurfaces = (int *)Z_Malloc(mod_m->mdxm->numSurfaces * 4, TAG_GHOUL2, qtrue);
|
||||
memset(activeSurfaces, 0, (mod_m->mdxm->numSurfaces * 4));
|
||||
activeBones = (int *)Z_Malloc(mod_a->mdxa->numBones * 4, TAG_GHOUL2, qtrue);
|
||||
memset(activeBones, 0, (mod_a->mdxa->numBones * 4));
|
||||
|
||||
G2_FindRecursiveSurface(mod_m, surf, ghoul2[modelIndex].mSlist, activeSurfaces);
|
||||
|
||||
// now generate the used bone list
|
||||
CConstructBoneList CBL(ghoul2[modelIndex].mSurfaceRoot,
|
||||
activeBones,
|
||||
ghoul2[modelIndex].mSlist,
|
||||
mod_m,
|
||||
ghoul2[modelIndex].mBlist);
|
||||
|
||||
G2_ConstructUsedBoneList(CBL);
|
||||
|
||||
// now remove all procedural or override surfaces that refer to surfaces that arent on this list
|
||||
G2_RemoveRedundantGeneratedSurfaces(ghoul2[modelIndex].mSlist, activeSurfaces);
|
||||
|
||||
// now remove all bones that are pointing at bones that aren't active
|
||||
G2_RemoveRedundantBoneOverrides(ghoul2[modelIndex].mBlist, activeBones);
|
||||
|
||||
// then remove all bolts that point at surfaces or bones that *arent* active.
|
||||
G2_RemoveRedundantBolts(ghoul2[modelIndex].mBltlist, ghoul2[modelIndex].mSlist, activeSurfaces, activeBones);
|
||||
|
||||
// then remove all models on this ghoul2 instance that use those bolts that are being removed.
|
||||
for (int i=0; i<ghoul2.size(); i++)
|
||||
{
|
||||
// are we even bolted to anything?
|
||||
if (ghoul2[i].mModelBoltLink != -1)
|
||||
{
|
||||
int boltMod = (ghoul2[i].mModelBoltLink >> MODEL_SHIFT) & MODEL_AND;
|
||||
int boltNum = (ghoul2[i].mModelBoltLink >> BOLT_SHIFT) & BOLT_AND;
|
||||
// if either the bolt list is too small, or the bolt we are pointing at references nothing, remove this model
|
||||
if ((ghoul2[boltMod].mBltlist.size() <= boltNum) ||
|
||||
((ghoul2[boltMod].mBltlist[boltNum].boneNumber == -1) &&
|
||||
(ghoul2[boltMod].mBltlist[boltNum].surfaceNumber == -1)))
|
||||
{
|
||||
G2API_RemoveGhoul2Model(entstate, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remember to free what we used
|
||||
Z_Free(activeSurfaces);
|
||||
Z_Free(activeBones);
|
||||
|
||||
return (qtrue);
|
||||
}
|
||||
}
|
||||
assert(0);*/
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
extern int G2_DecideTraceLod(CGhoul2Info &ghoul2, int useLod);
|
||||
int G2_AddSurface(CGhoul2Info *ghoul2, int surfaceNumber, int polyNumber, float BarycentricI, float BarycentricJ, int lod )
|
||||
{
|
||||
|
||||
surfaceInfo_t temp_slist_entry;
|
||||
|
||||
// decide if LOD is legal
|
||||
lod = G2_DecideTraceLod(*(CGhoul2Info *)(ghoul2), lod);
|
||||
|
||||
// first up, see if we have a free one already set up - look only from the end of the constant surfaces onwards
|
||||
for (int i=0; i<ghoul2->mSlist.size(); i++)
|
||||
{
|
||||
// is the surface count -1? That would indicate it's free
|
||||
if (ghoul2->mSlist[i].surface == -1)
|
||||
{
|
||||
ghoul2->mSlist[i].offFlags = G2SURFACEFLAG_GENERATED;
|
||||
ghoul2->mSlist[i].surface = 10000; // no model will ever have 10000 surfaces
|
||||
ghoul2->mSlist[i].genBarycentricI = BarycentricI;
|
||||
ghoul2->mSlist[i].genBarycentricJ = BarycentricJ;
|
||||
ghoul2->mSlist[i].genPolySurfaceIndex = ((polyNumber & 0xffff) << 16) | (surfaceNumber & 0xffff);
|
||||
ghoul2->mSlist[i].genLod = lod;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// ok, didn't find one. Better create one
|
||||
|
||||
temp_slist_entry.offFlags = G2SURFACEFLAG_GENERATED;
|
||||
temp_slist_entry.surface = 10000;
|
||||
temp_slist_entry.genBarycentricI = BarycentricI;
|
||||
temp_slist_entry.genBarycentricJ = BarycentricJ;
|
||||
temp_slist_entry.genPolySurfaceIndex = ((polyNumber & 0xffff) << 16) | (surfaceNumber & 0xffff);
|
||||
temp_slist_entry.genLod = lod;
|
||||
|
||||
ghoul2->mSlist.push_back(temp_slist_entry);
|
||||
|
||||
return (ghoul2->mSlist.size() -1 );
|
||||
}
|
||||
|
||||
qboolean G2_RemoveSurface(surfaceInfo_v &slist, const int index)
|
||||
{
|
||||
// did we find it?
|
||||
if (index != -1)
|
||||
{
|
||||
// set us to be the 'not active' state
|
||||
slist[index].surface = -1;
|
||||
|
||||
unsigned int newSize = slist.size();
|
||||
// now look through the list from the back and see if there is a block of -1's we can resize off the end of the list
|
||||
for (int i=slist.size()-1; i>-1; i--)
|
||||
{
|
||||
if (slist[i].surface == -1)
|
||||
{
|
||||
newSize = i;
|
||||
}
|
||||
// once we hit one that isn't a -1, we are done.
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
// do we need to resize?
|
||||
if (newSize != slist.size())
|
||||
{
|
||||
// yes, so lets do it
|
||||
slist.resize(newSize);
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
|
||||
// no
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
int G2_GetParentSurface(CGhoul2Info *ghlInfo, const int index)
|
||||
{
|
||||
model_t *mod = (model_t *)ghlInfo->currentModel;
|
||||
mdxmSurface_t *surf = 0;
|
||||
mdxmHierarchyOffsets_t *surfIndexes = (mdxmHierarchyOffsets_t *)((byte *)mod->mdxm + sizeof(mdxmHeader_t));
|
||||
mdxmSurfHierarchy_t *surfInfo = 0;
|
||||
|
||||
// walk each surface and see if this index is listed in it's children
|
||||
surf = (mdxmSurface_t *)G2_FindSurface((void *)mod, index, 0);
|
||||
surfInfo = (mdxmSurfHierarchy_t *)((byte *)surfIndexes + surfIndexes->offsets[surf->thisSurfaceIndex]);
|
||||
|
||||
return surfInfo->parentIndex;
|
||||
|
||||
}
|
||||
|
||||
int G2_GetSurfaceIndex(CGhoul2Info *ghlInfo, const char *surfaceName)
|
||||
{
|
||||
model_t *mod = (model_t *)ghlInfo->currentModel;
|
||||
int flags;
|
||||
|
||||
return G2_IsSurfaceLegal(mod, surfaceName, &flags);
|
||||
}
|
||||
|
||||
int G2_IsSurfaceRendered(CGhoul2Info *ghlInfo, const char *surfaceName, surfaceInfo_v &slist)
|
||||
{
|
||||
int flags = 0;//, surfFlags = 0;
|
||||
int surfIndex = 0;
|
||||
assert(ghlInfo->currentModel);
|
||||
assert(ghlInfo->currentModel->mdxm);
|
||||
if (!ghlInfo->currentModel->mdxm)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// now travel up the skeleton to see if any of it's ancestors have a 'no descendants' turned on
|
||||
|
||||
// find the original surface in the surface list
|
||||
int surfNum = G2_IsSurfaceLegal((model_t *)ghlInfo->currentModel, surfaceName, &flags);
|
||||
if ( surfNum != -1 )
|
||||
{//must be legal
|
||||
const mdxmHierarchyOffsets_t *surfIndexes = (mdxmHierarchyOffsets_t *)((byte *)ghlInfo->currentModel->mdxm + sizeof(mdxmHeader_t));
|
||||
const mdxmSurfHierarchy_t *surfInfo = (mdxmSurfHierarchy_t *)((byte *)surfIndexes + surfIndexes->offsets[surfNum]);
|
||||
surfNum = surfInfo->parentIndex;
|
||||
// walk the surface hierarchy up until we hit the root
|
||||
while (surfNum != -1)
|
||||
{
|
||||
const mdxmSurface_t *parentSurf;
|
||||
int parentFlags;
|
||||
const mdxmSurfHierarchy_t *parentSurfInfo;
|
||||
|
||||
parentSurfInfo = (mdxmSurfHierarchy_t *)((byte *)surfIndexes + surfIndexes->offsets[surfNum]);
|
||||
|
||||
// find the original surface in the surface list
|
||||
//G2 was bug, above comment was accurate, but we don't want the original flags, we want the parent flags
|
||||
G2_IsSurfaceLegal((model_t *)ghlInfo->currentModel, parentSurfInfo->name, &parentFlags);
|
||||
|
||||
// now see if we already have overriden this surface in the slist
|
||||
parentSurf = G2_FindSurface(ghlInfo, slist, parentSurfInfo->name, &surfIndex);
|
||||
if (parentSurf)
|
||||
{
|
||||
// set descendants value
|
||||
parentFlags = slist[surfIndex].offFlags;
|
||||
}
|
||||
// now we have the parent flags, lets see if any have the 'no descendants' flag set
|
||||
if (parentFlags & G2SURFACEFLAG_NODESCENDANTS)
|
||||
{
|
||||
flags |= G2SURFACEFLAG_OFF;
|
||||
break;
|
||||
}
|
||||
// set up scan of next parent
|
||||
surfNum = parentSurfInfo->parentIndex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if ( flags == 0 )
|
||||
{//it's not being overridden by a parent
|
||||
// now see if we already have overriden this surface in the slist
|
||||
const mdxmSurface_t *surf = G2_FindSurface(ghlInfo, slist, surfaceName, &surfIndex);
|
||||
if (surf)
|
||||
{
|
||||
// set descendants value
|
||||
flags = slist[surfIndex].offFlags;
|
||||
}
|
||||
// ok, at this point in flags we have what this surface is set to, and the index of the surface itself
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
472
codemp/ghoul2/ghoul2_shared.h
Normal file
472
codemp/ghoul2/ghoul2_shared.h
Normal file
@@ -0,0 +1,472 @@
|
||||
#if defined (_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
#if !defined(GHOUL2_SHARED_H_INC)
|
||||
#define GHOUL2_SHARED_H_INC
|
||||
|
||||
/*
|
||||
Ghoul2 Insert Start
|
||||
*/
|
||||
#pragma warning (push, 3) //go back down to 3 for the stl include
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#pragma warning (pop)
|
||||
using namespace std;
|
||||
/*
|
||||
Ghoul2 Insert End
|
||||
*/
|
||||
|
||||
#define MDXABONEDEF
|
||||
#include "../renderer/mdx_format.h"
|
||||
|
||||
struct model_s;
|
||||
|
||||
//rww - RAGDOLL_BEGIN
|
||||
#define G2T_SV_TIME (0)
|
||||
#define G2T_CG_TIME (1)
|
||||
#define NUM_G2T_TIME (2)
|
||||
|
||||
void G2API_SetTime(int currentTime,int clock);
|
||||
int G2API_GetTime(int argTime); // this may or may not return arg depending on ghoul2_time cvar
|
||||
//rww - RAGDOLL_END
|
||||
|
||||
//===================================================================
|
||||
//
|
||||
// G H O U L I I D E F I N E S
|
||||
//
|
||||
// we save the whole surfaceInfo_t struct
|
||||
struct surfaceInfo_t
|
||||
{
|
||||
int offFlags; // what the flags are for this model
|
||||
int surface; // index into array held inside the model definition of pointers to the actual surface data loaded in - used by both client and game
|
||||
float genBarycentricJ; // point 0 barycentric coors
|
||||
float genBarycentricI; // point 1 barycentric coors - point 2 is 1 - point0 - point1
|
||||
int genPolySurfaceIndex; // used to point back to the original surface and poly if this is a generated surface
|
||||
int genLod; // used to determine original lod of original surface and poly hit location
|
||||
|
||||
surfaceInfo_t():
|
||||
offFlags(0),
|
||||
surface(0),
|
||||
genBarycentricJ(0),
|
||||
genBarycentricI(0),
|
||||
genPolySurfaceIndex(0),
|
||||
genLod(0)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define MDXABONEDEF // used in the mdxformat.h file to stop redefinitions of the bone struct.
|
||||
|
||||
// we save the whole structure here.
|
||||
struct boneInfo_t
|
||||
{
|
||||
int boneNumber; // what bone are we overriding?
|
||||
mdxaBone_t matrix; // details of bone angle overrides - some are pre-done on the server, some in ghoul2
|
||||
int flags; // flags for override
|
||||
int startFrame; // start frame for animation
|
||||
int endFrame; // end frame for animation NOTE anim actually ends on endFrame+1
|
||||
int startTime; // time we started this animation
|
||||
int pauseTime; // time we paused this animation - 0 if not paused
|
||||
float animSpeed; // speed at which this anim runs. 1.0f means full speed of animation incoming - ie if anim is 20hrtz, we run at 20hrts. If 5hrts, we run at 5 hrts
|
||||
float blendFrame; // frame PLUS LERP value to blend from
|
||||
int blendLerpFrame; // frame to lerp the blend frame with.
|
||||
int blendTime; // Duration time for blending - used to calc amount each frame of new anim is blended with last frame of the last anim
|
||||
int blendStart; // Time when blending starts - not necessarily the same as startTime since we might start half way through an anim
|
||||
int boneBlendTime; // time for duration of bone angle blend with normal animation
|
||||
int boneBlendStart; // time bone angle blend with normal animation began
|
||||
int lastTime; // this does not go across the network
|
||||
mdxaBone_t newMatrix; // This is the lerped matrix that Ghoul2 uses on the client side - does not go across the network
|
||||
|
||||
//rww - RAGDOLL_BEGIN
|
||||
int lastTimeUpdated; // if non-zero this is all intialized
|
||||
int lastContents;
|
||||
vec3_t lastPosition;
|
||||
vec3_t velocityEffector;
|
||||
vec3_t lastAngles;
|
||||
vec3_t minAngles;
|
||||
vec3_t maxAngles;
|
||||
vec3_t currentAngles;
|
||||
vec3_t anglesOffset;
|
||||
vec3_t positionOffset;
|
||||
float radius;
|
||||
float weight; // current radius cubed
|
||||
int ragIndex;
|
||||
vec3_t velocityRoot; // I am really tired of recomiling the whole game to add a param here
|
||||
int ragStartTime;
|
||||
int firstTime;
|
||||
int firstCollisionTime;
|
||||
int restTime;
|
||||
int RagFlags;
|
||||
int DependentRagIndexMask;
|
||||
mdxaBone_t originalTrueBoneMatrix;
|
||||
mdxaBone_t parentTrueBoneMatrix; // figure I will need this sooner or later
|
||||
mdxaBone_t parentOriginalTrueBoneMatrix; // figure I will need this sooner or later
|
||||
vec3_t originalOrigin;
|
||||
vec3_t originalAngles;
|
||||
vec3_t lastShotDir;
|
||||
mdxaBone_t *basepose;
|
||||
mdxaBone_t *baseposeInv;
|
||||
mdxaBone_t *baseposeParent;
|
||||
mdxaBone_t *baseposeInvParent;
|
||||
int parentRawBoneIndex;
|
||||
mdxaBone_t ragOverrideMatrix; // figure I will need this sooner or later
|
||||
|
||||
mdxaBone_t extraMatrix; // figure I will need this sooner or later
|
||||
vec3_t extraVec1; // I am really tired of recomiling the whole game to add a param here
|
||||
float extraFloat1;
|
||||
int extraInt1;
|
||||
|
||||
vec3_t ikPosition;
|
||||
float ikSpeed;
|
||||
|
||||
vec3_t epVelocity; //velocity factor, can be set, and is also maintained by physics based on gravity, mass, etc.
|
||||
float epGravFactor; //gravity factor maintained by bone physics
|
||||
int solidCount; //incremented every time we try to move and are in solid - if we get out of solid, it is reset to 0
|
||||
bool physicsSettled; //true when the bone is on ground and finished bouncing, etc. but may still be pushed into solid by other bones
|
||||
bool snapped; //the bone is broken out of standard constraints
|
||||
|
||||
int parentBoneIndex;
|
||||
|
||||
float offsetRotation;
|
||||
|
||||
//user api overrides
|
||||
float overGradSpeed;
|
||||
|
||||
vec3_t overGoalSpot;
|
||||
bool hasOverGoal;
|
||||
|
||||
mdxaBone_t animFrameMatrix; //matrix for the bone in the desired settling pose -rww
|
||||
int hasAnimFrameMatrix;
|
||||
|
||||
int airTime; //base is in air, be more quick and sensitive about collisions
|
||||
//rww - RAGDOLL_END
|
||||
|
||||
boneInfo_t():
|
||||
boneNumber(-1),
|
||||
flags(0),
|
||||
startFrame(0),
|
||||
endFrame(0),
|
||||
startTime(0),
|
||||
pauseTime(0),
|
||||
animSpeed(0),
|
||||
blendFrame(0),
|
||||
blendLerpFrame(0),
|
||||
blendTime(0),
|
||||
blendStart(0),
|
||||
boneBlendTime(0),
|
||||
boneBlendStart(0),
|
||||
lastTime(0),
|
||||
RagFlags(0)
|
||||
{
|
||||
matrix.matrix[0][0] = matrix.matrix[0][1] = matrix.matrix[0][2] = matrix.matrix[0][3] =
|
||||
matrix.matrix[1][0] = matrix.matrix[1][1] = matrix.matrix[1][2] = matrix.matrix[1][3] =
|
||||
matrix.matrix[2][0] = matrix.matrix[2][1] = matrix.matrix[2][2] = matrix.matrix[2][3] = 0.0f;
|
||||
}
|
||||
|
||||
};
|
||||
//we save from top to boltUsed here. Don't bother saving the position, it gets rebuilt every frame anyway
|
||||
struct boltInfo_t{
|
||||
int boneNumber; // bone number bolt attaches to
|
||||
int surfaceNumber; // surface number bolt attaches to
|
||||
int surfaceType; // if we attach to a surface, this tells us if it is an original surface or a generated one - doesn't go across the network
|
||||
int boltUsed; // nor does this
|
||||
mdxaBone_t position; // this does not go across the network
|
||||
boltInfo_t():
|
||||
boneNumber(-1),
|
||||
surfaceNumber(-1),
|
||||
surfaceType(0),
|
||||
boltUsed(0)
|
||||
{}
|
||||
};
|
||||
|
||||
#ifdef _SOF2
|
||||
typedef enum
|
||||
{
|
||||
PGORE_NONE,
|
||||
PGORE_ARMOR,
|
||||
PGORE_BULLETSMALL,
|
||||
PGORE_BULLETMED,
|
||||
PGORE_BULLETBIG,
|
||||
PGORE_HEGRENADE,
|
||||
PGORE_COUNT
|
||||
} goreEnum_t;
|
||||
|
||||
struct goreEnumShader_t
|
||||
{
|
||||
goreEnum_t shaderEnum;
|
||||
char shaderName[MAX_QPATH];
|
||||
};
|
||||
|
||||
struct SSkinGoreData
|
||||
{
|
||||
vec3_t angles;
|
||||
vec3_t position;
|
||||
int currentTime;
|
||||
int entNum;
|
||||
vec3_t rayDirection; // in world space
|
||||
vec3_t hitLocation; // in world space
|
||||
vec3_t scale;
|
||||
float SSize; // size of splotch in the S texture direction in world units
|
||||
float TSize; // size of splotch in the T texture direction in world units
|
||||
float theta; // angle to rotate the splotch
|
||||
|
||||
// qhandle_t shader; // handle to shader for gore, this better be rendered after the shader of the underlying surface
|
||||
// this shader should also have "clamp" mode, not tiled.
|
||||
goreEnum_t shaderEnum; // enum that'll get switched over to the shader's actual handle
|
||||
};
|
||||
#endif // _SOF2
|
||||
|
||||
#define MAX_GHOUL_COUNT_BITS 8 // bits required to send across the MAX_G2_MODELS inside of the networking - this is the only restriction on ghoul models possible per entity
|
||||
|
||||
typedef vector <surfaceInfo_t> surfaceInfo_v;
|
||||
typedef vector <boneInfo_t> boneInfo_v;
|
||||
typedef vector <boltInfo_t> boltInfo_v;
|
||||
typedef vector <pair<int,mdxaBone_t> > mdxaBone_v;
|
||||
|
||||
// defines for stuff to go into the mflags
|
||||
#define GHOUL2_NOCOLLIDE 0x001
|
||||
#define GHOUL2_NORENDER 0x002
|
||||
#define GHOUL2_NOMODEL 0x004
|
||||
#define GHOUL2_NEWORIGIN 0x008
|
||||
|
||||
class CBoneCache;
|
||||
|
||||
// NOTE order in here matters. We save out from mModelindex to mFlags, but not the STL vectors that are at the top or the bottom.
|
||||
class CGhoul2Info
|
||||
{
|
||||
public:
|
||||
surfaceInfo_v mSlist;
|
||||
boltInfo_v mBltlist;
|
||||
boneInfo_v mBlist;
|
||||
// save from here
|
||||
int mModelindex;
|
||||
qhandle_t mCustomShader;
|
||||
qhandle_t mCustomSkin;
|
||||
int mModelBoltLink;
|
||||
int mSurfaceRoot;
|
||||
int mLodBias;
|
||||
int mNewOrigin; // this contains the bolt index of the new origin for this model
|
||||
#ifdef _G2_GORE
|
||||
int mGoreSetTag;
|
||||
#endif
|
||||
qhandle_t mModel; // this and the next entries do NOT go across the network. They are for gameside access ONLY
|
||||
char mFileName[MAX_QPATH];
|
||||
int mAnimFrameDefault;
|
||||
int mSkelFrameNum;
|
||||
int mMeshFrameNum;
|
||||
int mFlags; // used for determining whether to do full collision detection against this object
|
||||
// to here
|
||||
int *mTransformedVertsArray; // used to create an array of pointers to transformed verts per surface for collision detection
|
||||
CBoneCache *mBoneCache;
|
||||
int mSkin;
|
||||
|
||||
// these occasionally are not valid (like after a vid_restart)
|
||||
// call the questionably efficient G2_SetupModelPointers(this) to insure validity
|
||||
bool mValid; // all the below are proper and valid
|
||||
const model_s *currentModel;
|
||||
int currentModelSize;
|
||||
const model_s *animModel;
|
||||
int currentAnimModelSize;
|
||||
const mdxaHeader_t *aHeader;
|
||||
|
||||
#ifdef _G2_LISTEN_SERVER_OPT
|
||||
int entityNum;
|
||||
#endif
|
||||
|
||||
CGhoul2Info():
|
||||
mModelindex(-1),
|
||||
mCustomShader(0),
|
||||
mCustomSkin(0),
|
||||
mModelBoltLink(0),
|
||||
mModel(0),
|
||||
mSurfaceRoot(0),
|
||||
mAnimFrameDefault(0),
|
||||
mSkelFrameNum(-1),
|
||||
mMeshFrameNum(-1),
|
||||
mFlags(0),
|
||||
mTransformedVertsArray(0),
|
||||
mLodBias(0),
|
||||
mSkin(0),
|
||||
mNewOrigin(-1),
|
||||
#ifdef _G2_GORE
|
||||
mGoreSetTag(0),
|
||||
#endif
|
||||
mBoneCache(0),
|
||||
currentModel(0),
|
||||
currentModelSize(0),
|
||||
animModel(0),
|
||||
currentAnimModelSize(0),
|
||||
aHeader(0),
|
||||
#ifdef _G2_LISTEN_SERVER_OPT
|
||||
entityNum(ENTITYNUM_NONE),
|
||||
#endif
|
||||
mValid(false)
|
||||
{
|
||||
mFileName[0] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class CGhoul2Info_v;
|
||||
|
||||
class IGhoul2InfoArray
|
||||
{
|
||||
public:
|
||||
virtual int New()=0;
|
||||
virtual void Delete(int handle)=0;
|
||||
virtual bool IsValid(int handle) const=0;
|
||||
virtual vector<CGhoul2Info> &Get(int handle)=0;
|
||||
virtual const vector<CGhoul2Info> &Get(int handle) const=0;
|
||||
};
|
||||
|
||||
IGhoul2InfoArray &TheGhoul2InfoArray();
|
||||
|
||||
class CGhoul2Info_v
|
||||
{
|
||||
IGhoul2InfoArray &InfoArray() const
|
||||
{
|
||||
return TheGhoul2InfoArray();
|
||||
}
|
||||
|
||||
void Alloc()
|
||||
{
|
||||
assert(!mItem); //already alloced
|
||||
mItem=InfoArray().New();
|
||||
assert(!Array().size());
|
||||
}
|
||||
void Free()
|
||||
{
|
||||
if (mItem)
|
||||
{
|
||||
assert(InfoArray().IsValid(mItem));
|
||||
InfoArray().Delete(mItem);
|
||||
mItem=0;
|
||||
}
|
||||
}
|
||||
vector<CGhoul2Info> &Array()
|
||||
{
|
||||
assert(InfoArray().IsValid(mItem));
|
||||
return InfoArray().Get(mItem);
|
||||
}
|
||||
const vector<CGhoul2Info> &Array() const
|
||||
{
|
||||
assert(InfoArray().IsValid(mItem));
|
||||
return InfoArray().Get(mItem);
|
||||
}
|
||||
public:
|
||||
int mItem; //dont' be bad and muck with this
|
||||
CGhoul2Info_v()
|
||||
{
|
||||
mItem=0;
|
||||
}
|
||||
CGhoul2Info_v(const int item)
|
||||
{ //be VERY carefull with what you pass in here
|
||||
mItem=item;
|
||||
}
|
||||
~CGhoul2Info_v()
|
||||
{
|
||||
Free(); //this had better be taken care of via the clean ghoul2 models call
|
||||
}
|
||||
void operator=(const CGhoul2Info_v &other)
|
||||
{
|
||||
mItem=other.mItem;
|
||||
}
|
||||
void operator=(const int otherItem) //assigning one from the VM side item number
|
||||
{
|
||||
mItem=otherItem;
|
||||
}
|
||||
void DeepCopy(const CGhoul2Info_v &other)
|
||||
{
|
||||
Free();
|
||||
if (other.mItem)
|
||||
{
|
||||
Alloc();
|
||||
Array()=other.Array();
|
||||
int i;
|
||||
for (i=0;i<size();i++)
|
||||
{
|
||||
Array()[i].mBoneCache=0;
|
||||
Array()[i].mTransformedVertsArray=0;
|
||||
Array()[i].mSkelFrameNum=0;
|
||||
Array()[i].mMeshFrameNum=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
CGhoul2Info &operator[](int idx)
|
||||
{
|
||||
assert(mItem);
|
||||
assert(idx>=0&&idx<size());
|
||||
return Array()[idx];
|
||||
}
|
||||
const CGhoul2Info &operator[](int idx) const
|
||||
{
|
||||
assert(mItem);
|
||||
assert(idx>=0&&idx<size());
|
||||
return Array()[idx];
|
||||
}
|
||||
void resize(int num)
|
||||
{
|
||||
assert(num>=0);
|
||||
if (num)
|
||||
{
|
||||
if (!mItem)
|
||||
{
|
||||
Alloc();
|
||||
}
|
||||
}
|
||||
if (mItem||num)
|
||||
{
|
||||
Array().resize(num);
|
||||
}
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
void push_back(const CGhoul2Info &model)
|
||||
{
|
||||
if (!mItem)
|
||||
{
|
||||
Alloc();
|
||||
}
|
||||
Array().push_back(model);
|
||||
}
|
||||
int size() const
|
||||
{
|
||||
if (!IsValid())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return Array().size();
|
||||
}
|
||||
bool IsValid() const
|
||||
{
|
||||
return InfoArray().IsValid(mItem);
|
||||
}
|
||||
void kill()
|
||||
{
|
||||
// this scary method zeros the infovector handle without actually freeing it
|
||||
// it is used for some places where a copy is made, but we don't want to go through the trouble
|
||||
// of making a deep copy
|
||||
mItem=0;
|
||||
}
|
||||
};
|
||||
|
||||
// collision detection stuff
|
||||
#define G2_FRONTFACE 1
|
||||
#define G2_BACKFACE 0
|
||||
|
||||
|
||||
// calling defines for the trace function
|
||||
enum EG2_Collision
|
||||
{
|
||||
G2_NOCOLLIDE,
|
||||
G2_COLLIDE,
|
||||
G2_RETURNONHIT
|
||||
};
|
||||
|
||||
|
||||
//====================================================================
|
||||
|
||||
#endif // GHOUL2_SHARED_H_INC
|
||||
Reference in New Issue
Block a user