void Creature::LoadFromData(CreatureLoadDataPacket& load_data) { JsonNode * json_root = load_data.base_node.toNode(); // Load points and topology JsonNode * json_mesh = GetJSONLevelNodeFromKey(*json_root, "mesh"); global_pts = ReadJSONPoints3D(*json_mesh, "points", total_num_pts); global_indices = ReadJSONUints(*json_mesh,"indices", total_num_indices); global_uvs = ReadJSONPoints2D(*json_mesh, "uvs", total_num_pts); render_colours = new glm::uint8[total_num_pts * 4]; render_pts = new glm::float32[total_num_pts * 3]; FillRenderColours(255, 255, 255, 255); // Load bones meshBone * root_bone = CreateBones(*json_root, "skeleton"); // Load regions std::vector<meshRenderRegion *> regions = CreateRegions(*json_mesh, "regions", global_indices, global_pts, global_uvs); // Add into composition render_composition = new meshRenderBoneComposition(); render_composition->setRootBone(root_bone); render_composition->getRootBone()->computeRestParentTransforms(); for(auto& cur_region : regions) { cur_region->setMainBoneKey(root_bone->getKey()); cur_region->determineMainBone(root_bone); render_composition->addRegion(cur_region); } render_composition->initBoneMap(); render_composition->initRegionsMap(); for(auto& cur_region : regions) { cur_region->initFastNormalWeightMap(render_composition->getBonesMap()); } render_composition->resetToWorldRestPts(); // Fill up available animation names JsonNode * json_anim_base = GetJSONLevelNodeFromKey(*json_root, "animation"); animation_names = GetJSONKeysFromNode(*json_anim_base); }
void ALeapMotionHandActor::Init(int32 HandIdParam, const TSubclassOf<class ALeapMotionBoneActor>& BoneBlueprint) { FLeapMotionDevice* Device = FLeapMotionControllerPlugin::GetLeapDeviceSafe(); if (Device && Device->IsConnected()) { Leap::Hand Hand = Device->Frame().hand(HandIdParam); HandId = HandIdParam; bool IsLeft; Device->GetIsHandLeft(HandId, IsLeft); HandSide = IsLeft ? ELeapSide::Left : ELeapSide::Right; } CreateBones(BoneBlueprint); OnHandAdded.Broadcast(HandId); }
bool SetApexDestructibleAsset(UDestructibleMesh& DestructibleMesh, NxDestructibleAsset& ApexDestructibleAsset, FSkeletalMeshImportData* OutData, EDestructibleImportOptions::Type Options) { DestructibleMesh.PreEditChange(NULL); ExistingDestMeshData * ExistDestMeshDataPtr = SaveExistingDestMeshData(&DestructibleMesh); // The asset is going away, which will destroy any actors created from it. We must destroy the physics state of any destructible mesh components before we release the asset. for(TObjectIterator<UDestructibleComponent> It; It; ++It) { UDestructibleComponent* DestructibleComponent = *It; if(DestructibleComponent->SkeletalMesh == &DestructibleMesh && DestructibleComponent->IsPhysicsStateCreated()) { DestructibleComponent->DestroyPhysicsState(); } } // Release old NxDestructibleAsset if it exists if (DestructibleMesh.ApexDestructibleAsset != NULL && DestructibleMesh.ApexDestructibleAsset != &ApexDestructibleAsset) { GPhysCommandHandler->DeferredRelease(DestructibleMesh.ApexDestructibleAsset); } // BRGTODO - need to remove the render data from the ApexDestructibleAsset, no longer need it // Removing const cast ... we'll have to make it non-const anyway when we modify it DestructibleMesh.ApexDestructibleAsset = &ApexDestructibleAsset; if ( !(Options&EDestructibleImportOptions::PreserveSettings) ) { // Resize the depth parameters array to the appropriate size DestructibleMesh.DefaultDestructibleParameters.DepthParameters.Init(FDestructibleDepthParameters(), ApexDestructibleAsset.getDepthCount()); // Resize the fracture effects array to the appropriate size DestructibleMesh.FractureEffects.AddZeroed(ApexDestructibleAsset.getDepthCount()); // Load the UnrealEd-editable parameters from the destructible asset DestructibleMesh.LoadDefaultDestructibleParametersFromApexAsset(); } // Create body setup for the destructible mesh DestructibleMesh.CreateBodySetup(); #if 0 // BRGTODO // warning for missing smoothing group info CheckSmoothingInfo(FbxMesh); #endif FSkeletalMeshImportData TempData; // Fill with data from buffer FSkeletalMeshImportData* SkelMeshImportDataPtr = &TempData; if( OutData ) { SkelMeshImportDataPtr = OutData; } // Get all material names here ImportMaterialsForSkelMesh(*SkelMeshImportDataPtr, ApexDestructibleAsset); // Import animation hierarchy, although this is trivial for an Apex Destructible Asset CreateBones(*SkelMeshImportDataPtr, ApexDestructibleAsset); // Import graphics data bool bHaveNormals, bHaveTangents; if (!FillSkelMeshImporterFromApexDestructibleAsset(*SkelMeshImportDataPtr, ApexDestructibleAsset, bHaveNormals, bHaveTangents)) { return false; } #if 0 // BRGTODO - what is this? if( SkelMeshImportDataPtr->Materials.Num() == FbxMatList.Num() ) { // reorder material according to "SKinXX" in material name SetMaterialSkinXXOrder(*SkelMeshImportDataPtr, FbxMatList ); } #endif #if 0 // BRGTODO - what is this? if( ImportOptions->bSplitNonMatchingTriangles ) { DoUnSmoothVerts(*SkelMeshImportDataPtr); } #endif // process materials from import data ProcessImportMeshMaterials( DestructibleMesh.Materials,*SkelMeshImportDataPtr ); // process reference skeleton from import data int32 SkeletalDepth=0; if(!ProcessImportMeshSkeleton(DestructibleMesh.RefSkeleton, SkeletalDepth, *SkelMeshImportDataPtr)) { return false; } UE_LOG(LogApexDestructibleAssetImport, Warning, TEXT("Bones digested - %i Depth of hierarchy - %i"), DestructibleMesh.RefSkeleton.GetNum(), SkeletalDepth); // process bone influences from import data ProcessImportMeshInfluences(*SkelMeshImportDataPtr); FSkeletalMeshResource& DestructibleMeshResource = *DestructibleMesh.GetImportedResource(); check(DestructibleMeshResource.LODModels.Num() == 0); DestructibleMeshResource.LODModels.Empty(); new(DestructibleMeshResource.LODModels)FStaticLODModel(); DestructibleMesh.LODInfo.Empty(); DestructibleMesh.LODInfo.AddZeroed(); DestructibleMesh.LODInfo[0].LODHysteresis = 0.02f; // Create initial bounding box based on expanded version of reference pose for meshes without physics assets. Can be overridden by artist. FBox BoundingBox(SkelMeshImportDataPtr->Points.GetData(), SkelMeshImportDataPtr->Points.Num()); DestructibleMesh.Bounds= FBoxSphereBounds(BoundingBox); // Store whether or not this mesh has vertex colors DestructibleMesh.bHasVertexColors = SkelMeshImportDataPtr->bHasVertexColors; FStaticLODModel& LODModel = DestructibleMeshResource.LODModels[0]; // Pass the number of texture coordinate sets to the LODModel. Ensure there is at least one UV coord LODModel.NumTexCoords = FMath::Max<uint32>(1,SkelMeshImportDataPtr->NumTexCoords); // if( bCreateRenderData ) // We always create render data { // copy vertex data needed to generate skinning streams for LOD TArray<FVector> LODPoints; TArray<FMeshWedge> LODWedges; TArray<FMeshFace> LODFaces; TArray<FVertInfluence> LODInfluences; TArray<int32> LODPointToRawMap; SkelMeshImportDataPtr->CopyLODImportData(LODPoints,LODWedges,LODFaces,LODInfluences,LODPointToRawMap); IMeshUtilities& MeshUtilities = FModuleManager::Get().LoadModuleChecked<IMeshUtilities>("MeshUtilities"); // Create actual rendering data. if (!MeshUtilities.BuildSkeletalMesh(DestructibleMeshResource.LODModels[0], DestructibleMesh.RefSkeleton, LODInfluences,LODWedges,LODFaces,LODPoints,LODPointToRawMap,false,!bHaveNormals,!bHaveTangents)) { DestructibleMesh.MarkPendingKill(); return false; } // Presize the per-section shadow casting array with the number of sections in the imported LOD. const int32 NumSections = LODModel.Sections.Num(); for ( int32 SectionIndex = 0 ; SectionIndex < NumSections ; ++SectionIndex ) { DestructibleMesh.LODInfo[0].TriangleSortSettings.AddZeroed(); } if (ExistDestMeshDataPtr) { RestoreExistingDestMeshData(ExistDestMeshDataPtr, &DestructibleMesh); delete ExistDestMeshDataPtr; ExistDestMeshDataPtr = NULL; } DestructibleMesh.CalculateInvRefMatrices(); DestructibleMesh.PostEditChange(); DestructibleMesh.MarkPackageDirty(); #if 0 // BRGTODO : Check, we don't need this, do we? // We have to go and fix any AnimSetMeshLinkup objects that refer to this skeletal mesh, as the reference skeleton has changed. for(TObjectIterator<UAnimSet> It;It;++It) { UAnimSet* AnimSet = *It; // Get DestructibleMesh path name FName SkelMeshName = FName( *DestructibleMesh.GetPathName() ); // See if we have already cached this Skeletal Mesh. const int32* IndexPtr = AnimSet->SkelMesh2LinkupCache.Find( SkelMeshName ); if( IndexPtr ) { AnimSet->LinkupCache( *IndexPtr ).BuildLinkup( &DestructibleMesh, AnimSet ); } } #endif // Now iterate over all skeletal mesh components re-initialising them. for(TObjectIterator<UDestructibleComponent> It; It; ++It) { UDestructibleComponent* DestructibleComponent = *It; if(DestructibleComponent->SkeletalMesh == &DestructibleMesh) { FComponentReregisterContext ReregisterContext(DestructibleComponent); } } } #if INVERT_Y_AND_V // Apply transformation for Y inversion const physx::PxMat44 MirrorY = physx::PxMat44(physx::PxVec4(1.0f, -1.0f, 1.0f, 1.0f)); #if !USE_TEMPORARY_TRANSFORMATION_FUNCTION ApexDestructibleAsset.applyTransformation(MirrorY, 1.0f); #else ApplyTransformationToApexDestructibleAsset( ApexDestructibleAsset, MirrorY ); #endif #endif return true; }