Ejemplo n.º 1
0
        private bool SteeringLogic()
        {
            Vector3 vector2;
            Color?  nullable;

            if (!base.IsFunctional)
            {
                return(false);
            }
            MyGridPhysics physics = base.CubeGrid.Physics;

            if (physics == null)
            {
                return(false);
            }
            if ((base.Stator != null) && MyFixedGrids.IsRooted(base.Stator.CubeGrid))
            {
                return(false);
            }
            if (this.m_slipCountdown > 0)
            {
                this.m_slipCountdown--;
            }
            if (this.m_staticHitCount == 0)
            {
                if (this.m_contactCountdown <= 0)
                {
                    return(false);
                }
                this.m_contactCountdown--;
                if (this.m_contactCountdown == 0)
                {
                    this.m_frictionCollector = 0f;
                    this.m_contactNormals.Clear();
                    return(false);
                }
            }
            Vector3 linearVelocity = physics.LinearVelocity;

            if (MyUtils.IsZero(ref linearVelocity, 1E-05f) || !physics.IsActive)
            {
                return(false);
            }
            MatrixD  worldMatrix       = base.WorldMatrix;
            Vector3D centerOfMassWorld = physics.CenterOfMassWorld;

            if (!this.m_contactNormals.GetAvgNormal(out vector2))
            {
                return(false);
            }
            this.LastUsedGroundNormal = vector2;
            Vector3 up          = (Vector3)worldMatrix.Up;
            Vector3 guideVector = Vector3.Cross(vector2, up);

            linearVelocity = Vector3.ProjectOnPlane(ref linearVelocity, ref vector2);
            Vector3 direction = Vector3.ProjectOnVector(ref linearVelocity, ref guideVector);
            Vector3 vector6   = direction - linearVelocity;

            if (MyUtils.IsZero(ref vector6, 1E-05f))
            {
                return(false);
            }
            bool    flag  = false;
            bool    flag2 = false;
            float   num   = 6f * this.m_frictionCollector;
            Vector3 vec   = Vector3.ProjectOnVector(ref vector6, ref up);
            float   num2  = vec.Length();
            bool    flag3 = num2 > num;

            if (!flag3 && (this.m_slipCountdown == 0))
            {
                if (num2 < 0.1)
                {
                    flag2 = true;
                }
            }
            else
            {
                flag = true;
                vec  = (vec * ((1f / num2) * num)) * (1f - MyPhysicsConfig.WheelSlipCutAwayRatio);
                if (flag3)
                {
                    this.m_slipCountdown = MyPhysicsConfig.WheelSlipCountdown;
                }
            }
            if (!flag2)
            {
                vec *= 1f - ((1f - this.m_frictionCollector) * MyPhysicsConfig.WheelSurfaceMaterialSteerRatio);
                Vector3 vector9 = Vector3.ProjectOnPlane(ref vec, ref vector2);
                MyMechanicalConnectionBlockBase stator = base.Stator;
                MyPhysicsBody body = null;
                if (stator != null)
                {
                    body = base.Stator.CubeGrid.Physics;
                }
                vector9 *= 0.1f;
                if (body == null)
                {
                    physics.ApplyImpulse(vector9 * physics.Mass, centerOfMassWorld);
                }
                else
                {
                    Vector3D          zero       = Vector3D.Zero;
                    MyMotorSuspension suspension = stator as MyMotorSuspension;
                    if (suspension != null)
                    {
                        Vector3 vector10;
                        vector9 *= MyMath.Clamp(suspension.Friction * 2f, 0f, 1f);
                        suspension.GetCoMVectors(out vector10);
                        zero = Vector3D.TransformNormal(-vector10, stator.CubeGrid.WorldMatrix);
                    }
                    Vector3D pos = centerOfMassWorld + zero;
                    float    wheelImpulseBlending = MyPhysicsConfig.WheelImpulseBlending;
                    vector9 = (this.m_lastFrameImpuse * wheelImpulseBlending) + (vector9 * (1f - wheelImpulseBlending));
                    this.m_lastFrameImpuse = vector9;
                    body.ApplyImpulse(vector9 * body.Mass, pos);
                    if (MyDebugDrawSettings.DEBUG_DRAW_WHEEL_PHYSICS)
                    {
                        nullable = null;
                        MyRenderProxy.DebugDrawArrow3DDir(pos, -zero, Color.Red, nullable, false, 0.1, null, 0.5f, false);
                        MyRenderProxy.DebugDrawSphere(pos, 0.1f, Color.Yellow, 1f, false, false, true, false);
                    }
                }
            }
            if (MyDebugDrawSettings.DEBUG_DRAW_WHEEL_PHYSICS)
            {
                nullable = null;
                MyRenderProxy.DebugDrawArrow3DDir(centerOfMassWorld, linearVelocity, Color.Yellow, nullable, false, 0.1, null, 0.5f, false);
                nullable = null;
                MyRenderProxy.DebugDrawArrow3DDir(centerOfMassWorld, direction, Color.Blue, nullable, false, 0.1, null, 0.5f, false);
                nullable = null;
                MyRenderProxy.DebugDrawArrow3DDir(centerOfMassWorld, vec, Color.MediumPurple, nullable, false, 0.1, null, 0.5f, false);
                nullable = null;
                MyRenderProxy.DebugDrawArrow3DDir(centerOfMassWorld + linearVelocity, vector6, Color.Red, nullable, false, 0.1, null, 0.5f, false);
                nullable = null;
                MyRenderProxy.DebugDrawArrow3DDir(centerOfMassWorld + up, vector2, Color.AliceBlue, nullable, false, 0.1, null, 0.5f, false);
                nullable = null;
                MyRenderProxy.DebugDrawArrow3DDir(centerOfMassWorld, Vector3.ProjectOnPlane(ref vec, ref vector2), flag ? Color.DarkRed : Color.IndianRed, nullable, false, 0.1, null, 0.5f, false);
                if (this.m_slipCountdown > 0)
                {
                    MyRenderProxy.DebugDrawText3D(centerOfMassWorld + (up * 2f), "Drift", Color.Red, 1f, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, -1, false);
                }
                MyRenderProxy.DebugDrawText3D(centerOfMassWorld + (up * 1.2f), this.m_staticHitCount.ToString(), Color.Red, 1f, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, -1, false);
            }
            return(!flag2);
        }
Ejemplo n.º 2
0
        private MyAttachableTopBlockBase FindMatchingTop()
        {
            Debug.Assert(CubeGrid != null);
            Debug.Assert(m_penetrations != null);
            Debug.Assert(CubeGrid.Physics != null);
            if (CubeGrid == null)
            {
                MySandboxGame.Log.WriteLine("MyPistonBase.FindMatchingTop(): Cube grid == null!");
                return(null);
            }

            if (m_penetrations == null)
            {
                MySandboxGame.Log.WriteLine("MyPistonBase.FindMatchingTop(): penetrations cache == null!");
                return(null);
            }

            if (CubeGrid.Physics == null)
            {
                MySandboxGame.Log.WriteLine("MyPistonBase.FindMatchingTop(): Cube grid physics == null!");
                return(null);
            }

            Quaternion orientation;
            Vector3D   pos;
            Vector3    halfExtents;

            ComputeTopQueryBox(out pos, out halfExtents, out orientation);
            try
            {
                MyPhysics.GetPenetrationsBox(ref halfExtents, ref pos, ref orientation, m_penetrations, MyPhysics.CollisionLayers.DefaultCollisionLayer);
                foreach (var obj in m_penetrations)
                {
                    var entity = obj.GetCollisionEntity();
                    if (entity == null || entity == CubeGrid)
                    {
                        continue;
                    }

                    MyAttachableTopBlockBase top = FindTopInGrid(entity, pos);

                    if (top != null)
                    {
                        return(top);
                    }

                    MyPhysicsBody body = entity.Physics as MyPhysicsBody;
                    if (body != null)
                    {
                        foreach (var child in body.WeldInfo.Children)
                        {
                            top = FindTopInGrid(child.Entity, pos);
                            if (top != null)
                            {
                                return(top);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
            }
            finally
            {
                m_penetrations.Clear();
            }
            return(null);
        }
        private void InitInternal()
        {
            // TODO: This will be fixed and made much more simple once ore models are done
            // https://app.asana.com/0/6594565324126/10473934569658

            var physicalItem = MyDefinitionManager.Static.GetPhysicalItemDefinition(Item.Content);

            string model = physicalItem.Model;

            VoxelMaterial = null;
            float scale = 1.0f;

            if (Item.Content is MyObjectBuilder_Ore)
            {
                string oreSubTypeId = physicalItem.Id.SubtypeId.ToString();
                foreach (var mat in MyDefinitionManager.Static.GetVoxelMaterialDefinitions())
                {
                    if (oreSubTypeId == mat.MinedOre)
                    {
                        VoxelMaterial = mat;
                        model         = MyDebris.GetRandomDebrisVoxel();
                        scale         = (float)Math.Pow((float)Item.Amount * physicalItem.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f);
                        break;
                    }
                }

                scale = (float)Math.Pow((float)Item.Amount * physicalItem.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f);
            }

            if (scale < 0.05f)
            {
                Close();
            }
            else if (scale < 0.15f)
            {
                scale = 0.15f;
            }

            FormatDisplayName(m_displayedText, Item);
            Init(m_displayedText, model, null, null, null);

            PositionComp.Scale = scale; // Must be set after init


            var     massProperties           = new HkMassProperties();
            HkShape shape                    = GetPhysicsShape(physicalItem.Mass * (float)Item.Amount, scale, out massProperties);
            var     scaleMatrix              = Matrix.CreateScale(scale);
            HkConvexTransformShape transform = new HkConvexTransformShape((HkConvexShape)shape, ref scaleMatrix, HkReferencePolicy.None);

            if (Physics != null)
            {
                Physics.Close();
            }
            Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS);
            Physics.CreateFromCollisionObject(transform, Vector3.Zero, MatrixD.Identity, massProperties, MyPhysics.FloatingObjectCollisionLayer);
            Physics.MaterialType = VoxelMaterial != null ? MyMaterialType.ROCK : MyMaterialType.METAL;

            Physics.Enabled = true;
            transform.Base.RemoveReference();
            Physics.PlayCollisionCueEnabled = true;
            NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME;
        }
Ejemplo n.º 4
0
        private void InitInternal()
        {
            // TODO: This will be fixed and made much more simple once ore models are done
            // https://app.asana.com/0/6594565324126/10473934569658

            var itemDefinition = MyDefinitionManager.Static.GetPhysicalItemDefinition(Item.Content);

            m_health = itemDefinition.Health;

            // Setting voxel material (if applicable)
            VoxelMaterial = null;
            if (itemDefinition.VoxelMaterial != MyStringHash.NullOrEmpty)
            {
                VoxelMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(itemDefinition.VoxelMaterial.String);
            }
            else if (Item.Content is MyObjectBuilder_Ore)
            {
                string oreSubTypeId    = itemDefinition.Id.SubtypeName;
                string materialName    = (Item.Content as MyObjectBuilder_Ore).GetMaterialName();
                bool   hasMaterialName = (Item.Content as MyObjectBuilder_Ore).HasMaterialName();

                foreach (var mat in MyDefinitionManager.Static.GetVoxelMaterialDefinitions())
                {
                    if ((hasMaterialName && materialName == mat.Id.SubtypeName) || (hasMaterialName == false && oreSubTypeId == mat.MinedOre))
                    {
                        VoxelMaterial = mat;
                        break;
                    }
                }
            }

            // Setting the item's model
            string model = itemDefinition.Model;

            if (itemDefinition.HasModelVariants)
            {
                int modelNum = itemDefinition.Models.Length;
                Debug.Assert(m_modelVariant >= 0 && m_modelVariant < modelNum, "Model variant overflow. This can happen if model variants changed");
                m_modelVariant = m_modelVariant % modelNum;

                model = itemDefinition.Models[m_modelVariant];
            }
            else if (Item.Content is MyObjectBuilder_Ore && VoxelMaterial != null)
            {
                // Only ores without found voxel material use the defined model (otherwise, the scrap metal does not work)
                model = MyDebris.GetRandomDebrisVoxel();
            }

            // Setting the scale
            float scale = this.Item.Scale;

            if (Item.Content is MyObjectBuilder_Ore)
            {
                scale *= (float)Math.Pow((float)Item.Amount * itemDefinition.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f);
            }
            else
            {
                scale *= (float)Math.Pow(itemDefinition.Volume / itemDefinition.ModelVolume, 0.333f);
            }
            if (scale < 0.05f)
            {
                Close();
            }
            else if (scale < 0.15f)
            {
                scale = 0.15f;
            }

            FormatDisplayName(m_displayedText, Item);
            Debug.Assert(model != null, "Floating object model is null");
            Init(m_displayedText, model, null, null, null);

            PositionComp.Scale = scale; // Must be set after init

            var massProperties = new HkMassProperties();
            var mass           = MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(itemDefinition.Mass) : itemDefinition.Mass;

            mass = mass * (float)Item.Amount;

            HkShape shape       = GetPhysicsShape(mass, scale, out massProperties);
            var     scaleMatrix = Matrix.CreateScale(scale);

            if (Physics != null)
            {
                Physics.Close();
            }
            Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS);

            int layer = mass > MyPerGameSettings.MinimumLargeShipCollidableMass ? MyPhysics.CollisionLayers.FloatingObjectCollisionLayer : MyPhysics.CollisionLayers.LightFloatingObjectCollisionLayer;

            if (VoxelMaterial != null || (shape.IsConvex && scale != 1f))
            {
                HkConvexTransformShape transform = new HkConvexTransformShape((HkConvexShape)shape, ref scaleMatrix, HkReferencePolicy.None);

                Physics.CreateFromCollisionObject(transform, Vector3.Zero, MatrixD.Identity, massProperties, layer);

                Physics.Enabled = true;
                transform.Base.RemoveReference();
            }
            else
            {
                Physics.CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, massProperties, layer);
                Physics.Enabled = true;
            }

            Physics.MaterialType            = this.EvaluatePhysicsMaterial(itemDefinition.PhysicalMaterial);
            Physics.PlayCollisionCueEnabled = true;
            Physics.RigidBody.ContactSoundCallbackEnabled = true;
            m_easeCollisionForce      = new HkEasePenetrationAction(Physics.RigidBody, 2f);
            m_massChangeForCollisions = 0.010f;

            NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME;
        }
Ejemplo n.º 5
0
        public override void Init(MyObjectBuilder_EntityBase objectBuilder)
        {
            base.Init(objectBuilder);
            var ob = objectBuilder as MyObjectBuilder_FracturedPiece;

            if (ob.Shapes.Count == 0)
            {
                return;
                //Debug.Fail("Invalid fracture piece! Dont call init without valid OB. Use pool/noinit.");
                //throw new Exception("Fracture piece has no shapes."); //throwing exception, otherwise there is fp with null physics which can mess up somwhere else
            }

            foreach (var shape in ob.Shapes)
            {
                Render.AddPiece(shape.Name, Matrix.CreateFromQuaternion(shape.Orientation));
            }
            OriginalBlocks.Clear();
            foreach (var def in ob.BlockDefinitions)
            {
                string model = null;
                MyPhysicalModelDefinition mdef;
                if (MyDefinitionManager.Static.TryGetDefinition <MyPhysicalModelDefinition>(def, out mdef))
                {
                    model = mdef.Model;
                }
                MyCubeBlockDefinition blockDef = null;
                MyDefinitionManager.Static.TryGetDefinition <MyCubeBlockDefinition>(def, out blockDef);

                if (model == null)
                {
                    Debug.Fail("Fracture piece Definition not found");
                    continue;
                }

                model = mdef.Model;
                if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null)
                {
                    MyDestructionData.Static.LoadModelDestruction(model, mdef, Vector3.One);
                }
                var shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0];
                var si    = new HkdShapeInstanceInfo(shape, null, null);
                m_children.Add(si);
                shape.GetChildren(m_children);

                if (blockDef != null && blockDef.BuildProgressModels != null)
                {
                    foreach (var progress in blockDef.BuildProgressModels)
                    {
                        model = progress.File;
                        if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null)
                        {
                            MyDestructionData.Static.LoadModelDestruction(model, blockDef, Vector3.One);
                        }
                        shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0];
                        si    = new HkdShapeInstanceInfo(shape, null, null);
                        m_children.Add(si);
                        shape.GetChildren(m_children);
                    }
                }

                OriginalBlocks.Add(def);
            }
            m_shapes.AddRange(ob.Shapes);

            Vector3?offset      = null;
            int     shapeAtZero = 0;

            for (int i = 0; i < m_children.Count; i++)
            {
                var child = m_children[i];
                Func <MyObjectBuilder_FracturedPiece.Shape, bool> x = s => s.Name == child.ShapeName;
                var result = m_shapes.Where(x);
                if (result.Count() > 0)
                {
                    var found = result.First();
                    var m     = Matrix.CreateFromQuaternion(found.Orientation);
                    if (!offset.HasValue && found.Name == m_shapes[0].Name)
                    {
                        offset      = child.GetTransform().Translation;
                        shapeAtZero = m_shapeInfos.Count;
                    }
                    m.Translation = child.GetTransform().Translation;
                    var si = new HkdShapeInstanceInfo(child.Shape.Clone(), m);
                    if (found.Fixed)
                    {
                        si.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED);
                    }
                    m_shapeInfos.Add(si);
                    m_shapes.Remove(found);
                }
                else
                {
                    child.GetChildren(m_children);
                }
            }

            if (m_shapeInfos.Count == 0)
            {
                List <string> shapesToLoad = new List <string>();
                foreach (var obShape in ob.Shapes)
                {
                    shapesToLoad.Add(obShape.Name);
                }

                var shapesStr = shapesToLoad.Aggregate((str1, str2) => str1 + ", " + str2);
                var blocksStr = OriginalBlocks.Aggregate("", (str, defId) => str + ", " + defId.ToString());
                var failMsg   = "No relevant shape was found for fractured piece. It was probably reexported and names changed. Shapes: " + shapesStr + ". Original blocks: " + shapesStr;

                Debug.Fail(failMsg);
                //HkdShapeInstanceInfo si = new HkdShapeInstanceInfo(new HkdBreakableShape((HkShape)new HkBoxShape(Vector3.One)), Matrix.Identity);
                //m_shapeInfos.Add(si);
                throw new Exception(failMsg);
            }

            if (offset.HasValue)
            {
                for (int i = 0; i < m_shapeInfos.Count; i++)
                {
                    var m = m_shapeInfos[i].GetTransform();
                    m.Translation -= offset.Value;
                    m_shapeInfos[i].SetTransform(ref m);
                }
                {
                    var m = m_shapeInfos[shapeAtZero].GetTransform();
                    m.Translation = Vector3.Zero;
                    m_shapeInfos[shapeAtZero].SetTransform(ref m);
                }
            }

            if (m_shapeInfos.Count > 0)
            {
                if (m_shapeInfos.Count == 1)
                {
                    Shape = m_shapeInfos[0].Shape;
                }
                else
                {
                    Shape = new HkdCompoundBreakableShape(null, m_shapeInfos);
                    ((HkdCompoundBreakableShape)Shape).RecalcMassPropsFromChildren();
                }
                Shape.SetStrenght(MyDestructionConstants.STRENGTH);
                var mp = new HkMassProperties();
                Shape.BuildMassProperties(ref mp);
                Shape.SetChildrenParent(Shape);
                Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS);
                Physics.CanUpdateAccelerations    = true;
                Physics.InitialSolverDeactivation = HkSolverDeactivation.High;
                Physics.CreateFromCollisionObject(Shape.GetShape(), Vector3.Zero, PositionComp.WorldMatrix, mp);
                Physics.BreakableBody = new HkdBreakableBody(Shape, Physics.RigidBody, null, (Matrix)PositionComp.WorldMatrix);
                Physics.BreakableBody.AfterReplaceBody += Physics.FracturedBody_AfterReplaceBody;

                if (OriginalBlocks.Count > 0)
                {
                    MyPhysicalModelDefinition def;
                    if (MyDefinitionManager.Static.TryGetDefinition <MyPhysicalModelDefinition>(OriginalBlocks[0], out def))
                    {
                        Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId;
                    }
                }


                var  rigidBody = Physics.RigidBody;
                bool isFixed   = MyDestructionHelper.IsFixed(Physics.BreakableBody.BreakableShape);
                if (isFixed)
                {
                    rigidBody.UpdateMotionType(HkMotionType.Fixed);
                    rigidBody.LinearVelocity  = Vector3.Zero;
                    rigidBody.AngularVelocity = Vector3.Zero;
                }


                Physics.Enabled = true;
            }
            m_children.Clear();
            m_shapeInfos.Clear();
        }
Ejemplo n.º 6
0
        public static bool PrefixUpdateMassFromInventories(List <MyCubeBlock> blocks, MyPhysicsBody rb, MyGridShape __instance)
        {
            RefTimeSpan time;

            if (!lastUpdateTimestamp.TryGetValue(__instance, out time))
            {
                lastUpdateTimestamp.Add(__instance, new RefTimeSpan(MySession.Static.ElapsedGameTime));
                return(true);
            }

            if ((MySession.Static.ElapsedGameTime - time.timespan).TotalMilliseconds < 1000)
            {
                return(false);
            }

            lastUpdateTimestamp.Remove(__instance);
            lastUpdateTimestamp.Add(__instance, new RefTimeSpan(MySession.Static.ElapsedGameTime));

            return(true);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// precise collision detection based on data from broadphase. Collision detection runs multithreaded.
        /// </summary>
        protected void NearPhaseUpdate(float timeStep)
        {
            m_InteractionsList = m_BroadPhase.GetRBElementInteractionList();

            if (MyFakes.DEBUG_DRAW_COLLIDING_ENTITIES)
            {
                bool  logToConsole = false;
                bool  debugDraw    = true;
                bool  drawText     = true;
                float textSize     = 0.7f;

                Vector2 screenPos = new Vector2(100, 100);

                if (logToConsole)
                {
                    Console.WriteLine("-----------------------------");
                }

                Vector4 color = new Vector4(1, 0, 0, 1);

                foreach (MyRBElementInteraction i in m_InteractionsList)
                {
                    object obj = i.GetRigidBody1().m_UserData;
                    if (obj is MyPhysicsBody)
                    {
                        MyPhysicsBody rb   = (MyPhysicsBody)obj;
                        string        name = rb.Entity.ToString() + " " + i.GetRigidBody1().GUID;

                        if (debugDraw)
                        {
                            MyDebugDrawCachedLines.AddAABB(rb.Entity.WorldAABB, Color.Red);
                        }

                        if (drawText)
                        {
                            System.Text.StringBuilder sb0 = new System.Text.StringBuilder(100);
                            sb0.Append(ParseLastElement(i.ToString()));
                            MyDebugDraw.TextBatch.AddText(screenPos, sb0, Color.Red, textSize);
                            screenPos.Y += 20 * textSize;

                            System.Text.StringBuilder sb = new System.Text.StringBuilder(100);
                            sb.Append(ParseLastElement(name));
                            MyDebugDraw.TextBatch.AddText(screenPos, sb, Color.YellowGreen, textSize);
                            screenPos.Y += 20 * textSize;
                        }

                        if (logToConsole)
                        {
                            Console.ForegroundColor = ConsoleColor.Yellow;
                            Console.WriteLine(name);
                            Console.ForegroundColor = ConsoleColor.Gray;
                        }
                    }

                    object obj2 = i.GetRigidBody2().m_UserData;
                    if (obj2 is MyPhysicsBody)
                    {
                        MyPhysicsBody rb2   = (MyPhysicsBody)obj2;
                        string        name2 = rb2.Entity.ToString() + " " + i.GetRigidBody2().GUID;

                        if (debugDraw)
                        {
                            MyDebugDrawCachedLines.AddAABB(rb2.Entity.WorldAABB, Color.Red);
                        }

                        if (drawText)
                        {
                            System.Text.StringBuilder sb2 = new System.Text.StringBuilder(100);
                            sb2.Append(ParseLastElement(name2));

                            MyDebugDraw.TextBatch.AddText(screenPos, sb2, Color.LightBlue, textSize);
                            screenPos.Y += 20 * textSize;
                        }

                        if (logToConsole)
                        {
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.WriteLine(name2);
                            Console.ForegroundColor = ConsoleColor.Gray;
                        }
                    }

                    if (drawText)
                    {
                        screenPos.Y += 10 * textSize;
                    }
                }
            }

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Processing interactions");

#if RENDER_PROFILING
            foreach (MyRBElementInteraction i in m_InteractionsList)
            {
                i.DoWork();
            }
            //Parallel.For(0, m_InteractionsList.Count, m_InteractionAction, 1);
#else
            /*foreach (MyRBElementInteraction i in m_InteractionsList)
             * {
             *  i.DoWork();
             * } */
            //Peaks
            //System.Threading.Tasks.Parallel.For(0, m_InteractionsList.Count, m_InteractionAction);
            Parallel.For(0, m_InteractionsList.Count, m_InteractionAction, 1);
#endif

            /*
             * Dictionary<MinerWars.AppCode.Game.Entities.MyEntity, HashSet<MinerWars.AppCode.Game.Entities.MyEntity>> test = new Dictionary<Game.Managers.EntityManager.Entities.MyEntity, HashSet<Game.Managers.EntityManager.Entities.MyEntity>>();
             *
             * foreach (MyRBElementInteraction i in m_InteractionsList)
             * {
             * MinerWars.AppCode.Game.Entities.MyEntity e1 = ((MyPhysicsBody)i.GetRigidBody1().m_UserData).Entity;
             * MinerWars.AppCode.Game.Entities.MyEntity e2 = ((MyPhysicsBody)i.GetRigidBody2().m_UserData).Entity;
             *
             * if (test.ContainsKey(e1))
             * {
             * if (!test[e1].Add(e2))
             * {
             * }
             * }
             * else
             * {
             * HashSet<Game.Managers.EntityManager.Entities.MyEntity> hs = new HashSet<Game.Managers.EntityManager.Entities.MyEntity>();
             * hs.Add(e2);
             * test.Add(e1, hs);
             * }
             * if (test.ContainsKey(e2))
             * {
             * if (!test[e2].Add(e1))
             * {
             * }
             * }
             * else
             * {
             * HashSet<Game.Managers.EntityManager.Entities.MyEntity> hs = new HashSet<Game.Managers.EntityManager.Entities.MyEntity>();
             * hs.Add(e1);
             * test.Add(e2, hs);
             *
             * }
             * }   */


            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            m_InteractionsList.Clear();
        }
Ejemplo n.º 8
0
        public override void AccumulateCorrection(ref VRageMath.Vector3 correction, ref float weight)
        {
            // Don't do any correction if we're not moving
            if (Parent.Speed < 0.01)
            {
                return;
            }

            Vector3D position = Parent.PositionAndOrientation.Translation;

            // Find trees
            Quaternion rotation    = Quaternion.Identity;
            HkShape    sphereShape = new HkSphereShape(6);

            MyPhysics.GetPenetrationsShape(sphereShape, ref position, ref rotation, m_trees, MyPhysics.CollisionLayers.NoVoxelCollisionLayer);

            foreach (var tree in m_trees)
            {
                // Make sure the tree is actually a tree
                if (tree.Body == null)
                {
                    continue;
                }
                MyPhysicsBody physicsBody = tree.Body.UserObject as MyPhysicsBody;
                if (physicsBody == null)
                {
                    continue;
                }

                HkShape bodyShape = tree.Body.GetShape();
                if (bodyShape.ShapeType != HkShapeType.StaticCompound)
                {
                    continue;
                }

                // Get the static compound shape
                HkStaticCompoundShape staticCompoundShape = (HkStaticCompoundShape)bodyShape;

                int  instanceId;
                uint childKey;
                staticCompoundShape.DecomposeShapeKey(tree.ShapeKey, out instanceId, out childKey);

                // Get the local shape position, and add entity world position
                Vector3D item = staticCompoundShape.GetInstanceTransform(instanceId).Translation;
                item += physicsBody.GetWorldMatrix().Translation;

                // Avoid tree
                Vector3D dir  = item - position;
                var      dist = dir.Normalize();
                dir = Vector3D.Reject(Parent.ForwardVector, dir);

                dir.Y = 0.0f;
                if (dir.Z * dir.Z + dir.X * dir.X < 0.1)
                {
                    Vector3D dirLocal = Vector3D.TransformNormal(dir, Parent.PositionAndOrientationInverted);
                    dir = position - item;
                    dir = Vector3D.Cross(Vector3D.Up, dir);
                    if (dirLocal.X < 0)
                    {
                        dir = -dir;
                    }
                }

                dir.Normalize();

                correction += (6f - dist) * Weight * dir;
                if (!correction.IsValid())
                {
                    System.Diagnostics.Debugger.Break();
                }
            }

            m_trees.Clear();

            weight += Weight;
        }
Ejemplo n.º 9
0
        public override void Init(MyObjectBuilder_EntityBase objectBuilder)
        {
            base.Init(objectBuilder);
            var ob = objectBuilder as MyObjectBuilder_FracturedPiece;

            if (ob.Shapes.Count == 0)
            {
                Debug.Fail("Invalid fracture piece! Dont call init without valid OB. Use pool/noinit.");
                throw new Exception("Fracture piece has no shapes."); //throwing exception, otherwise there is fp with null physics which can mess up somwhere else
            }

            foreach (var shape in ob.Shapes)
            {
                Render.AddPiece(shape.Name, Matrix.CreateFromQuaternion(shape.Orientation));
            }
            OriginalBlocks.Clear();
            foreach (var def in ob.BlockDefinitions)
            {
                string model = null;
                MyPhysicalModelDefinition mdef;
                if (MyDefinitionManager.Static.TryGetDefinition <MyPhysicalModelDefinition>(def, out mdef))
                {
                    model = mdef.Model;
                }

                if (model == null)
                {
                    Debug.Fail("Fracture piece Definition not found");
                    continue;
                }
                if (MyModels.GetModelOnlyData(model).HavokBreakableShapes == null)
                {
                    MyDestructionData.Static.LoadModelDestruction(mdef, false, Vector3.One);
                }
                var shape = MyModels.GetModelOnlyData(model).HavokBreakableShapes[0];
                var si    = new HkdShapeInstanceInfo(shape, null, null);
                m_children.Add(si);
                shape.GetChildren(m_children);
                OriginalBlocks.Add(def);
            }
            m_shapes.AddRange(ob.Shapes);

            Vector3?offset      = null;
            int     shapeAtZero = 0;

            for (int i = 0; i < m_children.Count; i++)
            {
                var child = m_children[i];
                Func <MyObjectBuilder_FracturedPiece.Shape, bool> x = s => s.Name == child.ShapeName;
                var result = m_shapes.Where(x);
                if (result.Count() > 0)
                {
                    var found = result.First();
                    var m     = Matrix.CreateFromQuaternion(found.Orientation);
                    if (!offset.HasValue && found.Name == m_shapes[0].Name)
                    {
                        offset      = child.GetTransform().Translation;
                        shapeAtZero = m_shapeInfos.Count;
                    }
                    m.Translation = child.GetTransform().Translation;
                    var si = new HkdShapeInstanceInfo(child.Shape.Clone(), m);
                    if (found.Fixed)
                    {
                        si.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED);
                    }
                    m_shapeInfos.Add(si);
                    m_shapes.Remove(found);
                }
                else
                {
                    child.GetChildren(m_children);
                }
            }

            if (m_shapeInfos.Count == 0)
            {
                Debug.Fail("No relevant shape was found for fractured piece. It was probably reexported and names changed.");
                //HkdShapeInstanceInfo si = new HkdShapeInstanceInfo(new HkdBreakableShape((HkShape)new HkBoxShape(Vector3.One)), Matrix.Identity);
                //m_shapeInfos.Add(si);
                throw new Exception("No relevant shape was found for fractured piece. It was probably reexported and names changed.");
            }

            if (offset.HasValue)
            {
                for (int i = 0; i < m_shapeInfos.Count; i++)
                {
                    var m = m_shapeInfos[i].GetTransform();
                    m.Translation -= offset.Value;
                    m_shapeInfos[i].SetTransform(ref m);
                }
                {
                    var m = m_shapeInfos[shapeAtZero].GetTransform();
                    m.Translation = Vector3.Zero;
                    m_shapeInfos[shapeAtZero].SetTransform(ref m);
                }
            }

            if (m_shapeInfos.Count > 0)
            {
                if (m_shapeInfos.Count == 1)
                {
                    Shape = m_shapeInfos[0].Shape;
                }
                else
                {
                    Shape = new HkdCompoundBreakableShape(null, m_shapeInfos);
                    ((HkdCompoundBreakableShape)Shape).RecalcMassPropsFromChildren();
                }
                Shape.SetStrenght(MyDestructionConstants.STRENGTH);
                var mp = new HkMassProperties();
                Shape.BuildMassProperties(ref mp);
                Shape.SetChildrenParent(Shape);
                Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS);
                Physics.InitialSolverDeactivation = HkSolverDeactivation.Medium;
                Physics.CreateFromCollisionObject(Shape.GetShape(), Vector3.Zero, PositionComp.WorldMatrix, mp);
                Physics.BreakableBody = new HkdBreakableBody(Shape, Physics.RigidBody, MyPhysics.SingleWorld.DestructionWorld, (Matrix)PositionComp.WorldMatrix);
                Physics.BreakableBody.AfterReplaceBody += Physics.FracturedBody_AfterReplaceBody;

                var  rigidBody = Physics.RigidBody;
                bool isFixed   = MyDestructionHelper.IsFixed(Physics.BreakableBody.BreakableShape);
                if (isFixed)
                {
                    rigidBody.UpdateMotionType(HkMotionType.Fixed);
                    rigidBody.LinearVelocity  = Vector3.Zero;
                    rigidBody.AngularVelocity = Vector3.Zero;
                }

                //Cannot set keyframed in constructor, because Havok does not allow set CoM on kinematic object..
                if (!Sync.IsServer)
                {
                    Physics.RigidBody.UpdateMotionType(HkMotionType.Keyframed);
                }
                Physics.Enabled = true;
            }
            m_children.Clear();
            m_shapeInfos.Clear();
        }
Ejemplo n.º 10
0
        public void ReloadDetectors(bool refreshNetworks = true)
        {
            m_detectors.Clear();
            m_detectorInteractiveObjects.Clear();

            if (DetectorPhysics != null)
            {
                DetectorPhysics.Close();
            }

            List <HkShape> shapes = new List <HkShape>();
            BoundingBox    aabb   = new BoundingBox(-Vector3.One / 2, Vector3.One / 2);

            if (Render.GetModel() != null)
            {
                foreach (var dummy in Render.GetModel().Dummies)
                {
                    var          dummyLowerCaseKey = dummy.Key.ToLower();
                    const string DETECTOR_PREFIX   = "detector_";
                    if (dummyLowerCaseKey.StartsWith(DETECTOR_PREFIX) && dummyLowerCaseKey.Length > DETECTOR_PREFIX.Length)
                    {
                        String[] parts = dummyLowerCaseKey.Split('_');
                        if (parts.Length < 2)
                        {
                            continue;
                        }

                        var           dummyData = dummy.Value;
                        List <Matrix> matrices;
                        if (!m_detectors.TryGetValue(parts[1], out matrices))
                        {
                            matrices = new List <Matrix>();
                            m_detectors[parts[1]] = matrices;
                        }
                        matrices.Add(Matrix.Invert(dummyData.Matrix));

                        // TODO: this should be nicer
                        int shapeKey          = shapes.Count;
                        var interactiveObject = CreateInteractiveObject(parts[1], dummyLowerCaseKey, dummyData, shapeKey);
                        if (interactiveObject != null)
                        {
                            unsafe
                            {
                                fixed(Vector3 *corner = m_detectorVertices)
                                aabb.GetCornersUnsafe(corner);
                            }
                            for (int i = 0; i < BoundingBox.CornerCount; i++)
                            {
                                m_detectorVertices[i] = Vector3.Transform(m_detectorVertices[i], dummyData.Matrix);
                            }

                            shapes.Add(new HkConvexVerticesShape(m_detectorVertices, BoundingBox.CornerCount, false, 0));
                            m_detectorInteractiveObjects.Add(shapeKey, interactiveObject);
                        }
                    }
                }
            }

            if (shapes.Count > 0)
            {
                var listShape = new HkListShape(shapes.GetInternalArray(), shapes.Count, HkReferencePolicy.TakeOwnership);
                DetectorPhysics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DISABLE_COLLISION_RESPONSE);
                DetectorPhysics.CreateFromCollisionObject((HkShape)listShape, Vector3.Zero, WorldMatrix);
                DetectorPhysics.Enabled = true;
                listShape.Base.RemoveReference();
            }

            /*
             * var inventoryBlock = this as IMyInventoryOwner;
             * if (refreshNetworks && inventoryBlock != null)
             * {
             *  CubeGrid.ConveyorSystem.Remove(inventoryBlock);
             *  CubeGrid.ConveyorSystem.Add(inventoryBlock);
             * }*/
        }
Ejemplo n.º 11
0
 internal void UpdateAfterSimulation10()
 {
     this.UpdateRigidBodyShape();
     if (this.m_voxelMap.Storage != null)
     {
         foreach (IMyEntity entity in this.m_nearbyEntities)
         {
             if (entity != null)
             {
                 bool          flag    = false;
                 MyPhysicsBody physics = entity.Physics as MyPhysicsBody;
                 if (((physics != null) && (physics.RigidBody != null)) && ((physics.RigidBody.Layer == 0x17) || (physics.RigidBody.Layer == 10)))
                 {
                     flag = true;
                 }
                 if ((((entity is MyCubeGrid) || flag) && !entity.MarkedForClose) && (entity.Physics != null))
                 {
                     BoundingBoxD xd;
                     this.GetPrediction(entity, out xd);
                     if (xd.Intersects(this.m_voxelMap.PositionComp.WorldAABB))
                     {
                         Vector3I           vectori;
                         Vector3I           vectori2;
                         HkUniformGridShape shape;
                         int num1;
                         if (flag || !UseLod1VoxelPhysics)
                         {
                             num1 = 0;
                         }
                         else
                         {
                             num1 = 1;
                         }
                         int          lod  = num1;
                         int          num2 = 1 << (lod & 0x1f);
                         BoundingBoxD xd2  = xd.TransformFast(this.m_voxelMap.PositionComp.WorldMatrixInvScaled);
                         xd2.Translate(this.m_voxelMap.SizeInMetresHalf);
                         Vector3 max = (Vector3)xd2.Max;
                         Vector3 min = (Vector3)xd2.Min;
                         this.ClampVoxelCoords(ref min, ref max, out vectori, out vectori2);
                         vectori  = vectori >> lod;
                         vectori2 = vectori2 >> lod;
                         int size = ((vectori2 - vectori) + 1).Size;
                         if (size >= m_cellsToGenerateBuffer.Length)
                         {
                             m_cellsToGenerateBuffer = new Vector3I[MathHelper.GetNearestBiggerPowerOfTwo(size)];
                         }
                         if (this.GetShape(lod, out shape))
                         {
                             if (shape.Base.IsZero)
                             {
                                 MyAnalyticsHelper.ReportBug("Null voxel shape", "SE-7366", true, @"E:\Repo1\Sources\Sandbox.Game\Engine\Voxels\MyVoxelPhysicsBody.cs", 680);
                             }
                             else
                             {
                                 int requiredCellsCount = shape.GetMissingCellsInRange(ref vectori, ref vectori2, m_cellsToGenerateBuffer);
                                 if (requiredCellsCount != 0)
                                 {
                                     BoundingBoxI box = new BoundingBoxI((vectori * 8) * num2, (Vector3I)(((vectori2 + 1) * 8) * num2));
                                     box.Translate(this.m_voxelMap.StorageMin);
                                     if ((requiredCellsCount > 0) && (this.m_voxelMap.Storage.Intersect(ref box, lod, true) != ContainmentType.Intersects))
                                     {
                                         this.SetEmptyShapes(lod, ref shape, requiredCellsCount);
                                     }
                                     else
                                     {
                                         for (int i = 0; i < requiredCellsCount; i++)
                                         {
                                             this.StartPrecalcJobPhysicsIfNeeded(lod, i);
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
         this.ScheduleBatchJobs();
         if (this.m_bodiesInitialized)
         {
             this.CheckAndDiscardShapes();
         }
     }
 }
Ejemplo n.º 12
0
        protected MyMotorRotor FindMatchingRotor()
        {
            Debug.Assert(CubeGrid != null);
            Debug.Assert(m_penetrations != null);
            Debug.Assert(CubeGrid.Physics != null);
            if (CubeGrid == null)
            {
                MySandboxGame.Log.WriteLine("MyMotorStator.FindMatchingRotor(): Cube grid == null!");
                return(null);
            }

            if (m_penetrations == null)
            {
                MySandboxGame.Log.WriteLine("MyMotorStator.FindMatchingRotor(): penetrations cache == null!");
                return(null);
            }

            if (CubeGrid.Physics == null)
            {
                MySandboxGame.Log.WriteLine("MyMotorStator.FindMatchingRotor(): Cube grid physics == null!");
                return(null);
            }

            Quaternion orientation;
            Vector3D   pos;
            Vector3    halfExtents;

            ComputeRotorQueryBox(out pos, out halfExtents, out orientation);
            try
            {
                MyPhysics.GetPenetrationsBox(ref halfExtents, ref pos, ref orientation, m_penetrations, MyPhysics.CollisionLayers.DefaultCollisionLayer);
                foreach (var obj in m_penetrations)
                {
                    var entity = obj.GetCollisionEntity();
                    if (entity == null || entity == CubeGrid)
                    {
                        continue;
                    }

                    MyMotorRotor rotor = FindRotorInGrid(entity);

                    if (rotor != null)
                    {
                        return(rotor);
                    }

                    MyPhysicsBody body = entity.Physics as MyPhysicsBody;
                    if (body != null)
                    {
                        foreach (var child in  body.WeldInfo.Children)
                        {
                            rotor = FindRotorInGrid(child.Entity);
                            if (rotor != null)
                            {
                                return(rotor);
                            }
                        }
                    }
                }
            }
            finally
            {
                m_penetrations.Clear();
            }
            return(null);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Reveals this group to game and physics logic.
        /// </summary>
        public void Reveal()
        {
            foreach (var entity in Grids)
            {
                if (entity.Parent == null)
                {
                    MyGamePruningStructure.Add(entity);
                }
            }


            foreach (var body in Grids)
            {
                var world = body.Physics?.HavokWorld;
                if (world == null || body.Physics.IsWelded)
                {
                    continue;
                }
                try
                {
                    world.LockCriticalOperations();
                    ActivateRigidBody(body, world, body.Physics.RigidBody);
                    ActivateRigidBody(body, world, body.Physics.RigidBody2);
                    foreach (var constraint in body.Physics.Constraints)
                    {
                        if (MyPhysicsBody.IsConstraintValid(constraint))
                        {
                            world.AddConstraint(constraint);
                        }
                    }
                }
                finally
                {
                    world.UnlockCriticalOperations();
                }
            }

            foreach (var entity in Grids)
            {
                if (entity.Parent == null)
                {
                    RegisterRecursive(entity);
                }
            }

            void RegisterRecursive(IMyEntity e)
            {
                MyEntities.RegisterForUpdate((MyEntity)e);
                if (e.Hierarchy == null)
                {
                    return;
                }

                foreach (var child in e.Hierarchy.Children)
                {
                    RegisterRecursive(child.Container.Entity);
                }
            }

            void ActivateRigidBody(MyCubeGrid grid, HkWorld world, HkRigidBody body)
            {
                if (body == null)
                {
                    return;
                }

                // make it dynamic
                if (body.GetMotionType() != HkMotionType.Dynamic && !grid.IsStatic)
                {
                    body.UpdateMotionType(HkMotionType.Dynamic);
                }

                // wake it up
                body.Activate();
                // restore velocity?
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Conceals this group from game and physics logic.
        /// </summary>
        public void Conceal()
        {
            foreach (var body in Grids)
            {
                if (body.Parent == null)
                {
                    UnregisterRecursive(body);
                }
            }

            foreach (var body in Grids)
            {
                var world = body.Physics?.HavokWorld;
                if (world == null || body.Physics.IsWelded)
                {
                    continue;
                }
                try
                {
                    world.LockCriticalOperations();
                    foreach (var constraint in body.Physics.Constraints)
                    {
                        if (MyPhysicsBody.IsConstraintValid(constraint))
                        {
                            world.RemoveConstraint(constraint);
                        }
                    }
                    DeactivateRigidBody(body, world, body.Physics.RigidBody);
                    DeactivateRigidBody(body, world, body.Physics.RigidBody2);
                }
                finally
                {
                    world.UnlockCriticalOperations();
                }
            }

            foreach (var entity in Grids)
            {
                if (entity.Parent == null)
                {
                    MyGamePruningStructure.Remove(entity);
                }
            }

            void DeactivateRigidBody(MyCubeGrid grid, HkWorld world, HkRigidBody body)
            {
                if (world == null || body == null)
                {
                    return;
                }
                // stop it
                body.LinearVelocity  = Vector3.Zero;
                body.AngularVelocity = Vector3.Zero;
                // put it to sleep
                body.Deactivate();
                // make it static
                if (body.GetMotionType() != HkMotionType.Fixed)
                {
                    body.UpdateMotionType(HkMotionType.Fixed);
                }
                // Remove from collision
                // Cache velocity?
            }

            void UnregisterRecursive(IMyEntity e)
            {
                MyEntities.UnregisterForUpdate((MyEntity)e);
                if (e.Hierarchy == null)
                {
                    return;
                }

                foreach (var child in e.Hierarchy.Children)
                {
                    UnregisterRecursive(child.Container.Entity);
                }
            }
        }