// Liang-Barsky line clipping. Return true if the line isn't completely clipped.
        static bool ClipLine(ref Vector3 start, ref Vector3 end, MyMwcVector3Int min, MyMwcVector3Int max)
        {
            Vector3 dir = end - start;

            if (MyMwcUtils.IsZero(dir))
            {
                return(IsPointInside(start, min, max));
            }
            float tE = 0, tL = 1;

            if (IntersectionT(min.X - start.X, dir.X, ref tE, ref tL) && IntersectionT(start.X - max.X - 1, -dir.X, ref tE, ref tL) &&
                IntersectionT(min.Y - start.Y, dir.Y, ref tE, ref tL) && IntersectionT(start.Y - max.Y - 1, -dir.Y, ref tE, ref tL) &&
                IntersectionT(min.Z - start.Z, dir.Z, ref tE, ref tL) && IntersectionT(start.Z - max.Z - 1, -dir.Z, ref tE, ref tL))
            {
                if (tL < 1)
                {
                    end = start + tL * dir;
                }
                if (tE > 0)
                {
                    start += tE * dir;
                }
                return(true);
            }
            return(false);
        }
        public void AddShake(float shakePower)
        {
            if (MyFakes.DISABLE_CAMERA_HEADSHAKE)
            {
                return;
            }

            if (MyMwcUtils.IsZero(shakePower))
            {
                return;
            }

            if (MyMwcUtils.IsZero(m_MaxShake))
            {
                return;
            }

            float pow = (shakePower / m_MaxShake);

            //MyMwcLog.WriteLine(pow.ToString());

            if (m_CurrentShakePosPower < pow)
            {
                m_CurrentShakePosPower = pow;
            }
            if (m_CurrentShakeDirPower < pow * m_DirReduction)
            {
                m_CurrentShakeDirPower = pow * m_DirReduction;
            }

            m_ShakePos = new Vector3(m_CurrentShakePosPower * m_MaxShakePos, m_CurrentShakePosPower * m_MaxShakePos, m_CurrentShakePosPower * m_MaxShakePos);
            m_ShakeDir = new Vector3(m_CurrentShakeDirPower * m_MaxShakeDir, 0.0f, m_CurrentShakeDirPower * m_MaxShakeDir);

            m_Shake = true;
        }
        static bool IntersectionT(float n, float d, ref float tE, ref float tL)
        {
            if (MyMwcUtils.IsZero(d))
            {
                return(n <= 0);
            }
            float t = n / d;

            if (d > 0)
            {
                if (t > tL)
                {
                    return(false);
                }
                if (t > tE)
                {
                    tE = t;
                }
            }
            else
            {
                if (t < tE)
                {
                    return(false);
                }
                if (t < tL)
                {
                    tL = t;
                }
            }
            return(true);
        }
Esempio n. 4
0
        /// <summary>
        /// Applies external force to the physics object.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="force">The force.</param>
        /// <param name="position">The position.</param>
        /// <param name="torque">The torque.</param>
        public void AddForce(MyPhysicsForceType type, Vector3?force, Vector3?position, Vector3?torque)
        {
            MyUtils.AssertIsValid(force);
            MyUtils.AssertIsValid(position);
            MyUtils.AssertIsValid(torque);

            switch (type)
            {
            case MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE:
            {
                Matrix tempM = rigidBody.Matrix;
                tempM.Translation = Vector3.Zero;

                if (force != null && !MyMwcUtils.IsZero(force.Value))
                {
                    Vector3 tmpForce = Vector3.Transform(force.Value, tempM);

                    this.rigidBody.ApplyForce(tmpForce);
                }

                if (torque != null && !MyMwcUtils.IsZero(torque.Value))
                {
                    Vector3 tmpTorque = Vector3.Transform(torque.Value, tempM);

                    this.rigidBody.ApplyTorque(tmpTorque);
                }
            }
            break;

            case MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE:
            {
                if (force.HasValue && position.HasValue)
                {
                    this.rigidBody.ApplyImpulse(force.Value, position.Value);
                }

                if (torque.HasValue)
                {
                    this.rigidBody.ApplyTorque(torque.Value);
                }
            }
            break;

            default:
            {
                Debug.Fail("Unhandled enum!");
            }
            break;
            }
        }
Esempio n. 5
0
        public static float AngleBetween(Vector3 a, Vector3 b)
        {
            var dotProd      = Vector3.Dot(a, b);
            var lenProd      = a.Length() * b.Length();
            var divOperation = dotProd / lenProd;

            if (MyMwcUtils.IsZero(1.0f - divOperation))
            {
                return(0);
            }
            else
            {
                return((float)(Math.Acos(divOperation)));
            }
        }
Esempio n. 6
0
        private void SetAngularVelocity(Vector3 vel)
        {
            MinerWars.AppCode.Game.Utils.MyUtils.AssertIsValid(vel);

            if (ReadFlag(RigidBodyFlag.RBF_KINEMATIC) || ReadFlag(RigidBodyFlag.RBF_RBO_STATIC))
            {
                return;
            }

            if (MyMwcUtils.IsZero(m_AngularVelocity - vel))
            {
                return;
            }

            m_AngularVelocity = vel;
            WakeUp();
        }
Esempio n. 7
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;
        }
        public static void Calculate(List <MyMwcVector3Int> result, float gridSize, Vector3 lineStart, Vector3 lineEnd, MyMwcVector3Int min, MyMwcVector3Int max)
        {
            var dir = lineEnd - lineStart;

            MyCommonDebugUtils.AssertDebug(MyUtils.IsValid(dir));

            // handle start==end
            Vector3 start = lineStart / gridSize;

            if (MyMwcUtils.IsZero(dir))
            {
                if (IsPointInside(start, min, max))
                {
                    result.Add(GetGridPoint(ref start, min, max));
                }
                return;
            }

            // start/end in grid coordinates: clip them to the bounding box, return if no intersection
            Vector3 end = lineEnd / gridSize;

            if (ClipLine(ref start, ref end, min, max) == false)
            {
                return;
            }


            // reflect coordinates so that dir is always positive
            Vector3 sign = Sign(dir); MyMwcVector3Int signInt = SignInt(dir);

            // current/final grid position
            MyMwcVector3Int cur   = GetGridPoint(ref start, min, max) * signInt;
            MyMwcVector3Int final = GetGridPoint(ref end, min, max) * signInt;

            dir   *= sign;
            start *= sign;

            // dx = increase of t when we increase x by 1
            // nextX = t of the next point on the line with x whole
            float dx = 1 / dir.X, nextX = dx * ((float)Math.Floor(start.X + 1) - start.X);
            float dy = 1 / dir.Y, nextY = dy * ((float)Math.Floor(start.Y + 1) - start.Y);
            float dz = 1 / dir.Z, nextZ = dz * ((float)Math.Floor(start.Z + 1) - start.Z);

            // 3D DDA
            while (true)
            {
                result.Add(cur * signInt);

                if (nextX < nextZ)
                {
                    if (nextX < nextY)
                    {
                        nextX += dx; if (++cur.X > final.X)
                        {
                            break;
                        }
                    }
                    else
                    {
                        nextY += dy; if (++cur.Y > final.Y)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    if (nextZ < nextY)
                    {
                        nextZ += dz; if (++cur.Z > final.Z)
                        {
                            break;
                        }
                    }
                    else
                    {
                        nextY += dy; if (++cur.Y > final.Y)
                        {
                            break;
                        }
                    }
                }
            }
        }
        //  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 EqualsValues(object value1, object value2)
 {
     return(MyMwcUtils.IsZero((Vector4)value1 - (Vector4)value2));
 }
Esempio n. 11
0
 public override Vector3 GetCenter()
 {
     //We agreed that everything in our solar area is in plane
     System.Diagnostics.Debug.Assert(MyMwcUtils.IsZero(OrbitProperties.AreaCenter.Y));
     return(OrbitProperties.AreaCenter);
 }