void ToggleImportModeVisibility(VisualElement fieldBlock, ImportState importState) { if (fieldBlock != null) { var unimportedMode = fieldBlock.Q(k_UnimportedMode); if (unimportedMode != null) { unimportedMode.style.display = (importState == ImportState.Unimported) ? DisplayStyle.Flex : DisplayStyle.None; } var versionCheckMode = fieldBlock.Q(k_VersionCheckMode); if (versionCheckMode != null) { versionCheckMode.style.display = (importState == ImportState.VersionCheck) ? DisplayStyle.Flex : DisplayStyle.None; } var upToDateMode = fieldBlock.Q(k_UpToDataMode); if (upToDateMode != null) { upToDateMode.style.display = (importState == ImportState.UpToDate) ? DisplayStyle.Flex : DisplayStyle.None; } var outOfDateMode = fieldBlock.Q(k_OutOfDateMode); if (outOfDateMode != null) { outOfDateMode.style.display = (importState == ImportState.OutOfDate) ? DisplayStyle.Flex : DisplayStyle.None; } } }
void ImportComplete(SerializationCompletionReason status, WorldAnchorTransferBatch anchorBatch) { if (status == SerializationCompletionReason.Succeeded) { if (anchorBatch.GetAllIds().Length > 0) { string first = anchorBatch.GetAllIds()[0]; if (SharingStage.Instance.ShowDetailedLogs) { Debug.Log("Anchor Manager: Sucessfully imported anchor " + first); } this.worldAnchor = anchorBatch.LockObject(first, gameObject); StatusTextDisplay.Instance.SetStatusText("synchronised"); } base.FireCompleted(true); } else { StatusTextDisplay.Instance.SetStatusText("retrying synchronisation"); Debug.LogError("Anchor Manager: Import failed"); currentState = ImportState.DataDownloadedReadyForImport; } }
public override void Initialise(List <MailFolder> folderList) { Status = MessageProcessorStatus.Initialising; _outlook = new Application(); var pstPath = Regex.Replace(_saveFolder + @"\" + _pstName + ".pst", @"\\+", @"\"); Logger.Info("Writing to PST " + pstPath); _pstHandle = PstHandle(_outlook.GetNamespace("MAPI"), pstPath, _pstName); _rootFolder = _pstHandle.GetRootFolder() as Folder; //_importFolder = GetCreateFolder(_rootFolder.FolderPath + @"\_zinkuba_import", _outlook); if (_createAllFolders) { foreach (var mailFolder in folderList) { GetCreateFolder(_rootFolder.FolderPath + @"\" + mailFolder.DestinationFolder, _outlook, true); } } _lastState = new ImportState(); _queue = new PCQueue <MsgDescriptor, ImportState>(Name + "-pstTarget") { ProduceMethod = ProcessMessage, InitialiseProducer = () => _lastState, ShutdownProducer = ShutdownQueue }; _queue.Start(); Status = MessageProcessorStatus.Initialised; Logger.Info("PstTarget Initialised"); }
void Update() { #if UNITY_WSA && !UNITY_EDITOR if (SharingStage.Instance.IsConnected) { switch (currentState) { case ImportState.Start: ConnectToRoom(); this.currentState = ImportState.ReadyToImport; break; case ImportState.ReadyToImport: MakeAnchorDataRequest(); break; case ImportState.DataDownloadedReadyForImport: // DataReady is set when the anchor download completes. currentState = ImportState.Importing; StatusTextDisplay.Instance.SetStatusText("importing synchronisation data"); WorldAnchorTransferBatch.ImportAsync(rawAnchorData, ImportComplete); break; } } #endif }
public override void Initialise(List <MailFolder> folderList) { Status = MessageProcessorStatus.Initialising; _mainFolderList = folderList; service = ExchangeHelper.ExchangeConnect(_hostname, _username, _password); //service.TraceEnabled = true; //service.TraceFlags = TraceFlags.All; folders = new List <ExchangeFolder>(); ExchangeHelper.GetAllSubFolders(service, new ExchangeFolder { Folder = Folder.Bind(service, WellKnownFolderName.MsgFolderRoot) }, folders, false); if (_createAllFolders) { // we need to create all folders which don't exist foreach (var mailFolder in _mainFolderList) { GetCreateFolder(mailFolder.DestinationFolder); } } _lastState = new ImportState(); _queue = new PCQueue <RawMessageDescriptor, ImportState>(Name + "-exchangeTarget") { ProduceMethod = ProcessMessage, InitialiseProducer = () => _lastState, ShutdownProducer = ShutdownQueue }; _queue.Start(); Status = MessageProcessorStatus.Initialised; }
public void Convert(ModelRoot gltf, PssgFile pssg) { // Get a list of nodes in the default scene as a flat list Dictionary <int, int> nodeBoneIndexMap = new Dictionary <int, int>(); var rootNode = gltf.DefaultScene.FindNode(n => n.Name.StartsWith("Scene Root")); if (rootNode is null) { throw new InvalidDataException("The default scene must have node name starting with `Scene Root`."); } // Determine libraries in which to store data var nodeLib = pssg.FindNodes("LIBRARY", "type", "NODE").First(); var rdsLib = pssg.FindNodes("LIBRARY", "type", "RENDERDATASOURCE").First(); var ribLib = pssg.FindNodes("LIBRARY", "type", "RENDERINTERFACEBOUND").First(); var state = new ImportState(ShaderInputInfo.CreateFromPssg(pssg).ToDictionary(si => si.ShaderGroupId)); // Clear out the libraries nodeLib.RemoveChildNodes(nodeLib.ChildNodes.Where(n => n.Name == "ROOTNODE")); rdsLib.RemoveChildNodes(rdsLib.ChildNodes.Where(n => n.Name == "RENDERDATASOURCE")); ribLib.RemoveChildNodes(ribLib.ChildNodes.Where(n => n.Name == "DATABLOCK")); // Write the scene graph, and collect mesh data ConvertSceneNodes(pssg, nodeLib, rootNode, state); }
public Wizard(Form form, String fileName, String yearMonth, DataRowView excelRow) { FileName = fileName; YearMonth = yearMonth; ExcelRow = excelRow; ImportErrors = new List<string>(); currentImportState = ImportState.None; validator = Validator.GetInstance(); validator.clear(); }
private void UpdateProgressMessage() { // Calculate base progress based on state float baseProgress = 0; float stateProgress = 0; string message = "Serializing translations..."; ImportState state = currentStatus.Value; if (state == ImportState.ReadFile) { // Get the CSV status CsvReader.ReadStatus.State csvState = csvReadStatus.CurrentState; if (csvState == CsvReader.ReadStatus.State.ReadingFileIntoRows) { // Report that we're reading the file. // Progress is not calculated here because we do not // check how long the CSV file is. message = "Parsing CSV file into text..."; } else { // Report the text is being split into cells message = "Splitting text into cells..."; // Calculate the progress baseProgress = (int)csvState; stateProgress = csvReadStatus.ProgressPercent; } } else { // Check the state if (state == ImportState.ConvertToTranslations) { // Report cells are being converted message = "Converting cells into translations..."; } // Calculate the progress baseProgress = ((int)state) + 1; stateProgress = progressReport.ProgressPercent; } // Calculate progress baseProgress /= TotalStates; stateProgress /= TotalStates; baseProgress += stateProgress; Progress = baseProgress; // Update message ProgressMessage.Clear(); ProgressMessage.Append(baseProgress.ToString("00%")); ProgressMessage.Append(": "); ProgressMessage.Append(message); }
protected virtual ICollection <IValidationRule> GetValidationRulesForState(ImportState state) { if (state == null) { throw new ArgumentNullException("state"); } var type = typeof(ISateValidationRule <>).MakeGenericType(state.GetType()); return(this._ruleFactory.GetValidationRules <ImportState>(s => this._dependencyResolver.ResolveAll(type)) .ToList()); }
public void ThreadPoolPageImportCallback(Object threadContext) { ImportState stateInfo = (ImportState)threadContext; Page page = stateInfo.page; //destinationView.Pages[threadIndex]; ManualResetEvent manualEvent = stateInfo.manualEvent; int threadIndex = stateInfo.threadIndex; Debug.Print("Thread started for page {0}...", page.Name); ImportPage(page); Debug.Print("Thread completed for page {0}...", page.Name); manualEvent.Set(); }
public void Convert(ModelRoot gltf, PssgFile pssg) { // Get a list of nodes in the default scene as a flat list Dictionary <int, int> nodeBoneIndexMap = new Dictionary <int, int>(); var rootNode = gltf.DefaultScene.FindNode(n => n.Name.StartsWith("Scene Root")); if (rootNode is null) { throw new InvalidDataException("The default scene must have node name starting with `Scene Root`."); } // Determine libraries in which to store data var nodeLib = pssg.FindNodes("LIBRARY", "type", "NODE").FirstOrDefault(); PssgNode rdsLib; PssgNode ribLib; if (nodeLib is not null) { rdsLib = pssg.FindNodes("LIBRARY", "type", "RENDERDATASOURCE").First(); ribLib = pssg.FindNodes("LIBRARY", "type", "RENDERINTERFACEBOUND").First(); } else { // F1 games use YYY, and put almost everything in this lib nodeLib = pssg.FindNodes("LIBRARY", "type", "YYY").FirstOrDefault(); if (nodeLib is null) { throw new InvalidDataException("Could not find library with scene nodes."); } rdsLib = nodeLib; ribLib = nodeLib; } var state = new ImportState(rdsLib, ribLib, ShaderInputInfo.CreateFromPssg(pssg).ToDictionary(si => si.ShaderGroupId)); // Clear out the libraries nodeLib.RemoveChildNodes(nodeLib.ChildNodes.Where(n => n.Name == "ROOTNODE")); rdsLib.RemoveChildNodes(rdsLib.ChildNodes.Where(n => n.Name == "RENDERDATASOURCE")); ribLib.RemoveChildNodes(ribLib.ChildNodes.Where(n => n.Name == "DATABLOCK")); // Write the scene graph, and collect mesh data ConvertSceneNodes(pssg, nodeLib, rootNode, state); // Seems in Dirt Rally 2.0 there is a bunch of useless data in lib SEGMENTSET // lets get rid of it var ssLibNode = pssg.FindNodes("LIBRARY", "type", "SEGMENTSET").FirstOrDefault(); if (ssLibNode is not null) { ssLibNode.ParentNode?.RemoveChild(ssLibNode); } }
/* Saves general file info in FileInfo collection */ public async Task SaveFileInfo(string session, int count, string filename, ImportState state, string description) { FileInformation fileInfo = new FileInformation { Session = session, UploadedFileName = filename, FinalState = state, Description = description, RecordCount = count }; await _fileRepository.InsertFileInfoDetails(fileInfo); }
void MakeAnchorDataRequest() { StatusTextDisplay.Instance.SetStatusText("requesting data"); if (roomManager.DownloadAnchor(currentRoom, currentRoom.GetAnchorName(0))) { currentState = ImportState.DataRequested; } else { Debug.LogError("Anchor Manager: Couldn't make the download request."); currentState = ImportState.Failed; } }
private void ShutdownQueue(ImportState state, Exception ex) { try { if (ex != null) { throw ex; } Status = MessageProcessorStatus.Completed; } catch (Exception e) { Logger.Error("Message Reader failed : " + e.Message, e); Status = MessageProcessorStatus.UnknownError; } Close(); }
private static PssgNode CreateRenderNode(PssgNode parent, Node gltfNode, ImportState state) { var node = new PssgNode(state.RenderNodeName, parent.File, parent); node.AddAttribute("stopTraversal", 0u); node.AddAttribute("nickname", gltfNode.Name); node.AddAttribute("id", gltfNode.Name); parent.ChildNodes.Add(node); state.MatShaderMapping.Clear(); // Now add a new mesh from mesh builder ConvertMesh(node, gltfNode, state); // Write the mesh data WriteMeshData(state); return(node); }
private static void CreateMatrixPaletteNode(PssgNode parent, ImportState state) { var node = new PssgNode("MATRIXPALETTENODE", parent.File, parent); node.AddAttribute("stopTraversal", 0u); node.AddAttribute("id", $"x{state.LodNumber}_MPN"); parent.ChildNodes.Add(node); var transformNode = new PssgNode("TRANSFORM", node.File, node); transformNode.Value = GetTransform(Matrix4x4.Identity); node.ChildNodes.Add(transformNode); var bboxNode = new PssgNode("BOUNDINGBOX", node.File, node); bboxNode.Value = GetBoundingBoxData(Vector3.Zero, Vector3.Zero); node.ChildNodes.Add(bboxNode); foreach (var shader in state.MatShaderMapping.Values) { var rsiNode = new PssgNode("MATRIXPALETTERENDERINSTANCE", node.File, node); rsiNode.AddAttribute("jointCount", (uint)shader.JointNames.Count); rsiNode.AddAttribute("sourceCount", 1u); rsiNode.AddAttribute("indices", $"#{shader.Rds.Name}"); rsiNode.AddAttribute("streamCount", 0u); rsiNode.AddAttribute("shader", $"#{shader.ShaderInstanceName}"); rsiNode.AddAttribute("id", shader.Rds.Name.Replace("RDS", "RSI")); node.ChildNodes.Add(rsiNode); var risNode = new PssgNode("RENDERINSTANCESOURCE", rsiNode.File, rsiNode); risNode.AddAttribute("source", $"#{shader.Rds.Name}"); rsiNode.ChildNodes.Add(risNode); foreach (var jointName in shader.JointNames) { var mpsjNode = new PssgNode("MATRIXPALETTESKINJOINT", rsiNode.File, rsiNode); mpsjNode.AddAttribute("joint", $"#{jointName}"); rsiNode.ChildNodes.Add(mpsjNode); } } }
/// <summary>Initialize the importer</summary> /// <remarks>Called by host to have an importer prepare for a load and to pass in importer initialization parameters /// (SQL Server name, target database, etc).</remarks> /// <param name="Filemask">Path to the file(s) to import. May be a filemask</param> /// <param name="connString">Database connection string</param> /// <param name="Server">SQL Server name</param> /// <param name="UseWindowsAuth">Whether to use an integrated/trusted SQL connection</param> /// <param name="SQLLogin">SQL login name (implies <c>UseWindowsAuth</c>==false)</param> /// <param name="SQLPassword">SQL password (implies <c>UseWindowsAuth</c>==false)</param> /// <param name="DatabaseName">Target database name</param> /// <param name="Logger"><c>ILogger</c> instance - use to communicate status/debug messages back to host</param> /// <returns>void</returns> public void Initialize(string Filemask, string connString, string Server, bool UseWindowsAuth, string SQLLogin, string SQLPassword, string DatabaseName, ILogger Logger) { // Persist inputs from host this.traceFileSpec = Filemask; this.connStr = connString; this.sqlServer = Server; this.sqlLogin = SQLLogin; this.sqlPassword = SQLPassword; this.database = DatabaseName; this.useWindowsAuth = UseWindowsAuth; this.logger = Logger; // Init status members state = ImportState.Idle; is_cancelled = false; knownRowsets = new ArrayList(); this.totalLinesProcessed = 0; this.totalRowsInserted = 0; if (null == this.linuxPerfImporter) { return; } }
void OnAnchorDonwloadCompleted( bool successful, AnchorDownloadRequest request, XString failureReason) { // If we downloaded anchor data successfully we should import the data. if (successful) { StatusTextDisplay.Instance.SetStatusText( "synchronisation data downloaded"); int datasize = request.GetDataSize(); if (SharingStage.Instance.ShowDetailedLogs) { Debug.LogFormat("Anchor Manager: Anchor size: {0} bytes.", datasize.ToString()); } rawAnchorData = new byte[datasize]; request.GetData(rawAnchorData, datasize); currentState = ImportState.DataDownloadedReadyForImport; } else { StatusTextDisplay.Instance.SetStatusText( "retrying synchronisation request"); // If we failed, we can ask for the data again. Debug.LogWarning("Anchor Manager: Anchor DL failed " + failureReason); #if UNITY_WSA && !UNITY_EDITOR MakeAnchorDataRequest(); #endif } }
/// <summary>Initialize the importer</summary> /// <remarks>Called by host to have an importer prepare for a load and to pass in importer initialization parameters /// (SQL Server name, target database, etc).</remarks> /// <param name="Filemask">Path to the file(s) to import. May be a filemask</param> /// <param name="connString">Database connection string</param> /// <param name="Server">SQL Server name</param> /// <param name="UseWindowsAuth">Whether to use an integrated/trusted SQL connection</param> /// <param name="SQLLogin">SQL login name (implies <c>UseWindowsAuth</c>==false)</param> /// <param name="SQLPassword">SQL password (implies <c>UseWindowsAuth</c>==false)</param> /// <param name="DatabaseName">Target database name</param> /// <param name="Logger"><c>ILogger</c> instance - use to communicate status/debug messages back to host</param> /// <returns>void</returns> public void Initialize(string Filemask, string connString, string Server, bool UseWindowsAuth, string SQLLogin, string SQLPassword, string DatabaseName, ILogger Logger) { // Persist inputs from host this.traceFileSpec = Filemask; this.connStr = connString; this.sqlServer = Server; this.sqlLogin = SQLLogin; this.sqlPassword = SQLPassword; this.database = DatabaseName; this.useWindowsAuth = UseWindowsAuth; this.logger = Logger; // Init status members state = ImportState.Idle; canceled = false; knownRowsets = new ArrayList(); this.totalLinesProcessed = 0; this.totalRowsInserted = 0; if (null == this.readTracePath) { FindReadTraceExe(); } Util.Logger.LogMessage(@"ReadTrace.exe Path: " + (null == this.readTracePath ? "(NOT FOUND)" : this.readTracePath)); return; }
/// <inheritdoc /> public ImportResult ImportFromSplitwise() { lock (SplitwiseManager.lockObj) { if (SplitwiseManager.importStatus == ImportState.Running) { return(ImportResult.AlreadyRunning); } SplitwiseManager.importStatus = ImportState.Running; } var lastRan = this.Context.SynchronizationTimes .Single() .SplitwiseLastRun; // Get the new and updated expenses from Splitwise. var timestamp = DateTime.UtcNow; var newExpenses = this.splitwiseContext.GetExpenses(lastRan); var newExpenseIds = newExpenses.Select(t => t.Id).ToSet(); // Load relevant entities and store them in a dictionary. var splitwiseTransactionsById = this.Context.SplitwiseTransactions .IncludeAll() .Where(t => newExpenseIds.Contains(t.Id)) .AsEnumerable() .ToDictionary(t => t.Id); var transactionsBySplitwiseId = this.Context.Transactions .IncludeAll() .Where(t => t.SplitwiseTransactionId.HasValue) .Where(t => newExpenseIds.Contains(t.SplitwiseTransactionId.Value)) .AsEnumerable() .ToDictionary(t => t.SplitwiseTransactionId.Value); this.ConcurrentInvoke(() => { var processor = new TransactionProcessor(this.Context, this.splitwiseContext); this.Context.SetSplitwiseSynchronizationTime(timestamp); foreach (var newExpense in newExpenses) { var splitwiseTransactionMaybe = splitwiseTransactionsById.TryGetValue(newExpense.Id); if (splitwiseTransactionMaybe.IsSome && splitwiseTransactionMaybe.Value.UpdatedAt == newExpense.UpdatedAt) { // The last updated at is equal to the one stored, meaning that the latest update was // triggered by this application and is already handled. continue; } // The new expense is not known and the user has no share, so it's irrelevant. if (splitwiseTransactionMaybe.IsNone && !newExpense.HasShare) { continue; } var transaction = transactionsBySplitwiseId.TryGetValue(newExpense.Id); // Revert the transaction before updating values, don't send the update to Splitwise again. if (transaction.IsSome) { processor.RevertIfProcessed(transaction.Value, true); // Remove the transaction, it is re-added if needed. this.Context.Transactions.Remove(transaction.Value); } // Update the values of the Splitwise transaction, or create a new one. var splitwiseTransaction = splitwiseTransactionMaybe.Match( st => { this.Context.SplitDetails.RemoveRange(st.SplitDetails); st.UpdateValues(newExpense); st.SplitDetails = newExpense.Splits.Select(s => s.ToSplitDetailEntity()).ToList(); return(st); }, () => { var st = newExpense.ToSplitwiseTransactionEntity(); this.Context.SplitwiseTransactions.Add(st); return(st); }); // Remove the Splitwise transaction if it is irrelevant if (!splitwiseTransaction.HasShare) { this.Context.SplitwiseTransactions.Remove(splitwiseTransaction); continue; } // If the Splitwise transaction was already completely imported and is importable after the update, // then try to update the transaction. if (transaction.IsSome && splitwiseTransaction.Importable && // If the account or category is now obsolete, then the Splitwise transaction has to be re-imported. !transaction.Value.Account.IsObsolete && !transaction.Value.Category.IsObsolete) { transaction = splitwiseTransaction.ToTransaction( transaction.Value.Account, transaction.Value.Category); this.Context.Transactions.Add(transaction.Value); processor.ProcessIfNeeded(transaction.Value); } } this.Context.SaveChanges(); }); SplitwiseManager.importStatus = ImportState.NotRunning; return(ImportResult.Completed); }
public void nextState() { currentImportState = currentImportState + 1; }
private static void ConvertSceneNodes(PssgFile pssg, PssgNode parent, Node gltfNode, ImportState state) { PssgNode node; if (gltfNode.Name.StartsWith("Scene Root", StringComparison.InvariantCulture)) { node = new PssgNode("ROOTNODE", parent.File, parent); node.AddAttribute("stopTraversal", 0u); node.AddAttribute("nickname", "Scene Root"); node.AddAttribute("id", "Scene Root"); parent.ChildNodes.Add(node); } else if (gltfNode.Mesh is not null) { _ = CreateRenderNode(parent, gltfNode, state); return; } else { node = new PssgNode("NODE", parent.File, parent); node.AddAttribute("stopTraversal", 0u); node.AddAttribute("nickname", gltfNode.Name); node.AddAttribute("id", gltfNode.Name); parent.ChildNodes.Add(node); } var transformNode = new PssgNode("TRANSFORM", node.File, node) { Value = GetTransform(gltfNode.LocalMatrix) }; node.ChildNodes.Add(transformNode); var bboxNode = new PssgNode("BOUNDINGBOX", node.File, node) { Value = GetBoundingBoxData(Vector3.Zero, Vector3.Zero) }; node.ChildNodes.Add(bboxNode); foreach (var child in gltfNode.VisualChildren) { ConvertSceneNodes(pssg, node, child, state); } }
public static void SetProgress(string session, ImportState state, int percentage) { ImportStateResponse resp = new ImportStateResponse(state, percentage); sessionMap[session] = resp; }
private static void CreateMatrixPaletteJointNode(PssgNode parent, Node gltfNode, ImportState state) { var node = new PssgNode("MATRIXPALETTEJOINTNODE", parent.File, parent); node.AddAttribute("stopTraversal", 0u); node.AddAttribute("nickname", gltfNode.Name); node.AddAttribute("id", gltfNode.Name); node.AddAttribute("jointID", state.JointId); node.AddAttribute("matrixPalette", $"#x{state.LodNumber}_MPN"); parent.ChildNodes.Add(node); // Now add a new mesh from mesh builder ConvertMesh(node, gltfNode, state); state.JointId++; }
private static PssgNode CreateMatrixPaletteBundleNode(PssgNode parent, Node gltfNode, int lodNumber, ImportState state) { PssgNode node = new PssgNode("MATRIXPALETTEBUNDLENODE", parent.File, parent); node.AddAttribute("stopTraversal", 0u); node.AddAttribute("nickname", $"LOD{lodNumber}_"); node.AddAttribute("id", $"LOD{lodNumber}_"); parent.ChildNodes.Add(node); var transformNode = new PssgNode("TRANSFORM", node.File, node); transformNode.Value = GetTransform(gltfNode.LocalMatrix); node.ChildNodes.Add(transformNode); var bboxNode = new PssgNode("BOUNDINGBOX", node.File, node); bboxNode.Value = GetBoundingBoxData(Vector3.Zero, Vector3.Zero); node.ChildNodes.Add(bboxNode); state.LodNumber = lodNumber; state.MatShaderMapping.Clear(); foreach (var child in gltfNode.VisualChildren) { if (child.Mesh is null) { continue; } if (child.Mesh.Primitives.Count == 0) { continue; } CreateMatrixPaletteJointNode(node, child, state); } CreateMatrixPaletteNode(node, state); // Write the mesh data WriteMeshData(state); return(node); }
/// <summary> /// Start the conversion process /// </summary> public void Convert() { #region Debug stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); System.Diagnostics.Debug.Print(DateTime.Now + " : " + "Table-to-form GUID creation initiated. Elapsed: " + stopwatch.Elapsed.TotalSeconds.ToString()); #endregion // Debug int artifacts = 0; if (SetStatus != null) { SetStatus("Getting data..."); } DT = sourceDriver.GetTableData(tableName, columnNames); artifacts = (DT.Rows.Count * destinationView.Pages.Count) + DT.Rows.Count; if (SetMaxProgressBarValue != null) { SetMaxProgressBarValue((double)artifacts); } #region Set up global record ID values if (SetStatus != null) { SetStatus("Starting global record ID generation..."); } DT.Columns.Add(new DataColumn("GlobalRecordId", typeof(string))); int currentRow = 0; foreach (DataRow row in DT.Rows) { string GUID = System.Guid.NewGuid().ToString(); row["GlobalRecordId"] = GUID; currentRow++; } System.Diagnostics.Debug.Print(DateTime.Now + " : " + "All GUIDs generated. Starting GUID assignment. Elapsed: " + stopwatch.Elapsed.TotalSeconds.ToString()); // set PK DataColumn[] parentPrimaryKeyColumns = new DataColumn[1]; parentPrimaryKeyColumns[0] = DT.Columns["GlobalRecordId"]; DT.PrimaryKey = parentPrimaryKeyColumns; int min = 0; int max = DT.Rows.Count; int q = max / 4; int Q1 = min + q; int Q2 = Q1 + q; int Q3 = max - q; conn = destinationDriver.GetConnection(); conn.Open(); doneEvents = new ManualResetEvent[4]; Debug.Print("Launching 4 GUID assignment tasks..."); GUIDState guidStateInfo; doneEvents[0] = new ManualResetEvent(false); guidStateInfo = new GUIDState(doneEvents[0], 0, 0, Q1); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolGUIDAssignCallback), guidStateInfo); doneEvents[1] = new ManualResetEvent(false); guidStateInfo = new GUIDState(doneEvents[1], 1, Q1, Q2); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolGUIDAssignCallback), guidStateInfo); doneEvents[2] = new ManualResetEvent(false); guidStateInfo = new GUIDState(doneEvents[2], 2, Q2, Q3); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolGUIDAssignCallback), guidStateInfo); doneEvents[3] = new ManualResetEvent(false); guidStateInfo = new GUIDState(doneEvents[3], 3, Q3, max); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolGUIDAssignCallback), guidStateInfo); WaitHandle.WaitAll(doneEvents); #endregion // Set up global record ID values doneEvents = null; if (SetStatus != null) { SetStatus("Populating field data..."); } System.Diagnostics.Debug.Print(DateTime.Now + " : " + "All GUIDs assigned. Starting page data import. Elapsed: " + stopwatch.Elapsed.TotalSeconds.ToString()); int pageCount = destinationView.Pages.Count; doneEvents = new ManualResetEvent[pageCount]; Debug.Print("Launch {0} tasks...", pageCount); ImportState stateInfo; for (int i = 0; i < pageCount; i++) { doneEvents[i] = new ManualResetEvent(false); stateInfo = new ImportState(destinationView.Pages[i], doneEvents[i], i); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolPageImportCallback), stateInfo); } WaitHandle.WaitAll(doneEvents); conn.Close(); conn.Dispose(); conn = null; stopwatch.Stop(); System.Diagnostics.Debug.Print(DateTime.Now + " : " + "Processing complete. Elapsed: " + stopwatch.Elapsed.TotalSeconds.ToString()); }
private static void ConvertSceneNodes(PssgFile pssg, PssgNode parent, Node gltfNode, ImportState state) { PssgNode node; Match lodMatch; if (gltfNode.Name.StartsWith("Scene Root")) { node = new PssgNode("ROOTNODE", parent.File, parent); node.AddAttribute("stopTraversal", 0u); node.AddAttribute("nickname", "Scene Root"); node.AddAttribute("id", "Scene Root"); parent.ChildNodes.Add(node); } else if ((lodMatch = state.LodMatcher.Match(gltfNode.Name)).Success) { var lodNumber = int.Parse(lodMatch.Groups[1].Value); node = CreateMatrixPaletteBundleNode(parent, gltfNode, lodNumber, state); return; } else { node = new PssgNode("NODE", parent.File, parent); node.AddAttribute("stopTraversal", 0u); node.AddAttribute("nickname", gltfNode.Name); node.AddAttribute("id", gltfNode.Name); parent.ChildNodes.Add(node); } var transformNode = new PssgNode("TRANSFORM", node.File, node); transformNode.Value = GetTransform(gltfNode.LocalMatrix); node.ChildNodes.Add(transformNode); var bboxNode = new PssgNode("BOUNDINGBOX", node.File, node); bboxNode.Value = GetBoundingBoxData(Vector3.Zero, Vector3.Zero); node.ChildNodes.Add(bboxNode); foreach (var child in gltfNode.VisualChildren) { ConvertSceneNodes(pssg, node, child, state); } }
private void ImportField(GFF.FieldDefinition def, KeyValue data, long offset, ref long newOffset, ImportState state) { var output = this.Data; output.Seek(offset + def.Offset, SeekOrigin.Begin); if (def.IsList == true) { if (def.IsReference == true && (data.Value != null || def.Type != GFF.FieldType.Generic)) { throw new NotSupportedException(); } var list = (IList)data.Value; if (list == null) { output.WriteValueU32(0xFFFFFFFF, LittleEndian); } else { output.WriteValueU32((uint)newOffset, LittleEndian); output.Seek(newOffset, SeekOrigin.Begin); output.WriteValueS32(list.Count, LittleEndian); newOffset += 4; uint itemSize; if (def.Type == GFF.FieldType.Structure) { var subdef = this.Structures[def.StructureId]; itemSize = subdef.DataSize; } else { itemSize = GFF.Builtin.SizeOf(def.Type); } newOffset += list.Count * itemSize; switch (def.Type) { case GFF.FieldType.String: { throw new NotImplementedException(); } case GFF.FieldType.Structure: { var subdef = this.Structures[def.StructureId]; long itemOffset = output.Position; foreach (var item in list) { this.ImportStructure( subdef, (KeyValue)item, itemOffset, ref newOffset, state); itemOffset += itemSize; } break; } default: { if (def.Type == GFF.FieldType.UInt8 && list.GetType() == typeof(byte[])) { var bytes = (byte[])list; output.Write(bytes, 0, bytes.Length); } else { long itemOffset = output.Position; foreach (var item in list) { GFF.Builtin.Serialize(output, def.Type, item, LittleEndian); itemOffset += itemSize; } } break; } } } } else { if (def.IsReference == true && def.Type != GFF.FieldType.Structure) { throw new NotSupportedException(); } switch (def.Type) { case GFF.FieldType.String: { var s = data.As<string>(); if (s == null || s.Length == 0) { output.WriteValueU32(0xFFFFFFFF, LittleEndian); } else { var length = s.Length + 1; output.WriteValueU32((uint)newOffset, LittleEndian); output.Seek(newOffset, SeekOrigin.Begin); output.WriteValueS32(length, LittleEndian); output.WriteString(s, LittleEndian ? Encoding.Unicode : Encoding.BigEndianUnicode); output.WriteValueU16(0, LittleEndian); newOffset += 4 + (2 * length); } break; } case GFF.FieldType.TalkString: { var s = data.As<GFF.Builtins.TalkString>(); output.WriteValueU32(s.Id, LittleEndian); if (s.String == null) { output.WriteValueU32(0xFFFFFFFF, LittleEndian); } else if (s.String.Length == 0) { output.WriteValueU32(0, LittleEndian); } else { var length = s.String.Length + 1; output.WriteValueU32((uint)newOffset, LittleEndian); output.Seek(newOffset, SeekOrigin.Begin); output.WriteValueS32(length, LittleEndian); output.WriteString(s.String, LittleEndian ? Encoding.Unicode : Encoding.BigEndianUnicode); output.WriteValueU16(0, LittleEndian); newOffset += 4 + (2 * length); } break; } case GFF.FieldType.Structure: { if (def.IsReference == true) { if (data == null || data.Values == null) { output.WriteValueU32(0xFFFFFFFF, LittleEndian); } else { output.WriteValueU32((uint)newOffset, LittleEndian); output.Seek(newOffset, SeekOrigin.Begin); var subdef = this.Structures[def.StructureId]; newOffset += subdef.DataSize; this.ImportStructure( subdef, data, output.Position, ref newOffset, state); } } else { var subdef = this.Structures[def.StructureId]; this.ImportStructure( subdef, data, output.Position, ref newOffset, state); } break; } default: { GFF.Builtin.Serialize(output, def.Type, data.Value, LittleEndian); break; } } } }
private ImportState ProcessMessage(RawMessageDescriptor msg, ImportState importState) { //pool.QueueWorkItem(() => ImportRunner(msg)); ImportBulk(msg); return(importState); }
/// <summary> /// Start the conversion process /// </summary> public void Convert() { #region Debug stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); System.Diagnostics.Debug.Print(DateTime.Now + " : " + "Table-to-form GUID creation initiated. Elapsed: " + stopwatch.Elapsed.TotalSeconds.ToString()); #endregion // Debug int artifacts = 0; if (SetStatus != null) { SetStatus("Getting data..."); } DT = sourceDriver.GetTableData(tableName, columnNames); artifacts = (DT.Rows.Count * destinationView.Pages.Count) + DT.Rows.Count; if (SetMaxProgressBarValue != null) { SetMaxProgressBarValue((double)artifacts); } #region Set up global record ID values if (SetStatus != null) { SetStatus("Starting global record ID generation..."); } DT.Columns.Add(new DataColumn("GlobalRecordId", typeof(string))); int currentRow = 0; foreach (DataRow row in DT.Rows) { string GUID = System.Guid.NewGuid().ToString(); row["GlobalRecordId"] = GUID; currentRow++; } System.Diagnostics.Debug.Print(DateTime.Now + " : " + "All GUIDs generated. Starting GUID assignment. Elapsed: " + stopwatch.Elapsed.TotalSeconds.ToString()); // set PK DataColumn[] parentPrimaryKeyColumns = new DataColumn[1]; parentPrimaryKeyColumns[0] = DT.Columns["GlobalRecordId"]; DT.PrimaryKey = parentPrimaryKeyColumns; int min = 0; int max = DT.Rows.Count; int q = max / 4; int Q1 = min + q; int Q2 = Q1 + q; int Q3 = max - q; conn = destinationDriver.GetConnection(); conn.Open(); doneEvents = new ManualResetEvent[4]; Debug.Print("Launching 4 GUID assignment tasks..."); GUIDState guidStateInfo; doneEvents[0] = new ManualResetEvent(false); guidStateInfo = new GUIDState(doneEvents[0], 0, 0, Q1); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolGUIDAssignCallback), guidStateInfo); doneEvents[1] = new ManualResetEvent(false); guidStateInfo = new GUIDState(doneEvents[1], 1, Q1, Q2); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolGUIDAssignCallback), guidStateInfo); doneEvents[2] = new ManualResetEvent(false); guidStateInfo = new GUIDState(doneEvents[2], 2, Q2, Q3); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolGUIDAssignCallback), guidStateInfo); doneEvents[3] = new ManualResetEvent(false); guidStateInfo = new GUIDState(doneEvents[3], 3, Q3, max); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolGUIDAssignCallback), guidStateInfo); WaitHandle.WaitAll(doneEvents); #endregion // Set up global record ID values doneEvents = null; if (SetStatus != null) { SetStatus("Populating field data..."); } System.Diagnostics.Debug.Print(DateTime.Now + " : " + "All GUIDs assigned. Starting page data import. Elapsed: " + stopwatch.Elapsed.TotalSeconds.ToString()); int pageCount = destinationView.Pages.Count; doneEvents = new ManualResetEvent[pageCount]; Debug.Print("Launch {0} tasks...", pageCount); ImportState stateInfo; for (int i = 0; i < pageCount; i++) { doneEvents[i] = new ManualResetEvent(false); stateInfo = new ImportState(destinationView.Pages[i], doneEvents[i], i); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolPageImportCallback), stateInfo); } WaitHandle.WaitAll(doneEvents); conn.Close(); conn.Dispose(); conn = null; stopwatch.Stop(); System.Diagnostics.Debug.Print(DateTime.Now + " : " + "Processing complete. Elapsed: " + stopwatch.Elapsed.TotalSeconds.ToString()); }
private static void ConvertMesh(PssgNode mpjnNode, Node gltfNode, ImportState state) { var mesh = gltfNode.Mesh; if (mesh.Primitives.Any(p => p.Material == null)) { throw new NotImplementedException($"The converter does not support primitives ({mesh.Name}) with a null material."); } var transformNode = new PssgNode("TRANSFORM", mpjnNode.File, mpjnNode); transformNode.Value = GetTransform(gltfNode.LocalMatrix); mpjnNode.ChildNodes.Add(transformNode); var bboxNode = new PssgNode("BOUNDINGBOX", mpjnNode.File, mpjnNode); mpjnNode.ChildNodes.Add(bboxNode); // Add to the material shader mapping var gltfMats = mesh.Primitives.Select(p => p.Material); ConvertMaterials(gltfMats, mpjnNode.File, state); // Export Vertices, Normals, TexCoords, VertexWeights and Faces Mesh gltfMesh = gltfNode.Mesh; var meshDecoder = gltfMesh.Decode(); Vector3 minExtent = new Vector3(float.MaxValue); Vector3 maxExtent = new Vector3(float.MinValue); foreach (var p in meshDecoder.Primitives) { // skip primitives that aren't tris if (!p.TriangleIndices.Any()) { continue; } // Get the new material index in grn int faceMatId = p.Material.LogicalIndex; ShaderInstanceData shaderData; if (state.MatShaderMapping.ContainsKey(faceMatId)) { shaderData = state.MatShaderMapping[faceMatId]; } else { throw new InvalidDataException($"Mesh ({gltfMesh.Name}) has an invalid material id " + faceMatId + "."); } var rds = shaderData.Rds; var tris = p.TriangleIndices.ToArray(); var baseVertexIndex = rds.Positions.Count; var mpriNode = new PssgNode("MATRIXPALETTERENDERINSTANCE", mpjnNode.File, mpjnNode); mpriNode.AddAttribute("streamOffset", (uint)(rds.Positions.Count)); mpriNode.AddAttribute("elementCountFromOffset", (uint)(p.VertexCount)); mpriNode.AddAttribute("indexOffset", (uint)(rds.Indices.Count)); mpriNode.AddAttribute("indicesCountFromOffset", (uint)(tris.Length * 3)); mpriNode.AddAttribute("sourceCount", 1u); mpriNode.AddAttribute("indices", $"#{rds.Name}"); mpriNode.AddAttribute("streamCount", 0u); mpriNode.AddAttribute("shader", $"#{shaderData.ShaderInstanceName}"); mpriNode.AddAttribute("id", $"MPJRI{state.MpjriCount}"); state.MpjriCount++; mpjnNode.ChildNodes.Add(mpriNode); var risNode = new PssgNode("RENDERINSTANCESOURCE", mpriNode.File, mpriNode); risNode.AddAttribute("source", $"#{shaderData.Rds.Name}"); mpriNode.ChildNodes.Add(risNode); var texCoordSet = GetDiffuseBaseColorTexCoord(p.Material); string texCoordAccessorName = $"TEXCOORD_{texCoordSet}"; // Make sure we have all the necessary data if (p.VertexCount < 3) { throw new InvalidDataException($"Mesh ({gltfMesh.Name}) must have at least 3 positions."); } if (p.TexCoordsCount <= texCoordSet) { throw new InvalidDataException($"Mesh ({gltfMesh.Name}) must have tex coord set {texCoordSet}."); } // Grab the data for (int i = 0; i < p.VertexCount; ++i) { var pos = p.GetPosition(i); var color = p.GetColor(i, 0); // Compute extents for bounding box minExtent.X = Math.Min(pos.X, minExtent.X); minExtent.Y = Math.Min(pos.Y, minExtent.Y); minExtent.Z = Math.Min(pos.Z, minExtent.Z); maxExtent.X = Math.Max(pos.X, maxExtent.X); maxExtent.Y = Math.Max(pos.Y, maxExtent.Y); maxExtent.Z = Math.Max(pos.Z, maxExtent.Z); rds.Positions.Add(pos); rds.Normals.Add(p.GetNormal(i)); rds.Tangents.Add(p.GetTangent(i)); rds.TexCoords0.Add(p.GetTextureCoord(i, texCoordSet)); rds.Colors.Add(color); rds.SkinIndices.Add(state.JointId); } foreach (var tri in p.TriangleIndices) { var a = tri.A + baseVertexIndex; var b = tri.B + baseVertexIndex; var c = tri.C + baseVertexIndex; rds.Indices.Add((ushort)a); rds.Indices.Add((ushort)b); rds.Indices.Add((ushort)c); } } bboxNode.Value = GetBoundingBoxData(minExtent, maxExtent);
// This method is called from the ImportConflictWindow class after the user // has chosen what should happen with newly imported files. public static void HandleFileReplacements(bool replaceOld) { if (replaceOld) { if (mWasConfigFileUpdated == ImportState.RENAMED) { if (AssetDatabase.DeleteAsset( QCARUtilities.GlobalVars.CONFIG_XML_PATH)) { string renameError = AssetDatabase.RenameAsset( mUnwantedConfigXMLPath, "config"); if (renameError != "") { Debug.LogError("Rename operation returns: " + renameError); } } else { Debug.LogError("Could not delete asset with name: " + QCARUtilities.GlobalVars.CONFIG_XML_PATH); } mWasConfigFileUpdated = ImportState.ADDED; } if (mWasDATFileUpdated == ImportState.RENAMED) { if (AssetDatabase.DeleteAsset( QCARUtilities.GlobalVars.DAT_PATH)) { string renameError = AssetDatabase.RenameAsset( mUnwantedDATPath, "qcar-resources"); if (renameError != "") { Debug.LogError("Rename operation returns: " + renameError); } } else { Debug.LogError("Could not delete asset with name: " + QCARUtilities.GlobalVars.DAT_PATH); } mWasDATFileUpdated = ImportState.ADDED; } } else { if (mWasConfigFileUpdated == ImportState.RENAMED) { AssetDatabase.DeleteAsset(mUnwantedConfigXMLPath); mWasConfigFileUpdated = ImportState.ADDED; } if (mWasDATFileUpdated == ImportState.RENAMED) { AssetDatabase.DeleteAsset(mUnwantedDATPath); mWasDATFileUpdated = ImportState.ADDED; } } mUnwantedConfigXMLPath = null; mUnwantedDATPath = null; SceneManager.Instance.FilesUpdated(mWasConfigFileUpdated, mWereTexturesUpdated, mWasDATFileUpdated); mProcessingReplacement = false; }
// This method is called by Unity whenever assets are updated (deleted, // moved or added). public static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { // We ignore new requests until we finished replacement actions. if (mProcessingReplacement) { return; } mWasConfigFileUpdated = ImportState.NONE; mWereTexturesUpdated = ImportState.NONE; mWasDATFileUpdated = ImportState.NONE; bool replacementDetected = false; // We are using regular expression to determine if a file has been // renamed by Unity. Regex configFileRegex = new Regex( QCARUtilities.GlobalVars.REGEXED_CONFIG_XML_PATH, RegexOptions.IgnoreCase); Regex datFileRegex = new Regex( QCARUtilities.GlobalVars.REGEXED_DAT_PATH, RegexOptions.IgnoreCase); // Check if there are relevant files that have been imported. foreach (string importedAsset in importedAssets) { if (importedAsset.IndexOf( QCARUtilities.GlobalVars.CONFIG_XML_PATH, System.StringComparison.OrdinalIgnoreCase) != -1) { mWasConfigFileUpdated = ImportState.ADDED; } else if (importedAsset.IndexOf( QCARUtilities.GlobalVars.PATH_TO_TARGET_TEXTURES, System.StringComparison.OrdinalIgnoreCase) != -1) { mWereTexturesUpdated = ImportState.ADDED; } else if (importedAsset.IndexOf( QCARUtilities.GlobalVars.DAT_PATH, System.StringComparison.OrdinalIgnoreCase) != -1) { mWasDATFileUpdated = ImportState.ADDED; } else if (configFileRegex.IsMatch(importedAsset)) { replacementDetected = true; mWasConfigFileUpdated = ImportState.RENAMED; mUnwantedConfigXMLPath = importedAsset; } else if (datFileRegex.IsMatch(importedAsset)) { replacementDetected = true; mWasDATFileUpdated = ImportState.RENAMED; mUnwantedDATPath = importedAsset; } } // Check if there are relevant files that have been deleted. foreach (string deletedAsset in deletedAssets) { if (deletedAsset.IndexOf( QCARUtilities.GlobalVars.CONFIG_XML_PATH, System.StringComparison.OrdinalIgnoreCase) != -1) { mWasConfigFileUpdated = ImportState.DELETED; } else if (deletedAsset.IndexOf( QCARUtilities.GlobalVars.PATH_TO_TARGET_TEXTURES, System.StringComparison.OrdinalIgnoreCase) != -1) { mWereTexturesUpdated = ImportState.DELETED; } else if (deletedAsset.IndexOf( QCARUtilities.GlobalVars.DAT_PATH, System.StringComparison.OrdinalIgnoreCase) != -1) { mWasDATFileUpdated = ImportState.DELETED; } } // If a file needs to be replaced we delay the update callback call // until the user has made a decision between keeping the old or the // new files. if (replacementDetected) { mProcessingReplacement = true; ImportConflictWindow.ShowWindow(); } else { bool filesUpdated = ((mWasConfigFileUpdated != ImportState.NONE) || (mWereTexturesUpdated != ImportState.NONE) || (mWasDATFileUpdated != ImportState.NONE)); // We only alert the SceneManager if files have actually been // changed. if (filesUpdated) { SceneManager.Instance.FilesUpdated(mWasConfigFileUpdated, mWereTexturesUpdated, mWasDATFileUpdated); } } }
private static PssgNode CreateMatrixPaletteBundleNode(PssgNode parent, Node gltfNode, int lodNumber, ImportState state) { PssgNode node = new PssgNode("MATRIXPALETTEBUNDLENODE", parent.File, parent); node.AddAttribute("stopTraversal", 0u); node.AddAttribute("nickname", $"LOD{lodNumber}_"); node.AddAttribute("id", $"LOD{lodNumber}_"); parent.ChildNodes.Add(node); var transformNode = new PssgNode("TRANSFORM", node.File, node); transformNode.Value = GetTransform(gltfNode.LocalMatrix); node.ChildNodes.Add(transformNode); var bboxNode = new PssgNode("BOUNDINGBOX", node.File, node); bboxNode.Value = GetBoundingBoxData(Vector3.Zero, Vector3.Zero); node.ChildNodes.Add(bboxNode); state.LodNumber = lodNumber; state.JointId = 0; state.MatShaderMapping.Clear(); List <string> jointNames = new List <string>(); foreach (var child in gltfNode.VisualChildren) { if (child.Mesh is null) { continue; } if (child.Mesh.Primitives.Count == 0) { continue; } CreateMatrixPaletteJointNode(node, child, state); jointNames.Add(node.ChildNodes.Last().Attributes["id"].GetValue <string>()); } CreateMatrixPaletteNode(node, jointNames, state); // Write the mesh data var rdsLib = node.File.FindNodes("LIBRARY", "type", "RENDERDATASOURCE").First(); var ribLib = node.File.FindNodes("LIBRARY", "type", "RENDERINTERFACEBOUND").First(); WriteMeshData(rdsLib, ribLib, state); return(node); }
private void ImportStructure(GFF.StructureDefinition def, KeyValue data, long offset, ref long newOffset, ImportState state) { foreach (var fieldDef in def.Fields) { if (fieldDef.Id == 16208) { } KeyValue value; if (data.Values.ContainsKey(fieldDef.Id) == false) { //throw new InvalidOperationException(); value = new KeyValue(fieldDef.Type, null); } else { value = data[fieldDef.Id]; } this.ImportField(fieldDef, value, offset, ref newOffset, state); } }
public WizardController(String mfileName) { currentImportState = ImportState.None; fileName = mfileName; }
public ImportStateModel(ImportState state) { Session = state.Session.ToString(); Completed = state.Completed; ErrorMessage = state.ErrorMsg; }
private static void ConvertMesh(PssgNode renderNode, Node gltfNode, ImportState state) { var mesh = gltfNode.Mesh; if (mesh.Primitives.Any(p => p.Material == null)) { throw new NotImplementedException($"The converter does not support primitives ({mesh.Name}) with a null material."); } var transformNode = new PssgNode("TRANSFORM", renderNode.File, renderNode) { Value = GetTransform(gltfNode.LocalMatrix) }; renderNode.ChildNodes.Add(transformNode); var bboxNode = new PssgNode("BOUNDINGBOX", renderNode.File, renderNode); renderNode.ChildNodes.Add(bboxNode); // Add to the material shader mapping var gltfMats = mesh.Primitives.Select(p => p.Material); ConvertMaterials(gltfMats, renderNode.File, state); // Export Vertices, Normals, TexCoords, VertexWeights and Faces var gltfMesh = gltfNode.Mesh; var meshDecoder = gltfMesh.Decode(); var minExtent = new Vector3(float.MaxValue); var maxExtent = new Vector3(float.MinValue); foreach (var p in meshDecoder.Primitives) { // skip primitives that aren't tris if (!p.TriangleIndices.Any()) { continue; } // Get the new material index in grn var faceMatId = p.Material.LogicalIndex; ShaderInstanceData shaderData; if (state.MatShaderMapping.ContainsKey(faceMatId)) { shaderData = state.MatShaderMapping[faceMatId]; } else { throw new InvalidDataException($"Mesh ({gltfMesh.Name}) has an invalid material id " + faceMatId + "."); } var rds = shaderData.Rds; var tris = p.TriangleIndices.ToArray(); var baseVertexIndex = rds.Positions.Count; var rsiNode = new PssgNode("RENDERSTREAMINSTANCE", renderNode.File, renderNode); rsiNode.AddAttribute("sourceCount", 1u); rsiNode.AddAttribute("indices", $"#{rds.Name}"); rsiNode.AddAttribute("streamCount", 0u); rsiNode.AddAttribute("shader", $"#{shaderData.ShaderInstanceName}"); rsiNode.AddAttribute("id", $"!RSI{state.RenderStreamInstanceCount}"); state.RenderStreamInstanceCount++; renderNode.ChildNodes.Add(rsiNode); var risNode = new PssgNode("RENDERINSTANCESOURCE", rsiNode.File, rsiNode); risNode.AddAttribute("source", $"#{shaderData.Rds.Name}"); rsiNode.ChildNodes.Add(risNode); var texCoordSet0 = GetDiffuseBaseColorTexCoord(p.Material); var texCoordSet1 = GetOcclusionTexCoord(p.Material); var texCoordSet2 = GetEmissiveTexCoord(p.Material); var texCoordSet3 = GetNormalTexCoord(p.Material); if (state.IsF1) { // F1 stores spec occ first, then diffuse var temp = texCoordSet0; texCoordSet0 = texCoordSet1; texCoordSet1 = temp; } // Make sure we have all the necessary data if (p.VertexCount < 3) { throw new InvalidDataException($"Mesh ({gltfMesh.Name}) must have at least 3 positions."); } // Grab the data for (var i = 0; i < p.VertexCount; ++i) { var pos = p.GetPosition(i); var color = p.GetColor(i, 0); // Compute extents for bounding box minExtent.X = Math.Min(pos.X, minExtent.X); minExtent.Y = Math.Min(pos.Y, minExtent.Y); minExtent.Z = Math.Min(pos.Z, minExtent.Z); maxExtent.X = Math.Max(pos.X, maxExtent.X); maxExtent.Y = Math.Max(pos.Y, maxExtent.Y); maxExtent.Z = Math.Max(pos.Z, maxExtent.Z); rds.Positions.Add(pos); rds.Normals.Add(p.GetNormal(i)); rds.Tangents.Add(p.GetTangent(i)); rds.TexCoords0.Add(p.GetTextureCoord(i, texCoordSet0)); rds.TexCoords1.Add(p.GetTextureCoord(i, texCoordSet1)); rds.TexCoords2.Add(p.GetTextureCoord(i, texCoordSet2)); rds.TexCoords3.Add(p.GetTextureCoord(i, texCoordSet3)); rds.Colors.Add(color); rds.SkinIndices.Add(0); } foreach (var(A, B, C) in p.TriangleIndices) { var a = A + baseVertexIndex; var b = B + baseVertexIndex; var c = C + baseVertexIndex; rds.Indices.Add((ushort)a); rds.Indices.Add((ushort)b); rds.Indices.Add((ushort)c); } } bboxNode.Value = GetBoundingBoxData(minExtent, maxExtent);
public void previousState() { currentImportState = currentImportState - 1; }