Beispiel #1
0
        public void CreateFlagSimulationFromNode(SCNNode node)
        {
            var meshData  = new ClothSimMetalNode(this.device, Width, Height);
            var clothNode = SCNNode.FromGeometry(meshData.Geometry);

            var flag = node.FindChildNode("flagStaticWave", true);

            if (flag != null)
            {
                var boundingBoxMax = SCNVector3.Zero;
                var boundingBoxMin = SCNVector3.Zero;
                flag.GetBoundingBox(ref boundingBoxMin, ref boundingBoxMax);
                var existingFlagBV = boundingBoxMax - boundingBoxMin;

                var rescaleToMatchSizeMatrix = SCNMatrix4.Scale(existingFlagBV.X / (float)Width);

                var rotation       = SCNQuaternion.FromAxisAngle(SCNVector3.UnitX, (float)Math.PI / 2f);
                var localTransform = rescaleToMatchSizeMatrix * SCNMatrix4.Rotate(rotation.ToQuaternion());

                localTransform.Transpose();
                var currentTransform = SCNMatrix4.Transpose(flag.Transform);
                var newTransform     = currentTransform * localTransform;

                clothNode.Transform = SCNMatrix4.Transpose(newTransform);// flag.Transform * localTransform;
                if (clothNode.Geometry != null)
                {
                    clothNode.Geometry.FirstMaterial = flag.Geometry?.FirstMaterial;
                    if (clothNode.Geometry.FirstMaterial != null)
                    {
                        clothNode.Geometry.FirstMaterial.DoubleSided = true;
                    }
                }

                flag.ParentNode.ReplaceChildNode(flag, clothNode);
                clothNode.Geometry.SetupPaintColorMask("flag_flagA");
                clothNode.SetPaintColors();
                clothNode.FixNormalMaps();

                this.clothData.Add(new ClothData(clothNode, meshData));
            }
        }
Beispiel #2
0
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    if (this.ClothNode != null)
                    {
                        this.ClothNode.Dispose();
                        this.ClothNode = null;
                    }

                    if (this.MeshData != null)
                    {
                        this.MeshData.Dispose();
                        this.MeshData = null;
                    }
                }

                this.disposed = true;
            }
        }
Beispiel #3
0
        public void Deform(ClothSimMetalNode mesh, SimulationData simData)
        {
            var w = this.pipelineStateClothSim.ThreadExecutionWidth;
            var threadsPerThreadgroup = new MTLSize((nint)w, 1, 1);

            var threadgroupsPerGrid = new MTLSize((mesh.VertexCount + (int)w - 1) / (int)w, 1, 1);

            var clothSimCommandBuffer  = this.commandQueue.CommandBuffer();
            var clothSimCommandEncoder = clothSimCommandBuffer?.ComputeCommandEncoder;

            if (clothSimCommandEncoder != null)
            {
                clothSimCommandEncoder.SetComputePipelineState(pipelineStateClothSim);

                clothSimCommandEncoder.SetBuffer(mesh.Vb1, 0, 0);
                clothSimCommandEncoder.SetBuffer(mesh.Vb2, 0, 1);
                clothSimCommandEncoder.SetBuffer(mesh.VelocityBuffers[mesh.CurrentBufferIndex], 0, 2);

                mesh.CurrentBufferIndex = (mesh.CurrentBufferIndex + 1) % 2;
                clothSimCommandEncoder.SetBuffer(mesh.VelocityBuffers[mesh.CurrentBufferIndex], 0, 3);

                //var pointer = System.Runtime.InteropServices.Marshal.GetComInterfaceForObject(simData, typeof(SimulationData));
                //clothSimCommandEncoder?.SetBytes(pointer, (nuint)System.Runtime.InteropServices.Marshal.SizeOf<SimulationData>(), 4);

                clothSimCommandEncoder.DispatchThreadgroups(threadgroupsPerGrid, threadsPerThreadgroup: threadsPerThreadgroup);

                clothSimCommandEncoder.EndEncoding();
            }

            clothSimCommandBuffer?.Commit();

            //

            var normalComputeCommandBuffer  = this.commandQueue.CommandBuffer();
            var normalComputeCommandEncoder = normalComputeCommandBuffer?.ComputeCommandEncoder;

            if (normalComputeCommandEncoder != null)
            {
                normalComputeCommandEncoder.SetComputePipelineState(pipelineStateNormalUpdate);
                normalComputeCommandEncoder.SetBuffer(mesh.Vb2, 0, 0);
                normalComputeCommandEncoder.SetBuffer(mesh.Vb1, 0, 1);
                normalComputeCommandEncoder.SetBuffer(mesh.NormalWorkBuffer, 0, 2);
                normalComputeCommandEncoder.DispatchThreadgroups(threadgroupsPerGrid, threadsPerThreadgroup);

                normalComputeCommandEncoder.EndEncoding();
            }

            normalComputeCommandBuffer?.Commit();

            //

            var normalSmoothComputeCommandBuffer  = this.commandQueue.CommandBuffer();
            var normalSmoothComputeCommandEncoder = normalSmoothComputeCommandBuffer?.ComputeCommandEncoder;

            if (normalSmoothComputeCommandEncoder != null)
            {
                normalSmoothComputeCommandEncoder.SetComputePipelineState(pipelineStateNormalSmooth);
                normalSmoothComputeCommandEncoder.SetBuffer(mesh.NormalWorkBuffer, 0, 0);
                normalSmoothComputeCommandEncoder.SetBuffer(mesh.NormalBuffer, 0, 1);
                normalSmoothComputeCommandEncoder.DispatchThreadgroups(threadgroupsPerGrid, threadsPerThreadgroup);

                normalSmoothComputeCommandEncoder.EndEncoding();
            }

            normalSmoothComputeCommandBuffer?.Commit();
        }
Beispiel #4
0
 public ClothData(SCNNode clothNode, ClothSimMetalNode meshData)
 {
     this.ClothNode = clothNode;
     this.MeshData  = meshData;
 }