예제 #1
0
        public void InitializeLot()
        {
            CleanupLastWorld();

            if (FSOEnvironment.Enable3D)
            {
                var rc = new FSO.LotView.RC.WorldRC(GameFacade.GraphicsDevice);
                World = rc;
            }
            else
            {
                World = new FSO.LotView.World(GameFacade.GraphicsDevice);
            }

            World.Opacity = 1;
            GameFacade.Scenes.Add(World);

            var globalLink = new VMTS1GlobalLinkStub();

            Driver = new VMServerDriver(globalLink);

            vm = new VM(new VMContext(World), Driver, new UIHeadlineRendererProvider());
            vm.ListenBHAVChanges();
            vm.Init();

            using (var file = new BinaryReader(File.OpenRead(Path.Combine(FSOEnvironment.ContentDir, "cas.fsov"))))
            {
                var marshal = new FSO.SimAntics.Marshals.VMMarshal();
                marshal.Deserialize(file);
                marshal.PlatformState = new VMTS1LotState();
                vm.Load(marshal);
                vm.Reset();
            }
            vm.Tick();

            vm.Context.Clock.Hours = 12;
            vm.MyUID = uint.MaxValue;
            var settings = GlobalSettings.Default;
            var myClient = new VMNetClient
            {
                PersistID   = uint.MaxValue,
                RemoteIP    = "local",
                AvatarState = new VMNetAvatarPersistState()
                {
                    Name         = settings.LastUser ?? "",
                    DefaultSuits = new VMAvatarDefaultSuits(settings.DebugGender),
                    BodyOutfit   = settings.DebugBody,
                    HeadOutfit   = settings.DebugHead,
                    PersistID    = uint.MaxValue,
                    SkinTone     = (byte)settings.DebugSkin,
                    Gender       = (short)(settings.DebugGender ? 1 : 0),
                    Permissions  = FSO.SimAntics.Model.TSOPlatform.VMTSOAvatarPermissions.Admin,
                    Budget       = 1000000
                }
            };

            var server = (VMServerDriver)Driver;

            server.ConnectClient(myClient);

            HeadAvatars = new VMAvatar[18];
            for (int i = 0; i < 18; i++)
            {
                HeadAvatars[i] = (VMAvatar)vm.Context.CreateObjectInstance(0x7FD96B54, LotTilePos.OUT_OF_WORLD, Direction.NORTH, true).BaseObject;
            }

            BodyAvatars = new VMAvatar[18];
            for (int i = 0; i < 18; i++)
            {
                BodyAvatars[i] = (VMAvatar)vm.Context.CreateObjectInstance(0x7FD96B54, LotTilePos.OUT_OF_WORLD, Direction.NORTH, true).BaseObject;
            }

            PopulateSimType("ma");
        }
        public static void SaveOBJ(string destPath, STR locations)
        {
            var exportedFlr = new HashSet <ushort>();
            var gd          = GameFacade.GraphicsDevice;
            var mtlBuilder  = new StringBuilder();

            Directory.CreateDirectory(destPath);

            //var mtlMem = new MemoryStream();
            //var mtlIO = new StreamWriter(mtlMem);
            var mtlIO = new StreamWriter(new FileStream(Path.Combine(destPath, "neighbourhood.mtl"), FileMode.Create, FileAccess.Write, FileShare.None));

            var path     = Path.Combine(destPath, "neighbourhood.obj");
            var filename = Path.GetFileNameWithoutExtension(path);

            using (var io = new StreamWriter(new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None)))
            {
                io.WriteLine("# Generated by the Simitone Neighbourhood Exporter.");
                io.WriteLine("# The purpose is to allow users to mesh neighbourhood surroundings using");
                io.WriteLine("# the projected physical positions and terrain profiles of lots as a starting point.");

                io.WriteLine("mtllib neighbourhood.mtl");
                io.WriteLine("s 1");

                int indCount = 1;
                for (int i = 0; i < locations.Length; i++)
                {
                    var loc   = locations.GetString(i).Split(',');
                    var num   = int.Parse(loc[0].TrimStart());
                    var pos2d = new Vector2(int.Parse(loc[1].TrimStart()), int.Parse(loc[2].TrimStart()));

                    var house = Content.Get().Neighborhood.GetHouse(num);

                    World world;
                    if (FSOEnvironment.Enable3D)
                    {
                        world = new FSO.LotView.RC.WorldRC(GameFacade.GraphicsDevice);
                    }
                    else
                    {
                        world = new FSO.LotView.World(GameFacade.GraphicsDevice);
                    }

                    world.Opacity = 1;
                    GameFacade.Scenes.Add(world);

                    var globalLink = new VMTS1GlobalLinkStub();
                    var driver     = new VMServerDriver(globalLink);

                    var vm = new VM(new VMContext(world), driver, new UIHeadlineRendererProvider());
                    vm.ListenBHAVChanges();
                    vm.Init();

                    vm.SetGlobalValue(11, (short)num);

                    var activator = new VMTS1Activator(vm, vm.Context.World, (short)num);
                    var blueprint = activator.LoadFromIff(house);

                    var floorVerts = blueprint.Terrain.GetVertices(gd);
                    blueprint.FloorGeom.FullReset(gd, false);
                    var groundfloor = blueprint.FloorGeom.Floors[0];

                    //we need to calculate the
                    var minHeight = int.MaxValue;
                    var heights   = vm.Context.Architecture.Terrain.Heights;
                    for (int j = 0; j < heights.Length; j++)
                    {
                        if ((j % blueprint.Width) == 0 || (j % blueprint.Width) == blueprint.Width - 1 || j < blueprint.Width || j >= (blueprint.Height - 1) * blueprint.Width)
                        {
                            continue;
                        }
                        var h = heights[j];
                        if (h != 0 && h < minHeight)
                        {
                            minHeight = h;
                        }
                    }
                    if (minHeight == int.MaxValue)
                    {
                        minHeight = 0;
                    }
                    var scale = (locations.Length > 30 ? 1f : 2f) * 1.4142135623730950488016887242097f;
                    var baseV = new Vector3(pos2d.X + pos2d.Y * 2, 0, pos2d.Y * 2 - pos2d.X) / scale;
                    baseV.Y -= (minHeight * 3 / 160f) * 3;

                    var ctr = blueprint.GetFineBounds().Location.ToVector2() + blueprint.GetFineBounds().Size.ToVector2() / 2;

                    var voff = baseV + new Vector3(ctr.X, 0, ctr.Y) * 3f / -1;

                    voff.X = (int)(voff.X / 3) * 3;
                    voff.Z = (int)(voff.Z / 3) * 3;

                    SetOutsideTime(GameFacade.GraphicsDevice, vm, world, 0.5f, false);
                    world.State.PrepareLighting();
                    var facade = new LotFacadeGenerator();
                    facade.FLOOR_TILES        = blueprint.Width;
                    facade.GROUND_SUBDIV      = blueprint.Width;
                    facade.FLOOR_RES_PER_TILE = 4;
                    facade.LotName            = "p" + num.ToString();
                    facade.Generate(GameFacade.GraphicsDevice, (WorldRC)world, blueprint);
                    facade.AppendOBJ(io, filename, indCount, voff / 3);
                    facade.AppendMTL(mtlIO, Path.GetDirectoryName(path));
                    indCount = facade.LastIndex;

                    /*
                     * foreach (var group in groundfloor.GroupForTileType)
                     * {
                     *  if (!exportedFlr.Contains(group.Key) && group.Key != 0 && group.Key < 65000)
                     *  {
                     *      //get and export this floor's texture. add it as a material as well.
                     *      var floor = Content.Get().WorldFloors.Get(group.Key).Near.Frames[0].GetTexture(gd);
                     *      using (var flrStream = new FileStream(Path.Combine(destPath, "flr_" + group.Key + ".png"), FileMode.Create, FileAccess.Write, FileShare.None))
                     *          floor.SaveAsPng(flrStream, floor.Width, floor.Height);
                     *
                     *      //add as material
                     *      GenerateMTL("flr_" + group.Key, mtlBuilder);
                     *  }
                     *  //write out verts and indices.
                     *
                     *
                     *  var indices = group.Value.BuildIndexData();
                     *  var done = new Dictionary<int, int>(); //index remap
                     *
                     *  if (group.Key == 0)
                     *  {
                     *      //grass... export as grass colour
                     *      io.WriteLine("usemtl " + "grass");
                     *      io.WriteLine("o " + "lot_" + num + "_grass");
                     *
                     *  }
                     *  else
                     *  {
                     *      //export with floor textured material
                     *      io.WriteLine("usemtl " + "flr_" + group.Key);
                     *      io.WriteLine("o " + "lot_" + num + "_" + group.Key);
                     *  }
                     *
                     *  var indexStr = new StringBuilder();
                     *  indexStr.Append("f ");
                     *
                     *  for (int j = 0; j < indices.Length; j++)
                     *  {
                     *      var index = indices[j];
                     *      int remapped = index;
                     *      if (!done.TryGetValue(index, out remapped))
                     *      {
                     *          remapped = indCount;
                     *          done.Add(index, indCount++);
                     *          //append a vertex
                     *          var vert = floorVerts[index];
                     *          vert.Position += voff;
                     *          io.Write("v " + vert.Position.X.ToString(CultureInfo.InvariantCulture) + " " + vert.Position.Y.ToString(CultureInfo.InvariantCulture) + " " + vert.Position.Z.ToString(CultureInfo.InvariantCulture));
                     *          io.WriteLine((group.Key == 0) ? " " + vert.Color.X.ToString(CultureInfo.InvariantCulture) + " " + vert.Color.Y.ToString(CultureInfo.InvariantCulture) + " " + vert.Color.Z.ToString(CultureInfo.InvariantCulture) : "");
                     *          io.WriteLine("vt " + vert.GrassInfo.Y.ToString(CultureInfo.InvariantCulture) + " " + (1 - vert.GrassInfo.Z).ToString(CultureInfo.InvariantCulture));
                     *      }
                     *      indexStr.Append(remapped + "/" + remapped);
                     *      if (j % 3 == 2)
                     *      {
                     *          indexStr.AppendLine();
                     *          if (j != indices.Length - 1) indexStr.Append("f ");
                     *      }
                     *      else indexStr.Append(" ");
                     *  }
                     *
                     *  io.WriteLine(indexStr);
                     * }
                     */

                    GameFacade.Scenes.Remove(world);
                    world.Dispose();
                }
            }

            mtlIO.Close();
        }