public void Move(SimulateMethodArgs args)
        {
            PhysicsScene  scene      = demo.Engine.Factory.PhysicsSceneManager.Get(args.OwnerSceneIndex);
            PhysicsObject objectBase = scene.Factory.PhysicsObjectManager.Get(args.OwnerIndex);

            float time = args.Time;

            if ((bodyUp == null) || (bodyDown == null) || (turretBodyUp == null) || (turretBodyDown == null) || (turretGun1 == null) || (turretGun2 == null) || (turretConstraint == null))
            {
                return;
            }

            totalTime += time;

            PhysicsObject turret = turretBodyUp.RigidGroupOwner;

            if (objectBase.IsBrokenRigidGroup || turret.IsBrokenRigidGroup || turretConstraint.IsBroken)
            {
                return;
            }

            Vector3 gravityDirection = vectorZero;
            Vector3 upObjectForce    = vectorZero;
            Vector3 upTurretForce    = vectorZero;
            Vector3 distance         = vectorZero;
            Vector3 direction        = vectorZero;

            scene.GetGravityDirection(ref gravityDirection);

            Vector3.Multiply(ref gravityDirection, -scene.GravityAcceleration * objectBase.Integral.Mass, out upObjectForce);
            Vector3.Multiply(ref gravityDirection, -scene.GravityAcceleration * turret.Integral.Mass, out upTurretForce);

            objectBase.WorldAccumulator.AddWorldForce(ref upObjectForce);
            turret.WorldAccumulator.AddWorldForce(ref upTurretForce);

            PhysicsObject amphibian1Body             = scene.Factory.PhysicsObjectManager.Find(amphibian1BodyName);
            PhysicsObject amphibian1TurretBodyDown   = scene.Factory.PhysicsObjectManager.Find(amphibian1TurretBodyDownName);
            Constraint    amphibian1TurretConstraint = scene.Factory.ConstraintManager.Find(amphibian1TurretConstraintName);
            Vector3       bodyDownPosition           = vectorZero;

            if ((amphibian1Body != null) && (amphibian1TurretBodyDown != null) && (amphibian1TurretConstraint != null) && !amphibian1Body.IsBrokenRigidGroup && !amphibian1TurretConstraint.IsBroken)
            {
                Vector3 amphibianTurretPosition = vectorZero;

                amphibian1TurretBodyDown.RigidGroupOwner.MainWorldTransform.GetPosition(ref amphibianTurretPosition);
                bodyDown.MainWorldTransform.GetPosition(ref bodyDownPosition);

                Vector3.Subtract(ref amphibianTurretPosition, ref bodyDownPosition, out distance);
                Vector3.Normalize(ref distance, out direction);
            }

            Vector3 force = vectorZero;
            Vector3 right = vectorZero;

            Vector3.Cross(ref direction, ref unitY, out right);
            Vector3.Multiply(ref right, 100.0f, out right);

            if (frameCount < 200)
            {
                Vector3.Subtract(ref force, ref right, out force);
            }
            else
            {
                Vector3.Add(ref force, ref right, out force);
            }

            if (frameCount > 400)
            {
                frameCount = 0;
            }

            if (distance.Length > 100.0f)
            {
                Vector3.Multiply(ref direction, 1000.0f, out right);
                Vector3.Add(ref force, ref right, out force);
            }

            if (distance.Y > 0.0f)
            {
                force.Y += distance.Y * 100.0f;
            }

            objectBase.WorldAccumulator.AddWorldForce(ref force);
            turret.WorldAccumulator.AddWorldForce(ref force);

            frameCount++;
            shotFrameCount++;

            Vector3 turretAxis        = vectorZero;
            Vector3 turretDirection   = vectorZero;
            Vector3 turretGunPosition = vectorZero;

            Vector3 turretBodyDownPosition = vectorZero;
            Vector3 turretGun1Position     = vectorZero;
            Vector3 turretGun2Position     = vectorZero;

            turretBodyDown.MainWorldTransform.GetPosition(ref turretBodyDownPosition);
            turretGun1.MainWorldTransform.GetPosition(ref turretGun1Position);
            turretGun2.MainWorldTransform.GetPosition(ref turretGun2Position);

            Vector3.Add(ref turretGun1Position, ref turretGun2Position, out turretGunPosition);
            Vector3.Multiply(ref turretGunPosition, 0.5f, out turretGunPosition);
            Vector3.Subtract(ref turretGunPosition, ref turretBodyDownPosition, out turretDirection);
            turretDirection.Normalize();
            Vector3.Cross(ref turretDirection, ref direction, out turretAxis);

            turretDirection.Y = 0.0f;
            direction.Y       = 0.0f;
            float turretAngle = 0.0f;

            Vector3.Dot(ref turretDirection, ref direction, out turretAngle);
            turretAngle = (float)Math.Acos(turretAngle);
            Vector3.Multiply(ref turretAxis, turretAngle, out turretAxis);

            Vector3 velocity = vectorZero;

            turret.MainWorldTransform.GetAngularVelocity(ref velocity);
            Vector3.Subtract(ref velocity, ref turretAxis, out velocity);
            turret.MainWorldTransform.SetAngularVelocity(ref velocity);

            if ((Math.Abs(turretAngle) < 0.1f) && (distance.Length < 100.0f) && (shotFrameCount > maxShotFrameCount))
            {
                shotFrameCount = 0;

                shotCount = (shotCount + 1) % maxShotCount;
                shot1NameBuilder.Remove(shot1NameLength, shot1NameBuilder.Length - shot1NameLength);
                shot1NameBuilder.Append(shotCount);
                shotInstanceIndexName = shot1NameBuilder.ToString();

                shot1BaseNameBuilder.Remove(shot1BaseNameLength, shot1BaseNameBuilder.Length - shot1BaseNameLength);
                shot1BaseNameBuilder.Append(shotCount);
                shotBaseInstanceIndexName = shot1BaseNameBuilder.ToString();

                shot1LightNameBuilder.Remove(shot1LightNameLength, shot1LightNameBuilder.Length - shot1LightNameLength);
                shot1LightNameBuilder.Append(shotCount);
                shotLightInstanceIndexName = shot1LightNameBuilder.ToString();

                shot1      = scene.Factory.PhysicsObjectManager.FindOrCreate(shotInstanceIndexName);
                shot1Base  = scene.Factory.PhysicsObjectManager.FindOrCreate(shotBaseInstanceIndexName);
                shot1Light = scene.Factory.PhysicsObjectManager.FindOrCreate(shotLightInstanceIndexName);

                shot1.AddChildPhysicsObject(shot1Base);
                shot1.AddChildPhysicsObject(shot1Light);

                Matrix4 turretGun1Rotation = matrixIdentity;
                Vector3 shot1Position      = vectorZero;
                Vector3 shot1LocalPosition = vectorZero;

                turretGun1.MainWorldTransform.GetRotation(ref turretGun1Rotation);

                shot1LocalPosition.X = 0.0f;
                shot1LocalPosition.Y = 2.0f;
                shot1LocalPosition.Z = 0.0f;

                Vector3.TransformVector(ref shot1LocalPosition, ref turretGun1Rotation, out shot1Position);
                Vector3.Add(ref shot1Position, ref turretGun1Position, out shot1Position);
                Vector3 shot1Direction = vectorZero;
                Vector3 shot1Scale     = vectorZero;

                shot1Direction.X = turretGun1Rotation.Row1.X;
                shot1Direction.Y = turretGun1Rotation.Row1.Y;
                shot1Direction.Z = turretGun1Rotation.Row1.Z;

                shot1Scale.X = shot1Scale.Y = shot1Scale.Z = 0.5f;

                shot1.InitLocalTransform.SetRotation(ref matrixIdentity);
                shot1.InitLocalTransform.SetPosition(ref shot1Position);

                Vector3.Multiply(ref shot1Direction, 200.0f, out shot1Direction);

                shot1.InitLocalTransform.SetLinearVelocity(ref shot1Direction);
                shot1.InitLocalTransform.SetAngularVelocity(ref vectorZero);
                shot1.MaxSimulationFrameCount = maxShotSimulationFrameCount;
                shot1.EnableRemovePhysicsObjectsFromManagerAfterMaxSimulationFrameCount = false;

                shot1Base.Shape               = sphere;
                shot1Base.UserDataStr         = sphereName;
                shot1Base.Material.RigidGroup = true;
                shot1Base.InitLocalTransform.SetScale(ref shot1Scale);
                shot1Base.Integral.SetDensity(1.0f);
                shot1Base.EnableCollisions = true;
                shot1Base.DisableCollision(turretGun1, true);
                shot1Base.MaxDisableCollisionFrameCount = 10;
                shot1Base.EnableBreakRigidGroup         = false;
                shot1Base.CreateSound(true);

                shot1Light.Shape       = sphere;
                shot1Light.UserDataStr = sphereName;
                shot1Light.CreateLight(true);
                shot1Light.Light.Type  = PhysicsLightType.Point;
                shot1Light.Light.Range = 20.0f;
                shot1Light.Light.SetDiffuse(1.0f, 0.7f, 0.0f);
                shot1Light.InitLocalTransform.SetScale(20.0f);
                shot1Light.Material.RigidGroup     = true;
                shot1Light.Material.UserDataStr    = yellowName;
                shot1Light.EnableBreakRigidGroup   = false;
                shot1Light.EnableCollisions        = false;
                shot1Light.EnableCursorInteraction = false;
                shot1Light.EnableAddToCameraDrawTransparentPhysicsObjects = false;

                scene.UpdateFromInitLocalTransform(shot1);

                shot2NameBuilder.Remove(shot2NameLength, shot2NameBuilder.Length - shot2NameLength);
                shot2NameBuilder.Append(shotCount);
                shotInstanceIndexName = shot2NameBuilder.ToString();

                shot2BaseNameBuilder.Remove(shot2BaseNameLength, shot2BaseNameBuilder.Length - shot2BaseNameLength);
                shot2BaseNameBuilder.Append(shotCount);
                shotBaseInstanceIndexName = shot2BaseNameBuilder.ToString();

                shot2LightNameBuilder.Remove(shot2LightNameLength, shot2LightNameBuilder.Length - shot2LightNameLength);
                shot2LightNameBuilder.Append(shotCount);
                shotLightInstanceIndexName = shot2LightNameBuilder.ToString();

                shot2      = scene.Factory.PhysicsObjectManager.FindOrCreate(shotInstanceIndexName);
                shot2Base  = scene.Factory.PhysicsObjectManager.FindOrCreate(shotBaseInstanceIndexName);
                shot2Light = scene.Factory.PhysicsObjectManager.FindOrCreate(shotLightInstanceIndexName);

                shot2.AddChildPhysicsObject(shot2Base);
                shot2.AddChildPhysicsObject(shot2Light);

                Matrix4 turretGun2Rotation = matrixIdentity;
                Vector3 shot2Position      = vectorZero;
                Vector3 shot2LocalPosition = vectorZero;

                turretGun2.MainWorldTransform.GetRotation(ref turretGun2Rotation);

                shot2LocalPosition.X = 0.0f;
                shot2LocalPosition.Y = 2.0f;
                shot2LocalPosition.Z = 0.0f;

                Vector3.TransformVector(ref shot2LocalPosition, ref turretGun2Rotation, out shot2Position);
                Vector3.Add(ref shot2Position, ref turretGun1Position, out shot2Position);
                Vector3 shot2Direction = vectorZero;
                Vector3 shot2Scale     = vectorZero;

                shot2Direction.X = turretGun2Rotation.Row1.X;
                shot2Direction.Y = turretGun2Rotation.Row1.Y;
                shot2Direction.Z = turretGun2Rotation.Row1.Z;

                shot2Scale.X = shot2Scale.Y = shot2Scale.Z = 0.5f;

                shot2.InitLocalTransform.SetRotation(ref matrixIdentity);
                shot2.InitLocalTransform.SetPosition(ref shot2Position);

                Vector3.Multiply(ref shot2Direction, 200.0f, out shot2Direction);

                shot2.InitLocalTransform.SetLinearVelocity(ref shot2Direction);
                shot2.InitLocalTransform.SetAngularVelocity(ref vectorZero);
                shot2.MaxSimulationFrameCount = maxShotSimulationFrameCount;
                shot2.EnableRemovePhysicsObjectsFromManagerAfterMaxSimulationFrameCount = false;

                shot2Base.Shape               = sphere;
                shot2Base.UserDataStr         = sphereName;
                shot2Base.Material.RigidGroup = true;
                shot2Base.InitLocalTransform.SetScale(ref shot2Scale);
                shot2Base.Integral.SetDensity(10.0f);
                shot2Base.EnableCollisions = true;
                shot2Base.DisableCollision(turretGun2, true);
                shot2Base.MaxDisableCollisionFrameCount = 10;
                shot2Base.EnableBreakRigidGroup         = false;
                shot2Base.CreateSound(true);

                shot2Light.Shape       = sphere;
                shot2Light.UserDataStr = sphereName;
                shot2Light.CreateLight(true);
                shot2Light.Light.Type  = PhysicsLightType.Point;
                shot2Light.Light.Range = 20.0f;
                shot2Light.Light.SetDiffuse(1.0f, 0.7f, 0.0f);
                shot2Light.InitLocalTransform.SetScale(20.0f);
                shot2Light.Material.RigidGroup     = true;
                shot2Light.Material.UserDataStr    = yellowName;
                shot2Light.EnableBreakRigidGroup   = false;
                shot2Light.EnableCollisions        = false;
                shot2Light.EnableCursorInteraction = false;
                shot2Light.EnableAddToCameraDrawTransparentPhysicsObjects = false;

                scene.UpdateFromInitLocalTransform(shot2);
            }

            Vector3 bodyUpPosition = vectorZero;
            Vector3 upDirection    = vectorZero;

            bodyDown.MainWorldTransform.GetPosition(ref bodyDownPosition);
            bodyUp.MainWorldTransform.GetPosition(ref bodyUpPosition);

            Vector3.Subtract(ref bodyDownPosition, ref bodyUpPosition, out upDirection);
            upDirection.Normalize();

            float   bodyAngle = 0.0f;
            Vector3 axis      = vectorZero;

            Vector3.Dot(ref upDirection, ref gravityDirection, out bodyAngle);
            bodyAngle = (float)Math.Acos(bodyAngle);

            if (Math.Abs(bodyAngle) > 0.005f)
            {
                bodyAngle *= 0.005f / Math.Abs(bodyAngle);
            }

            Vector3.Cross(ref gravityDirection, ref upDirection, out axis);

            objectBase.MainWorldTransform.GetAngularVelocity(ref velocity);
            Vector3.Multiply(ref velocity, 0.98f, out velocity);
            Vector3.Multiply(ref axis, bodyAngle * 400.0f, out axis);
            Vector3.Add(ref velocity, ref axis, out velocity);
            objectBase.MainWorldTransform.SetAngularVelocity(ref velocity);

            Vector3 turretBodyUpPosition = vectorZero;

            turretBodyUp.MainWorldTransform.GetPosition(ref turretBodyUpPosition);

            Vector3.Subtract(ref turretBodyDownPosition, ref turretBodyUpPosition, out upDirection);
            upDirection.Normalize();

            Vector3.Dot(ref upDirection, ref gravityDirection, out bodyAngle);
            bodyAngle = (float)Math.Acos(bodyAngle);

            if (Math.Abs(bodyAngle) > 0.005f)
            {
                bodyAngle *= 0.005f / Math.Abs(bodyAngle);
            }

            Vector3.Cross(ref gravityDirection, ref upDirection, out axis);

            turret.MainWorldTransform.GetAngularVelocity(ref velocity);
            Vector3.Multiply(ref velocity, 0.98f, out velocity);
            Vector3.Multiply(ref axis, bodyAngle * 400.0f, out axis);
            Vector3.Add(ref velocity, ref axis, out velocity);
            turret.MainWorldTransform.SetAngularVelocity(ref velocity);
        }
示例#2
0
        void Fly(SimulateMethodArgs args)
        {
            PhysicsScene  scene      = demo.Engine.Factory.PhysicsSceneManager.Get(args.OwnerSceneIndex);
            PhysicsObject objectBase = scene.Factory.PhysicsObjectManager.Get(args.OwnerIndex);

            float time = args.Time;

            if (!enableFly)
            {
                return;
            }

            totalStartTime += time;

            bool  rotorUpWorking   = true;
            bool  rotorBackWorking = true;
            float rotorSpeedFactor = 0.0f;

            if (totalStartTime > maxStartTime)
            {
                totalFlyTime    += time;
                rotorSpeedFactor = 1.2f;
            }
            else
            {
                totalFlyTime     = 0.0f;
                rotorSpeedFactor = 0.6f;
            }

            if (totalFlyTime >= maxFlyTime)
            {
                totalStartTime = 0.0f;
                enableFly      = false;

                if (cabinFrontButtonConstraint != null)
                {
                    cabinFrontButtonConstraint.ControlDistanceX = 0.0f;
                }
            }

            if (upRotorConstraint != null)
            {
                if (upRotorConstraint.PhysicsObject1 != null)
                {
                    if (upRotorConstraint.PhysicsObject1.IsBrokenRigidGroup || upRotorConstraint.IsBroken || (totalFlyTime >= maxFlyTime))
                    {
                        rotorUpWorking = false;
                    }
                }

                if (upRotorConstraint.PhysicsObject2 != null)
                {
                    if (upRotorConstraint.PhysicsObject2.IsBrokenRigidGroup || upRotorConstraint.IsBroken || (totalFlyTime >= maxFlyTime))
                    {
                        rotorUpWorking = false;
                    }
                }
            }
            else
            {
                rotorUpWorking = false;
            }

            if (backRotorConstraint != null)
            {
                if (rotorUpWorking)
                {
                    if (backRotorConstraint.PhysicsObject1 != null)
                    {
                        if (backRotorConstraint.PhysicsObject1.IsBrokenRigidGroup || backRotorConstraint.IsBroken)
                        {
                            rotorBackWorking = false;
                        }
                    }

                    if (backRotorConstraint.PhysicsObject2 != null)
                    {
                        if (backRotorConstraint.PhysicsObject2.IsBrokenRigidGroup || backRotorConstraint.IsBroken)
                        {
                            rotorBackWorking = false;
                        }
                    }
                }
                else
                {
                    rotorBackWorking = false;
                }
            }
            else
            {
                rotorBackWorking = false;
            }

            float   rotorUpAngularVelocity   = 0.0f;
            float   rotorBackAngularVelocity = 0.0f;
            Vector3 velocity = vectorZero;

            if ((upRotor != null) && (totalFlyTime < maxFlyTime) && rotorUpWorking)
            {
                Vector3.Multiply(ref unitY, -rotorSpeedFactor * maxRotorUpAngularVelocity, out velocity);
                upRotor.MainWorldTransform.SetLocalAngularVelocity(ref velocity);
                rotorUpAngularVelocity = velocity.Length;
            }

            if ((backRotor != null) && (totalFlyTime < maxFlyTime) && rotorBackWorking)
            {
                Vector3.Multiply(ref unitZ, rotorSpeedFactor * maxRotorBackAngularVelocity, out velocity);
                backRotor.MainWorldTransform.SetLocalAngularVelocity(ref velocity);
                rotorBackAngularVelocity = velocity.Length;
            }

            Vector3 gravityDirection = vectorZero;

            scene.GetGravityDirection(ref gravityDirection);

            if (rotorUpWorking)
            {
                if ((rotorUpAngularVelocity > maxRotorUpAngularVelocity))
                {
                    float upFactor = 1.0f;
                    if (!rotorBackWorking)
                    {
                        upFactor = 0.5f;
                    }

                    Vector3.Multiply(ref gravityDirection, -maxRotorUpFlyForce * scene.GravityAcceleration * upFactor, out force);

                    objectBase.WorldAccumulator.AddWorldForce(ref force);
                }
            }

            if (rotorBackWorking && rotorUpWorking)
            {
                if (rotorUpAngularVelocity > maxRotorUpAngularVelocity)
                {
                    Vector3.Multiply(ref unitY, maxRotorBackFlyCompensationForce, out force);

                    objectBase.WorldAccumulator.AddLocalTorque(ref force);
                }
                else
                {
                    Vector3.Multiply(ref unitY, maxRotorBackStartCompensationForce, out force);

                    objectBase.WorldAccumulator.AddLocalTorque(ref force);
                }
            }

            if ((rotorUpAngularVelocity > maxRotorUpAngularVelocity) && (rotorBackAngularVelocity > maxRotorBackAngularVelocity))
            {
                Vector3 deltaVelocity = vectorZero;
                Vector3 moveDirection = vectorZero;
                Vector3 position      = vectorZero;

                objectBase.MainWorldTransform.GetPosition(ref position);

                if (totalFlyTime < maxFlyTime * 0.2f)
                {
                    objectBase.MainWorldTransform.GetLinearVelocity(ref velocity);
                    Vector3.Multiply(ref velocity, maxMoveDirectionDamping, out velocity);
                    objectBase.MainWorldTransform.SetLinearVelocity(ref velocity);

                    Vector3.Subtract(ref flyPosition1, ref position, out moveDirection);
                    moveDirection.Normalize();
                    Vector3.Multiply(ref moveDirection, objectBase.Integral.Mass, out force);

                    objectBase.WorldAccumulator.AddWorldForce(ref force);
                }
                else
                if (totalFlyTime < maxFlyTime * 0.4f)
                {
                    objectBase.MainWorldTransform.GetLinearVelocity(ref velocity);
                    Vector3.Multiply(ref velocity, maxMoveDirectionDamping, out velocity);
                    objectBase.MainWorldTransform.SetLinearVelocity(ref velocity);

                    Vector3.Subtract(ref flyPosition2, ref position, out moveDirection);
                    moveDirection.Normalize();
                    Vector3.Multiply(ref moveDirection, objectBase.Integral.Mass, out force);

                    objectBase.WorldAccumulator.AddWorldForce(ref force);
                }
                else
                if (totalFlyTime < maxFlyTime * 0.6f)
                {
                    objectBase.MainWorldTransform.GetLinearVelocity(ref velocity);
                    Vector3.Multiply(ref velocity, maxMoveDirectionDamping, out velocity);
                    objectBase.MainWorldTransform.SetLinearVelocity(ref velocity);

                    Vector3.Subtract(ref flyPosition3, ref position, out moveDirection);
                    moveDirection.Normalize();
                    Vector3.Multiply(ref moveDirection, objectBase.Integral.Mass, out force);

                    objectBase.WorldAccumulator.AddWorldForce(ref force);
                }
                else
                if (totalFlyTime < maxFlyTime * 0.8f)
                {
                    objectBase.MainWorldTransform.GetLinearVelocity(ref velocity);
                    Vector3.Multiply(ref velocity, maxMoveDirectionDamping, out velocity);
                    objectBase.MainWorldTransform.SetLinearVelocity(ref velocity);

                    Vector3.Subtract(ref flyPosition4, ref position, out moveDirection);
                    moveDirection.Normalize();
                    Vector3.Multiply(ref moveDirection, objectBase.Integral.Mass, out force);

                    objectBase.WorldAccumulator.AddWorldForce(ref force);
                }
                else
                if (totalFlyTime < maxFlyTime * 0.95f)
                {
                    objectBase.MainWorldTransform.GetLinearVelocity(ref velocity);
                    Vector3.Multiply(ref velocity, maxMoveDirectionDamping, out velocity);
                    objectBase.MainWorldTransform.SetLinearVelocity(ref velocity);

                    Vector3.Subtract(ref endFlyPosition, ref position, out moveDirection);
                    moveDirection.Normalize();
                    Vector3.Multiply(ref moveDirection, objectBase.Integral.Mass, out force);

                    objectBase.WorldAccumulator.AddWorldForce(ref force);
                }
                else
                if (totalFlyTime < maxFlyTime)
                {
                    objectBase.WorldAccumulator.GetTotalWorldForce(ref force);
                    Vector3.Multiply(ref force, 0.9f, out force);
                    objectBase.WorldAccumulator.SetTotalWorldForce(ref force);

                    objectBase.MainWorldTransform.GetLinearVelocity(ref velocity);
                    Vector3.Multiply(ref velocity, maxMoveDirectionDamping, out velocity);
                    objectBase.MainWorldTransform.SetLinearVelocity(ref velocity);

                    Vector3.Subtract(ref landingPosition, ref position, out moveDirection);
                    moveDirection.Normalize();
                    Vector3.Multiply(ref moveDirection, objectBase.Integral.Mass, out force);

                    objectBase.WorldAccumulator.AddWorldForce(ref force);
                }

                if ((upRotorBody != null) && (upBody2 != null) && (tail4 != null) && (tail3 != null) && (totalFlyTime < maxFlyTime))
                {
                    Vector3 axis              = vectorZero;
                    Vector3 forwardDirection  = vectorZero;
                    Vector3 tailStartPosition = vectorZero;
                    Vector3 tailEndPosition   = vectorZero;

                    tail4.MainWorldTransform.GetPosition(ref tailStartPosition);
                    tail3.MainWorldTransform.GetPosition(ref tailEndPosition);

                    Vector3.Subtract(ref tailEndPosition, ref tailStartPosition, out forwardDirection);
                    forwardDirection.Normalize();

                    float bodyAngle = 0.0f;

                    Vector3.Dot(ref forwardDirection, ref moveDirection, out bodyAngle);
                    bodyAngle = (float)Math.Acos(bodyAngle);
                    Vector3.Cross(ref moveDirection, ref forwardDirection, out axis);

                    objectBase.MainWorldTransform.GetAngularVelocity(ref velocity);
                    Vector3.Multiply(ref velocity, 0.5f, out velocity);
                    Vector3.Multiply(ref axis, bodyAngle * (float)time, out axis);
                    Vector3.Add(ref velocity, ref axis, out velocity);
                    objectBase.MainWorldTransform.SetAngularVelocity(ref velocity);

                    Vector3 upDirection = vectorZero;

                    Vector3 upBodyStartPosition = vectorZero;
                    Vector3 upBodyEndPosition   = vectorZero;

                    upRotorBody.MainWorldTransform.GetPosition(ref upBodyStartPosition);
                    upBody2.MainWorldTransform.GetPosition(ref upBodyEndPosition);

                    Vector3.Subtract(ref upBodyEndPosition, ref upBodyStartPosition, out upDirection);
                    upDirection.Normalize();

                    Vector3.Dot(ref upDirection, ref gravityDirection, out bodyAngle);
                    bodyAngle = (float)Math.Acos(bodyAngle);
                    Vector3.Cross(ref gravityDirection, ref upDirection, out axis);

                    objectBase.MainWorldTransform.GetAngularVelocity(ref velocity);
                    Vector3.Multiply(ref axis, bodyAngle * (float)time, out axis);
                    Vector3.Add(ref velocity, ref axis, out velocity);
                    objectBase.MainWorldTransform.SetAngularVelocity(ref velocity);
                }

                objectBase.MainWorldTransform.GetPosition(ref position);

                if (position.Y > maxFlyHeight)
                {
                    float distance = position.Y - maxFlyHeight;

                    Vector3.Multiply(ref gravityDirection, distance * maxHeightDamping, out deltaVelocity);

                    objectBase.MainWorldTransform.GetLinearVelocity(ref velocity);
                    Vector3.Add(ref velocity, ref deltaVelocity, out velocity);
                    objectBase.MainWorldTransform.SetLinearVelocity(ref velocity);
                }
            }
        }
示例#3
0
        public void Flame(SimulateMethodArgs args)
        {
            PhysicsScene  scene      = demo.Engine.Factory.PhysicsSceneManager.Get(args.OwnerSceneIndex);
            PhysicsObject objectBase = scene.Factory.PhysicsObjectManager.Get(args.OwnerIndex);

            float time = args.Time;

            if (objectBase.IsBrokenRigidGroup || (bodyEmitter == null) || (constraint1 == null) || constraint1.IsBroken)
            {
                if ((bodyLight != null) && (bodyLight.Light != null) && bodyLight.Light.Enabled)
                {
                    bodyLight.Light.Enabled = false;
                }

                return;
            }

            frameCount++;

            if (frameCount > maxParticleFrameCount)
            {
                frameCount = 0;

                bodyLight.Light.Intensity = (float)random.NextDouble() * 0.2f + 0.8f;

                particleCount = (particleCount + 1) % maxParticleCount;
                particleNameBuilder.Remove(particleNameLength, particleNameBuilder.Length - particleNameLength);
                particleNameBuilder.Append(particleCount);
                particleInstanceIndexName = particleNameBuilder.ToString();

                particle = scene.Factory.PhysicsObjectManager.FindOrCreate(particleInstanceIndexName);

                particle.Shape                           = sphere;
                particle.UserDataStr                     = sphereName;
                particle.Material.UserDataStr            = yellowName;
                particle.Material.TransparencyFactor     = 0.9f;
                particle.Material.TransparencyStepFactor = -0.01f;
                particle.CreateSound(true);
                particle.Sound.Range              = 50.0f;
                particle.Sound.AmplitudeFactor    = 1000.0f;
                particle.Sound.MinAmplitudeFactor = 0.0f;
                particle.Sound.UserDataStr        = soundName;

                bodyEmitter.MainWorldTransform.GetPosition(ref position);

                particle.InitLocalTransform.SetRotation(ref matrixIdentity);
                particle.InitLocalTransform.SetPosition(ref position);

                Vector3 velocity = vectorZero;

                scene.GetGravityDirection(ref velocity);

                Vector3.Multiply(ref velocity, -10.0f, out velocity);

                particle.InitLocalTransform.SetLinearVelocity(ref velocity);
                particle.InitLocalTransform.SetAngularVelocity(ref vectorZero);
                particle.Integral.SetDensity(0.002f);
                particle.DisableCollision(bodyMain, true);
                particle.MaxSimulationFrameCount       = maxParticleSimulationFrameCount;
                particle.MaxDisableCollisionFrameCount = 10;
                particle.EnableCursorInteraction       = false;
                particle.EnableLocalGravity            = true;
                particle.EnableRemovePhysicsObjectsFromManagerAfterMaxSimulationFrameCount = false;
                particle.Material.TransparencySecondPass = false;

                scene.UpdateFromInitLocalTransform(particle);
            }
        }
示例#4
0
        public void Move(SimulateMethodArgs args)
        {
            PhysicsScene  scene      = demo.Engine.Factory.PhysicsSceneManager.Get(args.OwnerSceneIndex);
            PhysicsObject objectBase = scene.Factory.PhysicsObjectManager.Get(args.OwnerIndex);

            if (!objectBase.Camera.Enabled)
            {
                return;
            }
            if (!objectBase.Camera.Active)
            {
                return;
            }

            float time = (float)args.Time;

            Vector3 deltaRotation            = vectorZero;
            Vector3 deltaTranslation         = vectorZero;
            float   rotationSpeed            = 8.0f;
            float   translationSpeed         = 8.0f;
            float   jumpSpeed                = 8.0f;
            float   swimUpSpeed              = 0.2f;
            float   swimUpOnSurfaceSpeed     = 0.06f;
            float   translationInFluidFactor = 0.15f;
            float   soundPositionFactor      = 0.1f;
            bool    enableJump               = false;
            bool    enableSwimUp             = false;
            bool    enableShot               = false;

            bool cameraBodyCollision = cameraBody.IsColliding();
            bool cameraDownCollision = cameraDown.IsColliding();

            DemoMouseState    mouseState    = demo.GetMouseState();
            DemoKeyboardState keyboardState = demo.GetKeyboardState();

            if (mouseState[MouseButton.Right])
            {
                deltaRotation.Y += MathHelper.DegreesToRadians(rotationSpeed * (mouseState.X - oldMouseState.X) * time);
                deltaRotation.X += MathHelper.DegreesToRadians(rotationSpeed * (mouseState.Y - oldMouseState.Y) * time);
            }

            mousePosition.X = mouseState.X;
            mousePosition.Y = mouseState.Y;

            if (!objectBase.Camera.EnableControl)
            {
                if (mouseState[MouseButton.Middle] && !oldMouseState[MouseButton.Middle])
                {
                    enableShot = true;
                }

                if ((keyboardState[Key.ControlRight] && !oldKeyboardState[Key.ControlRight]) ||
                    (keyboardState[Key.ControlLeft] && !oldKeyboardState[Key.ControlLeft]))
                {
                    enableShot = true;
                }
            }

            PhysicsObject cursorA = scene.Factory.PhysicsObjectManager.Find(cursorAName);
            PhysicsObject cursorB = scene.Factory.PhysicsObjectManager.Find(cursorBName);

            if (!demo.EnableMenu)
            {
                if (cursorA != null)
                {
                    cursorA.EnableDrawing = true;
                }

                if (cursorB != null)
                {
                    cursorB.EnableDrawing = true;
                }
            }
            else
            {
                if (cursorA != null)
                {
                    cursorA.EnableDrawing = false;
                }

                if (cursorB != null)
                {
                    cursorB.EnableDrawing = false;
                }
            }

            if (!objectBase.Camera.EnableControl)
            {
                if (keyboardState[Key.W])
                {
                    deltaTranslation.Z += translationSpeed * time;
                }

                if (keyboardState[Key.S])
                {
                    deltaTranslation.Z -= translationSpeed * time;
                }

                if (keyboardState[Key.D])
                {
                    deltaTranslation.X += translationSpeed * time;
                }

                if (keyboardState[Key.A])
                {
                    deltaTranslation.X -= translationSpeed * time;
                }

                if (keyboardState[Key.Space] && !oldKeyboardState[Key.Space])
                {
                    enableJump = true;
                }

                if (keyboardState[Key.Space])
                {
                    enableSwimUp = true;
                }
            }

            if (keyboardState[Key.Tab] && !oldKeyboardState[Key.Tab])
            {
                enableDistance = !enableDistance;
            }

            oldMouseState    = mouseState;
            oldKeyboardState = keyboardState;

            Vector3 gravityDirection = vectorZero;

            scene.GetGravityDirection(ref gravityDirection);

            if (!objectBase.Camera.EnableControl)
            {
                if (deltaRotation.LengthSquared != 0.0f)
                {
                    Vector3 euler = vectorZero;
                    objectBase.Camera.GetEuler(ref euler);
                    Vector3.Add(ref euler, ref deltaRotation, out euler);
                    objectBase.Camera.SetEuler(ref euler);

                    Matrix4 rotationX, rotationY;
                    Matrix4.CreateRotationX(-euler.X, out rotationX);
                    Matrix4.CreateRotationY(-euler.Y, out rotationY);
                    Matrix4.Mult(ref rotationY, ref rotationX, out cameraRotation);

                    objectBase.Camera.SetRotation(ref cameraRotation);

                    Matrix4.CreateRotationY(euler.Y, out rotation);

                    objectBase.RigidGroupOwner.MainWorldTransform.SetRotation(ref rotation);
                    objectBase.RigidGroupOwner.RecalculateMainTransform();
                }
            }
            else
            {
                Vector3 euler          = vectorZero;
                Matrix4 objectRotation = matrixIdentity;
                objectBase.Camera.GetEuler(ref euler);
                Vector3.Add(ref euler, ref deltaRotation, out euler);
                objectBase.RigidGroupOwner.MainWorldTransform.GetRotation(ref objectRotation);

                Matrix4 rotationX, rotationY;
                Matrix4.CreateRotationX(euler.X, out rotationX);
                Matrix4.CreateRotationY(euler.Y, out rotationY);

                Matrix4.Mult(ref rotationX, ref rotationY, out cameraRotation);
                Matrix4.Mult(ref cameraRotation, ref objectRotation, out rotation);

                objectBase.Camera.SetEuler(ref euler);
                objectBase.Camera.SetTransposeRotation(ref rotation);
            }

            if (deltaTranslation.LengthSquared != 0.0f)
            {
                if (objectBase.RigidGroupOwner.IsUnderFluidSurface)
                {
                    objectBase.RigidGroupOwner.MaxPreUpdateLinearVelocity  = 10.0f;
                    objectBase.RigidGroupOwner.MaxPostUpdateLinearVelocity = 10.0f;

                    if (enableSwimUp)
                    {
                        objectBase.InitLocalTransform.GetTransposeRotation(ref rotation);
                        Vector3.TransformVector(ref deltaTranslation, ref rotation, out direction);

                        objectBase.MainWorldTransform.GetRotation(ref rotation);
                        Vector3.TransformVector(ref direction, ref rotation, out moveForce);
                        Vector3.Multiply(ref moveForce, translationInFluidFactor * objectBase.RigidGroupOwner.Integral.Mass / (time * time), out moveForce);

                        objectBase.RigidGroupOwner.WorldAccumulator.AddWorldForce(ref moveForce);
                    }
                    else
                    {
                        objectBase.Camera.GetTransposeRotation(ref rotation);
                        Vector3.TransformVector(ref deltaTranslation, ref rotation, out moveForce);
                        Vector3.Multiply(ref moveForce, translationInFluidFactor * objectBase.RigidGroupOwner.Integral.Mass / (time * time), out moveForce);

                        objectBase.RigidGroupOwner.WorldAccumulator.AddWorldForce(ref moveForce);
                    }
                }
                else
                {
                    if (cameraDownCollision)
                    {
                        objectBase.RigidGroupOwner.MaxPreUpdateLinearVelocity  = 100000.0f;
                        objectBase.RigidGroupOwner.MaxPostUpdateLinearVelocity = 100000.0f;

                        objectBase.InitLocalTransform.GetTransposeRotation(ref rotation);
                        Vector3.TransformVector(ref deltaTranslation, ref rotation, out direction);

                        objectBase.MainWorldTransform.GetRotation(ref rotation);
                        Vector3.TransformVector(ref direction, ref rotation, out moveForce);
                        Vector3.Multiply(ref moveForce, objectBase.RigidGroupOwner.Integral.Mass / (time * time), out moveForce);

                        objectBase.RigidGroupOwner.WorldAccumulator.AddWorldForce(ref moveForce);
                        cameraDown.UpdateFeedbackForce(ref moveForce);
                    }
                    else
                    {
                        if (objectBase.RigidGroupOwner.IsInFluid)
                        {
                            objectBase.RigidGroupOwner.MaxPreUpdateLinearVelocity  = 10.0f;
                            objectBase.RigidGroupOwner.MaxPostUpdateLinearVelocity = 10.0f;

                            objectBase.InitLocalTransform.GetTransposeRotation(ref rotation);
                            Vector3.TransformVector(ref deltaTranslation, ref rotation, out direction);

                            objectBase.MainWorldTransform.GetRotation(ref rotation);
                            Vector3.TransformVector(ref direction, ref rotation, out moveForce);
                            Vector3.Multiply(ref moveForce, translationInFluidFactor * objectBase.RigidGroupOwner.Integral.Mass / (time * time), out moveForce);

                            objectBase.RigidGroupOwner.WorldAccumulator.AddWorldForce(ref moveForce);
                        }
                    }
                }
            }

            if (enableSwimUp)
            {
                if (cameraDown.IsUnderFluidSurface && cameraBody.IsUnderFluidSurface)
                {
                    objectBase.RigidGroupOwner.MaxPreUpdateLinearVelocity  = 10.0f;
                    objectBase.RigidGroupOwner.MaxPostUpdateLinearVelocity = 10.0f;

                    PhysicsObject fluidPhysicsObject = objectBase.RigidGroupOwner.FluidPhysicsObject;
                    fluidPhysicsObject.InternalControllers.FluidController.GetNormal(ref fluidNormal);

                    Vector3.Multiply(ref fluidNormal, swimUpSpeed * objectBase.RigidGroupOwner.Integral.Mass / time, out moveForce);

                    objectBase.RigidGroupOwner.WorldAccumulator.AddWorldForce(ref moveForce);
                }
                else
                if (!cameraDownCollision && cameraBody.IsInFluid && (deltaTranslation.LengthSquared == 0.0f))
                {
                    objectBase.RigidGroupOwner.MaxPreUpdateLinearVelocity  = 10.0f;
                    objectBase.RigidGroupOwner.MaxPostUpdateLinearVelocity = 10.0f;

                    PhysicsObject fluidPhysicsObject = objectBase.RigidGroupOwner.FluidPhysicsObject;
                    fluidPhysicsObject.InternalControllers.FluidController.GetNormal(ref fluidNormal);

                    Vector3.Multiply(ref fluidNormal, swimUpOnSurfaceSpeed * objectBase.RigidGroupOwner.Integral.Mass / time, out moveForce);

                    objectBase.RigidGroupOwner.WorldAccumulator.AddWorldForce(ref moveForce);
                }
            }

            if (enableJump)
            {
                if (!enableControl && !objectBase.Camera.EnableControl && cameraDownCollision && !cameraDown.IsUnderFluidSurface && !cameraBody.IsUnderFluidSurface)
                {
                    objectBase.RigidGroupOwner.MaxPreUpdateLinearVelocity  = 100000.0f;
                    objectBase.RigidGroupOwner.MaxPostUpdateLinearVelocity = 100000.0f;

                    Vector3.Multiply(ref gravityDirection, -jumpSpeed * objectBase.RigidGroupOwner.Integral.Mass / time, out moveForce);

                    objectBase.RigidGroupOwner.WorldAccumulator.AddWorldForce(ref moveForce);
                    cameraDown.UpdateFeedbackForce(ref moveForce);
                }
            }

            if (enableDistance)
            {
                if (distance > maxDistance)
                {
                    distance -= 2.0f;
                }

                if (enableDistanceCollision)
                {
                    float margin = 1.0f;

                    objectBase.MainWorldTransform.GetPosition(ref startPoint);

                    objectBase.Camera.GetTransposeRotation(ref cameraRotation);

                    direction.X = cameraRotation.Row2.X;
                    direction.Y = cameraRotation.Row2.Y;
                    direction.Z = cameraRotation.Row2.Z;

                    Vector3.Multiply(ref direction, distance, out direction);
                    Vector3.Add(ref startPoint, ref direction, out endPoint);

                    scene.UpdatePhysicsObjectsIntersectedBySegment(ref startPoint, ref endPoint, margin, true);

                    float minDistance = float.MaxValue;
                    float curDistance = 0.0f;

                    for (int i = 0; i < scene.IntersectedPhysicsObjectsCount; i++)
                    {
                        PhysicsObject hitObject = scene.GetIntersectedPhysicsObject(i, ref hitPoint);

                        if (hitObject.RigidGroupOwner == objectBase.RigidGroupOwner)
                        {
                            continue;
                        }

                        //if ((hitObject.InternalControllers.FluidController != null) && hitObject.InternalControllers.FluidController.Enabled)
                        //    continue;

                        if (!hitObject.EnableCollisions)
                        {
                            continue;
                        }

                        Vector3.Subtract(ref startPoint, ref hitPoint, out hitDistance);
                        curDistance = hitDistance.Length;

                        if (curDistance < minDistance)
                        {
                            minDistance = curDistance;
                        }
                    }

                    if (minDistance < Math.Abs(distance))
                    {
                        distance = -minDistance;
                    }
                }
            }
            else
            {
                if (distance < 0.0f)
                {
                    distance += 2.0f;
                }

                if (distance > 0.0f)
                {
                    distance = 0.0f;
                }
            }

            if (enableDistance)
            {
                if (distance > maxDistance)
                {
                    if ((cameraUp != null) && (cameraBody != null) && (cameraDown != null))
                    {
                        objectBase.RigidGroupOwner.EnableDrawing = true;
                        cameraUp.EnableDrawing   = true;
                        cameraBody.EnableDrawing = true;
                        cameraDown.EnableDrawing = true;
                    }
                }
            }
            else
            {
                if (distance >= 0.0f)
                {
                    if ((cameraUp != null) && (cameraBody != null) && (cameraDown != null))
                    {
                        objectBase.RigidGroupOwner.EnableDrawing = false;
                        cameraUp.EnableDrawing   = false;
                        cameraBody.EnableDrawing = false;
                        cameraDown.EnableDrawing = false;
                    }
                }
            }

            enableControl = objectBase.Camera.EnableControl;

            float   gravityDistance       = 0.0f;
            Vector3 gravityLinearVelocity = vectorZero;
            Vector3 tangentLinearVelocity = vectorZero;
            Vector3 velocity = vectorZero;

            objectBase.MainWorldTransform.GetLinearVelocity(ref velocity);
            Vector3.Dot(ref gravityDirection, ref velocity, out gravityDistance);
            Vector3.Multiply(ref gravityDirection, gravityDistance, out gravityLinearVelocity);
            Vector3.Subtract(ref velocity, ref gravityLinearVelocity, out tangentLinearVelocity);

            float tangentLength = tangentLinearVelocity.Length;

            if (tangentLength > maxTangentLength)
            {
                tangentLinearVelocity *= maxTangentLength / tangentLength;
            }

            Vector3.Add(ref gravityLinearVelocity, ref tangentLinearVelocity, out velocity);

            objectBase.RigidGroupOwner.MainWorldTransform.SetLinearVelocity(ref velocity);

            objectBase.Camera.Projection.CreatePerspectiveLH(1.0f, 11000.0f, 70.0f, demo.WindowWidth, demo.WindowHeight);

            objectBase.MainWorldTransform.GetPosition(ref position);
            objectBase.Camera.GetTransposeRotation(ref cameraRotation);

            objectBase.Camera.View.CreateLookAtLH(ref position, ref cameraRotation, distance);
            objectBase.Camera.UpdateFrustum();

            objectBase.Camera.View.GetViewMatrix(ref view);
            objectBase.Camera.Projection.GetProjectionMatrix(ref projection);

            Vector3 rayPosition, rayDirection;

            rayPosition = rayDirection = vectorZero;

            objectBase.UnProjectToRay(ref mousePosition, 0, 0, demo.WindowWidth, demo.WindowHeight, 0.0f, 1.0f, ref view, ref matrixIdentity, ref projection, ref rayPosition, ref rayDirection);

            PhysicsObject cursor = scene.Factory.PhysicsObjectManager.Find(cursorName);

            if (cursor != null)
            {
                Vector3 cursorPosition      = vectorZero;
                Matrix4 cursorLocalRotation = matrixIdentity;
                Matrix4 cursorWorldRotation = matrixIdentity;

                cursor.InitLocalTransform.GetPosition(ref cursorPosition);
                cursor.InitLocalTransform.GetRotation(ref cursorLocalRotation);
                cursor.MainWorldTransform.GetRotation(ref cursorWorldRotation);

                objectBase.Camera.GetTransposeRotation(ref cameraRotation);
                Matrix4.Mult(ref cursorLocalRotation, ref cameraRotation, out rotation);

                Vector3.TransformVector(ref cursorPosition, ref cursorWorldRotation, out position);

                cursor.MainWorldTransform.SetRotation(ref rotation);
                Vector3.Add(ref position, ref rayPosition, out position);
                Vector3.Add(ref position, ref rayDirection, out position);
                cursor.MainWorldTransform.SetPosition(ref position);

                cursor.RecalculateMainTransform();
            }

            CursorController cursorController = objectBase.InternalControllers.CursorController;

            if (cursorController.IsDragging)
            {
                if (cursorController.HitPhysicsObject.Integral.IsStatic && (cursorController.HitPhysicsObject.InternalControllers.HeightmapController != null) && cursorController.HitPhysicsObject.InternalControllers.HeightmapController.Enabled)
                {
                    Vector3 cursorStartPosition = vectorZero;
                    Vector3 cursorEndPosition   = vectorZero;

                    cursorController.GetAnchor1(ref cursorStartPosition);
                    cursorController.GetAnchor2(ref cursorEndPosition);

                    Vector3.Subtract(ref cursorEndPosition, ref cursorStartPosition, out direction);

                    float dir = direction.Y;

                    if (dir != 0.0f)
                    {
                        Vector3 scale = vectorZero;

                        cursorController.HitPhysicsObject.MainWorldTransform.GetScale(ref scale);

                        float positionX = cursorStartPosition.X + 0.5f * scale.X;
                        float positionY = cursorStartPosition.Y + 0.5f * scale.Y;
                        float positionZ = cursorStartPosition.Z + 0.5f * scale.Z;

                        cursorController.HitPhysicsObject.InternalControllers.HeightmapController.AddHeight(positionX, positionY, positionZ, dir / scale.Y);
                        cursorController.HitPhysicsObject.InternalControllers.HeightmapController.UpdateBounding();

                        // To change the friction and restitution of the heightmap surface by the cursor, add the following lines of code

                        //cursorController.HitPhysicsObject.InternalControllers.HeightmapController.SetFriction(positionX, positionY, positionZ, 0.0f);
                        //cursorController.HitPhysicsObject.InternalControllers.HeightmapController.SetRestitution(positionX, positionY, positionZ, 2.0f);

                        cursorStartPosition.Y += dir;
                        cursorController.SetAnchor1(ref cursorStartPosition);
                    }
                }

                if (cursorController.HitPhysicsObject.Integral.IsStatic && (cursorController.HitPhysicsObject.InternalControllers.HeightmapController != null) && cursorController.HitPhysicsObject.InternalControllers.HeightmapController.Enabled)
                {
                    Vector3 cursorStartPosition = vectorZero;
                    Vector3 cursorEndPosition   = vectorZero;

                    cursorController.GetAnchor1(ref cursorStartPosition);
                    cursorController.GetAnchor2(ref cursorEndPosition);

                    Vector3.Subtract(ref cursorEndPosition, ref cursorStartPosition, out direction);

                    if (direction.LengthSquared != 0.0f)
                    {
                        // To move the heightmap surface by the cursor, add the following lines of code

                        //cursorController.HitPhysicsObject.MainWorldTransform.GetPosition(ref cursorStartPosition);

                        //Vector3.Add(ref cursorStartPosition, ref direction, out cursorStartPosition);

                        //cursorController.HitPhysicsObject.MainWorldTransform.SetPosition(ref cursorStartPosition);
                        //cursorController.HitPhysicsObject.RecalculateMainTransform();
                    }
                }

                if (cursorController.HitPhysicsObject.Integral.IsStatic && (cursorController.HitPhysicsObject.InternalControllers.FluidController != null) && cursorController.HitPhysicsObject.InternalControllers.FluidController.Enabled)
                {
                    Vector3 cursorStartPosition = vectorZero;
                    Vector3 cursorEndPosition   = vectorZero;

                    cursorController.GetAnchor1(ref cursorStartPosition);
                    cursorController.GetAnchor2(ref cursorEndPosition);

                    Vector3.Subtract(ref cursorEndPosition, ref cursorStartPosition, out direction);

                    if (direction.LengthSquared != 0.0f)
                    {
                        // To move the fluid surface by the cursor, add the following lines of code
                        // and set EnableCursorInteraction flag to true in the Lake class

                        //cursorController.HitPhysicsObject.MainWorldTransform.GetPosition(ref cursorStartPosition);

                        //Vector3.Add(ref cursorStartPosition, ref direction, out cursorStartPosition);

                        //cursorController.HitPhysicsObject.MainWorldTransform.SetPosition(ref cursorStartPosition);
                        //cursorController.HitPhysicsObject.RecalculateMainTransform();
                    }
                }
            }

            objectBase.MainWorldTransform.GetPosition(ref listenerPosition);
            objectBase.Camera.GetTransposeRotation(ref rotation);

            Vector3.Multiply(ref listenerPosition, soundPositionFactor, out position);
            listenerTopDirection.X   = rotation.Row1.X;
            listenerTopDirection.Y   = rotation.Row1.Y;
            listenerTopDirection.Z   = rotation.Row1.Z;
            listenerFrontDirection.X = rotation.Row2.X;
            listenerFrontDirection.Y = rotation.Row2.Y;
            listenerFrontDirection.Z = rotation.Row2.Z;

            listener.Position       = position;
            listener.TopDirection   = listenerTopDirection;
            listener.FrontDirection = listenerFrontDirection;
            listenerRange           = objectBase.Sound.Range;

            if (enableShot)
            {
                Vector3 shotScale, shotColor;

                shotCount = (shotCount + 1) % shotTab.Length;
                string shotCountName = shotCount.ToString();

                PhysicsObject shot      = scene.Factory.PhysicsObjectManager.FindOrCreate(shotName + shotCountName);
                PhysicsObject shotBase  = scene.Factory.PhysicsObjectManager.FindOrCreate(shotBaseName + shotCountName);
                PhysicsObject shotLight = scene.Factory.PhysicsObjectManager.FindOrCreate(shotLightName + shotCountName);

                shot.AddChildPhysicsObject(shotBase);
                shot.AddChildPhysicsObject(shotLight);

                shotTab[shotCount] = shotBase;
                enableShotTab      = true;

                shotScale = shotColor = vectorZero;

                shotScale.X = shotScale.Y = shotScale.Z = 0.5f;
                Vector3.Multiply(ref rayDirection, 300.0f, out rayDirection);

                shot.InitLocalTransform.SetRotation(ref matrixIdentity);
                shot.InitLocalTransform.SetPosition(ref rayPosition);
                shot.InitLocalTransform.SetLinearVelocity(ref rayDirection);
                shot.InitLocalTransform.SetAngularVelocity(ref vectorZero);
                shot.MaxSimulationFrameCount = 200;
                shot.EnableRemovePhysicsObjectsFromManagerAfterMaxSimulationFrameCount = false;
                //shot.EnableLocalGravity = true;

                shotBase.Shape       = sphere;
                shotBase.UserDataStr = sphereName;
                shotBase.InitLocalTransform.SetScale(ref shotScale);
                shotBase.Integral.SetDensity(10.0f);
                shotBase.Material.RigidGroup   = true;
                shotBase.EnableBreakRigidGroup = false;
                shotBase.EnableCollisions      = true;
                shotBase.CreateSound(true);

                if ((cameraUp != null) && (cameraBody != null) && (cameraDown != null))
                {
                    shotBase.DisableCollision(cameraUp, true);
                    shotBase.DisableCollision(cameraBody, true);
                    shotBase.DisableCollision(cameraDown, true);
                    shotBase.MaxDisableCollisionFrameCount = 50;
                }

                shotLight.Shape       = sphere;
                shotLight.UserDataStr = sphereName;
                shotLight.CreateLight(true);
                shotLight.Light.Type  = PhysicsLightType.Point;
                shotLight.Light.Range = 20.0f;

                shotColor.X = (float)Math.Max(random.NextDouble(), random.NextDouble());
                shotColor.Y = (float)Math.Max(random.NextDouble(), random.NextDouble());
                shotColor.Z = (float)Math.Max(random.NextDouble(), random.NextDouble());

                shotLight.Light.SetDiffuse(ref shotColor);
                shotLight.InitLocalTransform.SetScale(20.0f);
                shotLight.Material.RigidGroup     = true;
                shotLight.Material.UserDataStr    = yellowName;
                shotLight.EnableBreakRigidGroup   = false;
                shotLight.EnableCollisions        = false;
                shotLight.EnableCursorInteraction = false;
                shotLight.EnableAddToCameraDrawTransparentPhysicsObjects = false;

                scene.UpdateFromInitLocalTransform(shot);

                shotSoundGroup = demo.SoundGroups[hitName];
                shotSoundGroup.MaxHitRepeatTime = 0.0f;

                if (shotSound == null)
                {
                    shotSound = shotSoundGroup.GetSound(objectBase.Sound, listener, emitter);
                }

                shotSound.Update(time);

                Vector3.Multiply(ref rayPosition, soundPositionFactor, out shotSound.HitPosition);
                shotSound.HitVolume = 1.0f;

                shotSound.FrontDirection.X = rotation.Row2.X;
                shotSound.FrontDirection.Y = rotation.Row2.Y;
                shotSound.FrontDirection.Z = rotation.Row2.Z;

                demo.SoundQueue.EnqueueSound(shotSound);
            }
            else
            {
                PhysicsObject shotBase;
                DemoSound     shotBaseSound;

                if (shotSound != null)
                {
                    shotSound.Update(time);

                    if (shotSound.Stop())
                    {
                        shotSound.SoundGroup.SetSound(shotSound);
                        shotSound = null;
                    }
                }

                if (enableShotTab)
                {
                    enableShotTab = false;

                    for (int i = 0; i < shotTab.Length; i++)
                    {
                        shotBase = shotTab[i];

                        if (shotBase != null)
                        {
                            if (shotBase.Sound.UserDataObj != null)
                            {
                                enableShotTab = true;
                                shotBaseSound = (DemoSound)shotBase.Sound.UserDataObj;
                                shotBaseSound.Update(time);

                                if (shotBaseSound.Stop())
                                {
                                    shotBaseSound.SoundGroup.SetSound(shotBaseSound);
                                    shotBase.Sound.UserDataObj = null;
                                    shotTab[i] = null;
                                }
                            }
                        }
                    }
                }
            }

            objectBase.Camera.UpdatePhysicsObjects(true, true, true);
            objectBase.Camera.SortDrawPhysicsObjects(PhysicsCameraSortOrderType.DrawPriorityShapePrimitiveType);
            objectBase.Camera.SortTransparentPhysicsObjects(PhysicsCameraSortOrderType.DrawPriorityShapePrimitiveType);
            objectBase.Camera.SortLightPhysicsObjects(PhysicsCameraSortOrderType.DrawPriorityShapePrimitiveType);

            PhysicsObject  currentPhysicsObject;
            PhysicsSound   currentSound;
            DemoSoundGroup soundGroup;
            DemoSound      sound;

            if (demo.SoundQueue.SoundCount > 0)
            {
                return;
            }

            for (int i = 0; i < scene.TotalPhysicsObjectCount; i++)
            {
                if (demo.SoundQueue.SoundCount >= demo.SoundQueue.MaxSoundCount)
                {
                    break;
                }

                currentPhysicsObject = scene.GetPhysicsObject(i);

                currentSound = !currentPhysicsObject.EnableSoundFromRigidGroupOwner ? currentPhysicsObject.Sound : currentPhysicsObject.RigidGroupOwner.Sound;

                if (currentSound == null)
                {
                    continue;
                }

                if (!currentSound.Enabled)
                {
                    continue;
                }

                if (currentSound.UserDataStr == null)
                {
                    soundGroup = demo.SoundGroups[defaultName];
                }
                else
                {
                    soundGroup = demo.SoundGroups[currentSound.UserDataStr];
                }

                if (currentPhysicsObject.IsSleeping && (currentSound.UserDataObj == null) && !soundGroup.EnableBackground)
                {
                    continue;
                }

                if (currentPhysicsObject.GetSoundData(ref listenerPosition, listenerRange, soundGroup.EnableHit, soundGroup.EnableRoll, soundGroup.EnableSlide, soundGroup.EnableBackground, currentSound.BackgroundVolumeVelocityModulation, ref hitPosition, ref rollPosition, ref slidePosition, ref backgroundPosition, ref hitVolume, ref rollVolume, ref slideVolume, ref backgroundVolume))
                {
                    if (currentSound.UserDataObj == null)
                    {
                        sound = soundGroup.GetSound(currentSound, listener, emitter);
                        currentSound.UserDataObj = sound;
                    }
                    else
                    {
                        sound = (DemoSound)currentSound.UserDataObj;
                    }

                    sound.Update(time);

                    currentPhysicsObject.MainWorldTransform.GetTransposeRotation(ref rotation);

                    Vector3.Multiply(ref hitPosition, soundPositionFactor, out sound.HitPosition);
                    Vector3.Multiply(ref rollPosition, soundPositionFactor, out sound.RollPosition);
                    Vector3.Multiply(ref slidePosition, soundPositionFactor, out sound.SlidePosition);
                    Vector3.Multiply(ref backgroundPosition, soundPositionFactor, out sound.BackgroundPosition);

                    sound.HitVolume        = hitVolume;
                    sound.RollVolume       = rollVolume;
                    sound.SlideVolume      = slideVolume;
                    sound.BackgroundVolume = backgroundVolume;

                    sound.FrontDirection.X = rotation.Row2.X;
                    sound.FrontDirection.Y = rotation.Row2.Y;
                    sound.FrontDirection.Z = rotation.Row2.Z;

                    demo.SoundQueue.EnqueueSound(sound);
                }
                else
                {
                    if (currentSound.UserDataObj != null)
                    {
                        sound = (DemoSound)currentSound.UserDataObj;
                        sound.Update(time);

                        if (sound.Stop())
                        {
                            soundGroup.SetSound(sound);
                            currentSound.UserDataObj = null;
                        }
                    }
                }
            }
        }