Esempio n. 1
0
 /// <summary>
 /// This function takes vertices from the source buffer and moves them by
 /// descent vector times stepLength (Pk*stepLength).
 /// Then it writes them into the destination buffer with new positions.
 /// This function does not change data in the source buffer.
 /// </summary>
 /// <param name="device"></param>
 /// <param name="srcVertexBuffer"></param>
 /// <param name="dstVertexBuffer"></param>
 /// <param name="parameters"></param>
 public void MoveVertices(StructuredBuffer srcVertexBuffer,
                          StructuredBuffer dstVertexBuffer, ComputeParams parameters)
 {
     parameters.MaxParticles = (uint)ParticleCount;
     paramsCB.SetData(parameters);
     device.ComputeShaderConstants[0] = paramsCB;
     device.ComputeShaderResources[0] = srcVertexBuffer;
     device.SetCSRWBuffer(0, dstVertexBuffer, (int)parameters.MaxParticles);
     device.PipelineState = factory[(int)(ComputeFlags.COMPUTE | ComputeFlags.MOVE)];
     device.Dispatch(MathUtil.IntDivUp((int)parameters.MaxParticles, BlockSize));
     device.ResetStates();
 }
Esempio n. 2
0
        /// <summary>
        /// This function calculates two values:
        /// 1. Energy E for every vertex				(N floats)
        /// 2. Descent vector which equals -grad(E)		(3*N floats)
        /// Values are overwritten into the same buffer
        /// </summary>
        /// <param name="device"></param>
        /// <param name="rwVertexBuffer"></param>
        /// <param name="parameters"></param>
        public void CalcDescentVector(StructuredBuffer rwVertexBuffer, ComputeParams parameters)
        {
            parameters.MaxParticles = (uint)ParticleCount;

            paramsCB.SetData(parameters);
            device.ComputeShaderConstants[0] = paramsCB;
            device.SetCSRWBuffer(0, rwVertexBuffer, (int)parameters.MaxParticles);

            device.ComputeShaderResources[2] = LinksIndexBuffer;
            device.ComputeShaderResources[3] = LinksBuffer;
            device.ComputeShaderResources[4] = SelectBuffer;
            device.PipelineState             = factory[(int)(
                                                           ComputeFlags.COMPUTE | ComputeFlags.SIMULATION |
                                                           ComputeFlags.EULER | ComputeFlags.LINKS)];

            //		device.PipelineState = factory[(int)(
            //			ComputeFlags.COMPUTE | ComputeFlags.SIMULATION |
            //			ComputeFlags.EULER)];
            device.Dispatch(MathUtil.IntDivUp((int)parameters.MaxParticles, BlockSize));
            //		device.ResetStates();

            // add localization forces:
            device.PipelineState = factory[(int)(ComputeFlags.COMPUTE | ComputeFlags.LOCAL)];
            if (categories.Count > 0)
            {
                foreach (var cat in categories)
                {
                    parameters.LocalCenter = new Vector4(cat.Center, 0);
                    parameters.LocalRadius = cat.Radius;
                    parameters.StartIndex  = cat.startIndex;
                    parameters.EndIndex    = cat.endIndex;
                    paramsCB.SetData(parameters);
                    //			device.ComputeShaderConstants[0] = paramsCB;
                    device.Dispatch(MathUtil.IntDivUp((int)(cat.endIndex - cat.startIndex), BlockSize));
                }
            }
            device.ResetStates();
        }
Esempio n. 3
0
        /// <summary>
        /// This function calculates the following values:
        /// 1. Total energy at (k+1)th iteration (from nextStateBuffer).
        /// 2. Dot product of kth descent vector and (k+1)th energy gradient (which equals minus (k+1)th descent vector)
        /// </summary>
        /// <param name="device"></param>
        /// <param name="currentStateBuffer"></param>
        /// <param name="nextStateBuffer"></param>
        /// <param name="outputValues"></param>
        /// <param name="parameters"></param>
        /// <param name="energy"></param>
        /// <param name="pTgradE"></param>
        public void CalcTotalEnergyAndDotProduct(StructuredBuffer currentStateBuffer,
                                                 StructuredBuffer nextStateBuffer, StructuredBuffer outputValues, ComputeParams parameters,
                                                 out float energy, out float pTgradE, out float checkSum)
        {
            parameters.MaxParticles = (uint)ParticleCount;
            energy   = 0;
            pTgradE  = 0;
            checkSum = 0;

            if (UseGPU)
            {
                // preform reduction on GPU:
                paramsCB.SetData(parameters);
                device.ComputeShaderConstants[0] = paramsCB;
                device.ComputeShaderResources[0] = currentStateBuffer;
                device.ComputeShaderResources[1] = nextStateBuffer;
                device.SetCSRWBuffer(1, outputValues, MathUtil.IntDivUp((int)parameters.MaxParticles, BlockSize));
                device.PipelineState = factory[(int)ComputeFlags.COMPUTE | (int)ComputeFlags.REDUCTION];
                device.Dispatch(MathUtil.IntDivUp((int)parameters.MaxParticles, BlockSize));

                // perform final summation:
                Vector4[] valueBufferCPU = new Vector4[MathUtil.IntDivUp((int)parameters.MaxParticles, BlockSize)];
                outputValues.GetData(valueBufferCPU);
                foreach (var value in valueBufferCPU)
                {
                    energy   += value.X;
                    pTgradE  += value.Y;
                    checkSum += value.Z;
                }
            }
            else             // if not use GPU
            {
                // perform summation on CPU:
                Particle3d[] currentBufferCPU = new Particle3d[parameters.MaxParticles];
                Particle3d[] nextBufferCPU    = new Particle3d[parameters.MaxParticles];

                currentStateBuffer.GetData(currentBufferCPU);
                nextStateBuffer.GetData(nextBufferCPU);


                for (int i = 0; i < parameters.MaxParticles; ++i)
                {
                    Vector3 force1 = currentBufferCPU[i].Force;
                    Vector3 force2 = nextBufferCPU[i].Force;

                    pTgradE  += -1.0f * Vector3.Dot(force1, force2);
                    energy   += nextBufferCPU[i].Energy;
                    checkSum += nextBufferCPU[i].Mass;
                }
            }

            energy /= 2;             // because each pair is counted 2 times
        }
Esempio n. 4
0
        /// <summary>
        /// This function takes vertices from the source buffer and moves them by
        /// descent vector times stepLength (Pk*stepLength).
        /// Then it writes them into the destination buffer with new positions.
        /// This function does not change data in the source buffer.
        /// </summary>
        /// <param name="device"></param>
        /// <param name="srcVertexBuffer"></param>
        /// <param name="dstVertexBuffer"></param>
        /// <param name="parameters"></param>
        public void MoveVertices(StructuredBuffer srcVertexBuffer,
							StructuredBuffer dstVertexBuffer, ComputeParams parameters)
        {
            parameters.MaxParticles = (uint)ParticleCount;
            paramsCB.SetData(parameters);
            device.ComputeShaderConstants[0] = paramsCB;
            device.ComputeShaderResources[0] = srcVertexBuffer;
            device.SetCSRWBuffer(0, dstVertexBuffer, (int)parameters.MaxParticles);
            device.PipelineState = factory[(int)(ComputeFlags.COMPUTE | ComputeFlags.MOVE)];
            device.Dispatch(MathUtil.IntDivUp((int)parameters.MaxParticles, BlockSize));
            device.ResetStates();
        }
Esempio n. 5
0
        /// <summary>
        /// This function calculates the following values:
        /// 1. Total energy at (k+1)th iteration (from nextStateBuffer).
        /// 2. Dot product of kth descent vector and (k+1)th energy gradient (which equals minus (k+1)th descent vector)
        /// </summary>
        /// <param name="device"></param>
        /// <param name="currentStateBuffer"></param>
        /// <param name="nextStateBuffer"></param>
        /// <param name="outputValues"></param>
        /// <param name="parameters"></param>
        /// <param name="energy"></param>
        /// <param name="pTgradE"></param>
        public void CalcTotalEnergyAndDotProduct(StructuredBuffer currentStateBuffer,
			StructuredBuffer nextStateBuffer, StructuredBuffer outputValues, ComputeParams parameters,
			out float energy, out float pTgradE, out float checkSum)
        {
            parameters.MaxParticles = (uint)ParticleCount;
            energy = 0;
            pTgradE = 0;
            checkSum = 0;

            if (UseGPU)
            {
                // preform reduction on GPU:
                paramsCB.SetData(parameters);
                device.ComputeShaderConstants[0] = paramsCB;
                device.ComputeShaderResources[0] = currentStateBuffer;
                device.ComputeShaderResources[1] = nextStateBuffer;
                device.SetCSRWBuffer(1, outputValues, MathUtil.IntDivUp((int)parameters.MaxParticles, BlockSize));
                device.PipelineState = factory[(int)ComputeFlags.COMPUTE | (int)ComputeFlags.REDUCTION];
                device.Dispatch(MathUtil.IntDivUp((int)parameters.MaxParticles, BlockSize));

                // perform final summation:
                Vector4[] valueBufferCPU = new Vector4[MathUtil.IntDivUp((int)parameters.MaxParticles, BlockSize)];
                outputValues.GetData(valueBufferCPU);
                foreach (var value in valueBufferCPU)
                {
                    energy += value.X;
                    pTgradE += value.Y;
                    checkSum += value.Z;
                }
            }
            else // if not use GPU
            {
                // perform summation on CPU:
                Particle3d[] currentBufferCPU = new Particle3d[parameters.MaxParticles];
                Particle3d[] nextBufferCPU = new Particle3d[parameters.MaxParticles];

                currentStateBuffer.GetData(currentBufferCPU);
                nextStateBuffer.GetData(nextBufferCPU);

                for (int i = 0; i < parameters.MaxParticles; ++i)
                {
                    Vector3 force1 = currentBufferCPU[i].Force;
                    Vector3 force2 = nextBufferCPU[i].Force;

                    pTgradE += -1.0f * Vector3.Dot(force1, force2);
                    energy += nextBufferCPU[i].Energy;
                    checkSum += nextBufferCPU[i].Mass;
                }
            }

            energy /= 2; // because each pair is counted 2 times
        }
Esempio n. 6
0
        /// <summary>
        /// This function calculates two values:
        /// 1. Energy E for every vertex				(N floats)
        /// 2. Descent vector which equals -grad(E)		(3*N floats)
        /// Values are overwritten into the same buffer
        /// </summary>
        /// <param name="device"></param>
        /// <param name="rwVertexBuffer"></param>
        /// <param name="parameters"></param>
        public void CalcDescentVector(StructuredBuffer rwVertexBuffer, ComputeParams parameters)
        {
            parameters.MaxParticles = (uint)ParticleCount;

            paramsCB.SetData(parameters);
            device.ComputeShaderConstants[0] = paramsCB;
            device.SetCSRWBuffer(0, rwVertexBuffer, (int)parameters.MaxParticles);

            device.ComputeShaderResources[2] = LinksIndexBuffer;
            device.ComputeShaderResources[3] = LinksBuffer;
            device.ComputeShaderResources[4] = SelectBuffer;
            device.PipelineState = factory[(int)(
                ComputeFlags.COMPUTE | ComputeFlags.SIMULATION |
                ComputeFlags.EULER | ComputeFlags.LINKS)];

            //		device.PipelineState = factory[(int)(
            //			ComputeFlags.COMPUTE | ComputeFlags.SIMULATION |
            //			ComputeFlags.EULER)];
            device.Dispatch(MathUtil.IntDivUp((int)parameters.MaxParticles, BlockSize));
            //		device.ResetStates();

            // add localization forces:
            device.PipelineState = factory[(int)(ComputeFlags.COMPUTE | ComputeFlags.LOCAL)];
            if (categories.Count > 0)
            {
                foreach (var cat in categories)
                {
                    parameters.LocalCenter = new Vector4(cat.Center, 0);
                    parameters.LocalRadius = cat.Radius;
                    parameters.StartIndex = cat.startIndex;
                    parameters.EndIndex = cat.endIndex;
                    paramsCB.SetData(parameters);
                    //			device.ComputeShaderConstants[0] = paramsCB;
                    device.Dispatch(MathUtil.IntDivUp((int)(cat.endIndex - cat.startIndex), BlockSize));
                }
            }
            device.ResetStates();
        }