private void RecreateWeldedShape(HkShape thisShape) { if (RigidBody == null || RigidBody.IsDisposed) { Debug.Fail("Missing rigid body"); MyTrace.Send(TraceWindow.Analytics, "Recreating welded shape without RB", string.Format("{0},{1}", Entity.MarkedForClose, WeldInfo.Children.Count)); return; } ProfilerShort.Begin("RecreateWeldedShape"); //me.Tranform.Translation = Entity.PositionComp.LocalAABB.Center; if (WeldInfo.Children.Count == 0) { RigidBody.SetShape(thisShape); if (RigidBody2 != null) RigidBody2.SetShape(thisShape); } else { ProfilerShort.Begin("Create shapes"); //m_tmpElements.Add(WeldInfo.MassElement); m_tmpShapeList.Add(thisShape); foreach (var child in WeldInfo.Children) { var transformShape = new HkTransformShape(child.WeldedRigidBody.GetShape(), ref child.WeldInfo.Transform); HkShape.SetUserData(transformShape, child.WeldedRigidBody); m_tmpShapeList.Add(transformShape); //m_tmpElements.Add(child.WeldInfo.MassElement); } //var list = new HkListShape(m_tmpShapeList.ToArray(), HkReferencePolicy.None); var list = new HkSmartListShape(0); foreach (var shape in m_tmpShapeList) list.AddShape(shape); RigidBody.SetShape(list); if (RigidBody2 != null) RigidBody2.SetShape(list); list.Base.RemoveReference(); WeldedMarkBreakable(); for (int i = 1; i < m_tmpShapeList.Count; i++) m_tmpShapeList[i].RemoveReference(); m_tmpShapeList.Clear(); ProfilerShort.End(); ProfilerShort.Begin("CalcMassProps"); UpdateMassProps(); //m_tmpElements.Clear(); ProfilerShort.End(); } ProfilerShort.End(); }
public void Weld(MyPhysicsBody other, bool recreateShape = true) { if (other.WeldInfo.Parent == this) //already welded to this { return; } if (other.IsWelded && !IsWelded) { other.Weld(this); return; } if (IsWelded) { WeldInfo.Parent.Weld(other); return; } if (other.WeldInfo.Children.Count > 0) { Debug.Fail("Welding other welded gorup"); other.UnweldAll(false); //they should end in same group and get welded } ProfilerShort.Begin("Weld"); HkShape thisShape; bool firstWelded = WeldInfo.Children.Count == 0; if (firstWelded) { //RemoveConstraints(RigidBody); WeldedRigidBody = RigidBody; thisShape = RigidBody.GetShape(); if (HavokWorld != null) { HavokWorld.RemoveRigidBody(WeldedRigidBody); } RigidBody = HkRigidBody.Clone(WeldedRigidBody); if (HavokWorld != null) { HavokWorld.AddRigidBody(RigidBody); } HkShape.SetUserData(thisShape, RigidBody); Entity.OnPhysicsChanged += WeldedEntity_OnPhysicsChanged; WeldInfo.UpdateMassProps(RigidBody); //Entity.OnClose += Entity_OnClose; } else { thisShape = GetShape(); } other.Deactivate(); var transform = other.Entity.WorldMatrix * Entity.WorldMatrixInvScaled; other.WeldInfo.Transform = transform; other.WeldInfo.UpdateMassProps(other.RigidBody); Debug.Assert(other.WeldedRigidBody == null); other.WeldedRigidBody = other.RigidBody; other.RigidBody = RigidBody; other.WeldInfo.Parent = this; other.ClusterObjectID = ClusterObjectID; WeldInfo.Children.Add(other); //if(recreateShape) // RecreateWeldedShape(thisShape); ProfilerShort.BeginNextBlock("OnPhysicsChanged"); //(other.Entity as MyEntity).RaisePhysicsChanged(); //other.Entity.OnPhysicsChanged += WeldedEntity_OnPhysicsChanged; //Debug.Assert(other.m_constraints.Count == 0, "Constraints left in welded body"); ProfilerShort.BeginNextBlock("RemoveConstraints"); ProfilerShort.End(); OnWelded(other); other.OnWelded(this); }
internal unsafe HkBvCompressedMeshShape CreateShape(VrVoxelMesh mesh, int lod) { HkBvCompressedMeshShape shape; if (((mesh == null) || (mesh.TriangleCount == 0)) || (mesh.VertexCount == 0)) { return((HkBvCompressedMeshShape)HkShape.Empty); } using (MyUtils.ReuseCollection <int>(ref m_indexListCached)) { using (MyUtils.ReuseCollection <Vector3>(ref m_vertexListCached)) { using (MyUtils.ReuseCollection <byte>(ref m_materialListCached)) { List <int> indexListCached = m_indexListCached; List <Vector3> vertexListCached = m_vertexListCached; List <byte> materialListCached = m_materialListCached; vertexListCached.EnsureCapacity <Vector3>(mesh.VertexCount); indexListCached.EnsureCapacity <int>(mesh.TriangleCount * 3); materialListCached.EnsureCapacity <byte>(mesh.TriangleCount); int index = 0; while (true) { if (index >= mesh.TriangleCount) { float scale = mesh.Scale; VrVoxelVertex *vertices = mesh.Vertices; Vector3 vector = (Vector3)((mesh.Start * scale) - (this.m_voxelMap.StorageMin * 1f)); int num4 = 0; while (true) { if (num4 >= mesh.VertexCount) { uint userData = 0xfffffffe; int num5 = 0; while (true) { if (num5 >= mesh.TriangleCount) { int[] pinned numArray; try { int *numPtr; byte[] pinned buffer; if (((numArray = indexListCached.GetInternalArray <int>()) == null) || (numArray.Length == 0)) { numPtr = null; } else { numPtr = numArray; } try { byte *numPtr2; Vector3[] pinned vectorArray; if (((buffer = materialListCached.GetInternalArray <byte>()) == null) || (buffer.Length == 0)) { numPtr2 = null; } else { numPtr2 = buffer; } try { Vector3 *vectorPtr; if (((vectorArray = vertexListCached.GetInternalArray <Vector3>()) == null) || (vectorArray.Length == 0)) { vectorPtr = null; } else { vectorPtr = vectorArray; } float physicsConvexRadius = MyPerGameSettings.PhysicsConvexRadius; if (userData == -2) { userData = uint.MaxValue; } HkBvCompressedMeshShape local1 = new HkBvCompressedMeshShape(vectorPtr, vertexListCached.Count, numPtr, indexListCached.Count, numPtr2, materialListCached.Count, HkWeldingType.None, physicsConvexRadius); HkShape.SetUserData((HkShape)local1, userData); shape = local1; } finally { vectorArray = null; } } finally { buffer = null; } } finally { numArray = null; } break; } VrVoxelTriangle triangle = mesh.Triangles[num5]; byte material = vertices[triangle.V0].Material; if (userData == -2) { userData = material; } else if (userData != material) { userData = uint.MaxValue; } materialListCached.Add(material); num5++; } break; } vertexListCached.Add((vertices[num4].Position * scale) + vector); num4++; } break; } indexListCached.Add(mesh.Triangles[index].V0); indexListCached.Add(mesh.Triangles[index].V2); indexListCached.Add(mesh.Triangles[index].V1); index++; } } } } return(shape); }