/// <summary> /// Pushes a new render target onto the render target stack. /// </summary> /// <param name="viewport">The viewport object.</param> /// <param name="renderTargets">A structure containing all relevant render targets.</param> /// <param name="camera">The camera for the new render target.</param> /// <param name="viewInformation">The view information.</param> /// <exception cref="System.ObjectDisposedException">RenderState</exception> internal void PushRenderTarget( RenderTargets renderTargets, SharpDX.Mathematics.Interop.RawViewportF viewport, Camera3DBase camera, ViewInformation viewInformation) { if (m_disposed) { throw new ObjectDisposedException("RenderState"); } //Build new render stack entry RenderStackEntry newEntry = new RenderStackEntry(); newEntry.Matrix4Stack = new Matrix4Stack(); newEntry.Camera = camera; newEntry.RenderTargets = renderTargets; newEntry.SingleViewport = viewport; newEntry.ViewInformation = viewInformation; //Overtake device settings newEntry.Apply(m_device.DeviceImmediateContextD3D11); //Push new entry onto the stack m_renderSettingsStack.Push(m_currentRenderSettings); m_currentRenderSettings = newEntry; }
/// <summary> /// Called when the sample has to startup. /// </summary> /// <param name="targetRenderLoop">The target render loop.</param> /// <returns></returns> public override async Task OnStartupAsync(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Build dummy scene Scene scene = targetRenderLoop.Scene; Camera3DBase camera = targetRenderLoop.Camera as Camera3DBase; // Build scene initially if we are on first load if (scene.CountObjects <= 0) { await scene.ManipulateSceneAsync((manipulator) => { // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); // Create the wall in the middle AppendWallObjectToScene(manipulator); // Now create all pallets AppendPalletObjectsToScene(manipulator); }); // Configure camera camera.Position = new Vector3(30f, 30f, 30f); camera.Target = new Vector3(0f, 0f, 0f); camera.UpdateCamera(); } }
/// <summary> /// Called when the sample has to startup. /// </summary> /// <param name="targetRenderLoop">The target render loop.</param> public override async Task OnStartupAsync(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Build dummy scene Scene scene = targetRenderLoop.Scene; Camera3DBase camera = targetRenderLoop.Camera as Camera3DBase; await targetRenderLoop.Scene.ManipulateSceneAsync((manipulator) => { // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); TextGeometryOptions textOptions = TextGeometryOptions.Default; textOptions.FontSize = 50; textOptions.MakeVolumetricText = true; textOptions.SurfaceVertexColor = Color.Blue; textOptions.VolumetricSideSurfaceVertexColor = Color4.CornflowerBlue; GenericObject textObject = manipulator.Add3DText($"Seeing# {Environment.NewLine} Text3D Sample", textOptions); textObject.YPos = textOptions.VolumetricTextDepth; }); // Configure camera camera.Position = new Vector3(0.7f, 8.5f, -15f); camera.RelativeTarget = new Vector3(0.44f, -0.62f, 0.64f); camera.UpdateCamera(); }
/// <summary> /// Update camera for mouse input. /// </summary> private static void UpdateForMouse(Camera3DBase actCamera, bool isControlKeyDown, MouseOrPointerState mouseState) { // Handle mouse move if (mouseState.MoveDistanceDip != Vector2.Zero) { var moving = mouseState.MoveDistanceDip; if (mouseState.IsButtonDown(MouseButton.Left) && mouseState.IsButtonDown(MouseButton.Right)) { actCamera.Zoom(moving.Y / -50f); } else if (mouseState.IsButtonDown(MouseButton.Left)) { actCamera.Strave(moving.X / 50f); actCamera.UpDown(-moving.Y / 50f); } else if (mouseState.IsButtonDown(MouseButton.Right)) { actCamera.Rotate(-moving.X / 200f, -moving.Y / 200f); } } // Handle mouse wheel if (mouseState.WheelDelta != 0) { var multiplier = 1f; if (isControlKeyDown) { multiplier = 2f; } actCamera.Zoom(mouseState.WheelDelta / 100f * multiplier); } }
private async void OnMainWindow_Loaded(object sender, RoutedEventArgs e) { CtrlRenderPanel.RenderLoop.ClearColor = Color4.CornflowerBlue; // Build scene graph await CtrlRenderPanel.Scene.ManipulateSceneAsync((manipulator) => { // Create pallet geometry resource PalletType pType = new PalletType(); pType.ContentColor = Color4.GreenColor; var resPalletGeometry = manipulator.AddResource <GeometryResource>( () => new GeometryResource(pType)); // Create pallet object GenericObject palletObject = manipulator.AddGeneric(resPalletGeometry); palletObject.Color = Color4.GreenColor; palletObject.EnableShaderGeneratedBorder(); palletObject.BuildAnimationSequence() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_180DEG, EngineMath.RAD_45DEG), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_360DEG, EngineMath.RAD_45DEG), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, 0f, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .CallAction(() => palletObject.RotationEuler = Vector3.Zero) .ApplyAndRewind(); }); // Configure camera Camera3DBase camera = CtrlRenderPanel.Camera; camera.Position = new Vector3(2f, 2f, 2f); camera.Target = new Vector3(0f, 0.5f, 0f); camera.UpdateCamera(); }
/// <summary> /// This update method gets called on each update pass for each scenes /// this component is attached to. /// </summary> /// <param name="updateState">Current update state.</param> /// <param name="correspondingView">The view which attached this component (may be null).</param> protected override void Update(SceneRelatedUpdateState updateState, ViewInformation correspondingView) { Camera3DBase actCamera = correspondingView.Camera; if (actCamera == null) { return; } foreach (InputFrame actInputFrame in updateState.InputFrames) { foreach (var actInputState in actInputFrame.GetInputStates(correspondingView)) { // Handle keyboard KeyboardState actKeyboardState = actInputState as KeyboardState; bool isControlKeyDown = false; if (actKeyboardState != null) { UpdateForKeyboard(actCamera, actKeyboardState, out isControlKeyDown); continue; } // Handle mouse (or pointer) MouseOrPointerState mouseState = actInputState as MouseOrPointerState; if (mouseState != null) { UpdateForMouse(actCamera, isControlKeyDown, mouseState); } } } }
private async void OnMainPage_Loaded(object sender, RoutedEventArgs e) { if (m_panelPainter != null) { return; } // Attach the painter to the target render panel m_panelPainter = new SeeingSharpPanelPainter(this.RenderTargetPanel); m_panelPainter.RenderLoop.ClearColor = Color4.CornflowerBlue; // Build scene graph await m_panelPainter.Scene.ManipulateSceneAsync((manipulator) => { // Define a BACKGROUND layer and configure layer IDs // => Ensures correct render order SceneLayer bgLayer = manipulator.AddLayer("BACKGROUND"); manipulator.SetLayerOrderID(bgLayer, 0); manipulator.SetLayerOrderID(Scene.DEFAULT_LAYER_NAME, 1); // Add the background texture painter to the BACKGROUND layer var resBackgroundTexture = manipulator.AddTexture( new AssemblyResourceUriBuilder( "SeeingSharp.Tutorials.Introduction03", true, "Assets/Textures/Background.png")); manipulator.Add(new FullscreenTextureObject(resBackgroundTexture), bgLayer.Name); // Create pallet geometry resource PalletType pType = new PalletType(); pType.ContentColor = Color4.GreenColor; var resPalletGeometry = manipulator.AddResource <GeometryResource>( () => new GeometryResource(pType)); // Create pallet object and add it to the scene // => The DEFAULT layer is used by default GenericObject palletObject = manipulator.AddGeneric(resPalletGeometry); palletObject.Color = Color4.GreenColor; palletObject.EnableShaderGeneratedBorder(); palletObject.BuildAnimationSequence() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_180DEG, EngineMath.RAD_45DEG), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_360DEG, EngineMath.RAD_45DEG), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, 0f, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .CallAction(() => palletObject.RotationEuler = Vector3.Zero) .ApplyAndRewind(); }); // Configure camera Camera3DBase camera = m_panelPainter.Camera; camera.Position = new Vector3(2f, 2f, 2f); camera.Target = new Vector3(0f, 0.5f, 0f); camera.UpdateCamera(); }
/// <summary> /// Initializes a new instance of the <see cref="RenderState"/> class. /// </summary> internal RenderState( EngineDevice device, RenderTargets renderTargets, Viewport viewport, Camera3DBase camera, ViewInformation viewInformation) : this(device) { this.Reset(renderTargets, viewport, camera, viewInformation); }
/// <summary> /// Initializes a new instance of the <see cref="RenderState"/> class. /// </summary> internal RenderState( EngineDevice device, PerformanceAnalyzer performanceCalculator, RenderTargets renderTargets, SharpDX.Mathematics.Interop.RawViewportF viewport, Camera3DBase camera, ViewInformation viewInformation) : this(device, performanceCalculator) { Reset(renderTargets, viewport, camera, viewInformation); }
/// <summary> /// Called when the sample has to startup. /// </summary> /// <param name="targetRenderLoop">The target render loop.</param> /// <returns></returns> public override async Task OnStartupAsync(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Build dummy scene Scene scene = targetRenderLoop.Scene; Camera3DBase camera = targetRenderLoop.Camera as Camera3DBase; // Build scene initially if we are on first load if (scene.CountObjects <= 0) { await scene.ManipulateSceneAsync((manipulator) => { // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); // Create pallet geometry resource PalletType pType = new PalletType(); pType.ContentColor = Color4.Transparent; var resPalletGeometry = manipulator.AddResource <GeometryResource>( () => new GeometryResource(pType)); // Create pallet object GenericObject palletObject = manipulator.AddGeneric(resPalletGeometry); palletObject.Color = Color4.GreenColor; palletObject.EnableShaderGeneratedBorder(); palletObject.BuildAnimationSequence() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_180DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_360DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .CallAction(() => palletObject.RotationEuler = Vector3.Zero) .ApplyAndRewind(); var resSkyboxTexture = manipulator.AddTexture( new AssemblyResourceLink( typeof(SeeingSharpSampleResources), "Textures.SkyBox.dds")); // Create the skybox on a new layer manipulator.AddLayer("Skybox"); SkyboxObject skyboxObject = new SkyboxObject(resSkyboxTexture); manipulator.Add(skyboxObject, "Skybox"); }); // Configure camera camera.Position = new Vector3(5f, 3f, 5f); camera.Target = new Vector3(0f, 2f, 0f); camera.UpdateCamera(); } }
/// <summary> /// Update camera for keyboard input. /// </summary> private static void UpdateForKeyboard( PerSceneContext componentContext, Camera3DBase actCamera, KeyboardState actKeyboardState) { foreach (WinVirtualKey actKey in actKeyboardState.KeysDown) { switch (actKey) { case WinVirtualKey.Up: case WinVirtualKey.W: case WinVirtualKey.NumPad8: componentContext.CameraHVRotation = componentContext.CameraHVRotation + new Vector2(0f, SINGLE_ROTATION_V); break; case WinVirtualKey.Down: case WinVirtualKey.S: case WinVirtualKey.NumPad2: componentContext.CameraHVRotation = componentContext.CameraHVRotation - new Vector2(0f, SINGLE_ROTATION_V); break; case WinVirtualKey.Left: case WinVirtualKey.A: case WinVirtualKey.NumPad4: componentContext.CameraHVRotation = componentContext.CameraHVRotation - new Vector2(SINGLE_ROTATION_H, 0f); break; case WinVirtualKey.Right: case WinVirtualKey.D: case WinVirtualKey.NumPad6: componentContext.CameraHVRotation = componentContext.CameraHVRotation + new Vector2(SINGLE_ROTATION_H, 0f); break; case WinVirtualKey.Q: case WinVirtualKey.NumPad3: componentContext.CameraDistance = componentContext.CameraDistance * 1.05f; break; case WinVirtualKey.E: case WinVirtualKey.NumPad9: componentContext.CameraDistance = componentContext.CameraDistance * 0.95f; break; } } }
private async Task OnStartupAsync_Fallback(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Build dummy scene Scene scene = targetRenderLoop.Scene; Camera3DBase camera = targetRenderLoop.Camera as Camera3DBase; await targetRenderLoop.Scene.ManipulateSceneAsync((manipulator) => { // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); // Define texture and material resource var resTexture = manipulator.AddTexture( new AssemblyResourceLink( typeof(SeeingSharpSampleResources), "Textures.NoCaptureDevice.png")); var resMaterial = manipulator.AddSimpleColoredMaterial(resTexture); // Create pallet geometry resource PalletType pType = new PalletType(); pType.ContentMaterial = resMaterial; var resPalletGeometry = manipulator.AddResource <GeometryResource>( () => new GeometryResource(pType)); // Create pallet object GenericObject palletObject = manipulator.AddGeneric(resPalletGeometry); palletObject.Color = Color4.GreenColor; palletObject.EnableShaderGeneratedBorder(); palletObject.BuildAnimationSequence() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_180DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_360DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, 0f, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .CallAction(() => palletObject.RotationEuler = Vector3.Zero) .ApplyAndRewind(); }); // Configure camera camera.Position = new Vector3(2f, 2f, 2f); camera.Target = new Vector3(0f, 0.5f, 0f); camera.UpdateCamera(); }
/// <summary> /// Called when the sample has to startup. /// </summary> /// <param name="targetRenderLoop">The target render loop.</param> public override async Task OnStartupAsync(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Get and configure the camera Camera3DBase camera = targetRenderLoop.Camera as PerspectiveCamera3D; camera.Position = new Vector3(0f, 5f, -7f); camera.Target = new Vector3(0f, 0f, 0f); camera.UpdateCamera(); // Open the video file // see original vide at: https://www.flickr.com/photos/mlinksva/20939860191/in/photolist-xUofUg-xzKr45-xzKn65-xzhfV1-xPfMqh-wTxmUk-wSd5bL-xwAUF3-wSbSW3-xNqVYR-xNqUyB-xKte5J-xKtbMh-wQKVu5-wQVbiV-wQLHns-xKsHiQ-xvapef-xKsF1y-xMMyY2-xvbbXC-xvb5Xy-xNqkBK-xvb25o-xvafSW-xvb4FW-xKsavw-xMM69V-wQUtWn-xvgDSv-xLW62q-xvbig9-wQL8p7-xMMFog-wQV8CK-wQLGcS-wQLLZY-wQKN9U-xvhorD-xNq5we-xvbh7f-wQU3KF-xLWiZE-xvgVqe-wQKKEq-xvaJN3-xNqjhF-wQUEhH-xKspPw-wQRXGt // Licensed under public domain ResourceLink videoLink = new AssemblyResourceLink( typeof(SeeingSharpSampleResources), "Videos.DummyVideoLandscape.mp4"); m_videoReader = new AsyncRealtimeVideoReader(videoLink); m_videoReader.VideoReachedEnd += (sender, eArgs) => { m_videoReader.SetCurrentPosition(TimeSpan.Zero); }; // Define scene await targetRenderLoop.Scene.ManipulateSceneAsync((manipulator) => { // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); // Define texture and resource var resVideoTexture = manipulator.AddResource <VideoTextureResource>( () => new VideoTextureResource(m_videoReader)); var resVideoMaterial = manipulator.AddSimpleColoredMaterial(resVideoTexture, addToAlpha: 1f); var geoResource = manipulator.AddResource <GeometryResource>( () => new GeometryResource(new PalletType( palletMaterial: NamedOrGenericKey.Empty, contentMaterial: resVideoMaterial))); // Add the object GenericObject newObject = manipulator.AddGeneric(geoResource); newObject.RotationEuler = new Vector3(0f, EngineMath.RAD_90DEG / 2f, 0f); newObject.Scaling = new Vector3(2f, 2f, 2f); newObject.EnableShaderGeneratedBorder(); }); }
/// <summary> /// Queries for all scenes to be rendered for all given RenderLoop objects. /// </summary> /// <param name="registeredRenderLoops">The render loops from which to get the scenes.</param> /// <param name="scenesToRender">The collection to be modiefied.</param> /// <param name="camerasToUpdate">A list containing all cameras which are defined in currently bound scenes.</param> private static void QueryForScenesAndCameras(List <RenderLoop> registeredRenderLoops, List <Scene> scenesToRender, List <Camera3DBase> camerasToUpdate) { scenesToRender.Clear(); camerasToUpdate.Clear(); for (int loop = 0; loop < registeredRenderLoops.Count; loop++) { Scene actScene = registeredRenderLoops[loop].Scene; if ((actScene != null) && (!scenesToRender.Contains(actScene))) { scenesToRender.Add(actScene); } Camera3DBase actCamera = registeredRenderLoops[loop].Camera; if ((actCamera != null) && (!camerasToUpdate.Contains(actCamera))) { camerasToUpdate.Add(actCamera); } } }
/// <summary> /// Initializes a new instance of the <see cref="MainWindowViewModel"/> class. /// </summary> public MainWindowViewModel() { if (!SeeingSharpApplication.IsInitialized) { return; } m_scene = new Scene(); m_scene.DiscardAutomaticUnload = true; m_camera = new PerspectiveCamera3D(); m_loadedFileVM = new LoadedFileViewModel(m_scene); m_miscObjectsVM = new MiscGraphicsObjectsViewModel(m_scene); this.CommandOpen = new DelegateCommand(OnCommandOpen_Execute); this.CommandClose = new DelegateCommand(OnCommandClose_Execute, OnCommandClose_CanExecute); this.CommandReload = new DelegateCommand(OnCommandReload_Execute, OnCommandReload_CanExecute); }
/// <summary> /// Resets the render state. /// </summary> /// <param name="viewport">The viewport.</param> /// <param name="camera">The camera for the new render target.</param> /// <param name="viewInformation">The view information.</param> /// <param name="renderTargets">The render targets used for rendering.</param> internal void Reset( RenderTargets renderTargets, SharpDX.Mathematics.Interop.RawViewportF viewport, Camera3DBase camera, ViewInformation viewInformation) { m_renderSettingsStack.Clear(); m_sceneStack.Clear(); m_currentScene = null; m_world = new Matrix4Stack(Matrix4x4.Identity); //Inititialize current render properties m_currentRenderSettings = new RenderStackEntry(); m_currentRenderSettings.Matrix4Stack = new Matrix4Stack(); m_currentRenderSettings.RenderTargets = renderTargets; m_currentRenderSettings.SingleViewport = viewport; m_currentRenderSettings.Camera = camera; m_currentRenderSettings.ViewInformation = viewInformation; //Apply initial render properties m_currentRenderSettings.Apply(m_device.DeviceImmediateContextD3D11); }
/// <summary> /// Update camera for mouse input. /// </summary> private static void UpdateForMouse( PerSceneContext componentContext, Camera3DBase actCamera, MouseOrPointerState mouseState) { // Handle mouse move if (mouseState.MoveDistanceDip != Vector2.Zero) { Vector2 moving = mouseState.MoveDistanceDip; if (mouseState.IsButtonDown(MouseButton.Left) && mouseState.IsButtonDown(MouseButton.Right)) { float multiplyer = 1.05f; if (moving.Y < 0f) { multiplyer = 0.95f; } componentContext.CameraDistance = componentContext.CameraDistance * multiplyer; } else if (mouseState.IsButtonDown(MouseButton.Left) || mouseState.IsButtonDown(MouseButton.Right)) { componentContext.CameraHVRotation = componentContext.CameraHVRotation + new Vector2( SINGLE_ROTATION_H * (moving.X / 4f), SINGLE_ROTATION_V * (moving.Y / 4f)); } } // Handle mouse wheel if (mouseState.WheelDelta != 0) { float multiplyer = 0.95f - (Math.Abs(mouseState.WheelDelta) / 1000f); if (mouseState.WheelDelta < 0) { multiplyer = 1.05f + (Math.Abs(mouseState.WheelDelta) / 1000f); } componentContext.CameraDistance = componentContext.CameraDistance * multiplyer; } }
/// <summary> /// Called when the sample has to startup. /// </summary> /// <param name="targetRenderLoop">The target render loop.</param> public override async Task OnStartupAsync(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Build dummy scene Scene scene = targetRenderLoop.Scene; Camera3DBase camera = targetRenderLoop.Camera as Camera3DBase; await targetRenderLoop.Scene.ManipulateSceneAsync((manipulator) => { // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); // Define texture and material resource var resTexture = manipulator.AddTexture( new AssemblyResourceLink( typeof(SeeingSharpSampleResources), "Textures.SimpleTexture.png")); var resMaterial = manipulator.AddSimpleColoredMaterial(resTexture); // Create pallet geometry resource PalletType pType = new PalletType(); pType.ContentMaterial = resMaterial; var resPalletGeometry = manipulator.AddResource <GeometryResource>( () => new GeometryResource(pType)); // Create pallet object CustomPalletObject palletObject = new CustomPalletObject(resPalletGeometry); palletObject.Color = Color4.GreenColor; palletObject.EnableShaderGeneratedBorder(); manipulator.Add(palletObject); }); // Configure camera camera.Position = new Vector3(0f, 4f, -4f); camera.Target = new Vector3(0f, 0.5f, 0f); camera.UpdateCamera(); }
/// <summary> /// A method that starts the app view. /// </summary> public void Run() { RenderLoop targetRenderLoop = m_mainWindowPainter.RenderLoop; Camera3DBase camera = targetRenderLoop.Camera; // Configure camera camera.Position = new Vector3(-5f, -5f, -5f); camera.Target = new Vector3(0f, 0.5f, 0f); camera.UpdateCamera(); targetRenderLoop.Scene.ManipulateSceneAsync((manipulator) => { // Create pallet geometry resource PalletType pType = new PalletType(); pType.ContentColor = Color4.Transparent; var resPalletGeometry = manipulator.AddResource <GeometryResource>( () => new GeometryResource(pType)); // Create pallet object GenericObject palletObject = manipulator.AddGeneric(resPalletGeometry); palletObject.Position = new Vector3(); palletObject.Color = Color4.GreenColor; palletObject.EnableShaderGeneratedBorder(); palletObject.BuildAnimationSequence() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_180DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_360DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .CallAction(() => palletObject.RotationEuler = Vector3.Zero) .ApplyAndRewind(); }).FireAndForget(); targetRenderLoop.SceneComponents.Add( new FreeMovingCameraComponent()); m_mainWindow.Activate(); m_mainWindow.Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessUntilQuit); }
/// <summary> /// Called when the sample has to startup. /// </summary> /// <param name="targetRenderLoop">The target render loop.</param> public override async Task OnStartupAsync(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Build dummy scene Scene scene = targetRenderLoop.Scene; Camera3DBase camera = targetRenderLoop.Camera as Camera3DBase; await targetRenderLoop.Scene.ManipulateSceneAsync((manipulator) => { // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); // Create pallet geometry resource PalletType pType = new PalletType(); pType.ContentColor = Color4.Transparent; var resPalletGeometry = manipulator.AddResource <GeometryResource>( () => new GeometryResource(pType)); // Create pallet object GenericObject palletObject = manipulator.AddGeneric(resPalletGeometry); palletObject.Color = Color4.GreenColor; palletObject.EnableShaderGeneratedBorder(); palletObject.BuildAnimationSequence() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_180DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_360DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .CallAction(() => palletObject.RotationEuler = Vector3.Zero) .ApplyAndRewind(); }); // Configure camera camera.Position = new Vector3(2f, 2f, 2f); camera.Target = new Vector3(0f, 0.5f, 0f); camera.UpdateCamera(); }
/// <summary> /// Called when the sample has to startup. /// </summary> /// <param name="targetRenderLoop">The target render loop.</param> public override async Task OnStartupAsync(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Build dummy scene m_renderLoop = targetRenderLoop; Scene scene = m_renderLoop.Scene; Camera3DBase camera = m_renderLoop.Camera as Camera3DBase; // Build scene initially if we are on first load if (scene.CountObjects <= 0) { NamedOrGenericKey resGeometry = NamedOrGenericKey.Empty; await scene.ManipulateSceneAsync((manipulator) => { // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); // Define banana object ObjectType bananaType = ACFileLoader.ImportObjectType( new AssemblyResourceLink( typeof(SeeingSharpSampleResources), "Models.Banana.ac")); resGeometry = manipulator.AddGeometry(bananaType); }); // Triggers async object creation TriggerAsyncObjectCreation(m_renderLoop, resGeometry); // Configure camera camera.Position = new Vector3(-10f, 8f, -10f); camera.Target = new Vector3(5f, 0f, 5f); camera.UpdateCamera(); } }
/// <summary> /// Called when the sample has to startup. /// </summary> /// <param name="targetRenderLoop">The target render loop.</param> public override async Task OnStartupAsync(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Build dummy scene Scene scene = targetRenderLoop.Scene; Camera3DBase camera = targetRenderLoop.Camera as Camera3DBase; // Build scene initially if we are on first load if (scene.CountObjects <= 0) { await scene.ManipulateSceneAsync((manipulator) => { // Create pallet geometry resource PalletType pType = new PalletType(); pType.ContentColor = Color4.Transparent; var resPalletGeometry = manipulator.AddResource <GeometryResource>( () => new GeometryResource(pType)); // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); // Build the wall object AppendWallObjectToScene(manipulator, SIDE_LENGTH); // Trigger building of the pallet stack BuildPalletCubes(manipulator, new NamedOrGenericKey[] { resPalletGeometry }, SIDE_LENGTH); }); // Configure camera camera.Position = new Vector3(30f, 30f, 30f); camera.Target = new Vector3(0f, 10f, 0f); camera.UpdateCamera(); } }
/// <summary> /// Called when the sample has to startup. /// </summary> /// <param name="targetRenderLoop">The target render loop.</param> public override async Task OnStartupAsync(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Build dummy scene Scene scene = targetRenderLoop.Scene; Camera3DBase camera = targetRenderLoop.Camera as Camera3DBase; // Build scene initially if we are on first load if (scene.CountObjects <= 0) { await scene.ManipulateSceneAsync((manipulator) => { // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); // Load model resource ObjectType modelType = ACFileLoader.ImportObjectType( new AssemblyResourceLink( typeof(SeeingSharpSampleResources), "Models.Penguin.ac")); var resModel = manipulator.AddResource(() => new GeometryResource(modelType)); // Create and add an instance to the scene GenericObject modelObject = new GenericObject(resModel); modelObject.Scaling = new Vector3(10f, 10f, 10f); manipulator.Add(modelObject); }); // Configure camera camera.Position = new Vector3(-10f, 20f, 20f); camera.Target = new Vector3(0f, 6f, 0f); camera.UpdateCamera(); } }
/// <summary> /// Called when the sample has to startup. /// </summary> /// <param name="targetRenderLoop">The target render loop.</param> public override async Task OnStartupAsync(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Build dummy scene Scene scene = targetRenderLoop.Scene; Camera3DBase camera = targetRenderLoop.Camera as Camera3DBase; // Define 2D overlay m_solidBrush = new SolidBrushResource(Color4.LightSteelBlue.ChangeAlphaTo(0.7f)); m_textFormat = new TextFormatResource("Arial", 36); m_textBrush = new SolidBrushResource(Color4.RedColor); Action <Graphics2D> draw2DAction = (graphics) => { // 2D rendering is made here RectangleF d2dRectangle = new RectangleF( 10, 10, graphics.ScreenSize.Width - 20, graphics.ScreenSize.Height - 20); if (d2dRectangle.Width < 100) { return; } if (d2dRectangle.Height < 100) { return; } // Draw background rectangle graphics.FillRoundedRectangle( d2dRectangle, 30, 30, m_solidBrush); // Draw the text d2dRectangle.Inflate(-10, -10); d2dRectangle.Y = d2dRectangle.Y + 15f; graphics.DrawText("Hello Direct2D!", m_textFormat, d2dRectangle, m_textBrush); }; await targetRenderLoop.Scene.ManipulateSceneAsync((manipulator) => { // Add the 2D layer to the scene manipulator.AddDrawingLayer(draw2DAction); // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); // Create pallet geometry resource PalletType pType = new PalletType(); pType.ContentColor = Color4.Transparent; var resPalletGeometry = manipulator.AddResource <GeometryResource>( () => new GeometryResource(pType)); // Create pallet object GenericObject palletObject = manipulator.AddGeneric(resPalletGeometry); palletObject.Color = Color4.GreenColor; palletObject.EnableShaderGeneratedBorder(); palletObject.BuildAnimationSequence() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_180DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_360DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .CallAction(() => palletObject.RotationEuler = Vector3.Zero) .ApplyAndRewind(); }); // Configure camera camera.Position = new Vector3(2f, 2f, 2f); camera.Target = new Vector3(0f, 0.5f, 0f); camera.UpdateCamera(); }
/// <summary> /// Called when the sample has to startup. /// </summary> /// <param name="targetRenderLoop">The target render loop.</param> public override async Task OnStartupAsync(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Build dummy scene Scene scene = targetRenderLoop.Scene; Camera3DBase camera = targetRenderLoop.Camera as Camera3DBase; // 2D rendering is made here m_solidBrush = new SolidBrushResource(Color4.Gray); m_textFormat = new TextFormatResource("Arial", 36); m_textBrush = new SolidBrushResource(Color4.RedColor); Custom2DDrawingLayer d2dDrawingLayer = new Custom2DDrawingLayer((graphics) => { RectangleF d2dRectangle = new RectangleF(10, 10, 236, 236); graphics.Clear(Color4.LightBlue); graphics.FillRoundedRectangle( d2dRectangle, 30, 30, m_solidBrush); d2dRectangle.Inflate(-10, -10); graphics.DrawText("Hello Direct2D!", m_textFormat, d2dRectangle, m_textBrush); }); // Build 3D scene await targetRenderLoop.Scene.ManipulateSceneAsync((manipulator) => { // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); // Define Direct2D texture resource var resD2DTexture = manipulator.AddResource <Direct2DTextureResource>( () => new Direct2DTextureResource(d2dDrawingLayer, 256, 256)); var resD2DMaterial = manipulator.AddSimpleColoredMaterial(resD2DTexture); // Create pallet geometry resource PalletType pType = new PalletType(); pType.PalletMaterial = NamedOrGenericKey.Empty; pType.ContentMaterial = resD2DMaterial; var resPalletGeometry = manipulator.AddResource <GeometryResource>( () => new GeometryResource(pType)); // Create pallet object GenericObject palletObject = manipulator.AddGeneric(resPalletGeometry); palletObject.Color = Color4.GreenColor; palletObject.EnableShaderGeneratedBorder(); palletObject.BuildAnimationSequence() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_180DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_360DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .CallAction(() => palletObject.RotationEuler = Vector3.Zero) .ApplyAndRewind(); }); // Configure camera camera.Position = new Vector3(2f, 2f, 2f); camera.Target = new Vector3(0f, 0.5f, 0f); camera.UpdateCamera(); }
protected override void Update(SceneRelatedUpdateState updateState, ViewInformation correspondingView, PerSceneContext componentContext) { Camera3DBase actCamera = correspondingView.Camera; if (actCamera == null) { return; } foreach (InputFrame actInputFrame in updateState.InputFrames) { foreach (var actInputState in actInputFrame.GetInputStates(correspondingView)) { // Handle keyboard KeyboardState actKeyboardState = actInputState as KeyboardState; if (actKeyboardState != null) { UpdateForKeyboard(componentContext, actCamera, actKeyboardState); continue; } // Handle mouse (or pointer) MouseOrPointerState mouseState = actInputState as MouseOrPointerState; if (mouseState != null) { UpdateForMouse(componentContext, actCamera, mouseState); } } } // Ensure that our values are in allowed ranges float maxRad = EngineMath.RAD_90DEG * 0.99f; float minRad = EngineMath.RAD_90DEG * -0.99f; componentContext.CameraHVRotation.X = componentContext.CameraHVRotation.X % EngineMath.RAD_360DEG; if (componentContext.CameraDistance < this.CameraDistanceMin) { componentContext.CameraDistance = this.CameraDistanceMin; } if (componentContext.CameraDistance > this.CameraDistanceMax) { componentContext.CameraDistance = this.CameraDistanceMax; } if (componentContext.CameraHVRotation.Y <= minRad) { componentContext.CameraHVRotation.Y = minRad; } if (componentContext.CameraHVRotation.Y >= maxRad) { componentContext.CameraHVRotation.Y = maxRad; } // Update camera position and rotation Vector3 cameraOffset = Vector3.UnitX; cameraOffset = Vector3.TransformNormal( cameraOffset, Matrix4x4.CreateRotationY(componentContext.CameraHVRotation.X)); cameraOffset = Vector3.TransformNormal( cameraOffset, Matrix4x4.CreateFromAxisAngle(Vector3.Cross(cameraOffset, Vector3.UnitY), componentContext.CameraHVRotation.Y)); Vector3 focusedLocation = this.GetFocusedLocation(); actCamera.Position = focusedLocation + cameraOffset * componentContext.CameraDistance; actCamera.Target = focusedLocation; }
/// <summary> /// Executes view update using the given update state object. /// </summary> /// <param name="updateState">The update state.</param> internal void UpdateForView(SceneRelatedUpdateState updateState) { if (m_disposed) { throw new ObjectDisposedException("ViewRelatedLayerSubset"); } // TODO: Trigger some other logic to update transparent object order // TODO: Performance improvement!!! bool anyOrderChanges = false; Camera3DBase camera = m_viewInformation.Camera; m_objectsPassTransparentRender.Subscriptions.Sort(new Comparison <RenderPassSubscription>((left, right) => { SceneSpacialObject leftSpacial = left.SceneObject as SceneSpacialObject; SceneSpacialObject rightSpacial = right.SceneObject as SceneSpacialObject; if ((leftSpacial != null) && (rightSpacial != null)) { float leftDistance = (camera.Position - leftSpacial.Position).LengthSquared(); float rightDistance = (camera.Position - rightSpacial.Position).LengthSquared(); anyOrderChanges = true; return(rightDistance.CompareTo(leftDistance)); } else if (leftSpacial != null) { anyOrderChanges = true; return(-1); } else if (rightSpacial != null) { anyOrderChanges = true; return(1); } { return(0); } })); if (anyOrderChanges) { // Synchronize ordering changes with corresponding scene object for (int loop = 0; loop < m_objectsPassTransparentRender.Subscriptions.Count; loop++) { var actSubscription = m_objectsPassTransparentRender.Subscriptions[loop]; actSubscription.SubscriptionIndex = loop; actSubscription.SceneObject.UpdateSubscription(actSubscription, this); m_objectsPassTransparentRender.Subscriptions[loop] = actSubscription; } } // Update all objects related to this view m_isSubscribeUnsubscribeAllowed = true; try { // Update subscriptions based on visibility check result if (m_changedVisibilitiesAction != null) { m_changedVisibilitiesAction(); m_changedVisibilitiesAction = null; } // Unsubscribe all invalid objects SceneObject actInvalidObject = null; while (m_invalidObjectsToDeregister.Count > 0) { actInvalidObject = m_invalidObjectsToDeregister.Dequeue(); actInvalidObject.UnsubsribeFromAllPasses(this); } // Update subsccriptions based on boject state List <SceneObject> allObjects = m_sceneLayer.ObjectsInternal; int allObjectsLength = allObjects.Count; int visibleObjectCount = m_viewInformation.Owner.VisibleObjectCountInternal; for (int loop = 0; loop < allObjectsLength; loop++) { SceneObject actSceneObject = allObjects[loop]; if (m_invalidObjects.ContainsKey(actSceneObject)) { continue; } if (actSceneObject.IsLayerViewSubsetRegistered(this.ViewIndex) && actSceneObject.IsVisible(m_viewInformation)) { actSceneObject.UpdateForView(updateState, this); visibleObjectCount++; } } m_viewInformation.Owner.VisibleObjectCountInternal = visibleObjectCount; } finally { m_isSubscribeUnsubscribeAllowed = false; } // Reorganize subscriptions if there is anything unsubscribed if (m_anythingUnsubscribed) { m_anythingUnsubscribed = false; foreach (var actPassProperties in m_objectsPerPass) { if (actPassProperties.UnsubscribeCallCount <= 0) { continue; } // Variables for consistency checking int givenUnsubscribeCount = actPassProperties.UnsubscribeCallCount; int trueUnsubscribeCount = 0; // Handle case where we have unsubscribed some // => Build new subscription list and ignore all whith 'IsSubscribed' == false List <RenderPassSubscription> newSubscriptionList = new List <RenderPassSubscription>( (actPassProperties.Subscriptions.Count - actPassProperties.UnsubscribeCallCount) + 128); for (int loop = 0; loop < actPassProperties.Subscriptions.Count; loop++) { RenderPassSubscription actSubscription = actPassProperties.Subscriptions[loop]; if (!actSubscription.IsSubscribed) { actSubscription.SceneObject.ClearSubscriptionsWithoutUnsubscribeCall(this, actSubscription); trueUnsubscribeCount++; continue; } // Add this item to new subscription list actSubscription.SubscriptionIndex = newSubscriptionList.Count; newSubscriptionList.Add(actSubscription); actSubscription.SceneObject.UpdateSubscription(actSubscription, this); } actPassProperties.Subscriptions = newSubscriptionList; actPassProperties.UnsubscribeCallCount = 0; // Check for consistency: Does unsubscribe-count match true unsubscriptions using IsSubscribed flag if (givenUnsubscribeCount != trueUnsubscribeCount) { throw new SeeingSharpException("Inconsistency: Given unsubscribe count does not mach true count of unsubscriptions!"); } } } }
protected override async void OnLoad(EventArgs e) { base.OnLoad(e); // Attach the painter to the target render panel m_ctrlRenderControl.RenderLoop.ClearColor = Color4.CornflowerBlue; // Build scene graph await m_ctrlRenderControl.Scene.ManipulateSceneAsync((manipulator) => { // Define a BACKGROUND layer and configure layer IDs // => Ensures correct render order SceneLayer bgLayer = manipulator.AddLayer("BACKGROUND"); manipulator.SetLayerOrderID(bgLayer, 0); manipulator.SetLayerOrderID(Scene.DEFAULT_LAYER_NAME, 1); // Add the background texture painter to the BACKGROUND layer var resBackgroundTexture = manipulator.AddTexture( new AssemblyResourceUriBuilder( "SeeingSharp.Tutorials.Introduction04", true, "Assets/Textures/Background.png")); manipulator.Add(new FullscreenTextureObject(resBackgroundTexture), bgLayer.Name); // Create pallet geometry resource PalletType pType = new PalletType(); pType.ContentColor = Color4.GreenColor; var resPalletGeometry = manipulator.AddResource <GeometryResource>( () => new GeometryResource(pType)); // Create pallet object and add it to the scene // => The DEFAULT layer is used by default for (int loopX = 0; loopX < 11; loopX++) { for (int loopY = 0; loopY < 11; loopY++) { GenericObject palletObject = manipulator.AddGeneric(resPalletGeometry); palletObject.Color = Color4.GreenColor; palletObject.Position = new Vector3( -10f + loopX * 2f, -10f + loopY * 2f, 0f); palletObject.Tag1 = $"Pallet (X={loopX}, Y={loopY})"; palletObject.EnableShaderGeneratedBorder(); palletObject.BuildAnimationSequence() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_180DEG, EngineMath.RAD_45DEG), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_360DEG, EngineMath.RAD_45DEG), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, 0f, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .CallAction(() => palletObject.RotationEuler = Vector3.Zero) .ApplyAndRewind(); } } }); // Configure camera Camera3DBase camera = m_ctrlRenderControl.Camera; camera.Position = new Vector3(0f, 0f, -25f); camera.Target = new Vector3(0f, 0f, 0f); camera.UpdateCamera(); }
/// <summary> /// Called when the sample has to startup. /// </summary> /// <param name="targetRenderLoop">The target render loop.</param> public override async Task OnStartupAsync(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Start the device chooser m_deviceChooser = new CaptureDeviceChooser(); // Show fallback-scene if we don't have a capture device if (m_deviceChooser.DeviceCount <= 0) { await OnStartupAsync_Fallback(targetRenderLoop); return; } // Get and configure the camera Camera3DBase camera = targetRenderLoop.Camera as PerspectiveCamera3D; camera.Position = new Vector3(0f, 5f, -7f); camera.Target = new Vector3(0f, 0f, 0f); camera.UpdateCamera(); // Open the video file m_videoReader = new AsyncRealtimeVideoReader(m_deviceChooser.DeviceInfos.First()); m_videoReader.VideoReachedEnd += (sender, eArgs) => { m_videoReader.SetCurrentPosition(TimeSpan.Zero); }; // Define scene await targetRenderLoop.Scene.ManipulateSceneAsync((manipulator) => { // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); // Define texture and resource var resVideoTexture = manipulator.AddResource <VideoTextureResource>( () => new VideoTextureResource(m_videoReader)); var resVideoMaterial = manipulator.AddSimpleColoredMaterial(resVideoTexture, addToAlpha: 1f); var geoResource = manipulator.AddResource <GeometryResource>( () => new GeometryResource(new PalletType( palletMaterial: NamedOrGenericKey.Empty, contentMaterial: resVideoMaterial))); // Add the object GenericObject newObject = manipulator.AddGeneric(geoResource); newObject.RotationEuler = new Vector3(0f, EngineMath.RAD_90DEG / 2f, 0f); newObject.Scaling = new Vector3(2f, 2f, 2f); newObject.EnableShaderGeneratedBorder(); // Start pallet rotating animation newObject.BuildAnimationSequence() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_180DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_360DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, 0f, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .CallAction(() => newObject.RotationEuler = Vector3.Zero) .ApplyAndRewind(); }); }
/// <summary> /// Called when the sample has to startup. /// </summary> /// <param name="targetRenderLoop">The target render loop.</param> public override async Task OnStartupAsync(RenderLoop targetRenderLoop) { targetRenderLoop.EnsureNotNull(nameof(targetRenderLoop)); // Build dummy scene Scene scene = targetRenderLoop.Scene; Camera3DBase camera = targetRenderLoop.Camera as Camera3DBase; // Define resources m_starBitmap = new StandardBitmapResource( new AssemblyResourceLink( typeof(SeeingSharpSampleResources), "Bitmaps.StarColored_128x128.png")); m_startBitmapShaded = new GaussianBlurEffectResource(m_starBitmap); m_startBitmapShaded.StandardDeviation = 4f; // Define 2D overlay Action <Graphics2D> draw2DAction = (graphics) => { graphics.DrawBitmap( m_starBitmap, new Vector2(10f, 10f), 1f, BitmapInterpolationMode.Linear); graphics.DrawImage( m_startBitmapShaded, new Vector2(150f, 10f)); }; await targetRenderLoop.Scene.ManipulateSceneAsync((manipulator) => { // Add the 2D layer to the scene manipulator.AddDrawingLayer(draw2DAction); // Create floor SampleSceneBuilder.BuildStandardFloor( manipulator, Scene.DEFAULT_LAYER_NAME); // Create pallet geometry resource PalletType pType = new PalletType(); pType.ContentColor = Color4.Transparent; var resPalletGeometry = manipulator.AddResource <GeometryResource>( () => new GeometryResource(pType)); // Create pallet object GenericObject palletObject = manipulator.AddGeneric(resPalletGeometry); palletObject.Color = Color4.GreenColor; palletObject.EnableShaderGeneratedBorder(); palletObject.BuildAnimationSequence() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_180DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .RotateEulerAnglesTo(new Vector3(0f, EngineMath.RAD_360DEG, 0f), TimeSpan.FromSeconds(2.0)) .WaitFinished() .CallAction(() => palletObject.RotationEuler = Vector3.Zero) .ApplyAndRewind(); }); // Configure camera camera.Position = new Vector3(2f, 2f, 2f); camera.Target = new Vector3(0f, 0.5f, 0f); camera.UpdateCamera(); }