private void OnDestroy() { Flex.FreeBuffer(_particleBuffer); Flex.FreeBuffer(_velocityBuffer); Flex.FreeBuffer(_phaseBuffer); Flex.DestroySolver(_solver); Flex.Shutdown(_library); }
public void Release() { if (m_handle) { Unmap(); Flex.FreeBuffer(m_handle); m_handle.Clear(); } }
public void TestSetParticlesPhases() { float DELTA_T = 0.016f; float INTERACTION_DISTANCE = 0.5f; float SOLID_REST_DISTANCE = 0.2f; Flex.Library lib = Flex.Init(Flex.FLEX_VERSION, ErrorCallback); Flex.SolverDesc desc = default(Flex.SolverDesc); Flex.SetSolverDescDefaults(ref desc); desc.maxParticles = 1000; desc.maxDiffuseParticles = 1000; Flex.Solver solver = Flex.CreateSolver(lib, ref desc); Flex.Params prms = new Flex.Params(); Flex.GetParams(solver, ref prms); prms.radius = INTERACTION_DISTANCE; prms.solidRestDistance = SOLID_REST_DISTANCE; Flex.SetParams(solver, ref prms); Flex.Buffer particles = CreateBuffer(lib, 2, 4, new float[] { -0.001f, 0.0f, 0.0f, 1.0f, 0.001f, 0.0f, 0.0f, 1.0f, }); Flex.SetParticles(solver, particles); Flex.Buffer phases = CreateBuffer(lib, 2, 1, new int[] { Flex.MakePhase(1, Flex.Phase.SelfCollide), Flex.MakePhase(1, Flex.Phase.SelfCollide), }); Flex.SetPhases(solver, phases); Flex.SetActiveCount(solver, 2); Flex.Buffer active = CreateBuffer(lib, 2, 1, new int[] { 0, 1, }); Flex.SetActive(solver, active); Flex.UpdateSolver(solver, DELTA_T, 1); Flex.GetParticles(solver, particles); float[] values; ReadBuffer(lib, particles, 2, 4, out values); Assert.AreEqual(SOLID_REST_DISTANCE, Vector3.Distance(new Vector3(values[0], values[1], values[2]), new Vector3(values[4], values[5], values[6]))); Flex.FreeBuffer(particles); Flex.FreeBuffer(phases); Flex.FreeBuffer(active); Flex.DestroySolver(solver); Flex.Shutdown(lib); }
public void TestAllocFreeBuffer() { Flex.Library lib = Flex.Init(Flex.FLEX_VERSION, ErrorCallback); Flex.Buffer buffer0 = Flex.AllocBuffer(lib, 1000, 4, Flex.BufferType.Host); Flex.Buffer buffer1 = Flex.AllocBuffer(lib, 1000, 4, Flex.BufferType.Device); Flex.FreeBuffer(buffer0); Flex.FreeBuffer(buffer1); Flex.Shutdown(lib); }
public void TestSetSpringConstraints() { float DELTA_T = 0.016f; float INTERACTION_DISTANCE = 0.5f; float SOLID_REST_DISTANCE = 0.2f; float SPRING_LENGTH = 1.0f; Flex.Library lib = Flex.Init(Flex.FLEX_VERSION, ErrorCallback); Flex.SolverDesc desc = default(Flex.SolverDesc); Flex.SetSolverDescDefaults(ref desc); desc.maxParticles = 1000; desc.maxDiffuseParticles = 1000; Flex.Solver solver = Flex.CreateSolver(lib, ref desc); Flex.Params prms = new Flex.Params(); Flex.GetParams(solver, ref prms); prms.radius = INTERACTION_DISTANCE; prms.solidRestDistance = SOLID_REST_DISTANCE; Flex.SetParams(solver, ref prms); Flex.Buffer particles = CreateBuffer(lib, 2, 4, new float[] { -0.001f, 0.0f, 0.0f, 1.0f, 0.001f, 0.0f, 0.0f, 1.0f, }); Flex.SetParticles(solver, particles); Flex.Buffer indices = CreateBuffer(lib, 2, 1, new int[] { 0, 1 }); Flex.Buffer lengths = CreateBuffer(lib, 1, 1, new float[] { SPRING_LENGTH }); Flex.Buffer stiffness = CreateBuffer(lib, 1, 1, new float[] { 1.0f }); Flex.SetSprings(solver, indices, lengths, stiffness, 1); Flex.SetActiveCount(solver, 2); Flex.Buffer active = CreateBuffer(lib, 2, 1, new int[] { 0, 1 }); Flex.SetActive(solver, active); Flex.UpdateSolver(solver, DELTA_T, 1); Flex.GetParticles(solver, particles); float[] values; ReadBuffer(lib, particles, 2, 4, out values); Assert.AreEqual(SPRING_LENGTH, Vector3.Distance(new Vector3(values[0], values[1], values[2]), new Vector3(values[4], values[5], values[6])), 0.001f); Flex.FreeBuffer(particles); Flex.FreeBuffer(indices); Flex.FreeBuffer(lengths); Flex.FreeBuffer(stiffness); Flex.FreeBuffer(active); Flex.DestroySolver(solver); Flex.Shutdown(lib); }
public void TestSetGetParticlesVelocities() { Vector3 GRAVITY = new Vector3(1, 2, 3); float DELTA_T = 0.016f; Flex.Library lib = Flex.Init(Flex.FLEX_VERSION, ErrorCallback); Flex.SolverDesc desc = default(Flex.SolverDesc); Flex.SetSolverDescDefaults(ref desc); desc.maxParticles = 1000; desc.maxDiffuseParticles = 1000; Flex.Solver solver = Flex.CreateSolver(lib, ref desc); Flex.Params prms = new Flex.Params(); Flex.GetParams(solver, ref prms); prms.gravity = GRAVITY; Flex.SetParams(solver, ref prms); Flex.Buffer particles = CreateBuffer(lib, 1, 4, new float[] { 0.0f, 0.0f, 0.0f, 1.0f, }); Flex.SetParticles(solver, particles); Flex.Buffer velocities = CreateBuffer(lib, 1, 3, new float[] { 0.0f, 0.0f, 0.0f, }); Flex.SetVelocities(solver, velocities); Flex.SetActiveCount(solver, 1); Flex.Buffer active = CreateBuffer(lib, 1, 1, new int[] { 0 }); Flex.SetActive(solver, active); Flex.UpdateSolver(solver, DELTA_T, 1); Flex.GetVelocities(solver, velocities); float[] values; ReadBuffer(lib, velocities, 1, 3, out values); Assert.AreEqual(GRAVITY * DELTA_T, new Vector3(values[0], values[1], values[2])); Flex.FreeBuffer(particles); Flex.FreeBuffer(velocities); Flex.FreeBuffer(active); Flex.DestroySolver(solver); Flex.Shutdown(lib); }
void Destroy() { if (m_mesh) { DestroyImmediate(m_mesh); } if (m_prepareFluidMaterial) { DestroyImmediate(m_prepareFluidMaterial); } if (m_indexBuffer != null) { m_indexBuffer.Release(); } if (m_positionBuffer != null) { m_positionBuffer.Release(); m_positionBuffer = null; } if (m_anisotropy1Buffer != null) { m_anisotropy1Buffer.Release(); m_anisotropy1Buffer = null; } if (m_anisotropy2Buffer != null) { m_anisotropy2Buffer.Release(); m_anisotropy2Buffer = null; } if (m_anisotropy3Buffer != null) { m_anisotropy3Buffer.Release(); m_anisotropy3Buffer = null; } if (m_positionBuffer0) { Flex.FreeBuffer(m_positionBuffer0); m_positionBuffer0.Clear(); } if (m_anisotropy1Buffer0) { Flex.FreeBuffer(m_anisotropy1Buffer0); m_anisotropy1Buffer0.Clear(); } if (m_anisotropy2Buffer0) { Flex.FreeBuffer(m_anisotropy2Buffer0); m_anisotropy2Buffer0.Clear(); } if (m_anisotropy3Buffer0) { Flex.FreeBuffer(m_anisotropy3Buffer0); m_anisotropy3Buffer0.Clear(); } }
public void TestParamsPlaneCollision() { float DELTA_T = 0.016f; float INTERACTION_DISTANCE = 0.5f; float SOLID_REST_DISTANCE = 0.2f; Vector3 GRAVITY = new Vector3(0, -9.81f, 0); Flex.Library lib = Flex.Init(Flex.FLEX_VERSION, ErrorCallback); Flex.SolverDesc desc = default(Flex.SolverDesc); Flex.SetSolverDescDefaults(ref desc); desc.maxParticles = 1000; desc.maxDiffuseParticles = 0; Flex.Solver solver = Flex.CreateSolver(lib, ref desc); Flex.Params prms = new Flex.Params(); Flex.GetParams(solver, ref prms); prms.radius = INTERACTION_DISTANCE; prms.solidRestDistance = SOLID_REST_DISTANCE; prms.gravity = GRAVITY; prms.plane0 = new Vector4(0.0f, 1.0f, 0.0f, 0.0f); prms.numPlanes = 1; Flex.SetParams(solver, ref prms); Flex.Buffer particles = CreateBuffer(lib, 1, 4, new float[] { 0.0f, 2.0f, 0.0f, 1.0f }); Flex.SetParticles(solver, particles); Flex.SetActiveCount(solver, 1); Flex.Buffer active = CreateBuffer(lib, 1, 1, new int[] { 0 }); Flex.CopyDesc cpyDsc; cpyDsc.srcOffset = cpyDsc.dstOffset = 0; cpyDsc.elementCount = 1; Flex.SetActive(solver, active, ref cpyDsc); for (int i = 0; i < 100; ++i) { Flex.UpdateSolver(solver, DELTA_T, 1); } Flex.GetParticles(solver, particles); float[] values; ReadBuffer(lib, particles, 1, 4, out values); Assert.AreEqual(0, values[1], 0.001f); Flex.FreeBuffer(active); Flex.FreeBuffer(particles); Flex.DestroySolver(solver); Flex.Shutdown(lib); }
public void TestMapUnmapBuffer() { Flex.Library lib = Flex.Init(Flex.FLEX_VERSION, ErrorCallback); Flex.Buffer buffer = Flex.AllocBuffer(lib, 1000, sizeof(float) * 4, Flex.BufferType.Host); float[] positions = new float[1000 * 4]; for (int i = 0; i < positions.Length; i += 4) { positions[i + 0] = 0.1f * i; positions[i + 1] = positions[i + 3] = 0.0f; positions[i + 3] = 0.1f; } IntPtr ptr = Flex.Map(buffer, 0); Marshal.Copy(positions, 0, ptr, positions.Length); Flex.Unmap(buffer); Flex.FreeBuffer(buffer); Flex.Shutdown(lib); }
public void TestSetGetActive() { Flex.Library lib = Flex.Init(Flex.FLEX_VERSION, ErrorCallback); Flex.SolverDesc desc = default(Flex.SolverDesc); Flex.SetSolverDescDefaults(ref desc); desc.maxParticles = 1000; desc.maxDiffuseParticles = 1000; Flex.Solver solver = Flex.CreateSolver(lib, ref desc); Flex.SetActiveCount(solver, 2); Flex.Buffer active = CreateBuffer(lib, 2, 1, new int[] { 2, 1 }); Flex.SetActive(solver, active); Assert.AreEqual(2, Flex.GetActiveCount(solver)); Flex.FreeBuffer(active); Flex.DestroySolver(solver); Flex.Shutdown(lib); }
public ShapeData(Collider collider) { bool dynamic = false; if (collider is SphereCollider) { SphereCollider sphereCollider = collider as SphereCollider; Vector3 scale = collider.transform.localScale; geometry.sphere.radius = sphereCollider.radius * Mathf.Max(scale.x, scale.y, scale.z); flags = Flex.MakeShapeFlags(Flex.CollisionShapeType.Sphere, dynamic); shapeMin = Vector3.one * -geometry.sphere.radius; shapeMax = Vector3.one * geometry.sphere.radius; shapeCenter = sphereCollider.center; shapeCenter.x *= scale.x; shapeCenter.y *= scale.y; shapeCenter.z *= scale.z; } else if (collider is CapsuleCollider) { CapsuleCollider capsuleCollider = collider as CapsuleCollider; Vector3 scale = collider.transform.localScale; if (capsuleCollider.direction == 1) { scale = new Vector3(scale.y, scale.z, scale.x); } if (capsuleCollider.direction == 2) { scale = new Vector3(scale.z, scale.x, scale.y); } geometry.capsule.radius = capsuleCollider.radius * Mathf.Max(scale.y, scale.z); geometry.capsule.halfHeight = capsuleCollider.height * scale.x * 0.5f - geometry.capsule.radius; flags = Flex.MakeShapeFlags(Flex.CollisionShapeType.Capsule, dynamic); shapeMin = new Vector3(-geometry.capsule.halfHeight - geometry.capsule.radius, -geometry.capsule.radius, -geometry.capsule.radius); shapeMax = new Vector3(geometry.capsule.halfHeight + geometry.capsule.radius, geometry.capsule.radius, geometry.capsule.radius); shapeCenter = capsuleCollider.center; shapeCenter.x *= scale.x; shapeCenter.y *= scale.y; shapeCenter.z *= scale.z; if (capsuleCollider.direction == 1) { shapePreRotation = Quaternion.Euler(0.0f, 0.0f, 90.0f); } if (capsuleCollider.direction == 2) { shapePreRotation = Quaternion.Euler(0.0f, 90.0f, 0.0f); } } else if (collider is BoxCollider) { BoxCollider boxCollider = collider as BoxCollider; Vector3 scale = collider.transform.localScale; Vector3 halfSize = new Vector3(boxCollider.size.x * scale.x * 0.5f, boxCollider.size.y * scale.y * 0.5f, boxCollider.size.z * scale.z * 0.5f); geometry.box.halfExtents = halfSize; flags = Flex.MakeShapeFlags(Flex.CollisionShapeType.Box, dynamic); shapeMin = -halfSize; shapeMax = halfSize; shapeCenter = boxCollider.center; shapeCenter.x *= scale.x; shapeCenter.y *= scale.y; shapeCenter.z *= scale.z; } else if (collider is MeshCollider) { MeshCollider meshCollider = collider as MeshCollider; Mesh mesh = meshCollider.sharedMesh; if (mesh) { Vector3 scale = collider.transform.localScale; Vector3 boundsMin = new Vector3(mesh.bounds.min.x * scale.x, mesh.bounds.min.y * scale.y, mesh.bounds.min.z * scale.z); Vector3 boundsMax = new Vector3(mesh.bounds.max.x * scale.x, mesh.bounds.max.y * scale.y, mesh.bounds.max.z * scale.z); Vector3[] vertices = mesh.vertices; int[] triangles = mesh.triangles; if (vertices.Length > 0 && triangles.Length > 0) { bool useConvex = meshCollider.convex; if (useConvex) { Vector4[] planes = new Vector4[triangles.Length / 3]; Vector3[] bounds = new Vector3[2]; int planeCount = FlexUtils.ConvexPlanes(ref vertices[0], ref scale, ref triangles[0], triangles.Length / 3, ref planes[0], ref bounds[0]); // Convex meshes in Flex can't have more than 64 faces if (planeCount <= 64) { m_flexConvex = Flex.CreateConvexMesh(FlexContainer.library); Flex.Buffer planeBuffer = Flex.AllocBuffer(FlexContainer.library, planeCount, sizeof(float) * 4, Flex.BufferType.Host); FlexUtils.FastCopy(planes, Flex.Map(planeBuffer)); Flex.Unmap(planeBuffer); Flex.UpdateConvexMesh(FlexContainer.library, m_flexConvex, planeBuffer, planeCount, ref bounds[0], ref bounds[1]); geometry.convexMesh.scale = Vector3.one; geometry.convexMesh.mesh = m_flexConvex; Flex.FreeBuffer(planeBuffer); flags = Flex.MakeShapeFlags(Flex.CollisionShapeType.ConvexMesh, dynamic); shapeMin = bounds[0]; shapeMax = bounds[1]; } else { useConvex = false; } } if (!useConvex) { int[] uniqueInds = new int[vertices.Length]; int[] originalToUniqueMap = new int[vertices.Length]; int uniqueVertCount = FlexExt.CreateWeldedMeshIndices(ref vertices[0], vertices.Length, ref uniqueInds[0], ref originalToUniqueMap[0], 0.0001f); // @@@ Vector4[] uniqueVerts = new Vector4[uniqueVertCount]; for (int i = 0; i < uniqueVertCount; ++i) { uniqueVerts[i] = new Vector3(vertices[uniqueInds[i]].x * scale.x, vertices[uniqueInds[i]].y * scale.y, vertices[uniqueInds[i]].z * scale.z); } Flex.Buffer vertexBuffer = Flex.AllocBuffer(FlexContainer.library, uniqueVerts.Length, sizeof(float) * 4, Flex.BufferType.Host); FlexUtils.FastCopy(uniqueVerts, Flex.Map(vertexBuffer)); Flex.Unmap(vertexBuffer); int[] indices = new int[triangles.Length]; for (int i = 0; i < triangles.Length; ++i) { indices[i] = originalToUniqueMap[triangles[i]]; } Flex.Buffer indexBuffer = Flex.AllocBuffer(FlexContainer.library, indices.Length, sizeof(int), Flex.BufferType.Host); FlexUtils.FastCopy(indices, Flex.Map(indexBuffer)); Flex.Unmap(indexBuffer); m_flexMesh = Flex.CreateTriangleMesh(FlexContainer.library); Flex.UpdateTriangleMesh(FlexContainer.library, m_flexMesh, vertexBuffer, indexBuffer, uniqueVertCount, indices.Length / 3, ref boundsMin, ref boundsMax); geometry.triMesh.scale = Vector3.one; geometry.triMesh.mesh = m_flexMesh; Flex.FreeBuffer(vertexBuffer); Flex.FreeBuffer(indexBuffer); flags = Flex.MakeShapeFlags(Flex.CollisionShapeType.TriangleMesh, dynamic); Flex.GetTriangleMeshBounds(FlexContainer.library, m_flexMesh, ref shapeMin, ref shapeMax); } } } } shapePrevPosition = collider.transform.position + collider.transform.rotation * shapeCenter; shapePrevRotation = collider.transform.rotation * shapePreRotation; }
public void TestSetRigidsGetTransforms() { float DELTA_T = 0.016f; float INTERACTION_DISTANCE = 0.5f; float SOLID_REST_DISTANCE = 0.2f; Vector3 GRAVITY = new Vector3(1, 2, 3); Flex.Library lib = Flex.Init(Flex.FLEX_VERSION, ErrorCallback); Flex.SolverDesc desc = default(Flex.SolverDesc); Flex.SetSolverDescDefaults(ref desc); desc.maxParticles = 1000; desc.maxDiffuseParticles = 1000; Flex.Solver solver = Flex.CreateSolver(lib, ref desc); Flex.Params prms = new Flex.Params(); Flex.GetParams(solver, ref prms); prms.radius = INTERACTION_DISTANCE; prms.solidRestDistance = SOLID_REST_DISTANCE; prms.gravity = GRAVITY; Flex.SetParams(solver, ref prms); Flex.Buffer particles = CreateBuffer(lib, 8, 4, new float[] { 0.1f, 0.1f, 0.1f, 1.0f, -0.1f, 0.1f, 0.1f, 1.0f, -0.1f, -0.1f, 0.1f, 1.0f, 0.1f, -0.1f, 0.1f, 1.0f, 0.1f, 0.1f, -0.1f, 1.0f, -0.1f, 0.1f, -0.1f, 1.0f, -0.1f, -0.1f, -0.1f, 1.0f, 0.1f, -0.1f, -0.1f, 1.0f, }); Flex.SetParticles(solver, particles); Flex.Buffer active = CreateBuffer(lib, 8, 1, new int[] { 0, 1, 2, 3, 4, 5, 6, 7 }); Flex.SetActive(solver, active); Flex.Buffer offsets = CreateBuffer(lib, 2, 1, new int[] { 0, 8 }); Flex.Buffer indices = CreateBuffer(lib, 8, 1, new int[] { 0, 1, 2, 3, 4, 5, 6, 7 }); Flex.Buffer positions = CreateBuffer(lib, 8, 3, new float[] { 0.1f, 0.1f, 0.1f, -0.1f, 0.1f, 0.1f, -0.1f, -0.1f, 0.1f, 0.1f, -0.1f, 0.1f, 0.1f, 0.1f, -0.1f, -0.1f, 0.1f, -0.1f, -0.1f, -0.1f, -0.1f, 0.1f, -0.1f, -0.1f, }); const float N = 0.57735026918962576450914878050196f; // 1 / sqrt(3) Flex.Buffer normals = CreateBuffer(lib, 8, 4, new float[] { N, N, N, 0, -N, N, N, 0, -N, -N, N, 0, N, -N, N, 0, N, N, -N, 0, -N, N, -N, 0, -N, -N, -N, 0, N, -N, -N, 0, }); Flex.Buffer stiffness = CreateBuffer(lib, 1, 1, new float[] { 1.0f }); Flex.Buffer thresholds = CreateBuffer(lib, 1, 1, new float[] { 1.0f }); Flex.Buffer creeps = CreateBuffer(lib, 1, 1, new float[] { 1.0f }); Flex.Buffer rotations = CreateBuffer(lib, 1, 4, new float[] { 0.0f, 0.0f, 0.0f, 1.0f }); Flex.Buffer translations = CreateBuffer(lib, 1, 3, new float[] { 0.0f, 0.0f, 0.0f }); Flex.SetRigids(solver, offsets, indices, positions, normals, stiffness, thresholds, creeps, rotations, translations, 1, 8); Flex.UpdateSolver(solver, DELTA_T, 1); Flex.Buffer nullBuffer = default(Flex.Buffer); Flex.GetRigids(solver, nullBuffer, nullBuffer, nullBuffer, nullBuffer, nullBuffer, nullBuffer, nullBuffer, rotations, translations); float[] values; ReadBuffer(lib, translations, 1, 3, out values); Vector3 expectedPosition = GRAVITY * DELTA_T * DELTA_T; Vector3 currentPosition = new Vector3(values[0], values[1], values[2]); Assert.AreEqual(expectedPosition.magnitude, currentPosition.magnitude, 0.001f); Flex.FreeBuffer(translations); Flex.FreeBuffer(rotations); Flex.FreeBuffer(creeps); Flex.FreeBuffer(thresholds); Flex.FreeBuffer(stiffness); Flex.FreeBuffer(normals); Flex.FreeBuffer(positions); Flex.FreeBuffer(indices); Flex.FreeBuffer(offsets); Flex.FreeBuffer(active); Flex.FreeBuffer(particles); Flex.DestroySolver(solver); Flex.Shutdown(lib); }