Esempio n. 1
0
        //  Add decal and all surounding triangles for voxel intersection
        static void AddDecalVoxel(MyDecalTexturesEnum decalTexture, float decalSize, float decalScale, Vector4 color, bool alphaBlendByAngle,
                                  ref MyIntersectionResultLineTriangleEx intersection, ref MyPlane rightPlane, ref MyPlane upPlane, float lightSize, float emissivity, float decalNormalOffset)
        {
            MyVoxelMap voxelMap = (MyVoxelMap)intersection.Entity;

            MyMwcVector3Int renderCellCoord     = voxelMap.GetVoxelRenderCellCoordinateFromMeters(ref intersection.IntersectionPointInWorldSpace);
            BoundingSphere  decalBoundingSphere = new BoundingSphere(intersection.IntersectionPointInWorldSpace, decalSize);

            //  If whole decal can't fit inside of render cell, we won't add any of its triangles. This is because
            //  when hiding/removing triangles after explosion, it is easier to check only one render cell.
            BoundingBox renderCellBoundingBox;

            voxelMap.GetRenderCellBoundingBox(ref renderCellCoord, out renderCellBoundingBox);

            // TODO simon - commented as an experiment. If there are bugs with decals on voxels, remove the comment below
            //if (renderCellBoundingBox.Contains(decalBoundingSphere) != ContainmentType.Contains) return;

            //  If we get null, buffer is full so no new decals can't be placed
            MyDecalsForVoxelsTriangleBuffer decalsBuffer = m_decalsForVoxels.GetTrianglesBuffer(voxelMap, ref renderCellCoord, decalTexture, ref renderCellBoundingBox);

            if (decalsBuffer == null)
            {
                return;
            }

            //  We need to create decals on neighborhood triangles too, so we check all triangles if they fall in decal's sphere and if yes, we place decal on them.
            //  We check triangles from same voxelmap or model only.

            m_neighbourTriangles.Clear();
            //intersection.VoxelMap.GetTrianglesIntersectingSphere(ref decalBoundingSphere, intersection.TriangleHelperIndex, m_neighbourTriangles, decalsBuffer.MaxNeighbourTriangles);
            voxelMap.GetTrianglesIntersectingSphere(ref decalBoundingSphere, m_neighbourTriangles, decalsBuffer.MaxNeighbourTriangles, false);

            int trianglesToAdd = m_neighbourTriangles.Count;// +1;

            if (trianglesToAdd == 0)
            {
                return;
            }

            if (decalsBuffer.CanAddTriangles(trianglesToAdd) == true)
            {
                var normalSum = CalculateDominantNormal(m_neighbourTriangles);
                normalSum *= decalNormalOffset;

                //  Create decal for every neighbour triangleVertexes
                for (int i = 0; i < m_neighbourTriangles.Count; i++)
                {
                    trianglesToAdd--;

                    var triangle = m_neighbourTriangles[i];
                    triangle.Vertexes.Vertex0 += normalSum;
                    triangle.Vertexes.Vertex1 += normalSum;
                    triangle.Vertexes.Vertex2 += normalSum;
                    m_neighbourTriangles[i]    = triangle;

                    decalsBuffer.Add(m_neighbourTriangles[i], intersection.NormalInWorldSpace, ref rightPlane,
                                     ref upPlane, decalScale, trianglesToAdd, color, alphaBlendByAngle, lightSize, intersection.IntersectionPointInWorldSpace, emissivity);
                }
            }
        }
Esempio n. 2
0
        //  Add decal and all surounding triangles for model intersection
        static void AddDecalModel(MyDecalTexturesEnum decalTexture, float decalSize, float decalScale, Vector4 color, bool alphaBlendByAngle,
                                  ref MyIntersectionResultLineTriangleEx intersection, ref MyPlane rightPlane, ref MyPlane upPlane, float lightSize, float emissivity, float decalNormalOffset)
        {
            MyDecalsForPhysObjectsTriangleBuffer decalsBuffer = m_decalsForModels.GetTrianglesBuffer(intersection.Entity, decalTexture);

            //  If we get null, buffer is full so no new decals can't be placed
            if (decalsBuffer == null)
            {
                return;
            }

            //  We need to create decals on neighborhood triangles too, so we check all triangles if they fall in decal's sphere and if yes, we place decal on them.
            //  We check triangles from same voxelmap or model only.

            BoundingSphere decalSphere = new BoundingSphere(intersection.IntersectionPointInObjectSpace, decalSize);

            m_neighbourTriangles.Clear();

            intersection.Entity.GetTrianglesIntersectingSphere(ref decalSphere, intersection.NormalInObjectSpace, MyDecalsConstants.MAX_NEIGHBOUR_ANGLE, m_neighbourTriangles, decalsBuffer.MaxNeighbourTriangles);

            int trianglesToAdd = m_neighbourTriangles.Count;

            if (trianglesToAdd == 0)
            {
                return;
            }

            if (decalsBuffer.CanAddTriangles(trianglesToAdd))
            {
                Vector3 normalSum = Vector3.Zero;
                if (MyFakes.USE_DOMINANT_NORMAL_OFFSET_FOR_MODELS)
                {
                    normalSum  = CalculateDominantNormal(m_neighbourTriangles);
                    normalSum *= decalNormalOffset;
                }

                //  Create decal for every neighbour triangleVertexes
                for (int i = 0; i < m_neighbourTriangles.Count; i++)
                {
                    trianglesToAdd--;

                    if (MyFakes.USE_DOMINANT_NORMAL_OFFSET_FOR_MODELS)
                    {
                        var triangle = m_neighbourTriangles[i];
                        triangle.Vertexes.Vertex0 += normalSum;
                        triangle.Vertexes.Vertex1 += normalSum;
                        triangle.Vertexes.Vertex2 += normalSum;
                        m_neighbourTriangles[i]    = triangle;
                    }

                    decalsBuffer.Add(m_neighbourTriangles[i], intersection.Triangle.InputTriangleNormal,
                                     ref rightPlane, ref upPlane, decalScale, decalSize, trianglesToAdd, color, alphaBlendByAngle, lightSize, intersection.IntersectionPointInObjectSpace, emissivity);
                }
            }
        }
Esempio n. 3
0
        //  Add cockpit decal and all surounding triangles. Method needs intersection, but result of the intersection must be with ideal glass, not any other part of a miner ship.
        public static void Add(MyCockpitGlassDecalTexturesEnum decalTexture, float decalSize, float angle, float alpha,
                               ref MyIntersectionResultLineTriangleEx idealIntersection, bool alphaBlendByAngle)
        {
            MyCockpitGlassDecalsBuffer buffer = GetBuffer(decalTexture);

            //	Polomer decalu a scale faktor pre vypocet textury.
            //  Decal size is something as radius of a decal, so when converting from real metres to texture space, we need to divide by 2.0
            float decalScale = 1.0f / decalSize / 2.0f;

            Vector3 rightVector = MyMwcUtils.Normalize(idealIntersection.Triangle.InputTriangle.Vertex0 - idealIntersection.IntersectionPointInObjectSpace);
            Vector3 upVector    = MyMwcUtils.Normalize(Vector3.Cross(rightVector, idealIntersection.NormalInObjectSpace));

            //  We create world matrix for the decal and then rotate the matrix, so we can extract rotated right/up vectors/planes for texture coord0 calculations
            Matrix decalMatrix = Matrix.CreateRotationZ(angle) * Matrix.CreateWorld(idealIntersection.IntersectionPointInObjectSpace, idealIntersection.NormalInObjectSpace, upVector);

            //	Right plane
            MyPlane rightPlane;

            rightPlane.Point  = idealIntersection.IntersectionPointInObjectSpace;
            rightPlane.Normal = MyUtils.GetTransformNormalNormalized(Vector3.Right, ref decalMatrix);

            //	Up plane
            MyPlane upPlane;

            upPlane.Point  = idealIntersection.IntersectionPointInObjectSpace;
            upPlane.Normal = MyUtils.GetTransformNormalNormalized(Vector3.Up, ref decalMatrix);

            float?maxAngle = null;

            if (alphaBlendByAngle == false)
            {
                maxAngle = MyCockpitGlassDecalsConstants.MAX_NEIGHBOUR_ANGLE;
            }

            BoundingSphere decalSphere = new BoundingSphere(idealIntersection.IntersectionPointInObjectSpace, decalSize);

            m_neighbourTriangles.Clear();
            //idealIntersection.PhysObject.GetTrianglesIntersectingSphere(ref decalSphere, idealIntersection.NormalInObjectSpace, maxAngle, idealIntersection.TriangleHelperIndex, m_neighbourTriangles, buffer.MaxNeighbourTriangles);
            idealIntersection.Entity.GetTrianglesIntersectingSphere(ref decalSphere, idealIntersection.NormalInObjectSpace, maxAngle, m_neighbourTriangles, buffer.MaxNeighbourTriangles);

            int trianglesToAdd = m_neighbourTriangles.Count;// +1;

            if (buffer.CanAddTriangles(trianglesToAdd) == true)
            {
                //  Decal on triangleVertexes we hit
//                buffer.Add(idealIntersection.Triangle.InputTriangle, idealIntersection.NormalInObjectSpace, ref rightPlane, ref upPlane, decalScale, color, alphaBlendByAngle, ref decalSphere);

                //  Create decal for every neighbour triangleVertexes
                for (int i = 0; i < m_neighbourTriangles.Count; i++)
                {
                    buffer.Add(m_neighbourTriangles[i].Vertexes, idealIntersection.NormalInObjectSpace, ref rightPlane, ref upPlane, decalScale, alpha, alphaBlendByAngle, ref decalSphere);
                }
            }
        }
        public override bool GetIntersectionWithLine(ref MyLine line, out MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
        {
            t = null;
            foreach (MyPrefabBase prefab in m_prefabs)
            {
                MyEntity entity = prefab as MyEntity;
                MyIntersectionResultLineTriangleEx?prefabIntersectionResult;
                entity.GetIntersectionWithLine(ref line, out prefabIntersectionResult);
                t = MyIntersectionResultLineTriangleEx.GetCloserIntersection(ref t, ref prefabIntersectionResult);
            }

            return(t != null);
        }
Esempio n. 5
0
        public MyIntersectionResultLineTriangleEx?GetIntersectionWithLine(ref MyLine line)
        {
            MyIntersectionResultLineTriangleEx?result = null;

            //  Test against childs of this phys object (in this case guns)
            foreach (MyGunBase gun in m_guns)
            {
                MyIntersectionResultLineTriangleEx?intersectionGun = gun.GetIntersectionWithLine(ref line);

                result = MyIntersectionResultLineTriangleEx.GetCloserIntersection(ref result, ref intersectionGun);
            }

            return(result);
        }
        /// <summary>
        /// Returns interstection with line
        /// </summary>
        /// <param name="line">Line</param>
        /// <returns></returns>
        public MyIntersectionResultLineTriangleEx?GetIntersectionWithLine(ref MyLine line)
        {
            MyIntersectionResultLineTriangleEx?result = null;

            //  Test against childs of this phys object (in this case guns)
            foreach (MyGunBase gun in GetMountedWeaponsWithHarvesterAndDrill())
            {
                MyIntersectionResultLineTriangleEx?intersectionGun;
                gun.GetIntersectionWithLine(ref line, out intersectionGun);
                result = MyIntersectionResultLineTriangleEx.GetCloserIntersection(ref result, ref intersectionGun);
            }

            return(result);
        }
Esempio n. 7
0
        public static MyIntersectionResultLineTriangleEx?GetIntersectionWithLine(ref MyLine line)
        {
            MyIntersectionResultLineTriangleEx?result = null;

            //  Check all voxel maps
            for (int value = 0; value < m_voxelMaps.Count; value++)
            {
                MyIntersectionResultLineTriangleEx?testResultEx;
                m_voxelMaps[value].GetIntersectionWithLine(ref line, out testResultEx);

                //  If intersection occured and distance to intersection is closer to origin than any previous intersection)
                result = MyIntersectionResultLineTriangleEx.GetCloserIntersection(ref result, ref testResultEx);
            }

            return(result);
        }
Esempio n. 8
0
        //  If explosion was with voxels, crease dirt decals in player's cockpit glass
        //  We don't throw random number of debris lines from explosion (because it will be waste). Instead we get intersection line from explosion center to player head,
        //  which should intersect the cockpit glass. Plus we move player head by random vector.
        void CreateDirtDecalOnCockpitGlass(ref BoundingSphere explosionSphere)
        {
            MySmallShip player      = MySession.PlayerShip;
            float       maxDistance = m_explosionSphere.Radius * MyExplosionsConstants.EXPLOSION_RADIUS_MULTPLIER_FOR_DIRT_GLASS_DECALS;
            float       distance    = Vector3.Distance(player.GetPosition(), explosionSphere.Center) - player.ModelLod0.BoundingSphere.Radius;

            //  Decal interpolator - based on distance to explosion, range <0..1>
            //  But then increased because we aren't able to reach max distance so we need to help it little bit
            float interpolator = 1 - MathHelper.Clamp(distance / maxDistance, 0, 1);

            interpolator = (float)Math.Pow(interpolator, 3f);

            //  Don't create dirt decal if we are too far
            if (interpolator <= 0.0f)
            {
                return;
            }

            //  Chech intersection between explosion and player's head. BUT move the line in player's head direction, because we don't want to make intersection with object which caused the explosion
            //MyLine line = new MyLine(intersection.IntersectionPointInWorldSpace, player.GetPosition(), true);
            //MyLine line = new MyLine(intersection.IntersectionPointInWorldSpace, MyCamera.m_initialSunWindPosition, true);
            //Vector3 playerHeadPositionWorld = MyUtils.GetTransform(MyFakes.PLAYER_HEAD_FOR_COCKPIT_INTERIOR_FAKE_TRANSLATION * -1, ref player.WorldMatrix);
            Vector3 playerHeadPositionWorld = player.GetPlayerHeadForCockpitInterior();
            MyLine  line = new MyLine(explosionSphere.Center, playerHeadPositionWorld, true);

            line.From += line.Direction * MyExplosionsConstants.OFFSET_LINE_FOR_DIRT_DECAL;

            MyIntersectionResultLineTriangleEx?glassIntersection = MyEntities.GetIntersectionWithLine_IgnoreOtherThanSpecifiedClass(ref line, new Type[] { typeof(MySmallShip) });

            if ((glassIntersection != null) && (glassIntersection.Value.Entity is MyCockpitGlassEntity))
            {
                //  Decal alpha (never is 1.0f, because we want to see through the dirt)
                float alpha = MathHelper.Clamp(MathHelper.Lerp(0.2f, 1.0f, interpolator) - 0.1f, 0, 1);
                //const float ALPHA_INCREASE = 0.4f;
                //float alpha = 1 - (float)Math.Pow(MathHelper.Clamp(distance / maxDistance, 0, 1), 5);
                //float alpha = (float)MathHelper.SmoothStep(0, 1, 1 - MathHelper.Clamp(distance / maxDistance, 0, 1));
                //float alpha = MathHelper.Clamp(1 - MathHelper.Clamp(distance / maxDistance, 0, 1) + ALPHA_INCREASE, ALPHA_INCREASE, 1);

                //  Decal size
                float size = MathHelper.Lerp(2.5f, 4f, interpolator);

                MyIntersectionResultLineTriangleEx glassIntersection2 = glassIntersection.Value;

                MyCockpitGlassDecals.Add(MyCockpitGlassDecalTexturesEnum.DirtOnGlass, size, MyMwcUtils.GetRandomRadian(), alpha, ref glassIntersection2, true);
            }
        }
Esempio n. 9
0
        public void Reset()
        {
            this.CapsuleIndex = -1;
            this.BoneIndex    = -1;
            CapsuleD ed = new CapsuleD();

            this.Capsule = ed;
            Vector3 vector = new Vector3();

            this.HitNormalBindingPose = vector;
            vector = new Vector3();
            this.HitPositionBindingPose = vector;
            Matrix matrix = new Matrix();

            this.BindingTransformation = matrix;
            MyIntersectionResultLineTriangleEx ex = new MyIntersectionResultLineTriangleEx();

            this.Triangle = ex;
            this.HitHead  = false;
        }
Esempio n. 10
0
        /// <summary>
        /// Tests a line for intersection with models of blocks on the grid.
        /// </summary>
        public static bool Intersects(this MySlimBlock slim, ref LineD localLine, out MyIntersectionResultLineTriangleEx?result, IntersectionFlags flags = DefaultFlags)
        {
            Logger.TraceLog("Checking slim block: " + slim.getBestName() + ", line from: " + localLine.From + ", to: " + localLine.To);

            if (slim.FatBlock != null)
            {
                return(Intersects(slim.FatBlock, ref localLine, out result));
            }

            MyCube cube;

            if (!slim.CubeGrid.TryGetCube(slim.Position, out cube))
            {
                throw new Exception("Failed to get MyCube for " + slim.nameWithId());
            }

            foreach (MyCubePart part in cube.Parts)
            {
                Matrix  localMatrix = part.InstanceData.LocalMatrix;
                Matrix  invLocal; Matrix.Invert(ref localMatrix, out invLocal);
                MatrixD invLocalD = invLocal;

                Logger.TraceLog("Checking part: " + part.Model.AssetName + ", line from " + localLine.From + " to " + localLine.To + " becomes " +
                                Vector3D.Transform(localLine.From, ref invLocalD) + " to " + Vector3D.Transform(localLine.To, ref invLocalD));

                result = part.Model.GetTrianglePruningStructure().GetIntersectionWithLine(slim.CubeGrid, ref localLine, ref invLocalD, flags);
                if (result.HasValue)
                {
                    MyIntersectionResultLineTriangleEx value = result.Value;
                    Vector3.Transform(ref value.IntersectionPointInObjectSpace, ref localMatrix, out value.IntersectionPointInObjectSpace);
                    Matrix orientation = localMatrix.GetOrientation();
                    Vector3.Transform(ref value.NormalInObjectSpace, ref orientation, out value.NormalInObjectSpace);

                    result = value;
                    return(true);
                }
            }

            result = null;
            return(false);
        }
Esempio n. 11
0
        public override unsafe bool GetIntersectionWithLine(ref LineD line, out MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = 3)
        {
            MyOrientedBoundingBoxD xd2 = new MyOrientedBoundingBoxD(this.m_detectorBox * base.PositionComp.WorldMatrix);

            t = 0;
            double?nullable = xd2.Intersects(ref line);

            if (nullable != null)
            {
                MyIntersectionResultLineTriangleEx ex = new MyIntersectionResultLineTriangleEx {
                    Entity = this,
                    IntersectionPointInWorldSpace = line.From + ((nullable.Value + 0.2) * line.Direction)
                };
                MyIntersectionResultLineTriangleEx *exPtr1 = (MyIntersectionResultLineTriangleEx *)ref ex;
                exPtr1->IntersectionPointInObjectSpace = (Vector3)Vector3D.Transform(ex.IntersectionPointInWorldSpace, base.PositionComp.WorldMatrixInvScaled);
                ex.NormalInWorldSpace = (Vector3) - line.Direction;
                MyIntersectionResultLineTriangleEx *exPtr2 = (MyIntersectionResultLineTriangleEx *)ref ex;
                exPtr2->NormalInObjectSpace = (Vector3)Vector3D.TransformNormal(ex.NormalInWorldSpace, base.PositionComp.WorldMatrixInvScaled);
                t = new MyIntersectionResultLineTriangleEx?(ex);
            }
            return(t != 0);
        }
Esempio n. 12
0
        //  Method finds intersection with line and any voxel triangleVertexes in this voxel map. Closes intersection is returned.
        internal override bool GetIntersectionWithLine(ref LineD worldLine, out MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
        {
            t = null;

            double intersectionDistance;
            LineD  line = (LineD)worldLine;

            if (!PositionComp.WorldAABB.Intersects(line, out intersectionDistance))
            {
                return(false);
            }

            ProfilerShort.Begin("VoxelMap.LineIntersection");
            try
            {
                Line localLine = new Line(worldLine.From - PositionLeftBottomCorner,
                                          worldLine.To - PositionLeftBottomCorner, true);
                MyIntersectionResultLineTriangle tmpResult;
                if (Storage.Geometry.Intersect(ref localLine, out tmpResult, flags))
                {
                    t = new MyIntersectionResultLineTriangleEx(tmpResult, this, ref worldLine);
                    var tmp = t.Value.IntersectionPointInWorldSpace;
                    tmp.AssertIsValid();
                    return(true);
                }
                else
                {
                    t = null;
                    return(false);
                }
            }
            finally
            {
                ProfilerShort.End();
            }
        }
Esempio n. 13
0
        private void CreateDecals(Vector3 direction)
        {
            MyRender.GetRenderProfiler().StartProfilingBlock("Collisions");

            MyRender.GetRenderProfiler().StartProfilingBlock("Raycast");

            var intersectionEndPoint   = m_explosionSphere.Center + 1.5f * m_explosionSphere.Radius * direction;
            var intersectionStartPoint = m_explosionSphere.Center - 1.5f * m_explosionSphere.Radius * direction;
            var line = new MyLine(intersectionStartPoint, intersectionEndPoint);

            var result = MyEntities.GetIntersectionWithLine(ref line, null, null, true, true, false, false, true, AppCode.Physics.Collisions.IntersectionFlags.ALL_TRIANGLES, true);

            MyRender.GetRenderProfiler().EndProfilingBlock();
            MyRender.GetRenderProfiler().StartProfilingBlock("Add decal");

            if (result.HasValue)
            {
                MyIntersectionResultLineTriangleEx intersection = result.Value;

                var radius = m_explosionSphere.Radius * (result.Value.Entity is MyVoxelMap ? 1.0f : MyMwcUtils.GetRandomFloat(0.4f, 0.6f));

                MyDecals.Add(
                    MyDecalTexturesEnum.ExplosionSmut,
                    radius,
                    MyMwcUtils.GetRandomRadian(),
                    GetSmutDecalRandomColor(),
                    true,
                    ref intersection,
                    0,
                    0,
                    MyDecalsConstants.DECAL_OFFSET_BY_NORMAL_FOR_SMUT_DECALS);
            }

            MyRender.GetRenderProfiler().EndProfilingBlock();
            MyRender.GetRenderProfiler().EndProfilingBlock();

            //var elements = MyEntities.GetElementsInBox(ref boundingBox);

            //foreach (MyRBElement element in elements)
            //{
            //    var rigidBody = (MyPhysicsBody)element.GetRigidBody().m_UserData;
            //    var entity = rigidBody.Entity;

            //    if (entity is MyExplosionDebrisBase || entity is MyPrefabContainer)
            //        continue;

            //    // Making interesection of line from the explosion center to every object closed to explosion
            //    // and placing smut decals

            //    // FIX : when hitting another samll boat explosion and entity position are equal !!!
            //    //if (m_explosionSphere.Center == entity.GetPosition())
            //    //    continue;

            //    // FIX : when hitting another samll boat explosion and direction is < Epsilon !!!
            //    if ((entity.GetPosition() - m_explosionSphere.Center).LengthSquared() <
            //        2 * MyMwcMathConstants.EPSILON_SQUARED)
            //        continue;

            //    MyRender.GetRenderProfiler().StartProfilingBlock("Line intersection");
            //    MyIntersectionResultLineTriangleEx? intersection = null;
            //    if (direction.HasValue)
            //    {
            //        var intersectionEndPoint = m_explosionSphere.Center + 1.5f * m_explosionSphere.Radius * direction.Value;
            //        var intersectionStartPoint = m_explosionSphere.Center - 1.5f * m_explosionSphere.Radius * direction.Value;
            //        MyLine intersectionLine = new MyLine(intersectionStartPoint, intersectionEndPoint, true);
            //        entity.GetIntersectionWithLine(ref intersectionLine, out intersection);
            //    }
            //    else if (intersection == null && entity is MyVoxelMap)
            //    {
            //        // fall back if we dont have direction
            //        var intersectionEndPoint = entity.GetPosition();
            //        MyLine intersectionLine = new MyLine(m_explosionSphere.Center, intersectionEndPoint, true);
            //        entity.GetIntersectionWithLine(ref intersectionLine, out intersection);
            //    }
            //    MyRender.GetRenderProfiler().EndProfilingBlock();

            //    if (intersection == null)
            //        continue;

            //    MyIntersectionResultLineTriangleEx intersectionValue = intersection.Value;

            //    if (entity is MyVoxelMap)
            //    {
            //        MyRender.GetRenderProfiler().StartProfilingBlock("Decals");

            //        MyDecals.Add(
            //            MyDecalTexturesEnum.ExplosionSmut,
            //            m_explosionSphere.Radius,
            //            MyMwcUtils.GetRandomRadian(),
            //            GetSmutDecalRandomColor(),
            //            true,
            //            ref intersectionValue,
            //            0,
            //            0, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL_FOR_SMUT_DECALS);

            //        MyRender.GetRenderProfiler().EndProfilingBlock();
            //    }
            //    else if (((entity is MySmallShip) == false) &&
            //             ((entity is MySmallDebris) == false)
            //             && ((entity is MyAmmoBase) == false))
            //    {
            //        //  Create explosion smut decal on model we hit by this missile
            //        MyDecals.Add(
            //            MyDecalTexturesEnum.ExplosionSmut,
            //            MyMwcUtils.GetRandomFloat(m_explosionSphere.Radius * 0.4f, m_explosionSphere.Radius * 0.6f),
            //            MyMwcUtils.GetRandomRadian(),
            //            GetSmutDecalRandomColor(),
            //            true,
            //            ref intersectionValue,
            //            0,
            //            0, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL);
            //    }
            //}
            //elements.Clear();
        }
 public void Reset()
 {
     CapsuleIndex = -1;
     BoneIndex = -1;
     Capsule = new CapsuleD();
     HitNormalBindingPose = new Vector3();
     HitPositionBindingPose = new Vector3();
     Triangle = new MyIntersectionResultLineTriangleEx();
     HitHead = false;
 }
Esempio n. 15
0
        //  Method finds intersection with line and any voxel triangleVertexes in this voxel map. Closes intersection is returned.
        public override bool GetIntersectionWithLine(ref MyLine line, out MyIntersectionResultLineTriangleEx? t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
        {
            ++MyPerformanceCounter.PerCameraDraw.RayCastModelsProcessed;

            t = null;
            //  Line and voxel map bounding box intersection test
            //  We don't need to transform line into voxel map space, because they both are always in world space
            if (IsLineIntersectingBoundingBoxOfThisVoxelMap(ref line) == false)
                return false;

            MyIntersectionResultLineTriangle? result = null;
            if (MyVoxelMaps.GetSortedDataCellList() == null)
                return false;

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

            MyVoxelMaps.GetSortedDataCellList().Clear();

            MyMwcVector3Int cellCoord;

            MyLine modelSpaceLine = new MyLine(line.From - PositionLeftBottomCorner, line.To - PositionLeftBottomCorner, true);
            MyLine gridLine = modelSpaceLine;

            // convert from center-based to corner-based coordinates
            gridLine.From -= MyVoxelConstants.VOXEL_SIZE_VECTOR_HALF;
            gridLine.To -= MyVoxelConstants.VOXEL_SIZE_VECTOR_HALF;

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("VoxelMap.LineIntersection AABB sweep");
            SweepResult.Clear();
            MyGridIntersection.Calculate(
                SweepResult,
                (int)MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_METRES,
                modelSpaceLine.From,
                modelSpaceLine.To,
                new MyMwcVector3Int(0, 0, 0),
                DataCellsCountMinusOne
            );
            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("VoxelMap.LineIntersection test AABBs");
            float? minDistanceUntilNow = null;
            BoundingBox cellBoundingBox;

            if (MyFakes.DRAW_TESTED_CELLS_IN_VOXEL_LINE_INTERSECTION)
            {
                // debug: draw all intersected cells
                var mat = Matrix.Identity;
                var color = new Vector4(1, 1, 0, 0.5f);
                foreach (var coord in SweepResult)
                {
                    cellCoord = coord;
                    GetDataCellBoundingBox(ref cellCoord, out cellBoundingBox);
                    MySimpleObjectDraw.DrawWireFramedBox(ref mat, ref cellBoundingBox, ref color, 0.01f, 1);
                }
            }

            //List<float> allIntersections = new List<float>();
            //foreach (var coord in SweepResult)
            for (int index = 0; index < SweepResult.Count; index++)
            {
                var coord = SweepResult[index];
                cellCoord = coord;
                //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("VoxelMap.LineIntersection init tests");

                GetDataCellBoundingBox(ref cellCoord, out cellBoundingBox);

                float? distanceToBoundingBox = MyUtils.GetLineBoundingBoxIntersection(ref line, ref cellBoundingBox);

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

                // Sweep results are sorted; when we get far enough, make an early exit
                const float earlyOutDistance = 1.948557f * MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_METRES;  // = sqrt(3) * 9/8 * cell_side
                if (minDistanceUntilNow != null && distanceToBoundingBox != null && minDistanceUntilNow + earlyOutDistance < distanceToBoundingBox.Value)
                {
                    break;
                }
                //  Continue to check only if distance to data cell bounding box is closer than closest intersection point found so far
                //                if ((distanceToBoundingBox.HasValue == false) || ((minDistanceUntilNow != null) && (minDistanceUntilNow < distanceToBoundingBox.Value)))
                //                    continue;

                //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("VoxelMap.LineIntersection get cell");

                //  Get cell from cache. If not there, precalc it and store in the cache.
                //  If null is returned, we know that cell doesn't contain any triangleVertexes so we don't need to do intersections.
                MyVoxelCacheCellData cachedDataCell = null;
                using (MyVoxelCacheData.Locker.AcquireSharedUsing())
                {

                    cachedDataCell = MyVoxelCacheData.GetCell(this, ref cellCoord, true);


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

                    if (cachedDataCell == null || cachedDataCell.VoxelTrianglesCount == 0) continue;

                    GetCellLineIntersectionOctree(ref result, ref modelSpaceLine, ref minDistanceUntilNow, cachedDataCell, flags);
                }
            }

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

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

            if (result != null)
            {
                t = new MyIntersectionResultLineTriangleEx(result.Value, this, ref line);
                return true;
            }
            else
            {
                t = null;
                return false;
            }
        }
Esempio n. 16
0
        internal bool Intersect(ref Line worldLine, out MyIntersectionResultLineTriangleEx?result, IntersectionFlags flags)
        {
            Line localLine = new Line(worldLine.From - m_voxelMap.PositionLeftBottomCorner,
                                      worldLine.To - m_voxelMap.PositionLeftBottomCorner, true);

            Profiler.Begin("VoxelMap.LineIntersection AABB sweep");
            m_sweepResultCache.Clear();
            MyGridIntersection.Calculate(
                m_sweepResultCache,
                (int)MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES,
                localLine.From,
                localLine.To,
                new Vector3I(0, 0, 0),
                m_cellsCount - 1
                );
            Profiler.End();

            Profiler.Begin("VoxelMap.LineIntersection test AABBs");
            float?      minDistanceUntilNow = null;
            BoundingBox cellBoundingBox;
            Vector3I    cellCoord;
            MyIntersectionResultLineTriangle?tmpResult = null;

            for (int index = 0; index < m_sweepResultCache.Count; index++)
            {
                var coord = m_sweepResultCache[index];
                cellCoord = coord;

                GetDataCellBoundingBox(ref cellCoord, out cellBoundingBox);

                float?distanceToBoundingBox = MyUtils.GetLineBoundingBoxIntersection(ref worldLine, ref cellBoundingBox);

                // Sweep results are sorted; when we get far enough, make an early exit
                const float earlyOutDistance = 1.948557f * MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES;  // = sqrt(3) * 9/8 * cell_side
                if (minDistanceUntilNow != null && distanceToBoundingBox != null && minDistanceUntilNow + earlyOutDistance < distanceToBoundingBox.Value)
                {
                    break;
                }

                //  Get cell from cache. If not there, precalc it and store in the cache.
                //  If null is returned, we know that cell doesn't contain any triangleVertexes so we don't need to do intersections.
                CellData cachedDataCell = GetCell(MyLodTypeEnum.LOD0, ref cellCoord);

                if (cachedDataCell == null || cachedDataCell.VoxelTrianglesCount == 0)
                {
                    continue;
                }

                GetCellLineIntersectionOctree(ref tmpResult, ref localLine, ref minDistanceUntilNow, cachedDataCell, flags);
            }

            Profiler.End();

            if (tmpResult.HasValue)
            {
                result = new MyIntersectionResultLineTriangleEx(tmpResult.Value, m_voxelMap, ref worldLine);
                return(true);
            }
            else
            {
                result = null;
                return(false);
            }
        }
        /// <summary>
        /// Returns closest hit from line start position.
        /// </summary>
        public bool GetIntersectionWithLine(ref LineD line, ref MyCharacterHitInfo info, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
        {
            // TODO: This now uses caspule of physics rigid body on the character, it needs to be changed to ragdoll
            //       Currently this approach will be used to support Characters with different skeleton than humanoid
            if (info == null)
                info = new MyCharacterHitInfo();

            info.Reset();

            bool capsulesReady = UpdateCapsuleBones();
            if (!capsulesReady)
                return false;

            double closestDistanceToHit = double.MaxValue;

            Vector3D hitPosition = Vector3D.Zero;
            Vector3D hitPosition2 = Vector3D.Zero;
            Vector3 hitNormal = Vector3.Zero;
            Vector3 hitNormal2 = Vector3.Zero;

            int capsuleIndex = -1;
            for (int i = 0; i < m_bodyCapsules.Length; i++)
            {
                CapsuleD capsule = m_bodyCapsules[i];
                if (capsule.Intersect(line, ref hitPosition, ref hitPosition2, ref hitNormal, ref hitNormal2))
                {
                    double distanceToHit = Vector3.Distance(hitPosition, line.From);
                    if (distanceToHit >= closestDistanceToHit)
                        continue;

                    closestDistanceToHit = distanceToHit;
                    capsuleIndex = i;
                }
            }

            if (capsuleIndex != -1)
            {
                Matrix worldMatrix = PositionComp.WorldMatrix;
                int boneIndex = FindBestBone(capsuleIndex, ref hitPosition, ref worldMatrix);

                // Transform line to model static position and compute accurate collision there
                // 1. Transform line in local coordinates (used later)
                Matrix worldMatrixInv = PositionComp.WorldMatrixNormalizedInv;
                Vector3 fromTrans = Vector3.Transform(line.From, ref worldMatrixInv);
                Vector3 toTrans = Vector3.Transform(line.To, ref worldMatrixInv);
                LineD lineLocal = new LineD(fromTrans, toTrans);

                // 2. Transform line to to bone pose in binding position
                var bone = AnimationController.CharacterBones[boneIndex];
                bone.ComputeAbsoluteTransform();
                Matrix boneAbsTrans = bone.AbsoluteTransform;
                Matrix skinTransform = bone.SkinTransform;
                Matrix boneTrans = skinTransform * boneAbsTrans;
                Matrix invBoneTrans = Matrix.Invert(boneTrans);
                fromTrans = Vector3.Transform(fromTrans, ref invBoneTrans);
                toTrans = Vector3.Transform(toTrans, ref invBoneTrans);

                // 3. Move back line to world coordinates
                LineD lineTransWorld = new LineD(Vector3.Transform(fromTrans, ref worldMatrix), Vector3.Transform(toTrans, ref worldMatrix));
                MyIntersectionResultLineTriangleEx? triangle_;
                bool success = base.GetIntersectionWithLine(ref lineTransWorld, out triangle_, flags);
                if (success)
                {
                    MyIntersectionResultLineTriangleEx triangle = triangle_.Value;

                    info.CapsuleIndex = capsuleIndex;
                    info.BoneIndex = boneIndex;
                    info.Capsule = m_bodyCapsules[info.CapsuleIndex];
                    info.HitHead = info.CapsuleIndex == 0 && m_bodyCapsules.Length > 1;
                    info.HitPositionBindingPose = triangle.IntersectionPointInObjectSpace;
                    info.HitNormalBindingPose = triangle.NormalInObjectSpace;

                    // 4. Move intersection from binding to dynamic pose
                    MyTriangle_Vertexes vertices = new MyTriangle_Vertexes();
                    vertices.Vertex0 = Vector3.Transform(triangle.Triangle.InputTriangle.Vertex0, ref boneTrans);
                    vertices.Vertex1 = Vector3.Transform(triangle.Triangle.InputTriangle.Vertex1, ref boneTrans);
                    vertices.Vertex2 = Vector3.Transform(triangle.Triangle.InputTriangle.Vertex2, ref boneTrans);
                    Vector3 triangleNormal = Vector3.TransformNormal(triangle.Triangle.InputTriangleNormal, boneTrans);
                    MyIntersectionResultLineTriangle triraw = new MyIntersectionResultLineTriangle(ref vertices, ref triangleNormal, triangle.Triangle.Distance);

                    Vector3 intersectionLocal = Vector3.Transform(triangle.IntersectionPointInObjectSpace, ref boneTrans);
                    Vector3 normalLocal = Vector3.TransformNormal(triangle.NormalInObjectSpace, boneTrans);

                    // 5. Store results
                    triangle = new MyIntersectionResultLineTriangleEx();
                    triangle.Triangle = triraw;
                    triangle.IntersectionPointInObjectSpace = intersectionLocal;
                    triangle.NormalInObjectSpace = normalLocal;
                    triangle.IntersectionPointInWorldSpace = Vector3.Transform(intersectionLocal, ref worldMatrix);
                    triangle.NormalInWorldSpace = Vector3.TransformNormal(normalLocal, worldMatrix);
                    triangle.InputLineInObjectSpace = lineLocal;

                    info.Triangle = triangle;

                    if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW)
                    {
                        MyRenderProxy.DebugClearPersistentMessages();
                        MyRenderProxy.DebugDrawCapsule(info.Capsule.P0, info.Capsule.P1, info.Capsule.Radius, Color.Aqua, false, persistent: true);

                        Vector3 p0Local = Vector3.Transform(info.Capsule.P0, ref worldMatrixInv);
                        Vector3 p1Local = Vector3.Transform(info.Capsule.P1, ref worldMatrixInv);
                        Vector3 p0LocalTrans = Vector3.Transform(p0Local, ref invBoneTrans);
                        Vector3 p1LocalTrans = Vector3.Transform(p1Local, ref invBoneTrans);
                        MyRenderProxy.DebugDrawCapsule(Vector3.Transform(p0LocalTrans, ref worldMatrix), Vector3.Transform(p1LocalTrans, ref worldMatrix), info.Capsule.Radius, Color.Brown, false, persistent: true);

                        MyRenderProxy.DebugDrawLine3D(line.From, line.To, Color.Blue, Color.Red, false, true);
                        MyRenderProxy.DebugDrawLine3D(lineTransWorld.From, lineTransWorld.To, Color.Green, Color.Yellow, false, true);
                        MyRenderProxy.DebugDrawSphere(triangle.IntersectionPointInWorldSpace, 0.02f, Color.Red, 1, false, persistent: true);
                        MyRenderProxy.DebugDrawAxis((MatrixD)boneTrans * WorldMatrix, 0.1f, false, true, true);
                    }

                    return true;
                }
            }

            return false;
        }
Esempio n. 18
0
        //  Add decal and all surounding triangles according to the type of intersection (model or voxel)
        public static void Add(MyDecalTexturesEnum decalTexture, float decalSize, float angle, Vector4 color, bool alphaBlendByAngle,
                               ref MyIntersectionResultLineTriangleEx intersection, float lightSize, float emissivity, float decalNormalOffset)
        {
            if (!MyRenderConstants.RenderQualityProfile.EnableDecals)
            {
                return;
            }

            //  Ignore decals too far away
            if (Vector3.Distance(MyCamera.Position, intersection.IntersectionPointInWorldSpace) > (MyDecalsConstants.MAX_DISTANCE_FOR_ADDING_DECALS / MyCamera.Zoom.GetZoomLevel()))
            {
                return;
            }

            //	Polomer decalu a scale faktor pre vypocet textury.
            //  Decal size is something as radius of a decal, so when converting from real metres to texture space, we need to divide by 2.0
            float decalScale = 1.0f / (2.0f * decalSize);

            // Fix: This is safer way to get right vector.
            Vector3             rightVector;
            MyTriangle_Vertexes triangle = intersection.Triangle.InputTriangle;

            if ((triangle.Vertex0 - intersection.IntersectionPointInObjectSpace).Length() > MyMwcMathConstants.EPSILON)
            {
                rightVector = MyMwcUtils.Normalize(triangle.Vertex0 - intersection.IntersectionPointInObjectSpace);
            }
            else if ((triangle.Vertex1 - intersection.IntersectionPointInObjectSpace).Length() > MyMwcMathConstants.EPSILON)
            {
                rightVector = MyMwcUtils.Normalize(triangle.Vertex1 - intersection.IntersectionPointInObjectSpace);
            }
            else if ((triangle.Vertex2 - intersection.IntersectionPointInObjectSpace).Length() > MyMwcMathConstants.EPSILON)
            {
                rightVector = MyMwcUtils.Normalize(triangle.Vertex2 - intersection.IntersectionPointInObjectSpace);
            }
            else
            {
                System.Diagnostics.Debug.Assert(false, "Normal has zero length! Probably invalid intersection point!");
                return;
            }

            Vector3 upVector = Vector3.Cross(rightVector, intersection.NormalInObjectSpace);

            if (!MyMwcUtils.HasValidLength(upVector))
            {
                //System.Diagnostics.Debug.Assert(false, "Invalid result of cross produt!");
                return;
            }

            upVector = MyMwcUtils.Normalize(upVector);

            //  We create world matrix for the decal and then rotate the matrix, so we can extract rotated right/up vectors/planes for texture coord0 calculations
            Matrix decalMatrix = Matrix.CreateRotationZ(angle) * Matrix.CreateWorld(intersection.IntersectionPointInObjectSpace, intersection.NormalInObjectSpace, upVector);

            //	Right plane
            MyPlane rightPlane;

            rightPlane.Point  = intersection.IntersectionPointInObjectSpace;
            rightPlane.Normal = MyUtils.GetTransformNormalNormalized(Vector3.Right, ref decalMatrix);

            //	Up plane
            MyPlane upPlane;

            upPlane.Point  = intersection.IntersectionPointInObjectSpace;
            upPlane.Normal = MyUtils.GetTransformNormalNormalized(Vector3.Up, ref decalMatrix);

            if (intersection.Entity is MyVoxelMap)
            {
                AddDecalVoxel(decalTexture, decalSize, decalScale, color, alphaBlendByAngle, ref intersection, ref rightPlane, ref upPlane, lightSize, emissivity, decalNormalOffset);
            }
            else
            {
                AddDecalModel(decalTexture, decalSize, decalScale, color, alphaBlendByAngle, ref intersection, ref rightPlane, ref upPlane, lightSize, emissivity, decalNormalOffset);
            }
        }
Esempio n. 19
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);
        }
Esempio n. 20
0
        public override bool GetIntersectionWithLine(ref MyLine line, out MyIntersectionResultLineTriangleEx? t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
        {
            t = null;
            foreach (MyPrefabBase prefab in m_prefabs)
            {
                MyEntity entity = prefab as MyEntity;
                MyIntersectionResultLineTriangleEx? prefabIntersectionResult;
                entity.GetIntersectionWithLine(ref line, out prefabIntersectionResult);
                t = MyIntersectionResultLineTriangleEx.GetCloserIntersection(ref t, ref prefabIntersectionResult);
            }

            return t != null;
        }