コード例 #1
0
        private static Vector3 GetDirection(Vector3 position, Vector3 sphereCenter)
        {
            Vector3 dist = position - sphereCenter;

            if (MyUtils.IsValid(dist) && MyMwcUtils.HasValidLength(dist))
            {
                return(Vector3.Normalize(dist));
            }
            else
            {
                return(MyMwcUtils.GetRandomVector3Normalized());
            }
        }
コード例 #2
0
ファイル: MyDecals.cs プロジェクト: whztt07/Miner-Wars-2081
        //  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);
            }
        }
コード例 #3
0
ファイル: MyMissile.cs プロジェクト: whztt07/Miner-Wars-2081
        /// <summary>
        /// Updates resource.
        /// </summary>
        public override void UpdateBeforeSimulation()
        {
            try
            {
                MyRender.GetRenderProfiler().StartProfilingBlock("MyMissile.UpdateBeforeSimulation");

                //Large ship weapons wont make bots curious
                if ((!(OwnerEntity is MyLargeShipMissileLauncherBarrel)) && MyMwcUtils.HasValidLength(this.WorldMatrix.Translation - m_previousPosition))
                {
                    MyLine line = new MyLine(this.WorldMatrix.Translation, m_previousPosition);
                    MyDangerZones.Instance.Notify(line, OwnerEntity);
                }

                if (m_isExploded)
                {
                    //  Create explosion
                    MyExplosion newExplosion = MyExplosions.AddExplosion();
                    if (newExplosion != null)
                    {
                        float radius = m_ammoProperties.ExplosionRadius;

                        // Explicitly on Marek's request (ticket 4740)
                        bool amplifyRadius = m_collidedEntity != null?MyFactions.GetFactionsRelation(m_collidedEntity.Faction, Faction) != MyFactionRelationEnum.Friend : false;

                        if (amplifyRadius)
                        {
                            radius *= 2;
                        }

                        BoundingSphere explosionSphere = new BoundingSphere(m_collisionPoint.HasValue ? m_collisionPoint.Value : GetPosition(), radius);

                        //  Call main explosion starter
                        MyExplosionInfo info = new MyExplosionInfo()
                        {
                            PlayerDamage            = m_ammoProperties.HealthDamage,
                            Damage                  = m_ammoProperties.ShipDamage,
                            EmpDamage               = m_ammoProperties.EMPDamage,
                            ExplosionType           = m_explosionType,
                            ExplosionSphere         = explosionSphere,
                            LifespanMiliseconds     = MyExplosionsConstants.EXPLOSION_LIFESPAN,
                            ExplosionForceDirection = MyExplosionForceDirection.EXPLOSION,
                            GroupMask               = Physics.GroupMask,
                            CascadeLevel            = CascadedExplosionLevel,
                            HitEntity               = m_collidedEntity,
                            ParticleScale           = 1.5f,
                            OwnerEntity             = this.OwnerEntity,
                            Direction               = WorldMatrix.Forward,
                            VoxelExplosionCenter    = explosionSphere.Center + m_ammoProperties.ExplosionRadius * WorldMatrix.Forward * 0.5f,
                            ExplosionFlags          = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT,
                            VoxelCutoutScale        = amplifyRadius ? 0.5f : 1.0f,
                            PlaySound               = true,
                        };

                        newExplosion.Start(ref info);
                    }

                    if (m_collidedEntity != null && !m_collidedEntity.IsExploded())
                    {
                        m_collidedEntity.Physics.AddForce(
                            MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE,
                            WorldMatrix.Forward * MyMissileConstants.HIT_STRENGTH_IMPULSE,
                            GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 2,
                            MyMissileConstants.HIT_STRENGTH_IMPULSE * MyMwcUtils.GetRandomVector3Normalized());
                        m_collidedEntity.OnClose -= m_collidedEntity_OnClose;
                    }

                    MarkForClose();

                    return;
                }

                bool firstTargetting = m_elapsedMiliseconds == 0;

                base.UpdateBeforeSimulation();

                m_missileTargetUpdate += MyConstants.PHYSICS_STEP_SIZE_IN_MILLISECONDS;

                if (m_missileTargetUpdate >= MyGuidedMissileConstants.MISSILE_TARGET_UPDATE_INTERVAL_IN_MS || firstTargetting)
                {
                    m_missileTargetUpdate = 0;

                    switch (m_missileType)
                    {
                    case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Radar_Detection:
                    {
                        MySmallShip targetShip = m_targetEntity as MySmallShip;
                        if (targetShip != null && targetShip.IsRadarJammed())
                        {
                            m_targetEntity = null;
                        }
                    }
                    break;

                    case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Engine_Detection:
                    {
                        m_targetEntities.Clear();

                        Matrix proj = Matrix.CreateOrthographic(MyGuidedMissileConstants.ENGINE_GUIDED_MISSILE_RADIUS, MyGuidedMissileConstants.ENGINE_GUIDED_MISSILE_RADIUS, 0, 1000);
                        Matrix view = Matrix.CreateLookAt(GetPosition(), GetPosition() + WorldMatrix.Forward, WorldMatrix.Up);
                        m_visualFrustum.Matrix = view * proj;

                        MyEntities.GetAllIntersectionWithBoundingFrustum(ref m_visualFrustum, m_targetEntities);

                        if (m_targetEntities.Contains(m_targetEntity))
                        {
                            break;
                        }

                        MyEntity target = null;
                        float    closestToMissileDirection = float.MaxValue;

                        foreach (MyEntity entity in m_targetEntities)
                        {
                            if (CanTarget(entity))
                            {
                                MySmallShip targetShip = entity as MySmallShip;
                                if (targetShip != null)
                                {
                                    if ((targetShip.IsEngineTurnedOff()))
                                    {
                                        continue;
                                    }
                                }

                                Vector3 targetPos     = entity.GetPosition();
                                Vector3 missilePos    = this.GetPosition();
                                Vector3 missilePosEnd = this.GetPosition() + this.WorldMatrix.Forward * 10000;
                                Vector3 closestPos    = MyUtils.GetClosestPointOnLine(ref missilePos, ref missilePosEnd, ref targetPos);

                                float distance = Vector3.Distance(closestPos, targetPos);
                                if (distance < closestToMissileDirection)
                                {
                                    closestToMissileDirection = distance;
                                    target = entity;
                                }
                            }
                        }

                        UpdateTarget(target);
                    }
                    break;

                    case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Visual_Detection:
                    {
                        Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(MyGuidedMissileConstants.VISUAL_GUIDED_MISSILE_FOV), 1, 10, MyGuidedMissileConstants.VISUAL_GUIDED_MISSILE_RANGE);
                        m_visualFrustum.Matrix = Matrix.Invert(WorldMatrix) * projectionMatrix;

                        m_targetEntities.Clear();
                        MyEntities.GetAllIntersectionWithBoundingFrustum(ref m_visualFrustum, m_targetEntities);
                        int testsLimit = 8;

                        if (m_targetEntities.Contains(m_targetEntity))
                        {
                            break;
                        }

                        MyEntity target = null;         //looks better if missile gets "lost"

                        float closestToMissileDirection = float.MaxValue;

                        foreach (MyEntity entity in m_targetEntities)
                        {
                            if (!CanTarget(entity))
                            {
                                continue;
                            }

                            if (testsLimit-- == 0)
                            {
                                break;
                            }

                            if (MyEnemyTargeting.CanSee(this, entity) == null)
                            {
                                Vector3 targetPos     = entity.GetPosition();
                                Vector3 missilePos    = this.GetPosition();
                                Vector3 missilePosEnd = this.GetPosition() + this.WorldMatrix.Forward * 10000;
                                Vector3 closestPos    = MyUtils.GetClosestPointOnLine(ref missilePos, ref missilePosEnd, ref targetPos);

                                float distance = Vector3.Distance(closestPos, targetPos);
                                if (distance < closestToMissileDirection)
                                {
                                    closestToMissileDirection = distance;
                                    target = entity;
                                }
                            }
                        }

                        UpdateTarget(target);
                    }
                    break;
                    }
                }

                if ((m_initTime - m_elapsedMiliseconds) > 0)
                {   //simulating missile launch and engine ignition
                    MyEntity owner = OwnerEntity;
                    if (owner != null)
                    {
                        Vector3 transformedInitDir = Vector3.TransformNormal(m_initDir, owner.WorldMatrix); //
                        Vector3 initialVelocity    = Vector3.Zero;
                        if (owner.Physics != null)
                        {
                            initialVelocity = owner.Physics.LinearVelocity;
                        }
                        Physics.LinearVelocity = transformedInitDir * m_ammoProperties.InitialSpeed + initialVelocity;
                    }
                }
                else
                {
                    //  This will help blend "initial velocity" and "thrust velocity" so at the beginning missile is powered by initiatal velocity only, but later
                    float velocityBlend = MathHelper.Clamp((float)(m_elapsedMiliseconds - m_initTime) / m_blendVelocities, 0, 1);

                    if (velocityBlend == 1.0f)
                    {
                        m_actualSpeed = m_ammoProperties.DesiredSpeed;
                    }
                    else
                    {
                        float    initialSpeed = 0.0f;
                        MyEntity owner        = OwnerEntity;
                        if (owner != null)
                        {
                            if (owner.Physics != null)
                            {
                                initialSpeed = owner.Physics.LinearVelocity.Length();
                            }
                        }

                        m_actualSpeed = velocityBlend * m_ammoProperties.DesiredSpeed + ((1.0f - velocityBlend) * (m_ammoProperties.InitialSpeed + initialSpeed));

                        if (m_missileType != MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Missile_Basic && m_smokeEffect == null)
                        {
                            // if (MyCamera.GetDistanceWithFOV(GetPosition()) < 150)
                            {
                                /*
                                 * MyParticleEffect startEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_MissileStart);
                                 * startEffect.WorldMatrix = WorldMatrix;
                                 */
                                m_smokeEffect             = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Missile);
                                m_smokeEffect.WorldMatrix = WorldMatrix;
                                m_smokeEffect.AutoDelete  = false;
                            }
                        }
                    }

                    m_desiredVelocity = GetDesiredVelocity(m_targetEntity);

                    Physics.LinearVelocity = m_desiredVelocity * m_actualSpeed * 1.0f;
                }

                Physics.AngularVelocity = Vector3.Zero;

                if ((m_elapsedMiliseconds > m_missileTimeout) || (Vector3.Distance(GetPosition(), m_origin) >= m_maxTrajectory))
                {
                    Explode();
                    return;
                }


                if (m_smokeEffect != null)
                {
                    Matrix smokeMatrix = Matrix.CreateWorld(WorldMatrix.Translation - 0.5f * WorldMatrix.Forward, WorldMatrix.Forward, WorldMatrix.Up);
                    m_smokeEffect.WorldMatrix = smokeMatrix;
                }

                if (m_targetEntity != null)
                {
                    if (m_targetEntity.Physics != null)
                    {
                        m_targetVelocity = m_targetEntity.Physics.LinearVelocity;
                    }
                    else
                    {
                        m_targetVelocity = Vector3.Zero;
                    }
                }
            }
            finally
            {
                MyRender.GetRenderProfiler().EndProfilingBlock();
            }
        }