@@ -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
181184void 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