internal static List <Item> ImportFromHierarchy(NJS_OBJECT objm, EditorItemSelection selectionManager, OnScreenDisplay osd, bool multiple = false) { List <Item> createdItems = new List <Item>(); if (objm.Attach != null) { objm.Attach.ProcessVertexData(); LevelItem lvlitem = new LevelItem(objm.Attach, new Vertex(objm.Position.X, objm.Position.Y, objm.Position.Z), objm.Rotation, levelItems.Count, selectionManager) { Visible = true }; createdItems.Add(lvlitem); } if (multiple) { if (objm.Children != null && objm.Children.Count > 0) { int c = 0; foreach (NJS_OBJECT child in objm.Children) { createdItems.AddRange(ImportFromHierarchy(child, selectionManager, osd, true)); } } } return(createdItems); }
public static Vertex CenterFromSelection(List <Item> SelectedItems) { if (SelectedItems == null) { return(new Vertex()); } List <Vertex> vertList = new List <Vertex>(); foreach (Item item in SelectedItems) { if (item is LevelItem) { LevelItem levelItem = (LevelItem)item; vertList.Add(levelItem.CollisionData.Bounds.Center); } else { vertList.Add(item.Position); } } return(Vertex.CenterOfPoints(vertList)); }
public static void AddLevelItem(LevelItem item) { LevelData.levelItems.Add(item); changes.Push("Add level item"); InvalidateRenderState(); }
public static void RemoveLevelItem(LevelItem item) { LevelData.levelItems.Remove(item); changes.Push("Remove level item"); InvalidateRenderState(); }
public static void DuplicateSelection(EditorItemSelection selection, out bool errorFlag, out string errorMsg) { if (selection.ItemCount < 0) { errorFlag = true; errorMsg = "Negative selection count... what did you do?!?"; return; } List <Item> newItems = new List <Item>(); List <Item> currentItems = selection.GetSelection(); // duplicate goes here for (int i = 0; i < selection.ItemCount; i++) { if (currentItems[i] is MissionSETItem) { MissionSETItem originalItem = (MissionSETItem)currentItems[i]; MissionSETItem newItem = new MissionSETItem(originalItem.GetBytes(), 0, originalItem.GetPRMBytes(), 0, selection); MissionSETItems[Character].Add(newItem); newItems.Add(newItem); } else if (currentItems[i] is SETItem) { SETItem originalItem = (SETItem)currentItems[i]; SETItem newItem = new SETItem(originalItem.GetBytes(), 0, selection); //SETItems[Character].Add(newItem); AddSETItem(Character, newItem); newItems.Add(newItem); } else if (currentItems[i] is LevelItem) { LevelItem originalItem = (LevelItem)currentItems[0]; LevelItem newItem = new LevelItem(originalItem.CollisionData.Model.Attach, originalItem.Position, originalItem.Rotation, levelItems.Count, selection); newItem.CollisionData.SurfaceFlags = originalItem.CollisionData.SurfaceFlags; newItems.Add(newItem); } else if (currentItems[i] is CAMItem) { CAMItem originalItem = (CAMItem)currentItems[i]; CAMItem newItem = new CAMItem(originalItem.GetBytes(), 0, selection); CAMItems[Character].Add(newItem); newItems.Add(newItem); } } selection.Clear(); selection.Add(newItems); changes.Push("Duplicate Item"); InvalidateRenderState(); errorFlag = false; errorMsg = ""; }
public static int GetIndexOfItem(LevelItem item) { if (levelItems.Contains(item)) { return(levelItems.IndexOf(item)); } else { return(-1); } }
public static List <Item> ImportFromFile(string filePath, Device d3ddevice, EditorCamera camera, out bool errorFlag, out string errorMsg, EditorItemSelection selectionManager) { List <Item> createdItems = new List <Item>(); if (!File.Exists(filePath)) { errorFlag = true; errorMsg = "File does not exist!"; return(null); } DirectoryInfo filePathInfo = new DirectoryInfo(filePath); bool importError = false; string importErrorMsg = ""; switch (filePathInfo.Extension) { case ".obj": case ".objf": Vector3 pos = camera.Position + (-20 * camera.Look); LevelItem item = new LevelItem(d3ddevice, filePath, new Vertex(pos.X, pos.Y, pos.Z), new Rotation(), LevelItems.Count, selectionManager) { Visible = true }; createdItems.Add(item); break; case ".txt": NodeTable.ImportFromFile(d3ddevice, filePath, out importError, out importErrorMsg, selectionManager); break; default: errorFlag = true; errorMsg = "Invalid file format!"; return(null); } StateChanged(); errorFlag = importError; errorMsg = importErrorMsg; return(createdItems); }
public static List<Item> ImportFromFile(string filePath, Device d3ddevice, EditorCamera camera, out bool errorFlag, out string errorMsg, EditorItemSelection selectionManager) { List<Item> createdItems = new List<Item>(); if (!File.Exists(filePath)) { errorFlag = true; errorMsg = "File does not exist!"; return null; } DirectoryInfo filePathInfo = new DirectoryInfo(filePath); bool importError = false; string importErrorMsg = ""; switch (filePathInfo.Extension) { case ".obj": case ".objf": Vector3 pos = camera.Position + (-20 * camera.Look); LevelItem item = new LevelItem(d3ddevice, filePath, new Vertex(pos.X, pos.Y, pos.Z), new Rotation(), LevelItems.Count, selectionManager) { Visible = true }; createdItems.Add(item); break; case ".txt": NodeTable.ImportFromFile(d3ddevice, filePath, out importError, out importErrorMsg, selectionManager); break; default: errorFlag = true; errorMsg = "Invalid file format!"; return null; } StateChanged(); errorFlag = importError; errorMsg = importErrorMsg; return createdItems; }
public static void DuplicateSelection(Device d3ddevice, EditorItemSelection selection, out bool errorFlag, out string errorMsg) { if (selection.ItemCount < 0) { errorFlag = true; errorMsg = "Negative selection count... what did you do?!?"; return; } List<Item> newItems = new List<Item>(); List<Item> currentItems = selection.GetSelection(); // duplicate goes here for (int i = 0; i < selection.ItemCount; i++) { if (currentItems[i] is SETItem) { SETItem originalItem = (SETItem)currentItems[i]; SETItem newItem = new SETItem(originalItem.GetBytes(), 0, selection); SETItems[Character].Add(newItem); newItems.Add(newItem); } else if (currentItems[i] is LevelItem) { LevelItem originalItem = (LevelItem)currentItems[0]; LevelItem newItem = new LevelItem(d3ddevice, originalItem.CollisionData.Model.Attach, originalItem.Position, originalItem.Rotation, LevelItems.Count, selection); newItem.CollisionData.SurfaceFlags = originalItem.CollisionData.SurfaceFlags; newItems.Add(newItem); } else if (currentItems[i] is CAMItem) { CAMItem originalItem = (CAMItem)currentItems[i]; CAMItem newItem = new CAMItem(originalItem.GetBytes(), 0, selection); CAMItems[Character].Add(newItem); newItems.Add(newItem); } } selection.Clear(); selection.Add(newItems); InvalidateRenderState(); errorFlag = false; errorMsg = ""; }
/// <summary> /// Imports a nodetable (a single-level instance heirarchy layout) file. /// </summary> /// <param name="filePath">full path to file (with extension) to import data from.</param> /// <param name="errorFlag">Set to TRUE if an error occured.</param> /// <param name="errorMsg">Suggested error message to show to the user.</param> public static void ImportFromFile(Device dev, string filePath, out bool errorFlag, out string errorMsg, EditorItemSelection selectionManager) { if (!File.Exists(filePath)) { errorFlag = true; errorMsg = "File not found!"; return; } Stream nodeTable = File.OpenRead(filePath); StreamReader nodeTableStream = new StreamReader(nodeTable); string folderPath = Path.GetDirectoryName(filePath); string version = nodeTableStream.ReadLine(); string[] versionSplit = version.Split(' '); #region Version Validity Check if (versionSplit.Length <= 1 || versionSplit[0] != "ver") // invalid file { errorFlag = true; errorMsg = "Invalid file! (Version Check Failed)"; return; } // versionNumber is the last string in the split sequence, with the ; character as the delimiter string[] versionNumberSplit = versionSplit[1].Split(';'); string versionNumber = versionNumberSplit[0]; if ((versionNumber != "1") && (versionNumber != "1.5") && (versionNumber != "1.6")) { errorFlag = true; errorMsg = "Invalid Nodetable version number was supplied"; nodeTable.Close(); return; } #endregion // get node count from next line string[] nodeCountLines = nodeTableStream.ReadLine().Split(' '); if ((nodeCountLines[0] != "node") || (nodeCountLines[1] != "count")) { errorFlag = true; errorMsg = "Error in node count!"; nodeTable.Close(); return; } nodeCountLines = nodeCountLines[2].Split(';'); int nodeCount = 0; if (!Int32.TryParse(nodeCountLines[0], out nodeCount)) { errorFlag = true; errorMsg = "Error parsing node count!"; nodeTable.Close(); return; } nodeTableStream.ReadLine(); // aligning List<KeyValuePair<int, Attach>> instanceMgr = new List<KeyValuePair<int, Attach>>(); if (versionNumber == "1.5") { for (int n = 0; n < nodeCount; n++) { string nodeInput = nodeTableStream.ReadLine(); string[] nodeDescriptorSplit = nodeInput.Split(' '); string[] nodeIndexSplit = nodeDescriptorSplit[1].Split(';'); int nodeIndex = 0; if (!Int32.TryParse(nodeIndexSplit[0], out nodeIndex)) { errorFlag = true; errorMsg = String.Format("Error parsing node label for node {0}.", n); nodeTableStream.Close(); return; } #region Position Read/Parse Vertex position; float xPos, yPos, zPos; string[] positionSplit = nodeTableStream.ReadLine().Split(' '); if (positionSplit[0] != "pos") { errorFlag = true; errorMsg = String.Format("Error retrieving position values for node {0}", n); nodeTableStream.Close(); return; } positionSplit[3] = positionSplit[3].Split(';')[0]; if ((float.TryParse(positionSplit[1], out xPos)) && (float.TryParse(positionSplit[2], out yPos)) && (float.TryParse(positionSplit[3], out zPos))) { position = new Vertex(xPos, yPos, zPos); } else { errorFlag = true; errorMsg = String.Format("Error parsing position values for node {0}", n); nodeTableStream.Close(); return; } #endregion #region Rotation Read/Parse Rotation rotation; float xRot, yRot, zRot; string[] rotationSplit = nodeTableStream.ReadLine().Split(' '); if (rotationSplit[0] != "rot") { errorFlag = true; errorMsg = String.Format("Error retrieving rotation values for node {0}", n); nodeTableStream.Close(); return; } rotationSplit[3] = rotationSplit[3].Split(';')[0]; if (float.TryParse(rotationSplit[1], out xRot) && float.TryParse(rotationSplit[2], out yRot) && float.TryParse(rotationSplit[3], out zRot)) { rotation = new Rotation(Rotation.DegToBAMS(xRot), Rotation.DegToBAMS(yRot), Rotation.DegToBAMS(zRot)); } else { errorFlag = true; errorMsg = String.Format("Error parsing rotation values for node {0}", n); nodeTableStream.Close(); return; } #endregion #region Creating LevelItem string modelFilePath = String.Concat(folderPath, "/", nodeIndex, ".obj"); if (!File.Exists(modelFilePath)) { errorFlag = true; errorMsg = String.Format("File not found: {0}", modelFilePath); nodeTableStream.Close(); return; } if (nodeDescriptorSplit[0] == "node") { LevelItem levelItem = new LevelItem(dev, modelFilePath, position, rotation, LevelData.LevelItems.Count, selectionManager); instanceMgr.Add(new KeyValuePair<int, Attach>(nodeIndex, levelItem.CollisionData.Model.Attach)); } else if (nodeDescriptorSplit[0] == "instance") { Attach instanceBaseAttach = instanceMgr.Find(item => item.Key == nodeIndex).Value; LevelItem levelItem = new LevelItem(dev, instanceBaseAttach, position, rotation, LevelData.LevelItems.Count, selectionManager); } #endregion nodeTableStream.ReadLine(); // aligning } } else if (versionNumber == "1") { // version 1 does not support instances. Just read and construct. throw new NotImplementedException(); } else if (versionNumber == "1.6") { for (int n = 0; n < nodeCount; n++) { string nodeInput = nodeTableStream.ReadLine(); string[] nodeDescriptorSplit = nodeInput.Split(' '); string[] nodeIndexSplit = nodeDescriptorSplit[1].Split(';'); int nodeIndex = 0; if (!Int32.TryParse(nodeIndexSplit[0], out nodeIndex)) { errorFlag = true; errorMsg = String.Format("Error parsing node label for node {0}.", n); nodeTableStream.Close(); return; } #region Position Read/Parse Vertex position; float xPos, yPos, zPos; string[] positionSplit = nodeTableStream.ReadLine().Split(' '); if (positionSplit[0] != "pos") { errorFlag = true; errorMsg = String.Format("Error retrieving position values for node {0}", n); nodeTableStream.Close(); return; } positionSplit[3] = positionSplit[3].Split(';')[0]; if ((float.TryParse(positionSplit[1], out xPos)) && (float.TryParse(positionSplit[2], out yPos)) && (float.TryParse(positionSplit[3], out zPos))) { position = new Vertex(xPos, yPos, zPos); } else { errorFlag = true; errorMsg = String.Format("Error parsing position values for node {0}", n); nodeTableStream.Close(); return; } #endregion #region Rotation Read/Parse Rotation rotation; float xRot, yRot, zRot; string[] rotationSplit = nodeTableStream.ReadLine().Split(' '); if (rotationSplit[0] != "rot") { errorFlag = true; errorMsg = String.Format("Error retrieving rotation values for node {0}", n); nodeTableStream.Close(); return; } rotationSplit[3] = rotationSplit[3].Split(';')[0]; if (float.TryParse(rotationSplit[1], out xRot) && float.TryParse(rotationSplit[2], out yRot) && float.TryParse(rotationSplit[3], out zRot)) { rotation = new Rotation(Rotation.DegToBAMS(xRot), Rotation.DegToBAMS(yRot), Rotation.DegToBAMS(zRot)); } else { errorFlag = true; errorMsg = String.Format("Error parsing rotation values for node {0}", n); nodeTableStream.Close(); return; } #endregion #region SurfaceFlags Read/Parse string surfaceFlags = ""; string surfaceFlagsLine = nodeTableStream.ReadLine(); string[] surfaceFlagsSplit = surfaceFlagsLine.Split(' '); if (surfaceFlagsSplit[0] == "surfaceflags") { surfaceFlags = surfaceFlagsSplit[1].Split(';')[0]; surfaceFlagsSplit = surfaceFlags.Split('X'); surfaceFlags = surfaceFlagsSplit[1]; } #endregion #region Creating LevelItem string modelFilePath = String.Concat(folderPath, "/", nodeIndex, ".obj"); if (!File.Exists(modelFilePath)) { errorFlag = true; errorMsg = String.Format("File not found: {0}", modelFilePath); nodeTableStream.Close(); return; } if (nodeDescriptorSplit[0] == "node") { LevelItem levelItem = new LevelItem(dev, modelFilePath, position, rotation, LevelData.LevelItems.Count, selectionManager); levelItem.Flags = surfaceFlags; instanceMgr.Add(new KeyValuePair<int, Attach>(nodeIndex, levelItem.CollisionData.Model.Attach)); } else if (nodeDescriptorSplit[0] == "instance") { Attach instanceBaseAttach = instanceMgr.Find(item => item.Key == nodeIndex).Value; LevelItem levelItem = new LevelItem(dev, instanceBaseAttach, position, rotation, LevelData.LevelItems.Count, selectionManager); levelItem.Flags = surfaceFlags; } #endregion nodeTableStream.ReadLine(); // aligning } } nodeTable.Close(); errorFlag = false; errorMsg = "Import successful!"; }
public static List <Item> ImportFromFile(string filePath, EditorCamera camera, out bool errorFlag, out string errorMsg, EditorItemSelection selectionManager, OnScreenDisplay osd, bool multiple = false) { List <Item> createdItems = new List <Item>(); if (!File.Exists(filePath)) { errorFlag = true; errorMsg = "File does not exist!"; return(null); } DirectoryInfo filePathInfo = new DirectoryInfo(filePath); bool importError = false; string importErrorMsg = ""; Vector3 pos = camera.Position + (-20 * camera.Look); switch (filePathInfo.Extension) { case ".sa1mdl": ModelFile mf = new ModelFile(filePath); NJS_OBJECT objm = mf.Model; osd.ClearMessageList(); osd.AddMessage("Importing models, please wait...", 3000); osd.ClearMessageList(); createdItems.AddRange(ImportFromHierarchy(objm, selectionManager, osd, multiple)); osd.AddMessage("Stage import complete!", 100); break; case ".obj": case ".objf": LevelItem item = new LevelItem(filePath, new Vertex(pos.X, pos.Y, pos.Z), new Rotation(), levelItems.Count, selectionManager) { Visible = true }; createdItems.Add(item); break; case ".txt": NodeTable.ImportFromFile(filePath, out importError, out importErrorMsg, selectionManager); break; case ".dae": case ".fbx": Assimp.AssimpContext context = new Assimp.AssimpContext(); Assimp.Configs.FBXPreservePivotsConfig conf = new Assimp.Configs.FBXPreservePivotsConfig(false); context.SetConfig(conf); Assimp.Scene scene = context.ImportFile(filePath, Assimp.PostProcessSteps.Triangulate); for (int i = 0; i < scene.RootNode.ChildCount; i++) { osd.ClearMessageList(); osd.AddMessage("Importing model " + i.ToString() + " of " + scene.RootNode.ChildCount.ToString() + "...", 3000); Assimp.Node child = scene.RootNode.Children[i]; List <Assimp.Mesh> meshes = new List <Assimp.Mesh>(); foreach (int j in child.MeshIndices) { meshes.Add(scene.Meshes[j]); } bool isVisible = true; for (int j = 0; j < child.MeshCount; j++) { if (scene.Materials[meshes[j].MaterialIndex].Name.Contains("Collision")) { isVisible = false; break; } } ModelFormat mfmt = ModelFormat.Basic; if (isVisible) { switch (geo.Format) { case LandTableFormat.SA2: mfmt = ModelFormat.Chunk; break; case LandTableFormat.SA2B: mfmt = ModelFormat.GC; break; } } NJS_OBJECT obj = AssimpStuff.AssimpImport(scene, child, mfmt, TextureBitmaps[leveltexs].Select(a => a.Name).ToArray(), !multiple); { //sa2 collision patch if (obj.Attach.GetType() == typeof(BasicAttach)) { BasicAttach ba = obj.Attach as BasicAttach; foreach (NJS_MATERIAL mats in ba.Material) { mats.DoubleSided = true; } } //cant check for transparent texture so i gotta force alpha for now, temporary else if (obj.Attach.GetType() == typeof(ChunkAttach)) { ChunkAttach ca = obj.Attach as ChunkAttach; foreach (PolyChunk polys in ca.Poly) { if (polys.GetType() == typeof(PolyChunkMaterial)) { PolyChunkMaterial mat = polys as PolyChunkMaterial; mat.SourceAlpha = AlphaInstruction.SourceAlpha; mat.DestinationAlpha = AlphaInstruction.InverseSourceAlpha; } else if (polys.GetType() == typeof(PolyChunkStrip)) { PolyChunkStrip str = polys as PolyChunkStrip; //str.UseAlpha = true; } } } } obj.Attach.ProcessVertexData(); LevelItem newLevelItem = new LevelItem(obj.Attach, new Vertex(obj.Position.X + pos.X, obj.Position.Y + pos.Y, obj.Position.Z + pos.Z), obj.Rotation, levelItems.Count, selectionManager) { Visible = isVisible }; createdItems.Add(newLevelItem); } osd.ClearMessageList(); osd.AddMessage("Stage import complete!", 100); break; default: errorFlag = true; errorMsg = "Invalid file format!"; return(null); } StateChanged(); errorFlag = importError; errorMsg = importErrorMsg; return(createdItems); }