Esempio n. 1
0
        public void Initialize(RaceFile race)
        {
            if (SmokeTableIndex > 1)
            {
                //-2 because index is 1-based in race file and #1 is the default (no smoke)
                SmokeParticles = new MaterialSmokeParticleSystem(race.SmokeTables[SmokeTableIndex - 2]);
                _emitter = new ParticleEmitter(SmokeParticles, 5, Vector3.Zero);
            }

            if (_defaultTyreSmokeSystem == null)
                _defaultTyreSmokeSystem = new TyreSmokeParticleSystem();
        }
Esempio n. 2
0
        public static Actor GenerateTrackActor(RaceFile file, CActorHierarchy actors, out List<NonCar> nonCarInstances)
        {
            List<Vector3> verts = new List<Vector3>();
            List<ushort> indices = new List<ushort>();
            List<ushort> materialIndices = new List<ushort>();
            List<OpenC1.CActor> actorsList = actors.All();
            nonCarInstances = new List<NonCar>();

            for (int i = 0; i < actorsList.Count; i++)
            {
                CActor actor = actorsList[i];
                if (actor.Model == null) continue;
                if (actor.Name.StartsWith("&"))
                {
                    if (Char.IsDigit(actor.Name[1]) && Char.IsDigit(actor.Name[2]))
                    {
                        NonCar nc = GenerateNonCar(actor, file.NonCars);
                        if (nc != null)
                        {
                            nonCarInstances.Add(nc);
                            continue;  //dont-merge with track
                        }
                    }
                }

                int baseIndex = verts.Count;
                for (int j = 0; j < actor.Model.VertexCount; j++)
                    verts.Add(Vector3.Zero);

                foreach (Polygon poly in actor.Model.Polygons)
                {
                    if (poly.MaterialIndex < 0)
                        continue;

                    string materialName = actor.Model.MaterialNames == null ? "none" : actor.Model.MaterialNames[poly.MaterialIndex];
                    //this is a non-solid material
                    if (materialName.StartsWith("!"))
                        continue;

                    int index = baseIndex + poly.Vertex1;

                    indices.Add((ushort)index);
                    if (verts[index] == Vector3.Zero)
                    {
                        Vector3 transformedVec = Vector3.Transform(actors.Models._vertexPositions[actor.Model.VertexBaseIndex + poly.Vertex1], actor.Matrix);
                        verts[index] = transformedVec;
                    }
                    index = baseIndex + poly.Vertex2;
                    indices.Add((ushort)index);
                    if (verts[index] == Vector3.Zero)
                    {
                        Vector3 transformedVec = Vector3.Transform(actors.Models._vertexPositions[actor.Model.VertexBaseIndex + poly.Vertex2], actor.Matrix);
                        verts[index] = transformedVec;
                    }
                    index = baseIndex + poly.Vertex3;
                    indices.Add((ushort)index);
                    if (verts[index] == Vector3.Zero)
                    {
                        Vector3 transformedVec = Vector3.Transform(actors.Models._vertexPositions[actor.Model.VertexBaseIndex + poly.Vertex3], actor.Matrix);
                        verts[index] = transformedVec;
                    }

                    if (Char.IsDigit(materialName[0]))
                    {
                        ushort matModiferId = (ushort)(ushort.Parse(materialName.Substring(0, 1)) + 1);
                        if (matModiferId >= file.MaterialModifiers.Count) matModiferId = 0;

                        materialIndices.Add(matModiferId);
                    }
                    else
                        materialIndices.Add(0);
                }
            }

            TriangleMeshDescription meshDesc = new TriangleMeshDescription();
            meshDesc.TriangleCount = indices.Count / 3;
            meshDesc.VertexCount = verts.Count;

            meshDesc.AllocateVertices<Vector3>(meshDesc.VertexCount);
            meshDesc.AllocateTriangles<ushort>(meshDesc.TriangleCount);
            meshDesc.AllocateMaterialIndices<ushort>(materialIndices.Count);

            meshDesc.TriangleStream.SetData(indices.ToArray());
            meshDesc.VerticesStream.SetData(verts.ToArray());
            meshDesc.MaterialIndicesStream.SetData(materialIndices.ToArray());
            meshDesc.Flags = MeshFlag.Indices16Bit;

            MemoryStream s = new MemoryStream();

            Cooking.InitializeCooking();
            Cooking.CookTriangleMesh(meshDesc, s);
            Cooking.CloseCooking();

            s.Position = 0;
            TriangleMesh triangleMesh = PhysX.Instance.Core.CreateTriangleMesh(s);

            TriangleMeshShapeDescription shape = new TriangleMeshShapeDescription()
            {
                TriangleMesh = triangleMesh,
            };

            ActorDescription actorDescription = new ActorDescription()
            {
                GlobalPose = Matrix.CreateTranslation(0, 0, 0),
                Shapes = { shape }
            };

            foreach (Checkpoint checkpoint in file.Checkpoints)
            {
                ActorDescription actorDesc = new ActorDescription();

                BoxShapeDescription box = new BoxShapeDescription(checkpoint.BBox.GetSize());
                box.Flags = ShapeFlag.TriggerOnEnter | ShapeFlag.Visualization;
                actorDesc.Shapes.Add(box);
                Actor actor = PhysX.Instance.Scene.CreateActor(actorDesc);
                actor.GlobalPosition = checkpoint.BBox.GetCenter();
                actor.UserData = checkpoint;
            }

            StillDesign.PhysX.Actor environment = PhysX.Instance.Scene.CreateActor(actorDescription);
            environment.Group = PhysXConsts.TrackId;
            environment.Shapes[0].SetFlag(ShapeFlag.Visualization, false);

            CreateDefaultWaterSpecVols(file, actorsList, actors.Models);

            for (int i = 1; i < file.SpecialVolumes.Count; i++)
            {
                SpecialVolume vol = file.SpecialVolumes[i];

                Vector3 scale = new Vector3();
                Vector3 trans = new Vector3();
                Quaternion q = new Quaternion();
                Matrix matrix = vol.Matrix;
                bool success = matrix.Decompose(out scale, out q, out trans);
                if (scale.Z == 0) scale.Z = 0.1f;

                ActorDescription actorDesc = new ActorDescription();
                BoxShapeDescription box = new BoxShapeDescription(scale);

                if (success)
                {
                    if (float.IsNaN(q.X))
                        continue;
                    box.LocalRotation = Matrix.CreateFromQuaternion(q);
                }
                else
                {
                    //if the matrix cannot be decomposed, like part of the long tunnel in coasta...
                    // get the rotation by calculating some points and working out rotation from them
                    Vector3 v1 = Vector3.Transform(new Vector3(-1, -1, 1), matrix);
                    Vector3 v2 = Vector3.Transform(new Vector3(-1, 1, -1), matrix);
                    Vector3 forwards = v2 - v1;
                    forwards.Normalize();
                    box.LocalRotation = Matrix.CreateWorld(Vector3.Zero, forwards, Vector3.Up);
                }

                box.Flags = ShapeFlag.TriggerOnEnter | ShapeFlag.TriggerOnLeave | ShapeFlag.Visualization;
                actorDesc.Shapes.Add(box);
                Actor actor = PhysX.Instance.Scene.CreateActor(actorDesc);

                actor.GlobalPosition = vol.Matrix.Translation;
                actor.UserData = vol;
            }

            return environment;
        }
Esempio n. 3
0
        public Race(string filename, string playerVehicleFile)
        {
            Race.Current = this;

            Logger.Log("Starting race " + Path.GetFileName(filename));

            ConfigFile = new RaceFile(filename);

            foreach (string matFileName in ConfigFile.MaterialFiles)
            {
                MatFile matFile = new MatFile(matFileName);
                ResourceCache.Add(matFile);
            }

            foreach (string pixFileName in ConfigFile.PixFiles)
            {
                PixFile pixFile = new PixFile(pixFileName);
                ResourceCache.Add(pixFile);
            }

            if (GameVars.Emulation == EmulationMode.Demo)
                ResourceCache.Add(new CMaterial("drkcurb.mat", 226)); //demo doesn't have this file, I guess the color is hard-coded
            else
                ResourceCache.Add(new MatFile("drkcurb.mat"));

            ResourceCache.ResolveMaterials();

            if (filename.Contains("TESTMAP")) //nasty hack...
                GameVars.Scale.Y *= 0.5f;

            DatFile modelFile = new DatFile(ConfigFile.ModelFile);

            ActFile actFile = new ActFile(ConfigFile.ActorFile);
            _actors = actFile.Hierarchy;
            _actors.AttachModels(modelFile.Models);
            _actors.ResolveTransforms(false, ConfigFile.Grooves);

            if (filename.Contains("TESTMAP")) //nasty hack...
                GameVars.Scale.Y *= 2f;

            // link the actors and grooves
            foreach (BaseGroove g in ConfigFile.Grooves)
                g.SetActor(_actors.GetByName(g.ActorName));

            // link the funks and materials
            foreach (BaseFunk f in ConfigFile.Funks)
            {
                f.Resolve();
            }

            if (ConfigFile.SkyboxTexture != "none")
            {
                PixFile horizonPix = new PixFile(ConfigFile.SkyboxTexture);
                _skybox = SkyboxGenerator.Generate(horizonPix.PixMaps[0].Texture, ConfigFile.SkyboxRepetitionsX - 3f, ConfigFile.DepthCueMode);
                _skybox.HeightOffset = -220 + ConfigFile.SkyboxPositionY * 1.5f;
            }

            Physics.TrackProcessor.GenerateTrackActor(ConfigFile, _actors, out _nonCars);

            Logger.Log("NonCars: " + _nonCars.Count);

            GridPlacer.Reset();

            List<int> opponentIds = new List<int>();
            List<int> pickedNbrs = new List<int>();
            for (int i = 0; i < 5; i++)
            {
                int index = 0;
                while (true)
                {
                    index = Engine.Random.Next(1, OpponentsFile.Instance.Opponents.Count);
                    if (!pickedNbrs.Contains(index))
                    {
                        pickedNbrs.Add(index);
                        break;
                    }
                }
                try
                {
                    Opponents.Add(new Opponent(OpponentsFile.Instance.Opponents[index].FileName, ConfigFile.GridPosition, ConfigFile.GridDirection));
                    NbrOpponents++;
                }
                catch(Exception ex)
                {
                    Logger.Log("Error while loading opponent " + OpponentsFile.Instance.Opponents[index].FileName + ", " + ex.Message);
                }
            }

            foreach (CopStartPoint point in ConfigFile.CopStartPoints)
            {
                Opponents.Add(new Opponent(point.IsSpecialForces ? "bigapc.txt" : "apc.txt", point.Position, 0, new CopDriver()));
            }

            foreach (Opponent o in Opponents) Drivers.Add(o.Driver);

            OpponentController.Nodes = ConfigFile.OpponentPathNodes;

            PlayerVehicle = new Vehicle(GameVars.BasePath + @"cars\" + playerVehicleFile, new PlayerDriver());
            PlayerVehicle.PlaceOnGrid(ConfigFile.GridPosition, ConfigFile.GridDirection);
            Drivers.Add(PlayerVehicle.Driver);

            Peds = new PedestrianController(ConfigFile.Peds);
            _map = new RaceMap(this);

            RaceTime = new RaceTimeController();

            PhysX.Instance.Scene.SetActorGroupPairFlags(PhysXConsts.TrackId, PhysXConsts.VehicleId, ContactPairFlag.Forces | ContactPairFlag.OnStartTouch | ContactPairFlag.OnTouch);
            PhysX.Instance.Scene.SetActorGroupPairFlags(PhysXConsts.VehicleId, PhysXConsts.NonCarId, ContactPairFlag.Forces | ContactPairFlag.OnStartTouch | ContactPairFlag.OnTouch);
            PhysX.Instance.Scene.SetActorGroupPairFlags(PhysXConsts.TrackId, PhysXConsts.NonCarId, ContactPairFlag.OnTouch);
            PhysX.Instance.Scene.SetActorGroupPairFlags(PhysXConsts.VehicleId, PhysXConsts.VehicleId, ContactPairFlag.Forces | ContactPairFlag.OnTouch | ContactPairFlag.OnStartTouch | ContactPairFlag.OnEndTouch);
        }
Esempio n. 4
0
        private static void CreateDefaultWaterSpecVols(RaceFile file, List<CActor> actors, CModelGroup models)
        {
            // Water specvols don't seem to be included anywhere in the map definition. We figure them out here by
            // looking for non-solid horizontal polygons

            if (file.SpecialVolumes.Count == 0) return;

            for (int i = 0; i < actors.Count; i++)
            {
                CActor actor = actors[i];
                if (actor.Model == null) continue;

                CModel model = actor.Model;
                bool foundWater = false;
                Vector3 min = new Vector3(9999), max = new Vector3(-9999);
                List<Vector3> waterVerts = new List<Vector3>();
                foreach (Polygon poly in model.Polygons)
                {
                    if (poly.MaterialIndex < 0) continue;
                    string materialName = actor.Model.MaterialNames == null ? "none" : actor.Model.MaterialNames[poly.MaterialIndex];
                    //this is a non-solid material
                    if (materialName.StartsWith("!"))
                    {
                        // if this is a flat horizontal plane, mark it as water
                        float y1 = models._vertexPositions[model.VertexBaseIndex + poly.Vertex1].Y;
                        float y2 = models._vertexPositions[model.VertexBaseIndex + poly.Vertex2].Y;
                        float y3 = models._vertexPositions[model.VertexBaseIndex + poly.Vertex3].Y;

                        if (Math.Abs(y1 - y2) < 0.15f && Math.Abs(y1 - y3) < 0.15f)
                        {
                            foundWater = true;
                            waterVerts.Add(Vector3.Transform(models._vertexPositions[model.VertexBaseIndex + poly.Vertex1], actor.Matrix));
                            waterVerts.Add(Vector3.Transform(models._vertexPositions[model.VertexBaseIndex + poly.Vertex2], actor.Matrix));
                            waterVerts.Add(Vector3.Transform(models._vertexPositions[model.VertexBaseIndex + poly.Vertex3], actor.Matrix));
                        }
                    }
                }

                if (foundWater)
                {
                    //add a bottom
                    waterVerts.Add(new Vector3(waterVerts[0].X, waterVerts[0].Y - 6 * GameVars.Scale.Y, waterVerts[0].Z));

                    BoundingBox bb = BoundingBox.CreateFromPoints(waterVerts);

                    Matrix m = Matrix.CreateScale(bb.GetSize()) * Matrix.CreateTranslation(bb.GetCenter());

                    SpecialVolume vol = file.SpecialVolumes[0].Copy(); //copy default water
                    vol.Matrix = m;
                    file.SpecialVolumes.Add(vol);
                }
            }
        }