Skip to content

Commit 8c4e69a

Browse files
committed
Move skeleton building and blending to engine
1 parent 74e26bb commit 8c4e69a

File tree

7 files changed

+256
-13
lines changed

7 files changed

+256
-13
lines changed

src/engine/client/cg_msgdef.h

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,18 +91,38 @@ namespace Util {
9191
}
9292
};
9393

94+
template<> struct SerializeTraits<std::vector<BoneMod>> {
95+
static void Write( Writer& stream, const std::vector<BoneMod>& boneMods ) {
96+
stream.WriteSize( boneMods.size() );
97+
stream.WriteData( boneMods.data(), boneMods.size() * sizeof( BoneMod ) );
98+
}
99+
100+
static std::vector<BoneMod> Read( Reader& stream ) {
101+
std::vector<BoneMod> boneMods;
102+
const size_t size = stream.ReadSize<BoneMod>();
103+
boneMods.resize( size );
104+
stream.ReadData( boneMods.data(), size * sizeof( BoneMod ) );
105+
return boneMods;
106+
}
107+
};
108+
94109
// Use that bone optimization for refEntity_t
95110
template<> struct SerializeTraits<refEntity_t> {
96111
static void Write(Writer& stream, const refEntity_t& ent)
97112
{
98-
stream.WriteData(&ent, offsetof(refEntity_t, skeleton));
99-
stream.Write<refSkeleton_t>(ent.skeleton);
113+
stream.WriteData(&ent, offsetof(refEntity_t, tag));
114+
stream.Write<std::string>( ent.tag );
115+
stream.Write<std::vector<BoneMod>>( ent.boneMods );
116+
// stream.Write<refSkeleton_t>(ent.skeleton);
100117
}
118+
101119
static refEntity_t Read(Reader& stream)
102120
{
103121
refEntity_t ent;
104-
stream.ReadData(&ent, offsetof(refEntity_t, skeleton));
105-
ent.skeleton = stream.Read<refSkeleton_t>();
122+
stream.ReadData(&ent, offsetof(refEntity_t, tag));
123+
ent.tag = stream.Read<std::string>();
124+
ent.boneMods = stream.Read<std::vector<BoneMod>>();
125+
// ent.skeleton = stream.Read<refSkeleton_t>();
106126
return ent;
107127
}
108128
};

src/engine/renderer/tr_animation.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,32 @@ static int IQMBuildSkeleton( refSkeleton_t *skel, skelAnimation_t *skelAnim,
997997
return true;
998998
}
999999

1000+
void R_TransformSkeleton( refSkeleton_t* skel, const float scale ) {
1001+
skel->scale = scale;
1002+
1003+
switch ( skel->type ) {
1004+
case refSkeletonType_t::SK_INVALID:
1005+
case refSkeletonType_t::SK_ABSOLUTE:
1006+
return;
1007+
1008+
default:
1009+
break;
1010+
}
1011+
1012+
// calculate absolute transforms
1013+
for ( refBone_t* bone = &skel->bones[0]; bone < &skel->bones[skel->numBones]; bone++ ) {
1014+
if ( bone->parentIndex >= 0 ) {
1015+
refBone_t* parent;
1016+
1017+
parent = &skel->bones[bone->parentIndex];
1018+
1019+
TransCombine( &bone->t, &parent->t, &bone->t );
1020+
}
1021+
}
1022+
1023+
skel->type = refSkeletonType_t::SK_ABSOLUTE;
1024+
}
1025+
10001026
/*
10011027
==============
10021028
RE_BuildSkeleton
@@ -1152,6 +1178,7 @@ int RE_BuildSkeleton( refSkeleton_t *skel, qhandle_t hAnim, int startFrame, int
11521178
}
11531179

11541180
// FIXME: clear existing bones and bounds?
1181+
skel->numBones = 0;
11551182
return false;
11561183
}
11571184

src/engine/renderer/tr_local.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3349,6 +3349,7 @@ void GLimp_LogComment_( std::string comment );
33493349
int RE_CheckSkeleton( refSkeleton_t *skel, qhandle_t hModel, qhandle_t hAnim );
33503350
int RE_BuildSkeleton( refSkeleton_t *skel, qhandle_t anim, int startFrame, int endFrame, float frac,
33513351
bool clearOrigin );
3352+
void R_TransformSkeleton( refSkeleton_t* skel, const float scale );
33523353
int RE_BlendSkeleton( refSkeleton_t *skel, const refSkeleton_t *blend, float frac );
33533354
int RE_AnimNumFrames( qhandle_t hAnim );
33543355
int RE_AnimFrameRate( qhandle_t hAnim );

src/engine/renderer/tr_main.cpp

Lines changed: 158 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,6 +1825,33 @@ static void R_SortDrawSurfs()
18251825
R_AddDrawViewCmd( false );
18261826
}
18271827

1828+
static void PositionEntityOnTag( refEntity_t* entity, const refEntity_t* parent, orientation_t* orientation ) {
1829+
// FIXME: allow origin offsets along tag?
1830+
VectorCopy( parent->origin, entity->origin );
1831+
1832+
for ( int i = 0; i < 3; i++ ) {
1833+
VectorMA( entity->origin, orientation->origin[i], parent->axis[i], entity->origin );
1834+
}
1835+
1836+
// had to cast away the const to avoid compiler problems...
1837+
AxisMultiply( orientation->axis, ( ( refEntity_t* ) parent )->axis, entity->axis );
1838+
entity->backlerp = parent->backlerp;
1839+
}
1840+
1841+
static void PositionRotatedEntityOnTag( refEntity_t* entity, const refEntity_t* parent, orientation_t* orientation ) {
1842+
// FIXME: allow origin offsets along tag?
1843+
VectorCopy( parent->origin, entity->origin );
1844+
1845+
for ( int i = 0; i < 3; i++ ) {
1846+
VectorMA( entity->origin, orientation->origin[i], parent->axis[i], entity->origin );
1847+
}
1848+
1849+
// had to cast away the const to avoid compiler problems...
1850+
axis_t tempAxis;
1851+
AxisMultiply( entity->axis, orientation->axis, tempAxis );
1852+
AxisMultiply( tempAxis, ( ( refEntity_t* ) parent )->axis, entity->axis );
1853+
}
1854+
18281855
/*
18291856
=============
18301857
R_AddEntitySurfaces
@@ -1889,19 +1916,146 @@ void R_AddEntitySurfaces()
18891916
}
18901917
else
18911918
{
1892-
switch ( tr.currentModel->type )
1893-
{
1919+
switch ( tr.currentModel->type ) {
18941920
case modtype_t::MOD_MESH:
18951921
R_AddMDVSurfaces( ent );
18961922
break;
18971923

18981924
case modtype_t::MOD_MD5:
1899-
R_AddMD5Surfaces( ent );
1925+
/* Log::Warn("%i %s: old: %i-%i %f new: %i-%i %f | %f %f", ent->e.animationHandle,
1926+
R_GetAnimationByHandle( ent->e.animationHandle )->name, ent->e.startFrame,
1927+
ent->e.endFrame, ent->e.lerp, ent->e.startFrame2, ent->e.endFrame2, ent->e.lerp2,
1928+
ent->e.blendLerp, ent->e.scale ); */
1929+
switch ( ent->e.positionOnTag ) {
1930+
case EntityTag::ON_TAG:
1931+
{
1932+
orientation_t orientation;
1933+
RE_LerpTagET( &orientation, &tr.refdef.entities[ent->e.attachmentEntity].e, ent->e.tag.c_str(), 0 );
1934+
PositionEntityOnTag( &ent->e, &tr.refdef.entities[ent->e.attachmentEntity].e, &orientation );
1935+
R_RotateEntityForViewParms( ent, &tr.viewParms, &tr.orientation );
1936+
break;
1937+
}
1938+
1939+
case EntityTag::ON_TAG_ROTATED:
1940+
{
1941+
orientation_t orientation;
1942+
RE_LerpTagET( &orientation, &tr.refdef.entities[ent->e.attachmentEntity].e, ent->e.tag.c_str(), 0 );
1943+
PositionRotatedEntityOnTag( &ent->e, &tr.refdef.entities[ent->e.attachmentEntity].e, &orientation );
1944+
R_RotateEntityForViewParms( ent, &tr.viewParms, &tr.orientation );
1945+
break;
1946+
}
1947+
1948+
case EntityTag::NONE:
1949+
default:
1950+
break;
1951+
}
1952+
1953+
if ( ent->e.scale == 0 ) {
1954+
ent->e.scale = 1;
1955+
}
1956+
if ( ent->e.animationHandle == 0 ) {
1957+
ent->e.animationHandle = ent->e.animationHandle2;
1958+
} else if ( ent->e.animationHandle2 == 0 ) {
1959+
ent->e.animationHandle2 = ent->e.animationHandle;
1960+
}
1961+
1962+
RE_BuildSkeleton( &ent->e.skeleton, ent->e.animationHandle, ent->e.startFrame, ent->e.endFrame,
1963+
ent->e.lerp, ent->e.clearOrigin );
1964+
ent->e.skeleton.scale = ent->e.scale;
1965+
if ( ent->e.blendLerp > 0.0 ) {
1966+
refSkeleton_t skel;
1967+
RE_BuildSkeleton( &skel, ent->e.animationHandle2, ent->e.startFrame2, ent->e.endFrame2,
1968+
ent->e.lerp2, ent->e.clearOrigin2 );
1969+
RE_BlendSkeleton( &ent->e.skeleton, &skel, ent->e.blendLerp );
1970+
}
1971+
1972+
for ( const BoneMod& boneMod : ent->e.boneMods ) {
1973+
QuatMultiply2( ent->e.skeleton.bones[boneMod.index].t.rot, boneMod.rotation );
1974+
}
1975+
1976+
if ( ent->e.boundsAdd ) {
1977+
matrix_t mat;
1978+
vec3_t bounds[2];
1979+
1980+
MatrixFromAngles( mat, ent->e.boundsRotation[0], ent->e.boundsRotation[1], ent->e.boundsRotation[2] );
1981+
MatrixTransformBounds( mat, ent->e.skeleton.bounds[0], ent->e.skeleton.bounds[1], bounds[0], bounds[1] );
1982+
BoundsAdd( ent->e.skeleton.bounds[0], ent->e.skeleton.bounds[1], bounds[0], bounds[1] );
1983+
}
1984+
1985+
if ( !( ent->e.renderfx & RF_NORENDER ) ) {
1986+
R_AddMD5Surfaces( ent );
1987+
}
19001988
break;
19011989

19021990
case modtype_t::MOD_IQM:
1903-
R_AddIQMSurfaces( ent );
1991+
{
1992+
/* Log::Warn("%i %s: old: %i-%i %f new: %i-%i %f | %f %f", ent->e.animationHandle,
1993+
R_GetAnimationByHandle( ent->e.animationHandle )->name, ent->e.startFrame,
1994+
ent->e.endFrame, ent->e.lerp, ent->e.startFrame2, ent->e.endFrame2, ent->e.lerp2,
1995+
ent->e.blendLerp, ent->e.scale ); */
1996+
switch ( ent->e.positionOnTag ) {
1997+
case EntityTag::ON_TAG:
1998+
{
1999+
orientation_t orientation;
2000+
RE_LerpTagET( &orientation, &tr.refdef.entities[ent->e.attachmentEntity].e, ent->e.tag.c_str(), 0 );
2001+
PositionEntityOnTag( &ent->e, &tr.refdef.entities[ent->e.attachmentEntity].e, &orientation );
2002+
R_RotateEntityForViewParms( ent, &tr.viewParms, &tr.orientation );
2003+
break;
2004+
}
2005+
2006+
case EntityTag::ON_TAG_ROTATED:
2007+
{
2008+
orientation_t orientation;
2009+
RE_LerpTagET( &orientation, &tr.refdef.entities[ent->e.attachmentEntity].e, ent->e.tag.c_str(), 0 );
2010+
PositionRotatedEntityOnTag( &ent->e, &tr.refdef.entities[ent->e.attachmentEntity].e, &orientation );
2011+
R_RotateEntityForViewParms( ent, &tr.viewParms, &tr.orientation );
2012+
break;
2013+
}
2014+
2015+
case EntityTag::NONE:
2016+
default:
2017+
break;
2018+
}
2019+
2020+
bool transform = true;
2021+
if ( ent->e.scale == 0 ) {
2022+
ent->e.scale = 1;
2023+
}
2024+
if ( ent->e.animationHandle == 0 ) {
2025+
ent->e.animationHandle = ent->e.animationHandle2;
2026+
} else if ( ent->e.animationHandle2 == 0 ) {
2027+
ent->e.animationHandle2 = ent->e.animationHandle;
2028+
}
2029+
2030+
ent->e.skeleton.scale = ent->e.scale;
2031+
RE_BuildSkeleton( &ent->e.skeleton, ent->e.animationHandle, ent->e.startFrame, ent->e.endFrame,
2032+
ent->e.lerp, ent->e.clearOrigin );
2033+
if ( ent->e.blendLerp > 0.0 ) {
2034+
refSkeleton_t skel;
2035+
RE_BuildSkeleton( &skel, ent->e.animationHandle2, ent->e.startFrame2, ent->e.endFrame2,
2036+
ent->e.lerp2, ent->e.clearOrigin2 );
2037+
RE_BlendSkeleton( &ent->e.skeleton, &skel, ent->e.blendLerp );
2038+
}
2039+
2040+
for ( const BoneMod& boneMod : ent->e.boneMods ) {
2041+
QuatMultiply2( ent->e.skeleton.bones[boneMod.index].t.rot, boneMod.rotation );
2042+
}
2043+
R_TransformSkeleton( &ent->e.skeleton, ent->e.scale );
2044+
2045+
if ( ent->e.boundsAdd ) {
2046+
matrix_t mat;
2047+
vec3_t bounds[2];
2048+
2049+
MatrixFromAngles( mat, ent->e.boundsRotation[0], ent->e.boundsRotation[1], ent->e.boundsRotation[2] );
2050+
MatrixTransformBounds( mat, ent->e.skeleton.bounds[0], ent->e.skeleton.bounds[1], bounds[0], bounds[1] );
2051+
BoundsAdd( ent->e.skeleton.bounds[0], ent->e.skeleton.bounds[1], bounds[0], bounds[1] );
2052+
}
2053+
2054+
if ( !( ent->e.renderfx & RF_NORENDER ) ) {
2055+
R_AddIQMSurfaces( ent );
2056+
}
19042057
break;
2058+
}
19052059

19062060
case modtype_t::MOD_BSP:
19072061
R_AddBSPModelSurfaces( ent );

src/engine/renderer/tr_types.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ enum class refSkeletonType_t
153153
SK_ABSOLUTE
154154
};
155155

156+
struct BoneMod {
157+
int index;
158+
vec3_t translation;
159+
quat_t rotation;
160+
};
161+
156162
struct alignas(16) refSkeleton_t
157163
{
158164
refSkeletonType_t type; // skeleton has been reset
@@ -167,6 +173,12 @@ struct alignas(16) refSkeleton_t
167173

168174
// XreaL END
169175

176+
enum class EntityTag {
177+
NONE,
178+
ON_TAG,
179+
ON_TAG_ROTATED
180+
};
181+
170182
struct refEntity_t
171183
{
172184
refEntityType_t reType;
@@ -203,6 +215,28 @@ struct refEntity_t
203215

204216
int altShaderIndex;
205217

218+
qhandle_t animationHandle;
219+
int startFrame;
220+
int endFrame;
221+
float lerp;
222+
int clearOrigin;
223+
qhandle_t animationHandle2;
224+
int startFrame2;
225+
int endFrame2;
226+
float lerp2;
227+
int clearOrigin2;
228+
float blendLerp;
229+
float scale;
230+
231+
int boundsAdd;
232+
vec3_t boundsRotation;
233+
234+
EntityTag positionOnTag = EntityTag::NONE;
235+
int attachmentEntity;
236+
std::string tag;
237+
238+
std::vector<BoneMod> boneMods;
239+
206240
// KEEP SKELETON AT THE END OF THE STRUCTURE
207241
// it is to make a serialization hack for refEntity_t easier
208242
// by memcpying up to skeleton and then serializing skeleton

src/shared/client/cg_api.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,14 @@ void trap_R_ClearScene()
283283
cmdBuffer.SendMsg<Render::ClearSceneMsg>();
284284
}
285285

286-
void trap_R_AddRefEntityToScene( const refEntity_t *re )
286+
/* HACK: We need the entityNum to get the correct positions for entities that need to be attached to another entity's bone
287+
This must be equal to the r_numEntities in engine at the time of adding the entity */
288+
static int entityNum;
289+
int trap_R_AddRefEntityToScene( const refEntity_t *re )
287290
{
288291
cmdBuffer.SendMsg<Render::AddRefEntityToSceneMsg>(*re);
292+
entityNum++;
293+
return entityNum - 1;
289294
}
290295

291296
void trap_R_AddPolyToScene( qhandle_t hShader, int numVerts, const polyVert_t *verts )
@@ -350,6 +355,7 @@ void trap_R_AddLightToScene( const vec3_t origin, float radius, float intensity,
350355

351356
void trap_R_RenderScene( const refdef_t *fd )
352357
{
358+
entityNum = 0;
353359
cmdBuffer.SendMsg<Render::RenderSceneMsg>(*fd);
354360
}
355361

@@ -391,7 +397,7 @@ void trap_R_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs )
391397
VectorCopy(mymaxs, maxs);
392398
}
393399

394-
int trap_R_LerpTag( orientation_t *tag, const refEntity_t *refent, const char *tagName, int startIndex )
400+
int trap_R_LerpTag( orientation_t *tag, const refEntity_t* refent, const char *tagName, int startIndex )
395401
{
396402
int result;
397403
VM::SendMsg<Render::LerpTagMsg>(*refent, tagName, startIndex, *tag, result);
@@ -436,6 +442,7 @@ qhandle_t trap_R_RegisterAnimation( const char *name )
436442
int trap_R_BuildSkeleton( refSkeleton_t *skel, qhandle_t anim, int startFrame, int endFrame, float frac, bool clearOrigin )
437443
{
438444
int result;
445+
skel->numBones = 0;
439446
VM::SendMsg<Render::BuildSkeletonMsg>(anim, startFrame, endFrame, frac, clearOrigin, *skel, result);
440447
return result;
441448
}
@@ -448,7 +455,7 @@ int trap_R_BlendSkeleton( refSkeleton_t *skel, const refSkeleton_t *blend, float
448455

449456
if ( skel->numBones != blend->numBones )
450457
{
451-
Log::Warn("trap_R_BlendSkeleton: different number of bones %d != %d", skel->numBones, blend->numBones);
458+
// Log::Warn("trap_R_BlendSkeleton: different number of bones %d != %d", skel->numBones, blend->numBones);
452459
return false;
453460
}
454461

src/shared/client/cg_api.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ qhandle_t trap_R_RegisterModel( const char *name );
6565
qhandle_t trap_R_RegisterSkin( const char *name );
6666
qhandle_t trap_R_RegisterShader( const char *name, int flags );
6767
void trap_R_ClearScene();
68-
void trap_R_AddRefEntityToScene( const refEntity_t *re );
68+
int trap_R_AddRefEntityToScene( const refEntity_t *re );
6969
void trap_R_AddPolyToScene( qhandle_t hShader, int numVerts, const polyVert_t *verts );
7070
void trap_R_AddPolysToScene( qhandle_t hShader, int numVerts, const polyVert_t *verts, int numPolys );
7171
void trap_R_AddLightToScene( const vec3_t origin, float radius, float intensity, float r, float g, float b, int flags );
@@ -80,7 +80,7 @@ void trap_R_ResetClipRegion();
8080
void trap_R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader );
8181
void trap_R_DrawRotatedPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader, float angle );
8282
void trap_R_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs );
83-
int trap_R_LerpTag( orientation_t *tag, const refEntity_t *refent, const char *tagName, int startIndex );
83+
int trap_R_LerpTag( orientation_t *tag, const refEntity_t* refent, const char *tagName, int startIndex );
8484
void trap_R_GetTextureSize( qhandle_t handle, int *x, int *y );
8585
qhandle_t trap_R_GenerateTexture( const byte *data, int x, int y );
8686
void trap_GetCurrentSnapshotNumber( int *snapshotNumber, int *serverTime );

0 commit comments

Comments
 (0)