Skip to content

Commit 3827ec0

Browse files
committed
- GetViewPosition builtin for cgame to allow stuff like text drawn over entities
- MDR physics: allows MDR bones to move independently of model by a defined file on bone numbers, their type, etc. (like hair and flags), but broken (currently ifdef'd out) - ifdef'd out IQM support as that's broken, we aren't using it, and only other whole games are using it - Removed attempt at r_lowEndVideo
1 parent d825d6f commit 3827ec0

File tree

16 files changed

+635
-68
lines changed

16 files changed

+635
-68
lines changed

code/cgame/cg_public.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ typedef enum {
183183
CG_TESTPRINTINT,
184184
CG_TESTPRINTFLOAT,
185185
CG_ACOS,
186-
CG_R_LFX_PARTICLEEFFECT // leilei - particle effects
186+
CG_R_LFX_PARTICLEEFFECT, // leilei - particle effects
187+
CG_R_VIEWPOSITION // leilei - view position
187188
} cgameImport_t;
188189

189190

code/cgame/cg_syscalls.asm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,4 @@ equ testPrintInt -110
104104
equ testPrintFloat -111
105105
equ acos -112
106106
equ trap_R_LFX_ParticleEffect -113
107+
equ trap_R_GetViewPosition -114

code/client/cl_cgame.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,9 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
637637
case CG_R_LFX_PARTICLEEFFECT:
638638
re.LFX_ParticleEffect( args[1], VMA(2), VMA(3));
639639
return 0;
640-
640+
case CG_R_VIEWPOSITION:
641+
re.GetViewPosition( VMA(1) );
642+
return VMA(1);
641643
case CG_PC_ADD_GLOBAL_DEFINE:
642644
return botlib_export->PC_AddGlobalDefine( VMA(1) );
643645
case CG_PC_LOAD_SOURCE:

code/qcommon/qcommon.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3434

3535
//#define PRE_RELEASE_DEMO
3636

37+
// leilei - broken things
38+
39+
//#define BROKEN_MDRPHYS // MDR physics are not serialized!
40+
//#define BROKEN_IQM // crashes (and we don't plan to use the format anyway. IQM users are other games)
41+
3742
//============================================================================
3843

3944
//

code/qcommon/qfiles.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,22 @@ typedef struct {
300300
int ofsEnd; // end of file
301301
} mdrHeader_t;
302302

303+
#ifdef BROKEN_MDRPHYS
304+
// leilei - bone deformery
305+
// MDR loading also checks for a text file that can set these properties so the "MDP" code can get to work with them.
306+
// and working from the cliententity.
307+
typedef struct {
308+
309+
vec3_t ofs[MDR_MAX_BONES];
310+
vec3_t wgt[MDR_MAX_BONES];
311+
float jiggle[MDR_MAX_BONES];
312+
313+
} mdrClBoneDeformSet_t;
314+
315+
typedef struct {
316+
mdrClBoneDeformSet_t def[4]; // up to 4 can alter bones
317+
} mdrDeformity_t;
318+
#endif
303319

304320
/*
305321
==============================================================================

code/renderer_oa/tr_animation.c

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ R_MDRAddAnimSurfaces
177177
*/
178178

179179
// much stuff in there is just copied from R_AddMd3Surfaces in tr_mesh.c
180+
#ifdef BROKEN_MDRPHYS
181+
int TheRealMDL; // leilei HACK - tr.currentModel->index returns an incorrect index at this point, so we must set this from tr_main.
182+
#endif
180183

181184
void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) {
182185
mdrHeader_t *header;
@@ -217,6 +220,11 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) {
217220
ent->e.oldframe = 0;
218221
}
219222

223+
#ifdef BROKEN_MDRPHYS
224+
TheRealMDL = tr.currentModel->index;
225+
#endif
226+
227+
220228
//
221229
// cull the entire model if merged bounding box of both frames
222230
// is outside the view frustum.
@@ -302,6 +310,7 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) {
302310
surface = (mdrSurface_t *)( (byte *)surface + surface->ofsEnd );
303311
}
304312
}
313+
extern float ProjectRadius( float r, vec3_t location );
305314

306315
/*
307316
==============
@@ -337,6 +346,21 @@ void RB_MDRSurfaceAnim( mdrSurface_t *surface )
337346
frontlerp = 1.0f - backlerp;
338347
}
339348

349+
if (r_lerpbias->integer)
350+
{
351+
float projectedRadius, fsh, lerpscale, radius;
352+
trRefEntity_t *ent = backEnd.currentEntity;
353+
fsh = 1;
354+
radius = 1;
355+
lerpscale = r_lerpbias->value*-0.2;
356+
if ( ( projectedRadius = ProjectRadius( radius, ent->e.origin ) ) != 0 )
357+
{
358+
fsh = 1.0f - projectedRadius * lerpscale;
359+
}
360+
if (fsh > 1)
361+
backlerp = 0;
362+
}
363+
340364
header = (mdrHeader_t *)((byte *)surface + surface->ofsHeader);
341365

342366
frameSize = (size_t)( &((mdrFrame_t *)0)->bones[ header->numBones ] );
@@ -519,3 +543,265 @@ void MC_UnCompress(float mat[3][4],const unsigned char * comp)
519543
val-=1<<(MC_BITS_VECT-1);
520544
mat[2][2]=((float)(val))*MC_SCALE_VECT;
521545
}
546+
547+
#ifdef BROKEN_MDRPHYS
548+
549+
/*
550+
==============
551+
RB_ClientDeformedMDRSurfaceAnim
552+
553+
leilei - This is for supporting the eventual creation of player customization on special 'generic' player models
554+
where sliders determine the body types.
555+
556+
tl;dr: jiggle bones and body sliders.
557+
==============
558+
*/
559+
560+
vec3_t oldorg;
561+
vec3_t neworg;
562+
vec3_t oofs;
563+
int thme;
564+
int thmend;
565+
566+
void RB_MDRP_Spring ( mdrBone_t bone, mdrPhysics_t phys, int bindex, vec3_t ofs, vec3_t ofs3, vec3_t ofs4, vec3_t bm1, vec3_t bm2, vec3_t bm3 )
567+
{
568+
vec3_t lfrom, lto, bold,bnew;
569+
int i;
570+
mdrPhysLocal_t *pl;
571+
// Get our position
572+
VectorCopy(ofs, lfrom);
573+
574+
// Take in some of our animation's changes, exaggerate a bit
575+
lto[0] = DotProduct( ofs, bm1 ) * 5;
576+
lto[1] = DotProduct( ofs, bm2 ) * 5;
577+
lto[2] = DotProduct( ofs, bm3 ) * 5;
578+
579+
// Transform from the world
580+
lfrom[0] = DotProduct( lto, backEnd.currentEntity->e.axis[0] );
581+
lfrom[1] = DotProduct( lto, backEnd.currentEntity->e.axis[1] );
582+
lfrom[2] = DotProduct( lto, backEnd.currentEntity->e.axis[2] );
583+
VectorAdd(lfrom,backEnd.currentEntity->e.origin, lfrom);
584+
585+
pl = &backEnd.currentEntity->pl;
586+
587+
if (tr.refdef.time > (pl->time[bindex] + 100))
588+
{
589+
// it's either been too long since the last physics rendering, or the framerate is too low
590+
// so reset the stuff
591+
VectorCopy(lfrom, bold);
592+
VectorCopy(lfrom, bnew);
593+
VectorClear(pl->vel[bindex]);
594+
pl->time[bindex] = tr.refdef.time + 16.667f; // 60fps
595+
return;
596+
}
597+
598+
else if (tr.refdef.time > pl->time[bindex])
599+
{
600+
int k;
601+
VectorCopy(pl->neworg[bindex], bnew);
602+
VectorCopy(pl->oldorg[bindex], bold);
603+
for(k=0;k<3;k++)
604+
{
605+
float res = 0;
606+
bnew[k] = (bnew[k] + bnew[k] + bold[k] + bnew[k]) / 4;
607+
bold[k] = (bold[k] + lfrom[k] + lfrom[k] + bold[k]) / (4+res);
608+
bold[k] += (pl->vel[bindex][k] * -phys.spring); // and a bit of spring
609+
bold[k] += (pl->vel[bindex][k] * (-phys.spring * 0.5f)); // and a bit of spring
610+
pl->vel[bindex][k]= (bnew[k] - bold[k]) * phys.limitl[k];
611+
}
612+
VectorCopy(bnew, pl->neworg[bindex]);
613+
VectorCopy(bold, pl->oldorg[bindex]);
614+
pl->time[bindex] = tr.refdef.time + 16.667f; // 60fps
615+
}
616+
617+
ofs3[0] = DotProduct( pl->vel[bindex], backEnd.currentEntity->e.axis[0] );
618+
ofs3[1] = DotProduct( pl->vel[bindex], backEnd.currentEntity->e.axis[1] );
619+
ofs3[2] = DotProduct( pl->vel[bindex], backEnd.currentEntity->e.axis[2] );
620+
621+
for(i=0;i<3;i++)
622+
{
623+
ofs3[i] *= (phys.spring);
624+
ofs4[i] = ofs3[i] * phys.limitr[i];
625+
ofs3[i] *= (phys.limitl[i]);
626+
if (ofs3[i] > (phys.limitl[i]*4)) pl->vel[bindex][i] -= (pl->vel[bindex][i]*0.8); // there's a limit
627+
}
628+
629+
630+
}
631+
632+
void RB_ClientDeformedMDRSurfaceAnim( mdrSurface_t *surface )
633+
{
634+
int i, j, k;
635+
float frontlerp, backlerp;
636+
int *triangles;
637+
int indexes;
638+
int baseIndex, baseVertex;
639+
int numVerts;
640+
int skipPhys = 0;
641+
mdrVertex_t *v;
642+
mdrHeader_t *header;
643+
mdrFrame_t *frame;
644+
mdrFrame_t *oldFrame;
645+
mdrBone_t bones[MDR_MAX_BONES], *bonePtr, *bone;
646+
model_t *mdl;
647+
mdl = R_GetModelByHandle( backEnd.currentEntity->e.hModel );
648+
TheRealMDL = mdl->index;
649+
650+
int frameSize;
651+
652+
if (skipPhys || !r_mdrPhysics->integer)
653+
{
654+
RB_MDRSurfaceAnim( surface );
655+
return;
656+
}
657+
658+
//ri.Printf( PRINT_DEVELOPER, "DEFORMED! %i aka %s.......OR IS IT %i aka %s ?!??\n", tr.currentModel->index, tr.currentModel->name, TheRealMDL, tr.models[TheRealMDL]->name);
659+
//ri.Printf(PRINT_WARNING,"MDP Rendered model index is %i\n", tr.currentModel->index);
660+
// don't lerp if lerping off, or this is the only frame, or the last frame...
661+
//
662+
if (backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame)
663+
{
664+
backlerp = 0; // if backlerp is 0, lerping is off and frontlerp is never used
665+
frontlerp = 1;
666+
}
667+
else
668+
{
669+
backlerp = backEnd.currentEntity->e.backlerp;
670+
frontlerp = 1.0f - backlerp;
671+
}
672+
// if (!r_lerpModels->integer) backlerp = 0;
673+
674+
675+
header = (mdrHeader_t *)((byte *)surface + surface->ofsHeader);
676+
677+
frameSize = (size_t)( &((mdrFrame_t *)0)->bones[ header->numBones ] );
678+
679+
frame = (mdrFrame_t *)((byte *)header + header->ofsFrames +
680+
backEnd.currentEntity->e.frame * frameSize );
681+
oldFrame = (mdrFrame_t *)((byte *)header + header->ofsFrames +
682+
backEnd.currentEntity->e.oldframe * frameSize );
683+
684+
RB_CheckOverflow( surface->numVerts, surface->numTriangles );
685+
686+
triangles = (int *) ((byte *)surface + surface->ofsTriangles);
687+
indexes = surface->numTriangles * 3;
688+
baseIndex = tess.numIndexes;
689+
baseVertex = tess.numVertexes;
690+
691+
// Set up all triangles.
692+
for (j = 0 ; j < indexes ; j++)
693+
{
694+
tess.indexes[baseIndex + j] = baseVertex + triangles[j];
695+
}
696+
tess.numIndexes += indexes;
697+
698+
//
699+
// lerp all the needed bones
700+
//
701+
if ( !backlerp )
702+
{
703+
// no lerping needed
704+
bonePtr = frame->bones;
705+
}
706+
707+
else
708+
{
709+
bonePtr = bones;
710+
711+
for ( i = 0 ; i < header->numBones*12 ; i++ )
712+
{
713+
((float *)bonePtr)[i] = frontlerp * ((float *)frame->bones)[i] + backlerp * ((float *)oldFrame->bones)[i];
714+
}
715+
716+
}
717+
718+
//
719+
// deform the vertexes by the lerped bones
720+
//
721+
numVerts = surface->numVerts;
722+
v = (mdrVertex_t *) ((byte *)surface + surface->ofsVerts);
723+
for ( j = 0; j < numVerts; j++ )
724+
{
725+
726+
vec3_t tempVert, tempNormal;
727+
mdrWeight_t *w;
728+
729+
VectorClear( tempVert );
730+
VectorClear( tempNormal );
731+
w = v->weights;
732+
733+
for ( k = 0 ; k < v->numWeights ; k++, w++ )
734+
{
735+
vec3_t bmx[3];
736+
int p = 0;
737+
// Set up the bones
738+
bone = bonePtr + w->boneIndex;
739+
740+
vec3_t ofs, ofs2, ofs3, ofs4;
741+
742+
// Leilei - Iterate physics
743+
744+
float tblend;
745+
746+
tblend = 1.0;
747+
VectorCopy(bone->matrix[0], bmx[0]);
748+
VectorCopy(bone->matrix[1], bmx[1]);
749+
VectorCopy(bone->matrix[2], bmx[2]);
750+
751+
VectorCopy(w->offset, ofs); // Local offset to modify
752+
VectorCopy(w->offset, ofs2); // Final offset to push to the rendering
753+
if (tblend > 1) tblend = 1.0f;
754+
if (tblend < 0) tblend = 0.0f;
755+
756+
float wt21 = w->boneWeight;
757+
float wt22 = w->boneWeight;
758+
float wt23 = w->boneWeight;
759+
760+
// Go through the known physics properties for the model
761+
for(p=0;p<MAX_MDR_PHYSICS;p++)
762+
{
763+
// See if our current bone matches with anything
764+
if (mdl->phys.p[p].targbone == w->boneIndex)
765+
{
766+
if (mdl->phys.p[p].type == MDP_SPRING)
767+
{
768+
769+
RB_MDRP_Spring ( *bone, mdl->phys.p[p], w->boneIndex, ofs, ofs3, ofs4, bmx[0], bmx[1], bmx[2] );
770+
bmx[2][2] += (ofs4[2]); // rotate
771+
772+
ofs2[0] += ofs3[0];
773+
ofs2[1] += ofs3[1];
774+
ofs2[2] += ofs3[2];
775+
776+
}
777+
}
778+
}
779+
780+
781+
tempVert[0] += wt21 * ( DotProduct( bmx[0], ofs2 ) + bone->matrix[0][3] );
782+
tempVert[1] += wt22 * ( DotProduct( bmx[1], ofs2 ) + bone->matrix[1][3] );
783+
tempVert[2] += wt23 * ( DotProduct( bmx[2], ofs2 ) + bone->matrix[2][3] );
784+
785+
tempNormal[0] += wt21 * DotProduct( bmx[0], v->normal );
786+
tempNormal[1] += wt22 * DotProduct( bmx[1], v->normal );
787+
tempNormal[2] += wt23 * DotProduct( bmx[2], v->normal );
788+
789+
}
790+
791+
tess.xyz[baseVertex + j][0] = tempVert[0];
792+
tess.xyz[baseVertex + j][1] = tempVert[1];
793+
tess.xyz[baseVertex + j][2] = tempVert[2];
794+
795+
tess.normal[baseVertex + j][0] = tempNormal[0];
796+
tess.normal[baseVertex + j][1] = tempNormal[1];
797+
tess.normal[baseVertex + j][2] = tempNormal[2];
798+
799+
tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
800+
tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
801+
802+
v = (mdrVertex_t *)&v->weights[v->numWeights];
803+
}
804+
tess.numVertexes += surface->numVerts;
805+
}
806+
807+
#endif

0 commit comments

Comments
 (0)