public unsafe void TestComponentAccess() { var entity = new Entity(); entity.AddChild(new Entity("child1") { new LightComponent() }); var modelComponent = new ModelComponent(); var compiledUpdate = UpdateEngine.Compile(typeof(Entity), new List <UpdateMemberInfo> { new UpdateMemberInfo("[ModelComponent.Key]", 0), new UpdateMemberInfo("child1[LightComponent.Key].Intensity", 0), }); var testData = new TestData[] { 32.0f }; fixed(TestData *dataPtr = testData) { UpdateEngine.Run(entity, compiledUpdate, (IntPtr)dataPtr, new[] { new UpdateObjectData(modelComponent) }); } Assert.That(entity.Get(ModelComponent.Key), Is.EqualTo(modelComponent)); Assert.That(entity.GetChild(0).Get(LightComponent.Key).Intensity, Is.EqualTo(32.0f)); }
public void TestParameterCollectionResolver() { var test = new TestParameterCollectionClass(); var test2 = new object(); UpdateEngine.RegisterMemberResolver(new ParameterCollectionResolver()); var updateMemberInfo = new List <UpdateMemberInfo> { new UpdateMemberInfo($"Parameters[{nameof(ParameterCollectionUpdateEngineTest)}.{nameof(IntKey)}]", 0), new UpdateMemberInfo($"Parameters[{nameof(ParameterCollectionUpdateEngineTest)}.{nameof(BlittableKey)}].IntField", 0), new UpdateMemberInfo($"Parameters[{nameof(ParameterCollectionUpdateEngineTest)}.{nameof(BlittableKey)}].IntProperty", 0), new UpdateMemberInfo($"Parameters[{nameof(ParameterCollectionUpdateEngineTest)}.{nameof(ObjectKey)}]", 0), }; var blittableData = new TestUpdateEngine.TestData[] { 123, 456 }; var objectData = new[] { new UpdateObjectData(test2) }; TestUpdateEngine.RunUpdateEngine(test, updateMemberInfo, blittableData, objectData); Assert.Equal(123, test.Parameters.Get(IntKey)); Assert.Equal(123, test.Parameters.Get(BlittableKey).IntField); Assert.Equal(123, test.Parameters.Get(BlittableKey).IntProperty); Assert.Equal(test2, test.Parameters.Get(ObjectKey)); }
public void TestTestClassList() { UpdateEngine.RegisterMemberResolver(new ListUpdateResolver <TestClass>()); var test = new TestClass(); var test2 = new TestClass(); var updateMemberInfo = new List <UpdateMemberInfo> { new UpdateMemberInfo("TestClassList[0]", 0), new UpdateMemberInfo("TestClassList[0].IntField", 0), new UpdateMemberInfo("TestClassList[1]", 1), new UpdateMemberInfo("TestClassList[1].IntField", 8), }; var blittableData = new TestData[] { 123, 456 }; var objectData = new[] { new UpdateObjectData(test), new UpdateObjectData(test2) }; RunUpdateEngine(test, updateMemberInfo, blittableData, objectData); Assert.Equal(test, test.TestClassList[0]); Assert.Equal(123, test.TestClassList[0].IntField); Assert.Equal(test2, test.TestClassList[1]); Assert.Equal(456, test.TestClassList[1].IntField); }
private void btnInstallUpdates_Click(object sender, EventArgs e) { UpdateEngine.PrepareForInstall(_updatesFilePath); // Exit the main application loop Application.Exit(); }
private void bCreateEngine_Click(object sender, EventArgs e) { if (_Engine != null) { _Engine.Dispose(); } _Engine = new UpdateEngine(eUpdateDownloadTestUrl.Text, new Version(eUpdateDownloadCheckVersion.Text)); if (cbCheckSignatures.Checked) { _Engine.RsaPublicKey = _PrivateKey.ToXmlString(false); } _Engine.Logger = new InternalLogger() { Form = this }; _Engine.DownloadFolder = eFolder.Text; _Engine.UpdateFound += engine_UpdateFound; _Engine.UpdateDownloadProgressChanged += engine_UpdateDownloadProgressChanged; _Engine.UpdateDownloadFinished += engine_UpdateDownloadFinished; _Engine.UpdateDownloadStarting += engine_UpdatedownloadStarting; bStartUpdateCheck.Enabled = true; bOneTimeCheck.Enabled = true; bDownloadAvailable.Enabled = true; bMonitoringOnly.Enabled = true; }
public unsafe void TestComponentAccess() { var entity = new Entity(); entity.AddChild(new Entity("child1") { new LightComponent() }); var modelComponent = new ModelComponent(); var compiledUpdate = UpdateEngine.Compile(typeof(Entity), new List <UpdateMemberInfo> { new UpdateMemberInfo("[ModelComponent]", 0), new UpdateMemberInfo("child1[LightComponent.Key].Intensity", 0), // Keep key just for backward comp, we will remove it }); var testData = new TestData[] { 32.0f }; fixed(TestData *dataPtr = testData) { UpdateEngine.Run(entity, compiledUpdate, (IntPtr)dataPtr, new[] { new UpdateObjectData(modelComponent) }); } Assert.Equal(modelComponent, entity.Get <ModelComponent>()); Assert.Equal(32.0f, entity.GetChild(0).Get <LightComponent>().Intensity); }
protected override bool Setup(IRootConfig rootConfig, IServerConfig config) { //TODO 读取配置设置isDebug Debug.SetLogger(Logger, true); try { updateInterval = int.Parse(config.Options.Get("UpdateInterval")); SyncDebugSystem.isDebug = bool.Parse(config.Options.Get("IsDebug")); } catch { } Debug.Log("SyncService Setup Mode: " + config.Mode + "\nupdateInterval " + updateInterval + "\nisDebug " + SyncDebugSystem.isDebug); dataBaseService.Init(this, config); m_timerService.Init(this, config); matchService.Init(this, config); loginService.Init(this, config); reConnectService.Init(this, config); selectCharacterService.Init(this, config); settlementService.Init(this, config); m_aiService.Init(this, config); CommandMessageService <CommandComponent> .Init(); UpdateEngine.Init(updateInterval); return(base.Setup(rootConfig, config)); }
public void TestManyProperties() { var test = new TestClass(); var test2 = new TestClass(); var test3 = new TestClass(); UpdateEngine.RegisterMemberResolver(new ArrayUpdateResolver <int>()); UpdateEngine.RegisterMemberResolver(new ListUpdateResolver <int>()); UpdateEngine.RegisterMemberResolver(new ArrayUpdateResolver <TestClass>()); // Combine many of the other tests in one, to easily test if switching from one member to another works well var updateMemberInfo = new List <UpdateMemberInfo> { new UpdateMemberInfo("IntField", 0), new UpdateMemberInfo("IntProperty", 8), new UpdateMemberInfo("NonBlittableStructField.TestClassField", 0), new UpdateMemberInfo("NonBlittableStructField.TestClassProperty", 0), new UpdateMemberInfo("NonBlittableStructProperty.TestClassField", 0), new UpdateMemberInfo("NonBlittableStructProperty.TestClassProperty", 0), new UpdateMemberInfo("ObjectField", 0), new UpdateMemberInfo("ObjectProperty", 0), new UpdateMemberInfo("IntArray[0]", 0), new UpdateMemberInfo("IntArray[2]", 0), new UpdateMemberInfo("IntArray[3]", 8), new UpdateMemberInfo("IntList[0]", 0), new UpdateMemberInfo("IntList[2]", 0), new UpdateMemberInfo("IntList[3]", 8), new UpdateMemberInfo("TestClassArray[0]", 0), new UpdateMemberInfo("TestClassArray[0].IntField", 0), new UpdateMemberInfo("TestClassArray[1]", 1), new UpdateMemberInfo("TestClassArray[1].IntField", 8), }; var blittableData = new TestData[] { 123, 456 }; var objectData = new[] { new UpdateObjectData(test2), new UpdateObjectData(test3) }; RunUpdateEngine(test, updateMemberInfo, blittableData, objectData); Assert.Equal(123, test.IntField); Assert.Equal(456, test.IntProperty); Assert.Equal(test2, test.NonBlittableStructField.TestClassField); Assert.Equal(test2, test.NonBlittableStructField.TestClassProperty); Assert.Equal(test2, test.NonBlittableStructProperty.TestClassField); Assert.Equal(test2, test.NonBlittableStructProperty.TestClassProperty); Assert.Equal(test2, test.ObjectField); Assert.Equal(test2, test.ObjectProperty); Assert.Equal(123, test.IntArray[0]); Assert.Equal(0, test.IntArray[1]); Assert.Equal(123, test.IntArray[2]); Assert.Equal(456, test.IntArray[3]); Assert.Equal(123, test.IntList[0]); Assert.Equal(0, test.IntList[1]); Assert.Equal(123, test.IntList[2]); Assert.Equal(456, test.IntList[3]); Assert.Equal(test2, test.TestClassArray[0]); Assert.Equal(123, test.TestClassArray[0].IntField); Assert.Equal(test3, test.TestClassArray[1]); Assert.Equal(456, test.TestClassArray[1].IntField); }
private async Task <bool> CheckForUpdates() { bool success = true; string xmlUrl = ""; string[] encodedXML = Assembly.GetExecutingAssembly().ManifestModule.Name.Split('_'); if (Program.Arguments.Length == 1) { Logger.Log("XML passed via CLI."); xmlUrl = Program.Arguments[0]; } else if (encodedXML.Length == 2) { Logger.Log("XML passed via module name."); xmlUrl = Encoding.UTF8.GetString(Convert.FromBase64String(encodedXML[1].Replace(".exe", ""))); } else { Logger.Log("XML path has not been passed to Super Update!", LogLevels.Exception); return(false); } success = await XmlEngine.ReadXML(xmlUrl); if (!success) { return(success); } success = await UpdateEngine.DetectUpdates(); if (!success) { return(success); } if (UpdateEngine.CurrentVersion != UpdateEngine.LatestVersion) { if (UpdateEngine.LatestVersion.Attributes["UpdateMessage"] != null) { Logger.Log(UpdateEngine.LatestVersion.Attributes["UpdateMessage"].Value, LogLevels.Information); } else { Logger.Log("Found new version, press \"Install\" to begin.", LogLevels.Information); } } else { XmlNode noUpdateMessage = XmlEngine.UpdateXML.SelectSingleNode("/SuperUpdate/Settings/MessageNoUpdate"); if (noUpdateMessage != null) { Logger.Log(noUpdateMessage.Attributes["Text"].Value, LogLevels.Information); } else { Logger.Log("No updates are available.", LogLevels.Information); } } return(success); }
private static unsafe void RunUpdateEngine(TestClass test, List <UpdateMemberInfo> updateMemberInfo, TestData[] blittableData, UpdateObjectData[] objectData) { var compiledUpdate = UpdateEngine.Compile(test.GetType(), updateMemberInfo); fixed(TestData *dataPtr = blittableData) { UpdateEngine.Run(test, compiledUpdate, (IntPtr)dataPtr, objectData); } }
internal static unsafe void RunUpdateEngine(object test, List <UpdateMemberInfo> updateMemberInfo, TestData[] blittableData, UpdateObjectData[] objectData, Type typeOverride = null) { var compiledUpdate = UpdateEngine.Compile(typeOverride ?? test.GetType(), updateMemberInfo); fixed(TestData *dataPtr = blittableData) { UpdateEngine.Run(test, compiledUpdate, (IntPtr)dataPtr, objectData); } }
private static void Main(string[] args) { var engine = new UpdateEngine(); if (engine.IsUpdateAvailable) { engine.Update(); } }
static void Main(string[] args) { try { _mutex = Mutex.OpenExisting("SQLiteCompare"); MessageBox.Show("Another instance of SQLiteCompare is already active.\r\n" + "Please close it first.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } catch (Exception ex) { _mutex = new Mutex(false, "SQLiteCompare"); } // Configure log4net BasicConfigurator.Configure(); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException); // Issue a log message that contains the version of the application. _log.Info("==========================================================================="); _log.Info(" SQLite Compare [" + Utils.GetSoftwareVersion() + " build " + Utils.GetSoftwareBuild() + "]"); _log.Info("==========================================================================="); // Remove any stale table change files TableChanges.RemoveStaleChangeFiles(); try { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); MainForm mf = new MainForm(); if (args.Length > 1) { mf.setFiles(args[0], args[1]); } _mainForm = mf; Application.Run(_mainForm); _mainForm = null; } catch (Exception ex) { _mainForm = null; _log.Error("Got exception from main loop", ex); ShowUnexpectedErrorDialog(ex); } finally { // Remove all active change files TableChanges.RemoveActiveChangeFiles(); } // finally // If there are pending software updates - apply them now UpdateEngine.ApplyPendingUpdates(); }
private void btnCancel_Click(object sender, EventArgs e) { if (UpdateEngine.IsBusy) { UpdateEngine.CancelAsync(); Cursor = Cursors.WaitCursor; } else { this.Close(); } }
public IActionResult PutEngine(Guid engineId, [FromBody] PutEngine model) { if (ModelState.IsValid) { var command = new UpdateEngine(engineId, model.Name, model.Power, model.Torque, model.Cylinders, model.Displacement); commandBus.AddCommand(command); commandBus.InvokeCommandsQueue(); return(GetEngine(command.Id)); } return(BadRequest(ModelState)); }
private void RegenerateUpdateChannels(List <AnimationBlender.Channel> channels) { var updateMemberInfos = new List <UpdateMemberInfo>(); foreach (var channel in channels) { updateMemberInfos.Add(new UpdateMemberInfo { Name = channel.PropertyName, DataOffset = channel.Offset }); } compiledUpdate = UpdateEngine.Compile(typeof(Entity), updateMemberInfos); }
private void CheckUpdatesDialog_Shown(object sender, EventArgs e) { UpdateEngine.DownloadUpdatesCompleted += new DownloadUpdatesCompletedEventHandler(UpdateEngine_DownloadUpdatesCompleted); // When starting normally (not programmatically) - we'll first check if there are // pending software updates if (!_startDownload) { UpdateEngine.CheckForUpdatesCompleted += new CheckForUpdatesCompletedEventHandler(UpdateEngine_CheckForUpdatesCompleted); UpdateEngine.CheckForUpdatesAsync(); } }
private void btnInstallNewUpdates_Click(object sender, EventArgs e) { if (UpdateEngine.IsBusy) { return; } lblDownloadingUpdates.Visible = true; pbrDownloadProgress.Visible = true; btnCancel.Text = "Cancel"; btnDownloadUpdates.Enabled = false; UpdateEngine.DownloadUpdatesAsync(); }
public void TestOutOfBoundsSkip() { var test = new TestClass { TestClassArray = { [0] = new TestClass(), [1] = new TestClass() }, TestClassList = { [0] = new TestClass(), [1] = new TestClass() } }; // Check that ctor of TestClass properly initialized size of array/list to 4 (this test relies on it) Assert.Equal(4, test.IntArray.Length); Assert.Equal(4, test.IntList.Count); Assert.Equal(2, test.TestClassArray.Length); Assert.Equal(2, test.TestClassList.Count); UpdateEngine.RegisterMemberResolver(new ArrayUpdateResolver <int>()); UpdateEngine.RegisterMemberResolver(new ListUpdateResolver <int>()); // Combine many of the other tests in one, to easily test if switching from one member to another works well var updateMemberInfo = new List <UpdateMemberInfo> { new UpdateMemberInfo("IntArray[0]", 0), new UpdateMemberInfo("IntArray[4]", 0), new UpdateMemberInfo("IntList[0]", 0), new UpdateMemberInfo("IntList[4]", 0), new UpdateMemberInfo("TestClassArray[0].IntField", 0), new UpdateMemberInfo("TestClassArray[2].IntField", 0), new UpdateMemberInfo("TestClassList[0].IntField", 0), new UpdateMemberInfo("TestClassList[2].IntField", 0), }; var blittableData = new TestData[] { 123 }; // This shouldn't crash RunUpdateEngine(test, updateMemberInfo, blittableData, null); // Update shouldn't have been done (we skip the whole stuff if it goes out of bound) Assert.Equal(0, test.IntArray[0]); Assert.Equal(0, test.IntList[0]); Assert.Equal(0, test.TestClassArray[0].IntField); Assert.Equal(0, test.TestClassList[0].IntField); }
public void TestNullSkip() { var test = new TestClass { IntList = null, IntArray = null }; UpdateEngine.RegisterMemberResolver(new ArrayUpdateResolver <int>()); UpdateEngine.RegisterMemberResolver(new ListUpdateResolver <int>()); UpdateEngine.RegisterMemberResolver(new ArrayUpdateResolver <TestClass>()); // Combine many of the other tests in one, to easily test if switching from one member to another works well var updateMemberInfo = new List <UpdateMemberInfo> { new UpdateMemberInfo("NonBlittableStructField.TestClassField.IntField", 0), new UpdateMemberInfo("NonBlittableStructField.TestClassField.IntProperty", 0), new UpdateMemberInfo("NonBlittableStructField.TestClassProperty.IntField", 0), new UpdateMemberInfo("NonBlittableStructField.TestClassProperty.IntProperty", 0), new UpdateMemberInfo("ObjectField.(Stride.Engine.Tests.TestClass,Stride.Engine.Tests).IntField", 0), new UpdateMemberInfo("ObjectProperty.(Stride.Engine.Tests.TestClass,Stride.Engine.Tests).IntField", 0), new UpdateMemberInfo("IntArray[0]", 0), new UpdateMemberInfo("IntArray[2]", 0), new UpdateMemberInfo("IntArray[3]", 0), new UpdateMemberInfo("IntField", 0), new UpdateMemberInfo("IntList[0]", 0), new UpdateMemberInfo("IntList[2]", 0), new UpdateMemberInfo("IntList[3]", 0), new UpdateMemberInfo("TestClassArray[0].IntField", 0), new UpdateMemberInfo("TestClassArray[1].IntField", 0), new UpdateMemberInfo("IntProperty", 0), }; var blittableData = new TestData[] { 123 }; // Just check that it doesn't crash and some set are properly done RunUpdateEngine(test, updateMemberInfo, blittableData, null); Assert.Equal(123, test.IntField); Assert.Equal(123, test.IntProperty); // Also try with null array test.TestClassArray = null; blittableData[0] = 456; RunUpdateEngine(test, updateMemberInfo, blittableData, null); Assert.Equal(456, test.IntField); Assert.Equal(456, test.IntProperty); }
public unsafe void Update(Entity entity, AnimationClipResult result) { // Check if we need to regenerate "update channels" (i.e. how to copy data from result to hierarchy) if (compiledUpdate.UpdateOperations == null || // First time?... currentSourceChannels != result.Channels || // ... or changed? currentSourceChannels.Count != currentSourceChannelCount) // .. or modified? (could only append channel) { RegenerateUpdateChannels(result.Channels); currentSourceChannels = result.Channels; currentSourceChannelCount = currentSourceChannels.Count; } // Copy results to node hierarchy fixed(byte *structures = result.Data) { UpdateEngine.Run(entity, compiledUpdate, (IntPtr)structures, result.Objects); } }
private void CheckUpdatesDialog_FormClosing(object sender, FormClosingEventArgs e) { if (UpdateEngine.IsBusy) { UpdateEngine.CancelAsync(); Cursor = Cursors.WaitCursor; e.Cancel = true; } else { UpdateEngine.DownloadUpdatesCompleted -= new DownloadUpdatesCompletedEventHandler(UpdateEngine_DownloadUpdatesCompleted); if (!_startDownload) { UpdateEngine.CheckForUpdatesCompleted -= new CheckForUpdatesCompletedEventHandler(UpdateEngine_CheckForUpdatesCompleted); } } // else }
protected override bool Setup(IRootConfig rootConfig, IServerConfig config) { //TODO 读取配置设置isDebug Debug.SetLogger(Logger, true); Debug.Log("SyncService Setup Mode: " + config.Mode); DataBaseService.Init(); matchService.Init(this); loginService.Init(this); reConnectService.Init(this); selectCharacterService.Init(this); CommandMessageService <CommandComponent> .Init(); GameMessageService.Init(); UpdateEngine.Init(updateInterval); return(base.Setup(rootConfig, config)); }
public void CommandValid_EngineUpdated() { var engineId = InsertEngineToDatabase(); var updateEngineCommand = new UpdateEngine(engineId, "Updated", power: 150, torque: 300, cylinders: 6, displacement: 3000); A.CallTo(() => updateEngineValidator.Validate(updateEngineCommand)).DoesNothing(); updateEngineHandler.Handle(updateEngineCommand); context.SaveChanges(); var result = context.Engine.FirstOrDefault(e => e.Id == updateEngineCommand.Id); A.CallTo(() => updateEngineValidator.Validate(updateEngineCommand)).MustHaveHappened(Repeated.Exactly.Once); Assert.NotNull(result); Assert.Equal(result.Id, updateEngineCommand.Id); Assert.Equal(result.Name, updateEngineCommand.Name); Assert.Equal(result.Power, updateEngineCommand.Power); Assert.Equal(result.Torque, updateEngineCommand.Torque); Assert.Equal(result.Cylinders, updateEngineCommand.Cylinders); Assert.Equal(result.Displacement, updateEngineCommand.Displacement); }
public void ValidatorThrowsException_HandlerThrowsException() { var engineId = InsertEngineToDatabase(); var updateEngineCommand = new UpdateEngine(engineId, "Updated", power: 150, torque: 300, cylinders: 6, displacement: 3000); A.CallTo(() => updateEngineValidator.Validate(updateEngineCommand)).Throws <Exception>(); Assert.ThrowsAny <Exception>(() => updateEngineHandler.Handle(updateEngineCommand)); A.CallTo(() => updateEngineValidator.Validate(updateEngineCommand)).MustHaveHappened(Repeated.Exactly.Once); context.SaveChanges(); var result = context.Engine.FirstOrDefault(e => e.Id == updateEngineCommand.Id); Assert.NotNull(result); Assert.Equal(engineId, result.Id); Assert.Equal(expectedEngineCylinders, result.Cylinders); Assert.Equal(expectedEngineDisplacement, result.Displacement); Assert.Equal(expectedEngineFuelType, result.FuelType); Assert.Equal(expectedEngineName, result.Name); Assert.Equal(expectedEnginePower, result.Power); Assert.Equal(expectedEngineTorque, result.Torque); }
private unsafe object ExportAnimation(ICommandContext commandContext, ContentManager contentManager, bool failOnEmptyAnimation) { // Read from model file var modelSkeleton = LoadSkeleton(commandContext, contentManager); // we get model skeleton to compare it to real skeleton we need to map to AdjustSkeleton(modelSkeleton); TimeSpan duration; var animationClips = LoadAnimation(commandContext, contentManager, out duration); // Fix the animation frames double startFrameSeconds = StartFrame.TotalSeconds; double endFrameSeconds = EndFrame.TotalSeconds; var startTime = CompressedTimeSpan.FromSeconds(-startFrameSeconds); foreach (var clip in animationClips) { foreach (var animationCurve in clip.Value.Curves) { animationCurve.ShiftKeys(startTime); } } var durationTimeSpan = TimeSpan.FromSeconds((endFrameSeconds - startFrameSeconds)); if (duration > durationTimeSpan) { duration = durationTimeSpan; } var animationClip = new AnimationClip { Duration = duration }; if (animationClips.Count > 0) { AnimationClip rootMotionAnimationClip = null; // If root motion is explicitely enabled, or if there is no skeleton, try to find root node and apply animation directly on TransformComponent if ((AnimationRootMotion || SkeletonUrl == null) && modelSkeleton.Nodes.Length >= 1) { // No skeleton, map root node only // TODO: For now, it seems to be located on node 1 in FBX files. Need to check if always the case, and what happens with Assimp var rootNode0 = modelSkeleton.Nodes.Length >= 1 ? modelSkeleton.Nodes[0].Name : null; var rootNode1 = modelSkeleton.Nodes.Length >= 2 ? modelSkeleton.Nodes[1].Name : null; if ((rootNode0 != null && animationClips.TryGetValue(rootNode0, out rootMotionAnimationClip)) || (rootNode1 != null && animationClips.TryGetValue(rootNode1, out rootMotionAnimationClip))) { foreach (var channel in rootMotionAnimationClip.Channels) { var curve = rootMotionAnimationClip.Curves[channel.Value.CurveIndex]; // Root motion var channelName = channel.Key; if (channelName.StartsWith("Transform.")) { animationClip.AddCurve($"[TransformComponent.Key]." + channelName.Replace("Transform.", string.Empty), curve); } // Also apply Camera curves // TODO: Add some other curves? if (channelName.StartsWith("Camera.")) { animationClip.AddCurve($"[CameraComponent.Key]." + channelName.Replace("Camera.", string.Empty), curve); } } } } // Load asset reference skeleton if (SkeletonUrl != null) { var skeleton = contentManager.Load <Skeleton>(SkeletonUrl); var skeletonMapping = new SkeletonMapping(skeleton, modelSkeleton); // Process missing nodes foreach (var nodeAnimationClipEntry in animationClips) { var nodeName = nodeAnimationClipEntry.Key; var nodeAnimationClip = nodeAnimationClipEntry.Value; var nodeIndex = modelSkeleton.Nodes.IndexOf(x => x.Name == nodeName); // Node doesn't exist in skeleton? skip it if (nodeIndex == -1 || skeletonMapping.SourceToSource[nodeIndex] != nodeIndex) { continue; } // Skip root motion node (if any) if (nodeAnimationClip == rootMotionAnimationClip) { continue; } // Find parent node var parentNodeIndex = modelSkeleton.Nodes[nodeIndex].ParentIndex; if (parentNodeIndex != -1 && skeletonMapping.SourceToSource[parentNodeIndex] != parentNodeIndex) { // Some nodes were removed, we need to concat the anim curves var currentNodeIndex = nodeIndex; var nodesToMerge = new List <Tuple <ModelNodeDefinition, AnimationBlender, AnimationClipEvaluator> >(); while (currentNodeIndex != -1 && currentNodeIndex != skeletonMapping.SourceToSource[parentNodeIndex]) { AnimationClip animationClipToMerge; AnimationClipEvaluator animationClipEvaluator = null; AnimationBlender animationBlender = null; if (animationClips.TryGetValue(modelSkeleton.Nodes[currentNodeIndex].Name, out animationClipToMerge)) { animationBlender = new AnimationBlender(); animationClipEvaluator = animationBlender.CreateEvaluator(animationClipToMerge); } nodesToMerge.Add(Tuple.Create(modelSkeleton.Nodes[currentNodeIndex], animationBlender, animationClipEvaluator)); currentNodeIndex = modelSkeleton.Nodes[currentNodeIndex].ParentIndex; } // Put them in proper parent to children order nodesToMerge.Reverse(); // Find all key times // TODO: We should detect discontinuities and keep them var animationKeysSet = new HashSet <CompressedTimeSpan>(); foreach (var node in nodesToMerge) { if (node.Item3 != null) { foreach (var curve in node.Item3.Clip.Curves) { foreach (CompressedTimeSpan time in curve.Keys) { animationKeysSet.Add(time); } } } } // Sort key times var animationKeys = animationKeysSet.ToList(); animationKeys.Sort(); var animationOperations = new FastList <AnimationOperation>(); var combinedAnimationClip = new AnimationClip(); var translationCurve = new AnimationCurve <Vector3>(); var rotationCurve = new AnimationCurve <Quaternion>(); var scaleCurve = new AnimationCurve <Vector3>(); // Evaluate at every key frame foreach (var animationKey in animationKeys) { var matrix = Matrix.Identity; // Evaluate node foreach (var node in nodesToMerge) { // Needs to be an array in order for it to be modified by the UpdateEngine, otherwise it would get passed by value var modelNodeDefinitions = new ModelNodeDefinition[1] { node.Item1 }; if (node.Item2 != null && node.Item3 != null) { // Compute AnimationClipResult animationClipResult = null; animationOperations.Clear(); animationOperations.Add(AnimationOperation.NewPush(node.Item3, animationKey)); node.Item2.Compute(animationOperations, ref animationClipResult); var updateMemberInfos = new List <UpdateMemberInfo>(); foreach (var channel in animationClipResult.Channels) { if (channel.IsUserCustomProperty) { continue; } updateMemberInfos.Add(new UpdateMemberInfo { Name = "[0]." + channel.PropertyName, DataOffset = channel.Offset }); } // TODO: Cache this var compiledUpdate = UpdateEngine.Compile(typeof(ModelNodeDefinition[]), updateMemberInfos); fixed(byte *data = animationClipResult.Data) { UpdateEngine.Run(modelNodeDefinitions, compiledUpdate, (IntPtr)data, null); } } Matrix localMatrix; var transformTRS = modelNodeDefinitions[0].Transform; Matrix.Transformation(ref transformTRS.Scale, ref transformTRS.Rotation, ref transformTRS.Position, out localMatrix); matrix = Matrix.Multiply(localMatrix, matrix); } // Done evaluating, let's decompose matrix TransformTRS transform; matrix.Decompose(out transform.Scale, out transform.Rotation, out transform.Position); // Create a key translationCurve.KeyFrames.Add(new KeyFrameData <Vector3>(animationKey, transform.Position)); rotationCurve.KeyFrames.Add(new KeyFrameData <Quaternion>(animationKey, transform.Rotation)); scaleCurve.KeyFrames.Add(new KeyFrameData <Vector3>(animationKey, transform.Scale)); } combinedAnimationClip.AddCurve($"{nameof(ModelNodeTransformation.Transform)}.{nameof(TransformTRS.Position)}", translationCurve); combinedAnimationClip.AddCurve($"{nameof(ModelNodeTransformation.Transform)}.{nameof(TransformTRS.Rotation)}", rotationCurve); combinedAnimationClip.AddCurve($"{nameof(ModelNodeTransformation.Transform)}.{nameof(TransformTRS.Scale)}", scaleCurve); nodeAnimationClip = combinedAnimationClip; } var transformStart = $"{nameof(ModelNodeTransformation.Transform)}."; var transformPosition = $"{nameof(ModelNodeTransformation.Transform)}.{nameof(TransformTRS.Position)}"; foreach (var channel in nodeAnimationClip.Channels) { var curve = nodeAnimationClip.Curves[channel.Value.CurveIndex]; // TODO: Root motion var channelName = channel.Key; if (channelName.StartsWith(transformStart)) { if (channelName == transformPosition) { // Translate node with parent 0 using PivotPosition var keyFrames = ((AnimationCurve <Vector3>)curve).KeyFrames; for (int i = 0; i < keyFrames.Count; ++i) { if (parentNodeIndex == 0) { keyFrames.Items[i].Value -= PivotPosition; } keyFrames.Items[i].Value *= ScaleImport; } } animationClip.AddCurve($"[ModelComponent.Key].Skeleton.NodeTransformations[{skeletonMapping.SourceToTarget[nodeIndex]}]." + channelName, curve); } } } } if (ImportCustomAttributes) { // Add clips clips animating other properties than node transformations foreach (var nodeAnimationClipPair in animationClips) { var nodeName = nodeAnimationClipPair.Key; var nodeAnimationClip = nodeAnimationClipPair.Value; foreach (var channel in nodeAnimationClip.Channels) { var channelName = channel.Key; var channelValue = channel.Value; if (channelValue.IsUserCustomProperty) { animationClip.AddCurve(nodeName + "_" + channelName, nodeAnimationClip.Curves[channel.Value.CurveIndex], true); } } } } } if (animationClip.Channels.Count == 0) { var logString = $"File {SourcePath} doesn't have any animation information."; if (failOnEmptyAnimation) { commandContext.Logger.Error(logString); return(null); } commandContext.Logger.Info(logString); } else { if (animationClip.Duration.Ticks == 0) { commandContext.Logger.Verbose($"File {SourcePath} has a 0 tick long animation."); } // Optimize and set common parameters animationClip.RepeatMode = AnimationRepeatMode; animationClip.Optimize(); } return(animationClip); }
internal static void __Initialize__() { UpdateEngine.RegisterMemberResolver(new ParameterCollectionResolver()); }
internal static void __Initialize__() { UpdateEngine.RegisterMemberResolver(new EntityChildPropertyResolver()); }
protected virtual void OnEngineUpdate() { display.Invoke(new MethodInvoker(delegate { UpdateEngine?.Invoke(this, EventArgs.Empty); })); }
/// <summary> /// This method will check for updates in the main form and display them to the user. /// </summary> /// <returns>bool: True on success.</returns> private async Task <bool> CheckForUpdates() { bool success; string xmlUrl = ""; FileStream fs = File.OpenRead(Process.GetCurrentProcess().MainModule.FileName); StreamReader sr = new StreamReader(fs); fs.Seek(-2048, SeekOrigin.End); List <string> srLines = new List <string>(); while (!sr.EndOfStream) { srLines.Add(await sr.ReadLineAsync()); } if ( srLines.Count >= 2 && srLines[srLines.Count - 2] == "" && srLines[srLines.Count - 1] != "" && Uri.TryCreate(srLines[srLines.Count - 1], UriKind.RelativeOrAbsolute, out Uri uri) ) { xmlUrl = uri.ToString(); } if (Program.Arguments.Length == 1) { Logger.Log("XML passed via CLI."); xmlUrl = Program.Arguments[0]; } else if (xmlUrl != "") { Logger.Log("XML passed via binary."); } else { Logger.Log("XML path has not been passed to Super Update!", LogLevels.Exception); return(false); } success = await XmlEngine.ReadXML(xmlUrl); if (!success) { return(success); } success = await UpdateEngine.DetectUpdates(); if (!success) { return(success); } if (UpdateEngine.CurrentVersion != UpdateEngine.LatestVersion) { if (UpdateEngine.LatestVersion.Attributes["UpdateMessage"] != null) { Logger.Log(UpdateEngine.LatestVersion.Attributes["UpdateMessage"].Value, LogLevels.Information); } else { Logger.Log("Found new version, press \"Install\" to begin.", LogLevels.Information); } } else { XmlNode noUpdateMessage = XmlEngine.UpdateXML.SelectSingleNode("/SU:SuperUpdate/SU:Settings/SU:MessageNoUpdate", XmlEngine.XNS); if (noUpdateMessage != null) { Logger.Log(noUpdateMessage.Attributes["Text"].Value, LogLevels.Information); } else { Logger.Log("No updates are available.", LogLevels.Information); } } return(success); }