// @TODO - change this delivering directly command list from the renderer after implementing overall rendering system public void SkeletonDebugDrawing(SharpDX.Direct3D12.GraphicsCommandList commandList, Boolean bDebugDraw = true) { // @TODO - temporary to check if animation is working H1SkeletalMeshComponent skeletalMeshComponent = H1Global <H1World> .Instance.PersistentLevel.GetActor(0).GetActorComponent <H1SkeletalMeshComponent>(); List <H1AnimInstance.InterpolatedLocalTransform> interpolatedLocalTransforms = new List <H1AnimInstance.InterpolatedLocalTransform>(); for (Int32 boneIndex = 0; boneIndex < m_Skeleton.RefSkeleton.RefBoneInfoList.Count; ++boneIndex) { H1AnimInstance.InterpolatedLocalTransform interpolatedLocalTransform = new H1AnimInstance.InterpolatedLocalTransform(); H1MeshBoneInfo meshBoneInfo = m_Skeleton.RefSkeleton.RefBoneInfoList[boneIndex]; interpolatedLocalTransform.BoneName = meshBoneInfo.Name; interpolatedLocalTransform.LocalTransform = m_Skeleton.RefSkeleton.RefBoneBases[boneIndex]; interpolatedLocalTransforms.Add(interpolatedLocalTransform); } // extract interpolated local transforms skeletalMeshComponent.AnimScriptInstance.ExtractInterpolatedLocalTransform(0.0f, ref interpolatedLocalTransforms); H1Transform[] globalTransforms = new H1Transform[m_Skeleton.RefSkeleton.RefBoneBases.Count]; // tracking only upper parent index by one Int32[] transformParentIndices = new Int32[m_Skeleton.RefSkeleton.RefBoneBases.Count]; for (Int32 boneIndex = 0; boneIndex < m_Skeleton.RefSkeleton.RefBoneInfoList.Count; ++boneIndex) { H1MeshBoneInfo meshBoneInfo = m_Skeleton.RefSkeleton.RefBoneInfoList[boneIndex]; //H1Transform localTransform = m_Skeleton.RefSkeleton.RefBoneBases[boneIndex]; H1Transform localTransform = interpolatedLocalTransforms[boneIndex].LocalTransform; // extract parent locals List <H1Transform> parentLocalTransforms = new List <H1Transform>(); H1MeshBoneInfo currMeshBoneInfo = meshBoneInfo; while (currMeshBoneInfo.ParentIndex != -1) { //parentLocalTransforms.Add(m_Skeleton.RefSkeleton.RefBoneBases[currMeshBoneInfo.ParentIndex]); parentLocalTransforms.Add(interpolatedLocalTransforms[currMeshBoneInfo.ParentIndex].LocalTransform); currMeshBoneInfo = m_Skeleton.RefSkeleton.RefBoneInfoList[currMeshBoneInfo.ParentIndex]; } // generate global transform for current bone space // 1. start to transform current local transformation matrix Matrix globalTransformMtx = localTransform.Transformation; // 2. from curr bone space to root space by going up to each parent node space for (Int32 index = 0; index < parentLocalTransforms.Count; ++index) { Matrix parentLocalTransformMtx = parentLocalTransforms[index].Transformation; globalTransformMtx = Matrix.Multiply(globalTransformMtx, parentLocalTransformMtx); } // decompose global matrix and generate H1Transform Vector3 translation; Vector3 scale; Quaternion rotate; globalTransformMtx.Decompose(out scale, out rotate, out translation); H1Transform globalTransform = new H1Transform(); globalTransform.Translation = translation; globalTransform.Scaling = scale; globalTransform.Rotation = rotate; globalTransforms[boneIndex] = globalTransform; transformParentIndices[boneIndex] = meshBoneInfo.ParentIndex; } // set bone matrices Int32 currGlobalBoneIndex = 0; foreach (H1Transform boneTransform in globalTransforms) { // @TODO - temporary scaling to match when we importing vertices in H1AssimpImporter //boneTransform.Scaling = boneTransform.Scaling * 0.01f; // get global offset matrices Matrix globalOffsetMatrix = m_Skeleton.RefSkeleton.RefOffsetBases[currGlobalBoneIndex].Transformation; // pass multiplied global offset matrices and animated global matrices H1Global <H1ManagedRenderer> .Instance.SetBoneMatrix(currGlobalBoneIndex, Matrix.Multiply(globalOffsetMatrix, boneTransform.Transformation)); currGlobalBoneIndex++; } // when debug draw is enabled if (bDebugDraw == true) { for (Int32 boneIndex = 0; boneIndex < globalTransforms.Count(); ++boneIndex) { Int32 parentIndex = transformParentIndices[boneIndex]; if (parentIndex < 0) { continue; } H1Transform parentBoneTransform = globalTransforms[parentIndex]; H1Transform boneTransform = globalTransforms[boneIndex]; Vector3 parentLoc = parentBoneTransform.Translation * 0.005f; Vector3 currLoc = boneTransform.Translation * 0.005f; float length = (currLoc - parentLoc).Length(); if (length < 0.001f) { continue; } Vector3 zAxis = Vector3.Normalize(currLoc - parentLoc); Matrix pitchMtx = Matrix.RotationYawPitchRoll(0, 0.1f, 0); Vector4 rotatedZAxis = Vector3.Transform(zAxis, pitchMtx); rotatedZAxis /= rotatedZAxis.W; Vector3 yAxis = Vector3.Normalize(Vector3.Cross(zAxis, Vector3.Normalize(new Vector3(rotatedZAxis.X, rotatedZAxis.Y, rotatedZAxis.Z)))); Vector3 xAxis = Vector3.Normalize(Vector3.Cross(zAxis, yAxis)); //H1RenderUtils.DrawCapsule(commandList, parentLoc, xAxis, yAxis, zAxis, 0.03f, length / 2.0f, 16); H1RenderUtils.DrawDashedLine(commandList, parentLoc, currLoc, 2.0f); //H1RenderUtils.DrawWireStar(commandList, currLoc, 0.03f); } } }
private void PopulateCommandListsForSkeletalMesh() { m_CommandList.CommandAllocator.Reset(); //m_DeviceContext.MainCommandListPool m_CommandList.CommandList.Reset(m_CommandList.CommandAllocator, m_PipelineState); // set viewport and sissors m_CommandList.CommandList.SetGraphicsRootSignature(m_RootSignature); // @TODO - redesign this section // extract and update bone matrix H1SkeletalMeshComponent skeletalMeshComponent = H1Global <H1World> .Instance.PersistentLevel.GetActor(0).GetActorComponent <H1SkeletalMeshComponent>(); skeletalMeshComponent.SkeletalMesh.SkeletonDebugDrawing(m_CommandList.CommandList, false); m_TransformationCBPointer = m_ConstantBuffer.Map(0); //Utilities.Write(m_TransformationCBPointer, ref m_TransformationCB); List <Matrix> dataToCopy = new List <Matrix>(); dataToCopy.Add(m_TransformationCB.viewProjectionMatrix); foreach (Matrix mtx in m_TransformationCB.BoneMatrices) { dataToCopy.Add(mtx); } Utilities.Write(m_TransformationCBPointer, dataToCopy.ToArray(), 0, 101); m_ConstantBuffer.Unmap(0); m_CommandList.CommandList.SetDescriptorHeaps(1, new DescriptorHeap[] { m_ConstantBufferViewHeap }); //m_CommandList.SetDescriptorHeaps(2, new DescriptorHeap[] { m_ConstantBufferViewHeap, m_srvDescriptorHeap }); GpuDescriptorHandle hDescriptor = m_ConstantBufferViewHeap.GPUDescriptorHandleForHeapStart; m_CommandList.CommandList.SetGraphicsRootDescriptorTable(0, hDescriptor); hDescriptor += m_ConstantBufferDescriptorSize; //Int32 sizeInBytes = (Utilities.SizeOf<TransformationCB>() + 255) & ~255; //hDescriptor += sizeInBytes; m_CommandList.CommandList.SetGraphicsRootDescriptorTable(1, hDescriptor); m_CommandList.CommandList.SetViewport(m_Viewport); m_CommandList.CommandList.SetScissorRectangles(m_SissorRect); // use barrier to notify we are using the m_RenderTarget Resource rtvBackBuffer = m_SwapChainDX12.GetBackBuffer(m_FrameIndex); m_CommandList.CommandList.ResourceBarrierTransition(rtvBackBuffer, ResourceStates.Present, ResourceStates.RenderTarget); //CpuDescriptorHandle rtvHandle = m_RenderTargetViewHeap.CPUDescriptorHandleForHeapStart; //rtvHandle += m_FrameIndex * m_RTVDescriptorSize; //CpuDescriptorHandle dsvHandle = m_DepthStencilViewHeap.CPUDescriptorHandleForHeapStart; CpuDescriptorHandle rtvHandle = m_DeviceContext.Dx12Device.RenderTargetDescriptorCache.GetCpuAddressByOffset(m_FrameIndex); // @TODO - need to set the depth value consistent with frame counts! CpuDescriptorHandle dsvHandle = m_DeviceContext.Dx12Device.DepthStencilDescriptorCache.GetCpuAddressByOffset(0); m_CommandList.CommandList.SetRenderTargets(rtvHandle, dsvHandle); // clear the render target & depth stencil m_CommandList.CommandList.ClearRenderTargetView(rtvHandle, new Color4(0, 0.2f, 0.4f, 1), 0, null); m_CommandList.CommandList.ClearDepthStencilView(dsvHandle, ClearFlags.FlagsDepth, 1.0f, 0, 0, null); // record commands m_CommandList.CommandList.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList; H1SkeletalMeshObjectGPUSkin skeletalMeshObject = H1Global <H1World> .Instance.PersistentLevel.GetActor(0).GetActorComponent <H1SkeletalMeshComponent>().SkeletalMeshObjectGPUSkin; H1SkeletalMeshObjectGPUSkin.H1SkeletalMeshObjectLOD skeletalMeshObjectLOD_0 = skeletalMeshObject.GetSkeletalMeshObjectLODByIndex(0); SharpDX.Direct3D12.IndexBufferView rawIBV = ((Gen2Layer.H1IndexBufferView)skeletalMeshObjectLOD_0.IndexBuffer.View).View; m_CommandList.CommandList.SetIndexBuffer(rawIBV); H1SkeletalMesh skeletalMesh = H1Global <H1World> .Instance.PersistentLevel.GetActor(0).GetActorComponent <H1SkeletalMeshComponent>().SkeletalMesh; List <H1SkelMeshSection> skelSections = skeletalMesh.SkeletalMeshResource.GetLODModel(0).Sections; Int32 sectionIndex = 0; Int32 currIndexBufferOffset = 0; Int32 totalCount = skeletalMeshObjectLOD_0.GPUSkinVertexFactories.VertexFactories.Count; for (Int32 vertexfactoryIndex = 0; vertexfactoryIndex < totalCount; ++vertexfactoryIndex) { var vertexfactory = skeletalMeshObjectLOD_0.GPUSkinVertexFactories.VertexFactories[vertexfactoryIndex]; vertexfactory.setVertexBuffers(m_CommandList.CommandList); H1SkelMeshSection currSkelMeshSection = skelSections[sectionIndex]; Int32 indexCount = Convert.ToInt32(currSkelMeshSection.NumTriangles) * 3; m_CommandList.CommandList.DrawIndexedInstanced(indexCount, 1, currIndexBufferOffset, 0, 0); currIndexBufferOffset += indexCount; sectionIndex++; } // use barrier to notify that we are going to present the render target m_CommandList.CommandList.ResourceBarrierTransition(rtvBackBuffer, ResourceStates.RenderTarget, ResourceStates.Present); // execute the command m_CommandList.CommandList.Close(); }
public void Initialize(IntPtr windowHandle, int width, int height) { m_WindowHandle = windowHandle; //@TODO - re-ordering this correctly! // renderer m_Renderer = H1Global <H1ManagedRenderer> .Instance; m_Renderer.Initialize(width, height, windowHandle); // asset importer (Assimp) m_AssimpImporter = H1Global <H1AssimpImporter> .Instance; m_AssimpImporter.Initialize(); // world system m_World = H1Global <H1World> .Instance; Int32 lvIndex = m_World.AddLevel(new H1Level()); // set persistent level H1Level persistentLevel = m_World.GetLevel(lvIndex); m_World.PersistentLevel = persistentLevel; H1AssetContext AssetContext = H1Global <H1AssimpImporter> .Instance.asset; if (AssetContext != null) { H1ModelContext ModelContext = H1Global <H1AssimpImporter> .Instance.asset.GetModel(0); // create temporary actor H1Actor testActor = new H1Actor(); H1StaticMeshComponent staticMeshComponent = new H1StaticMeshComponent(); staticMeshComponent.StaticMesh = new H1StaticMesh(ModelContext); testActor.AddActorComponent <H1StaticMeshComponent>(staticMeshComponent); // create temporary skeletal mesh component H1SkeletalMeshComponent skeletalMeshComponent = new H1SkeletalMeshComponent(); skeletalMeshComponent.SkeletalMesh = new H1SkeletalMesh(); H1StaticLODModel staticLODModelRef = skeletalMeshComponent.SkeletalMesh.PrepareProcessAssetContext(ModelContext.SkeletalContexts[0]); skeletalMeshComponent.SkeletalMesh.ProcessAssetContext(staticLODModelRef, ModelContext.Meshes.ToArray(), ModelContext.SkeletalContexts[0]); skeletalMeshComponent.AnimScriptInstance.ProcessAnimationContext(ModelContext.AnimationContext); // generate skeletalmeshobject skeletalMeshComponent.GenerateSkeleltalMeshObjectGpuSkin(); testActor.AddActorComponent <H1SkeletalMeshComponent>(skeletalMeshComponent); // add the actor to the world m_World.PersistentLevel.AddActor(testActor); //@TODO - temporary force to order to working // after load assets m_Renderer.LoadAssets(); } // @TODO - make the global accessor to access the current running app class! m_WPFInputManager = H1Global <H1InputManagerWpf> .Instance; H1InteractionContext <Window> context = new H1InteractionContext <Window>(Application.Current.MainWindow); m_WPFInputManager.Initialize(context); // initialize the camera m_Camera = new H1Camera(); // set the camera properties Vector3 eye = new Vector3(0.0f, 0.0f, -10.0f); Vector3 lookAtPoint = new Vector3(0.0f, 0.0f, 0.0f); Vector3 upVector = new Vector3(0.0f, 1.0f, 0.0f); float fov = Convert.ToSingle((Math.PI / 180.0) * 45.0); float nearZ = 1.0f; float farZ = 10000.0f; float focusRadius = 1.0f; float aspectRatio = m_Renderer.Width / m_Renderer.Height; // set the camera state m_Camera.SetState(H1ViewTypes.Perspective, eye, lookAtPoint, upVector, fov, aspectRatio, nearZ, farZ, focusRadius); // camera controller m_CameraController = new H1CameraController(); m_CameraController.Camera = m_Camera; m_VisualDebugger = H1Global <H1VisualDebugger> .Instance; // task scheduler (fiber-based) c++ SGDManagedEngineWrapper.H1ManagedTaskSchedulerLayerWrapper.InitializeTaskScheduler(); SGDManagedEngineWrapper.H1ManagedTaskSchedulerLayerWrapper.StartTaskScheduler(); }