@@ -90,6 +90,7 @@ static inline void calcEnvMapping(FRenderVert& vert, const DirectX::XMMATRIX& sc
9090 vert.V = (XMVectorGetY (envNorm) + 1.0 ) * 0.5 * 256.0 ;
9191}
9292
93+ #if !UNDYING
9394void UD3D9RenderDevice::renderMeshActor (FSceneNode* frame, AActor* actor, RenderList& renderList, SpecialCoord* specialCoord) {
9495#ifdef UTGLR_DEBUG_SHOW_CALL_COUNTS
9596 {
@@ -230,15 +231,9 @@ void UD3D9RenderDevice::renderMeshActor(FSceneNode* frame, AActor* actor, Render
230231#endif // UTGLR_NO_LODMESH
231232 {
232233 isLod = false ;
233- #if UNDYING
234- numVerts = mesh->FrameVerts (actor);
235- samples = New<FVector>(GMem, numVerts);
236- mesh->GetFrame (samples, sizeof (samples[0 ]), GMath.UnitCoords , actor, frame);
237- #else
238234 numVerts = mesh->FrameVerts ;
239235 samples = New<FVector>(GMem, numVerts);
240236 mesh->GetFrame (samples, sizeof (samples[0 ]), GMath.UnitCoords , actor);
241- #endif
242237 numTris = mesh->Tris .Num ();
243238 }
244239
@@ -462,7 +457,214 @@ void UD3D9RenderDevice::renderMeshActor(FSceneNode* frame, AActor* actor, Render
462457
463458 unguard;
464459}
460+ #else
461+
462+ void UD3D9RenderDevice::renderMeshActor (FSceneNode* frame, AActor* actor, RenderList& renderList, SpecialCoord* specialCoord) {
463+ #ifdef UTGLR_DEBUG_SHOW_CALL_COUNTS
464+ {
465+ static int si;
466+ dout << L" utd3d9r: renderMeshActor = " << si++ << std::endl;
467+ }
468+ #endif
469+ using namespace DirectX ;
470+ guard (UD3D9RenderDevice::renderMeshActor);
471+ UMesh* mesh = actor->Mesh ;
472+ if (!mesh)
473+ return ;
474+
475+ // dout << "rendering actor " << actor->GetName() << std::endl;
476+ XMMATRIX actorMatrix = XMMatrixIdentity ();
477+
478+ mesh->SetResolution (actor, -1 );
479+ TRefArray<FMeshTri> tris = mesh->GetTris (actor);
480+ INT numVerts = mesh->FrameVerts (actor);
481+
482+ // The old switcheroo, trick the game to not transform the mesh verts to object position
483+ FVector origLoc = actor->Location ;
484+ FVector origPrePiv = actor->PrePivot ;
485+ FRotator origRot = actor->Rotation ;
486+ FLOAT origScale = actor->DrawScale ;
487+ actor->Location = FVector (0 , 0 , 0 );
488+ actor->PrePivot = FVector (0 , 0 , 0 );
489+ actor->Rotation = FRotator (0 , 0 , 0 );
490+ USkelMesh* skelMesh = Cast<USkelMesh>(actor->Mesh );
491+ if (skelMesh) {
492+ // Don't exactly know what this is doing / why it works but it took 3 weeks to figure out 💀
493+ // The mesh has some kind of pre-scale offset that itself gets scaled with the DrawScale
494+ // eg. groundskeeper is offset in Z ~ 3.75 and 3.5714 before scale of 1.05, this gets me that number.
495+ FPlace offsetScaled = skelMesh->ToActor (actor);
496+ actor->DrawScale = 1 .0f ;
497+ FPlace offsetIdentity = skelMesh->ToActor (actor);
498+ XMMATRIX matLoc = XMMatrixTranslationFromVector (FVecToDXVec (offsetScaled.Pos - offsetIdentity.Pos ));
499+ actorMatrix *= matLoc;
500+ }
501+ actor->DrawScale = 1 .0f ;
502+
503+ FVector* samples = New<FVector>(GMem, numVerts);
504+ mesh->GetFrame (samples, sizeof (samples[0 ]), GMath.UnitCoords , actor, frame);
505+ INT numTris = tris.Num ();
506+
507+ actor->Location = origLoc;
508+ actor->PrePivot = origPrePiv;
509+ actor->Rotation = origRot;
510+ actor->DrawScale = origScale;
511+
512+ bool renderAsParticles = actor->bParticles ;
513+ if (!renderAsParticles) {
514+ XMMATRIX matScale = XMMatrixScaling (actor->DrawScale , actor->DrawScale , actor->DrawScale );
515+ actorMatrix *= matScale;
516+ }
517+ if (specialCoord && specialCoord->enabled ) {
518+ actorMatrix *= FCoordToDXMat (specialCoord->coord );
519+ actorMatrix *= FCoordToDXMat (specialCoord->baseCoord );
520+ }
521+ else {
522+ XMMATRIX matLoc = XMMatrixTranslationFromVector (FVecToDXVec (actor->Location + actor->PrePivot ));
523+ XMMATRIX matRot = FRotToDXRotMat (actor->Rotation );
524+ actorMatrix *= matRot;
525+ actorMatrix *= matLoc;
526+ }
527+
528+ FTime currentTime = frame->Viewport ->CurrentTime ;
529+ DWORD baseFlags = getBasePolyFlags (actor);
530+
531+ if (renderAsParticles) {
532+ FLOAT lux = Clamp (actor->ScaleGlow * 0 .5f + actor->AmbientGlow / 256 .f , 0 .f , 1 .f );
533+ FPlane color = FVector (lux, lux, lux);
534+ if (GIsEditor && (baseFlags & PF_Selected)) {
535+ color = color * 0.4 + FVector (0.0 , 0.6 , 0.0 );
536+ }
537+ UTexture* tex = actor->Texture ->Get (currentTime);
538+ for (INT i = 0 ; i < numVerts; i++) {
539+ FVector& sample = samples[i];
540+ if (tex) {
541+
542+ // Transform the local-space point into world-space
543+ XMVECTOR xpoint = FVecToDXVec (sample);
544+ xpoint = XMVector3Transform (xpoint, actorMatrix);
545+ FVector point = DXVecToFVec (xpoint);
546+
547+ FTextureInfo texInfo;
548+ tex->Lock (texInfo, currentTime, -1 , this );
549+ renderSpriteGeo (frame, point, actor->DrawScale , texInfo, baseFlags, color);
550+ tex->Unlock (texInfo);
551+ }
552+ }
553+ return ;
554+ }
555+
556+ UniqueValueArray<UTexture*> textures (mesh->Textures .Num ());
557+ UTexture* envTex = nullptr ;
558+
559+ // Lock all mesh textures
560+ for (int i = 0 ; i < mesh->Textures .Num (); i++) {
561+ UTexture* tex = mesh->GetTexture (i, actor);
562+ if (!tex && actor->Texture ) {
563+ tex = actor->Texture ;
564+ }
565+ else if (!tex) {
566+ continue ;
567+ }
568+ tex = tex->Get (currentTime);
569+ textures.insert (i, tex);
570+ envTex = tex;
571+ }
572+ if (actor->Texture ) {
573+ envTex = actor->Texture ;
574+ }
575+ else if (actor->Region .Zone && actor->Region .Zone ->EnvironmentMap ) {
576+ envTex = actor->Region .Zone ->EnvironmentMap ;
577+ }
578+ else if (actor->Level ->EnvironmentMap ) {
579+ envTex = actor->Level ->EnvironmentMap ;
580+ }
581+ if (!envTex) {
582+ return ;
583+ }
584+
585+ bool fatten = actor->Fatness != 128 ;
586+ FLOAT fatness = (actor->Fatness / 16.0 ) - 8.0 ;
587+
588+ FVector* normals = NewZeroed<FVector>(GMem, numVerts);
589+
590+ // Calculate normals
591+ // Already zeroed on new
592+ for (int i = 0 ; i < numTris; i++) {
593+ int sampleIdx[3 ];
594+ const FMeshTri& tri = tris (i);
595+ for (int j = 0 ; j < 3 ; j++) {
596+ sampleIdx[j] = tri.iVertex [j];
597+ }
598+ FVector fNorm = (samples[sampleIdx[1 ]] - samples[sampleIdx[0 ]]) ^ (samples[sampleIdx[2 ]] - samples[sampleIdx[0 ]]);
599+ for (int j = 0 ; j < 3 ; j++) {
600+ normals[sampleIdx[j]] += fNorm ;
601+ }
602+ }
603+ for (int i = 0 ; i < numVerts; i++) {
604+ XMVECTOR normal = FVecToDXVec (normals[i]);
605+ normal = XMVector3Normalize (normal);
606+ normals[i] = DXVecToFVec (normal);
607+ }
608+
609+ XMMATRIX screenSpaceMat = actorMatrix * FCoordToDXMat (frame->Uncoords );
610+
611+ ActorRenderData& renderData = renderList.emplace_back ();
612+ renderData.actorMatrix = ToD3DMATRIX (actorMatrix);
613+ SurfKeyBucketVector<UTexture*, FRenderVert>& surfaceBuckets = renderData.surfaceBuckets ;
614+ surfaceBuckets.reserve (numTris);
465615
616+ int vertMaxCount = numTris * 3 ;
617+ // Process all triangles on the mesh
618+ for (INT i = 0 ; i < numTris; i++) {
619+ INT sampleIdx[3 ];
620+ DWORD polyFlags;
621+ INT texIdx;
622+ FMeshUV triUV[3 ];
623+ const FMeshTri& tri = tris (i);
624+ for (int j = 0 ; j < 3 ; j++) {
625+ sampleIdx[j] = tri.iVertex [j];
626+ triUV[j] = tri.Tex [j];
627+ }
628+ texIdx = tri.TextureIndex ;
629+ polyFlags = tri.PolyFlags ;
630+
631+ polyFlags |= baseFlags;
632+
633+ bool environMapped = polyFlags & PF_Environment;
634+ UTexture** tex = textures.at (texIdx);
635+ if (environMapped || tex == nullptr ) {
636+ tex = &envTex;
637+ }
638+ float scaleU = (*tex)->Scale * (*tex)->USize / 256.0 ;
639+ float scaleV = (*tex)->Scale * (*tex)->VSize / 256.0 ;
640+
641+ // Sort triangles into surface/flag groups
642+ std::vector<FRenderVert>& pointsVec = surfaceBuckets.get (*tex, polyFlags);
643+ pointsVec.reserve (vertMaxCount);
644+ for (INT j = 0 ; j < 3 ; j++) {
645+ FRenderVert& vert = pointsVec.emplace_back ();
646+ FVector pos = samples[sampleIdx[j]];
647+ const FVector& norm = normals[sampleIdx[j]];
648+ if (fatten) {
649+ pos += norm * fatness;
650+ }
651+ vert.pos = pos;
652+ vert.norm = norm;
653+ vert.U = triUV[j].U ;
654+ vert.V = triUV[j].V ;
655+
656+ // Calculate the environment UV mapping
657+ if (environMapped) {
658+ calcEnvMapping (vert, screenSpaceMat, frame);
659+ }
660+ vert.U *= scaleU;
661+ vert.V *= scaleV;
662+ }
663+ }
664+
665+ unguard;
666+ }
667+ #endif
466668
467669#if UNREAL_GOLD_OLDUNREAL
468670void UD3D9RenderDevice::renderStaticMeshActor (FSceneNode* frame, AActor* actor, RenderList& renderList, SpecialCoord* specialCoord) {
0 commit comments