public static HkContactBodyData?CastShapeReturnContactBodyData(Vector3D to, HkShape shape, ref MatrixD transform, uint collisionFilter, float extraPenetration, bool ignoreConvexShape = true) { m_resultWorlds.Clear(); Clusters.Intersects(to, m_resultWorlds); if (m_resultWorlds.Count == 0) { return(null); } var world = m_resultWorlds[0]; Matrix transformF = transform; transformF.Translation = (Vector3)(transform.Translation - world.AABB.Center); Vector3 toF = (Vector3)(to - world.AABB.Center); HkContactBodyData?result = ((HkWorld)world.UserData).CastShapeReturnContactBodyData(toF, shape, ref transformF, collisionFilter, extraPenetration); if (result == null) { return(null); } HkContactBodyData cpd = result.Value; cpd.HitPosition += world.AABB.Center; return(cpd); }
public static Vector3D?CastShapeReturnPoint(Vector3D to, HkShape shape, ref MatrixD transform, int filterLayer, float extraPenetration) { m_resultWorlds.Clear(); Clusters.Intersects(to, m_resultWorlds); if (m_resultWorlds.Count == 0) { return(null); } var world = m_resultWorlds[0]; Matrix transformF = transform; transformF.Translation = (Vector3)(transform.Translation - world.AABB.Center); Vector3 toF = (Vector3)(to - world.AABB.Center); var result = ((HkWorld)world.UserData).CastShapeReturnPoint(toF, shape, ref transformF, filterLayer, extraPenetration); if (result == null) { return(null); } return((Vector3D)result + world.AABB.Center); }
protected override void OnComplete() { base.OnComplete(); if (((MySession.Static != null) == MySession.Static.GetComponent <MyPrecalcComponent>().Loaded) && !this.m_isCancelled) { this.m_targetPhysics.OnBatchTaskComplete(this.m_newShapes, this.Lod); } foreach (HkBvCompressedMeshShape shape in this.m_newShapes.Values) { HkShape shape2 = shape.Base; if (!shape2.IsZero) { shape.Base.RemoveReference(); } } if (ReferenceEquals(this.m_targetPhysics.RunningBatchTask[this.Lod], this)) { this.m_targetPhysics.RunningBatchTask[this.Lod] = null; } this.m_targetPhysics = null; this.CellBatch.Clear(); this.m_newShapes.Clear(); this.m_isCancelled = false; m_instancePool.Deallocate(this); }
public override void CreatePhysicsShape(out HkShape shape, out HkMassProperties massProperties, float mass) { HkSphereShape shape2 = new HkSphereShape((0.5f * ((MyEntity)base.Entity).Render.GetModel().BoundingSphere.Radius) * base.Entity.PositionComp.Scale.Value); shape = (HkShape)shape2; massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(shape2.Radius * 0.5f, mass); }
public virtual void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties) { var boxShape = new HkBoxShape(((((MyEntity)Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value); shape = boxShape; massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, massProperties.Mass); }
HkShape CreateShape(MyModel model, HkShapeType shapeType) { if (model.HavokCollisionShapes != null && model.HavokCollisionShapes.Length > 0) { HkShape sh = model.HavokCollisionShapes[0]; sh.AddReference(); return(sh); } switch (shapeType) { case HkShapeType.Box: Vector3 halfExtents = (model.BoundingBox.Max - model.BoundingBox.Min) / 2; return(new HkBoxShape(Vector3.Max(halfExtents - 0.1f, new Vector3(0.05f)), 0.02f)); break; case HkShapeType.Sphere: return(new HkSphereShape(model.BoundingSphere.Radius)); break; case HkShapeType.ConvexVertices: m_tmpVerts.Clear(); for (int i = 0; i < model.GetVerticesCount(); i++) { m_tmpVerts.Add(model.GetVertex(i)); } return(new HkConvexVerticesShape(m_tmpVerts.GetInternalArray(), m_tmpVerts.Count, true, 0.1f)); break; } throw new InvalidOperationException("This shape is not supported"); }
public override void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties) { var sphereShape = new HkSphereShape(((MyEntity)Entity).Render.GetModel().BoundingSphere.Radius *Entity.PositionComp.Scale.Value); shape = sphereShape; massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(sphereShape.Radius, 1); }
private void CreateConstraint(MyEntitySubpart subpart, ref HkConstraint constraint, ref HkFixedConstraintData constraintData) { if (subpart != null) { bool flag = !Sync.IsServer; if (subpart.Physics == null) { HkShape[] havokCollisionShapes = subpart.ModelCollision.HavokCollisionShapes; if ((havokCollisionShapes != null) && (havokCollisionShapes.Length != 0)) { MyPhysicsBody body = new MyPhysicsBody(subpart, flag ? RigidBodyFlag.RBF_STATIC : (RigidBodyFlag.RBF_UNLOCKED_SPEEDS | RigidBodyFlag.RBF_DOUBLED_KINEMATIC)) { IsSubpart = true }; subpart.Physics = body; HkShape shape = havokCollisionShapes[0]; MyPositionComponentBase positionComp = subpart.PositionComp; Vector3 center = positionComp.LocalVolume.Center; HkMassProperties properties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(positionComp.LocalAABB.HalfExtents, 100f); int collisionFilter = base.CubeGrid.IsStatic ? 9 : 0x10; body.CreateFromCollisionObject(shape, center, positionComp.WorldMatrix, new HkMassProperties?(properties), collisionFilter); } } if (flag) { subpart.Physics.Enabled = true; } else { base.CreateSubpartConstraint(subpart, out constraintData, out constraint); base.CubeGrid.Physics.AddConstraint(constraint); constraint.SetVirtualMassInverse(Vector4.Zero, Vector4.One); } } }
public static HkShape CreateCharacterShape(float height, float width, float headHeight, float headSize, float headForwardOffset, float downOffset = 0, bool capsuleForHead = false) { HkCapsuleShape capsule = new HkCapsuleShape(Vector3.Up * (height - downOffset) / 2.0f, Vector3.Down * (height) / 2.0f, width / 2.0f); if (headSize > 0) { HkConvexShape headShape; if (capsuleForHead) { headShape = new HkCapsuleShape(new Vector3(0, 0, -0.3f), new Vector3(0, 0, 0.3f), headSize); } else { headShape = new HkSphereShape(headSize); } //headShape = new HkCapsuleShape(new Vector3(0, 0, -0.05f), new Vector3(0, 0, 0.05f), headSize); HkShape[] shapes = new HkShape[] { capsule, new HkConvexTranslateShape(headShape, Vector3.Up * (headHeight - downOffset) / 2.0f + Vector3.Forward * headForwardOffset, HkReferencePolicy.TakeOwnership), }; return(new HkListShape(shapes, shapes.Length, HkReferencePolicy.TakeOwnership)); } else { return(capsule); } }
public static bool CastShapeReturnContactBodyDatas(Vector3D to, HkShape shape, ref MatrixD transform, uint collisionFilter, float extraPenetration, List <HkContactBodyData> result, bool ignoreConvexShape = true) { m_resultWorlds.Clear(); Clusters.Intersects(to, m_resultWorlds); if (m_resultWorlds.Count == 0) { return(false); } var world = m_resultWorlds[0]; Matrix transformF = transform; transformF.Translation = (Vector3)(transform.Translation - world.AABB.Center); Vector3 toF = (Vector3)(to - world.AABB.Center); m_resultShapeCasts.Clear(); if (((HkWorld)world.UserData).CastShapeReturnContactBodyDatas(toF, shape, ref transformF, collisionFilter, extraPenetration, m_resultShapeCasts)) { foreach (var res in m_resultShapeCasts) { HkContactBodyData cpd = res.Value; cpd.HitPosition += world.AABB.Center; result.Add(cpd); } return(true); } return(false); }
public static HkShape CreateCharacterShape(float height, float width, float headHeight, float headSize, float headForwardOffset, float downOffset = 0, bool capsuleForHead = false) { HkCapsuleShape capsule = new HkCapsuleShape(Vector3.Up * (height - downOffset) / 2.0f, Vector3.Down * (height) / 2.0f, width / 2.0f); if (headSize > 0) { HkConvexShape headShape; if (capsuleForHead) { headShape = new HkCapsuleShape(new Vector3(0, 0, -0.3f), new Vector3(0, 0, 0.3f), headSize); } else { headShape = new HkSphereShape(headSize); } //headShape = new HkCapsuleShape(new Vector3(0, 0, -0.05f), new Vector3(0, 0, 0.05f), headSize); HkShape[] shapes = new HkShape[] { capsule, new HkConvexTranslateShape(headShape, Vector3.Up * (headHeight - downOffset) / 2.0f + Vector3.Forward * headForwardOffset, HkReferencePolicy.TakeOwnership), }; return new HkListShape(shapes, shapes.Length, HkReferencePolicy.TakeOwnership); } else { return capsule; } }
public static HkContactPoint?CastShapeReturnContact(Vector3D to, HkShape shape, ref MatrixD transform, int filterLayer, float extraPenetration, out Vector3 worldTranslation) { m_resultWorlds.Clear(); Clusters.Intersects(to, m_resultWorlds); worldTranslation = Vector3.Zero; if (m_resultWorlds.Count == 0) { return(null); } var world = m_resultWorlds[0]; worldTranslation = world.AABB.Center; Matrix transformF = transform; transformF.Translation = (Vector3)(transform.Translation - world.AABB.Center); Vector3 toF = (Vector3)(to - world.AABB.Center); HkContactPoint?result = ((HkWorld)world.UserData).CastShapeReturnContact(toF, shape, ref transformF, filterLayer, extraPenetration); if (result == null) { return(null); } return(result); }
public override void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties) { var sphereShape = new HkSphereShape(((MyEntity)Entity).Render.GetModel().BoundingSphere.Radius * Entity.PositionComp.Scale.Value); shape = sphereShape; var mass = SphereMass(sphereShape.Radius, VoxelDensity); massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(sphereShape.Radius, mass); }
public static bool GetShapeCenter(HkShape shape, uint shapeKey, MyCubeGrid grid, ref Vector3D shapeCenter) { bool shapeSet = true; switch (shape.ShapeType) { case HkShapeType.List: var listShape = (HkListShape)shape; shape = listShape.GetChildByIndex((int)shapeKey); break; case HkShapeType.Mopp: var moppShape = (HkMoppBvTreeShape)shape; shape = moppShape.ShapeCollection.GetShape(shapeKey, null); break; case HkShapeType.Box: var boxShape = (HkBoxShape)shape; shape = boxShape; break; case HkShapeType.ConvexTranslate: var convexTranslateShape = (HkConvexShape)shape; shape = convexTranslateShape; break; case HkShapeType.ConvexTransform: var convexTransformShape = (HkConvexTransformShape)shape; shape = convexTransformShape; break; /* case HkShapeType.BvTree: * var bvTreeShape = (HkBvTreeShape)shape; * var iterator = bvTreeShape.Base.GetContainer(); * while (iterator.CurrentValue.IsContainer() && iterator.CurrentValue.ShapeType != HkShapeType.ConvexTranslate && iterator.CurrentValue.ShapeType != HkShapeType.ConvexTransform) * iterator.Next(); * if (iterator.IsValid) * shape = iterator.CurrentValue; * else * shapeSet = false; * break;*/ default: shapeSet = false; break; } if (shapeSet) { Vector4 min4, max4; shape.GetLocalAABB(0.05f, out min4, out max4); Vector3 worldMin = Vector3.Transform(new Vector3(min4), grid.PositionComp.WorldMatrix); Vector3 worldMax = Vector3.Transform(new Vector3(max4), grid.PositionComp.WorldMatrix); var worldAABB = new BoundingBoxD(worldMin, worldMax); shapeCenter = worldAABB.Center; } return(shapeSet); }
public virtual void CreatePhysicsShape(out HkShape shape, out HkMassProperties massProperties, float mass) { HkBoxShape shape2 = new HkBoxShape(((((MyEntity)base.Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)base.Entity).Render.GetModel().BoundingBox.Min) / 2f) * base.Entity.PositionComp.Scale.Value); Vector3 translation = (((MyEntity)base.Entity).Render.GetModel().BoundingBox.Max + ((MyEntity)base.Entity).Render.GetModel().BoundingBox.Min) / 2f; shape = (HkShape) new HkTransformShape((HkShape)shape2, ref translation, ref Quaternion.Identity); massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(shape2.HalfExtents, mass); massProperties.CenterOfMass = translation; }
public virtual void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties) { var boxShape = new HkBoxShape(((((MyEntity)Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value); var pos = ((((MyEntity)Entity).Render.GetModel().BoundingBox.Max + ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2); shape = new HkTransformShape(boxShape, ref pos, ref Quaternion.Identity); //shape = boxShape; massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, boxShape.HalfExtents.Volume * 0.5f); massProperties.CenterOfMass = pos; }
public static bool GetShapeCenter(HkShape shape, uint shapeKey, MyCubeGrid grid, ref Vector3D shapeCenter) { return false; //Disabled because of bad computing shapeCenter in relation with grid (alway around grid center). //Called on grid part which has havok shape (only door?). bool shapeSet = true; switch (shape.ShapeType) { case HkShapeType.List: var listShape = (HkListShape)shape; shape = listShape.GetChildByIndex((int)shapeKey); break; case HkShapeType.Mopp: var moppShape = (HkMoppBvTreeShape)shape; shape = moppShape.ShapeCollection.GetShape(shapeKey, null); break; case HkShapeType.Box: var boxShape = (HkBoxShape)shape; shape = boxShape; break; case HkShapeType.ConvexTranslate: var convexTranslateShape = (HkConvexShape)shape; shape = convexTranslateShape; break; case HkShapeType.ConvexTransform: var convexTransformShape = (HkConvexTransformShape)shape; shape = convexTransformShape; break; /* case HkShapeType.BvTree: var bvTreeShape = (HkBvTreeShape)shape; var iterator = bvTreeShape.Base.GetContainer(); while (iterator.CurrentValue.IsContainer() && iterator.CurrentValue.ShapeType != HkShapeType.ConvexTranslate && iterator.CurrentValue.ShapeType != HkShapeType.ConvexTransform) iterator.Next(); if (iterator.IsValid) shape = iterator.CurrentValue; else shapeSet = false; break;*/ default: shapeSet = false; break; } if (shapeSet) { Vector4 min4, max4; shape.GetLocalAABB(0.05f, out min4, out max4); Vector3 worldMin = Vector3.Transform(new Vector3(min4), grid.PositionComp.WorldMatrix); Vector3 worldMax = Vector3.Transform(new Vector3(max4), grid.PositionComp.WorldMatrix); var worldAABB = new BoundingBoxD(worldMin, worldMax); shapeCenter = worldAABB.Center; } return shapeSet; }
public static void GetPenetrationsShape(HkShape shape, ref Vector3D translation, ref Quaternion rotation, List <HkRigidBody> results, int filter) { m_resultWorlds.Clear(); Clusters.Intersects(translation, m_resultWorlds); foreach (var world in m_resultWorlds) { Vector3 translationF = translation - world.AABB.Center; ((HkWorld)world.UserData).GetPenetrationsShape(shape, ref translationF, ref rotation, results, filter); } }
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 static HkShape CreateCharacterShape(float height, float width, float headHeight, float headSize, float headForwardOffset, float downOffset = 0f, bool capsuleForHead = false) { HkCapsuleShape shape = new HkCapsuleShape((Vector3.Up * (height - downOffset)) / 2f, (Vector3.Down * height) / 2f, width / 2f); if (headSize <= 0f) { return((HkShape)shape); } HkConvexShape childShape = !capsuleForHead ? ((HkConvexShape) new HkSphereShape(headSize)) : ((HkConvexShape) new HkCapsuleShape(new Vector3(0f, 0f, -0.3f), new Vector3(0f, 0f, 0.3f), headSize)); HkShape[] shapes = new HkShape[] { (HkShape)shape, (HkShape) new HkConvexTranslateShape(childShape, ((Vector3.Up * (headHeight - downOffset)) / 2f) + (Vector3.Forward * headForwardOffset), HkReferencePolicy.TakeOwnership) }; return((HkShape) new HkListShape(shapes, shapes.Length, HkReferencePolicy.TakeOwnership)); }
private void ReplaceShape(HkShape shape) { if (shape.IsZero) { IsEmpty = true; } else { RigidBody.SetShape(shape); shape.RemoveReference(); m_voxelMap.RaisePhysicsChanged(); } }
public void AddInstance(int itemId, ref ItemInfo item, HkShape shape) { if (!shape.IsZero) { Matrix m; Matrix.CreateFromQuaternion(ref item.Rotation, out m); m.Translation = item.Position; var instance = Shape.AddInstance(shape, m); m_itemToShapeInstance[itemId] = instance; m_shapeInstanceToItem[instance] = itemId; } }
public override void AccumulateCorrection(ref Vector3 correction, ref float weight) { if (base.Parent.Speed >= 0.01) { MatrixD positionAndOrientation = base.Parent.PositionAndOrientation; Vector3D translation = positionAndOrientation.Translation; Quaternion identity = Quaternion.Identity; MyPhysics.GetPenetrationsShape((HkShape) new HkSphereShape(6f), ref translation, ref identity, this.m_trees, 9); foreach (HkBodyCollision collision in this.m_trees) { if (collision.Body == null) { continue; } MyPhysicsBody userObject = collision.Body.UserObject as MyPhysicsBody; if (userObject != null) { HkShape shape = collision.Body.GetShape(); if (shape.ShapeType == HkShapeType.StaticCompound) { int num; uint num2; HkStaticCompoundShape shape2 = (HkStaticCompoundShape)shape; shape2.DecomposeShapeKey(collision.ShapeKey, out num, out num2); Vector3D vectord2 = shape2.GetInstanceTransform(num).Translation + userObject.GetWorldMatrix().Translation; Vector3D direction = vectord2 - translation; double num3 = direction.Normalize(); direction = Vector3D.Reject(base.Parent.ForwardVector, direction); direction.Y = 0.0; if (((direction.Z * direction.Z) + (direction.X * direction.X)) < 0.1) { direction = translation - vectord2; direction = Vector3D.Cross(Vector3D.Up, direction); if (Vector3D.TransformNormal(direction, base.Parent.PositionAndOrientationInverted).X < 0.0) { direction = -direction; } } direction.Normalize(); correction += ((6.0 - num3) * base.Weight) * direction; if (!correction.IsValid()) { Debugger.Break(); } } } } this.m_trees.Clear(); weight += base.Weight; } }
public void DebugDrawPhysicalShapes() { MyCubeGrid targetGrid = MyCubeGrid.GetTargetGrid(); if (targetGrid != null) { List <MyCubeGrid> list = new List <MyCubeGrid>(); foreach (MyGroups <MyCubeGrid, MyGridLogicalGroupData> .Node node in MyCubeGridGroups.Static.Logical.GetGroup(targetGrid).Nodes) { list.Add(node.NodeData); } MatrixD.Invert(list[0].WorldMatrix); foreach (MyCubeGrid grid2 in list) { if (MyPerGameSettings.Game == GameEnum.SE_GAME) { HkGridShape shape1 = new HkGridShape(grid2.GridSize, HkReferencePolicy.None); MyCubeBlockCollector collector1 = new MyCubeBlockCollector(); collector1.Collect(grid2, new MyVoxelSegmentation(), MyVoxelSegmentationType.Simple, new Dictionary <Vector3I, HkMassElement>()); foreach (HkShape shape in collector1.Shapes) { this.DebugDrawShape("", shape, grid2.WorldMatrix); } continue; } foreach (MySlimBlock block in grid2.GetBlocks()) { if (block.FatBlock != null) { if (block.FatBlock is MyCompoundCubeBlock) { foreach (MySlimBlock block2 in (block.FatBlock as MyCompoundCubeBlock).GetBlocks()) { HkShape shape = block2.FatBlock.ModelCollision.HavokCollisionShapes[0]; this.DebugDrawShape(block2.BlockDefinition.Id.SubtypeName, shape, block2.FatBlock.PositionComp.WorldMatrix); } continue; } if (block.FatBlock.ModelCollision.HavokCollisionShapes != null) { foreach (HkShape shape3 in block.FatBlock.ModelCollision.HavokCollisionShapes) { this.DebugDrawShape(block.BlockDefinition.Id.SubtypeName, shape3, block.FatBlock.PositionComp.WorldMatrix); } } } } } } }
public static void DrawShape(HkShape shape, MatrixD worldMatrix, Color color, float alpha, bool shaded = true) { color.A = (byte)(alpha * 255f); if (shape.ShapeType != HkShapeType.Capsule) { MyRenderProxy.DebugDrawSphere(worldMatrix.Translation, 0.05f, color, 1f, false, false, true, false); } else { HkCapsuleShape shape2 = (HkCapsuleShape)shape; Vector3 vector = (Vector3)Vector3.Transform(shape2.VertexB, worldMatrix); MyRenderProxy.DebugDrawCapsule(Vector3.Transform(shape2.VertexA, worldMatrix), vector, shape2.Radius, color, false, false, false); } }
internal void OnTaskComplete(MyCellCoord coord, HkShape childShape) { Debug.Assert(RigidBody != null, "RigidBody in voxel physics is null! This must not happen."); if (RigidBody != null) { HkUniformGridShape shape = GetShape(coord.Lod); Debug.Assert(shape.Base.IsValid); shape.SetChild(coord.CoordInLod.X, coord.CoordInLod.Y, coord.CoordInLod.Z, childShape, HkReferencePolicy.None); //BoundingBoxD worldAabb; //MyVoxelCoordSystems.GeometryCellCoordToWorldAABB(m_voxelMap.PositionLeftBottomCorner, ref coord, out worldAabb); //VRageRender.MyRenderProxy.DebugDrawAABB(worldAabb, Color.Green, 1f, 1f, true); m_needsShapeUpdate = true; } }
public static List <MyCubeBlockDefinition.MountPoint> AutogenerateMountpoints(MyModel model, float gridSize) { var shapes = model.HavokCollisionShapes; if (shapes == null) { if (model.HavokBreakableShapes == null) { return(new List <MyCubeBlockDefinition.MountPoint>()); } shapes = new HkShape[] { model.HavokBreakableShapes[0].GetShape() }; } return(AutogenerateMountpoints(shapes, gridSize)); }
private void RequestShapeBlockingInternal(int x, int y, int z, out HkShape shape, out HkReferencePolicy refPolicy, bool lod1physics) { ProfilerShort.Begin("MyVoxelPhysicsBody.RequestShapeBlocking"); if (!m_bodiesInitialized) { CreateRigidBodies(); } int lod = lod1physics ? 1 : 0; var cellCoord = new MyCellCoord(lod, new Vector3I(x, y, z)); shape = HkShape.Empty; // shape must take ownership, otherwise shapes created here will leak, since I can't remove reference refPolicy = HkReferencePolicy.TakeOwnership; //MyPrecalcComponent.QueueJobCancel(m_workTracker, cellCoord); if (m_voxelMap.MarkedForClose) { ProfilerShort.End(); return; } if (MyDebugDrawSettings.DEBUG_DRAW_REQUEST_SHAPE_BLOCKING) { BoundingBoxD aabb; MyVoxelCoordSystems.GeometryCellCoordToWorldAABB(m_voxelMap.PositionLeftBottomCorner, ref cellCoord, out aabb); MyRenderProxy.DebugDrawAABB(aabb, lod1physics ? Color.Yellow : Color.Red, 1, 1, true); } ProfilerShort.Begin("Generating geometry"); MyIsoMesh geometryData = CreateMesh(m_voxelMap.Storage, cellCoord); ProfilerShort.End(); if (!MyIsoMesh.IsEmpty(geometryData)) { ProfilerShort.Begin("Shape from geometry"); shape = CreateShape(geometryData, true); shape.AddReference(); var args = new MyPrecalcJobPhysicsPrefetch.Args() { GeometryCell = cellCoord, TargetPhysics = this, Tracker = m_workTracker, SimpleShape = shape }; MyPrecalcJobPhysicsPrefetch.Start(args); m_needsShapeUpdate = true; ProfilerShort.End(); } ProfilerShort.End(); }
public static bool GetShapeCenter(HkShape shape, int shapeKey, MyCubeGrid grid, ref Vector3D shapeCenter) { bool shapeSet = true; switch (shape.ShapeType) { case HkShapeType.List: var listShape = (HkListShape)shape; shape = listShape.GetChildByIndex(shapeKey); break; case HkShapeType.Mopp: var moppShape = (HkMoppBvTreeShape)shape; shape = moppShape.ShapeCollection.GetShape((uint)shapeKey, null); break; case HkShapeType.Box: var boxShape = (HkBoxShape)shape; shape = boxShape; break; case HkShapeType.ConvexTranslate: var convexTranslateShape = (HkConvexShape)shape; shape = convexTranslateShape; break; case HkShapeType.ConvexTransform: var convexTransformShape = (HkConvexTransformShape)shape; shape = convexTransformShape; break; default: shapeSet = false; break; } if (shapeSet) { Vector4 min4, max4; shape.GetLocalAABB(0.05f, out min4, out max4); Vector3 worldMin = Vector3.Transform(new Vector3(min4), grid.PositionComp.WorldMatrix); Vector3 worldMax = Vector3.Transform(new Vector3(max4), grid.PositionComp.WorldMatrix); var worldAABB = new BoundingBoxD(worldMin, worldMax); shapeCenter = worldAABB.Center; } return(shapeSet); }
public static bool GetShapeCenter(HkShape shape, int shapeKey, MyCubeGrid grid, ref Vector3D shapeCenter) { bool shapeSet = true; switch (shape.ShapeType) { case HkShapeType.List: var listShape = (HkListShape)shape; shape = listShape.GetChildByIndex(shapeKey); break; case HkShapeType.Mopp: var moppShape = (HkMoppBvTreeShape)shape; shape = moppShape.ShapeCollection.GetShape((uint)shapeKey, null); break; case HkShapeType.Box: var boxShape = (HkBoxShape)shape; shape = boxShape; break; case HkShapeType.ConvexTranslate: var convexTranslateShape = (HkConvexShape)shape; shape = convexTranslateShape; break; case HkShapeType.ConvexTransform: var convexTransformShape = (HkConvexTransformShape)shape; shape = convexTransformShape; break; default: shapeSet = false; break; } if (shapeSet) { Vector4 min4, max4; shape.GetLocalAABB(0.05f, out min4, out max4); Vector3 worldMin = Vector3.Transform(new Vector3(min4), grid.PositionComp.WorldMatrix); Vector3 worldMax = Vector3.Transform(new Vector3(max4), grid.PositionComp.WorldMatrix); var worldAABB = new BoundingBoxD(worldMin, worldMax); shapeCenter = worldAABB.Center; } return shapeSet; }
public static void DrawShape(HkShape shape, MatrixD worldMatrix, Color color, float alpha, bool shaded = true) { color.A = (byte)(alpha * 255); switch (shape.ShapeType) { case HkShapeType.Capsule: var capsule = (HkCapsuleShape)shape; Vector3 vertexA = Vector3.Transform(capsule.VertexA, worldMatrix); Vector3 vertexB = Vector3.Transform(capsule.VertexB, worldMatrix); VRageRender.MyRenderProxy.DebugDrawCapsule(vertexA, vertexB, capsule.Radius, color, false, false); break; default: // TODO: Add code to draw shape properly, AABB is not usefull.. VRageRender.MyRenderProxy.DebugDrawSphere(worldMatrix.Translation, 0.05f, color, 1.0f, false); break; } }
public static IEnumerable <HkShape> GetAllShapes(this HkShape shape) { if (shape.IsContainer()) { var iterator = shape.GetContainer(); while (iterator.CurrentShapeKey != HkShape.InvalidShapeKey) { foreach (var child in iterator.CurrentValue.GetAllShapes()) { yield return(child); } iterator.Next(); } yield break; } yield return(shape); }
private bool TargetEntityPenetratesCharacterInHeadPivotPosition(MyEntity entity, ref MatrixD shapeTransform) { HkShape shape = entity.Physics.RigidBody.GetShape(); Vector3D translation = shapeTransform.Translation; Quaternion rotation = Quaternion.CreateFromRotationMatrix(shapeTransform); m_tmpBodies.Clear(); MyPhysics.GetPenetrationsShape(shape, ref translation, ref rotation, m_tmpBodies, MyPhysics.ObjectDetectionCollisionLayer); foreach (var rigidBody in m_tmpBodies) { if (rigidBody.GetEntity() == Owner) { return(false); } } return(true); }
static bool FindMountPoint(HkShapeCutterUtil cutter, HkShape shape, Vector3 direction, float gridSize, List <Sandbox.Definitions.MyCubeBlockDefinition.MountPoint> mountPoints) { //VRageRender.MyRenderProxy.DebugDrawLine3D(drawMatrix.Translation, Vector3D.Transform(direction, drawMatrix), Color.Green, Color.Green, false); //float offset = (gridSize * 0.9f) / 2.0f; float offset = (gridSize * 0.75f) / 2.0f; //because fracture pieces can be bit inside the cube Plane plane = new Plane(-direction, offset); float minimumSize = 0.2f; Vector3 min, max; if (cutter.Cut(shape, new Vector4(plane.Normal.X, plane.Normal.Y, plane.Normal.Z, plane.D), out min, out max)) { var aabb = new BoundingBox(min, max); aabb.InflateToMinimum(new Vector3(minimumSize)); float centerOffset = gridSize * 0.5f; // VRageRender.MyRenderProxy.DebugDrawOBB(boxC, Color.Red, 0.02f, true, false); MyCubeBlockDefinition.MountPoint mountPoint = new MyCubeBlockDefinition.MountPoint(); mountPoint.Normal = new Vector3I(direction); mountPoint.Start = (aabb.Min + new Vector3(centerOffset)) / gridSize; mountPoint.End = (aabb.Max + new Vector3(centerOffset)) / gridSize; mountPoint.Enabled = true; //because it didnt work if shape wasnt realy near the edge var zExt = Vector3.Abs(direction) * mountPoint.Start; bool add = zExt.AbsMax() > 0.5f; mountPoint.Start -= zExt; mountPoint.Start -= direction * 0.04f; mountPoint.End -= Vector3.Abs(direction) * mountPoint.End; mountPoint.End += direction * 0.04f; if (add) { mountPoint.Start += Vector3.Abs(direction); mountPoint.End += Vector3.Abs(direction); } mountPoints.Add(mountPoint); return(true); } return(false); }
public override void DoWork() { ProfilerShort.Begin("MyPrecalcJobPhysicsPrefetch.DoWork"); //try { if (m_isCancelled) { ProfilerShort.End(); return; } if (m_args.Storage != null) { var geometryData = m_args.TargetPhysics.CreateMesh(m_args.Storage, m_args.GeometryCell); if (m_isCancelled) { ProfilerShort.End(); return; } if (!MyIsoMesh.IsEmpty(geometryData)) { m_result = m_args.TargetPhysics.CreateShape(geometryData); } } else { m_result = m_args.TargetPhysics.BakeCompressedMeshShape((HkSimpleMeshShape) m_args.SimpleShape); m_args.SimpleShape.RemoveReference(); } } //finally { ProfilerShort.End(); } }
private void AddPhysicalShape(HkShape shape, Matrix rdWorldMatrix) { switch (shape.ShapeType) { case Havok.HkShapeType.Box: Havok.HkBoxShape box = (HkBoxShape)shape; Vector3D vMin = new Vector3D(-box.HalfExtents.X, -box.HalfExtents.Y, -box.HalfExtents.Z); Vector3D vMax = new Vector3D(box.HalfExtents.X, box.HalfExtents.Y, box.HalfExtents.Z); BoundingBoxD boundingBox = new BoundingBoxD(vMin, vMax); BoundingBoxToTranslatedTriangles(boundingBox, rdWorldMatrix); break; case Havok.HkShapeType.List: var listShape = (HkListShape)shape; var iterator = listShape.GetIterator(); while (iterator.IsValid) { AddPhysicalShape(iterator.CurrentValue, rdWorldMatrix); iterator.Next(); } break; case HkShapeType.Mopp: var compoundShape = (HkMoppBvTreeShape)shape; AddPhysicalShape(compoundShape.ShapeCollection, rdWorldMatrix); break; case HkShapeType.ConvexTransform: var transformShape = (HkConvexTransformShape)shape; AddPhysicalShape(transformShape.ChildShape, transformShape.Transform * rdWorldMatrix); break; case HkShapeType.ConvexTranslate: var translateShape = (HkConvexTranslateShape)shape; var mat = Matrix.CreateTranslation(translateShape.Translation); AddPhysicalShape((HkShape)translateShape.ChildShape, mat * rdWorldMatrix); break; case HkShapeType.Sphere: var sphereShape = (HkSphereShape)shape; m_icosphereMesh.AddTrianglesToWorldVertices(rdWorldMatrix.Translation, sphereShape.Radius); break; case HkShapeType.Capsule: return; ProfilerShort.Begin("Capsule"); var capsuleShape = (HkCapsuleShape)shape; Line line = new Line(capsuleShape.VertexA, capsuleShape.VertexB); m_capsuleMesh.AddTrianglesToWorldVertices(rdWorldMatrix, capsuleShape.Radius, line); ProfilerShort.End(); break; case HkShapeType.ConvexVertices: var convexShape = (HkConvexVerticesShape)shape; HkGeometry geometry = new HkGeometry(); Vector3 center; convexShape.GetGeometry(geometry, out center); for (int i = 0; i < geometry.TriangleCount; i++) { int i0, i1, i2, materialIndex; geometry.GetTriangle(i, out i0, out i1, out i2, out materialIndex); m_worldVertices.Triangles.Add(m_worldVertices.VerticesMaxValue + i0); m_worldVertices.Triangles.Add(m_worldVertices.VerticesMaxValue + i1); m_worldVertices.Triangles.Add(m_worldVertices.VerticesMaxValue + i2); } for (int i = 0; i < geometry.VertexCount; i++) { Vector3 vec = geometry.GetVertex(i); Vector3.Transform(ref vec, ref rdWorldMatrix, out vec); m_worldVertices.Vertices.Add(vec); } m_worldVertices.VerticesMaxValue += geometry.VertexCount; break; default: // For breakpoint. Don't judge me :( break; } }
public override void UpdateAfterSimulation10() { base.UpdateAfterSimulation10(); if (!Sync.IsServer || !IsWorking || !ResourceSink.IsPowered) return; var rotation1 = Quaternion.CreateFromForwardUp(WorldMatrix.Forward, WorldMatrix.Up); var position1 = PositionComp.GetPosition() + Vector3D.Transform(PositionComp.LocalVolume.Center + (m_fieldMax.Value + m_fieldMin.Value) * 0.5f, rotation1); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Recreate Field"); if (m_recreateField) { m_recreateField = false; m_fieldShape.RemoveReference(); m_fieldShape = GetHkShape(); ResourceSink.Update(); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); var boundingBox = new BoundingBoxD(m_fieldMin.Value, m_fieldMax.Value).Translate(PositionComp.LocalVolume.Center).Transform(WorldMatrix.GetOrientation()).Translate(PositionComp.GetPosition()); m_potentialPenetrations.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref boundingBox, m_potentialPenetrations); m_potentialVoxelPenetrations.Clear(); MyGamePruningStructure.GetAllVoxelMapsInBox(ref boundingBox, m_potentialVoxelPenetrations);//disabled until heightmap queries are finished VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Sensor Physics"); LastDetectedEntity = null; bool empty = true; foreach (var entity in m_potentialPenetrations) { if (entity is MyVoxelBase) { //voxels are handled in different loop (becaose of planets) continue; } if (ShouldDetect(entity)) { Quaternion rotation2; Vector3 posDiff; HkShape? shape2; if (GetPropertiesFromEntity(entity, ref position1, out rotation2, out posDiff, out shape2)) { if (entity.GetPhysicsBody().HavokWorld.IsPenetratingShapeShape(m_fieldShape, ref Vector3.Zero, ref rotation1, shape2.Value, ref posDiff, ref rotation2)) { LastDetectedEntity = entity; empty = false; break; } } } } if (DetectAsteroids) { foreach (var entity in m_potentialVoxelPenetrations) { var voxel = entity as MyVoxelPhysics; if (voxel != null) { Vector3D localPositionMin, localPositionMax; VRage.Voxels.MyVoxelCoordSystems.WorldPositionToLocalPosition(boundingBox.Min, voxel.PositionComp.WorldMatrix, voxel.PositionComp.WorldMatrixInvScaled, voxel.SizeInMetresHalf, out localPositionMin); VRage.Voxels.MyVoxelCoordSystems.WorldPositionToLocalPosition(boundingBox.Max, voxel.PositionComp.WorldMatrix, voxel.PositionComp.WorldMatrixInvScaled, voxel.SizeInMetresHalf, out localPositionMax); var aabb = new BoundingBox(localPositionMin, localPositionMax); aabb.Translate(voxel.StorageMin); if (voxel.Storage.Intersect(ref aabb) != ContainmentType.Disjoint) { LastDetectedEntity = voxel; empty = false; break; } } else { Quaternion rotation2; Vector3 posDiff; HkShape? shape2; if (GetPropertiesFromEntity(entity, ref position1, out rotation2, out posDiff, out shape2)) { if (entity.GetPhysicsBody().HavokWorld.IsPenetratingShapeShape(m_fieldShape, ref Vector3.Zero, ref rotation1, shape2.Value, ref posDiff, ref rotation2)) { LastDetectedEntity = entity; empty = false; break; } } } } } IsActive = !empty; m_potentialPenetrations.Clear(); m_potentialVoxelPenetrations.Clear(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); }
public static HkContactPoint? CastShapeReturnContact(Vector3D to, HkShape shape, ref MatrixD transform, int filterLayer, float extraPenetration, out Vector3 worldTranslation) { m_resultWorlds.Clear(); Clusters.Intersects(to, m_resultWorlds); worldTranslation = Vector3.Zero; if (m_resultWorlds.Count == 0) return null; var world = m_resultWorlds[0]; worldTranslation = world.AABB.Center; Matrix transformF = transform; transformF.Translation = (Vector3)(transform.Translation - world.AABB.Center); Vector3 toF = (Vector3)(to - world.AABB.Center); HkContactPoint? result = ((HkWorld)world.UserData).CastShapeReturnContact(toF, shape, ref transformF, filterLayer, extraPenetration); if (result == null) { return null; } return result; }
static bool FindMountPoint(HkShapeCutterUtil cutter, HkShape shape, Vector3 direction, float gridSize, List<Sandbox.Definitions.MyCubeBlockDefinition.MountPoint> mountPoints) { //VRageRender.MyRenderProxy.DebugDrawLine3D(drawMatrix.Translation, Vector3D.Transform(direction, drawMatrix), Color.Green, Color.Green, false); //float offset = (gridSize * 0.9f) / 2.0f; float offset = (gridSize * 0.75f) / 2.0f; //because fracture pieces can be bit inside the cube Plane plane = new Plane(-direction, offset); float minimumSize = 0.2f; Vector3 min, max; if (cutter.Cut(shape, new Vector4(plane.Normal.X, plane.Normal.Y, plane.Normal.Z, plane.D), out min, out max)) { var aabb = new BoundingBox(min, max); aabb.InflateToMinimum(new Vector3(minimumSize)); float centerOffset = gridSize * 0.5f; // VRageRender.MyRenderProxy.DebugDrawOBB(boxC, Color.Red, 0.02f, true, false); MyCubeBlockDefinition.MountPoint mountPoint = new MyCubeBlockDefinition.MountPoint(); mountPoint.Normal = new Vector3I(direction); mountPoint.Start = (aabb.Min + new Vector3(centerOffset)) / gridSize; mountPoint.End = (aabb.Max + new Vector3(centerOffset)) / gridSize; mountPoint.Enabled = true; //because it didnt work if shape wasnt realy near the edge var zExt = Vector3.Abs(direction) * mountPoint.Start; bool add = zExt.AbsMax() > 0.5f; mountPoint.Start -= zExt; mountPoint.Start -= direction * 0.04f; mountPoint.End -= Vector3.Abs(direction) * mountPoint.End; mountPoint.End += direction * 0.04f; if (add) { mountPoint.Start += Vector3.Abs(direction); mountPoint.End += Vector3.Abs(direction); } mountPoints.Add(mountPoint); return true; } return false; }
protected virtual void CreateBody(ref HkShape shape, HkMassProperties? massProperties) { ProfilerShort.Begin("CreateBody"); HkRigidBodyCinfo rbInfo = new HkRigidBodyCinfo(); rbInfo.AngularDamping = m_angularDamping; rbInfo.LinearDamping = m_linearDamping; rbInfo.Shape = shape; rbInfo.SolverDeactivation = InitialSolverDeactivation; rbInfo.ContactPointCallbackDelay = ContactPointDelay; if (massProperties.HasValue) { rbInfo.SetMassProperties(massProperties.Value); } GetInfoFromFlags(rbInfo, Flags); RigidBody = new HkRigidBody(rbInfo); ProfilerShort.End(); }
private static bool TestQueryIntersection(HkShape shape, MatrixD transform) { MatrixD transform1D = m_lastQueryTransform; MatrixD transform2D = transform; transform2D.Translation = transform2D.Translation - transform1D.Translation; transform1D.Translation = Vector3D.Zero; Matrix t1 = transform1D; Matrix t2 = transform2D; return MyPhysics.IsPenetratingShapeShape(m_lastQueryBox, ref t1, shape, ref t2); }
public static void GetPenetrationsShape(HkShape shape, ref Vector3D translation, ref Quaternion rotation, List<HkBodyCollision> results, int filter) { m_resultWorlds.Clear(); Clusters.Intersects(translation, m_resultWorlds); foreach (var world in m_resultWorlds) { Vector3 translationF = translation - world.AABB.Center; ((HkWorld)world.UserData).GetPenetrationsShape(shape, ref translationF, ref rotation, results, filter); } }
public static bool IsPenetratingShapeShape(HkShape shape1, ref Matrix transform1, HkShape shape2, ref Matrix transform2) { return (Clusters.GetList().First() as HkWorld).IsPenetratingShapeShape(shape1, ref transform1, shape2, ref transform2); }
public static float? CastShape(Vector3D to, HkShape shape, ref MatrixD transform, int filterLayer, float extraPenetration = 0) { m_resultWorlds.Clear(); Clusters.Intersects(to, m_resultWorlds); if (m_resultWorlds.Count == 0) return null; var world = m_resultWorlds[0]; Matrix transformF = transform; transformF.Translation = (Vector3)(transform.Translation - world.AABB.Center); Vector3 toF = (Vector3)(to - world.AABB.Center); return ((HkWorld)world.UserData).CastShape(toF, shape, ref transformF, filterLayer, extraPenetration); }
public static bool IsPenetratingShapeShape(HkShape shape1, ref Vector3D translation1, ref Quaternion rotation1, HkShape shape2, ref Vector3D translation2, ref Quaternion rotation2) { //rotations have to be normalized rotation1.Normalize(); rotation2.Normalize(); //jn: TODO this is world independent test, just transform so shape1 is on zero and querry on any world m_resultWorlds.Clear(); Clusters.Intersects(translation1, m_resultWorlds); foreach (var world in m_resultWorlds) { if (world.AABB.Contains(translation2) != ContainmentType.Contains) return false; Vector3 translation1F = translation1 - world.AABB.Center; Vector3 translation2F = translation2 - world.AABB.Center; if (((HkWorld)world.UserData).IsPenetratingShapeShape(shape1, ref translation1F, ref rotation1, shape2, ref translation2F, ref rotation2)) return true; } return false; }
public static bool CastShapeReturnContactBodyDatas(Vector3D to, HkShape shape, ref MatrixD transform, uint collisionFilter, float extraPenetration, List<HitInfo> result, bool ignoreConvexShape = true) { m_resultWorlds.Clear(); Clusters.Intersects(to, m_resultWorlds); if (m_resultWorlds.Count == 0) return false; var world = m_resultWorlds[0]; Matrix transformF = transform; transformF.Translation = (Vector3)(transform.Translation - world.AABB.Center); Vector3 toF = (Vector3)(to - world.AABB.Center); m_resultShapeCasts.Clear(); if (((HkWorld)world.UserData).CastShapeReturnContactBodyDatas(toF, shape, ref transformF, collisionFilter, extraPenetration, m_resultShapeCasts)) { foreach (var res in m_resultShapeCasts) { HkWorld.HitInfo cpd = res.Value; HitInfo hitInfo = new HitInfo() { HkHitInfo = cpd, Position = cpd.Position + world.AABB.Center }; result.Add(hitInfo); } return true; } return false; }
public static HitInfo? CastShapeReturnContactBodyData(Vector3D to, HkShape shape, ref MatrixD transform, uint collisionFilter, float extraPenetration, bool ignoreConvexShape = true) { m_resultWorlds.Clear(); Clusters.Intersects(to, m_resultWorlds); if (m_resultWorlds.Count == 0) return null; var world = m_resultWorlds[0]; Matrix transformF = transform; transformF.Translation = (Vector3)(transform.Translation - world.AABB.Center); Vector3 toF = (Vector3)(to - world.AABB.Center); HkWorld.HitInfo? result = ((HkWorld)world.UserData).CastShapeReturnContactBodyData(toF, shape, ref transformF, collisionFilter, extraPenetration); if (result == null) { return null; } HkWorld.HitInfo cpd = result.Value; HitInfo hitInfo = new HitInfo(cpd, cpd.Position + world.AABB.Center); return hitInfo; }
private void RecreateWeldedShape(HkShape thisShape) { m_tmpShapeList.Add(thisShape); if (WeldInfo.Children.Count == 0) { RigidBody.SetShape(thisShape); if (RigidBody2 != null) RigidBody2.SetShape(thisShape); } else { 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); } var list = new HkListShape(m_tmpShapeList.ToArray(), HkReferencePolicy.None); RigidBody.SetShape(list); if (RigidBody2 != null) RigidBody2.SetShape(list); list.Base.RemoveReference(); m_tmpShapeList.Clear(); } }
private HkShape CreateBreakableBody(HkShape shape, HkMassProperties? massProperties) { ProfilerShort.Begin("CreateGridBody"); HkdBreakableShape breakable; HkMassProperties massProps = massProperties.HasValue ? massProperties.Value : new HkMassProperties(); if (!Shape.BreakableShape.IsValid()) Shape.CreateBreakableShape(); breakable = Shape.BreakableShape; if (!breakable.IsValid()) { breakable = new HkdBreakableShape(shape); if (massProperties.HasValue) { var mp = massProperties.Value; breakable.SetMassProperties(ref mp); } else breakable.SetMassRecursively(50); } else breakable.BuildMassProperties(ref massProps); shape = breakable.GetShape(); //doesnt add reference HkRigidBodyCinfo rbInfo = new HkRigidBodyCinfo(); rbInfo.AngularDamping = m_angularDamping; rbInfo.LinearDamping = m_linearDamping; rbInfo.SolverDeactivation = m_grid.IsStatic ? InitialSolverDeactivation : HkSolverDeactivation.Low; rbInfo.ContactPointCallbackDelay = ContactPointDelay; rbInfo.Shape = shape; rbInfo.SetMassProperties(massProps); //rbInfo.Position = Entity.PositionComp.GetPosition(); //obsolete with large worlds? GetInfoFromFlags(rbInfo, Flags); if (m_grid.IsStatic) { rbInfo.MotionType = HkMotionType.Dynamic; rbInfo.QualityType = HkCollidableQualityType.Moving; } HkRigidBody rb = new HkRigidBody(rbInfo); if (m_grid.IsStatic) { rb.UpdateMotionType(HkMotionType.Fixed); } rb.EnableDeactivation = true; BreakableBody = new HkdBreakableBody(breakable, rb, null, Matrix.Identity); //DestructionBody.ConnectToWorld(HavokWorld, 0.05f); BreakableBody.AfterReplaceBody += FracturedBody_AfterReplaceBody; //RigidBody.SetWorldMatrix(Entity.PositionComp.WorldMatrix); //breakable.Dispose(); ProfilerShort.End(); return shape; }
public static bool TestBlockPlacementArea( MyCubeGrid targetGrid, ref MyGridPlacementSettings settings, MyBlockOrientation blockOrientation, MyCubeBlockDefinition blockDefinition, ref Vector3D translation, ref Quaternion rotation, ref Vector3 halfExtents, ref BoundingBoxD localAabb, out MyCubeGrid touchingGrid, MyEntity ignoredEntity = null, bool ignoreFracturedPieces = false) { touchingGrid = null; ProfilerShort.Begin("UseModelIntersection"); if (blockDefinition != null && blockDefinition.UseModelIntersection) { var model = VRage.Game.Models.MyModels.GetModelOnlyData(blockDefinition.Model); if (model != null) { bool newErrorFound; model.CheckLoadingErrors(blockDefinition.Context, out newErrorFound); if (newErrorFound) MyDefinitionErrors.Add(blockDefinition.Context, "There was error during loading of model, please check log file.", TErrorSeverity.Error); } if (model != null && model.HavokCollisionShapes != null) { int shapeCount = model.HavokCollisionShapes.Length; HkShape[] shapes = new HkShape[shapeCount]; for (int q = 0; q < shapeCount; ++q) { shapes[q] = model.HavokCollisionShapes[q]; } var shape = new HkListShape(shapes, shapeCount, HkReferencePolicy.None); Quaternion q2 = Quaternion.CreateFromForwardUp(Base6Directions.GetVector(blockOrientation.Forward), Base6Directions.GetVector(blockOrientation.Up)); rotation = rotation * q2; MyPhysics.GetPenetrationsShape(shape, ref translation, ref rotation, m_physicsBoxQueryList, MyPhysics.CollisionLayers.CharacterCollisionLayer); shape.Base.RemoveReference(); } else { Debug.Assert(m_physicsBoxQueryList.Count == 0, "List not cleared"); MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref rotation, m_physicsBoxQueryList, MyPhysics.CollisionLayers.CharacterCollisionLayer); } } else { Debug.Assert(m_physicsBoxQueryList.Count == 0, "List not cleared"); MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref rotation, m_physicsBoxQueryList, MyPhysics.CollisionLayers.CharacterCollisionLayer); } m_lastQueryBox.HalfExtents = halfExtents; m_lastQueryTransform = MatrixD.CreateFromQuaternion(rotation); m_lastQueryTransform.Translation = translation; var worldMatrix = targetGrid != null ? targetGrid.WorldMatrix : MatrixD.Identity; ProfilerShort.BeginNextBlock("TestPlacementAreaInternal"); bool result = TestPlacementAreaInternal(targetGrid, ref settings, blockDefinition, blockOrientation, ref localAabb, ignoredEntity, ref worldMatrix, out touchingGrid, ignoreFracturedPieces: ignoreFracturedPieces); ProfilerShort.End(); return result; }
protected override void CreateBody(ref HkShape shape, HkMassProperties? massProperties) { if (MyPerGameSettings.Destruction)// && shape.ShapeType == HkShapeType.StaticCompound) { shape = CreateBreakableBody(shape, massProperties); } else { HkRigidBodyCinfo rbInfo = new HkRigidBodyCinfo(); rbInfo.AngularDamping = m_angularDamping; rbInfo.LinearDamping = m_linearDamping; rbInfo.Shape = shape; rbInfo.SolverDeactivation = InitialSolverDeactivation; rbInfo.ContactPointCallbackDelay = ContactPointDelay; if (massProperties.HasValue) { rbInfo.SetMassProperties(massProperties.Value); } GetInfoFromFlags(rbInfo, Flags); if (m_grid.IsStatic) { rbInfo.MotionType = HkMotionType.Dynamic; rbInfo.QualityType = HkCollidableQualityType.Moving; } RigidBody = new HkRigidBody(rbInfo); if (m_grid.IsStatic) { RigidBody.UpdateMotionType(HkMotionType.Fixed); } //RigidBody.UpdateMotionType(HkMotionType.Dynamic); //base.CreateBody(ref shape, massProperties); } }
public virtual void CreateFromCollisionObject(HkShape shape, Vector3 center, MatrixD worldTransform, HkMassProperties? massProperties = null, int collisionFilter = MyPhysics.DefaultCollisionLayer) { MyPhysics.AssertThread(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyPhysicsBody::CreateFromCollisionObject()"); Debug.Assert(RigidBody == null, "Must be removed from scene and null"); CloseRigidBody(); Center = center; CanUpdateAccelerations = true; //m_motionState = new MyMotionState(worldTransform); CreateBody(ref shape, massProperties); RigidBody.UserObject = this; //RigidBody.SetWorldMatrix(worldTransform); RigidBody.Layer = collisionFilter; if ((int)(Flags & RigidBodyFlag.RBF_DISABLE_COLLISION_RESPONSE) > 0) { RigidBody.Layer = MyPhysics.NoCollisionLayer; } if ((int)(Flags & RigidBodyFlag.RBF_DOUBLED_KINEMATIC) > 0) { HkRigidBodyCinfo rbInfo2 = new HkRigidBodyCinfo(); rbInfo2.AngularDamping = m_angularDamping; rbInfo2.LinearDamping = m_linearDamping; rbInfo2.Shape = shape; rbInfo2.MotionType = HkMotionType.Keyframed; rbInfo2.QualityType = HkCollidableQualityType.Keyframed; RigidBody2 = new HkRigidBody(rbInfo2); RigidBody2.UserObject = this; RigidBody2.SetWorldMatrix(worldTransform); } //m_motionState.Body = this; VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); }
public override void Init(MyObjectBuilder_CubeBlock objectBuilder, MyCubeGrid cubeGrid) { SyncFlag = true; var sinkComp = new MyResourceSinkComponent(); sinkComp.Init( BlockDefinition.ResourceSinkGroup, BlockDefinition.RequiredPowerInput, this.CalculateRequiredPowerInput); ResourceSink = sinkComp; base.Init(objectBuilder, cubeGrid); m_items = new List<ToolbarItem>(2); for (int i = 0; i < 2; i++) { m_items.Add(new ToolbarItem() { EntityID = 0 }); } Toolbar = new MyToolbar(MyToolbarType.ButtonPanel, 2, 1); Toolbar.DrawNumbers = false; var builder = (MyObjectBuilder_SensorBlock)objectBuilder; m_fieldMin.Value = Vector3.Clamp(builder.FieldMin, new Vector3(-MaxRange), -Vector3.One); m_fieldMax.Value = Vector3.Clamp(builder.FieldMax, Vector3.One, new Vector3(MaxRange)); PlayProximitySound = builder.PlaySound; DetectPlayers = builder.DetectPlayers; DetectFloatingObjects = builder.DetectFloatingObjects; DetectSmallShips = builder.DetectSmallShips; DetectLargeShips = builder.DetectLargeShips; DetectStations = builder.DetectStations; DetectAsteroids = builder.DetectAsteroids; DetectOwner = builder.DetectOwner; DetectFriendly = builder.DetectFriendly; DetectNeutral = builder.DetectNeutral; DetectEnemy = builder.DetectEnemy; m_active.Value = builder.IsActive; Toolbar.Init(builder.Toolbar, this); for (int i = 0; i < 2; i++) { var item = Toolbar.GetItemAtIndex(i); if (item == null) continue; m_items.RemoveAt(i); m_items.Insert(i, ToolbarItem.FromItem(item)); } Toolbar.ItemChanged += Toolbar_ItemChanged; NeedsUpdate |= MyEntityUpdateEnum.EACH_10TH_FRAME; SlimBlock.ComponentStack.IsFunctionalChanged += ComponentStack_IsFunctionalChanged; ResourceSink.IsPoweredChanged += Receiver_IsPoweredChanged; ResourceSink.RequiredInputChanged += Receiver_RequiredInputChanged; ResourceSink.Update(); m_fieldShape = GetHkShape(); OnClose += delegate(MyEntity self) { m_fieldShape.RemoveReference(); }; m_gizmoColor = MySandboxGame.IsDirectX11 ? new Vector4(0.35f, 0, 0, 0.5f) : new Vector4(0.1f, 0, 0, 0.1f); }
public static void DrawCollisionShape(HkShape shape, MatrixD worldMatrix, float alpha, ref int shapeIndex, string customText = null, bool isPhantom = false) { var color = GetShapeColor(shape.ShapeType, ref shapeIndex, isPhantom); if (isPhantom) alpha *= alpha; color.A = (byte)(alpha * 255); bool shaded = true; float expandSize = 0.02f; float expandRatio = 1.035f; bool drawCustomText = false; switch (shape.ShapeType) { case HkShapeType.Sphere: { var sphere = (HkSphereShape)shape; float radius = sphere.Radius; VRageRender.MyRenderProxy.DebugDrawSphere(worldMatrix.Translation, radius, color, alpha, true, shaded); if (isPhantom) { VRageRender.MyRenderProxy.DebugDrawSphere(worldMatrix.Translation, radius, color, 1.0f, true, false); VRageRender.MyRenderProxy.DebugDrawSphere(worldMatrix.Translation, radius, color, 1.0f, true, false, false); } drawCustomText = true; break; } case HkShapeType.Capsule: { // Sphere and OBB to show cylinder space var capsule = (HkCapsuleShape)shape; Vector3D vertexA = Vector3.Transform(capsule.VertexA, worldMatrix); Vector3D vertexB = Vector3.Transform(capsule.VertexB, worldMatrix); VRageRender.MyRenderProxy.DebugDrawCapsule(vertexA, vertexB, capsule.Radius, color, true, shaded); drawCustomText = true; break; } case HkShapeType.Cylinder: { // Sphere and OBB to show cylinder space var cylinder = (HkCylinderShape)shape; VRageRender.MyRenderProxy.DebugDrawCylinder(worldMatrix, cylinder.VertexA, cylinder.VertexB, cylinder.Radius, color, alpha, true, shaded); drawCustomText = true; break; } case HkShapeType.Box: { var box = (HkBoxShape)shape; VRageRender.MyRenderProxy.DebugDrawOBB(MatrixD.CreateScale(box.HalfExtents * 2 + new Vector3(expandSize)) * worldMatrix, color, alpha, true, shaded); if (isPhantom) { VRageRender.MyRenderProxy.DebugDrawOBB(Matrix.CreateScale(box.HalfExtents * 2 + new Vector3(expandSize)) * worldMatrix, color, 1.0f, true, false); VRageRender.MyRenderProxy.DebugDrawOBB(Matrix.CreateScale(box.HalfExtents * 2 + new Vector3(expandSize)) * worldMatrix, color, 1.0f, true, false, false); } drawCustomText = true; break; } case HkShapeType.ConvexVertices: { var convexShape = (HkConvexVerticesShape)shape; Vector3 center; convexShape.GetGeometry(DebugGeometry, out center); Vector3D transformedCenter = Vector3D.Transform(center, worldMatrix.GetOrientation()); var matrix = worldMatrix; matrix = MatrixD.CreateScale(expandRatio) * matrix; matrix.Translation -= transformedCenter * (expandRatio - 1); //matrix.Translation += transformedCenter; DrawGeometry(DebugGeometry, matrix, color, true, true); drawCustomText = true; break; } case HkShapeType.ConvexTranslate: { var translateShape = (HkConvexTranslateShape)shape; DrawCollisionShape((HkShape)translateShape.ChildShape, Matrix.CreateTranslation(translateShape.Translation) * worldMatrix, alpha, ref shapeIndex, customText); break; } case HkShapeType.ConvexTransform: { var transformShape = (HkConvexTransformShape)shape; DrawCollisionShape(transformShape.ChildShape, transformShape.Transform * worldMatrix, alpha, ref shapeIndex, customText); break; } case HkShapeType.Mopp: { var compoundShape = (HkMoppBvTreeShape)shape; DrawCollisionShape(compoundShape.ShapeCollection, worldMatrix, alpha, ref shapeIndex, customText); break; } case HkShapeType.List: { var listShape = (HkListShape)shape; var iterator = listShape.GetIterator(); while (iterator.IsValid) { //string text = (customText ?? string.Empty) + "[" + iterator.CurrentShapeKey + "]"; DrawCollisionShape(iterator.CurrentValue, worldMatrix, alpha, ref shapeIndex, customText); iterator.Next(); } break; } case HkShapeType.StaticCompound: { var compoundShape = (HkStaticCompoundShape)shape; if (DebugDrawFlattenHierarchy) { var it = compoundShape.GetIterator(); while (it.IsValid) { if (compoundShape.IsShapeKeyEnabled(it.CurrentShapeKey)) { string text = (customText ?? string.Empty) + "-" + it.CurrentShapeKey + "-"; DrawCollisionShape(it.CurrentValue, worldMatrix, alpha, ref shapeIndex, text); } it.Next(); } } else { for (int i = 0; i < compoundShape.InstanceCount; i++) { bool enabled = compoundShape.IsInstanceEnabled(i); string text; if (enabled) text = (customText ?? string.Empty) + "<" + i + ">"; else text = (customText ?? string.Empty) + "(" + i + ")"; if (enabled) DrawCollisionShape(compoundShape.GetInstance(i), compoundShape.GetInstanceTransform(i) * worldMatrix, alpha, ref shapeIndex, text); } } break; } case HkShapeType.Triangle: { HkTriangleShape tri = (HkTriangleShape)shape; VRageRender.MyRenderProxy.DebugDrawTriangle(tri.Pt0, tri.Pt1, tri.Pt2, Color.Green, false, false); break; } case HkShapeType.BvTree: { var gridShape = (HkGridShape)shape; if (HkGridShapeCellDebugDraw && !gridShape.Base.IsZero) { Vector3S min, max; var cellSize = gridShape.CellSize; int count = gridShape.GetShapeInfoCount(); for (int i = 0; i < count; i++) { try { gridShape.GetShapeInfo(i, out min, out max, m_tmpShapeList); Vector3 size = max * cellSize - min * cellSize; Vector3 center = (max * cellSize + min * cellSize) / 2.0f; size += Vector3.One * cellSize; var clr = color; if (min == max) { clr = new Color(1.0f, 0.2f, 0.1f); } VRageRender.MyRenderProxy.DebugDrawOBB(Matrix.CreateScale(size + new Vector3(expandSize)) * Matrix.CreateTranslation(center) * worldMatrix, clr, alpha, true, shaded); } finally { m_tmpShapeList.Clear(); } } } else { var msg = MyRenderProxy.PrepareDebugDrawTriangles(); try { using (HkShapeBuffer buf = new HkShapeBuffer()) { var treeShape = (HkBvTreeShape)shape; for (var i = treeShape.GetIterator(buf); i.IsValid; i.Next()) { var child = i.CurrentValue; if (child.ShapeType == HkShapeType.Triangle) { var tri = (HkTriangleShape)child; msg.AddTriangle(tri.Pt0, tri.Pt1, tri.Pt2); } else { DrawCollisionShape(child, worldMatrix, alpha, ref shapeIndex); } } } } finally { MyRenderProxy.DebugDrawTriangles(msg, worldMatrix, color, false, false); } } break; } case HkShapeType.BvCompressedMesh: { if (MyDebugDrawSettings.DEBUG_DRAW_TRIANGLE_PHYSICS) { var meshShape = (HkBvCompressedMeshShape)shape; meshShape.GetGeometry(DebugGeometry); DrawGeometry(DebugGeometry, worldMatrix, Color.Green, false, false); drawCustomText = true; } break; } case HkShapeType.Bv: { var bvShape = (HkBvShape)shape; DrawCollisionShape(bvShape.BoundingVolumeShape, worldMatrix, alpha, ref shapeIndex, null, true); DrawCollisionShape(bvShape.ChildShape, worldMatrix, alpha, ref shapeIndex); break; } case HkShapeType.PhantomCallback: { // Nothing to draw, it's just shape with events MyRenderProxy.DebugDrawText3D(worldMatrix.Translation, "Phantom", Color.Green, 0.75f, false); break; } default: break; } if (drawCustomText && customText != null) { color.A = 255; MyRenderProxy.DebugDrawText3D(worldMatrix.Translation, customText, color, 0.8f, false); } }
bool GetPropertiesFromEntity(MyEntity entity,ref Vector3D position1, out Quaternion rotation2, out Vector3 posDiff, out HkShape? shape2) { rotation2 = new Quaternion(); posDiff = Vector3.Zero; shape2 = null; if (entity.Physics == null || !entity.Physics.Enabled) { return false; } if (entity.Physics.RigidBody != null) { shape2 = entity.Physics.RigidBody.GetShape(); var worldMatrix = entity.WorldMatrix; rotation2 = Quaternion.CreateFromForwardUp(worldMatrix.Forward, worldMatrix.Up); posDiff = entity.PositionComp.GetPosition() - position1; if (entity is MyVoxelBase) { var voxel = entity as MyVoxelBase; posDiff -= voxel.Size / 2; } } else if (entity.GetPhysicsBody().CharacterProxy != null) { shape2 = entity.GetPhysicsBody().CharacterProxy.GetShape(); var worldMatrix = entity.WorldMatrix; rotation2 = Quaternion.CreateFromForwardUp(worldMatrix.Forward, worldMatrix.Up); posDiff = entity.PositionComp.GetPosition() - position1; } else { return false; } return true; }
protected override void CreateBody(ref HkShape shape, HkMassProperties? massProperties) { if (MyPerGameSettings.Destruction)// && shape.ShapeType == HkShapeType.StaticCompound) { ProfilerShort.Begin("CreateGridBody"); HkdBreakableShape breakable; HkMassProperties massProps = massProperties.HasValue ? massProperties.Value : new HkMassProperties(); if (!Shape.BreakableShape.IsValid()) Shape.CreateBreakableShape(); breakable = Shape.BreakableShape; if (!breakable.IsValid()) { breakable = new HkdBreakableShape(shape); if (massProperties.HasValue) { var mp = massProperties.Value; breakable.SetMassProperties(ref mp); } else breakable.SetMassRecursively(50); } else breakable.BuildMassProperties(ref massProps); shape = breakable.GetShape(); //doesnt add reference HkRigidBodyCinfo rbInfo = new HkRigidBodyCinfo(); rbInfo.AngularDamping = m_angularDamping; rbInfo.LinearDamping = m_linearDamping; rbInfo.SolverDeactivation = m_grid.IsStatic ? InitialSolverDeactivation : HkSolverDeactivation.Low; rbInfo.ContactPointCallbackDelay = ContactPointDelay; rbInfo.Shape = shape; rbInfo.SetMassProperties(massProps); //rbInfo.Position = Entity.PositionComp.GetPosition(); //obsolete with large worlds? GetInfoFromFlags(rbInfo, Flags); HkRigidBody rb = new HkRigidBody(rbInfo); rb.EnableDeactivation = true; BreakableBody = new HkdBreakableBody(breakable, rb, MyPhysics.SingleWorld.DestructionWorld, Matrix.Identity); //DestructionBody.ConnectToWorld(HavokWorld, 0.05f); BreakableBody.AfterReplaceBody += FracturedBody_AfterReplaceBody; //RigidBody.SetWorldMatrix(Entity.PositionComp.WorldMatrix); //breakable.Dispose(); ProfilerShort.End(); } else { base.CreateBody(ref shape, massProperties); } }
public static float? CastShapeInAllWorlds(Vector3D to, HkShape shape, ref MatrixD transform, int filterLayer, float extraPenetration = 0) { m_resultWorlds.Clear(); Clusters.CastRay(transform.Translation, to, m_resultWorlds); foreach (var world in m_resultWorlds) { Matrix transformF = transform; transformF.Translation = (Vector3)(transform.Translation - world.AABB.Center); Vector3 toF = (Vector3)(to - world.AABB.Center); var hitValue = ((HkWorld)world.UserData).CastShape(toF, shape, ref transformF, filterLayer, extraPenetration); if (hitValue.HasValue) { m_resultWorlds.Clear(); return hitValue; } } m_resultWorlds.Clear(); return null; }