Example #1
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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;
        }