Example #1
0
        //private bool TestAABB(ref BoundingBox bbox)
        //{
        //    return (bbox.Max - bbox.Min).Length() < MyLightsConstants.MAX_SPOTLIGHT_AABB_DIAGONAL;
        //}

        private static void CalculateAABB(ref BoundingBox bbox, out float scaleZ, out float scaleXY, ref Vector3 position, ref Vector3 direction, ref Vector3 up, float reflectorConeMaxAngleCos, float reflectorRange)
        {
            float cosAngle = 1 - reflectorConeMaxAngleCos;

            scaleZ = reflectorRange;
            // Calculate cone side (hypotenuse of triangle)
            float side = reflectorRange / cosAngle;

            // Calculate cone bottom scale (Pythagoras theorem)
            scaleXY = (float)System.Math.Sqrt(side * side - reflectorRange * reflectorRange) * 2;

            up = MyMwcUtils.Normalize(up);
            Vector3 coneSideDirection = Vector3.Cross(up, direction);

            coneSideDirection = MyMwcUtils.Normalize(coneSideDirection);
            Vector3 coneCenter = position + direction * scaleZ;
            Vector3 pt1        = coneCenter + coneSideDirection * scaleXY / 2 + up * scaleXY / 2;
            Vector3 pt2        = coneCenter - coneSideDirection * scaleXY / 2 + up * scaleXY / 2;
            Vector3 pt3        = coneCenter + coneSideDirection * scaleXY / 2 - up * scaleXY / 2;
            Vector3 pt4        = coneCenter - coneSideDirection * scaleXY / 2 - up * scaleXY / 2;

            bbox = bbox.CreateInvalid();
            bbox = bbox.Include(ref position);
            //bbox = bbox.Include(ref coneCenter);
            bbox = bbox.Include(ref pt1);
            bbox = bbox.Include(ref pt2);
            bbox = bbox.Include(ref pt3);
            bbox = bbox.Include(ref pt4);
        }
        /// <summary>
        /// Collapses an edge defined by its two endpoint vertices.
        /// </summary>
        /// <param name="keptVertexIndex">The index of the vertex that will NOT be removed in the process.
        /// However, it will be moved if it's not locked.</param>
        /// <param name="removedVertexIndex">The index of the vertex that WILL be removed in the process.</param>
        private void CollapseEdge(short keptVertexIndex, short removedVertexIndex)
        {
            Debug.Assert(!IsVertexLocked(removedVertexIndex));

            // if I can move the kept vertex, make its new position the average of the previous positions
            bool interpolate = !IsVertexLocked(keptVertexIndex);

            if (interpolate)
            {
                var keptVertex = m_vertices[keptVertexIndex];

                keptVertex.Position = .5f *
                                      (keptVertex.Position + m_vertices[removedVertexIndex].Position);

                keptVertex.Normal = MyMwcUtils.Normalize(
                    (keptVertex.Normal + m_vertices[removedVertexIndex].Normal));

                m_vertices[keptVertexIndex] = keptVertex;
            }

            var removedVertexTriangles = m_adjacentTriangleIndices[removedVertexIndex];

            for (int i = removedVertexTriangles.Count - 1; i >= 0; i--)
            {
                var triangleIndex = removedVertexTriangles[i];
                var triangle      = m_triangles[triangleIndex];

                if (triangle.VertexIndex0 == removedVertexIndex)
                {
                    triangle.VertexIndex0 = keptVertexIndex;
                    Debug.Assert(keptVertexIndex < m_vertices.Count);
                }
                if (triangle.VertexIndex1 == removedVertexIndex)
                {
                    triangle.VertexIndex1 = keptVertexIndex;
                    Debug.Assert(keptVertexIndex < m_vertices.Count);
                }
                if (triangle.VertexIndex2 == removedVertexIndex)
                {
                    triangle.VertexIndex2 = keptVertexIndex;
                    Debug.Assert(keptVertexIndex < m_vertices.Count);
                }

                // todo find out why test for zero-surface does not work
                if (IsDegenerated(triangle) /*|| HasZeroSurface(triangle)*/)
                {
                    // delete triangle
                    RemoveTriangle(triangleIndex);
                }
                else
                {
                    // update triangle
                    m_triangles[triangleIndex] = triangle;
                    if (!m_adjacentTriangleIndices[keptVertexIndex].Contains(triangleIndex))
                    {
                        m_adjacentTriangleIndices[keptVertexIndex].Add(triangleIndex);
                    }
                }
            }
        }
Example #3
0
        //Creates rotation matrix from direction (dir must be normalized)
        public static Matrix MatrixFromDir(Vector3 dir)
        {
            Vector3 right = new Vector3(0.0f, 0.0f, 1.0f);
            Vector3 up;
            float   d = dir.Z;

            if (d > -0.99999 && d < 0.99999)
            { // to avoid problems with normalize in special cases
                right = right - dir * d;
                right = MyMwcUtils.Normalize(right);
                up    = Vector3.Cross(dir, right);
            }
            else
            { //dir lies with z axis
                right = new Vector3(dir.Z, 0, -dir.X);
                up    = new Vector3(0, 1, 0);
            };

            Matrix m = Matrix.Identity;

            m.Right   = right;
            m.Up      = up;
            m.Forward = dir;

            return(m);
        }
Example #4
0
        /// <summary>
        /// Updates velocity from external accel and gravitation
        /// </summary>=
        public void UpdateVelocity(float dt)
        {
            // apply directional gravity
            m_ExternalLinearAcceleration += MyPhysics.physicsSystem.Gravitation * dt;

            // apply point gravity
            Vector3 accelerationFromPoints = Vector3.Zero;

            foreach (var gravityPoint in MyPhysics.physicsSystem.GravitationPoints)
            {
                float   distance    = Vector3.Distance(Position, gravityPoint.Item1.Center);
                float   power       = MathHelper.Clamp(1 - distance / gravityPoint.Item1.Radius, 0, 1);
                Vector3 dirToCenter = Vector3.Normalize(gravityPoint.Item1.Center - Position);
                accelerationFromPoints += dirToCenter * power * gravityPoint.Item2;
            }

            m_ExternalLinearAcceleration += accelerationFromPoints * dt;


            m_Velocity += m_ExternalLinearAcceleration * dt;

            m_AngularVelocity += m_ExternalAngularAcceleration * dt;

            if (m_MaxAngularVelocity > 0.0f && m_AngularVelocity.Length() > m_MaxAngularVelocity)
            {
                m_AngularVelocity  = MyMwcUtils.Normalize(m_AngularVelocity);
                m_AngularVelocity *= m_MaxAngularVelocity;
            }

            if (m_MaxLinearVelocity > 0.0f && m_Velocity.Length() > m_MaxLinearVelocity)
            {
                m_Velocity  = MyMwcUtils.Normalize(m_Velocity);
                m_Velocity *= m_MaxLinearVelocity;
            }
        }
Example #5
0
        public static Vector3 PointOnOrbit(this Random random, float orbitRadius, float orbitRadiusDev, float angleRad, float angleRadDev)
        {
            float   ang        = MathHelper.Lerp(angleRad - angleRadDev, angleRad + angleRadDev, Float(random));
            Vector3 orbitPoint = new Vector3((float)Math.Sin(ang) * orbitRadius, 0, (float)Math.Cos(ang) * orbitRadius);
            Vector3 toOrbit    = MyMwcUtils.Normalize(orbitPoint);

            return(orbitPoint + MyMwcUtils.Normalize(toOrbit * Float(random, -1, 1) + Vector3.Up * Float(random, -1, 1)) * orbitRadiusDev * Float(random));
        }
Example #6
0
        /// <summary>
        /// Simple prediction, not used
        /// </summary>
        /// <param name="targetEntity"></param>
        /// <returns></returns>
        protected Vector3 GetPredictedVelocityToTargetEntity(MyEntity targetEntity)
        {
            Vector3?targetDir = null;

            Vector3?decoyPosition = DetectDecoys();

            if (decoyPosition.HasValue)
            {
                var decoyToMissile = decoyPosition.Value - GetPosition();
                if (decoyToMissile.LengthSquared() < MyDecoyFlareConstants.DECOY_KILL_RADIUS * MyDecoyFlareConstants.DECOY_KILL_RADIUS)
                {
                    Explode();
                    return(Vector3.Zero);
                }

                targetDir = decoyToMissile;
                targetDir = MyMwcUtils.Normalize(targetDir.Value);
            }
            else if (targetEntity != null)
            {
                //calculate position to navigate missile to
                targetDir = targetEntity.WorldMatrix.Translation - WorldMatrix.Translation; //simple solution

                float distance = (this.WorldMatrix.Translation - targetEntity.WorldMatrix.Translation).Length();
                float time     = distance / m_actualSpeed;

                if (time > MyGuidedMissileConstants.MISSILE_PREDICATION_TIME_TRESHOLD)
                {
                    m_predicatedPosition = time * m_targetVelocity + targetEntity.WorldMatrix.Translation;
                    targetDir            = m_predicatedPosition - WorldMatrix.Translation; //simple solution
                }

                targetDir = MyMwcUtils.Normalize(targetDir.Value);
            }

            if (targetDir.HasValue)
            {
                //create new navigation direction
                Vector3 actualDir = WorldMatrix.Forward;

                Vector3 rotationAxis   = Vector3.Cross(actualDir, targetDir.Value);
                Matrix  rotationMatrix = Matrix.CreateFromAxisAngle(rotationAxis, m_turnSpeed * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS);
                rotationMatrix.Right   = MyMwcUtils.Normalize(rotationMatrix.Right);
                rotationMatrix.Up      = MyMwcUtils.Normalize(rotationMatrix.Up);
                rotationMatrix.Forward = MyMwcUtils.Normalize(rotationMatrix.Forward);

                Matrix newBodyMatrix = WorldMatrix * rotationMatrix;

                newBodyMatrix.Translation = WorldMatrix.Translation;

                SetWorldMatrix(newBodyMatrix);

                return(newBodyMatrix.Forward);
            }

            //no target ship, fly straight ahead
            return(WorldMatrix.Forward);
        }
Example #7
0
        public static Matrix NormalizeMatrix(Matrix matrix)
        {
            Matrix m = matrix;

            m.Right   = MyMwcUtils.Normalize(m.Right);
            m.Up      = MyMwcUtils.Normalize(m.Up);
            m.Forward = MyMwcUtils.Normalize(m.Forward);
            return(m);
        }
        protected override bool Interact(bool staticCollision)
        {
            if (!staticCollision && GetRigidBody1().IsStatic() && GetRigidBody2().IsStatic())
            {
                return(false);
            }

            MyRBSphereElement sphere1 = (MyRBSphereElement)RBElement1;
            MyRBSphereElement sphere2 = (MyRBSphereElement)RBElement2;

            Matrix matrix1 = sphere1.GetGlobalTransformation();
            Matrix matrix2 = sphere2.GetGlobalTransformation();

            Vector3 p1     = matrix1.Translation;
            Vector3 p2     = matrix2.Translation;
            Vector3 d      = p2 - p1;
            float   length = d.Length();

            float contactRadius = sphere1.Radius + sphere2.Radius;

            float eps = MyPhysics.physicsSystem.GetRigidBodyModule().CollisionEpsilon;

            if (staticCollision)
            {
                return(length < contactRadius);
            }

            // from now on we handle dynamic collision
            float dynEps = 0;

            if (!staticCollision && length > eps)
            {
                dynEps = Vector3.Dot(GetRigidBody1().LinearVelocity - GetRigidBody2().LinearVelocity, d) / length * MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep;
                if (dynEps < 0)
                {
                    dynEps = 0;
                }
            }

            if (length > MyMwcMathConstants.EPSILON && length < contactRadius + eps + dynEps)
            {
                Vector3 n     = MyMwcUtils.Normalize(d);
                Vector3 p     = p1 + n * (sphere1.Radius + (length - contactRadius) * 0.5f);
                float   error = length - (contactRadius + 0.5f * eps);

                MySmallCollPointInfo[] collInfo = MyContactInfoCache.SCPIStackAlloc();
                collInfo[0] = new MySmallCollPointInfo(p - matrix1.Translation, p - matrix2.Translation, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, n, error, p);

                MyPhysics.physicsSystem.GetContactConstraintModule().AddContactConstraint(this, collInfo, 1);

                MyContactInfoCache.FreeStackAlloc(collInfo);

                return(true);
            }
            return(false);
        }
Example #9
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);
                }
            }
        }
Example #10
0
        //  This method will start sun wind. Or if there is one coming, this will reset it so it will start again.
        public static void Start()
        {
            //  Activate sun wind
            IsActive = true;

            m_smallBillboardsStarted = false;

            m_timeLastUpdate = MyMinerGame.TotalGamePlayTimeInMilliseconds;

            //  Place sun wind at farest possible negative Z position
            //Vector3 directionToSunNormalized = MyMwcUtils.Normalize(MyGuiScreenGameBase.Static.SunPosition - MyCamera.Position); MyMwcSectorGroups.Get(MyGuiScreenGameBase.Static.Sector.SectorGroup).GetDirectionToSunNormalized();
            Vector3 directionToSunNormalized = MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized();

            m_initialSunWindPosition     = MyCamera.Position + directionToSunNormalized * MySunWindConstants.SUN_WIND_LENGTH_HALF;
            m_directionFromSunNormalized = -directionToSunNormalized;

            //  Start the sound of burning (looping)
            StopCue();
            m_burningCue = MyAudio.AddCue3D(MySoundCuesEnum.SfxSolarWind, m_initialSunWindPosition, m_directionFromSunNormalized, Vector3.Up, Vector3.Zero);
            //MySounds.UpdateCuePitch(m_burningCue, MyMwcUtils.GetRandomFloat(-1, +1));

            m_speed = MyMwcUtils.GetRandomFloat(MySunWindConstants.SPEED_MIN, MySunWindConstants.SPEED_MAX);

            m_strength = MyMwcUtils.GetRandomFloat(0, 1);

            MyUtils.GetPerpendicularVector(ref m_directionFromSunNormalized, out m_rightVector);
            m_downVector = MyMwcUtils.Normalize(Vector3.Cross(m_directionFromSunNormalized, m_rightVector));

            StartBillboards();

            // Reinit computed max distances, they'll be computed in update
            m_computedMaxDistances = 0;

            m_deltaTime = 0;

            // Collect entities
            m_sunwindEntities.Clear();
            foreach (var entity in MyEntities.GetEntities())
            {
                if (!(entity is MySmallShip))
                {
                    continue;
                }

                // Do not move with indestructibles (NPCs etc)
                if (!entity.IsDestructible)
                {
                    continue;
                }

                m_sunwindEntities.Add(entity);
            }
        }
        public static void DrawLine(Vector3 start, Vector3 end, MyTransparentMaterialEnum?material, ref Vector4 color, float thickness)
        {
            Vector3 dir = end - start;
            float   len = dir.Length();

            if (len > 0.1f)
            {
                dir = MyMwcUtils.Normalize(dir);

                MyTransparentGeometry.AddLineBillboard(material ?? MyTransparentMaterialEnum.ProjectileTrailLine, color, start, dir, len, thickness);
            }
        }
Example #12
0
        //  IMPORTANT: This struct must be initialized using this constructor, or by filling all four fields. It's because
        //  some code may need length or distance, and if they aren't calculated, we can have problems.
        public MyLine(Vector3 from, Vector3 to, bool calculateBoundingBox = true)
        {
            From      = from;
            To        = to;
            Direction = MyMwcUtils.Normalize(to - from);
            Vector3.Distance(ref to, ref from, out Length);

            //  Calculate line's bounding box, but only if we know we will need it
            BoundingBox = BoundingBoxHelper.InitialBox;
            if (calculateBoundingBox == true)
            {
                BoundingBoxHelper.AddLine(ref this, ref BoundingBox);
            }
        }
Example #13
0
        static Vector3 CalculateDominantNormal(List <MyTriangle_Vertex_Normals> triangleVertexNormals)
        {
            Vector3 normalSum = Vector3.Zero;

            for (int i = 0; i < triangleVertexNormals.Count; i++)
            {
                normalSum +=
                    triangleVertexNormals[i].Normals.Normal0 +
                    triangleVertexNormals[i].Normals.Normal1 +
                    triangleVertexNormals[i].Normals.Normal2;
            }

            return(MyMwcUtils.Normalize(normalSum));
        }
Example #14
0
        /// <summary>
        /// Get random direction near base direction
        /// </summary>
        /// <param name="random"></param>
        /// <param name="baseDirection"></param>
        /// <param name="maxAngleDeviation">Max angle deviation in radians PI/2 is right angle</param>
        /// <returns></returns>
        public static Vector3 Direction(this Random random, Vector3 baseDirection, float maxAngleDeviation)
        {
            Vector3 otherDir = Vector3.Up;

            if (baseDirection == otherDir || baseDirection == -otherDir)
            {
                otherDir = Vector3.Left;
            }

            Vector3 planar1 = Vector3.Cross(baseDirection, otherDir);
            Vector3 planar2 = Vector3.Cross(baseDirection, planar1);
            float   maxDist = (float)Math.Tan(maxAngleDeviation);

            return(MyMwcUtils.Normalize(baseDirection + planar1 * random.Float(-maxDist, maxDist) + planar2 * random.Float(-maxDist, maxDist)));
        }
Example #15
0
        private void UpdateLightWorldMatrix()
        {
            if (m_pointLight != null)
            {
                Matrix newMat = m_pointLocalMatrix * base.WorldMatrix;

                m_pointLight.SetPosition(newMat.Translation);
                m_pointLight.ReflectorDirection = newMat.Down;
                m_pointLight.ReflectorDirection = MyMwcUtils.Normalize(m_pointLight.ReflectorDirection);
                m_pointLight.ReflectorUp        = newMat.Right;
                m_pointLight.ReflectorUp        = MyMwcUtils.Normalize(m_pointLight.ReflectorUp);

                // move the light outwards in the direction of the lamp, for purposes of glare
                m_pointLight.SetPosition(m_pointLight.Position + 0.75f * m_pointLight.ReflectorDirection);
            }
        }
            public static Vector3 LinearVector(ref Vector3 B, ref Vector3 A, float LastTime, float t)
            {
                Vector3 diffVector = A - B;
                float   length     = diffVector.Length();

                if (diffVector.Length() < PREDICTION_MINIMAL_EPSILON)
                {
                    return(A);
                }
                float lastSpeed = length / LastTime;
                float newLength = lastSpeed * t;

                diffVector = MyMwcUtils.Normalize(diffVector);
                diffVector = Vector3.Negate(diffVector);
                return(Vector3.Multiply(diffVector, newLength));
            }
Example #17
0
        public void Draw()
        {
            Vector3 dir = MyMwcUtils.Normalize(MyCamera.Position - Position);

            float timeBlic = MyMinerGame.TotalGamePlayTimeInMilliseconds % TimerForBlic;

            if (timeBlic > BLIC_DURATON_IN_MILISECONDS)
            {
                timeBlic = TimerForBlic - timeBlic;
            }
            timeBlic = MathHelper.Clamp(1 - timeBlic / BLIC_DURATON_IN_MILISECONDS, 0, 1);

            float radius = MathHelper.Lerp(RadiusMin, RadiusMax, timeBlic);

            MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.ReflectorGlareAlphaBlended, Vector4.One, Position + dir, radius, 0);
            Light.Range = radius * 4;
        }
Example #18
0
        public void DoWork()
        {
            try
            {
                MyEntities.EntityCloseLock.AcquireShared();

                if (m_bot == null)
                {
                    return;
                }

                BoundingSphere boundingSphere = new BoundingSphere(m_position, m_bot.WorldVolume.Radius * 2.0f);
                if (MyEntities.GetIntersectionWithSphere(ref boundingSphere) != null)
                {
                    return;
                }

                Matrix transform            = Matrix.CreateWorld(m_position, MyMwcUtils.Normalize(m_targetPosition - m_position), m_up);
                float  distanceToRoutePoint = Vector3.Dot(m_targetPosition - m_position, transform.Forward);

                for (int i = 0; i < m_points.Length; i++)
                {
                    Vector3 transformedPoint = Vector3.Transform(m_points[i], transform);
                    MyLine  line             = new MyLine(transformedPoint, transformedPoint + transform.Forward * distanceToRoutePoint, true);

                    var result = MyEntities.GetIntersectionWithLine(ref line, m_bot, null, true);
                    if (result.HasValue)
                    {
                        // Collision detected
                        return;
                    }
                }

                Result = m_position;
            }
            finally
            {
                if (m_bot != null)
                {
                    m_bot.OnClose -= m_bot_OnClose;
                }
                MyEntities.EntityCloseLock.ReleaseShared();
            }
        }
        /// <summary>
        /// Draw occlusion bounding box method with our premade effect and box.
        /// </summary>
        /// <param name="bbox"></param>
        /// <param name="scale"></param>
        /// <param name="enableDepthTesting"></param>
        /// <param name="billboardLike">Indicates whether the occlusion object (box) is rotated to face the camera or not.</param>
        public static void DrawOcclusionBoundingBox(BoundingBox bbox, float scale, bool enableDepthTesting, bool billboardLike = false, bool useDepthTarget = true)
        {
            useDepthTarget &= !MyRenderConstants.RenderQualityProfile.ForwardRender;

            var    cameraToBBox = bbox.GetCenter() - MyCamera.Position;
            Matrix worldMatrix  = billboardLike ? Matrix.CreateWorld(Vector3.Zero, MyMwcUtils.Normalize(cameraToBBox), MyMwcUtils.Normalize(MyCamera.UpVector + MyCamera.LeftVector)) : Matrix.Identity;

            Vector3 scaleV = (bbox.Max - bbox.Min) * scale;

            worldMatrix            *= Matrix.CreateScale(scaleV);
            worldMatrix.Translation = cameraToBBox;



            MyEffectOcclusionQueryDraw effectOQ = MyRender.GetEffect(MyEffects.OcclusionQueryDrawMRT) as MyEffectOcclusionQueryDraw;

            if (enableDepthTesting && !MyRenderConstants.RenderQualityProfile.ForwardRender)
            {
                effectOQ.SetTechnique(MyEffectOcclusionQueryDraw.Technique.DepthTestEnabled);
            }
            else
            {
                effectOQ.SetTechnique(MyEffectOcclusionQueryDraw.Technique.DepthTestDisabled);
            }


            effectOQ.SetWorldMatrix(worldMatrix);
            effectOQ.SetViewMatrix(MyCamera.ViewMatrixAtZero);
            effectOQ.SetProjectionMatrix(MyCamera.ProjectionMatrix);

            if (useDepthTarget)
            {
                var depthRenderTarget = MyRender.GetRenderTarget(MyRenderTargets.Depth);
                effectOQ.SetDepthRT(depthRenderTarget);
                effectOQ.SetScale(MyRender.GetScaleForViewport(depthRenderTarget));
            }

            effectOQ.Begin();

            //draw
            m_modelBoxLowRes.Render();

            effectOQ.End();
        }
        public static void DrawTransparentPyramid(ref Vector3 start, ref MyQuad backQuad, ref Vector4 vctColor, int divideRatio, float thickness, MyTransparentMaterialEnum?lineMaterial = null)
        {
            Vector3 vctZero = Vector3.Zero;

            m_lineBuffer.Clear();
            GenerateLines(start, backQuad.Point0, backQuad.Point1, ref m_lineBuffer, divideRatio);
            GenerateLines(start, backQuad.Point1, backQuad.Point2, ref m_lineBuffer, divideRatio);
            GenerateLines(start, backQuad.Point2, backQuad.Point3, ref m_lineBuffer, divideRatio);
            GenerateLines(start, backQuad.Point3, backQuad.Point0, ref m_lineBuffer, divideRatio);

            foreach (MyLine line in m_lineBuffer)
            {
                Vector3 dir = line.To - line.From;
                float   len = dir.Length();
                if (len > 0.1f)
                {
                    dir = MyMwcUtils.Normalize(dir);

                    MyTransparentGeometry.AddLineBillboard(lineMaterial ?? MyTransparentMaterialEnum.ProjectileTrailLine, vctColor, line.From, dir, len, thickness);
                }
            }
        }
Example #21
0
        public static void Draw()
        {
            if (MyFakes.TEST_MISSION_1_ENABLED)
            {
                if (m_remainingPrimaryTargetsCounter == 0)
                {
                    if (m_russianDropZoneLight != null)
                    {
                        Vector3 dir = MyMwcUtils.Normalize(MyCamera.Position - RUSSIAN_DROP_ZONE_POSITION);

                        float timeBlic = MyMinerGame.TotalGamePlayTimeInMilliseconds % 980;
                        if (timeBlic > 250)
                        {
                            timeBlic = 980 - timeBlic;
                        }
                        timeBlic = MathHelper.Clamp(1 - timeBlic / 250, 0, 1);

                        float alpha = MathHelper.Lerp(0.1f, 0.6f, timeBlic);

                        m_dropZoneLightColor.W = alpha;
                        m_russianDropZoneLight.Start(MyLight.LightTypeEnum.PointLight, RUSSIAN_DROP_ZONE_POSITION, m_dropZoneLightColor, 1, 200);

                        float radius = MathHelper.Lerp(0.1f, 150f, timeBlic);

                        MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.ReflectorGlareAlphaBlended, m_dropZoneLightColor,
                                                                RUSSIAN_DROP_ZONE_POSITION + dir * 5, radius, 0);
                    }
                    else
                    {
                        m_russianDropZoneLight = MyLights.AddLight();
                        if (m_russianDropZoneLight != null)
                        {
                            m_russianDropZoneLight.Start(MyLight.LightTypeEnum.PointLight, 1);
                        }
                    }
                }
            }
        }
Example #22
0
        //  AddPoint
        //  if pt is less than Sqrt(combinationDistanceSq) from one of the
        //  others the original is replaced with the mean of it
        //  and pt, and false is returned. true means that pt was
        //  added to pts
        private bool AddPoint(List <MyCP> pts, Vector3 pt, Vector3 normal, float depth, float combinationDistanceSq)
        {
            for (int i = pts.Count; i-- != 0;)
            {
                if (PointPointDistanceSq(pts[i].m_Position, pt) < combinationDistanceSq)
                {
                    //pts[i] = 0.5f * (pts[i] + pt);
                    return(false);
                }
            }
            MyCP cp = new MyCP();

            cp.m_Normal   = -normal;
            cp.m_Normal   = MyMwcUtils.Normalize(cp.m_Normal);
            cp.m_Position = pt;
            cp.m_Depth    = depth * 0.1f - 0.5f * MyPhysicsConfig.CollisionEpsilon;
            if (cp.m_Depth < -0.5f)
            {
                cp.m_Depth *= 0.5f;
            }
            pts.Add(cp);
            return(true);
        }
Example #23
0
        //  Generate explosion particles. These will be smoke, explosion and some polyline particles.
        void GenerateExplosionParticles(MyParticleEffectsIDEnum newParticlesType, BoundingSphere explosionSphere, float particleScale)
        {
            Vector3 dirToCamera = MyCamera.Position - explosionSphere.Center;

            if (MyMwcUtils.IsZero(dirToCamera))
            {
                dirToCamera = MyCamera.ForwardVector;
            }
            else
            {
                dirToCamera = MyMwcUtils.Normalize(dirToCamera);
            }

            //  Move explosion particles in the direction of camera, so we won't see billboards intersecting the large ship
            BoundingSphere tempExplosionSphere = m_explosionSphere;

            tempExplosionSphere.Center = m_explosionSphere.Center + dirToCamera * 0.9f;

            MyParticleEffect explosionEffect = MyParticlesManager.CreateParticleEffect((int)newParticlesType);

            explosionEffect.WorldMatrix          = Matrix.CreateTranslation(tempExplosionSphere.Center);
            explosionEffect.UserRadiusMultiplier = tempExplosionSphere.Radius;
            explosionEffect.UserScale            = particleScale;
        }
Example #24
0
        //  Draw the projectile but only if desired polyline trail distance can fit in the trajectory (otherwise we will see polyline growing from the origin and it's ugly).
        //  Or draw if this is last draw of this projectile (useful for short-distance shots).
        public void Draw()
        {
            const float PROJECTILE_POLYLINE_DESIRED_LENGTH = 120;

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

            if ((trajectoryLength > 0) || (m_state == MyProjectileStateEnum.KILLED))
            {
                if (m_state == MyProjectileStateEnum.KILLED)
                {
                    m_state = MyProjectileStateEnum.KILLED_AND_DRAWN;
                }

                if (!m_positionChecked)
                {
                    return;
                }



                //  If we calculate previous position using normalized direction (insted of velocity), projectile trails will
                //  look like coming from cannon, and that is desired. Even during fast movement, acceleration, rotation or changes in movement directions.
                //Vector3 previousPosition = m_position - m_directionNormalized * projectileTrailLength * 1.05f;
                Vector3 previousPosition = m_position - m_directionNormalized * PROJECTILE_POLYLINE_DESIRED_LENGTH * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                //Vector3 previousPosition = m_previousPosition;
                //Vector3 previousPosition = m_initialSunWindPosition - MyMwcUtils.Normalize(m_desiredVelocity) * projectileTrailLength;

                Vector3 direction = Vector3.Normalize(m_position - previousPosition);

                float projectileTrailLength = 40 * LengthMultiplier;// PROJECTILE_POLYLINE_DESIRED_LENGTH;

                projectileTrailLength *= MyMwcUtils.GetRandomFloat(0.6f, 0.8f);

                if (trajectoryLength < projectileTrailLength)
                {
                    projectileTrailLength = trajectoryLength;
                }

                previousPosition = m_position - projectileTrailLength * direction;
                if (m_externalAddition >= 1.0f)
                {
                    m_externalAddition = 0.5f;
                }


                //float color = MyMwcUtils.GetRandomFloat(1, 2);
                float color     = MyMwcUtils.GetRandomFloat(1, 2);
                float thickness = m_thicknessMultiplier * MyMwcUtils.GetRandomFloat(0.2f, 0.3f);

                //  Line particles (polyline) don't look good in distance. Start and end aren't rounded anymore and they just
                //  look like a pieces of paper. Especially when zoom-in.
                thickness *= MathHelper.Lerp(0.2f, 0.8f, MyCamera.Zoom.GetZoomLevel());

                float alphaCone  = 1;
                float alphaGlare = 1;

                if (BlendByCameraDirection)
                {
                    float angle = 1 - Math.Abs(Vector3.Dot(MyMwcUtils.Normalize(MyCamera.ForwardVector), direction));
                    alphaGlare = (float)Math.Pow(1 - angle, 2);
                    alphaCone  = (1 - (float)Math.Pow(1 - angle, 30));
                }

                MyTransparentGeometry.AddLineBillboard(MyTransparentMaterialEnum.ProjectileTrailLine, new Vector4(m_ammoProperties.TrailColor * color, 1) * alphaCone,
                                                       previousPosition, direction, projectileTrailLength, thickness);

                if (FrontBillboardMaterial.HasValue)
                {
                    MyTransparentGeometry.AddPointBillboard(FrontBillboardMaterial.Value, new Vector4(m_ammoProperties.TrailColor * color, 1) * alphaGlare, m_position, 0.8f * FrontBillboardSize, 0);
                }
            }
        }
        //	Special method that loads data into GPU, and can be called only from Draw method, never from LoadContent or from background thread.
        //	Because that would lead to empty vertex/index buffers if they are filled/created while game is minimized (remember the issue - alt-tab during loading screen)
        static void LoadInDraw()
        {
            if (m_loaded)
            {
                return;
            }

            //  In fact it doesn't matter how large is cube, it will always look same as we are always in its middle
            //  I changed it from 1.0 to 100.0 only because will small length I had problems with near frustum plane and crazy aspect ratios.
            const float CUBE_LENGTH_HALF = 100;

            Vector3 shapeSize     = Vector3.One * CUBE_LENGTH_HALF;
            Vector3 shapePosition = Vector3.Zero;

            MyVertexFormatPositionTexture3[] boxVertices = new MyVertexFormatPositionTexture3[36];

            Vector3 topLeftFront     = shapePosition + new Vector3(-1.0f, 1.0f, -1.0f) * shapeSize;
            Vector3 bottomLeftFront  = shapePosition + new Vector3(-1.0f, -1.0f, -1.0f) * shapeSize;
            Vector3 topRightFront    = shapePosition + new Vector3(1.0f, 1.0f, -1.0f) * shapeSize;
            Vector3 bottomRightFront = shapePosition + new Vector3(1.0f, -1.0f, -1.0f) * shapeSize;
            Vector3 topLeftBack      = shapePosition + new Vector3(-1.0f, 1.0f, 1.0f) * shapeSize;
            Vector3 topRightBack     = shapePosition + new Vector3(1.0f, 1.0f, 1.0f) * shapeSize;
            Vector3 bottomLeftBack   = shapePosition + new Vector3(-1.0f, -1.0f, 1.0f) * shapeSize;
            Vector3 bottomRightBack  = shapePosition + new Vector3(1.0f, -1.0f, 1.0f) * shapeSize;

            Vector3 textureTopLeftFront     = MyMwcUtils.Normalize(topLeftFront);
            Vector3 textureBottomLeftFront  = MyMwcUtils.Normalize(bottomLeftFront);
            Vector3 textureTopRightFront    = MyMwcUtils.Normalize(topRightFront);
            Vector3 textureBottomRightFront = MyMwcUtils.Normalize(bottomRightFront);
            Vector3 textureTopLeftBack      = MyMwcUtils.Normalize(topLeftBack);
            Vector3 textureTopRightBack     = MyMwcUtils.Normalize(topRightBack);
            Vector3 textureBottomLeftBack   = MyMwcUtils.Normalize(bottomLeftBack);
            Vector3 textureBottomRightBack  = MyMwcUtils.Normalize(bottomRightBack);

            textureTopLeftFront.Z     *= -1;
            textureBottomLeftFront.Z  *= -1;
            textureTopRightFront.Z    *= -1;
            textureBottomRightFront.Z *= -1;
            textureTopLeftBack.Z      *= -1;
            textureTopRightBack.Z     *= -1;
            textureBottomLeftBack.Z   *= -1;
            textureBottomRightBack.Z  *= -1;

            // Front face.
            boxVertices[0] = new MyVertexFormatPositionTexture3(topLeftFront, textureTopLeftFront);
            boxVertices[1] = new MyVertexFormatPositionTexture3(bottomLeftFront, textureBottomLeftFront);
            boxVertices[2] = new MyVertexFormatPositionTexture3(topRightFront, textureTopRightFront);
            boxVertices[3] = new MyVertexFormatPositionTexture3(bottomLeftFront, textureBottomLeftFront);
            boxVertices[4] = new MyVertexFormatPositionTexture3(bottomRightFront, textureBottomRightFront);
            boxVertices[5] = new MyVertexFormatPositionTexture3(topRightFront, textureTopRightFront);

            // Back face.
            boxVertices[6]  = new MyVertexFormatPositionTexture3(topLeftBack, textureTopLeftBack);
            boxVertices[7]  = new MyVertexFormatPositionTexture3(topRightBack, textureTopRightBack);
            boxVertices[8]  = new MyVertexFormatPositionTexture3(bottomLeftBack, textureBottomLeftBack);
            boxVertices[9]  = new MyVertexFormatPositionTexture3(bottomLeftBack, textureBottomLeftBack);
            boxVertices[10] = new MyVertexFormatPositionTexture3(topRightBack, textureTopRightBack);
            boxVertices[11] = new MyVertexFormatPositionTexture3(bottomRightBack, textureBottomRightBack);

            // Top face.
            boxVertices[12] = new MyVertexFormatPositionTexture3(topLeftFront, textureTopLeftFront);
            boxVertices[13] = new MyVertexFormatPositionTexture3(topRightBack, textureTopRightBack);
            boxVertices[14] = new MyVertexFormatPositionTexture3(topLeftBack, textureTopLeftBack);
            boxVertices[15] = new MyVertexFormatPositionTexture3(topLeftFront, textureTopLeftFront);
            boxVertices[16] = new MyVertexFormatPositionTexture3(topRightFront, textureTopRightFront);
            boxVertices[17] = new MyVertexFormatPositionTexture3(topRightBack, textureTopRightBack);

            // Bottom face.
            boxVertices[18] = new MyVertexFormatPositionTexture3(bottomLeftFront, textureBottomLeftFront);
            boxVertices[19] = new MyVertexFormatPositionTexture3(bottomLeftBack, textureBottomLeftBack);
            boxVertices[20] = new MyVertexFormatPositionTexture3(bottomRightBack, textureBottomRightBack);
            boxVertices[21] = new MyVertexFormatPositionTexture3(bottomLeftFront, textureBottomLeftFront);
            boxVertices[22] = new MyVertexFormatPositionTexture3(bottomRightBack, textureBottomRightBack);
            boxVertices[23] = new MyVertexFormatPositionTexture3(bottomRightFront, textureBottomRightFront);

            // Left face.
            boxVertices[24] = new MyVertexFormatPositionTexture3(topLeftFront, textureTopLeftFront);
            boxVertices[25] = new MyVertexFormatPositionTexture3(bottomLeftBack, textureBottomLeftBack);
            boxVertices[26] = new MyVertexFormatPositionTexture3(bottomLeftFront, textureBottomLeftFront);
            boxVertices[27] = new MyVertexFormatPositionTexture3(topLeftBack, textureTopLeftBack);
            boxVertices[28] = new MyVertexFormatPositionTexture3(bottomLeftBack, textureBottomLeftBack);
            boxVertices[29] = new MyVertexFormatPositionTexture3(topLeftFront, textureTopLeftFront);

            // Right face.
            boxVertices[30] = new MyVertexFormatPositionTexture3(topRightFront, textureTopRightFront);
            boxVertices[31] = new MyVertexFormatPositionTexture3(bottomRightFront, textureBottomRightFront);
            boxVertices[32] = new MyVertexFormatPositionTexture3(bottomRightBack, textureBottomRightBack);
            boxVertices[33] = new MyVertexFormatPositionTexture3(topRightBack, textureTopRightBack);
            boxVertices[34] = new MyVertexFormatPositionTexture3(topRightFront, textureTopRightFront);
            boxVertices[35] = new MyVertexFormatPositionTexture3(bottomRightBack, textureBottomRightBack);

            // if we've loaded the cube from DDS, orient it towards the sun
            var sun   = MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized();
            var toSun = new Quaternion(Vector3.Cross(Vector3.UnitX, sun), Vector3.Dot(Vector3.UnitX, sun));  // default orientation is +x

            toSun.Normalize();
            for (int i = 0; i < boxVertices.Length; i++)
            {
                boxVertices[i].Position = Vector3.Transform(boxVertices[i].Position, toSun);
            }

            m_boxVertexBuffer = new VertexBuffer(MyMinerGame.Static.GraphicsDevice, MyVertexFormatPositionTexture3.Stride * boxVertices.Length, Usage.WriteOnly, VertexFormat.None, Pool.Default);
            m_boxVertexBuffer.Lock(0, 0, LockFlags.None).WriteRange(boxVertices);
            m_boxVertexBuffer.Unlock();
            m_boxVertexBuffer.DebugName = "BackgroundCube";

            m_loaded = true;
        }
Example #26
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            if (bot.Leader != null)
            {
                if (ShouldFallAsleep(bot))
                {
                    bot.IsSleeping = true;
                    return;
                }

                Vector3 leaderToBot             = bot.GetPosition() - bot.Leader.GetPosition();
                Vector3 formationPositionActual = bot.Leader.GetFormationPosition(bot);
                Vector3 botToFormationPosition  = formationPositionActual - bot.GetPosition();

                float leaderDistance            = leaderToBot.Length();
                float formationPositionDistance = botToFormationPosition.Length();

                Vector3 flyTo;
                if (formationPositionDistance > MyMwcMathConstants.EPSILON_SQUARED && leaderDistance > MyMwcMathConstants.EPSILON)
                {
                    float leaderFactor = MathHelper.Clamp(leaderDistance - 5, 0, 25) / 20;
                    flyTo = (1.0f - leaderFactor) * leaderToBot / leaderDistance + leaderFactor * botToFormationPosition / formationPositionDistance;
                    flyTo = MyMwcUtils.Normalize(flyTo);
                    flyTo = bot.GetPosition() + flyTo * formationPositionDistance;

                    // Update leader visibility
                    if (visibilityCheckTimer <= 0)
                    {
                        MyLine line = new MyLine(bot.GetPosition(), formationPositionActual, true);
                        leaderVisible = !MyEntities.GetIntersectionWithLine(ref line, bot, bot.Leader, true, ignoreSmallShips: true).HasValue;

                        visibilityCheckTimer = 0.5f;
                    }
                    else
                    {
                        visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                    }
                }
                else
                {
                    // Bot is on formation position
                    flyTo         = bot.GetPosition() + bot.WorldMatrix.Forward;
                    leaderVisible = true;
                }

                if (leaderVisible)
                {
                    bool    afterburner = /*bot.Leader.IsAfterburnerOn() || */ formationPositionDistance > AFTERBURNER_DISTANCE;
                    Vector3 lookTarget  = formationPositionDistance < LOOK_DISTANCE ? formationPositionActual + bot.Leader.WorldMatrix.Forward * 5000 : formationPositionActual;

                    float factor = MathHelper.Clamp(formationPositionDistance / 200, 0.5f, 1.0f);

                    factor = factor * factor * factor;

                    bot.Move(flyTo, lookTarget, bot.Leader.WorldMatrix.Up, afterburner, 1, 25, factor, slowRotation: true);

                    checkTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

                    findSmallship.Init(bot);
                }
                else
                {
                    if (leaderDistance > MIN_LEADER_DISTANCE)
                    {
                        findSmallship.Update(bot, bot.Leader);

                        if (findSmallship.PathNotFound)
                        {
                            //We dont want our friends sleeping elsewhere
                            //  bot.IsSleeping = true;
                        }
                    }
                }
            }
        }
Example #27
0
        public static void Update()
        {
            //TODO: use only for profiling

            /*
             * long startTime;
             * MyWindowsAPIWrapper.QueryPerformanceCounter(out startTime);
             */

            bool renderEnviromentMaps = MyRender.EnableLights && MyRender.EnableLightsRuntime && MyRender.EnableSun && (MyRender.EnableEnvironmentMapAmbient || MyRender.EnableEnvironmentMapReflection);

            if (!renderEnviromentMaps)
            {
                return;
            }

            if (BlendDistance > MainMapMaxDistance)
            {
                throw new InvalidOperationException("BlendDistance must be lower than MainMapMaxDistance");
            }

            MyRender.RenderOcclusionsImmediatelly = true;

            Vector3 cameraPos = MyCamera.Position;

            if (MainMapPosition.HasValue && (cameraPos - MainMapPosition.Value).Length() > InstantRefreshDistance)
            {
                m_renderInstantly = true;
            }

            // Makes evironment camera pos 300m in front of real camera
            //cameraPos += Vector3.Normalize(MyCamera.ForwardVector) * 300

            if (MainMapPosition == null)
            {
                LastUpdateTime  = 0;
                MainMapPosition = cameraPos;
                m_environmentMapRendererMain.StartUpdate(MainMapPosition.Value, m_renderInstantly);
                m_renderInstantly = false;

                BlendFactor = 0.0f;
            }
            else
            {
                float mainMapDistance = (MainMapPosition.Value - cameraPos).Length();

                // When behind blend distance
                if (mainMapDistance > BlendDistance)
                {
                    // Create AuxMap if not created
                    if (AuxMapPosition == null)
                    {
                        LastUpdateTime = 0;
                        AuxMapPosition = cameraPos;
                        m_environmentMapRendererAux.StartUpdate(AuxMapPosition.Value, m_renderInstantly);
                        m_renderInstantly = false;
                    }

                    // Wait till rendering done before blending
                    if (m_environmentMapRendererAux.IsDone())
                    {
                        // Set proper blend factor
                        BlendFactor = (mainMapDistance - BlendDistance) / (MainMapMaxDistance - BlendDistance);
                    }
                }
                else if ((mainMapDistance + Hysteresis) < BlendDistance)
                {
                    AuxMapPosition = null;
                }

                // If MainMap should not be even displayed...swap aux and main and display
                if (mainMapDistance > MainMapMaxDistance && m_environmentMapRendererAux.IsDone())
                {
                    var tmp = m_environmentMapRendererAux;
                    m_environmentMapRendererAux  = m_environmentMapRendererMain;
                    m_environmentMapRendererMain = tmp;
                    MainMapPosition = cameraPos + MyMwcUtils.Normalize(MainMapPosition.Value - cameraPos) * BlendDistance;
                    AuxMapPosition  = null;
                    BlendFactor     = 0.0f;
                }
            }

            m_environmentMapRendererMain.ContinueUpdate();
            m_environmentMapRendererAux.ContinueUpdate();

            MyRender.RenderOcclusionsImmediatelly = false;

            /*
             * long frq;
             * MyWindowsAPIWrapper.QueryPerformanceFrequency(out frq);
             *
             * long stopTime;
             * MyWindowsAPIWrapper.QueryPerformanceCounter(out stopTime);
             *
             * float updateTime = ((float)(stopTime - startTime)) / frq * 1000.0f;
             * if(updateTime > LastUpdateTime)
             * {
             *  LastUpdateTime = updateTime;
             * }
             * */
        }
        private void UpdateParticlesLife()
        {
            int counter = 0;

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("ParticleGeneration-UpdateParticlesLife");

            MyParticleGeneration inheritedGeneration = null;
            Vector3 previousParticlePosition         = m_effect.WorldMatrix.Translation;
            float   particlesToCreate = 0;

            m_AABB = m_AABB.CreateInvalid();
            m_AABB = m_AABB.Include(ref previousParticlePosition);

            if (OnDie.GetValue <int>() != -1)
            {
                inheritedGeneration = GetInheritedGeneration(OnDie.GetValue <int>());

                if (inheritedGeneration == null)
                {
                    OnDie.SetValue(-1);
                }
                else
                {
                    inheritedGeneration.IsInherited = true;
                    particlesToCreate = inheritedGeneration.m_particlesToCreate;
                }
            }

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

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("ParticleGeneration-Update01");

            Vector3 previousTrail0 = previousParticlePosition;
            Vector3 previousTrail1 = previousParticlePosition;

            using (ParticlesLock.AcquireExclusiveUsing())
            {
                while (counter < m_particles.Count)
                {
                    float motionInheritance;
                    MotionInheritance.GetInterpolatedValue(m_effect.GetElapsedTime(), out motionInheritance);

                    MyAnimatedParticle particle = m_particles[counter];

                    if (motionInheritance > 0)
                    {
                        m_effect.CalculateDeltaMatrix = true;
                    }

                    if (particle.Update())
                    {
                        if (motionInheritance > 0)
                        {
                            particle.AddMotionInheritance(ref motionInheritance, ref m_effect.DeltaMatrix);
                        }

                        if (counter == 0)
                        {
                            previousParticlePosition = particle.ActualPosition;
                            previousTrail0           = particle.Quad.Point1;
                            previousTrail1           = particle.Quad.Point2;
                            particle.Quad.Point0     = particle.ActualPosition;
                            particle.Quad.Point2     = particle.ActualPosition;
                        }

                        counter++;


                        if (particle.Type == MyParticleTypeEnum.Trail)
                        {
                            if (particle.ActualPosition == previousParticlePosition)
                            {
                                particle.Quad.Point0 = particle.ActualPosition;
                                particle.Quad.Point1 = particle.ActualPosition;
                                particle.Quad.Point2 = particle.ActualPosition;
                                particle.Quad.Point3 = particle.ActualPosition;
                            }
                            else
                            {
                                MyPolyLine polyLine = new MyPolyLine();
                                polyLine.Thickness = particle.Thickness;
                                polyLine.Point0    = particle.ActualPosition;
                                polyLine.Point1    = previousParticlePosition;

                                Vector3 direction           = polyLine.Point1 - polyLine.Point0;
                                Vector3 normalizedDirection = MyMwcUtils.Normalize(polyLine.Point1 - polyLine.Point0);


                                polyLine.Point1 = polyLine.Point0 + (polyLine.Point1 - polyLine.Point0);

                                polyLine.LineDirectionNormalized = normalizedDirection;
                                MyUtils.GetPolyLineQuad(out particle.Quad, ref polyLine);

                                particle.Quad.Point0 = previousTrail0 + direction * 0.15f;
                                particle.Quad.Point3 = previousTrail1 + direction * 0.15f;
                                previousTrail0       = particle.Quad.Point1;
                                previousTrail1       = particle.Quad.Point2;
                            }
                        }

                        previousParticlePosition = particle.ActualPosition;

                        m_AABB         = m_AABB.Include(ref previousParticlePosition);
                        particle.Flags = GetEffect().IsInFrustum ? particle.Flags | MyAnimatedParticle.ParticleFlags.IsInFrustum : particle.Flags & ~MyAnimatedParticle.ParticleFlags.IsInFrustum;
                        continue;
                    }

                    if (inheritedGeneration != null)
                    {
                        inheritedGeneration.m_particlesToCreate = particlesToCreate;
                        inheritedGeneration.EffectMatrix        = Matrix.CreateWorld(particle.ActualPosition, Vector3.Normalize(particle.Velocity), Vector3.Cross(Vector3.Left, particle.Velocity));
                        inheritedGeneration.UpdateParticlesCreation();
                    }

                    m_particles.Remove(particle);
                    MyTransparentGeometry.DeallocateAnimatedParticle(particle);
                }
            }

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
        }
        //  Update position, check collisions, etc. and draw if particle still lives.
        //  Return false if particle dies/timeouts in this tick.
        public bool Draw(MyBillboard billboard)
        {
            MyTransparentGeometry.StartParticleProfilingBlock("Distance calculation");
            //  This time is scaled according to planned lifespan of the particle

            // Distance for sorting
            Vector3 campos = MyCamera.Position;

            Vector3.DistanceSquared(ref campos, ref m_actualPosition, out billboard.DistanceSquared);

            MyTransparentGeometry.EndParticleProfilingBlock();

            // If distance to camera is really small don't draw it.
            if (billboard.DistanceSquared <= 1)
            {
                return(false);
            }

            MyTransparentGeometry.StartParticleProfilingBlock("Quad calculation");

            MyTransparentGeometry.StartParticleProfilingBlock("actualRadius");
            float actualRadius = 1;

            Radius.GetInterpolatedValue <float>(m_normalizedTime, out actualRadius);
            MyTransparentGeometry.EndParticleProfilingBlock();

            billboard.ContainedBillboards.Clear();

            billboard.Near   = m_generation.GetEffect().Near;
            billboard.Lowres = m_generation.GetEffect().LowRes || MyRenderConstants.RenderQualityProfile.LowResParticles;

            float alpha = 1;

            if (Type == MyParticleTypeEnum.Point)
            {
                MyTransparentGeometry.StartParticleProfilingBlock("GetBillboardQuadRotated");
                MyUtils.GetBillboardQuadRotated(billboard, ref m_actualPosition, actualRadius, m_actualAngle);
                MyTransparentGeometry.EndParticleProfilingBlock();
            }
            else if (Type == MyParticleTypeEnum.Line)
            {
                if (MyMwcUtils.IsZero(Velocity.LengthSquared()))
                {
                    Velocity = MyMwcUtils.GetRandomVector3Normalized();
                }

                MyQuad quad = new MyQuad();

                MyPolyLine polyLine = new MyPolyLine();
                polyLine.LineDirectionNormalized = MyMwcUtils.Normalize(Velocity);

                if (m_actualAngle > 0)
                {
                    polyLine.LineDirectionNormalized = Vector3.TransformNormal(polyLine.LineDirectionNormalized, Matrix.CreateRotationY(MathHelper.ToRadians(m_actualAngle)));
                }

                polyLine.Point0   = m_actualPosition;
                polyLine.Point1.X = m_actualPosition.X + polyLine.LineDirectionNormalized.X * actualRadius;
                polyLine.Point1.Y = m_actualPosition.Y + polyLine.LineDirectionNormalized.Y * actualRadius;
                polyLine.Point1.Z = m_actualPosition.Z + polyLine.LineDirectionNormalized.Z * actualRadius;

                if (m_actualAngle > 0)
                { //centerize
                    polyLine.Point0.X = polyLine.Point0.X - polyLine.LineDirectionNormalized.X * actualRadius * 0.5f;
                    polyLine.Point0.Y = polyLine.Point0.Y - polyLine.LineDirectionNormalized.Y * actualRadius * 0.5f;
                    polyLine.Point0.Z = polyLine.Point0.Z - polyLine.LineDirectionNormalized.Z * actualRadius * 0.5f;
                    polyLine.Point1.X = polyLine.Point1.X - polyLine.LineDirectionNormalized.X * actualRadius * 0.5f;
                    polyLine.Point1.Y = polyLine.Point1.Y - polyLine.LineDirectionNormalized.Y * actualRadius * 0.5f;
                    polyLine.Point1.Z = polyLine.Point1.Z - polyLine.LineDirectionNormalized.Z * actualRadius * 0.5f;
                }

                polyLine.Thickness = Thickness;
                MyUtils.GetPolyLineQuad(out quad, ref polyLine);

                if (this.m_generation.AlphaAnisotropic)
                {
                    float angle     = 1 - Math.Abs(Vector3.Dot(MyMwcUtils.Normalize(MyCamera.ForwardVector), polyLine.LineDirectionNormalized));
                    float alphaCone = (float)Math.Pow(angle, 0.5f);
                    alpha = alphaCone;
                }

                billboard.Position0 = quad.Point0;
                billboard.Position1 = quad.Point1;
                billboard.Position2 = quad.Point2;
                billboard.Position3 = quad.Point3;
            }
            else if (Type == MyParticleTypeEnum.Trail)
            {
                if (Quad.Point0 == Quad.Point2) //not moving particle
                {
                    return(false);
                }
                if (Quad.Point1 == Quad.Point3) //not moving particle was previous one
                {
                    return(false);
                }
                if (Quad.Point0 == Quad.Point3) //not moving particle was previous one
                {
                    return(false);
                }

                billboard.Position0 = Quad.Point0;
                billboard.Position1 = Quad.Point1;
                billboard.Position2 = Quad.Point2;
                billboard.Position3 = Quad.Point3;

                //if (this.m_generation.AlphaAnisotropic)

                /*   { //Trails are anisotropic by default (nobody wants them to see ugly)
                 *     Vector3 lineDir = Vector3.Normalize(Quad.Point1 - Quad.Point0);
                 *     float angle = 1 - Math.Abs(Vector3.Dot(MyMwcUtils.Normalize(MyCamera.ForwardVector), lineDir));
                 *     float alphaCone = (float)Math.Pow(angle, 0.3f);
                 *     alpha = alphaCone;
                 * }*/
            }
            else
            {
                throw new NotSupportedException(Type + " is not supported particle type");
            }

            MyTransparentGeometry.EndParticleProfilingBlock();

            MyTransparentGeometry.StartParticleProfilingBlock("Material calculation");

            Vector4 color;

            Color.GetInterpolatedValue <Vector4>(m_normalizedTime, out color);

            int   material1         = (int)MyTransparentMaterialEnum.Test;
            int   material2         = (int)MyTransparentMaterialEnum.Test;
            float textureBlendRatio = 0;

            if ((Flags & ParticleFlags.BlendTextures) != 0)
            {
                float prevTime, nextTime, difference;
                Material.GetPreviousValue(m_normalizedTime, out material1, out prevTime);
                Material.GetNextValue(m_normalizedTime, out material2, out nextTime, out difference);

                if (prevTime != nextTime)
                {
                    textureBlendRatio = (m_normalizedTime - prevTime) * difference;
                }
            }
            else
            {
                Material.GetInterpolatedValue <int>(m_normalizedTime, out material1);
            }

            MyTransparentGeometry.EndParticleProfilingBlock();

            //This gets 0.44ms for 2000 particles
            MyTransparentGeometry.StartParticleProfilingBlock("billboard.Start");


            billboard.MaterialEnum      = (MyTransparentMaterialEnum)material1;
            billboard.BlendMaterial     = (MyTransparentMaterialEnum)material2;
            billboard.BlendTextureRatio = textureBlendRatio;
            billboard.EnableColorize    = false;

            billboard.Color = color * alpha * m_generation.GetEffect().UserColorMultiplier;

            MyTransparentGeometry.EndParticleProfilingBlock();

            return(true);
        }
        protected override bool Interact(bool staticCollision)
        {
            if (!staticCollision && GetRigidBody1().IsStatic() && GetRigidBody2().IsStatic())
            {
                return(false);
            }

            MyRBBoxElement    box    = null;
            MyRBSphereElement sphere = null;

            if (RBElement1.GetElementType() == MyRBElementType.ET_BOX)
            {
                SwapElements();
            }

            box    = (MyRBBoxElement)RBElement2;
            sphere = (MyRBSphereElement)RBElement1;

            Matrix  boxMatrix    = box.GetGlobalTransformation();
            Vector3 sphereCenter = sphere.GetGlobalTransformation().Translation;

            Matrix invBoxMatrix = Matrix.Invert(boxMatrix);

            Vector3 boxLocalsphereCenter = Vector3.Transform(sphereCenter, invBoxMatrix);

            bool    penetration = false;
            Vector3 normal      = new Vector3();
            Vector3 closestPos  = new Vector3();
            uint    customData  = 0;

            box.GetClosestPoint(boxLocalsphereCenter, ref closestPos, ref normal, ref penetration, ref customData);

            closestPos = Vector3.Transform(closestPos, boxMatrix);

            normal = -Vector3.TransformNormal(normal, boxMatrix);
            normal = MyMwcUtils.Normalize(normal);

            float vLength = (sphereCenter - closestPos).Length();

            if (staticCollision)
            {
                return(vLength > 0 && vLength < sphere.Radius);
            }
            else
            {
                float eps = MyPhysics.physicsSystem.GetRigidBodyModule().CollisionEpsilon;
                float dt  = MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep;

                Vector3 pointVelocity1 = new Vector3();
                Vector3 pointVelocity2 = new Vector3();

                GetRigidBody1().GetGlobalPointVelocity(ref closestPos, out pointVelocity1);
                GetRigidBody2().GetGlobalPointVelocity(ref closestPos, out pointVelocity2);

                float dynEps = 0;
                if (vLength >= eps)
                {
                    float dot = Vector3.Dot(pointVelocity1 - pointVelocity2, normal) * dt;
                    if (dot >= 0)
                    {
                        dynEps = dot;
                    }
                }

                float radius = sphere.Radius;

                //Second part of condition commented due to 5968: Bug B - rocket passing through prefab
                //Does not seem to have any reason to be there
                if (vLength > 0 /*&& vLength < (radius + eps + dynEps)*/)
                {
                    float error = vLength - (radius + 0.5f * eps);
                    //error = System.Math.Min(error, eps);

                    MySmallCollPointInfo[] collInfo = MyContactInfoCache.SCPIStackAlloc();

                    collInfo[0] = new MySmallCollPointInfo(closestPos - sphereCenter, closestPos - boxMatrix.Translation, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, normal, error, closestPos);

                    MyPhysics.physicsSystem.GetContactConstraintModule().AddContactConstraint(this, collInfo, 1);

                    MyContactInfoCache.FreeStackAlloc(collInfo);
                }
            }
            return(false);
        }