29 #include "../idlib/precompiled.h"
43 static
const char *brittleFracture_SnapshotName = "_BrittleFracture_Snapshot_";
55 maxShatterRadius = 0.0f;
56 minShatterRadius = 0.0f;
57 linearVelocityScale = 0.0f;
58 angularVelocityScale = 0.0f;
66 disableFracture =
false;
68 lastRenderEntityUpdate = -1;
71 fl.networkSync =
true;
74 isXraySurface =
false;
86 for ( i = 0; i <
shards.Num(); i++ ) {
87 shards[
i]->decals.DeleteContents(
true );
107 savefile->
Write( &flags,
sizeof( flags ) );
134 for ( i = 0; i <
shards.Num(); i++ ) {
138 for ( j = 0; j <
shards[
i]->decals.Num(); j++ ) {
143 for ( j = 0; j <
shards[
i]->neighbours.Num(); j++ ) {
150 for ( j = 0; j <
shards[
i]->edgeHasNeighbour.Num(); j++ ) {
181 savefile->
Read( &
fl,
sizeof(
fl ) );
211 for ( i = 0; i <
num; i++ ) {
215 for ( i = 0; i <
num; i++ ) {
220 for ( j = 0; j <
shards[
i]->decals.Num(); j++ ) {
226 shards[
i]->neighbours.SetNum( j );
227 for ( j = 0; j <
shards[
i]->neighbours.Num(); j++ ) {
235 shards[
i]->edgeHasNeighbour.SetNum( j );
236 for ( j = 0; j <
shards[
i]->edgeHasNeighbour.Num(); j++ ) {
244 if (
shards[i]->droppedTime < 0 ) {
252 savefile->
ReadBool( isXraySurface );
296 isXraySurface =
false;
302 isXraySurface =
true;
347 shards.RemoveIndex( index );
350 for ( i = index; i <
shards.Num(); i++ ) {
351 shards[
i]->clipModel->SetId( i );
361 int i,
j, k,
n, msec, numTris, numDecalTris;
386 for ( i = 0; i <
shards.Num(); i++ ) {
387 n =
shards[
i]->winding.GetNumPoints();
391 for ( k = 0; k <
shards[
i]->decals.Num(); k++ ) {
392 n =
shards[
i]->decals[k]->GetNumPoints();
394 numDecalTris += n - 2;
406 for ( i = 0; i <
shards.Num(); i++ ) {
411 if (
shards[i]->droppedTime >= 0 ) {
425 tangents = ( plane.
Normal() * axis ).ToMat3();
431 v->
xyz = origin + winding[0].ToVec3() * axis;
432 v->
st[0] = winding[0].s;
433 v->
st[1] = winding[0].t;
441 v->
xyz = origin + winding[j-1].ToVec3() * axis;
442 v->
st[0] = winding[j-1].s;
443 v->
st[1] = winding[j-1].t;
451 v->
xyz = origin + winding[
j].ToVec3() * axis;
452 v->
st[0] = winding[
j].s;
453 v->
st[1] = winding[
j].t;
471 for ( k = 0; k <
shards[
i]->decals.Num(); k++ ) {
478 v->
xyz = origin + decalWinding[0].ToVec3() * axis;
479 v->
st[0] = decalWinding[0].s;
480 v->
st[1] = decalWinding[0].t;
488 v->
xyz = origin + decalWinding[j-1].ToVec3() * axis;
489 v->
st[0] = decalWinding[j-1].s;
490 v->
st[1] = decalWinding[j-1].t;
498 v->
xyz = origin + decalWinding[
j].ToVec3() * axis;
499 v->
st[0] = decalWinding[
j].s;
500 v->
st[1] = decalWinding[
j].t;
526 memset( &surface, 0,
sizeof( surface ) );
532 memset( &surface, 0,
sizeof( surface ) );
551 gameLocal.
Error(
"idBrittleFracture::ModelCallback: callback with NULL game entity" );
593 int i, startTime, endTime, droppedTime;
595 bool atRest =
true, fading =
false;
598 for ( i = 0; i <
shards.Num(); i++ ) {
599 droppedTime =
shards[
i]->droppedTime;
600 if ( droppedTime != -1 ) {
621 for ( i = 0; i <
shards.Num(); i++ ) {
644 for ( i = 0; i <
shards.Num(); i++ ) {
670 if (
shards[
id]->droppedTime != -1 ) {
671 shards[
id]->physicsObj.ApplyImpulse( 0, point, impulse );
688 if (
shards[
id]->droppedTime != -1 ) {
689 shards[
id]->physicsObj.AddForce( 0, point, force );
712 msg.
Init( msgBuf,
sizeof( msgBuf ) );
727 if ( damageDefName ) {
747 axis[2].NormalVectors( axistemp[0], axistemp[1] );
748 axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] *
s;
749 axis[1] = axistemp[ 0 ] * s + axistemp[ 1 ] * -
c;
751 textureAxis[0] = axis[0] * ( 1.0f /
decalSize );
752 textureAxis[0][3] = -( point * textureAxis[0].Normal() ) + 0.5
f;
754 textureAxis[1] = axis[1] * ( 1.0f /
decalSize );
755 textureAxis[1][3] = -( point * textureAxis[1].Normal() ) + 0.5
f;
757 for ( i = 0; i <
shards.Num(); i++ ) {
759 origin =
shards[
i]->clipModel->GetOrigin();
760 axis =
shards[
i]->clipModel->GetAxis();
765 idVec3 p = origin + winding[
j].ToVec3() * axis;
767 st[
j].
x = d0 = textureAxis[0].Distance( p );
768 st[
j].
y = d1 = textureAxis[1].Distance( p );
785 shards[
i]->decals.Append( decal );
789 (*decal)[
j].ToVec3() = winding[
j].ToVec3();
790 (*decal)[
j].s = st[
j].
x;
791 (*decal)[
j].t = st[
j].
y;
804 int i,
j, clipModelId;
837 dir2 = origin - point;
875 msg.
Init( msgBuf,
sizeof( msgBuf ) );
901 for ( i = 0; i <
shards.Num(); i++ ) {
924 int i,
j, numIslands;
925 int queueStart, queueEnd;
926 shard_t *curShard, *nextShard, **queue;
935 for ( i = 0; i <
shards.Num(); i++ ) {
939 for ( i = 0; i <
shards.Num(); i++ ) {
941 if (
shards[i]->droppedTime != -1 ) {
945 if (
shards[i]->islandNum ) {
952 shards[
i]->islandNum = numIslands+1;
955 if (
shards[i]->atEdge ) {
959 for ( curShard = queue[queueStart]; queueStart < queueEnd; curShard = queue[++queueStart] ) {
973 queue[queueEnd++] = nextShard;
976 if ( nextShard->
atEdge ) {
984 if ( !touchesEdge ) {
985 for ( j = 0; j < queueEnd; j++ ) {
986 DropShard( queue[j], point, dir, 0.0
f, time );
1040 int i,
j, bestPlane;
1041 float a,
c,
s, dist, bestDist;
1043 idPlane windingPlane, splitPlanes[2];
1058 axis[2] = windingPlane.
Normal();
1060 if ( isXraySurface ) {
1071 axis[2].NormalVectors( axistemp[0], axistemp[1] );
1072 axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] *
s;
1073 axis[1] = axistemp[ 0 ] * s + axistemp[ 1 ] * -
c;
1078 for ( i = 0; i < 2; i++ ) {
1082 dist = splitPlanes[
i].
Distance( w[j].ToVec3() );
1083 if ( dist > bestDist ) {
1091 if ( !w.
Split( &back, splitPlanes[bestPlane] ) ) {
1102 w[
j].ToVec3() -= origin;
1128 if ( !renderModel ) {
1137 if ( isXraySurface ) {
1138 for ( i = 0; i < 1 ; i++ ) {
1139 surf = renderModel->
Surface( i );
1173 for ( i = 0; i < 1 ; i++ ) {
1174 surf = renderModel->
Surface( i );
1179 for ( k = 0; k < 3; k++ ) {
1190 for ( i = 0; i < 1 ; i++ ) {
1191 surf = renderModel->
Surface( i );
1196 for ( k = 0; k < 3; k++ ) {
1222 for ( i = 0; i <
shards.Num(); i++ ) {
1231 p1 = origin1 + w1[k].ToVec3() * axis1;
1232 p2 = origin1 + w1[(k+1)%w1.
GetNumPoints()].ToVec3() * axis1;
1246 for ( j = 0; j <
shards.Num(); j++ ) {
1259 if ( l < shard1->neighbours.Num() ) {
1268 p1 = origin2 + w2[
l].ToVec3() * axis2;
1271 if ( plane[2].Side( p1, 0.1
f ) ==
SIDE_ON && plane[3].Side( p1, 0.1
f ) ==
SIDE_ON ) {
1272 if ( plane[2].Side( p2, 0.1
f ) ==
SIDE_ON && plane[3].Side( p2, 0.1
f ) ==
SIDE_ON ) {
1322 if ( trace->
c.
id < 0 || trace->
c.
id >=
shards.Num() ) {
1326 point =
shards[trace->
c.
id]->clipModel->GetOrigin();
void SetupPolygon(const idVec3 *v, const int count)
virtual ~idBrittleFracture(void)
void SetAngularVelocity(const idVec3 &newAngularVelocity, int id=0)
void SetClipModel(idClipModel *model, float density, int id=0, bool freeOld=true)
renderEntity_t renderEntity
bool AddBounds(const idBounds &a)
float GetFloat(const char *key, const char *defaultString="0") const
idMat3 ToMat3(void) const
idList< bool > edgeHasNeighbour
virtual srfTriangles_t * AllocSurfaceTriangles(int numVerts, int numIndexes) const =0
void WriteString(const char *string)
void RemoveEqualPoints(const float epsilon=ON_EPSILON)
bool UpdateRenderEntity(renderEntity_s *renderEntity, const renderView_t *renderView) const
int GetInt(const char *key, const char *defaultString="0") const
void ApplyImpulse(const int id, const idVec3 &point, const idVec3 &impulse)
float GetArea(void) const
assert(prefInfo.fullscreenBtn)
virtual const idSoundShader * FindSound(const char *name, bool makeDefault=true)=0
const idVec3 & Normal(void) const
void ReadMaterial(const idMaterial *&material)
void SetSelf(idEntity *e)
virtual bool ClientReceiveEvent(int event, int time, const idBitMsg &msg)
struct idEntity::entityFlags_s fl
void SetColor(dword color)
const int MAX_EVENT_PARAM_SIZE
const idEventDef EV_Activate("activate","e")
void RemoveShard(int index)
virtual qhandle_t AddEntityDef(const renderEntity_t *re)=0
float Distance(const idVec3 &v) const
void void void void void Error(const char *fmt,...) const id_attribute((format(printf
void AssureSize(int newSize)
void Write(const void *buffer, int len)
const idMat3 & GetAxis(void) const
void ReadWinding(idWinding &winding)
virtual void AddForce(idEntity *ent, int id, const idVec3 &point, const idVec3 &force)
const idMaterial * shader
static float ClampFloat(float min, float max, float value)
virtual void AddSurface(modelSurface_t surface)=0
const char * GetName(void) const
void ReadBool(bool &value)
void Event_Touch(idEntity *other, trace_t *trace)
virtual const idVec3 & GetLinearVelocity(int id=0) const =0
void WriteStaticObject(const idClass &obj)
static float Sqrt(float x)
const int SHADERPARM_GREEN
virtual void FreeModelDef(void)
float angularVelocityScale
dword PackColor(const idVec4 &color)
const idVec3 & GetOrigin(void) const
idPhysics_StaticMulti physicsObj
virtual const idMaterial * FindMaterial(const char *name, bool makeDefault=true)=0
bool IsBroken(void) const
void SetNormal(const idVec3 &normal)
idPhysics_RigidBody physicsObj
void LittleBitField(void *bp, int elsize)
float linearVelocityScale
deferredEntityCallback_t callback
int lastRenderEntityUpdate
int Split(idFixedWinding *back, const idPlane &plane, const float epsilon=ON_EPSILON)
void WriteMaterial(const idMaterial *material)
#define EVENT(event, function)
void Init(byte *data, int length)
virtual void ClientPredictionThink(void)
void WriteBool(const bool value)
virtual void InitEmpty(const char *name)=0
bool StartSoundShader(const idSoundShader *shader, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length)
const int SHADERPARM_BLUE
bool noDynamicInteractions
void Restore(idRestoreGame *savefile)
void SetSelf(idEntity *e)
virtual void VPCALL MinMax(float &min, float &max, const float *src, const int count)=0
#define FLOATSIGNBITSET(f)
const int SHARD_FADE_START
idPhysics * GetPhysics(void) const
int GetNumPoints(void) const
#define MAX_POINTS_ON_WINDING
void WriteWinding(const idWinding &winding)
const char * GetString(const char *key, const char *defaultString="") const
GLubyte GLubyte GLubyte GLubyte w
void ReadFloat(float &value)
bool StartSound(const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length)
void void Read(void *buffer, int len)
void SetPhysics(idPhysics *phys)
void Shatter(const idVec3 &point, const idVec3 &impulse, const int time)
idList< idFixedWinding * > decals
void WriteFloat(const float value)
virtual float GetMass(int id=-1) const =0
bool GetBool(const char *key, const char *defaultString="0") const
srfTriangles_t * geometry
END_CLASS const int SHARD_ALIVE_TIME
const int GetContentFlags(void) const
virtual void Present(void)
bool IsAtRest(void) const
void ServerSendEvent(int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient) const
virtual const modelSurface_t * Surface(int surfaceNum) const =0
void GetPlane(idVec3 &normal, float &dist) const
float ReadFloat(void) const
const idVec3 & GetGravity(void) const
void Fracture_r(idFixedWinding &w)
static bool ModelCallback(renderEntity_s *renderEntity, const renderView_t *renderView)
void DeleteContents(bool clear)
virtual void UpdateEntityDef(qhandle_t entityHandle, const renderEntity_t *re)=0
void SetFriction(const float linear, const float angular, const float contact)
void SetBool(const char *key, bool val)
GLubyte GLubyte GLubyte a
void SetAxis(const idMat3 &newAxis, int id=-1)
void ReadBounds(idBounds &bounds)
void ProjectDecal(const idVec3 &point, const idVec3 &dir, const int time, const char *damageDefName)
virtual void FreeModel(idRenderModel *model)=0
void WriteInt(const int value)
idDeclManager * declManager
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
idEntity * entities[MAX_GENTITIES]
void Shrink(const float m)
virtual bool ClientReceiveEvent(int event, int time, const idBitMsg &msg)
void SetAxis(const idMat3 &newAxis, int id=-1)
static const float TWO_PI
void SetContents(int contents, int id=-1)
void ReadStaticObject(idClass &obj)
void DropFloatingIslands(const idVec3 &point, const idVec3 &impulse, const int time)
int Append(const type &obj)
idRenderModelManager * renderModelManager
void AddShard(idClipModel *clipModel, idFixedWinding &w)
void SetClipMask(int mask, int id=-1)
const idMaterial * decalMaterial
bool IsCleared(void) const
bool RemoveIndex(int index)
void FindNeighbours(void)
const idMaterial * material
virtual void Killed(idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location)
idVec3 GetCenter(void) const
bool ShouldCreateBackSides(void) const
idList< shard_t * > shards
#define CLASS_DECLARATION(nameofsuperclass, nameofclass)
void RestorePhysics(idPhysics *phys)
void BecomeActive(int flags)
void RemoveIndex(int id=0, bool freeClipModel=true)
void WriteBounds(const idBounds &bounds)
const idEventDef EV_Remove("<immediateremove>", NULL)
idList< struct shard_s * > neighbours
virtual void ApplyImpulse(idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse)
void SetGravity(const idVec3 &newGravity)
void Event_Activate(idEntity *activator)
const idDeclEntityDef * FindEntityDef(const char *name, bool makeDefault=true) const
idRenderWorld * gameRenderWorld
void AddPoint(const idVec3 &v)
static idEntityFx * StartFx(const char *fx, const idVec3 *useOrigin, const idMat3 *useAxis, idEntity *ent, bool bind)
void SetClipModel(idClipModel *model, float density, int id=0, bool freeOld=true)
bool PostEventMS(const idEventDef *ev, int time)
const idEventDef EV_Touch("<touch>","et")
void SetBouncyness(const float b)
float shaderParms[MAX_ENTITY_SHADER_PARMS]
void ReadString(idStr &string)
void BecomeInactive(int flags)
void CreateFractures(const idRenderModel *renderModel)
virtual void AddDamageEffect(const trace_t &collision, const idVec3 &velocity, const char *damageDefName)
void ActivateTargets(idEntity *activator) const
void SetContents(int contents, int id=-1)
idClipModel * GetClipModel(int id=0) const
void DropShard(shard_t *shard, const idVec3 &point, const idVec3 &dir, const float impulse, const int time)
void SetOrigin(const idVec3 &newOrigin, int id=-1)
void SetOrigin(const idVec3 &newOrigin, int id=-1)
bool Evaluate(int timeStepMSec, int endTimeMSec)
void FitThroughPoint(const idVec3 &p)
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
virtual idRenderModel * AllocModel()=0
void SetMass(float mass, int id=-1)
idSIMDProcessor * SIMDProcessor
void Save(idSaveGame *savefile) const
virtual int NumSurfaces() const =0