void CVertMeshViewer::Dump() { CMeshViewer::Dump(); const UVertMesh *Mesh = static_cast<UVertMesh*>(Object); // ULodMesh appPrintf( "\nLodMesh info:\n=============\n" "version %d\n" "VertexCount %d\n" "Verts # %d\n" "MeshScale %g %g %g\n" "MeshOrigin %g %g %g\n" "RotOrigin %d %d %d\n" "FaceLevel # %d\n" "Faces # %d\n" "CollapseWedgeThus # %d\n" "Wedges # %d\n" "Impostor: %s (%s)\n" "SkinTessFactor %g\n", Mesh->Version, Mesh->VertexCount, Mesh->Verts.Num(), FVECTOR_ARG(Mesh->MeshScale), FVECTOR_ARG(Mesh->MeshOrigin), FROTATOR_ARG(Mesh->RotOrigin), Mesh->FaceLevel.Num(), Mesh->Faces.Num(), Mesh->CollapseWedgeThus.Num(), Mesh->Wedges.Num(), Mesh->HasImpostor ? "true" : "false", Mesh->SpriteMaterial ? MATERIAL_CAST(Mesh->SpriteMaterial)->Name : "none", Mesh->SkinTesselationFactor ); int i; appPrintf("Textures: %d\n", Mesh->Textures.Num()); for (i = 0; i < Mesh->Textures.Num(); i++) { const UUnrealMaterial *Tex = MATERIAL_CAST(Mesh->Textures[i]); if (Tex) appPrintf(" %d: %s (%s)\n", i, Tex->Name, Tex->GetClassName()); else appPrintf(" %d: null\n", i); } appPrintf("Materials: %d\n", Mesh->Materials.Num()); for (i = 0; i < Mesh->Materials.Num(); i++) { const FMeshMaterial &Mat = Mesh->Materials[i]; appPrintf(" %d: tex=%d flags=%08X\n", i, Mat.TextureIndex, Mat.PolyFlags); } // const UVertMesh *Mesh = static_cast<UVertMesh*>(Object); appPrintf( "\nVertMesh info:\n==============\n" "Verts # %d Normals # %d\n" "f150 # %d\n" "AnimSeqs # %d\n" "Bounding: Boxes # %d Spheres # %d\n" "VertexCount %d FrameCount %d\n" "AnimMeshVerts # %d\n" "StreamVersion %d\n", Mesh->Verts2.Num(), Mesh->Normals.Num(), Mesh->f150.Num(), Mesh->AnimSeqs.Num(), Mesh->BoundingBoxes.Num(), Mesh->BoundingSpheres.Num(), Mesh->VertexCount, Mesh->FrameCount, Mesh->AnimMeshVerts.Num(), Mesh->StreamVersion ); }
void ULodMesh::Serialize(FArchive &Ar) { guard(ULodMesh::Serialize); Super::Serialize(Ar); Ar << Version << VertexCount << Verts; if (Version <= 1 || Ar.Game == GAME_SplinterCell) { // skip FMeshTri2 section TArray<FMeshTri2> tmp; Ar << tmp; } #if VANGUARD if (Ar.Game == GAME_Vanguard && Ar.ArLicenseeVer >= 9) { TArray<FVanguardSkin> Skins; int unk74; Ar << Skins << unk74; if (Skins.Num()) CopyArray(Textures, Skins[0].Textures); goto after_textures; } #endif // VANGUARD Ar << Textures; after_textures: #if DEBUG_SKELMESH for (int i = 0; i < Textures.Num(); i++) appPrintf("Tex[%d] = %s\n", i, Textures[i] ? Textures[i]->Name : "None"); #endif #if SPLINTER_CELL if (Ar.Game == GAME_SplinterCell && Version >= 3) { TArray<UObject*> unk80; Ar << unk80; } #endif // SPLINTER_CELL #if LOCO if (Ar.Game == GAME_Loco) { int unk7C; TArray<FName> unk80; TArray<FLocoUnk2> unk8C; TArray<FLocoUnk1> unk98; if (Version >= 5) Ar << unk98; if (Version >= 6) Ar << unk80; if (Version >= 7) Ar << unk8C << unk7C; } #endif // LOCO Ar << MeshScale << MeshOrigin << RotOrigin; #if DEBUG_SKELMESH appPrintf("Scale: %g %g %g\nOrigin: %g %g %g\nRotation: %d %d %d\n", FVECTOR_ARG(MeshScale), FVECTOR_ARG(MeshOrigin), FROTATOR_ARG(RotOrigin)); #endif if (Version <= 1 || Ar.Game == GAME_SplinterCell) { // skip 2nd obsolete section TArray<word> tmp; Ar << tmp; } Ar << FaceLevel << Faces << CollapseWedgeThus << Wedges << Materials; Ar << MeshScaleMax; #if EOS if (Ar.Game == GAME_EOS && Ar.ArLicenseeVer >= 42) goto lod_fields2; #endif Ar << LODHysteresis; lod_fields2: Ar << LODStrength << LODMinVerts << LODMorph << LODZDisplace; #if SPLINTER_CELL if (Ar.Game == GAME_SplinterCell) return; #endif if (Version >= 3) { Ar << HasImpostor << SpriteMaterial; Ar << ImpLocation << ImpRotation << ImpScale << ImpColor; Ar << ImpSpaceMode << ImpDrawMode << ImpLightMode; } if (Version >= 4) { Ar << SkinTesselationFactor; } #if LINEAGE2 if (Ar.Game == GAME_Lineage2 && Version >= 5) { int unk; Ar << unk; } #endif // LINEAGE2 #if BATTLE_TERR if (Ar.Game == GAME_BattleTerr && Version >= 5) { TArray<int> unk; Ar << unk; } #endif // BATTLE_TERR #if SWRC if (Ar.Game == GAME_RepCommando && Version >= 7) { int unkD4, unkD8, unkDC, unkE0; Ar << unkD4 << unkD8 << unkDC << unkE0; } #endif // SWRC unguard; }
CSkelMeshViewer::CSkelMeshViewer(CSkeletalMesh* Mesh0, CApplication* Window) : CMeshViewer(Mesh0->OriginalMesh, Window) , Mesh(Mesh0) , AnimIndex(-1) , IsFollowingMesh(false) , ShowSkel(0) , ShowLabels(false) , ShowAttach(false) , ShowUV(false) { CSkelMeshInstance *SkelInst = new CSkelMeshInstance(); SkelInst->SetMesh(Mesh); if (GForceAnimSet) { CAnimSet *AttachAnim = GetAnimSet(GForceAnimSet); if (!AttachAnim) { appPrintf("WARNING: specified wrong AnimSet (%s class) object to attach\n", GForceAnimSet->GetClassName()); GForceAnimSet = NULL; } if (AttachAnim) SkelInst->SetAnim(AttachAnim); } else if (Mesh->OriginalMesh->IsA("SkeletalMesh")) // UE2 class { const USkeletalMesh *OriginalMesh = static_cast<USkeletalMesh*>(Mesh->OriginalMesh); if (OriginalMesh->Animation) SkelInst->SetAnim(OriginalMesh->Animation->ConvertedAnim); } Inst = SkelInst; // compute bounds for the current mesh CVec3 Mins, Maxs; if (Mesh0->Lods.Num()) { const CSkelMeshLod &Lod = Mesh0->Lods[0]; ComputeBounds(&Lod.Verts[0].Position, Lod.NumVerts, sizeof(CSkelMeshVertex), Mins, Maxs); // ... transform bounds SkelInst->BaseTransformScaled.TransformPointSlow(Mins, Mins); SkelInst->BaseTransformScaled.TransformPointSlow(Maxs, Maxs); } else { Mins = Maxs = nullVec3; } // extend bounds with additional meshes for (int i = 0; i < TaggedMeshes.Num(); i++) { CSkelMeshInstance* Inst = TaggedMeshes[i]; if (Inst->pMesh != SkelInst->pMesh) { const CSkeletalMesh *Mesh2 = Inst->pMesh; // the same code for Inst CVec3 Bounds2[2]; const CSkelMeshLod &Lod2 = Mesh2->Lods[0]; ComputeBounds(&Lod2.Verts[0].Position, Lod2.NumVerts, sizeof(CSkelMeshVertex), Bounds2[0], Bounds2[1]); Inst->BaseTransformScaled.TransformPointSlow(Bounds2[0], Bounds2[0]); Inst->BaseTransformScaled.TransformPointSlow(Bounds2[1], Bounds2[1]); ComputeBounds(Bounds2, 2, sizeof(CVec3), Mins, Maxs, true); // include Bounds2 into Mins/Maxs } // reset animation for all meshes TaggedMeshes[i]->TweenAnim(NULL, 0); } InitViewerPosition(Mins, Maxs); #if HIGHLIGHT_CURRENT TimeSinceCreate = -2; // ignore first 2 frames: 1st frame will be called after mesh changing, 2nd frame could load textures etc #endif #if SHOW_BOUNDS appPrintf("Bounds.min = %g %g %g\n", FVECTOR_ARG(Mesh->BoundingBox.Min)); appPrintf("Bounds.max = %g %g %g\n", FVECTOR_ARG(Mesh->BoundingBox.Max)); appPrintf("Origin = %g %g %g\n", FVECTOR_ARG(Mesh->MeshOrigin)); appPrintf("Sphere = %g %g %g R=%g\n", FVECTOR_ARG(Mesh->BoundingSphere), Mesh->BoundingSphere.R); appPrintf("Offset = %g %g %g\n", VECTOR_ARG(offset)); #endif // SHOW_BOUNDS }