Exemple #1
0
        /// <summary>
        /// Draws a collision shape. Mesh draw code is taken from the XNA Vertex Lighting Sample
        /// </summary>
        /// <param name="shape"></param>
        /// <param name="modelMatrix"></param>
        public void DrawCollisionShape(ShapeData shape, Matrix modelMatrix)
        {
            if (collisionShapeEffect == null)
            {
                InitCollisionShapeVisualization();
            }

            if (shape is SphereShapeData)
            {
                SphereShapeData sphereData  = (shape as SphereShapeData);
                Matrix          worldMatrix = Matrix.CreateScale(sphereData.Radius) * sphereData.Offset *
                                              modelMatrix;
                DrawCollisionShapeMesh(worldMatrix, sphereMesh);
            }
            else if (shape is BoxShapeData)
            {
                BoxShapeData boxData     = (shape as BoxShapeData);
                Matrix       worldMatrix = Matrix.CreateScale(boxData.Dimensions * 0.7f) * Matrix.CreateFromQuaternion(Quaternion.Inverse(Quaternion.CreateFromRotationMatrix(boxData.Offset))) * Matrix.CreateTranslation(boxData.Offset.Translation) * modelMatrix;
                DrawCollisionShapeMesh(worldMatrix, cubeMesh);
            }
            else if (shape is MeshShapeData)
            {
                MeshShapeData meshData    = (shape as MeshShapeData);
                Matrix        worldMatrix = meshData.Offset * modelMatrix;
                DrawCollisionMeshShape(worldMatrix, meshData);
            }
        }
Exemple #2
0
        public void EnablePlayerPhysics()
        {
            //// Crate Player Shape:
            SphereShapeData sData = new SphereShapeData();

            sData.Radius = 5;
            player.AddShape(sData);
        }
Exemple #3
0
        public Blast(ICanyonShooterGame game, ContactGroup contactGroup, Vector3 position, float force, float radius)
        {
            // TODO fix ode errors on multithreading

            if (!game.Physics.MultiThreading)
            {
                SphereShapeData sphere = new SphereShapeData();
                sphere.Radius       = radius;
                sphere.ContactGroup = (int)contactGroup;

                ShapeData[] shapes = new ShapeData[1];
                shapes[0] = sphere;

                VolumeQueryResult result = game.Physics.VolumeQuery(
                    Matrix.CreateTranslation(position), // transform
                    "Blast Area",                       // name
                    shapes);

                /*    for (int i = 0; i < result.NumSolids; i++)
                 *  {
                 *      Solid s = result.GetSolid(i);
                 *      ITransformable t = s.UserData as ITransformable;
                 *
                 *      if (t != null)
                 *      {
                 *          Vector3 direction = t.GlobalPosition - position;
                 *
                 *          float distance = direction.Length();
                 *
                 *          if (distance < radius)
                 *          {
                 *              float attenuation = 1.0f - distance/radius;
                 *
                 *              Force f = new Force();
                 *
                 *              // TODO make the force single step.
                 *              //f.SingleStep = true;
                 *              f.Duration = 0.1f;
                 *
                 *              f.Type = ForceType.GlobalForce;
                 *              f.Direction = attenuation*attenuation*force*Vector3.Normalize(direction);
                 *
                 *              t.AddForce(f);
                 *          }
                 *      }
                 *  }*/
            }
        }
Exemple #4
0
        public UltraPhaserProjectile(ICanyonShooterGame game, Vector3 startPosition, Vector3 direction, UltraPhaser owner, WeaponHolderType weaponHolderType)
            : base(game, startPosition, direction, "Lasergun", weaponHolderType)
        {
            this.game  = game;
            this.Owner = owner;

            // ist nur instanz von einem model, daher nicht selbst anzeigen sondern durch die waffe
            Visible = false;

            if (direction.Length() > 0)
            {
                direction.Normalize();
            }

            Velocity = direction * 500 + owner.Velocity;

            //add Collision Hit Object:
            SphereShapeData hitObject = new SphereShapeData();

            hitObject.Radius              = 0.1f;
            hitObject.Material.Hardness   = 0.1f;
            hitObject.Material.Bounciness = 0.0f;
            hitObject.Material.Friction   = 1.0f;
            hitObject.Material.Density    = 1000f;
            hitObject.ContactGroup        = (int)ContactGroup;

            AddShape(hitObject);
            InfluencedByGravity = false;

            AutoDestruction     = true;
            AutoDestructionTime = TimeSpan.FromSeconds(2);

            Rotation = Helper.RotateTo(direction, DefaultDirection);

            // Größe der Laserstrahlen
            LocalScale = new Vector3(0.5f, 0, 5);

            // initialize the rotation
            MakeRotation();
        }
Exemple #5
0
        protected void Load(string name, InstancingType instancing)
        {
            if (name == null || name == string.Empty)
            {
                return;
            }

            // load description
            ModelDescription desc = game.Content.Load <ModelDescription>(".\\Content\\Models\\" + name + "Desc");

            LocalRotation = Quaternion.CreateFromAxisAngle(desc.BaseRotationAxis, MathHelper.ToRadians(desc.BaseRotationAngle));

            // load fbx
            Microsoft.Xna.Framework.Graphics.Model model = game.Content.Load <Microsoft.Xna.Framework.Graphics.Model>(".\\Content\\Models\\" + desc.BaseFBX);

            // process meshes
            foreach (ModelMesh modelmesh in model.Meshes)
            {
                // wrap ModelMesh in adapter
                IMesh mesh;
                switch (instancing)
                {
                case InstancingType.None:
                    mesh = new ModelMeshAdapterMesh(game, modelmesh);
                    break;

                case InstancingType.Constants:
                    mesh = new ConstantsInstancingModelMeshAdapterMesh(game, modelmesh);
                    break;

                case InstancingType.Hardware:
                    mesh = new HardwareInstancingModelMeshAdapterMesh(game, modelmesh);
                    break;

                default:
                    throw new Exception();
                }
                mesh.Parent = this;
                meshes.Add(mesh);

                // get material name. prefer the one with the mesh's name before *
                string materialName = "";
                foreach (MeshMaterial matdesc in desc.Materials)
                {
                    if (matdesc.MeshName == modelmesh.Name)
                    {
                        materialName = matdesc.MaterialName;
                        break;
                    }
                    if (matdesc.MeshName == "*")
                    {
                        if (materialName == "")
                        {
                            materialName = matdesc.MaterialName;
                        }
                    }
                }

                // load material
                Material material = Material.Create(game, materialName, instancing);
                materials.Add(material);

                // tell the mesh which effect to use
                mesh.Effect = material.Effect;
            }

            // get weapon slots
            foreach (WeaponDescription weapon in desc.Weapons)
            {
                WeaponSlot slot = new WeaponSlot(
                    (WeaponType)Enum.Parse(typeof(WeaponType), weapon.WeaponType, false),
                    weapon.Position,
                    weapon.RotationAxis,
                    weapon.RotationAngle,
                    weapon.Scaling);

                weaponSlots.Add(slot);
            }

            // get collision shapes
            foreach (Box box in desc.CollisionShapes.Boxes)
            {
                BoxShapeData shape = new BoxShapeData();
                shape.Dimensions = box.Size;
                Matrix m = Matrix.CreateFromQuaternion(Quaternion.CreateFromAxisAngle(box.OffsetRotationAxis, box.OffsetRotationAngle));
                m.Translation             = box.OffsetPosition;
                shape.Offset              = m;
                shape.Material.Friction   = desc.Friction;
                shape.Material.Bounciness = desc.Bounciness;
                shape.Material.Hardness   = desc.Hardness;
                collisionShapes.Add(shape);
            }
            foreach (Capsule capsule in desc.CollisionShapes.Capsules)
            {
                CapsuleShapeData shape = new CapsuleShapeData();
                shape.Radius = capsule.Radius;
                shape.Length = capsule.Length;
                Matrix m = Matrix.CreateFromQuaternion(Quaternion.CreateFromAxisAngle(capsule.OffsetRotationAxis, capsule.OffsetRotationAngle));
                m.Translation             = capsule.OffsetPosition;
                shape.Offset              = m;
                shape.Material.Friction   = desc.Friction;
                shape.Material.Bounciness = desc.Bounciness;
                shape.Material.Hardness   = desc.Hardness;
                collisionShapes.Add(shape);
            }
            foreach (Sphere sphere in desc.CollisionShapes.Spheres)
            {
                SphereShapeData shape = new SphereShapeData();
                shape.Radius = sphere.Radius;
                Matrix m = Matrix.CreateTranslation(sphere.OffsetPosition);
                shape.Offset              = m;
                shape.Material.Friction   = desc.Friction;
                shape.Material.Bounciness = desc.Bounciness;
                shape.Material.Hardness   = desc.Hardness;
                collisionShapes.Add(shape);
            }

            wreckageModels = desc.Wreckages;

            // get particle effects
            if (game.World != null)
            {
                foreach (ParticleEffectDescription effect in desc.ParticleEffects)
                {
                    IEffect fx = game.Effects.CreateEffect(effect.EffectName);
                    fx.Parent        = this;
                    fx.LocalPosition = effect.Position;
                    fx.LocalRotation = Quaternion.CreateFromAxisAngle(effect.RotationAxis, effect.RotationAngle);
                    fx.LocalScale    = effect.Scaling;
                    game.World.AddEffect(fx);
                    particleEffects.Add(fx); // for calling Destroy() later
                    fx.Play();
                }
            }

            // afterburner
            foreach (AfterBurnerEffectDescription ab in desc.AfterBurnerEffects)
            {
                AfterBurner a = new AfterBurner(game);

                a.Parent = this;

                a.LocalPosition = ab.Position;
                a.LocalScale    = ab.Scaling;
                a.LocalRotation = Quaternion.CreateFromAxisAngle(ab.RotationAxis, ab.RotationAngle);

                a.LoadTheContent();

                afterBurnerEffects.Add(a);
            }

            // get animations
            foreach (MeshAnimation anim in desc.Animations)
            {
                foreach (IMesh mesh in meshes)
                {
                    if (mesh.Name == anim.MeshName)
                    {
                        mesh.Animation = anim;

                        break; // inner foreach
                    }
                }
            }

            // mass
            mass = desc.Mass;

            // base rotation
            LocalRotation = Quaternion.CreateFromAxisAngle(desc.BaseRotationAxis, desc.BaseRotationAngle);

            // save name
            this.name = name;
        }
Exemple #6
0
        public override void AddShape(ShapeData data)
        {
            if (data.Material.Density < 0)
            {
                return;
            }

            dGeomID        newGeomID        = null;
            dGeomID        newTransformID   = null;
            dTriMeshDataID newTrimeshDataID = null;
            dSpaceID       tempSpaceID      = null;

            Tao.Ode.Ode.dMass newMass = new Tao.Ode.Ode.dMass();

            if (new Matrix() == data.Offset)
            {
                // No offset transform.
                tempSpaceID    = spaceID;
                newTransformID = null;
            }
            else
            {
                // Use ODE's geom transform object.
                tempSpaceID    = IntPtr.Zero;
                newTransformID = spaceID.CreateGeomTransform();
            }

            // Allocate a new GeomData object.
            GeomData newGeomData = new GeomData();

            switch (data.Type)
            {
            case ShapeType.Box:
            {
                BoxShapeData boxData = data as BoxShapeData;

                newGeomID = tempSpaceID.CreateBoxGeom(boxData.Dimensions.X,
                                                      boxData.Dimensions.Y,
                                                      boxData.Dimensions.Z);

                Tao.Ode.Ode.dMassSetBox(ref newMass, data.Material.Density,
                                        boxData.Dimensions.X,
                                        boxData.Dimensions.Y,
                                        boxData.Dimensions.Z);
                break;
            }

            case ShapeType.Sphere:
            {
                SphereShapeData sphereData = data as SphereShapeData;

                newGeomID = tempSpaceID.CreateSphereGeom(sphereData.Radius);

                Tao.Ode.Ode.dMassSetSphere(ref newMass, data.Material.Density, sphereData.Radius);
                break;
            }

            case ShapeType.Capsule:
            {
                CapsuleShapeData capsuleData = data as CapsuleShapeData;

                newGeomID = tempSpaceID.CreateCylinderGeom(capsuleData.Radius, capsuleData.Length);

                // The "direction" parameter orients the mass along one of the
                // body's local axes; x=1, y=2, z=3.  This axis MUST
                // correspond with the axis along which the capsule is
                // initially aligned, which is the capsule's local Z axis.

                /*Tao.Ode.Ode.dMassSetCylinder(ref newMass, data.Material.Density,
                 *                      3, capsuleData.Radius, capsuleData.Length);*/
                Tao.Ode.Ode.dMassSetCapsule(ref newMass, data.Material.Density, 3,
                                            capsuleData.Radius, capsuleData.Length);
                break;
            }

            case ShapeType.Plane:
            {
                PlaneShapeData planeData = data as PlaneShapeData;
                if (!this.data.IsStatic)
                {
                    //OPAL_LOGGER( "warning" ) << "opal::ODESolid::addPlane: " <<
                    //"Plane Shape added to a non-static Solid.  " <<
                    //"The Solid will be made static." << std::endl;

                    // ODE planes can't have bodies, so make it static.
                    this.Static = true;
                }

                // TODO: make this fail gracefully and print warning: plane
                // offset transform ignored.
                if (newTransformID != null)
                {
                    break;
                }

                // ODE planes must have their normal vector (abc) normalized.
                Vector3 normal = new Vector3(planeData.Abcd[0], planeData.Abcd[1], planeData.Abcd[2]);
                normal.Normalize();

                newGeomID = tempSpaceID.CreatePlaneGeom(normal.X, normal.Y, normal.Z, planeData.Abcd[3]);

                // Note: ODE planes cannot have mass, but this is already
                // handled since static Solids ignore mass.

                // Solids with planes are the only non-"placeable" Solids.
                isPlaceable = false;
                break;
            }

            //case RAY_SHAPE:
            //{
            //	RayShapeData& rayData = (RayShapeData&)data;
            //	newGeomID = dCreateRay(spaceID,
            //		(dReal)rayData.ray.getLength());
            //	Point3r origin = rayData.ray.getOrigin();
            //	Vec3r dir = rayData.ray.getDir();
            //	dGeomRaySet(newGeomID, (dReal)origin[0], (dReal)origin[1],
            //		(dReal)origin[2], (dReal)dir[0], (dReal)dir[1],
            //		(dReal)dir[2]);
            //	// Note: rays don't have mass.
            //	break;
            //}
            case ShapeType.Mesh:
            {
                MeshShapeData meshData = data as MeshShapeData;

                // Setup trimesh data pointer.  It is critical that the
                // size of OPAL reals at this point match the size of ODE's
                // dReals.
                newTrimeshDataID = dTriMeshDataID.Create();

                // Old way... This is problematic because ODE interprets
                // the vertex array as an array of dVector3s which each
                // have 4 elements.
                //dGeomTriMeshDataBuildSimple(newTrimeshDataID,
                //	(dReal*)meshData.vertexArray, meshData.numVertices,
                //	(int*)meshData.triangleArray, 3 * meshData.numTriangles);

                //#ifdef dSINGLE
                newTrimeshDataID.BuildSingle(meshData.VertexArray, 3 * sizeof(float),
                                             meshData.NumVertices,
                                             meshData.TriangleArray,
                                             3 * meshData.NumTriangles,
                                             3 * sizeof(int));
                //#else
                //                    dGeomTriMeshDataBuildDouble( newTrimeshDataID,
                //                                                 ( void* ) meshData.vertexArray, 3 * sizeof( real ),
                //                                                 meshData.numVertices, ( void* ) meshData.triangleArray,
                //                                                 3 * meshData.numTriangles, 3 * sizeof( unsigned int ) );
                //#endif

                newGeomID = tempSpaceID.CreateTriMeshGeom(newTrimeshDataID);

                // This is a simple way to set the mass of an arbitrary
                // mesh.  Ideally we would compute the exact volume and
                // intertia tensor.  Instead we just use a box
                // inertia tensor from its axis-aligned bounding box.
                float[] aabb = newGeomID.AABB;

                //					dGeomGetAABB( newGeomID, aabb );
                Tao.Ode.Ode.dMassSetBox(ref newMass, data.Material.Density,
                                        aabb[1] - aabb[0], aabb[3] - aabb[2],
                                        aabb[5] - aabb[4]);
                break;
            }

            default:
                throw new InvalidOperationException("OdeSolid.AddShape");
            }

            // This will do nothing if this is a static Solid.
            AddMass(newMass, data.Offset);

            // Store new Shape.
            this.data.AddShape(data);

            // Update the Solid's local AABB.  The new shape's local AABB
            // must be transformed using the shape's offset from the Solid.
            BoundingBox shapeAABB = data.LocalAABB;
            //data.LocalAABBgetLocalAABB( shapeAABB );
            Vector3 minExtents = Vector3.Transform(shapeAABB.Min, data.Offset);
            Vector3 maxExtents = Vector3.Transform(shapeAABB.Max, data.Offset);

            shapeAABB.Min = minExtents;
            shapeAABB.Max = maxExtents;

            AddToLocalAABB(shapeAABB);

            if (newGeomData == null)
            {
                return;
            }

            // Setup GeomData.
            newGeomData.Solid         = this;
            newGeomData.Shape         = this.data.GetShapeData(this.data.NumShapes - 1);
            newGeomData.GeomID        = newGeomID;
            newGeomData.TransformID   = newTransformID;
            newGeomData.SpaceID       = spaceID;
            newGeomData.TrimeshDataID = newTrimeshDataID;

            // Setup the geom.
            SetupNewGeom(newGeomData);
        }