/** * Generates the particle based physical representation of the cloth mesh. This is the initialization method for the cloth object * and should not be called directly once the object has been created. */ protected override IEnumerator Initialize() { initialized = false; initializing = false; if (sharedTopology == null) { Debug.LogError("No ObiMeshTopology provided. Cannot initialize physical representation."); yield break; } else if (!sharedTopology.Initialized) { Debug.LogError("The provided ObiMeshTopology contains no data. Cannot initialize physical representation."); yield break; } initializing = true; RemoveFromSolver(null); GameObject.DestroyImmediate(topology); topology = GameObject.Instantiate(sharedTopology); active = new bool[topology.heVertices.Length]; positions = new Vector3[topology.heVertices.Length]; restPositions = new Vector4[topology.heVertices.Length]; velocities = new Vector3[topology.heVertices.Length]; invMasses = new float[topology.heVertices.Length]; principalRadii = new Vector3[topology.heVertices.Length]; phases = new int[topology.heVertices.Length]; areaContribution = new float[topology.heVertices.Length]; deformableTriangles = new int[topology.heFaces.Length * 3]; initialScaleMatrix.SetTRS(Vector3.zero, Quaternion.identity, transform.lossyScale); // Create a particle for each vertex: for (int i = 0; i < topology.heVertices.Length; i++) { Oni.Vertex vertex = topology.heVertices[i]; // Get the particle's area contribution. areaContribution[i] = 0; foreach (Oni.Face face in topology.GetNeighbourFacesEnumerator(vertex)) { areaContribution[i] += topology.GetFaceArea(face) / 3; } // Get the shortest neighbour edge, particle radius will be half of its length. float minEdgeLength = Single.MaxValue; foreach (Oni.HalfEdge edge in topology.GetNeighbourEdgesEnumerator(vertex)) { // vertices at each end of the edge: Vector3 v1 = initialScaleMatrix * topology.heVertices[topology.GetHalfEdgeStartVertex(edge)].position; Vector3 v2 = initialScaleMatrix * topology.heVertices[edge.endVertex].position; minEdgeLength = Mathf.Min(minEdgeLength, Vector3.Distance(v1, v2)); } active[i] = true; invMasses[i] = (skinnedMeshRenderer == null && areaContribution[i] > 0) ? (1.0f / (DEFAULT_PARTICLE_MASS * areaContribution[i])) : 0; positions[i] = initialScaleMatrix * vertex.position; restPositions[i] = positions[i]; restPositions[i][3] = 1; // activate rest position. principalRadii[i] = Vector3.one * minEdgeLength * 0.5f; phases[i] = Oni.MakePhase(1, selfCollisions?Oni.ParticlePhase.SelfCollide:0); if (i % 500 == 0) { yield return(new CoroutineJob.ProgressInfo("ObiCloth: generating particles...", i / (float)topology.heVertices.Length)); } } // Generate deformable triangles: for (int i = 0; i < topology.heFaces.Length; i++) { Oni.Face face = topology.heFaces[i]; Oni.HalfEdge e1 = topology.heHalfEdges[face.halfEdge]; Oni.HalfEdge e2 = topology.heHalfEdges[e1.nextHalfEdge]; Oni.HalfEdge e3 = topology.heHalfEdges[e2.nextHalfEdge]; deformableTriangles[i * 3] = e1.endVertex; deformableTriangles[i * 3 + 1] = e2.endVertex; deformableTriangles[i * 3 + 2] = e3.endVertex; if (i % 500 == 0) { yield return(new CoroutineJob.ProgressInfo("ObiCloth: generating deformable geometry...", i / (float)topology.heFaces.Length)); } } List <ObiMeshTopology.HEEdge> edges = topology.GetEdgeList(); DistanceConstraints.Clear(); ObiDistanceConstraintBatch distanceBatch = new ObiDistanceConstraintBatch(true, false); DistanceConstraints.AddBatch(distanceBatch); // Create distance springs: for (int i = 0; i < edges.Count; i++) { Oni.HalfEdge hedge = topology.heHalfEdges[edges[i].halfEdgeIndex]; Oni.Vertex startVertex = topology.heVertices[topology.GetHalfEdgeStartVertex(hedge)]; Oni.Vertex endVertex = topology.heVertices[hedge.endVertex]; distanceBatch.AddConstraint(topology.GetHalfEdgeStartVertex(hedge), hedge.endVertex, Vector3.Distance(initialScaleMatrix * startVertex.position, initialScaleMatrix * endVertex.position), 1, 1); if (i % 500 == 0) { yield return(new CoroutineJob.ProgressInfo("ObiCloth: generating structural constraints...", i / (float)topology.heHalfEdges.Length)); } } // Cook distance constraints, for better cache and SIMD use: distanceBatch.Cook(); // Create aerodynamic constraints: AerodynamicConstraints.Clear(); ObiAerodynamicConstraintBatch aeroBatch = new ObiAerodynamicConstraintBatch(false, false); AerodynamicConstraints.AddBatch(aeroBatch); for (int i = 0; i < topology.heVertices.Length; i++) { aeroBatch.AddConstraint(i, areaContribution[i], AerodynamicConstraints.dragCoefficient, AerodynamicConstraints.liftCoefficient); if (i % 500 == 0) { yield return(new CoroutineJob.ProgressInfo("ObiCloth: generating aerodynamic constraints...", i / (float)topology.heFaces.Length)); } } //Create skin constraints (if needed) if (skinnedMeshRenderer != null) { SkinConstraints.Clear(); ObiSkinConstraintBatch skinBatch = new ObiSkinConstraintBatch(true, false); SkinConstraints.AddBatch(skinBatch); for (int i = 0; i < topology.heVertices.Length; ++i) { skinBatch.AddConstraint(i, initialScaleMatrix * topology.heVertices[i].position, Vector3.up, 0.05f, 0.1f, 0, 1); if (i % 500 == 0) { yield return(new CoroutineJob.ProgressInfo("ObiCloth: generating skin constraints...", i / (float)topology.heVertices.Length)); } } for (int i = 0; i < topology.normals.Length; ++i) { skinBatch.skinNormals[topology.visualMap[i]] = topology.normals[i]; } skinBatch.Cook(); } //Create pressure constraints if the mesh is closed: VolumeConstraints.Clear(); if (topology.IsClosed) { ObiVolumeConstraintBatch volumeBatch = new ObiVolumeConstraintBatch(false, false); VolumeConstraints.AddBatch(volumeBatch); float avgInitialScale = (initialScaleMatrix.m00 + initialScaleMatrix.m11 + initialScaleMatrix.m22) * 0.33f; int[] triangleIndices = new int[topology.heFaces.Length * 3]; for (int i = 0; i < topology.heFaces.Length; i++) { Oni.Face face = topology.heFaces[i]; Oni.HalfEdge e1 = topology.heHalfEdges[face.halfEdge]; Oni.HalfEdge e2 = topology.heHalfEdges[e1.nextHalfEdge]; Oni.HalfEdge e3 = topology.heHalfEdges[e2.nextHalfEdge]; triangleIndices[i * 3] = e1.endVertex; triangleIndices[i * 3 + 1] = e2.endVertex; triangleIndices[i * 3 + 2] = e3.endVertex; if (i % 500 == 0) { yield return(new CoroutineJob.ProgressInfo("ObiCloth: generating volume constraints...", i / (float)topology.heFaces.Length)); } } volumeBatch.AddConstraint(triangleIndices, topology.MeshVolume * avgInitialScale, 1, 1); } //Create bending constraints: BendingConstraints.Clear(); ObiBendConstraintBatch bendBatch = new ObiBendConstraintBatch(true, false); BendingConstraints.AddBatch(bendBatch); Dictionary <int, int> cons = new Dictionary <int, int>(); for (int i = 0; i < topology.heVertices.Length; i++) { Oni.Vertex vertex = topology.heVertices[i]; foreach (Oni.Vertex n1 in topology.GetNeighbourVerticesEnumerator(vertex)) { float cosBest = 0; Oni.Vertex vBest = n1; foreach (Oni.Vertex n2 in topology.GetNeighbourVerticesEnumerator(vertex)) { float cos = Vector3.Dot((n1.position - vertex.position).normalized, (n2.position - vertex.position).normalized); if (cos < cosBest) { cosBest = cos; vBest = n2; } } if (!cons.ContainsKey(vBest.index) || cons[vBest.index] != n1.index) { cons[n1.index] = vBest.index; Vector3 n1Pos = initialScaleMatrix * n1.position; Vector3 bestPos = initialScaleMatrix * vBest.position; Vector3 vertexPos = initialScaleMatrix * vertex.position; float[] bendRestPositions = new float[] { n1Pos[0], n1Pos[1], n1Pos[2], bestPos[0], bestPos[1], bestPos[2], vertexPos[0], vertexPos[1], vertexPos[2] }; float restBend = Oni.BendingConstraintRest(bendRestPositions); bendBatch.AddConstraint(n1.index, vBest.index, vertex.index, restBend, 0, 1); } } if (i % 500 == 0) { yield return(new CoroutineJob.ProgressInfo("ObiCloth: adding bend constraints...", i / (float)sharedTopology.heVertices.Length)); } } bendBatch.Cook(); // Initialize tether constraints: TetherConstraints.Clear(); // Initialize pin constraints: PinConstraints.Clear(); ObiPinConstraintBatch pinBatch = new ObiPinConstraintBatch(false, false); PinConstraints.AddBatch(pinBatch); initializing = false; initialized = true; if (skinnedMeshRenderer == null) { InitializeWithRegularMesh(); } else { InitializeWithSkinnedMesh(); } }
public void SetCollisionMaterials(ObiNativeCollisionMaterialList materials) { Oni.SetCollisionMaterials(materials.GetIntPtr()); }
public void SetEdgeMeshData(ObiNativeEdgeMeshHeaderList headers, ObiNativeBIHNodeList nodes, ObiNativeEdgeList edges, ObiNativeVector2List vertices) { Oni.SetEdgeMeshData(headers.GetIntPtr(), nodes.GetIntPtr(), edges.GetIntPtr(), vertices.GetIntPtr()); }
/** * Sends blueprint particle data to the solver. */ private void LoadBlueprintParticles(ObiActorBlueprint bp) { Matrix4x4 l2sTransform = actorLocalToSolverMatrix; Quaternion l2sRotation = l2sTransform.rotation; for (int i = 0; i < solverIndices.Length; i++) { int k = solverIndices[i]; if (bp.positions != null && i < bp.positions.Length) { m_Solver.startPositions[k] = m_Solver.prevPositions[k] = m_Solver.positions[k] = l2sTransform.MultiplyPoint3x4(bp.positions[i]); m_Solver.renderablePositions[k] = l2sTransform.MultiplyPoint3x4(bp.positions[i]); } if (bp.orientations != null && i < bp.orientations.Length) { m_Solver.startOrientations[k] = m_Solver.prevOrientations[k] = m_Solver.orientations[k] = l2sRotation * bp.orientations[i]; m_Solver.renderableOrientations[k] = l2sRotation * bp.orientations[i]; } if (bp.velocities != null && i < bp.velocities.Length) { m_Solver.velocities[k] = l2sTransform.MultiplyVector(bp.velocities[i]); } if (bp.angularVelocities != null && i < bp.angularVelocities.Length) { m_Solver.angularVelocities[k] = l2sTransform.MultiplyVector(bp.angularVelocities[i]); } if (bp.invMasses != null && i < bp.invMasses.Length) { m_Solver.invMasses[k] = bp.invMasses[i]; } if (bp.invRotationalMasses != null && i < bp.invRotationalMasses.Length) { m_Solver.invRotationalMasses[k] = bp.invRotationalMasses[i]; } if (bp.principalRadii != null && i < bp.principalRadii.Length) { m_Solver.principalRadii[k] = bp.principalRadii[i]; } if (bp.phases != null && i < bp.phases.Length) { m_Solver.phases[k] = Oni.MakePhase(bp.phases[i], 0); } if (bp.restPositions != null && i < bp.restPositions.Length) { m_Solver.restPositions[k] = bp.restPositions[i]; } if (bp.restOrientations != null && i < bp.restOrientations.Length) { m_Solver.restOrientations[k] = bp.restOrientations[i]; } if (bp.colors != null && i < bp.colors.Length) { m_Solver.colors[k] = bp.colors[i]; } } m_ActiveParticleCount = blueprint.activeParticleCount; m_Solver.activeParticleCountChanged = true; // Push active particles to the solver: m_Solver.PushActiveParticles(); // Recalculate inertia tensors (shape matching constraints rest shape need up to date inertia tensors, for instance). Oni.RecalculateInertiaTensors(m_Solver.OniSolver); // Push collision materials: PushCollisionMaterial(); }
public void SetColliders(ObiNativeColliderShapeList shapes, ObiNativeAabbList bounds, ObiNativeAffineTransformList transforms, int count) { Oni.SetColliders(shapes.GetIntPtr(), bounds.GetIntPtr(), transforms.GetIntPtr(), count); }
public void CalculateRestShapeMatching() { Oni.RecalculateInertiaTensors(((OniSolverImpl)this.constraints.solver).oniSolver); Oni.CalculateRestShapeMatching(((OniSolverImpl)this.constraints.solver).oniSolver, oniBatch); }
public void SetHeightFieldData(ObiNativeHeightFieldHeaderList headers, ObiNativeFloatList samples) { Oni.SetHeightFieldData(headers.GetIntPtr(), samples.GetIntPtr()); }
void UpdateHeightmaps() { Oni.UnpinMemory(heightmapsHandle); heightmapsHandle = Oni.PinMemory(oniHeightmaps.ToArray()); Oni.SetHeightmapShapes(oniColliderGroup, heightmapsHandle.AddrOfPinnedObject()); }
void OnEnable() { oniColliderGroup = Oni.CreateColliderGroup(); UpdateBodiesInfo(); }
void UpdateBoxes() { Oni.UnpinMemory(boxesHandle); boxesHandle = Oni.PinMemory(oniBoxes.ToArray()); Oni.SetBoxShapes(oniColliderGroup, boxesHandle.AddrOfPinnedObject()); }
void UpdateCapsules() { Oni.UnpinMemory(capsulesHandle); capsulesHandle = Oni.PinMemory(oniCapsules.ToArray()); Oni.SetCapsuleShapes(oniColliderGroup, capsulesHandle.AddrOfPinnedObject()); }
void UpdateSpheres() { Oni.UnpinMemory(spheresHandle); spheresHandle = Oni.PinMemory(oniSpheres.ToArray()); Oni.SetSphereShapes(oniColliderGroup, spheresHandle.AddrOfPinnedObject()); }
/** * Removes this collider from a given solver. */ public void RemoveFromSolver(ObiSolver solver) { solvers.Remove(solver); Oni.RemoveCollider(solver.OniSolver, oniCollider); }
public void Teardown() { Oni.UnpinMemory(activeConstraintsHandle); CustomTeardown(); }
/** * Sends local particle data to the solver. */ public virtual void PushDataToSolver(ParticleData data = ParticleData.NONE) { if (!InSolver) { return; } Matrix4x4 l2sTransform = ActorLocalToSolverMatrix; Quaternion l2sRotation = l2sTransform.rotation; for (int i = 0; i < particleIndices.Length; i++) { int k = particleIndices[i]; if ((data & ParticleData.POSITIONS) != 0 && positions != null && i < positions.Length) { solver.positions[k] = l2sTransform.MultiplyPoint3x4(positions[i]); } if ((data & ParticleData.ORIENTATIONS) != 0 && orientations != null && i < orientations.Length) { solver.orientations[k] = l2sRotation * orientations[i]; } if ((data & ParticleData.VELOCITIES) != 0 && velocities != null && i < velocities.Length) { solver.velocities[k] = l2sTransform.MultiplyVector(velocities[i]); } if ((data & ParticleData.ANGULAR_VELOCITIES) != 0 && angularVelocities != null && i < angularVelocities.Length) { solver.angularVelocities[k] = l2sTransform.MultiplyVector(angularVelocities[i]); } if ((data & ParticleData.INV_MASSES) != 0 && invMasses != null && i < invMasses.Length) { solver.invMasses[k] = invMasses[i]; } if ((data & ParticleData.INV_ROTATIONAL_MASSES) != 0 && invRotationalMasses != null && i < invRotationalMasses.Length) { solver.invRotationalMasses[k] = invRotationalMasses[i]; } if ((data & ParticleData.PRINCIPAL_RADII) != 0 && principalRadii != null && i < principalRadii.Length) { solver.principalRadii[k] = principalRadii[i]; } if ((data & ParticleData.PHASES) != 0 && phases != null && i < phases.Length) { solver.phases[k] = phases[i]; } if ((data & ParticleData.REST_POSITIONS) != 0 && restPositions != null && i < restPositions.Length) { solver.restPositions[k] = restPositions[i]; } if ((data & ParticleData.REST_ORIENTATIONS) != 0 && restOrientations != null && i < restOrientations.Length) { solver.restOrientations[k] = restOrientations[i]; } } if ((data & ParticleData.COLLISION_MATERIAL) != 0) { IntPtr[] materials = new IntPtr[particleIndices.Length]; for (int i = 0; i < particleIndices.Length; i++) { materials[i] = collisionMaterial != null ? collisionMaterial.OniCollisionMaterial : IntPtr.Zero; } Oni.SetCollisionMaterials(solver.OniSolver, materials, particleIndices, particleIndices.Length); } if ((data & ParticleData.ACTIVE_STATUS) != 0) { solver.UpdateActiveParticles(); } // Recalculate inertia tensors if needed: if ((data & (ParticleData.PRINCIPAL_RADII | ParticleData.INV_ROTATIONAL_MASSES | ParticleData.INV_MASSES)) != 0) { Oni.RecalculateInertiaTensors(solver.OniSolver); } }
public void SetSkinConstraints(ObiNativeIntList particleIndices, ObiNativeVector4List skinPoints, ObiNativeVector4List skinNormals, ObiNativeFloatList skinRadiiBackstop, ObiNativeFloatList skinCompliance, ObiNativeFloatList lambdas, int count) { Oni.SetSkinConstraints(oniBatch, particleIndices.GetIntPtr(), skinPoints.GetIntPtr(), skinNormals.GetIntPtr(), skinRadiiBackstop.GetIntPtr(), skinCompliance.GetIntPtr(), lambdas.GetIntPtr(), count); }
public void RemoveBatch(IAerodynamicConstraintsBatchImpl batch) { Oni.RemoveBatch(((OniSolverImpl)solver).oniSolver, ((OniConstraintsBatchImpl)batch).oniBatch); }
// Update is called once per frame void FixedUpdate() { if (pickArgs1 != null && cnt1 == 0) { ObiSolver solver = picker.Cloth.Solver; Vector3 targetPosition = pickArgs1.worldPosition; if (solver.simulateInLocalSpace) { targetPosition = solver.transform.InverseTransformPoint(targetPosition); } // TAG THIS PARTICLE produce a little sphere once click Vector4[] positions = new Vector4[1]; Vector4[] velocities = new Vector4[1]; int solverIndex = picker.Cloth.particleIndices[pickArgs1.particleIndex]; Oni.GetParticlePositions(solver.OniSolver, positions, 1, solverIndex); // Oni.GetParticlePositions() GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); //Debug.Log(sphere.GetType()); sphere.transform.position = positions[0]; sphere.transform.localScale = new Vector3(0.04f, 0.04f, 0.04f); sphere.AddComponent <ObiCollider>(); Renderer thissphere = sphere.GetComponent <Renderer>(); thissphere.material.color = Color.red; tmptwoobjectfordraw[0] = sphere; sphere.GetComponent <ObiCollider>().Phase = 1; // particleindexsphere[counttwo][4] = pickArgs.particleIndex; // centerparciel[0] = pickArgs1.particleIndex; countparticle++; cnt1++; } else if (pickArgs2 != null && cnt2 == 0) { ObiSolver solver = picker.Cloth.Solver; Vector3 targetPosition = pickArgs2.worldPosition; if (solver.simulateInLocalSpace) { targetPosition = solver.transform.InverseTransformPoint(targetPosition); } // TAG THIS PARTICLE produce a little sphere once click Vector4[] positions = new Vector4[1]; Vector4[] velocities = new Vector4[1]; int solverIndex = picker.Cloth.particleIndices[pickArgs2.particleIndex]; Oni.GetParticlePositions(solver.OniSolver, positions, 1, solverIndex); // Oni.GetParticlePositions() GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); //Debug.Log(sphere.GetType()); sphere.transform.position = positions[0]; sphere.transform.localScale = new Vector3(0.04f, 0.04f, 0.04f); sphere.AddComponent <ObiCollider>(); Renderer thissphere = sphere.GetComponent <Renderer>(); thissphere.material.color = Color.blue; tmptwoobjectfordraw[1] = sphere; sphere.GetComponent <ObiCollider>().Phase = 1; // particleindexsphere[counttwo][4] = pickArgs.particleIndex; //centerparciel[1] = pickArgs2.particleIndex; countparticle++; cnt2++; rotateaxis = tmptwoobjectfordraw[1].transform.position - tmptwoobjectfordraw[0].transform.position; rotatepoint = (tmptwoobjectfordraw[1].transform.position + tmptwoobjectfordraw[0].transform.position) / 2; } if (cnt1 == 1 && cnt2 == 1 && dflag == 0) { dflag = 1; } if (draw_line_instruction.flag == 2 && flag == 0) //two black { //Debug.Log("pos"); if (pickArgs3 != null && cnt3 == 0) { //Debug.Log("pos==="); ObiSolver solver = picker.Cloth.Solver; Vector3 targetPosition = pickArgs3.worldPosition; if (solver.simulateInLocalSpace) { targetPosition = solver.transform.InverseTransformPoint(targetPosition); } // TAG THIS PARTICLE produce a little sphere once click Vector4[] positions = new Vector4[1]; Vector4[] velocities = new Vector4[1]; int solverIndex = picker.Cloth.particleIndices[pickArgs3.particleIndex]; Oni.GetParticlePositions(solver.OniSolver, positions, 1, solverIndex); // Oni.GetParticlePositions() GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); //Debug.Log(sphere.GetType()); sphere.transform.position = positions[0]; sphere.transform.localScale = new Vector3(0.04f, 0.04f, 0.04f); sphere.AddComponent <ObiCollider>(); Renderer thissphere = sphere.GetComponent <Renderer>(); thissphere.material.color = Color.black; twoobject[0] = sphere; sphere.GetComponent <ObiCollider>().Phase = 1; // particleindexsphere[counttwo][4] = pickArgs.particleIndex; centerparciel[0] = pickArgs3.particleIndex; countparticle++; cnt3++; } if (pickArgs4 != null && cnt4 == 0) { ObiSolver solver = picker.Cloth.Solver; Vector3 targetPosition = pickArgs4.worldPosition; if (solver.simulateInLocalSpace) { targetPosition = solver.transform.InverseTransformPoint(targetPosition); } // TAG THIS PARTICLE produce a little sphere once click Vector4[] positions = new Vector4[1]; Vector4[] velocities = new Vector4[1]; int solverIndex = picker.Cloth.particleIndices[pickArgs4.particleIndex]; Oni.GetParticlePositions(solver.OniSolver, positions, 1, solverIndex); // Oni.GetParticlePositions() GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); //Debug.Log(sphere.GetType()); sphere.transform.position = positions[0]; sphere.transform.localScale = new Vector3(0.04f, 0.04f, 0.04f); sphere.AddComponent <ObiCollider>(); Renderer thissphere = sphere.GetComponent <Renderer>(); thissphere.material.color = Color.black; twoobject[1] = sphere; sphere.GetComponent <ObiCollider>().Phase = 1; // particleindexsphere[counttwo][4] = pickArgs.particleIndex; centerparciel[1] = pickArgs4.particleIndex; countparticle++; cnt4++; } flag = 1; pinrotate_ready(); } else if (draw_line_instruction.flag == 2 && flag == 1) { rotatenow(); } }
protected override void UpdateAdaptor() { adaptor.Set(sourceCollider, Phase, Thickness); Oni.UpdateCollider(oniCollider, ref adaptor); }
public void StartStep() { Oni.SignalFrameStart(); }
public void OnDisable() { Oni.DestroyDistanceField(oniDistanceField); }
/** * Generates the particle based physical representation of the bone hierarcht. This is the initialization method for the actor * and should not be called directly once the object has been created. */ protected override IEnumerator Initialize() { initialized = false; initializing = true; RemoveFromSolver(null); // get a list of bones in preorder: bones = new List <Transform>(); foreach (Transform bone in EnumerateBonesBreadthFirst()) { bones.Add(bone); } parentIndices = new int[bones.Count]; active = new bool[bones.Count]; positions = new Vector3[bones.Count]; velocities = new Vector3[bones.Count]; invMasses = new float[bones.Count]; solidRadii = new float[bones.Count]; phases = new int[bones.Count]; restPositions = new Vector4[bones.Count]; frozen = new bool[bones.Count]; DistanceConstraints.Clear(); ObiDistanceConstraintBatch distanceBatch = new ObiDistanceConstraintBatch(false, false, MIN_YOUNG_MODULUS, MAX_YOUNG_MODULUS); DistanceConstraints.AddBatch(distanceBatch); BendingConstraints.Clear(); ObiBendConstraintBatch bendingBatch = new ObiBendConstraintBatch(false, false, MIN_YOUNG_MODULUS, MAX_YOUNG_MODULUS); BendingConstraints.AddBatch(bendingBatch); SkinConstraints.Clear(); ObiSkinConstraintBatch skinBatch = new ObiSkinConstraintBatch(true, false, MIN_YOUNG_MODULUS, MAX_YOUNG_MODULUS); SkinConstraints.AddBatch(skinBatch); for (int i = 0; i < bones.Count; ++i) { active[i] = true; invMasses[i] = 1.0f / DEFAULT_PARTICLE_MASS; positions[i] = transform.InverseTransformPoint(bones[i].position); restPositions[i] = positions[i]; restPositions[i][3] = 0; solidRadii[i] = particleRadius; frozen[i] = false; phases[i] = Oni.MakePhase(1, selfCollisions?Oni.ParticlePhase.SelfCollide:0); parentIndices[i] = -1; if (bones[i].parent != null) { parentIndices[i] = bones.IndexOf(bones[i].parent); } skinBatch.AddConstraint(i, positions[i], Vector3.up, 0.05f, 0, 0, 1); foreach (Transform child in bones[i]) { int childIndex = bones.IndexOf(child); if (childIndex >= 0) { // add distance constraint between the bone and its child. distanceBatch.AddConstraint(i, childIndex, Vector3.Distance(bones[i].position, child.position), 1, 1); if (parentIndices[i] >= 0) { Transform parent = bones[parentIndices[i]]; float[] restPositions = new float[] { parent.position[0], parent.position[1], parent.position[2], child.position[0], child.position[1], child.position[2], bones[i].position[0], bones[i].position[1], bones[i].position[2] }; float restBend = Oni.BendingConstraintRest(restPositions); // add bend constraint between the bone, its parent and its child. bendingBatch.AddConstraint(parentIndices[i], childIndex, i, restBend, 0, 0); } } } if (i % 10 == 0) { yield return(new CoroutineJob.ProgressInfo("ObiBone: generating particles...", i / (float)bones.Count)); } } skinBatch.Cook(); initializing = false; initialized = true; }
public void UpdateWorld() { Oni.UpdateColliderGrid(); }
public void RemoveBatch(IDistanceConstraintsBatchImpl batch) { Oni.RemoveBatch(((OniSolverImpl)solver).oniSolver, ((OniConstraintsBatchImpl)batch).oniBatch); }
public void SetRigidbodies(ObiNativeRigidbodyList rigidbody) { Oni.SetRigidbodies(rigidbody.GetIntPtr()); }
public void AccumulateSimulationTime(float dt) { Oni.AddSimulationTime(oniSolver, dt); }
public void SetTriangleMeshData(ObiNativeTriangleMeshHeaderList headers, ObiNativeBIHNodeList nodes, ObiNativeTriangleList triangles, ObiNativeVector3List vertices) { Oni.SetTriangleMeshData(headers.GetIntPtr(), nodes.GetIntPtr(), triangles.GetIntPtr(), vertices.GetIntPtr()); }
public void ResetSimulationTime() { Oni.ResetSimulationTime(oniSolver); }
public void SetDistanceFieldData(ObiNativeDistanceFieldHeaderList headers, ObiNativeDFNodeList nodes) { Oni.SetDistanceFieldData(headers.GetIntPtr(), nodes.GetIntPtr()); }
public ObiCapsuleShapeTracker(CharacterController collider) { this.collider = collider; adaptor.is2D = false; oniShape = Oni.CreateShape(Oni.ShapeType.Capsule); }