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(); }