void Source_OnAddedToSolver(object sender, EventArgs e) { UpdateTransformData(); // In case source and target are the same object: if (SelfSkinning) { deformableMesh = source.DeformableMesh; // If source and target are different objects, create a new deformable mesh for the target: } else { deformableMesh = Oni.CreateDeformableMesh(source.Solver.OniSolver, IntPtr.Zero, IntPtr.Zero, transformData, IntPtr.Zero, sharedMesh.vertexCount, sharedMesh.vertexCount); GetMeshDataArrays(skinnedMesh); } Oni.SetDeformableMeshSkinMap(deformableMesh, source.DeformableMesh, skinMap.TriangleSkinMap); source.Solver.OnFrameEnd += Source_Solver_OnFrameEnd; }
public override bool AddToSolver(object info) { // Note: we use the new keyword to hide ObiClothBase's implementation with our own, and be able to call ObiActor's AddToSolver from here. if (Initialized && base.AddToSolver(info)) { particleIndicesHandle = Oni.PinMemory(particleIndices); for (int i = 0; i < 16; ++i) { transformData[i] = transform.worldToLocalMatrix[i]; } deformableMesh = Oni.CreateDeformableMesh(Solver.OniSolver, topology.HalfEdgeMesh, IntPtr.Zero, transformData, particleIndicesHandle.AddrOfPinnedObject(), sharedMesh.vertexCount + pooledVertices, sharedMesh.vertexCount); // allocate extra memory for the topology: topology.SetVertexCapacity(usedParticles + pooledParticles, sharedMesh.vertexCount + pooledVertices); Oni.SetDeformableMeshTBNUpdate(deformableMesh, normalsUpdate, updateTangents); GetMeshDataArrays(clothMesh); CallOnDeformableMeshSetup(); return(true); } return(false); }
public override bool AddToSolver(object info) { if (Initialized && base.AddToSolver(info)) { particleIndicesHandle = Oni.PinMemory(particleIndices); Matrix4x4 w2lTransform = ActorWorldToLocalMatrix; // if solver data is expressed in local space, convert // from solver's local space to world, then from world to actor local space: if (Solver.simulateInLocalSpace) { w2lTransform *= Solver.transform.localToWorldMatrix; } for (int i = 0; i < 16; ++i) { transformData[i] = w2lTransform[i]; } IntPtr skinbatch = IntPtr.Zero; if (SkinConstraints.GetFirstBatch() != null) { skinbatch = SkinConstraints.GetFirstBatch().OniBatch; } deformableMesh = Oni.CreateDeformableMesh(Solver.OniSolver, topology.HalfEdgeMesh, skinbatch, transformData, particleIndicesHandle.AddrOfPinnedObject(), sharedMesh.vertexCount, sharedMesh.vertexCount); Oni.SetDeformableMeshTBNUpdate(deformableMesh, normalsUpdate, updateTangents); GetMeshDataArrays(clothMesh); UpdateBindPosesAndWeights(); UpdateBoneTransforms(); // Inits skeletal skinning, to ensure all particles are skinned during the first frame. This ensures // that the initial position of particles is the initial skinned position, instead of that dictated by the rootbone's local space. Oni.ForceDeformableMeshSkeletalSkinning(deformableMesh); CallOnDeformableMeshSetup(); // remove bone weights so that the mesh is not affected by Unity's skinning: clothMesh.boneWeights = new BoneWeight[] {}; return(true); } return(false); }
public override bool AddToSolver(object info) { if (Initialized && base.AddToSolver(info)) { particleIndicesHandle = Oni.PinMemory(particleIndices); for (int i = 0; i < 16; ++i) { transformData[i] = transform.worldToLocalMatrix[i]; } IntPtr skinbatch = IntPtr.Zero; if (SkinConstraints.GetBatches().Count > 0) { skinbatch = SkinConstraints.GetBatches()[0].OniBatch; } deformableMesh = Oni.CreateDeformableMesh(Solver.OniSolver, topology.HalfEdgeMesh, skinbatch, transformData, particleIndicesHandle.AddrOfPinnedObject(), sharedMesh.vertexCount, sharedMesh.vertexCount); Oni.SetDeformableMeshTBNUpdate(deformableMesh, normalsUpdate, updateTangents); GetMeshDataArrays(clothMesh); SetSkinnedMeshAnimationInfo(); CallOnDeformableMeshSetup(); return(true); } return(false); }
public void Bind(Transform sourceTransform, Transform targetTransform) { bound = false; if (sourceTopology == null || sourceTopology.InputMesh == null || targetMesh == null || sourceTransform == null || targetTransform == null) { return; } this.sourceSkinTransform = new SkinTransform(sourceTransform); this.targetSkinTransform = new SkinTransform(targetTransform); IntPtr solver = Oni.CreateSolver(0, 0); // get source mesh: float[] transformData = new float[16]; for (int i = 0; i < 16; ++i) { transformData[i] = sourceTransform.worldToLocalMatrix[i]; } IntPtr sourceDefMesh = Oni.CreateDeformableMesh(solver, sourceTopology.HalfEdgeMesh, IntPtr.Zero, transformData, IntPtr.Zero, sourceTopology.InputMesh.vertexCount, sourceTopology.InputMesh.vertexCount); GCHandle sourceTrianglesHandle = Oni.PinMemory(sourceTopology.InputMesh.triangles); GCHandle sourceVerticesHandle = Oni.PinMemory(sourceTopology.InputMesh.vertices); GCHandle sourceNormalsHandle = Oni.PinMemory(sourceTopology.InputMesh.normals); GCHandle sourceTangentsHandle = Oni.PinMemory(sourceTopology.InputMesh.tangents); Oni.SetDeformableMeshData(sourceDefMesh, sourceTrianglesHandle.AddrOfPinnedObject(), sourceVerticesHandle.AddrOfPinnedObject(), sourceNormalsHandle.AddrOfPinnedObject(), sourceTangentsHandle.AddrOfPinnedObject(), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); // get target mesh transform data: for (int i = 0; i < 16; ++i) { transformData[i] = targetTransform.worldToLocalMatrix[i]; } IntPtr targetDefMesh = Oni.CreateDeformableMesh(solver, IntPtr.Zero, IntPtr.Zero, transformData, IntPtr.Zero, targetMesh.vertexCount, targetMesh.vertexCount); GCHandle meshTrianglesHandle = Oni.PinMemory(targetMesh.triangles); GCHandle meshVerticesHandle = Oni.PinMemory(targetMesh.vertices); GCHandle meshNormalsHandle = Oni.PinMemory(targetMesh.normals); GCHandle meshTangentsHandle = Oni.PinMemory(targetMesh.tangents); Oni.SetDeformableMeshData(targetDefMesh, meshTrianglesHandle.AddrOfPinnedObject(), meshVerticesHandle.AddrOfPinnedObject(), meshNormalsHandle.AddrOfPinnedObject(), meshTangentsHandle.AddrOfPinnedObject(), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); // Perform the binding process: Oni.Bind(triangleSkinMap, sourceDefMesh, targetDefMesh, masterFlags, slaveFlags); // Cleanup data: Oni.UnpinMemory(sourceTrianglesHandle); Oni.UnpinMemory(sourceVerticesHandle); Oni.UnpinMemory(sourceNormalsHandle); Oni.UnpinMemory(sourceTangentsHandle); Oni.UnpinMemory(meshTrianglesHandle); Oni.UnpinMemory(meshVerticesHandle); Oni.UnpinMemory(meshNormalsHandle); Oni.UnpinMemory(meshTangentsHandle); Oni.DestroyDeformableMesh(solver, sourceDefMesh); Oni.DestroyDeformableMesh(solver, targetDefMesh); Oni.DestroySolver(solver); // Get skinned vertex count: int skinCount = Oni.GetSkinnedVertexCount(triangleSkinMap); // Create arrays of the appropiate size to store skinning data: skinnedVertices = new int[skinCount]; skinnedTriangles = new int[skinCount]; baryPositions = new Vector3[skinCount]; baryNormals = new Vector3[skinCount]; baryTangents = new Vector3[skinCount]; // Retrieve skinning data: Oni.GetSkinInfo(triangleSkinMap, skinnedVertices, skinnedTriangles, baryPositions, baryNormals, baryTangents); bound = true; }