static void PreallocateObjects()
        {
            if (m_objectPool == null)
            {
                m_objectPool = new MyObjectsPool <MyExplosionDebrisModel>(MyExplosionsConstants.MAX_EXPLOSION_DEBRIS_OBJECTS);
            }
            m_objectPool.DeallocateAll();

            List <MyRBElementDesc> collisionPrimitives = new List <MyRBElementDesc>();

            MyPhysicsObjects      physobj    = MyPhysics.physicsSystem.GetPhysicsObjects();
            MyRBSphereElementDesc sphereDesc = physobj.GetRBSphereElementDesc();

            sphereDesc.SetToDefault();
            sphereDesc.m_RBMaterial = MyMaterialsConstants.GetMaterialProperties(MODEL_DEBRIS_MATERIAL_TYPE).PhysicsMaterial;

            collisionPrimitives.Add(sphereDesc);

            int counter = 0;

            foreach (var item in m_objectPool.GetPreallocatedItemsArray())
            {
                MyModelsEnum   modelEnum      = (MyModelsEnum)((int)MyModelsEnum.Debris1 + counter % 31);
                MyModel        model          = MyModels.GetModelOnlyData(modelEnum);
                BoundingSphere boundingSphere = model.BoundingSphere;

                sphereDesc.m_Radius             = boundingSphere.Radius;
                sphereDesc.m_Matrix.Translation = boundingSphere.Center;

                item.Value.Init(collisionPrimitives, modelEnum);
                counter++;
            }
        }
        static void PreallocateObjects()
        {
            if (m_objectPool == null)
            {
                m_objectPool = new MyObjectsPool <MyExplosionDebrisVoxel>(MyExplosionsConstants.MAX_EXPLOSION_DEBRIS_OBJECTS);
            }
            m_objectPool.DeallocateAll();

            //  This collision primitive is used by every instance of this class
            MyModel                model               = MyModels.GetModelOnlyData(VOXEL_DEBRIS_MODEL_ENUM);
            BoundingSphere         boundingSphere      = model.BoundingSphere;
            List <MyRBElementDesc> collisionPrimitives = new List <MyRBElementDesc>();

            MyPhysicsObjects      physobj      = MyPhysics.physicsSystem.GetPhysicsObjects();
            MyRBSphereElementDesc sphereDesc   = physobj.GetRBSphereElementDesc();
            MyMaterialType        materialType = MyMaterialType.ROCK;

            sphereDesc.SetToDefault();
            sphereDesc.m_RBMaterial         = MyMaterialsConstants.GetMaterialProperties(materialType).PhysicsMaterial;
            sphereDesc.m_Radius             = boundingSphere.Radius;
            sphereDesc.m_Matrix.Translation = model.BoundingSphere.Center;

            collisionPrimitives.Add(sphereDesc);


            int counter = 0;

            foreach (LinkedListNode <MyExplosionDebrisVoxel> item in m_objectPool.GetPreallocatedItemsArray())
            {
                item.Value.Init(collisionPrimitives);
                counter++;
            }
        }
Exemple #3
0
        public override void Init(string displayName, Microsoft.Xna.Framework.Vector3 relativePosition, Microsoft.Xna.Framework.Matrix localOrientation, MyMwcObjectBuilder_PrefabBase objectBuilder, MyPrefabConfiguration prefabConfig)
        {
            m_config = prefabConfig;
            MyPrefabConfigurationKinematicRotating config = (MyPrefabConfigurationKinematicRotating)prefabConfig;

            base.Init(displayName, relativePosition, localOrientation, objectBuilder, prefabConfig);
            Physics.RemoveAllElements();

            // create the box
            MyPhysicsObjects            physobj          = MyPhysics.physicsSystem.GetPhysicsObjects();
            MyRBTriangleMeshElementDesc trianglemeshDesc = physobj.GetRBTriangleMeshElementDesc();

            trianglemeshDesc.SetToDefault();
            trianglemeshDesc.m_Model      = ModelLod0;
            trianglemeshDesc.m_RBMaterial = MyMaterialsConstants.GetMaterialProperties(config.MaterialType).PhysicsMaterial;;


            MyRBTriangleMeshElement trEl = (MyRBTriangleMeshElement)physobj.CreateRBElement(trianglemeshDesc);

            this.Physics = new MyPhysicsBody(this, 1.0f, RigidBodyFlag.RBF_RBO_STATIC)
            {
                MaterialType = config.MaterialType
            };
            this.Physics.Enabled        = true;
            this.Physics.CollisionLayer = MyConstants.COLLISION_LAYER_PREFAB_KINEMATIC;
            this.Physics.AddElement(trEl, true);

            MyModel model = MyModels.GetModelOnlyDummies(m_config.ModelLod0Enum);

            foreach (var dummyKVP in model.Dummies)
            {
                if (dummyKVP.Key.StartsWith("Dummy"))
                {
                    MyModelDummy dummy                         = dummyKVP.Value;
                    MyModelsEnum rotatingPartModel             = MyModels.GetModelEnumByAssetName(dummy.CustomData["LINKEDMODEL"].ToString());
                    MyPrefabKinematicRotatingPart rotatingPart = new MyPrefabKinematicRotatingPart(this.GetOwner());
                    rotatingPart.Init(this, rotatingPartModel, config.MaterialType, dummy.Matrix, config.RotatingVelocity, true, config.SoundLooping, config.SoundOpening, config.SoundClosing);
                    m_parts.Add(rotatingPart);
                }
            }

            AppCode.Physics.MyPhysics.physicsSystem.GetRigidBodyModule().EnableCollisionInLayers(MyConstants.COLLISION_LAYER_PREFAB_KINEMATIC, MyConstants.COLLISION_LAYER_MISSILE, true);
            AppCode.Physics.MyPhysics.physicsSystem.GetRigidBodyModule().EnableCollisionInLayers(MyConstants.COLLISION_LAYER_PREFAB_KINEMATIC, MyConstants.COLLISION_LAYER_ALL, true);
            AppCode.Physics.MyPhysics.physicsSystem.GetRigidBodyModule().EnableCollisionInLayers(MyConstants.COLLISION_LAYER_PREFAB_KINEMATIC, MyConstants.COLLISION_LAYER_MODEL_DEBRIS, true);
            AppCode.Physics.MyPhysics.physicsSystem.GetRigidBodyModule().EnableCollisionInLayers(MyConstants.COLLISION_LAYER_PREFAB_KINEMATIC, MyConstants.COLLISION_LAYER_VOXEL_DEBRIS, true);
            AppCode.Physics.MyPhysics.physicsSystem.GetRigidBodyModule().EnableCollisionInLayers(MyConstants.COLLISION_LAYER_PREFAB_KINEMATIC, MyConstants.COLLISION_LAYER_PREFAB_KINEMATIC_PART, false);

            NeedsUpdate = false;
            EnabledChanged();
            //Enabled = true;
        }
Exemple #4
0
        //  Update position, check collisions, etc.
        //  Return false if projectile dies/timeouts in this tick.
        public bool Update()
        {
            //  Projectile was killed , but still not last time drawn, so we don't need to do update (we are waiting for last draw)
            if (m_state == MyProjectileStateEnum.KILLED)
            {
                return(true);
            }

            //  Projectile was killed and last time drawn, so we can finally remove it from buffer
            if (m_state == MyProjectileStateEnum.KILLED_AND_DRAWN)
            {
                if (m_trailEffect != null)
                {
                    // stop the trail effect
                    m_trailEffect.Stop();
                    m_trailEffect = null;
                }

                return(false);
            }

            Vector3 position = m_position;

            m_position += m_velocity * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            m_velocity  = m_externalVelocity * m_externalAddition + m_directionNormalized * m_speed;
            if (m_externalAddition < 1.0f)
            {
                m_externalAddition *= 0.5f;
            }

            //  Distance timeout
            float trajectoryLength = Vector3.Distance(m_position, m_origin);

            if (trajectoryLength >= m_maxTrajectory)
            {
                if (m_trailEffect != null)
                {
                    // stop the trail effect
                    m_trailEffect.Stop();
                    m_trailEffect = null;
                }

                m_state = MyProjectileStateEnum.KILLED;
                return(true);
            }

            if (m_trailEffect != null)
            {
                m_trailEffect.WorldMatrix = Matrix.CreateTranslation(m_position);
            }

            m_checkIntersectionIndex++;
            m_checkIntersectionIndex = m_checkIntersectionIndex % CHECK_INTERSECTION_INTERVAL;

            //check only each n-th intersection
            if (m_checkIntersectionIndex != 0)
            {
                return(true);
            }

            //  Calculate hit point, create decal and throw debris particles
            Vector3 lineEndPosition = position + CHECK_INTERSECTION_INTERVAL * (m_velocity * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS);

            MyLine line = new MyLine(m_positionChecked ? position : m_origin, lineEndPosition, true);

            m_positionChecked = true;

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MyEntities.GetIntersectionWithLine()");
            MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, m_ignorePhysObject, null, false);

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

            MyEntity physObject = intersection != null ? intersection.Value.Entity : null;

            if (physObject != null)
            {
                while (physObject.Physics == null && physObject.Parent != null)
                {
                    physObject = physObject.Parent;
                }
            }

            if ((intersection != null) && (physObject != null) && (physObject.Physics.CollisionLayer != MyConstants.COLLISION_LAYER_UNCOLLIDABLE) && m_ignorePhysObject != physObject)
            {
                MyIntersectionResultLineTriangleEx intersectionValue = intersection.Value;

                bool isPlayerShip = MySession.PlayerShip == physObject;

                MyMaterialType materialType = isPlayerShip ? MyMaterialType.PLAYERSHIP : physObject.Physics.MaterialType;

                //material properties
                MyMaterialTypeProperties materialProperties = MyMaterialsConstants.GetMaterialProperties(materialType);

                bool isProjectileGroupKilled = false;

                if (m_sharedGroup != null)
                {
                    isProjectileGroupKilled = m_sharedGroup.Killed;
                    m_sharedGroup.Killed    = true;
                }

                if (!isProjectileGroupKilled)
                {
                    //  Play bullet hit cue
                    MyAudio.AddCue3D(m_ammoProperties.IsExplosive ? materialProperties.ExpBulletHitCue : materialProperties.BulletHitCue, intersectionValue.IntersectionPointInWorldSpace, Vector3.Zero, Vector3.Zero, Vector3.Zero);
                }

                float decalAngle = MyMwcUtils.GetRandomRadian();

                //  If we hit the glass of a miner ship, we need to create special bullet hole decals
                //  drawn from inside the cockpit and change phys object so rest of the code will think we hit the parent
                //  IMPORTANT: Intersection between projectile and glass is calculated only for mining ship in which player sits. So for enemies this will be never calculated.
                if (intersection.Value.Entity is MyCockpitGlassEntity)
                {
                    if (!isProjectileGroupKilled)
                    {
                        MyCockpitGlassDecalTexturesEnum bulletHoleDecalTexture;
                        float bulletHoleDecalSize;

                        if (MyMwcUtils.GetRandomBool(3))
                        {
                            bulletHoleDecalTexture = MyCockpitGlassDecalTexturesEnum.BulletHoleOnGlass;
                            bulletHoleDecalSize    = 0.25f;
                        }
                        else
                        {
                            bulletHoleDecalTexture = MyCockpitGlassDecalTexturesEnum.BulletHoleSmallOnGlass;
                            bulletHoleDecalSize    = 0.1f;
                        }

                        //  Place bullet hole decal on player's cockpit glass (seen from inside the ship)
                        MyCockpitGlassDecals.Add(bulletHoleDecalTexture, bulletHoleDecalSize, decalAngle, 1.0f, ref intersectionValue, false);

                        //  Create hit particles throwed into the cockpit (it's simulation of broken glass particles)
                        //  IMPORTANT: This particles will be relative to miner ship, so we create them in object space coordinates and update them by object WorldMatrix every time we draw them
                        //MyParticleEffects.CreateHitParticlesGlass(ref intersectionValue.IntersectionPointInObjectSpace, ref intersectionValue.NormalInWorldSpace, ref line.Direction, physObject.Parent);
                    }
                }

                //  If this was "mine", it must explode
                else if (physObject is MyMineBase)
                {
                    m_state = MyProjectileStateEnum.KILLED;
                    if (!IsDummy)
                    {
                        (physObject as MyAmmoBase).Explode();
                    }
                    return(true);
                }

                //  If this was missile, cannon shot, it must explode if it is not mine missile
                else if (physObject is MyAmmoBase)
                {
                    if (((MyAmmoBase)physObject).OwnerEntity == m_ignorePhysObject)
                    {
                        m_state = MyProjectileStateEnum.KILLED;
                        if (!IsDummy)
                        {
                            (physObject as MyAmmoBase).Explode();
                        }
                        return(true);
                    }
                }

                else if (this.OwnerEntity is MySmallShip && (MySmallShip)this.OwnerEntity == MySession.PlayerShip && physObject is MyStaticAsteroid && !physObject.IsDestructible)
                {
                    if (this.m_ammoProperties.IsExplosive || (this.m_ammoProperties.AmmoType == MyAmmoType.Explosive && this.m_weapon is Weapons.MyShotGun))
                    {
                        HUD.MyHud.ShowIndestructableAsteroidNotification();
                    }
                }

                else if (!isProjectileGroupKilled && !isPlayerShip)
                {
                    //  Create smoke and debris particle at the place of voxel/model hit
                    m_ammoProperties.OnHitParticles(ref intersectionValue.IntersectionPointInWorldSpace, ref intersectionValue.Triangle.InputTriangleNormal, ref line.Direction, physObject, m_weapon, OwnerEntity);

                    MySurfaceImpactEnum surfaceImpact;
                    if (intersectionValue.Entity is MyVoxelMap)
                    {
                        var voxelMap   = intersectionValue.Entity as MyVoxelMap;
                        var voxelCoord = voxelMap.GetVoxelCenterCoordinateFromMeters(ref intersectionValue.IntersectionPointInWorldSpace);
                        var material   = voxelMap.GetVoxelMaterial(ref voxelCoord);
                        if (material == MyMwcVoxelMaterialsEnum.Indestructible_01 ||
                            material == MyMwcVoxelMaterialsEnum.Indestructible_02 ||
                            material == MyMwcVoxelMaterialsEnum.Indestructible_03 ||
                            material == MyMwcVoxelMaterialsEnum.Indestructible_04 ||
                            material == MyMwcVoxelMaterialsEnum.Indestructible_05_Craters_01)
                        {
                            surfaceImpact = MySurfaceImpactEnum.INDESTRUCTIBLE;
                        }
                        else
                        {
                            surfaceImpact = MySurfaceImpactEnum.DESTRUCTIBLE;
                        }
                    }
                    else if (intersectionValue.Entity is MyStaticAsteroid)
                    {
                        surfaceImpact = MySurfaceImpactEnum.INDESTRUCTIBLE;
                    }
                    else
                    {
                        surfaceImpact = MySurfaceImpactEnum.METAL;
                    }

                    m_ammoProperties.OnHitMaterialSpecificParticles(ref intersectionValue.IntersectionPointInWorldSpace, ref intersectionValue.Triangle.InputTriangleNormal, ref line.Direction, physObject, surfaceImpact, m_weapon);
                }

                if (!(physObject is MyExplosionDebrisBase) && physObject != MySession.PlayerShip)
                {
                    //  Decal size depends on material. But for mining ship create smaller decal as original size looks to large on the ship.
                    float decalSize = MyMwcUtils.GetRandomFloat(materialProperties.BulletHoleSizeMin,
                                                                materialProperties.BulletHoleSizeMax);

                    //  Place bullet hole decal
                    float randomColor = MyMwcUtils.GetRandomFloat(0.5f, 1.0f);

                    MyDecals.Add(
                        materialProperties.BulletHoleDecal,
                        decalSize,
                        decalAngle,
                        new Vector4(randomColor, randomColor, randomColor, 1),
                        false,
                        ref intersectionValue,
                        0.0f,
                        m_ammoProperties.DecalEmissivity, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL);
                }

                if (!(physObject is MyVoxelMap) && !IsDummy)
                {
                    ApplyProjectileForce(physObject, intersectionValue.IntersectionPointInWorldSpace, m_directionNormalized, isPlayerShip);
                }


                //  If this object is miner ship, then shake his head little bit
                if (physObject is MySmallShip && !IsDummy)
                {
                    MySmallShip minerShip = (MySmallShip)physObject;
                    minerShip.IncreaseHeadShake(MyHeadShakeConstants.HEAD_SHAKE_AMOUNT_AFTER_PROJECTILE_HIT);
                }



                //Handle damage

                MyEntity damagedObject = intersectionValue.Entity;

                // not a very nice way to damage actual prefab associated with the large ship weapon (if MyPrefabLargeWeapon is reworked, it might change)
                if (damagedObject is MyLargeShipBarrelBase)
                {
                    damagedObject = damagedObject.Parent;
                }
                if (damagedObject is MyLargeShipGunBase)
                {
                    MyLargeShipGunBase physObj = damagedObject as MyLargeShipGunBase;
                    if (physObj.PrefabParent != null)
                    {
                        damagedObject = physObj.PrefabParent;
                    }
                }

                //  Decrease health of stricken object
                if (!IsDummy)
                {
                    damagedObject.DoDamage(m_ammoProperties.HealthDamage, m_ammoProperties.ShipDamage, m_ammoProperties.EMPDamage, m_ammoProperties.DamageType, m_ammoProperties.AmmoType, m_ignorePhysObject);
                    if (MyMultiplayerGameplay.IsRunning)
                    {
                        var ammo = MyAmmoConstants.FindAmmo(m_ammoProperties);
                        MyMultiplayerGameplay.Static.ProjectileHit(damagedObject, intersectionValue.IntersectionPointInWorldSpace, this.m_directionNormalized, ammo, this.OwnerEntity);
                    }
                }

                if (m_trailEffect != null)
                {
                    // stop the trail effect
                    m_trailEffect.Stop();
                    m_trailEffect = null;
                }

                //  Kill this projectile (set the position to intersection point, so we draw trail polyline only up to this point)
                m_position = intersectionValue.IntersectionPointInWorldSpace;
                m_state    = MyProjectileStateEnum.KILLED;

                return(true);
            }

            return(true);
        }
Exemple #5
0
        //  Plays one-time cue of impact/collision/hit between two objects. Logic behind will preserve that only one sound is played, even if coldet routine gives us this collision two times.
        //  We also check deceleration needed for playing the sound and if we aren't currently playing sound of collision for this two objects.
        internal static void PlayCollisionCue(MyContactEventInfo contactEventInfo, MyMaterialsConstants.MyMaterialCollisionType type)
        {
            var physicsObject0 = (MyPhysicsBody)contactEventInfo.m_RigidBody1.m_UserData;
            var physicsObject1 = (MyPhysicsBody)contactEventInfo.m_RigidBody2.m_UserData;

            //  We won't add more collision sounds if dictionary is full (we need to wait until some cues are removed)
            if (m_collisionDictionary.Count > MyAudioConstants.MAX_COLLISION_SOUNDS)
            {
                if ((physicsObject0.Entity != MySession.PlayerShip) && (physicsObject1.Entity != MySession.PlayerShip))
                {
                    return;
                }
            }

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


            Vector3 ZERO_CUE_VALUES = Vector3.Zero;
            MySoundCue? cue0 = null;
            float volume = 1;// MathHelper.Lerp(MySoundsConstants.DECELERATION_MIN_VOLUME, MySoundsConstants.DECELERATION_MAX_VOLUME, deceleration / MySoundsConstants.MAX_DECELERATION);

            MyMaterialType materialType1 = physicsObject0.MaterialType;
            MyMaterialType materialType2 = physicsObject1.MaterialType;

            if (physicsObject0.Entity == MySession.PlayerShip)
                materialType1 = MyMaterialType.PLAYERSHIP;

            if (physicsObject1.Entity == MySession.PlayerShip)
                materialType2 = MyMaterialType.PLAYERSHIP;


            if (type == MyMaterialsConstants.MyMaterialCollisionType.End && m_collisionDictionary.ContainsKey(contactEventInfo.m_Guid))
            {
                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("cue.Stop");

                //We are already playing this collision and we need to end it with specific sound

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartNextBlock("AddCue3D");

                MySoundCuesEnum? collisionSound = MyMaterialsConstants.GetCollisionCue(MyMaterialsConstants.MyMaterialCollisionType.End, materialType1, materialType2);
                if (collisionSound.HasValue)
                {
                    MySoundCue cue = m_collisionDictionary[contactEventInfo.m_Guid];
                    cue.Stop(StopFlags.Release);

                    cue0 = AddCue3D(collisionSound.Value, contactEventInfo.m_ContactPoint, ZERO_CUE_VALUES,
                            ZERO_CUE_VALUES, ZERO_CUE_VALUES, volume);
                }

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
            }
            else
            {
                if (type == MyMaterialsConstants.MyMaterialCollisionType.Start)
                {
                    //  If we aren't already playing collision cue for this particular combination of physical objects, now is the time
                    if (!m_collisionDictionary.ContainsKey(contactEventInfo.m_Guid))
                    {
                        MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Start audio");

                        MySoundCuesEnum? collisionSound = MyMaterialsConstants.GetCollisionCue(MyMaterialsConstants.MyMaterialCollisionType.Start, materialType1, materialType2);
                        if (collisionSound.HasValue)
                        {
                            List<int> soundInstances;
                            if (!m_collisionSoundsDictionary.TryGetValue((int)collisionSound.Value, out soundInstances))
                            {
                                m_collisionSoundsDictionary.Add((int)collisionSound, soundInstances = new List<int>());

                            }
                            if (soundInstances.Count < MyAudioConstants.MAX_COLLISION_SOUNDS_PER_SECOND)
                            {
                                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("AddCue3D");
                                cue0 = AddCue3D(collisionSound.Value, contactEventInfo.m_ContactPoint, ZERO_CUE_VALUES,
                                    ZERO_CUE_VALUES, ZERO_CUE_VALUES, volume);
                                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                                if (cue0.HasValue)
                                {
                                    soundInstances.Add(MyMinerGame.TotalTimeInMilliseconds);
                                }
                            }
                        }

                        MyMaterialTypeProperties materialProps1 = MyMaterialsConstants.GetMaterialProperties(materialType1);
                        MyMaterialTypeProperties materialProps2 = MyMaterialsConstants.GetMaterialProperties(materialType2);

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

                        Vector3 particleDir = contactEventInfo.m_Velocity1.LengthSquared() > contactEventInfo.m_Velocity2.LengthSquared() ? contactEventInfo.m_Velocity1 - contactEventInfo.m_Velocity2 : contactEventInfo.m_Velocity2 - contactEventInfo.m_Velocity1;
                        if (MyMwcUtils.IsZero(particleDir.LengthSquared()))
                        {
                            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                            return; //it is valid because of collision in rotation
                        }

                        MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Collision particles");

                        particleDir = -MyMwcUtils.Normalize(particleDir);

                        if (Vector3.DistanceSquared(MyCamera.Position, contactEventInfo.m_ContactPoint) < 100 * 100)
                        {
                            //  Create smoke particles at the place of collision
                            bool doSparks = materialProps1.DoSparksOnCollision || materialProps2.DoSparksOnCollision;
                            bool doSmoke = materialProps1.DoSmokeOnCollision || materialProps2.DoSmokeOnCollision;
                            MyParticleEffects.CreateCollisionParticles(contactEventInfo.m_ContactPoint, particleDir, false, doSparks);
                            MyParticleEffects.CreateCollisionParticles(contactEventInfo.m_ContactPoint, contactEventInfo.m_ContactNormal, doSmoke, false);
                        }

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

#if DEBUG_AUDIO
                        Matrix colMatrix = Matrix.CreateWorld(contactEventInfo.m_ContactPoint, particleDir, Vector3.Up);
                        m_soundCollisions.Add(colMatrix);                         
#endif

                    }
                    else if (type == MyMaterialsConstants.MyMaterialCollisionType.Touch)
                    {
                        MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Touch");

                        MySoundCuesEnum? scrapeSound = MyMaterialsConstants.GetCollisionCue(MyMaterialsConstants.MyMaterialCollisionType.Touch, materialType1, materialType2);
                        if (scrapeSound.HasValue)
                        {
                            cue0 = AddCue3D(scrapeSound.Value, contactEventInfo.m_ContactPoint, ZERO_CUE_VALUES,
                                ZERO_CUE_VALUES, ZERO_CUE_VALUES, volume);
                        }

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

                        //  Create smoke particles at the place of collision
                        //MyParticleEffects.CreateCollisionParticles(contactEventInfo.m_ContactPoint, physicsObject1.GetVelocity() - physicsObject0.GetVelocity());
                    }

                    if (cue0.HasValue)
                    {
                        if (!m_collisionDictionary.ContainsKey(contactEventInfo.m_Guid))
                        {
                            m_collisionDictionary.Add(contactEventInfo.m_Guid, cue0.Value);
                        }
                    }
                }
            }

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
        }
        public virtual void Init(string hudLabelText, MyMwcObjectBuilder_PrefabContainer objectBuilder, Matrix matrix)
        {
            m_intializing = true;
            StringBuilder hudLabelTextSb = (string.IsNullOrEmpty(hudLabelText) ? null : new StringBuilder(hudLabelText));

            base.Init(hudLabelTextSb, null, null, null, null, objectBuilder);

            DisplayName = objectBuilder.DisplayName;

            SetWorldMatrix(matrix);

            Flags |= EntityFlags.EditableInEditor;

            this.Faction = objectBuilder.Faction;

            //during container initialization, it is not necessary to check if prefab is outside boundaries, because it cannot be saved that way
            foreach (MyMwcObjectBuilder_PrefabBase prefabBuilder in objectBuilder.Prefabs)
            {
                CreateAndAddPrefab(null, prefabBuilder);
            }

            // we must initialize inventory after prefabs, because some prefabs are registered on OnInventoryContentChanged event
            if (objectBuilder.Inventory != null)
            {
                Inventory.Init(objectBuilder.Inventory, MyMwcUtils.GetRandomFloat(1.1f, 2f));
            }

            //Commit();

            UpdateAABBHr();

            // ----- THIS PHYSICS IS NEEDED BECAUSE ENTITY DETECTOR -----
            this.Physics = new MyPhysicsBody(this, 1.0f, UseKinematicPhysics ? RigidBodyFlag.RBF_KINEMATIC : RigidBodyFlag.RBF_RBO_STATIC)
            {
                MaterialType = MyMaterialType.METAL
            };
            MyPhysicsObjects   physobj = MyPhysics.physicsSystem.GetPhysicsObjects();
            MyRBBoxElementDesc boxDesc = physobj.GetRBBoxElementDesc();

            boxDesc.SetToDefault();
            boxDesc.m_RBMaterial     = MyMaterialsConstants.GetMaterialProperties(MyMaterialType.METAL).PhysicsMaterial;
            boxDesc.m_Size           = UseKinematicPhysics ? WorldAABBHr.Size() : Vector3.One;
            boxDesc.m_CollisionLayer = UseKinematicPhysics ? MyConstants.COLLISION_LAYER_DEFAULT : MyConstants.COLLISION_LAYER_UNCOLLIDABLE;
            MyRBBoxElement boxEl = (MyRBBoxElement)physobj.CreateRBElement(boxDesc);

            this.Physics.AddElement(boxEl, true);
            this.Physics.Enabled = true;
            this.Physics.RigidBody.KinematicLinear = false;
            // ----- THIS PHYSICS IS NEEDED BECAUSE ENTITY DETECTOR -----

            /*
             * MyRBBoxElementDesc boxDesc = physobj.GetRBBoxElementDesc();
             * MyMaterialType materialType = MyMaterialType.METAL;
             * boxDesc.SetToDefault();
             * boxDesc.m_Size = Vector3.One;
             * boxDesc.m_CollisionLayer = MyConstants.COLLISION_LAYER_UNCOLLIDABLE;
             * boxDesc.m_RBMaterial = MyMaterialsConstants.GetMaterialProperties(materialType).PhysicsMaterial;
             */
            //m_selectionBox = (MyRBBoxElement)physobj.CreateRBElement(boxDesc);
            m_selectionBox = new BoundingBox(-Vector3.One, Vector3.One);

            // to be selectable in editor
            //this.Physics.AddElement(m_selectionBox, true);

            m_userID  = objectBuilder.UserOwnerID;
            m_faction = objectBuilder.Faction;

            VisibleInGame = false;
            // set here later on user id when firstly created object inserted into scene

            //m_selectionBox = new BoundingBox(m_worldAABB.Min, m_worldAABB.Max);

            if (OnPrefabContainerInitialized != null)
            {
                OnPrefabContainerInitialized(this);
            }

            //StringBuilder displayName;
            //if (!string.IsNullOrEmpty(DisplayName))
            //{
            //    MyHud.ChangeText(this, new StringBuilder(DisplayName), null, 0, MyHudIndicatorFlagsEnum.SHOW_TEXT | MyHudIndicatorFlagsEnum.SHOW_BORDER_INDICATORS | MyHudIndicatorFlagsEnum.SHOW_ONLY_IF_DETECTED_BY_RADAR);
            //}
            m_intializing = false;

            UpdateGenerators();

            UseProperties = new MyUseProperties(MyUseType.FromHUB, MyUseType.FromHUB);
            if (objectBuilder.UseProperties == null)
            {
                UseProperties.Init(MyUseType.FromHUB, MyUseType.FromHUB, 3, 4000, false);
            }
            else
            {
                UseProperties.Init(objectBuilder.UseProperties);
            }

            AlarmOn    = objectBuilder.AlarmOn;
            RefillTime = objectBuilder.RefillTime;

            // check possible values
            if (Inventory.TemplateType != null && RefillTime == null)
            {
                RefillTime = DEFAULT_REFILL_TIME_IN_SEC;
            }
            else if (Inventory.TemplateType == null && RefillTime != null)
            {
                RefillTime = null;
            }
        }