aboutsummaryrefslogtreecommitdiff
path: root/tools/ArtistTools/source/CoreLib
diff options
context:
space:
mode:
authorBryan Galdrikian <[email protected]>2017-02-24 09:32:20 -0800
committerBryan Galdrikian <[email protected]>2017-02-24 09:32:20 -0800
commite1bf674c16e3c8472b29574159c789cd3f0c64e0 (patch)
tree9f0cfce09c71a2c27ff19589fcad6cd83504477c /tools/ArtistTools/source/CoreLib
parentfirst commit (diff)
downloadblast-e1bf674c16e3c8472b29574159c789cd3f0c64e0.tar.xz
blast-e1bf674c16e3c8472b29574159c789cd3f0c64e0.zip
Updating to [email protected] and [email protected] with a new directory structure.
NvBlast folder is gone, files have been moved to top level directory. README is changed to reflect this.
Diffstat (limited to 'tools/ArtistTools/source/CoreLib')
-rw-r--r--tools/ArtistTools/source/CoreLib/Anim/AnimUtil.cpp419
-rw-r--r--tools/ArtistTools/source/CoreLib/Anim/AnimUtil.h217
-rw-r--r--tools/ArtistTools/source/CoreLib/Anim/FbxUtil.cpp1023
-rw-r--r--tools/ArtistTools/source/CoreLib/Anim/FbxUtil.h64
-rw-r--r--tools/ArtistTools/source/CoreLib/Backdoor/backdoor.cpp263
-rw-r--r--tools/ArtistTools/source/CoreLib/Backdoor/backdoor.h52
-rw-r--r--tools/ArtistTools/source/CoreLib/CoreLib.cpp1460
-rw-r--r--tools/ArtistTools/source/CoreLib/CoreLib.h121
-rw-r--r--tools/ArtistTools/source/CoreLib/Parameters/FoundationHolder.h138
-rw-r--r--tools/ArtistTools/source/CoreLib/PluginInterface.h137
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.cpp31
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.h65
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.cpp138
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.h56
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.cpp890
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.h90
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.cpp256
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.h72
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.cpp319
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.h43
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.cpp225
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.h43
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.cpp208
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.h72
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.cpp29
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.h64
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.cpp333
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.h69
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.cpp33
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.h14
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.cpp315
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.h83
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.cpp31
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.h81
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.cpp222
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.h63
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.cpp564
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.h254
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.cpp467
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.h74
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.cpp384
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.h85
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.cpp371
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.h110
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.cpp141
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.h29
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.cpp231
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.h42
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.cpp99
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.h68
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.cpp29
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.h89
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.cpp386
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.h68
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.cpp33
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.h14
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.cpp343
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.h83
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/GPUProfiler.cpp87
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/GPUProfiler.h61
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/GeometryData/BoneGeometryData.h305
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/GeometryData/LightGeometryData.h269
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/GeometryData/WindGeometryData.h2513
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.cpp351
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.h175
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.cpp86
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.h124
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.cpp47
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.h72
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/LightShaderParam.h83
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/MeshShaderParam.h142
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/ShadowMap.cpp36
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/ShadowMap.h48
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.cpp493
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.h75
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/Camera.cpp867
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/Camera.h128
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/Gamepad.cpp1310
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/Gamepad.h68
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.cpp319
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.h173
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/Light.cpp744
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/Light.h152
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/MeshData.cpp108
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/MeshData.h74
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/Mouse.cpp105
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/Mouse.h103
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/SimpleScene.cpp1312
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/SimpleScene.h184
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/Automate.cpp530
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/Automate.h23
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/CoreLibUtils.h65
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/MathUtil.cpp327
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/MathUtil.h557
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/Profiler.cpp82
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/Profiler.h51
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/Settings.cpp767
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/Settings.h392
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/Stats.cpp76
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/Stats.h54
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/Timer.cpp80
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/Timer.h68
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.cpp75
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.h136
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp1448
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h208
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.cpp106
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.h31
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp151
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/D3DWidget.h51
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.cpp263
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.h47
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.cpp177
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.h80
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp906
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.h100
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp93
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h39
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.cpp190
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.h51
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/OutputWindow.cpp22
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/OutputWindow.h22
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.cpp17
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.h284
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/SlideSpinBoxInt.h15
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/TipListView.cpp42
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/TipListView.h26
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/UIGlobal.h37
-rw-r--r--tools/ArtistTools/source/CoreLib/corelib_global.h20
129 files changed, 30026 insertions, 0 deletions
diff --git a/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.cpp b/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.cpp
new file mode 100644
index 0000000..5ab1563
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.cpp
@@ -0,0 +1,419 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// This file contains wrapper functions to make hair lib easy to setup and use
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#include <vector>
+#include <string>
+
+#include "AnimUtil.h"
+#include "MathUtil.h"
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+AnimationCache::~AnimationCache()
+{
+ Release();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void AnimationCache::Initialize(int numBones, NvInt32 frameStart, NvInt32 frameEnd)
+{
+ m_numBones = numBones;
+ m_frameStart = frameStart;
+ m_frameEnd = frameEnd;
+
+ m_numFrames = frameEnd - frameStart + 1;
+
+ Release();
+ Allocate();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void AnimationCache::Allocate()
+{
+ m_pBoneMatrices = new atcore_float4x4[m_numFrames * m_numBones];
+// m_pBoneNames = new char[NV_HAIR_MAX_STRING * m_numBones];
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void AnimationCache::Release()
+{
+ if (m_pBoneMatrices)
+ delete []m_pBoneMatrices;
+
+ if (m_pBoneNames)
+ delete []m_pBoneNames;
+
+ m_pBoneMatrices = 0;
+ m_pBoneNames = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool AnimationCache::GetInterpolationInfo(float frame, int& indexStart, int& indexEnd, float &fracFrame)
+{
+ if (frame < m_frameStart)
+ return false;
+
+ if (frame > m_frameEnd)
+ return false;
+
+ int startFrame = (int)frame;
+
+ fracFrame = frame - startFrame;
+
+ indexStart = (int)(frame - m_frameStart);
+ indexEnd = indexStart + 1;
+
+ if (indexEnd >= (int)m_numFrames)
+ {
+ indexEnd = indexStart;
+ fracFrame = 0.0f;
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+int AnimationCache::FindBone(const char *toFind) const
+{
+ if (!toFind)
+ return -1;
+ /*
+ for (int i = 0; i < m_numBones; i++)
+ {
+ const char* boneName = GetBoneName(i);
+ if (!strcmp(boneName, toFind))
+ return i;
+ }
+ */
+ return -1;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool AnimationCache::FindBoneMapping( int numBones, const NvChar* boneNames, int* mappedBoneId) const
+{
+ // mappedBoneId must be pre-allocated
+
+ for (int i = 0; i < numBones; i++)
+ {
+ //mappedBoneId[i] = FindBone(boneNames + i * NV_HAIR_MAX_STRING);
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void BoneData::Allocate(NvUInt32 numBones)
+{
+ Release();
+
+ m_numBones = numBones;
+
+ m_pPoseMatrices = new atcore_float4x4[numBones];
+ m_pSkinMatrices = new atcore_float4x4[numBones];
+ m_pBoneMatrices = new atcore_float4x4[numBones];
+
+ m_pSkinDQs = new atcore_dualquaternion[numBones];
+ //m_pBoneNames = new char[NV_HAIR_MAX_STRING * m_numBones];
+ m_pMappedBoneId = new int[numBones];
+
+ for (int i = 0; i < numBones; i++)
+ {
+ gfsdk_makeIdentity(m_pPoseMatrices[i]);
+ gfsdk_makeIdentity(m_pSkinMatrices[i]);
+ m_pMappedBoneId[i] = -1;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void BoneData::Release()
+{
+ if (m_pPoseMatrices)
+ {
+ delete []m_pPoseMatrices;
+ m_pPoseMatrices = 0;
+ }
+
+ if (m_pBoneMatrices)
+ {
+ delete []m_pBoneMatrices;
+ m_pBoneMatrices = 0;
+ }
+
+ if (m_pSkinMatrices)
+ {
+ delete []m_pSkinMatrices;
+ m_pSkinMatrices = 0;
+ }
+
+ if (m_pSkinDQs)
+ {
+ delete []m_pSkinDQs;
+ m_pSkinDQs = 0;
+ }
+
+ if (m_pBoneNames)
+ {
+ delete []m_pBoneNames;
+ m_pBoneNames = 0;
+ }
+
+ if (m_pMappedBoneId)
+ {
+ delete []m_pMappedBoneId;
+ m_pMappedBoneId = 0;
+ }
+
+ m_numBones = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void BoneData::InitializeAnimationCache(AnimationCache* pGlobalCache, const char* nodeName)
+{
+ if (!pGlobalCache || !pGlobalCache->isValid())
+ return;
+
+ pGlobalCache->FindBoneMapping(m_numBones, m_pBoneNames, m_pMappedBoneId);
+
+ m_nodeId = pGlobalCache->FindBone(nodeName);
+
+ m_pAnimationCache = pGlobalCache;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool BoneData::Update(float frameTime, const char* rootBoneName, bool bindPose, bool zup)
+{
+ if (!m_pAnimationCache || !m_pAnimationCache->isValid() )
+ bindPose = true;
+
+ atcore_float4x4 model;
+ gfsdk_makeIdentity(model);
+
+ if (bindPose)
+ {
+ for (int i = 0; i < m_numBones; i++)
+ {
+ m_pBoneMatrices[i] = m_pPoseMatrices[i];
+ m_pSkinMatrices[i] = model;
+ m_pSkinDQs[i] = gfsdk_makeDQ(m_pSkinMatrices[i]);
+ }
+ return true;
+ }
+
+ int indexStart, indexEnd;
+ float fracFrame = 0.0f;
+ if (false == m_pAnimationCache->GetInterpolationInfo(frameTime, indexStart, indexEnd, fracFrame))
+ return false;
+
+ atcore_float4x4* pBoneStart = m_pAnimationCache->GetNodeMatrices(indexStart);
+ atcore_float4x4* pBoneEnd = m_pAnimationCache->GetNodeMatrices(indexEnd);
+
+ int numBones = m_numBones;
+
+ atcore_float4x4 root;
+ gfsdk_makeIdentity(root);
+
+ if (rootBoneName)
+ {
+ int rootIndex = m_pAnimationCache->FindBone(rootBoneName);
+
+ if (rootIndex >= 0)
+ {
+ root = gfsdk_lerp(pBoneStart[rootIndex], pBoneEnd[rootIndex], fracFrame);
+
+ atcore_float3 lT = gfsdk_getTranslation(root);
+
+ if (zup)
+ lT.z = 0;
+ else
+ lT.y = 0;
+
+ gfsdk_makeIdentity(root);
+ gfsdk_setTranslation(root, -1.0f * lT);
+ }
+ }
+
+ // interpolate skinning matrix
+ for (int i = 0; i < numBones; i++)
+ {
+ atcore_float4x4 bone;
+
+ int index = m_pMappedBoneId[i];
+ if (index >= 0)
+ bone = gfsdk_lerp(pBoneStart[index], pBoneEnd[index], fracFrame);
+ else
+ gfsdk_makeIdentity(bone);
+
+ atcore_float4x4 pose = m_pPoseMatrices[i];
+
+ m_pBoneMatrices[i] = bone;
+ m_pSkinMatrices[i] = gfsdk_inverse(pose) * bone * root;
+ m_pSkinDQs[i] = gfsdk_makeDQ(m_pSkinMatrices[i]);
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void MeshDesc::Allocate(NvUInt32 numVertices, NvUInt32 numTriangles)
+{
+ Release();
+
+ m_NumTriangles = numTriangles;
+ m_NumVertices = numVertices;
+
+ m_pVertices = new atcore_float3[numVertices];
+
+ m_pVertexNormals = new atcore_float3[numTriangles * 3];
+ m_pFaceNormals = new atcore_float3[numTriangles * 3];
+
+ m_pTangents = new atcore_float3[numTriangles * 3];
+
+ m_pIndices = new NvUInt32[numTriangles * 3];
+ m_pTexCoords = new atcore_float2[numTriangles * 3];
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void MeshDesc::Release()
+{
+ if (m_pVertices)
+ delete []m_pVertices;
+ if (m_pVertexNormals)
+ delete []m_pVertexNormals;
+ if (m_pFaceNormals)
+ delete []m_pFaceNormals;
+ if (m_pTangents)
+ delete []m_pTangents;
+
+ if (m_pIndices)
+ delete []m_pIndices;
+ if (m_pTexCoords)
+ delete []m_pTexCoords;
+
+ m_NumTriangles = 0;
+ m_NumVertices = 0;
+
+ m_pVertices = nullptr;
+ m_pVertexNormals = nullptr;
+ m_pFaceNormals = nullptr;
+ m_pTangents = nullptr;
+
+ m_pIndices = nullptr;
+ m_pTexCoords = nullptr;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void MeshDesc::UpdateNormal(bool updateVertexNormal)
+{
+ atcore_float3* vertexNormal = new atcore_float3[m_NumVertices];
+ memset(vertexNormal, 0, sizeof(atcore_float3) * m_NumVertices);
+
+ for (int i = 0; i < m_NumTriangles; i++)
+ {
+ atcore_float3 faceNormal;
+
+ int fidx = i*3;
+ int id0 = m_pIndices[fidx++];
+ int id1 = m_pIndices[fidx++];
+ int id2 = m_pIndices[fidx++];
+
+ atcore_float3 p0 = m_pVertices[id0];
+ atcore_float3 p1 = m_pVertices[id1];
+ atcore_float3 p2 = m_pVertices[id2];
+ atcore_float3 p01 = p1 - p0;
+ atcore_float3 p02 = p2 - p0;
+
+ faceNormal.x = p01.y * p02.z - p01.z * p02.y;
+ faceNormal.y = p01.z * p02.x - p01.x * p02.z;
+ faceNormal.z = p01.x * p02.y - p01.y * p02.x;
+
+ gfsdk_normalize(faceNormal);
+
+ m_pFaceNormals[i * 3 + 0] = faceNormal;
+ m_pFaceNormals[i * 3 + 1] = faceNormal;
+ m_pFaceNormals[i * 3 + 2] = faceNormal;
+
+ vertexNormal[id0] += faceNormal;
+ vertexNormal[id1] += faceNormal;
+ vertexNormal[id2] += faceNormal;
+ }
+
+ if (updateVertexNormal)
+ {
+ for (int i = 0; i < m_NumVertices; ++i)
+ gfsdk_normalize(vertexNormal[i]);
+
+ for (int i = 0; i < m_NumTriangles; i++)
+ {
+ int fidx = i*3;
+ int id0 = m_pIndices[fidx++];
+ int id1 = m_pIndices[fidx++];
+ int id2 = m_pIndices[fidx++];
+
+ for (int k = 0; k < 3; k++)
+ {
+ int fidx = i*3 + k;
+ int vidx = m_pIndices[fidx];
+ m_pVertexNormals[fidx] = vertexNormal[vidx];
+ }
+ }
+ }
+
+ delete []vertexNormal;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void SkinData::Allocate(NvUInt32 numBones, NvUInt32 numVertices)
+{
+ Release();
+
+ m_boneData.Allocate(numBones);
+
+ m_pBoneIndices = new atcore_float4[numVertices];
+ m_pBoneWeights = new atcore_float4[numVertices];
+
+ memset(m_pBoneIndices, 0, sizeof(atcore_float4) * numVertices);
+ memset(m_pBoneWeights, 0, sizeof(atcore_float4) * numVertices);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void SkinData::Release()
+{
+ // clear memory
+ if (m_pBoneIndices)
+ delete []m_pBoneIndices;
+ if (m_pBoneWeights)
+ delete []m_pBoneWeights;
+
+ m_pBoneIndices = 0;
+ m_pBoneWeights = 0;
+
+ m_boneData.Release();
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.h b/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.h
new file mode 100644
index 0000000..8de718c
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.h
@@ -0,0 +1,217 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#pragma once
+
+#include "MathUtil.h"
+#include <string.h>
+
+//#include <Nv/Blast/NvHairSdk.h>
+
+////////////////////////////////////////////////////////////////////////////////////////
+// cache for animated bone data
+struct CORELIB_EXPORT AnimationCache
+{
+ NvUInt32 m_numBones;
+ NvChar* m_pBoneNames;
+
+ NvInt32 m_frameStart;
+ NvInt32 m_frameEnd;
+ NvUInt32 m_numFrames;
+
+ atcore_float4x4* m_pBoneMatrices;
+
+ AnimationCache() :
+ m_numBones(0),
+ m_frameStart(0),
+ m_frameEnd(0),
+ m_numFrames(0),
+ m_pBoneMatrices(nullptr),
+ m_pBoneNames(nullptr)
+ {
+ }
+
+ bool isValid() const {
+ return (m_numBones > 0) && (m_numFrames > 0) && (m_pBoneMatrices != 0);
+ }
+
+ void Allocate();
+ void Release();
+ void Initialize(int numBones, NvInt32 frameStart, NvInt32 frameEnd);
+
+ bool GetInterpolationInfo(float frameTime, int& indexStart, int& indexEnd, float &fracFrame);
+
+ const atcore_float4x4* GetNodeMatrices(int index) const { return m_pBoneMatrices + index * m_numBones; }
+ atcore_float4x4* GetNodeMatrices(int index) { return m_pBoneMatrices + index * m_numBones; }
+ /*
+ const char* GetBoneName(int index) const
+ {
+ return m_pBoneNames + index * NV_HAIR_MAX_STRING;
+ }
+
+ void SetBoneName(int index, const char* boneName)
+ {
+ char* str = m_pBoneNames + index * NV_HAIR_MAX_STRING;
+ strcpy_s(str, NV_HAIR_MAX_STRING, boneName);
+ }
+ */
+ int FindBone(const char *boneName) const;
+ bool FindBoneMapping( int numBones, const NvChar* boneNames, int* mappedBoneId) const;
+
+ ~AnimationCache();
+};
+
+////////////////////////////////////////////////////////////////////////////////////////
+// bone matrices at each frame
+////////////////////////////////////////////////////////////////////////////////////////
+struct CORELIB_EXPORT BoneData
+{
+ NvUInt32 m_numBones;
+ NvChar* m_pBoneNames;
+
+ atcore_float4x4* m_pPoseMatrices; // rest pose for each bone
+ atcore_float4x4* m_pBoneMatrices; // updated bone matrix
+ atcore_float4x4* m_pSkinMatrices; // interpolated skinning matrix for current frame
+ atcore_dualquaternion* m_pSkinDQs; // dual quats
+
+ AnimationCache* m_pAnimationCache;
+ int* m_pMappedBoneId;
+ int m_nodeId;
+
+public:
+ BoneData() :
+ m_numBones(0),
+ m_pBoneNames(nullptr),
+ m_pPoseMatrices(nullptr),
+ m_pBoneMatrices(nullptr),
+ m_pSkinMatrices(nullptr),
+ m_pSkinDQs(nullptr),
+ m_pAnimationCache(nullptr),
+ m_pMappedBoneId(nullptr),
+ m_nodeId(-1)
+ {}
+
+ void Allocate(NvUInt32 numBones);
+ void Release();
+ /*
+ const char* getBoneName(int index)
+ {
+ return m_pBoneNames + index * NV_HAIR_MAX_STRING;
+ }
+
+ void setBoneName(int index, const char* boneName)
+ {
+ char* str = m_pBoneNames + index * NV_HAIR_MAX_STRING;
+ strcpy_s(str, NV_HAIR_MAX_STRING, boneName);
+ }
+ */
+ void InitializeAnimationCache(AnimationCache* pGlobalCache, const char* nodeName);
+ bool Update(float frameTime, const char* rootBoneName, bool bindPose, bool zup);
+
+};
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Skinning data
+struct CORELIB_EXPORT SkinData
+{
+ BoneData m_boneData;
+
+ atcore_float4* m_pBoneIndices;
+ atcore_float4* m_pBoneWeights;
+
+public:
+ SkinData() :
+ m_pBoneIndices(nullptr),
+ m_pBoneWeights(nullptr)
+ {}
+
+ void Allocate(NvUInt32 numBones, NvUInt32 numVertices);
+ void Release();
+};
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+struct CORELIB_EXPORT MeshDesc
+{
+ NvUInt32 m_NumVertices;
+ NvUInt32 m_NumTriangles;
+
+ atcore_float3* m_pVertices;
+ atcore_float3* m_pVertexNormals;
+ atcore_float3* m_pFaceNormals;
+ atcore_float3* m_pTangents;
+
+ NvUInt32* m_pIndices;
+ atcore_float2* m_pTexCoords;
+
+public:
+ MeshDesc() :
+ m_NumVertices(0),
+ m_NumTriangles(0),
+
+ m_pVertices(nullptr),
+ m_pVertexNormals(nullptr),
+ m_pFaceNormals(nullptr),
+ m_pTangents(nullptr),
+
+ m_pIndices(nullptr),
+ m_pTexCoords(nullptr)
+ {}
+
+ void Allocate(NvUInt32 numVertices, NvUInt32 numTriangles);
+ void Release();
+
+ void UpdateNormal(bool updateVertexNormal = false);
+};
+
+////////////////////////////////////////////////////////////////////////////////////////
+#define MATERIAL_NAME_SIZE 128
+
+struct CORELIB_EXPORT MeshMaterial
+{
+ NvChar m_name[MATERIAL_NAME_SIZE];
+
+ atcore_float3 m_ambientColor;
+ float m_ambientFactor;
+
+ atcore_float3 m_diffuseColor;
+ float m_diffuseFactor;
+
+ float m_specularFactor;
+ float m_shininess;
+
+ NvChar m_diffuseTexture[MATERIAL_NAME_SIZE];
+ NvChar m_specularTexture[MATERIAL_NAME_SIZE];
+ NvChar m_bumpTexture[MATERIAL_NAME_SIZE];
+ NvChar m_normalTexture[MATERIAL_NAME_SIZE];
+ NvChar m_transparentTexture[MATERIAL_NAME_SIZE];
+
+public:
+ MeshMaterial()
+ {}
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.cpp b/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.cpp
new file mode 100644
index 0000000..97ba7d8
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.cpp
@@ -0,0 +1,1023 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// This file contains wrapper functions to make hair lib easy to setup and use
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#include "fbxsdk.h"
+#include <vector>
+#include <string>
+
+#include "FbxUtil.h"
+#include "MathUtil.h"
+
+//#include <Nv/Blast/NvHairSdk.h>
+
+// local functions used only in this file
+namespace {
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Get the geometry offset to a node. It is never inherited by the children.
+ FbxAMatrix GetGeometry(FbxNode* pNode)
+ {
+ const FbxVector4 lT = pNode->GetGeometricTranslation(FbxNode::eSourcePivot);
+ const FbxVector4 lR = pNode->GetGeometricRotation(FbxNode::eSourcePivot);
+ const FbxVector4 lS = pNode->GetGeometricScaling(FbxNode::eSourcePivot);
+
+ return FbxAMatrix(lT, lR, lS);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ void convertFromFbxMatrix(atcore_float4x4& transform, FbxAMatrix& tmatrix)
+ {
+ float* data = (float*)&transform;
+
+ // update skinning matrix
+ for (int row = 0; row < 4; row++)
+ for (int col = 0; col < 4; col++)
+ {
+ data[ row * 4 + col] = float(tmatrix.Get(row,col));
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ bool checkMesh(FbxNode* pNode)
+ {
+ FbxMesh* pMesh = pNode->GetMesh();
+ if (!pMesh)
+ return false;
+
+ return true;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ bool checkSkinned(FbxNode* pNode)
+ {
+ FbxGeometry* pFbxGeometry = pNode->GetGeometry();
+ if (!pFbxGeometry)
+ return false;
+
+ FbxSkin* pFbxSkin = (FbxSkin*)pFbxGeometry->GetDeformer(0, FbxDeformer::eSkin);
+ if (!pFbxSkin)
+ return false;
+
+ return true;
+ }
+}
+
+namespace
+{
+ FbxManager* s_FbxManager = nullptr;
+ FbxScene* s_FbxScene = nullptr;
+
+
+ /////////////////////////////////////////////////////////////////////////////
+ // find node by name
+ FbxNode*
+ FindNodeByName(FbxScene* scene, const char* nodeName)
+ {
+ if (!scene)
+ return 0;
+
+ if (!nodeName)
+ return 0;
+
+ for (int i = 0; i < scene->GetNodeCount(); i++)
+ {
+ FbxNode* node = scene->GetNode(i);
+ const char* name = node->GetName();
+ if (!strcmp(nodeName, name))
+ return node;
+ }
+ return 0;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool
+FbxUtil::Release(void)
+{
+ if (s_FbxScene)
+ {
+ s_FbxScene->Destroy();
+ s_FbxScene = nullptr;
+ }
+
+ if (s_FbxManager)
+ {
+ s_FbxManager->Destroy();
+ s_FbxManager = nullptr;
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool FbxUtil::Initialize(const char* fbxFileName, float sceneUnit)
+{
+ if (fbxFileName)
+ {
+ FbxImporter* s_FbxImporter = nullptr;
+
+ if (!s_FbxManager)
+ s_FbxManager = FbxManager::Create();
+
+ if (!s_FbxImporter)
+ s_FbxImporter = FbxImporter::Create(s_FbxManager, "");
+
+ if (!s_FbxScene)
+ s_FbxScene = FbxScene::Create(s_FbxManager, "");
+
+ if (!s_FbxImporter->Initialize(fbxFileName, -1))
+ return false;
+
+ if (!s_FbxImporter->Import(s_FbxScene))
+ return false;
+
+ FbxGlobalSettings& settings = s_FbxScene->GetGlobalSettings();
+
+ FbxSystemUnit fbxUnit = settings.GetSystemUnit();
+
+ if ((sceneUnit > 0.0f) && (sceneUnit != fbxUnit.GetScaleFactor()))
+ {
+ FbxSystemUnit convertUnit(sceneUnit);
+ convertUnit.ConvertScene(s_FbxScene);
+ }
+
+ s_FbxImporter->Destroy();
+
+ // get time info
+ FbxTimeSpan timespan;
+ settings.GetTimelineDefaultTimeSpan(timespan);
+
+ FbxTime startTime = timespan.GetStart();
+ FbxTime endTime = timespan.GetStop();
+
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool FbxUtil::GetGlobalSettings(float* pStartFrame, float* pEndFrame, float *pFps, int *upAxis, char* rootBoneName)
+{
+ return false;
+
+ /*
+ if ( !s_FbxScene)
+ return false;
+
+ FbxGlobalSettings& settings = s_FbxScene->GetGlobalSettings();
+
+ FbxTimeSpan timespan;
+ settings.GetTimelineDefaultTimeSpan(timespan);
+
+ FbxTime startTime = timespan.GetStart();
+ FbxTime endTime = timespan.GetStop();
+
+ if (pStartFrame)
+ *pStartFrame = (float)startTime.GetFrameCount();
+
+ if (pEndFrame)
+ *pEndFrame = (float)endTime.GetFrameCount();
+
+ if (pFps)
+ *pFps = (float)endTime.GetFrameRate(FbxTime::GetGlobalTimeMode());
+
+ if (upAxis)
+ {
+ int upSign = 0;
+ FbxAxisSystem axisSystem = settings.GetAxisSystem();
+ FbxAxisSystem::EUpVector upVector = axisSystem.GetUpVector(upSign);
+
+ enum FbxAxisSystem::ECoordSystem coordSystem = axisSystem.GetCoorSystem();
+
+ switch (upVector)
+ {
+ case FbxAxisSystem::eXAxis: *upAxis = 0; break;
+ case FbxAxisSystem::eYAxis: *upAxis = 1; break;
+ case FbxAxisSystem::eZAxis: *upAxis = 2; break;
+ }
+ }
+
+ if (rootBoneName)
+ {
+ FbxNode* pRoot = s_FbxScene->GetRootNode();
+ if (pRoot)
+ {
+ strncpy(rootBoneName, pRoot->GetName(), NV_HAIR_MAX_STRING);
+ }
+ else
+ strcpy(rootBoneName, "");
+ }
+
+ return true;
+ */
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+bool
+FbxUtil::InitializeAnimationCache(AnimationCache& animCache)
+{
+ return false;
+
+ /*
+ if (!s_FbxScene)
+ return false;
+
+ float startFrame, endFrame, fps;
+ FbxUtil::GetGlobalSettings(&startFrame, &endFrame, &fps);
+
+ int numNodes = s_FbxScene->GetNodeCount();
+
+ ////////////////////////////////////////////
+ animCache.Initialize(numNodes, (NvInt32)startFrame, (NvInt32)endFrame);
+
+ for (int i = 0; i < numNodes; i++)
+ {
+ FbxNode* node = s_FbxScene->GetNode(i);
+ const char* nodeName = node->GetName();
+ animCache.SetBoneName(i, nodeName);
+ }
+
+ ////////////////////////////////////////////
+ for (NvInt frame = animCache.m_frameStart; frame <= animCache.m_frameEnd; frame++)
+ {
+ FbxTime lTime;
+ lTime.SetSecondDouble( frame / fps);
+
+ int index = frame - animCache.m_frameStart;
+ atcore_float4x4 *pNodeMatrices = animCache.GetNodeMatrices(index);
+
+ for (int i = 0; i < numNodes; i++)
+ {
+ FbxNode* node = s_FbxScene->GetNode(i);
+ FbxAMatrix nodeMatrix = node->EvaluateGlobalTransform(lTime);
+ convertFromFbxMatrix(pNodeMatrices[i], nodeMatrix);
+ }
+ }
+
+ return true;
+ */
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+static FbxSkin* GetFbxSkin( FbxNode* pFbxNode )
+{
+ if (!pFbxNode)
+ return 0;
+
+ FbxMesh* pFbxMesh = pFbxNode->GetMesh();
+ if (!pFbxMesh)
+ return 0;
+
+ FbxGeometry* pFbxGeometry = pFbxNode->GetGeometry();
+ if (!pFbxGeometry)
+ return 0;
+
+ int deformerCount = pFbxGeometry->GetDeformerCount(FbxDeformer::eSkin);
+
+ FbxSkin *pFbxSkin = 0;
+ if (deformerCount > 0)
+ pFbxSkin = (FbxSkin*)pFbxGeometry->GetDeformer(0, FbxDeformer::eSkin);
+
+ return pFbxSkin;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+static int GetNumMeshPoints( FbxNode* pFbxNode)
+{
+ if (!pFbxNode)
+ return 0;
+
+ FbxMesh* pFbxMesh = pFbxNode->GetMesh();
+ if (!pFbxMesh)
+ return 0;
+
+ return pFbxMesh->GetControlPointsCount();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+static bool GetBoneData(FbxSkin *pFbxSkin, FbxNode* pFbxNode, NvChar* pBoneNames, atcore_float4x4 *pBindPoses)
+{
+ return false;
+
+ /*
+ if (!pFbxSkin || !pFbxNode)
+ return false;
+
+ int numBones = (int)pFbxSkin->GetClusterCount();
+
+ for (int i = 0; i < numBones; i++)
+ {
+ FbxCluster* pFbxCluster = pFbxSkin->GetCluster(i);
+
+ FbxNode* pLink = pFbxCluster->GetLink();
+
+ // copy bone names
+ const char* boneName = pLink->GetName();
+ char* str = pBoneNames + i * NV_HAIR_MAX_STRING;
+ strcpy_s(str, NV_HAIR_MAX_STRING, boneName);
+
+ // write pose matrix
+ {
+ FbxAMatrix lReferenceGlobalInitPosition;
+ pFbxCluster->GetTransformMatrix(lReferenceGlobalInitPosition);
+
+ FbxAMatrix lReferenceGeometry = GetGeometry(pFbxNode);
+ lReferenceGlobalInitPosition *= lReferenceGeometry;
+
+ FbxAMatrix lClusterGlobalInitPosition;
+ pFbxCluster->GetTransformLinkMatrix(lClusterGlobalInitPosition);
+
+ FbxAMatrix lClusterMatrix = lClusterGlobalInitPosition.Inverse() * lReferenceGlobalInitPosition;
+ convertFromFbxMatrix(pBindPoses[i], lClusterMatrix.Inverse());
+ }
+ }
+ return true;
+ */
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+static bool GetSkinningWeights(FbxSkin* pFbxSkin, atcore_float4* boneIndices, atcore_float4* boneWeights, int numPoints)
+{
+ int numClusters = (int)pFbxSkin->GetClusterCount();
+ if (numClusters == 0)
+ return false;
+
+ // copy skinning weights and indices
+ int* pIndexCounts = new int[numPoints];
+ memset(pIndexCounts, 0, sizeof(int) * numPoints);
+
+ for (int i = 0; i < numClusters; i++)
+ {
+ if (!pFbxSkin) continue;
+
+ FbxCluster* pFbxCluster = pFbxSkin->GetCluster(i);
+
+ if (!pFbxCluster) continue;
+
+ int cpCount = pFbxCluster->GetControlPointIndicesCount();
+ int* pPointIndices = pFbxCluster->GetControlPointIndices();
+ double* pWeights = pFbxCluster->GetControlPointWeights();
+
+ for (int j = 0; j < cpCount; j++)
+ {
+ if (pWeights[j] == 0.0f)
+ continue;
+
+ int pointIndex = pPointIndices[j];
+ int& cnt = pIndexCounts[pointIndex];
+
+ float* pBoneIndex = (float*)&boneIndices[pointIndex];
+ float* pBoneWeights = (float*)&boneWeights[pointIndex];
+
+ if (cnt < 4)
+ {
+ pBoneIndex[cnt] = float(i);
+ pBoneWeights[cnt] = float(pWeights[j]);
+ cnt++;
+ }
+ else // over 4, so we just bind to largest weights
+ {
+ float minWeight = (float)pWeights[j];
+ int minIndex = -1;
+ for (int b = 0; b < 4; b++)
+ {
+ float w = pBoneWeights[b];
+
+ if (w < minWeight)
+ {
+ minWeight = w;
+ minIndex = b;
+ }
+ }
+
+ if (minIndex >= 0)
+ {
+ pBoneIndex[minIndex] = float(i);
+ pBoneWeights[minIndex] = float(pWeights[j]);
+ }
+
+ cnt++;
+ }
+ }
+ }
+
+ for (int i = 0; i < numPoints; i++)
+ {
+ float* pBoneWeights = (float*)&boneWeights[i];
+
+ float weightsum = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ weightsum += pBoneWeights[i];
+ }
+
+ if (weightsum == 0)
+ continue;
+
+ for (int i = 0; i < 4; i++)
+ pBoneWeights[i] /= weightsum;
+ }
+
+ if (pIndexCounts) delete []pIndexCounts;
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+bool FbxUtil::InitializeSkinData( const char* meshName, SkinData& skinData)
+{
+ return false;
+
+ /*
+ FbxNode* pFbxNode = FindNodeByName(s_FbxScene, meshName);
+ if (!pFbxNode)
+ return false;
+
+ FbxSkin* pFbxSkin = GetFbxSkin(pFbxNode);
+ int numPoints = GetNumMeshPoints(pFbxNode);
+
+ BoneData& boneData = skinData.m_boneData;
+
+ if (pFbxSkin)
+ {
+ int numBones = (int)pFbxSkin->GetClusterCount();
+ skinData.Allocate(numBones, numPoints);
+
+ // get bone data (bind pose, bone names, ..)
+ GetBoneData(pFbxSkin, pFbxNode, boneData.m_pBoneNames, boneData.m_pPoseMatrices);
+
+ // get skinning weights
+ atcore_float4* boneIndices = skinData.m_pBoneIndices;
+ atcore_float4* boneWeights = skinData.m_pBoneWeights;
+
+ GetSkinningWeights(pFbxSkin, boneIndices, boneWeights, numPoints);
+ }
+ else // no skinning, use model matrix
+ {
+ int numBones = 1;
+
+ skinData.Allocate(numBones, numPoints);
+
+ // copy bone name
+ const char* boneName = pFbxNode->GetName();
+ boneData.setBoneName(0, boneName);
+
+ // make pose matrix
+ gfsdk_makeIdentity(boneData.m_pPoseMatrices[0]);
+
+ // all the vertices map to the model matrix
+ atcore_float4* boneIndices = skinData.m_pBoneIndices;
+ atcore_float4* boneWeights = skinData.m_pBoneWeights;
+
+ for (int i = 0; i < numPoints; i++)
+ {
+ boneIndices[i] = gfsdk_makeFloat4(0, 0, 0, 0);
+ boneWeights[i] = gfsdk_makeFloat4(1, 0, 0, 0);
+ }
+ }
+
+ return true;
+ */
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool FbxUtil::GetMeshInfo(int* numMeshes, char** meshNames, char** skinned)
+{
+ int cnt = 0;
+
+ for (int i = 0; i < s_FbxScene->GetNodeCount(); i++)
+ {
+ FbxNode* pNode = s_FbxScene->GetNode(i);
+ if (checkMesh(pNode))
+ cnt++;
+ }
+
+ char *pNameBuffer = new char[cnt * 128];
+ char *pSkinnedBuffer = new char[cnt];
+
+ cnt = 0;
+ for (int i = 0; i < s_FbxScene->GetNodeCount(); i++)
+ {
+ FbxNode* pNode = s_FbxScene->GetNode(i);
+
+ if (!checkMesh(pNode))
+ continue;
+
+ strcpy(pNameBuffer + cnt * 128, pNode->GetName());
+
+ pSkinnedBuffer[cnt] = checkSkinned(pNode);
+
+ cnt++;
+ }
+
+ *numMeshes = cnt;
+ if (skinned)
+ {
+ *skinned = pSkinnedBuffer;
+ }
+ else
+ delete []pSkinnedBuffer;
+
+ *meshNames = pNameBuffer;
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool FbxUtil::GetMeshMaterials( const NvChar* meshName, int *numMaterials, MeshMaterial** materials)
+{
+ if (!s_FbxScene)
+ return false;
+
+ FbxNode* pNode = FindNodeByName(s_FbxScene, meshName);
+ if (!pNode)
+ return false;
+
+ int numMats = pNode->GetMaterialCount();
+
+ *materials = new MeshMaterial[numMats];
+
+ int matCnt = 0;
+
+ for (int i = 0; i < numMats; i++)
+ {
+ FbxSurfaceMaterial *mat = pNode->GetMaterial(i);
+ if (!mat) continue;
+ if (mat->GetUserDataPtr()) continue;
+
+ MeshMaterial& material = (*materials)[matCnt];
+
+ strcpy(material.m_name, mat->GetName());
+ strcpy(material.m_diffuseTexture, "");
+ strcpy(material.m_bumpTexture, "");
+ strcpy(material.m_transparentTexture, "");
+ strcpy(material.m_normalTexture, "");
+
+ (atcore_float3&)material.m_ambientColor = gfsdk_makeFloat3(1.0f, 1.0f, 1.0f);
+ (atcore_float3&)material.m_diffuseColor = gfsdk_makeFloat3(1.0f, 1.0f, 1.0f);
+
+ FbxProperty prop;
+ FbxProperty fact;
+ FbxDouble3 d3;
+
+ // get ambient
+ {
+ fact = mat->FindProperty(FbxSurfaceMaterial::sAmbientFactor);
+ material.m_ambientFactor = fact.IsValid() ? (float)fact.Get<FbxDouble>() : 0.1f;
+
+ prop = mat->FindProperty(FbxSurfaceMaterial::sAmbient);
+ if (prop.IsValid())
+ {
+ FbxDouble3 d3 = prop.Get<FbxDouble3>();
+ material.m_ambientColor = gfsdk_makeFloat3((float)d3[0], (float)d3[1], (float)d3[2]);
+ }
+ }
+
+ // get specular
+ {
+ fact = mat->FindProperty(FbxSurfaceMaterial::sSpecularFactor);
+ material.m_specularFactor = fact.IsValid() ? (float)fact.Get<FbxDouble>() : 0.1f;
+
+ fact = mat->FindProperty(FbxSurfaceMaterial::sShininess);
+ material.m_shininess = fact.IsValid() ? (float)fact.Get<FbxDouble>() : 20.0f;
+ }
+
+ // get diffuse
+ {
+ fact = mat->FindProperty(FbxSurfaceMaterial::sDiffuseFactor);
+ material.m_diffuseFactor = fact.IsValid() ? (float)fact.Get<FbxDouble>() : 0.5f;
+
+ prop = mat->FindProperty(FbxSurfaceMaterial::sDiffuse);
+ if (prop.IsValid())
+ {
+ FbxDouble3 d3 = prop.Get<FbxDouble3>();
+ material.m_diffuseColor = gfsdk_makeFloat3((float)d3[0], (float)d3[1], (float)d3[2]);
+
+ const FbxFileTexture* tex = prop.GetSrcObject<FbxFileTexture>();
+ if (tex)
+ strcpy(material.m_diffuseTexture, tex->GetFileName());
+ }
+ }
+
+ // get normal map
+ {
+ prop = mat->FindProperty(FbxSurfaceMaterial::sNormalMap);
+ if (prop.IsValid())
+ {
+ const FbxFileTexture* tex = prop.GetSrcObject<FbxFileTexture>();
+ if (tex)
+ strcpy(material.m_normalTexture, tex->GetFileName());
+ }
+ }
+
+ matCnt++;
+ }
+
+ *numMaterials = matCnt;
+
+ return true;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool FbxUtil::CreateMeshDescriptor(const char* meshName, MeshDesc &desc)
+{
+ if (!s_FbxScene)
+ return false;
+
+ FbxNode* pNode = FindNodeByName(s_FbxScene, meshName);
+ if (!pNode)
+ return false;
+
+ // read growth mesh data
+ FbxMesh* pMesh = pNode->GetMesh();
+ if (!pMesh)
+ return false;
+
+ int cpCount = pMesh->GetControlPointsCount();
+
+ int triCount = 0;
+ for (int i = 0; i < pMesh->GetPolygonCount(); i++)
+ {
+ int psize = pMesh->GetPolygonSize(i);
+ triCount += (psize - 2);
+ }
+
+ // allocate buffers
+ desc.Allocate(cpCount, triCount);
+
+ // read positions
+ FbxVector4* points = pMesh->GetControlPoints();
+ for (int i = 0; i < desc.m_NumVertices; i++)
+ desc.m_pVertices[i] = gfsdk_makeFloat3(float(points[i].mData[0]), float(points[i].mData[1]), float(points[i].mData[2]));
+
+ memset(desc.m_pTexCoords, 0, sizeof(atcore_float2) * desc.m_NumTriangles * 3);
+
+ // read uvs
+ FbxLayerElementUV* leUV = pMesh->GetLayer(0)->GetUVs();
+
+ FbxGeometryElementNormal *lNormals = pMesh->GetElementNormal();
+ FbxGeometryElementTangent* lTangents = pMesh->GetElementTangent();
+
+ int tcnt = 0;
+ int vertexBase = 0;
+ for (int i = 0; i < pMesh->GetPolygonCount(); i++)
+ {
+ int vcnt = pMesh->GetPolygonSize(i);
+ for (int j = 0; j < (vcnt-2); j++)
+ {
+ int pIndex[3] = { 0, j+1, j+2 };
+
+ // get polygon index
+ for (int p = 0; p < 3; ++p)
+ desc.m_pIndices[tcnt*3+p] = pMesh->GetPolygonVertex(i, pIndex[p]);
+
+ // get face normal
+ if (lNormals)
+ {
+ FbxLayerElement::EMappingMode mode = lNormals->GetMappingMode();
+
+ for (int p = 0; p < 3; ++p)
+ {
+ int vertexId = vertexBase + pIndex[p];
+ int normalId = vertexId;
+ if (mode == FbxGeometryElement::eByPolygonVertex)
+ {
+ if (lNormals->GetReferenceMode() == FbxGeometryElement::eIndexToDirect)
+ normalId = lNormals->GetIndexArray().GetAt(vertexId);
+ }
+ else if (mode == FbxGeometryElement::eByControlPoint)
+ normalId = pMesh->GetPolygonVertex(i, pIndex[p]);
+
+ const FbxVector4 &n = lNormals->GetDirectArray().GetAt(normalId);
+ desc.m_pVertexNormals[tcnt*3+p] = gfsdk_makeFloat3((float)n[0], (float)n[1], (float)n[2]);
+ }
+ }
+
+ // get face normal
+ if (lTangents)
+ {
+ FbxLayerElement::EMappingMode mode = lTangents->GetMappingMode();
+
+ for (int p = 0; p < 3; ++p)
+ {
+ int vertexId = vertexBase + pIndex[p];
+ int tangentId = vertexId;
+ if (mode == FbxGeometryElement::eByPolygonVertex)
+ {
+ if (lTangents->GetReferenceMode() == FbxGeometryElement::eIndexToDirect)
+ tangentId = lTangents->GetIndexArray().GetAt(vertexId);
+ }
+ else if (mode == FbxGeometryElement::eByControlPoint)
+ tangentId = pMesh->GetPolygonVertex(i, pIndex[p]);
+
+ const FbxVector4 &n = lTangents->GetDirectArray().GetAt(tangentId);
+ desc.m_pTangents[tcnt*3+p] = gfsdk_makeFloat3((float)n[0], (float)n[1], (float)n[2]);
+ }
+ }
+
+ if (leUV)
+ {
+ int i0 = pMesh->GetTextureUVIndex(i, 0);
+ int i1 = pMesh->GetTextureUVIndex(i, j+1);
+ int i2 = pMesh->GetTextureUVIndex(i, j+2);
+
+ FbxVector2 texCoord0 = leUV->GetDirectArray().GetAt(i0);
+ FbxVector2 texCoord1 = leUV->GetDirectArray().GetAt(i1);
+ FbxVector2 texCoord2 = leUV->GetDirectArray().GetAt(i2);
+
+ desc.m_pTexCoords[tcnt*3+0] = gfsdk_makeFloat2(1.0f * float(texCoord0[0]), 1.0f - float(texCoord0[1]));
+ desc.m_pTexCoords[tcnt*3+1] = gfsdk_makeFloat2(1.0f * float(texCoord1[0]), 1.0f - float(texCoord1[1]));
+ desc.m_pTexCoords[tcnt*3+2] = gfsdk_makeFloat2(1.0f * float(texCoord2[0]), 1.0f - float(texCoord2[1]));
+ }
+
+ tcnt++;
+ }
+ vertexBase += vcnt;
+ }
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/*
+bool FbxUtil::CreateHairFromFbx(const char* guideName, const char* growthMeshName, NvHair::AssetDescriptor& hairAsset)
+{
+ if (!s_FbxScene)
+ return false;
+
+ // read growth mesh data
+ MeshDesc meshDesc;
+ if (false == FbxUtil::CreateMeshDescriptor(growthMeshName, meshDesc))
+ return false;
+
+ FbxNode* pHairNode = FindNodeByName(s_FbxScene, guideName);
+ if (!pHairNode)
+ return false;
+
+ FbxNode* pMeshNode = FindNodeByName(s_FbxScene, growthMeshName);
+ if (!pMeshNode)
+ return false;
+
+ FbxSkin* pFbxSkin = GetFbxSkin(pMeshNode);
+ int numBones = 1;
+
+ if (pFbxSkin)
+ numBones = (int)pFbxSkin->GetClusterCount();
+
+ // get skin data from mesh
+ int numPoints = meshDesc.m_NumVertices;
+
+ atcore_float4* pMeshBoneIndices = new atcore_float4[numPoints];
+ atcore_float4* pMeshBoneWeights = new atcore_float4[numPoints];
+
+ GetSkinningWeights(pFbxSkin, pMeshBoneIndices, pMeshBoneWeights, numPoints);
+
+ // create raw hair array
+ FbxLine* pLine = pHairNode->GetLine();
+ if (!pLine)
+ return false;
+
+ int cpCount = pLine->GetControlPointsCount();
+ int curveCount = pLine->GetEndPointCount();
+
+ atcore_float3* pVertices = new atcore_float3[cpCount];
+ NvUInt32* pEndIndices = new NvUInt32[curveCount];
+
+ FbxVector4* pFbxPoints = pLine->GetControlPoints();
+ FbxArray<int>* pFbxEndIndices = pLine->GetEndPointArray();
+
+ for (int i = 0; i < cpCount; i++)
+ pVertices[i] = gfsdk_makeFloat3(float(pFbxPoints[i][0]), float(pFbxPoints[i][1]), float(pFbxPoints[i][2]));
+
+ for (int i = 0; i < curveCount; i++)
+ pEndIndices[i] = (*pFbxEndIndices)[i];
+
+ // check against closest growth mesh points
+ const float distThreshold = 25.0;
+
+ int numValidHairs = 0;
+ int numValidHairVertices = 0;
+
+ int* pMeshToHairMap = new int[meshDesc.m_NumVertices];
+ int* pHairToMeshMap = new int[curveCount];
+ int* pHairToHairMap = new int[curveCount];
+ float* pMinDistances = new float[meshDesc.m_NumVertices];
+ atcore_float3* pRootVertices = new atcore_float3[curveCount];
+ atcore_float3* pTriangleCenters = new atcore_float3[meshDesc.m_NumTriangles];
+
+ // initialize triangle centers
+ for (int i = 0; i < meshDesc.m_NumTriangles; i++)
+ {
+ NvUInt32 v0 = meshDesc.m_pIndices[i*3 + 0];
+ NvUInt32 v1 = meshDesc.m_pIndices[i * 3 + 1];
+ NvUInt32 v2 = meshDesc.m_pIndices[i * 3 + 2];
+
+ atcore_float3 p0 = meshDesc.m_pVertices[v0];
+ atcore_float3 p1 = meshDesc.m_pVertices[v1];
+ atcore_float3 p2 = meshDesc.m_pVertices[v2];
+
+ pTriangleCenters[i] = 1.0f / 3.0f * (p0 + p1 + p2);
+ }
+
+ // initialize mesh to hair map
+ for (int i = 0; i < meshDesc.m_NumVertices; i++)
+ {
+ pMeshToHairMap[i] = -1;
+ pMinDistances[i] = FLT_MAX;
+ }
+
+ // copy root vertices of input hairs
+
+ for (int i = 0; i < curveCount; i++)
+ {
+ int root = (i == 0) ? 0 : pEndIndices[i-1]+1;
+ pRootVertices[i] = pVertices[root];
+ pHairToMeshMap[i] = -1;
+ }
+
+ // for each input hair curve, find the closest mesh vertex
+ for (int i = 0; i < curveCount; i++)
+ {
+ atcore_float3 hp = pRootVertices[i];
+
+ float minDist = FLT_MAX;
+ int closestTriangle = -1;
+ for (int j = 0; j < meshDesc.m_NumTriangles; j++)
+ {
+ atcore_float3 c = pTriangleCenters[j];
+
+ float distSquared = gfsdk_lengthSquared(hp - c);
+ if (distSquared < minDist)
+ {
+ minDist = distSquared;
+ closestTriangle = j;
+ }
+ }
+
+ if (closestTriangle >= 0)
+ {
+ for (int k = 0; k < 3; k++)
+ {
+ NvUInt32 v = meshDesc.m_pIndices[closestTriangle * 3 + k];
+ atcore_float3 p = meshDesc.m_pVertices[v];
+
+ float distSquared = gfsdk_lengthSquared(hp - p);
+ if (distSquared < pMinDistances[v])
+ {
+ pMinDistances[v] = distSquared;
+ pMeshToHairMap[v] = i;
+ }
+ }
+ }
+ }
+
+ // prepare mapping from new hair set to mesh and old hairs
+ for (int i = 0; i < meshDesc.m_NumVertices; i++)
+ {
+ int closestHair = pMeshToHairMap[i];
+ if (closestHair < 0)
+ continue;
+
+ pHairToMeshMap[numValidHairs] = i;
+ pHairToHairMap[numValidHairs] = closestHair;
+ pMeshToHairMap[i] = numValidHairs; // update hair with new hair index
+
+ int root = (closestHair == 0) ? 0 : pEndIndices[closestHair-1]+1;
+ int tip = pEndIndices[closestHair];
+
+ numValidHairVertices += (tip - root + 1);
+ numValidHairs++;
+ }
+
+ // allocate new hairs
+ hairAsset.m_numGuideHairs = numValidHairs;
+ hairAsset.m_numVertices = numValidHairVertices;
+
+ hairAsset.m_boneIndices = new atcore_float4[hairAsset.m_numGuideHairs];
+ hairAsset.m_boneWeights = new atcore_float4[hairAsset.m_numGuideHairs];
+
+ hairAsset.m_vertices = new atcore_float3[hairAsset.m_numVertices];
+ hairAsset.m_endIndices = new NvUInt32[hairAsset.m_numGuideHairs];
+ hairAsset.m_faceIndices = new NvUInt32[meshDesc.m_NumTriangles * 3];
+ hairAsset.m_faceUvs = new atcore_float2[meshDesc.m_NumTriangles * 3];
+
+ hairAsset.m_numBones = numBones;
+ hairAsset.m_boneNames = new NvChar[NV_HAIR_MAX_STRING * hairAsset.m_numBones];
+ hairAsset.m_bindPoses = new atcore_float4x4[hairAsset.m_numBones];
+ hairAsset.m_boneParents = new NvInt32[hairAsset.m_numBones];
+
+ if (pFbxSkin)
+ GetBoneData(pFbxSkin, pMeshNode, hairAsset.m_boneNames, hairAsset.m_bindPoses);
+ else
+ {
+ strcpy(hairAsset.m_boneNames, "Root");
+ gfsdk_makeIdentity(hairAsset.m_bindPoses[0]);
+ hairAsset.m_boneParents[0] = -1;
+ }
+
+ // copy vertex data
+ int vertexCnt = 0;
+
+ for (int i = 0; i < hairAsset.m_numGuideHairs; i++)
+ {
+ int oldHair = pHairToHairMap[i];
+
+ int oldRoot = (oldHair == 0) ? 0 : pEndIndices[oldHair-1]+1;
+ int oldTip = pEndIndices[oldHair];
+
+ int offset = oldTip - oldRoot;
+
+ int newRoot = vertexCnt;
+ int newTip = vertexCnt + offset;
+
+ vertexCnt += (offset + 1);
+
+ hairAsset.m_endIndices[i] = newTip;
+
+ int meshVertex = pHairToMeshMap[i];
+ atcore_float3 meshRoot = meshDesc.m_pVertices[meshVertex];
+ atcore_float3 hairRoot = pVertices[oldRoot];
+
+ atcore_float3 rootOffset = meshRoot - hairRoot;
+
+ for (int j = 0; j <= offset; j++)
+ hairAsset.m_vertices[newRoot + j] = pVertices[oldRoot + j] + rootOffset;
+
+ hairAsset.m_boneIndices[i] = gfsdk_makeFloat4(0,0,0,0);
+ hairAsset.m_boneWeights[i] = gfsdk_makeFloat4(1,0,0,0);
+
+ if (pFbxSkin)
+ {
+ hairAsset.m_boneIndices[i] = pMeshBoneIndices[meshVertex];
+ hairAsset.m_boneWeights[i] = pMeshBoneWeights[meshVertex];
+ }
+ }
+
+ // copy face indices and texture uvs
+ int faceCnt = 0;
+ for (int i = 0; i < meshDesc.m_NumTriangles; i++)
+ {
+ NvUInt32 i0 = meshDesc.m_pIndices[i * 3 + 0];
+ NvUInt32 i1 = meshDesc.m_pIndices[i * 3 + 1];
+ NvUInt32 i2 = meshDesc.m_pIndices[i * 3 + 2];
+
+ int h0 = pMeshToHairMap[i0];
+ int h1 = pMeshToHairMap[i1];
+ int h2 = pMeshToHairMap[i2];
+
+ if ((h0 < 0) || (h1 < 0) || (h2 < 0))
+ continue; // invalid face
+
+ hairAsset.m_faceIndices[ faceCnt * 3 + 0] = h0;
+ hairAsset.m_faceIndices[ faceCnt * 3 + 1] = h1;
+ hairAsset.m_faceIndices[ faceCnt * 3 + 2] = h2;
+
+ hairAsset.m_faceUvs[ faceCnt * 3 + 0 ] = meshDesc.m_pTexCoords[i * 3 + 0];
+ hairAsset.m_faceUvs[ faceCnt * 3 + 1 ] = meshDesc.m_pTexCoords[i * 3 + 1];
+ hairAsset.m_faceUvs[ faceCnt * 3 + 2 ] = meshDesc.m_pTexCoords[i * 3 + 2];
+
+ faceCnt++;
+ }
+
+ hairAsset.m_numFaces = faceCnt;
+
+ delete []pMeshBoneIndices;
+ delete []pMeshBoneWeights;
+
+ delete []pMeshToHairMap;
+ delete []pHairToMeshMap;
+ delete []pHairToHairMap;
+
+ return true;
+}
+*/
diff --git a/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.h b/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.h
new file mode 100644
index 0000000..26e61a9
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.h
@@ -0,0 +1,64 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#pragma once
+
+#include "AnimUtil.h"
+
+//#include <Nv/Blast/NvHairSdk.h>
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Helper for fbx file load
+class CORELIB_EXPORT FbxUtil
+{
+public:
+
+ /// initialize fbx loader.
+ static bool Initialize(const nvidia::Char* fbxFileName, nvidia::Float sceneUnit = 0.0f);
+ static bool Release(void);
+
+ static bool InitializeAnimationCache(AnimationCache& cache);
+
+ /// Get global frame range and fps information from fbx.
+ static bool GetGlobalSettings(nvidia::Float32* pStarfFrame = 0, nvidia::Float32* pEndFrame = 0, nvidia::Float32 *pFps = 0, int* upAxis = 0, char* rootBoneName = 0);
+
+ /// get skinning data from the mesh node
+ static bool InitializeSkinData( const nvidia::Char* meshName, SkinData& pSkinningDataToUpdate);
+
+ /// create mesh descriptor from fbx mesh node
+ static bool CreateMeshDescriptor(const nvidia::Char* meshName, MeshDesc &meshDesc);
+
+ /// get all the renderable meshes from the fbx scene
+ static bool GetMeshInfo(int* numMeshes, char** meshNames, char** skinned = 0);
+
+ /// get mesh material info from fbx scene
+ static bool GetMeshMaterials(const nvidia::Char* meshName, int *numMaterials, MeshMaterial** materials);
+
+ /// get hair directly from fbx
+// static bool CreateHairFromFbx(const char* guideName, const char* growthMeshName, NvHair::AssetDescriptor &hairAsset);
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Backdoor/backdoor.cpp b/tools/ArtistTools/source/CoreLib/Backdoor/backdoor.cpp
new file mode 100644
index 0000000..222debd
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Backdoor/backdoor.cpp
@@ -0,0 +1,263 @@
+#include "backdoor.h"
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <Windows.h>
+#include "Nv.h"
+
+namespace BACKDOOR
+{
+
+ struct Header
+ {
+ int mCount;
+ int mType;
+ };
+
+#define MAX_BACKDOOR_PACKET 1024 // maximum size of a send/receive packet
+#define HEADER_SIZE (sizeof(Header))
+#define DATA_SIZE (MAX_BACKDOOR_PACKET - HEADER_SIZE)
+#define STRING_SIZE (DATA_SIZE - 1)
+#define MAX_ARGS 32
+#pragma warning(disable:4996)
+
+ // Chagne this helper class to use the memory mapped IO API relevant to your system.
+ // This implementation uses the Windows API for a memory mapped shared file system.
+ class MemoryMappedFile
+ {
+ public:
+
+ MemoryMappedFile(const char *mappingObject,unsigned int mapSize);
+ ~MemoryMappedFile(void);
+ void * getBaseAddress(void);
+ private:
+ class MemoryMappedFileImpl *mImpl;
+ };
+
+
+ class MemoryMappedFileImpl
+ {
+ public:
+ HANDLE mMapFile;
+ void * mHeader;
+ };
+
+ MemoryMappedFile::MemoryMappedFile(const char *mappingObject,unsigned int mapSize)
+ {
+ mImpl = (MemoryMappedFileImpl *)::malloc(sizeof(MemoryMappedFileImpl));
+ mImpl->mHeader = NV_NULL;
+ mImpl->mMapFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS,FALSE,mappingObject);
+ if ( mImpl->mMapFile == NV_NULL )
+ {
+ mImpl->mMapFile = CreateFileMappingA(
+ INVALID_HANDLE_VALUE, // use paging file
+ NV_NULL, // default security
+ PAGE_READWRITE, // read/write access
+ 0, // maximum object size (high-order DWORD)
+ mapSize, // maximum object size (low-order DWORD)
+ mappingObject);
+ }
+ if ( mImpl->mMapFile )
+ {
+ mImpl->mHeader = MapViewOfFile(mImpl->mMapFile,FILE_MAP_ALL_ACCESS,0,0,mapSize);
+ }
+
+ }
+
+ MemoryMappedFile::~MemoryMappedFile(void)
+ {
+
+ if ( mImpl->mHeader )
+ {
+ UnmapViewOfFile(mImpl->mHeader);
+ if ( mImpl->mMapFile )
+ {
+ CloseHandle(mImpl->mMapFile);
+ }
+ }
+
+ ::free(mImpl);
+ }
+
+ void * MemoryMappedFile::getBaseAddress(void)
+ {
+ return mImpl->mHeader;
+ }
+
+
+
+class _Backdoor : public Backdoor
+{
+ MemoryMappedFile *mReceiveFile;
+ MemoryMappedFile *mSendFile;
+ const char *mArgv[MAX_ARGS];
+ char mBuffer[MAX_BACKDOOR_PACKET];
+
+ int mSendCount;
+ int mReceiveCount;
+
+public:
+ _Backdoor(const char *sendName, // The name of the shared memory file to act as the 'sender' stream.
+ const char *receiveName) // The name of the shared memory file to act as the 'receive' message stream.
+ {
+ mSendCount = 0; // This is a semaphore used to signal when a new message has been sent.
+ mReceiveCount = 0; // This is a semaphore used to detect if a new message has been received.
+ mReceiveFile = new MemoryMappedFile(receiveName,MAX_BACKDOOR_PACKET); // Open the receive stream file
+ mSendFile = new MemoryMappedFile(sendName,MAX_BACKDOOR_PACKET); // Open the send stream file
+ }
+
+ virtual ~_Backdoor(void)
+ {
+ delete mReceiveFile; // Close the receive stream file
+ delete mSendFile; // Close the send stream file.
+ }
+
+ virtual void send(const char *fmt,...)
+ {
+ char wbuff[DATA_SIZE];
+ wbuff[STRING_SIZE] = 0;
+ _vsnprintf(wbuff,STRING_SIZE, fmt, (char *)(&fmt+1));
+
+ mSendCount++; // Increment the send counter.
+ size_t len = strlen(wbuff);
+
+ if ( len < STRING_SIZE && mSendFile )
+ {
+ char *baseAddress = (char *)mSendFile->getBaseAddress(); // get the base address of the shared memory
+ int *dest = (int *)baseAddress;
+
+ baseAddress+=sizeof(Header);
+
+ memcpy(baseAddress,wbuff,len+1); // First copy the message.
+ *dest = mSendCount; // Now revised the send count semaphore so the other process knows there is a new message to processs.
+ }
+ }
+
+ virtual const char **getInput(int &argc)
+ {
+ const char **ret = NV_NULL;
+ argc = 0;
+
+ if ( mReceiveFile )
+ {
+ const char *baseAddress = (const char *)mReceiveFile->getBaseAddress();
+ const int *source = (const int *)baseAddress;
+ baseAddress+=sizeof(Header);
+ if ( *source != mReceiveCount )
+ {
+ mReceiveCount = *source;
+ memcpy(mBuffer,baseAddress,DATA_SIZE);
+
+ char *scan = mBuffer;
+ while ( *scan == 32 ) scan++; // skip leading spaces
+ if ( *scan ) // if not EOS
+ {
+ argc = 1;
+ mArgv[0] = scan; // set the first argument
+
+ while ( *scan && argc < MAX_ARGS) // while still data and we haven't exceeded the maximum argument count.
+ {
+ while ( *scan && *scan != 32 ) scan++; // scan forward to the next space
+ if ( *scan == 32 ) // if we hit a space
+ {
+ *scan = 0; // null-terminate the argument
+ scan++; // skip to the next character
+ while ( *scan == 32 ) scan++; // skip any leading spaces
+ if ( *scan ) // if there is still a valid non-space character process that as the next argument
+ {
+ mArgv[argc] = scan;
+ argc++;
+ }
+ }
+ }
+ ret = mArgv;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+ bool sendData(char* ptr, size_t size, int dataType)
+ {
+ if ( size > DATA_SIZE || !mSendFile )
+ return false;
+
+ mSendCount++; // Increment the send counter.
+
+ char *baseAddress = (char *)mSendFile->getBaseAddress(); // get the base address of the shared memory
+
+ Header* header = (Header*)baseAddress;
+
+ header->mCount = mSendCount;
+ header->mType = dataType;
+
+ baseAddress+=sizeof(Header);
+ memcpy(baseAddress,ptr, size);
+
+ return true;
+ }
+
+ bool receiveData(char* ptr, size_t size, int dataType)
+ {
+ if ( size > DATA_SIZE || !mReceiveFile )
+ return false;
+
+ const char *baseAddress = (const char *)mReceiveFile->getBaseAddress();
+ const int *source = (const int *)baseAddress;
+
+ Header* header = (Header*)baseAddress;
+ if (header->mType != dataType)
+ return false;
+
+ baseAddress+=sizeof(Header);
+
+ if ( *source != mReceiveCount )
+ {
+ mReceiveCount = *source;
+ memcpy(ptr, baseAddress, size);
+ }
+
+ return true;
+ }
+
+ bool checkMessage(const char* msg)
+ {
+ if (!mReceiveFile)
+ return false;
+
+ const char *baseAddress = (const char *)mReceiveFile->getBaseAddress();
+ const int *source = (const int *)baseAddress;
+
+ if (*source == mReceiveCount)
+ return false;
+
+ if ( *source != mReceiveCount )
+ {
+ baseAddress+=sizeof(Header);
+
+ return (!strcmp(baseAddress, msg));
+ }
+
+ return false;
+ }
+
+ virtual void release(void)
+ {
+ delete this;
+ }
+
+
+};
+
+}; // end of namespace
+
+using namespace BACKDOOR;
+
+
+Backdoor * createBackdoor(const char *sendName,const char *receiveName)
+{
+ _Backdoor *ret = new _Backdoor(sendName,receiveName);
+ return static_cast< Backdoor *>(ret);
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Backdoor/backdoor.h b/tools/ArtistTools/source/CoreLib/Backdoor/backdoor.h
new file mode 100644
index 0000000..a8ea1ac
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Backdoor/backdoor.h
@@ -0,0 +1,52 @@
+#ifndef BACKDOOR_H
+
+#define BACKDOOR_H
+
+// This is a tiny helper class that let's you easily perform communication using shared file memory between
+// two processes on the same machine. It is built to comple on Windows; but relatively minor changes
+// are necesary to make it work on other platforms; just change the memory mapped IO calls.
+//
+// This same technique would work as well if you simply opened a file on disk; though shared memory is much
+// faster.
+//
+// This is not meant to be some kind of sophisticated inter-process communciations class. Instead it's just
+// used for the very basic use case where you need to easily send simple 'commands' between two proceses.
+//
+// This code snippet comes with a console application which can be used to send commands to another process
+// and display received messaegs from that other process.
+//
+// Simply launch this console app with a command line argument indicating whether it is considered the 'server'
+// or the 'client'. You can test it by launching it twice; once as server and once as client and then send
+// chat messages back and forth.
+//
+// Written by John W. Ratcliff on February 10, 2013 and released into the public domain.
+//
+
+class Backdoor
+{
+public:
+
+ virtual void send(const char *str,...) = 0; // This sends a 'command' to the other process. Uses the printf style format for convenience.
+
+ // This method consumes an inomcing command from the other process and parses it into an argc/argv format.
+ virtual const char **getInput(int &argc) = 0;
+
+ virtual bool sendData(char* ptr, size_t size, int dataType) = 0;
+
+ virtual bool receiveData(char* ptr, size_t size, int dataType) = 0;
+
+ virtual bool checkMessage(const char* msg) = 0;
+
+ // This method releases the Backdoor interface class.
+ virtual void release(void) = 0;
+protected:
+ virtual ~Backdoor(void)
+ {
+ }
+};
+
+Backdoor * createBackdoor(const char *sendName,const char *receiveName);
+
+
+#endif
diff --git a/tools/ArtistTools/source/CoreLib/CoreLib.cpp b/tools/ArtistTools/source/CoreLib/CoreLib.cpp
new file mode 100644
index 0000000..b94b1d9
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/CoreLib.cpp
@@ -0,0 +1,1460 @@
+#include <QtWidgets/QApplication>
+#include <QtCore/QTimer>
+#include <QtCore/QFile>
+#include <QtCore/QDir>
+#include <QtWidgets/QMessageBox>
+#include <QtCore/QFileInfo>
+
+#include "Nv.h"
+
+#include "AppMainWindow.h"
+#include "D3DWidget.h"
+#include "SimpleScene.h"
+#include "Automate.h"
+#include "Settings.h"
+#include "RenderInterface.h"
+#include "GlobalSettings.h"
+
+#ifndef NV_ARTISTTOOLS
+#include "FurCharacter.h"
+#include "PluginBlast.h"
+#endif // NV_ARTISTTOOLS
+
+#include "RenderPlugin.h"
+
+void SetupStyles()
+{
+ //QFile styleFile( ":/AppMainWindow/ThemeDefault.qss" );
+ QString appPath = QCoreApplication::applicationDirPath();
+ QString themeFilePath = appPath + "/ArtistToolsTheme.qss";
+ QFile styleFile;
+ if (QFile::exists(themeFilePath))
+ {
+ styleFile.setFileName(themeFilePath);
+ }
+ else
+ {
+ styleFile.setFileName(":/AppMainWindow/ThemeDark.qss");
+ }
+ styleFile.open(QFile::ReadOnly);
+
+ QString styleSheet(styleFile.readAll());
+ QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false);
+ qApp->setStyleSheet(styleSheet);
+}
+
+int ShowErrorMsg(int errorCode)
+{
+ const char* errorMsg = 0;
+ switch (errorCode)
+ {
+ case 1:
+ errorMsg = "Fail to create GPU device and context. "
+ "Please make sure you are using an independant GPU and choose '3D App - Game Development' in the Global Settings page in its Control Panel.";
+ break;
+ case 2:
+ errorMsg = "Fail to initialize all the shared shaders, resources, etc. "
+ "Please make sure you are using an independant GPU and choose '3D App - Game Development' in the Global Settings page in its Control Panel.";
+ break;
+ case 3:
+ errorMsg = "Fail to create render window, target, swap chains, etc. "
+ "Please make sure you are using an independant GPU and choose '3D App - Game Development' in the Global Settings page in its Control Panel.";
+ break;
+ case 4:
+ // Unable to load/start the dll.
+ errorMsg = "Unable to load and/or start the Blast dll. "
+ "Please make sure the appropriate hairworks dll is the same directory as the viewer executable.";
+ break;
+ default:
+ errorMsg = "We need define one error message!";
+ }
+ QMessageBox messageBox;
+ messageBox.information(0, "Error", errorMsg);
+ return errorCode;
+}
+
+extern void CreateAppMainWindow();
+extern void ReleaseAppMainWindow();
+
+int RunApp(QApplication& app)
+{
+ CreateAppMainWindow();
+
+ // resolution
+ int windowWidth = 0;
+ int windowHeight = 0;
+ std::string resolution = AppSettings::Inst().GetOptionValue("User/Resolution")->Value.Enum;
+ int width, height;
+ sscanf(resolution.c_str(), "%dx%d", &windowWidth, &windowHeight);
+
+ // aa sample count
+ int sampleCount = 8;
+ if (stricmp(AppSettings::Inst().GetOptionValue("User/AA")->Value.Enum, "2X") == 0)
+ {
+ sampleCount = 2;
+ }
+ else if (stricmp(AppSettings::Inst().GetOptionValue("User/AA")->Value.Enum, "4X") == 0)
+ {
+ sampleCount = 4;
+ }
+ else if (stricmp(AppSettings::Inst().GetOptionValue("User/AA")->Value.Enum, "8X") == 0)
+ {
+ sampleCount = 8;
+ }
+ else if (stricmp(AppSettings::Inst().GetOptionValue("User/AA")->Value.Enum, "Off") == 0)
+ {
+ sampleCount = 1;
+ }
+
+ // device id
+ int deviceID = (AppSettings::Inst().GetOptionValue("User/Device")->Value.Int);
+ if (deviceID < 0 || deviceID > 3)
+ {
+ deviceID = -1; // when -1 to choose a good GPU
+ }
+
+ // backdoor connection mode
+ int backdoor = 0;
+ if (stricmp(AppSettings::Inst().GetOptionValue("User/Backdoor")->Value.String, "master") == 0)
+ {
+ backdoor = 1;
+ }
+ else if (stricmp(AppSettings::Inst().GetOptionValue("User/Backdoor")->Value.String, "slave") == 0)
+ {
+ backdoor = 2;
+ }
+
+ AppMainWindow::setConnectionMode(backdoor);
+
+ SimpleScene::Inst();
+#ifdef NV_ARTISTTOOLS
+ CoreLib::Inst()->SimpleScene_SimpleScene();
+#endif // NV_ARTISTTOOLS
+ // initialize main window
+ // HAIR-285 Viewer - new command line to start Viewer in full screen
+ AppMainWindow::Inst().InitUI();
+ if (windowWidth == 0)
+ AppMainWindow::Inst().showFullScreen();
+ else if (windowWidth<0)
+ AppMainWindow::Inst().showMaximized();
+ else
+ AppMainWindow::Inst().resize(windowWidth, windowHeight);
+
+ D3DWidget* d3dWidget = AppMainWindow::Inst().GetRenderWidget();
+
+ HWND hWidget = (HWND)d3dWidget->winId();
+
+ // create GPU device and context
+ if (false == RenderInterface::InitDevice(deviceID))
+ return ShowErrorMsg(1);
+
+ // initialize all the shared shaders, resources, etc
+ if (false == RenderInterface::Initialize())
+ return ShowErrorMsg(2);
+
+ // create render window, target, swap chains, etc.
+ if (false == RenderInterface::CreateRenderWindow(hWidget, sampleCount))
+ return ShowErrorMsg(3);
+
+ SimpleScene* scene = SimpleScene::Inst();
+ if (false == scene->Initialize(hWidget, backdoor))
+ return ShowErrorMsg(4);
+
+ GlobalSettings::Inst().setRenderFps(60);
+
+ GlobalSettings::GetFrameTimer().start();
+
+ QObject::connect(&GlobalSettings::GetFrameTimer(), SIGNAL(timeout()), d3dWidget, SLOT(Timeout()));
+ QObject::connect(&app, SIGNAL(aboutToQuit()), d3dWidget, SLOT(Shutdown()));
+
+ SetupStyles();
+
+ AppMainWindow::Inst().show();
+ AppMainWindow::Inst().update();
+
+ std::string title = "";
+
+#ifdef NV_ARTISTTOOLS
+ title = "ArtistTools";
+#else
+ title = "Blast Viewer";
+#endif // NV_ARTISTTOOLS
+
+#ifdef _WIN64
+ title.append(" x64");
+#endif
+
+#ifdef _DEBUG
+ title.append(" (Debug)");
+#else
+#endif
+
+ std::string strApi = RenderPlugin::Instance()->GetRenderApi();
+ title.append(" ");
+ title.append(strApi);
+
+ switch (backdoor)
+ {
+ case 1:
+ title.append(" (Master Mode)");
+ break;
+ case 2:
+ title.append(" (Slave Mode)");
+ break;
+ }
+
+ AppMainWindow::Inst().setWindowTitle(title.c_str());
+
+ OptionValue* option = AppSettings::Inst().GetOptionValue("User/HideUI");
+ if (option)
+ {
+ if (option->Value.Bool == OA_TRUE)
+ {
+ AppMainWindow::Inst().shortcut_expert();
+ }
+ }
+
+#ifndef NV_ARTISTTOOLS
+ option = AppSettings::Inst().GetOptionValue("User/FurAssetPath");
+ if (option && option->Value.String && strlen(option->Value.String))
+ {
+ const char* path = option->Value.String;
+ QFileInfo fi(path);
+ QByteArray dir = QDir::toNativeSeparators(fi.absoluteDir().absolutePath()).toLocal8Bit();
+ QByteArray file = fi.fileName().toLocal8Bit();
+ scene->GetFurCharacter().LoadHairAsset(dir, file);
+ }
+#else
+ CoreLib::Inst()->CoreLib_RunApp();
+#endif // NV_ARTISTTOOLS
+
+ option = AppSettings::Inst().GetOptionValue("User/ProjectPath");
+ if (option && option->Value.String && strlen(option->Value.String))
+ {
+ const char* path = option->Value.String;
+ QFileInfo fi(path);
+ QByteArray dir = QDir::toNativeSeparators(fi.absoluteDir().absolutePath()).toLocal8Bit();
+ QByteArray file = fi.fileName().toLocal8Bit();
+ scene->LoadProject(dir, file);
+ }
+ option = AppSettings::Inst().GetOptionValue("User/Play");
+ if (option)
+ {
+ if (option->Value.Bool == OA_TRUE)
+ {
+ AppMainWindow::Inst().shortcut_pause();
+ }
+ }
+
+ int ret = app.exec();
+ // release GUI before releasing QApplication (and QWindowsContext) to avoid crash.
+ // e.g. GWDCC-415 Blast Viewer crashes when quit after clicked any main menu.
+ ReleaseAppMainWindow();
+ return ret;
+}
+
+static void ShowUsage()
+{
+ char message[] = {
+ "FurViewer Command-line Options:\n\n"
+ "Usage: FurViewer.[win64|win32].exe [file] [options]...\n\n"
+ "[file]: \n"
+ "\t: File to load. .furproj, .apx or .apb are supported.\n\t ex) media/HairBall/Hairball.furproj\n\n"
+ "[options]:\n"
+ "-size <width>x<height>\n\t: Window resolution\t ex) -size 1024x768\n"
+ "-aa <1|2|4|8>\n\t: MSAA anti-aliasing options. 1 for off.\t ex) -aa 4 or -aa 1\n"
+ "-backdoor <master|slave>\n\t: Backdoor options\n"
+ "-device <0|1|2|3>\n\t: Which GPU to use\n"
+ "-noui \n\t: Set this option to hide UI\n"
+ "-play \n\t: Play the default animation if it has\n"
+ "-fullscreen \n\t: Start the application in full screen\n"
+ "-maxscreen \n\t: Start the application in max sized screen\n"
+ "-demoMode playlistname.plist \n\t: Start the application and demo the projects in a fur playlist stored in media/playlists folder.\n"
+ };
+ QMessageBox messageBox;
+ messageBox.information(0, "Usage", message);
+}
+
+bool ParseCommandLineOptions(int argc, char* argv[])
+{
+ AppSettings& settings = AppSettings::Inst();
+
+ for (int idx = 1; idx < argc; ++idx)
+ {
+ if (!stricmp(argv[idx], "-size"))
+ {
+ if ((idx + 1) < argc)
+ {
+ oaValue value;
+ value.Enum = argv[idx + 1];
+ settings.SetOptionValue("User/Resolution", OA_TYPE_ENUM, &value);
+ idx++; // Skip next option
+ }
+ }
+ else if (!stricmp(argv[idx], "-fullscreen"))
+ {
+ // HAIR-285 Viewer - new command line to start Viewer in full screen
+ oaValue value;
+ value.Enum = "0x0";
+ settings.SetOptionValue("User/Resolution", OA_TYPE_ENUM, &value);;
+ }
+ else if (!stricmp(argv[idx], "-maxscreen"))
+ {
+ // HAIR-285 Viewer - new command line to start Viewer in full screen
+ oaValue value;
+ value.Enum = "-1x0";
+ settings.SetOptionValue("User/Resolution", OA_TYPE_ENUM, &value);;
+ }
+ else if (!stricmp(argv[idx], "-backdoor"))
+ {
+ if ((idx + 1) < argc)
+ {
+ oaValue value;
+ bool isValid = true;
+ if (!strcmp(argv[idx + 1], "master"))
+ value.String = "master";
+ else if (!strcmp(argv[idx + 1], "slave"))
+ value.String = "slave";
+ else
+ isValid = false;
+
+ if (isValid)
+ settings.SetOptionValue("User/Backdoor", OA_TYPE_STRING, &value);
+ idx++; // Skip next option
+ }
+ }
+ else if (!stricmp(argv[idx], "-aa"))
+ {
+ if ((idx + 1) < argc)
+ {
+ oaValue value;
+ bool isValid = true;
+ if (!strcmp(argv[idx + 1], "1"))
+ value.Enum = "Off";
+ else if (!strcmp(argv[idx + 1], "2"))
+ value.Enum = "2X";
+ else if (!strcmp(argv[idx + 1], "4"))
+ value.Enum = "4X";
+ else if (!strcmp(argv[idx + 1], "8"))
+ value.Enum = "8X";
+ else
+ isValid = false;
+ if (isValid)
+ settings.SetOptionValue("User/AA", OA_TYPE_ENUM, &value);
+ idx++; // Skip next option
+ }
+ }
+ else if (!stricmp(argv[idx], "-device"))
+ {
+ if ((idx + 1) < argc)
+ {
+ oaValue value;
+ bool isValid = true;
+ if (!strcmp(argv[idx + 1], "0"))
+ value.Int = 0;
+ else if (!strcmp(argv[idx + 1], "1"))
+ value.Int = 1;
+ else if (!strcmp(argv[idx + 1], "2"))
+ value.Int = 2;
+ else if (!strcmp(argv[idx + 1], "3"))
+ value.Int = 3;
+ else
+ isValid = false;
+ if (isValid)
+ settings.SetOptionValue("User/Device", OA_TYPE_INT, &value);
+ idx++; // Skip next option
+ }
+ }
+ else if (!stricmp(argv[idx], "-noui"))
+ {
+ oaValue value;
+ value.Bool = OA_TRUE;
+ settings.SetOptionValue("User/HideUI", OA_TYPE_BOOL, &value);
+ }
+ else if (!stricmp(argv[idx], "-perf"))
+ {
+ oaValue value;
+ value.Bool = OA_TRUE;
+ settings.SetOptionValue("User/PerfMode", OA_TYPE_BOOL, &value);
+ }
+ else if (!stricmp(argv[idx], "-play"))
+ {
+ oaValue value;
+ value.Bool = OA_TRUE;
+ settings.SetOptionValue("User/Play", OA_TYPE_BOOL, &value);
+ }
+ else if (!stricmp(argv[idx], "-install"))
+ {
+ // Install mode
+ // Just ignore here
+ }
+ else if (!stricmp(argv[idx], "-openautomate"))
+ {
+ // OpenAutomate mode
+ // Just ignore here
+ idx++; // Skip next option
+ }
+ else if (!stricmp(argv[idx], "-demoMode"))
+ {
+ //QMessageBox messageBox;
+ //messageBox.information(0, "debug", argv[idx]);
+ idx++; // check next arg
+ if (idx < argc)
+ {
+ bool isValid = false;
+ char* extension = strrchr(argv[idx], '.');
+ if (extension)
+ {
+ if (!_stricmp(extension, ".plist"))
+ {
+ oaValue value;
+ value.String = argv[idx];
+ settings.SetOptionValue("User/FurDemoPlaylist", OA_TYPE_STRING, &value);
+ isValid = true;
+ }
+ }
+ }
+ }
+ else // Try to load the file
+ {
+ bool isValid = false;
+ char* extension = strrchr(argv[idx], '.');
+ if (extension)
+ {
+ if (!_stricmp(extension, ".furproj"))
+ {
+ oaValue value;
+ value.String = argv[idx];
+ settings.SetOptionValue("User/ProjectPath", OA_TYPE_STRING, &value);
+ isValid = true;
+ }
+ else if (!_stricmp(extension, ".apx") || !_stricmp(extension, ".apb"))
+ {
+ oaValue value;
+ value.String = argv[idx];
+ settings.SetOptionValue("User/FurAssetPath", OA_TYPE_STRING, &value);
+ isValid = true;
+ }
+ }
+ if (!isValid)
+ {
+ // Invalid option
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+typedef RenderPlugin*(*Func)(void);
+
+void GetRenderPlugins(QApplication& app, std::vector<std::string>& render_plugins)
+{
+ HMODULE module = NULL;
+ Func CreateFunc = NULL;
+ RenderPlugin* Plugin = NULL;
+
+ QDir pluginsDir(app.applicationDirPath());
+ foreach(QString fileName, pluginsDir.entryList(QDir::Files)) {
+#ifdef NV_ARTISTTOOLS
+ if (!fileName.startsWith("Render"))
+#else
+ if (!fileName.startsWith("FurRender"))
+#endif
+ {
+ continue;
+ }
+
+#ifdef _WIN64
+#ifdef _DEBUG
+ if (!fileName.endsWith(".win64.d.dll"))
+ {
+ continue;
+ }
+#else
+ if (!fileName.endsWith(".win64.dll"))
+ {
+ continue;
+ }
+#endif
+#else
+#ifdef _DEBUG
+ if (!fileName.endsWith(".win32.d.dll"))
+ {
+ continue;
+ }
+#else
+ if (!fileName.endsWith(".win32.dll"))
+ {
+ continue;
+ }
+#endif
+#endif
+
+ QByteArray tmp = pluginsDir.absoluteFilePath(fileName).toUtf8();
+ const char* pName = tmp.data();
+ module = LoadLibraryA(pName);
+ if (NULL == module)
+ continue;
+
+ CreateFunc = (Func)GetProcAddress(module, "CreateRenderPlugin");
+ if (NULL == CreateFunc)
+ continue;
+
+ Plugin = CreateFunc();
+ if (NULL != Plugin)
+ {
+ std::string name = Plugin->GetRenderApi();
+ render_plugins.push_back(name);
+ delete Plugin;
+ Plugin = NULL;
+ }
+ }
+}
+
+
+#include "RenderPlugin.h"
+#include "CoreLib.h"
+
+#include <io.h>
+#include <stdio.h>
+#include <stdlib.h>
+#define LINE 10
+
+#ifndef NV_ARTISTTOOLS
+int CoreLib::CoreMain(int argc, char *argv[])
+#else
+int CoreLib::CoreMain(int argc, char *argv[], bool withPlugin)
+#endif
+{
+#ifdef OPEN_CONSOLE
+ AllocConsole();
+ freopen("CONOUT$", "w", stdout);
+ freopen("CONOUT$", "w", stderr);
+#endif
+
+ QApplication a(argc, argv);
+
+ AppSettings::Inst().InitOptions();
+
+ if (!ParseCommandLineOptions(argc, argv))
+ {
+ // Invalid option. Show the usage and quit
+ ShowUsage();
+ return 0;
+ }
+#if (0) // Install mode for OpenAutomate is not tested yet
+ bool isAutomateInstallMode = GetAutomateInstallModeOption(argc, argv);
+ if (isAutomateInstallMode)
+ {
+ if (AutomateInstallApp())
+ {
+ QMessageBox messageBox;
+ messageBox.information(0, "Info", "Install succeeded");
+ }
+ else
+ {
+ QMessageBox messageBox;
+ messageBox.information(0, "Info", "Install failed. Did you run with admin privilege?");
+ }
+ return 0;
+ }
+#endif
+ std::string openAutomateOptions = GetAutomateOption(argc, argv);
+ if (!openAutomateOptions.empty())
+ {
+ AutomateInit(openAutomateOptions.c_str());
+ }
+
+ std::vector<std::string> render_plugins;
+ std::vector<std::string>::iterator it;
+
+ FILE *pf;
+ if ((_access("RenderPlugin.txt", 0)) == -1)
+ {
+ GetRenderPlugins(a, render_plugins);
+
+ if (render_plugins.size() > 1)
+ {
+ pf = fopen("RenderPlugin.txt", "a");
+ for (it = render_plugins.begin(); it != render_plugins.end(); it++)
+ {
+ fprintf(pf, "%s\n", (*it).c_str());
+ }
+ fclose(pf);
+ }
+ }
+ else
+ {
+ pf = fopen("RenderPlugin.txt", "r");
+ char buf[LINE];
+ while (1) {
+ memset(buf, 0, LINE);
+ if (fscanf(pf, "%s", buf) == -1)
+ break;
+ render_plugins.push_back(buf);
+ }
+ fclose(pf);
+ }
+
+ RenderPlugin::Load(render_plugins);
+
+ std::string strApi = RenderPlugin::Instance()->GetRenderApi();
+ if ("" == strApi)
+ {
+ return -1;
+ }
+
+#ifdef NV_ARTISTTOOLS
+ if (withPlugin)
+ {
+ LoadPlugins(a);
+ }
+#else
+ bool loaded = PluginBlast::Create(strApi);
+ if (!loaded)
+ {
+ return -1;
+ }
+#endif
+
+ return RunApp(a);
+}
+
+CoreLib::CoreLib()
+{
+
+}
+
+CoreLib::~CoreLib()
+{
+
+}
+
+CoreLib* CoreLib::Inst()
+{
+ static CoreLib coreLib;
+ return &coreLib;
+}
+
+#ifdef NV_ARTISTTOOLS
+#include <QtWidgets/QApplication>
+#include <QtCore/QTimer>
+#include <QtCore/QFile>
+#include <QtCore/QDir>
+#include <QtWidgets/QMessageBox>
+#include <QtCore/QFileInfo>
+
+#include "Nv.h"
+
+#include "AppMainWindow.h"
+#include "D3DWidget.h"
+#include "SimpleScene.h"
+#include "Automate.h"
+#include "Settings.h"
+#include "RenderInterface.h"
+#include "Light.h"
+
+#include <QtCore/QPluginLoader>
+void CoreLib::LoadPlugins(QApplication& app)
+{
+ QDir pluginsDir(app.applicationDirPath());
+ foreach(QString fileName, pluginsDir.entryList(QDir::Files)) {
+ if (!fileName.startsWith("Plugin"))
+ {
+ continue;
+ }
+
+#ifdef _WIN64
+#ifdef _DEBUG
+ if (!fileName.endsWith(".win64.d.dll"))
+ {
+ continue;
+ }
+#else
+ if (!fileName.endsWith(".win64.dll"))
+ {
+ continue;
+ }
+#endif
+#else
+#ifdef _DEBUG
+ if (!fileName.endsWith(".win32.d.dll"))
+ {
+ continue;
+ }
+#else
+ if (!fileName.endsWith(".win32.dll"))
+ {
+ continue;
+ }
+#endif
+#endif
+
+ PluginInterface* pInterface;
+ QByteArray tmp = pluginsDir.absoluteFilePath(fileName).toUtf8();
+ const char* pName = tmp.data();
+ QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
+ QObject *plugin = pluginLoader.instance();
+ if (plugin) {
+ pInterface = qobject_cast<PluginInterface *>(plugin);
+ if (pInterface)
+ {
+ std::string strApi = RenderPlugin::Instance()->GetRenderApi();
+ bool loaded = pInterface->LoadRenderPlugin(strApi);
+ if (!loaded)
+ {
+ continue;
+ }
+
+ QString name = pInterface->GetPluginName();
+ m_PluginInterfaces[name] = pInterface;
+ }
+ }
+ else
+ {
+ QMessageBox::critical(nullptr, "", pluginLoader.errorString());
+ }
+ }
+}
+
+PluginInterface* CoreLib::GetPluginInterface(QString name)
+{
+ PluginInterface* pPluginInterface = 0;
+ std::map<QString, PluginInterface*>::iterator it;
+ it = m_PluginInterfaces.find(name);
+ if (it != m_PluginInterfaces.end())
+ {
+ pPluginInterface = it->second;
+ }
+ return pPluginInterface;
+}
+
+bool CoreLib::GetBoneNames(std::vector<std::string>& BoneNames)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->GetBoneNames(BoneNames))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::CoreLib_RunApp()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->CoreLib_RunApp())
+ break;
+ }
+
+ return true;
+}
+
+bool CoreLib::MainToolbar_updateValues()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->MainToolbar_updateValues())
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::CurveEditor_updateValues(int _paramId, float* _values)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->CurveEditor_updateValues(_paramId, _values))
+ break;
+ }
+ return true;
+}
+bool CoreLib::CurveEditor_onUpdateValues(int _paramId, float* _values)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->CurveEditor_onUpdateValues(_paramId, _values))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::DisplayMeshesPanel_updateValues()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->DisplayMeshesPanel_updateValues())
+ break;
+ }
+ return true;
+}
+bool CoreLib::DisplayMeshesPanel_EmitToggleSignal(unsigned int id, bool visible)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->DisplayMeshesPanel_EmitToggleSignal(id, visible))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::Camera_LoadParameters(void* ptr, Camera* pCamera)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->Camera_LoadParameters(ptr, pCamera))
+ break;
+ }
+ return true;
+}
+bool CoreLib::Camera_SaveParameters(void* ptr, Camera* pCamera)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->Camera_SaveParameters(ptr, pCamera))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::Light_loadParameters(NvParameterized::Handle& handle, Light* pLight)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->Light_loadParameters(handle, pLight))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::Light_saveParameters(NvParameterized::Handle& handle, Light* pLight)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->Light_saveParameters(handle, pLight))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::Gamepad_ToggleSimulation()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->Gamepad_ToggleSimulation())
+ break;
+ }
+ return true;
+}
+bool CoreLib::Gamepad_LoadSamples(QString fn)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->Gamepad_LoadSamples(fn))
+ break;
+ }
+ return true;
+}
+bool CoreLib::Gamepad_ResetScene()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->Gamepad_ResetScene())
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::Gamepad_StartAnimation()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->Gamepad_StartAnimation())
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::GamepadHandler_ShowHair()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->GamepadHandler_ShowHair())
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::GamepadHandler_SpinWindStrength(float windStrength)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->GamepadHandler_SpinWindStrength(windStrength))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::Gamepad_ResetAnimation()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->Gamepad_ResetAnimation())
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::Gamepad_PlayPauseAnimation()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->Gamepad_PlayPauseAnimation())
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::SimpleScene_SimpleScene()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_SimpleScene())
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_Initialize(int backdoor)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_Initialize(backdoor))
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_Shutdown()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_Shutdown())
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_Clear()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_Clear())
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_Draw_DX12()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_Draw_DX12())
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_Draw_DX11()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_Draw_DX11())
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_FitCamera(atcore_float3& center, atcore_float3& extents)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_FitCamera(center, extents))
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_DrawGround()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_DrawGround())
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_DrawWind()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_DrawWind())
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_DrawAxis()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_DrawAxis())
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_LoadSceneFromFbx(const char* dir, const char* fbxName)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_LoadSceneFromFbx(dir, fbxName))
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_LoadProject(const char* dir, const char* file)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_LoadProject(dir, file))
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_SaveProject(const char* dir, const char* file)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_SaveProject(dir, file))
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_LoadParameters(NvParameterized::Interface* iface)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_LoadParameters(iface))
+ break;
+ }
+ return true;
+}
+bool CoreLib::SimpleScene_SaveParameters(NvParameterized::Interface* iface)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_SaveParameters(iface))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::SimpleScene_LoadCameraBookmarks(NvParameterized::Interface* iface)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_LoadCameraBookmarks(iface))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::SimpleScene_SaveCameraBookmarks(NvParameterized::Interface* iface)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_SaveCameraBookmarks(iface))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::D3DWidget_resizeEvent(QResizeEvent* e)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3DWidget_resizeEvent(e))
+ break;
+ }
+ return true;
+}
+bool CoreLib::D3DWidget_paintEvent(QPaintEvent* e)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3DWidget_paintEvent(e))
+ break;
+ }
+ return true;
+}
+bool CoreLib::D3DWidget_mousePressEvent(QMouseEvent* e)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3DWidget_mousePressEvent(e))
+ break;
+ }
+ return true;
+}
+bool CoreLib::D3DWidget_mouseReleaseEvent(QMouseEvent* e)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3DWidget_mouseReleaseEvent(e))
+ break;
+ }
+ return true;
+}
+bool CoreLib::D3DWidget_mouseMoveEvent(QMouseEvent* e)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3DWidget_mouseMoveEvent(e))
+ break;
+ }
+ return true;
+}
+bool CoreLib::D3DWidget_wheelEvent(QWheelEvent * e)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3DWidget_wheelEvent(e))
+ break;
+ }
+ return true;
+}
+bool CoreLib::D3DWidget_keyPressEvent(QKeyEvent* e)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3DWidget_keyPressEvent(e))
+ break;
+ }
+ return true;
+}
+bool CoreLib::D3DWidget_keyReleaseEvent(QKeyEvent* e)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3DWidget_keyReleaseEvent(e))
+ break;
+ }
+ return true;
+}
+bool CoreLib::D3DWidget_dragEnterEvent(QDragEnterEvent *e)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3DWidget_dragEnterEvent(e))
+ break;
+ }
+ return true;
+}
+bool CoreLib::D3DWidget_dragMoveEvent(QDragMoveEvent *e)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3DWidget_dragMoveEvent(e))
+ break;
+ }
+ return true;
+}
+bool CoreLib::D3DWidget_dragLeaveEvent(QDragLeaveEvent *e)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3DWidget_dragLeaveEvent(e))
+ break;
+ }
+ return true;
+}
+bool CoreLib::D3DWidget_dropEvent(QDropEvent *e)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3DWidget_dropEvent(e))
+ break;
+ }
+ return true;
+}
+bool CoreLib::D3DWidget_contextMenuEvent(QContextMenuEvent *e)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3DWidget_contextMenuEvent(e))
+ break;
+ }
+ return true;
+}
+
+#ifdef NV_ARTISTTOOLS
+bool CoreLib::D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderShader*>& ShaderMap)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->D3D11Shaders_InitializeShadersD3D11(ShaderMap))
+ break;
+ }
+ return true;
+}
+#endif // NV_ARTISTTOOLS
+
+bool CoreLib::AppMainWindow_AppMainWindow()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_AppMainWindow())
+ break;
+ }
+ return true;
+}
+bool CoreLib::AppMainWindow_InitMenuItems(QMenuBar* pMenuBar)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_InitMenuItems(pMenuBar))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::AppMainWindow_InitMainTab(QWidget *displayScrollAreaContents, QVBoxLayout *displayScrollAreaLayout, int idx)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_InitMainTab(displayScrollAreaContents, displayScrollAreaLayout, idx))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::AppMainWindow_InitPluginTab(QTabWidget* pTabWidget)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_InitPluginTab(pTabWidget))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::AppMainWindow_InitUI()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_InitUI())
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::AppMainWindow_updateUI()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_updateUI())
+ break;
+ }
+ return true;
+}
+bool CoreLib::AppMainWindow_updatePluginUI()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_updatePluginUI())
+ break;
+ }
+ return true;
+}
+bool CoreLib::AppMainWindow_processDragAndDrop(QString fname)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_processDragAndDrop(fname))
+ break;
+ }
+ return true;
+}
+bool CoreLib::AppMainWindow_closeEvent(QCloseEvent *event)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_closeEvent(event))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::AppMainWindow_menu_about()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_menu_about())
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::AppMainWindow_menu_opendoc()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_menu_opendoc())
+ break;
+ }
+ return true;
+}
+#if USE_CURVE_EDITOR
+bool CoreLib::AppMainWindow_UpdateCurveEditor()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_UpdateCurveEditor())
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::AppMainWindow_ShowCurveEditor(int paramId)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_ShowCurveEditor(paramId))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::AppMainWindow_onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_onCurveAttributeChanged(attribute))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::AppMainWindow_onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_onColorAttributeChanged(attribute))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::AppMainWindow_onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_onReloadColorAttributeTexture(attribute, reloadColorTex, selectedCtrlPntIndex))
+ break;
+ }
+ return true;
+}
+#endif
+bool CoreLib::AppMainWindow_InitToolbar(QWidget *pQWidget, QVBoxLayout* pLayout)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_InitToolbar(pQWidget, pLayout))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::AppMainWindow_shortcut_expert(bool mode)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_shortcut_expert(mode))
+ break;
+ }
+ return true;
+}
+
+bool CoreLib::AppMainWindow_updateMainToolbar()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_updateMainToolbar())
+ break;
+ }
+ return true;
+}
+
+#endif \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/CoreLib.h b/tools/ArtistTools/source/CoreLib/CoreLib.h
new file mode 100644
index 0000000..3d86bcf
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/CoreLib.h
@@ -0,0 +1,121 @@
+#ifndef CORELIB_H
+#define CORELIB_H
+
+#include "corelib_global.h"
+#include "PluginInterface.h"
+#include "NvParameterized.h"
+#if USE_CURVE_EDITOR
+#include <Attribute.h>
+#endif
+
+class QCloseEvent;
+class Camera;
+class Light;
+namespace NvParameterized
+{
+ class Interface;
+ class Handle;
+}
+class D3D11RenderShader;
+
+class CORELIB_EXPORT CoreLib
+{
+public:
+ CoreLib();
+ ~CoreLib();
+
+ static CoreLib* Inst();
+#ifndef NV_ARTISTTOOLS
+ int CoreMain(int argc, char *argv[]);
+#else
+ int CoreMain(int argc, char *argv[], bool withPlugin = true);
+
+ bool CoreLib_RunApp();
+ void LoadPlugins(QApplication& app);
+ PluginInterface* GetPluginInterface(QString name);
+
+ bool GetBoneNames(std::vector<std::string>& BoneNames);
+ bool MainToolbar_updateValues();
+
+ bool CurveEditor_updateValues(int _paramId, float* _values);
+ bool CurveEditor_onUpdateValues(int _paramId, float* _values);
+
+ bool DisplayMeshesPanel_updateValues();
+ bool DisplayMeshesPanel_EmitToggleSignal(unsigned int id, bool visible);
+
+ bool Camera_LoadParameters(void* ptr, Camera* pCamera);
+ bool Camera_SaveParameters(void* ptr, Camera* pCamera);
+ bool Light_loadParameters(NvParameterized::Handle& handle, Light* pLight);
+ bool Light_saveParameters(NvParameterized::Handle& handle, Light* pLight);
+
+ bool Gamepad_ToggleSimulation();
+ bool Gamepad_LoadSamples(QString fn);
+ bool Gamepad_ResetScene();
+ bool Gamepad_StartAnimation();
+ bool GamepadHandler_ShowHair();
+ bool GamepadHandler_SpinWindStrength(float windStrength);
+ bool Gamepad_ResetAnimation();
+ bool Gamepad_PlayPauseAnimation();
+
+ bool SimpleScene_SimpleScene();
+ bool SimpleScene_Initialize(int backdoor);
+ bool SimpleScene_Shutdown();
+ bool SimpleScene_Clear();
+ bool SimpleScene_Draw_DX12();
+ bool SimpleScene_Draw_DX11();
+ bool SimpleScene_FitCamera(atcore_float3& center, atcore_float3& extents);
+ bool SimpleScene_DrawGround();
+ bool SimpleScene_DrawWind();
+ bool SimpleScene_DrawAxis();
+ bool SimpleScene_LoadSceneFromFbx(const char* dir, const char* fbxName);
+ bool SimpleScene_LoadProject(const char* dir, const char* file);
+ bool SimpleScene_SaveProject(const char* dir, const char* file);
+ bool SimpleScene_LoadParameters(NvParameterized::Interface* iface);
+ bool SimpleScene_SaveParameters(NvParameterized::Interface* iface);
+ bool SimpleScene_LoadCameraBookmarks(NvParameterized::Interface* iface);
+ bool SimpleScene_SaveCameraBookmarks(NvParameterized::Interface* iface);
+
+ bool D3DWidget_resizeEvent(QResizeEvent* e);
+ bool D3DWidget_paintEvent(QPaintEvent* e);
+ bool D3DWidget_mousePressEvent(QMouseEvent* e);
+ bool D3DWidget_mouseReleaseEvent(QMouseEvent* e);
+ bool D3DWidget_mouseMoveEvent(QMouseEvent* e);
+ bool D3DWidget_wheelEvent(QWheelEvent * e);
+ bool D3DWidget_keyPressEvent(QKeyEvent* e);
+ bool D3DWidget_keyReleaseEvent(QKeyEvent* e);
+ bool D3DWidget_dragEnterEvent(QDragEnterEvent *e);
+ bool D3DWidget_dragMoveEvent(QDragMoveEvent *e);
+ bool D3DWidget_dragLeaveEvent(QDragLeaveEvent *e);
+ bool D3DWidget_dropEvent(QDropEvent *e);
+ bool D3DWidget_contextMenuEvent(QContextMenuEvent *e);
+
+ bool D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderShader*>& ShaderMap);
+
+ bool AppMainWindow_AppMainWindow();
+ bool AppMainWindow_InitMenuItems(QMenuBar* pMenuBar);
+ bool AppMainWindow_InitMainTab(QWidget *displayScrollAreaContents, QVBoxLayout *displayScrollAreaLayout, int idx);
+ bool AppMainWindow_InitPluginTab(QTabWidget* pTabWidget);
+ bool AppMainWindow_InitUI();
+ bool AppMainWindow_updateUI();
+ bool AppMainWindow_updatePluginUI();
+ bool AppMainWindow_processDragAndDrop(QString fname);
+ bool AppMainWindow_closeEvent(QCloseEvent *event);
+ bool AppMainWindow_InitToolbar(QWidget *pQWidget, QVBoxLayout* pLayout);
+ bool AppMainWindow_shortcut_expert(bool mode);
+ bool AppMainWindow_updateMainToolbar();
+
+ bool AppMainWindow_menu_about();
+ bool AppMainWindow_menu_opendoc();
+#if USE_CURVE_EDITOR
+ bool AppMainWindow_UpdateCurveEditor();
+ bool AppMainWindow_ShowCurveEditor(int paramId);
+ bool AppMainWindow_onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute);
+ bool AppMainWindow_onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute);
+ bool AppMainWindow_onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex);
+#endif
+private:
+ std::map<QString, PluginInterface*> m_PluginInterfaces;
+#endif // NV_ARTISTTOOLS
+};
+
+#endif // CORELIB_H
diff --git a/tools/ArtistTools/source/CoreLib/Parameters/FoundationHolder.h b/tools/ArtistTools/source/CoreLib/Parameters/FoundationHolder.h
new file mode 100644
index 0000000..5ec7868
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Parameters/FoundationHolder.h
@@ -0,0 +1,138 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "NvErrorCallback.h"
+#include "NsGlobals.h"
+#include "NsVersionNumber.h"
+
+class DefaultErrorCallback : public nvidia::NvErrorCallback
+{
+public:
+ DefaultErrorCallback(void)
+ {
+ }
+
+ virtual void reportError(nvidia::NvErrorCode::Enum code, const char* message, const char* file, int line)
+ {
+ NV_UNUSED(code);
+ printf("PhysX: %s : %s : %d\r\n", message, file, line);
+ }
+private:
+};
+
+class DefaultAllocator : public nvidia::NvAllocatorCallback
+{
+public:
+ DefaultAllocator(void)
+ {
+ }
+
+ ~DefaultAllocator(void)
+ {
+ }
+
+ virtual void* allocate(size_t size, const char* typeName, const char* filename, int line)
+ {
+ NV_UNUSED(typeName);
+ NV_UNUSED(filename);
+ NV_UNUSED(line);
+ void *ret = ::_aligned_malloc(size, 16);
+ return ret;
+ }
+
+ virtual void deallocate(void* ptr)
+ {
+ ::_aligned_free(ptr);
+ }
+private:
+};
+
+
+#if 0
+class FoundationHolder
+{
+ NvFoundation* mFoundation;
+ FoundationHolder()
+ :mFoundation(nullptr)
+ {
+ }
+
+ ~FoundationHolder()
+ {
+ if (mFoundation)
+ {
+ // to-do
+ // we should release foundation. but Hair SDK could release it first.
+ //mFoundation->release();
+ mFoundation = nullptr;
+ }
+ }
+
+public:
+
+ static NvFoundation* GetFoundation()
+ {
+ static FoundationHolder fh;
+ if (fh.mFoundation == nullptr)
+ {
+ static DefaultAllocator sDefaultAllocator;
+ static DefaultErrorCallback sDefaultErrorCallback;
+ fh.mFoundation = NvCreateFoundation(NV_FOUNDATION_VERSION, sDefaultAllocator, sDefaultErrorCallback);
+ assert(fh.mFoundation != nullptr);
+ }
+ return fh.mFoundation;
+ }
+};
+
+#else
+
+class FoundationHolder
+{
+ bool m_isInitialized;
+ public:
+ static void GetFoundation()
+ {
+ static FoundationHolder s_holder;
+ if (!s_holder.m_isInitialized)
+ {
+ static DefaultAllocator sDefaultAllocator;
+ static DefaultErrorCallback sDefaultErrorCallback;
+ nvidia::shdfnd::initializeSharedFoundation(NV_FOUNDATION_VERSION, sDefaultAllocator, sDefaultErrorCallback);
+
+ s_holder.m_isInitialized = true;
+ }
+ }
+ ~FoundationHolder()
+ {
+ //nvidia::terminateSharedFoundation();
+ }
+};
+
+#endif
diff --git a/tools/ArtistTools/source/CoreLib/PluginInterface.h b/tools/ArtistTools/source/CoreLib/PluginInterface.h
new file mode 100644
index 0000000..aae8da8
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/PluginInterface.h
@@ -0,0 +1,137 @@
+#ifndef BlastInterface_H
+#define BlastInterface_H
+
+#include <QtCore/QString>
+#include <QtCore/QObject>
+#if USE_CURVE_EDITOR
+#include <Attribute.h>
+#endif
+#include <Nv/NvBlastCommon.h>
+class QMenuBar;
+class QHBoxLayout;
+class QVBoxLayout;
+class QTabWidget;
+
+class Camera;
+class Light;
+enum RenderApi;
+namespace NvParameterized
+{
+ class Interface;
+ class Handle;
+}
+class D3D11RenderShader;
+class QCloseEvent;
+#define NV_AT_UNUSED
+
+class QResizeEvent;
+class QPaintEvent;
+class QMouseEvent;
+class QWheelEvent;
+class QKeyEvent;
+class QDragEnterEvent;
+class QDragMoveEvent;
+class QDragLeaveEvent;
+class QDropEvent;
+class QContextMenuEvent;
+
+class PluginInterface
+{
+public:
+ virtual ~PluginInterface() {}
+
+ virtual QString GetPluginName() = 0;
+
+ virtual bool CoreLib_RunApp() = 0;
+
+ virtual bool LoadRenderPlugin(std::string api) = 0;
+
+ virtual bool GetBoneNames(std::vector<std::string>& BoneNames) = 0;
+
+ NV_AT_UNUSED virtual bool MainToolbar_updateValues() = 0;
+
+ NV_AT_UNUSED virtual bool CurveEditor_updateValues(int _paramId, float* _values) = 0;
+ NV_AT_UNUSED virtual bool CurveEditor_onUpdateValues(int _paramId, float* _values) = 0;
+
+ virtual bool DisplayMeshesPanel_updateValues() = 0;
+ virtual bool DisplayMeshesPanel_EmitToggleSignal(unsigned int id, bool visible) = 0;
+
+ virtual bool Camera_LoadParameters(void* ptr, Camera* pCamera) = 0;
+ virtual bool Camera_SaveParameters(void * ptr, Camera* pCamera) = 0;
+
+ virtual bool Gamepad_ToggleSimulation() = 0;
+ virtual bool Gamepad_ResetScene() = 0;
+ NV_AT_UNUSED virtual bool Gamepad_LoadSamples(QString fn) = 0;
+ virtual bool Gamepad_StartAnimation() = 0;
+ virtual bool GamepadHandler_ShowHair() = 0;
+ virtual bool GamepadHandler_SpinWindStrength(float windStrength) = 0;
+ virtual bool Gamepad_ResetAnimation() = 0;
+ virtual bool Gamepad_PlayPauseAnimation() = 0;
+
+ virtual bool Light_loadParameters(NvParameterized::Handle& handle, Light* pLight) = 0;
+ virtual bool Light_saveParameters(NvParameterized::Handle& handle, Light* pLight) = 0;
+
+ virtual bool SimpleScene_SimpleScene() = 0;
+ virtual bool SimpleScene_Initialize(int backdoor) = 0;
+ virtual bool SimpleScene_Shutdown() = 0;
+ virtual bool SimpleScene_Clear() = 0;
+ virtual bool SimpleScene_Draw_DX12() = 0;
+ virtual bool SimpleScene_Draw_DX11() = 0;
+ virtual bool SimpleScene_FitCamera(atcore_float3& center, atcore_float3& extents) = 0;
+ virtual bool SimpleScene_LoadSceneFromFbx(const char* dir, const char* fbxName) = 0;
+ virtual bool SimpleScene_LoadProject(const char* dir, const char* file) = 0;
+ virtual bool SimpleScene_SaveProject(const char* dir, const char* file) = 0;
+ virtual bool SimpleScene_LoadParameters(NvParameterized::Interface* iface) = 0;
+ virtual bool SimpleScene_SaveParameters(NvParameterized::Interface* iface) = 0;
+ virtual bool SimpleScene_LoadCameraBookmarks(NvParameterized::Interface* iface) = 0;
+ virtual bool SimpleScene_SaveCameraBookmarks(NvParameterized::Interface* iface) = 0;
+ NV_AT_UNUSED virtual bool SimpleScene_DrawGround() = 0;
+ NV_AT_UNUSED virtual bool SimpleScene_DrawWind() = 0;
+ NV_AT_UNUSED virtual bool SimpleScene_DrawAxis() = 0;
+
+ virtual bool D3DWidget_resizeEvent(QResizeEvent* e) = 0;
+ virtual bool D3DWidget_paintEvent(QPaintEvent* e) = 0;
+ virtual bool D3DWidget_mousePressEvent(QMouseEvent* e) = 0;
+ virtual bool D3DWidget_mouseReleaseEvent(QMouseEvent* e) = 0;
+ virtual bool D3DWidget_mouseMoveEvent(QMouseEvent* e) = 0;
+ virtual bool D3DWidget_wheelEvent(QWheelEvent * e) = 0;
+ virtual bool D3DWidget_keyPressEvent(QKeyEvent* e) = 0;
+ virtual bool D3DWidget_keyReleaseEvent(QKeyEvent* e) = 0;
+ virtual bool D3DWidget_dragEnterEvent(QDragEnterEvent *e) = 0;
+ virtual bool D3DWidget_dragMoveEvent(QDragMoveEvent *e) = 0;
+ virtual bool D3DWidget_dragLeaveEvent(QDragLeaveEvent *e) = 0;
+ virtual bool D3DWidget_dropEvent(QDropEvent *e) = 0;
+ virtual bool D3DWidget_contextMenuEvent(QContextMenuEvent *e) = 0;
+
+ virtual bool D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderShader*>& ShaderMap) = 0;
+
+ virtual bool AppMainWindow_AppMainWindow() = 0;
+ virtual bool AppMainWindow_InitMenuItems(QMenuBar* pMenuBar) = 0;
+ virtual bool AppMainWindow_InitMainTab(QWidget *displayScrollAreaContents, QVBoxLayout *displayScrollAreaLayout, int idx) = 0;
+ virtual bool AppMainWindow_InitPluginTab(QTabWidget* pTabWidget) = 0;
+ virtual bool AppMainWindow_InitUI() = 0;
+ virtual bool AppMainWindow_updateUI() = 0;
+ virtual bool AppMainWindow_updatePluginUI() = 0;
+ NV_AT_UNUSED virtual bool AppMainWindow_processDragAndDrop(QString fname) = 0;
+ virtual bool AppMainWindow_closeEvent(QCloseEvent *event) = 0;
+ virtual bool AppMainWindow_InitToolbar(QWidget *pQWidget, QVBoxLayout* pLayout) = 0;
+ virtual bool AppMainWindow_shortcut_expert(bool mode) = 0;
+ virtual bool AppMainWindow_updateMainToolbar() = 0;
+
+ virtual bool AppMainWindow_menu_about() = 0;
+ virtual bool AppMainWindow_menu_opendoc() = 0;
+#if USE_CURVE_EDITOR
+ virtual bool AppMainWindow_UpdateCurveEditor() = 0;
+ virtual bool AppMainWindow_ShowCurveEditor(int paramId) = 0;
+ virtual bool AppMainWindow_onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute) = 0;
+ virtual bool AppMainWindow_onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute) = 0;
+ virtual bool AppMainWindow_onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex) = 0;
+#endif
+};
+
+QT_BEGIN_NAMESPACE
+#define PluginInterface_iid "com.nvidia.PluginInterface"
+Q_DECLARE_INTERFACE(PluginInterface, PluginInterface_iid)
+QT_END_NAMESPACE
+
+#endif \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.cpp
new file mode 100644
index 0000000..4e261f1
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.cpp
@@ -0,0 +1,31 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D11Buffer.h"
+
+// shared path
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.h b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.h
new file mode 100644
index 0000000..d9d9730
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.h
@@ -0,0 +1,65 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "RenderResources.h"
+
+#include "d3d11.h"
+
+// GPU resources for texture
+struct GPUBufferD3D11 : public GPUBufferResource
+{
+ ID3D11Buffer* m_pD3D11Resource;
+
+public:
+ static GPUBufferResource* Create(ID3D11Buffer* pResource) {
+ GPUBufferD3D11* pBuffer = new GPUBufferD3D11;
+ pBuffer->m_pD3D11Resource = pResource;
+ return pBuffer;
+ }
+
+ static ID3D11Buffer* GetResource(GPUBufferResource* pBuffer)
+ {
+ GPUBufferD3D11* pD3D11Buffer = dynamic_cast<GPUBufferD3D11*>(pBuffer);
+ if (!pD3D11Buffer)
+ return 0;
+ return pD3D11Buffer->m_pD3D11Resource;
+ }
+
+ ~GPUBufferD3D11()
+ {
+ Release();
+ }
+
+ void Release()
+ {
+ SAFE_RELEASE(m_pD3D11Resource);
+ }
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.cpp
new file mode 100644
index 0000000..060a0cb
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.cpp
@@ -0,0 +1,138 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D11GPUProfiler.h"
+
+#include "D3D11RenderInterface.h"
+
+///////////////////////////////////////////////////////////////
+// factory function to create D3D11 GPU profiler
+/*
+GPUProfiler* GPUProfiler::CreateD3D11()
+{
+ GPUProfiler* pProfiler = new D3D11GPUProfiler;
+ pProfiler->Initialize();
+ return pProfiler;
+}
+*/
+///////////////////////////////////////////////////////////////
+D3D11GPUProfiler::~D3D11GPUProfiler()
+{
+ Release();
+}
+
+///////////////////////////////////////////////////////////////
+void D3D11GPUProfiler::Initialize()
+{
+ ID3D11Device *pDevice = RenderInterfaceD3D11::GetDevice();
+
+ m_pContext = RenderInterfaceD3D11::GetDeviceContext();
+
+ D3D11_QUERY_DESC desc;
+ memset(&desc, 0, sizeof(D3D11_QUERY_DESC));
+ desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT;
+ desc.MiscFlags = 0;
+
+ pDevice->CreateQuery(&desc, &m_pQueryDisjoint);
+
+ desc.Query = D3D11_QUERY_TIMESTAMP;
+
+ for (int i = 0; i < MAX_QUERY_COUNT; i++)
+ {
+ pDevice->CreateQuery(&desc, &m_pQueryStart[i]);
+ pDevice->CreateQuery(&desc, &m_pQueryEnd[i]);
+ }
+ m_enable = true;
+}
+
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; }
+#endif
+
+///////////////////////////////////////////////////////////////
+void D3D11GPUProfiler::Release()
+{
+ for (int i = 0; i < MAX_QUERY_COUNT; i++)
+ {
+ SAFE_RELEASE(m_pQueryStart[i]);
+ SAFE_RELEASE(m_pQueryEnd[i]);
+ }
+
+ SAFE_RELEASE(m_pQueryDisjoint);
+}
+
+///////////////////////////////////////////////////////////////
+void D3D11GPUProfiler::StartProfile(int id)
+{
+ if (!m_enable) return;
+
+ ID3D11Query* pQuery = m_pQueryStart[id];
+ m_pContext->End(pQuery);
+}
+
+///////////////////////////////////////////////////////////////
+void D3D11GPUProfiler::EndProfile(int id)
+{
+ if (!m_enable) return;
+
+ ID3D11Query* pQuery = m_pQueryEnd[id];
+ m_pContext->End(pQuery);
+}
+
+///////////////////////////////////////////////////////////////
+void D3D11GPUProfiler::StartFrame()
+{
+ if (!m_enable) return;
+
+ m_pContext->Begin(m_pQueryDisjoint);
+}
+
+///////////////////////////////////////////////////////////////
+void D3D11GPUProfiler::EndFrame()
+{
+ if (!m_enable) return;
+
+ m_pContext->End(m_pQueryDisjoint);
+
+ while(m_pContext->GetData(m_pQueryDisjoint, &m_disjointData, sizeof(D3D11_QUERY_DATA_TIMESTAMP_DISJOINT), 0) != S_OK);
+}
+
+///////////////////////////////////////////////////////////////
+float D3D11GPUProfiler::GetProfileData(int id)
+{
+ if (!m_enable)
+ return 0.0f;
+
+ UINT64 startTime = 0;
+ while(m_pContext->GetData(m_pQueryStart[id], &startTime, sizeof(UINT64), 0) != S_OK);
+
+ UINT64 endTime = 0;
+ while(m_pContext->GetData(m_pQueryEnd[id], &endTime, sizeof(UINT64), 0) != S_OK);
+
+ float frequency = static_cast<float>(m_disjointData.Frequency);
+ return (endTime - startTime) / frequency * 1000.0f;
+}
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.h b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.h
new file mode 100644
index 0000000..4c5b32f
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.h
@@ -0,0 +1,56 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "d3d11.h"
+
+#include "GPUProfiler.h"
+
+#define MAX_QUERY_COUNT 64
+struct D3D11GPUProfiler : public GPUProfiler
+{
+public:
+ ~D3D11GPUProfiler();
+
+ void Initialize();
+ void Release();
+ void StartProfile(int id);
+ void EndProfile(int id);
+ void StartFrame();
+ void EndFrame();
+ float GetProfileData(int id);
+
+protected:
+ ID3D11Query* m_pQueryDisjoint;
+ ID3D11Query* m_pQueryStart[MAX_QUERY_COUNT];
+ ID3D11Query* m_pQueryEnd[MAX_QUERY_COUNT];
+ D3D11_QUERY_DATA_TIMESTAMP_DISJOINT m_disjointData;
+ ID3D11DeviceContext* m_pContext;
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.cpp
new file mode 100644
index 0000000..71d1b7d
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.cpp
@@ -0,0 +1,890 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D11RenderInterface.h"
+
+#include "D3D11TextureResource.h"
+#include "D3D11Shaders.h"
+#include "D3D11Buffer.h"
+#include "Nv.h"
+#ifdef USE_11ON12_WRAPPER
+#include "D3D11on12Wrapper.h"
+#endif // USE_11ON12_WRAPPER
+namespace RenderInterfaceD3D11
+{
+ using namespace RenderInterface;
+
+ ID3D11SamplerState* m_pSamplerStates[SAMPLER_TYPE_END];
+ ID3D11BlendState* m_pBlendStates[BLEND_STATE_END];
+ ID3D11DepthStencilState* m_pDepthStencilStates[DEPTH_STENCIL_STATE_END];
+ ID3D11RasterizerState* m_pRasterizerStates[RASTERIZER_STATE_END];
+
+#ifdef USE_11ON12_WRAPPER
+#else
+ ID3D11DeviceContext* g_d3dDeviceContext = 0;
+ ID3D11Device* g_d3dDevice = 0;
+ IDXGIFactory1* g_pDXGIFactory1 = 0;
+ IDXGIDevice* g_dxgiDevice = 0;
+ IDXGIAdapter * g_pAdapter = 0;
+#endif // USE_11ON12_WRAPPER
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+ID3D11DeviceContext* GetDeviceContext()
+{
+#ifdef USE_11ON12_WRAPPER
+ return D3D11on12Wrapper::GetDeviceContext();
+#else
+ return g_d3dDeviceContext;
+#endif // USE_11ON12_WRAPPER
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+ID3D11Device* GetDevice()
+{
+#ifdef USE_11ON12_WRAPPER
+ return D3D11on12Wrapper::GetDevice11();
+#else
+ return g_d3dDevice;
+#endif // USE_11ON12_WRAPPER
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+IDXGIFactory1* GetDXGIFactory()
+{
+#ifdef USE_11ON12_WRAPPER
+ return D3D11on12Wrapper::GetDXGIFactory();
+#else
+ return g_pDXGIFactory1;
+#endif // USE_11ON12_WRAPPER
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+IDXGIDevice* GetDXGIDevice()
+{
+#ifdef USE_11ON12_WRAPPER
+ return nullptr;
+#else
+ return g_dxgiDevice;
+#endif // USE_11ON12_WRAPPER
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+IDXGIAdapter* GetAdapter()
+{
+#ifdef USE_11ON12_WRAPPER
+ return D3D11on12Wrapper::GetAdapter();
+#else
+ return g_pAdapter;
+#endif // USE_11ON12_WRAPPER
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool IsNvDeviceID(UINT id)
+{
+ return id == 0x10DE;
+}
+
+IDXGIAdapter* FindAdapter(IDXGIFactory* IDXGIFactory_0001, const WCHAR* targetName, bool& isNv)
+{
+ IDXGIAdapter* targetAdapter = nullptr;
+ std::vector<IDXGIAdapter*> adapters;
+ // check current adapter first. EnumAdapters could fail on some device
+ IDXGIAdapter* pAdapter = nullptr;
+ ID3D11Device* pD3dDevice = nullptr;
+ ID3D11DeviceContext* pD3dDeviceContext = nullptr;
+ DWORD createDeviceFlags = D3D11_CREATE_DEVICE_DEBUG;
+ D3D_FEATURE_LEVEL fl;
+ // This following code is the robust way to get all possible feature levels while handling DirectX 11.0 systems:
+ // please read https://blogs.msdn.microsoft.com/chuckw/2014/02/05/anatomy-of-direct3d-11-create-device/
+ D3D_FEATURE_LEVEL lvl[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0,
+ D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 };
+ HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr,
+ createDeviceFlags, lvl, _countof(lvl),
+ D3D11_SDK_VERSION, &pD3dDevice, &fl, &pD3dDeviceContext);
+ if (pD3dDevice)
+ {
+ IDXGIDevice* dxgiDevice = nullptr;
+ hr = pD3dDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice));
+ if (SUCCEEDED(hr))
+ {
+ hr = dxgiDevice->GetAdapter(&pAdapter);
+ if (pAdapter)
+ {
+ adapters.push_back(pAdapter);
+ }
+ SAFE_RELEASE(dxgiDevice);
+ }
+ SAFE_RELEASE(pD3dDeviceContext);
+ SAFE_RELEASE(pD3dDevice);
+ }
+
+ // Enum Adapters
+ unsigned int adapterNo = 0;
+ HRESULT hres = S_OK;
+ while (SUCCEEDED(hres = IDXGIFactory_0001->EnumAdapters(adapterNo, (IDXGIAdapter**)&pAdapter)))
+ {
+ adapters.push_back(pAdapter);
+ adapterNo++;
+ }
+ if (wcslen(targetName) != 0)
+ {
+ // find the adapter with specified name
+ for (int i = 0; i < adapters.size(); ++i)
+ {
+ IDXGIAdapter* pAdapter = adapters[i];
+ DXGI_ADAPTER_DESC aDesc;
+ pAdapter->GetDesc(&aDesc);
+ std::wstring aName = aDesc.Description;
+ if (aName.find(targetName) != std::string::npos)
+ {
+ targetAdapter = pAdapter;
+ isNv = IsNvDeviceID(aDesc.VendorId);
+ }
+ }
+ }
+ else
+ {
+ // no name specified, find one NV adapter
+ for (int i = 0; i < adapters.size(); ++i)
+ {
+ IDXGIAdapter* pAdapter = adapters[i];
+ DXGI_ADAPTER_DESC aDesc;
+ pAdapter->GetDesc(&aDesc);
+ std::wstring aName = aDesc.Description;
+ if (IsNvDeviceID(aDesc.VendorId))
+ {
+ targetAdapter = pAdapter;
+ isNv = true;
+ }
+ }
+ }
+ if (targetAdapter == nullptr)
+ targetAdapter = adapters[0];
+ for (int i = 0; i < adapters.size(); ++i)
+ {
+ IDXGIAdapter* pAdapter = adapters[i];
+ if(pAdapter != targetAdapter)
+ {
+ pAdapter->Release();
+ }
+ }
+
+ return targetAdapter;
+}
+
+HRESULT UseGoodGPUDevice()
+{
+#ifdef USE_11ON12_WRAPPER
+ return S_OK;
+#else
+ // create factory
+ if (g_pDXGIFactory1 == NV_NULL)
+ {
+ HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&g_pDXGIFactory1));
+ if (FAILED(hr))
+ return hr;
+ }
+
+ DWORD createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED; // 0; // I changed only this line.
+#ifdef _DEBUG
+ createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
+#endif
+ bool bNVAdapter = false;
+ WCHAR* pwName = L"";
+ g_pAdapter = FindAdapter(g_pDXGIFactory1, pwName, bNVAdapter);
+
+#ifdef _DEBUG
+ DXGI_ADAPTER_DESC adapterDesc;
+ g_pAdapter->GetDesc(&adapterDesc);
+ std::wstring adapterName = adapterDesc.Description;
+#endif
+
+ D3D_FEATURE_LEVEL fl;
+ HRESULT hr = D3D11CreateDevice(g_pAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
+ createDeviceFlags, 0, 0,
+ D3D11_SDK_VERSION, &g_d3dDevice, &fl, &g_d3dDeviceContext);
+
+ if(g_d3dDevice)
+ {
+ IDXGIDevice* dxgiDevice = nullptr;
+ hr = g_d3dDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice));
+ if (SUCCEEDED(hr))
+ {
+ g_dxgiDevice = dxgiDevice;
+ return hr;
+ }
+ else
+ {
+ SAFE_RELEASE(g_d3dDevice);
+ SAFE_RELEASE(g_pAdapter);
+ SAFE_RELEASE(g_pDXGIFactory1);
+ }
+ }
+ return hr;
+#endif // USE_11ON12_WRAPPER
+}
+
+bool InitDevice(int deviceID)
+{
+#ifdef USE_11ON12_WRAPPER
+ D3D11on12Wrapper::InitDevice();
+#else
+ if (deviceID == -1)
+ {
+ HRESULT hResult = UseGoodGPUDevice();
+ if (FAILED(hResult))
+ return false;
+
+ return true;
+ }
+
+ D3D_FEATURE_LEVEL featureLvl;
+
+ // create factory
+ if (g_pDXGIFactory1 == NV_NULL)
+ {
+ HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&g_pDXGIFactory1));
+ if (FAILED(hr))
+ return false;
+ }
+
+ // create adapter for selected device
+ if (g_pAdapter == NV_NULL)
+ {
+ HRESULT hr = g_pDXGIFactory1->EnumAdapters(deviceID, &g_pAdapter);
+ if (FAILED(hr))
+ return false;
+ }
+
+ UINT deviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED;
+#ifdef _DEBUG
+ deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
+#endif
+
+ // create device
+ HRESULT hResult = D3D11CreateDevice(
+ g_pAdapter,
+ D3D_DRIVER_TYPE_UNKNOWN, //D3D_DRIVER_TYPE_HARDWARE,
+ 0,
+ deviceFlags,
+ NV_NULL,
+ 0,
+ D3D11_SDK_VERSION,
+ &g_d3dDevice,
+ &featureLvl,
+ &g_d3dDeviceContext);
+
+ if(FAILED(hResult))
+ return false;
+#endif // USE_11ON12_WRAPPER
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool Initialize()
+{
+ if (!GetDevice() || !GetDeviceContext())
+ return false;
+
+ D3D11_COMPARISON_FUNC depthFunc = D3D11_COMPARISON_LESS;
+
+ InitializeShadersD3D11();
+ InitializeRenderStates();
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void Shutdown()
+{
+ DestroyShadersD3D11();
+ ClearRenderStates();
+
+ // release d3d resources
+ IDXGIFactory1* pDxgiFactory = GetDXGIFactory();
+ SAFE_RELEASE(pDxgiFactory);
+
+ IDXGIAdapter* pAdapter = GetAdapter();
+ SAFE_RELEASE(pAdapter);
+
+ IDXGIDevice* pDXGIDevice = GetDXGIDevice();
+ SAFE_RELEASE(pDXGIDevice);
+
+ ID3D11DeviceContext* pContext = GetDeviceContext();
+ SAFE_RELEASE(pContext);
+
+ ID3D11Device* pDevice = GetDevice();
+#if defined(DEBUG) || defined(_DEBUG)
+ // output d3d leak
+ ID3D11Debug *d3dDebug;
+ HRESULT hr = pDevice->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<void**>(&d3dDebug));
+ if (SUCCEEDED(hr))
+ {
+ hr = d3dDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);
+ }
+ if (d3dDebug != nullptr)
+ d3dDebug->Release();
+#endif
+
+ SAFE_RELEASE(pDevice);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void InitializeRenderStates()
+{
+ ID3D11Device* pDevice = GetDevice();
+ if (!pDevice)
+ return;
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // alpha blending state descriptors
+ /////////////////////////////////////////////////////////////////////////////////////////
+
+ // alpha blending enabled
+ {
+ D3D11_BLEND_DESC desc;
+ desc.AlphaToCoverageEnable = false;
+ desc.IndependentBlendEnable = false;
+
+ D3D11_RENDER_TARGET_BLEND_DESC &rtDesc = desc.RenderTarget[0];
+ {
+ rtDesc.BlendEnable = true;
+ rtDesc.SrcBlend = D3D11_BLEND_SRC_ALPHA;
+ rtDesc.DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
+ rtDesc.BlendOp = D3D11_BLEND_OP_ADD;
+ rtDesc.SrcBlendAlpha = D3D11_BLEND_ZERO;
+ rtDesc.DestBlendAlpha = D3D11_BLEND_ONE;
+ rtDesc.BlendOpAlpha = D3D11_BLEND_OP_ADD;
+ rtDesc.RenderTargetWriteMask = 0x0f;
+ }
+ pDevice->CreateBlendState(&desc, &m_pBlendStates[BLEND_STATE_ALPHA]);
+ }
+
+ // no alpha blending
+ {
+ D3D11_BLEND_DESC desc;
+ desc.AlphaToCoverageEnable = false;
+ desc.IndependentBlendEnable = false;
+
+ D3D11_RENDER_TARGET_BLEND_DESC &rtDesc = desc.RenderTarget[0];
+ {
+ rtDesc.BlendEnable = false;
+ rtDesc.SrcBlend = D3D11_BLEND_SRC_ALPHA;
+ rtDesc.DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
+ rtDesc.BlendOp = D3D11_BLEND_OP_ADD;
+ rtDesc.SrcBlendAlpha = D3D11_BLEND_ZERO;
+ rtDesc.DestBlendAlpha = D3D11_BLEND_ONE;
+ rtDesc.BlendOpAlpha = D3D11_BLEND_OP_ADD;
+ rtDesc.RenderTargetWriteMask = 0x0f;
+ }
+ pDevice->CreateBlendState(&desc, &m_pBlendStates[BLEND_STATE_NONE]);
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // depth and stencil
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+ D3D11_DEPTH_STENCIL_DESC depthTestDesc;
+ {
+ depthTestDesc.DepthEnable = true;
+ depthTestDesc.DepthFunc = D3D11_COMPARISON_LESS;
+ depthTestDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ depthTestDesc.StencilEnable = false;
+ depthTestDesc.StencilReadMask = 0xff;
+ depthTestDesc.StencilWriteMask = 0xff;
+ }
+
+ pDevice->CreateDepthStencilState(&depthTestDesc, &m_pDepthStencilStates[DEPTH_STENCIL_DEPTH_TEST]);
+
+ D3D11_DEPTH_STENCIL_DESC depthNone;
+ {
+ depthNone.DepthEnable = false;
+ depthNone.DepthFunc = D3D11_COMPARISON_LESS;
+ depthNone.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
+ depthNone.StencilEnable = false;
+ depthNone.StencilReadMask = 0xff;
+ depthNone.StencilWriteMask = 0xff;
+ }
+
+ pDevice->CreateDepthStencilState(&depthNone, &m_pDepthStencilStates[DEPTH_STENCIL_DEPTH_NONE]);
+
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // rasterizer
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+ D3D11_RASTERIZER_DESC rsDesc;
+
+ // solid cull front
+ {
+ rsDesc.FillMode = D3D11_FILL_SOLID;
+ rsDesc.CullMode = D3D11_CULL_FRONT;
+ rsDesc.AntialiasedLineEnable = false;
+ rsDesc.MultisampleEnable = true;
+ rsDesc.FrontCounterClockwise = true;
+ rsDesc.DepthBias = 10;
+ rsDesc.DepthBiasClamp = 0;
+ rsDesc.SlopeScaledDepthBias = 0;
+ rsDesc.DepthClipEnable = true;
+ rsDesc.ScissorEnable = 0;
+
+ pDevice->CreateRasterizerState(&rsDesc, &m_pRasterizerStates[RASTERIZER_STATE_FILL_CULL_FRONT]);
+ };
+
+ // solid cull back
+ {
+ rsDesc.FillMode = D3D11_FILL_SOLID;
+ rsDesc.CullMode = D3D11_CULL_BACK;
+ rsDesc.AntialiasedLineEnable = false;
+ rsDesc.MultisampleEnable = true;
+ rsDesc.FrontCounterClockwise = true;
+ rsDesc.DepthBias = 10;
+ rsDesc.DepthBiasClamp = 0;
+ rsDesc.SlopeScaledDepthBias = 0;
+ rsDesc.DepthClipEnable = true;
+ rsDesc.ScissorEnable = 0;
+
+ pDevice->CreateRasterizerState(&rsDesc, &m_pRasterizerStates[RASTERIZER_STATE_FILL_CULL_BACK]);
+ }
+
+ // solid cull none
+ {
+ rsDesc.FillMode = D3D11_FILL_SOLID;
+ rsDesc.CullMode = D3D11_CULL_NONE;
+ rsDesc.AntialiasedLineEnable = false;
+ rsDesc.MultisampleEnable = true;
+ rsDesc.FrontCounterClockwise = true;
+ rsDesc.DepthBias = 10;
+ rsDesc.DepthBiasClamp = 0;
+ rsDesc.SlopeScaledDepthBias = 0;
+ rsDesc.DepthClipEnable = true;
+ rsDesc.ScissorEnable = 0;
+
+ pDevice->CreateRasterizerState(&rsDesc, &m_pRasterizerStates[RASTERIZER_STATE_FILL_CULL_NONE]);
+
+ }
+
+ // wireframe cull none
+ {
+ rsDesc.FillMode = D3D11_FILL_WIREFRAME;
+ rsDesc.CullMode = D3D11_CULL_NONE;
+ rsDesc.AntialiasedLineEnable = false;
+ rsDesc.MultisampleEnable = true;
+ rsDesc.FrontCounterClockwise = 0;
+ rsDesc.DepthBias = 0;
+ rsDesc.DepthBiasClamp = 0;
+ rsDesc.SlopeScaledDepthBias = 0;
+ rsDesc.DepthClipEnable = true;
+ rsDesc.ScissorEnable = 0;
+ };
+
+ pDevice->CreateRasterizerState(&rsDesc, &m_pRasterizerStates[RASTERIZER_STATE_WIRE]);
+
+ // samplers
+
+ D3D11_SAMPLER_DESC linearSamplerDesc[1] = {
+ D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT,
+ D3D11_TEXTURE_ADDRESS_WRAP,
+ D3D11_TEXTURE_ADDRESS_WRAP,
+ D3D11_TEXTURE_ADDRESS_WRAP,
+ 0.0, 0, D3D11_COMPARISON_NEVER, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, D3D11_FLOAT32_MAX,
+ };
+ pDevice->CreateSamplerState(linearSamplerDesc, &m_pSamplerStates[SAMPLER_TYPE_LINEAR]);
+
+ // create point clamp sampler for PCF sampling for hair
+ D3D11_SAMPLER_DESC pointClampSamplerDesc[1] = {
+ D3D11_FILTER_MIN_MAG_MIP_POINT,
+ D3D11_TEXTURE_ADDRESS_CLAMP,
+ D3D11_TEXTURE_ADDRESS_CLAMP,
+ D3D11_TEXTURE_ADDRESS_CLAMP,
+ 0.0, 0, D3D11_COMPARISON_NEVER,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, D3D11_FLOAT32_MAX,
+ };
+ pDevice->CreateSamplerState(pointClampSamplerDesc, &m_pSamplerStates[SAMPLER_TYPE_POINTCLAMP]);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void ClearRenderStates()
+{
+ for (int i = 0; i < RASTERIZER_STATE_END; i++)
+ SAFE_RELEASE(m_pRasterizerStates[i]);
+
+ for (int i = 0; i < DEPTH_STENCIL_STATE_END; i++)
+ SAFE_RELEASE(m_pDepthStencilStates[i]);
+
+ for (int i = 0; i < SAMPLER_TYPE_END; i++)
+ SAFE_RELEASE(m_pSamplerStates[i]);
+
+ for (int i = 0; i < BLEND_STATE_END; i++)
+ SAFE_RELEASE(m_pBlendStates[i]);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void BindVertexShaderResources( int startSlot, int numSRVs, ID3D11ShaderResourceView** ppSRVs)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ pDeviceContext->VSSetShaderResources( startSlot, numSRVs, ppSRVs);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void BindPixelShaderResources( int startSlot, int numSRVs, ID3D11ShaderResourceView** ppSRVs)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ pDeviceContext->PSSetShaderResources( startSlot, numSRVs, ppSRVs);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void BindVertexShaderResources( int startSlot, int numSRVs, GPUShaderResource** ppSRVs)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ for (int i = startSlot; i < (startSlot + numSRVs); i++)
+ {
+ ID3D11ShaderResourceView* pSRV = D3D11TextureResource::GetResource(ppSRVs[i]);
+ pDeviceContext->VSSetShaderResources( i, 1, &pSRV);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void BindPixelShaderResources( int startSlot, int numSRVs, GPUShaderResource** ppSRVs)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ for (int i = startSlot; i < (startSlot + numSRVs); i++)
+ {
+ ID3D11ShaderResourceView* pSRV = D3D11TextureResource::GetResource(ppSRVs[i]);
+ pDeviceContext->PSSetShaderResources( i, 1, &pSRV);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void ClearPixelShaderResources( int startSlot, int numSRVs)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ // clean up
+ ID3D11ShaderResourceView* ppSRVNull[128];
+ memset(&ppSRVNull, 0, sizeof(ID3D11ShaderResourceView*)*128);
+
+ pDeviceContext->PSSetShaderResources( startSlot, numSRVs, ppSRVNull);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void ClearVertexShaderResources( int startSlot, int numSRVs)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ // clean up
+ ID3D11ShaderResourceView* ppSRVNull[128];
+ memset(&ppSRVNull, 0, sizeof(ID3D11ShaderResourceView*)*128);
+
+ pDeviceContext->VSSetShaderResources( startSlot, numSRVs, ppSRVNull);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void ClearInputLayout()
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ pDeviceContext->IASetInputLayout(nullptr);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void SetPrimitiveTopologyTriangleStrip()
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ pDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void SetPrimitiveTopologyTriangleList()
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ pDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void SetPrimitiveTopologyLineList()
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ pDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_LINELIST );
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ ID3D11Buffer* pD3D11Buffer = GPUBufferD3D11::GetResource(pBuffer);
+ if (!pD3D11Buffer)
+ return;
+
+ pDeviceContext->IASetVertexBuffers( 0, 1, &pD3D11Buffer, &stride, &offset );
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void ApplySampler(int slot, RenderInterface::SAMPLER_TYPE st)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ pDeviceContext->PSSetSamplers(slot, 1, &m_pSamplerStates[st] );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void ApplyDepthStencilState(DEPTH_STENCIL_STATE state)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ pDeviceContext->OMSetDepthStencilState(m_pDepthStencilStates[state], 0);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void ApplyRasterizerState(RASTERIZER_STATE state)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ pDeviceContext->RSSetState(m_pRasterizerStates[state]);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void ApplyBlendState(BLEND_STATE st)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ float zerov[] = {0,0,0,0};
+
+ pDeviceContext->OMSetBlendState(m_pBlendStates[st], zerov, 0xffffffff);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+void SetViewport(const RenderInterface::Viewport& vp)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ D3D11_VIEWPORT d3dViewport;
+
+ d3dViewport.TopLeftX = vp.TopLeftX;
+ d3dViewport.TopLeftY = vp.TopLeftY;
+
+ d3dViewport.Width = vp.Width;
+ d3dViewport.Height = vp.Height;
+
+ d3dViewport.MinDepth = vp.MinDepth;
+ d3dViewport.MaxDepth = vp.MaxDepth;
+
+ pDeviceContext->RSSetViewports(1, &d3dViewport);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+void GetViewport(RenderInterface::Viewport& vp)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ UINT numViewports = 1;
+ D3D11_VIEWPORT d3dViewport;
+ pDeviceContext->RSGetViewports(&numViewports, &d3dViewport);
+
+ vp.TopLeftX = d3dViewport.TopLeftX;
+ vp.TopLeftY = d3dViewport.TopLeftY;
+
+ vp.Width = d3dViewport.Width;
+ vp.Height = d3dViewport.Height;
+
+ vp.MinDepth = d3dViewport.MinDepth;
+ vp.MaxDepth = d3dViewport.MaxDepth;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void Draw(unsigned int vertexCount, unsigned int startCount)
+{
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ pDeviceContext->Draw(vertexCount, startCount);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// gpu buffer management
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+ID3D11Buffer* CreateD3D11Buffer(
+ D3D11_USAGE Usage, UINT ByteWidth, UINT StructureByteStride,
+ UINT BindFlags, UINT MiscFlags,
+ UINT CPUAccessFlags, void *pSysMem)
+{
+ ID3D11Device* pDevice = RenderInterfaceD3D11::GetDevice();
+ if (!pDevice)
+ return 0;
+
+ D3D11_BUFFER_DESC desc;
+
+ desc.Usage = Usage;
+ desc.ByteWidth = ByteWidth;
+ desc.StructureByteStride = StructureByteStride;
+ desc.BindFlags = BindFlags;
+ desc.MiscFlags = MiscFlags;
+ desc.CPUAccessFlags = CPUAccessFlags;
+
+ D3D11_SUBRESOURCE_DATA InitData;
+
+ InitData.pSysMem = pSysMem;
+ InitData.SysMemPitch = 0;
+ InitData.SysMemSlicePitch = 0;
+
+ ID3D11Buffer* pBuffer = 0;
+
+ HRESULT hr = pSysMem ? pDevice->CreateBuffer( &desc, &InitData, &pBuffer)
+ : pDevice->CreateBuffer( &desc, 0, &pBuffer);
+
+ if( FAILED(hr) )
+ return 0;
+
+ return pBuffer;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+ID3D11ShaderResourceView*
+CreateD3D11ShaderResourceView(
+ ID3D11Buffer* pBuffer,
+ DXGI_FORMAT Format,
+ D3D11_SRV_DIMENSION ViewDimension,
+ UINT NumElements,
+ UINT FirstElement = 0
+ )
+{
+ ID3D11Device* pDevice = RenderInterfaceD3D11::GetDevice();
+ if (!pDevice)
+ return 0;
+
+ ID3D11ShaderResourceView* pSRV = 0;
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC desc;
+ {
+ desc.Format = Format;
+ desc.ViewDimension = ViewDimension;
+ desc.Buffer.FirstElement = FirstElement;
+ desc.Buffer.NumElements = NumElements;
+ }
+
+ pDevice->CreateShaderResourceView( pBuffer, &desc, &pSRV);
+
+ return pSRV;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+GPUBufferResource* CreateVertexBuffer(
+ unsigned int ByteWidth, void* pSysMem)
+{
+ ID3D11Buffer* pD3D11Buffer = CreateD3D11Buffer(D3D11_USAGE_DEFAULT,
+ ByteWidth, 0, D3D11_BIND_VERTEX_BUFFER, 0, 0, pSysMem);
+
+ return GPUBufferD3D11::Create(pD3D11Buffer);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+GPUShaderResource* CreateShaderResource( unsigned int stride, unsigned int numElements, void* pSysMem)
+{
+ unsigned int byteWidth = numElements * stride;
+
+ ID3D11Buffer* pBuffer = CreateD3D11Buffer(
+ D3D11_USAGE_DEFAULT, byteWidth, 0,
+ D3D11_BIND_SHADER_RESOURCE, 0, 0, pSysMem);
+
+ // create SRV for bone indices
+ ID3D11ShaderResourceView* pSRV = CreateD3D11ShaderResourceView(
+ pBuffer,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ D3D11_SRV_DIMENSION_BUFFER,
+ numElements);
+
+ SAFE_RELEASE(pBuffer); // dec ref count as this is not explicitly used later
+
+ return D3D11TextureResource::Create(pSRV);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// create read only shader resource buffer
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+void CopyToDevice(
+ GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth)
+{
+ ID3D11Buffer* pBuffer = GPUBufferD3D11::GetResource(pDevicePtr);
+ if (!pBuffer)
+ return;
+
+ ID3D11DeviceContext* pDeviceContext = GetDeviceContext();
+ if (!pDeviceContext)
+ return;
+
+ pDeviceContext->UpdateSubresource(pBuffer, 0, NV_NULL, pSysMem, ByteWidth, 0);
+}
+
+} // end namespace
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.h b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.h
new file mode 100644
index 0000000..e5f3c02
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.h
@@ -0,0 +1,90 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "d3d11.h"
+
+#include "RenderInterface.h"
+
+#include "RenderPlugin.h"
+
+#ifdef NV_ARTISTTOOLS
+enum HAIR_SHADER_TYPE
+{
+ SHADER_TYPE_HAIR_SHADER_DEFAULT = RenderInterface::SHADER_TYPE_SIMPLE_COLOR + 1,
+ SHADER_TYPE_HAIR_SHADER_SHADOW,
+};
+#endif
+
+// abstract interface to D3D calls
+namespace RenderInterfaceD3D11
+{
+ CORERENDER_EXPORT bool InitDevice(int deviceID);
+ CORERENDER_EXPORT bool Initialize();
+ CORERENDER_EXPORT void Shutdown();
+
+ CORERENDER_EXPORT ID3D11DeviceContext* GetDeviceContext();
+ CORERENDER_EXPORT ID3D11Device* GetDevice();
+ IDXGIFactory1* GetDXGIFactory();
+ IDXGIAdapter* GetAdapter();
+
+ CORERENDER_EXPORT void InitializeRenderStates();
+ CORERENDER_EXPORT void ClearRenderStates();
+
+ CORERENDER_EXPORT void ApplySampler(int slot, RenderInterface::SAMPLER_TYPE st);
+ CORERENDER_EXPORT void ApplyDepthStencilState(RenderInterface::DEPTH_STENCIL_STATE st);
+ CORERENDER_EXPORT void ApplyRasterizerState(RenderInterface::RASTERIZER_STATE st);
+ CORERENDER_EXPORT void ApplyBlendState(RenderInterface::BLEND_STATE st);
+
+ CORERENDER_EXPORT void GetViewport(RenderInterface::Viewport& vp);
+ CORERENDER_EXPORT void SetViewport(const RenderInterface::Viewport& vp);
+
+ CORERENDER_EXPORT void BindVertexShaderResources( int startSlot, int numSRVs, GPUShaderResource** ppSRVs);
+ CORERENDER_EXPORT void BindPixelShaderResources( int startSlot, int numSRVs, GPUShaderResource** ppSRVs);
+
+ CORERENDER_EXPORT void ClearVertexShaderResources( int startSlot, int numSRVs);
+ CORERENDER_EXPORT void ClearPixelShaderResources( int startSlot, int numSRVs);
+
+ CORERENDER_EXPORT GPUBufferResource* CreateVertexBuffer( unsigned int ByteWidth, void* pSysMem);
+ CORERENDER_EXPORT GPUShaderResource* CreateShaderResource( unsigned int stride, unsigned int numElements, void* pSysMem );
+
+ CORERENDER_EXPORT void CopyToDevice(GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth);
+
+ CORERENDER_EXPORT void ClearInputLayout();
+
+ CORERENDER_EXPORT void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset = 0);
+
+ CORERENDER_EXPORT void SetPrimitiveTopologyTriangleStrip();
+ CORERENDER_EXPORT void SetPrimitiveTopologyTriangleList();
+ CORERENDER_EXPORT void SetPrimitiveTopologyLineList();
+
+
+ CORERENDER_EXPORT void Draw(unsigned int vertexCount, unsigned int startCount = 0);
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.cpp
new file mode 100644
index 0000000..3a4d27e
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.cpp
@@ -0,0 +1,256 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#include "D3D11RenderShader.h"
+
+#include "D3D11RenderInterface.h"
+#include "D3D11Wrapper.h"
+#include "Nv.h"
+
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(x) { if (x) x->Release(); }
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+D3D11RenderShader::D3D11RenderShader() :
+ m_pVertexShader(0),
+ m_pPixelShader(0),
+ m_pInputLayout(0)
+{
+ for (int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT; i++)
+ {
+ m_pParamBuffers[i] = nullptr;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+D3D11RenderShader::~D3D11RenderShader()
+{
+ SAFE_RELEASE(m_pVertexShader);
+ SAFE_RELEASE(m_pPixelShader);
+ SAFE_RELEASE(m_pInputLayout);
+
+ for (int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT; i++)
+ SAFE_RELEASE(m_pParamBuffers[i]);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+D3D11RenderShader* D3D11RenderShader::Create(
+ const char *name,
+ void* pVSBlob, size_t vsBlobSize,
+ void* pPSBlob, size_t psBlobSize,
+ UINT cbufferSize0, UINT cbufferSize1,
+ D3D11_INPUT_ELEMENT_DESC* pElemDesc, UINT numElements)
+{
+ D3D11RenderShader* pShader = new D3D11RenderShader;
+
+ pShader->CreateVSFromBlob(pVSBlob, vsBlobSize, pElemDesc, numElements);
+ pShader->CreatePSFromBlob(pPSBlob, psBlobSize);
+
+ if (cbufferSize0 > 0)
+ {
+ pShader->CreateParamBuffer(cbufferSize0, 0);
+ SET_D3D_DEBUG_NAME(pShader->getParamBuffer(0), name);
+ }
+
+ if (cbufferSize1 > 0)
+ {
+ pShader->CreateParamBuffer(cbufferSize1, 1);
+ SET_D3D_DEBUG_NAME(pShader->getParamBuffer(1), name);
+ }
+
+ if (pShader->getVertexShader())
+ SET_D3D_DEBUG_NAME(pShader->getVertexShader(), name);
+
+ if (pShader->getPixelShader())
+ SET_D3D_DEBUG_NAME(pShader->getPixelShader(), name);
+
+ if (pShader->getInputLayout())
+ SET_D3D_DEBUG_NAME(pShader->getInputLayout(), name);
+
+ return pShader;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool D3D11RenderShader::CreateVSFromBlob(
+ void* pBlob, size_t blobSize,
+ D3D11_INPUT_ELEMENT_DESC *desc, int elemCount)
+{
+ ID3D11Device *pDevice = RenderInterfaceD3D11::GetDevice();
+ if (!pDevice)
+ return false;
+
+ if (!pBlob || (blobSize == 0))
+ return false;
+
+ SAFE_RELEASE(m_pVertexShader);
+ SAFE_RELEASE(m_pInputLayout);
+
+ HRESULT res = pDevice->CreateVertexShader(pBlob, blobSize, NV_NULL, &m_pVertexShader);
+
+ if(FAILED(res)) return false;
+
+ if (desc)
+ {
+ res = pDevice->CreateInputLayout(desc, elemCount,
+ pBlob, blobSize, &m_pInputLayout);
+
+ if(FAILED(res)) return false;
+ }
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool D3D11RenderShader::CreatePSFromBlob(void* pBlob, size_t blobSize)
+{
+ ID3D11Device* pDevice = RenderInterfaceD3D11::GetDevice();
+ if (!pDevice)
+ return false;
+
+ if (!pBlob || (blobSize == 0))
+ return false;
+
+ SAFE_RELEASE(m_pPixelShader);
+
+ HRESULT res = pDevice->CreatePixelShader(pBlob, blobSize, NV_NULL, &m_pPixelShader);
+
+ if (FAILED(res))
+ return false;
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D11RenderShader::SetConstantBuffer()
+{
+ ID3D11DeviceContext* pContext = RenderInterfaceD3D11::GetDeviceContext();
+
+ //for (int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT; i++)
+ for (int i = 0; i < 2; i++)
+ {
+ pContext->PSSetConstantBuffers(i, 1, &m_pParamBuffers[i]);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D11RenderShader::MakeCurrent()
+{
+ ID3D11DeviceContext* pContext = RenderInterfaceD3D11::GetDeviceContext();
+
+ if (m_pInputLayout)
+ pContext->IASetInputLayout(m_pInputLayout);
+ else
+ pContext->IASetInputLayout(NV_NULL);
+
+
+ if (m_pVertexShader)
+ {
+ pContext->VSSetShader( m_pVertexShader, NV_NULL, 0);
+ if (m_pParamBuffers[0])
+ pContext->VSSetConstantBuffers(0, 1, &m_pParamBuffers[0]);
+ }
+
+ if (m_pPixelShader)
+ {
+ pContext->PSSetShader( m_pPixelShader, NV_NULL, 0);
+ if (m_pParamBuffers[0])
+ pContext->PSSetConstantBuffers(0, 1, &m_pParamBuffers[0]);
+ if (m_pParamBuffers[1])
+ pContext->PSSetConstantBuffers(1, 1, &m_pParamBuffers[1]);
+ }
+
+ pContext->GSSetShader( 0, 0, 0);
+ pContext->DSSetShader( 0, 0, 0);
+ pContext->HSSetShader( 0, 0, 0);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D11RenderShader::Disable()
+{
+ ID3D11DeviceContext* pContext = RenderInterfaceD3D11::GetDeviceContext();
+
+ pContext->IASetInputLayout(NV_NULL);
+
+ pContext->VSSetShader( 0, NV_NULL, 0);
+ pContext->PSSetShader( 0, NV_NULL, 0);
+ pContext->GSSetShader( 0, 0, 0);
+ pContext->DSSetShader( 0, 0, 0);
+ pContext->HSSetShader( 0, 0, 0);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool D3D11RenderShader::CreateParamBuffer( UINT sizeBuffer, UINT slot )
+{
+ ID3D11Device* pDevice = RenderInterfaceD3D11::GetDevice();
+ if (!pDevice)
+ return false;
+
+ SAFE_RELEASE(m_pParamBuffers[slot]);
+
+ D3D11_BUFFER_DESC Desc;
+ {
+ Desc.Usage = D3D11_USAGE_DYNAMIC;
+ Desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ Desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ Desc.MiscFlags = 0;
+ Desc.ByteWidth = sizeBuffer;
+ }
+
+ HRESULT hr = pDevice->CreateBuffer( &Desc, NV_NULL, &m_pParamBuffers[slot] );
+ if( FAILED(hr) )
+ false;
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void* D3D11RenderShader::MapParam(UINT slot)
+{
+ ID3D11DeviceContext* pContext = RenderInterfaceD3D11::GetDeviceContext();
+
+ if (!m_pParamBuffers[slot] || !pContext)
+ return 0;
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ HRESULT hr = pContext->Map(m_pParamBuffers[slot], 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+
+ if ( FAILED(hr))
+ return 0;
+
+ return mappedResource.pData;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D11RenderShader::UnmapParam( UINT slot )
+{
+ ID3D11DeviceContext* pContext = RenderInterfaceD3D11::GetDeviceContext();
+
+ if (pContext && m_pParamBuffers[slot])
+ pContext->Unmap( m_pParamBuffers[slot], 0);
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.h b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.h
new file mode 100644
index 0000000..1aad045
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.h
@@ -0,0 +1,72 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include <d3d11.h>
+#include "RenderPlugin.h"
+
+class CORERENDER_EXPORT D3D11RenderShader
+{
+public:
+ D3D11RenderShader();
+ ~D3D11RenderShader();
+
+ static D3D11RenderShader* Create(
+ const char *name,
+ void* pVSBlob, size_t vsBlobSize,
+ void* pPSBlob, size_t psBlobSize,
+ UINT cbufferSize0 = 0, UINT cbufferSize1 = 0,
+ D3D11_INPUT_ELEMENT_DESC* pElemDesc = 0, UINT numElements = 0);
+
+ void MakeCurrent();
+ void Disable();
+ void SetConstantBuffer();
+
+ void* MapParam(UINT slot = 0);
+ void UnmapParam(UINT slot = 0);
+
+ ID3D11VertexShader* getVertexShader() { return m_pVertexShader; }
+ ID3D11PixelShader* getPixelShader() { return m_pPixelShader; }
+ ID3D11InputLayout* getInputLayout() { return m_pInputLayout; }
+ ID3D11Buffer* getParamBuffer(UINT slot = 0) { return m_pParamBuffers[slot]; }
+
+protected:
+ bool CreateVSFromBlob(void* pBlob, size_t blobSize,
+ D3D11_INPUT_ELEMENT_DESC *desc, int elemCount);
+ bool CreatePSFromBlob(void* pBlob, size_t blobSize);
+ bool CreateParamBuffer(UINT sizeBuffer, UINT slot = 0);
+
+private:
+
+ ID3D11VertexShader* m_pVertexShader;
+ ID3D11PixelShader* m_pPixelShader;
+ ID3D11InputLayout* m_pInputLayout;
+ ID3D11Buffer* m_pParamBuffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT];
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.cpp
new file mode 100644
index 0000000..1274ed5
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.cpp
@@ -0,0 +1,319 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D11RendererWindow.h"
+
+#include "windows.h"
+
+#include "DXUT.h"
+#include "DXUTgui.h"
+#include "sdkmisc.h"
+
+#include "D3D11RenderInterface.h"
+#include "Nv.h"
+#ifdef USE_11ON12_WRAPPER
+#include "D3D11on12Wrapper.h"
+#endif // USE_11ON12_WRAPPER
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; }
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+D3D11RenderWindow::D3D11RenderWindow() :
+ m_sampleCount(8)
+ , m_sampleQuality(0)
+#ifdef USE_11ON12_WRAPPER
+#else
+ , m_pDXGISwapChain(NV_NULL)
+ , m_pD3D11BackBuffer(NV_NULL)
+ , m_pD3D11DepthBuffer(NV_NULL)
+ , m_pD3D11RenderTargetView(NV_NULL)
+ , m_pD3D11DepthStencilView(NV_NULL)
+#endif // USE_11ON12_WRAPPER
+{
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+D3D11RenderWindow::~D3D11RenderWindow()
+{
+ Free();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool D3D11RenderWindow::Create( HWND hWnd, unsigned int nSamples )
+{
+#ifdef USE_11ON12_WRAPPER
+#else
+ if (m_pD3D11BackBuffer != NV_NULL || m_pD3D11RenderTargetView != NV_NULL)
+ Free();
+#endif // USE_11ON12_WRAPPER
+
+ ID3D11Device *pDevice = RenderInterfaceD3D11::GetDevice();
+ if (!pDevice)
+ return false;
+
+ ID3D11DeviceContext* pDeviceContext = RenderInterfaceD3D11::GetDeviceContext();
+ if (!pDeviceContext)
+ return false;
+
+ if(nSamples > D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT)
+ nSamples = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT;
+
+ m_sampleCount = nSamples;
+ m_sampleQuality = 0;
+ if(nSamples > 1)
+ {
+ pDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, nSamples, &m_sampleQuality);
+ assert(m_sampleQuality > 0);
+ m_sampleQuality--;
+ }
+
+ RECT rc;
+ GetClientRect((HWND)hWnd, &rc);
+ int wBuf = rc.right - rc.left;
+ int hBuf = rc.bottom- rc.top;
+
+#ifdef USE_11ON12_WRAPPER
+ D3D11on12Wrapper::InitSwapchain(wBuf, hBuf, hWnd);
+#else
+ DXGI_SWAP_CHAIN_DESC swapChainDesc;
+ {
+ memset(&swapChainDesc, 0, sizeof(DXGI_SWAP_CHAIN_DESC));
+ swapChainDesc.BufferDesc.Width = wBuf;
+ swapChainDesc.BufferDesc.Height= hBuf;
+ swapChainDesc.BufferDesc.Format= DXGI_FORMAT_R8G8B8A8_UNORM;
+ swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
+ swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
+ swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+ swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+
+ swapChainDesc.BufferCount = 1;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+ swapChainDesc.OutputWindow = (HWND)hWnd;
+ swapChainDesc.SampleDesc.Count = m_sampleCount;
+ swapChainDesc.SampleDesc.Quality = m_sampleQuality;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+ swapChainDesc.Windowed = true;
+ }
+
+ // Create the swap chain
+ IDXGIFactory1* pDXGIFactory = RenderInterfaceD3D11::GetDXGIFactory();
+ HRESULT res = pDXGIFactory->CreateSwapChain(pDevice, &swapChainDesc, &m_pDXGISwapChain);
+ if (FAILED(res)) return false;
+#endif // USE_11ON12_WRAPPER
+
+ // create DXUT text rendering class
+ m_pDialogResourceManager = new CDXUTDialogResourceManager;
+ m_pDialogResourceManager->OnD3D11CreateDevice(pDevice, pDeviceContext);
+ m_pTextHelper = new CDXUTTextHelper( pDevice, pDeviceContext, m_pDialogResourceManager, 15 );
+
+ CreateRenderTarget();
+ Resize(wBuf, hBuf);
+ return true;// SUCCEEDED(res);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D11RenderWindow::Free()
+{
+ FreeBuffer();
+
+ SAFE_DELETE(m_pTextHelper);
+
+#ifdef USE_11ON12_WRAPPER
+#else
+ SAFE_RELEASE(m_pDXGISwapChain);
+#endif // USE_11ON12_WRAPPER
+
+ if (m_pDialogResourceManager)
+ {
+ m_pDialogResourceManager->OnD3D11DestroyDevice();
+ SAFE_DELETE(m_pDialogResourceManager);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D11RenderWindow::FreeBuffer()
+{
+#ifdef USE_11ON12_WRAPPER
+#else
+ SAFE_RELEASE(m_pD3D11RenderTargetView);
+ SAFE_RELEASE(m_pD3D11BackBuffer);
+ SAFE_RELEASE(m_pD3D11DepthStencilView);
+ SAFE_RELEASE(m_pD3D11DepthBuffer);
+#endif // USE_11ON12_WRAPPER
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D11RenderWindow::Present()
+{
+#ifdef USE_11ON12_WRAPPER
+ D3D11on12Wrapper::EndScene();
+#else
+ assert(m_pDXGISwapChain);
+
+ if(m_pDXGISwapChain)
+ {
+ //m_pDXGISwapChain->Present(1, 0); // present in vsync
+ m_pDXGISwapChain->Present(0, 0); // present in vsync off
+ }
+#endif // USE_11ON12_WRAPPER
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D11RenderWindow::Clear(float r, float g, float b)
+{
+#ifdef USE_11ON12_WRAPPER
+ D3D11on12Wrapper::BeginScene();
+ D3D11on12Wrapper::ClearScene(r, g, b);
+#else
+ const float clearColor[4] = {r, g, b, 1.0f};
+
+ ID3D11DeviceContext* pD3DContext = RenderInterfaceD3D11::GetDeviceContext();
+ pD3DContext->ClearRenderTargetView(m_pD3D11RenderTargetView, clearColor);
+ pD3DContext->ClearDepthStencilView(m_pD3D11DepthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0);
+#endif // USE_11ON12_WRAPPER
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool D3D11RenderWindow::Resize(int w, int h)
+{
+ assert(w > 0 && h > 0);
+ DXGI_SWAP_CHAIN_DESC swapChainDesc;
+ HRESULT res0 = m_pDXGISwapChain->GetDesc(&swapChainDesc);
+ if (w == (LONG)swapChainDesc.BufferDesc.Width &&
+ h == (LONG)swapChainDesc.BufferDesc.Height)
+ return true;
+
+#ifdef USE_11ON12_WRAPPER
+#else
+ //ID3D11DeviceContext* pD3DContext = RenderInterfaceD3D11::GetDeviceContext();
+ //ID3D11RenderTargetView *nullRTV = NULL;
+ //pD3DContext->OMSetRenderTargets(1, &nullRTV, NULL);
+ FreeBuffer();
+ swapChainDesc.BufferDesc.Width = w;
+ swapChainDesc.BufferDesc.Height = h;
+ //HRESULT res = m_pDXGISwapChain->ResizeBuffers(1, w, h, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
+ HRESULT res = m_pDXGISwapChain->ResizeBuffers(swapChainDesc.BufferCount, swapChainDesc.BufferDesc.Width,
+ swapChainDesc.BufferDesc.Height, swapChainDesc.BufferDesc.Format,
+ swapChainDesc.Flags);
+ assert(SUCCEEDED(res));
+#endif
+ return CreateRenderTarget();
+}
+
+bool D3D11RenderWindow::CreateRenderTarget()
+{
+#ifdef USE_11ON12_WRAPPER
+ D3D11on12Wrapper::ResizeScene(w, h);
+#else
+ ID3D11Device* pDevice = RenderInterfaceD3D11::GetDevice();
+ // Retrieve the 2D back buffer
+ HRESULT res = m_pDXGISwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&m_pD3D11BackBuffer);
+ assert(SUCCEEDED(res));
+
+ D3D11_TEXTURE2D_DESC descTex2D;
+ m_pD3D11BackBuffer->GetDesc(&descTex2D);
+
+ // Create the render target view
+ D3D11_RENDER_TARGET_VIEW_DESC descRenderTargetView;
+ {
+ memset(&descRenderTargetView, 0, sizeof(D3D11_RENDER_TARGET_VIEW_DESC));
+ descRenderTargetView.Format = descTex2D.Format;
+ descRenderTargetView.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; // -MS dimension to support MSAA
+ descRenderTargetView.Texture2D.MipSlice = 0;
+ }
+
+ res = pDevice->CreateRenderTargetView(m_pD3D11BackBuffer, &descRenderTargetView, &m_pD3D11RenderTargetView);
+
+ assert(SUCCEEDED(res));
+
+ DXGI_SWAP_CHAIN_DESC swapChainDesc;
+ HRESULT res0 = m_pDXGISwapChain->GetDesc(&swapChainDesc);
+ // Create the depth/stencil buffer and view
+ D3D11_TEXTURE2D_DESC depthStencilDesc;
+
+ depthStencilDesc.Width = swapChainDesc.BufferDesc.Width;
+ depthStencilDesc.Height = swapChainDesc.BufferDesc.Height;
+ depthStencilDesc.MipLevels = 1;
+ depthStencilDesc.ArraySize = 1;
+ depthStencilDesc.Format = DXGI_FORMAT_R24G8_TYPELESS;
+ depthStencilDesc.SampleDesc.Count = m_sampleCount;
+ depthStencilDesc.SampleDesc.Quality = m_sampleQuality;
+ depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
+ depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
+ depthStencilDesc.CPUAccessFlags = 0;
+ depthStencilDesc.MiscFlags = 0;
+
+ res = pDevice->CreateTexture2D(&depthStencilDesc, 0, &m_pD3D11DepthBuffer);
+ assert(SUCCEEDED(res));
+
+ D3D11_DEPTH_STENCIL_VIEW_DESC descDepthStencilView;
+ memset(&descDepthStencilView, 0, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC));
+ descDepthStencilView.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
+ descDepthStencilView.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; // -MS dimension to support MSAA
+ descDepthStencilView.Texture2D.MipSlice = 0;
+
+ res = pDevice->CreateDepthStencilView(m_pD3D11DepthBuffer, &descDepthStencilView, &m_pD3D11DepthStencilView);
+ assert(SUCCEEDED(res));
+
+ m_Width = swapChainDesc.BufferDesc.Width;
+ m_Height= swapChainDesc.BufferDesc.Height;
+
+ /////////////////////////////////////////
+ if (m_pDialogResourceManager)
+ {
+ DXGI_SURFACE_DESC backbufferDesc;
+ backbufferDesc.Width = descTex2D.Width;
+ backbufferDesc.Height = descTex2D.Height;
+ backbufferDesc.Format = descTex2D.Format;
+ backbufferDesc.SampleDesc = descTex2D.SampleDesc;
+
+ m_pDialogResourceManager->OnD3D11ResizedSwapChain(pDevice, &backbufferDesc);
+ }
+
+ // assume always the current render window, bind to render context immediately
+ ID3D11DeviceContext* pD3DContext = RenderInterfaceD3D11::GetDeviceContext();
+ pD3DContext->OMSetRenderTargets(1, &m_pD3D11RenderTargetView, m_pD3D11DepthStencilView);
+
+ // set the viewport transform
+ D3D11_VIEWPORT vp;
+ {
+ vp.TopLeftX = 0;
+ vp.TopLeftY = 0;
+ vp.Width = (float)m_Width;
+ vp.Height = (float)m_Height;
+ vp.MinDepth = 0.0f;
+ vp.MaxDepth = 1.0f;
+ }
+ pD3DContext->RSSetViewports(1, &vp);
+#endif // USE_11ON12_WRAPPER
+
+ return true;
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.h b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.h
new file mode 100644
index 0000000..88d5c8f
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <d3d11.h>
+
+// DXUT stuffs for text rendering
+class CDXUTDialogResourceManager;
+class CDXUTTextHelper;
+
+struct D3D11RenderWindow
+{
+public:
+ D3D11RenderWindow();
+ ~D3D11RenderWindow();
+
+ bool Create(HWND hWnd, unsigned int nSamples = 1);
+ bool Resize(int w, int h);
+ void Present();
+ void Clear(float r, float g, float b);
+ bool CreateRenderTarget();
+
+ // sample desc
+ UINT m_sampleCount;
+ UINT m_sampleQuality;
+#ifdef USE_11ON12_WRAPPER
+#else
+ int m_Height, m_Width;
+
+ IDXGISwapChain* m_pDXGISwapChain;
+ ID3D11Texture2D* m_pD3D11BackBuffer;
+ ID3D11Texture2D* m_pD3D11DepthBuffer;
+ ID3D11RenderTargetView* m_pD3D11RenderTargetView;
+ ID3D11DepthStencilView* m_pD3D11DepthStencilView;
+#endif // USE_11ON12_WRAPPER
+
+ CDXUTDialogResourceManager* m_pDialogResourceManager;
+ CDXUTTextHelper* m_pTextHelper;
+
+private:
+ void Free();
+ void FreeBuffer();
+
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.cpp
new file mode 100644
index 0000000..eba1184
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.cpp
@@ -0,0 +1,225 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D11Shaders.h"
+
+#include "MeshShaderParam.h"
+#include "LightShaderParam.h"
+
+//#include <Nv/Blast/NvHairSdk.h>
+#include "D3D11RenderShader.h"
+
+using namespace RenderInterface;
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Common shader settings
+//static D3D11RenderShader* g_pShaders[SHADER_TYPE_END];
+static std::map<int, D3D11RenderShader*> g_pShaders;
+/*
+namespace BodyShaderBlobs
+{
+ #include "Shaders/BodyShader_VS.h"
+ #include "Shaders/BodyShader_PS.h"
+}
+
+namespace BodyShadowBlobs
+{
+ #include "Shaders/BodyShadow_VS.h"
+ #include "Shaders/BodyShadow_PS.h"
+}
+
+namespace ScreenQuadBlobs
+{
+ #include "Shaders/ScreenQuad_VS.h"
+ #include "Shaders/ScreenQuad_PS.h"
+}
+
+namespace ScreenQuadColorBlobs
+{
+ #include "Shaders/ScreenQuadColor_VS.h"
+ #include "Shaders/ScreenQuadColor_PS.h"
+}
+
+namespace VisualizeShadowBlobs
+{
+ #include "Shaders/VisualizeShadow_VS.h"
+ #include "Shaders/VisualizeShadow_PS.h"
+}
+
+namespace ColorBlobs
+{
+ #include "Shaders/Color_VS.h"
+ #include "Shaders/Color_PS.h"
+}
+
+#ifndef NV_ARTISTTOOLS
+namespace BlastShaderBlobs
+{
+#include "Shaders/BlastShader_PS.h"
+}
+
+namespace BlastShadowBlobs
+{
+#include "Shaders/BlastShadow_PS.h"
+}
+#endif // NV_ARTISTTOOLS
+*/
+//////////////////////////////////////////////////////////////////////////
+bool InitializeShadersD3D11()
+{
+ /*
+ D3D11_INPUT_ELEMENT_DESC layoutBodyRender[] =
+ {
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "VERTEX_NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "FACE_NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 36, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "VERTEX_ID", 0, DXGI_FORMAT_R32_FLOAT, 0, 56, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ };
+
+ UINT numElements = sizeof(layoutBodyRender)/sizeof(D3D11_INPUT_ELEMENT_DESC);
+
+ g_pShaders[SHADER_TYPE_MESH_RENDERING] = D3D11RenderShader::Create( "MeshRenderShader",
+ (void*)BodyShaderBlobs::g_vs_main, sizeof(BodyShaderBlobs::g_vs_main),
+ (void*)BodyShaderBlobs::g_ps_main, sizeof(BodyShaderBlobs::g_ps_main),
+ sizeof(MeshShaderParam), 0,
+ &layoutBodyRender[0], numElements);
+
+ g_pShaders[SHADER_TYPE_MESH_SHADOW] = D3D11RenderShader::Create( "MeshShadowShader",
+ (void*)BodyShadowBlobs::g_vs_main, sizeof(BodyShadowBlobs::g_vs_main),
+ (void*)BodyShadowBlobs::g_ps_main, sizeof(BodyShadowBlobs::g_ps_main),
+ sizeof(MeshShadowShaderParam), 0,
+ &layoutBodyRender[0], numElements);
+
+ g_pShaders[SHADER_TYPE_SCREEN_QUAD] = D3D11RenderShader::Create( "ScreenQuadShader",
+ (void*)ScreenQuadBlobs::g_vs_main, sizeof(ScreenQuadBlobs::g_vs_main),
+ (void*)ScreenQuadBlobs::g_ps_main, sizeof(ScreenQuadBlobs::g_ps_main));
+
+ g_pShaders[SHADER_TYPE_SCREEN_QUAD_COLOR] = D3D11RenderShader::Create( "ScreenQuadColorShader",
+ (void*)ScreenQuadColorBlobs::g_vs_main, sizeof(ScreenQuadColorBlobs::g_vs_main),
+ (void*)ScreenQuadColorBlobs::g_ps_main, sizeof(ScreenQuadColorBlobs::g_ps_main));
+
+ g_pShaders[SHADER_TYPE_VISUALIZE_SHADOW] = D3D11RenderShader::Create( "VisualizeShadowShader",
+ (void*)VisualizeShadowBlobs::g_vs_main, sizeof(VisualizeShadowBlobs::g_vs_main),
+ (void*)VisualizeShadowBlobs::g_ps_main, sizeof(VisualizeShadowBlobs::g_ps_main),
+ sizeof(ShadowVizParam));
+
+ D3D11_INPUT_ELEMENT_DESC layout_Position_And_Color[] =
+ {
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ };
+ UINT numElements2 = sizeof(layout_Position_And_Color)/sizeof(D3D11_INPUT_ELEMENT_DESC);
+
+ g_pShaders[SHADER_TYPE_SIMPLE_COLOR] = D3D11RenderShader::Create( "Color",
+ (void*)ColorBlobs::g_vs_main, sizeof(ColorBlobs::g_vs_main),
+ (void*)ColorBlobs::g_ps_main, sizeof(ColorBlobs::g_ps_main),
+ sizeof(SimpleShaderParam), 0,
+ &layout_Position_And_Color[0], numElements2);
+
+#ifndef NV_ARTISTTOOLS
+ g_pShaders[SHADER_TYPE_HAIR_SHADER_DEFAULT] = D3D11RenderShader::Create(
+ "hairShaderDefault", 0, 0,
+ (void*)BlastShaderBlobs::g_ps_main, sizeof(BlastShaderBlobs::g_ps_main),
+ sizeof(NvHair::ShaderConstantBuffer),
+ sizeof(LightShaderParam)
+ );
+
+ g_pShaders[SHADER_TYPE_HAIR_SHADER_SHADOW] = D3D11RenderShader::Create(
+ "hairShadow", 0, 0,
+ (void*)BlastShadowBlobs::g_ps_main, sizeof(BlastShadowBlobs::g_ps_main),
+ sizeof(NvHair::ShaderConstantBuffer),
+ 0);
+#else
+ CoreLib::Inst()->D3D11Shaders_InitializeShadersD3D11(g_pShaders);
+#endif // NV_ARTISTTOOLS
+ */
+ return true;
+}
+
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; }
+#endif
+
+#ifndef SAFE_DELETE
+#define SAFE_DELETE(x) { if (x) delete x; x = 0; }
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+void DestroyShadersD3D11()
+{
+ for (int i = 0; i < g_pShaders.size(); i++)
+ {
+ D3D11RenderShader*& pShader = g_pShaders[i];
+ if (pShader)
+ {
+ delete pShader;
+ pShader = 0;
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+D3D11RenderShader* GetShaderD3D11(SHADER_TYPE st)
+{
+ return g_pShaders[st];
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void ApplyShaderD3D11(SHADER_TYPE st)
+{
+ D3D11RenderShader* pD3D11Shader = GetShaderD3D11(st);
+ if (!pD3D11Shader)
+ return;
+
+ pD3D11Shader->MakeCurrent();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void DisableShaderD3D11(RenderInterface::SHADER_TYPE st)
+{
+ D3D11RenderShader* pD3D11Shader = GetShaderD3D11(st);
+ if (!pD3D11Shader)
+ return;
+
+ pD3D11Shader->Disable();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void CopyShaderParamD3D11(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot)
+{
+ D3D11RenderShader* pD3D11Shader = GetShaderD3D11(st);
+ if (!pD3D11Shader)
+ return;
+
+ void* mappedParam = pD3D11Shader->MapParam(slot);
+
+ memcpy(mappedParam, pSysMem, bytes);
+
+ pD3D11Shader->UnmapParam(slot);
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.h b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.h
new file mode 100644
index 0000000..b1d4929
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.h
@@ -0,0 +1,43 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "RenderInterface.h"
+
+#include "RenderPlugin.h"
+
+///////////////////////////////////////////////////////////////////
+// default shaders
+///////////////////////////////////////////////////////////////////
+CORERENDER_EXPORT bool InitializeShadersD3D11();
+CORERENDER_EXPORT void DestroyShadersD3D11();
+
+CORERENDER_EXPORT void ApplyShaderD3D11(RenderInterface::SHADER_TYPE st);
+CORERENDER_EXPORT void DisableShaderD3D11(RenderInterface::SHADER_TYPE st);
+CORERENDER_EXPORT void CopyShaderParamD3D11(RenderInterface::SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot = 0);
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.cpp
new file mode 100644
index 0000000..90e30b2
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.cpp
@@ -0,0 +1,208 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D11ShadowMap.h"
+
+#include "RenderResources.h"
+
+#include "D3D11RenderInterface.h"
+#include "D3D11TextureResource.h"
+
+namespace
+{
+//////////////////////////////////////////////////////////////////////////////////////////////////
+D3D11_TEXTURE2D_DESC CreateD3D11TextureDesc(
+ DXGI_FORMAT Format, UINT Width, UINT Height,
+ UINT BindFlags, UINT SampleCount = 1, D3D11_USAGE Usage = D3D11_USAGE_DEFAULT, UINT CPUAccessFlags = 0,
+ UINT MiscFlags = 0, UINT ArraySize = 1, UINT MipLevels = 1)
+{
+
+ D3D11_TEXTURE2D_DESC desc;
+
+ desc.Format = Format;
+ desc.Width = Width;
+ desc.Height = Height;
+
+ desc.ArraySize = ArraySize;
+ desc.MiscFlags = MiscFlags;
+ desc.MipLevels = MipLevels;
+
+ desc.SampleDesc.Count = SampleCount;
+ desc.SampleDesc.Quality = 0;
+ desc.BindFlags = BindFlags;
+ desc.Usage = Usage;
+ desc.CPUAccessFlags = CPUAccessFlags;
+
+ return desc;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+D3D11_DEPTH_STENCIL_VIEW_DESC CreateD3D11DSVDesc(
+ DXGI_FORMAT Format, D3D11_DSV_DIMENSION ViewDimension,
+ UINT Flags = 0, UINT MipSlice = 0)
+{
+ D3D11_DEPTH_STENCIL_VIEW_DESC desc;
+
+ desc.Format = Format;
+ desc.ViewDimension = ViewDimension;
+ desc.Flags = Flags;
+ desc.Texture2D.MipSlice = MipSlice;
+
+ return desc;
+}
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+D3D11ShadowMap::D3D11ShadowMap(int resolution)
+{
+ m_pShadowTexture = nullptr;
+ m_pShadowRTV = nullptr;
+ m_pShadowSRV = nullptr;
+
+ m_pDepthTexture = nullptr;
+ m_pDepthDSV = nullptr;
+
+ ID3D11Device* pd3dDevice = RenderInterfaceD3D11::GetDevice();
+ if (!pd3dDevice)
+ return;
+
+ {
+ m_viewport.Width = float(resolution);
+ m_viewport.Height = float(resolution);
+ m_viewport.MinDepth = 0;
+ m_viewport.MaxDepth = 1;
+ m_viewport.TopLeftX = 0;
+ m_viewport.TopLeftY = 0;
+ }
+
+ HRESULT hr;
+
+ // create shadow render target
+ {
+ D3D11_TEXTURE2D_DESC texDesc = CreateD3D11TextureDesc(
+ DXGI_FORMAT_R32_FLOAT, UINT(m_viewport.Width), UINT(m_viewport.Height),
+ D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
+
+ hr = pd3dDevice->CreateTexture2D( &texDesc, NULL, &m_pShadowTexture );
+ hr = pd3dDevice->CreateShaderResourceView( m_pShadowTexture, NULL, &m_pShadowSRV );
+ hr = pd3dDevice->CreateRenderTargetView(m_pShadowTexture, NULL, &m_pShadowRTV);
+
+ m_shadowResource.m_pD3D11Resource = m_pShadowSRV;
+ }
+
+ // create shadow depth stencil
+ {
+ D3D11_TEXTURE2D_DESC texDesc = CreateD3D11TextureDesc(
+ DXGI_FORMAT_R32_TYPELESS, UINT(m_viewport.Width), UINT(m_viewport.Height),
+ D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE);
+
+ hr = pd3dDevice->CreateTexture2D( &texDesc, NULL, &m_pDepthTexture );
+
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc = CreateD3D11DSVDesc(
+ DXGI_FORMAT_D32_FLOAT, D3D11_DSV_DIMENSION_TEXTURE2D);
+
+ hr = pd3dDevice->CreateDepthStencilView(m_pDepthTexture, &dsvDesc, &m_pDepthDSV);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+D3D11ShadowMap::~D3D11ShadowMap()
+{
+ Release();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void D3D11ShadowMap::Release()
+{
+ SAFE_RELEASE(m_pShadowTexture);
+ SAFE_RELEASE(m_pShadowRTV);
+ SAFE_RELEASE(m_pShadowSRV);
+ SAFE_RELEASE(m_pDepthTexture);
+ SAFE_RELEASE(m_pDepthDSV);
+
+ m_shadowResource.m_pD3D11Resource = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+GPUShaderResource* D3D11ShadowMap::GetShadowSRV()
+{
+ return &m_shadowResource;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool D3D11ShadowMap::isValid()
+{
+ return m_pShadowTexture && m_pShadowRTV && m_pShadowSRV && m_pDepthTexture && m_pDepthDSV;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void D3D11ShadowMap::BeginRendering(float clearDepth)
+{
+ if (!isValid())
+ return;
+
+ ID3D11DeviceContext* pd3dContext = RenderInterfaceD3D11::GetDeviceContext();
+ if (!pd3dContext)
+ return;
+
+ pd3dContext->OMGetRenderTargets(1, &m_pPreviousRTV, &m_pPreviousDSV);
+ m_numPreviousViewports = 1;
+ pd3dContext->RSGetViewports(&m_numPreviousViewports, m_previousViewport);
+
+ pd3dContext->OMSetRenderTargets( 1, &m_pShadowRTV, m_pDepthDSV);
+ pd3dContext->RSSetViewports(1, &m_viewport);
+
+ float ClearColor[4] = { clearDepth, clearDepth, clearDepth, clearDepth};
+
+ pd3dContext->ClearRenderTargetView( m_pShadowRTV, ClearColor );
+ pd3dContext->ClearDepthStencilView( m_pDepthDSV, D3D11_CLEAR_DEPTH, 1.0, 0 );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void D3D11ShadowMap::EndRendering()
+{
+ if (!isValid())
+ return;
+
+ ID3D11DeviceContext* pd3dContext = RenderInterfaceD3D11::GetDeviceContext();
+ if (!pd3dContext)
+ return;
+
+ pd3dContext->OMSetRenderTargets(0, NULL, NULL);
+
+ if (m_pPreviousRTV)
+ {
+ pd3dContext->OMSetRenderTargets(1, &m_pPreviousRTV, m_pPreviousDSV);
+ m_pPreviousRTV->Release();
+ if (m_pPreviousDSV) m_pPreviousDSV->Release();
+ }
+
+ if (m_numPreviousViewports)
+ pd3dContext->RSSetViewports(m_numPreviousViewports, m_previousViewport);
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.h b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.h
new file mode 100644
index 0000000..fc9fe79
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.h
@@ -0,0 +1,72 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "ShadowMap.h"
+
+#include "d3d11.h"
+#include "D3D11TextureResource.h"
+
+class GPUShaderResource;
+class D3D11TextureResource;
+
+struct D3D11ShadowMap : public ShadowMap
+{
+ D3D11_VIEWPORT m_viewport;
+
+ ID3D11Texture2D* m_pShadowTexture;
+ ID3D11RenderTargetView* m_pShadowRTV;
+ ID3D11ShaderResourceView* m_pShadowSRV;
+
+ ID3D11Texture2D* m_pDepthTexture;
+ ID3D11DepthStencilView* m_pDepthDSV;
+ ID3D11ShaderResourceView* m_pDepthSRV;
+
+ D3D11TextureResource m_shadowResource;
+
+public:
+ D3D11ShadowMap(int resolution );
+ ~D3D11ShadowMap();
+
+ void Release();
+ void BeginRendering(float clearDepth);
+ void EndRendering();
+
+ GPUShaderResource* GetShadowSRV();
+
+protected:
+
+ bool isValid();
+
+ ID3D11RenderTargetView* m_pPreviousRTV;
+ ID3D11DepthStencilView* m_pPreviousDSV;
+ UINT m_numPreviousViewports;
+ D3D11_VIEWPORT m_previousViewport[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.cpp
new file mode 100644
index 0000000..2a8f7ee
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.cpp
@@ -0,0 +1,29 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D11TextureResource.h"
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.h b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.h
new file mode 100644
index 0000000..91d6539
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.h
@@ -0,0 +1,64 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "RenderResources.h"
+
+#include "d3d11.h"
+
+// GPU resources for texture
+struct D3D11TextureResource : public GPUShaderResource
+{
+ ID3D11ShaderResourceView* m_pD3D11Resource;
+
+public:
+ static GPUShaderResource* Create(ID3D11ShaderResourceView* pResource) {
+ D3D11TextureResource* pBuffer = new D3D11TextureResource;
+ pBuffer->m_pD3D11Resource = pResource;
+ return pBuffer;
+ }
+
+ static ID3D11ShaderResourceView* GetResource(GPUShaderResource* pBuffer)
+ {
+ D3D11TextureResource* pD3D11Buffer = dynamic_cast<D3D11TextureResource*>(pBuffer);
+ if (!pD3D11Buffer)
+ return 0;
+ return pD3D11Buffer->m_pD3D11Resource;
+ }
+
+ ~D3D11TextureResource()
+ {
+ }
+
+ void Release()
+ {
+ SAFE_RELEASE(m_pD3D11Resource);
+ }
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.cpp
new file mode 100644
index 0000000..b13c8e3
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.cpp
@@ -0,0 +1,333 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D11Util.h"
+
+#include "D3D11Shaders.h"
+#include "D3D11RenderShader.h"
+
+#include "D3DX10tex.h"
+#include "D3DX11tex.h"
+
+#include "D3D11Wrapper.h"
+#include "DXUT.h"
+#include "DXUTgui.h"
+#include "sdkmisc.h"
+#include "D3D11RendererWindow.h"
+#include "SimpleRenderable.h"
+//#include "MeshShaderParam.h"
+#include "D3D11RenderInterface.h"
+#include "D3D11TextureResource.h"
+
+namespace D3D11Util
+{
+ using namespace RenderInterface;
+
+ // D3D hook to render window
+ D3D11RenderWindow* g_pRenderWindow = 0;
+
+///////////////////////////////////////////////////////////////////////////////
+#include "../../../../../../external/stb_image/stb_image.c"
+
+GPUShaderResource*
+CreateTextureSRV(const char* texturename)
+{
+ ID3D11Device* pDevice = RenderInterfaceD3D11::GetDevice();
+ if (!pDevice)
+ return 0;
+
+ D3DX11_IMAGE_LOAD_INFO texLoadInfo;
+
+ texLoadInfo.MipLevels = 8;
+ texLoadInfo.MipFilter = D3DX10_FILTER_TRIANGLE;
+ texLoadInfo.Filter = D3DX10_FILTER_TRIANGLE;
+
+ ID3D11Resource *pRes = 0;
+
+ HRESULT hr;
+ D3DX11CreateTextureFromFileA(pDevice, texturename, &texLoadInfo, NULL, &pRes, &hr);
+
+ ID3D11Texture2D* texture = NULL;
+
+ if (!pRes)
+ {
+ // Try stb_image for .TGA
+ int width = 0;
+ int height = 0;
+ int numComponents = 0;
+ unsigned char *pSTBIRes = stbi_load(texturename, &width, &height, &numComponents, 4);
+
+ if (!pSTBIRes)
+ return 0;
+
+ const int requestedMipLevels = texLoadInfo.MipLevels;
+
+ D3D11_SUBRESOURCE_DATA* initData = new D3D11_SUBRESOURCE_DATA[requestedMipLevels];
+ ZeroMemory(initData, sizeof(D3D11_SUBRESOURCE_DATA)*requestedMipLevels);
+
+ struct Pixel
+ {
+ unsigned char rgba[4];
+ };
+
+ // prepare target buffer just large enough to include all the mip levels
+ Pixel* targets = new Pixel[width*height*2];
+
+ // copy the first mip level
+ memcpy(targets, pSTBIRes, width*height*4);
+
+ // now it's OK to delete the original
+ if (pSTBIRes)
+ stbi_image_free(pSTBIRes);
+
+ // current mip level width and height
+ int mipWidth = width;
+ int mipHeight = height;
+
+ // actual mip levels
+ int mipLevels = 0;
+
+ // current data
+ Pixel* source = targets;
+ Pixel* target = nullptr;
+
+ for (int idx = 0; idx < requestedMipLevels; ++idx)
+ {
+ // set initData
+ initData[idx].pSysMem = source;
+ initData[idx].SysMemPitch = mipWidth*4;
+ mipLevels++;
+
+ // skip generating mip for 1x1
+ if ((mipWidth == 1) && (mipHeight == 1))
+ break;
+
+ // skip generating mip for the last level
+ if (idx == (requestedMipLevels-1))
+ break;
+
+ // buffer for the next mip level
+ target = &source[mipWidth*mipHeight];
+
+ const int prevWidth = mipWidth; // previous mip's width
+
+ // generate the next mip level
+ mipWidth = max(1, mipWidth >> 1);
+ mipHeight = max(1, mipHeight >> 1);
+
+ Pixel samples[4];
+
+ for (int y = 0; y < mipHeight; ++y)
+ {
+ for (int x = 0; x < mipWidth; ++x)
+ {
+ const int px = x*2; // x in previous mip
+ const int py = y*2; // y in previous mip
+
+ samples[0] = source[py*prevWidth + px]; // left top
+ samples[1] = source[py*prevWidth + px+1]; // right top
+ samples[2] = source[(py+1)*prevWidth + px]; // left bottom
+ samples[3] = source[(py+1)*prevWidth + px+1]; // right bottom
+
+ // for each component
+ for (int comp = 0; comp < 4; ++comp)
+ {
+ // do the linear box filter for lower mip level
+ target[y*mipWidth + x].rgba[comp] = (samples[0].rgba[comp] + samples[1].rgba[comp] + samples[2].rgba[comp] + samples[3].rgba[comp])/4;
+ }
+ }
+ }
+
+ // update source
+ source = target;
+ }
+
+ D3D11_TEXTURE2D_DESC desc;
+ ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
+ desc.ArraySize = 1;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ desc.CPUAccessFlags = 0;
+ desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ desc.Height = height;
+ desc.Width = width;
+ desc.MipLevels = mipLevels;
+ desc.MiscFlags = 0;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+
+ HRESULT ret = pDevice->CreateTexture2D(&desc, initData, &texture);
+
+ delete initData;
+ delete targets;
+
+ if (ret != S_OK)
+ return 0;
+ }
+ else
+ {
+ pRes->QueryInterface(__uuidof( ID3D11Texture2D ), (LPVOID*)&texture);
+ }
+
+ D3D11_TEXTURE2D_DESC desc;
+ texture->GetDesc( &desc );
+
+ ID3D11ShaderResourceView* pTextureSRV = 0;
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
+ ZeroMemory( &SRVDesc, sizeof(SRVDesc) );
+ SRVDesc.Format = desc.Format;
+ SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ SRVDesc.Texture2D.MostDetailedMip = 0;
+ SRVDesc.Texture2D.MipLevels = desc.MipLevels;
+ pDevice->CreateShaderResourceView(texture, &SRVDesc, &pTextureSRV);
+
+ if (texture) texture->Release();
+
+ if (pRes)
+ pRes->Release();
+
+ return D3D11TextureResource::Create(pTextureSRV);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+bool GetDeviceInfoString(wchar_t *str)
+{
+ IDXGIAdapter* pAdapter = RenderInterfaceD3D11::GetAdapter();
+ if (!pAdapter)
+ return false;
+
+ auto adapterDescription = DXGI_ADAPTER_DESC();
+ pAdapter->GetDesc(&adapterDescription);
+
+ WCHAR* pDescStr = adapterDescription.Description;
+ float memInGB = float(adapterDescription.DedicatedVideoMemory) / 1e9f;
+ swprintf_s(str, 1000, L"%s(%.1fGb)\n", pDescStr, memInGB);
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Render window interafce
+/////////////////////////////////////////////////////////////////////////////////////////
+bool CreateRenderWindow(HWND hWnd, int nSamples)
+{
+ SAFE_DELETE(g_pRenderWindow);
+
+ g_pRenderWindow = new D3D11RenderWindow;
+ return g_pRenderWindow->Create(hWnd, nSamples);
+}
+
+D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles)
+{
+ deviceHandles.pAdapter = RenderInterfaceD3D11::GetAdapter();
+ deviceHandles.pFactory = RenderInterfaceD3D11::GetDXGIFactory();
+ deviceHandles.pDevice = RenderInterfaceD3D11::GetDevice();
+ deviceHandles.pDeviceContext = RenderInterfaceD3D11::GetDeviceContext();
+
+ deviceHandles.pDXGISwapChain = g_pRenderWindow->m_pDXGISwapChain;
+ deviceHandles.pD3D11BackBuffer = g_pRenderWindow->m_pD3D11BackBuffer;
+ deviceHandles.pD3D11RenderTargetView = g_pRenderWindow->m_pD3D11RenderTargetView;
+ deviceHandles.pD3D11DepthBuffer = g_pRenderWindow->m_pD3D11DepthBuffer;
+ deviceHandles.pD3D11DepthStencilView = g_pRenderWindow->m_pD3D11DepthStencilView;
+ return deviceHandles;
+}
+
+void DestroyRenderWindow()
+{
+ SAFE_DELETE(g_pRenderWindow);
+}
+
+bool ResizeRenderWindow(int w, int h)
+{
+ if (!g_pRenderWindow)
+ return false;
+
+ return g_pRenderWindow->Resize(w,h);
+}
+
+void PresentRenderWindow()
+{
+ if (!g_pRenderWindow)
+ return;
+
+ g_pRenderWindow->Present();
+}
+
+void ClearRenderWindow(float r, float g, float b)
+{
+ if (!g_pRenderWindow)
+ return;
+
+ g_pRenderWindow->Clear(r,g,b);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Text draw helper functions (using DXUT)
+/////////////////////////////////////////////////////////////////////////////////////////
+void TxtHelperBegin()
+{
+ if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper)
+ return;
+
+ g_pRenderWindow->m_pTextHelper->Begin();
+}
+
+void TxtHelperEnd()
+{
+ if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper)
+ return;
+
+ g_pRenderWindow->m_pTextHelper->End();
+}
+
+void TxtHelperSetInsertionPos(int x, int y)
+{
+ if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper)
+ return;
+
+ g_pRenderWindow->m_pTextHelper->SetInsertionPos(x, y);
+}
+
+void TxtHelperSetForegroundColor(float r, float g, float b, float a)
+{
+ if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper)
+ return;
+
+ g_pRenderWindow->m_pTextHelper->SetForegroundColor(DirectX::XMFLOAT4(r,g,b,a));
+}
+
+void TxtHelperDrawTextLine(wchar_t* str)
+{
+ if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper)
+ return;
+
+ g_pRenderWindow->m_pTextHelper->DrawTextLine(str);
+}
+
+} // end namespace \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.h b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.h
new file mode 100644
index 0000000..8a9176e
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.h
@@ -0,0 +1,69 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "d3d11.h"
+
+#include "RenderPlugin.h"
+
+class GPUShaderResource;
+class IDXGISwapChain;
+
+namespace D3D11Util
+{
+ ///////////////////////////////////////////////////////////////////
+ // render window management
+ ///////////////////////////////////////////////////////////////////
+ D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles);
+ bool CreateRenderWindow(HWND hWnd, int nSamples);
+ void DestroyRenderWindow();
+ bool ResizeRenderWindow(int w, int h);
+ void PresentRenderWindow();
+ void ClearRenderWindow(float r, float g, float b);
+
+ ///////////////////////////////////////////////////////////////////
+ // background textures
+ bool LoadBackgroundTexture(const char* filePath);
+ void RenderBackgroundTexture();
+ void ClearBackgroundTexture();
+ GPUShaderResource* CreateTextureSRV(const char* texturename);
+
+ ///////////////////////////////////////////////////////////////////
+ CORERENDER_EXPORT bool GetDeviceInfoString(wchar_t *str);
+
+ ///////////////////////////////////////////////////////////////////
+ // text helpers
+ CORERENDER_EXPORT void TxtHelperBegin();
+ CORERENDER_EXPORT void TxtHelperEnd();
+ CORERENDER_EXPORT void TxtHelperSetInsertionPos(int x, int y);
+ CORERENDER_EXPORT void TxtHelperSetForegroundColor(float r, float g, float b, float a = 1.0f);
+ CORERENDER_EXPORT void TxtHelperDrawTextLine(wchar_t* str);
+
+
+}
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.cpp
new file mode 100644
index 0000000..5a117f1
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.cpp
@@ -0,0 +1,33 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D11Wrapper.h"
+
+namespace D3DWrapper
+{
+
+} // end namespace \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.h b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.h
new file mode 100644
index 0000000..0d752d8
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "d3d11.h"
+
+namespace D3DWrapper
+{
+ inline void SetDebugName(ID3D11DeviceChild* pResource, const char *name)
+ {
+ if (pResource) pResource->SetPrivateData( WKPDID_D3DDebugObjectName, strlen(name), name);
+ }
+}
+
+#define SET_D3D_DEBUG_NAME(x, name) D3DWrapper::SetDebugName(x, name);
+#define SET_D3D_DEBUG_NAME_VAR(x) D3DWrapper::SetDebugName(x, #x);
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.cpp
new file mode 100644
index 0000000..93d3fdf
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.cpp
@@ -0,0 +1,315 @@
+#include "RenderPluginDx11.h"
+
+#include "D3D11RenderInterface.h"
+#include "D3D11Util.h"
+#include "D3D11Shaders.h"
+#include "D3D11GPUProfiler.h"
+#include "D3D11ShadowMap.h"
+
+RenderPlugin* CreateRenderPlugin(void)
+{
+ return new RenderPluginDx11;
+}
+
+RenderPluginDx11::RenderPluginDx11()
+{
+ m_RenderApi = "Dx11";
+}
+
+RenderPluginDx11::~RenderPluginDx11()
+{
+}
+
+// interface
+bool RenderPluginDx11::InitDevice(int deviceID)
+{
+ return RenderInterfaceD3D11::InitDevice(deviceID);
+}
+
+bool RenderPluginDx11::Initialize()
+{
+ return RenderInterfaceD3D11::Initialize();
+}
+
+void RenderPluginDx11::Shutdown()
+{
+ D3D11Util::DestroyRenderWindow();
+ RenderInterfaceD3D11::Shutdown();
+}
+
+void RenderPluginDx11::CopyToDevice(GPUBufferResource *pDevicePtr,
+ void* pSysMem, unsigned int ByteWidth)
+{
+ RenderInterfaceD3D11::CopyToDevice(pDevicePtr, pSysMem, ByteWidth);
+}
+
+void RenderPluginDx11::ApplyDepthStencilState(DEPTH_STENCIL_STATE state)
+{
+ RenderInterfaceD3D11::ApplyDepthStencilState(state);
+}
+
+void RenderPluginDx11::ApplyRasterizerState(RASTERIZER_STATE state)
+{
+ RenderInterfaceD3D11::ApplyRasterizerState(state);
+}
+
+void RenderPluginDx11::ApplySampler(int slot, SAMPLER_TYPE state)
+{
+ RenderInterfaceD3D11::ApplySampler(slot, state);
+}
+
+void RenderPluginDx11::ApplyBlendState(BLEND_STATE state)
+{
+ RenderInterfaceD3D11::ApplyBlendState(state);
+}
+
+void RenderPluginDx11::GetViewport(Viewport& vp)
+{
+ RenderInterfaceD3D11::GetViewport(vp);
+}
+
+void RenderPluginDx11::SetViewport(const Viewport& vp)
+{
+ RenderInterfaceD3D11::SetViewport(vp);
+}
+
+void RenderPluginDx11::BindVertexShaderResources(int startSlot,
+ int numSRVs, GPUShaderResource** ppSRVs)
+{
+ RenderInterfaceD3D11::BindVertexShaderResources(startSlot, numSRVs, ppSRVs);
+}
+
+void RenderPluginDx11::BindPixelShaderResources(int startSlot,
+ int numSRVs, GPUShaderResource** ppSRVs)
+{
+ RenderInterfaceD3D11::BindPixelShaderResources(startSlot, numSRVs, ppSRVs);
+}
+
+void RenderPluginDx11::ClearVertexShaderResources(int startSlot, int numSRVs)
+{
+ RenderInterfaceD3D11::ClearVertexShaderResources(startSlot, numSRVs);
+}
+
+void RenderPluginDx11::ClearPixelShaderResources(int startSlot, int numSRVs)
+{
+ RenderInterfaceD3D11::ClearPixelShaderResources(startSlot, numSRVs);
+}
+
+void RenderPluginDx11::ClearInputLayout()
+{
+ RenderInterfaceD3D11::ClearInputLayout();
+}
+
+void RenderPluginDx11::SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset)
+{
+ RenderInterfaceD3D11::SetVertexBuffer(pBuffer, stride, offset);
+}
+
+void RenderPluginDx11::SetPrimitiveTopologyTriangleStrip()
+{
+ RenderInterfaceD3D11::SetPrimitiveTopologyTriangleStrip();
+}
+
+void RenderPluginDx11::SetPrimitiveTopologyTriangleList()
+{
+ RenderInterfaceD3D11::SetPrimitiveTopologyTriangleList();
+}
+
+void RenderPluginDx11::SetPrimitiveTopologyLineList()
+{
+ RenderInterfaceD3D11::SetPrimitiveTopologyLineList();
+}
+
+void RenderPluginDx11::Draw(unsigned int vertexCount, unsigned int startCount)
+{
+ RenderInterfaceD3D11::Draw(vertexCount, startCount);
+}
+
+GPUBufferResource* RenderPluginDx11::CreateVertexBuffer(unsigned int ByteWidth, void* pSysMem)
+{
+ return RenderInterfaceD3D11::CreateVertexBuffer(ByteWidth, pSysMem);
+}
+
+GPUShaderResource* RenderPluginDx11::CreateShaderResource(unsigned int stride,
+ unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer)
+{
+ return RenderInterfaceD3D11::CreateShaderResource(stride, numElements, pSysMem);
+}
+
+void RenderPluginDx11::ApplyForShadow(int ForShadow)
+{
+}
+
+void RenderPluginDx11::SwitchToDX11()
+{
+}
+
+void RenderPluginDx11::FlushDX11()
+{
+}
+
+void RenderPluginDx11::FlushDX12()
+{
+}
+
+void RenderPluginDx11::ApplyPrimitiveTopologyLine()
+{
+}
+
+void RenderPluginDx11::ApplyPrimitiveTopologyTriangle()
+{
+}
+
+void RenderPluginDx11::SubmitGpuWork()
+{
+}
+
+void RenderPluginDx11::WaitForGpu()
+{
+}
+
+// util
+bool RenderPluginDx11::CreateRenderWindow(HWND hWnd, int nSamples)
+{
+ return D3D11Util::CreateRenderWindow(hWnd, nSamples);
+}
+
+bool RenderPluginDx11::ResizeRenderWindow(int w, int h)
+{
+ return D3D11Util::ResizeRenderWindow(w, h);
+}
+
+void RenderPluginDx11::PresentRenderWindow()
+{
+ D3D11Util::PresentRenderWindow();
+}
+
+void RenderPluginDx11::ClearRenderWindow(float r, float g, float b)
+{
+ D3D11Util::ClearRenderWindow(r, g, b);
+}
+
+bool RenderPluginDx11::GetDeviceInfoString(wchar_t *str)
+{
+ return D3D11Util::GetDeviceInfoString(str);
+}
+
+GPUShaderResource* RenderPluginDx11::CreateTextureSRV(const char* texturename)
+{
+ return D3D11Util::CreateTextureSRV(texturename);
+}
+
+void RenderPluginDx11::TxtHelperBegin()
+{
+ D3D11Util::TxtHelperBegin();
+}
+
+void RenderPluginDx11::TxtHelperEnd()
+{
+ D3D11Util::TxtHelperEnd();
+}
+
+void RenderPluginDx11::TxtHelperSetInsertionPos(int x, int y)
+{
+ D3D11Util::TxtHelperSetInsertionPos(x, y);
+}
+
+void RenderPluginDx11::TxtHelperSetForegroundColor(float r, float g, float b, float a)
+{
+ D3D11Util::TxtHelperSetForegroundColor(r, g, b, a);
+}
+
+void RenderPluginDx11::TxtHelperDrawTextLine(wchar_t* str)
+{
+ D3D11Util::TxtHelperDrawTextLine(str);
+}
+
+// shader
+bool RenderPluginDx11::InitializeShaders()
+{
+ return InitializeShadersD3D11();
+}
+
+void RenderPluginDx11::DestroyShaders()
+{
+ DestroyShadersD3D11();
+}
+
+void RenderPluginDx11::ApplyShader(SHADER_TYPE st)
+{
+ ApplyShaderD3D11(st);
+}
+
+void RenderPluginDx11::DisableShader(SHADER_TYPE st)
+{
+ DisableShaderD3D11(st);
+}
+
+void RenderPluginDx11::BindShaderResources(SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs)
+{
+}
+
+void RenderPluginDx11::CopyShaderParam(SHADER_TYPE st,
+ void* pSysMem, unsigned int bytes, unsigned int slot)
+{
+ CopyShaderParamD3D11(st, pSysMem, bytes, slot);
+}
+
+// GPUProfiler
+GPUProfiler* RenderPluginDx11::CreateGPUProfiler()
+{
+ GPUProfiler* pProfiler = new D3D11GPUProfiler;
+ pProfiler->Initialize();
+ return pProfiler;
+}
+
+// ShadowMap
+ShadowMap* RenderPluginDx11::CreateShadowMap(int resolution)
+{
+ return new D3D11ShadowMap(resolution);
+}
+
+// D3D12RenderContext
+void RenderPluginDx11::PreRender()
+{
+}
+
+void RenderPluginDx11::PostRender()
+{
+}
+
+// GPUMeshResources
+
+#include "MeshData.h"
+#include "AnimUtil.h"
+
+GPUMeshResources* RenderPluginDx11::GPUMeshResourcesCreate(MeshData* pMeshData, const SkinData& skinData)
+{
+ GPUMeshResources* resources = new GPUMeshResources;
+
+ int numIndices = pMeshData->m_NumIndices;
+ int numVertices = pMeshData->m_NumVertices;
+
+ resources->m_pVertexBuffer = CreateVertexBuffer(
+ sizeof(MeshData::MeshVertex) * numIndices, pMeshData->m_pMeshVertices);
+
+ resources->m_pBoneIndicesSRV = CreateShaderResource(
+ sizeof(atcore_float4), numVertices, skinData.m_pBoneIndices);
+
+ resources->m_pBoneWeightsSRV = CreateShaderResource(
+ sizeof(atcore_float4), numVertices, skinData.m_pBoneWeights);
+
+ return resources;
+}
+
+void RenderPluginDx11::GPUMeshResourcesRelease(GPUMeshResources* pResource)
+{
+ SAFE_RELEASE(pResource->m_pVertexBuffer);
+ SAFE_RELEASE(pResource->m_pBoneIndicesSRV);
+ SAFE_RELEASE(pResource->m_pBoneWeightsSRV);
+}
+
+D3DHandles& RenderPluginDx11::GetDeviceHandles(D3DHandles& deviceHandles)
+{
+ return D3D11Util::GetDeviceHandles(deviceHandles);
+}
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.h b/tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.h
new file mode 100644
index 0000000..a43eb94
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.h
@@ -0,0 +1,83 @@
+#pragma once
+
+#include "RenderPlugin.h"
+
+extern "C" CORERENDER_EXPORT RenderPlugin* CreateRenderPlugin(void);
+
+class CORERENDER_EXPORT RenderPluginDx11 : public RenderPlugin
+{
+public:
+ RenderPluginDx11();
+ ~RenderPluginDx11();
+
+ // interface
+ virtual bool InitDevice(int deviceID);
+ virtual bool Initialize();
+ virtual void Shutdown();
+ virtual void CopyToDevice(GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth);
+ virtual void ApplyDepthStencilState(DEPTH_STENCIL_STATE state);
+ virtual void ApplyRasterizerState(RASTERIZER_STATE state);
+ virtual void ApplySampler(int slot, SAMPLER_TYPE st);
+ virtual void ApplyBlendState(BLEND_STATE st);
+ virtual void GetViewport(Viewport& vp);
+ virtual void SetViewport(const Viewport& vp);
+ virtual void BindVertexShaderResources(int startSlot, int numSRVs, GPUShaderResource** ppSRVs);
+ virtual void BindPixelShaderResources(int startSlot, int numSRVs, GPUShaderResource** ppSRVs);
+ virtual void ClearVertexShaderResources(int startSlot, int numSRVs);
+ virtual void ClearPixelShaderResources(int startSlot, int numSRVs);
+ virtual void ClearInputLayout();
+ virtual void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset = 0);
+ virtual void SetPrimitiveTopologyTriangleStrip();
+ virtual void SetPrimitiveTopologyTriangleList();
+ virtual void SetPrimitiveTopologyLineList();
+ virtual void Draw(unsigned int vertexCount, unsigned int startCount = 0);
+ virtual GPUBufferResource* CreateVertexBuffer(unsigned int ByteWidth, void* pSysMem = 0);
+ virtual GPUShaderResource* CreateShaderResource(unsigned int stride, unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer = NULL);
+ virtual void ApplyForShadow(int ForShadow);
+ virtual void SwitchToDX11();
+ virtual void FlushDX11();
+ virtual void FlushDX12();
+ virtual void ApplyPrimitiveTopologyLine();
+ virtual void ApplyPrimitiveTopologyTriangle();
+ virtual void SubmitGpuWork();
+ virtual void WaitForGpu();
+
+ // util
+ virtual bool CreateRenderWindow(HWND hWnd, int nSamples);
+ virtual bool ResizeRenderWindow(int w, int h);
+ virtual void PresentRenderWindow();
+ virtual void ClearRenderWindow(float r, float g, float b);
+ virtual bool GetDeviceInfoString(wchar_t *str);
+ virtual GPUShaderResource* CreateTextureSRV(const char* texturename);
+ virtual void TxtHelperBegin();
+ virtual void TxtHelperEnd();
+ virtual void TxtHelperSetInsertionPos(int x, int y);
+ virtual void TxtHelperSetForegroundColor(float r, float g, float b, float a = 1.0f);
+ virtual void TxtHelperDrawTextLine(wchar_t* str);
+
+ // shader
+ virtual bool InitializeShaders();
+ virtual void DestroyShaders();
+ virtual void ApplyShader(SHADER_TYPE st);
+ virtual void DisableShader(SHADER_TYPE st);
+ virtual void BindShaderResources(SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs);
+ virtual void CopyShaderParam(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot = 0);
+
+ // GPUProfiler
+ virtual GPUProfiler* CreateGPUProfiler();
+
+ // ShadowMap
+ virtual ShadowMap* CreateShadowMap(int resolution);
+
+ // D3D12RenderContext
+ virtual void PreRender();
+ virtual void PostRender();
+
+ // GPUMeshResources
+ virtual GPUMeshResources* GPUMeshResourcesCreate(MeshData* pMeshData, const SkinData& skinData);
+ virtual void GPUMeshResourcesRelease(GPUMeshResources* pResource);
+
+ // Get devices related
+ virtual D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles);
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.cpp
new file mode 100644
index 0000000..0421792
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.cpp
@@ -0,0 +1,31 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D12Buffer.h"
+
+// shared path
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.h b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.h
new file mode 100644
index 0000000..ccf636b
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.h
@@ -0,0 +1,81 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "RenderResources.h"
+
+#include <d3d12.h>
+
+// GPU resources for texture
+struct GPUBufferD3D12 : public GPUBufferResource
+{
+ ID3D12Resource* m_pBuffer;
+ UINT m_pBufferSize;
+
+ D3D12_VERTEX_BUFFER_VIEW m_vertexBufferView;
+
+public:
+ static GPUBufferResource* Create(ID3D12Resource* pResource, int nSize) {
+ GPUBufferD3D12* pBuffer = new GPUBufferD3D12;
+ pBuffer->m_pBuffer = pResource;
+ pBuffer->m_pBufferSize = nSize;
+ return pBuffer;
+ }
+
+ static ID3D12Resource* GetResource(GPUBufferResource* pBuffer)
+ {
+ GPUBufferD3D12* pD3D12Buffer = dynamic_cast<GPUBufferD3D12*>(pBuffer);
+ if (!pD3D12Buffer)
+ return 0;
+ return pD3D12Buffer->m_pBuffer;
+ }
+
+ static D3D12_VERTEX_BUFFER_VIEW* GetVertexView(GPUBufferResource* pBuffer)
+ {
+ GPUBufferD3D12* pD3D12Buffer = dynamic_cast<GPUBufferD3D12*>(pBuffer);
+ if (!pD3D12Buffer)
+ return 0;
+
+ pD3D12Buffer->m_vertexBufferView.BufferLocation = pD3D12Buffer->m_pBuffer->GetGPUVirtualAddress();
+ pD3D12Buffer->m_vertexBufferView.StrideInBytes = 0;
+ pD3D12Buffer->m_vertexBufferView.SizeInBytes = pD3D12Buffer->m_pBufferSize;
+ return &pD3D12Buffer->m_vertexBufferView;
+ }
+
+ ~GPUBufferD3D12()
+ {
+ Release();
+ }
+
+ void Release()
+ {
+ SAFE_RELEASE(m_pBuffer);
+ }
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.cpp
new file mode 100644
index 0000000..b434c3c
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.cpp
@@ -0,0 +1,222 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D12GPUProfiler.h"
+
+#include "D3D12RenderInterface.h"
+#include "D3D12RenderContext.h"
+///////////////////////////////////////////////////////////////
+// factory function to create D3D12 GPU profiler
+/*
+GPUProfiler* GPUProfiler::CreateD3D12()
+{
+ GPUProfiler* pProfiler = new D3D12GPUProfiler;
+ pProfiler->Initialize();
+ return pProfiler;
+}
+*/
+
+///////////////////////////////////////////////////////////////
+D3D12GPUProfiler::~D3D12GPUProfiler()
+{
+ Release();
+}
+
+///////////////////////////////////////////////////////////////
+void D3D12GPUProfiler::Initialize()
+{
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+
+ /*
+ ID3D12Device* pDevice12 = pContext->GetDevice();
+
+ D3D12_QUERY_HEAP_DESC queryHeapDesc = {};
+ queryHeapDesc.Count = MAX_QUERY_COUNT * 2;
+ queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
+ ThrowIfFailed(pDevice12->CreateQueryHeap(&queryHeapDesc, IID_PPV_ARGS(&query_heap)));
+
+ D3D12_HEAP_PROPERTIES heap_prop;
+ heap_prop.Type = D3D12_HEAP_TYPE_DEFAULT;
+ heap_prop.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ heap_prop.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ heap_prop.CreationNodeMask = 0;
+ heap_prop.VisibleNodeMask = 0;
+
+ D3D12_RESOURCE_DESC res_desc;
+ res_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+ res_desc.Alignment = 0;
+ res_desc.Width = sizeof(UINT64) * 2;
+ res_desc.Height = 1;
+ res_desc.DepthOrArraySize = 1;
+ res_desc.MipLevels = 1;
+ res_desc.Format = DXGI_FORMAT_UNKNOWN;
+ res_desc.SampleDesc.Count = 1;
+ res_desc.SampleDesc.Quality = 0;
+ res_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ res_desc.Flags = D3D12_RESOURCE_FLAG_NONE;
+
+ ThrowIfFailed(pDevice12->CreateCommittedResource(&heap_prop, D3D12_HEAP_FLAG_NONE,
+ &res_desc, D3D12_RESOURCE_STATE_COMMON, nullptr,
+ IID_ID3D12Resource, reinterpret_cast<void**>(&query_result)));
+
+ heap_prop.Type = D3D12_HEAP_TYPE_READBACK;
+ ThrowIfFailed(pDevice12->CreateCommittedResource(&heap_prop, D3D12_HEAP_FLAG_NONE,
+ &res_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr,
+ IID_ID3D12Resource, reinterpret_cast<void**>(&query_result_readback)));
+ */
+
+ m_pContext = pContext->GetDeviceContext();
+
+ D3D11_QUERY_DESC desc;
+ memset(&desc, 0, sizeof(D3D11_QUERY_DESC));
+ desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT;
+ desc.MiscFlags = 0;
+
+ ID3D11Device* pDevice = pContext->GetDevice11();
+ pDevice->CreateQuery(&desc, &m_pQueryDisjoint);
+
+ desc.Query = D3D11_QUERY_TIMESTAMP;
+
+ for (int i = 0; i < MAX_QUERY_COUNT; i++)
+ {
+ pDevice->CreateQuery(&desc, &m_pQueryStart[i]);
+ pDevice->CreateQuery(&desc, &m_pQueryEnd[i]);
+ }
+ m_enable = true;
+}
+
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; }
+#endif
+
+///////////////////////////////////////////////////////////////
+void D3D12GPUProfiler::Release()
+{
+ for (int i = 0; i < MAX_QUERY_COUNT; i++)
+ {
+ SAFE_RELEASE(m_pQueryStart[i]);
+ SAFE_RELEASE(m_pQueryEnd[i]);
+ }
+
+ SAFE_RELEASE(m_pQueryDisjoint);
+}
+
+///////////////////////////////////////////////////////////////
+void D3D12GPUProfiler::StartProfile(int id)
+{
+ if (!m_enable) return;
+
+ /*
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ ID3D12GraphicsCommandList* pCommandList = pContext->GetGraphicsCommandList();
+ pCommandList->EndQuery(query_heap, D3D12_QUERY_TYPE_TIMESTAMP, id * 2);
+ */
+
+ ID3D11Query* pQuery = m_pQueryStart[id];
+ m_pContext->End(pQuery);
+}
+
+///////////////////////////////////////////////////////////////
+void D3D12GPUProfiler::EndProfile(int id)
+{
+ if (!m_enable) return;
+
+ /*
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ ID3D12GraphicsCommandList* pCommandList = pContext->GetGraphicsCommandList();
+ pCommandList->EndQuery(query_heap, D3D12_QUERY_TYPE_TIMESTAMP, id * 2 + 1);
+ */
+
+ ID3D11Query* pQuery = m_pQueryEnd[id];
+ m_pContext->End(pQuery);
+}
+
+///////////////////////////////////////////////////////////////
+void D3D12GPUProfiler::StartFrame()
+{
+ if (!m_enable) return;
+
+ m_pContext->Begin(m_pQueryDisjoint);
+}
+
+///////////////////////////////////////////////////////////////
+void D3D12GPUProfiler::EndFrame()
+{
+ if (!m_enable) return;
+
+ m_pContext->End(m_pQueryDisjoint);
+
+ while(m_pContext->GetData(m_pQueryDisjoint, &m_disjointData, sizeof(D3D11_QUERY_DATA_TIMESTAMP_DISJOINT), 0) != S_OK);
+}
+
+///////////////////////////////////////////////////////////////
+float D3D12GPUProfiler::GetProfileData(int id)
+{
+ if (!m_enable)
+ return 0.0f;
+
+ /*
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ ID3D12GraphicsCommandList* pCommandList = pContext->GetGraphicsCommandList();
+
+ UINT64 times[2];
+ D3D12_RESOURCE_BARRIER barrier;
+ barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
+ barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
+ barrier.Transition.pResource = query_result;
+ barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON;
+ barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
+ barrier.Transition.Subresource = 0;
+ pCommandList->ResourceBarrier(1, &barrier);
+
+ pCommandList->ResolveQueryData(query_heap, D3D12_QUERY_TYPE_TIMESTAMP, id * 2, 2, query_result, 0);
+
+ barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
+ barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
+ pCommandList->ResourceBarrier(1, &barrier);
+
+ pCommandList->CopyResource(query_result_readback, query_result);
+
+ barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE;
+ barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
+ pCommandList->ResourceBarrier(1, &barrier);
+
+ void* pData;
+ ThrowIfFailed(query_result_readback->Map(0, 0, &pData));
+ memcpy(times, pData, sizeof(UINT64) * 2);
+ query_result_readback->Unmap(0, 0);
+ */
+
+ UINT64 startTime = 0;
+ while(m_pContext->GetData(m_pQueryStart[id], &startTime, sizeof(UINT64), 0) != S_OK);
+
+ UINT64 endTime = 0;
+ while(m_pContext->GetData(m_pQueryEnd[id], &endTime, sizeof(UINT64), 0) != S_OK);
+
+ float frequency = static_cast<float>(m_disjointData.Frequency);
+ return (endTime - startTime) / frequency * 1000.0f;
+}
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.h b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.h
new file mode 100644
index 0000000..721b8a9
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.h
@@ -0,0 +1,63 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include <d3d11.h>
+/*
+#include <d3d12.h>
+*/
+#include "GPUProfiler.h"
+
+#define MAX_QUERY_COUNT 64
+struct D3D12GPUProfiler : public GPUProfiler
+{
+public:
+ ~D3D12GPUProfiler();
+
+ void Initialize();
+ void Release();
+ void StartProfile(int id);
+ void EndProfile(int id);
+ void StartFrame();
+ void EndFrame();
+ float GetProfileData(int id);
+
+protected:
+ ID3D11Query* m_pQueryDisjoint;
+ ID3D11Query* m_pQueryStart[MAX_QUERY_COUNT];
+ ID3D11Query* m_pQueryEnd[MAX_QUERY_COUNT];
+ D3D11_QUERY_DATA_TIMESTAMP_DISJOINT m_disjointData;
+ ID3D11DeviceContext* m_pContext;
+ /*
+ ID3D12QueryHeap* query_heap;
+ ID3D12Resource* query_result;
+ ID3D12Resource* query_result_readback;
+ */
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.cpp
new file mode 100644
index 0000000..8202139
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.cpp
@@ -0,0 +1,564 @@
+#include "D3D12RenderContext.h"
+
+const int nBufferCount = 2;
+//const int nBufferCount = 5;
+
+int nRenderTargetIndex = 1;
+//int nRenderTargetIndex = 4;
+
+D3D12RenderContext::D3D12RenderContext()
+{
+ m_sampleCount = 1;
+}
+
+D3D12RenderContext::~D3D12RenderContext()
+{
+}
+
+D3D12RenderContext* D3D12RenderContext::Instance()
+{
+ static D3D12RenderContext ri;
+ return &ri;
+}
+
+void GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter)
+{
+ IDXGIAdapter1* pAdapter = nullptr;
+ *ppAdapter = nullptr;
+
+ for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &pAdapter); ++adapterIndex)
+ {
+ DXGI_ADAPTER_DESC1 desc;
+ pAdapter->GetDesc1(&desc);
+
+ if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
+ {
+ // Don't select the Basic Render Driver adapter.
+ // If you want a software adapter, pass in "/warp" on the command line.
+ continue;
+ }
+
+ // Check to see if the adapter supports Direct3D 12, but don't create the
+ // actual device yet.
+ if (SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
+ {
+ break;
+ }
+ }
+
+ *ppAdapter = pAdapter;
+}
+
+void D3D12RenderContext::InitDevice()
+{
+ UINT d3d11DeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+#if defined(_DEBUG)
+ // Enable the D3D11 debug layer.
+ d3d11DeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
+ // Enable the D3D12 debug layer.
+ {
+ ComPtr<ID3D12Debug> debugController;
+ if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
+ {
+ debugController->EnableDebugLayer();
+ }
+ }
+#endif
+
+ ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&m_factory)));
+
+ GetHardwareAdapter(m_factory.Get(), &m_adapter);
+
+ auto adapterDescription = DXGI_ADAPTER_DESC();
+ m_adapter->GetDesc(&adapterDescription);
+
+ D3D12CreateDevice(m_adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device));
+ if (nullptr == m_device)
+ {
+ ComPtr<IDXGIAdapter> warpAdapter;
+ ThrowIfFailed(m_factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));
+ ThrowIfFailed(D3D12CreateDevice(warpAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)));
+ }
+
+ // Describe and create the command queue.
+ D3D12_COMMAND_QUEUE_DESC queueDesc = {};
+ queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
+ queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
+
+ ThrowIfFailed(m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue)));
+
+ ThrowIfFailed(D3D11On12CreateDevice(
+ m_device.Get(),
+ d3d11DeviceFlags, nullptr, 0,
+ reinterpret_cast<IUnknown**>(m_commandQueue.GetAddressOf()), 1, 0,
+ &m_d3d11Device,
+ &m_d3d11DeviceContext,
+ nullptr ));
+
+ ThrowIfFailed(m_d3d11Device.As(&m_d3d11On12Device));
+}
+
+void D3D12RenderContext::InitSwapchain(int nWidth, int nHeight, HWND hWnd)
+{
+ // Describe and create the swap chain.
+ DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
+ swapChainDesc.BufferCount = nBufferCount;
+ swapChainDesc.BufferDesc.Width = nWidth;
+ swapChainDesc.BufferDesc.Height = nHeight;
+ swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
+ swapChainDesc.OutputWindow = hWnd;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.Windowed = TRUE;
+
+ ComPtr<IDXGISwapChain> swapChain;
+ ThrowIfFailed(m_factory->CreateSwapChain(
+ m_commandQueue.Get(), // Swap chain needs the queue so that it can force a flush on it.
+ &swapChainDesc,
+ &swapChain
+ ));
+
+ ThrowIfFailed(swapChain.As(&m_swapChain));
+
+ // This sample does not support fullscreen transitions.
+ // ThrowIfFailed(m_factory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER));
+
+ m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();
+
+ ThrowIfFailed(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocator)));
+
+ // Create the command list.
+ ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), nullptr, IID_PPV_ARGS(&m_commandList)));
+
+ m_pCurrentRenderTarget = new D3D12RenderTarget(0, nBufferCount);
+ m_pCurrentRenderTarget->OnCreate(nWidth, nHeight);
+ m_pCurrentRenderTarget->SetClearColor(0.5, 0.5, 0.5);
+ m_RenderTargetMap[0] = m_pCurrentRenderTarget;
+
+ m_pD3D11RenderTargetView = new ID3D11RenderTargetView*[nBufferCount];
+ m_wrappedBackBuffers = new ID3D11Resource*[nBufferCount];
+ for (int n = 0; n < nBufferCount; n++)
+ {
+ m_pD3D11RenderTargetView[n] = nullptr;
+ m_wrappedBackBuffers[n] = nullptr;
+ }
+
+ PostCreate();
+}
+
+#ifndef Safe_Release
+#define Safe_Release(p) { if (p) { p->Release(); (p) = nullptr; } }
+#endif // !Safe_Delete
+
+void D3D12RenderContext::ResizeSwapchain(int width, int height)
+{
+ D3D12RenderTarget* rt = m_RenderTargetMap[0];
+
+ for (int n = 0; n < nBufferCount; n++)
+ {
+ Safe_Release(m_pD3D11RenderTargetView[n]);
+ Safe_Release(m_wrappedBackBuffers[n]);
+ }
+ m_d3d11DeviceContext->Flush();
+
+ rt->OnDestroy();
+
+ ThrowIfFailed(m_swapChain->ResizeBuffers(nBufferCount, width, height, DXGI_FORMAT_R8G8B8A8_UNORM, 0));
+
+ m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();
+
+ rt->OnResize(width, height);
+
+ for (int n = 0; n < nBufferCount; n++)
+ {
+ ID3D11On12Device* pDevice11On12 = GetDevice11On12();
+
+ D3D11_RESOURCE_FLAGS d3d11Flags = { D3D11_BIND_RENDER_TARGET };
+ ThrowIfFailed(pDevice11On12->CreateWrappedResource(
+ rt->GetTexture(n, false),
+ &d3d11Flags,
+ D3D12_RESOURCE_STATE_RENDER_TARGET,
+ D3D12_RESOURCE_STATE_PRESENT,
+ IID_PPV_ARGS(&m_wrappedBackBuffers[n])));
+
+ ThrowIfFailed(m_d3d11Device->CreateRenderTargetView(m_wrappedBackBuffers[n],
+ NULL, &m_pD3D11RenderTargetView[n]));
+ }
+}
+
+void D3D12RenderContext::PostCreate()
+{
+ m_srvUavHeap.Init(m_device.Get(), 256, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_FLAG_NONE);
+
+ {
+ ThrowIfFailed(m_commandList->Close());
+ ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
+ m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
+ }
+
+ {
+ ThrowIfFailed(m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence)));
+ m_fenceValue = 1;
+
+ // Create an event handle to use for frame synchronization.
+ m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
+ if (m_fenceEvent == nullptr)
+ {
+ ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()));
+ }
+
+ WaitForGpu();
+ }
+}
+
+void D3D12RenderContext::OnDestroy()
+{
+ WaitForGpu();
+ if (nullptr != m_fenceEvent)
+ {
+ CloseHandle(m_fenceEvent);
+ m_fenceEvent = nullptr;
+ }
+
+#if 0
+ ID3D12DebugDevice* debugInterface;
+ if (SUCCEEDED(m_device.Get()->QueryInterface(&debugInterface)))
+ {
+ debugInterface->ReportLiveDeviceObjects(D3D12_RLDO_DETAIL | D3D12_RLDO_IGNORE_INTERNAL);
+ debugInterface->Release();
+ }
+#endif // 0
+}
+
+void D3D12RenderContext::PreRender()
+{
+ ThrowIfFailed(m_commandAllocator->Reset());
+ ThrowIfFailed(m_commandList->Reset(m_commandAllocator.Get(), nullptr));
+}
+
+void D3D12RenderContext::PostRender()
+{
+ ThrowIfFailed(m_commandList->Close());
+ ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
+ m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
+
+ OnGpuWorkSubmitted(m_commandQueue.Get());
+
+ WaitForGpu();
+}
+
+void D3D12RenderContext::SubmitGpuWork()
+{
+ ThrowIfFailed(m_commandList->Close());
+ ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
+ m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
+
+ ThrowIfFailed(m_commandList->Reset(m_commandAllocator.Get(), nullptr));
+
+ OnGpuWorkSubmitted(m_commandQueue.Get());
+}
+
+
+void D3D12RenderContext::Flush()
+{
+ m_pCurrentRenderTarget->PostRender();
+ PostRender();
+ PreRender();
+ m_pCurrentRenderTarget->PreRender();
+}
+
+void D3D12RenderContext::Present()
+{
+ ThrowIfFailed(m_swapChain->Present(1, 0));
+ //ThrowIfFailed(m_swapChain->Present(0, 0));
+ m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();
+
+ //OnGpuWorkSubmitted(m_commandQueue.Get(), true);
+ //WaitForGpu();
+}
+
+int D3D12RenderContext::AllocRenderTargetIndex()
+{
+ return nRenderTargetIndex++;
+}
+
+
+void D3D12RenderContext::AddGpuInterface(GpuInterface* gpuIntf)
+{
+ m_gpuInterfaces.push_back(gpuIntf);
+}
+
+
+void D3D12RenderContext::OnGpuWorkSubmitted(ID3D12CommandQueue* queue)
+{
+ std::vector<GpuInterface*>::const_iterator cur = m_gpuInterfaces.begin();
+ std::vector<GpuInterface*>::const_iterator end = m_gpuInterfaces.end();
+
+ for (; cur != end; cur++)
+ {
+ (*cur)->onGpuWorkSubmitted(queue);
+ }
+}
+
+void D3D12RenderContext::UpdateGpuWorkCompleted()
+{
+ std::vector<GpuInterface*>::const_iterator cur = m_gpuInterfaces.begin();
+ std::vector<GpuInterface*>::const_iterator end = m_gpuInterfaces.end();
+
+ for (; cur != end; cur++)
+ {
+ (*cur)->updateGpuWorkCompleted();
+ }
+}
+
+D3D12RenderTarget* D3D12RenderContext::CreateRenderTarget(int renderTargetIndex, int nWidth, int nHeight)
+{
+ D3D12RenderTarget* pRenderTarget = new D3D12RenderTarget(renderTargetIndex);
+ pRenderTarget->OnCreate(nWidth, nHeight);
+ m_RenderTargetMap[renderTargetIndex] = pRenderTarget;
+ return pRenderTarget;
+}
+
+ID3D12Resource* D3D12RenderContext::GetTexture(int renderTargetIndex, int index)
+{
+ D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[renderTargetIndex];
+ ID3D12Resource* pTexture = pRenderTarget->GetTexture(index);
+ return pTexture;
+}
+
+void D3D12RenderContext::SetViewport(D3D12_VIEWPORT& vp)
+{
+ m_pCurrentRenderTarget->m_viewport = vp;
+ m_commandList->RSSetViewports(1, &vp);
+}
+
+void D3D12RenderContext::GetViewport(D3D12_VIEWPORT& vp)
+{
+ vp = m_pCurrentRenderTarget->m_viewport;
+}
+
+D3D12_RESOURCE_DESC D3D12RenderContext::GetBackBufferDesc()
+{
+ D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[0];
+ ID3D12Resource* pResource = pRenderTarget->GetTexture();
+ return pResource->GetDesc();
+}
+
+void D3D12RenderContext::SwitchToDX11()
+{
+ ReleaseRenderTarget();
+ PostRender();
+
+ if (nullptr == m_wrappedBackBuffers[m_frameIndex])
+ {
+ return;
+ }
+
+ m_d3d11On12Device->AcquireWrappedResources(&m_wrappedBackBuffers[m_frameIndex], 1);
+
+ m_d3d11DeviceContext->OMSetRenderTargets(1, &m_pD3D11RenderTargetView[m_frameIndex], nullptr);
+ D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[0];
+ D3D11_VIEWPORT vp;
+ {
+ vp.TopLeftX = 0;
+ vp.TopLeftY = 0;
+ vp.Width = (float)pRenderTarget->m_viewport.Width;
+ vp.Height = (float)pRenderTarget->m_viewport.Height;
+ vp.MinDepth = 0.0f;
+ vp.MaxDepth = 1.0f;
+ }
+ m_d3d11DeviceContext->RSSetViewports(1, &vp);
+}
+
+void D3D12RenderContext::FlushDX11()
+{
+ if (nullptr == m_wrappedBackBuffers[m_frameIndex])
+ {
+ return;
+ }
+
+ m_d3d11On12Device->ReleaseWrappedResources(&m_wrappedBackBuffers[m_frameIndex], 1);
+ m_d3d11DeviceContext->Flush();
+}
+
+ID3D12Resource* D3D12RenderContext::GetDepthStencilResource()
+{
+ D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[0];
+ return pRenderTarget->GetDepthStencilResource();
+}
+
+D3D12_CPU_DESCRIPTOR_HANDLE D3D12RenderContext::GetRenderTargetViewHandle()
+{
+ D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[0];
+ return pRenderTarget->GetRenderTargetViewHandle();
+}
+
+D3D12_CPU_DESCRIPTOR_HANDLE D3D12RenderContext::GetDepthStencilViewHandle()
+{
+ D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[0];
+ return pRenderTarget->GetDepthStencilViewHandle();
+}
+
+void D3D12RenderContext::AcquireRenderTarget(bool doClear, int renderTargetIndex)
+{
+ m_pCurrentRenderTarget = m_RenderTargetMap[renderTargetIndex];
+ m_pCurrentRenderTarget->PreRender(doClear);
+}
+
+void D3D12RenderContext::ReleaseRenderTarget(int renderTargetIndex)
+{
+ D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[renderTargetIndex];
+ pRenderTarget->PostRender();
+}
+
+void D3D12RenderContext::SetClearColor(int renderTargetIndex, float r, float g, float b, float a, float depth, float stencil)
+{
+ D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[renderTargetIndex];
+ pRenderTarget->SetClearColor(r, g, b, a, depth, stencil);
+}
+
+void D3D12RenderContext::WaitForGpu()
+{
+ const UINT64 fence = m_fenceValue;
+ ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), fence));
+ m_fenceValue++;
+
+ // Wait until the previous frame is finished.
+ if (m_fence->GetCompletedValue() < fence)
+ {
+ ThrowIfFailed(m_fence->SetEventOnCompletion(fence, m_fenceEvent));
+ WaitForSingleObject(m_fenceEvent, INFINITE);
+ }
+}
+
+void D3D12RenderContext::InitBuffer(NVHairReadOnlyBuffer& buffer)
+{
+ buffer.Init(&m_srvUavHeap);
+}
+
+void D3D12RenderContext::DestroyBuffer(NVHairReadOnlyBuffer& buffer)
+{
+ buffer.Release();
+}
+
+CD3DX12_CPU_DESCRIPTOR_HANDLE D3D12RenderContext::NVHairINT_CreateD3D12ReadOnlyBuffer(
+ UINT stride,
+ UINT numElements,
+ NVHairReadOnlyBuffer* pReadOnlyBuffer,
+ void* pSysMem)
+{
+ ID3D12Device* pd3dDevice = m_device.Get();
+ ID3D12GraphicsCommandList* pCommandList = m_commandList.Get();
+
+ UINT bufferSize = numElements * stride;
+
+ HRESULT hr;
+ hr = pd3dDevice->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
+ D3D12_HEAP_FLAG_NONE,
+ &CD3DX12_RESOURCE_DESC::Buffer(bufferSize),
+ D3D12_RESOURCE_STATE_COPY_DEST,
+ nullptr,
+ IID_PPV_ARGS(pReadOnlyBuffer->m_pBuffer.ReleaseAndGetAddressOf()));
+
+ hr = pd3dDevice->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
+ D3D12_HEAP_FLAG_NONE,
+ &CD3DX12_RESOURCE_DESC::Buffer(bufferSize),
+ D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr,
+ IID_PPV_ARGS(pReadOnlyBuffer->m_pBufferUpload.ReleaseAndGetAddressOf()));
+
+ D3D12_SUBRESOURCE_DATA data = {};
+ data.pData = reinterpret_cast<UINT8*>(pSysMem);
+ data.RowPitch = bufferSize;
+ data.SlicePitch = data.RowPitch;
+
+ PreRender();
+ UpdateSubresources<1>(pCommandList, pReadOnlyBuffer->m_pBuffer.Get(), pReadOnlyBuffer->m_pBufferUpload.Get(), 0, 0, 1, &data);
+ pCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(pReadOnlyBuffer->m_pBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE));
+ PostRender();
+
+ CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(pReadOnlyBuffer->m_pSrvUavHeap->m_pHeap.Get()->GetCPUDescriptorHandleForHeapStart(), pReadOnlyBuffer->m_srvIndex, pReadOnlyBuffer->m_pSrvUavHeap->m_sizeDescriptor);
+ D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
+ srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+ srvDesc.Format = DXGI_FORMAT_UNKNOWN;
+ srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
+ srvDesc.Buffer.FirstElement = 0;
+ srvDesc.Buffer.NumElements = numElements;
+ srvDesc.Buffer.StructureByteStride = stride;
+ srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
+ pd3dDevice->CreateShaderResourceView(pReadOnlyBuffer->m_pBuffer.Get(), &srvDesc, srvHandle);
+
+ return srvHandle;
+}
+
+CD3DX12_CPU_DESCRIPTOR_HANDLE D3D12RenderContext::NVHairINT_CreateD3D12Texture(ID3D12Resource* pTexture, int& nIndexInHeap)
+{
+ CD3DX12_CPU_DESCRIPTOR_HANDLE handle = {};
+
+ if (!pTexture)
+ return handle;
+
+ ID3D12Device* pDevice = m_device.Get();
+ if (!pDevice)
+ return handle;
+
+ nIndexInHeap = m_srvUavHeap.allocate();
+ if(nIndexInHeap == -1)
+ return handle;
+
+ CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(m_srvUavHeap.m_pHeap.Get()->GetCPUDescriptorHandleForHeapStart(),
+ nIndexInHeap, m_srvUavHeap.m_sizeDescriptor);
+
+ D3D12_RESOURCE_DESC desc = pTexture->GetDesc();
+
+ D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
+ srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+ srvDesc.Format = desc.Format;
+ srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MipLevels = 1;
+
+ pDevice->CreateShaderResourceView(pTexture, &srvDesc, srvHandle);
+
+ return srvHandle;
+}
+
+void D3D12RenderContext::NVHairINT_DestroyD3D12Texture(int& nIndexInHeap)
+{
+ if (nIndexInHeap != -1)
+ {
+ m_srvUavHeap.deallocate(nIndexInHeap);
+ }
+}
+
+void D3D12RenderContext::SetSampleCount(int nSampleCount)
+{
+ m_sampleCount = 1;
+
+ if (nSampleCount > D3D12_MAX_MULTISAMPLE_SAMPLE_COUNT)
+ nSampleCount = D3D12_MAX_MULTISAMPLE_SAMPLE_COUNT;
+
+ if (nSampleCount > 1)
+ {
+ D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS qualityLevels;
+ qualityLevels.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ qualityLevels.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE;
+ qualityLevels.NumQualityLevels = 0;
+ qualityLevels.SampleCount = nSampleCount;
+
+ ID3D12Device *pDevice = GetDevice();
+ pDevice->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &qualityLevels, sizeof(qualityLevels));
+
+ if (qualityLevels.NumQualityLevels > 0)
+ {
+ m_sampleCount = qualityLevels.SampleCount;
+ }
+ }
+}
+
+int D3D12RenderContext::GetSampleCount()
+{
+ return m_sampleCount;
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.h b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.h
new file mode 100644
index 0000000..2e0b393
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.h
@@ -0,0 +1,254 @@
+#pragma once
+
+#include "D3D12RenderTarget.h"
+#include "RenderPlugin.h"
+
+#include "d3dx12.h"
+#include <wrl.h>
+using namespace Microsoft::WRL;
+
+struct NVHairHeap
+{
+ ComPtr<ID3D12DescriptorHeap> m_pHeap;
+ UINT m_sizeHeap;
+ UINT m_currentIndex;
+ UINT m_sizeDescriptor;
+ std::vector<UINT> m_availableIndexes;
+
+ void Init(ID3D12Device* pd3dDevice, UINT size, D3D12_DESCRIPTOR_HEAP_TYPE type, D3D12_DESCRIPTOR_HEAP_FLAGS flags)
+ {
+ HRESULT hr;
+
+ D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {};
+ srvHeapDesc.NumDescriptors = size;
+ srvHeapDesc.Flags = flags;
+ srvHeapDesc.Type = type;
+ hr = pd3dDevice->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(m_pHeap.ReleaseAndGetAddressOf()));
+
+ if (SUCCEEDED(hr))
+ {
+ m_sizeHeap = size;
+ m_sizeDescriptor = pd3dDevice->GetDescriptorHandleIncrementSize(type);
+ }
+ else
+ {
+ m_sizeHeap = 0;
+ m_sizeDescriptor = 0;
+ }
+ m_currentIndex = 0;
+ m_availableIndexes.clear();
+ }
+
+ UINT allocate()
+ {
+ int availables = m_availableIndexes.size();
+ if (availables > 0)
+ {
+ UINT index = m_availableIndexes[availables - 1];
+ m_availableIndexes.pop_back();
+ return index;
+ }
+ UINT index = m_currentIndex++;
+ if (m_sizeHeap > m_currentIndex)
+ return index;
+ return (UINT)-1;
+ }
+
+ void deallocate(UINT availableIndex)
+ {
+ m_availableIndexes.push_back(availableIndex);
+ }
+
+ void Release()
+ {
+ if (m_pHeap) m_pHeap = nullptr;
+ m_sizeHeap = 0;
+ m_currentIndex = 0;
+ m_sizeDescriptor = 0;
+ m_availableIndexes.clear();
+ }
+};
+
+struct NVHairVertexBuffer
+{
+ ComPtr<ID3D12Resource> m_pBuffer;
+ ComPtr<ID3D12Resource> m_pBufferUpload;
+ D3D12_VERTEX_BUFFER_VIEW m_vertexBufferView;
+ NVHairHeap* m_pSrvUavHeap;
+ UINT m_uavIndex;
+
+ void Init(NVHairHeap* pHeap)
+ {
+ m_pBuffer = nullptr;
+ m_pBufferUpload = nullptr;
+ memset(&m_vertexBufferView, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW));
+ m_pSrvUavHeap = pHeap;
+
+ m_uavIndex = m_pSrvUavHeap->allocate();
+ }
+
+ D3D12_CPU_DESCRIPTOR_HANDLE getUavCpuHandle()
+ {
+ CD3DX12_CPU_DESCRIPTOR_HANDLE uavHandle(m_pSrvUavHeap->m_pHeap.Get()->GetCPUDescriptorHandleForHeapStart(), m_uavIndex, m_pSrvUavHeap->m_sizeDescriptor);
+ return uavHandle;
+ }
+
+ void Release()
+ {
+ if (m_pBuffer) m_pBuffer = nullptr;
+ if (m_pBufferUpload) m_pBufferUpload = nullptr;
+ memset(&m_vertexBufferView, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW));
+ if (m_pSrvUavHeap) m_pSrvUavHeap = nullptr;
+ m_uavIndex = (UINT)-1;
+ }
+};
+
+struct NVHairReadOnlyBuffer
+{
+ ComPtr<ID3D12Resource> m_pBuffer;
+ ComPtr<ID3D12Resource> m_pBufferUpload;
+ NVHairHeap* m_pSrvUavHeap;
+ UINT m_srvIndex;
+
+ void Init(NVHairHeap* pHeap)
+ {
+ m_pBuffer = nullptr;
+ m_pBufferUpload = nullptr;
+ m_pSrvUavHeap = pHeap;
+
+ m_srvIndex = m_pSrvUavHeap->allocate();
+ }
+
+ CD3DX12_CPU_DESCRIPTOR_HANDLE getSrvCpuHandle()
+ {
+ CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(m_pSrvUavHeap->m_pHeap.Get()->GetCPUDescriptorHandleForHeapStart(), m_srvIndex, m_pSrvUavHeap->m_sizeDescriptor);
+ return srvHandle;
+ }
+
+ void Release()
+ {
+ m_pSrvUavHeap->deallocate(m_srvIndex);
+
+ if (m_pBuffer) m_pBuffer = nullptr;
+ if (m_pBufferUpload) m_pBufferUpload = nullptr;
+ if (m_pSrvUavHeap) m_pSrvUavHeap = nullptr;
+ m_srvIndex = (UINT)-1;
+ }
+};
+
+class CORERENDER_EXPORT D3D12RenderContext
+{
+public:
+ ~D3D12RenderContext();
+ static D3D12RenderContext* Instance();
+
+ class GpuInterface
+ {
+ public:
+ virtual void onGpuWorkSubmitted(ID3D12CommandQueue* queue) = 0;
+ virtual void updateGpuWorkCompleted() = 0;
+ virtual ~GpuInterface() {}
+ };
+
+ typedef void (*GpuWorkSubmitFunc)(ID3D12CommandQueue* queue, void* data);
+ typedef void (*GpuUpdateCompletedFunc)(void* data);
+
+ void InitDevice();
+ void InitSwapchain(int width, int height, HWND hWnd);
+ void ResizeSwapchain(int width, int height);
+ void PostCreate();
+
+ void OnDestroy();
+
+ void PreRender();
+ void PostRender();
+ void Flush();
+
+ void SubmitGpuWork();
+ void WaitForGpu();
+
+ void UpdateGpuWorkCompleted();
+
+ void Present();
+
+ int AllocRenderTargetIndex();
+ D3D12RenderTarget* CreateRenderTarget(int renderTargetIndex, int nWidth, int nHeight);
+ void SetClearColor(int renderTargetIndex, float r, float g, float b, float a = 1.0, float depth = 1.0, float stencil = 0.0);
+ void AcquireRenderTarget(bool doClear = false, int renderTargetIndex = 0);
+ void ReleaseRenderTarget(int renderTargetIndex = 0);
+ ID3D12Resource* GetTexture(int renderTargetIndex, int index = 0);
+ void SetViewport(D3D12_VIEWPORT& vp);
+ void GetViewport(D3D12_VIEWPORT& vp);
+
+ ID3D12Device* GetDevice() { return m_device.Get(); }
+ ID3D12GraphicsCommandList* GetGraphicsCommandList() { return m_commandList.Get(); }
+ ID3D12CommandQueue* GetCommandQueue() const { return m_commandQueue.Get(); }
+
+ IDXGISwapChain3* GetSwapChain() { return m_swapChain.Get(); }
+ UINT GetFrameIndex() { return m_frameIndex; }
+
+ ID3D11Device* GetDevice11() { return m_d3d11Device.Get(); }
+ ID3D11On12Device* GetDevice11On12() { return m_d3d11On12Device.Get(); }
+ ID3D11DeviceContext* GetDeviceContext() { return m_d3d11DeviceContext.Get(); }
+
+ D3D12_RESOURCE_DESC GetBackBufferDesc();
+ void SwitchToDX11();
+ void FlushDX11();
+
+ ID3D12Resource* GetDepthStencilResource();
+ D3D12_CPU_DESCRIPTOR_HANDLE GetRenderTargetViewHandle();
+ D3D12_CPU_DESCRIPTOR_HANDLE GetDepthStencilViewHandle();
+
+ void InitBuffer(NVHairReadOnlyBuffer& buffer);
+ void DestroyBuffer(NVHairReadOnlyBuffer& buffer);
+
+ CD3DX12_CPU_DESCRIPTOR_HANDLE NVHairINT_CreateD3D12ReadOnlyBuffer(
+ UINT stride,
+ UINT numElements,
+ NVHairReadOnlyBuffer* pReadOnlyBuffer,
+ void* pSysMem);
+
+ CD3DX12_CPU_DESCRIPTOR_HANDLE NVHairINT_CreateD3D12Texture(ID3D12Resource* pTexture, int& nIndexInHeap);
+ void NVHairINT_DestroyD3D12Texture(int& nIndexInHeap);
+
+ void SetSampleCount(int nSampleCount);
+ int GetSampleCount();
+
+ void AddGpuInterface(GpuInterface* intf);
+
+private:
+ void OnGpuWorkSubmitted(ID3D12CommandQueue* queue);
+
+ D3D12RenderContext();
+
+ ComPtr<IDXGIFactory4> m_factory;
+ ComPtr<IDXGIAdapter1> m_adapter;
+
+ ComPtr<ID3D12Device> m_device;
+ ComPtr<ID3D12CommandQueue> m_commandQueue;
+ ComPtr<ID3D12CommandAllocator> m_commandAllocator;
+ ComPtr<ID3D12GraphicsCommandList> m_commandList;
+ ComPtr<IDXGISwapChain3> m_swapChain;
+
+ ComPtr<ID3D11Device> m_d3d11Device;
+ ComPtr<ID3D11On12Device> m_d3d11On12Device;
+ ComPtr<ID3D11DeviceContext> m_d3d11DeviceContext;
+ ID3D11Resource** m_wrappedBackBuffers;
+ ID3D11RenderTargetView** m_pD3D11RenderTargetView;
+
+ UINT m_frameIndex;
+ HANDLE m_fenceEvent;
+ ComPtr<ID3D12Fence> m_fence;
+ UINT64 m_fenceValue;
+
+ D3D12RenderTarget* m_pCurrentRenderTarget;
+ map<int, D3D12RenderTarget*> m_RenderTargetMap;
+
+ std::vector<GpuInterface*> m_gpuInterfaces;
+
+ NVHairHeap m_srvUavHeap;
+
+ // sample desc
+ UINT m_sampleCount;
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.cpp
new file mode 100644
index 0000000..2346683
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.cpp
@@ -0,0 +1,467 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D12RenderInterface.h"
+
+#include "D3D12TextureResource.h"
+#include "D3D12Shaders.h"
+#include "D3D12Buffer.h"
+
+#include "D3D12RenderContext.h"
+
+namespace RenderInterfaceD3D12
+{
+ using namespace RenderInterface;
+
+ D3D12_BLEND_DESC m_BlendStates[BLEND_STATE_END];
+ D3D12_DEPTH_STENCIL_DESC m_DepthStencilStates[DEPTH_STENCIL_STATE_END];
+ D3D12_RASTERIZER_DESC m_RasterizerStates[RASTERIZER_STATE_END];
+
+ D3D12RenderContext *pRenderContext = D3D12RenderContext::Instance();
+
+ SHADER_TYPE m_ShaderType;
+ RenderShaderStateKey m_ShaderStateKey;
+
+ map<RenderShaderStateKey, RenderShaderState*> m_RenderShaderStates;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool InitDevice(int deviceID)
+{
+ pRenderContext->InitDevice();
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool Initialize()
+{
+ if (!pRenderContext)
+ return false;
+
+ InitializeShadersD3D12();
+ InitializeRenderStates();
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void Shutdown()
+{
+ DestroyShadersD3D12();
+}
+
+RenderShaderState* GetShaderState()
+{
+ RenderShaderState* pShaderState = nullptr;
+ map<RenderShaderStateKey, RenderShaderState*>::iterator it = m_RenderShaderStates.find(m_ShaderStateKey);
+ if (it != m_RenderShaderStates.end())
+ {
+ pShaderState = it->second;
+ }
+ else
+ {
+ pShaderState = new RenderShaderState;
+ pShaderState->BlendState = m_BlendStates[m_ShaderStateKey.BlendState];
+ pShaderState->DepthStencilState = m_DepthStencilStates[m_ShaderStateKey.DepthStencilState];
+ pShaderState->RasterizerState = m_RasterizerStates[m_ShaderStateKey.RasterizerState];
+ pShaderState->PrimitiveTopologyType = m_ShaderStateKey.PrimitiveTopologyType;
+ if (m_ShaderStateKey.ForShadow)
+ {
+ pShaderState->RTVFormat = DXGI_FORMAT_R32_FLOAT;
+ pShaderState->DSVFormat = DXGI_FORMAT_D32_FLOAT;
+ }
+ else
+ {
+ pShaderState->RTVFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
+ pShaderState->DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
+ pShaderState->SampleCount = D3D12RenderContext::Instance()->GetSampleCount();
+ }
+
+ m_RenderShaderStates[m_ShaderStateKey] = pShaderState;
+ }
+ return pShaderState;
+}
+//////////////////////////////////////////////////////////////////////////////////////
+void InitializeRenderStates()
+{
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // alpha blending state descriptors
+ /////////////////////////////////////////////////////////////////////////////////////////
+
+ // alpha blending enabled
+ {
+ D3D12_BLEND_DESC desc = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
+ desc.AlphaToCoverageEnable = false;
+ desc.IndependentBlendEnable = false;
+
+ D3D12_RENDER_TARGET_BLEND_DESC &rtDesc = desc.RenderTarget[0];
+ {
+ rtDesc.BlendEnable = true;
+ rtDesc.SrcBlend = D3D12_BLEND_SRC_ALPHA;
+ rtDesc.DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
+ rtDesc.BlendOp = D3D12_BLEND_OP_ADD;
+ rtDesc.SrcBlendAlpha = D3D12_BLEND_ZERO;
+ rtDesc.DestBlendAlpha = D3D12_BLEND_ONE;
+ rtDesc.BlendOpAlpha = D3D12_BLEND_OP_ADD;
+ rtDesc.RenderTargetWriteMask = 0x0f;
+ }
+ m_BlendStates[BLEND_STATE_ALPHA] = desc;
+ }
+
+ // no alpha blending
+ {
+ D3D12_BLEND_DESC desc = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
+ desc.AlphaToCoverageEnable = false;
+ desc.IndependentBlendEnable = false;
+
+ D3D12_RENDER_TARGET_BLEND_DESC &rtDesc = desc.RenderTarget[0];
+ {
+ rtDesc.BlendEnable = false;
+ rtDesc.SrcBlend = D3D12_BLEND_SRC_ALPHA;
+ rtDesc.DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
+ rtDesc.BlendOp = D3D12_BLEND_OP_ADD;
+ rtDesc.SrcBlendAlpha = D3D12_BLEND_ZERO;
+ rtDesc.DestBlendAlpha = D3D12_BLEND_ONE;
+ rtDesc.BlendOpAlpha = D3D12_BLEND_OP_ADD;
+ rtDesc.RenderTargetWriteMask = 0x0f;
+ }
+ m_BlendStates[BLEND_STATE_NONE] = desc;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // depth and stencil
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+ D3D12_DEPTH_STENCIL_DESC depthTestDesc = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
+ {
+ depthTestDesc.DepthEnable = true;
+ depthTestDesc.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
+ depthTestDesc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
+ depthTestDesc.StencilEnable = false;
+ depthTestDesc.StencilReadMask = 0xff;
+ depthTestDesc.StencilWriteMask = 0xff;
+ }
+
+ m_DepthStencilStates[DEPTH_STENCIL_DEPTH_TEST] = depthTestDesc;
+
+ D3D12_DEPTH_STENCIL_DESC depthNone = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
+ {
+ depthNone.DepthEnable = false;
+ depthNone.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
+ depthNone.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
+ depthNone.StencilEnable = false;
+ depthNone.StencilReadMask = 0xff;
+ depthNone.StencilWriteMask = 0xff;
+ }
+
+ m_DepthStencilStates[DEPTH_STENCIL_DEPTH_NONE] = depthNone;
+
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // rasterizer
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+ D3D12_RASTERIZER_DESC rsDesc = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
+
+ // solid cull front
+ {
+ rsDesc.FillMode = D3D12_FILL_MODE_SOLID;
+ rsDesc.CullMode = D3D12_CULL_MODE_FRONT;
+ rsDesc.AntialiasedLineEnable = false;
+ rsDesc.MultisampleEnable = true;
+ rsDesc.FrontCounterClockwise = true;
+ rsDesc.DepthBias = 10;
+ rsDesc.DepthBiasClamp = 0;
+ rsDesc.SlopeScaledDepthBias = 0;
+ rsDesc.DepthClipEnable = true;
+ rsDesc.ForcedSampleCount = 0;
+
+ m_RasterizerStates[RASTERIZER_STATE_FILL_CULL_FRONT] = rsDesc;
+ };
+
+ // solid cull back
+ {
+ rsDesc.FillMode = D3D12_FILL_MODE_SOLID;
+ rsDesc.CullMode = D3D12_CULL_MODE_BACK;
+ rsDesc.AntialiasedLineEnable = false;
+ rsDesc.MultisampleEnable = true;
+ rsDesc.FrontCounterClockwise = true;
+ rsDesc.DepthBias = 10;
+ rsDesc.DepthBiasClamp = 0;
+ rsDesc.SlopeScaledDepthBias = 0;
+ rsDesc.DepthClipEnable = true;
+ rsDesc.ForcedSampleCount = 0;
+
+ m_RasterizerStates[RASTERIZER_STATE_FILL_CULL_BACK] = rsDesc;
+ }
+
+ // solid cull none
+ {
+ rsDesc.FillMode = D3D12_FILL_MODE_SOLID;
+ rsDesc.CullMode = D3D12_CULL_MODE_NONE;
+ rsDesc.AntialiasedLineEnable = false;
+ rsDesc.MultisampleEnable = true;
+ rsDesc.FrontCounterClockwise = true;
+ rsDesc.DepthBias = 10;
+ rsDesc.DepthBiasClamp = 0;
+ rsDesc.SlopeScaledDepthBias = 0;
+ rsDesc.DepthClipEnable = true;
+ rsDesc.ForcedSampleCount = 0;
+
+ m_RasterizerStates[RASTERIZER_STATE_FILL_CULL_NONE] = rsDesc;
+ }
+
+ // wireframe cull none
+ {
+ rsDesc.FillMode = D3D12_FILL_MODE_WIREFRAME;
+ rsDesc.CullMode = D3D12_CULL_MODE_NONE;
+ rsDesc.AntialiasedLineEnable = false;
+ rsDesc.MultisampleEnable = true;
+ rsDesc.FrontCounterClockwise = 0;
+ rsDesc.DepthBias = 0;
+ rsDesc.DepthBiasClamp = 0;
+ rsDesc.SlopeScaledDepthBias = 0;
+ rsDesc.DepthClipEnable = true;
+ rsDesc.ForcedSampleCount = 0;
+ };
+
+ m_RasterizerStates[RASTERIZER_STATE_WIRE] = rsDesc;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void SetPrimitiveTopologyTriangleStrip()
+{
+ ID3D12GraphicsCommandList* pCommandList = pRenderContext->GetGraphicsCommandList();
+ pCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void SetPrimitiveTopologyTriangleList()
+{
+ ID3D12GraphicsCommandList* pCommandList = pRenderContext->GetGraphicsCommandList();
+ pCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void SetPrimitiveTopologyLineList()
+{
+ ID3D12GraphicsCommandList* pCommandList = pRenderContext->GetGraphicsCommandList();
+ pCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_LINELIST);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset)
+{
+ D3D12_VERTEX_BUFFER_VIEW* vertexView = GPUBufferD3D12::GetVertexView(pBuffer);
+ if (!vertexView)
+ return;
+
+ vertexView->StrideInBytes = stride;
+ ID3D12GraphicsCommandList* m_commandList = pRenderContext->GetGraphicsCommandList();
+ m_commandList->IASetVertexBuffers(0, 1, vertexView);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void ApplyDepthStencilState(DEPTH_STENCIL_STATE state)
+{
+ m_ShaderStateKey.DepthStencilState = state;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void ApplyRasterizerState(RASTERIZER_STATE state)
+{
+ m_ShaderStateKey.RasterizerState = state;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void ApplyBlendState(BLEND_STATE state)
+{
+ m_ShaderStateKey.BlendState = state;
+}
+
+void ApplyPrimitiveTopologyType(D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType)
+{
+ m_ShaderStateKey.PrimitiveTopologyType = PrimitiveTopologyType;
+}
+
+void ApplyForShadow(int ForShadow)
+{
+ m_ShaderStateKey.ForShadow = ForShadow;
+}
+
+void SwitchToDX11()
+{
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ pContext->SwitchToDX11();
+}
+
+void FlushDX11()
+{
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ pContext->FlushDX11();
+}
+
+void FlushDX12()
+{
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ pContext->Flush();
+}
+
+void SubmitGpuWork()
+{
+ D3D12RenderContext::Instance()->SubmitGpuWork();
+}
+
+void WaitForGpu()
+{
+ D3D12RenderContext* context = D3D12RenderContext::Instance();
+ context->WaitForGpu();
+ context->UpdateGpuWorkCompleted();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+void SetViewport(const RenderInterface::Viewport& vp)
+{
+ ID3D12GraphicsCommandList* pCommandList = pRenderContext->GetGraphicsCommandList();
+
+ D3D12_VIEWPORT d3dViewport;
+
+ d3dViewport.TopLeftX = vp.TopLeftX;
+ d3dViewport.TopLeftY = vp.TopLeftY;
+
+ d3dViewport.Width = vp.Width;
+ d3dViewport.Height = vp.Height;
+
+ d3dViewport.MinDepth = vp.MinDepth;
+ d3dViewport.MaxDepth = vp.MaxDepth;
+
+ pRenderContext->SetViewport(d3dViewport);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+void GetViewport(RenderInterface::Viewport& vp)
+{
+ D3D12_VIEWPORT d3dViewport;
+ pRenderContext->GetViewport(d3dViewport);
+
+ vp.TopLeftX = d3dViewport.TopLeftX;
+ vp.TopLeftY = d3dViewport.TopLeftY;
+
+ vp.Width = d3dViewport.Width;
+ vp.Height = d3dViewport.Height;
+
+ vp.MinDepth = d3dViewport.MinDepth;
+ vp.MaxDepth = d3dViewport.MaxDepth;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void Draw(unsigned int vertexCount, unsigned int startCount)
+{
+ ID3D12GraphicsCommandList* pCommandList = pRenderContext->GetGraphicsCommandList();
+ pCommandList->DrawInstanced(vertexCount, 1, startCount, 0);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+GPUBufferResource* CreateVertexBuffer(
+ unsigned int ByteWidth, void* pSysMem)
+{
+ ID3D12Device* pDevice = D3D12RenderContext::Instance()->GetDevice();
+ if (!pDevice)
+ return false;
+
+ ID3D12Resource* pBuffer = nullptr;
+ ThrowIfFailed(pDevice->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
+ D3D12_HEAP_FLAG_NONE,
+ &CD3DX12_RESOURCE_DESC::Buffer(ByteWidth),
+ D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr,
+ IID_PPV_ARGS(&pBuffer)));
+ if (nullptr == pBuffer)
+ {
+ return false;
+ }
+
+ void* pData;
+ ThrowIfFailed(pBuffer->Map(0, nullptr, &pData));
+ memcpy(pData, pSysMem, ByteWidth);
+ pBuffer->Unmap(0, nullptr);
+
+ return GPUBufferD3D12::Create(pBuffer, ByteWidth);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+GPUShaderResource* CreateShaderResource(unsigned int stride,
+ unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer)
+{
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ if (!pContext)
+ return false;
+
+ ID3D12Device* pDevice = pContext->GetDevice();
+ ID3D12GraphicsCommandList* pCommandList = pContext->GetGraphicsCommandList();
+
+ pContext->NVHairINT_CreateD3D12ReadOnlyBuffer(stride, numElements, pReadOnlyBuffer, pSysMem);
+
+ int nIndexInHeap = -1;
+ return D3D12TextureResource::Create(pReadOnlyBuffer->m_pBuffer.Get(), pReadOnlyBuffer->getSrvCpuHandle(), nIndexInHeap);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// create read only shader resource buffer
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+void CopyToDevice(
+ GPUBufferResource *pGPUBuffer, void* pSysMem, unsigned int ByteWidth)
+{
+ ID3D12Resource* pBuffer = GPUBufferD3D12::GetResource(pGPUBuffer);
+ if (!pBuffer)
+ return;
+
+ void* pData;
+ ThrowIfFailed(pBuffer->Map(0, nullptr, &pData));
+ memcpy(pData, pSysMem, ByteWidth);
+ pBuffer->Unmap(0, nullptr);
+
+ /*
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ if (!pContext)
+ return;
+
+ ID3D12Device* pDevice = pContext->GetDevice();
+ ID3D12GraphicsCommandList* pCommandList = pContext->GetGraphicsCommandList();
+
+ D3D12_SUBRESOURCE_DATA data = {};
+ data.pData = reinterpret_cast<UINT8*>(pSysMem);
+ data.RowPitch = ByteWidth;
+ data.SlicePitch = data.RowPitch;
+
+ ID3D12Resource* m_pBufferUpload = GPUBufferD3D12::GetResourceUpload(pGPUBuffer, pDevice, ByteWidth);
+
+ UpdateSubresources<1>(pCommandList, pBuffer, m_pBufferUpload, 0, 0, 1, &data);
+ pCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(pBuffer,
+ D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE));
+ */
+}
+} // end namespace
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.h b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.h
new file mode 100644
index 0000000..8168936
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.h
@@ -0,0 +1,74 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+#include <d3d11.h>
+#include <d3d12.h>
+#include <dxgi1_4.h>
+#include "RenderInterface.h"
+#include "RenderPlugin.h"
+class RenderShaderState;
+// abstract interface to D3D calls
+namespace RenderInterfaceD3D12
+{
+ CORERENDER_EXPORT bool InitDevice(int deviceID);
+ CORERENDER_EXPORT bool Initialize();
+ CORERENDER_EXPORT void Shutdown();
+
+ RenderShaderState* GetShaderState();
+ void InitializeRenderStates();
+
+ CORERENDER_EXPORT void ApplyDepthStencilState(RenderInterface::DEPTH_STENCIL_STATE st);
+ CORERENDER_EXPORT void ApplyRasterizerState(RenderInterface::RASTERIZER_STATE st);
+ CORERENDER_EXPORT void ApplyBlendState(RenderInterface::BLEND_STATE st);
+ CORERENDER_EXPORT void ApplyPrimitiveTopologyType(D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType);
+ CORERENDER_EXPORT void ApplyForShadow(int ForShadow);
+ CORERENDER_EXPORT void SwitchToDX11();
+ CORERENDER_EXPORT void FlushDX11();
+ CORERENDER_EXPORT void FlushDX12();
+ CORERENDER_EXPORT void SubmitGpuWork();
+ CORERENDER_EXPORT void WaitForGpu();
+
+ CORERENDER_EXPORT void GetViewport(RenderInterface::Viewport& vp);
+ CORERENDER_EXPORT void SetViewport(const RenderInterface::Viewport& vp);
+
+ CORERENDER_EXPORT GPUBufferResource* CreateVertexBuffer( unsigned int ByteWidth, void* pSysMem);
+ CORERENDER_EXPORT GPUShaderResource* CreateShaderResource( unsigned int stride, unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer);
+
+ CORERENDER_EXPORT void CopyToDevice(GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth);
+
+ CORERENDER_EXPORT void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset = 0);
+
+ CORERENDER_EXPORT void SetPrimitiveTopologyTriangleStrip();
+ CORERENDER_EXPORT void SetPrimitiveTopologyTriangleList();
+ CORERENDER_EXPORT void SetPrimitiveTopologyLineList();
+
+
+ CORERENDER_EXPORT void Draw(unsigned int vertexCount, unsigned int startCount = 0);
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.cpp
new file mode 100644
index 0000000..f115349
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.cpp
@@ -0,0 +1,384 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#include "D3D12RenderShader.h"
+
+#include "D3D12RenderInterface.h"
+#include "D3D12Wrapper.h"
+#include "D3D12RenderContext.h"
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(x) { if (x) x->Release(); }
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+D3D12RenderShader::D3D12RenderShader()
+{
+ m_vertexShader = 0;
+ m_vertexShaderSize = 0;
+ m_pixelShader = 0;
+ m_pixelShaderSize = 0;
+
+ m_inputElementDescs = 0;
+ m_inputElementDescsNum = 0;
+
+ m_pRootSignature = 0;
+
+ m_scuHeap = 0;
+ m_scuDescriptorSize = 0;
+
+ m_samplerHeap = 0;
+ m_samplerDescriptorSize = 0;
+
+ m_PipelineStates.clear();
+
+ for (int i = 0; i < 2; i++)
+ {
+ m_ConstantBuffer[i] = nullptr;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+D3D12RenderShader::~D3D12RenderShader()
+{
+ for (int i = 0; i < 1; i++)
+ {
+ SAFE_RELEASE(m_ConstantBuffer[i]);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+D3D12RenderShader* D3D12RenderShader::Create(
+ const char *name,
+ void* vertexShader, size_t vertexShaderSize, void* pixelShader, size_t pixelShaderSize,
+ UINT cbufferSize0, UINT cbufferSize1,
+ D3D12_INPUT_ELEMENT_DESC* pElemDesc, UINT numElements,
+ int ShaderResourceNum, int UnorderedAccessNum, int SamplerNum)
+{
+ D3D12RenderContext* pAdapter = D3D12RenderContext::Instance();
+ ID3D12Device* m_device = pAdapter->GetDevice();
+
+ D3D12RenderShader* pShader = new D3D12RenderShader;
+
+ int sizeofuint = sizeof(UINT8);
+ pShader->m_vertexShaderSize = vertexShaderSize;
+ if (vertexShaderSize > 0)
+ {
+ pShader->m_vertexShader = new UINT8[vertexShaderSize / sizeofuint];
+ memcpy(pShader->m_vertexShader, vertexShader, vertexShaderSize);
+ }
+ pShader->m_pixelShaderSize = pixelShaderSize;
+ if (pixelShaderSize > 0)
+ {
+ pShader->m_pixelShader = new UINT8[pixelShaderSize / sizeofuint];
+ memcpy(pShader->m_pixelShader, pixelShader, pixelShaderSize);
+ }
+
+ pShader->m_inputElementDescsNum = numElements;
+ pShader->m_inputElementDescs = pElemDesc;
+
+ CD3DX12_DESCRIPTOR_RANGE ranges[3];
+ CD3DX12_ROOT_PARAMETER rootParameters[2];
+
+ int rangesindex = 0;
+ int rootParametersindex = 0;
+
+ if (ShaderResourceNum > 0)
+ {
+ ranges[rangesindex++].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, ShaderResourceNum, 0);
+ }
+ int ConstantBufferNum = 0;
+ if (cbufferSize0 > 0)
+ {
+ ConstantBufferNum++;
+ }
+ if (cbufferSize1 > 0)
+ {
+ ConstantBufferNum++;
+ }
+ if (ConstantBufferNum > 0)
+ {
+ ranges[rangesindex++].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, ConstantBufferNum, 0);
+ }
+ if (UnorderedAccessNum > 0)
+ {
+ ranges[rangesindex++].Init(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, UnorderedAccessNum, 0);
+ }
+ if (rangesindex > 0)
+ {
+ rootParameters[rootParametersindex++].InitAsDescriptorTable(rangesindex, &ranges[0], D3D12_SHADER_VISIBILITY_ALL);
+ }
+
+ if (SamplerNum > 0)
+ {
+ ranges[rangesindex].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, SamplerNum, 0);
+ rootParameters[rootParametersindex++].InitAsDescriptorTable(1, &ranges[rangesindex], D3D12_SHADER_VISIBILITY_ALL);
+ }
+
+ D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags =
+ D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
+ D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
+ D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
+ D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS;
+ CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
+ rootSignatureDesc.Init(rootParametersindex, rootParameters, 0, nullptr, rootSignatureFlags);
+
+ ComPtr<ID3DBlob> signature;
+ ComPtr<ID3DBlob> error;
+ ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
+ ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&pShader->m_pRootSignature)));
+
+ int numSCU = ShaderResourceNum + ConstantBufferNum + UnorderedAccessNum;
+ if (numSCU > 0)
+ {
+ D3D12_DESCRIPTOR_HEAP_DESC scuHeapDesc = {};
+ scuHeapDesc.NumDescriptors = numSCU;
+ scuHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
+ scuHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
+ ThrowIfFailed(m_device->CreateDescriptorHeap(&scuHeapDesc, IID_PPV_ARGS(&pShader->m_scuHeap)));
+ pShader->m_scuDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
+
+ if (ConstantBufferNum > 0)
+ {
+ CD3DX12_CPU_DESCRIPTOR_HANDLE scuHandle(pShader->m_scuHeap->GetCPUDescriptorHandleForHeapStart(),
+ ShaderResourceNum, pShader->m_scuDescriptorSize);
+
+ if (cbufferSize0 > 0)
+ {
+ pShader->CreateParamBuffer(cbufferSize0, 0);
+
+ // Describe and create a constant buffer view.
+ D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
+ // CB size is required to be 256-byte aligned.
+ cbvDesc.SizeInBytes = (cbufferSize0 + 255) & ~255;
+ cbvDesc.BufferLocation = pShader->m_ConstantBuffer[0]->GetGPUVirtualAddress();
+ m_device->CreateConstantBufferView(&cbvDesc, scuHandle);
+ scuHandle.Offset(pShader->m_scuDescriptorSize);
+ }
+ if (cbufferSize1 > 0)
+ {
+ pShader->CreateParamBuffer(cbufferSize1, 1);
+
+ // Describe and create a constant buffer view.
+ D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
+ // CB size is required to be 256-byte aligned.
+ cbvDesc.SizeInBytes = (cbufferSize1 + 255) & ~255;
+ cbvDesc.BufferLocation = pShader->m_ConstantBuffer[1]->GetGPUVirtualAddress();
+ m_device->CreateConstantBufferView(&cbvDesc, scuHandle);
+ }
+ }
+ }
+
+ if (SamplerNum > 0)
+ {
+ D3D12_DESCRIPTOR_HEAP_DESC samplerHeapDesc = {};
+ samplerHeapDesc.NumDescriptors = SamplerNum;
+ samplerHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
+ samplerHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
+ ThrowIfFailed(m_device->CreateDescriptorHeap(&samplerHeapDesc, IID_PPV_ARGS(&pShader->m_samplerHeap)));
+ pShader->m_samplerDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
+
+ CD3DX12_CPU_DESCRIPTOR_HANDLE samplerHandle(pShader->m_samplerHeap->GetCPUDescriptorHandleForHeapStart());
+
+ if(SamplerNum == 1)
+ {
+ D3D12_SAMPLER_DESC pointClampSamplerDesc[1] = {
+ D3D12_FILTER_MIN_MAG_MIP_POINT,
+ D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
+ D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
+ D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
+ 0.0, 0, D3D12_COMPARISON_FUNC_NEVER,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, D3D12_FLOAT32_MAX,
+ };
+ m_device->CreateSampler(pointClampSamplerDesc, samplerHandle);
+ }
+ else if(SamplerNum == 2)
+ {
+ D3D12_SAMPLER_DESC linearSamplerDesc[1] = {
+ D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT,
+ D3D12_TEXTURE_ADDRESS_MODE_WRAP,
+ D3D12_TEXTURE_ADDRESS_MODE_WRAP,
+ D3D12_TEXTURE_ADDRESS_MODE_WRAP,
+ 0.0, 0, D3D12_COMPARISON_FUNC_NEVER, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, D3D12_FLOAT32_MAX,
+ };
+ m_device->CreateSampler(linearSamplerDesc, samplerHandle);
+ samplerHandle.Offset(pShader->m_samplerDescriptorSize);
+
+ D3D12_SAMPLER_DESC pointClampSamplerDesc[1] = {
+ D3D12_FILTER_MIN_MAG_MIP_POINT,
+ D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
+ D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
+ D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
+ 0.0, 0, D3D12_COMPARISON_FUNC_NEVER,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, D3D12_FLOAT32_MAX,
+ };
+ m_device->CreateSampler(pointClampSamplerDesc, samplerHandle);
+ }
+ }
+
+ return pShader;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D12RenderShader::SetConstantBuffer()
+{
+ return;
+}
+
+ID3D12PipelineState* D3D12RenderShader::GetPipelineState(RenderShaderState* pShaderState)
+{
+ ID3D12PipelineState* pPipelineState = nullptr;
+ map<RenderShaderState*, ID3D12PipelineState*>::iterator it = m_PipelineStates.find(pShaderState);
+ if (it == m_PipelineStates.end())
+ {
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
+ psoDesc.InputLayout = { m_inputElementDescs, m_inputElementDescsNum };
+ psoDesc.pRootSignature = m_pRootSignature;
+ psoDesc.VS = { reinterpret_cast<UINT8*>(m_vertexShader), m_vertexShaderSize };
+ psoDesc.PS = { reinterpret_cast<UINT8*>(m_pixelShader), m_pixelShaderSize };
+ psoDesc.BlendState = pShaderState->BlendState;
+ psoDesc.RasterizerState = pShaderState->RasterizerState;
+ psoDesc.DepthStencilState = pShaderState->DepthStencilState;
+ psoDesc.SampleMask = UINT_MAX;
+ psoDesc.PrimitiveTopologyType = pShaderState->PrimitiveTopologyType;
+ psoDesc.NumRenderTargets = 1;
+ psoDesc.RTVFormats[0] = pShaderState->RTVFormat;
+ psoDesc.DSVFormat = pShaderState->DSVFormat;
+ psoDesc.SampleDesc.Count = pShaderState->SampleCount;
+
+ ID3D12Device* pDevice = D3D12RenderContext::Instance()->GetDevice();
+ ThrowIfFailed(pDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pPipelineState)));
+
+ m_PipelineStates[pShaderState] = pPipelineState;
+ }
+ else
+ {
+ pPipelineState = it->second;
+ }
+ return pPipelineState;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D12RenderShader::MakeCurrent()
+{
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ ID3D12GraphicsCommandList* m_commandList = pContext->GetGraphicsCommandList();
+
+ RenderShaderState* pShaderState = RenderInterfaceD3D12::GetShaderState();
+ if (nullptr == pShaderState)
+ {
+ return;
+ }
+
+ ID3D12PipelineState* pPipelineState = GetPipelineState(pShaderState);
+
+ m_commandList->SetGraphicsRootSignature(m_pRootSignature);
+ m_commandList->SetPipelineState(pPipelineState);
+
+ vector<ID3D12DescriptorHeap*> heaps;
+ if (nullptr != m_scuHeap)
+ {
+ heaps.push_back(m_scuHeap);
+ }
+ if (nullptr != m_samplerHeap)
+ {
+ heaps.push_back(m_samplerHeap);
+ }
+ if (heaps.size() > 0)
+ {
+ m_commandList->SetDescriptorHeaps(heaps.size(), heaps.data());
+ }
+ int heapindex = 0;
+ if (nullptr != m_scuHeap)
+ {
+ m_commandList->SetGraphicsRootDescriptorTable(heapindex++, m_scuHeap->GetGPUDescriptorHandleForHeapStart());
+ }
+ if (nullptr != m_samplerHeap)
+ {
+ m_commandList->SetGraphicsRootDescriptorTable(heapindex++, m_samplerHeap->GetGPUDescriptorHandleForHeapStart());
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D12RenderShader::Disable()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool D3D12RenderShader::CreateParamBuffer( UINT sizeBuffer, UINT slot )
+{
+ ID3D12Device* pDevice = D3D12RenderContext::Instance()->GetDevice();
+ if (!pDevice)
+ return false;
+
+ SAFE_RELEASE(m_ConstantBuffer[slot]);
+
+ ThrowIfFailed(pDevice->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
+ D3D12_HEAP_FLAG_NONE,
+ &CD3DX12_RESOURCE_DESC::Buffer(sizeBuffer),
+ D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr,
+ IID_PPV_ARGS(&m_ConstantBuffer[slot])));
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void* D3D12RenderShader::MapParam(UINT slot)
+{
+ if (!m_ConstantBuffer[slot])
+ return 0;
+
+ void* pData;
+ ThrowIfFailed(m_ConstantBuffer[slot]->Map(0, nullptr, &pData));
+ return pData;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D12RenderShader::UnmapParam( UINT slot )
+{
+ if (!m_ConstantBuffer[slot])
+ return;
+
+ m_ConstantBuffer[slot]->Unmap(0, nullptr);
+}
+
+void D3D12RenderShader::BindShaderResource(UINT slot, CD3DX12_CPU_DESCRIPTOR_HANDLE& handle)
+{
+ ID3D12Device* pDevice = D3D12RenderContext::Instance()->GetDevice();
+ if (!pDevice)
+ return;
+
+ CD3DX12_CPU_DESCRIPTOR_HANDLE destHandle(m_scuHeap->GetCPUDescriptorHandleForHeapStart(), slot, m_scuDescriptorSize);
+ if (handle.ptr != 0)
+ {
+ pDevice->CopyDescriptorsSimple(1, destHandle, handle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
+ }
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.h b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.h
new file mode 100644
index 0000000..d43783c
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.h
@@ -0,0 +1,85 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include <d3d11.h>
+#include <d3d12.h>
+
+#include "D3D12RenderTarget.h"
+
+class D3D12RenderShader
+{
+public:
+ D3D12RenderShader();
+ ~D3D12RenderShader();
+
+ static D3D12RenderShader* Create(
+ const char *name,
+ void* pVSBlob, size_t vsBlobSize,
+ void* pPSBlob, size_t psBlobSize,
+ UINT cbufferSize0 = 0, UINT cbufferSize1 = 0,
+ D3D12_INPUT_ELEMENT_DESC* pElemDesc = 0, UINT numElements = 0,
+ int ShaderResourceNum = 0, int UnorderedAccessNum = 0, int SamplerNum = 0);
+
+ void MakeCurrent();
+ void Disable();
+ void SetConstantBuffer();
+
+ void* MapParam(UINT slot = 0);
+ void UnmapParam(UINT slot = 0);
+
+ void BindShaderResource(UINT slot, CD3DX12_CPU_DESCRIPTOR_HANDLE& handle);
+
+protected:
+ bool CreateParamBuffer(UINT sizeBuffer, UINT slot = 0);
+
+private:
+ ID3D12PipelineState* GetPipelineState(RenderShaderState* pShaderState);
+
+ void* m_vertexShader;
+ SIZE_T m_vertexShaderSize;
+ void* m_pixelShader;
+ SIZE_T m_pixelShaderSize;
+
+ D3D12_INPUT_ELEMENT_DESC* m_inputElementDescs;
+ UINT m_inputElementDescsNum;
+
+ ID3D12RootSignature* m_pRootSignature;
+
+ ID3D12DescriptorHeap* m_scuHeap;
+ int m_scuDescriptorSize;
+
+ ID3D12Resource* m_ConstantBuffer[2];
+
+ ID3D12DescriptorHeap* m_samplerHeap;
+ int m_samplerDescriptorSize;
+
+ map<RenderShaderState*, ID3D12PipelineState*> m_PipelineStates;
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.cpp
new file mode 100644
index 0000000..301cad6
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.cpp
@@ -0,0 +1,371 @@
+#include "D3D12RenderTarget.h"
+#include "D3D12RenderContext.h"
+
+D3D12RenderTarget::D3D12RenderTarget(int renderTargetIndex, int nRenderTargetCount)
+{
+ m_RenderTargetIndex = renderTargetIndex;
+
+ m_RenderTargetCount = nRenderTargetCount;
+
+ m_BackBuffers = nullptr;
+ m_RenderTargets = nullptr;
+ m_DepthStencil = nullptr;
+
+ m_pRenderContext = D3D12RenderContext::Instance();
+
+ if (m_RenderTargetCount > 0)
+ {
+ m_BackBuffers = new ID3D12Resource*[m_RenderTargetCount];
+
+ for (int n = 0; n < m_RenderTargetCount; n++)
+ {
+ m_BackBuffers[n] = nullptr;
+ }
+
+ m_RenderTargets = new ID3D12Resource*[m_RenderTargetCount];
+
+ for (int n = 0; n < m_RenderTargetCount; n++)
+ {
+ m_RenderTargets[n] = nullptr;
+ }
+ }
+
+ if (renderTargetIndex == 0)
+ {
+ m_rtvClearValue.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ m_rtvClearValue.Color[0] = 0.0;
+ m_rtvClearValue.Color[1] = 0.0;
+ m_rtvClearValue.Color[2] = 0.0;
+ m_rtvClearValue.Color[3] = 1.0;
+ }
+ else
+ {
+ m_rtvClearValue.Format = DXGI_FORMAT_R32_FLOAT;
+ m_rtvClearValue.Color[0] = FLT_MAX;
+ m_rtvClearValue.Color[1] = FLT_MAX;
+ m_rtvClearValue.Color[2] = FLT_MAX;
+ m_rtvClearValue.Color[3] = FLT_MAX;
+ }
+
+ if (renderTargetIndex == 0)
+ {
+ m_dsvClearValue.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
+ }
+ else
+ {
+ m_dsvClearValue.Format = DXGI_FORMAT_D32_FLOAT;
+ }
+ m_dsvClearValue.DepthStencil.Depth = 1.0f;
+ m_dsvClearValue.DepthStencil.Stencil = 0;
+}
+
+D3D12RenderTarget::~D3D12RenderTarget()
+{
+ if (nullptr != m_BackBuffers)
+ {
+ delete[] m_BackBuffers;
+ m_BackBuffers = nullptr;
+ }
+
+ if (nullptr != m_RenderTargets)
+ {
+ delete[] m_RenderTargets;
+ m_RenderTargets = nullptr;
+ }
+}
+
+ID3D12Resource* D3D12RenderTarget::GetDepthStencilResource()
+{
+ return m_DepthStencil;
+}
+
+D3D12_CPU_DESCRIPTOR_HANDLE D3D12RenderTarget::GetRenderTargetViewHandle()
+{
+ CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());
+ return rtvHandle;
+}
+
+D3D12_CPU_DESCRIPTOR_HANDLE D3D12RenderTarget::GetDepthStencilViewHandle()
+{
+ CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
+ return dsvHandle;
+}
+
+void D3D12RenderTarget::CreateResource(int nWidth, int nHeight)
+{
+ ID3D12Device* m_device = m_pRenderContext->GetDevice();
+ int nSampleCount = m_pRenderContext->GetSampleCount();
+
+ CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());
+
+ if (m_RenderTargetIndex == 0)
+ {
+ IDXGISwapChain3* m_swapChain = m_pRenderContext->GetSwapChain();
+
+ // Create a RTV for each frame.
+ for (int n = 0; n < m_RenderTargetCount; n++)
+ {
+ ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(&m_BackBuffers[n])));
+
+ if (nSampleCount > 1)
+ {
+ // If we are multi-sampling - create a render target separate from the back buffer
+ CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_DEFAULT);
+ D3D12_RESOURCE_DESC desc = m_BackBuffers[n]->GetDesc();
+
+ desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+ desc.SampleDesc.Count = nSampleCount;
+ desc.SampleDesc.Quality = 0;
+ desc.Alignment = 0;
+
+ ThrowIfFailed(m_device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_RENDER_TARGET,
+ &m_rtvClearValue, IID_PPV_ARGS(&m_RenderTargets[n])));
+ }
+ else
+ {
+ // The render targets and back buffers are the same thing
+ m_RenderTargets[n] = m_BackBuffers[n];
+ }
+
+ m_device->CreateRenderTargetView(m_RenderTargets[n], nullptr, rtvHandle);
+ rtvHandle.Offset(1, m_rtvDescriptorSize);
+ }
+
+ {
+ auto resourceDesc = CD3DX12_RESOURCE_DESC::Tex2D(m_dsvClearValue.Format,
+ nWidth, nHeight, 1, 1, nSampleCount, 0,
+ D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);
+
+ ThrowIfFailed(m_device->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), // No need to read/write by CPU
+ D3D12_HEAP_FLAG_NONE,
+ &resourceDesc,
+ D3D12_RESOURCE_STATE_DEPTH_WRITE,
+ &m_dsvClearValue,
+ IID_PPV_ARGS(&m_DepthStencil)));
+
+ D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
+ dsvDesc.ViewDimension = nSampleCount <= 1 ? D3D12_DSV_DIMENSION_TEXTURE2D : D3D12_DSV_DIMENSION_TEXTURE2DMS;
+ dsvDesc.Format = m_dsvClearValue.Format;
+ dsvDesc.Texture2D.MipSlice = 0;
+ dsvDesc.Flags = D3D12_DSV_FLAG_NONE;
+ m_device->CreateDepthStencilView(m_DepthStencil, &dsvDesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
+ }
+ }
+ else
+ {
+ {
+ auto resourceDesc = CD3DX12_RESOURCE_DESC::Tex2D(m_rtvClearValue.Format,
+ nWidth, nHeight, 1, 1, 1, 0,
+ D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET);
+
+ D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {};
+ rtvDesc.Format = m_rtvClearValue.Format;
+ rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = 0;
+ rtvDesc.Texture2D.PlaneSlice = 0;
+
+ for (int n = 0; n < m_RenderTargetCount; n++)
+ {
+ m_device->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
+ D3D12_HEAP_FLAG_NONE,
+ &resourceDesc,
+ D3D12_RESOURCE_STATE_RENDER_TARGET,
+ &m_rtvClearValue,
+ IID_PPV_ARGS(&m_RenderTargets[n]));
+ m_device->CreateRenderTargetView(m_RenderTargets[n], &rtvDesc, rtvHandle);
+ rtvHandle.Offset(1, m_rtvDescriptorSize);
+ }
+ }
+
+ {
+ auto resourceDesc = CD3DX12_RESOURCE_DESC::Tex2D(m_dsvClearValue.Format,
+ nWidth, nHeight, 1, 1, 1, 0,
+ D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);
+
+ m_device->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
+ D3D12_HEAP_FLAG_NONE,
+ &resourceDesc,
+ D3D12_RESOURCE_STATE_DEPTH_WRITE,
+ &m_dsvClearValue,
+ IID_PPV_ARGS(&m_DepthStencil));
+
+ D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
+ dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
+ dsvDesc.Format = m_dsvClearValue.Format;
+ dsvDesc.Texture2D.MipSlice = 0;
+ dsvDesc.Flags = D3D12_DSV_FLAG_NONE;
+ m_device->CreateDepthStencilView(m_DepthStencil, &dsvDesc, m_dsvHeap.Get()->GetCPUDescriptorHandleForHeapStart());
+ }
+ }
+}
+
+void D3D12RenderTarget::OnCreate(int nWidth, int nHeight)
+{
+ ID3D12Device* m_device = m_pRenderContext->GetDevice();
+
+ // Create descriptor heaps.
+ {
+ // Describe and create a render target view (RTV) descriptor heap.
+ D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
+ rtvHeapDesc.NumDescriptors = m_RenderTargetCount;
+ rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
+ rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
+ ThrowIfFailed(m_device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap)));
+
+ m_rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
+
+ // Describe and create a render target view (RTV) descriptor heap.
+ D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
+ dsvHeapDesc.NumDescriptors = 1;
+ dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
+ dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
+ ThrowIfFailed(m_device->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_dsvHeap)));
+
+ m_dsvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
+ }
+
+ OnResize(nWidth, nHeight);
+}
+
+void D3D12RenderTarget::OnResize(int nWidth, int nHeight)
+{
+ CreateResource(nWidth, nHeight);
+
+ // viewport and scissor rect
+ {
+ memset(&m_viewport, 0, sizeof(m_viewport));
+ m_viewport.Width = nWidth;
+ m_viewport.Height = nHeight;
+ m_viewport.MaxDepth = 1.0;
+
+ memset(&m_scissorRect, 0, sizeof(m_scissorRect));
+ m_scissorRect.right = nWidth;
+ m_scissorRect.bottom = nHeight;
+ }
+}
+
+void D3D12RenderTarget::OnDestroy()
+{
+ for (int n = 0; n < m_RenderTargetCount; n++)
+ {
+ Safe_Release(m_RenderTargets[n]);
+
+ if (m_pRenderContext->GetSampleCount() > 1)
+ {
+ Safe_Release(m_BackBuffers[n]);
+ }
+ }
+ Safe_Release(m_DepthStencil);
+}
+
+void D3D12RenderTarget::PreRender(bool doClear)
+{
+ ID3D12GraphicsCommandList* m_commandList = m_pRenderContext->GetGraphicsCommandList();
+ m_commandList->RSSetViewports(1, &m_viewport);
+ m_commandList->RSSetScissorRects(1, &m_scissorRect);
+
+ int numSamples = 1;
+ UINT m_frameIndex = 0;
+ D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
+ if (m_RenderTargetIndex == 0)
+ {
+ numSamples = m_pRenderContext->GetSampleCount();
+ m_frameIndex = m_pRenderContext->GetFrameIndex();
+ if (numSamples <= 1)
+ {
+ state = D3D12_RESOURCE_STATE_PRESENT;
+ }
+ else
+ {
+ state = D3D12_RESOURCE_STATE_RESOLVE_SOURCE;
+ }
+ }
+
+ ID3D12Resource* pRenderTarget = m_RenderTargets[m_frameIndex];
+
+ m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(pRenderTarget, state, D3D12_RESOURCE_STATE_RENDER_TARGET));
+
+ CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart(), m_frameIndex, m_rtvDescriptorSize);
+ CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
+ m_commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
+
+ if (doClear)
+ {
+ m_commandList->ClearRenderTargetView(rtvHandle, m_rtvClearValue.Color, 0, nullptr);
+ m_commandList->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH,
+ m_dsvClearValue.DepthStencil.Depth, m_dsvClearValue.DepthStencil.Stencil, 0, nullptr);
+ }
+}
+
+void D3D12RenderTarget::PostRender()
+{
+ ID3D12GraphicsCommandList* m_commandList = m_pRenderContext->GetGraphicsCommandList();
+
+ int numSamples = 1;
+ UINT m_frameIndex = 0;
+ D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
+ if (m_RenderTargetIndex == 0)
+ {
+ numSamples = m_pRenderContext->GetSampleCount();
+ m_frameIndex = m_pRenderContext->GetFrameIndex();
+ state = D3D12_RESOURCE_STATE_PRESENT;
+ }
+
+ if (numSamples <= 1)
+ {
+ ID3D12Resource* renderTarget = m_RenderTargets[m_frameIndex];
+ CD3DX12_RESOURCE_BARRIER barrier(CD3DX12_RESOURCE_BARRIER::Transition(renderTarget, D3D12_RESOURCE_STATE_RENDER_TARGET, state));
+ m_commandList->ResourceBarrier(1, &barrier);
+ }
+ else
+ {
+ ID3D12Resource* backBuffer = m_BackBuffers[m_frameIndex];
+ ID3D12Resource* renderTarget = m_RenderTargets[m_frameIndex];
+
+ // Barriers to wait for the render target, and the backbuffer to be in correct state
+ {
+ D3D12_RESOURCE_BARRIER barriers[] =
+ {
+ CD3DX12_RESOURCE_BARRIER::Transition(renderTarget, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE),
+ CD3DX12_RESOURCE_BARRIER::Transition(backBuffer, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RESOLVE_DEST),
+ };
+ m_commandList->ResourceBarrier(2, barriers);
+ }
+ // Do the resolve...
+ m_commandList->ResolveSubresource(backBuffer, 0, renderTarget, 0, m_rtvClearValue.Format);
+ // Barrier until can present
+ {
+ CD3DX12_RESOURCE_BARRIER barrier(CD3DX12_RESOURCE_BARRIER::Transition(backBuffer, D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_PRESENT));
+ m_commandList->ResourceBarrier(1, &barrier);
+ }
+ }
+}
+
+void D3D12RenderTarget::SetClearColor(float r, float g, float b, float a, float depth, float stencil)
+{
+ m_rtvClearValue.Color[0] = r;
+ m_rtvClearValue.Color[1] = g;
+ m_rtvClearValue.Color[2] = b;
+ m_rtvClearValue.Color[3] = a;
+
+ m_dsvClearValue.DepthStencil.Depth = depth;
+ m_dsvClearValue.DepthStencil.Stencil = stencil;
+}
+
+ID3D12Resource* D3D12RenderTarget::GetTexture(int nIndex, bool bRenderTarget)
+{
+ if (nIndex < 0 || nIndex > m_RenderTargetCount)
+ return nullptr;
+
+ if (bRenderTarget)
+ {
+ return m_RenderTargets[nIndex];
+ }
+ else
+ {
+ return m_BackBuffers[nIndex];
+ }
+}
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.h b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.h
new file mode 100644
index 0000000..8ae0b7d
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.h
@@ -0,0 +1,110 @@
+#pragma once
+
+class D3D12RenderContext;
+
+#include "RenderInterface.h"
+using namespace RenderInterface;
+
+#include <d3d12.h>
+#include <d3d11on12.h>
+#include <dxgi1_4.h>
+#include <D3Dcompiler.h>
+#include <DirectXMath.h>
+#include "d3dx12.h"
+#include <string>
+#include <vector>
+#include <map>
+#include <wrl.h>
+#include <shellapi.h>
+using namespace std;
+using namespace DirectX;
+using namespace Microsoft::WRL;
+
+#ifndef Safe_Delete
+#define Safe_Delete(p) { if (p) { delete (p); (p) = nullptr; } }
+#endif // !Safe_Delete
+#ifndef Safe_Release
+#define Safe_Release(p) { if (p) { p->Release(); (p) = nullptr; } }
+#endif // !Safe_Delete
+
+inline void ThrowIfFailed(HRESULT hr)
+{
+ if (FAILED(hr))
+ {
+ throw;
+ }
+}
+
+typedef struct RenderShaderStateKey
+{
+ BLEND_STATE BlendState = BLEND_STATE_NONE;
+ RASTERIZER_STATE RasterizerState = RASTERIZER_STATE_FILL_CULL_NONE;
+ DEPTH_STENCIL_STATE DepthStencilState = DEPTH_STENCIL_DEPTH_TEST;
+ D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
+ int ForShadow = 0;
+
+ bool operator <(const RenderShaderStateKey &other) const
+ {
+ int key = (((BlendState * 10 + RasterizerState) * 10 + DepthStencilState) * 10 + PrimitiveTopologyType) * 10 + ForShadow;
+ int otherkey = (((other.BlendState * 10 + other.RasterizerState) * 10 + other.DepthStencilState) * 10 + other.PrimitiveTopologyType) * 10 + other.ForShadow;
+ return key < otherkey;
+ }
+} RenderShaderStateKey;
+
+typedef struct RenderShaderState
+{
+ D3D12_BLEND_DESC BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
+ D3D12_RASTERIZER_DESC RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
+ D3D12_DEPTH_STENCIL_DESC DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
+ D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
+ DXGI_FORMAT RTVFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
+ DXGI_FORMAT DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
+ int SampleCount = 1;
+} RenderShaderState;
+
+class D3D12RenderTarget
+{
+public:
+ D3D12RenderTarget(int renderTargetIndex, int nRenderTargetCount = 1);
+ ~D3D12RenderTarget();
+
+ void OnCreate(int nWidth, int nHeight);
+ void OnResize(int nWidth, int nHeight);
+ void OnDestroy();
+
+ void PreRender(bool doClear = false);
+ void PostRender();
+
+ void SetClearColor(float r, float g, float b, float a = 1.0, float depth = 1.0, float stencil = 0.0);
+
+ ID3D12Resource* GetTexture(int nIndex = 0, bool bRenderTarget = true);
+
+ D3D12_VIEWPORT m_viewport;
+
+ ID3D12Resource* GetDepthStencilResource();
+ D3D12_CPU_DESCRIPTOR_HANDLE GetRenderTargetViewHandle();
+ D3D12_CPU_DESCRIPTOR_HANDLE GetDepthStencilViewHandle();
+
+private:
+ void CreateResource(int nWidth, int nHeight);
+
+ int m_RenderTargetIndex;
+ int m_RenderTargetCount;
+
+ ID3D12Resource** m_BackBuffers;
+ ID3D12Resource** m_RenderTargets;
+ ID3D12Resource* m_DepthStencil;
+
+ ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
+ UINT m_rtvDescriptorSize;
+ ComPtr<ID3D12DescriptorHeap> m_dsvHeap;
+ UINT m_dsvDescriptorSize;
+
+ D3D12_RECT m_scissorRect;
+
+ D3D12RenderContext* m_pRenderContext;
+
+ D3D12_CLEAR_VALUE m_rtvClearValue;
+ D3D12_CLEAR_VALUE m_dsvClearValue;
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.cpp
new file mode 100644
index 0000000..b640ebd
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.cpp
@@ -0,0 +1,141 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D12RendererWindow.h"
+
+#include "DXUT.h"
+#include "DXUTgui.h"
+#include "sdkmisc.h"
+
+#include "D3D12RenderInterface.h"
+#include "D3D12RenderContext.h"
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; }
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+D3D12RenderWindow::D3D12RenderWindow()
+{
+ m_pRenderContext = D3D12RenderContext::Instance();
+
+ m_pDialogResourceManager = 0;
+ m_pTextHelper = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+D3D12RenderWindow::~D3D12RenderWindow()
+{
+ Free();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool D3D12RenderWindow::Create( HWND hWnd, unsigned int nSamples )
+{
+ m_pRenderContext->SetSampleCount(nSamples);
+
+ RECT rc;
+ GetClientRect((HWND)hWnd, &rc);
+ int wBuf = rc.right - rc.left;
+ int hBuf = rc.bottom- rc.top;
+
+ ID3D11Device *pDevice = m_pRenderContext->GetDevice11();
+ ID3D11DeviceContext* pDeviceContext = m_pRenderContext->GetDeviceContext();
+ if (nullptr != pDevice && nullptr != pDeviceContext)
+ {
+ m_pDialogResourceManager = new CDXUTDialogResourceManager;
+ m_pDialogResourceManager->OnD3D11CreateDevice(pDevice, pDeviceContext);
+ m_pTextHelper = new CDXUTTextHelper(pDevice, pDeviceContext, m_pDialogResourceManager, 15);
+ }
+
+ m_pRenderContext->InitSwapchain(wBuf, hBuf, hWnd);
+ Resize(wBuf, hBuf);
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D12RenderWindow::Free()
+{
+ FreeBuffer();
+
+ SAFE_DELETE(m_pTextHelper);
+
+ if (m_pDialogResourceManager)
+ {
+ m_pDialogResourceManager->OnD3D11DestroyDevice();
+ SAFE_DELETE(m_pDialogResourceManager);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D12RenderWindow::FreeBuffer()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D12RenderWindow::Present()
+{
+// m_pRenderContext->ReleaseRenderTarget();
+
+// m_pRenderContext->PostRender();
+
+ m_pRenderContext->Present();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void D3D12RenderWindow::Clear(float r, float g, float b)
+{
+ m_pRenderContext->PreRender();
+
+ m_pRenderContext->SetClearColor(0, r, g, b);
+ m_pRenderContext->AcquireRenderTarget(true);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool D3D12RenderWindow::Resize( int w, int h )
+{
+ assert(w > 0 && h > 0);
+
+ m_pRenderContext->ResizeSwapchain(w, h);
+
+ if (m_pDialogResourceManager)
+ {
+ ID3D11Device *pDevice = m_pRenderContext->GetDevice11();
+ D3D12_RESOURCE_DESC descTex2D = m_pRenderContext->GetBackBufferDesc();
+
+ DXGI_SURFACE_DESC backbufferDesc;
+ backbufferDesc.Width = descTex2D.Width;
+ backbufferDesc.Height = descTex2D.Height;
+ backbufferDesc.Format = descTex2D.Format;
+ backbufferDesc.SampleDesc = descTex2D.SampleDesc;
+
+ m_pDialogResourceManager->OnD3D11ResizedSwapChain(pDevice, &backbufferDesc);
+ }
+
+ return true;
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.h b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.h
new file mode 100644
index 0000000..abd5d9b
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <d3d12.h>
+class D3D12RenderContext;
+// DXUT stuffs for text rendering
+class CDXUTDialogResourceManager;
+class CDXUTTextHelper;
+
+struct D3D12RenderWindow
+{
+public:
+ D3D12RenderWindow();
+ ~D3D12RenderWindow();
+
+ bool Create(HWND hWnd, unsigned int nSamples = 1);
+ bool Resize(int w, int h);
+ void Present();
+ void Clear(float r, float g, float b);
+
+ CDXUTDialogResourceManager* m_pDialogResourceManager;
+ CDXUTTextHelper* m_pTextHelper;
+
+private:
+ void Free();
+ void FreeBuffer();
+
+ D3D12RenderContext* m_pRenderContext;
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.cpp
new file mode 100644
index 0000000..0c07409
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.cpp
@@ -0,0 +1,231 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D12Shaders.h"
+
+#include "MeshShaderParam.h"
+#include "LightShaderParam.h"
+
+//#include <Nv/Blast/NvHairSdk.h>
+#include "D3D12RenderShader.h"
+#include "D3D12RenderContext.h"
+#include "D3D12TextureResource.h"
+using namespace RenderInterface;
+
+D3D12_INPUT_ELEMENT_DESC layoutBodyRender[] =
+{
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ { "VERTEX_NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ { "FACE_NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 36, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 48, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ { "VERTEX_ID", 0, DXGI_FORMAT_R32_FLOAT, 0, 56, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+};
+
+D3D12_INPUT_ELEMENT_DESC layout_Position_And_Color[] =
+{
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+};
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Common shader settings
+//static D3D12RenderShader* g_pShaders[SHADER_TYPE_END];
+static std::map<int, D3D12RenderShader*> g_pShaders;
+/*
+namespace BodyShaderBlobs
+{
+ #include "Shaders/BodyShader_VS.h"
+ #include "Shaders/BodyShader_PS.h"
+}
+
+namespace BodyShadowBlobs
+{
+ #include "Shaders/BodyShadow_VS.h"
+ #include "Shaders/BodyShadow_PS.h"
+}
+
+namespace ScreenQuadBlobs
+{
+ #include "Shaders/ScreenQuad_VS.h"
+ #include "Shaders/ScreenQuad_PS.h"
+}
+
+namespace ScreenQuadColorBlobs
+{
+ #include "Shaders/ScreenQuadColor_VS.h"
+ #include "Shaders/ScreenQuadColor_PS.h"
+}
+
+namespace VisualizeShadowBlobs
+{
+ #include "Shaders/VisualizeShadow_VS.h"
+ #include "Shaders/VisualizeShadow_PS.h"
+}
+
+namespace ColorBlobs
+{
+ #include "Shaders/Color_VS.h"
+ #include "Shaders/Color_PS.h"
+}
+*/
+//////////////////////////////////////////////////////////////////////////
+bool InitializeShadersD3D12()
+{
+ /*
+ UINT numElements = sizeof(layoutBodyRender) / sizeof(D3D11_INPUT_ELEMENT_DESC);
+
+ g_pShaders[SHADER_TYPE_MESH_RENDERING] = D3D12RenderShader::Create("MeshRenderShader",
+ (void*)BodyShaderBlobs::g_vs_main, sizeof(BodyShaderBlobs::g_vs_main),
+ (void*)BodyShaderBlobs::g_ps_main, sizeof(BodyShaderBlobs::g_ps_main),
+ sizeof(MeshShaderParam), 0,
+ &layoutBodyRender[0], numElements,
+ 10, 0, 2);
+
+ g_pShaders[SHADER_TYPE_MESH_SHADOW] = D3D12RenderShader::Create("MeshShadowShader",
+ (void*)BodyShadowBlobs::g_vs_main, sizeof(BodyShadowBlobs::g_vs_main),
+ (void*)BodyShadowBlobs::g_ps_main, sizeof(BodyShadowBlobs::g_ps_main),
+ sizeof(MeshShadowShaderParam), 0,
+ &layoutBodyRender[0], numElements,
+ 2);
+
+ g_pShaders[SHADER_TYPE_SCREEN_QUAD] = D3D12RenderShader::Create("ScreenQuadShader",
+ (void*)ScreenQuadBlobs::g_vs_main, sizeof(ScreenQuadBlobs::g_vs_main),
+ (void*)ScreenQuadBlobs::g_ps_main, sizeof(ScreenQuadBlobs::g_ps_main),
+ 0, 0,
+ 0, 0,
+ 1, 0, 1);
+
+ g_pShaders[SHADER_TYPE_SCREEN_QUAD_COLOR] = D3D12RenderShader::Create("ScreenQuadColorShader",
+ (void*)ScreenQuadColorBlobs::g_vs_main, sizeof(ScreenQuadColorBlobs::g_vs_main),
+ (void*)ScreenQuadColorBlobs::g_ps_main, sizeof(ScreenQuadColorBlobs::g_ps_main));
+
+ g_pShaders[SHADER_TYPE_VISUALIZE_SHADOW] = D3D12RenderShader::Create("VisualizeShadowShader",
+ (void*)VisualizeShadowBlobs::g_vs_main, sizeof(VisualizeShadowBlobs::g_vs_main),
+ (void*)VisualizeShadowBlobs::g_ps_main, sizeof(VisualizeShadowBlobs::g_ps_main),
+ sizeof(ShadowVizParam), 0,
+ 0, 0,
+ 1, 0, 1);
+
+ UINT numElements2 = sizeof(layout_Position_And_Color) / sizeof(D3D11_INPUT_ELEMENT_DESC);
+
+ g_pShaders[SHADER_TYPE_SIMPLE_COLOR] = D3D12RenderShader::Create("Color",
+ (void*)ColorBlobs::g_vs_main, sizeof(ColorBlobs::g_vs_main),
+ (void*)ColorBlobs::g_ps_main, sizeof(ColorBlobs::g_ps_main),
+ sizeof(SimpleShaderParam), 0,
+ &layout_Position_And_Color[0], numElements2);
+
+ g_pShaders[SHADER_TYPE_HAIR_SHADER_DEFAULT] = D3D12RenderShader::Create(
+ "hairShaderDefault", 0, 0,
+ (void*)BlastShaderBlobs::g_ps_main, sizeof(BlastShaderBlobs::g_ps_main),
+ sizeof(NvHair::ShaderConstantBuffer),
+ sizeof(LightShaderParam)
+ );
+
+ g_pShaders[SHADER_TYPE_HAIR_SHADER_SHADOW] = D3D12RenderShader::Create(
+ "hairShadow", 0, 0,
+ (void*)BlastShadowBlobs::g_ps_main, sizeof(BlastShadowBlobs::g_ps_main),
+ sizeof(NvHair::ShaderConstantBuffer),
+ 0);
+ */
+ return true;
+}
+
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; }
+#endif
+
+#ifndef SAFE_DELETE
+#define SAFE_DELETE(x) { if (x) delete x; x = 0; }
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+void DestroyShadersD3D12()
+{
+ for (int i = 0; i < g_pShaders.size(); i++)
+ {
+ D3D12RenderShader*& pShader = g_pShaders[i];
+ if (pShader)
+ {
+ delete pShader;
+ pShader = 0;
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+D3D12RenderShader* GetShaderD3D12(SHADER_TYPE st)
+{
+ return g_pShaders[st];
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void ApplyShaderD3D12(SHADER_TYPE st)
+{
+ D3D12RenderShader* pD3D12Shader = GetShaderD3D12(st);
+ if (!pD3D12Shader)
+ return;
+
+ pD3D12Shader->MakeCurrent();
+}
+
+void BindShaderResourcesD3D12(SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs)
+{
+ D3D12RenderShader* pD3D12Shader = GetShaderD3D12(st);
+ if (!pD3D12Shader)
+ return;
+
+ for (int i = 0; i < numSRVs; i++)
+ {
+ CD3DX12_CPU_DESCRIPTOR_HANDLE handle = D3D12TextureResource::GetHandle(ppSRVs[i]);
+ pD3D12Shader->BindShaderResource(i, handle);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void DisableShaderD3D12(RenderInterface::SHADER_TYPE st)
+{
+ D3D12RenderShader* pD3D12Shader = GetShaderD3D12(st);
+ if (!pD3D12Shader)
+ return;
+
+ pD3D12Shader->Disable();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void CopyShaderParamD3D12(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot)
+{
+ D3D12RenderShader* pD3D12Shader = GetShaderD3D12(st);
+ if (!pD3D12Shader)
+ return;
+
+ void* mappedParam = pD3D12Shader->MapParam(slot);
+
+ memcpy(mappedParam, pSysMem, bytes);
+
+ pD3D12Shader->UnmapParam(slot);
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.h b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.h
new file mode 100644
index 0000000..29b0e1b
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.h
@@ -0,0 +1,42 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "RenderInterface.h"
+#include "RenderPlugin.h"
+///////////////////////////////////////////////////////////////////
+// default shaders
+///////////////////////////////////////////////////////////////////
+CORERENDER_EXPORT bool InitializeShadersD3D12();
+CORERENDER_EXPORT void DestroyShadersD3D12();
+
+CORERENDER_EXPORT void ApplyShaderD3D12(RenderInterface::SHADER_TYPE st);
+CORERENDER_EXPORT void DisableShaderD3D12(RenderInterface::SHADER_TYPE st);
+CORERENDER_EXPORT void BindShaderResourcesD3D12(RenderInterface::SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs);
+CORERENDER_EXPORT void CopyShaderParamD3D12(RenderInterface::SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot = 0);
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.cpp
new file mode 100644
index 0000000..342c6f3
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.cpp
@@ -0,0 +1,99 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D12ShadowMap.h"
+
+#include "RenderResources.h"
+
+#include "D3D12RenderInterface.h"
+#include "D3D12TextureResource.h"
+#include "D3D12RenderContext.h"
+
+//////////////////////////////////////////////////////////////////////////////
+D3D12ShadowMap::D3D12ShadowMap(int resolution)
+{
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ m_nIndex = pContext->AllocRenderTargetIndex();
+ m_pRenderTarget = pContext->CreateRenderTarget(m_nIndex, resolution, resolution);
+ ID3D12Resource* pTexture = pContext->GetTexture(m_nIndex);
+ int nIndexInHeap = -1;
+ CD3DX12_CPU_DESCRIPTOR_HANDLE handle = pContext->NVHairINT_CreateD3D12Texture(pTexture, nIndexInHeap);
+ m_ShadowResource.m_pResource = pTexture;
+ m_ShadowResource.m_Handle = handle;
+ m_ShadowResource.m_nIndexInHeap = nIndexInHeap;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+D3D12ShadowMap::~D3D12ShadowMap()
+{
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ pContext->NVHairINT_DestroyD3D12Texture(m_ShadowResource.m_nIndexInHeap);
+
+ Release();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void D3D12ShadowMap::Release()
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+GPUShaderResource* D3D12ShadowMap::GetShadowSRV()
+{
+ return &m_ShadowResource;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool D3D12ShadowMap::isValid()
+{
+ return m_pRenderTarget != nullptr;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void D3D12ShadowMap::BeginRendering(float clearDepth)
+{
+ if (!isValid())
+ return;
+
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ pContext->ReleaseRenderTarget();
+
+ pContext->AcquireRenderTarget(true, m_nIndex);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void D3D12ShadowMap::EndRendering()
+{
+ if (!isValid())
+ return;
+
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ pContext->ReleaseRenderTarget(m_nIndex);
+
+ pContext->AcquireRenderTarget();
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.h b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.h
new file mode 100644
index 0000000..dabf9a1
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.h
@@ -0,0 +1,68 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "ShadowMap.h"
+
+#include <d3d11.h>
+#include <d3d12.h>
+#include "D3D12TextureResource.h"
+
+#include "DXUT.h" // DXUT header
+#include "d3dx12.h"
+
+#include "D3D12RenderTarget.h"
+
+using namespace Microsoft::WRL;
+
+class GPUShaderResource;
+class D3D12TextureResource;
+
+struct D3D12ShadowMap : public ShadowMap
+{
+ D3D12TextureResource m_ShadowResource;
+
+ D3D12RenderTarget* m_pRenderTarget;
+
+public:
+ D3D12ShadowMap(int resolution );
+ ~D3D12ShadowMap();
+
+ void Release();
+ void BeginRendering(float clearDepth);
+ void EndRendering();
+
+ GPUShaderResource* GetShadowSRV();
+
+protected:
+
+ bool isValid();
+ int m_nIndex;
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.cpp
new file mode 100644
index 0000000..0247895
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.cpp
@@ -0,0 +1,29 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D12TextureResource.h"
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.h b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.h
new file mode 100644
index 0000000..b6c7584
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.h
@@ -0,0 +1,89 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "RenderResources.h"
+
+#include "d3d12.h"
+#include "d3dx12.h"
+
+// GPU resources for texture
+struct D3D12TextureResource : public GPUShaderResource
+{
+ ID3D12Resource* m_pResource;
+ CD3DX12_CPU_DESCRIPTOR_HANDLE m_Handle;
+ int m_nIndexInHeap;
+
+public:
+ static GPUShaderResource* Create(
+ ID3D12Resource* pResource,
+ CD3DX12_CPU_DESCRIPTOR_HANDLE handle,
+ int nIndexInHeap) {
+ D3D12TextureResource* pBuffer = new D3D12TextureResource;
+ pBuffer->m_pResource = pResource;
+ pBuffer->m_Handle = handle;
+ pBuffer->m_nIndexInHeap = nIndexInHeap;
+ return pBuffer;
+ }
+
+ static ID3D12Resource* GetResource(GPUShaderResource* pBuffer)
+ {
+ D3D12TextureResource* pD3D12Buffer = dynamic_cast<D3D12TextureResource*>(pBuffer);
+ if (!pD3D12Buffer)
+ return 0;
+ return pD3D12Buffer->m_pResource;
+ }
+
+ static CD3DX12_CPU_DESCRIPTOR_HANDLE GetHandle(GPUShaderResource* pBuffer)
+ {
+ CD3DX12_CPU_DESCRIPTOR_HANDLE handle = {};
+ D3D12TextureResource* pD3D12Buffer = dynamic_cast<D3D12TextureResource*>(pBuffer);
+ if (pD3D12Buffer)
+ handle = pD3D12Buffer->m_Handle;
+ else
+ handle.ptr = 0;
+ return handle;
+ }
+
+ D3D12TextureResource()
+ {
+ m_pResource = 0;
+ }
+
+ void Release()
+ {
+ SAFE_RELEASE(m_pResource);
+ }
+
+ ~D3D12TextureResource()
+ {
+ Release();
+ }
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.cpp
new file mode 100644
index 0000000..695bb41
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.cpp
@@ -0,0 +1,386 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include <DirectXTex.h>
+#include "D3D12Util.h"
+
+#include "D3D12Shaders.h"
+#include "D3D12RenderShader.h"
+
+#include "D3DX10tex.h"
+#include "D3DX11tex.h"
+
+#include "D3D12Wrapper.h"
+#include "DXUT.h"
+#include "DXUTgui.h"
+#include "sdkmisc.h"
+#include "D3D12RendererWindow.h"
+#include "SimpleRenderable.h"
+//#include "MeshShaderParam.h"
+#include "D3D12RenderInterface.h"
+#include "D3D12TextureResource.h"
+#include "D3D12RenderContext.h"
+namespace D3D12Util
+{
+ using namespace RenderInterface;
+
+ // D3D hook to render window
+ D3D12RenderWindow* g_pRenderWindow = 0;
+
+///////////////////////////////////////////////////////////////////////////////
+GPUShaderResource*
+ CreateTextureSRV(const char* texturename)
+{
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ if (!pContext)
+ return 0;
+ ID3D12Device* pDevice = pContext->GetDevice();
+ if (!pDevice)
+ return 0;
+ ID3D12GraphicsCommandList* pCommandList = pContext->GetGraphicsCommandList();
+ if (!pCommandList)
+ return 0;
+
+ unsigned char *pSTBIRes = 0;
+ int width = 0;
+ int height = 0;
+
+ size_t nu = strlen(texturename);
+ size_t n = (size_t)MultiByteToWideChar(CP_ACP, 0, (const char *)texturename, (int)nu, NULL, 0);
+ wchar_t* pwstr = new wchar_t[n];
+ MultiByteToWideChar(CP_ACP, 0, (const char *)texturename, (int)nu, pwstr, (int)n);
+ pwstr[n] = 0;
+
+ TexMetadata texMetadata;
+ ScratchImage scratchImage;
+ HRESULT loaded = LoadFromTGAFile(pwstr, &texMetadata, scratchImage);
+
+ if (loaded != S_OK)
+ {
+ loaded = LoadFromWICFile(pwstr, TEX_FILTER_DEFAULT | WIC_FLAGS_ALL_FRAMES, &texMetadata, scratchImage);
+ }
+
+ if (loaded != S_OK)
+ {
+ loaded = LoadFromDDSFile(pwstr, DDS_FLAGS_NONE, &texMetadata, scratchImage);
+ }
+
+ if (loaded == S_OK)
+ {
+ pSTBIRes = scratchImage.GetPixels();
+ width = texMetadata.width;
+ height = texMetadata.height;
+ }
+
+ if (!pSTBIRes)
+ return 0;
+
+ int numMipMaps = 0;
+ {
+ int mipWidth = width;
+ int mipHeight = height;
+ while (mipWidth > 1 || mipHeight > 1)
+ {
+ numMipMaps++;
+ mipWidth >>= 1;
+ mipHeight >>= 1;
+
+ if ((mipWidth * sizeof(uint32_t)) < D3D12_TEXTURE_DATA_PITCH_ALIGNMENT)
+ break;
+ }
+ }
+
+ std::vector<D3D12_PLACED_SUBRESOURCE_FOOTPRINT> layouts(numMipMaps);
+ std::vector<uint64_t> row_sizes_in_bytes(numMipMaps);
+ std::vector<uint32_t> num_rows(numMipMaps);
+
+ auto resourceDesc = CD3DX12_RESOURCE_DESC::Tex2D(
+ DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, (UINT16)numMipMaps, 1, 0, D3D12_RESOURCE_FLAG_NONE,
+ D3D12_TEXTURE_LAYOUT_UNKNOWN, 0);
+
+ uint64_t required_size = 0;
+ pDevice->GetCopyableFootprints(&resourceDesc, 0, numMipMaps, 0, &layouts[0], &num_rows[0], &row_sizes_in_bytes[0], &required_size);
+
+ HRESULT hr;
+ ID3D12Resource* mTextureUpload;
+ ID3D12Resource* mTexture;
+
+ hr = pDevice->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
+ D3D12_HEAP_FLAG_NONE,
+ &resourceDesc,
+ D3D12_RESOURCE_STATE_COPY_DEST,
+ nullptr,
+ IID_PPV_ARGS(&mTexture));
+ mTexture->SetName(L"Texture");
+ hr = pDevice->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
+ D3D12_HEAP_FLAG_NONE,
+ &CD3DX12_RESOURCE_DESC::Buffer(required_size),
+ D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr,
+ IID_PPV_ARGS(&mTextureUpload));
+ mTextureUpload->SetName(L"TextureUpload");
+
+ const int requestedMipLevels = numMipMaps;
+ D3D12_SUBRESOURCE_DATA* initData = new D3D12_SUBRESOURCE_DATA[requestedMipLevels];
+ ZeroMemory(initData, sizeof(D3D12_SUBRESOURCE_DATA)*requestedMipLevels);
+
+ struct Pixel
+ {
+ unsigned char rgba[4];
+ };
+
+ // prepare target buffer just large enough to include all the mip levels
+ Pixel* targets = new Pixel[width*height * 2];
+
+ // copy the first mip level
+ memcpy(targets, pSTBIRes, width*height * 4);
+
+ // current mip level width and height
+ int mipWidth = width;
+ int mipHeight = height;
+
+ // actual mip levels
+ int mipLevels = 0;
+
+ // current data
+ Pixel* source = targets;
+ Pixel* target = nullptr;
+
+ for (int idx = 0; idx < requestedMipLevels; ++idx)
+ {
+ // set initData
+ initData[idx].pData = source;
+ initData[idx].RowPitch = mipWidth * 4;
+ mipLevels++;
+
+ // skip generating mip for 1x1
+ if ((mipWidth == 1) && (mipHeight == 1))
+ break;
+
+ // skip generating mip for the last level
+ if (idx == (requestedMipLevels - 1))
+ break;
+
+ // buffer for the next mip level
+ target = &source[mipWidth*mipHeight];
+
+ const int prevWidth = mipWidth; // previous mip's width
+
+ // generate the next mip level
+ mipWidth = max(1, mipWidth >> 1);
+ mipHeight = max(1, mipHeight >> 1);
+
+ Pixel samples[4];
+
+ for (int y = 0; y < mipHeight; ++y)
+ {
+ for (int x = 0; x < mipWidth; ++x)
+ {
+ const int px = x * 2; // x in previous mip
+ const int py = y * 2; // y in previous mip
+
+ samples[0] = source[py*prevWidth + px]; // left top
+ samples[1] = source[py*prevWidth + px + 1]; // right top
+ samples[2] = source[(py + 1)*prevWidth + px]; // left bottom
+ samples[3] = source[(py + 1)*prevWidth + px + 1]; // right bottom
+
+ // for each component
+ for (int comp = 0; comp < 4; ++comp)
+ {
+ // do the linear box filter for lower mip level
+ target[y*mipWidth + x].rgba[comp] = (samples[0].rgba[comp] + samples[1].rgba[comp] + samples[2].rgba[comp] + samples[3].rgba[comp]) / 4;
+ }
+ }
+ }
+
+ // update source
+ source = target;
+ }
+
+ uint8_t* p;
+ mTextureUpload->Map(0, nullptr, reinterpret_cast<void**>(&p));
+ for (uint32_t i = 0; i < numMipMaps; ++i)
+ {
+ memcpy(p + layouts[i].Offset, initData[i].pData, layouts[i].Footprint.RowPitch * num_rows[i]);
+ }
+ mTextureUpload->Unmap(0, nullptr);
+
+ for (uint32_t i = 0; i < numMipMaps; ++i)
+ {
+ D3D12_TEXTURE_COPY_LOCATION src;
+ src.pResource = mTextureUpload;
+ src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
+ src.PlacedFootprint = layouts[i];
+
+ D3D12_TEXTURE_COPY_LOCATION dst;
+ dst.pResource = mTexture;
+ dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
+ dst.SubresourceIndex = i;
+ pCommandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr);
+ }
+ pCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(mTexture, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE));
+
+ delete initData;
+ delete targets;
+
+ int nIndexInHeap = -1;
+ CD3DX12_CPU_DESCRIPTOR_HANDLE handle = pContext->NVHairINT_CreateD3D12Texture(mTexture, nIndexInHeap);
+ return D3D12TextureResource::Create(mTexture, handle, nIndexInHeap);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+bool GetDeviceInfoString(wchar_t *str)
+{
+ ID3D11Device* pDevice = nullptr;// RenderInterfaceD3D12::GetDevice();
+ if (!pDevice)
+ return false;
+
+ {
+ IDXGIDevice1 *pDXGIDevice1 = NULL;
+ pDevice->QueryInterface(__uuidof(IDXGIDevice1), reinterpret_cast<void **>(&pDXGIDevice1));
+
+ IDXGIAdapter1 *pDXGIAdapter1 = NULL;
+ pDXGIDevice1->GetParent(__uuidof(IDXGIAdapter1), reinterpret_cast<void **>(&pDXGIAdapter1));
+
+ if (pDXGIAdapter1)
+ {
+ auto adapterDescription = DXGI_ADAPTER_DESC1();
+ pDXGIAdapter1->GetDesc1(&adapterDescription);
+
+ WCHAR* pDescStr = adapterDescription.Description;
+ float memInGB = float(adapterDescription.DedicatedVideoMemory) / 1e9f;
+ swprintf_s(str, 1000, L"%s(%.1fGb)\n", pDescStr, memInGB);
+ }
+ }
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Render window interafce
+/////////////////////////////////////////////////////////////////////////////////////////
+bool CreateRenderWindow(HWND hWnd, int nSamples)
+{
+ SAFE_DELETE(g_pRenderWindow);
+
+ g_pRenderWindow = new D3D12RenderWindow;
+ return g_pRenderWindow->Create(hWnd, nSamples);
+}
+
+D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles)
+{
+ /*
+ deviceHandles.pAdapter = RenderInterfaceD3D11::GetAdapter();
+ deviceHandles.pFactory = RenderInterfaceD3D11::GetDXGIFactory();
+ deviceHandles.pDevice = RenderInterfaceD3D11::GetDevice();
+ deviceHandles.pDeviceContext = RenderInterfaceD3D11::GetDeviceContext();
+
+ deviceHandles.pDXGISwapChain = g_pRenderWindow->m_pDXGISwapChain;
+ deviceHandles.pD3D11BackBuffer = g_pRenderWindow->m_pD3D11BackBuffer;
+ deviceHandles.pD3D11RenderTargetView = g_pRenderWindow->m_pD3D11RenderTargetView;
+ deviceHandles.pD3D11DepthBuffer = g_pRenderWindow->m_pD3D11DepthBuffer;
+ deviceHandles.pD3D11DepthStencilView = g_pRenderWindow->m_pD3D11DepthStencilView;
+ */
+ return deviceHandles;
+}
+
+void DestroyRenderWindow()
+{
+ SAFE_DELETE(g_pRenderWindow);
+}
+
+bool ResizeRenderWindow(int w, int h)
+{
+ if (!g_pRenderWindow)
+ return false;
+
+ return g_pRenderWindow->Resize(w,h);
+}
+
+void PresentRenderWindow()
+{
+ if (!g_pRenderWindow)
+ return;
+
+ g_pRenderWindow->Present();
+}
+
+void ClearRenderWindow(float r, float g, float b)
+{
+ if (!g_pRenderWindow)
+ return;
+
+ g_pRenderWindow->Clear(r,g,b);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Text draw helper functions (using DXUT)
+/////////////////////////////////////////////////////////////////////////////////////////
+void TxtHelperBegin()
+{
+ if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper)
+ return;
+
+ g_pRenderWindow->m_pTextHelper->Begin();
+}
+
+void TxtHelperEnd()
+{
+ if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper)
+ return;
+
+ g_pRenderWindow->m_pTextHelper->End();
+}
+
+void TxtHelperSetInsertionPos(int x, int y)
+{
+ if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper)
+ return;
+
+ g_pRenderWindow->m_pTextHelper->SetInsertionPos(x, y);
+}
+
+void TxtHelperSetForegroundColor(float r, float g, float b, float a)
+{
+ if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper)
+ return;
+
+ g_pRenderWindow->m_pTextHelper->SetForegroundColor(DirectX::XMFLOAT4(r,g,b,a));
+}
+
+void TxtHelperDrawTextLine(wchar_t* str)
+{
+ if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper)
+ return;
+
+ g_pRenderWindow->m_pTextHelper->DrawTextLine(str);
+}
+
+} // end namespace \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.h b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.h
new file mode 100644
index 0000000..f83b063
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.h
@@ -0,0 +1,68 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include <d3d12.h>
+
+#include "RenderPlugin.h"
+
+class GPUShaderResource;
+
+namespace D3D12Util
+{
+ ///////////////////////////////////////////////////////////////////
+ // render window management
+ ///////////////////////////////////////////////////////////////////
+ D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles);
+ bool CreateRenderWindow(HWND hWnd, int nSamples);
+ void DestroyRenderWindow();
+ bool ResizeRenderWindow(int w, int h);
+ void PresentRenderWindow();
+ void ClearRenderWindow(float r, float g, float b);
+
+ ///////////////////////////////////////////////////////////////////
+ // background textures
+ bool LoadBackgroundTexture(const char* filePath);
+ void RenderBackgroundTexture();
+ void ClearBackgroundTexture();
+ GPUShaderResource* CreateTextureSRV(const char* texturename);
+
+ ///////////////////////////////////////////////////////////////////
+ bool GetDeviceInfoString(wchar_t *str);
+
+ ///////////////////////////////////////////////////////////////////
+ // text helpers
+ void TxtHelperBegin();
+ void TxtHelperEnd();
+ void TxtHelperSetInsertionPos(int x, int y);
+ void TxtHelperSetForegroundColor(float r, float g, float b, float a = 1.0f);
+ void TxtHelperDrawTextLine(wchar_t* str);
+
+
+}
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.cpp
new file mode 100644
index 0000000..b534a36
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.cpp
@@ -0,0 +1,33 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "D3D12Wrapper.h"
+
+namespace D3DWrapper
+{
+
+} // end namespace \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.h b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.h
new file mode 100644
index 0000000..dc81e34
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <d3d11.h>
+
+namespace D3DWrapper
+{
+ inline void SetDebugName(ID3D11DeviceChild* pResource, const char *name)
+ {
+ if (pResource) pResource->SetPrivateData( WKPDID_D3DDebugObjectName, strlen(name), name);
+ }
+}
+
+#define SET_D3D_DEBUG_NAME(x, name) D3DWrapper::SetDebugName(x, name);
+#define SET_D3D_DEBUG_NAME_VAR(x) D3DWrapper::SetDebugName(x, #x);
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.cpp
new file mode 100644
index 0000000..9945d7c
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.cpp
@@ -0,0 +1,343 @@
+#include "RenderPluginDx12.h"
+
+#include "D3D12RenderInterface.h"
+#include "D3D12Util.h"
+#include "D3D12Shaders.h"
+#include "D3D12GPUProfiler.h"
+#include "D3D12ShadowMap.h"
+#include "D3D12RenderContext.h"
+
+RenderPlugin* CreateRenderPlugin(void)
+{
+ return new RenderPluginDx12;
+}
+
+RenderPluginDx12::RenderPluginDx12()
+{
+ m_RenderApi = "Dx12";
+}
+
+RenderPluginDx12::~RenderPluginDx12()
+{
+}
+
+// interface
+bool RenderPluginDx12::InitDevice(int deviceID)
+{
+ return RenderInterfaceD3D12::InitDevice(deviceID);
+}
+
+bool RenderPluginDx12::Initialize()
+{
+ return RenderInterfaceD3D12::Initialize();
+}
+
+void RenderPluginDx12::Shutdown()
+{
+ D3D12Util::DestroyRenderWindow();
+ RenderInterfaceD3D12::Shutdown();
+}
+
+void RenderPluginDx12::CopyToDevice(GPUBufferResource *pDevicePtr,
+ void* pSysMem, unsigned int ByteWidth)
+{
+ RenderInterfaceD3D12::CopyToDevice(pDevicePtr, pSysMem, ByteWidth);
+}
+
+void RenderPluginDx12::ApplyDepthStencilState(DEPTH_STENCIL_STATE state)
+{
+ RenderInterfaceD3D12::ApplyDepthStencilState(state);
+}
+
+void RenderPluginDx12::ApplyRasterizerState(RASTERIZER_STATE state)
+{
+ RenderInterfaceD3D12::ApplyRasterizerState(state);
+}
+
+void RenderPluginDx12::ApplySampler(int slot, SAMPLER_TYPE state)
+{
+}
+
+void RenderPluginDx12::ApplyBlendState(BLEND_STATE state)
+{
+ RenderInterfaceD3D12::ApplyBlendState(state);
+}
+
+void RenderPluginDx12::GetViewport(Viewport& vp)
+{
+ RenderInterfaceD3D12::GetViewport(vp);
+}
+
+void RenderPluginDx12::SetViewport(const Viewport& vp)
+{
+ RenderInterfaceD3D12::SetViewport(vp);
+}
+
+void RenderPluginDx12::BindVertexShaderResources(int startSlot,
+ int numSRVs, GPUShaderResource** ppSRVs)
+{
+}
+
+void RenderPluginDx12::BindPixelShaderResources(int startSlot,
+ int numSRVs, GPUShaderResource** ppSRVs)
+{
+}
+
+void RenderPluginDx12::ClearVertexShaderResources(int startSlot, int numSRVs)
+{
+}
+
+void RenderPluginDx12::ClearPixelShaderResources(int startSlot, int numSRVs)
+{
+}
+
+void RenderPluginDx12::ClearInputLayout()
+{
+}
+
+void RenderPluginDx12::SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset)
+{
+ RenderInterfaceD3D12::SetVertexBuffer(pBuffer, stride, offset);
+}
+
+void RenderPluginDx12::SetPrimitiveTopologyTriangleStrip()
+{
+ RenderInterfaceD3D12::SetPrimitiveTopologyTriangleStrip();
+}
+
+void RenderPluginDx12::SetPrimitiveTopologyTriangleList()
+{
+ RenderInterfaceD3D12::SetPrimitiveTopologyTriangleList();
+}
+
+void RenderPluginDx12::SetPrimitiveTopologyLineList()
+{
+ RenderInterfaceD3D12::SetPrimitiveTopologyLineList();
+}
+
+void RenderPluginDx12::Draw(unsigned int vertexCount, unsigned int startCount)
+{
+ RenderInterfaceD3D12::Draw(vertexCount, startCount);
+}
+
+GPUBufferResource* RenderPluginDx12::CreateVertexBuffer(unsigned int ByteWidth, void* pSysMem)
+{
+ return RenderInterfaceD3D12::CreateVertexBuffer(ByteWidth, pSysMem);
+}
+
+GPUShaderResource* RenderPluginDx12::CreateShaderResource(unsigned int stride,
+ unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer)
+{
+ return RenderInterfaceD3D12::CreateShaderResource(stride, numElements, pSysMem, pReadOnlyBuffer);
+}
+
+void RenderPluginDx12::ApplyForShadow(int ForShadow)
+{
+ RenderInterfaceD3D12::ApplyForShadow(ForShadow);
+}
+
+void RenderPluginDx12::SwitchToDX11()
+{
+ RenderInterfaceD3D12::SwitchToDX11();
+}
+
+void RenderPluginDx12::FlushDX11()
+{
+ RenderInterfaceD3D12::FlushDX11();
+}
+
+void RenderPluginDx12::FlushDX12()
+{
+ RenderInterfaceD3D12::FlushDX12();
+}
+
+void RenderPluginDx12::ApplyPrimitiveTopologyLine()
+{
+ RenderInterfaceD3D12::ApplyPrimitiveTopologyType(D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE);
+}
+
+void RenderPluginDx12::ApplyPrimitiveTopologyTriangle()
+{
+ RenderInterfaceD3D12::ApplyPrimitiveTopologyType(D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE);
+}
+
+void RenderPluginDx12::SubmitGpuWork()
+{
+ RenderInterfaceD3D12::SubmitGpuWork();
+}
+
+void RenderPluginDx12::WaitForGpu()
+{
+ RenderInterfaceD3D12::WaitForGpu();
+}
+
+// util
+bool RenderPluginDx12::CreateRenderWindow(HWND hWnd, int nSamples)
+{
+ return D3D12Util::CreateRenderWindow(hWnd, nSamples);
+}
+
+bool RenderPluginDx12::ResizeRenderWindow(int w, int h)
+{
+ return D3D12Util::ResizeRenderWindow(w, h);
+}
+
+void RenderPluginDx12::PresentRenderWindow()
+{
+ D3D12Util::PresentRenderWindow();
+}
+
+void RenderPluginDx12::ClearRenderWindow(float r, float g, float b)
+{
+ D3D12Util::ClearRenderWindow(r, g, b);
+}
+
+bool RenderPluginDx12::GetDeviceInfoString(wchar_t *str)
+{
+ return D3D12Util::GetDeviceInfoString(str);
+}
+
+GPUShaderResource* RenderPluginDx12::CreateTextureSRV(const char* texturename)
+{
+ return D3D12Util::CreateTextureSRV(texturename);
+}
+
+void RenderPluginDx12::TxtHelperBegin()
+{
+ D3D12Util::TxtHelperBegin();
+}
+
+void RenderPluginDx12::TxtHelperEnd()
+{
+ D3D12Util::TxtHelperEnd();
+}
+
+void RenderPluginDx12::TxtHelperSetInsertionPos(int x, int y)
+{
+ D3D12Util::TxtHelperSetInsertionPos(x, y);
+}
+
+void RenderPluginDx12::TxtHelperSetForegroundColor(float r, float g, float b, float a)
+{
+ D3D12Util::TxtHelperSetForegroundColor(r, g, b, a);
+}
+
+void RenderPluginDx12::TxtHelperDrawTextLine(wchar_t* str)
+{
+ D3D12Util::TxtHelperDrawTextLine(str);
+}
+
+// shader
+bool RenderPluginDx12::InitializeShaders()
+{
+ return InitializeShadersD3D12();
+}
+
+void RenderPluginDx12::DestroyShaders()
+{
+ DestroyShadersD3D12();
+}
+
+void RenderPluginDx12::ApplyShader(SHADER_TYPE st)
+{
+ ApplyShaderD3D12(st);
+}
+
+void RenderPluginDx12::DisableShader(SHADER_TYPE st)
+{
+ DisableShaderD3D12(st);
+}
+
+void RenderPluginDx12::BindShaderResources(SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs)
+{
+ BindShaderResourcesD3D12(st, numSRVs, ppSRVs);
+}
+
+void RenderPluginDx12::CopyShaderParam(SHADER_TYPE st,
+ void* pSysMem, unsigned int bytes, unsigned int slot)
+{
+ CopyShaderParamD3D12(st, pSysMem, bytes, slot);
+}
+
+// GPUProfiler
+GPUProfiler* RenderPluginDx12::CreateGPUProfiler()
+{
+ GPUProfiler* pProfiler = new D3D12GPUProfiler;
+ pProfiler->Initialize();
+ return pProfiler;
+}
+
+// ShadowMap
+ShadowMap* RenderPluginDx12::CreateShadowMap(int resolution)
+{
+ return new D3D12ShadowMap(resolution);
+}
+
+// D3D12RenderContext
+void RenderPluginDx12::PreRender()
+{
+ D3D12RenderContext::Instance()->PreRender();
+}
+
+void RenderPluginDx12::PostRender()
+{
+ D3D12RenderContext::Instance()->PostRender();
+}
+
+// GPUMeshResources
+#include "MeshData.h"
+#include "AnimUtil.h"
+
+class GPUMeshResourcesDx12 : public GPUMeshResources
+{
+public:
+ NVHairReadOnlyBuffer m_BoneIndicesBuffer;
+ NVHairReadOnlyBuffer m_BoneWeightsBuffer;
+};
+
+GPUMeshResources* RenderPluginDx12::GPUMeshResourcesCreate(MeshData* pMeshData, const SkinData& skinData)
+{
+ GPUMeshResources* resources = new GPUMeshResourcesDx12;
+
+ int numIndices = pMeshData->m_NumIndices;
+ int numVertices = pMeshData->m_NumVertices;
+
+ resources->m_pVertexBuffer = CreateVertexBuffer(
+ sizeof(MeshData::MeshVertex) * numIndices, pMeshData->m_pMeshVertices);
+
+ GPUMeshResourcesDx12* resourceDx12 = (GPUMeshResourcesDx12*)resources;
+ if (NULL != resourceDx12)
+ {
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ pContext->InitBuffer(resourceDx12->m_BoneIndicesBuffer);
+ pContext->InitBuffer(resourceDx12->m_BoneWeightsBuffer);
+ resources->m_pBoneIndicesSRV = CreateShaderResource(
+ sizeof(atcore_float4), numVertices, skinData.m_pBoneIndices, &resourceDx12->m_BoneIndicesBuffer);
+ resources->m_pBoneWeightsSRV = CreateShaderResource(
+ sizeof(atcore_float4), numVertices, skinData.m_pBoneWeights, &resourceDx12->m_BoneWeightsBuffer);
+ }
+
+ return resources;
+}
+
+void RenderPluginDx12::GPUMeshResourcesRelease(GPUMeshResources* pResource)
+{
+ SAFE_RELEASE(pResource->m_pVertexBuffer);
+ SAFE_RELEASE(pResource->m_pBoneIndicesSRV);
+ SAFE_RELEASE(pResource->m_pBoneWeightsSRV);
+
+ GPUMeshResourcesDx12* pResourceDx12 = (GPUMeshResourcesDx12*)pResource;
+ if (NULL == pResourceDx12)
+ {
+ return;
+ }
+
+ D3D12RenderContext* pContext = D3D12RenderContext::Instance();
+ pContext->DestroyBuffer(pResourceDx12->m_BoneIndicesBuffer);
+ pContext->DestroyBuffer(pResourceDx12->m_BoneWeightsBuffer);
+}
+
+D3DHandles& RenderPluginDx12::GetDeviceHandles(D3DHandles& deviceHandles)
+{
+ return D3D12Util::GetDeviceHandles(deviceHandles);
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.h b/tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.h
new file mode 100644
index 0000000..a88dfbf
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.h
@@ -0,0 +1,83 @@
+#pragma once
+
+#include "RenderPlugin.h"
+
+extern "C" CORERENDER_EXPORT RenderPlugin* CreateRenderPlugin(void);
+
+class CORERENDER_EXPORT RenderPluginDx12 : public RenderPlugin
+{
+public:
+ RenderPluginDx12();
+ ~RenderPluginDx12();
+
+ // interface
+ virtual bool InitDevice(int deviceID);
+ virtual bool Initialize();
+ virtual void Shutdown();
+ virtual void CopyToDevice(GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth);
+ virtual void ApplyDepthStencilState(DEPTH_STENCIL_STATE state);
+ virtual void ApplyRasterizerState(RASTERIZER_STATE state);
+ virtual void ApplySampler(int slot, SAMPLER_TYPE st);
+ virtual void ApplyBlendState(BLEND_STATE st);
+ virtual void GetViewport(Viewport& vp);
+ virtual void SetViewport(const Viewport& vp);
+ virtual void BindVertexShaderResources(int startSlot, int numSRVs, GPUShaderResource** ppSRVs);
+ virtual void BindPixelShaderResources(int startSlot, int numSRVs, GPUShaderResource** ppSRVs);
+ virtual void ClearVertexShaderResources(int startSlot, int numSRVs);
+ virtual void ClearPixelShaderResources(int startSlot, int numSRVs);
+ virtual void ClearInputLayout();
+ virtual void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset = 0);
+ virtual void SetPrimitiveTopologyTriangleStrip();
+ virtual void SetPrimitiveTopologyTriangleList();
+ virtual void SetPrimitiveTopologyLineList();
+ virtual void Draw(unsigned int vertexCount, unsigned int startCount = 0);
+ virtual GPUBufferResource* CreateVertexBuffer(unsigned int ByteWidth, void* pSysMem = 0);
+ virtual GPUShaderResource* CreateShaderResource(unsigned int stride, unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer = NULL);
+ virtual void ApplyForShadow(int ForShadow);
+ virtual void SwitchToDX11();
+ virtual void FlushDX11();
+ virtual void FlushDX12();
+ virtual void ApplyPrimitiveTopologyLine();
+ virtual void ApplyPrimitiveTopologyTriangle();
+ virtual void SubmitGpuWork();
+ virtual void WaitForGpu();
+
+ // util
+ virtual bool CreateRenderWindow(HWND hWnd, int nSamples);
+ virtual bool ResizeRenderWindow(int w, int h);
+ virtual void PresentRenderWindow();
+ virtual void ClearRenderWindow(float r, float g, float b);
+ virtual bool GetDeviceInfoString(wchar_t *str);
+ virtual GPUShaderResource* CreateTextureSRV(const char* texturename);
+ virtual void TxtHelperBegin();
+ virtual void TxtHelperEnd();
+ virtual void TxtHelperSetInsertionPos(int x, int y);
+ virtual void TxtHelperSetForegroundColor(float r, float g, float b, float a = 1.0f);
+ virtual void TxtHelperDrawTextLine(wchar_t* str);
+
+ // shader
+ virtual bool InitializeShaders();
+ virtual void DestroyShaders();
+ virtual void ApplyShader(SHADER_TYPE st);
+ virtual void DisableShader(SHADER_TYPE st);
+ virtual void BindShaderResources(SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs);
+ virtual void CopyShaderParam(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot = 0);
+
+ // GPUProfiler
+ virtual GPUProfiler* CreateGPUProfiler();
+
+ // ShadowMap
+ virtual ShadowMap* CreateShadowMap(int resolution);
+
+ // D3D12RenderContext
+ virtual void PreRender();
+ virtual void PostRender();
+
+ // GPUMeshResources
+ virtual GPUMeshResources* GPUMeshResourcesCreate(MeshData* pMeshData, const SkinData& skinData);
+ virtual void GPUMeshResourcesRelease(GPUMeshResources* pResource);
+
+ // Get devices related
+ virtual D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles);
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/GPUProfiler.cpp b/tools/ArtistTools/source/CoreLib/Render/GPUProfiler.cpp
new file mode 100644
index 0000000..08a3497
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/GPUProfiler.cpp
@@ -0,0 +1,87 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "GPUProfiler.h"
+
+#include "RenderPlugin.h"
+
+#ifndef SAFE_DELETE
+#define SAFE_DELETE(x) {if(x){delete x; x=nullptr;}}
+#endif
+
+GPUProfiler* g_pGPUProfiler = 0;
+
+void GPUProfiler_Initialize()
+{
+ g_pGPUProfiler = RenderPlugin::Instance()->CreateGPUProfiler();
+}
+
+void GPUProfiler_Shutdown()
+{
+ SAFE_DELETE(g_pGPUProfiler);
+}
+
+void GPUProfiler_Enable(bool b)
+{
+ if (g_pGPUProfiler)
+ g_pGPUProfiler->Enable(b);
+}
+
+void GPUProfiler_StartFrame()
+{
+ if (g_pGPUProfiler)
+ g_pGPUProfiler->StartFrame();
+}
+
+void GPUProfiler_EndFrame()
+{
+ if (g_pGPUProfiler)
+ g_pGPUProfiler->EndFrame();
+}
+
+void GPUProfiler_StartProfile(int id)
+{
+ if (g_pGPUProfiler)
+ g_pGPUProfiler->StartProfile(id);
+}
+
+void GPUProfiler_EndProfile(int id)
+{
+ if (g_pGPUProfiler)
+ g_pGPUProfiler->EndProfile(id);
+}
+
+float GPUProfiler_GetProfileData(int id)
+{
+ if (!g_pGPUProfiler)
+ return 0;
+
+ return g_pGPUProfiler->GetProfileData(id);
+}
+
+
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/GPUProfiler.h b/tools/ArtistTools/source/CoreLib/Render/GPUProfiler.h
new file mode 100644
index 0000000..65bb602
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/GPUProfiler.h
@@ -0,0 +1,61 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "corelib_global.h"
+
+struct CORELIB_EXPORT GPUProfiler
+{
+ bool m_enable;
+
+public:
+ // define base class virtual destructor to make sure child classes call destructor right.
+ virtual ~GPUProfiler() {}
+
+ void Enable(bool b) { m_enable = b; }
+
+ virtual void Initialize() = 0;
+ virtual void Release() = 0;
+ virtual void StartFrame() = 0;
+ virtual void EndFrame() = 0;
+ virtual void StartProfile(int id) = 0;
+ virtual void EndProfile(int id) = 0;
+ virtual float GetProfileData(int id) = 0;
+};
+
+// helper functions
+CORELIB_EXPORT void GPUProfiler_Initialize();
+CORELIB_EXPORT void GPUProfiler_Enable(bool);
+CORELIB_EXPORT void GPUProfiler_Shutdown();
+CORELIB_EXPORT void GPUProfiler_StartFrame();
+CORELIB_EXPORT void GPUProfiler_EndFrame();
+CORELIB_EXPORT void GPUProfiler_StartProfile(int id);
+CORELIB_EXPORT void GPUProfiler_EndProfile(int id);
+CORELIB_EXPORT float GPUProfiler_GetProfileData(int id);
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/GeometryData/BoneGeometryData.h b/tools/ArtistTools/source/CoreLib/Render/GeometryData/BoneGeometryData.h
new file mode 100644
index 0000000..4a6ea37
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/GeometryData/BoneGeometryData.h
@@ -0,0 +1,305 @@
+const int num_faces = 100;
+
+// pos.xyz, uv.uv, normal.xyz
+float vertices[100*3*8] = {
+0.250000, -0.951057, -0.181636, 0.000000, 0.900000, 0.277578, -0.881468, -0.382053,
+0.095491, -0.951057, -0.293893, 0.100000, 0.900000, 0.277578, -0.881468, -0.382053,
+0.181636, -0.809017, -0.559017, 0.100000, 0.800000, 0.277578, -0.881468, -0.382053,
+0.095491, -0.951057, -0.293893, 0.100000, 0.900000, -0.000000, -0.881468, -0.472244,
+-0.095492, -0.951057, -0.293893, 0.200000, 0.900000, -0.000000, -0.881468, -0.472244,
+-0.181636, -0.809017, -0.559017, 0.200000, 0.800000, -0.000000, -0.881468, -0.472244,
+-0.095492, -0.951057, -0.293893, 0.200000, 0.900000, -0.277578, -0.881468, -0.382053,
+-0.250000, -0.951057, -0.181636, 0.300000, 0.900000, -0.277578, -0.881468, -0.382053,
+-0.475528, -0.809017, -0.345491, 0.300000, 0.800000, -0.277578, -0.881468, -0.382053,
+-0.250000, -0.951057, -0.181636, 0.300000, 0.900000, -0.449130, -0.881468, -0.145931,
+-0.309017, -0.951057, 0.000000, 0.400000, 0.900000, -0.449130, -0.881468, -0.145931,
+-0.587785, -0.809017, 0.000000, 0.400000, 0.800000, -0.449130, -0.881468, -0.145931,
+-0.309017, -0.951057, 0.000000, 0.400000, 0.900000, -0.449130, -0.881468, 0.145931,
+-0.250000, -0.951057, 0.181636, 0.500000, 0.900000, -0.449130, -0.881468, 0.145931,
+-0.475528, -0.809017, 0.345492, 0.500000, 0.800000, -0.449130, -0.881468, 0.145931,
+-0.250000, -0.951057, 0.181636, 0.500000, 0.900000, -0.277578, -0.881468, 0.382053,
+-0.095491, -0.951057, 0.293893, 0.600000, 0.900000, -0.277578, -0.881468, 0.382053,
+-0.181636, -0.809017, 0.559017, 0.600000, 0.800000, -0.277578, -0.881468, 0.382053,
+-0.095491, -0.951057, 0.293893, 0.600000, 0.900000, 0.000000, -0.881468, 0.472244,
+0.095492, -0.951057, 0.293893, 0.700000, 0.900000, 0.000000, -0.881468, 0.472244,
+0.181636, -0.809017, 0.559017, 0.700000, 0.800000, 0.000000, -0.881468, 0.472244,
+0.095492, -0.951057, 0.293893, 0.700000, 0.900000, 0.277578, -0.881468, 0.382053,
+0.250000, -0.951057, 0.181636, 0.800000, 0.900000, 0.277578, -0.881468, 0.382053,
+0.475528, -0.809017, 0.345491, 0.800000, 0.800000, 0.277578, -0.881468, 0.382053,
+0.250000, -0.951057, 0.181636, 0.800000, 0.900000, 0.449130, -0.881468, 0.145931,
+0.309017, -0.951057, 0.000000, 0.900000, 0.900000, 0.449130, -0.881468, 0.145931,
+0.587785, -0.809017, 0.000000, 0.900000, 0.800000, 0.449131, -0.881468, 0.145931,
+0.309017, -0.951057, 0.000000, 0.900000, 0.900000, 0.449131, -0.881468, -0.145931,
+0.250000, -0.951057, -0.181636, 1.000000, 0.900000, 0.449131, -0.881468, -0.145931,
+0.475528, -0.809017, -0.345492, 1.000000, 0.800000, 0.449131, -0.881468, -0.145931,
+0.475528, -0.809017, -0.345492, 0.000000, 0.800000, 0.425919, -0.689152, -0.586227,
+0.181636, -0.809017, -0.559017, 0.100000, 0.800000, 0.425919, -0.689152, -0.586227,
+0.250000, -0.587785, -0.769421, 0.100000, 0.700000, 0.425919, -0.689152, -0.586227,
+0.181636, -0.809017, -0.559017, 0.100000, 0.800000, -0.000000, -0.689152, -0.724617,
+-0.181636, -0.809017, -0.559017, 0.200000, 0.800000, -0.000000, -0.689152, -0.724617,
+-0.250000, -0.587785, -0.769421, 0.200000, 0.700000, -0.000000, -0.689152, -0.724617,
+-0.181636, -0.809017, -0.559017, 0.200000, 0.800000, -0.425919, -0.689152, -0.586228,
+-0.475528, -0.809017, -0.345491, 0.300000, 0.800000, -0.425919, -0.689152, -0.586228,
+-0.654509, -0.587785, -0.475528, 0.300000, 0.700000, -0.425919, -0.689152, -0.586228,
+-0.475528, -0.809017, -0.345491, 0.300000, 0.800000, -0.689152, -0.689152, -0.223919,
+-0.587785, -0.809017, 0.000000, 0.400000, 0.800000, -0.689152, -0.689152, -0.223919,
+-0.809017, -0.587785, 0.000000, 0.400000, 0.700000, -0.689152, -0.689152, -0.223919,
+-0.587785, -0.809017, 0.000000, 0.400000, 0.800000, -0.689152, -0.689152, 0.223919,
+-0.475528, -0.809017, 0.345492, 0.500000, 0.800000, -0.689152, -0.689152, 0.223919,
+-0.654509, -0.587785, 0.475528, 0.500000, 0.700000, -0.689152, -0.689152, 0.223919,
+-0.475528, -0.809017, 0.345492, 0.500000, 0.800000, -0.425919, -0.689152, 0.586228,
+-0.181636, -0.809017, 0.559017, 0.600000, 0.800000, -0.425919, -0.689152, 0.586228,
+-0.250000, -0.587785, 0.769421, 0.600000, 0.700000, -0.425919, -0.689152, 0.586228,
+-0.181636, -0.809017, 0.559017, 0.600000, 0.800000, 0.000000, -0.689152, 0.724617,
+0.181636, -0.809017, 0.559017, 0.700000, 0.800000, 0.000000, -0.689152, 0.724617,
+0.250000, -0.587785, 0.769421, 0.700000, 0.700000, 0.000000, -0.689152, 0.724617,
+0.181636, -0.809017, 0.559017, 0.700000, 0.800000, 0.425919, -0.689152, 0.586227,
+0.475528, -0.809017, 0.345491, 0.800000, 0.800000, 0.425919, -0.689152, 0.586227,
+0.654509, -0.587785, 0.475528, 0.800000, 0.700000, 0.425919, -0.689152, 0.586227,
+0.475528, -0.809017, 0.345491, 0.800000, 0.800000, 0.689152, -0.689152, 0.223919,
+0.587785, -0.809017, 0.000000, 0.900000, 0.800000, 0.689152, -0.689152, 0.223919,
+0.809017, -0.587785, 0.000000, 0.900000, 0.700000, 0.689152, -0.689152, 0.223919,
+0.587785, -0.809017, 0.000000, 0.900000, 0.800000, 0.689152, -0.689152, -0.223919,
+0.475528, -0.809017, -0.345492, 1.000000, 0.800000, 0.689152, -0.689152, -0.223919,
+0.654509, -0.587785, -0.475528, 1.000000, 0.700000, 0.689152, -0.689152, -0.223919,
+0.654509, -0.587785, -0.475528, 0.000000, 0.700000, 0.528952, -0.436083, -0.728040,
+0.250000, -0.587785, -0.769421, 0.100000, 0.700000, 0.528952, -0.436083, -0.728040,
+0.293893, -0.309017, -0.904509, 0.100000, 0.600000, 0.528952, -0.436083, -0.728040,
+0.250000, -0.587785, -0.769421, 0.100000, 0.700000, -0.000000, -0.436083, -0.899906,
+-0.250000, -0.587785, -0.769421, 0.200000, 0.700000, -0.000000, -0.436083, -0.899906,
+-0.293893, -0.309017, -0.904509, 0.200000, 0.600000, -0.000000, -0.436083, -0.899906,
+-0.250000, -0.587785, -0.769421, 0.200000, 0.700000, -0.528952, -0.436083, -0.728040,
+-0.654509, -0.587785, -0.475528, 0.300000, 0.700000, -0.528952, -0.436083, -0.728040,
+-0.769421, -0.309017, -0.559017, 0.300000, 0.600000, -0.528952, -0.436083, -0.728040,
+-0.654509, -0.587785, -0.475528, 0.300000, 0.700000, -0.855862, -0.436083, -0.278086,
+-0.809017, -0.587785, 0.000000, 0.400000, 0.700000, -0.855862, -0.436083, -0.278086,
+-0.951057, -0.309017, 0.000000, 0.400000, 0.600000, -0.855862, -0.436083, -0.278086,
+-0.809017, -0.587785, 0.000000, 0.400000, 0.700000, -0.855862, -0.436083, 0.278086,
+-0.654509, -0.587785, 0.475528, 0.500000, 0.700000, -0.855862, -0.436083, 0.278086,
+-0.769421, -0.309017, 0.559017, 0.500000, 0.600000, -0.855862, -0.436083, 0.278086,
+-0.654509, -0.587785, 0.475528, 0.500000, 0.700000, -0.528952, -0.436083, 0.728040,
+-0.250000, -0.587785, 0.769421, 0.600000, 0.700000, -0.528952, -0.436083, 0.728039,
+-0.293893, -0.309017, 0.904509, 0.600000, 0.600000, -0.528952, -0.436083, 0.728039,
+-0.250000, -0.587785, 0.769421, 0.600000, 0.700000, 0.000000, -0.436083, 0.899906,
+0.250000, -0.587785, 0.769421, 0.700000, 0.700000, 0.000000, -0.436083, 0.899906,
+0.293893, -0.309017, 0.904509, 0.700000, 0.600000, 0.000000, -0.436083, 0.899906,
+0.250000, -0.587785, 0.769421, 0.700000, 0.700000, 0.528952, -0.436083, 0.728039,
+0.654509, -0.587785, 0.475528, 0.800000, 0.700000, 0.528952, -0.436083, 0.728040,
+0.769421, -0.309017, 0.559017, 0.800000, 0.600000, 0.528952, -0.436083, 0.728040,
+0.654509, -0.587785, 0.475528, 0.800000, 0.700000, 0.855862, -0.436083, 0.278086,
+0.809017, -0.587785, 0.000000, 0.900000, 0.700000, 0.855862, -0.436083, 0.278086,
+0.951057, -0.309017, 0.000000, 0.900000, 0.600000, 0.855862, -0.436083, 0.278086,
+0.809017, -0.587785, 0.000000, 0.900000, 0.700000, 0.855862, -0.436084, -0.278086,
+0.654509, -0.587785, -0.475528, 1.000000, 0.700000, 0.855862, -0.436084, -0.278086,
+0.769421, -0.309017, -0.559017, 1.000000, 0.600000, 0.855862, -0.436084, -0.278086,
+0.769421, -0.309017, -0.559017, 0.000000, 0.600000, 0.581228, -0.148952, -0.799992,
+0.293893, -0.309017, -0.904509, 0.100000, 0.600000, 0.581228, -0.148952, -0.799992,
+0.309017, 0.000000, -0.951057, 0.100000, 0.500000, 0.581228, -0.148952, -0.799992,
+0.293893, -0.309017, -0.904509, 0.100000, 0.600000, -0.000000, -0.148952, -0.988844,
+-0.293893, -0.309017, -0.904509, 0.200000, 0.600000, -0.000000, -0.148952, -0.988844,
+-0.309017, 0.000000, -0.951057, 0.200000, 0.500000, -0.000000, -0.148952, -0.988844,
+-0.293893, -0.309017, -0.904509, 0.200000, 0.600000, -0.581228, -0.148952, -0.799992,
+-0.769421, -0.309017, -0.559017, 0.300000, 0.600000, -0.581228, -0.148952, -0.799992,
+-0.809017, 0.000000, -0.587785, 0.300000, 0.500000, -0.581228, -0.148952, -0.799992,
+-0.769421, -0.309017, -0.559017, 0.300000, 0.600000, -0.940447, -0.148952, -0.305570,
+-0.951057, -0.309017, 0.000000, 0.400000, 0.600000, -0.940447, -0.148952, -0.305570,
+-1.000000, 0.000000, 0.000000, 0.400000, 0.500000, -0.940447, -0.148952, -0.305570,
+-0.951057, -0.309017, 0.000000, 0.400000, 0.600000, -0.940447, -0.148952, 0.305570,
+-0.769421, -0.309017, 0.559017, 0.500000, 0.600000, -0.940447, -0.148952, 0.305570,
+-0.809017, 0.000000, 0.587785, 0.500000, 0.500000, -0.940447, -0.148952, 0.305570,
+-0.769421, -0.309017, 0.559017, 0.500000, 0.600000, -0.581228, -0.148952, 0.799992,
+-0.293893, -0.309017, 0.904509, 0.600000, 0.600000, -0.581228, -0.148952, 0.799992,
+-0.309017, 0.000000, 0.951057, 0.600000, 0.500000, -0.581228, -0.148952, 0.799992,
+-0.293893, -0.309017, 0.904509, 0.600000, 0.600000, 0.000000, -0.148952, 0.988844,
+0.293893, -0.309017, 0.904509, 0.700000, 0.600000, 0.000000, -0.148952, 0.988844,
+0.309017, 0.000000, 0.951057, 0.700000, 0.500000, 0.000000, -0.148952, 0.988844,
+0.293893, -0.309017, 0.904509, 0.700000, 0.600000, 0.581228, -0.148952, 0.799992,
+0.769421, -0.309017, 0.559017, 0.800000, 0.600000, 0.581228, -0.148952, 0.799992,
+0.809017, 0.000000, 0.587785, 0.800000, 0.500000, 0.581228, -0.148952, 0.799992,
+0.769421, -0.309017, 0.559017, 0.800000, 0.600000, 0.940447, -0.148952, 0.305570,
+0.951057, -0.309017, 0.000000, 0.900000, 0.600000, 0.940447, -0.148952, 0.305570,
+1.000000, 0.000000, 0.000000, 0.900000, 0.500000, 0.940447, -0.148952, 0.305570,
+0.951057, -0.309017, 0.000000, 0.900000, 0.600000, 0.940447, -0.148952, -0.305570,
+0.769421, -0.309017, -0.559017, 1.000000, 0.600000, 0.940447, -0.148952, -0.305570,
+0.809017, 0.000000, -0.587785, 1.000000, 0.500000, 0.940447, -0.148952, -0.305570,
+0.809017, 0.000000, -0.587785, 0.000000, 0.500000, 0.581228, 0.148952, -0.799992,
+0.309017, 0.000000, -0.951057, 0.100000, 0.500000, 0.581228, 0.148952, -0.799992,
+0.293893, 0.309017, -0.904509, 0.100000, 0.400000, 0.581228, 0.148952, -0.799992,
+0.309017, 0.000000, -0.951057, 0.100000, 0.500000, -0.000000, 0.148952, -0.988844,
+-0.309017, 0.000000, -0.951057, 0.200000, 0.500000, -0.000000, 0.148952, -0.988844,
+-0.293893, 0.309017, -0.904509, 0.200000, 0.400000, -0.000000, 0.148952, -0.988844,
+-0.309017, 0.000000, -0.951057, 0.200000, 0.500000, -0.581228, 0.148952, -0.799992,
+-0.809017, 0.000000, -0.587785, 0.300000, 0.500000, -0.581228, 0.148952, -0.799992,
+-0.769421, 0.309017, -0.559017, 0.300000, 0.400000, -0.581228, 0.148952, -0.799992,
+-0.809017, 0.000000, -0.587785, 0.300000, 0.500000, -0.940447, 0.148952, -0.305570,
+-1.000000, 0.000000, 0.000000, 0.400000, 0.500000, -0.940447, 0.148952, -0.305570,
+-0.951057, 0.309017, 0.000000, 0.400000, 0.400000, -0.940447, 0.148952, -0.305570,
+-1.000000, 0.000000, 0.000000, 0.400000, 0.500000, -0.940447, 0.148952, 0.305570,
+-0.809017, 0.000000, 0.587785, 0.500000, 0.500000, -0.940447, 0.148952, 0.305570,
+-0.769421, 0.309017, 0.559017, 0.500000, 0.400000, -0.940447, 0.148952, 0.305570,
+-0.809017, 0.000000, 0.587785, 0.500000, 0.500000, -0.581228, 0.148952, 0.799992,
+-0.309017, 0.000000, 0.951057, 0.600000, 0.500000, -0.581228, 0.148952, 0.799992,
+-0.293893, 0.309017, 0.904509, 0.600000, 0.400000, -0.581228, 0.148952, 0.799992,
+-0.309017, 0.000000, 0.951057, 0.600000, 0.500000, 0.000000, 0.148952, 0.988844,
+0.309017, 0.000000, 0.951057, 0.700000, 0.500000, 0.000000, 0.148952, 0.988844,
+0.293893, 0.309017, 0.904509, 0.700000, 0.400000, 0.000000, 0.148952, 0.988844,
+0.309017, 0.000000, 0.951057, 0.700000, 0.500000, 0.581228, 0.148952, 0.799992,
+0.809017, 0.000000, 0.587785, 0.800000, 0.500000, 0.581228, 0.148952, 0.799992,
+0.769421, 0.309017, 0.559017, 0.800000, 0.400000, 0.581228, 0.148952, 0.799992,
+0.809017, 0.000000, 0.587785, 0.800000, 0.500000, 0.940447, 0.148952, 0.305570,
+1.000000, 0.000000, 0.000000, 0.900000, 0.500000, 0.940447, 0.148952, 0.305570,
+0.951057, 0.309017, 0.000000, 0.900000, 0.400000, 0.940447, 0.148952, 0.305570,
+1.000000, 0.000000, 0.000000, 0.900000, 0.500000, 0.940447, 0.148952, -0.305570,
+0.809017, 0.000000, -0.587785, 1.000000, 0.500000, 0.940447, 0.148952, -0.305570,
+0.769421, 0.309017, -0.559017, 1.000000, 0.400000, 0.940447, 0.148952, -0.305569,
+0.769421, 0.309017, -0.559017, 0.000000, 0.400000, 0.528952, 0.436083, -0.728040,
+0.293893, 0.309017, -0.904509, 0.100000, 0.400000, 0.528952, 0.436083, -0.728040,
+0.250000, 0.587785, -0.769421, 0.100000, 0.300000, 0.528952, 0.436083, -0.728040,
+0.293893, 0.309017, -0.904509, 0.100000, 0.400000, -0.000000, 0.436083, -0.899906,
+-0.293893, 0.309017, -0.904509, 0.200000, 0.400000, -0.000000, 0.436083, -0.899906,
+-0.250000, 0.587785, -0.769421, 0.200000, 0.300000, -0.000000, 0.436083, -0.899906,
+-0.293893, 0.309017, -0.904509, 0.200000, 0.400000, -0.528952, 0.436083, -0.728039,
+-0.769421, 0.309017, -0.559017, 0.300000, 0.400000, -0.528952, 0.436083, -0.728039,
+-0.654509, 0.587785, -0.475528, 0.300000, 0.300000, -0.528952, 0.436083, -0.728039,
+-0.769421, 0.309017, -0.559017, 0.300000, 0.400000, -0.855862, 0.436083, -0.278086,
+-0.951057, 0.309017, 0.000000, 0.400000, 0.400000, -0.855862, 0.436083, -0.278086,
+-0.809017, 0.587785, 0.000000, 0.400000, 0.300000, -0.855862, 0.436083, -0.278086,
+-0.951057, 0.309017, 0.000000, 0.400000, 0.400000, -0.855862, 0.436083, 0.278086,
+-0.769421, 0.309017, 0.559017, 0.500000, 0.400000, -0.855862, 0.436083, 0.278086,
+-0.654509, 0.587785, 0.475528, 0.500000, 0.300000, -0.855862, 0.436083, 0.278086,
+-0.769421, 0.309017, 0.559017, 0.500000, 0.400000, -0.528952, 0.436083, 0.728039,
+-0.293893, 0.309017, 0.904509, 0.600000, 0.400000, -0.528952, 0.436083, 0.728039,
+-0.250000, 0.587785, 0.769421, 0.600000, 0.300000, -0.528952, 0.436083, 0.728039,
+-0.293893, 0.309017, 0.904509, 0.600000, 0.400000, 0.000000, 0.436083, 0.899906,
+0.293893, 0.309017, 0.904509, 0.700000, 0.400000, 0.000000, 0.436083, 0.899906,
+0.250000, 0.587785, 0.769421, 0.700000, 0.300000, 0.000000, 0.436083, 0.899906,
+0.293893, 0.309017, 0.904509, 0.700000, 0.400000, 0.528952, 0.436083, 0.728040,
+0.769421, 0.309017, 0.559017, 0.800000, 0.400000, 0.528952, 0.436083, 0.728040,
+0.654509, 0.587785, 0.475528, 0.800000, 0.300000, 0.528952, 0.436083, 0.728040,
+0.769421, 0.309017, 0.559017, 0.800000, 0.400000, 0.855862, 0.436083, 0.278086,
+0.951057, 0.309017, 0.000000, 0.900000, 0.400000, 0.855862, 0.436083, 0.278086,
+0.809017, 0.587785, 0.000000, 0.900000, 0.300000, 0.855862, 0.436083, 0.278086,
+0.951057, 0.309017, 0.000000, 0.900000, 0.400000, 0.855862, 0.436084, -0.278086,
+0.769421, 0.309017, -0.559017, 1.000000, 0.400000, 0.855862, 0.436084, -0.278086,
+0.654509, 0.587785, -0.475528, 1.000000, 0.300000, 0.855862, 0.436084, -0.278086,
+0.654509, 0.587785, -0.475528, 0.000000, 0.300000, 0.425919, 0.689152, -0.586227,
+0.250000, 0.587785, -0.769421, 0.100000, 0.300000, 0.425919, 0.689152, -0.586227,
+0.181636, 0.809017, -0.559017, 0.100000, 0.200000, 0.425919, 0.689152, -0.586227,
+0.250000, 0.587785, -0.769421, 0.100000, 0.300000, -0.000000, 0.689152, -0.724617,
+-0.250000, 0.587785, -0.769421, 0.200000, 0.300000, -0.000000, 0.689152, -0.724617,
+-0.181636, 0.809017, -0.559017, 0.200000, 0.200000, -0.000000, 0.689152, -0.724617,
+-0.250000, 0.587785, -0.769421, 0.200000, 0.300000, -0.425919, 0.689152, -0.586227,
+-0.654509, 0.587785, -0.475528, 0.300000, 0.300000, -0.425919, 0.689152, -0.586227,
+-0.475528, 0.809017, -0.345491, 0.300000, 0.200000, -0.425919, 0.689152, -0.586227,
+-0.654509, 0.587785, -0.475528, 0.300000, 0.300000, -0.689152, 0.689152, -0.223919,
+-0.809017, 0.587785, 0.000000, 0.400000, 0.300000, -0.689152, 0.689152, -0.223919,
+-0.587785, 0.809017, 0.000000, 0.400000, 0.200000, -0.689152, 0.689152, -0.223919,
+-0.809017, 0.587785, 0.000000, 0.400000, 0.300000, -0.689152, 0.689152, 0.223919,
+-0.654509, 0.587785, 0.475528, 0.500000, 0.300000, -0.689152, 0.689152, 0.223919,
+-0.475528, 0.809017, 0.345492, 0.500000, 0.200000, -0.689152, 0.689152, 0.223919,
+-0.654509, 0.587785, 0.475528, 0.500000, 0.300000, -0.425919, 0.689152, 0.586228,
+-0.250000, 0.587785, 0.769421, 0.600000, 0.300000, -0.425919, 0.689152, 0.586228,
+-0.181636, 0.809017, 0.559017, 0.600000, 0.200000, -0.425919, 0.689152, 0.586228,
+-0.250000, 0.587785, 0.769421, 0.600000, 0.300000, 0.000000, 0.689152, 0.724617,
+0.250000, 0.587785, 0.769421, 0.700000, 0.300000, 0.000000, 0.689152, 0.724617,
+0.181636, 0.809017, 0.559017, 0.700000, 0.200000, 0.000000, 0.689152, 0.724617,
+0.250000, 0.587785, 0.769421, 0.700000, 0.300000, 0.425919, 0.689152, 0.586227,
+0.654509, 0.587785, 0.475528, 0.800000, 0.300000, 0.425919, 0.689152, 0.586227,
+0.475528, 0.809017, 0.345491, 0.800000, 0.200000, 0.425919, 0.689152, 0.586227,
+0.654509, 0.587785, 0.475528, 0.800000, 0.300000, 0.689152, 0.689152, 0.223919,
+0.809017, 0.587785, 0.000000, 0.900000, 0.300000, 0.689152, 0.689152, 0.223919,
+0.587785, 0.809017, 0.000000, 0.900000, 0.200000, 0.689152, 0.689152, 0.223919,
+0.809017, 0.587785, 0.000000, 0.900000, 0.300000, 0.689152, 0.689152, -0.223919,
+0.654509, 0.587785, -0.475528, 1.000000, 0.300000, 0.689152, 0.689152, -0.223919,
+0.475528, 0.809017, -0.345492, 1.000000, 0.200000, 0.689152, 0.689152, -0.223919,
+0.475528, 0.809017, -0.345492, 0.000000, 0.200000, 0.277578, 0.881468, -0.382053,
+0.181636, 0.809017, -0.559017, 0.100000, 0.200000, 0.277578, 0.881468, -0.382053,
+0.095491, 0.951057, -0.293893, 0.100000, 0.100000, 0.277578, 0.881468, -0.382053,
+0.181636, 0.809017, -0.559017, 0.100000, 0.200000, -0.000000, 0.881468, -0.472244,
+-0.181636, 0.809017, -0.559017, 0.200000, 0.200000, -0.000000, 0.881468, -0.472244,
+-0.095492, 0.951057, -0.293893, 0.200000, 0.100000, -0.000000, 0.881468, -0.472244,
+-0.181636, 0.809017, -0.559017, 0.200000, 0.200000, -0.277578, 0.881468, -0.382053,
+-0.475528, 0.809017, -0.345491, 0.300000, 0.200000, -0.277578, 0.881468, -0.382053,
+-0.250000, 0.951057, -0.181636, 0.300000, 0.100000, -0.277578, 0.881468, -0.382053,
+-0.475528, 0.809017, -0.345491, 0.300000, 0.200000, -0.449130, 0.881468, -0.145931,
+-0.587785, 0.809017, 0.000000, 0.400000, 0.200000, -0.449130, 0.881468, -0.145931,
+-0.309017, 0.951057, 0.000000, 0.400000, 0.100000, -0.449130, 0.881468, -0.145931,
+-0.587785, 0.809017, 0.000000, 0.400000, 0.200000, -0.449130, 0.881468, 0.145931,
+-0.475528, 0.809017, 0.345492, 0.500000, 0.200000, -0.449130, 0.881468, 0.145931,
+-0.250000, 0.951057, 0.181636, 0.500000, 0.100000, -0.449131, 0.881468, 0.145931,
+-0.475528, 0.809017, 0.345492, 0.500000, 0.200000, -0.277578, 0.881468, 0.382053,
+-0.181636, 0.809017, 0.559017, 0.600000, 0.200000, -0.277578, 0.881468, 0.382053,
+-0.095491, 0.951057, 0.293893, 0.600000, 0.100000, -0.277578, 0.881468, 0.382053,
+-0.181636, 0.809017, 0.559017, 0.600000, 0.200000, 0.000000, 0.881468, 0.472244,
+0.181636, 0.809017, 0.559017, 0.700000, 0.200000, 0.000000, 0.881468, 0.472244,
+0.095492, 0.951057, 0.293893, 0.700000, 0.100000, 0.000000, 0.881468, 0.472244,
+0.181636, 0.809017, 0.559017, 0.700000, 0.200000, 0.277578, 0.881468, 0.382053,
+0.475528, 0.809017, 0.345491, 0.800000, 0.200000, 0.277578, 0.881468, 0.382053,
+0.250000, 0.951057, 0.181636, 0.800000, 0.100000, 0.277578, 0.881468, 0.382053,
+0.475528, 0.809017, 0.345491, 0.800000, 0.200000, 0.449131, 0.881468, 0.145931,
+0.587785, 0.809017, 0.000000, 0.900000, 0.200000, 0.449131, 0.881468, 0.145931,
+0.309017, 0.951057, 0.000000, 0.900000, 0.100000, 0.449130, 0.881468, 0.145931,
+0.587785, 0.809017, 0.000000, 0.900000, 0.200000, 0.449131, 0.881468, -0.145931,
+0.475528, 0.809017, -0.345492, 1.000000, 0.200000, 0.449131, 0.881468, -0.145931,
+0.250000, 0.951057, -0.181636, 1.000000, 0.100000, 0.449131, 0.881468, -0.145931,
+0.095491, -0.951057, -0.293893, 0.100000, 0.900000, 0.096557, -0.986415, -0.132899,
+0.250000, -0.951057, -0.181636, 0.000000, 0.900000, 0.096557, -0.986415, -0.132899,
+0.000000, -1.000000, 0.000000, 0.050000, 1.000000, 0.096557, -0.986415, -0.132899,
+-0.095492, -0.951057, -0.293893, 0.200000, 0.900000, -0.000000, -0.986415, -0.164272,
+0.095491, -0.951057, -0.293893, 0.100000, 0.900000, -0.000000, -0.986415, -0.164272,
+0.000000, -1.000000, 0.000000, 0.150000, 1.000000, -0.000000, -0.986415, -0.164272,
+-0.250000, -0.951057, -0.181636, 0.300000, 0.900000, -0.096557, -0.986415, -0.132899,
+-0.095492, -0.951057, -0.293893, 0.200000, 0.900000, -0.096557, -0.986415, -0.132899,
+0.000000, -1.000000, 0.000000, 0.250000, 1.000000, -0.096557, -0.986415, -0.132899,
+-0.309017, -0.951057, 0.000000, 0.400000, 0.900000, -0.156233, -0.986415, -0.050763,
+-0.250000, -0.951057, -0.181636, 0.300000, 0.900000, -0.156233, -0.986415, -0.050763,
+0.000000, -1.000000, 0.000000, 0.350000, 1.000000, -0.156233, -0.986415, -0.050763,
+-0.250000, -0.951057, 0.181636, 0.500000, 0.900000, -0.156233, -0.986415, 0.050763,
+-0.309017, -0.951057, 0.000000, 0.400000, 0.900000, -0.156233, -0.986415, 0.050763,
+0.000000, -1.000000, 0.000000, 0.450000, 1.000000, -0.156233, -0.986415, 0.050763,
+-0.095491, -0.951057, 0.293893, 0.600000, 0.900000, -0.096557, -0.986415, 0.132899,
+-0.250000, -0.951057, 0.181636, 0.500000, 0.900000, -0.096557, -0.986415, 0.132899,
+0.000000, -1.000000, 0.000000, 0.550000, 1.000000, -0.096557, -0.986415, 0.132899,
+0.095492, -0.951057, 0.293893, 0.700000, 0.900000, 0.000000, -0.986415, 0.164272,
+-0.095491, -0.951057, 0.293893, 0.600000, 0.900000, 0.000000, -0.986415, 0.164272,
+0.000000, -1.000000, 0.000000, 0.650000, 1.000000, 0.000000, -0.986415, 0.164272,
+0.250000, -0.951057, 0.181636, 0.800000, 0.900000, 0.096557, -0.986415, 0.132899,
+0.095492, -0.951057, 0.293893, 0.700000, 0.900000, 0.096557, -0.986415, 0.132899,
+0.000000, -1.000000, 0.000000, 0.750000, 1.000000, 0.096557, -0.986415, 0.132899,
+0.309017, -0.951057, 0.000000, 0.900000, 0.900000, 0.156233, -0.986415, 0.050763,
+0.250000, -0.951057, 0.181636, 0.800000, 0.900000, 0.156233, -0.986415, 0.050763,
+0.000000, -1.000000, 0.000000, 0.850000, 1.000000, 0.156233, -0.986415, 0.050763,
+0.250000, -0.951057, -0.181636, 1.000000, 0.900000, 0.156233, -0.986415, -0.050763,
+0.309017, -0.951057, 0.000000, 0.900000, 0.900000, 0.156233, -0.986415, -0.050763,
+0.000000, -1.000000, 0.000000, 0.950000, 1.000000, 0.156233, -0.986415, -0.050763,
+0.250000, 0.951057, -0.181636, 0.000000, 0.100000, 0.096557, 0.986415, -0.132899,
+0.095491, 0.951057, -0.293893, 0.100000, 0.100000, 0.096557, 0.986415, -0.132899,
+0.000000, 1.000000, 0.000000, 0.050000, 0.000000, 0.096557, 0.986415, -0.132899,
+0.095491, 0.951057, -0.293893, 0.100000, 0.100000, -0.000000, 0.986415, -0.164272,
+-0.095492, 0.951057, -0.293893, 0.200000, 0.100000, -0.000000, 0.986415, -0.164272,
+0.000000, 1.000000, 0.000000, 0.150000, 0.000000, -0.000000, 0.986415, -0.164272,
+-0.095492, 0.951057, -0.293893, 0.200000, 0.100000, -0.096557, 0.986415, -0.132899,
+-0.250000, 0.951057, -0.181636, 0.300000, 0.100000, -0.096557, 0.986415, -0.132899,
+0.000000, 1.000000, 0.000000, 0.250000, 0.000000, -0.096557, 0.986415, -0.132899,
+-0.250000, 0.951057, -0.181636, 0.300000, 0.100000, -0.156233, 0.986415, -0.050763,
+-0.309017, 0.951057, 0.000000, 0.400000, 0.100000, -0.156233, 0.986415, -0.050763,
+0.000000, 1.000000, 0.000000, 0.350000, 0.000000, -0.156233, 0.986415, -0.050763,
+-0.309017, 0.951057, 0.000000, 0.400000, 0.100000, -0.156233, 0.986415, 0.050763,
+-0.250000, 0.951057, 0.181636, 0.500000, 0.100000, -0.156233, 0.986415, 0.050763,
+0.000000, 1.000000, 0.000000, 0.450000, 0.000000, -0.156233, 0.986415, 0.050763,
+-0.250000, 0.951057, 0.181636, 0.500000, 0.100000, -0.096557, 0.986415, 0.132899,
+-0.095491, 0.951057, 0.293893, 0.600000, 0.100000, -0.096557, 0.986415, 0.132899,
+0.000000, 1.000000, 0.000000, 0.550000, 0.000000, -0.096557, 0.986415, 0.132899,
+-0.095491, 0.951057, 0.293893, 0.600000, 0.100000, 0.000000, 0.986415, 0.164272,
+0.095492, 0.951057, 0.293893, 0.700000, 0.100000, 0.000000, 0.986415, 0.164272,
+0.000000, 1.000000, 0.000000, 0.650000, 0.000000, 0.000000, 0.986415, 0.164272,
+0.095492, 0.951057, 0.293893, 0.700000, 0.100000, 0.096557, 0.986415, 0.132899,
+0.250000, 0.951057, 0.181636, 0.800000, 0.100000, 0.096557, 0.986415, 0.132899,
+0.000000, 1.000000, 0.000000, 0.750000, 0.000000, 0.096557, 0.986415, 0.132899,
+0.250000, 0.951057, 0.181636, 0.800000, 0.100000, 0.156233, 0.986415, 0.050763,
+0.309017, 0.951057, 0.000000, 0.900000, 0.100000, 0.156233, 0.986415, 0.050763,
+0.000000, 1.000000, 0.000000, 0.850000, 0.000000, 0.156233, 0.986415, 0.050763,
+0.309017, 0.951057, 0.000000, 0.900000, 0.100000, 0.156233, 0.986415, -0.050763,
+0.250000, 0.951057, -0.181636, 1.000000, 0.100000, 0.156233, 0.986415, -0.050763,
+0.000000, 1.000000, 0.000000, 0.950000, 0.000000, 0.156233, 0.986415, -0.050763,
+};
diff --git a/tools/ArtistTools/source/CoreLib/Render/GeometryData/LightGeometryData.h b/tools/ArtistTools/source/CoreLib/Render/GeometryData/LightGeometryData.h
new file mode 100644
index 0000000..ed21841
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/GeometryData/LightGeometryData.h
@@ -0,0 +1,269 @@
+const int num_faces = 88;
+
+// pos.xyz, uv.uv, normal.xyz
+float vertices[88*3*8] = {
+2.977119, 2.977121, -34.306633, 0.375000, 0.687500, 0.177861, 0.429396, -0.885429,
+0.000000, 4.210287, -34.306633, 0.406250, 0.687500, 0.177861, 0.429396, -0.885429,
+0.000000, 9.084861, -31.942669, 0.406250, 0.640508, 0.177861, 0.429396, -0.885429,
+0.000000, 4.210287, -34.306633, 0.406250, 0.687500, -0.177861, 0.429396, -0.885429,
+-2.977119, 2.977121, -34.306633, 0.437500, 0.687500, -0.177861, 0.429396, -0.885429,
+-6.423970, 6.423968, -31.942669, 0.437500, 0.640508, -0.177861, 0.429396, -0.885429,
+-2.977119, 2.977121, -34.306633, 0.437500, 0.687500, -0.429395, 0.177862, -0.885430,
+-4.210285, 0.000002, -34.306633, 0.468750, 0.687500, -0.429395, 0.177862, -0.885430,
+-9.084864, -0.000001, -31.942669, 0.468750, 0.640508, -0.429395, 0.177862, -0.885429,
+-4.210285, 0.000002, -34.306633, 0.468750, 0.687500, -0.429395, -0.177862, -0.885430,
+-2.977119, -2.977118, -34.306633, 0.500000, 0.687500, -0.429395, -0.177862, -0.885430,
+-6.423970, -6.423972, -31.942667, 0.500000, 0.640508, -0.429395, -0.177862, -0.885430,
+-2.977119, -2.977118, -34.306633, 0.500000, 0.687500, -0.177861, -0.429395, -0.885429,
+0.000000, -4.210283, -34.306633, 0.531250, 0.687500, -0.177861, -0.429395, -0.885429,
+0.000000, -9.084865, -31.942671, 0.531250, 0.640508, -0.177861, -0.429395, -0.885429,
+0.000000, -4.210283, -34.306633, 0.531250, 0.687500, 0.177862, -0.429395, -0.885429,
+2.977120, -2.977118, -34.306633, 0.562500, 0.687500, 0.177862, -0.429395, -0.885429,
+6.423971, -6.423972, -31.942667, 0.562500, 0.640508, 0.177862, -0.429395, -0.885429,
+2.977120, -2.977118, -34.306633, 0.562500, 0.687500, 0.429395, -0.177862, -0.885430,
+4.210286, 0.000002, -34.306633, 0.593750, 0.687500, 0.429395, -0.177862, -0.885430,
+9.084865, -0.000001, -31.942669, 0.593750, 0.640508, 0.429395, -0.177862, -0.885429,
+4.210286, 0.000002, -34.306633, 0.593750, 0.687500, 0.429395, 0.177862, -0.885429,
+2.977119, 2.977121, -34.306633, 0.625000, 0.687500, 0.429395, 0.177862, -0.885429,
+6.423971, 6.423968, -31.942669, 0.625000, 0.640508, 0.429395, 0.177862, -0.885429,
+-4.210285, 0.000002, -34.306633, 0.343750, 0.843750, -0.124125, -0.051414, -0.990934,
+0.000000, 0.000002, -34.834015, 0.500000, 0.843750, -0.124125, -0.051414, -0.990934,
+-2.977119, -2.977118, -34.306633, 0.389515, 0.733265, -0.124125, -0.051414, -0.990934,
+10.861003, 0.000000, -10.002398, 0.593750, 0.499530, 0.791070, 0.327672, -0.516564,
+7.679888, 7.679888, -10.002398, 0.625000, 0.499530, 0.791071, 0.327672, -0.516564,
+12.349342, 12.349340, 0.110407, 0.625000, 0.311560, 0.791070, 0.327672, -0.516564,
+7.679889, -7.679889, -10.002397, 0.562500, 0.499530, 0.791071, -0.327672, -0.516564,
+10.861003, 0.000000, -10.002398, 0.593750, 0.499530, 0.791070, -0.327672, -0.516564,
+17.464600, 0.000000, 0.110407, 0.593750, 0.311560, 0.791070, -0.327672, -0.516564,
+0.000000, -10.861002, -10.002398, 0.531250, 0.499530, 0.327672, -0.791071, -0.516564,
+7.679889, -7.679889, -10.002397, 0.562500, 0.499530, 0.327672, -0.791071, -0.516564,
+12.349343, -12.349342, 0.110407, 0.562500, 0.311560, 0.327672, -0.791071, -0.516564,
+-7.679888, -7.679888, -10.002398, 0.500000, 0.499530, -0.327672, -0.791071, -0.516564,
+0.000000, -10.861002, -10.002398, 0.531250, 0.499530, -0.327672, -0.791071, -0.516564,
+0.000001, -17.464596, 0.110407, 0.531250, 0.311560, -0.327672, -0.791071, -0.516564,
+-10.861002, 0.000000, -10.002398, 0.468750, 0.499530, -0.791071, -0.327672, -0.516564,
+-7.679888, -7.679888, -10.002398, 0.500000, 0.499530, -0.791071, -0.327672, -0.516564,
+-12.349340, -12.349340, 0.110407, 0.500000, 0.311560, -0.791071, -0.327672, -0.516564,
+-7.679888, 7.679888, -10.002398, 0.437500, 0.499530, -0.791071, 0.327672, -0.516564,
+-10.861002, 0.000000, -10.002398, 0.468750, 0.499530, -0.791071, 0.327672, -0.516564,
+-17.464596, 0.000000, 0.110407, 0.468750, 0.311560, -0.791071, 0.327672, -0.516564,
+0.000000, 10.861002, -10.002398, 0.406250, 0.499530, -0.327672, 0.791071, -0.516564,
+-7.679888, 7.679888, -10.002398, 0.437500, 0.499530, -0.327672, 0.791071, -0.516564,
+-12.349340, 12.349340, 0.110407, 0.437500, 0.311560, -0.327672, 0.791071, -0.516564,
+7.679888, 7.679888, -10.002398, 0.375000, 0.499530, 0.327672, 0.791071, -0.516564,
+0.000000, 10.861002, -10.002398, 0.406250, 0.499530, 0.327672, 0.791071, -0.516564,
+0.000001, 17.464598, 0.110407, 0.406250, 0.311560, 0.327672, 0.791071, -0.516564,
+10.861003, -0.000001, -29.138687, 0.593750, 0.593515, 0.923880, 0.382683, 0.000000,
+7.679888, 7.679889, -29.138687, 0.625000, 0.593515, 0.923880, 0.382683, 0.000000,
+7.679888, 7.679888, -10.002398, 0.625000, 0.499530, 0.923880, 0.382683, 0.000000,
+7.679889, -7.679891, -29.138687, 0.562500, 0.593515, 0.923880, -0.382683, 0.000000,
+10.861003, -0.000001, -29.138687, 0.593750, 0.593515, 0.923880, -0.382683, 0.000000,
+10.861003, 0.000000, -10.002398, 0.593750, 0.499530, 0.923880, -0.382683, 0.000000,
+0.000000, -10.861003, -29.138685, 0.531250, 0.593515, 0.382683, -0.923880, 0.000000,
+7.679889, -7.679891, -29.138687, 0.562500, 0.593515, 0.382683, -0.923880, 0.000000,
+7.679889, -7.679889, -10.002397, 0.562500, 0.499530, 0.382683, -0.923880, 0.000000,
+-7.679888, -7.679889, -29.138689, 0.500000, 0.593515, -0.382683, -0.923880, 0.000000,
+0.000000, -10.861003, -29.138685, 0.531250, 0.593515, -0.382683, -0.923880, 0.000000,
+0.000000, -10.861002, -10.002398, 0.531250, 0.499530, -0.382683, -0.923880, 0.000000,
+-10.861002, -0.000001, -29.138687, 0.468750, 0.593515, -0.923880, -0.382683, 0.000000,
+-7.679888, -7.679889, -29.138689, 0.500000, 0.593515, -0.923880, -0.382683, 0.000000,
+-7.679888, -7.679888, -10.002398, 0.500000, 0.499530, -0.923880, -0.382683, 0.000000,
+-7.679888, 7.679889, -29.138687, 0.437500, 0.593515, -0.923880, 0.382683, 0.000000,
+-10.861002, -0.000001, -29.138687, 0.468750, 0.593515, -0.923880, 0.382683, 0.000000,
+-10.861002, 0.000000, -10.002398, 0.468750, 0.499530, -0.923880, 0.382683, 0.000000,
+0.000000, 10.860999, -29.138687, 0.406250, 0.593515, -0.382683, 0.923880, -0.000000,
+-7.679888, 7.679889, -29.138687, 0.437500, 0.593515, -0.382683, 0.923880, -0.000000,
+-7.679888, 7.679888, -10.002398, 0.437500, 0.499530, -0.382683, 0.923880, -0.000000,
+7.679888, 7.679889, -29.138687, 0.375000, 0.593515, 0.382683, 0.923880, -0.000000,
+0.000000, 10.860999, -29.138687, 0.406250, 0.593515, 0.382683, 0.923880, -0.000000,
+0.000000, 10.861002, -10.002398, 0.406250, 0.499530, 0.382683, 0.923880, -0.000000,
+9.084865, -0.000001, -31.942669, 0.593750, 0.640508, 0.797373, 0.330283, -0.505083,
+6.423971, 6.423968, -31.942669, 0.625000, 0.640508, 0.797373, 0.330283, -0.505083,
+7.679888, 7.679889, -29.138687, 0.625000, 0.593515, 0.797373, 0.330283, -0.505083,
+6.423971, -6.423972, -31.942667, 0.562500, 0.640508, 0.797373, -0.330283, -0.505083,
+9.084865, -0.000001, -31.942669, 0.593750, 0.640508, 0.797373, -0.330283, -0.505083,
+10.861003, -0.000001, -29.138687, 0.593750, 0.593515, 0.797373, -0.330283, -0.505083,
+0.000000, -9.084865, -31.942671, 0.531250, 0.640508, 0.330283, -0.797373, -0.505083,
+6.423971, -6.423972, -31.942667, 0.562500, 0.640508, 0.330283, -0.797373, -0.505083,
+7.679889, -7.679891, -29.138687, 0.562500, 0.593515, 0.330283, -0.797373, -0.505083,
+-6.423970, -6.423972, -31.942667, 0.500000, 0.640508, -0.330283, -0.797373, -0.505083,
+0.000000, -9.084865, -31.942671, 0.531250, 0.640508, -0.330283, -0.797373, -0.505083,
+0.000000, -10.861003, -29.138685, 0.531250, 0.593515, -0.330283, -0.797373, -0.505083,
+-9.084864, -0.000001, -31.942669, 0.468750, 0.640508, -0.797373, -0.330283, -0.505083,
+-6.423970, -6.423972, -31.942667, 0.500000, 0.640508, -0.797374, -0.330282, -0.505083,
+-7.679888, -7.679889, -29.138689, 0.500000, 0.593515, -0.797374, -0.330282, -0.505083,
+-6.423970, 6.423968, -31.942669, 0.437500, 0.640508, -0.797373, 0.330283, -0.505083,
+-9.084864, -0.000001, -31.942669, 0.468750, 0.640508, -0.797373, 0.330283, -0.505083,
+-10.861002, -0.000001, -29.138687, 0.468750, 0.593515, -0.797373, 0.330283, -0.505083,
+0.000000, 9.084861, -31.942669, 0.406250, 0.640508, -0.330282, 0.797373, -0.505084,
+-6.423970, 6.423968, -31.942669, 0.437500, 0.640508, -0.330282, 0.797373, -0.505084,
+-7.679888, 7.679889, -29.138687, 0.437500, 0.593515, -0.330282, 0.797373, -0.505084,
+6.423971, 6.423968, -31.942669, 0.375000, 0.640508, 0.330282, 0.797373, -0.505084,
+0.000000, 9.084861, -31.942669, 0.406250, 0.640508, 0.330282, 0.797373, -0.505084,
+0.000000, 10.860999, -29.138687, 0.406250, 0.593515, 0.330282, 0.797373, -0.505084,
+2.977119, 2.977121, -34.306633, 0.610485, 0.954235, 0.124125, 0.051414, -0.990934,
+4.210286, 0.000002, -34.306633, 0.656250, 0.843750, 0.124125, 0.051414, -0.990934,
+0.000000, 0.000002, -34.834015, 0.500000, 0.843750, 0.124125, 0.051414, -0.990934,
+0.000000, 0.000002, -34.834015, 0.500000, 0.843750, 0.124125, -0.051414, -0.990934,
+4.210286, 0.000002, -34.306633, 0.656250, 0.843750, 0.124125, -0.051414, -0.990934,
+2.977120, -2.977118, -34.306633, 0.610485, 0.733265, 0.124125, -0.051414, -0.990934,
+0.000000, 0.000002, -34.834015, 0.500000, 0.843750, 0.051415, -0.124125, -0.990934,
+2.977120, -2.977118, -34.306633, 0.610485, 0.733265, 0.051415, -0.124125, -0.990934,
+0.000000, -4.210283, -34.306633, 0.500000, 0.687500, 0.051415, -0.124125, -0.990934,
+0.000000, 0.000002, -34.834015, 0.500000, 0.843750, -0.051414, -0.124125, -0.990934,
+0.000000, -4.210283, -34.306633, 0.500000, 0.687500, -0.051414, -0.124125, -0.990934,
+-2.977119, -2.977118, -34.306633, 0.389515, 0.733265, -0.051414, -0.124125, -0.990934,
+-2.977119, 2.977121, -34.306633, 0.389515, 0.954235, -0.124125, 0.051414, -0.990934,
+0.000000, 0.000002, -34.834015, 0.500000, 0.843750, -0.124125, 0.051414, -0.990934,
+-4.210285, 0.000002, -34.306633, 0.343750, 0.843750, -0.124125, 0.051414, -0.990934,
+0.000000, 4.210287, -34.306633, 0.500000, 1.000000, -0.051414, 0.124125, -0.990934,
+0.000000, 0.000002, -34.834015, 0.500000, 0.843750, -0.051414, 0.124125, -0.990934,
+-2.977119, 2.977121, -34.306633, 0.389515, 0.954235, -0.051414, 0.124125, -0.990934,
+2.977119, 2.977121, -34.306633, 0.610485, 0.954235, 0.051414, 0.124125, -0.990934,
+0.000000, 0.000002, -34.834015, 0.500000, 0.843750, 0.051414, 0.124125, -0.990934,
+0.000000, 4.210287, -34.306633, 0.500000, 1.000000, 0.051414, 0.124125, -0.990934,
+12.349342, 12.349340, 0.110407, 0.610485, 0.045765, 0.382683, 0.923880, 0.000000,
+0.000001, 17.464598, 0.110407, 0.500000, 0.000000, 0.382683, 0.923880, 0.000000,
+0.000001, 17.464598, 1.144262, 0.500000, 0.000000, 0.382683, 0.923880, 0.000000,
+0.000001, 17.464598, 0.110407, 0.500000, 0.000000, -0.382683, 0.923880, -0.000000,
+-12.349340, 12.349340, 0.110407, 0.389515, 0.045765, -0.382683, 0.923880, -0.000000,
+-12.349340, 12.349340, 1.144262, 0.389515, 0.045765, -0.382683, 0.923880, -0.000000,
+-12.349340, 12.349340, 0.110407, 0.389515, 0.045765, -0.923880, 0.382683, 0.000000,
+-17.464596, 0.000000, 0.110407, 0.343750, 0.156250, -0.923880, 0.382683, 0.000000,
+-17.464596, 0.000000, 1.144262, 0.343750, 0.156250, -0.923880, 0.382683, 0.000000,
+-17.464596, 0.000000, 0.110407, 0.343750, 0.156250, -0.923880, -0.382683, 0.000000,
+-12.349340, -12.349340, 0.110407, 0.389515, 0.266735, -0.923880, -0.382683, 0.000000,
+-12.349340, -12.349340, 1.144262, 0.389515, 0.266735, -0.923880, -0.382683, 0.000000,
+-12.349340, -12.349340, 0.110407, 0.389515, 0.266735, -0.382683, -0.923880, -0.000002,
+0.000001, -17.464596, 0.110407, 0.500000, 0.312500, -0.382683, -0.923880, -0.000002,
+0.000001, -17.464600, 1.144262, 0.500000, 0.312500, -0.382683, -0.923880, -0.000002,
+0.000001, -17.464596, 0.110407, 0.500000, 0.312500, 0.382683, -0.923880, -0.000002,
+12.349343, -12.349342, 0.110407, 0.610485, 0.266735, 0.382683, -0.923880, -0.000002,
+12.349343, -12.349342, 1.144262, 0.610485, 0.266735, 0.382683, -0.923880, -0.000002,
+12.349343, -12.349342, 0.110407, 0.610485, 0.266735, 0.923880, -0.382683, 0.000000,
+17.464600, 0.000000, 0.110407, 0.656250, 0.156250, 0.923880, -0.382683, 0.000000,
+17.464600, 0.000000, 1.144262, 0.656250, 0.156250, 0.923880, -0.382683, 0.000000,
+17.464600, 0.000000, 0.110407, 0.656250, 0.156250, 0.923880, 0.382683, 0.000000,
+12.349342, 12.349340, 0.110407, 0.610485, 0.045765, 0.923880, 0.382683, 0.000000,
+12.349342, 12.349340, 1.144262, 0.610485, 0.045765, 0.923880, 0.382683, 0.000000,
+12.349342, 12.349340, 1.144262, 0.610485, 0.045765, -0.117337, -0.283277, 0.951833,
+0.000001, 17.464598, 1.144262, 0.500000, 0.000000, -0.117337, -0.283277, 0.951833,
+0.000001, 15.735191, 0.629568, 0.500000, 0.000000, -0.117337, -0.283277, 0.951833,
+0.000001, 17.464598, 1.144262, 0.500000, 0.000000, 0.117337, -0.283277, 0.951833,
+-12.349340, 12.349340, 1.144262, 0.389515, 0.045765, 0.117337, -0.283277, 0.951833,
+-11.126453, 11.126453, 0.629568, 0.389515, 0.045765, 0.117337, -0.283277, 0.951833,
+-12.349340, 12.349340, 1.144262, 0.389515, 0.045765, 0.283277, -0.117337, 0.951833,
+-17.464596, 0.000000, 1.144262, 0.343750, 0.156250, 0.283277, -0.117337, 0.951833,
+-15.735189, 0.000000, 0.629568, 0.343750, 0.156250, 0.283277, -0.117337, 0.951833,
+-17.464596, 0.000000, 1.144262, 0.343750, 0.156250, 0.283277, 0.117337, 0.951833,
+-12.349340, -12.349340, 1.144262, 0.389515, 0.266735, 0.283277, 0.117337, 0.951833,
+-11.126453, -11.126453, 0.629568, 0.389515, 0.266735, 0.283277, 0.117337, 0.951833,
+-12.349340, -12.349340, 1.144262, 0.389515, 0.266735, 0.117337, 0.283277, 0.951833,
+0.000001, -17.464600, 1.144262, 0.500000, 0.312500, 0.117337, 0.283277, 0.951833,
+0.000001, -15.735191, 0.629568, 0.500000, 0.312500, 0.117337, 0.283277, 0.951833,
+0.000001, -17.464600, 1.144262, 0.500000, 0.312500, -0.117337, 0.283277, 0.951833,
+12.349343, -12.349342, 1.144262, 0.610485, 0.266735, -0.117337, 0.283277, 0.951833,
+11.126457, -11.126455, 0.629568, 0.610485, 0.266735, -0.117337, 0.283277, 0.951833,
+12.349343, -12.349342, 1.144262, 0.610485, 0.266735, -0.283277, 0.117337, 0.951833,
+17.464600, 0.000000, 1.144262, 0.656250, 0.156250, -0.283277, 0.117337, 0.951833,
+15.735193, 0.000000, 0.629568, 0.656250, 0.156250, -0.283277, 0.117337, 0.951833,
+17.464600, 0.000000, 1.144262, 0.656250, 0.156250, -0.283277, -0.117337, 0.951833,
+12.349342, 12.349340, 1.144262, 0.610485, 0.045765, -0.283277, -0.117337, 0.951833,
+11.126455, 11.126453, 0.629568, 0.610485, 0.045765, -0.283277, -0.117337, 0.951833,
+15.735193, 0.000000, 0.629568, 0.656250, 0.156250, -0.301379, -0.124836, 0.945297,
+11.126455, 11.126453, 0.629568, 0.610485, 0.045765, -0.301379, -0.124836, 0.945297,
+1.172339, 1.172337, -3.858527, 0.610485, 0.045765, -0.301379, -0.124836, 0.945297,
+11.126455, 11.126453, 0.629568, 0.610485, 0.045765, -0.124835, -0.301379, 0.945297,
+0.000001, 15.735191, 0.629568, 0.500000, 0.000000, -0.124835, -0.301379, 0.945297,
+0.000001, 1.657940, -3.858527, 0.500000, 0.000000, -0.124835, -0.301379, 0.945297,
+0.000001, 15.735191, 0.629568, 0.500000, 0.000000, 0.124835, -0.301379, 0.945297,
+-11.126453, 11.126453, 0.629568, 0.389515, 0.045765, 0.124835, -0.301379, 0.945297,
+-1.172335, 1.172337, -3.858527, 0.389515, 0.045765, 0.124835, -0.301379, 0.945297,
+-11.126453, 11.126453, 0.629568, 0.389515, 0.045765, 0.301379, -0.124835, 0.945297,
+-15.735189, 0.000000, 0.629568, 0.343750, 0.156250, 0.301379, -0.124835, 0.945297,
+-1.657938, 0.000000, -3.858527, 0.343750, 0.156250, 0.301379, -0.124835, 0.945297,
+-15.735189, 0.000000, 0.629568, 0.343750, 0.156250, 0.301379, 0.124835, 0.945297,
+-11.126453, -11.126453, 0.629568, 0.389515, 0.266735, 0.301379, 0.124835, 0.945297,
+-1.172335, -1.172337, -3.858527, 0.389515, 0.266735, 0.301379, 0.124835, 0.945297,
+-11.126453, -11.126453, 0.629568, 0.389515, 0.266735, 0.124836, 0.301379, 0.945297,
+0.000001, -15.735191, 0.629568, 0.500000, 0.312500, 0.124835, 0.301379, 0.945297,
+0.000001, -1.657940, -3.858527, 0.500000, 0.312500, 0.124836, 0.301379, 0.945297,
+0.000001, -15.735191, 0.629568, 0.500000, 0.312500, -0.124835, 0.301379, 0.945297,
+11.126457, -11.126455, 0.629568, 0.610485, 0.266735, -0.124835, 0.301379, 0.945297,
+1.172339, -1.172337, -3.858527, 0.610485, 0.266735, -0.124835, 0.301379, 0.945297,
+11.126457, -11.126455, 0.629568, 0.610485, 0.266735, -0.301379, 0.124835, 0.945297,
+15.735193, 0.000000, 0.629568, 0.656250, 0.156250, -0.301379, 0.124835, 0.945297,
+1.657941, 0.000000, -3.858527, 0.656250, 0.156250, -0.301379, 0.124835, 0.945297,
+1.657941, 0.000000, -3.858527, 0.656250, 0.156250, 0.923878, 0.382687, 0.000000,
+1.172339, 1.172337, -3.858527, 0.610485, 0.045765, 0.923878, 0.382687, 0.000000,
+1.172338, 1.172337, 18.507620, 0.610485, 0.045765, 0.890349, 0.368798, -0.266959,
+1.172339, 1.172337, -3.858527, 0.610485, 0.045765, 0.382687, 0.923878, 0.000000,
+0.000001, 1.657940, -3.858527, 0.500000, 0.000000, 0.382687, 0.923878, 0.000000,
+0.000001, 1.657940, 18.507620, 0.500000, 0.000000, 0.368799, 0.890348, -0.266960,
+0.000001, 1.657940, -3.858527, 0.500000, 0.000000, -0.382687, 0.923878, -0.000000,
+-1.172335, 1.172337, -3.858527, 0.389515, 0.045765, -0.382687, 0.923878, -0.000000,
+-1.172336, 1.172337, 18.507620, 0.389515, 0.045765, -0.368799, 0.890348, -0.266959,
+-1.172335, 1.172337, -3.858527, 0.389515, 0.045765, -0.923878, 0.382687, -0.000000,
+-1.657938, 0.000000, -3.858527, 0.343750, 0.156250, -0.923878, 0.382687, -0.000000,
+-1.657939, 0.000000, 18.507620, 0.343750, 0.156250, -0.890348, 0.368798, -0.266960,
+-1.657938, 0.000000, -3.858527, 0.343750, 0.156250, -0.923878, -0.382687, -0.000000,
+-1.172335, -1.172337, -3.858527, 0.389515, 0.266735, -0.923878, -0.382687, -0.000000,
+-1.172336, -1.172337, 18.507620, 0.389515, 0.266735, -0.890348, -0.368798, -0.266959,
+-1.172335, -1.172337, -3.858527, 0.389515, 0.266735, -0.382687, -0.923878, -0.000000,
+0.000001, -1.657940, -3.858527, 0.500000, 0.312500, -0.382687, -0.923878, -0.000000,
+0.000001, -1.657940, 18.507620, 0.500000, 0.312500, -0.368799, -0.890348, -0.266960,
+0.000001, -1.657940, -3.858527, 0.500000, 0.312500, 0.382687, -0.923878, 0.000000,
+1.172339, -1.172337, -3.858527, 0.610485, 0.266735, 0.382687, -0.923878, 0.000000,
+1.172338, -1.172337, 18.507620, 0.610485, 0.266735, 0.368799, -0.890348, -0.266959,
+1.172339, -1.172337, -3.858527, 0.610485, 0.266735, 0.923878, -0.382687, 0.000000,
+1.657941, 0.000000, -3.858527, 0.656250, 0.156250, 0.923878, -0.382687, 0.000000,
+1.657941, 0.000000, 18.507620, 0.656250, 0.156250, 0.890348, -0.368798, -0.266960,
+1.657941, 0.000000, 18.507620, 0.656250, 0.156250, 0.890348, 0.368798, -0.266960,
+1.172338, 1.172337, 18.507620, 0.610485, 0.045765, 0.890349, 0.368798, -0.266959,
+3.204545, 3.204544, 18.507618, 0.610485, 0.045765, 0.916255, 0.379530, 0.128197,
+1.172338, -1.172337, 18.507620, 0.610485, 0.266735, 0.890349, -0.368798, -0.266959,
+1.657941, 0.000000, 18.507620, 0.656250, 0.156250, 0.890348, -0.368798, -0.266960,
+4.531928, 0.000000, 18.507618, 0.656250, 0.156250, 0.916255, -0.379530, 0.128199,
+0.000001, -1.657940, 18.507620, 0.500000, 0.312500, 0.368799, -0.890348, -0.266960,
+1.172338, -1.172337, 18.507620, 0.610485, 0.266735, 0.368799, -0.890348, -0.266959,
+3.204545, -3.204544, 18.507618, 0.610485, 0.266735, 0.379530, -0.916255, 0.128197,
+-1.172336, -1.172337, 18.507620, 0.389515, 0.266735, -0.368799, -0.890348, -0.266959,
+0.000001, -1.657940, 18.507620, 0.500000, 0.312500, -0.368799, -0.890348, -0.266960,
+0.000000, -4.531925, 18.507618, 0.500000, 0.312500, -0.379530, -0.916255, 0.128199,
+-1.657939, 0.000000, 18.507620, 0.343750, 0.156250, -0.890348, -0.368798, -0.266960,
+-1.172336, -1.172337, 18.507620, 0.389515, 0.266735, -0.890348, -0.368798, -0.266959,
+-3.204544, -3.204544, 18.507618, 0.389515, 0.266735, -0.916255, -0.379530, 0.128197,
+-1.172336, 1.172337, 18.507620, 0.389515, 0.045765, -0.890348, 0.368798, -0.266959,
+-1.657939, 0.000000, 18.507620, 0.343750, 0.156250, -0.890348, 0.368798, -0.266960,
+-4.531927, 0.000000, 18.507618, 0.343750, 0.156250, -0.916254, 0.379530, 0.128199,
+0.000001, 1.657940, 18.507620, 0.500000, 0.000000, -0.368799, 0.890348, -0.266960,
+-1.172336, 1.172337, 18.507620, 0.389515, 0.045765, -0.368799, 0.890348, -0.266959,
+-3.204544, 3.204544, 18.507618, 0.389515, 0.045765, -0.379530, 0.916255, 0.128197,
+1.172338, 1.172337, 18.507620, 0.610485, 0.045765, 0.368799, 0.890348, -0.266959,
+0.000001, 1.657940, 18.507620, 0.500000, 0.000000, 0.368799, 0.890348, -0.266960,
+0.000000, 4.531925, 18.507618, 0.500000, 0.000000, 0.379530, 0.916255, 0.128199,
+3.204545, -3.204544, 18.507618, 0.610485, 0.266735, 0.916255, -0.379530, 0.128197,
+4.531928, 0.000000, 18.507618, 0.656250, 0.156250, 0.916255, -0.379530, 0.128199,
+0.000000, 0.000000, 27.158279, 0.500000, 0.156250, 0.831594, -0.344462, 0.435657,
+0.000000, -4.531925, 18.507618, 0.500000, 0.312500, 0.379530, -0.916255, 0.128199,
+3.204545, -3.204544, 18.507618, 0.610485, 0.266735, 0.379530, -0.916255, 0.128197,
+0.000000, 0.000000, 27.158279, 0.500000, 0.156250, 0.344462, -0.831594, 0.435657,
+-3.204544, -3.204544, 18.507618, 0.389515, 0.266735, -0.379530, -0.916255, 0.128197,
+0.000000, -4.531925, 18.507618, 0.500000, 0.312500, -0.379530, -0.916255, 0.128199,
+0.000000, 0.000000, 27.158279, 0.500000, 0.156250, -0.344462, -0.831594, 0.435657,
+-4.531927, 0.000000, 18.507618, 0.343750, 0.156250, -0.916254, -0.379530, 0.128199,
+-3.204544, -3.204544, 18.507618, 0.389515, 0.266735, -0.916255, -0.379530, 0.128197,
+0.000000, 0.000000, 27.158279, 0.500000, 0.156250, -0.831594, -0.344462, 0.435657,
+-3.204544, 3.204544, 18.507618, 0.389515, 0.045765, -0.916255, 0.379530, 0.128197,
+-4.531927, 0.000000, 18.507618, 0.343750, 0.156250, -0.916254, 0.379530, 0.128199,
+0.000000, 0.000000, 27.158279, 0.500000, 0.156250, -0.831594, 0.344462, 0.435657,
+0.000000, 4.531925, 18.507618, 0.500000, 0.000000, -0.379530, 0.916255, 0.128199,
+-3.204544, 3.204544, 18.507618, 0.389515, 0.045765, -0.379530, 0.916255, 0.128197,
+0.000000, 0.000000, 27.158279, 0.500000, 0.156250, -0.344462, 0.831594, 0.435657,
+3.204545, 3.204544, 18.507618, 0.610485, 0.045765, 0.379530, 0.916255, 0.128197,
+0.000000, 4.531925, 18.507618, 0.500000, 0.000000, 0.379530, 0.916255, 0.128199,
+0.000000, 0.000000, 27.158279, 0.500000, 0.156250, 0.344462, 0.831594, 0.435657,
+4.531928, 0.000000, 18.507618, 0.656250, 0.156250, 0.916255, 0.379530, 0.128199,
+3.204545, 3.204544, 18.507618, 0.610485, 0.045765, 0.916255, 0.379530, 0.128197,
+0.000000, 0.000000, 27.158279, 0.500000, 0.156250, 0.831594, 0.344462, 0.435657,
+};
diff --git a/tools/ArtistTools/source/CoreLib/Render/GeometryData/WindGeometryData.h b/tools/ArtistTools/source/CoreLib/Render/GeometryData/WindGeometryData.h
new file mode 100644
index 0000000..3d1390a
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/GeometryData/WindGeometryData.h
@@ -0,0 +1,2513 @@
+const int num_faces = 836;
+
+// pos.xyz, uv.uv, normal.xyz
+float vertices[836*3*8] = {
+-1.002737, 3.502487, -29.476650, 1.000000, 0.966243, -0.570521, -0.819696, 0.051023,
+-1.002737, 3.589727, -28.074986, 1.000000, 0.922656, -0.569426, -0.818637, 0.074745,
+-1.336982, 4.293425, -28.133030, 0.500000, 0.922656, -0.999926, -0.012083, 0.001603,
+-1.336982, 4.293425, -28.133030, 0.500000, 0.922656, -0.999926, -0.012083, 0.001603,
+-1.002737, 4.997122, -28.191074, 0.000000, 0.932486, -0.582174, 0.810005, -0.070467,
+-1.002737, 4.921762, -29.530731, 0.000000, 0.966243, -0.582241, 0.811733, -0.045666,
+-1.002737, 5.199909, -26.333269, 0.000000, 0.859409, -0.582690, 0.803052, -0.124820,
+-1.002737, 4.997122, -28.191074, 0.000000, 0.932486, -0.582174, 0.810005, -0.070467,
+-1.336982, 4.293425, -28.133030, 0.500000, 0.922656, -0.999926, -0.012083, 0.001603,
+-1.336982, 4.293425, -28.133030, 0.500000, 0.922656, -0.999926, -0.012083, 0.001603,
+-1.002737, 3.589727, -28.074986, 1.000000, 0.922656, -0.569426, -0.818637, 0.074745,
+-1.002737, 3.807196, -26.139326, 1.000000, 0.859409, -0.566467, -0.814177, 0.127399,
+-1.002737, 3.807196, -26.139326, 1.000000, 0.859409, -0.566467, -0.814177, 0.127399,
+-1.002737, 4.261988, -23.779169, 1.000000, 0.775297, -0.564634, -0.800896, 0.199384,
+-1.336982, 4.951294, -23.914915, 0.500000, 0.775297, -0.999837, -0.017439, 0.004781,
+-1.336982, 4.951294, -23.914915, 0.500000, 0.775297, -0.999837, -0.017439, 0.004781,
+-1.002737, 5.640600, -24.050657, 0.000000, 0.786333, -0.583127, 0.787897, -0.197941,
+-1.002737, 5.199909, -26.333269, 0.000000, 0.859409, -0.582690, 0.803052, -0.124820,
+-1.002737, 6.429670, -21.436577, 0.000000, 0.669113, -0.579786, 0.770207, -0.265761,
+-1.002737, 5.640600, -24.050657, 0.000000, 0.786333, -0.583127, 0.787897, -0.197941,
+-1.336982, 4.951294, -23.914915, 0.500000, 0.775297, -0.999837, -0.017439, 0.004781,
+-1.336982, 4.951294, -23.914915, 0.500000, 0.775297, -0.999837, -0.017439, 0.004781,
+-1.002737, 4.261988, -23.779169, 1.000000, 0.775297, -0.564634, -0.800896, 0.199384,
+-1.002737, 5.061195, -21.104027, 1.000000, 0.669113, -0.566458, -0.779905, 0.266220,
+-1.002737, 5.061195, -21.104027, 1.000000, 0.669113, -0.566458, -0.779905, 0.266220,
+-1.002737, 6.120935, -18.335461, 1.000000, 0.547971, -0.566613, -0.758528, 0.321845,
+-1.336982, 6.802818, -18.519814, 0.500000, 0.547971, -0.999946, -0.009100, 0.005070,
+-1.336982, 6.802818, -18.519814, 0.500000, 0.547971, -0.999946, -0.009100, 0.005070,
+-1.002737, 7.484703, -18.704168, 0.000000, 0.551894, -0.576888, 0.751118, -0.320970,
+-1.002737, 6.429670, -21.436577, 0.000000, 0.669113, -0.579786, 0.770207, -0.265761,
+-1.002737, 8.723274, -16.066572, 0.000000, 0.418984, -0.570577, 0.739144, -0.357922,
+-1.002737, 7.484703, -18.704168, 0.000000, 0.551894, -0.576888, 0.751118, -0.320970,
+-1.336982, 6.802818, -18.519814, 0.500000, 0.547971, -0.999946, -0.009100, 0.005070,
+-1.336982, 6.802818, -18.519814, 0.500000, 0.547971, -0.999946, -0.009100, 0.005070,
+-1.002737, 6.120935, -18.335461, 1.000000, 0.547971, -0.566613, -0.758528, 0.321845,
+-1.002737, 7.357327, -15.695049, 1.000000, 0.418984, -0.568348, -0.740553, 0.358555,
+-1.002737, 7.357327, -15.695049, 1.000000, 0.418984, -0.568348, -0.740553, 0.358555,
+-1.002737, 8.627859, -13.158705, 1.000000, 0.282904, -0.571429, -0.737705, 0.359528,
+-1.336982, 9.314625, -13.332255, 0.500000, 0.282904, -0.999983, 0.005125, -0.002905,
+-1.336982, 9.314625, -13.332255, 0.500000, 0.282904, -0.999983, 0.005125, -0.002905,
+-1.002737, 10.001389, -13.505806, 0.000000, 0.286075, -0.565597, 0.742253, -0.359389,
+-1.002737, 8.723274, -16.066572, 0.000000, 0.418984, -0.570577, 0.739144, -0.357922,
+-1.002737, 11.175043, -11.003893, 0.000000, 0.140482, -0.562513, 0.757929, -0.330337,
+-1.002737, 10.001389, -13.505806, 0.000000, 0.286075, -0.565597, 0.742253, -0.359389,
+-1.336982, 9.314625, -13.332255, 0.500000, 0.282904, -0.999983, 0.005125, -0.002905,
+-1.336982, 9.314625, -13.332255, 0.500000, 0.282904, -0.999983, 0.005125, -0.002905,
+-1.002737, 8.627859, -13.158705, 1.000000, 0.282904, -0.571429, -0.737705, 0.359528,
+-1.002737, 9.790028, -10.702334, 1.000000, 0.140482, -0.576949, -0.747604, 0.328966,
+-1.002737, 9.790028, -10.702334, 1.000000, 0.140482, -0.576949, -0.747604, 0.328966,
+-1.003346, 10.657795, -8.543959, 1.020833, -0.009381, -0.588551, -0.767718, 0.253411,
+-1.337592, 11.355911, -8.670841, 0.583333, -0.069211, -0.999594, 0.026023, -0.011609,
+-1.337592, 11.355911, -8.670841, 0.583333, -0.069211, -0.999594, 0.026023, -0.011609,
+-1.003346, 12.054029, -8.797724, 0.000000, -0.005111, -0.560047, 0.787144, -0.258362,
+-1.002737, 11.175043, -11.003893, 0.000000, 0.140482, -0.562513, 0.757929, -0.330337,
+-1.005175, 12.448139, -7.124194, 0.666667, -0.726194, -0.564732, 0.815815, -0.124590,
+-1.003346, 12.054029, -8.797724, 0.000000, -0.005111, -0.560047, 0.787144, -0.258362,
+-1.337592, 11.355911, -8.670841, 0.583333, -0.069211, -0.999594, 0.026023, -0.011609,
+-1.337592, 11.355911, -8.670841, 0.583333, -0.069211, -0.999594, 0.026023, -0.011609,
+-1.003346, 10.657795, -8.543959, 1.020833, -0.009381, -0.588551, -0.767718, 0.253411,
+-1.005175, 11.045135, -6.901599, 1.083333, -0.167786, -0.591577, -0.797310, 0.119726,
+-1.005175, 11.045135, -6.901599, 1.083333, -0.167786, -0.591577, -0.797310, 0.119726,
+-1.006394, 11.114811, -5.517140, 1.000000, -0.170915, -0.583093, -0.812392, -0.004755,
+-1.340640, 11.818584, -5.617008, 1.166667, -0.809096, -0.999853, 0.017074, 0.001872,
+-1.340640, 11.818584, -5.617008, 1.166667, -0.809096, -0.999853, 0.017074, 0.001872,
+-1.006394, 12.522362, -5.716876, 1.333333, -1.447277, -0.566040, 0.824377, 0.001632,
+-1.005175, 12.448139, -7.124194, 0.666667, -0.726194, -0.564732, 0.815815, -0.124590,
+-1.002737, 11.560024, -0.158328, 0.000000, -0.503387, -0.548128, 0.812439, 0.198744,
+-1.003346, 12.142200, -2.567771, 0.000000, -0.336720, -0.545383, 0.819886, 0.174196,
+-1.337592, 11.435898, -2.488622, 0.500000, -0.336720, -0.999671, 0.024155, 0.008634,
+-1.337592, 11.435898, -2.488622, 0.500000, -0.336720, -0.999671, 0.024155, 0.008634,
+-1.003346, 10.729588, -2.409474, 1.000000, -0.336720, -0.568927, -0.804482, -0.170679,
+-1.002737, 10.154959, -0.010050, 1.000000, -0.503387, -0.554465, -0.809442, -0.193318,
+-1.002737, 10.154959, -0.010050, 1.000000, -0.503387, -0.554465, -0.809442, -0.193318,
+-1.002737, 9.503082, 2.725576, 1.000000, -0.671927, -0.543427, -0.820485, -0.177458,
+-1.336982, 10.194935, 2.646095, 0.500000, -0.671927, -0.999975, -0.006839, -0.001674,
+-1.336982, 10.194935, 2.646095, 0.500000, -0.671927, -0.999975, -0.006839, -0.001674,
+-1.002737, 10.886791, 2.566613, 0.000000, -0.670054, -0.549613, 0.814083, 0.187601,
+-1.002737, 11.560024, -0.158328, 0.000000, -0.503387, -0.548128, 0.812439, 0.198744,
+-1.002737, 10.314148, 5.254678, 0.000000, -0.844213, -0.550065, 0.824042, 0.135588,
+-1.002737, 10.886791, 2.566613, 0.000000, -0.670054, -0.549613, 0.814083, 0.187601,
+-1.336982, 10.194935, 2.646095, 0.500000, -0.671927, -0.999975, -0.006839, -0.001674,
+-1.336982, 10.194935, 2.646095, 0.500000, -0.671927, -0.999975, -0.006839, -0.001674,
+-1.002737, 9.503082, 2.725576, 1.000000, -0.671927, -0.543427, -0.820485, -0.177458,
+-1.002737, 8.971350, 5.457178, 1.000000, -0.844213, -0.532911, -0.837943, -0.117722,
+-1.002737, 8.971350, 5.457178, 1.000000, -0.844213, -0.532911, -0.837943, -0.117722,
+-1.002737, 8.743584, 8.108688, 1.000000, -1.016250, -0.522039, -0.852900, 0.006099,
+-1.336982, 9.384014, 7.968127, 0.500000, -1.016250, -0.999385, -0.034959, -0.002597,
+-1.336982, 9.384014, 7.968127, 0.500000, -1.016250, -0.999385, -0.034959, -0.002597,
+-1.002737, 10.024443, 7.827566, 0.000000, -1.018373, -0.552727, 0.833125, 0.019881,
+-1.002737, 10.314148, 5.254678, 0.000000, -0.844213, -0.550065, 0.824042, 0.135588,
+-1.002737, 10.200031, 10.206976, 0.000000, -1.184038, -0.545898, 0.826469, -0.137636,
+-1.002737, 10.024443, 7.827566, 0.000000, -1.018373, -0.552727, 0.833125, 0.019881,
+-1.336982, 9.384014, 7.968127, 0.500000, -1.016250, -0.999385, -0.034959, -0.002597,
+-1.336982, 9.384014, 7.968127, 0.500000, -1.016250, -0.999385, -0.034959, -0.002597,
+-1.002737, 8.743584, 8.108688, 1.000000, -1.016250, -0.522039, -0.852900, 0.006099,
+-1.002737, 9.003599, 10.604042, 1.000000, -1.184038, -0.512969, -0.841946, 0.167304,
+-1.002737, 9.003599, 10.604042, 1.000000, -1.184038, -0.512969, -0.841946, 0.167304,
+-1.002737, 9.694744, 12.910284, 1.000000, -1.349954, -0.500990, -0.803388, 0.321833,
+-1.336982, 10.239292, 12.641662, 0.500000, -1.349954, -0.999218, -0.036495, 0.015192,
+-1.336982, 10.239292, 12.641662, 0.500000, -1.349954, -0.999218, -0.036495, 0.015192,
+-1.002737, 10.783842, 12.373039, 0.000000, -1.349704, -0.535040, 0.792292, -0.293266,
+-1.002737, 10.200031, 10.206976, 0.000000, -1.184038, -0.545898, 0.826469, -0.137636,
+-1.002737, 11.718807, 14.305887, 0.000000, -1.516370, -0.524951, 0.731928, -0.434405,
+-1.002737, 10.783842, 12.373039, 0.000000, -1.349704, -0.535040, 0.792292, -0.293266,
+-1.336982, 10.239292, 12.641662, 0.500000, -1.349954, -0.999218, -0.036495, 0.015192,
+-1.336982, 10.239292, 12.641662, 0.500000, -1.349954, -0.999218, -0.036495, 0.015192,
+-1.002737, 9.694744, 12.910284, 1.000000, -1.349954, -0.500990, -0.803388, 0.321833,
+-1.002737, 10.760361, 14.994465, 1.000000, -1.516370, -0.490912, -0.740187, 0.459488,
+-1.002737, 10.760361, 14.994465, 1.000000, -1.516370, -0.490912, -0.740187, 0.459488,
+-1.002737, 12.090717, 16.772659, 1.000000, -1.679268, -0.484165, -0.653669, 0.581636,
+-1.336982, 12.495934, 16.355419, 0.500000, -1.679268, -0.999037, -0.033130, 0.028753,
+-1.336982, 12.495934, 16.355419, 0.500000, -1.679268, -0.999037, -0.033130, 0.028753,
+-1.002737, 12.901150, 15.938179, 0.000000, -1.683037, -0.520176, 0.645820, -0.558867,
+-1.002737, 11.718807, 14.305887, 0.000000, -1.516370, -0.524951, 0.731928, -0.434405,
+-1.002737, 14.227100, 17.202572, 0.000000, -1.834628, -0.519663, 0.527798, -0.671848,
+-1.002737, 12.901150, 15.938179, 0.000000, -1.683037, -0.520176, 0.645820, -0.558867,
+-1.336982, 12.495934, 16.355419, 0.500000, -1.679268, -0.999037, -0.033130, 0.028753,
+-1.336982, 12.495934, 16.355419, 0.500000, -1.679268, -0.999037, -0.033130, 0.028753,
+-1.002737, 12.090717, 16.772659, 1.000000, -1.679268, -0.484165, -0.653669, 0.581636,
+-1.002737, 13.576077, 18.160946, 1.000000, -1.834628, -0.481336, -0.535363, 0.694048,
+-1.002737, 13.576077, 18.160946, 1.000000, -1.834628, -0.481336, -0.535363, 0.694048,
+-1.002737, 15.212280, 19.181923, 1.000000, -1.988039, -0.480827, -0.389724, 0.785443,
+-1.336982, 15.450417, 18.654261, 0.500000, -1.988039, -0.998886, -0.021466, 0.042031,
+-1.336982, 15.450417, 18.654261, 0.500000, -1.988039, -0.998886, -0.021466, 0.042031,
+-1.002737, 15.688553, 18.126600, 0.000000, -1.986219, -0.519424, 0.384311, -0.763219,
+-1.002737, 14.227100, 17.202572, 0.000000, -1.834628, -0.519663, 0.527798, -0.671848,
+-1.002737, 17.277420, 18.737804, 0.000000, -2.145087, -0.519855, 0.222506, -0.824768,
+-1.002737, 15.688553, 18.126600, 0.000000, -1.986219, -0.519424, 0.384311, -0.763219,
+-1.336982, 15.450417, 18.654261, 0.500000, -1.988039, -0.998886, -0.021466, 0.042031,
+-1.336982, 15.450417, 18.654261, 0.500000, -1.988039, -0.998886, -0.021466, 0.042031,
+-1.002737, 15.212280, 19.181923, 1.000000, -1.988039, -0.480827, -0.389724, 0.785443,
+-1.002737, 16.995155, 19.858189, 1.000000, -2.145087, -0.479530, -0.225145, 0.848151,
+-1.002737, 16.995155, 19.858189, 1.000000, -2.145087, -0.479530, -0.225145, 0.848151,
+-1.002737, 18.890533, 20.158619, 1.000000, -2.305904, -0.477686, -0.044014, 0.877427,
+-1.336982, 18.926823, 19.584188, 0.500000, -2.305904, -0.998704, -0.001978, 0.050855,
+-1.336982, 18.926823, 19.584188, 0.500000, -2.305904, -0.998704, -0.001978, 0.050855,
+-1.002737, 18.963112, 19.009758, 0.000000, -2.303954, -0.519106, 0.044200, -0.853567,
+-1.002737, 17.277420, 18.737804, 0.000000, -2.145087, -0.519855, 0.222506, -0.824768,
+-1.002737, 20.715042, 18.916035, 0.000000, -2.470621, -0.518180, -0.147145, -0.842519,
+-1.002737, 18.963112, 19.009758, 0.000000, -2.303954, -0.519106, 0.044200, -0.853567,
+-1.336982, 18.926823, 19.584188, 0.500000, -2.305904, -0.998704, -0.001978, 0.050855,
+-1.336982, 18.926823, 19.584188, 0.500000, -2.305904, -0.998704, -0.001978, 0.050855,
+-1.002737, 18.890533, 20.158619, 1.000000, -2.305904, -0.477686, -0.044014, 0.877427,
+-1.002737, 20.864250, 20.052088, 1.000000, -2.470621, -0.474232, 0.150976, 0.867358,
+-1.002737, 20.864250, 20.052088, 1.000000, -2.470621, -0.474232, 0.150976, 0.867358,
+-1.002737, 22.911228, 19.457972, 1.000000, -2.646001, -0.471248, 0.342725, 0.812690,
+-1.336982, 22.719658, 18.922981, 0.500000, -2.646001, -0.998523, 0.022590, 0.049420,
+-1.336982, 22.719658, 18.922981, 0.500000, -2.646001, -0.998523, 0.022590, 0.049420,
+-1.002737, 22.528088, 18.387989, 0.000000, -2.637287, -0.514483, -0.334572, -0.789537,
+-1.002737, 20.715042, 18.916035, 0.000000, -2.470621, -0.518180, -0.147145, -0.842519,
+-1.002737, 24.397125, 17.356983, 0.000000, -2.838810, -0.512162, -0.495528, -0.701529,
+-1.002737, 22.528088, 18.387989, 0.000000, -2.637287, -0.514483, -0.334572, -0.789537,
+-1.336982, 22.719658, 18.922981, 0.500000, -2.646001, -0.998523, 0.022590, 0.049420,
+-1.336982, 22.719658, 18.922981, 0.500000, -2.646001, -0.998523, 0.022590, 0.049420,
+-1.002737, 22.911228, 19.457972, 1.000000, -2.646001, -0.471248, 0.342725, 0.812690,
+-1.002737, 25.026405, 18.295650, 1.000000, -2.838810, -0.470077, 0.507995, 0.721781,
+-1.002737, 25.026405, 18.295650, 1.000000, -2.838810, -0.470077, 0.507995, 0.721781,
+-1.002737, 26.982025, 16.592329, 1.000000, -3.038383, -0.470672, 0.656259, 0.589739,
+-1.336982, 26.551086, 16.221825, 0.500000, -3.038383, -0.998387, 0.041476, 0.038776,
+-1.336982, 26.551086, 16.221825, 0.500000, -3.038383, -0.998387, 0.041476, 0.038776,
+-1.002737, 26.120163, 15.851318, 0.000000, -3.040334, -0.515999, -0.637877, -0.571716,
+-1.002737, 24.397125, 17.356983, 0.000000, -2.838810, -0.512162, -0.495528, -0.701529,
+-1.002737, 27.495193, 13.899298, 0.000000, -3.234054, -0.529173, -0.759785, -0.377761,
+-1.002737, 26.120163, 15.851318, 0.000000, -3.040334, -0.515999, -0.637877, -0.571716,
+-1.336982, 26.551086, 16.221825, 0.500000, -3.038383, -0.998387, 0.041476, 0.038776,
+-1.336982, 26.551086, 16.221825, 0.500000, -3.038383, -0.998387, 0.041476, 0.038776,
+-1.002737, 26.982025, 16.592329, 1.000000, -3.038383, -0.470672, 0.656259, 0.589739,
+-1.002737, 28.550339, 14.375221, 1.000000, -3.234054, -0.475606, 0.784875, 0.397203,
+-1.002737, 28.550339, 14.375221, 1.000000, -3.234054, -0.475606, 0.784875, 0.397203,
+-1.002737, 29.425041, 11.768046, 1.000000, -3.421010, -0.486094, 0.865825, 0.118573,
+-1.336982, 28.829937, 11.681159, 0.500000, -3.421010, -0.997287, 0.072725, 0.011376,
+-1.336982, 28.829937, 11.681159, 0.500000, -3.421010, -0.997287, 0.072725, 0.011376,
+-1.002737, 28.234837, 11.594271, 0.000000, -3.427773, -0.549861, -0.829859, -0.094800,
+-1.002737, 27.495193, 13.899298, 0.000000, -3.234054, -0.529173, -0.759785, -0.377761,
+-1.002737, 28.051701, 9.029581, 0.000000, -3.594440, -0.552394, -0.818572, 0.157487,
+-1.002737, 28.234837, 11.594271, 0.000000, -3.427773, -0.549861, -0.829859, -0.094800,
+-1.336982, 28.829937, 11.681159, 0.500000, -3.421010, -0.997287, 0.072725, 0.011376,
+-1.336982, 28.829937, 11.681159, 0.500000, -3.421010, -0.997287, 0.072725, 0.011376,
+-1.002737, 29.425041, 11.768046, 1.000000, -3.421010, -0.486094, 0.865825, 0.118573,
+-1.002737, 29.299828, 8.894522, 1.000000, -3.594440, -0.508085, 0.850361, -0.136877,
+-1.002737, 29.299828, 8.894522, 1.000000, -3.594440, -0.508085, 0.850361, -0.136877,
+-1.002737, 28.522129, 6.172330, 1.000000, -3.741287, -0.527924, 0.793569, -0.302563,
+-1.336982, 27.897224, 6.377859, 0.500000, -3.741288, -0.999306, 0.035287, -0.011950,
+-1.336982, 27.897224, 6.377859, 0.500000, -3.741288, -0.999306, 0.035287, -0.011950,
+-1.002737, 27.272324, 6.583387, 0.000000, -3.761107, -0.563170, -0.762896, 0.317537,
+-1.002737, 28.051701, 9.029581, 0.000000, -3.594440, -0.552394, -0.818572, 0.157487,
+-1.002737, 26.223228, 4.633848, 0.000000, -3.848496, -0.571231, -0.699650, 0.429169,
+-1.002737, 27.272324, 6.583387, 0.000000, -3.761107, -0.563170, -0.762896, 0.317537,
+-1.336982, 27.897224, 6.377859, 0.500000, -3.741288, -0.999306, 0.035287, -0.011950,
+-1.336982, 27.897224, 6.377859, 0.500000, -3.741288, -0.999306, 0.035287, -0.011950,
+-1.002737, 28.522129, 6.172330, 1.000000, -3.741287, -0.527924, 0.793569, -0.302563,
+-1.002737, 27.439381, 4.019153, 1.000000, -3.848496, -0.545786, 0.725589, -0.419091,
+-1.002737, 27.439381, 4.019153, 1.000000, -3.848496, -0.545786, 0.725589, -0.419091,
+-1.002737, 26.363422, 2.436586, 1.020833, -3.882167, -0.561369, 0.675750, -0.477732,
+-1.336982, 25.778152, 2.814326, 0.583333, -3.762508, -0.999924, 0.011227, -0.005182,
+-1.336982, 25.778152, 2.814326, 0.583333, -3.762508, -0.999924, 0.011227, -0.005182,
+-1.002737, 25.192875, 3.192066, 0.000000, -3.935886, -0.573805, -0.657830, 0.487860,
+-1.002737, 26.223228, 4.633848, 0.000000, -3.848496, -0.571231, -0.699650, 0.429169,
+-1.002737, 24.600067, 1.327282, 1.166667, -2.723639, -0.595697, -0.491752, -0.635079,
+-0.742768, 24.296909, 1.783397, 1.333333, -1.447277, -0.428917, -0.894621, -0.125234,
+-1.002737, 24.469711, 2.269146, 0.666667, -2.691582, -0.583534, -0.710408, 0.393458,
+-1.002737, 24.469711, 2.269146, 0.666667, -2.691582, -0.583534, -0.710408, 0.393458,
+-1.002737, 25.192875, 3.192066, 0.000000, -3.935886, -0.573805, -0.657830, 0.487860,
+-1.336982, 25.778152, 2.814326, 0.583333, -3.762508, -0.999924, 0.011227, -0.005182,
+-1.336982, 25.778152, 2.814326, 0.583333, -3.762508, -0.999924, 0.011227, -0.005182,
+-1.002737, 26.363422, 2.436586, 1.020833, -3.882167, -0.561369, 0.675750, -0.477732,
+-1.002737, 25.606094, 1.426226, 1.083333, -3.808398, -0.572183, 0.564519, -0.594916,
+-1.002737, 25.606094, 1.426226, 1.083333, -3.808398, -0.572183, 0.564519, -0.594916,
+-0.742768, 25.130249, 1.141007, 1.000000, -4.000000, -0.424007, 0.088516, -0.901323,
+-1.002737, 24.600067, 1.327282, 1.166667, -2.723639, -0.595697, -0.491752, -0.635079,
+1.002737, 3.502487, -29.476650, 2.000000, 0.966243, 0.570521, -0.819696, 0.051023,
+1.002737, 3.589725, -28.074989, 2.000000, 0.922656, 0.569426, -0.818637, 0.074745,
+0.000000, 3.355162, -28.055641, 1.500000, 0.922656, -0.000000, -0.995829, 0.091245,
+0.000000, 3.355162, -28.055641, 1.500000, 0.922656, -0.000000, -0.995829, 0.091245,
+-1.002737, 3.589727, -28.074986, 1.000000, 0.922656, -0.569426, -0.818637, 0.074745,
+-1.002737, 3.502487, -29.476650, 1.000000, 0.966243, -0.570521, -0.819696, 0.051023,
+-1.002737, 3.807196, -26.139326, 1.000000, 0.859409, -0.566467, -0.814177, 0.127399,
+-1.002737, 3.589727, -28.074986, 1.000000, 0.922656, -0.569426, -0.818637, 0.074745,
+0.000000, 3.355162, -28.055641, 1.500000, 0.922656, -0.000000, -0.995829, 0.091245,
+0.000000, 3.355162, -28.055641, 1.500000, 0.922656, -0.000000, -0.995829, 0.091245,
+1.002737, 3.589725, -28.074989, 2.000000, 0.922656, 0.569426, -0.818637, 0.074745,
+1.002737, 3.807196, -26.139326, 2.000000, 0.859409, 0.566467, -0.814178, 0.127399,
+1.002737, 3.807196, -26.139326, 2.000000, 0.859409, 0.566467, -0.814178, 0.127399,
+1.002737, 4.261988, -23.779171, 2.000000, 0.775297, 0.564634, -0.800896, 0.199384,
+0.000000, 4.032219, -23.733923, 1.500000, 0.775297, 0.000000, -0.970479, 0.241185,
+0.000000, 4.032219, -23.733923, 1.500000, 0.775297, 0.000000, -0.970479, 0.241185,
+-1.002737, 4.261988, -23.779169, 1.000000, 0.775297, -0.564634, -0.800896, 0.199384,
+-1.002737, 3.807196, -26.139326, 1.000000, 0.859409, -0.566467, -0.814177, 0.127399,
+-1.002737, 5.061195, -21.104027, 1.000000, 0.669113, -0.566458, -0.779905, 0.266220,
+-1.002737, 4.261988, -23.779169, 1.000000, 0.775297, -0.564634, -0.800896, 0.199384,
+0.000000, 4.032219, -23.733923, 1.500000, 0.775297, 0.000000, -0.970479, 0.241185,
+0.000000, 4.032219, -23.733923, 1.500000, 0.775297, 0.000000, -0.970479, 0.241185,
+1.002737, 4.261988, -23.779171, 2.000000, 0.775297, 0.564634, -0.800896, 0.199384,
+1.002737, 5.061195, -21.104025, 2.000000, 0.669113, 0.566458, -0.779905, 0.266220,
+1.002737, 5.061195, -21.104025, 2.000000, 0.669113, 0.566458, -0.779905, 0.266220,
+1.002737, 6.120935, -18.335461, 2.000000, 0.547971, 0.566613, -0.758528, 0.321845,
+0.000000, 5.893641, -18.274008, 1.500000, 0.547971, -0.000000, -0.920850, 0.389917,
+0.000000, 5.893641, -18.274008, 1.500000, 0.547971, -0.000000, -0.920850, 0.389917,
+-1.002737, 6.120935, -18.335461, 1.000000, 0.547971, -0.566613, -0.758528, 0.321845,
+-1.002737, 5.061195, -21.104027, 1.000000, 0.669113, -0.566458, -0.779905, 0.266220,
+-1.002737, 7.357327, -15.695049, 1.000000, 0.418984, -0.568348, -0.740553, 0.358555,
+-1.002737, 6.120935, -18.335461, 1.000000, 0.547971, -0.566613, -0.758528, 0.321845,
+0.000000, 5.893641, -18.274008, 1.500000, 0.547971, -0.000000, -0.920850, 0.389917,
+0.000000, 5.893641, -18.274008, 1.500000, 0.547971, -0.000000, -0.920850, 0.389917,
+1.002737, 6.120935, -18.335461, 2.000000, 0.547971, 0.566613, -0.758528, 0.321845,
+1.002737, 7.357327, -15.695049, 2.000000, 0.418984, 0.568348, -0.740553, 0.358555,
+1.002737, 7.357327, -15.695049, 2.000000, 0.418984, 0.568348, -0.740553, 0.358555,
+1.002737, 8.627859, -13.158705, 2.000000, 0.282904, 0.571429, -0.737705, 0.359528,
+0.000000, 8.398937, -13.100854, 1.500000, 0.282904, 0.000000, -0.898731, 0.438502,
+0.000000, 8.398937, -13.100854, 1.500000, 0.282904, 0.000000, -0.898731, 0.438502,
+-1.002737, 8.627859, -13.158705, 1.000000, 0.282904, -0.571429, -0.737705, 0.359528,
+-1.002737, 7.357327, -15.695049, 1.000000, 0.418984, -0.568348, -0.740553, 0.358555,
+-1.002737, 9.790028, -10.702334, 1.000000, 0.140482, -0.576949, -0.747604, 0.328966,
+-1.002737, 8.627859, -13.158705, 1.000000, 0.282904, -0.571429, -0.737705, 0.359528,
+0.000000, 8.398937, -13.100854, 1.500000, 0.282904, 0.000000, -0.898731, 0.438502,
+0.000000, 8.398937, -13.100854, 1.500000, 0.282904, 0.000000, -0.898731, 0.438502,
+1.002737, 8.627859, -13.158705, 2.000000, 0.282904, 0.571429, -0.737705, 0.359528,
+1.002737, 9.790028, -10.702334, 2.000000, 0.140482, 0.576977, -0.747533, 0.329077,
+1.002737, 9.790028, -10.702334, 2.000000, 0.140482, 0.576977, -0.747533, 0.329077,
+1.002127, 10.657795, -8.543959, 2.000000, 0.010562, 0.588607, -0.767452, 0.254084,
+-0.000610, 10.425087, -8.501664, 1.500000, 0.010562, 0.000044, -0.949091, 0.315003,
+-0.000610, 10.425087, -8.501664, 1.500000, 0.010562, 0.000044, -0.949091, 0.315003,
+-1.003346, 10.657795, -8.543959, 1.020833, -0.009381, -0.588551, -0.767718, 0.253411,
+-1.002737, 9.790028, -10.702334, 1.000000, 0.140482, -0.576949, -0.747604, 0.328966,
+-1.005175, 11.045135, -6.901599, 1.083333, -0.167786, -0.591577, -0.797310, 0.119726,
+-1.003346, 10.657795, -8.543959, 1.020833, -0.009381, -0.588551, -0.767718, 0.253411,
+-0.000610, 10.425087, -8.501664, 1.500000, 0.010562, 0.000044, -0.949091, 0.315003,
+-0.000610, 10.425087, -8.501664, 1.500000, 0.010562, 0.000044, -0.949091, 0.315003,
+1.002127, 10.657795, -8.543959, 2.000000, 0.010562, 0.588607, -0.767452, 0.254084,
+1.000299, 11.045135, -6.901599, 2.000000, -0.088013, 0.591516, -0.797171, 0.120947,
+1.000299, 11.045135, -6.901599, 2.000000, -0.088013, 0.591516, -0.797171, 0.120947,
+0.999079, 11.114811, -5.517140, 2.000000, -0.170915, 0.582792, -0.812607, -0.004817,
+-0.003657, 10.880220, -5.483850, 1.500000, -0.170915, -0.000127, -0.999975, -0.007088,
+-0.003657, 10.880220, -5.483850, 1.500000, -0.170915, -0.000127, -0.999975, -0.007088,
+-1.006394, 11.114811, -5.517140, 1.000000, -0.170915, -0.583093, -0.812392, -0.004755,
+-1.005175, 11.045135, -6.901599, 1.083333, -0.167786, -0.591577, -0.797310, 0.119726,
+-1.002737, 10.154959, -0.010050, 1.000000, -0.503387, -0.554465, -0.809442, -0.193318,
+-1.003346, 10.729588, -2.409474, 1.000000, -0.336720, -0.568927, -0.804482, -0.170679,
+-0.000610, 10.494156, -2.383091, 1.500000, -0.336720, 0.000040, -0.977947, -0.208854,
+-0.000610, 10.494156, -2.383091, 1.500000, -0.336720, 0.000040, -0.977947, -0.208854,
+1.002127, 10.729588, -2.409474, 2.000000, -0.336720, 0.568931, -0.804350, -0.171283,
+1.002737, 10.154957, -0.010050, 2.000000, -0.503387, 0.554487, -0.809403, -0.193422,
+1.002737, 10.154957, -0.010050, 2.000000, -0.503387, 0.554487, -0.809403, -0.193422,
+1.002737, 9.503082, 2.725576, 2.000000, -0.671927, 0.543427, -0.820485, -0.177458,
+0.000000, 9.272461, 2.752070, 1.500000, -0.671927, -0.000000, -0.977791, -0.209581,
+0.000000, 9.272461, 2.752070, 1.500000, -0.671927, -0.000000, -0.977791, -0.209581,
+-1.002737, 9.503082, 2.725576, 1.000000, -0.671927, -0.543427, -0.820485, -0.177458,
+-1.002737, 10.154959, -0.010050, 1.000000, -0.503387, -0.554465, -0.809442, -0.193318,
+-1.002737, 8.971350, 5.457178, 1.000000, -0.844213, -0.532911, -0.837943, -0.117722,
+-1.002737, 9.503082, 2.725576, 1.000000, -0.671927, -0.543427, -0.820485, -0.177458,
+0.000000, 9.272461, 2.752070, 1.500000, -0.671927, -0.000000, -0.977791, -0.209581,
+0.000000, 9.272461, 2.752070, 1.500000, -0.671927, -0.000000, -0.977791, -0.209581,
+1.002737, 9.503082, 2.725576, 2.000000, -0.671927, 0.543427, -0.820485, -0.177458,
+1.002737, 8.971350, 5.457179, 2.000000, -0.844213, 0.532911, -0.837943, -0.117722,
+1.002737, 8.971350, 5.457179, 2.000000, -0.844213, 0.532911, -0.837943, -0.117722,
+1.002737, 8.743584, 8.108689, 2.000000, -1.016250, 0.522039, -0.852900, 0.006099,
+0.000000, 8.530107, 8.155542, 1.500000, -1.016250, 0.000000, -0.999937, 0.011225,
+0.000000, 8.530107, 8.155542, 1.500000, -1.016250, 0.000000, -0.999937, 0.011225,
+-1.002737, 8.743584, 8.108688, 1.000000, -1.016250, -0.522039, -0.852900, 0.006099,
+-1.002737, 8.971350, 5.457178, 1.000000, -0.844213, -0.532911, -0.837943, -0.117722,
+-1.002737, 9.003599, 10.604042, 1.000000, -1.184038, -0.512969, -0.841946, 0.167304,
+-1.002737, 8.743584, 8.108688, 1.000000, -1.016250, -0.522039, -0.852900, 0.006099,
+0.000000, 8.530107, 8.155542, 1.500000, -1.016250, 0.000000, -0.999937, 0.011225,
+0.000000, 8.530107, 8.155542, 1.500000, -1.016250, 0.000000, -0.999937, 0.011225,
+1.002737, 8.743584, 8.108689, 2.000000, -1.016250, 0.522039, -0.852900, 0.006099,
+1.002737, 9.003599, 10.604041, 2.000000, -1.184038, 0.512969, -0.841946, 0.167304,
+1.002737, 9.003599, 10.604041, 2.000000, -1.184038, 0.512969, -0.841946, 0.167304,
+1.002737, 9.694744, 12.910284, 2.000000, -1.349954, 0.500990, -0.803388, 0.321833,
+0.000000, 9.513226, 12.999825, 1.500000, -1.349954, 0.000000, -0.927387, 0.374104,
+0.000000, 9.513226, 12.999825, 1.500000, -1.349954, 0.000000, -0.927387, 0.374104,
+-1.002737, 9.694744, 12.910284, 1.000000, -1.349954, -0.500990, -0.803388, 0.321833,
+-1.002737, 9.003599, 10.604042, 1.000000, -1.184038, -0.512969, -0.841946, 0.167304,
+-1.002737, 10.760361, 14.994465, 1.000000, -1.516370, -0.490912, -0.740187, 0.459488,
+-1.002737, 9.694744, 12.910284, 1.000000, -1.349954, -0.500990, -0.803388, 0.321833,
+0.000000, 9.513226, 12.999825, 1.500000, -1.349954, 0.000000, -0.927387, 0.374104,
+0.000000, 9.513226, 12.999825, 1.500000, -1.349954, 0.000000, -0.927387, 0.374104,
+1.002737, 9.694744, 12.910284, 2.000000, -1.349954, 0.500990, -0.803388, 0.321833,
+1.002737, 10.760361, 14.994465, 2.000000, -1.516370, 0.490912, -0.740187, 0.459488,
+1.002737, 10.760361, 14.994465, 2.000000, -1.516370, 0.490912, -0.740187, 0.459488,
+1.002737, 12.090717, 16.772659, 2.000000, -1.679268, 0.484165, -0.653669, 0.581636,
+0.000000, 11.955647, 16.911739, 1.500000, -1.679268, 0.000000, -0.746148, 0.665780,
+0.000000, 11.955647, 16.911739, 1.500000, -1.679268, 0.000000, -0.746148, 0.665780,
+-1.002737, 12.090717, 16.772659, 1.000000, -1.679268, -0.484165, -0.653669, 0.581636,
+-1.002737, 10.760361, 14.994465, 1.000000, -1.516370, -0.490912, -0.740187, 0.459488,
+-1.002737, 13.576077, 18.160946, 1.000000, -1.834628, -0.481336, -0.535363, 0.694048,
+-1.002737, 12.090717, 16.772659, 1.000000, -1.679268, -0.484165, -0.653669, 0.581636,
+0.000000, 11.955647, 16.911739, 1.500000, -1.679268, 0.000000, -0.746148, 0.665780,
+0.000000, 11.955647, 16.911739, 1.500000, -1.679268, 0.000000, -0.746148, 0.665780,
+1.002737, 12.090717, 16.772659, 2.000000, -1.679268, 0.484165, -0.653669, 0.581636,
+1.002737, 13.576080, 18.160946, 2.000000, -1.834628, 0.481336, -0.535363, 0.694048,
+1.002737, 13.576080, 18.160946, 2.000000, -1.834628, 0.481336, -0.535363, 0.694048,
+1.002737, 15.212280, 19.181923, 2.000000, -1.988039, 0.480828, -0.389724, 0.785442,
+0.000000, 15.132900, 19.357809, 1.500000, -1.988039, 0.000001, -0.443892, 0.896080,
+0.000000, 15.132900, 19.357809, 1.500000, -1.988039, 0.000001, -0.443892, 0.896080,
+-1.002737, 15.212280, 19.181923, 1.000000, -1.988039, -0.480827, -0.389724, 0.785443,
+-1.002737, 13.576077, 18.160946, 1.000000, -1.834628, -0.481336, -0.535363, 0.694048,
+-1.002737, 16.995155, 19.858189, 1.000000, -2.145087, -0.479530, -0.225145, 0.848151,
+-1.002737, 15.212280, 19.181923, 1.000000, -1.988039, -0.480827, -0.389724, 0.785443,
+0.000000, 15.132900, 19.357809, 1.500000, -1.988039, 0.000001, -0.443892, 0.896080,
+0.000000, 15.132900, 19.357809, 1.500000, -1.988039, 0.000001, -0.443892, 0.896080,
+1.002737, 15.212280, 19.181923, 2.000000, -1.988039, 0.480828, -0.389724, 0.785442,
+1.002737, 16.995155, 19.858189, 2.000000, -2.145087, 0.479530, -0.225145, 0.848151,
+1.002737, 16.995155, 19.858189, 2.000000, -2.145087, 0.479530, -0.225145, 0.848151,
+1.002737, 18.890533, 20.158619, 2.000000, -2.305904, 0.477686, -0.044014, 0.877427,
+0.000000, 18.878441, 20.350098, 1.500000, -2.305904, 0.000000, -0.050074, 0.998746,
+0.000000, 18.878441, 20.350098, 1.500000, -2.305904, 0.000000, -0.050074, 0.998746,
+-1.002737, 18.890533, 20.158619, 1.000000, -2.305904, -0.477686, -0.044014, 0.877427,
+-1.002737, 16.995155, 19.858189, 1.000000, -2.145087, -0.479530, -0.225145, 0.848151,
+-1.002737, 20.864250, 20.052088, 1.000000, -2.470621, -0.474232, 0.150976, 0.867358,
+-1.002737, 18.890533, 20.158619, 1.000000, -2.305904, -0.477686, -0.044014, 0.877427,
+0.000000, 18.878441, 20.350098, 1.500000, -2.305904, 0.000000, -0.050074, 0.998746,
+0.000000, 18.878441, 20.350098, 1.500000, -2.305904, 0.000000, -0.050074, 0.998746,
+1.002737, 18.890533, 20.158619, 2.000000, -2.305904, 0.477686, -0.044014, 0.877427,
+1.002737, 20.864250, 20.052088, 2.000000, -2.470621, 0.474231, 0.150976, 0.867359,
+1.002737, 20.864250, 20.052088, 2.000000, -2.470621, 0.474231, 0.150976, 0.867359,
+1.002737, 22.911228, 19.457972, 2.000000, -2.646001, 0.471248, 0.342725, 0.812690,
+0.000000, 22.975082, 19.636301, 1.500000, -2.646001, 0.000000, 0.388135, 0.921603,
+0.000000, 22.975082, 19.636301, 1.500000, -2.646001, 0.000000, 0.388135, 0.921603,
+-1.002737, 22.911228, 19.457972, 1.000000, -2.646001, -0.471248, 0.342725, 0.812690,
+-1.002737, 20.864250, 20.052088, 1.000000, -2.470621, -0.474232, 0.150976, 0.867358,
+-1.002737, 25.026405, 18.295650, 1.000000, -2.838810, -0.470077, 0.507995, 0.721781,
+-1.002737, 22.911228, 19.457972, 1.000000, -2.646001, -0.471248, 0.342725, 0.812690,
+0.000000, 22.975082, 19.636301, 1.500000, -2.646001, 0.000000, 0.388135, 0.921603,
+0.000000, 22.975082, 19.636301, 1.500000, -2.646001, 0.000000, 0.388135, 0.921603,
+1.002737, 22.911228, 19.457972, 2.000000, -2.646001, 0.471248, 0.342725, 0.812690,
+1.002737, 25.026405, 18.295650, 2.000000, -2.838810, 0.470077, 0.507995, 0.721781,
+1.002737, 25.026405, 18.295650, 2.000000, -2.838810, 0.470077, 0.507995, 0.721781,
+1.002737, 26.982021, 16.592329, 2.000000, -3.038383, 0.470672, 0.656258, 0.589740,
+0.000000, 27.125668, 16.715830, 1.500000, -3.038383, 0.000001, 0.743876, 0.668318,
+0.000000, 27.125668, 16.715830, 1.500000, -3.038383, 0.000001, 0.743876, 0.668318,
+-1.002737, 26.982025, 16.592329, 1.000000, -3.038383, -0.470672, 0.656259, 0.589739,
+-1.002737, 25.026405, 18.295650, 1.000000, -2.838810, -0.470077, 0.507995, 0.721781,
+-1.002737, 28.550339, 14.375221, 1.000000, -3.234054, -0.475606, 0.784875, 0.397203,
+-1.002737, 26.982025, 16.592329, 1.000000, -3.038383, -0.470672, 0.656259, 0.589739,
+0.000000, 27.125668, 16.715830, 1.500000, -3.038383, 0.000001, 0.743876, 0.668318,
+0.000000, 27.125668, 16.715830, 1.500000, -3.038383, 0.000001, 0.743876, 0.668318,
+1.002737, 26.982021, 16.592329, 2.000000, -3.038383, 0.470672, 0.656258, 0.589740,
+1.002737, 28.550339, 14.375221, 2.000000, -3.234054, 0.475606, 0.784875, 0.397204,
+1.002737, 28.550339, 14.375221, 2.000000, -3.234054, 0.475606, 0.784875, 0.397204,
+1.002737, 29.425041, 11.768046, 2.000000, -3.421010, 0.486093, 0.865826, 0.118573,
+0.000000, 29.623409, 11.797009, 1.500000, -3.421010, 0.000000, 0.990552, 0.137137,
+0.000000, 29.623409, 11.797009, 1.500000, -3.421010, 0.000000, 0.990552, 0.137137,
+-1.002737, 29.425041, 11.768046, 1.000000, -3.421010, -0.486094, 0.865825, 0.118573,
+-1.002737, 28.550339, 14.375221, 1.000000, -3.234054, -0.475606, 0.784875, 0.397203,
+-1.002737, 29.299828, 8.894522, 1.000000, -3.594440, -0.508085, 0.850361, -0.136877,
+-1.002737, 29.425041, 11.768046, 1.000000, -3.421010, -0.486094, 0.865825, 0.118573,
+0.000000, 29.623409, 11.797009, 1.500000, -3.421010, 0.000000, 0.990552, 0.137137,
+0.000000, 29.623409, 11.797009, 1.500000, -3.421010, 0.000000, 0.990552, 0.137137,
+1.002737, 29.425041, 11.768046, 2.000000, -3.421010, 0.486093, 0.865826, 0.118573,
+1.002737, 29.299828, 8.894522, 2.000000, -3.594440, 0.508084, 0.850362, -0.136877,
+1.002737, 29.299828, 8.894522, 2.000000, -3.594440, 0.508084, 0.850362, -0.136877,
+1.002737, 28.522129, 6.172330, 2.000000, -3.741287, 0.527923, 0.793569, -0.302564,
+0.000000, 28.730427, 6.103821, 1.500000, -3.741288, 0.000000, 0.935308, -0.353834,
+0.000000, 28.730427, 6.103821, 1.500000, -3.741288, 0.000000, 0.935308, -0.353834,
+-1.002737, 28.522129, 6.172330, 1.000000, -3.741287, -0.527924, 0.793569, -0.302563,
+-1.002737, 29.299828, 8.894522, 1.000000, -3.594440, -0.508085, 0.850361, -0.136877,
+-1.002737, 27.439381, 4.019153, 1.000000, -3.848496, -0.545786, 0.725589, -0.419091,
+-1.002737, 28.522129, 6.172330, 1.000000, -3.741287, -0.527924, 0.793569, -0.302563,
+0.000000, 28.730427, 6.103821, 1.500000, -3.741288, 0.000000, 0.935308, -0.353834,
+0.000000, 28.730427, 6.103821, 1.500000, -3.741288, 0.000000, 0.935308, -0.353834,
+1.002737, 28.522129, 6.172330, 2.000000, -3.741287, 0.527923, 0.793569, -0.302564,
+1.002737, 27.439377, 4.019153, 2.000000, -3.848496, 0.545786, 0.725589, -0.419091,
+1.002737, 27.439377, 4.019153, 2.000000, -3.848496, 0.545786, 0.725589, -0.419091,
+1.002737, 26.363422, 2.436586, 2.000000, -3.922053, 0.561369, 0.675750, -0.477732,
+0.000000, 26.558514, 2.310673, 1.500000, -3.922053, 0.000001, 0.817607, -0.575776,
+0.000000, 26.558514, 2.310673, 1.500000, -3.922053, 0.000001, 0.817607, -0.575776,
+-1.002737, 26.363422, 2.436586, 1.020833, -3.882167, -0.561369, 0.675750, -0.477732,
+-1.002737, 27.439381, 4.019153, 1.000000, -3.848496, -0.545786, 0.725589, -0.419091,
+0.000000, 25.158775, 0.885566, 1.500000, -4.000000, 0.000000, 0.098978, -0.995090,
+-0.742768, 25.130249, 1.141007, 1.000000, -4.000000, -0.424007, 0.088516, -0.901323,
+-1.002737, 25.606094, 1.426226, 1.083333, -3.808398, -0.572183, 0.564519, -0.594916,
+-1.002737, 25.606094, 1.426226, 1.083333, -3.808398, -0.572183, 0.564519, -0.594916,
+-1.002737, 26.363422, 2.436586, 1.020833, -3.882167, -0.561369, 0.675750, -0.477732,
+0.000000, 26.558514, 2.310673, 1.500000, -3.922053, 0.000001, 0.817607, -0.575776,
+0.000000, 26.558514, 2.310673, 1.500000, -3.922053, 0.000001, 0.817607, -0.575776,
+1.002737, 26.363422, 2.436586, 2.000000, -3.922053, 0.561369, 0.675750, -0.477732,
+1.002737, 25.606094, 1.426226, 2.000000, -3.967943, 0.572183, 0.564519, -0.594916,
+1.002737, 25.606094, 1.426226, 2.000000, -3.967943, 0.572183, 0.564519, -0.594916,
+0.742768, 25.130249, 1.141007, 2.000000, -4.000000, 0.424007, 0.088516, -0.901323,
+0.000000, 25.158775, 0.885566, 1.500000, -4.000000, 0.000000, 0.098978, -0.995090,
+1.002737, 4.921762, -29.530731, 3.000000, 0.966243, 0.582240, 0.811733, -0.045667,
+1.002737, 4.997122, -28.191074, 3.000000, 0.922656, 0.582175, 0.810004, -0.070467,
+1.336982, 4.293425, -28.133030, 2.500000, 0.922656, 0.999926, -0.012083, 0.001603,
+1.336982, 4.293425, -28.133030, 2.500000, 0.922656, 0.999926, -0.012083, 0.001603,
+1.002737, 3.589725, -28.074989, 2.000000, 0.922656, 0.569426, -0.818637, 0.074745,
+1.002737, 3.502487, -29.476650, 2.000000, 0.966243, 0.570521, -0.819696, 0.051023,
+1.002737, 3.807196, -26.139326, 2.000000, 0.859409, 0.566467, -0.814178, 0.127399,
+1.002737, 3.589725, -28.074989, 2.000000, 0.922656, 0.569426, -0.818637, 0.074745,
+1.336982, 4.293425, -28.133030, 2.500000, 0.922656, 0.999926, -0.012083, 0.001603,
+1.336982, 4.293425, -28.133030, 2.500000, 0.922656, 0.999926, -0.012083, 0.001603,
+1.002737, 4.997122, -28.191074, 3.000000, 0.922656, 0.582175, 0.810004, -0.070467,
+1.002737, 5.199909, -26.333269, 3.000000, 0.859409, 0.582690, 0.803052, -0.124820,
+1.002737, 5.199909, -26.333269, 3.000000, 0.859409, 0.582690, 0.803052, -0.124820,
+1.002737, 5.640600, -24.050657, 3.000000, 0.775297, 0.583127, 0.787897, -0.197941,
+1.336982, 4.951294, -23.914915, 2.500000, 0.775297, 0.999837, -0.017439, 0.004781,
+1.336982, 4.951294, -23.914915, 2.500000, 0.775297, 0.999837, -0.017439, 0.004781,
+1.002737, 4.261988, -23.779171, 2.000000, 0.775297, 0.564634, -0.800896, 0.199384,
+1.002737, 3.807196, -26.139326, 2.000000, 0.859409, 0.566467, -0.814178, 0.127399,
+1.002737, 5.061195, -21.104025, 2.000000, 0.669113, 0.566458, -0.779905, 0.266220,
+1.002737, 4.261988, -23.779171, 2.000000, 0.775297, 0.564634, -0.800896, 0.199384,
+1.336982, 4.951294, -23.914915, 2.500000, 0.775297, 0.999837, -0.017439, 0.004781,
+1.336982, 4.951294, -23.914915, 2.500000, 0.775297, 0.999837, -0.017439, 0.004781,
+1.002737, 5.640600, -24.050657, 3.000000, 0.775297, 0.583127, 0.787897, -0.197941,
+1.002737, 6.429670, -21.436577, 3.000000, 0.669113, 0.579786, 0.770207, -0.265761,
+1.002737, 6.429670, -21.436577, 3.000000, 0.669113, 0.579786, 0.770207, -0.265761,
+1.002737, 7.484703, -18.704170, 3.000000, 0.547971, 0.576888, 0.751119, -0.320970,
+1.336982, 6.802818, -18.519814, 2.500000, 0.547971, 0.999946, -0.009100, 0.005070,
+1.336982, 6.802818, -18.519814, 2.500000, 0.547971, 0.999946, -0.009100, 0.005070,
+1.002737, 6.120935, -18.335461, 2.000000, 0.547971, 0.566613, -0.758528, 0.321845,
+1.002737, 5.061195, -21.104025, 2.000000, 0.669113, 0.566458, -0.779905, 0.266220,
+1.002737, 7.357327, -15.695049, 2.000000, 0.418984, 0.568348, -0.740553, 0.358555,
+1.002737, 6.120935, -18.335461, 2.000000, 0.547971, 0.566613, -0.758528, 0.321845,
+1.336982, 6.802818, -18.519814, 2.500000, 0.547971, 0.999946, -0.009100, 0.005070,
+1.336982, 6.802818, -18.519814, 2.500000, 0.547971, 0.999946, -0.009100, 0.005070,
+1.002737, 7.484703, -18.704170, 3.000000, 0.547971, 0.576888, 0.751119, -0.320970,
+1.002737, 8.723274, -16.066572, 3.000000, 0.418984, 0.570576, 0.739144, -0.357922,
+1.002737, 8.723274, -16.066572, 3.000000, 0.418984, 0.570576, 0.739144, -0.357922,
+1.002737, 10.001389, -13.505806, 3.000000, 0.282904, 0.565597, 0.742254, -0.359389,
+1.336982, 9.314625, -13.332256, 2.500000, 0.282904, 0.999983, 0.005126, -0.002905,
+1.336982, 9.314625, -13.332256, 2.500000, 0.282904, 0.999983, 0.005126, -0.002905,
+1.002737, 8.627859, -13.158705, 2.000000, 0.282904, 0.571429, -0.737705, 0.359528,
+1.002737, 7.357327, -15.695049, 2.000000, 0.418984, 0.568348, -0.740553, 0.358555,
+1.002737, 9.790028, -10.702334, 2.000000, 0.140482, 0.576977, -0.747533, 0.329077,
+1.002737, 8.627859, -13.158705, 2.000000, 0.282904, 0.571429, -0.737705, 0.359528,
+1.336982, 9.314625, -13.332256, 2.500000, 0.282904, 0.999983, 0.005126, -0.002905,
+1.336982, 9.314625, -13.332256, 2.500000, 0.282904, 0.999983, 0.005126, -0.002905,
+1.002737, 10.001389, -13.505806, 3.000000, 0.282904, 0.565597, 0.742254, -0.359389,
+1.002737, 11.175043, -11.003893, 3.000000, 0.140482, 0.562569, 0.757951, -0.330192,
+1.002737, 11.175043, -11.003893, 3.000000, 0.140482, 0.562569, 0.757951, -0.330192,
+1.002127, 12.054029, -8.797724, 2.958333, -0.009381, 0.560195, 0.787255, -0.257702,
+1.336373, 11.355911, -8.670841, 2.500000, 0.010562, 0.999602, 0.026239, -0.010414,
+1.336373, 11.355911, -8.670841, 2.500000, 0.010562, 0.999602, 0.026239, -0.010414,
+1.002127, 10.657795, -8.543959, 2.000000, 0.010562, 0.588607, -0.767452, 0.254084,
+1.002737, 9.790028, -10.702334, 2.000000, 0.140482, 0.576977, -0.747533, 0.329077,
+1.333325, 11.818588, -5.617008, 2.500000, -0.170915, 0.999852, 0.017082, 0.001868,
+0.999079, 11.114811, -5.517140, 2.000000, -0.170915, 0.582792, -0.812607, -0.004817,
+1.000299, 11.045135, -6.901599, 2.000000, -0.088013, 0.591516, -0.797171, 0.120947,
+1.000299, 11.045135, -6.901599, 2.000000, -0.088013, 0.591516, -0.797171, 0.120947,
+1.002127, 10.657795, -8.543959, 2.000000, 0.010562, 0.588607, -0.767452, 0.254084,
+1.336373, 11.355911, -8.670841, 2.500000, 0.010562, 0.999602, 0.026239, -0.010414,
+1.336373, 11.355911, -8.670841, 2.500000, 0.010562, 0.999602, 0.026239, -0.010414,
+1.002127, 12.054029, -8.797724, 2.958333, -0.009381, 0.560195, 0.787255, -0.257702,
+1.000299, 12.448139, -7.124194, 2.833333, -0.167786, 0.564659, 0.816023, -0.123558,
+1.000299, 12.448139, -7.124194, 2.833333, -0.167786, 0.564659, 0.816023, -0.123558,
+0.999079, 12.522362, -5.716876, 3.000000, -0.170915, 0.565733, 0.824587, 0.001687,
+1.333325, 11.818588, -5.617008, 2.500000, -0.170915, 0.999852, 0.017082, 0.001868,
+1.002737, 10.154957, -0.010050, 2.000000, -0.503387, 0.554487, -0.809403, -0.193422,
+1.002127, 10.729588, -2.409474, 2.000000, -0.336720, 0.568931, -0.804350, -0.171283,
+1.336373, 11.435898, -2.488622, 2.500000, -0.336720, 0.999684, 0.024018, 0.007427,
+1.336373, 11.435898, -2.488622, 2.500000, -0.336720, 0.999684, 0.024018, 0.007427,
+1.002127, 12.142200, -2.567771, 3.000000, -0.336720, 0.545588, 0.819894, 0.173516,
+1.002737, 11.560024, -0.158328, 3.000000, -0.503387, 0.548192, 0.812432, 0.198592,
+1.002737, 11.560024, -0.158328, 3.000000, -0.503387, 0.548192, 0.812432, 0.198592,
+1.002737, 10.886791, 2.566613, 3.000000, -0.671927, 0.549613, 0.814083, 0.187601,
+1.336982, 10.194935, 2.646095, 2.500000, -0.671927, 0.999975, -0.006839, -0.001674,
+1.336982, 10.194935, 2.646095, 2.500000, -0.671927, 0.999975, -0.006839, -0.001674,
+1.002737, 9.503082, 2.725576, 2.000000, -0.671927, 0.543427, -0.820485, -0.177458,
+1.002737, 10.154957, -0.010050, 2.000000, -0.503387, 0.554487, -0.809403, -0.193422,
+1.002737, 8.971350, 5.457179, 2.000000, -0.844213, 0.532911, -0.837943, -0.117722,
+1.002737, 9.503082, 2.725576, 2.000000, -0.671927, 0.543427, -0.820485, -0.177458,
+1.336982, 10.194935, 2.646095, 2.500000, -0.671927, 0.999975, -0.006839, -0.001674,
+1.336982, 10.194935, 2.646095, 2.500000, -0.671927, 0.999975, -0.006839, -0.001674,
+1.002737, 10.886791, 2.566613, 3.000000, -0.671927, 0.549613, 0.814083, 0.187601,
+1.002737, 10.314148, 5.254678, 3.000000, -0.844213, 0.550065, 0.824042, 0.135587,
+1.002737, 10.314148, 5.254678, 3.000000, -0.844213, 0.550065, 0.824042, 0.135587,
+1.002737, 10.024445, 7.827566, 3.000000, -1.016250, 0.552727, 0.833125, 0.019881,
+1.336982, 9.384014, 7.968127, 2.500000, -1.016250, 0.999385, -0.034959, -0.002597,
+1.336982, 9.384014, 7.968127, 2.500000, -1.016250, 0.999385, -0.034959, -0.002597,
+1.002737, 8.743584, 8.108689, 2.000000, -1.016250, 0.522039, -0.852900, 0.006099,
+1.002737, 8.971350, 5.457179, 2.000000, -0.844213, 0.532911, -0.837943, -0.117722,
+1.002737, 9.003599, 10.604041, 2.000000, -1.184038, 0.512969, -0.841946, 0.167304,
+1.002737, 8.743584, 8.108689, 2.000000, -1.016250, 0.522039, -0.852900, 0.006099,
+1.336982, 9.384014, 7.968127, 2.500000, -1.016250, 0.999385, -0.034959, -0.002597,
+1.336982, 9.384014, 7.968127, 2.500000, -1.016250, 0.999385, -0.034959, -0.002597,
+1.002737, 10.024445, 7.827566, 3.000000, -1.016250, 0.552727, 0.833125, 0.019881,
+1.002737, 10.200031, 10.206976, 3.000000, -1.184038, 0.545898, 0.826469, -0.137636,
+1.002737, 10.200031, 10.206976, 3.000000, -1.184038, 0.545898, 0.826469, -0.137636,
+1.002737, 10.783842, 12.373039, 3.000000, -1.349954, 0.535040, 0.792292, -0.293267,
+1.336982, 10.239292, 12.641662, 2.500000, -1.349954, 0.999218, -0.036495, 0.015192,
+1.336982, 10.239292, 12.641662, 2.500000, -1.349954, 0.999218, -0.036495, 0.015192,
+1.002737, 9.694744, 12.910284, 2.000000, -1.349954, 0.500990, -0.803388, 0.321833,
+1.002737, 9.003599, 10.604041, 2.000000, -1.184038, 0.512969, -0.841946, 0.167304,
+1.002737, 10.760361, 14.994465, 2.000000, -1.516370, 0.490912, -0.740187, 0.459488,
+1.002737, 9.694744, 12.910284, 2.000000, -1.349954, 0.500990, -0.803388, 0.321833,
+1.336982, 10.239292, 12.641662, 2.500000, -1.349954, 0.999218, -0.036495, 0.015192,
+1.336982, 10.239292, 12.641662, 2.500000, -1.349954, 0.999218, -0.036495, 0.015192,
+1.002737, 10.783842, 12.373039, 3.000000, -1.349954, 0.535040, 0.792292, -0.293267,
+1.002737, 11.718807, 14.305887, 3.000000, -1.516370, 0.524951, 0.731928, -0.434405,
+1.002737, 11.718807, 14.305887, 3.000000, -1.516370, 0.524951, 0.731928, -0.434405,
+1.002737, 12.901150, 15.938179, 3.000000, -1.679268, 0.520177, 0.645820, -0.558867,
+1.336982, 12.495934, 16.355419, 2.500000, -1.679268, 0.999037, -0.033131, 0.028753,
+1.336982, 12.495934, 16.355419, 2.500000, -1.679268, 0.999037, -0.033131, 0.028753,
+1.002737, 12.090717, 16.772659, 2.000000, -1.679268, 0.484165, -0.653669, 0.581636,
+1.002737, 10.760361, 14.994465, 2.000000, -1.516370, 0.490912, -0.740187, 0.459488,
+1.002737, 13.576080, 18.160946, 2.000000, -1.834628, 0.481336, -0.535363, 0.694048,
+1.002737, 12.090717, 16.772659, 2.000000, -1.679268, 0.484165, -0.653669, 0.581636,
+1.336982, 12.495934, 16.355419, 2.500000, -1.679268, 0.999037, -0.033131, 0.028753,
+1.336982, 12.495934, 16.355419, 2.500000, -1.679268, 0.999037, -0.033131, 0.028753,
+1.002737, 12.901150, 15.938179, 3.000000, -1.679268, 0.520177, 0.645820, -0.558867,
+1.002737, 14.227100, 17.202572, 3.000000, -1.834628, 0.519663, 0.527798, -0.671848,
+1.002737, 14.227100, 17.202572, 3.000000, -1.834628, 0.519663, 0.527798, -0.671848,
+1.002737, 15.688553, 18.126600, 3.000000, -1.988039, 0.519424, 0.384311, -0.763219,
+1.336982, 15.450417, 18.654261, 2.500000, -1.988039, 0.998886, -0.021467, 0.042031,
+1.336982, 15.450417, 18.654261, 2.500000, -1.988039, 0.998886, -0.021467, 0.042031,
+1.002737, 15.212280, 19.181923, 2.000000, -1.988039, 0.480828, -0.389724, 0.785442,
+1.002737, 13.576080, 18.160946, 2.000000, -1.834628, 0.481336, -0.535363, 0.694048,
+1.002737, 16.995155, 19.858189, 2.000000, -2.145087, 0.479530, -0.225145, 0.848151,
+1.002737, 15.212280, 19.181923, 2.000000, -1.988039, 0.480828, -0.389724, 0.785442,
+1.336982, 15.450417, 18.654261, 2.500000, -1.988039, 0.998886, -0.021467, 0.042031,
+1.336982, 15.450417, 18.654261, 2.500000, -1.988039, 0.998886, -0.021467, 0.042031,
+1.002737, 15.688553, 18.126600, 3.000000, -1.988039, 0.519424, 0.384311, -0.763219,
+1.002737, 17.277420, 18.737804, 3.000000, -2.145087, 0.519855, 0.222506, -0.824768,
+1.002737, 17.277420, 18.737804, 3.000000, -2.145087, 0.519855, 0.222506, -0.824768,
+1.002737, 18.963112, 19.009758, 3.000000, -2.305904, 0.519106, 0.044200, -0.853567,
+1.336982, 18.926823, 19.584188, 2.500000, -2.305904, 0.998704, -0.001978, 0.050856,
+1.336982, 18.926823, 19.584188, 2.500000, -2.305904, 0.998704, -0.001978, 0.050856,
+1.002737, 18.890533, 20.158619, 2.000000, -2.305904, 0.477686, -0.044014, 0.877427,
+1.002737, 16.995155, 19.858189, 2.000000, -2.145087, 0.479530, -0.225145, 0.848151,
+1.002737, 20.864250, 20.052088, 2.000000, -2.470621, 0.474231, 0.150976, 0.867359,
+1.002737, 18.890533, 20.158619, 2.000000, -2.305904, 0.477686, -0.044014, 0.877427,
+1.336982, 18.926823, 19.584188, 2.500000, -2.305904, 0.998704, -0.001978, 0.050856,
+1.336982, 18.926823, 19.584188, 2.500000, -2.305904, 0.998704, -0.001978, 0.050856,
+1.002737, 18.963112, 19.009758, 3.000000, -2.305904, 0.519106, 0.044200, -0.853567,
+1.002737, 20.715042, 18.916035, 3.000000, -2.470621, 0.518180, -0.147145, -0.842519,
+1.002737, 20.715042, 18.916035, 3.000000, -2.470621, 0.518180, -0.147145, -0.842519,
+1.002737, 22.528091, 18.387989, 3.000000, -2.646001, 0.514483, -0.334572, -0.789537,
+1.336982, 22.719658, 18.922981, 2.500000, -2.646001, 0.998523, 0.022591, 0.049420,
+1.336982, 22.719658, 18.922981, 2.500000, -2.646001, 0.998523, 0.022591, 0.049420,
+1.002737, 22.911228, 19.457972, 2.000000, -2.646001, 0.471248, 0.342725, 0.812690,
+1.002737, 20.864250, 20.052088, 2.000000, -2.470621, 0.474231, 0.150976, 0.867359,
+1.002737, 25.026405, 18.295650, 2.000000, -2.838810, 0.470077, 0.507995, 0.721781,
+1.002737, 22.911228, 19.457972, 2.000000, -2.646001, 0.471248, 0.342725, 0.812690,
+1.336982, 22.719658, 18.922981, 2.500000, -2.646001, 0.998523, 0.022591, 0.049420,
+1.336982, 22.719658, 18.922981, 2.500000, -2.646001, 0.998523, 0.022591, 0.049420,
+1.002737, 22.528091, 18.387989, 3.000000, -2.646001, 0.514483, -0.334572, -0.789537,
+1.002737, 24.397125, 17.356983, 3.000000, -2.838810, 0.512162, -0.495528, -0.701529,
+1.002737, 24.397125, 17.356983, 3.000000, -2.838810, 0.512162, -0.495528, -0.701529,
+1.002737, 26.120163, 15.851318, 3.000000, -3.038383, 0.515999, -0.637877, -0.571716,
+1.336982, 26.551086, 16.221825, 2.500000, -3.038383, 0.998387, 0.041476, 0.038776,
+1.336982, 26.551086, 16.221825, 2.500000, -3.038383, 0.998387, 0.041476, 0.038776,
+1.002737, 26.982021, 16.592329, 2.000000, -3.038383, 0.470672, 0.656258, 0.589740,
+1.002737, 25.026405, 18.295650, 2.000000, -2.838810, 0.470077, 0.507995, 0.721781,
+1.002737, 28.550339, 14.375221, 2.000000, -3.234054, 0.475606, 0.784875, 0.397204,
+1.002737, 26.982021, 16.592329, 2.000000, -3.038383, 0.470672, 0.656258, 0.589740,
+1.336982, 26.551086, 16.221825, 2.500000, -3.038383, 0.998387, 0.041476, 0.038776,
+1.336982, 26.551086, 16.221825, 2.500000, -3.038383, 0.998387, 0.041476, 0.038776,
+1.002737, 26.120163, 15.851318, 3.000000, -3.038383, 0.515999, -0.637877, -0.571716,
+1.002737, 27.495193, 13.899298, 3.000000, -3.234054, 0.529173, -0.759785, -0.377761,
+1.002737, 27.495193, 13.899298, 3.000000, -3.234054, 0.529173, -0.759785, -0.377761,
+1.002737, 28.234837, 11.594270, 3.000000, -3.421010, 0.549862, -0.829858, -0.094800,
+1.336982, 28.829941, 11.681159, 2.500000, -3.421010, 0.997287, 0.072725, 0.011376,
+1.336982, 28.829941, 11.681159, 2.500000, -3.421010, 0.997287, 0.072725, 0.011376,
+1.002737, 29.425041, 11.768046, 2.000000, -3.421010, 0.486093, 0.865826, 0.118573,
+1.002737, 28.550339, 14.375221, 2.000000, -3.234054, 0.475606, 0.784875, 0.397204,
+1.002737, 29.299828, 8.894522, 2.000000, -3.594440, 0.508084, 0.850362, -0.136877,
+1.002737, 29.425041, 11.768046, 2.000000, -3.421010, 0.486093, 0.865826, 0.118573,
+1.336982, 28.829941, 11.681159, 2.500000, -3.421010, 0.997287, 0.072725, 0.011376,
+1.336982, 28.829941, 11.681159, 2.500000, -3.421010, 0.997287, 0.072725, 0.011376,
+1.002737, 28.234837, 11.594270, 3.000000, -3.421010, 0.549862, -0.829858, -0.094800,
+1.002737, 28.051701, 9.029581, 3.000000, -3.594440, 0.552395, -0.818570, 0.157487,
+1.002737, 28.051701, 9.029581, 3.000000, -3.594440, 0.552395, -0.818570, 0.157487,
+1.002737, 27.272324, 6.583387, 3.000000, -3.741287, 0.563171, -0.762895, 0.317537,
+1.336982, 27.897228, 6.377859, 2.500000, -3.741288, 0.999306, 0.035287, -0.011950,
+1.336982, 27.897228, 6.377859, 2.500000, -3.741288, 0.999306, 0.035287, -0.011950,
+1.002737, 28.522129, 6.172330, 2.000000, -3.741287, 0.527923, 0.793569, -0.302564,
+1.002737, 29.299828, 8.894522, 2.000000, -3.594440, 0.508084, 0.850362, -0.136877,
+1.002737, 27.439377, 4.019153, 2.000000, -3.848496, 0.545786, 0.725589, -0.419091,
+1.002737, 28.522129, 6.172330, 2.000000, -3.741287, 0.527923, 0.793569, -0.302564,
+1.336982, 27.897228, 6.377859, 2.500000, -3.741288, 0.999306, 0.035287, -0.011950,
+1.336982, 27.897228, 6.377859, 2.500000, -3.741288, 0.999306, 0.035287, -0.011950,
+1.002737, 27.272324, 6.583387, 3.000000, -3.741287, 0.563171, -0.762895, 0.317537,
+1.002737, 26.223228, 4.633848, 3.000000, -3.848496, 0.571231, -0.699649, 0.429169,
+1.002737, 26.223228, 4.633848, 3.000000, -3.848496, 0.571231, -0.699649, 0.429169,
+1.002737, 25.192875, 3.192066, 3.000000, -3.922053, 0.573805, -0.657830, 0.487860,
+1.336982, 25.778152, 2.814326, 2.500000, -3.922053, 0.999924, 0.011227, -0.005182,
+1.336982, 25.778152, 2.814326, 2.500000, -3.922053, 0.999924, 0.011227, -0.005182,
+1.002737, 26.363422, 2.436586, 2.000000, -3.922053, 0.561369, 0.675750, -0.477732,
+1.002737, 27.439377, 4.019153, 2.000000, -3.848496, 0.545786, 0.725589, -0.419091,
+1.002737, 24.600067, 1.327282, 2.500000, -4.000000, 0.595697, -0.491752, -0.635079,
+0.742768, 25.130249, 1.141007, 2.000000, -4.000000, 0.424007, 0.088516, -0.901323,
+1.002737, 25.606094, 1.426226, 2.000000, -3.967943, 0.572183, 0.564519, -0.594916,
+1.002737, 25.606094, 1.426226, 2.000000, -3.967943, 0.572183, 0.564519, -0.594916,
+1.002737, 26.363422, 2.436586, 2.000000, -3.922053, 0.561369, 0.675750, -0.477732,
+1.336982, 25.778152, 2.814326, 2.500000, -3.922053, 0.999924, 0.011227, -0.005182,
+1.336982, 25.778152, 2.814326, 2.500000, -3.922053, 0.999924, 0.011227, -0.005182,
+1.002737, 25.192875, 3.192066, 3.000000, -3.922053, 0.573805, -0.657830, 0.487860,
+1.002737, 24.469711, 2.269146, 3.000000, -3.967943, 0.583534, -0.710408, 0.393458,
+1.002737, 24.469711, 2.269146, 3.000000, -3.967943, 0.583534, -0.710408, 0.393458,
+0.742768, 24.296909, 1.783397, 3.000000, -4.000000, 0.428917, -0.894621, -0.125234,
+1.002737, 24.600067, 1.327282, 2.500000, -4.000000, 0.595697, -0.491752, -0.635079,
+-1.002737, 4.921762, -29.530731, 4.000000, 0.966243, -0.582241, 0.811733, -0.045666,
+-1.002737, 4.997122, -28.191074, 4.000000, 0.932486, -0.582174, 0.810005, -0.070467,
+0.000000, 5.231688, -28.210423, 3.500000, 0.922656, 0.000000, 0.996270, -0.086288,
+0.000000, 5.231688, -28.210423, 3.500000, 0.922656, 0.000000, 0.996270, -0.086288,
+1.002737, 4.997122, -28.191074, 3.000000, 0.922656, 0.582175, 0.810004, -0.070467,
+1.002737, 4.921762, -29.530731, 3.000000, 0.966243, 0.582240, 0.811733, -0.045667,
+1.002737, 5.199909, -26.333269, 3.000000, 0.859409, 0.582690, 0.803052, -0.124820,
+1.002737, 4.997122, -28.191074, 3.000000, 0.922656, 0.582175, 0.810004, -0.070467,
+0.000000, 5.231688, -28.210423, 3.500000, 0.922656, 0.000000, 0.996270, -0.086288,
+0.000000, 5.231688, -28.210423, 3.500000, 0.922656, 0.000000, 0.996270, -0.086288,
+-1.002737, 4.997122, -28.191074, 4.000000, 0.932486, -0.582174, 0.810005, -0.070467,
+-1.002737, 5.199909, -26.333269, 4.000000, 0.859409, -0.582690, 0.803052, -0.124820,
+-1.002737, 5.199909, -26.333269, 4.000000, 0.859409, -0.582690, 0.803052, -0.124820,
+-1.002737, 5.640600, -24.050657, 4.000000, 0.786333, -0.583127, 0.787897, -0.197941,
+0.000000, 5.870369, -24.095905, 3.500000, 0.775297, 0.000000, 0.969755, -0.244081,
+0.000000, 5.870369, -24.095905, 3.500000, 0.775297, 0.000000, 0.969755, -0.244081,
+1.002737, 5.640600, -24.050657, 3.000000, 0.775297, 0.583127, 0.787897, -0.197941,
+1.002737, 5.199909, -26.333269, 3.000000, 0.859409, 0.582690, 0.803052, -0.124820,
+1.002737, 6.429670, -21.436577, 3.000000, 0.669113, 0.579786, 0.770207, -0.265761,
+1.002737, 5.640600, -24.050657, 3.000000, 0.775297, 0.583127, 0.787897, -0.197941,
+0.000000, 5.870369, -24.095905, 3.500000, 0.775297, 0.000000, 0.969755, -0.244081,
+0.000000, 5.870369, -24.095905, 3.500000, 0.775297, 0.000000, 0.969755, -0.244081,
+-1.002737, 5.640600, -24.050657, 4.000000, 0.786333, -0.583127, 0.787897, -0.197941,
+-1.002737, 6.429670, -21.436577, 4.000000, 0.669113, -0.579786, 0.770207, -0.265761,
+-1.002737, 6.429670, -21.436577, 4.000000, 0.669113, -0.579786, 0.770207, -0.265761,
+-1.002737, 7.484703, -18.704168, 4.000000, 0.551894, -0.576888, 0.751118, -0.320970,
+0.000000, 7.711994, -18.765621, 3.500000, 0.547971, -0.000000, 0.919277, -0.393611,
+0.000000, 7.711994, -18.765621, 3.500000, 0.547971, -0.000000, 0.919277, -0.393611,
+1.002737, 7.484703, -18.704170, 3.000000, 0.547971, 0.576888, 0.751119, -0.320970,
+1.002737, 6.429670, -21.436577, 3.000000, 0.669113, 0.579786, 0.770207, -0.265761,
+1.002737, 8.723274, -16.066572, 3.000000, 0.418984, 0.570576, 0.739144, -0.357922,
+1.002737, 7.484703, -18.704170, 3.000000, 0.547971, 0.576888, 0.751119, -0.320970,
+0.000000, 7.711994, -18.765621, 3.500000, 0.547971, -0.000000, 0.919277, -0.393611,
+0.000000, 7.711994, -18.765621, 3.500000, 0.547971, -0.000000, 0.919277, -0.393611,
+-1.002737, 7.484703, -18.704168, 4.000000, 0.551894, -0.576888, 0.751118, -0.320970,
+-1.002737, 8.723274, -16.066572, 4.000000, 0.418984, -0.570577, 0.739144, -0.357922,
+-1.002737, 8.723274, -16.066572, 4.000000, 0.418984, -0.570577, 0.739144, -0.357922,
+-1.002737, 10.001389, -13.505806, 4.000000, 0.286075, -0.565597, 0.742253, -0.359389,
+0.000000, 10.230309, -13.563657, 3.500000, 0.282904, -0.000000, 0.900257, -0.435359,
+0.000000, 10.230309, -13.563657, 3.500000, 0.282904, -0.000000, 0.900257, -0.435359,
+1.002737, 10.001389, -13.505806, 3.000000, 0.282904, 0.565597, 0.742254, -0.359389,
+1.002737, 8.723274, -16.066572, 3.000000, 0.418984, 0.570576, 0.739144, -0.357922,
+1.002737, 11.175043, -11.003893, 3.000000, 0.140482, 0.562569, 0.757951, -0.330192,
+1.002737, 10.001389, -13.505806, 3.000000, 0.282904, 0.565597, 0.742254, -0.359389,
+0.000000, 10.230309, -13.563657, 3.500000, 0.282904, -0.000000, 0.900257, -0.435359,
+0.000000, 10.230309, -13.563657, 3.500000, 0.282904, -0.000000, 0.900257, -0.435359,
+-1.002737, 10.001389, -13.505806, 4.000000, 0.286075, -0.565597, 0.742253, -0.359389,
+-1.002737, 11.175043, -11.003893, 4.000000, 0.140482, -0.562513, 0.757929, -0.330337,
+-1.002737, 11.175043, -11.003893, 4.000000, 0.140482, -0.562513, 0.757929, -0.330337,
+-1.003346, 12.054029, -8.797724, 4.000000, -0.005111, -0.560047, 0.787144, -0.258362,
+-0.000610, 12.286734, -8.840019, 3.333333, -0.069211, 0.000044, 0.950614, -0.310377,
+-0.000610, 12.286734, -8.840019, 3.333333, -0.069211, 0.000044, 0.950614, -0.310377,
+1.002127, 12.054029, -8.797724, 2.958333, -0.009381, 0.560195, 0.787255, -0.257702,
+1.002737, 11.175043, -11.003893, 3.000000, 0.140482, 0.562569, 0.757951, -0.330192,
+1.000299, 12.448139, -7.124194, 2.833333, -0.167786, 0.564659, 0.816023, -0.123558,
+1.002127, 12.054029, -8.797724, 2.958333, -0.009381, 0.560195, 0.787255, -0.257702,
+-0.000610, 12.286734, -8.840019, 3.333333, -0.069211, 0.000044, 0.950614, -0.310377,
+-0.000610, 12.286734, -8.840019, 3.333333, -0.069211, 0.000044, 0.950614, -0.310377,
+-1.003346, 12.054029, -8.797724, 4.000000, -0.005111, -0.560047, 0.787144, -0.258362,
+-1.005175, 12.448139, -7.124194, 2.666667, -0.726194, -0.564732, 0.815815, -0.124590,
+-1.005175, 12.448139, -7.124194, 2.666667, -0.726194, -0.564732, 0.815815, -0.124590,
+-1.006394, 12.522362, -5.716876, 1.333333, -1.447277, -0.566040, 0.824377, 0.001632,
+-0.003657, 12.756954, -5.750165, 2.166667, -0.809096, -0.000126, 1.000000, 0.000870,
+-0.003657, 12.756954, -5.750165, 2.166667, -0.809096, -0.000126, 1.000000, 0.000870,
+0.999079, 12.522362, -5.716876, 3.000000, -0.170915, 0.565733, 0.824587, 0.001687,
+1.000299, 12.448139, -7.124194, 2.833333, -0.167786, 0.564659, 0.816023, -0.123558,
+1.002737, 11.560024, -0.158328, 3.000000, -0.503387, 0.548192, 0.812432, 0.198592,
+1.002127, 12.142200, -2.567771, 3.000000, -0.336720, 0.545588, 0.819894, 0.173516,
+-0.000610, 12.377636, -2.594154, 3.500000, -0.336720, 0.000041, 0.978486, 0.206311,
+-0.000610, 12.377636, -2.594154, 3.500000, -0.336720, 0.000041, 0.978486, 0.206311,
+-1.003346, 12.142200, -2.567771, 4.000000, -0.336720, -0.545383, 0.819886, 0.174196,
+-1.002737, 11.560024, -0.158328, 4.000000, -0.503387, -0.548128, 0.812439, 0.198744,
+-1.002737, 11.560024, -0.158328, 4.000000, -0.503387, -0.548128, 0.812439, 0.198744,
+-1.002737, 10.886791, 2.566613, 4.000000, -0.670054, -0.549613, 0.814083, 0.187601,
+0.000000, 11.117409, 2.540119, 3.500000, -0.671927, 0.000000, 0.974103, 0.226104,
+0.000000, 11.117409, 2.540119, 3.500000, -0.671927, 0.000000, 0.974103, 0.226104,
+1.002737, 10.886791, 2.566613, 3.000000, -0.671927, 0.549613, 0.814083, 0.187601,
+1.002737, 11.560024, -0.158328, 3.000000, -0.503387, 0.548192, 0.812432, 0.198592,
+1.002737, 10.314148, 5.254678, 3.000000, -0.844213, 0.550065, 0.824042, 0.135587,
+1.002737, 10.886791, 2.566613, 3.000000, -0.671927, 0.549613, 0.814083, 0.187601,
+0.000000, 11.117409, 2.540119, 3.500000, -0.671927, 0.000000, 0.974103, 0.226104,
+0.000000, 11.117409, 2.540119, 3.500000, -0.671927, 0.000000, 0.974103, 0.226104,
+-1.002737, 10.886791, 2.566613, 4.000000, -0.670054, -0.549613, 0.814083, 0.187601,
+-1.002737, 10.314148, 5.254678, 4.000000, -0.844213, -0.550065, 0.824042, 0.135588,
+-1.002737, 10.314148, 5.254678, 4.000000, -0.844213, -0.550065, 0.824042, 0.135588,
+-1.002737, 10.024443, 7.827566, 4.000000, -1.018373, -0.552727, 0.833125, 0.019881,
+0.000000, 10.237921, 7.780712, 3.500000, -1.016250, -0.000000, 0.999593, 0.028523,
+0.000000, 10.237921, 7.780712, 3.500000, -1.016250, -0.000000, 0.999593, 0.028523,
+1.002737, 10.024445, 7.827566, 3.000000, -1.016250, 0.552727, 0.833125, 0.019881,
+1.002737, 10.314148, 5.254678, 3.000000, -0.844213, 0.550065, 0.824042, 0.135587,
+1.002737, 10.200031, 10.206976, 3.000000, -1.184038, 0.545898, 0.826469, -0.137636,
+1.002737, 10.024445, 7.827566, 3.000000, -1.016250, 0.552727, 0.833125, 0.019881,
+0.000000, 10.237921, 7.780712, 3.500000, -1.016250, -0.000000, 0.999593, 0.028523,
+0.000000, 10.237921, 7.780712, 3.500000, -1.016250, -0.000000, 0.999593, 0.028523,
+-1.002737, 10.024443, 7.827566, 4.000000, -1.018373, -0.552727, 0.833125, 0.019881,
+-1.002737, 10.200031, 10.206976, 4.000000, -1.184038, -0.545898, 0.826469, -0.137636,
+-1.002737, 10.200031, 10.206976, 4.000000, -1.184038, -0.545898, 0.826469, -0.137636,
+-1.002737, 10.783842, 12.373039, 4.000000, -1.349704, -0.535040, 0.792292, -0.293266,
+0.000000, 10.965359, 12.283498, 3.500000, -1.349954, -0.000000, 0.938935, -0.344095,
+0.000000, 10.965359, 12.283498, 3.500000, -1.349954, -0.000000, 0.938935, -0.344095,
+1.002737, 10.783842, 12.373039, 3.000000, -1.349954, 0.535040, 0.792292, -0.293267,
+1.002737, 10.200031, 10.206976, 3.000000, -1.184038, 0.545898, 0.826469, -0.137636,
+1.002737, 11.718807, 14.305887, 3.000000, -1.516370, 0.524951, 0.731928, -0.434405,
+1.002737, 10.783842, 12.373039, 3.000000, -1.349954, 0.535040, 0.792292, -0.293267,
+0.000000, 10.965359, 12.283498, 3.500000, -1.349954, -0.000000, 0.938935, -0.344095,
+0.000000, 10.965359, 12.283498, 3.500000, -1.349954, -0.000000, 0.938935, -0.344095,
+-1.002737, 10.783842, 12.373039, 4.000000, -1.349704, -0.535040, 0.792292, -0.293266,
+-1.002737, 11.718807, 14.305887, 4.000000, -1.516370, -0.524951, 0.731928, -0.434405,
+-1.002737, 11.718807, 14.305887, 4.000000, -1.516370, -0.524951, 0.731928, -0.434405,
+-1.002737, 12.901150, 15.938179, 4.000000, -1.683037, -0.520176, 0.645820, -0.558867,
+0.000000, 13.036221, 15.799099, 3.500000, -1.679268, 0.000000, 0.757369, -0.652987,
+0.000000, 13.036221, 15.799099, 3.500000, -1.679268, 0.000000, 0.757369, -0.652987,
+1.002737, 12.901150, 15.938179, 3.000000, -1.679268, 0.520177, 0.645820, -0.558867,
+1.002737, 11.718807, 14.305887, 3.000000, -1.516370, 0.524951, 0.731928, -0.434405,
+1.002737, 14.227100, 17.202572, 3.000000, -1.834628, 0.519663, 0.527798, -0.671848,
+1.002737, 12.901150, 15.938179, 3.000000, -1.679268, 0.520177, 0.645820, -0.558867,
+0.000000, 13.036221, 15.799099, 3.500000, -1.679268, 0.000000, 0.757369, -0.652987,
+0.000000, 13.036221, 15.799099, 3.500000, -1.679268, 0.000000, 0.757369, -0.652987,
+-1.002737, 12.901150, 15.938179, 4.000000, -1.683037, -0.520176, 0.645820, -0.558867,
+-1.002737, 14.227100, 17.202572, 4.000000, -1.834628, -0.519663, 0.527798, -0.671848,
+-1.002737, 14.227100, 17.202572, 4.000000, -1.834628, -0.519663, 0.527798, -0.671848,
+-1.002737, 15.688553, 18.126600, 4.000000, -1.986219, -0.519424, 0.384311, -0.763219,
+0.000000, 15.767933, 17.950714, 3.500000, -1.988039, 0.000000, 0.450479, -0.892787,
+0.000000, 15.767933, 17.950714, 3.500000, -1.988039, 0.000000, 0.450479, -0.892787,
+1.002737, 15.688553, 18.126600, 3.000000, -1.988039, 0.519424, 0.384311, -0.763219,
+1.002737, 14.227100, 17.202572, 3.000000, -1.834628, 0.519663, 0.527798, -0.671848,
+1.002737, 17.277420, 18.737804, 3.000000, -2.145087, 0.519855, 0.222506, -0.824768,
+1.002737, 15.688553, 18.126600, 3.000000, -1.988039, 0.519424, 0.384311, -0.763219,
+0.000000, 15.767933, 17.950714, 3.500000, -1.988039, 0.000000, 0.450479, -0.892787,
+0.000000, 15.767933, 17.950714, 3.500000, -1.988039, 0.000000, 0.450479, -0.892787,
+-1.002737, 15.688553, 18.126600, 4.000000, -1.986219, -0.519424, 0.384311, -0.763219,
+-1.002737, 17.277420, 18.737804, 4.000000, -2.145087, -0.519855, 0.222506, -0.824768,
+-1.002737, 17.277420, 18.737804, 4.000000, -2.145087, -0.519855, 0.222506, -0.824768,
+-1.002737, 18.963112, 19.009758, 4.000000, -2.303954, -0.519106, 0.044200, -0.853567,
+0.000000, 18.975204, 18.818281, 3.500000, -2.305904, -0.000000, 0.051821, -0.998656,
+0.000000, 18.975204, 18.818281, 3.500000, -2.305904, -0.000000, 0.051821, -0.998656,
+1.002737, 18.963112, 19.009758, 3.000000, -2.305904, 0.519106, 0.044200, -0.853567,
+1.002737, 17.277420, 18.737804, 3.000000, -2.145087, 0.519855, 0.222506, -0.824768,
+1.002737, 20.715042, 18.916035, 3.000000, -2.470621, 0.518180, -0.147145, -0.842519,
+1.002737, 18.963112, 19.009758, 3.000000, -2.305904, 0.519106, 0.044200, -0.853567,
+0.000000, 18.975204, 18.818281, 3.500000, -2.305904, -0.000000, 0.051821, -0.998656,
+0.000000, 18.975204, 18.818281, 3.500000, -2.305904, -0.000000, 0.051821, -0.998656,
+-1.002737, 18.963112, 19.009758, 4.000000, -2.303954, -0.519106, 0.044200, -0.853567,
+-1.002737, 20.715042, 18.916035, 4.000000, -2.470621, -0.518180, -0.147145, -0.842519,
+-1.002737, 20.715042, 18.916035, 4.000000, -2.470621, -0.518180, -0.147145, -0.842519,
+-1.002737, 22.528088, 18.387989, 4.000000, -2.637287, -0.514483, -0.334572, -0.789537,
+0.000000, 22.464233, 18.209660, 3.500000, -2.646001, -0.000000, -0.390600, -0.920561,
+0.000000, 22.464233, 18.209660, 3.500000, -2.646001, -0.000000, -0.390600, -0.920561,
+1.002737, 22.528091, 18.387989, 3.000000, -2.646001, 0.514483, -0.334572, -0.789537,
+1.002737, 20.715042, 18.916035, 3.000000, -2.470621, 0.518180, -0.147145, -0.842519,
+1.002737, 24.397125, 17.356983, 3.000000, -2.838810, 0.512162, -0.495528, -0.701529,
+1.002737, 22.528091, 18.387989, 3.000000, -2.646001, 0.514483, -0.334572, -0.789537,
+0.000000, 22.464233, 18.209660, 3.500000, -2.646001, -0.000000, -0.390600, -0.920561,
+0.000000, 22.464233, 18.209660, 3.500000, -2.646001, -0.000000, -0.390600, -0.920561,
+-1.002737, 22.528088, 18.387989, 4.000000, -2.637287, -0.514483, -0.334572, -0.789537,
+-1.002737, 24.397125, 17.356983, 4.000000, -2.838810, -0.512162, -0.495528, -0.701529,
+-1.002737, 24.397125, 17.356983, 4.000000, -2.838810, -0.512162, -0.495528, -0.701529,
+-1.002737, 26.120163, 15.851318, 4.000000, -3.040334, -0.515999, -0.637877, -0.571716,
+0.000000, 25.976517, 15.727814, 3.500000, -3.038383, -0.000000, -0.744667, -0.667436,
+0.000000, 25.976517, 15.727814, 3.500000, -3.038383, -0.000000, -0.744667, -0.667436,
+1.002737, 26.120163, 15.851318, 3.000000, -3.038383, 0.515999, -0.637877, -0.571716,
+1.002737, 24.397125, 17.356983, 3.000000, -2.838810, 0.512162, -0.495528, -0.701529,
+1.002737, 27.495193, 13.899298, 3.000000, -3.234054, 0.529173, -0.759785, -0.377761,
+1.002737, 26.120163, 15.851318, 3.000000, -3.038383, 0.515999, -0.637877, -0.571716,
+0.000000, 25.976517, 15.727814, 3.500000, -3.038383, -0.000000, -0.744667, -0.667436,
+0.000000, 25.976517, 15.727814, 3.500000, -3.038383, -0.000000, -0.744667, -0.667436,
+-1.002737, 26.120163, 15.851318, 4.000000, -3.040334, -0.515999, -0.637877, -0.571716,
+-1.002737, 27.495193, 13.899298, 4.000000, -3.234054, -0.529173, -0.759785, -0.377761,
+-1.002737, 27.495193, 13.899298, 4.000000, -3.234054, -0.529173, -0.759785, -0.377761,
+-1.002737, 28.234837, 11.594271, 4.000000, -3.427773, -0.549861, -0.829859, -0.094800,
+0.000000, 28.036469, 11.565307, 3.500000, -3.421010, -0.000000, -0.993846, -0.110776,
+0.000000, 28.036469, 11.565307, 3.500000, -3.421010, -0.000000, -0.993846, -0.110776,
+1.002737, 28.234837, 11.594270, 3.000000, -3.421010, 0.549862, -0.829858, -0.094800,
+1.002737, 27.495193, 13.899298, 3.000000, -3.234054, 0.529173, -0.759785, -0.377761,
+1.002737, 28.051701, 9.029581, 3.000000, -3.594440, 0.552395, -0.818570, 0.157487,
+1.002737, 28.234837, 11.594270, 3.000000, -3.421010, 0.549862, -0.829858, -0.094800,
+0.000000, 28.036469, 11.565307, 3.500000, -3.421010, -0.000000, -0.993846, -0.110776,
+0.000000, 28.036469, 11.565307, 3.500000, -3.421010, -0.000000, -0.993846, -0.110776,
+-1.002737, 28.234837, 11.594271, 4.000000, -3.427773, -0.549861, -0.829859, -0.094800,
+-1.002737, 28.051701, 9.029581, 4.000000, -3.594440, -0.552394, -0.818572, 0.157487,
+-1.002737, 28.051701, 9.029581, 4.000000, -3.594440, -0.552394, -0.818572, 0.157487,
+-1.002737, 27.272324, 6.583387, 4.000000, -3.761107, -0.563170, -0.762896, 0.317537,
+0.000000, 27.064018, 6.651896, 3.500000, -3.741288, 0.000000, -0.921832, 0.387591,
+0.000000, 27.064018, 6.651896, 3.500000, -3.741288, 0.000000, -0.921832, 0.387591,
+1.002737, 27.272324, 6.583387, 3.000000, -3.741287, 0.563171, -0.762895, 0.317537,
+1.002737, 28.051701, 9.029581, 3.000000, -3.594440, 0.552395, -0.818570, 0.157487,
+1.002737, 26.223228, 4.633848, 3.000000, -3.848496, 0.571231, -0.699649, 0.429169,
+1.002737, 27.272324, 6.583387, 3.000000, -3.741287, 0.563171, -0.762895, 0.317537,
+0.000000, 27.064018, 6.651896, 3.500000, -3.741288, 0.000000, -0.921832, 0.387591,
+0.000000, 27.064018, 6.651896, 3.500000, -3.741288, 0.000000, -0.921832, 0.387591,
+-1.002737, 27.272324, 6.583387, 4.000000, -3.761107, -0.563170, -0.762896, 0.317537,
+-1.002737, 26.223228, 4.633848, 4.000000, -3.848496, -0.571231, -0.699650, 0.429169,
+-1.002737, 26.223228, 4.633848, 4.000000, -3.848496, -0.571231, -0.699650, 0.429169,
+-1.002737, 25.192875, 3.192066, 4.000000, -3.935886, -0.573805, -0.657830, 0.487860,
+0.000000, 24.997784, 3.317980, 3.500000, -3.922053, -0.000000, -0.801896, 0.597463,
+0.000000, 24.997784, 3.317980, 3.500000, -3.922053, -0.000000, -0.801896, 0.597463,
+1.002737, 25.192875, 3.192066, 3.000000, -3.922053, 0.573805, -0.657830, 0.487860,
+1.002737, 26.223228, 4.633848, 3.000000, -3.848496, 0.571231, -0.699649, 0.429169,
+0.000000, 24.041351, 1.768998, 3.500000, -4.000000, 0.000000, -0.991299, -0.131630,
+0.742768, 24.296909, 1.783397, 3.000000, -4.000000, 0.428917, -0.894621, -0.125234,
+1.002737, 24.469711, 2.269146, 3.000000, -3.967943, 0.583534, -0.710408, 0.393458,
+1.002737, 24.469711, 2.269146, 3.000000, -3.967943, 0.583534, -0.710408, 0.393458,
+1.002737, 25.192875, 3.192066, 3.000000, -3.922053, 0.573805, -0.657830, 0.487860,
+0.000000, 24.997784, 3.317980, 3.500000, -3.922053, -0.000000, -0.801896, 0.597463,
+0.000000, 24.997784, 3.317980, 3.500000, -3.922053, -0.000000, -0.801896, 0.597463,
+-1.002737, 25.192875, 3.192066, 4.000000, -3.935886, -0.573805, -0.657830, 0.487860,
+-1.002737, 24.469711, 2.269146, 4.000000, -3.967943, -0.583534, -0.710408, 0.393458,
+-1.002737, 24.469711, 2.269146, 4.000000, -3.967943, -0.583534, -0.710408, 0.393458,
+-0.742768, 24.296909, 1.783397, 4.000000, -4.000000, -0.428917, -0.894621, -0.125234,
+0.000000, 24.041351, 1.768998, 3.500000, -4.000000, 0.000000, -0.991299, -0.131630,
+-1.002737, -1.292564, -32.294178, 1.000000, 0.972854, -0.576236, -0.817066, 0.018853,
+-1.002737, -1.259859, -30.876823, 1.000000, 0.937170, -0.573164, -0.818796, 0.032517,
+-1.336982, -0.552929, -30.921089, 0.500000, 0.937170, -0.999978, -0.006540, 0.000687,
+-1.336982, -0.552929, -30.921089, 0.500000, 0.937170, -0.999978, -0.006540, 0.000687,
+-1.002737, 0.153999, -30.965355, 0.000000, 0.945709, -0.580105, 0.814042, -0.028521,
+-1.002737, 0.129889, -32.334755, 0.000000, 0.972854, -0.578352, 0.815661, -0.014359,
+-1.002737, 0.245815, -29.027195, 0.000000, 0.884407, -0.580554, 0.811733, -0.063605,
+-1.002737, 0.153999, -30.965355, 0.000000, 0.945709, -0.580105, 0.814042, -0.028521,
+-1.336982, -0.552929, -30.921089, 0.500000, 0.937170, -0.999978, -0.006540, 0.000687,
+-1.336982, -0.552929, -30.921089, 0.500000, 0.937170, -0.999978, -0.006540, 0.000687,
+-1.002737, -1.259859, -30.876823, 1.000000, 0.937170, -0.573164, -0.818796, 0.032517,
+-1.002737, -1.156864, -28.875961, 1.000000, 0.884407, -0.570246, -0.818776, 0.066533,
+-1.002737, -1.156864, -28.875961, 1.000000, 0.884407, -0.570246, -0.818776, 0.066533,
+-1.002737, -0.895025, -26.385366, 1.000000, 0.812277, -0.568649, -0.814249, 0.116778,
+-1.336982, -0.199492, -26.493555, 0.500000, 0.812277, -0.999928, -0.011914, 0.001651,
+-1.336982, -0.199492, -26.493555, 0.500000, 0.812277, -0.999928, -0.011914, 0.001651,
+-1.002737, 0.496042, -26.601746, 0.000000, 0.823105, -0.581048, 0.805721, -0.114877,
+-1.002737, 0.245815, -29.027195, 0.000000, 0.884407, -0.580554, 0.811733, -0.063605,
+-1.002737, 0.995396, -23.770485, 0.000000, 0.718491, -0.583417, 0.789634, -0.190008,
+-1.002737, 0.496042, -26.601746, 0.000000, 0.823105, -0.581048, 0.805721, -0.114877,
+-1.336982, -0.199492, -26.493555, 0.500000, 0.812277, -0.999928, -0.011914, 0.001651,
+-1.336982, -0.199492, -26.493555, 0.500000, 0.812277, -0.999928, -0.011914, 0.001651,
+-1.002737, -0.895025, -26.385366, 1.000000, 0.812277, -0.568649, -0.814249, 0.116778,
+-1.002737, -0.385786, -23.498796, 1.000000, 0.718491, -0.565019, -0.802220, 0.192863,
+-1.002737, -0.385786, -23.498796, 1.000000, 0.718491, -0.565019, -0.802220, 0.192863,
+-1.000716, 0.522999, -20.483551, 1.046875, 0.600702, -0.555184, -0.771596, 0.310500,
+-1.334961, 1.211163, -20.628946, 0.687500, 0.612715, -0.999676, -0.020934, 0.014474,
+-1.334961, 1.211163, -20.628946, 0.687500, 0.612715, -0.999676, -0.020934, 0.014474,
+-1.000716, 1.899328, -20.774343, 0.000000, 0.613877, -0.578823, 0.757196, -0.302684,
+-1.002737, 0.995396, -23.770485, 0.000000, 0.718491, -0.583417, 0.789634, -0.190008,
+-0.994652, 3.363289, -17.854239, 1.500000, 0.568689, -0.554925, 0.739714, -0.380633,
+-1.000716, 1.899328, -20.774343, 0.000000, 0.613877, -0.578823, 0.757196, -0.302684,
+-1.334961, 1.211163, -20.628946, 0.687500, 0.612715, -0.999676, -0.020934, 0.014474,
+-1.334961, 1.211163, -20.628946, 0.687500, 0.612715, -0.999676, -0.020934, 0.014474,
+-1.000716, 0.522999, -20.483551, 1.046875, 0.600702, -0.555184, -0.771596, 0.310500,
+-0.994652, 1.983473, -17.606916, 1.187500, 0.456561, -0.553223, -0.737418, 0.387504,
+-0.994652, 1.983473, -17.606916, 1.187500, 0.456561, -0.553223, -0.737418, 0.387504,
+-0.990610, 3.544037, -14.721523, 1.000000, 0.267209, -0.562098, -0.749029, 0.350717,
+-1.324855, 4.237772, -14.807808, 2.000000, 0.395355, -0.999804, 0.015791, -0.011962,
+-1.324855, 4.237772, -14.807808, 2.000000, 0.395355, -0.999804, 0.015791, -0.011962,
+-0.990610, 4.931509, -14.894089, 3.000000, 0.523501, -0.544986, 0.762408, -0.348891,
+-0.994652, 3.363289, -17.854239, 1.500000, 0.568689, -0.554925, 0.739714, -0.380633,
+-1.002737, 6.556976, -6.071414, 0.000000, -0.308178, -0.553122, 0.818963, 0.152824,
+-1.000716, 6.770885, -8.754030, 0.000000, -0.079458, -0.549751, 0.833161, -0.060139,
+-1.334961, 6.071638, -8.749280, 0.500000, -0.079458, -0.999000, 0.044233, -0.006500,
+-1.334961, 6.071638, -8.749280, 0.500000, -0.079458, -0.999000, 0.044233, -0.006500,
+-1.000716, 5.372389, -8.744530, 1.000000, -0.079458, -0.594849, -0.801661, 0.059106,
+-1.002737, 5.163677, -6.177338, 1.000000, -0.308178, -0.587361, -0.794674, -0.153298,
+-1.002737, 5.163677, -6.177338, 1.000000, -0.308178, -0.587361, -0.794674, -0.153298,
+-1.002737, 4.402004, -3.694788, 1.000000, -0.537451, -0.571136, -0.774985, -0.270559,
+-1.336982, 5.093796, -3.594290, 0.500000, -0.537451, -0.999877, 0.014256, 0.006545,
+-1.336982, 5.093796, -3.594290, 0.500000, -0.537451, -0.999877, 0.014256, 0.006545,
+-1.002737, 5.785589, -3.493792, 0.000000, -0.536897, -0.556039, 0.785897, 0.270530,
+-1.002737, 6.556976, -6.071414, 0.000000, -0.308178, -0.553122, 0.818963, 0.152824,
+-1.002737, 4.735826, -0.785002, 0.000000, -0.767833, -0.563593, 0.774459, 0.287360,
+-1.002737, 5.785589, -3.493792, 0.000000, -0.536897, -0.556039, 0.785897, 0.270530,
+-1.336982, 5.093796, -3.594290, 0.500000, -0.537451, -0.999877, 0.014256, 0.006545,
+-1.336982, 5.093796, -3.594290, 0.500000, -0.537451, -0.999877, 0.014256, 0.006545,
+-1.002737, 4.402004, -3.694788, 1.000000, -0.537451, -0.571136, -0.774985, -0.270559,
+-1.002737, 3.362402, -1.013249, 1.000000, -0.767833, -0.559574, -0.778227, -0.285025,
+-1.002737, 3.362402, -1.013249, 1.000000, -0.767833, -0.559574, -0.778227, -0.285025,
+-1.002737, 2.394936, 1.783656, 1.046875, -0.973474, -0.550621, -0.806194, -0.216490,
+-1.336982, 3.076645, 1.877820, 0.687500, -0.955495, -0.999725, -0.022213, -0.007478,
+-1.336982, 3.076645, 1.877820, 0.687500, -0.955495, -0.999725, -0.022213, -0.007478,
+-1.002737, 3.758350, 1.971984, 0.000000, -0.998770, -0.573360, 0.788967, 0.220880,
+-1.002737, 4.735826, -0.785002, 0.000000, -0.767833, -0.563593, 0.774459, 0.287360,
+-1.002737, 3.203825, 4.694192, 1.500000, -0.960717, -0.573166, 0.812586, 0.105755,
+-1.002737, 3.758350, 1.971984, 0.000000, -0.998770, -0.573360, 0.788967, 0.220880,
+-1.336982, 3.076645, 1.877820, 0.687500, -0.955495, -0.999725, -0.022213, -0.007478,
+-1.336982, 3.076645, 1.877820, 0.687500, -0.955495, -0.999725, -0.022213, -0.007478,
+-1.002737, 2.394936, 1.783656, 1.046875, -0.973474, -0.550621, -0.806194, -0.216490,
+-1.002737, 1.849670, 4.612304, 1.187500, -1.128520, -0.548005, -0.830422, -0.100446,
+-1.002737, 1.849670, 4.612304, 1.187500, -1.128520, -0.548005, -0.830422, -0.100446,
+-1.002737, 1.707661, 7.456823, 1.000000, -1.306215, -0.546192, -0.837529, 0.014826,
+-1.336982, 2.380295, 7.427917, 2.000000, -1.114440, -0.999670, -0.025705, 0.000199,
+-1.336982, 2.380295, 7.427917, 2.000000, -1.114440, -0.999670, -0.025705, 0.000199,
+-1.002737, 3.052929, 7.399012, 3.000000, -0.922665, -0.571504, 0.820505, -0.012461,
+-1.002737, 3.203825, 4.694192, 1.500000, -0.960717, -0.573166, 0.812586, 0.105755,
+-1.022346, 4.637777, 15.286472, 1.333333, -1.667888, -0.574184, 0.765044, -0.291584,
+-1.007639, 3.836994, 12.751901, 0.000000, -1.613659, -0.571038, 0.793815, -0.209219,
+-1.341885, 3.176014, 12.915927, 0.500000, -1.613659, -0.999798, -0.020077, 0.001135,
+-1.341885, 3.176014, 12.915927, 0.500000, -1.613659, -0.999798, -0.020077, 0.001135,
+-1.007639, 2.515034, 13.079953, 1.000000, -1.613659, -0.551445, -0.808533, 0.205386,
+-1.022346, 3.341311, 15.726742, 1.166667, -1.691614, -0.553953, -0.781075, 0.288198,
+-1.022346, 3.341311, 15.726742, 1.166667, -1.691614, -0.553953, -0.781075, 0.288198,
+-1.032151, 4.412262, 18.174877, 1.000000, -1.776346, -0.555665, -0.740194, 0.378615,
+-1.366396, 5.044981, 17.903212, 1.833333, -1.749232, -0.999757, -0.019426, 0.010462,
+-1.366396, 5.044981, 17.903212, 1.833333, -1.749232, -0.999757, -0.019426, 0.010462,
+-1.032151, 5.677700, 17.631544, 2.666667, -1.722117, -0.577835, 0.723604, -0.377496,
+-1.022346, 4.637777, 15.286472, 1.333333, -1.667888, -0.574184, 0.765044, -0.291584,
+-1.002737, 8.987209, 23.827108, 0.500000, -2.000000, -0.690086, 0.408969, 0.597098,
+-0.742768, 9.282909, 23.329664, 0.000000, -2.000000, -0.487251, 0.872639, 0.032983,
+-1.002737, 9.038933, 22.663582, 0.000000, -1.969517, -0.582357, 0.720010, -0.377421,
+-1.002737, 9.038933, 22.663582, 0.000000, -1.969517, -0.582357, 0.720010, -0.377421,
+-1.007639, 8.160118, 21.422651, 0.000000, -1.939034, -0.574068, 0.669723, -0.471080,
+-1.341885, 7.556932, 21.789433, 0.500000, -1.939034, -0.999989, 0.000304, 0.004665,
+-1.341885, 7.556932, 21.789433, 0.500000, -1.939034, -0.999989, 0.000304, 0.004665,
+-1.007639, 6.953747, 22.156216, 1.000000, -1.939034, -0.571627, -0.672843, 0.469600,
+-1.002737, 7.854620, 23.452549, 1.000000, -1.969517, -0.579230, -0.604597, 0.546768,
+-1.002737, 7.854620, 23.452549, 1.000000, -1.969517, -0.579230, -0.604597, 0.546768,
+-0.742768, 8.411285, 23.925793, 1.000000, -2.000000, -0.485429, -0.281111, 0.827850,
+-1.002737, 8.987209, 23.827108, 0.500000, -2.000000, -0.690086, 0.408969, 0.597098,
+1.002737, -1.292564, -32.294174, 2.000000, 0.972854, 0.576237, -0.817066, 0.018853,
+1.002737, -1.259859, -30.876823, 2.000000, 0.937170, 0.573164, -0.818795, 0.032517,
+0.000000, -1.495502, -30.862072, 1.500000, 0.937170, 0.000000, -0.999196, 0.040090,
+0.000000, -1.495502, -30.862072, 1.500000, 0.937170, 0.000000, -0.999196, 0.040090,
+-1.002737, -1.259859, -30.876823, 1.000000, 0.937170, -0.573164, -0.818796, 0.032517,
+-1.002737, -1.292564, -32.294178, 1.000000, 0.972854, -0.576236, -0.817066, 0.018853,
+-1.002737, -1.156864, -28.875961, 1.000000, 0.884407, -0.570246, -0.818776, 0.066533,
+-1.002737, -1.259859, -30.876823, 1.000000, 0.937170, -0.573164, -0.818796, 0.032517,
+0.000000, -1.495502, -30.862072, 1.500000, 0.937170, 0.000000, -0.999196, 0.040090,
+0.000000, -1.495502, -30.862072, 1.500000, 0.937170, 0.000000, -0.999196, 0.040090,
+1.002737, -1.259859, -30.876823, 2.000000, 0.937170, 0.573164, -0.818795, 0.032517,
+1.002737, -1.156864, -28.875965, 2.000000, 0.884407, 0.570246, -0.818775, 0.066533,
+1.002737, -1.156864, -28.875965, 2.000000, 0.884407, 0.570246, -0.818775, 0.066533,
+1.002737, -0.895025, -26.385365, 2.000000, 0.812277, 0.568649, -0.814249, 0.116778,
+0.000000, -1.126870, -26.349302, 1.500000, 0.812277, 0.000000, -0.989855, 0.142082,
+0.000000, -1.126870, -26.349302, 1.500000, 0.812277, 0.000000, -0.989855, 0.142082,
+-1.002737, -0.895025, -26.385366, 1.000000, 0.812277, -0.568649, -0.814249, 0.116778,
+-1.002737, -1.156864, -28.875961, 1.000000, 0.884407, -0.570246, -0.818776, 0.066533,
+-1.002737, -0.385786, -23.498796, 1.000000, 0.718491, -0.565019, -0.802220, 0.192863,
+-1.002737, -0.895025, -26.385366, 1.000000, 0.812277, -0.568649, -0.814249, 0.116778,
+0.000000, -1.126870, -26.349302, 1.500000, 0.812277, 0.000000, -0.989855, 0.142082,
+0.000000, -1.126870, -26.349302, 1.500000, 0.812277, 0.000000, -0.989855, 0.142082,
+1.002737, -0.895025, -26.385365, 2.000000, 0.812277, 0.568649, -0.814249, 0.116778,
+1.002737, -0.385786, -23.498796, 2.000000, 0.718491, 0.564910, -0.802377, 0.192532,
+1.002737, -0.385786, -23.498796, 2.000000, 0.718491, 0.564910, -0.802377, 0.192532,
+1.004758, 0.522999, -20.483551, 2.000000, 0.596697, 0.555081, -0.772140, 0.309331,
+0.002021, 0.293610, -20.435085, 1.500000, 0.596697, -0.000089, -0.928581, 0.371129,
+0.002021, 0.293610, -20.435085, 1.500000, 0.596697, -0.000089, -0.928581, 0.371129,
+-1.000716, 0.522999, -20.483551, 1.046875, 0.600702, -0.555184, -0.771596, 0.310500,
+-1.002737, -0.385786, -23.498796, 1.000000, 0.718491, -0.565019, -0.802220, 0.192863,
+-0.994652, 1.983473, -17.606916, 1.187500, 0.456561, -0.553223, -0.737418, 0.387504,
+-1.000716, 0.522999, -20.483551, 1.046875, 0.600702, -0.555184, -0.771596, 0.310500,
+0.002021, 0.293610, -20.435085, 1.500000, 0.596697, -0.000089, -0.928581, 0.371129,
+0.002021, 0.293610, -20.435085, 1.500000, 0.596697, -0.000089, -0.928581, 0.371129,
+1.004758, 0.522999, -20.483551, 2.000000, 0.596697, 0.555081, -0.772140, 0.309331,
+1.010821, 1.983473, -17.606916, 2.000000, 0.440543, 0.553586, -0.738015, 0.385845,
+1.010821, 1.983473, -17.606916, 2.000000, 0.440543, 0.553586, -0.738015, 0.385845,
+1.014864, 3.544037, -14.721523, 2.000000, 0.267209, 0.562535, -0.748836, 0.350428,
+0.012127, 3.312792, -14.692760, 1.500000, 0.267209, 0.000169, -0.904592, 0.426279,
+0.012127, 3.312792, -14.692760, 1.500000, 0.267209, 0.000169, -0.904592, 0.426279,
+-0.990610, 3.544037, -14.721523, 1.000000, 0.267209, -0.562098, -0.749029, 0.350717,
+-0.994652, 1.983473, -17.606916, 1.187500, 0.456561, -0.553223, -0.737418, 0.387504,
+-1.002737, 5.163677, -6.177338, 1.000000, -0.308178, -0.587361, -0.794674, -0.153298,
+-1.000716, 5.372389, -8.744530, 1.000000, -0.079458, -0.594849, -0.801661, 0.059106,
+0.002021, 5.139305, -8.742946, 1.500000, -0.079458, -0.000101, -0.997122, 0.075814,
+0.002021, 5.139305, -8.742946, 1.500000, -0.079458, -0.000101, -0.997122, 0.075814,
+1.004758, 5.372389, -8.744530, 2.000000, -0.079458, 0.594556, -0.801738, 0.060986,
+1.002737, 5.163681, -6.177338, 2.000000, -0.308178, 0.587260, -0.794834, -0.152858,
+1.002737, 5.163681, -6.177338, 2.000000, -0.308178, 0.587260, -0.794834, -0.152858,
+1.002737, 4.402004, -3.694788, 2.000000, -0.537451, 0.571136, -0.774985, -0.270560,
+0.000000, 4.171406, -3.728287, 1.500000, -0.537451, 0.000000, -0.943782, -0.330570,
+0.000000, 4.171406, -3.728287, 1.500000, -0.537451, 0.000000, -0.943782, -0.330570,
+-1.002737, 4.402004, -3.694788, 1.000000, -0.537451, -0.571136, -0.774985, -0.270559,
+-1.002737, 5.163677, -6.177338, 1.000000, -0.308178, -0.587361, -0.794674, -0.153298,
+-1.002737, 3.362402, -1.013249, 1.000000, -0.767833, -0.559574, -0.778227, -0.285025,
+-1.002737, 4.402004, -3.694788, 1.000000, -0.537451, -0.571136, -0.774985, -0.270559,
+0.000000, 4.171406, -3.728287, 1.500000, -0.537451, 0.000000, -0.943782, -0.330570,
+0.000000, 4.171406, -3.728287, 1.500000, -0.537451, 0.000000, -0.943782, -0.330570,
+1.002737, 4.402004, -3.694788, 2.000000, -0.537451, 0.571136, -0.774985, -0.270560,
+1.002737, 3.362402, -1.013249, 2.000000, -0.767833, 0.559574, -0.778227, -0.285025,
+1.002737, 3.362402, -1.013249, 2.000000, -0.767833, 0.559574, -0.778227, -0.285025,
+1.002737, 2.394936, 1.783656, 2.000000, -0.979466, 0.550621, -0.806194, -0.216490,
+0.000000, 2.167702, 1.752268, 1.500000, -0.979466, -0.000000, -0.966229, -0.257685,
+0.000000, 2.167702, 1.752268, 1.500000, -0.979466, -0.000000, -0.966229, -0.257685,
+-1.002737, 2.394936, 1.783656, 1.046875, -0.973474, -0.550621, -0.806194, -0.216490,
+-1.002737, 3.362402, -1.013249, 1.000000, -0.767833, -0.559574, -0.778227, -0.285025,
+-1.002737, 1.849670, 4.612304, 1.187500, -1.128520, -0.548005, -0.830422, -0.100446,
+-1.002737, 2.394936, 1.783656, 1.046875, -0.973474, -0.550621, -0.806194, -0.216490,
+0.000000, 2.167702, 1.752268, 1.500000, -0.979466, -0.000000, -0.966229, -0.257685,
+0.000000, 2.167702, 1.752268, 1.500000, -0.979466, -0.000000, -0.966229, -0.257685,
+1.002737, 2.394936, 1.783656, 2.000000, -0.979466, 0.550621, -0.806194, -0.216490,
+1.002737, 1.849670, 4.612304, 2.000000, -1.152493, 0.548005, -0.830422, -0.100446,
+1.002737, 1.849670, 4.612304, 2.000000, -1.152493, 0.548005, -0.830422, -0.100446,
+1.002737, 1.707661, 7.456823, 2.000000, -1.306215, 0.546192, -0.837529, 0.014826,
+0.000000, 1.483450, 7.466458, 1.500000, -1.306215, 0.000000, -0.999837, 0.018050,
+0.000000, 1.483450, 7.466458, 1.500000, -1.306215, 0.000000, -0.999837, 0.018050,
+-1.002737, 1.707661, 7.456823, 1.000000, -1.306215, -0.546192, -0.837529, 0.014826,
+-1.002737, 1.849670, 4.612304, 1.187500, -1.128520, -0.548005, -0.830422, -0.100446,
+-1.022346, 3.341311, 15.726742, 1.166667, -1.691614, -0.553953, -0.781075, 0.288198,
+-1.007639, 2.515034, 13.079953, 1.000000, -1.613659, -0.551445, -0.808533, 0.205386,
+-0.004902, 2.294706, 13.134627, 1.500000, -1.613659, 0.000247, -0.968748, 0.248048,
+-0.004902, 2.294706, 13.134627, 1.500000, -1.613659, 0.000247, -0.968748, 0.248048,
+0.997835, 2.515034, 13.079953, 2.000000, -1.613659, 0.552074, -0.807195, 0.208929,
+0.983128, 3.341311, 15.726744, 2.000000, -1.695003, 0.553551, -0.779630, 0.292845,
+0.983128, 3.341311, 15.726744, 2.000000, -1.695003, 0.553551, -0.779630, 0.292845,
+0.973323, 4.412262, 18.174875, 2.000000, -1.776346, 0.554281, -0.740975, 0.379115,
+-0.029414, 4.201355, 18.265430, 1.500000, -1.776346, -0.000535, -0.890739, 0.454514,
+-0.029414, 4.201355, 18.265430, 1.500000, -1.776346, -0.000535, -0.890739, 0.454514,
+-1.032151, 4.412262, 18.174877, 1.000000, -1.776346, -0.555665, -0.740194, 0.378615,
+-1.022346, 3.341311, 15.726742, 1.166667, -1.691614, -0.553953, -0.781075, 0.288198,
+0.000000, 8.401409, 24.234768, 1.500000, -2.000000, -0.000001, -0.291501, 0.956571,
+-0.742768, 8.411285, 23.925793, 1.000000, -2.000000, -0.485429, -0.281111, 0.827850,
+-1.002737, 7.854620, 23.452549, 1.000000, -1.969517, -0.579230, -0.604597, 0.546768,
+-1.002737, 7.854620, 23.452549, 1.000000, -1.969517, -0.579230, -0.604597, 0.546768,
+-1.007639, 6.953747, 22.156216, 1.000000, -1.939034, -0.571627, -0.672843, 0.469600,
+-0.004902, 6.752687, 22.278475, 1.500000, -1.939034, 0.000369, -0.822635, 0.568570,
+-0.004902, 6.752687, 22.278475, 1.500000, -1.939034, 0.000369, -0.822635, 0.568570,
+0.997835, 6.953747, 22.156214, 2.000000, -1.939034, 0.572743, -0.675634, 0.464203,
+1.002737, 7.854620, 23.452549, 2.000000, -1.969517, 0.580173, -0.605657, 0.544591,
+1.002737, 7.854620, 23.452549, 2.000000, -1.969517, 0.580173, -0.605657, 0.544591,
+0.742768, 8.411285, 23.925795, 2.000000, -2.000000, 0.485428, -0.281111, 0.827851,
+0.000000, 8.401409, 24.234768, 1.500000, -2.000000, -0.000001, -0.291501, 0.956571,
+1.002737, 0.129889, -32.334755, 2.937500, 0.946466, 0.578352, 0.815661, -0.014359,
+1.002737, 0.153999, -30.965355, 2.906250, 0.897588, 0.580105, 0.814042, -0.028521,
+1.336982, -0.552929, -30.921089, 2.500000, 0.937170, 0.999978, -0.006539, 0.000687,
+1.336982, -0.552929, -30.921089, 2.500000, 0.937170, 0.999978, -0.006539, 0.000687,
+1.002737, -1.259859, -30.876823, 2.000000, 0.937170, 0.573164, -0.818795, 0.032517,
+1.002737, -1.292564, -32.294174, 2.000000, 0.972854, 0.576237, -0.817066, 0.018853,
+1.002737, -1.156864, -28.875965, 2.000000, 0.884407, 0.570246, -0.818775, 0.066533,
+1.002737, -1.259859, -30.876823, 2.000000, 0.937170, 0.573164, -0.818795, 0.032517,
+1.336982, -0.552929, -30.921089, 2.500000, 0.937170, 0.999978, -0.006539, 0.000687,
+1.336982, -0.552929, -30.921089, 2.500000, 0.937170, 0.999978, -0.006539, 0.000687,
+1.002737, 0.153999, -30.965355, 2.906250, 0.897588, 0.580105, 0.814042, -0.028521,
+1.002737, 0.245815, -29.027195, 2.937500, 0.858019, 0.580554, 0.811733, -0.063605,
+1.002737, 0.245815, -29.027195, 2.937500, 0.858019, 0.580554, 0.811733, -0.063605,
+1.002737, 0.496042, -26.601746, 2.968750, 0.804268, 0.581048, 0.805721, -0.114877,
+1.336982, -0.199492, -26.493555, 2.500000, 0.812277, 0.999928, -0.011914, 0.001651,
+1.336982, -0.199492, -26.493555, 2.500000, 0.812277, 0.999928, -0.011914, 0.001651,
+1.002737, -0.895025, -26.385365, 2.000000, 0.812277, 0.568649, -0.814249, 0.116778,
+1.002737, -1.156864, -28.875965, 2.000000, 0.884407, 0.570246, -0.818775, 0.066533,
+1.002737, -0.385786, -23.498796, 2.000000, 0.718491, 0.564910, -0.802377, 0.192532,
+1.002737, -0.895025, -26.385365, 2.000000, 0.812277, 0.568649, -0.814249, 0.116778,
+1.336982, -0.199492, -26.493555, 2.500000, 0.812277, 0.999928, -0.011914, 0.001651,
+1.336982, -0.199492, -26.493555, 2.500000, 0.812277, 0.999928, -0.011914, 0.001651,
+1.002737, 0.496042, -26.601746, 2.968750, 0.804268, 0.581048, 0.805721, -0.114877,
+1.002737, 0.995396, -23.770485, 2.937500, 0.712843, 0.583294, 0.789623, -0.190427,
+1.002737, 0.995396, -23.770485, 2.937500, 0.712843, 0.583294, 0.789623, -0.190427,
+1.004758, 1.899328, -20.774343, 2.890625, 0.592229, 0.578470, 0.756840, -0.304248,
+1.339004, 1.211163, -20.628948, 2.500000, 0.596697, 0.999699, -0.021427, 0.011933,
+1.339004, 1.211163, -20.628948, 2.500000, 0.596697, 0.999699, -0.021427, 0.011933,
+1.004758, 0.522999, -20.483551, 2.000000, 0.596697, 0.555081, -0.772140, 0.309331,
+1.002737, -0.385786, -23.498796, 2.000000, 0.718491, 0.564910, -0.802377, 0.192532,
+1.010821, 1.983473, -17.606916, 2.000000, 0.440543, 0.553586, -0.738015, 0.385845,
+1.004758, 0.522999, -20.483551, 2.000000, 0.596697, 0.555081, -0.772140, 0.309331,
+1.339004, 1.211163, -20.628948, 2.500000, 0.596697, 0.999699, -0.021427, 0.011933,
+1.339004, 1.211163, -20.628948, 2.500000, 0.596697, 0.999699, -0.021427, 0.011933,
+1.004758, 1.899328, -20.774343, 2.890625, 0.592229, 0.578470, 0.756840, -0.304248,
+1.010821, 3.363289, -17.854240, 2.875000, 0.450913, 0.554791, 0.739026, -0.382161,
+1.010821, 3.363289, -17.854240, 2.875000, 0.450913, 0.554791, 0.739026, -0.382161,
+1.014864, 4.931509, -14.894089, 3.000000, 0.267209, 0.545447, 0.762198, -0.348629,
+1.349109, 4.237772, -14.807808, 2.500000, 0.267209, 0.999805, 0.015731, -0.011963,
+1.349109, 4.237772, -14.807808, 2.500000, 0.267209, 0.999805, 0.015731, -0.011963,
+1.014864, 3.544037, -14.721523, 2.000000, 0.267209, 0.562535, -0.748836, 0.350428,
+1.010821, 1.983473, -17.606916, 2.000000, 0.440543, 0.553586, -0.738015, 0.385845,
+1.002737, 5.163681, -6.177338, 2.000000, -0.308178, 0.587260, -0.794834, -0.152858,
+1.004758, 5.372389, -8.744530, 2.000000, -0.079458, 0.594556, -0.801738, 0.060986,
+1.339004, 6.071638, -8.749280, 2.500000, -0.079458, 0.999013, 0.044275, -0.003633,
+1.339004, 6.071638, -8.749280, 2.500000, -0.079458, 0.999013, 0.044275, -0.003633,
+1.004758, 6.770885, -8.754030, 3.000000, -0.079458, 0.549543, 0.833398, -0.058740,
+1.002737, 6.556976, -6.071414, 2.937500, -0.360878, 0.552962, 0.818993, 0.153246,
+1.002737, 6.556976, -6.071414, 2.937500, -0.360878, 0.552962, 0.818993, 0.153246,
+1.002737, 5.785589, -3.493792, 2.968750, -0.549437, 0.556039, 0.785897, 0.270530,
+1.336982, 5.093796, -3.594290, 2.500000, -0.537451, 0.999877, 0.014256, 0.006545,
+1.336982, 5.093796, -3.594290, 2.500000, -0.537451, 0.999877, 0.014256, 0.006545,
+1.002737, 4.402004, -3.694788, 2.000000, -0.537451, 0.571136, -0.774985, -0.270560,
+1.002737, 5.163681, -6.177338, 2.000000, -0.308178, 0.587260, -0.794834, -0.152858,
+1.002737, 3.362402, -1.013249, 2.000000, -0.767833, 0.559574, -0.778227, -0.285025,
+1.002737, 4.402004, -3.694788, 2.000000, -0.537451, 0.571136, -0.774985, -0.270560,
+1.336982, 5.093796, -3.594290, 2.500000, -0.537451, 0.999877, 0.014256, 0.006545,
+1.336982, 5.093796, -3.594290, 2.500000, -0.537451, 0.999877, 0.014256, 0.006545,
+1.002737, 5.785589, -3.493792, 2.968750, -0.549437, 0.556039, 0.785897, 0.270530,
+1.002737, 4.735826, -0.785002, 2.937500, -0.763077, 0.563593, 0.774459, 0.287360,
+1.002737, 4.735826, -0.785002, 2.937500, -0.763077, 0.563593, 0.774459, 0.287360,
+1.002737, 3.758350, 1.971984, 2.890625, -0.966339, 0.573361, 0.788967, 0.220880,
+1.336982, 3.076645, 1.877820, 2.500000, -0.979466, 0.999725, -0.022213, -0.007478,
+1.336982, 3.076645, 1.877820, 2.500000, -0.979466, 0.999725, -0.022213, -0.007478,
+1.002737, 2.394936, 1.783656, 2.000000, -0.979466, 0.550621, -0.806194, -0.216490,
+1.002737, 3.362402, -1.013249, 2.000000, -0.767833, 0.559574, -0.778227, -0.285025,
+1.336982, 2.380295, 7.427917, 2.500000, -1.306215, 0.999670, -0.025705, 0.000199,
+1.002737, 1.707661, 7.456823, 2.000000, -1.306215, 0.546192, -0.837529, 0.014826,
+1.002737, 1.849670, 4.612304, 2.000000, -1.152493, 0.548005, -0.830422, -0.100446,
+1.002737, 1.849670, 4.612304, 2.000000, -1.152493, 0.548005, -0.830422, -0.100446,
+1.002737, 2.394936, 1.783656, 2.000000, -0.979466, 0.550621, -0.806194, -0.216490,
+1.336982, 3.076645, 1.877820, 2.500000, -0.979466, 0.999725, -0.022213, -0.007478,
+1.336982, 3.076645, 1.877820, 2.500000, -0.979466, 0.999725, -0.022213, -0.007478,
+1.002737, 3.758350, 1.971984, 2.890625, -0.966339, 0.573361, 0.788967, 0.220880,
+1.002737, 3.203825, 4.694192, 2.875000, -1.123764, 0.573167, 0.812586, 0.105755,
+1.002737, 3.203825, 4.694192, 2.875000, -1.123764, 0.573167, 0.812586, 0.105755,
+1.002737, 3.052929, 7.399012, 3.000000, -1.306215, 0.571504, 0.820504, -0.012461,
+1.336982, 2.380295, 7.427917, 2.500000, -1.306215, 0.999670, -0.025705, 0.000199,
+0.983128, 3.341311, 15.726744, 2.000000, -1.695003, 0.553551, -0.779630, 0.292845,
+0.997835, 2.515034, 13.079953, 2.000000, -1.613659, 0.552074, -0.807195, 0.208929,
+1.332080, 3.176014, 12.915927, 2.500000, -1.613659, 0.999801, -0.018232, 0.008046,
+1.332080, 3.176014, 12.915927, 2.500000, -1.613659, 0.999801, -0.018232, 0.008046,
+0.997834, 3.836994, 12.751901, 3.000000, -1.613659, 0.571655, 0.794480, -0.204969,
+0.983128, 4.637777, 15.286472, 2.833333, -1.698392, 0.573967, 0.767126, -0.286495,
+0.983128, 4.637777, 15.286472, 2.833333, -1.698392, 0.573967, 0.767126, -0.286495,
+0.973323, 5.677700, 17.631544, 3.000000, -1.776346, 0.576561, 0.724323, -0.378066,
+1.307569, 5.044981, 17.903212, 2.500000, -1.776346, 0.999751, -0.019683, 0.010530,
+1.307569, 5.044981, 17.903212, 2.500000, -1.776346, 0.999751, -0.019683, 0.010530,
+0.973323, 4.412262, 18.174875, 2.000000, -1.776346, 0.554281, -0.740975, 0.379115,
+0.983128, 3.341311, 15.726744, 2.000000, -1.695003, 0.553551, -0.779630, 0.292845,
+1.002737, 8.987209, 23.827108, 2.500000, -2.000000, 0.690085, 0.408969, 0.597099,
+0.742768, 8.411285, 23.925795, 2.000000, -2.000000, 0.485428, -0.281111, 0.827851,
+1.002737, 7.854620, 23.452549, 2.000000, -1.969517, 0.580173, -0.605657, 0.544591,
+1.002737, 7.854620, 23.452549, 2.000000, -1.969517, 0.580173, -0.605657, 0.544591,
+0.997835, 6.953747, 22.156214, 2.000000, -1.939034, 0.572743, -0.675634, 0.464203,
+1.332080, 7.556932, 21.789433, 2.500000, -1.939034, 0.999977, -0.005048, -0.004524,
+1.332080, 7.556932, 21.789433, 2.500000, -1.939034, 0.999977, -0.005048, -0.004524,
+0.997834, 8.160118, 21.422651, 3.000000, -1.939034, 0.574744, 0.665807, -0.475784,
+1.002737, 9.038933, 22.663582, 3.000000, -1.969517, 0.583232, 0.718345, -0.379238,
+1.002737, 9.038933, 22.663582, 3.000000, -1.969517, 0.583232, 0.718345, -0.379238,
+0.742768, 9.282909, 23.329664, 3.000000, -2.000000, 0.487250, 0.872639, 0.032983,
+1.002737, 8.987209, 23.827108, 2.500000, -2.000000, 0.690085, 0.408969, 0.597099,
+-1.002737, 0.129889, -32.334755, 3.500000, 0.761751, -0.578352, 0.815661, -0.014359,
+-1.002737, 0.153999, -30.965355, 3.000000, 0.523501, -0.580105, 0.814042, -0.028521,
+0.000000, 0.389645, -30.980114, 3.125000, 0.778842, -0.000000, 0.999403, -0.034561,
+0.000000, 0.389645, -30.980114, 3.125000, 0.778842, -0.000000, 0.999403, -0.034561,
+1.002737, 0.153999, -30.965355, 2.906250, 0.897588, 0.580105, 0.814042, -0.028521,
+1.002737, 0.129889, -32.334755, 2.937500, 0.946466, 0.578352, 0.815661, -0.014359,
+1.002737, 0.245815, -29.027195, 2.937500, 0.858019, 0.580554, 0.811733, -0.063605,
+1.002737, 0.153999, -30.965355, 2.906250, 0.897588, 0.580105, 0.814042, -0.028521,
+0.000000, 0.389645, -30.980114, 3.125000, 0.778842, -0.000000, 0.999403, -0.034561,
+0.000000, 0.389645, -30.980114, 3.125000, 0.778842, -0.000000, 0.999403, -0.034561,
+-1.002737, 0.153999, -30.965355, 3.000000, 0.523501, -0.580105, 0.814042, -0.028521,
+-1.002737, 0.245815, -29.027195, 3.500000, 0.673303, -0.580554, 0.811733, -0.063605,
+-1.002737, 0.245815, -29.027195, 3.500000, 0.673303, -0.580554, 0.811733, -0.063605,
+-1.002737, 0.496042, -26.601746, 4.000000, 0.823105, -0.581048, 0.805721, -0.114877,
+0.000000, 0.727886, -26.637808, 3.375000, 0.780241, 0.000000, 0.990007, -0.141020,
+0.000000, 0.727886, -26.637808, 3.375000, 0.780241, 0.000000, 0.990007, -0.141020,
+1.002737, 0.496042, -26.601746, 2.968750, 0.804268, 0.581048, 0.805721, -0.114877,
+1.002737, 0.245815, -29.027195, 2.937500, 0.858019, 0.580554, 0.811733, -0.063605,
+1.002737, 0.995396, -23.770485, 2.937500, 0.712843, 0.583294, 0.789623, -0.190427,
+1.002737, 0.496042, -26.601746, 2.968750, 0.804268, 0.581048, 0.805721, -0.114877,
+0.000000, 0.727886, -26.637808, 3.375000, 0.780241, 0.000000, 0.990007, -0.141020,
+0.000000, 0.727886, -26.637808, 3.375000, 0.780241, 0.000000, 0.990007, -0.141020,
+-1.002737, 0.496042, -26.601746, 4.000000, 0.823105, -0.581048, 0.805721, -0.114877,
+-1.002737, 0.995396, -23.770485, 3.500000, 0.673303, -0.583417, 0.789634, -0.190008,
+-1.002737, 0.995396, -23.770485, 3.500000, 0.673303, -0.583417, 0.789634, -0.190008,
+-1.000716, 1.899328, -20.774343, 3.000000, 0.523501, -0.578823, 0.757196, -0.302684,
+0.002021, 2.128716, -20.822807, 3.062500, 0.578824, -0.000086, 0.927679, -0.373379,
+0.002021, 2.128716, -20.822807, 3.062500, 0.578824, -0.000086, 0.927679, -0.373379,
+1.004758, 1.899328, -20.774343, 2.890625, 0.592229, 0.578470, 0.756840, -0.304248,
+1.002737, 0.995396, -23.770485, 2.937500, 0.712843, 0.583294, 0.789623, -0.190427,
+0.012127, 5.162754, -14.922852, 3.000000, 0.395355, 0.000167, 0.910359, -0.413819,
+1.014864, 4.931509, -14.894089, 3.000000, 0.267209, 0.545447, 0.762198, -0.348629,
+1.010821, 3.363289, -17.854240, 2.875000, 0.450913, 0.554791, 0.739026, -0.382161,
+1.010821, 3.363289, -17.854240, 2.875000, 0.450913, 0.554791, 0.739026, -0.382161,
+1.004758, 1.899328, -20.774343, 2.890625, 0.592229, 0.578470, 0.756840, -0.304248,
+0.002021, 2.128716, -20.822807, 3.062500, 0.578824, -0.000086, 0.927679, -0.373379,
+0.002021, 2.128716, -20.822807, 3.062500, 0.578824, -0.000086, 0.927679, -0.373379,
+-1.000716, 1.899328, -20.774343, 3.000000, 0.523501, -0.578823, 0.757196, -0.302684,
+-0.994652, 3.363289, -17.854239, 3.000000, 0.523501, -0.554925, 0.739714, -0.380633,
+-0.994652, 3.363289, -17.854239, 3.000000, 0.523501, -0.554925, 0.739714, -0.380633,
+-0.990610, 4.931509, -14.894089, 3.000000, 0.523501, -0.544986, 0.762408, -0.348891,
+0.012127, 5.162754, -14.922852, 3.000000, 0.395355, 0.000167, 0.910359, -0.413819,
+1.002737, 6.556976, -6.071414, 2.937500, -0.360878, 0.552962, 0.818993, 0.153246,
+1.004758, 6.770885, -8.754030, 3.000000, -0.079458, 0.549543, 0.833398, -0.058740,
+0.002021, 7.003967, -8.755614, 3.000000, -0.501061, -0.000102, 0.997541, -0.070087,
+0.002021, 7.003967, -8.755614, 3.000000, -0.501061, -0.000102, 0.997541, -0.070087,
+-1.000716, 6.770885, -8.754030, 3.000000, -0.922665, -0.549751, 0.833161, -0.060139,
+-1.002737, 6.556976, -6.071414, 3.500000, -0.729781, -0.553122, 0.818963, 0.152824,
+-1.002737, 6.556976, -6.071414, 3.500000, -0.729781, -0.553122, 0.818963, 0.152824,
+-1.002737, 5.785589, -3.493792, 4.000000, -0.536897, -0.556039, 0.785897, 0.270530,
+0.000000, 6.016188, -3.460293, 3.375000, -0.585395, -0.000000, 0.945916, 0.324411,
+0.000000, 6.016188, -3.460293, 3.375000, -0.585395, -0.000000, 0.945916, 0.324411,
+1.002737, 5.785589, -3.493792, 2.968750, -0.549437, 0.556039, 0.785897, 0.270530,
+1.002737, 6.556976, -6.071414, 2.937500, -0.360878, 0.552962, 0.818993, 0.153246,
+1.002737, 4.735826, -0.785002, 2.937500, -0.763077, 0.563593, 0.774459, 0.287360,
+1.002737, 5.785589, -3.493792, 2.968750, -0.549437, 0.556039, 0.785897, 0.270530,
+0.000000, 6.016188, -3.460293, 3.375000, -0.585395, -0.000000, 0.945916, 0.324411,
+0.000000, 6.016188, -3.460293, 3.375000, -0.585395, -0.000000, 0.945916, 0.324411,
+-1.002737, 5.785589, -3.493792, 4.000000, -0.536897, -0.556039, 0.785897, 0.270530,
+-1.002737, 4.735826, -0.785002, 3.500000, -0.729781, -0.563593, 0.774459, 0.287360,
+-1.002737, 4.735826, -0.785002, 3.500000, -0.729781, -0.563593, 0.774459, 0.287360,
+-1.002737, 3.758350, 1.971984, 3.000000, -0.922665, -0.573360, 0.788967, 0.220880,
+0.000000, 3.985586, 2.003372, 3.062500, -0.926955, 0.000000, 0.962477, 0.271365,
+0.000000, 3.985586, 2.003372, 3.062500, -0.926955, 0.000000, 0.962477, 0.271365,
+1.002737, 3.758350, 1.971984, 2.890625, -0.966339, 0.573361, 0.788967, 0.220880,
+1.002737, 4.735826, -0.785002, 2.937500, -0.763077, 0.563593, 0.774459, 0.287360,
+1.002737, 3.203825, 4.694192, 2.875000, -1.123764, 0.573167, 0.812586, 0.105755,
+1.002737, 3.758350, 1.971984, 2.890625, -0.966339, 0.573361, 0.788967, 0.220880,
+0.000000, 3.985586, 2.003372, 3.062500, -0.926955, 0.000000, 0.962477, 0.271365,
+0.000000, 3.985586, 2.003372, 3.062500, -0.926955, 0.000000, 0.962477, 0.271365,
+-1.002737, 3.758350, 1.971984, 3.000000, -0.922665, -0.573360, 0.788967, 0.220880,
+-1.002737, 3.203825, 4.694192, 3.000000, -0.922665, -0.573166, 0.812586, 0.105755,
+-1.002737, 3.203825, 4.694192, 3.000000, -0.922665, -0.573166, 0.812586, 0.105755,
+-1.002737, 3.052929, 7.399012, 3.000000, -0.922665, -0.571504, 0.820505, -0.012461,
+0.000000, 3.277142, 7.389376, 3.000000, -1.114440, 0.000000, 0.999891, -0.014768,
+0.000000, 3.277142, 7.389376, 3.000000, -1.114440, 0.000000, 0.999891, -0.014768,
+1.002737, 3.052929, 7.399012, 3.000000, -1.306215, 0.571504, 0.820504, -0.012461,
+1.002737, 3.203825, 4.694192, 2.875000, -1.123764, 0.573167, 0.812586, 0.105755,
+-0.029414, 5.888605, 17.540989, 2.833333, -1.749232, -0.000556, 0.885983, -0.463718,
+0.973323, 5.677700, 17.631544, 3.000000, -1.776346, 0.576561, 0.724323, -0.378066,
+0.983128, 4.637777, 15.286472, 2.833333, -1.698392, 0.573967, 0.767126, -0.286495,
+0.983128, 4.637777, 15.286472, 2.833333, -1.698392, 0.573967, 0.767126, -0.286495,
+0.997834, 3.836994, 12.751901, 3.000000, -1.613659, 0.571655, 0.794480, -0.204969,
+-0.004902, 4.057320, 12.697225, 2.833333, -1.667888, 0.000259, 0.967531, -0.252752,
+-0.004902, 4.057320, 12.697225, 2.833333, -1.667888, 0.000259, 0.967531, -0.252752,
+-1.007639, 3.836994, 12.751901, 2.666667, -1.722117, -0.571038, 0.793815, -0.209219,
+-1.022346, 4.637777, 15.286472, 2.666667, -1.722117, -0.574184, 0.765044, -0.291584,
+-1.022346, 4.637777, 15.286472, 2.666667, -1.722117, -0.574184, 0.765044, -0.291584,
+-1.032151, 5.677700, 17.631544, 2.666667, -1.722117, -0.577835, 0.723604, -0.377496,
+-0.029414, 5.888605, 17.540989, 2.833333, -1.749232, -0.000556, 0.885983, -0.463718,
+0.000000, 9.573013, 23.419453, 3.500000, -2.000000, -0.000000, 0.997856, 0.065453,
+0.742768, 9.282909, 23.329664, 3.000000, -2.000000, 0.487250, 0.872639, 0.032983,
+1.002737, 9.038933, 22.663582, 3.000000, -1.969517, 0.583232, 0.718345, -0.379238,
+1.002737, 9.038933, 22.663582, 3.000000, -1.969517, 0.583232, 0.718345, -0.379238,
+0.997834, 8.160118, 21.422651, 3.000000, -1.939034, 0.574744, 0.665807, -0.475784,
+-0.004902, 8.361179, 21.300390, 3.500000, -1.939034, 0.000389, 0.815229, -0.579139,
+-0.004902, 8.361179, 21.300390, 3.500000, -1.939034, 0.000389, 0.815229, -0.579139,
+-1.007639, 8.160118, 21.422651, 4.000000, -1.939034, -0.574068, 0.669723, -0.471080,
+-1.002737, 9.038933, 22.663582, 4.000000, -1.969517, -0.582357, 0.720010, -0.377421,
+-1.002737, 9.038933, 22.663582, 4.000000, -1.969517, -0.582357, 0.720010, -0.377421,
+-0.742768, 9.282909, 23.329664, 4.000000, -2.000000, -0.487251, 0.872639, 0.032983,
+0.000000, 9.573013, 23.419453, 3.500000, -2.000000, -0.000000, 0.997856, 0.065453,
+-1.002737, -2.734034, 6.657467, 1.500000, 0.761751, -0.582703, 0.762742, 0.280503,
+-1.002737, -1.996943, 4.816424, 0.000000, 1.000000, -0.580237, 0.756078, 0.302774,
+-1.336982, -2.618040, 4.463405, 0.500000, 1.000000, -0.999977, -0.006223, -0.002555,
+-1.336982, -2.618040, 4.463405, 0.500000, 1.000000, -0.999977, -0.006223, -0.002555,
+-1.002737, -3.239137, 4.110385, 1.000000, 1.000000, -0.573276, -0.760494, -0.304965,
+-1.002737, -3.988198, 5.977939, 1.187500, 0.890530, -0.568961, -0.771457, -0.284847,
+-1.002737, -3.988198, 5.977939, 1.187500, 0.890530, -0.568961, -0.771457, -0.284847,
+-1.002737, -4.824668, 8.406097, 1.000000, 0.817855, -0.564875, -0.790113, -0.237986,
+-1.336982, -4.187579, 8.722692, 2.000000, 0.670678, -0.999851, -0.016874, -0.003651,
+-1.336982, -4.187579, 8.722692, 2.000000, 0.670678, -0.999851, -0.016874, -0.003651,
+-1.002737, -3.550490, 9.039287, 3.000000, 0.523501, -0.582189, 0.779143, 0.232362,
+-1.002737, -2.734034, 6.657467, 1.500000, 0.761751, -0.582703, 0.762742, 0.280503,
+-1.002737, -4.339600, 12.037193, 0.000000, 0.651188, -0.578711, 0.795540, 0.179472,
+-1.002737, -3.550490, 9.039287, 0.000000, 0.817855, -0.582189, 0.779143, 0.232362,
+-1.336982, -4.187579, 8.722692, 0.500000, 0.817855, -0.999851, -0.016874, -0.003651,
+-1.336982, -4.187579, 8.722692, 0.500000, 0.817855, -0.999851, -0.016874, -0.003651,
+-1.002737, -4.824668, 8.406097, 1.000000, 0.817855, -0.564875, -0.790113, -0.237986,
+-1.002737, -5.641894, 11.472322, 1.000000, 0.651188, -0.564280, -0.804601, -0.184946,
+-1.002737, -5.641894, 11.472322, 1.000000, 0.651188, -0.564280, -0.804601, -0.184946,
+-1.002737, -6.318611, 14.911804, 1.000000, 0.470545, -0.563019, -0.816504, -0.127790,
+-1.336982, -5.652997, 15.157051, 0.500000, 0.470545, -0.999903, -0.013895, -0.000479,
+-1.336982, -5.652997, 15.157051, 0.500000, 0.470545, -0.999903, -0.013895, -0.000479,
+-1.002737, -4.987385, 15.402298, 0.000000, 0.484521, -0.576620, 0.807781, 0.122473,
+-1.002737, -4.339600, 12.037193, 0.000000, 0.651188, -0.578711, 0.795540, 0.179472,
+-1.002737, -5.379865, 18.885717, 0.000000, 0.261948, -0.572718, 0.816712, 0.070540,
+-1.002737, -4.987385, 15.402298, 0.000000, 0.484521, -0.576620, 0.807781, 0.122473,
+-1.336982, -5.652997, 15.157051, 0.500000, 0.470545, -0.999903, -0.013895, -0.000479,
+-1.336982, -5.652997, 15.157051, 0.500000, 0.470545, -0.999903, -0.013895, -0.000479,
+-1.002737, -6.318611, 14.911804, 1.000000, 0.470545, -0.563019, -0.816504, -0.127790,
+-1.002737, -6.733546, 18.459730, 1.000000, 0.261948, -0.564150, -0.822280, -0.074773,
+-1.002737, -6.733546, 18.459730, 1.000000, 0.261948, -0.564150, -0.822280, -0.074773,
+-1.002737, -6.957025, 21.947737, 1.000000, 0.047044, -0.566391, -0.823173, -0.039848,
+-1.336982, -6.271589, 22.133167, 0.500000, 0.047044, -0.999991, -0.004281, 0.000323,
+-1.336982, -6.271589, 22.133167, 0.500000, 0.047044, -0.999991, -0.004281, 0.000323,
+-1.002737, -5.586154, 22.318600, 0.000000, 0.039374, -0.570604, 0.820419, 0.036373,
+-1.002737, -5.379865, 18.885717, 0.000000, 0.261948, -0.572718, 0.816712, 0.070540,
+-1.002737, -5.675372, 25.532089, 0.000000, -0.152521, -0.572885, 0.819555, 0.011471,
+-1.002737, -5.586154, 22.318600, 0.000000, 0.039374, -0.570604, 0.820419, 0.036373,
+-1.336982, -6.271589, 22.133167, 0.500000, 0.047044, -0.999991, -0.004281, 0.000323,
+-1.336982, -6.271589, 22.133167, 0.500000, 0.047044, -0.999991, -0.004281, 0.000323,
+-1.002737, -6.957025, 21.947737, 1.000000, 0.047044, -0.566391, -0.823173, -0.039848,
+-1.002737, -7.059372, 25.207462, 1.000000, -0.152521, -0.565822, -0.824400, -0.014526,
+-1.002737, -7.059372, 25.207462, 1.000000, -0.152521, -0.565822, -0.824400, -0.014526,
+-1.002737, -7.074721, 28.664906, 1.000000, -0.338108, -0.564757, -0.825254, 0.002341,
+-1.336982, -6.377152, 28.805500, 0.500000, -0.338108, -0.999930, -0.011845, 0.000045,
+-1.336982, -6.377152, 28.805500, 0.500000, -0.338108, -0.999930, -0.011845, 0.000045,
+-1.002737, -5.679584, 28.946095, 0.000000, -0.344415, -0.577055, 0.816690, -0.004975,
+-1.002737, -5.675372, 25.532089, 0.000000, -0.152521, -0.572885, 0.819555, 0.011471,
+-1.002737, -5.630855, 32.893612, 0.000000, -0.511082, -0.132943, 0.189166, -0.972904,
+-1.002737, -5.679584, 28.946095, 0.000000, -0.344415, -0.577055, 0.816690, -0.004975,
+-1.336982, -6.377152, 28.805500, 0.500000, -0.338108, -0.999930, -0.011845, 0.000045,
+-1.336982, -6.377152, 28.805500, 0.500000, -0.338108, -0.999930, -0.011845, 0.000045,
+-1.002737, -7.074721, 28.664906, 1.000000, -0.338108, -0.564757, -0.825254, 0.002341,
+-1.002737, -7.037199, 32.893612, 1.000000, -0.511082, -0.140149, -0.202450, -0.969212,
+-1.002737, -7.037199, 32.893612, 1.000000, -0.511082, -0.140149, -0.202450, -0.969212,
+-4.193409, -10.256766, 32.893612, 1.027778, -0.557378, -0.685012, -0.716396, 0.132421,
+-5.620958, -6.307936, 32.893612, 0.625000, -0.573582, -0.991757, -0.001005, 0.128133,
+-5.620958, -6.307936, 32.893612, 0.625000, -0.573582, -0.991757, -0.001005, 0.128133,
+-4.193409, -2.445326, 32.893612, 0.000000, -0.594415, -0.686924, 0.716419, 0.121978,
+-1.002737, -5.630855, 32.893612, 0.000000, -0.511082, -0.132943, 0.189166, -0.972904,
+-1.002737, -3.988198, 5.977939, 1.187500, 0.890530, -0.568961, -0.771457, -0.284847,
+-1.002737, -3.239137, 4.110385, 1.000000, 1.000000, -0.573276, -0.760494, -0.304965,
+0.000000, -3.446170, 3.992712, 1.500000, 1.000000, 0.000000, -0.928140, -0.372231,
+0.000000, -3.446170, 3.992712, 1.500000, 1.000000, 0.000000, -0.928140, -0.372231,
+1.002737, -3.239137, 4.110385, 2.000000, 1.000000, 0.573276, -0.760494, -0.304965,
+1.002737, -3.988198, 5.977940, 2.000000, 0.908927, 0.568961, -0.771457, -0.284847,
+1.002737, -3.988198, 5.977940, 2.000000, 0.908927, 0.568961, -0.771457, -0.284847,
+1.002737, -4.824668, 8.406097, 2.000000, 0.798956, 0.564875, -0.790113, -0.237986,
+0.000000, -5.037031, 8.300566, 1.500000, 0.798956, 0.000000, -0.957267, -0.289205,
+0.000000, -5.037031, 8.300566, 1.500000, 0.798956, 0.000000, -0.957267, -0.289205,
+-1.002737, -4.824668, 8.406097, 1.000000, 0.817855, -0.564875, -0.790113, -0.237986,
+-1.002737, -3.988198, 5.977939, 1.187500, 0.890530, -0.568961, -0.771457, -0.284847,
+-1.002737, -5.641894, 11.472322, 1.000000, 0.651188, -0.564280, -0.804601, -0.184946,
+-1.002737, -4.824668, 8.406097, 1.000000, 0.817855, -0.564875, -0.790113, -0.237986,
+0.000000, -5.037031, 8.300566, 1.500000, 0.798956, 0.000000, -0.957267, -0.289205,
+0.000000, -5.037031, 8.300566, 1.500000, 0.798956, 0.000000, -0.957267, -0.289205,
+1.002737, -4.824668, 8.406097, 2.000000, 0.798956, 0.564875, -0.790113, -0.237986,
+1.002737, -5.641894, 11.472323, 2.000000, 0.651188, 0.564280, -0.804601, -0.184946,
+1.002737, -5.641894, 11.472323, 2.000000, 0.651188, 0.564280, -0.804601, -0.184946,
+1.002737, -6.318611, 14.911802, 2.000000, 0.470545, 0.563019, -0.816504, -0.127790,
+0.000000, -6.540482, 14.830055, 1.500000, 0.470545, -0.000000, -0.987788, -0.155806,
+0.000000, -6.540482, 14.830055, 1.500000, 0.470545, -0.000000, -0.987788, -0.155806,
+-1.002737, -6.318611, 14.911804, 1.000000, 0.470545, -0.563019, -0.816504, -0.127790,
+-1.002737, -5.641894, 11.472322, 1.000000, 0.651188, -0.564280, -0.804601, -0.184946,
+-1.002737, -6.733546, 18.459730, 1.000000, 0.261948, -0.564150, -0.822280, -0.074773,
+-1.002737, -6.318611, 14.911804, 1.000000, 0.470545, -0.563019, -0.816504, -0.127790,
+0.000000, -6.540482, 14.830055, 1.500000, 0.470545, -0.000000, -0.987788, -0.155806,
+0.000000, -6.540482, 14.830055, 1.500000, 0.470545, -0.000000, -0.987788, -0.155806,
+1.002737, -6.318611, 14.911802, 2.000000, 0.470545, 0.563019, -0.816504, -0.127790,
+1.002737, -6.733546, 18.459730, 2.000000, 0.261948, 0.564150, -0.822280, -0.074773,
+1.002737, -6.733546, 18.459730, 2.000000, 0.261948, 0.564150, -0.822280, -0.074773,
+1.002737, -6.957025, 21.947737, 2.000000, 0.047044, 0.566391, -0.823173, -0.039848,
+0.000000, -7.185503, 21.885925, 1.500000, 0.047044, 0.000000, -0.998796, -0.049054,
+0.000000, -7.185503, 21.885925, 1.500000, 0.047044, 0.000000, -0.998796, -0.049054,
+-1.002737, -6.957025, 21.947737, 1.000000, 0.047044, -0.566391, -0.823173, -0.039848,
+-1.002737, -6.733546, 18.459730, 1.000000, 0.261948, -0.564150, -0.822280, -0.074773,
+-1.002737, -7.059372, 25.207462, 1.000000, -0.152521, -0.565822, -0.824400, -0.014526,
+-1.002737, -6.957025, 21.947737, 1.000000, 0.047044, -0.566391, -0.823173, -0.039848,
+0.000000, -7.185503, 21.885925, 1.500000, 0.047044, 0.000000, -0.998796, -0.049054,
+0.000000, -7.185503, 21.885925, 1.500000, 0.047044, 0.000000, -0.998796, -0.049054,
+1.002737, -6.957025, 21.947737, 2.000000, 0.047044, 0.566391, -0.823173, -0.039848,
+1.002737, -7.059372, 25.207462, 2.000000, -0.152521, 0.565821, -0.824400, -0.014526,
+1.002737, -7.059372, 25.207462, 2.000000, -0.152521, 0.565821, -0.824400, -0.014526,
+1.002737, -7.074721, 28.664906, 2.000000, -0.338108, 0.564757, -0.825254, 0.002341,
+0.000000, -7.307243, 28.618042, 1.500000, -0.338108, 0.000000, -0.999997, 0.002440,
+0.000000, -7.307243, 28.618042, 1.500000, -0.338108, 0.000000, -0.999997, 0.002440,
+-1.002737, -7.074721, 28.664906, 1.000000, -0.338108, -0.564757, -0.825254, 0.002341,
+-1.002737, -7.059372, 25.207462, 1.000000, -0.152521, -0.565822, -0.824400, -0.014526,
+-1.002737, -7.037199, 32.893612, 1.000000, -0.511082, -0.140149, -0.202450, -0.969212,
+-1.002737, -7.074721, 28.664906, 1.000000, -0.338108, -0.564757, -0.825254, 0.002341,
+0.000000, -7.307243, 28.618042, 1.500000, -0.338108, 0.000000, -0.999997, 0.002440,
+0.000000, -7.307243, 28.618042, 1.500000, -0.338108, 0.000000, -0.999997, 0.002440,
+1.002737, -7.074721, 28.664906, 2.000000, -0.338108, 0.564757, -0.825254, 0.002341,
+1.002737, -7.037199, 32.893612, 2.000000, -0.511082, 0.140149, -0.202450, -0.969212,
+1.002737, -7.037199, 32.893612, 2.000000, -0.511082, 0.140149, -0.202450, -0.969212,
+4.193409, -10.256766, 32.893612, 1.972222, -0.557378, 0.680284, -0.725440, 0.104643,
+0.000000, -11.548096, 32.893612, 1.500000, -0.573582, -0.004203, -0.998166, 0.060395,
+0.000000, -11.548096, 32.893612, 1.500000, -0.573582, -0.004203, -0.998166, 0.060395,
+-4.193409, -10.256766, 32.893612, 1.027778, -0.557378, -0.685012, -0.716396, 0.132421,
+-1.002737, -7.037199, 32.893612, 1.000000, -0.511082, -0.140149, -0.202450, -0.969212,
+1.002737, -3.988198, 5.977940, 2.000000, 0.908927, 0.568961, -0.771457, -0.284847,
+1.002737, -3.239137, 4.110385, 2.000000, 1.000000, 0.573276, -0.760494, -0.304965,
+1.336982, -2.618040, 4.463405, 2.500000, 1.000000, 0.999977, -0.006223, -0.002555,
+1.336982, -2.618040, 4.463405, 2.500000, 1.000000, 0.999977, -0.006223, -0.002555,
+1.002737, -1.996943, 4.816424, 3.000000, 1.000000, 0.580237, 0.756078, 0.302774,
+1.002737, -2.734034, 6.657467, 3.000000, 0.908927, 0.582703, 0.762742, 0.280503,
+1.002737, -2.734034, 6.657467, 3.000000, 0.908927, 0.582703, 0.762742, 0.280503,
+1.002737, -3.550490, 9.039287, 3.000000, 0.798956, 0.582189, 0.779143, 0.232362,
+1.336982, -4.187579, 8.722693, 2.500000, 0.798956, 0.999851, -0.016874, -0.003651,
+1.336982, -4.187579, 8.722693, 2.500000, 0.798956, 0.999851, -0.016874, -0.003651,
+1.002737, -4.824668, 8.406097, 2.000000, 0.798956, 0.564875, -0.790113, -0.237986,
+1.002737, -3.988198, 5.977940, 2.000000, 0.908927, 0.568961, -0.771457, -0.284847,
+1.002737, -5.641894, 11.472323, 2.000000, 0.651188, 0.564280, -0.804601, -0.184946,
+1.002737, -4.824668, 8.406097, 2.000000, 0.798956, 0.564875, -0.790113, -0.237986,
+1.336982, -4.187579, 8.722693, 2.500000, 0.798956, 0.999851, -0.016874, -0.003651,
+1.336982, -4.187579, 8.722693, 2.500000, 0.798956, 0.999851, -0.016874, -0.003651,
+1.002737, -3.550490, 9.039287, 3.000000, 0.798956, 0.582189, 0.779143, 0.232362,
+1.002737, -4.339600, 12.037193, 3.000000, 0.651188, 0.578711, 0.795540, 0.179472,
+1.002737, -4.339600, 12.037193, 3.000000, 0.651188, 0.578711, 0.795540, 0.179472,
+1.002737, -4.987385, 15.402298, 3.000000, 0.470545, 0.576620, 0.807781, 0.122473,
+1.336982, -5.652997, 15.157051, 2.500000, 0.470545, 0.999903, -0.013895, -0.000479,
+1.336982, -5.652997, 15.157051, 2.500000, 0.470545, 0.999903, -0.013895, -0.000479,
+1.002737, -6.318611, 14.911802, 2.000000, 0.470545, 0.563019, -0.816504, -0.127790,
+1.002737, -5.641894, 11.472323, 2.000000, 0.651188, 0.564280, -0.804601, -0.184946,
+1.002737, -6.733546, 18.459730, 2.000000, 0.261948, 0.564150, -0.822280, -0.074773,
+1.002737, -6.318611, 14.911802, 2.000000, 0.470545, 0.563019, -0.816504, -0.127790,
+1.336982, -5.652997, 15.157051, 2.500000, 0.470545, 0.999903, -0.013895, -0.000479,
+1.336982, -5.652997, 15.157051, 2.500000, 0.470545, 0.999903, -0.013895, -0.000479,
+1.002737, -4.987385, 15.402298, 3.000000, 0.470545, 0.576620, 0.807781, 0.122473,
+1.002737, -5.379865, 18.885717, 3.000000, 0.261948, 0.572718, 0.816712, 0.070540,
+1.002737, -5.379865, 18.885717, 3.000000, 0.261948, 0.572718, 0.816712, 0.070540,
+1.002737, -5.586154, 22.318600, 3.000000, 0.047044, 0.570604, 0.820419, 0.036373,
+1.336982, -6.271589, 22.133167, 2.500000, 0.047044, 0.999991, -0.004281, 0.000323,
+1.336982, -6.271589, 22.133167, 2.500000, 0.047044, 0.999991, -0.004281, 0.000323,
+1.002737, -6.957025, 21.947737, 2.000000, 0.047044, 0.566391, -0.823173, -0.039848,
+1.002737, -6.733546, 18.459730, 2.000000, 0.261948, 0.564150, -0.822280, -0.074773,
+1.002737, -7.059372, 25.207462, 2.000000, -0.152521, 0.565821, -0.824400, -0.014526,
+1.002737, -6.957025, 21.947737, 2.000000, 0.047044, 0.566391, -0.823173, -0.039848,
+1.336982, -6.271589, 22.133167, 2.500000, 0.047044, 0.999991, -0.004281, 0.000323,
+1.336982, -6.271589, 22.133167, 2.500000, 0.047044, 0.999991, -0.004281, 0.000323,
+1.002737, -5.586154, 22.318600, 3.000000, 0.047044, 0.570604, 0.820419, 0.036373,
+1.002737, -5.675372, 25.532089, 3.000000, -0.152521, 0.572885, 0.819555, 0.011471,
+1.002737, -5.675372, 25.532089, 3.000000, -0.152521, 0.572885, 0.819555, 0.011471,
+1.002737, -5.679584, 28.946095, 3.000000, -0.338108, 0.577055, 0.816690, -0.004975,
+1.336982, -6.377152, 28.805500, 2.500000, -0.338108, 0.999930, -0.011845, 0.000045,
+1.336982, -6.377152, 28.805500, 2.500000, -0.338108, 0.999930, -0.011845, 0.000045,
+1.002737, -7.074721, 28.664906, 2.000000, -0.338108, 0.564757, -0.825254, 0.002341,
+1.002737, -7.059372, 25.207462, 2.000000, -0.152521, 0.565821, -0.824400, -0.014526,
+1.002737, -7.037199, 32.893612, 2.000000, -0.511082, 0.140149, -0.202450, -0.969212,
+1.002737, -7.074721, 28.664906, 2.000000, -0.338108, 0.564757, -0.825254, 0.002341,
+1.336982, -6.377152, 28.805500, 2.500000, -0.338108, 0.999930, -0.011845, 0.000045,
+1.336982, -6.377152, 28.805500, 2.500000, -0.338108, 0.999930, -0.011845, 0.000045,
+1.002737, -5.679584, 28.946095, 3.000000, -0.338108, 0.577055, 0.816690, -0.004975,
+1.002737, -5.630855, 32.893612, 3.000000, -0.511082, 0.132943, 0.189166, -0.972904,
+1.002737, -5.630855, 32.893612, 3.000000, -0.511082, 0.132943, 0.189166, -0.972904,
+4.193409, -2.445326, 32.893612, 3.000000, -0.594415, 0.682263, 0.725032, 0.094055,
+5.620958, -6.307936, 32.893612, 2.375000, -0.573582, 0.996241, -0.000983, 0.086619,
+5.620958, -6.307936, 32.893612, 2.375000, -0.573582, 0.996241, -0.000983, 0.086619,
+4.193409, -10.256766, 32.893612, 1.972222, -0.557378, 0.680284, -0.725440, 0.104643,
+1.002737, -7.037199, 32.893612, 2.000000, -0.511082, 0.140149, -0.202450, -0.969212,
+-1.002737, -1.445931, 3.440848, 2.500000, -1.666667, -0.596303, 0.745197, 0.298504,
+-1.002737, -1.996943, 4.816424, 3.000000, -1.666667, -0.580237, 0.756078, 0.302774,
+0.000000, -1.789911, 4.934098, 3.000000, -1.833333, -0.000000, 0.928348, 0.371713,
+0.000000, -1.789911, 4.934098, 3.000000, -1.833333, -0.000000, 0.928348, 0.371713,
+1.002737, -1.996943, 4.816424, 3.000000, -2.000000, 0.580237, 0.756078, 0.302774,
+1.002737, -1.445931, 3.440848, 2.500000, -2.000000, 0.596303, 0.745197, 0.298504,
+1.002737, -2.734034, 6.657467, 3.000000, 0.908927, 0.582703, 0.762742, 0.280503,
+1.002737, -1.996943, 4.816424, 3.000000, 1.000000, 0.580237, 0.756078, 0.302774,
+0.000000, -1.789911, 4.934098, 3.500000, 1.000000, -0.000000, 0.928348, 0.371713,
+0.000000, -1.789911, 4.934098, 3.500000, 1.000000, -0.000000, 0.928348, 0.371713,
+-1.002737, -1.996943, 4.816424, 4.000000, 1.000000, -0.580237, 0.756078, 0.302774,
+-1.002737, -2.734034, 6.657467, 4.000000, 0.908927, -0.582703, 0.762742, 0.280503,
+-1.002737, -2.734034, 6.657467, 4.000000, 0.908927, -0.582703, 0.762742, 0.280503,
+-1.002737, -3.550490, 9.039287, 4.000000, 0.817855, -0.582189, 0.779143, 0.232362,
+0.000000, -3.338127, 9.144818, 3.500000, 0.798956, 0.000000, 0.958542, 0.284953,
+0.000000, -3.338127, 9.144818, 3.500000, 0.798956, 0.000000, 0.958542, 0.284953,
+1.002737, -3.550490, 9.039287, 3.000000, 0.798956, 0.582189, 0.779143, 0.232362,
+1.002737, -2.734034, 6.657467, 3.000000, 0.908927, 0.582703, 0.762742, 0.280503,
+1.002737, -4.339600, 12.037193, 3.000000, 0.651188, 0.578711, 0.795540, 0.179472,
+1.002737, -3.550490, 9.039287, 3.000000, 0.798956, 0.582189, 0.779143, 0.232362,
+0.000000, -3.338127, 9.144818, 3.500000, 0.798956, 0.000000, 0.958542, 0.284953,
+0.000000, -3.338127, 9.144818, 3.500000, 0.798956, 0.000000, 0.958542, 0.284953,
+-1.002737, -3.550490, 9.039287, 4.000000, 0.817855, -0.582189, 0.779143, 0.232362,
+-1.002737, -4.339600, 12.037193, 4.000000, 0.651188, -0.578711, 0.795540, 0.179472,
+-1.002737, -4.339600, 12.037193, 4.000000, 0.651188, -0.578711, 0.795540, 0.179472,
+-1.002737, -4.987385, 15.402298, 4.000000, 0.484521, -0.576620, 0.807781, 0.122473,
+0.000000, -4.765513, 15.484047, 3.500000, 0.470545, 0.000000, 0.988884, 0.148690,
+0.000000, -4.765513, 15.484047, 3.500000, 0.470545, 0.000000, 0.988884, 0.148690,
+1.002737, -4.987385, 15.402298, 3.000000, 0.470545, 0.576620, 0.807781, 0.122473,
+1.002737, -4.339600, 12.037193, 3.000000, 0.651188, 0.578711, 0.795540, 0.179472,
+1.002737, -5.379865, 18.885717, 3.000000, 0.261948, 0.572718, 0.816712, 0.070540,
+1.002737, -4.987385, 15.402298, 3.000000, 0.470545, 0.576620, 0.807781, 0.122473,
+0.000000, -4.765513, 15.484047, 3.500000, 0.470545, 0.000000, 0.988884, 0.148690,
+0.000000, -4.765513, 15.484047, 3.500000, 0.470545, 0.000000, 0.988884, 0.148690,
+-1.002737, -4.987385, 15.402298, 4.000000, 0.484521, -0.576620, 0.807781, 0.122473,
+-1.002737, -5.379865, 18.885717, 4.000000, 0.261948, -0.572718, 0.816712, 0.070540,
+-1.002737, -5.379865, 18.885717, 4.000000, 0.261948, -0.572718, 0.816712, 0.070540,
+-1.002737, -5.586154, 22.318600, 4.000000, 0.039374, -0.570604, 0.820419, 0.036373,
+0.000000, -5.357677, 22.380409, 3.500000, 0.047044, -0.000000, 0.999050, 0.043579,
+0.000000, -5.357677, 22.380409, 3.500000, 0.047044, -0.000000, 0.999050, 0.043579,
+1.002737, -5.586154, 22.318600, 3.000000, 0.047044, 0.570604, 0.820419, 0.036373,
+1.002737, -5.379865, 18.885717, 3.000000, 0.261948, 0.572718, 0.816712, 0.070540,
+1.002737, -5.675372, 25.532089, 3.000000, -0.152521, 0.572885, 0.819555, 0.011471,
+1.002737, -5.586154, 22.318600, 3.000000, 0.047044, 0.570604, 0.820419, 0.036373,
+0.000000, -5.357677, 22.380409, 3.500000, 0.047044, -0.000000, 0.999050, 0.043579,
+0.000000, -5.357677, 22.380409, 3.500000, 0.047044, -0.000000, 0.999050, 0.043579,
+-1.002737, -5.586154, 22.318600, 4.000000, 0.039374, -0.570604, 0.820419, 0.036373,
+-1.002737, -5.675372, 25.532089, 4.000000, -0.152521, -0.572885, 0.819555, 0.011471,
+-1.002737, -5.675372, 25.532089, 4.000000, -0.152521, -0.572885, 0.819555, 0.011471,
+-1.002737, -5.679584, 28.946095, 4.000000, -0.344415, -0.577055, 0.816690, -0.004975,
+0.000000, -5.447061, 28.992958, 3.500000, -0.338108, 0.000000, 0.999979, -0.006525,
+0.000000, -5.447061, 28.992958, 3.500000, -0.338108, 0.000000, 0.999979, -0.006525,
+1.002737, -5.679584, 28.946095, 3.000000, -0.338108, 0.577055, 0.816690, -0.004975,
+1.002737, -5.675372, 25.532089, 3.000000, -0.152521, 0.572885, 0.819555, 0.011471,
+1.002737, -5.630855, 32.893612, 3.000000, -0.511082, 0.132943, 0.189166, -0.972904,
+1.002737, -5.679584, 28.946095, 3.000000, -0.338108, 0.577055, 0.816690, -0.004975,
+0.000000, -5.447061, 28.992958, 3.500000, -0.338108, 0.000000, 0.999979, -0.006525,
+0.000000, -5.447061, 28.992958, 3.500000, -0.338108, 0.000000, 0.999979, -0.006525,
+-1.002737, -5.679584, 28.946095, 4.000000, -0.344415, -0.577055, 0.816690, -0.004975,
+-1.002737, -5.630855, 32.893612, 4.000000, -0.511082, -0.132943, 0.189166, -0.972904,
+-1.002737, -5.630855, 32.893612, 4.000000, -0.511082, -0.132943, 0.189166, -0.972904,
+-4.193409, -2.445326, 32.893612, 4.000000, -0.594415, -0.686924, 0.716419, 0.121978,
+0.000000, -1.067776, 32.893612, 3.500000, -0.594415, -0.004492, 0.998437, 0.055707,
+0.000000, -1.067776, 32.893612, 3.500000, -0.594415, -0.004492, 0.998437, 0.055707,
+4.193409, -2.445326, 32.893612, 3.000000, -0.594415, 0.682263, 0.725032, 0.094055,
+1.002737, -5.630855, 32.893612, 3.000000, -0.511082, 0.132943, 0.189166, -0.972904,
+-1.002737, -2.684134, 2.725971, 3.500000, -1.666667, -0.555812, -0.771611, -0.309336,
+-1.002737, -3.239137, 4.110385, 4.000000, -1.666667, -0.573276, -0.760494, -0.304965,
+-1.336982, -2.618040, 4.463405, 4.000000, -1.833333, -0.999977, -0.006223, -0.002555,
+-1.336982, -2.618040, 4.463405, 4.000000, -1.833333, -0.999977, -0.006223, -0.002555,
+-1.002737, -1.996943, 4.816424, 4.000000, -2.000000, -0.580237, 0.756078, 0.302774,
+-1.002737, -1.445931, 3.440848, 3.500000, -2.000000, -0.596303, 0.745197, 0.298504,
+1.002737, -2.684134, 2.725971, 4.500000, -1.666667, 0.555812, -0.771611, -0.309336,
+1.002737, -3.239137, 4.110385, 5.000000, -1.666667, 0.573276, -0.760494, -0.304965,
+0.000000, -3.446170, 3.992712, 5.000000, -1.833333, 0.000000, -0.928140, -0.372231,
+0.000000, -3.446170, 3.992712, 5.000000, -1.833333, 0.000000, -0.928140, -0.372231,
+-1.002737, -3.239137, 4.110385, 5.000000, -2.000000, -0.573276, -0.760494, -0.304965,
+-1.002737, -2.684134, 2.725971, 4.500000, -2.000000, -0.555812, -0.771611, -0.309336,
+-1.336982, -22.914524, -4.929887, 7.000000, -1.833333, -0.999805, -0.016666, 0.010584,
+-1.002737, -22.289114, -5.237599, 7.000000, -1.666667, -0.580101, 0.726129, -0.369081,
+-1.002737, -22.791559, -6.324653, 6.500000, -1.666667, -0.585182, 0.679392, -0.442706,
+-1.002737, -22.791559, -6.324653, 6.500000, -1.666667, -0.585182, 0.679392, -0.442706,
+-0.742768, -23.169422, -6.772669, 6.000000, -1.666667, -0.444774, 0.383424, -0.809421,
+-1.002737, -23.736286, -6.771559, 6.000000, -1.833333, -0.633041, -0.276747, -0.722959,
+-1.002737, -23.736286, -6.771559, 6.000000, -1.833333, -0.633041, -0.276747, -0.722959,
+-0.742768, -24.152987, -6.401496, 6.000000, -2.000000, -0.455754, -0.834431, -0.309862,
+-1.002737, -24.101816, -5.795360, 6.500000, -2.000000, -0.571338, -0.788867, 0.226409,
+-1.002737, -24.101816, -5.795360, 6.500000, -2.000000, -0.571338, -0.788867, 0.226409,
+-1.002737, -23.539934, -4.622173, 7.000000, -2.000000, -0.559738, -0.733607, 0.385376,
+-1.336982, -22.914524, -4.929887, 7.000000, -1.833333, -0.999805, -0.016666, 0.010584,
+-1.336982, -20.877926, -1.798224, 0.500000, 4.901888, -0.999242, -0.027513, 0.027552,
+-1.002737, -20.362839, -2.232996, 1.000000, 4.901887, -0.577401, 0.607255, -0.545756,
+-1.002737, -21.510138, -3.803390, 1.000000, 4.957545, -0.579339, 0.686160, -0.439944,
+-1.002737, -21.510138, -3.803390, 1.000000, 4.957545, -0.579339, 0.686160, -0.439944,
+-1.002737, -22.289114, -5.237599, 1.000000, 5.000000, -0.580101, 0.726129, -0.369081,
+-1.336982, -22.914524, -4.929887, 0.500000, 5.000000, -0.999805, -0.016666, 0.010584,
+-1.336982, -22.914524, -4.929887, 0.500000, 5.000000, -0.999805, -0.016666, 0.010584,
+-1.002737, -23.539934, -4.622173, 0.000000, 5.000000, -0.559738, -0.733607, 0.385376,
+-1.002737, -22.670450, -3.070609, 0.000000, 4.957545, -0.549531, -0.697669, 0.459646,
+-1.002737, -22.670450, -3.070609, 0.000000, 4.957545, -0.549531, -0.697669, 0.459646,
+-1.002737, -21.393009, -1.363454, 0.000000, 4.915090, -0.538985, -0.621423, 0.568620,
+-1.336982, -20.877926, -1.798224, 0.500000, 4.901888, -0.999242, -0.027513, 0.027552,
+-1.336982, -17.125900, 1.021948, 0.500000, 4.706708, -0.998755, -0.017888, 0.046575,
+-1.002737, -16.806824, 0.450041, 1.000000, 4.706708, -0.570721, 0.333495, -0.750372,
+-1.002737, -18.755436, -0.737389, 1.000000, 4.819824, -0.571841, 0.493951, -0.654989,
+-1.002737, -18.755436, -0.737389, 1.000000, 4.819824, -0.571841, 0.493951, -0.654989,
+-1.002737, -20.362839, -2.232996, 1.000000, 4.901887, -0.577401, 0.607255, -0.545756,
+-1.336982, -20.877926, -1.798224, 0.500000, 4.901888, -0.999242, -0.027513, 0.027552,
+-1.336982, -20.877926, -1.798224, 0.500000, 4.901888, -0.999242, -0.027513, 0.027552,
+-1.002737, -21.393009, -1.363454, 0.000000, 4.915090, -0.538985, -0.621423, 0.568620,
+-1.002737, -19.607264, 0.276508, 0.000000, 4.819824, -0.531663, -0.507888, 0.677779,
+-1.002737, -19.607264, 0.276508, 0.000000, 4.819824, -0.531663, -0.507888, 0.677779,
+-1.002737, -17.444981, 1.593854, 0.000000, 4.724558, -0.523473, -0.350048, 0.776815,
+-1.336982, -17.125900, 1.021948, 0.500000, 4.706708, -0.998755, -0.017888, 0.046575,
+-1.336982, -12.461710, 1.998980, 0.500000, 4.382352, -0.999581, -0.002143, 0.028884,
+-1.002737, -12.384212, 1.352605, 1.000000, 4.382352, -0.556840, 0.051516, -0.829021,
+-1.002737, -14.635897, 1.095908, 1.000000, 4.557891, -0.560822, 0.165222, -0.811283,
+-1.002737, -14.635897, 1.095908, 1.000000, 4.557891, -0.560822, 0.165222, -0.811283,
+-1.002737, -16.806824, 0.450041, 1.000000, 4.706708, -0.570721, 0.333495, -0.750372,
+-1.336982, -17.125900, 1.021948, 0.500000, 4.706708, -0.998755, -0.017888, 0.046575,
+-1.336982, -17.125900, 1.021948, 0.500000, 4.706708, -0.998755, -0.017888, 0.046575,
+-1.002737, -17.444981, 1.593854, 0.000000, 4.724558, -0.523473, -0.350048, 0.776815,
+-1.002737, -15.037928, 2.333167, 0.000000, 4.557892, -0.524224, -0.178780, 0.832603,
+-1.002737, -15.037928, 2.333167, 0.000000, 4.557892, -0.524224, -0.178780, 0.832603,
+-1.002737, -12.539209, 2.645355, 0.000000, 4.391225, -0.529316, -0.059790, 0.846315,
+-1.336982, -12.461710, 1.998980, 0.500000, 4.382352, -0.999581, -0.002143, 0.028884,
+-1.336982, -8.028582, 1.726443, 0.500000, 3.977933, -0.998903, 0.011916, 0.045285,
+-1.002737, -8.188779, 1.086162, 1.000000, 3.977933, -0.571796, -0.203921, -0.794648,
+-1.002737, -10.193326, 1.372527, 1.000000, 4.189068, -0.563923, -0.052320, -0.824168,
+-1.002737, -10.193326, 1.372527, 1.000000, 4.189068, -0.563923, -0.052320, -0.824168,
+-1.002737, -12.384212, 1.352605, 1.000000, 4.382352, -0.556840, 0.051516, -0.829021,
+-1.336982, -12.461710, 1.998980, 0.500000, 4.382352, -0.999581, -0.002143, 0.028884,
+-1.336982, -12.461710, 1.998980, 0.500000, 4.382352, -0.999581, -0.002143, 0.028884,
+-1.002737, -12.539209, 2.645355, 0.000000, 4.391225, -0.529316, -0.059790, 0.846315,
+-1.002737, -10.101929, 2.681329, 0.000000, 4.189068, -0.529646, 0.050516, 0.846713,
+-1.002737, -10.101929, 2.681329, 0.000000, 4.189068, -0.529646, 0.050516, 0.846713,
+-1.002737, -7.868385, 2.366725, 0.000000, 3.986911, -0.526810, 0.210598, 0.823480,
+-1.336982, -8.028582, 1.726443, 0.500000, 3.977933, -0.998903, 0.011916, 0.045285,
+-1.336982, -4.681401, -0.053863, 0.500000, 3.518014, -0.999076, 0.030579, 0.030219,
+-1.002737, -5.023273, -0.595701, 1.000000, 3.518014, -0.554291, -0.537252, -0.635706,
+-1.002737, -6.496116, 0.423996, 1.000000, 3.748844, -0.567467, -0.386666, -0.726960,
+-1.002737, -6.496116, 0.423996, 1.000000, 3.748844, -0.567467, -0.386666, -0.726960,
+-1.002737, -8.188779, 1.086162, 1.000000, 3.977933, -0.571796, -0.203921, -0.794648,
+-1.336982, -8.028582, 1.726443, 0.500000, 3.977933, -0.998903, 0.011916, 0.045285,
+-1.336982, -8.028582, 1.726443, 0.500000, 3.977933, -0.998903, 0.011916, 0.045285,
+-1.002737, -7.868385, 2.366725, 0.000000, 3.986911, -0.526810, 0.210598, 0.823480,
+-1.002737, -5.980879, 1.627182, 0.000000, 3.748844, -0.522694, 0.400366, 0.752661,
+-1.002737, -5.980879, 1.627182, 0.000000, 3.748844, -0.522694, 0.400366, 0.752661,
+-1.002737, -4.339529, 0.487975, 0.000000, 3.510776, -0.515414, 0.553092, 0.654552,
+-1.336982, -4.681401, -0.053863, 0.500000, 3.518014, -0.999076, 0.030579, 0.030219,
+-1.336982, -2.032626, -3.152671, 0.500000, 3.096704, -0.999446, 0.028671, 0.016899,
+-1.002737, -2.514818, -3.530164, 1.000000, 3.096704, -0.535283, -0.710141, -0.457353,
+-1.002737, -3.678185, -1.954659, 1.000000, 3.301661, -0.541786, -0.639146, -0.545858,
+-1.002737, -3.678185, -1.954659, 1.000000, 3.301661, -0.541786, -0.639146, -0.545858,
+-1.002737, -5.023273, -0.595701, 1.000000, 3.518014, -0.554291, -0.537252, -0.635706,
+-1.336982, -4.681401, -0.053863, 0.500000, 3.518014, -0.999076, 0.030579, 0.030219,
+-1.336982, -4.681401, -0.053863, 0.500000, 3.518014, -0.999076, 0.030579, 0.030219,
+-1.002737, -4.339529, 0.487975, 0.000000, 3.510776, -0.515414, 0.553092, 0.654552,
+-1.002737, -2.844458, -1.025621, 0.000000, 3.301661, -0.509526, 0.653879, 0.559309,
+-1.002737, -2.844458, -1.025621, 0.000000, 3.301661, -0.509526, 0.653879, 0.559309,
+-1.002737, -1.550434, -2.775177, 0.000000, 3.092546, -0.505987, 0.723592, 0.469458,
+-1.336982, -2.032626, -3.152671, 0.500000, 3.096704, -0.999446, 0.028671, 0.016899,
+-1.336982, -0.371475, -6.820555, 0.500000, 2.714038, -0.999078, 0.041649, 0.010372,
+-1.002737, -0.955311, -7.018215, 1.000000, 2.714038, -0.543592, -0.816934, -0.192683,
+-1.002737, -1.587135, -5.199499, 1.000000, 2.900065, -0.538039, -0.769598, -0.343850,
+-1.002737, -1.587135, -5.199499, 1.000000, 2.900065, -0.538039, -0.769598, -0.343850,
+-1.002737, -2.514818, -3.530164, 1.000000, 3.096704, -0.535283, -0.710141, -0.457353,
+-1.336982, -2.032626, -3.152671, 0.500000, 3.096704, -0.999446, 0.028671, 0.016899,
+-1.336982, -2.032626, -3.152671, 0.500000, 3.096704, -0.999446, 0.028671, 0.016899,
+-1.002737, -1.550434, -2.775177, 0.000000, 3.092546, -0.505987, 0.723592, 0.469458,
+-1.002737, -0.512230, -4.622262, 0.000000, 2.900065, -0.503207, 0.785550, 0.360132,
+-1.002737, -0.512230, -4.622262, 0.000000, 2.900065, -0.503207, 0.785550, 0.360132,
+-1.002737, 0.212360, -6.622896, 0.000000, 2.707584, -0.505652, 0.835716, 0.214230,
+-1.336982, -0.371475, -6.820555, 0.500000, 2.714038, -0.999078, 0.041649, 0.010372,
+-1.336982, -0.183937, -11.115767, 0.500000, 2.371212, -0.999002, 0.043336, -0.010816,
+-1.002737, -0.835270, -11.133001, 1.000000, 2.371212, -0.556778, -0.814518, 0.162970,
+-1.002737, -0.679522, -9.041862, 1.000000, 2.540917, -0.550509, -0.834486, -0.023924,
+-1.002737, -0.679522, -9.041862, 1.000000, 2.540917, -0.550509, -0.834486, -0.023924,
+-1.002737, -0.955311, -7.018215, 1.000000, 2.714038, -0.543592, -0.816934, -0.192683,
+-1.336982, -0.371475, -6.820555, 0.500000, 2.714038, -0.999078, 0.041649, 0.010372,
+-1.336982, -0.371475, -6.820555, 0.500000, 2.714038, -0.999078, 0.041649, 0.010372,
+-1.002737, 0.212360, -6.622896, 0.000000, 2.707584, -0.505652, 0.835716, 0.214230,
+-1.002737, 0.565540, -8.833092, 0.000000, 2.540917, -0.512670, 0.857167, 0.049331,
+-1.002737, 0.565540, -8.833092, 0.000000, 2.540917, -0.512670, 0.857167, 0.049331,
+-1.002737, 0.467394, -11.098533, 0.000000, 2.374251, -0.517497, 0.844529, -0.137721,
+-1.336982, -0.183937, -11.115767, 0.500000, 2.371212, -0.999002, 0.043336, -0.010816,
+-1.336982, -1.762512, -15.300098, 0.500000, 2.020624, -0.999977, 0.006790, -0.000522,
+-1.002737, -2.439466, -15.191065, 1.000000, 2.020624, -0.552162, -0.756555, 0.350343,
+-1.002737, -1.498060, -13.154191, 1.000000, 2.195430, -0.550846, -0.775955, 0.307348,
+-1.002737, -1.498060, -13.154191, 1.000000, 2.195430, -0.550846, -0.775955, 0.307348,
+-1.002737, -0.835270, -11.133001, 1.000000, 2.371212, -0.556778, -0.814518, 0.162970,
+-1.336982, -0.183937, -11.115767, 0.500000, 2.371212, -0.999002, 0.043336, -0.010816,
+-1.336982, -0.183937, -11.115767, 0.500000, 2.371212, -0.999002, 0.043336, -0.010816,
+-1.002737, 0.467394, -11.098533, 0.000000, 2.374251, -0.517497, 0.844529, -0.137721,
+-1.002737, -0.161999, -13.264900, 0.000000, 2.195430, -0.528455, 0.798898, -0.287224,
+-1.002737, -0.161999, -13.264900, 0.000000, 2.195430, -0.528455, 0.798898, -0.287224,
+-1.002737, -1.085560, -15.409132, 0.000000, 2.016609, -0.545979, 0.767296, -0.336399,
+-1.336982, -1.762512, -15.300098, 0.500000, 2.020624, -0.999977, 0.006790, -0.000522,
+-1.336982, -3.677238, -19.700720, 0.500000, 1.696742, -0.999943, -0.009227, 0.005371,
+-1.002737, -4.363696, -19.552979, 1.000000, 1.696742, -0.563275, -0.773529, 0.290474,
+-1.002737, -3.431055, -17.329250, 1.000000, 1.853850, -0.559291, -0.758482, 0.334513,
+-1.002737, -3.431055, -17.329250, 1.000000, 1.853850, -0.559291, -0.758482, 0.334513,
+-1.002737, -2.439466, -15.191065, 1.000000, 2.020624, -0.552162, -0.756555, 0.350343,
+-1.336982, -1.762512, -15.300098, 0.500000, 2.020624, -0.999977, 0.006790, -0.000522,
+-1.336982, -1.762512, -15.300098, 0.500000, 2.020624, -0.999977, 0.006790, -0.000522,
+-1.002737, -1.085560, -15.409132, 0.000000, 2.016609, -0.545979, 0.767296, -0.336399,
+-1.002737, -2.066217, -17.608171, 0.000000, 1.853850, -0.561407, 0.760416, -0.326481,
+-1.002737, -2.066217, -17.608171, 0.000000, 1.853850, -0.561407, 0.760416, -0.326481,
+-1.002737, -2.990782, -19.848455, 0.000000, 1.691091, -0.573541, 0.767562, -0.286181,
+-1.336982, -3.677238, -19.700720, 0.500000, 1.696742, -0.999943, -0.009227, 0.005371,
+-1.336982, -4.998410, -24.141369, 0.500000, 1.417808, -0.999879, -0.015054, 0.003873,
+-1.002737, -5.694758, -24.033106, 1.000000, 1.417808, -0.566494, -0.804616, 0.177981,
+-1.002737, -5.128252, -21.846479, 1.000000, 1.550938, -0.566340, -0.790066, 0.234638,
+-1.002737, -5.128252, -21.846479, 1.000000, 1.550938, -0.566340, -0.790066, 0.234638,
+-1.002737, -4.363696, -19.552979, 1.000000, 1.696742, -0.563275, -0.773529, 0.290474,
+-1.336982, -3.677238, -19.700720, 0.500000, 1.696742, -0.999943, -0.009227, 0.005371,
+-1.336982, -3.677238, -19.700720, 0.500000, 1.696742, -0.999943, -0.009227, 0.005371,
+-1.002737, -2.990782, -19.848455, 0.000000, 1.691091, -0.573541, 0.767562, -0.286181,
+-1.002737, -3.746061, -22.116426, 0.000000, 1.550938, -0.578794, 0.781497, -0.232937,
+-1.002737, -3.746061, -22.116426, 0.000000, 1.550938, -0.578794, 0.781497, -0.232937,
+-1.002737, -4.302059, -24.249632, 0.000000, 1.410785, -0.582444, 0.793471, -0.176531,
+-1.336982, -4.998410, -24.141369, 0.500000, 1.417808, -0.999879, -0.015054, 0.003873,
+-1.336982, -5.505962, -27.491592, 0.500000, 1.186658, -0.999932, -0.011525, 0.001722,
+-1.002737, -6.213656, -27.449341, 1.000000, 1.186658, -0.570758, -0.816393, 0.087968,
+-1.002737, -6.033253, -25.936214, 1.000000, 1.298722, -0.568446, -0.813396, 0.123515,
+-1.002737, -6.033253, -25.936214, 1.000000, 1.298722, -0.568446, -0.813396, 0.123515,
+-1.002737, -5.694758, -24.033106, 1.000000, 1.417808, -0.566494, -0.804616, 0.177981,
+-1.336982, -4.998410, -24.141369, 0.500000, 1.417808, -0.999879, -0.015054, 0.003873,
+-1.336982, -4.998410, -24.141369, 0.500000, 1.417808, -0.999879, -0.015054, 0.003873,
+-1.002737, -4.302059, -24.249632, 0.000000, 1.410785, -0.582444, 0.793471, -0.176531,
+-1.002737, -4.628780, -26.085621, 0.000000, 1.298722, -0.582983, 0.803361, -0.121414,
+-1.002737, -4.628780, -26.085621, 0.000000, 1.298722, -0.582983, 0.803361, -0.121414,
+-1.002737, -4.798269, -27.533844, 0.000000, 1.186658, -0.583018, 0.808019, -0.084825,
+-1.336982, -5.505962, -27.491592, 0.500000, 1.186658, -0.999932, -0.011525, 0.001722,
+-1.002737, -6.305892, -28.466030, 0.500000, 1.053028, -0.565626, -0.821288, 0.074517,
+-1.002737, -6.213656, -27.449341, 1.000000, 1.053028, -0.570758, -0.816393, 0.087968,
+-1.336982, -5.505962, -27.491592, 1.000000, 1.119843, -0.999932, -0.011525, 0.001722,
+-1.336982, -5.505962, -27.491592, 1.000000, 1.119843, -0.999932, -0.011525, 0.001722,
+-1.002737, -4.798269, -27.533844, 1.000000, 1.186658, -0.583018, 0.808019, -0.084825,
+-1.002737, -4.882575, -28.503754, 0.500000, 1.186658, -0.589040, 0.805068, -0.069986,
+0.000000, -22.080643, -5.340171, 1.000000, 1.026514, 0.000000, 0.892013, -0.452009,
+1.002737, -22.289114, -5.237599, 1.000000, 1.053028, 0.580101, 0.726128, -0.369081,
+1.002737, -22.791559, -6.324653, 0.500000, 1.053028, 0.585182, 0.679392, -0.442706,
+1.002737, -22.791559, -6.324653, 0.500000, 1.053028, 0.585182, 0.679392, -0.442706,
+0.742768, -23.169422, -6.772669, 0.000000, 1.053028, 0.444774, 0.383425, -0.809421,
+0.000000, -23.066525, -7.012697, 0.000000, 1.026514, -0.000000, 0.424976, -0.905205,
+0.000000, -23.066525, -7.012697, 0.000000, 1.026514, -0.000000, 0.424976, -0.905205,
+-0.742768, -23.169422, -6.772669, 0.000000, 1.000000, -0.444774, 0.383424, -0.809421,
+-1.002737, -22.791559, -6.324653, 0.500000, 1.000000, -0.585182, 0.679392, -0.442706,
+-1.002737, -22.791559, -6.324653, 0.500000, 1.000000, -0.585182, 0.679392, -0.442706,
+-1.002737, -22.289114, -5.237599, 1.000000, 1.000000, -0.580101, 0.726129, -0.369081,
+0.000000, -22.080643, -5.340171, 1.000000, 1.026514, 0.000000, 0.892013, -0.452009,
+0.000000, -20.191145, -2.377919, 1.500000, 4.901888, 0.000000, 0.744223, -0.667931,
+1.002737, -20.362839, -2.232996, 2.000000, 4.901887, 0.577401, 0.607255, -0.545756,
+1.002737, -21.510138, -3.803390, 2.000000, 4.957545, 0.579339, 0.686160, -0.439944,
+1.002737, -21.510138, -3.803390, 2.000000, 4.957545, 0.579339, 0.686160, -0.439944,
+1.002737, -22.289114, -5.237599, 2.000000, 5.000000, 0.580101, 0.726128, -0.369081,
+0.000000, -22.080643, -5.340171, 1.500000, 5.000000, 0.000000, 0.892013, -0.452009,
+0.000000, -22.080643, -5.340171, 1.500000, 5.000000, 0.000000, 0.892013, -0.452009,
+-1.002737, -22.289114, -5.237599, 1.000000, 5.000000, -0.580101, 0.726129, -0.369081,
+-1.002737, -21.510138, -3.803390, 1.000000, 4.957545, -0.579339, 0.686160, -0.439944,
+-1.002737, -21.510138, -3.803390, 1.000000, 4.957545, -0.579339, 0.686160, -0.439944,
+-1.002737, -20.362839, -2.232996, 1.000000, 4.901887, -0.577401, 0.607255, -0.545756,
+0.000000, -20.191145, -2.377919, 1.500000, 4.901888, 0.000000, 0.744223, -0.667931,
+0.000000, -16.700464, 0.259406, 1.500000, 4.706708, -0.000000, 0.404784, -0.914412,
+1.002737, -16.806824, 0.450041, 2.000000, 4.706708, 0.570721, 0.333495, -0.750372,
+1.002737, -18.755436, -0.737389, 2.000000, 4.819824, 0.571841, 0.493951, -0.654989,
+1.002737, -18.755436, -0.737389, 2.000000, 4.819824, 0.571841, 0.493951, -0.654989,
+1.002737, -20.362839, -2.232996, 2.000000, 4.901887, 0.577401, 0.607255, -0.545756,
+0.000000, -20.191145, -2.377919, 1.500000, 4.901888, 0.000000, 0.744223, -0.667931,
+0.000000, -20.191145, -2.377919, 1.500000, 4.901888, 0.000000, 0.744223, -0.667931,
+-1.002737, -20.362839, -2.232996, 1.000000, 4.901887, -0.577401, 0.607255, -0.545756,
+-1.002737, -18.755436, -0.737389, 1.000000, 4.819824, -0.571841, 0.493951, -0.654989,
+-1.002737, -18.755436, -0.737389, 1.000000, 4.819824, -0.571841, 0.493951, -0.654989,
+-1.002737, -16.806824, 0.450041, 1.000000, 4.706708, -0.570721, 0.333495, -0.750372,
+0.000000, -16.700464, 0.259406, 1.500000, 4.706708, -0.000000, 0.404784, -0.914412,
+0.000000, -12.358379, 1.137146, 1.500000, 4.382352, 0.000000, 0.060964, -0.998140,
+1.002737, -12.384212, 1.352605, 2.000000, 4.382352, 0.556840, 0.051516, -0.829021,
+1.002737, -14.635897, 1.095908, 2.000000, 4.557891, 0.560822, 0.165222, -0.811283,
+1.002737, -14.635897, 1.095908, 2.000000, 4.557891, 0.560822, 0.165222, -0.811283,
+1.002737, -16.806824, 0.450041, 2.000000, 4.706708, 0.570721, 0.333495, -0.750372,
+0.000000, -16.700464, 0.259406, 1.500000, 4.706708, -0.000000, 0.404784, -0.914412,
+0.000000, -16.700464, 0.259406, 1.500000, 4.706708, -0.000000, 0.404784, -0.914412,
+-1.002737, -16.806824, 0.450041, 1.000000, 4.706708, -0.570721, 0.333495, -0.750372,
+-1.002737, -14.635897, 1.095908, 1.000000, 4.557891, -0.560822, 0.165222, -0.811283,
+-1.002737, -14.635897, 1.095908, 1.000000, 4.557891, -0.560822, 0.165222, -0.811283,
+-1.002737, -12.384212, 1.352605, 1.000000, 4.382352, -0.556840, 0.051516, -0.829021,
+0.000000, -12.358379, 1.137146, 1.500000, 4.382352, 0.000000, 0.060964, -0.998140,
+0.000000, -8.242178, 0.872734, 1.500000, 3.977933, 0.000000, -0.248755, -0.968567,
+1.002737, -8.188779, 1.086162, 2.000000, 3.977933, 0.571796, -0.203921, -0.794648,
+1.002737, -10.193325, 1.372527, 2.000000, 4.189068, 0.563923, -0.052320, -0.824168,
+1.002737, -10.193325, 1.372527, 2.000000, 4.189068, 0.563923, -0.052320, -0.824168,
+1.002737, -12.384212, 1.352605, 2.000000, 4.382352, 0.556840, 0.051516, -0.829021,
+0.000000, -12.358379, 1.137146, 1.500000, 4.382352, 0.000000, 0.060964, -0.998140,
+0.000000, -12.358379, 1.137146, 1.500000, 4.382352, 0.000000, 0.060964, -0.998140,
+-1.002737, -12.384212, 1.352605, 1.000000, 4.382352, -0.556840, 0.051516, -0.829021,
+-1.002737, -10.193326, 1.372527, 1.000000, 4.189068, -0.563923, -0.052320, -0.824168,
+-1.002737, -10.193326, 1.372527, 1.000000, 4.189068, -0.563923, -0.052320, -0.824168,
+-1.002737, -8.188779, 1.086162, 1.000000, 3.977933, -0.571796, -0.203921, -0.794648,
+0.000000, -8.242178, 0.872734, 1.500000, 3.977933, 0.000000, -0.248755, -0.968567,
+0.000000, -5.137229, -0.776313, 1.500000, 3.518014, -0.000000, -0.646205, -0.763164,
+1.002737, -5.023273, -0.595701, 2.000000, 3.518014, 0.554291, -0.537252, -0.635706,
+1.002737, -6.496116, 0.423996, 2.000000, 3.748844, 0.567467, -0.386666, -0.726960,
+1.002737, -6.496116, 0.423996, 2.000000, 3.748844, 0.567467, -0.386666, -0.726960,
+1.002737, -8.188779, 1.086162, 2.000000, 3.977933, 0.571796, -0.203921, -0.794648,
+0.000000, -8.242178, 0.872734, 1.500000, 3.977933, 0.000000, -0.248755, -0.968567,
+0.000000, -8.242178, 0.872734, 1.500000, 3.977933, 0.000000, -0.248755, -0.968567,
+-1.002737, -8.188779, 1.086162, 1.000000, 3.977933, -0.571796, -0.203921, -0.794648,
+-1.002737, -6.496116, 0.423996, 1.000000, 3.748844, -0.567467, -0.386666, -0.726960,
+-1.002737, -6.496116, 0.423996, 1.000000, 3.748844, -0.567467, -0.386666, -0.726960,
+-1.002737, -5.023273, -0.595701, 1.000000, 3.518014, -0.554291, -0.537252, -0.635706,
+0.000000, -5.137229, -0.776313, 1.500000, 3.518014, -0.000000, -0.646205, -0.763164,
+0.000000, -2.675549, -3.655995, 1.500000, 3.096704, -0.000000, -0.841132, -0.540830,
+1.002737, -2.514818, -3.530164, 2.000000, 3.096704, 0.535283, -0.710141, -0.457354,
+1.002737, -3.678185, -1.954659, 2.000000, 3.301661, 0.541785, -0.639146, -0.545858,
+1.002737, -3.678185, -1.954659, 2.000000, 3.301661, 0.541785, -0.639146, -0.545858,
+1.002737, -5.023273, -0.595701, 2.000000, 3.518014, 0.554291, -0.537252, -0.635706,
+0.000000, -5.137229, -0.776313, 1.500000, 3.518014, -0.000000, -0.646205, -0.763164,
+0.000000, -5.137229, -0.776313, 1.500000, 3.518014, -0.000000, -0.646205, -0.763164,
+-1.002737, -5.023273, -0.595701, 1.000000, 3.518014, -0.554291, -0.537252, -0.635706,
+-1.002737, -3.678185, -1.954659, 1.000000, 3.301661, -0.541786, -0.639146, -0.545858,
+-1.002737, -3.678185, -1.954659, 1.000000, 3.301661, -0.541786, -0.639146, -0.545858,
+-1.002737, -2.514818, -3.530164, 1.000000, 3.096704, -0.535283, -0.710141, -0.457353,
+0.000000, -2.675549, -3.655995, 1.500000, 3.096704, -0.000000, -0.841132, -0.540830,
+0.000000, -1.149923, -7.084101, 1.500000, 2.714038, 0.000000, -0.973883, -0.227050,
+1.002737, -0.955311, -7.018215, 2.000000, 2.714038, 0.543591, -0.816934, -0.192683,
+1.002737, -1.587135, -5.199499, 2.000000, 2.900065, 0.538039, -0.769598, -0.343850,
+1.002737, -1.587135, -5.199499, 2.000000, 2.900065, 0.538039, -0.769598, -0.343850,
+1.002737, -2.514818, -3.530164, 2.000000, 3.096704, 0.535283, -0.710141, -0.457354,
+0.000000, -2.675549, -3.655995, 1.500000, 3.096704, -0.000000, -0.841132, -0.540830,
+0.000000, -2.675549, -3.655995, 1.500000, 3.096704, -0.000000, -0.841132, -0.540830,
+-1.002737, -2.514818, -3.530164, 1.000000, 3.096704, -0.535283, -0.710141, -0.457353,
+-1.002737, -1.587135, -5.199499, 1.000000, 2.900065, -0.538039, -0.769598, -0.343850,
+-1.002737, -1.587135, -5.199499, 1.000000, 2.900065, -0.538039, -0.769598, -0.343850,
+-1.002737, -0.955311, -7.018215, 1.000000, 2.714038, -0.543592, -0.816934, -0.192683,
+0.000000, -1.149923, -7.084101, 1.500000, 2.714038, 0.000000, -0.973883, -0.227050,
+0.000000, -1.052381, -11.138744, 1.500000, 2.371212, 0.000000, -0.979438, 0.201745,
+1.002737, -0.835270, -11.133000, 2.000000, 2.371212, 0.556778, -0.814518, 0.162970,
+1.002737, -0.679521, -9.041862, 2.000000, 2.540917, 0.550509, -0.834486, -0.023924,
+1.002737, -0.679521, -9.041862, 2.000000, 2.540917, 0.550509, -0.834486, -0.023924,
+1.002737, -0.955311, -7.018215, 2.000000, 2.714038, 0.543591, -0.816934, -0.192683,
+0.000000, -1.149923, -7.084101, 1.500000, 2.714038, 0.000000, -0.973883, -0.227050,
+0.000000, -1.149923, -7.084101, 1.500000, 2.714038, 0.000000, -0.973883, -0.227050,
+-1.002737, -0.955311, -7.018215, 1.000000, 2.714038, -0.543592, -0.816934, -0.192683,
+-1.002737, -0.679522, -9.041862, 1.000000, 2.540917, -0.550509, -0.834486, -0.023924,
+-1.002737, -0.679522, -9.041862, 1.000000, 2.540917, -0.550509, -0.834486, -0.023924,
+-1.002737, -0.835270, -11.133001, 1.000000, 2.371212, -0.556778, -0.814518, 0.162970,
+0.000000, -1.052381, -11.138744, 1.500000, 2.371212, 0.000000, -0.979438, 0.201745,
+0.000000, -2.665116, -15.154720, 1.500000, 2.020624, -0.000000, -0.906717, 0.421740,
+1.002737, -2.439466, -15.191065, 2.000000, 2.020624, 0.552162, -0.756556, 0.350343,
+1.002737, -1.498060, -13.154191, 2.000000, 2.195430, 0.550846, -0.775955, 0.307348,
+1.002737, -1.498060, -13.154191, 2.000000, 2.195430, 0.550846, -0.775955, 0.307348,
+1.002737, -0.835270, -11.133000, 2.000000, 2.371212, 0.556778, -0.814518, 0.162970,
+0.000000, -1.052381, -11.138744, 1.500000, 2.371212, 0.000000, -0.979438, 0.201745,
+0.000000, -1.052381, -11.138744, 1.500000, 2.371212, 0.000000, -0.979438, 0.201745,
+-1.002737, -0.835270, -11.133001, 1.000000, 2.371212, -0.556778, -0.814518, 0.162970,
+-1.002737, -1.498060, -13.154191, 1.000000, 2.195430, -0.550846, -0.775955, 0.307348,
+-1.002737, -1.498060, -13.154191, 1.000000, 2.195430, -0.550846, -0.775955, 0.307348,
+-1.002737, -2.439466, -15.191065, 1.000000, 2.020624, -0.552162, -0.756555, 0.350343,
+0.000000, -2.665116, -15.154720, 1.500000, 2.020624, -0.000000, -0.906717, 0.421740,
+0.000000, -4.592515, -19.503733, 1.500000, 1.696742, -0.000000, -0.936315, 0.351162,
+1.002737, -4.363696, -19.552979, 2.000000, 1.696742, 0.563275, -0.773529, 0.290474,
+1.002737, -3.431055, -17.329250, 2.000000, 1.853850, 0.559291, -0.758482, 0.334513,
+1.002737, -3.431055, -17.329250, 2.000000, 1.853850, 0.559291, -0.758482, 0.334513,
+1.002737, -2.439466, -15.191065, 2.000000, 2.020624, 0.552162, -0.756556, 0.350343,
+0.000000, -2.665116, -15.154720, 1.500000, 2.020624, -0.000000, -0.906717, 0.421740,
+0.000000, -2.665116, -15.154720, 1.500000, 2.020624, -0.000000, -0.906717, 0.421740,
+-1.002737, -2.439466, -15.191065, 1.000000, 2.020624, -0.552162, -0.756555, 0.350343,
+-1.002737, -3.431055, -17.329250, 1.000000, 1.853850, -0.559291, -0.758482, 0.334513,
+-1.002737, -3.431055, -17.329250, 1.000000, 1.853850, -0.559291, -0.758482, 0.334513,
+-1.002737, -4.363696, -19.552979, 1.000000, 1.696742, -0.563275, -0.773529, 0.290474,
+0.000000, -4.592515, -19.503733, 1.500000, 1.696742, -0.000000, -0.936315, 0.351162,
+0.000000, -5.926875, -23.997019, 1.500000, 1.417808, -0.000000, -0.976472, 0.215645,
+1.002737, -5.694758, -24.033106, 2.000000, 1.417808, 0.566494, -0.804616, 0.177981,
+1.002737, -5.128252, -21.846479, 2.000000, 1.550938, 0.566340, -0.790066, 0.234638,
+1.002737, -5.128252, -21.846479, 2.000000, 1.550938, 0.566340, -0.790066, 0.234638,
+1.002737, -4.363696, -19.552979, 2.000000, 1.696742, 0.563275, -0.773529, 0.290474,
+0.000000, -4.592515, -19.503733, 1.500000, 1.696742, -0.000000, -0.936315, 0.351162,
+0.000000, -4.592515, -19.503733, 1.500000, 1.696742, -0.000000, -0.936315, 0.351162,
+-1.002737, -4.363696, -19.552979, 1.000000, 1.696742, -0.563275, -0.773529, 0.290474,
+-1.002737, -5.128252, -21.846479, 1.000000, 1.550938, -0.566340, -0.790066, 0.234638,
+-1.002737, -5.128252, -21.846479, 1.000000, 1.550938, -0.566340, -0.790066, 0.234638,
+-1.002737, -5.694758, -24.033106, 1.000000, 1.417808, -0.566494, -0.804616, 0.177981,
+0.000000, -5.926875, -23.997019, 1.500000, 1.417808, -0.000000, -0.976472, 0.215645,
+0.000000, -6.449554, -27.435261, 1.500000, 1.186658, -0.000000, -0.994229, 0.107280,
+1.002737, -6.213656, -27.449341, 2.000000, 1.186658, 0.570758, -0.816393, 0.087968,
+1.002737, -6.033253, -25.936216, 2.000000, 1.298722, 0.568446, -0.813396, 0.123515,
+1.002737, -6.033253, -25.936216, 2.000000, 1.298722, 0.568446, -0.813396, 0.123515,
+1.002737, -5.694758, -24.033106, 2.000000, 1.417808, 0.566494, -0.804616, 0.177981,
+0.000000, -5.926875, -23.997019, 1.500000, 1.417808, -0.000000, -0.976472, 0.215645,
+0.000000, -5.926875, -23.997019, 1.500000, 1.417808, -0.000000, -0.976472, 0.215645,
+-1.002737, -5.694758, -24.033106, 1.000000, 1.417808, -0.566494, -0.804616, 0.177981,
+-1.002737, -6.033253, -25.936214, 1.000000, 1.298722, -0.568446, -0.813396, 0.123515,
+-1.002737, -6.033253, -25.936214, 1.000000, 1.298722, -0.568446, -0.813396, 0.123515,
+-1.002737, -6.213656, -27.449341, 1.000000, 1.186658, -0.570758, -0.816393, 0.087968,
+0.000000, -6.449554, -27.435261, 1.500000, 1.186658, -0.000000, -0.994229, 0.107280,
+1.002737, -6.305892, -28.466030, 1.500000, 1.053028, 0.565626, -0.821288, 0.074517,
+1.002737, -6.213656, -27.449341, 2.000000, 1.053028, 0.570758, -0.816393, 0.087968,
+0.000000, -6.449554, -27.435261, 2.000000, 1.119843, -0.000000, -0.994229, 0.107280,
+0.000000, -6.449554, -27.435261, 2.000000, 1.119843, -0.000000, -0.994229, 0.107280,
+-1.002737, -6.213656, -27.449341, 2.000000, 1.186658, -0.570758, -0.816393, 0.087968,
+-1.002737, -6.305892, -28.466030, 1.500000, 1.186658, -0.565626, -0.821288, 0.074517,
+1.336982, -22.914524, -4.929887, 2.000000, 1.026514, 0.999805, -0.016666, 0.010584,
+1.002737, -23.539934, -4.622173, 2.000000, 1.053028, 0.559738, -0.733607, 0.385376,
+1.002737, -24.101816, -5.795360, 1.500000, 1.053028, 0.571338, -0.788867, 0.226409,
+1.002737, -24.101816, -5.795360, 1.500000, 1.053028, 0.571338, -0.788867, 0.226409,
+0.742768, -24.152987, -6.401496, 1.000000, 1.053028, 0.455754, -0.834430, -0.309862,
+1.002737, -23.736286, -6.771559, 1.000000, 1.026514, 0.633041, -0.276748, -0.722959,
+1.002737, -23.736286, -6.771559, 1.000000, 1.026514, 0.633041, -0.276748, -0.722959,
+0.742768, -23.169422, -6.772669, 1.000000, 1.000000, 0.444774, 0.383425, -0.809421,
+1.002737, -22.791559, -6.324653, 1.500000, 1.000000, 0.585182, 0.679392, -0.442706,
+1.002737, -22.791559, -6.324653, 1.500000, 1.000000, 0.585182, 0.679392, -0.442706,
+1.002737, -22.289114, -5.237599, 2.000000, 1.000000, 0.580101, 0.726128, -0.369081,
+1.336982, -22.914524, -4.929887, 2.000000, 1.026514, 0.999805, -0.016666, 0.010584,
+1.336982, -20.877926, -1.798224, 2.500000, 4.901888, 0.999242, -0.027513, 0.027552,
+1.002737, -21.393009, -1.363454, 3.000000, 4.901887, 0.538985, -0.621423, 0.568620,
+1.002737, -22.670450, -3.070609, 3.000000, 4.957545, 0.549531, -0.697669, 0.459646,
+1.002737, -22.670450, -3.070609, 3.000000, 4.957545, 0.549531, -0.697669, 0.459646,
+1.002737, -23.539934, -4.622173, 3.000000, 5.000000, 0.559738, -0.733607, 0.385376,
+1.336982, -22.914524, -4.929887, 2.500000, 5.000000, 0.999805, -0.016666, 0.010584,
+1.336982, -22.914524, -4.929887, 2.500000, 5.000000, 0.999805, -0.016666, 0.010584,
+1.002737, -22.289114, -5.237599, 2.000000, 5.000000, 0.580101, 0.726128, -0.369081,
+1.002737, -21.510138, -3.803390, 2.000000, 4.957545, 0.579339, 0.686160, -0.439944,
+1.002737, -21.510138, -3.803390, 2.000000, 4.957545, 0.579339, 0.686160, -0.439944,
+1.002737, -20.362839, -2.232996, 2.000000, 4.901887, 0.577401, 0.607255, -0.545756,
+1.336982, -20.877926, -1.798224, 2.500000, 4.901888, 0.999242, -0.027513, 0.027552,
+1.336982, -17.125900, 1.021948, 2.500000, 4.706708, 0.998755, -0.017888, 0.046575,
+1.002737, -17.444981, 1.593854, 3.000000, 4.706708, 0.523473, -0.350048, 0.776815,
+1.002737, -19.607264, 0.276508, 3.000000, 4.819824, 0.531663, -0.507888, 0.677779,
+1.002737, -19.607264, 0.276508, 3.000000, 4.819824, 0.531663, -0.507888, 0.677779,
+1.002737, -21.393009, -1.363454, 3.000000, 4.901887, 0.538985, -0.621423, 0.568620,
+1.336982, -20.877926, -1.798224, 2.500000, 4.901888, 0.999242, -0.027513, 0.027552,
+1.336982, -20.877926, -1.798224, 2.500000, 4.901888, 0.999242, -0.027513, 0.027552,
+1.002737, -20.362839, -2.232996, 2.000000, 4.901887, 0.577401, 0.607255, -0.545756,
+1.002737, -18.755436, -0.737389, 2.000000, 4.819824, 0.571841, 0.493951, -0.654989,
+1.002737, -18.755436, -0.737389, 2.000000, 4.819824, 0.571841, 0.493951, -0.654989,
+1.002737, -16.806824, 0.450041, 2.000000, 4.706708, 0.570721, 0.333495, -0.750372,
+1.336982, -17.125900, 1.021948, 2.500000, 4.706708, 0.998755, -0.017888, 0.046575,
+1.336982, -12.461710, 1.998980, 2.500000, 4.382352, 0.999581, -0.002143, 0.028884,
+1.002737, -12.539209, 2.645355, 3.000000, 4.382352, 0.529316, -0.059790, 0.846315,
+1.002737, -15.037928, 2.333167, 3.000000, 4.557891, 0.524224, -0.178780, 0.832603,
+1.002737, -15.037928, 2.333167, 3.000000, 4.557891, 0.524224, -0.178780, 0.832603,
+1.002737, -17.444981, 1.593854, 3.000000, 4.706708, 0.523473, -0.350048, 0.776815,
+1.336982, -17.125900, 1.021948, 2.500000, 4.706708, 0.998755, -0.017888, 0.046575,
+1.336982, -17.125900, 1.021948, 2.500000, 4.706708, 0.998755, -0.017888, 0.046575,
+1.002737, -16.806824, 0.450041, 2.000000, 4.706708, 0.570721, 0.333495, -0.750372,
+1.002737, -14.635897, 1.095908, 2.000000, 4.557891, 0.560822, 0.165222, -0.811283,
+1.002737, -14.635897, 1.095908, 2.000000, 4.557891, 0.560822, 0.165222, -0.811283,
+1.002737, -12.384212, 1.352605, 2.000000, 4.382352, 0.556840, 0.051516, -0.829021,
+1.336982, -12.461710, 1.998980, 2.500000, 4.382352, 0.999581, -0.002143, 0.028884,
+1.336982, -8.028582, 1.726443, 2.500000, 3.977933, 0.998903, 0.011916, 0.045285,
+1.002737, -7.868385, 2.366725, 3.000000, 3.977933, 0.526810, 0.210598, 0.823480,
+1.002737, -10.101929, 2.681329, 3.000000, 4.189068, 0.529646, 0.050516, 0.846713,
+1.002737, -10.101929, 2.681329, 3.000000, 4.189068, 0.529646, 0.050516, 0.846713,
+1.002737, -12.539209, 2.645355, 3.000000, 4.382352, 0.529316, -0.059790, 0.846315,
+1.336982, -12.461710, 1.998980, 2.500000, 4.382352, 0.999581, -0.002143, 0.028884,
+1.336982, -12.461710, 1.998980, 2.500000, 4.382352, 0.999581, -0.002143, 0.028884,
+1.002737, -12.384212, 1.352605, 2.000000, 4.382352, 0.556840, 0.051516, -0.829021,
+1.002737, -10.193325, 1.372527, 2.000000, 4.189068, 0.563923, -0.052320, -0.824168,
+1.002737, -10.193325, 1.372527, 2.000000, 4.189068, 0.563923, -0.052320, -0.824168,
+1.002737, -8.188779, 1.086162, 2.000000, 3.977933, 0.571796, -0.203921, -0.794648,
+1.336982, -8.028582, 1.726443, 2.500000, 3.977933, 0.998903, 0.011916, 0.045285,
+1.336982, -4.681401, -0.053863, 2.500000, 3.518014, 0.999076, 0.030579, 0.030219,
+1.002737, -4.339529, 0.487975, 3.000000, 3.518014, 0.515414, 0.553092, 0.654552,
+1.002737, -5.980879, 1.627182, 3.000000, 3.748844, 0.522693, 0.400366, 0.752661,
+1.002737, -5.980879, 1.627182, 3.000000, 3.748844, 0.522693, 0.400366, 0.752661,
+1.002737, -7.868385, 2.366725, 3.000000, 3.977933, 0.526810, 0.210598, 0.823480,
+1.336982, -8.028582, 1.726443, 2.500000, 3.977933, 0.998903, 0.011916, 0.045285,
+1.336982, -8.028582, 1.726443, 2.500000, 3.977933, 0.998903, 0.011916, 0.045285,
+1.002737, -8.188779, 1.086162, 2.000000, 3.977933, 0.571796, -0.203921, -0.794648,
+1.002737, -6.496116, 0.423996, 2.000000, 3.748844, 0.567467, -0.386666, -0.726960,
+1.002737, -6.496116, 0.423996, 2.000000, 3.748844, 0.567467, -0.386666, -0.726960,
+1.002737, -5.023273, -0.595701, 2.000000, 3.518014, 0.554291, -0.537252, -0.635706,
+1.336982, -4.681401, -0.053863, 2.500000, 3.518014, 0.999076, 0.030579, 0.030219,
+1.336982, -2.032627, -3.152670, 2.500000, 3.096704, 0.999446, 0.028671, 0.016899,
+1.002737, -1.550435, -2.775177, 3.000000, 3.096704, 0.505988, 0.723592, 0.469458,
+1.002737, -2.844458, -1.025621, 3.000000, 3.301661, 0.509526, 0.653879, 0.559309,
+1.002737, -2.844458, -1.025621, 3.000000, 3.301661, 0.509526, 0.653879, 0.559309,
+1.002737, -4.339529, 0.487975, 3.000000, 3.518014, 0.515414, 0.553092, 0.654552,
+1.336982, -4.681401, -0.053863, 2.500000, 3.518014, 0.999076, 0.030579, 0.030219,
+1.336982, -4.681401, -0.053863, 2.500000, 3.518014, 0.999076, 0.030579, 0.030219,
+1.002737, -5.023273, -0.595701, 2.000000, 3.518014, 0.554291, -0.537252, -0.635706,
+1.002737, -3.678185, -1.954659, 2.000000, 3.301661, 0.541785, -0.639146, -0.545858,
+1.002737, -3.678185, -1.954659, 2.000000, 3.301661, 0.541785, -0.639146, -0.545858,
+1.002737, -2.514818, -3.530164, 2.000000, 3.096704, 0.535283, -0.710141, -0.457354,
+1.336982, -2.032627, -3.152670, 2.500000, 3.096704, 0.999446, 0.028671, 0.016899,
+1.336982, -0.371475, -6.820555, 2.500000, 2.714038, 0.999079, 0.041649, 0.010372,
+1.002737, 0.212362, -6.622896, 3.000000, 2.714038, 0.505651, 0.835716, 0.214230,
+1.002737, -0.512230, -4.622262, 3.000000, 2.900065, 0.503207, 0.785549, 0.360132,
+1.002737, -0.512230, -4.622262, 3.000000, 2.900065, 0.503207, 0.785549, 0.360132,
+1.002737, -1.550435, -2.775177, 3.000000, 3.096704, 0.505988, 0.723592, 0.469458,
+1.336982, -2.032627, -3.152670, 2.500000, 3.096704, 0.999446, 0.028671, 0.016899,
+1.336982, -2.032627, -3.152670, 2.500000, 3.096704, 0.999446, 0.028671, 0.016899,
+1.002737, -2.514818, -3.530164, 2.000000, 3.096704, 0.535283, -0.710141, -0.457354,
+1.002737, -1.587135, -5.199499, 2.000000, 2.900065, 0.538039, -0.769598, -0.343850,
+1.002737, -1.587135, -5.199499, 2.000000, 2.900065, 0.538039, -0.769598, -0.343850,
+1.002737, -0.955311, -7.018215, 2.000000, 2.714038, 0.543591, -0.816934, -0.192683,
+1.336982, -0.371475, -6.820555, 2.500000, 2.714038, 0.999079, 0.041649, 0.010372,
+1.336982, -0.183937, -11.115767, 2.500000, 2.371212, 0.999002, 0.043336, -0.010816,
+1.002737, 0.467394, -11.098533, 3.000000, 2.371212, 0.517497, 0.844529, -0.137721,
+1.002737, 0.565540, -8.833092, 3.000000, 2.540917, 0.512670, 0.857168, 0.049331,
+1.002737, 0.565540, -8.833092, 3.000000, 2.540917, 0.512670, 0.857168, 0.049331,
+1.002737, 0.212362, -6.622896, 3.000000, 2.714038, 0.505651, 0.835716, 0.214230,
+1.336982, -0.371475, -6.820555, 2.500000, 2.714038, 0.999079, 0.041649, 0.010372,
+1.336982, -0.371475, -6.820555, 2.500000, 2.714038, 0.999079, 0.041649, 0.010372,
+1.002737, -0.955311, -7.018215, 2.000000, 2.714038, 0.543591, -0.816934, -0.192683,
+1.002737, -0.679521, -9.041862, 2.000000, 2.540917, 0.550509, -0.834486, -0.023924,
+1.002737, -0.679521, -9.041862, 2.000000, 2.540917, 0.550509, -0.834486, -0.023924,
+1.002737, -0.835270, -11.133000, 2.000000, 2.371212, 0.556778, -0.814518, 0.162970,
+1.336982, -0.183937, -11.115767, 2.500000, 2.371212, 0.999002, 0.043336, -0.010816,
+1.336982, -1.762512, -15.300098, 2.500000, 2.020624, 0.999977, 0.006790, -0.000522,
+1.002737, -1.085560, -15.409132, 3.000000, 2.020624, 0.545979, 0.767296, -0.336399,
+1.002737, -0.161999, -13.264900, 3.000000, 2.195430, 0.528455, 0.798898, -0.287224,
+1.002737, -0.161999, -13.264900, 3.000000, 2.195430, 0.528455, 0.798898, -0.287224,
+1.002737, 0.467394, -11.098533, 3.000000, 2.371212, 0.517497, 0.844529, -0.137721,
+1.336982, -0.183937, -11.115767, 2.500000, 2.371212, 0.999002, 0.043336, -0.010816,
+1.336982, -0.183937, -11.115767, 2.500000, 2.371212, 0.999002, 0.043336, -0.010816,
+1.002737, -0.835270, -11.133000, 2.000000, 2.371212, 0.556778, -0.814518, 0.162970,
+1.002737, -1.498060, -13.154191, 2.000000, 2.195430, 0.550846, -0.775955, 0.307348,
+1.002737, -1.498060, -13.154191, 2.000000, 2.195430, 0.550846, -0.775955, 0.307348,
+1.002737, -2.439466, -15.191065, 2.000000, 2.020624, 0.552162, -0.756556, 0.350343,
+1.336982, -1.762512, -15.300098, 2.500000, 2.020624, 0.999977, 0.006790, -0.000522,
+1.336982, -3.677238, -19.700720, 2.500000, 1.696742, 0.999943, -0.009227, 0.005371,
+1.002737, -2.990782, -19.848455, 3.000000, 1.696742, 0.573541, 0.767561, -0.286181,
+1.002737, -2.066217, -17.608171, 3.000000, 1.853850, 0.561407, 0.760416, -0.326481,
+1.002737, -2.066217, -17.608171, 3.000000, 1.853850, 0.561407, 0.760416, -0.326481,
+1.002737, -1.085560, -15.409132, 3.000000, 2.020624, 0.545979, 0.767296, -0.336399,
+1.336982, -1.762512, -15.300098, 2.500000, 2.020624, 0.999977, 0.006790, -0.000522,
+1.336982, -1.762512, -15.300098, 2.500000, 2.020624, 0.999977, 0.006790, -0.000522,
+1.002737, -2.439466, -15.191065, 2.000000, 2.020624, 0.552162, -0.756556, 0.350343,
+1.002737, -3.431055, -17.329250, 2.000000, 1.853850, 0.559291, -0.758482, 0.334513,
+1.002737, -3.431055, -17.329250, 2.000000, 1.853850, 0.559291, -0.758482, 0.334513,
+1.002737, -4.363696, -19.552979, 2.000000, 1.696742, 0.563275, -0.773529, 0.290474,
+1.336982, -3.677238, -19.700720, 2.500000, 1.696742, 0.999943, -0.009227, 0.005371,
+1.336982, -4.998410, -24.141369, 2.500000, 1.417808, 0.999879, -0.015055, 0.003873,
+1.002737, -4.302059, -24.249632, 3.000000, 1.417808, 0.582444, 0.793471, -0.176531,
+1.002737, -3.746061, -22.116426, 3.000000, 1.550938, 0.578794, 0.781497, -0.232937,
+1.002737, -3.746061, -22.116426, 3.000000, 1.550938, 0.578794, 0.781497, -0.232937,
+1.002737, -2.990782, -19.848455, 3.000000, 1.696742, 0.573541, 0.767561, -0.286181,
+1.336982, -3.677238, -19.700720, 2.500000, 1.696742, 0.999943, -0.009227, 0.005371,
+1.336982, -3.677238, -19.700720, 2.500000, 1.696742, 0.999943, -0.009227, 0.005371,
+1.002737, -4.363696, -19.552979, 2.000000, 1.696742, 0.563275, -0.773529, 0.290474,
+1.002737, -5.128252, -21.846479, 2.000000, 1.550938, 0.566340, -0.790066, 0.234638,
+1.002737, -5.128252, -21.846479, 2.000000, 1.550938, 0.566340, -0.790066, 0.234638,
+1.002737, -5.694758, -24.033106, 2.000000, 1.417808, 0.566494, -0.804616, 0.177981,
+1.336982, -4.998410, -24.141369, 2.500000, 1.417808, 0.999879, -0.015055, 0.003873,
+1.336982, -5.505962, -27.491592, 2.500000, 1.186658, 0.999932, -0.011526, 0.001722,
+1.002737, -4.798269, -27.533844, 3.000000, 1.186658, 0.583019, 0.808019, -0.084825,
+1.002737, -4.628780, -26.085621, 3.000000, 1.298722, 0.582983, 0.803361, -0.121414,
+1.002737, -4.628780, -26.085621, 3.000000, 1.298722, 0.582983, 0.803361, -0.121414,
+1.002737, -4.302059, -24.249632, 3.000000, 1.417808, 0.582444, 0.793471, -0.176531,
+1.336982, -4.998410, -24.141369, 2.500000, 1.417808, 0.999879, -0.015055, 0.003873,
+1.336982, -4.998410, -24.141369, 2.500000, 1.417808, 0.999879, -0.015055, 0.003873,
+1.002737, -5.694758, -24.033106, 2.000000, 1.417808, 0.566494, -0.804616, 0.177981,
+1.002737, -6.033253, -25.936216, 2.000000, 1.298722, 0.568446, -0.813396, 0.123515,
+1.002737, -6.033253, -25.936216, 2.000000, 1.298722, 0.568446, -0.813396, 0.123515,
+1.002737, -6.213656, -27.449341, 2.000000, 1.186658, 0.570758, -0.816393, 0.087968,
+1.336982, -5.505962, -27.491592, 2.500000, 1.186658, 0.999932, -0.011526, 0.001722,
+1.002737, -4.882575, -28.503754, 2.500000, 1.053028, 0.589040, 0.805067, -0.069986,
+1.002737, -4.798269, -27.533844, 3.000000, 1.053028, 0.583019, 0.808019, -0.084825,
+1.336982, -5.505962, -27.491592, 3.000000, 1.119843, 0.999932, -0.011526, 0.001722,
+1.336982, -5.505962, -27.491592, 3.000000, 1.119843, 0.999932, -0.011526, 0.001722,
+1.002737, -6.213656, -27.449341, 3.000000, 1.186658, 0.570758, -0.816393, 0.087968,
+1.002737, -6.305892, -28.466030, 2.500000, 1.186658, 0.565626, -0.821288, 0.074517,
+0.000000, -23.748404, -4.519603, 3.000000, 1.026514, -0.000000, -0.884854, 0.465869,
+-1.002737, -23.539934, -4.622173, 3.000000, 1.053028, -0.559738, -0.733607, 0.385376,
+-1.002737, -24.101816, -5.795360, 2.500000, 1.053028, -0.571338, -0.788867, 0.226409,
+-1.002737, -24.101816, -5.795360, 2.500000, 1.053028, -0.571338, -0.788867, 0.226409,
+-0.742768, -24.152987, -6.401496, 2.000000, 1.053028, -0.455754, -0.834431, -0.309862,
+0.000000, -24.406044, -6.530420, 2.000000, 1.026514, 0.000000, -0.933376, -0.358900,
+0.000000, -24.406044, -6.530420, 2.000000, 1.026514, 0.000000, -0.933376, -0.358900,
+0.742768, -24.152987, -6.401496, 2.000000, 1.000000, 0.455754, -0.834430, -0.309862,
+1.002737, -24.101816, -5.795360, 2.500000, 1.000000, 0.571338, -0.788867, 0.226409,
+1.002737, -24.101816, -5.795360, 2.500000, 1.000000, 0.571338, -0.788867, 0.226409,
+1.002737, -23.539934, -4.622173, 3.000000, 1.000000, 0.559738, -0.733607, 0.385376,
+0.000000, -23.748404, -4.519603, 3.000000, 1.026514, -0.000000, -0.884854, 0.465869,
+0.000000, -21.564705, -1.218530, 3.500000, 4.901888, 0.000000, -0.737549, 0.675293,
+-1.002737, -21.393009, -1.363454, 4.000000, 4.915090, -0.538985, -0.621423, 0.568620,
+-1.002737, -22.670450, -3.070609, 4.000000, 4.957545, -0.549531, -0.697669, 0.459646,
+-1.002737, -22.670450, -3.070609, 4.000000, 4.957545, -0.549531, -0.697669, 0.459646,
+-1.002737, -23.539934, -4.622173, 4.000000, 5.000000, -0.559738, -0.733607, 0.385376,
+0.000000, -23.748404, -4.519603, 3.500000, 5.000000, -0.000000, -0.884854, 0.465869,
+0.000000, -23.748404, -4.519603, 3.500000, 5.000000, -0.000000, -0.884854, 0.465869,
+1.002737, -23.539934, -4.622173, 3.000000, 5.000000, 0.559738, -0.733607, 0.385376,
+1.002737, -22.670450, -3.070609, 3.000000, 4.957545, 0.549531, -0.697669, 0.459646,
+1.002737, -22.670450, -3.070609, 3.000000, 4.957545, 0.549531, -0.697669, 0.459646,
+1.002737, -21.393009, -1.363454, 3.000000, 4.901887, 0.538985, -0.621423, 0.568620,
+0.000000, -21.564705, -1.218530, 3.500000, 4.901888, 0.000000, -0.737549, 0.675293,
+0.000000, -17.551340, 1.784490, 3.500000, 4.706708, -0.000000, -0.412059, 0.911157,
+-1.002737, -17.444981, 1.593854, 4.000000, 4.724558, -0.523473, -0.350048, 0.776815,
+-1.002737, -19.607264, 0.276508, 4.000000, 4.819824, -0.531663, -0.507888, 0.677779,
+-1.002737, -19.607264, 0.276508, 4.000000, 4.819824, -0.531663, -0.507888, 0.677779,
+-1.002737, -21.393009, -1.363454, 4.000000, 4.915090, -0.538985, -0.621423, 0.568620,
+0.000000, -21.564705, -1.218530, 3.500000, 4.901888, 0.000000, -0.737549, 0.675293,
+0.000000, -21.564705, -1.218530, 3.500000, 4.901888, 0.000000, -0.737549, 0.675293,
+1.002737, -21.393009, -1.363454, 3.000000, 4.901887, 0.538985, -0.621423, 0.568620,
+1.002737, -19.607264, 0.276508, 3.000000, 4.819824, 0.531663, -0.507888, 0.677779,
+1.002737, -19.607264, 0.276508, 3.000000, 4.819824, 0.531663, -0.507888, 0.677779,
+1.002737, -17.444981, 1.593854, 3.000000, 4.706708, 0.523473, -0.350048, 0.776815,
+0.000000, -17.551340, 1.784490, 3.500000, 4.706708, -0.000000, -0.412059, 0.911157,
+0.000000, -12.565042, 2.860814, 3.500000, 4.382352, -0.000000, -0.071332, 0.997453,
+-1.002737, -12.539209, 2.645355, 4.000000, 4.391225, -0.529316, -0.059790, 0.846315,
+-1.002737, -15.037928, 2.333167, 4.000000, 4.557892, -0.524224, -0.178780, 0.832603,
+-1.002737, -15.037928, 2.333167, 4.000000, 4.557892, -0.524224, -0.178780, 0.832603,
+-1.002737, -17.444981, 1.593854, 4.000000, 4.724558, -0.523473, -0.350048, 0.776815,
+0.000000, -17.551340, 1.784490, 3.500000, 4.706708, -0.000000, -0.412059, 0.911157,
+0.000000, -17.551340, 1.784490, 3.500000, 4.706708, -0.000000, -0.412059, 0.911157,
+1.002737, -17.444981, 1.593854, 3.000000, 4.706708, 0.523473, -0.350048, 0.776815,
+1.002737, -15.037928, 2.333167, 3.000000, 4.557891, 0.524224, -0.178780, 0.832603,
+1.002737, -15.037928, 2.333167, 3.000000, 4.557891, 0.524224, -0.178780, 0.832603,
+1.002737, -12.539209, 2.645355, 3.000000, 4.382352, 0.529316, -0.059790, 0.846315,
+0.000000, -12.565042, 2.860814, 3.500000, 4.382352, -0.000000, -0.071332, 0.997453,
+0.000000, -7.814985, 2.580152, 3.500000, 3.977933, -0.000000, 0.247588, 0.968866,
+-1.002737, -7.868385, 2.366725, 4.000000, 3.986911, -0.526810, 0.210598, 0.823480,
+-1.002737, -10.101929, 2.681329, 4.000000, 4.189068, -0.529646, 0.050516, 0.846713,
+-1.002737, -10.101929, 2.681329, 4.000000, 4.189068, -0.529646, 0.050516, 0.846713,
+-1.002737, -12.539209, 2.645355, 4.000000, 4.391225, -0.529316, -0.059790, 0.846315,
+0.000000, -12.565042, 2.860814, 3.500000, 4.382352, -0.000000, -0.071332, 0.997453,
+0.000000, -12.565042, 2.860814, 3.500000, 4.382352, -0.000000, -0.071332, 0.997453,
+1.002737, -12.539209, 2.645355, 3.000000, 4.382352, 0.529316, -0.059790, 0.846315,
+1.002737, -10.101929, 2.681329, 3.000000, 4.189068, 0.529646, 0.050516, 0.846713,
+1.002737, -10.101929, 2.681329, 3.000000, 4.189068, 0.529646, 0.050516, 0.846713,
+1.002737, -7.868385, 2.366725, 3.000000, 3.977933, 0.526810, 0.210598, 0.823480,
+0.000000, -7.814985, 2.580152, 3.500000, 3.977933, -0.000000, 0.247588, 0.968866,
+0.000000, -4.225573, 0.668588, 3.500000, 3.518014, -0.000000, 0.644556, 0.764557,
+-1.002737, -4.339529, 0.487975, 4.000000, 3.510776, -0.515414, 0.553092, 0.654552,
+-1.002737, -5.980879, 1.627182, 4.000000, 3.748844, -0.522694, 0.400366, 0.752661,
+-1.002737, -5.980879, 1.627182, 4.000000, 3.748844, -0.522694, 0.400366, 0.752661,
+-1.002737, -7.868385, 2.366725, 4.000000, 3.986911, -0.526810, 0.210598, 0.823480,
+0.000000, -7.814985, 2.580152, 3.500000, 3.977933, -0.000000, 0.247588, 0.968866,
+0.000000, -7.814985, 2.580152, 3.500000, 3.977933, -0.000000, 0.247588, 0.968866,
+1.002737, -7.868385, 2.366725, 3.000000, 3.977933, 0.526810, 0.210598, 0.823480,
+1.002737, -5.980879, 1.627182, 3.000000, 3.748844, 0.522693, 0.400366, 0.752661,
+1.002737, -5.980879, 1.627182, 3.000000, 3.748844, 0.522693, 0.400366, 0.752661,
+1.002737, -4.339529, 0.487975, 3.000000, 3.518014, 0.515414, 0.553092, 0.654552,
+0.000000, -4.225573, 0.668588, 3.500000, 3.518014, -0.000000, 0.644556, 0.764557,
+0.000000, -1.389704, -2.649346, 3.500000, 3.096704, 0.000000, 0.838537, 0.544844,
+-1.002737, -1.550434, -2.775177, 4.000000, 3.092546, -0.505987, 0.723592, 0.469458,
+-1.002737, -2.844458, -1.025621, 4.000000, 3.301661, -0.509526, 0.653879, 0.559309,
+-1.002737, -2.844458, -1.025621, 4.000000, 3.301661, -0.509526, 0.653879, 0.559309,
+-1.002737, -4.339529, 0.487975, 4.000000, 3.510776, -0.515414, 0.553092, 0.654552,
+0.000000, -4.225573, 0.668588, 3.500000, 3.518014, -0.000000, 0.644556, 0.764557,
+0.000000, -4.225573, 0.668588, 3.500000, 3.518014, -0.000000, 0.644556, 0.764557,
+1.002737, -4.339529, 0.487975, 3.000000, 3.518014, 0.515414, 0.553092, 0.654552,
+1.002737, -2.844458, -1.025621, 3.000000, 3.301661, 0.509526, 0.653879, 0.559309,
+1.002737, -2.844458, -1.025621, 3.000000, 3.301661, 0.509526, 0.653879, 0.559309,
+1.002737, -1.550435, -2.775177, 3.000000, 3.096704, 0.505988, 0.723592, 0.469458,
+0.000000, -1.389704, -2.649346, 3.500000, 3.096704, 0.000000, 0.838537, 0.544844,
+0.000000, 0.406973, -6.557009, 3.500000, 2.714038, -0.000000, 0.968208, 0.250145,
+-1.002737, 0.212360, -6.622896, 4.000000, 2.707584, -0.505652, 0.835716, 0.214230,
+-1.002737, -0.512230, -4.622262, 4.000000, 2.900065, -0.503207, 0.785550, 0.360132,
+-1.002737, -0.512230, -4.622262, 4.000000, 2.900065, -0.503207, 0.785550, 0.360132,
+-1.002737, -1.550434, -2.775177, 4.000000, 3.092546, -0.505987, 0.723592, 0.469458,
+0.000000, -1.389704, -2.649346, 3.500000, 3.096704, 0.000000, 0.838537, 0.544844,
+0.000000, -1.389704, -2.649346, 3.500000, 3.096704, 0.000000, 0.838537, 0.544844,
+1.002737, -1.550435, -2.775177, 3.000000, 3.096704, 0.505988, 0.723592, 0.469458,
+1.002737, -0.512230, -4.622262, 3.000000, 2.900065, 0.503207, 0.785549, 0.360132,
+1.002737, -0.512230, -4.622262, 3.000000, 2.900065, 0.503207, 0.785549, 0.360132,
+1.002737, 0.212362, -6.622896, 3.000000, 2.714038, 0.505651, 0.835716, 0.214230,
+0.000000, 0.406973, -6.557009, 3.500000, 2.714038, -0.000000, 0.968208, 0.250145,
+0.000000, 0.684505, -11.092790, 3.500000, 2.371212, 0.000000, 0.987685, -0.156457,
+-1.002737, 0.467394, -11.098533, 4.000000, 2.374251, -0.517497, 0.844529, -0.137721,
+-1.002737, 0.565540, -8.833092, 4.000000, 2.540917, -0.512670, 0.857167, 0.049331,
+-1.002737, 0.565540, -8.833092, 4.000000, 2.540917, -0.512670, 0.857167, 0.049331,
+-1.002737, 0.212360, -6.622896, 4.000000, 2.707584, -0.505652, 0.835716, 0.214230,
+0.000000, 0.406973, -6.557009, 3.500000, 2.714038, -0.000000, 0.968208, 0.250145,
+0.000000, 0.406973, -6.557009, 3.500000, 2.714038, -0.000000, 0.968208, 0.250145,
+1.002737, 0.212362, -6.622896, 3.000000, 2.714038, 0.505651, 0.835716, 0.214230,
+1.002737, 0.565540, -8.833092, 3.000000, 2.540917, 0.512670, 0.857168, 0.049331,
+1.002737, 0.565540, -8.833092, 3.000000, 2.540917, 0.512670, 0.857168, 0.049331,
+1.002737, 0.467394, -11.098533, 3.000000, 2.371212, 0.517497, 0.844529, -0.137721,
+0.000000, 0.684505, -11.092790, 3.500000, 2.371212, 0.000000, 0.987685, -0.156457,
+0.000000, -0.859908, -15.445475, 3.500000, 2.020624, 0.000000, 0.916600, -0.399806,
+-1.002737, -1.085560, -15.409132, 4.000000, 2.016609, -0.545979, 0.767296, -0.336399,
+-1.002737, -0.161999, -13.264900, 4.000000, 2.195430, -0.528455, 0.798898, -0.287224,
+-1.002737, -0.161999, -13.264900, 4.000000, 2.195430, -0.528455, 0.798898, -0.287224,
+-1.002737, 0.467394, -11.098533, 4.000000, 2.374251, -0.517497, 0.844529, -0.137721,
+0.000000, 0.684505, -11.092790, 3.500000, 2.371212, 0.000000, 0.987685, -0.156457,
+0.000000, 0.684505, -11.092790, 3.500000, 2.371212, 0.000000, 0.987685, -0.156457,
+1.002737, 0.467394, -11.098533, 3.000000, 2.371212, 0.517497, 0.844529, -0.137721,
+1.002737, -0.161999, -13.264900, 3.000000, 2.195430, 0.528455, 0.798898, -0.287224,
+1.002737, -0.161999, -13.264900, 3.000000, 2.195430, 0.528455, 0.798898, -0.287224,
+1.002737, -1.085560, -15.409132, 3.000000, 2.020624, 0.545979, 0.767296, -0.336399,
+0.000000, -0.859908, -15.445475, 3.500000, 2.020624, 0.000000, 0.916600, -0.399806,
+0.000000, -2.761963, -19.897703, 3.500000, 1.696742, 0.000000, 0.936891, -0.349623,
+-1.002737, -2.990782, -19.848455, 4.000000, 1.691091, -0.573541, 0.767562, -0.286181,
+-1.002737, -2.066217, -17.608171, 4.000000, 1.853850, -0.561407, 0.760416, -0.326481,
+-1.002737, -2.066217, -17.608171, 4.000000, 1.853850, -0.561407, 0.760416, -0.326481,
+-1.002737, -1.085560, -15.409132, 4.000000, 2.016609, -0.545979, 0.767296, -0.336399,
+0.000000, -0.859908, -15.445475, 3.500000, 2.020624, 0.000000, 0.916600, -0.399806,
+0.000000, -0.859908, -15.445475, 3.500000, 2.020624, 0.000000, 0.916600, -0.399806,
+1.002737, -1.085560, -15.409132, 3.000000, 2.020624, 0.545979, 0.767296, -0.336399,
+1.002737, -2.066217, -17.608171, 3.000000, 1.853850, 0.561407, 0.760416, -0.326481,
+1.002737, -2.066217, -17.608171, 3.000000, 1.853850, 0.561407, 0.760416, -0.326481,
+1.002737, -2.990782, -19.848455, 3.000000, 1.696742, 0.573541, 0.767561, -0.286181,
+0.000000, -2.761963, -19.897703, 3.500000, 1.696742, 0.000000, 0.936891, -0.349623,
+0.000000, -4.069942, -24.285717, 3.500000, 1.417808, 0.000000, 0.976057, -0.217516,
+-1.002737, -4.302059, -24.249632, 4.000000, 1.410785, -0.582444, 0.793471, -0.176531,
+-1.002737, -3.746061, -22.116426, 4.000000, 1.550938, -0.578794, 0.781497, -0.232937,
+-1.002737, -3.746061, -22.116426, 4.000000, 1.550938, -0.578794, 0.781497, -0.232937,
+-1.002737, -2.990782, -19.848455, 4.000000, 1.691091, -0.573541, 0.767562, -0.286181,
+0.000000, -2.761963, -19.897703, 3.500000, 1.696742, 0.000000, 0.936891, -0.349623,
+0.000000, -2.761963, -19.897703, 3.500000, 1.696742, 0.000000, 0.936891, -0.349623,
+1.002737, -2.990782, -19.848455, 3.000000, 1.696742, 0.573541, 0.767561, -0.286181,
+1.002737, -3.746061, -22.116426, 3.000000, 1.550938, 0.578794, 0.781497, -0.232937,
+1.002737, -3.746061, -22.116426, 3.000000, 1.550938, 0.578794, 0.781497, -0.232937,
+1.002737, -4.302059, -24.249632, 3.000000, 1.417808, 0.582444, 0.793471, -0.176531,
+0.000000, -4.069942, -24.285717, 3.500000, 1.417808, 0.000000, 0.976057, -0.217516,
+0.000000, -4.562372, -27.547928, 3.500000, 1.186658, 0.000000, 0.994554, -0.104226,
+-1.002737, -4.798269, -27.533844, 4.000000, 1.186658, -0.583018, 0.808019, -0.084825,
+-1.002737, -4.628780, -26.085621, 4.000000, 1.298722, -0.582983, 0.803361, -0.121414,
+-1.002737, -4.628780, -26.085621, 4.000000, 1.298722, -0.582983, 0.803361, -0.121414,
+-1.002737, -4.302059, -24.249632, 4.000000, 1.410785, -0.582444, 0.793471, -0.176531,
+0.000000, -4.069942, -24.285717, 3.500000, 1.417808, 0.000000, 0.976057, -0.217516,
+0.000000, -4.069942, -24.285717, 3.500000, 1.417808, 0.000000, 0.976057, -0.217516,
+1.002737, -4.302059, -24.249632, 3.000000, 1.417808, 0.582444, 0.793471, -0.176531,
+1.002737, -4.628780, -26.085621, 3.000000, 1.298722, 0.582983, 0.803361, -0.121414,
+1.002737, -4.628780, -26.085621, 3.000000, 1.298722, 0.582983, 0.803361, -0.121414,
+1.002737, -4.798269, -27.533844, 3.000000, 1.186658, 0.583019, 0.808019, -0.084825,
+0.000000, -4.562372, -27.547928, 3.500000, 1.186658, 0.000000, 0.994554, -0.104226,
+-1.002737, -4.882575, -28.503754, 3.500000, 1.053028, -0.589040, 0.805068, -0.069986,
+-1.002737, -4.798269, -27.533844, 4.000000, 1.053028, -0.583018, 0.808019, -0.084825,
+0.000000, -4.562372, -27.547928, 4.000000, 1.119843, 0.000000, 0.994554, -0.104226,
+0.000000, -4.562372, -27.547928, 4.000000, 1.119843, 0.000000, 0.994554, -0.104226,
+1.002737, -4.798269, -27.533844, 4.000000, 1.186658, 0.583019, 0.808019, -0.084825,
+1.002737, -4.882575, -28.503754, 3.500000, 1.186658, 0.589040, 0.805067, -0.069986,
+1.010821, 4.753092, -11.679992, 3.500000, 1.000000, 0.576512, -0.780907, 0.240454,
+1.014864, 3.544037, -14.721523, 3.000000, 1.000000, 0.562535, -0.748836, 0.350428,
+1.349109, 4.237772, -14.807808, 3.000000, 1.026514, 0.999805, 0.015731, -0.011963,
+1.349109, 4.237772, -14.807808, 3.000000, 1.026514, 0.999805, 0.015731, -0.011963,
+1.014864, 4.931509, -14.894089, 3.000000, 1.053028, 0.545447, 0.762198, -0.348629,
+1.010821, 6.148220, -11.777804, 3.500000, 1.053028, 0.548873, 0.801150, -0.238531,
+1.010821, 6.148220, -11.777804, 3.500000, 1.053028, 0.548873, 0.801150, -0.238531,
+1.004758, 6.770885, -8.754030, 4.000000, 1.053028, 0.549543, 0.833398, -0.058740,
+1.339004, 6.071638, -8.749280, 4.000000, 1.026514, 0.999013, 0.044275, -0.003633,
+1.339004, 6.071638, -8.749280, 4.000000, 1.026514, 0.999013, 0.044275, -0.003633,
+1.004758, 5.372389, -8.744530, 4.000000, 1.000000, 0.594556, -0.801738, 0.060986,
+1.010821, 4.753092, -11.679992, 3.500000, 1.000000, 0.576512, -0.780907, 0.240454,
+-0.994652, 4.753092, -11.679992, 2.000000, 0.093876, -0.576606, -0.781401, 0.238616,
+-0.990610, 3.544037, -14.721523, 2.000000, 0.267209, -0.562098, -0.749029, 0.350717,
+0.012127, 3.312792, -14.692760, 2.500000, 0.267209, 0.000169, -0.904592, 0.426279,
+0.012127, 3.312792, -14.692760, 2.500000, 0.267209, 0.000169, -0.904592, 0.426279,
+1.014864, 3.544037, -14.721523, 3.000000, 0.267209, 0.562535, -0.748836, 0.350428,
+1.010821, 4.753092, -11.679992, 3.000000, 0.093875, 0.576512, -0.780907, 0.240454,
+1.010821, 4.753092, -11.679992, 3.000000, 0.093875, 0.576512, -0.780907, 0.240454,
+1.004758, 5.372389, -8.744530, 3.000000, -0.079458, 0.594556, -0.801738, 0.060986,
+0.002021, 5.139305, -8.742946, 2.500000, -0.079458, -0.000101, -0.997122, 0.075814,
+0.002021, 5.139305, -8.742946, 2.500000, -0.079458, -0.000101, -0.997122, 0.075814,
+-1.000716, 5.372389, -8.744530, 2.000000, -0.079458, -0.594849, -0.801661, 0.059106,
+-0.994652, 4.753092, -11.679992, 2.000000, 0.093876, -0.576606, -0.781401, 0.238616,
+-0.994652, 6.148220, -11.777804, 1.187500, 0.109894, -0.548576, 0.800857, -0.240193,
+-0.990610, 4.931509, -14.894089, 1.000000, 0.267209, -0.544986, 0.762408, -0.348891,
+-1.324855, 4.237772, -14.807808, 1.500000, 0.267209, -0.999804, 0.015791, -0.011962,
+-1.324855, 4.237772, -14.807808, 1.500000, 0.267209, -0.999804, 0.015791, -0.011962,
+-0.990610, 3.544037, -14.721523, 2.000000, 0.267209, -0.562098, -0.749029, 0.350717,
+-0.994652, 4.753092, -11.679992, 2.000000, 0.093876, -0.576606, -0.781401, 0.238616,
+-0.994652, 4.753092, -11.679992, 2.000000, 0.093876, -0.576606, -0.781401, 0.238616,
+-1.000716, 5.372389, -8.744530, 2.000000, -0.079458, -0.594849, -0.801661, 0.059106,
+-1.334961, 6.071638, -8.749280, 1.500000, -0.079458, -0.999000, 0.044233, -0.006500,
+-1.334961, 6.071638, -8.749280, 1.500000, -0.079458, -0.999000, 0.044233, -0.006500,
+-1.000716, 6.770885, -8.754030, 1.000000, -0.079458, -0.549751, 0.833161, -0.060139,
+-0.994652, 6.148220, -11.777804, 1.187500, 0.109894, -0.548576, 0.800857, -0.240193,
+1.010821, 6.148220, -11.777804, 1.500000, 0.222021, 0.548873, 0.801150, -0.238531,
+1.014864, 4.931509, -14.894089, 3.000000, 0.523501, 0.545447, 0.762198, -0.348629,
+0.012127, 5.162754, -14.922852, 2.000000, 0.395355, 0.000167, 0.910359, -0.413819,
+0.012127, 5.162754, -14.922852, 2.000000, 0.395355, 0.000167, 0.910359, -0.413819,
+-0.990610, 4.931509, -14.894089, 1.000000, 0.267209, -0.544986, 0.762408, -0.348891,
+-0.994652, 6.148220, -11.777804, 1.187500, 0.109894, -0.548576, 0.800857, -0.240193,
+-0.994652, 6.148220, -11.777804, 1.187500, 0.109894, -0.548576, 0.800857, -0.240193,
+-1.000716, 6.770885, -8.754030, 1.000000, -0.079458, -0.549751, 0.833161, -0.060139,
+0.002021, 7.003967, -8.755614, 0.500000, -0.079458, -0.000102, 0.997541, -0.070087,
+0.002021, 7.003967, -8.755614, 0.500000, -0.079458, -0.000102, 0.997541, -0.070087,
+1.004758, 6.770885, -8.754030, 0.000000, -0.079458, 0.549543, 0.833398, -0.058740,
+1.010821, 6.148220, -11.777804, 1.500000, 0.222021, 0.548873, 0.801150, -0.238531,
+-1.002737, 1.949966, 10.301342, 3.000000, 0.093875, -0.548106, -0.827983, 0.118418,
+-1.002737, 1.707661, 7.456823, 3.000000, 0.267209, -0.546192, -0.837529, 0.014826,
+0.000000, 1.483450, 7.466458, 3.000000, 0.395355, 0.000000, -0.999837, 0.018050,
+0.000000, 1.483450, 7.466458, 3.000000, 0.395355, 0.000000, -0.999837, 0.018050,
+1.002737, 1.707661, 7.456823, 3.000000, 0.523501, 0.546192, -0.837529, 0.014826,
+1.002737, 1.949966, 10.301342, 3.000000, -0.199582, 0.548430, -0.827643, 0.119301,
+1.002737, 1.949966, 10.301342, 3.000000, -0.199582, 0.548430, -0.827643, 0.119301,
+0.997835, 2.515034, 13.079953, 3.000000, -0.922665, 0.552074, -0.807195, 0.208929,
+-0.004902, 2.294706, 13.134627, 3.000000, -0.501061, 0.000247, -0.968748, 0.248048,
+-0.004902, 2.294706, 13.134627, 3.000000, -0.501061, 0.000247, -0.968748, 0.248048,
+-1.007639, 2.515034, 13.079953, 3.000000, -0.079458, -0.551445, -0.808533, 0.205386,
+-1.002737, 1.949966, 10.301342, 3.000000, 0.093875, -0.548106, -0.827983, 0.118418,
+-1.002737, 3.286348, 10.103830, 1.187500, -1.435965, -0.570397, 0.812622, -0.119555,
+-1.002737, 3.052929, 7.399012, 1.000000, -1.306215, -0.571504, 0.820505, -0.012461,
+-1.336982, 2.380295, 7.427917, 1.500000, -1.306215, -0.999670, -0.025705, 0.000199,
+-1.336982, 2.380295, 7.427917, 1.500000, -1.306215, -0.999670, -0.025705, 0.000199,
+-1.002737, 1.707661, 7.456823, 2.000000, -1.306215, -0.546192, -0.837529, 0.014826,
+-1.002737, 1.949966, 10.301342, 2.000000, -1.459937, -0.548106, -0.827983, 0.118418,
+-1.002737, 1.949966, 10.301342, 2.000000, -1.459937, -0.548106, -0.827983, 0.118418,
+-1.007639, 2.515034, 13.079953, 2.000000, -1.613659, -0.551445, -0.808533, 0.205386,
+-1.341885, 3.176014, 12.915927, 1.500000, -1.613659, -0.999798, -0.020077, 0.001135,
+-1.341885, 3.176014, 12.915927, 1.500000, -1.613659, -0.999798, -0.020077, 0.001135,
+-1.007639, 3.836994, 12.751901, 1.000000, -1.613659, -0.571038, 0.793815, -0.209219,
+-1.002737, 3.286348, 10.103830, 1.187500, -1.435965, -0.570397, 0.812622, -0.119555,
+1.002737, 3.286348, 10.103830, 1.500000, -1.268162, 0.570686, 0.812576, -0.118478,
+1.002737, 3.052929, 7.399012, 3.000000, -0.922665, 0.571504, 0.820504, -0.012461,
+0.000000, 3.277142, 7.389376, 2.000000, -1.114440, 0.000000, 0.999891, -0.014768,
+0.000000, 3.277142, 7.389376, 2.000000, -1.114440, 0.000000, 0.999891, -0.014768,
+-1.002737, 3.052929, 7.399012, 1.000000, -1.306215, -0.571504, 0.820505, -0.012461,
+-1.002737, 3.286348, 10.103830, 1.187500, -1.435965, -0.570397, 0.812622, -0.119555,
+-1.002737, 3.286348, 10.103830, 1.187500, -1.435965, -0.570397, 0.812622, -0.119555,
+-1.007639, 3.836994, 12.751901, 1.000000, -1.613659, -0.571038, 0.793815, -0.209219,
+-0.004902, 4.057320, 12.697225, 0.500000, -1.613659, 0.000259, 0.967531, -0.252752,
+-0.004902, 4.057320, 12.697225, 0.500000, -1.613659, 0.000259, 0.967531, -0.252752,
+0.997834, 3.836994, 12.751901, 0.000000, -1.613659, 0.571655, 0.794480, -0.204969,
+1.002737, 3.286348, 10.103830, 1.500000, -1.268162, 0.570686, 0.812576, -0.118478,
+1.002737, 1.949966, 10.301342, 3.000000, -1.459937, 0.548430, -0.827643, 0.119301,
+1.002737, 1.707661, 7.456823, 3.000000, -1.306215, 0.546192, -0.837529, 0.014826,
+1.336982, 2.380295, 7.427917, 3.000000, -1.114440, 0.999670, -0.025705, 0.000199,
+1.336982, 2.380295, 7.427917, 3.000000, -1.114440, 0.999670, -0.025705, 0.000199,
+1.002737, 3.052929, 7.399012, 3.000000, -0.922665, 0.571504, 0.820504, -0.012461,
+1.002737, 3.286348, 10.103830, 2.833333, -1.322391, 0.570686, 0.812576, -0.118478,
+1.002737, 3.286348, 10.103830, 2.833333, -1.322391, 0.570686, 0.812576, -0.118478,
+0.997834, 3.836994, 12.751901, 2.666667, -1.722117, 0.571655, 0.794480, -0.204969,
+1.332080, 3.176014, 12.915927, 2.833333, -1.667888, 0.999801, -0.018232, 0.008046,
+1.332080, 3.176014, 12.915927, 2.833333, -1.667888, 0.999801, -0.018232, 0.008046,
+0.997835, 2.515034, 13.079953, 3.000000, -1.613659, 0.552074, -0.807195, 0.208929,
+1.002737, 1.949966, 10.301342, 3.000000, -1.459937, 0.548430, -0.827643, 0.119301,
+0.983128, 5.711351, 20.357510, 2.000000, -1.459937, 0.562328, -0.698593, 0.442442,
+0.973323, 4.412262, 18.174875, 2.000000, -1.306215, 0.554281, -0.740975, 0.379115,
+1.307569, 5.044981, 17.903212, 2.500000, -1.306215, 0.999751, -0.019683, 0.010530,
+1.307569, 5.044981, 17.903212, 2.500000, -1.306215, 0.999751, -0.019683, 0.010530,
+0.973323, 5.677700, 17.631544, 3.000000, -1.306215, 0.576561, 0.724323, -0.378066,
+0.983128, 6.945759, 19.711123, 3.000000, -1.459937, 0.574803, 0.682785, -0.451006,
+0.983128, 6.945759, 19.711123, 3.000000, -1.459937, 0.574803, 0.682785, -0.451006,
+0.997834, 8.160118, 21.422651, 3.000000, -1.613659, 0.574744, 0.665807, -0.475784,
+1.332080, 7.556932, 21.789433, 2.500000, -1.613659, 0.999977, -0.005048, -0.004524,
+1.332080, 7.556932, 21.789433, 2.500000, -1.613659, 0.999977, -0.005048, -0.004524,
+0.997835, 6.953747, 22.156214, 2.000000, -1.613659, 0.572743, -0.675634, 0.464203,
+0.983128, 5.711351, 20.357510, 2.000000, -1.459937, 0.562328, -0.698593, 0.442442,
+-1.022346, 5.711351, 20.357510, 2.000000, -1.857690, -0.562464, -0.695442, 0.447208,
+-1.032151, 4.412262, 18.174877, 2.000000, -1.776346, -0.555665, -0.740194, 0.378615,
+-0.029414, 4.201355, 18.265430, 2.500000, -1.776346, -0.000535, -0.890739, 0.454514,
+-0.029414, 4.201355, 18.265430, 2.500000, -1.776346, -0.000535, -0.890739, 0.454514,
+0.973323, 4.412262, 18.174875, 3.000000, -1.776346, 0.554281, -0.740975, 0.379115,
+0.983128, 5.711351, 20.357510, 3.000000, -1.857690, 0.562328, -0.698593, 0.442442,
+0.983128, 5.711351, 20.357510, 3.000000, -1.857690, 0.562328, -0.698593, 0.442442,
+0.997835, 6.953747, 22.156214, 3.000000, -1.939034, 0.572743, -0.675634, 0.464203,
+-0.004902, 6.752687, 22.278475, 2.500000, -1.939034, 0.000369, -0.822635, 0.568570,
+-0.004902, 6.752687, 22.278475, 2.500000, -1.939034, 0.000369, -0.822635, 0.568570,
+-1.007639, 6.953747, 22.156216, 2.000000, -1.939034, -0.571627, -0.672843, 0.469600,
+-1.022346, 5.711351, 20.357510, 2.000000, -1.857690, -0.562464, -0.695442, 0.447208,
+-1.022346, 6.945759, 19.711123, 1.000000, -1.857690, -0.575450, 0.685898, -0.445422,
+-1.032151, 5.677700, 17.631544, 1.000000, -1.776346, -0.577835, 0.723604, -0.377496,
+-1.366396, 5.044981, 17.903212, 1.500000, -1.776346, -0.999757, -0.019426, 0.010462,
+-1.366396, 5.044981, 17.903212, 1.500000, -1.776346, -0.999757, -0.019426, 0.010462,
+-1.032151, 4.412262, 18.174877, 2.000000, -1.776346, -0.555665, -0.740194, 0.378615,
+-1.022346, 5.711351, 20.357510, 2.000000, -1.857690, -0.562464, -0.695442, 0.447208,
+-1.022346, 5.711351, 20.357510, 2.000000, -1.857690, -0.562464, -0.695442, 0.447208,
+-1.007639, 6.953747, 22.156216, 2.000000, -1.939034, -0.571627, -0.672843, 0.469600,
+-1.341885, 7.556932, 21.789433, 1.500000, -1.939034, -0.999989, 0.000304, 0.004665,
+-1.341885, 7.556932, 21.789433, 1.500000, -1.939034, -0.999989, 0.000304, 0.004665,
+-1.007639, 8.160118, 21.422651, 1.000000, -1.939034, -0.574068, 0.669723, -0.471080,
+-1.022346, 6.945759, 19.711123, 1.000000, -1.857690, -0.575450, 0.685898, -0.445422,
+-1.002737, 8.987209, 23.827108, 1.833333, -1.749232, -0.690086, 0.408969, 0.597098,
+-0.742768, 8.411285, 23.925793, 1.000000, -1.776346, -0.485429, -0.281111, 0.827850,
+0.000000, 8.401409, 24.234768, 1.000000, -1.857690, -0.000001, -0.291501, 0.956571,
+0.000000, 8.401409, 24.234768, 1.000000, -1.857690, -0.000001, -0.291501, 0.956571,
+0.742768, 8.411285, 23.925795, 1.000000, -1.939034, 0.485428, -0.281111, 0.827851,
+1.002737, 8.987209, 23.827108, 0.500000, -1.939034, 0.690085, 0.408969, 0.597099,
+1.002737, 8.987209, 23.827108, 0.500000, -1.939034, 0.690085, 0.408969, 0.597099,
+0.742768, 9.282909, 23.329664, 0.000000, -1.939034, 0.487250, 0.872639, 0.032983,
+0.000000, 9.573013, 23.419453, 1.333333, -1.830575, -0.000000, 0.997856, 0.065453,
+0.000000, 9.573013, 23.419453, 1.333333, -1.830575, -0.000000, 0.997856, 0.065453,
+-0.742768, 9.282909, 23.329664, 2.666667, -1.722117, -0.487251, 0.872639, 0.032983,
+-1.002737, 8.987209, 23.827108, 1.833333, -1.749232, -0.690086, 0.408969, 0.597098,
+0.983128, 6.945759, 19.711123, 1.500000, -2.000000, 0.574803, 0.682785, -0.451006,
+0.973323, 5.677700, 17.631544, 2.000000, -2.000000, 0.576561, 0.724323, -0.378066,
+-0.029414, 5.888605, 17.540989, 2.500000, -2.000000, -0.000556, 0.885983, -0.463718,
+-0.029414, 5.888605, 17.540989, 2.500000, -2.000000, -0.000556, 0.885983, -0.463718,
+-1.032151, 5.677700, 17.631544, 3.000000, -2.000000, -0.577835, 0.723604, -0.377496,
+-1.022346, 6.945759, 19.711123, 3.500000, -2.000000, -0.575450, 0.685898, -0.445422,
+-1.022346, 6.945759, 19.711123, 3.500000, -2.000000, -0.575450, 0.685898, -0.445422,
+-1.007639, 8.160118, 21.422651, 4.000000, -2.000000, -0.574068, 0.669723, -0.471080,
+-0.004902, 8.361179, 21.300390, 2.500000, -2.000000, 0.000389, 0.815229, -0.579139,
+-0.004902, 8.361179, 21.300390, 2.500000, -2.000000, 0.000389, 0.815229, -0.579139,
+0.997834, 8.160118, 21.422651, 1.000000, -2.000000, 0.574744, 0.665807, -0.475784,
+0.983128, 6.945759, 19.711123, 1.500000, -2.000000, 0.574803, 0.682785, -0.451006,
+-1.005175, 11.029587, -4.132468, 3.000000, -1.857690, -0.578521, -0.809497, -0.100142,
+-1.006394, 11.114811, -5.517140, 3.000000, -1.776346, -0.583093, -0.812392, -0.004755,
+-0.003657, 10.880220, -5.483850, 2.833333, -1.749232, -0.000127, -0.999975, -0.007088,
+-0.003657, 10.880220, -5.483850, 2.833333, -1.749232, -0.000127, -0.999975, -0.007088,
+0.999079, 11.114811, -5.517140, 2.666667, -1.722117, 0.582792, -0.812607, -0.004817,
+1.000299, 11.029585, -4.132468, 3.333333, -1.830575, 0.578319, -0.809495, -0.101318,
+1.000299, 11.029585, -4.132468, 3.333333, -1.830575, 0.578319, -0.809495, -0.101318,
+1.002127, 10.729588, -2.409474, 4.000000, -1.939034, 0.568931, -0.804350, -0.171283,
+-0.000610, 10.494156, -2.383091, 3.500000, -1.939034, 0.000040, -0.977947, -0.208854,
+-0.000610, 10.494156, -2.383091, 3.500000, -1.939034, 0.000040, -0.977947, -0.208854,
+-1.003346, 10.729588, -2.409474, 3.000000, -1.939034, -0.568927, -0.804482, -0.170679,
+-1.005175, 11.029587, -4.132468, 3.000000, -1.857690, -0.578521, -0.809497, -0.100142,
+-1.005175, 12.441681, -4.309345, 1.000000, -0.253818, -0.554831, 0.825951, 0.099839,
+-1.006394, 12.522362, -5.716876, 1.000000, -0.170915, -0.566040, 0.824377, 0.001632,
+-1.340640, 11.818584, -5.617008, 1.500000, -0.170915, -0.999853, 0.017074, 0.001872,
+-1.340640, 11.818584, -5.617008, 1.500000, -0.170915, -0.999853, 0.017074, 0.001872,
+-1.006394, 11.114811, -5.517140, 2.000000, -0.170915, -0.583093, -0.812392, -0.004755,
+-1.005175, 11.029587, -4.132468, 2.000000, -0.253818, -0.578521, -0.809497, -0.100142,
+-1.005175, 11.029587, -4.132468, 2.000000, -0.253818, -0.578521, -0.809497, -0.100142,
+-1.003346, 10.729588, -2.409474, 2.000000, -0.336720, -0.568927, -0.804482, -0.170679,
+-1.337592, 11.435898, -2.488622, 1.500000, -0.336720, -0.999671, 0.024155, 0.008634,
+-1.337592, 11.435898, -2.488622, 1.500000, -0.336720, -0.999671, 0.024155, 0.008634,
+-1.003346, 12.142200, -2.567771, 1.000000, -0.336720, -0.545383, 0.819886, 0.174196,
+-1.005175, 12.441681, -4.309345, 1.000000, -0.253818, -0.554831, 0.825951, 0.099839,
+0.000000, 25.158775, 0.885566, 0.666667, -0.891999, 0.000000, 0.098978, -0.995090,
+0.742768, 25.130249, 1.141007, 1.333333, -1.447277, 0.424007, 0.088516, -0.901323,
+1.002737, 24.600067, 1.327282, 1.166667, -0.809096, 0.595697, -0.491752, -0.635079,
+1.002737, 24.600067, 1.327282, 1.166667, -0.809096, 0.595697, -0.491752, -0.635079,
+0.742768, 24.296909, 1.783397, 1.000000, -0.170915, 0.428917, -0.894621, -0.125234,
+0.000000, 24.041351, 1.768998, 1.000000, -0.253818, 0.000000, -0.991299, -0.131630,
+0.000000, 24.041351, 1.768998, 1.000000, -0.253818, 0.000000, -0.991299, -0.131630,
+-0.742768, 24.296909, 1.783397, 1.000000, -0.336720, -0.428917, -0.894621, -0.125234,
+-1.002737, 24.600067, 1.327282, 0.500000, -0.336720, -0.595697, -0.491752, -0.635079,
+-1.002737, 24.600067, 1.327282, 0.500000, -0.336720, -0.595697, -0.491752, -0.635079,
+-0.742768, 25.130249, 1.141007, 0.000000, -0.336720, -0.424007, 0.088516, -0.901323,
+0.000000, 25.158775, 0.885566, 0.666667, -0.891999, 0.000000, 0.098978, -0.995090,
+1.000299, 12.441681, -4.309345, 1.500000, -4.000000, 0.554885, 0.826037, 0.098819,
+0.999079, 12.522362, -5.716876, 2.000000, -4.000000, 0.565733, 0.824587, 0.001687,
+-0.003657, 12.756954, -5.750165, 2.500000, -4.000000, -0.000126, 1.000000, 0.000870,
+-0.003657, 12.756954, -5.750165, 2.500000, -4.000000, -0.000126, 1.000000, 0.000870,
+-1.006394, 12.522362, -5.716876, 3.000000, -4.000000, -0.566040, 0.824377, 0.001632,
+-1.005175, 12.441681, -4.309345, 3.500000, -4.000000, -0.554831, 0.825951, 0.099839,
+-1.005175, 12.441681, -4.309345, 3.500000, -4.000000, -0.554831, 0.825951, 0.099839,
+-1.003346, 12.142200, -2.567771, 4.000000, -4.000000, -0.545383, 0.819886, 0.174196,
+-0.000610, 12.377636, -2.594154, 2.500000, -4.000000, 0.000041, 0.978486, 0.206311,
+-0.000610, 12.377636, -2.594154, 2.500000, -4.000000, 0.000041, 0.978486, 0.206311,
+1.002127, 12.142200, -2.567771, 1.000000, -4.000000, 0.545588, 0.819894, 0.173516,
+1.000299, 12.441681, -4.309345, 1.500000, -4.000000, 0.554885, 0.826037, 0.098819,
+1.000299, 11.029585, -4.132468, 4.000000, -3.848496, 0.578319, -0.809495, -0.101318,
+0.999079, 11.114811, -5.517140, 4.000000, -3.761107, 0.582792, -0.812607, -0.004817,
+1.333325, 11.818588, -5.617008, 4.000000, -3.594440, 0.999852, 0.017082, 0.001868,
+1.333325, 11.818588, -5.617008, 4.000000, -3.594440, 0.999852, 0.017082, 0.001868,
+0.999079, 12.522362, -5.716876, 4.000000, -3.427773, 0.565733, 0.824587, 0.001687,
+1.000299, 12.441681, -4.309345, 4.000000, -3.234054, 0.554885, 0.826037, 0.098819,
+1.000299, 12.441681, -4.309345, 4.000000, -3.234054, 0.554885, 0.826037, 0.098819,
+1.002127, 12.142200, -2.567771, 4.000000, -3.040334, 0.545588, 0.819894, 0.173516,
+1.336373, 11.435898, -2.488622, 4.000000, -3.488110, 0.999684, 0.024018, 0.007427,
+1.336373, 11.435898, -2.488622, 4.000000, -3.488110, 0.999684, 0.024018, 0.007427,
+1.002127, 10.729588, -2.409474, 4.000000, -3.935886, 0.568931, -0.804350, -0.171283,
+1.000299, 11.029585, -4.132468, 4.000000, -3.848496, 0.578319, -0.809495, -0.101318,
+1.002737, -23.736286, -6.771559, 0.500000, 1.053028, 0.633041, -0.276748, -0.722959,
+0.742768, -24.152987, -6.401496, 1.000000, 1.053028, 0.455754, -0.834430, -0.309862,
+0.000000, -24.406044, -6.530420, 1.500000, 1.053028, 0.000000, -0.933376, -0.358900,
+0.000000, -24.406044, -6.530420, 1.500000, 1.053028, 0.000000, -0.933376, -0.358900,
+-0.742768, -24.152987, -6.401496, 2.000000, 1.053028, -0.455754, -0.834431, -0.309862,
+-1.002737, -23.736286, -6.771559, 4.000000, -0.306819, -0.633041, -0.276747, -0.722959,
+-1.002737, -23.736286, -6.771559, 4.000000, -0.306819, -0.633041, -0.276747, -0.722959,
+-0.742768, -23.169422, -6.772669, 6.000000, -1.666667, -0.444774, 0.383424, -0.809421,
+0.000000, -23.066525, -7.012697, 3.000000, -0.306819, -0.000000, 0.424976, -0.905205,
+0.000000, -23.066525, -7.012697, 3.000000, -0.306819, -0.000000, 0.424976, -0.905205,
+0.742768, -23.169422, -6.772669, 0.000000, 1.053028, 0.444774, 0.383425, -0.809421,
+1.002737, -23.736286, -6.771559, 0.500000, 1.053028, 0.633041, -0.276748, -0.722959,
+1.336982, -2.618040, 4.463405, 4.000000, -0.333333, 0.999977, -0.006223, -0.002555,
+1.002737, -3.239137, 4.110385, 5.000000, -1.666667, 0.573276, -0.760494, -0.304965,
+1.002737, -2.684134, 2.725971, 2.500000, -0.689796, 0.555812, -0.771611, -0.309336,
+1.002737, -1.445931, 3.440848, 2.500000, -0.500000, 0.596303, 0.745197, 0.298504,
+1.002737, -1.996943, 4.816424, 3.000000, 1.000000, 0.580237, 0.756078, 0.302774,
+1.336982, -2.618040, 4.463405, 4.000000, -0.333333, 0.999977, -0.006223, -0.002555,
+-1.336982, -0.581338, -32.314465, 0.500000, 0.972854, 0.000000, -0.028514, -0.999593,
+-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593,
+-1.002737, -1.292564, -32.294178, 1.000000, 0.972854, 0.000000, -0.028512, -0.999593,
+-1.336982, 4.212124, -29.503693, 0.500000, 0.966243, 0.000000, -0.038077, -0.999275,
+-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275,
+-1.002737, 3.502487, -29.476650, 1.000000, 0.966243, 0.000000, -0.038077, -0.999275,
+-1.336982, -5.594234, -28.484890, 0.500000, 1.119843, -0.000004, -0.026495, -0.999649,
+0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649,
+-1.002737, -6.305892, -28.466030, 0.500000, 1.053028, -0.000002, -0.026494, -0.999649,
+-1.336982, -2.065033, 3.083410, 3.500000, -1.833333, 0.000000, 0.500000, -0.866025,
+0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025,
+-1.002737, -2.684134, 2.725971, 3.500000, -1.666667, 0.000000, 0.500000, -0.866025,
+1.002737, 0.129889, -32.334755, 2.937500, 0.946466, 0.000002, -0.028517, -0.999593,
+1.336982, -0.581338, -32.314465, 2.500000, 0.972854, 0.000000, -0.028517, -0.999593,
+-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593,
+-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593,
+1.336982, -0.581338, -32.314465, 2.500000, 0.972854, 0.000000, -0.028517, -0.999593,
+1.002737, -1.292564, -32.294174, 2.000000, 0.972854, 0.000002, -0.028516, -0.999593,
+-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593,
+1.002737, -1.292564, -32.294174, 2.000000, 0.972854, 0.000002, -0.028516, -0.999593,
+0.000000, -1.529640, -32.287415, 1.500000, 0.972854, 0.000002, -0.028513, -0.999593,
+-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593,
+0.000000, -1.529640, -32.287415, 1.500000, 0.972854, 0.000002, -0.028513, -0.999593,
+-1.002737, -1.292564, -32.294178, 1.000000, 0.972854, 0.000000, -0.028512, -0.999593,
+-1.002737, 0.129889, -32.334755, 3.500000, 0.761751, -0.000002, -0.028517, -0.999593,
+-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593,
+-1.336982, -0.581338, -32.314465, 0.500000, 0.972854, 0.000000, -0.028514, -0.999593,
+0.000000, 0.366964, -32.341518, 3.250000, 0.867302, 0.000000, -0.028517, -0.999593,
+-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593,
+-1.002737, 0.129889, -32.334755, 3.500000, 0.761751, -0.000002, -0.028517, -0.999593,
+1.002737, 0.129889, -32.334755, 2.937500, 0.946466, 0.000002, -0.028517, -0.999593,
+-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593,
+0.000000, 0.366964, -32.341518, 3.250000, 0.867302, 0.000000, -0.028517, -0.999593,
+1.002737, 4.921762, -29.530731, 3.000000, 0.966243, -0.000000, -0.038080, -0.999275,
+1.336982, 4.212124, -29.503689, 2.500000, 0.966243, 0.000000, -0.038077, -0.999275,
+-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275,
+-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275,
+1.336982, 4.212124, -29.503689, 2.500000, 0.966243, 0.000000, -0.038077, -0.999275,
+1.002737, 3.502487, -29.476650, 2.000000, 0.966243, 0.000000, -0.038075, -0.999275,
+-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275,
+1.002737, 3.502487, -29.476650, 2.000000, 0.966243, 0.000000, -0.038075, -0.999275,
+0.000000, 3.265942, -29.467636, 1.500000, 0.966243, 0.000000, -0.038076, -0.999275,
+-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275,
+0.000000, 3.265942, -29.467636, 1.500000, 0.966243, 0.000000, -0.038076, -0.999275,
+-1.002737, 3.502487, -29.476650, 1.000000, 0.966243, 0.000000, -0.038077, -0.999275,
+-1.002737, 4.921762, -29.530731, 4.000000, 0.966243, 0.000000, -0.038077, -0.999275,
+-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275,
+-1.336982, 4.212124, -29.503693, 0.500000, 0.966243, 0.000000, -0.038077, -0.999275,
+0.000000, 5.158308, -29.539745, 3.500000, 0.966243, -0.000000, -0.038080, -0.999275,
+-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275,
+-1.002737, 4.921762, -29.530731, 4.000000, 0.966243, 0.000000, -0.038077, -0.999275,
+1.002737, 4.921762, -29.530731, 3.000000, 0.966243, -0.000000, -0.038080, -0.999275,
+-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275,
+0.000000, 5.158308, -29.539745, 3.500000, 0.966243, -0.000000, -0.038080, -0.999275,
+1.002737, -4.882575, -28.503754, 2.500000, 1.053028, -0.000002, -0.026493, -0.999649,
+1.336982, -5.594234, -28.484890, 2.500000, 1.119843, 0.000002, -0.026495, -0.999649,
+0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649,
+0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649,
+1.336982, -5.594234, -28.484890, 2.500000, 1.119843, 0.000002, -0.026495, -0.999649,
+1.002737, -6.305892, -28.466030, 1.500000, 1.053028, 0.000002, -0.026494, -0.999649,
+0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649,
+1.002737, -6.305892, -28.466030, 1.500000, 1.053028, 0.000002, -0.026494, -0.999649,
+0.000000, -6.543112, -28.459743, 1.500000, 1.119843, 0.000000, -0.026496, -0.999649,
+0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649,
+0.000000, -6.543112, -28.459743, 1.500000, 1.119843, 0.000000, -0.026496, -0.999649,
+-1.002737, -6.305892, -28.466030, 0.500000, 1.053028, -0.000002, -0.026494, -0.999649,
+-1.002737, -4.882575, -28.503754, 3.500000, 1.053028, -0.000001, -0.026493, -0.999649,
+0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649,
+-1.336982, -5.594234, -28.484890, 0.500000, 1.119843, -0.000004, -0.026495, -0.999649,
+0.000000, -4.645356, -28.510036, 3.500000, 1.119843, 0.000000, -0.026488, -0.999649,
+0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649,
+-1.002737, -4.882575, -28.503754, 3.500000, 1.053028, -0.000001, -0.026493, -0.999649,
+1.002737, -4.882575, -28.503754, 2.500000, 1.053028, -0.000002, -0.026493, -0.999649,
+0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649,
+0.000000, -4.645356, -28.510036, 3.500000, 1.119843, 0.000000, -0.026488, -0.999649,
+1.002737, -1.445931, 3.440848, 2.500000, -0.500000, -0.000000, 0.500000, -0.866025,
+1.336982, -2.065033, 3.083410, 2.500000, -0.594898, 0.000000, 0.500000, -0.866025,
+0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025,
+0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025,
+1.336982, -2.065033, 3.083410, 2.500000, -0.594898, 0.000000, 0.500000, -0.866025,
+1.002737, -2.684134, 2.725971, 4.500000, -1.666667, -0.000000, 0.500000, -0.866025,
+0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025,
+1.002737, -2.684134, 2.725971, 4.500000, -1.666667, -0.000000, 0.500000, -0.866025,
+0.000000, -2.890502, 2.606825, 4.500000, -1.833333, 0.000000, 0.500000, -0.866026,
+0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025,
+0.000000, -2.890502, 2.606825, 4.500000, -1.833333, 0.000000, 0.500000, -0.866026,
+-1.002737, -2.684134, 2.725971, 3.500000, -1.666667, 0.000000, 0.500000, -0.866025,
+-1.002737, -1.445931, 3.440848, 2.500000, -1.666667, 0.000000, 0.500000, -0.866025,
+0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025,
+-1.336982, -2.065033, 3.083410, 3.500000, -1.833333, 0.000000, 0.500000, -0.866025,
+0.000000, -1.239565, 3.559994, 2.500000, -1.833333, 0.000000, 0.500000, -0.866025,
+0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025,
+-1.002737, -1.445931, 3.440848, 2.500000, -1.666667, 0.000000, 0.500000, -0.866025,
+1.002737, -1.445931, 3.440848, 2.500000, -0.500000, -0.000000, 0.500000, -0.866025,
+0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025,
+0.000000, -1.239565, 3.559994, 2.500000, -1.833333, 0.000000, 0.500000, -0.866025,
+4.193409, -2.445326, 32.893612, 3.000000, -0.594415, 0.682263, 0.725032, 0.094055,
+0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957,
+5.620958, -6.307936, 32.893612, 2.375000, -0.573582, 0.996241, -0.000983, 0.086619,
+0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957,
+4.193409, -10.256766, 32.893612, 1.972222, -0.557378, 0.680284, -0.725440, 0.104643,
+5.620958, -6.307936, 32.893612, 2.375000, -0.573582, 0.996241, -0.000983, 0.086619,
+0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957,
+0.000000, -11.548096, 32.893612, 1.500000, -0.573582, -0.004203, -0.998166, 0.060395,
+4.193409, -10.256766, 32.893612, 1.972222, -0.557378, 0.680284, -0.725440, 0.104643,
+0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957,
+-4.193409, -10.256766, 32.893612, 1.027778, -0.557378, -0.685012, -0.716396, 0.132421,
+0.000000, -11.548096, 32.893612, 1.500000, -0.573582, -0.004203, -0.998166, 0.060395,
+-5.620958, -6.307936, 32.893612, 0.625000, -0.573582, -0.991757, -0.001005, 0.128133,
+-4.193409, -10.256766, 32.893612, 1.027778, -0.557378, -0.685012, -0.716396, 0.132421,
+0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957,
+0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957,
+-4.193409, -2.445326, 32.893612, 0.000000, -0.594415, -0.686924, 0.716419, 0.121978,
+-5.620958, -6.307936, 32.893612, 0.625000, -0.573582, -0.991757, -0.001005, 0.128133,
+0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957,
+0.000000, -1.067776, 32.893612, 3.500000, -0.594415, -0.004492, 0.998437, 0.055707,
+-4.193409, -2.445326, 32.893612, 4.000000, -0.594415, -0.686924, 0.716419, 0.121978,
+0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957,
+4.193409, -2.445326, 32.893612, 3.000000, -0.594415, 0.682263, 0.725032, 0.094055,
+0.000000, -1.067776, 32.893612, 3.500000, -0.594415, -0.004492, 0.998437, 0.055707,
+};
diff --git a/tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.cpp b/tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.cpp
new file mode 100644
index 0000000..61586d8
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.cpp
@@ -0,0 +1,351 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "RenderInterface.h"
+#include "MeshShaderParam.h"
+#include "RenderPlugin.h"
+
+namespace RenderInterface
+{
+
+////////////////////////////////////////////////////////////////////////////////////////////
+bool InitDevice(int deviceID)
+{
+ if (!RenderPlugin::Instance()->InitDevice(deviceID))
+ {
+ MessageBox( 0, L"Could not create device.", L"Error", MB_ICONEXCLAMATION );
+ return false;
+ }
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool GetDeviceInfoString(wchar_t *str)
+{
+ return RenderPlugin::Instance()->GetDeviceInfoString(str);
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool Initialize()
+{
+ return RenderPlugin::Instance()->Initialize();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void Shutdown()
+{
+ RenderPlugin::Instance()->Shutdown();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// gpu buffer management
+///////////////////////////////////////////////////////////////////////////////
+GPUBufferResource* CreateVertexBuffer(
+ unsigned int ByteWidth, void* pSysMem)
+{
+ return RenderPlugin::Instance()->CreateVertexBuffer(ByteWidth, pSysMem);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void CopyToDevice(
+ GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth)
+{
+ RenderPlugin::Instance()->CopyToDevice(pDevicePtr, pSysMem, ByteWidth);
+}
+
+///////////////////////////////////////////////////////////////////
+// texture resource mangement
+///////////////////////////////////////////////////////////////////
+GPUShaderResource* CreateTextureResource(const char* filepath)
+{
+ return RenderPlugin::Instance()->CreateTextureSRV(filepath);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void RenderShadowMap(GPUShaderResource* pShadowSRV, float znear, float zfar)
+{
+ // update constant buffer
+ ShadowVizParam shaderParam;
+ {
+ shaderParam.m_zFar = zfar;
+ shaderParam.m_zNear = znear;
+ }
+ CopyShaderParam(SHADER_TYPE_VISUALIZE_SHADOW, &shaderParam, sizeof(ShadowVizParam), 0);
+
+ RenderPlugin::Instance()->BindPixelShaderResources(0, 1, &pShadowSRV);
+
+ // render states
+ RenderPlugin::Instance()->ApplySampler(0, SAMPLER_TYPE_POINTCLAMP);
+
+ RenderPlugin::Instance()->BindShaderResources(SHADER_TYPE_VISUALIZE_SHADOW, 1, &pShadowSRV);
+
+
+ RenderPlugin::Instance()->ApplyRasterizerState(RASTERIZER_STATE_FILL_CULL_NONE);
+ RenderPlugin::Instance()->ApplyDepthStencilState(DEPTH_STENCIL_DEPTH_NONE);
+
+ // set IA vars
+ RenderPlugin::Instance()->ClearInputLayout();
+
+ RenderPlugin::Instance()->SetPrimitiveTopologyTriangleStrip();
+
+ // set shader and tex resource
+ ApplyShader(SHADER_TYPE_VISUALIZE_SHADOW);
+
+ // draw quad
+ RenderPlugin::Instance()->Draw(3, 0);
+
+ // cleanup shader and its resource
+ RenderPlugin::Instance()->ClearPixelShaderResources(0, 1);
+ RenderPlugin::Instance()->DisableShader(SHADER_TYPE_VISUALIZE_SHADOW);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// render with full color shader
+void RenderScreenQuad(
+ GPUShaderResource* pTextureSRV
+ )
+{
+ RenderPlugin::Instance()->ApplyRasterizerState(RASTERIZER_STATE_FILL_CULL_NONE);
+ RenderPlugin::Instance()->ApplyDepthStencilState(DEPTH_STENCIL_DEPTH_NONE);
+
+ RenderPlugin::Instance()->ClearInputLayout();
+
+ RenderPlugin::Instance()->SetPrimitiveTopologyTriangleStrip();
+
+ if(pTextureSRV)
+ {
+ RenderPlugin::Instance()->BindShaderResources(SHADER_TYPE_SCREEN_QUAD, 1, &pTextureSRV);
+
+ ApplyShader(SHADER_TYPE_SCREEN_QUAD);
+
+ RenderPlugin::Instance()->BindPixelShaderResources(0, 1, &pTextureSRV);
+ RenderPlugin::Instance()->ApplySampler(0, SAMPLER_TYPE_POINTCLAMP);
+
+ RenderPlugin::Instance()->Draw(3,0);
+
+ RenderPlugin::Instance()->ClearPixelShaderResources(0, 1);
+ RenderPlugin::Instance()->DisableShader(SHADER_TYPE_SCREEN_QUAD);
+ }
+ else
+ {
+ ApplyShader(SHADER_TYPE_SCREEN_QUAD_COLOR);
+
+ RenderPlugin::Instance()->Draw(3,0);
+
+ RenderPlugin::Instance()->DisableShader(SHADER_TYPE_SCREEN_QUAD_COLOR);
+ }
+}
+
+
+void SubmitGpuWork()
+{
+ RenderPlugin::Instance()->SubmitGpuWork();
+}
+
+void WaitForGpu()
+{
+ RenderPlugin::Instance()->WaitForGpu();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// draw calls
+///////////////////////////////////////////////////////////////////////////////
+void DrawLineList(GPUBufferResource* pDevicePtr, unsigned int nVerts, unsigned int stride)
+{
+ RenderPlugin::Instance()->SetVertexBuffer(pDevicePtr, stride);
+ RenderPlugin::Instance()->SetPrimitiveTopologyLineList();
+ RenderPlugin::Instance()->Draw(nVerts, 0);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// render states management
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+void ApplyDepthStencilState(DEPTH_STENCIL_STATE state)
+{
+ RenderPlugin::Instance()->ApplyDepthStencilState(state);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void ApplyRasterizerState(RASTERIZER_STATE state)
+{
+ RenderPlugin::Instance()->ApplyRasterizerState(state);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void ApplySampler(int slot, SAMPLER_TYPE st)
+{
+ RenderPlugin::Instance()->ApplySampler(slot, st);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void ApplyBlendState(BLEND_STATE st)
+{
+ RenderPlugin::Instance()->ApplyBlendState(st);
+}
+
+void ApplyForShadow(int ForShadow)
+{
+ RenderPlugin::Instance()->ApplyForShadow(ForShadow);
+}
+
+void SwitchToDX11()
+{
+ RenderPlugin::Instance()->SwitchToDX11();
+}
+
+void FlushDX11()
+{
+ RenderPlugin::Instance()->FlushDX11();
+}
+
+void FlushDX12()
+{
+ RenderPlugin::Instance()->FlushDX12();
+}
+
+void ApplyPrimitiveTopologyLine()
+{
+ RenderPlugin::Instance()->ApplyPrimitiveTopologyLine();
+}
+
+void ApplyPrimitiveTopologyTriangle()
+{
+ RenderPlugin::Instance()->ApplyPrimitiveTopologyTriangle();
+}
+
+///////////////////////////////////////////////////////////////////
+// shader magement
+///////////////////////////////////////////////////////////////////
+void ApplyShader(SHADER_TYPE st)
+{
+ RenderPlugin::Instance()->ApplyShader(st);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void CopyShaderParam(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot)
+{
+ RenderPlugin::Instance()->CopyShaderParam(st, pSysMem, bytes, slot);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Viewport magement
+/////////////////////////////////////////////////////////////////////////////////////////
+void GetViewport(Viewport& vp)
+{
+ RenderPlugin::Instance()->GetViewport(vp);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SetViewport(const Viewport& vp)
+{
+ RenderPlugin::Instance()->SetViewport(vp);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Render window interafce
+/////////////////////////////////////////////////////////////////////////////////////////
+bool CreateRenderWindow(HWND hWnd, int nSamples)
+{
+ return RenderPlugin::Instance()->CreateRenderWindow(hWnd, nSamples);
+}
+
+bool ResizeRenderWindow(int w, int h)
+{
+ return RenderPlugin::Instance()->ResizeRenderWindow(w,h);
+}
+
+void PresentRenderWindow()
+{
+ return RenderPlugin::Instance()->PresentRenderWindow();
+}
+
+void ClearRenderWindow(float r, float g, float b)
+{
+ return RenderPlugin::Instance()->ClearRenderWindow(r,g,b);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Texture resource management
+///////////////////////////////////////////////////////////////////////////////
+static GPUShaderResource* g_backgroundTextureSRV = 0;
+
+bool LoadBackgroundTexture(const char* filePath)
+{
+ ClearBackgroundTexture();
+
+ RenderPlugin::Instance()->PreRender();
+ g_backgroundTextureSRV = RenderPlugin::Instance()->CreateTextureSRV(filePath);
+ RenderPlugin::Instance()->PostRender();
+
+ return (g_backgroundTextureSRV != 0);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void RenderBackgroundTexture()
+{
+ RenderScreenQuad(g_backgroundTextureSRV);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void ClearBackgroundTexture()
+{
+ SAFE_RELEASE(g_backgroundTextureSRV);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Text draw helper functions (using DXUT)
+/////////////////////////////////////////////////////////////////////////////////////////
+void TxtHelperBegin()
+{
+ RenderPlugin::Instance()->TxtHelperBegin();
+}
+
+void TxtHelperEnd()
+{
+ RenderPlugin::Instance()->TxtHelperEnd();
+}
+
+void TxtHelperSetInsertionPos(int x, int y)
+{
+ RenderPlugin::Instance()->TxtHelperSetInsertionPos(x,y);
+}
+
+void TxtHelperSetForegroundColor(float r, float g, float b, float a)
+{
+ RenderPlugin::Instance()->TxtHelperSetForegroundColor(r,g,b,a);
+}
+
+void TxtHelperDrawTextLine(wchar_t* str)
+{
+ RenderPlugin::Instance()->TxtHelperDrawTextLine(str);
+}
+
+} // end namespace \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.h b/tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.h
new file mode 100644
index 0000000..9bc4036
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.h
@@ -0,0 +1,175 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "windows.h"
+
+#include "RenderResources.h"
+
+// API agnostic interface for rendering
+namespace RenderInterface
+{
+ ///////////////////////////////////////////////////////////////////
+ enum RASTERIZER_STATE
+ {
+ RASTERIZER_STATE_FILL_CULL_NONE,
+ RASTERIZER_STATE_FILL_CULL_FRONT,
+ RASTERIZER_STATE_FILL_CULL_BACK,
+ RASTERIZER_STATE_WIRE,
+ RASTERIZER_STATE_END
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ enum DEPTH_STENCIL_STATE
+ {
+ DEPTH_STENCIL_DEPTH_TEST,
+ DEPTH_STENCIL_DEPTH_NONE,
+ DEPTH_STENCIL_STATE_END
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ enum SAMPLER_TYPE
+ {
+ SAMPLER_TYPE_LINEAR,
+ SAMPLER_TYPE_POINTCLAMP,
+ SAMPLER_TYPE_END,
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ enum BLEND_STATE
+ {
+ BLEND_STATE_ALPHA,
+ BLEND_STATE_NONE,
+ BLEND_STATE_END
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ enum SHADER_TYPE
+ {
+ SHADER_TYPE_MESH_RENDERING,
+ SHADER_TYPE_MESH_SHADOW,
+ SHADER_TYPE_SCREEN_QUAD,
+ SHADER_TYPE_SCREEN_QUAD_COLOR,
+ SHADER_TYPE_VISUALIZE_SHADOW,
+ SHADER_TYPE_SIMPLE_COLOR,
+#ifndef NV_ARTISTTOOLS
+ SHADER_TYPE_HAIR_SHADER_DEFAULT,
+ SHADER_TYPE_HAIR_SHADER_SHADOW,
+#endif // NV_ARTISTTOOLS
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ // global acess for render context and device to minimize D3D entry points
+ ///////////////////////////////////////////////////////////////////
+ CORELIB_EXPORT bool InitDevice(int deviceID);
+ CORELIB_EXPORT bool Initialize();
+ CORELIB_EXPORT void Shutdown();
+
+ CORELIB_EXPORT void SubmitGpuWork();
+ CORELIB_EXPORT void WaitForGpu();
+
+ ///////////////////////////////////////////////////////////////////
+ // render window management
+ ///////////////////////////////////////////////////////////////////
+ CORELIB_EXPORT bool CreateRenderWindow(HWND hWnd, int nSamples);
+ CORELIB_EXPORT bool ResizeRenderWindow(int w, int h);
+ CORELIB_EXPORT void PresentRenderWindow();
+ CORELIB_EXPORT void ClearRenderWindow(float r, float g, float b);
+
+ ///////////////////////////////////////////////////////////////////
+ // shader magement
+ ///////////////////////////////////////////////////////////////////
+ CORELIB_EXPORT void ApplyShader(SHADER_TYPE st);
+ CORELIB_EXPORT void CopyShaderParam(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot = 0);
+
+ ///////////////////////////////////////////////////////////////////
+ // viewport management
+ ///////////////////////////////////////////////////////////////////
+ struct Viewport
+ {
+ float TopLeftX;
+ float TopLeftY;
+ float Width;
+ float Height;
+ float MinDepth;
+ float MaxDepth;
+ };
+
+ CORELIB_EXPORT void GetViewport(Viewport& vp);
+ CORELIB_EXPORT void SetViewport(const Viewport& vp);
+
+ ///////////////////////////////////////////////////////////////////
+ // gpu buffer management
+ ///////////////////////////////////////////////////////////////////
+ CORELIB_EXPORT GPUBufferResource* CreateVertexBuffer( unsigned int ByteWidth, void* pSysMem = 0);
+ CORELIB_EXPORT void CopyToDevice(GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth);
+
+ ///////////////////////////////////////////////////////////////////
+ // texture resource mangement
+ ///////////////////////////////////////////////////////////////////
+ CORELIB_EXPORT GPUShaderResource* CreateTextureResource(const char* filePath);
+ CORELIB_EXPORT void RenderShadowMap(GPUShaderResource* pShadowSRV, float znear, float zfar);
+
+ ///////////////////////////////////////////////////////////////////
+ // render state management
+ ///////////////////////////////////////////////////////////////////
+ CORELIB_EXPORT void ApplyDepthStencilState(DEPTH_STENCIL_STATE state);
+ CORELIB_EXPORT void ApplyRasterizerState(RASTERIZER_STATE state);
+ CORELIB_EXPORT void ApplySampler(int slot, SAMPLER_TYPE st);
+ CORELIB_EXPORT void ApplyBlendState(BLEND_STATE st);
+
+ CORELIB_EXPORT void ApplyForShadow(int ForShadow);
+ CORELIB_EXPORT void SwitchToDX11();
+ CORELIB_EXPORT void FlushDX11();
+ CORELIB_EXPORT void FlushDX12();
+ CORELIB_EXPORT void ApplyPrimitiveTopologyLine();
+ CORELIB_EXPORT void ApplyPrimitiveTopologyTriangle();
+ ///////////////////////////////////////////////////////////////////
+ // draw calls
+ ///////////////////////////////////////////////////////////////////
+ void DrawLineList(GPUBufferResource* pVertexBuffer, unsigned int nVerts, unsigned int bytesize);
+
+ ///////////////////////////////////////////////////////////////////
+ // background textures
+ ///////////////////////////////////////////////////////////////////
+ bool LoadBackgroundTexture(const char* filePath);
+ void RenderBackgroundTexture();
+ void ClearBackgroundTexture();
+
+ ///////////////////////////////////////////////////////////////////
+ CORELIB_EXPORT bool GetDeviceInfoString(wchar_t *str);
+
+ ///////////////////////////////////////////////////////////////////
+ // text helpers
+ CORELIB_EXPORT void TxtHelperBegin();
+ CORELIB_EXPORT void TxtHelperEnd();
+ CORELIB_EXPORT void TxtHelperSetInsertionPos(int x, int y);
+ CORELIB_EXPORT void TxtHelperSetForegroundColor(float r, float g, float b, float a = 1.0f);
+ CORELIB_EXPORT void TxtHelperDrawTextLine(wchar_t* str);
+}
diff --git a/tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.cpp b/tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.cpp
new file mode 100644
index 0000000..3df8c85
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.cpp
@@ -0,0 +1,86 @@
+#include "RenderPlugin.h"
+
+#include <io.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+RenderPlugin* g_Plugin = nullptr;
+
+RenderPlugin::RenderPlugin()
+{
+ m_RenderApi = "";
+}
+
+typedef RenderPlugin*(*Func)(void);
+
+bool RenderPlugin::Load(std::vector<std::string>& render_plugins)
+{
+ if (render_plugins.size() == 0)
+ {
+ return false;
+ }
+
+ std::vector<std::string>::iterator it;
+ std::string pluginDll = "";
+ HMODULE module = NULL;
+ Func CreateFunc = NULL;
+ bool loaded = false;
+ for (it = render_plugins.begin(); it != render_plugins.end(); it++)
+ {
+#ifdef NV_ARTISTTOOLS
+ pluginDll = "RenderPlugin";
+#else
+ pluginDll = "FurRender";
+#endif
+
+ pluginDll.append(*it);
+
+#ifdef _WIN64
+ pluginDll.append(".win64");
+#else
+ pluginDll.append(".win32");
+#endif
+
+#ifdef _DEBUG
+ pluginDll.append(".d");
+#else
+#endif
+
+ pluginDll.append(".dll");
+
+ module = LoadLibraryA(pluginDll.c_str());
+ if (NULL == module)
+ return false;
+
+ CreateFunc = (Func)GetProcAddress(module, "CreateRenderPlugin");
+ if (NULL == CreateFunc)
+ return false;
+
+ g_Plugin = CreateFunc();
+ if (NULL != g_Plugin)
+ {
+ loaded = true;
+ break;
+ }
+ }
+ return loaded;
+}
+
+RenderPlugin::~RenderPlugin()
+{
+}
+
+
+RenderPlugin* RenderPlugin::Instance()
+{
+ return g_Plugin;
+}
+
+void RenderPlugin::Destroy()
+{
+ if (nullptr == g_Plugin)
+ return;
+
+ delete g_Plugin;
+ g_Plugin = nullptr;
+}
diff --git a/tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.h b/tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.h
new file mode 100644
index 0000000..e755aea
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.h
@@ -0,0 +1,124 @@
+#pragma once
+
+#include "RenderInterface.h"
+using namespace RenderInterface;
+
+class NVHairReadOnlyBuffer;
+class GPUProfiler;
+class ShadowMap;
+
+class IDXGIAdapter;
+class IUnknown;
+class IDXGIFactory1;
+class IDXGISwapChain;
+
+struct D3DHandles
+{
+public:
+ IDXGIAdapter* pAdapter;
+ IDXGIFactory1* pFactory;
+ IUnknown* pDevice;
+ IUnknown* pDeviceContext;
+
+ IDXGISwapChain* pDXGISwapChain;
+ IUnknown* pD3D11BackBuffer;
+ IUnknown* pD3D11RenderTargetView;
+ IUnknown* pD3D11DepthBuffer;
+ IUnknown* pD3D11DepthStencilView;
+};
+
+#ifdef CORERENDER_LIB
+# define CORERENDER_EXPORT Q_DECL_EXPORT
+#else
+# define CORERENDER_EXPORT Q_DECL_IMPORT
+#endif
+
+class CORELIB_EXPORT RenderPlugin
+{
+public:
+ static bool Load(std::vector<std::string>& render_plugins);
+ static RenderPlugin* Instance();
+ static void Destroy();
+
+ ~RenderPlugin();
+
+ // self
+ virtual std::string GetRenderApi() { return m_RenderApi; }
+
+ // interface
+ virtual bool InitDevice(int deviceID) = 0;
+ virtual bool Initialize() = 0;
+ virtual void Shutdown() = 0;
+ virtual void CopyToDevice(GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth) = 0;
+ virtual void ApplyDepthStencilState(DEPTH_STENCIL_STATE state) = 0;
+ virtual void ApplyRasterizerState(RASTERIZER_STATE state) = 0;
+ virtual void ApplySampler(int slot, SAMPLER_TYPE st) = 0;
+ virtual void ApplyBlendState(BLEND_STATE st) = 0;
+ virtual void GetViewport(Viewport& vp) = 0;
+ virtual void SetViewport(const Viewport& vp) = 0;
+ virtual void BindVertexShaderResources(int startSlot, int numSRVs, GPUShaderResource** ppSRVs) = 0;
+ virtual void BindPixelShaderResources(int startSlot, int numSRVs, GPUShaderResource** ppSRVs) = 0;
+ virtual void ClearVertexShaderResources(int startSlot, int numSRVs) = 0;
+ virtual void ClearPixelShaderResources(int startSlot, int numSRVs) = 0;
+ virtual void ClearInputLayout() = 0;
+ virtual void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset = 0) = 0;
+ virtual void SetPrimitiveTopologyTriangleStrip() = 0;
+ virtual void SetPrimitiveTopologyTriangleList() = 0;
+ virtual void SetPrimitiveTopologyLineList() = 0;
+ virtual void Draw(unsigned int vertexCount, unsigned int startCount = 0) = 0;
+ virtual GPUBufferResource* CreateVertexBuffer(unsigned int ByteWidth, void* pSysMem = 0) = 0;
+ virtual GPUShaderResource* CreateShaderResource(unsigned int stride, unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer = NULL) = 0;
+
+ // interface dx12
+ virtual void ApplyForShadow(int ForShadow) = 0;
+ virtual void SwitchToDX11() = 0;
+ virtual void FlushDX11() = 0;
+ virtual void FlushDX12() = 0;
+ virtual void ApplyPrimitiveTopologyLine() = 0;
+ virtual void ApplyPrimitiveTopologyTriangle() = 0;
+ virtual void SubmitGpuWork() = 0;
+ virtual void WaitForGpu() = 0;
+
+ // util
+ virtual bool CreateRenderWindow(HWND hWnd, int nSamples) = 0;
+ virtual bool ResizeRenderWindow(int w, int h) = 0;
+ virtual void PresentRenderWindow() = 0;
+ virtual void ClearRenderWindow(float r, float g, float b) = 0;
+ virtual bool GetDeviceInfoString(wchar_t *str) = 0;
+ virtual GPUShaderResource* CreateTextureSRV(const char* texturename) = 0;
+ virtual void TxtHelperBegin() = 0;
+ virtual void TxtHelperEnd() = 0;
+ virtual void TxtHelperSetInsertionPos(int x, int y) = 0;
+ virtual void TxtHelperSetForegroundColor(float r, float g, float b, float a = 1.0f) = 0;
+ virtual void TxtHelperDrawTextLine(wchar_t* str) = 0;
+
+ // shader
+ virtual bool InitializeShaders() = 0;
+ virtual void DestroyShaders() = 0;
+ virtual void ApplyShader(SHADER_TYPE st) = 0;
+ virtual void DisableShader(SHADER_TYPE st) = 0;
+ virtual void BindShaderResources(SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs) = 0;
+ virtual void CopyShaderParam(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot = 0) = 0;
+
+ // GPUProfiler
+ virtual GPUProfiler* CreateGPUProfiler() = 0;
+
+ // ShadowMap
+ virtual ShadowMap* CreateShadowMap(int resolution) = 0;
+
+ // D3D12RenderContext
+ virtual void PreRender() = 0;
+ virtual void PostRender() = 0;
+
+ // GPUMeshResources
+ virtual GPUMeshResources* GPUMeshResourcesCreate(MeshData* pMeshData, const SkinData& skinData) = 0;
+ virtual void GPUMeshResourcesRelease(GPUMeshResources* pResource) = 0;
+
+ // Get devices related
+ virtual D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles) = 0;
+
+protected:
+ RenderPlugin();
+ std::string m_RenderApi;
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.cpp b/tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.cpp
new file mode 100644
index 0000000..19863fc
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.cpp
@@ -0,0 +1,47 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "RenderResources.h"
+
+// shared path
+#include "AnimUtil.h"
+#include "MeshData.h"
+
+#include "RenderPlugin.h"
+
+////////////////////////////////////////////////////////////////////////////////////////
+GPUMeshResources* GPUMeshResources::Create(MeshData* pMeshData, const SkinData& skinData)
+{
+ return RenderPlugin::Instance()->GPUMeshResourcesCreate(pMeshData, skinData);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+void GPUMeshResources::Release()
+{
+ RenderPlugin::Instance()->GPUMeshResourcesRelease(this);
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.h b/tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.h
new file mode 100644
index 0000000..c261730
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.h
@@ -0,0 +1,72 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#pragma once
+
+#include "corelib_global.h"
+#include "CoreLib.h"
+
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; }
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////
+// API specific GPU resources (todo - add reference counting)
+//////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////////
+class GPUBufferResource
+{
+public:
+ virtual ~GPUBufferResource() {}
+ virtual void Release() = 0;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////
+class GPUShaderResource
+{
+public:
+ virtual ~GPUShaderResource() {}
+ virtual void Release() = 0;
+};
+
+class MeshData;
+class SkinData;
+
+////////////////////////////////////////////////////////////////////////////////////////
+class GPUMeshResources
+{
+public:
+ GPUBufferResource* m_pVertexBuffer;
+ GPUShaderResource* m_pBoneIndicesSRV;
+ GPUShaderResource* m_pBoneWeightsSRV;
+
+ static GPUMeshResources* Create(MeshData*, const SkinData& skinData);
+ void Release();
+};
+
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/LightShaderParam.h b/tools/ArtistTools/source/CoreLib/Render/LightShaderParam.h
new file mode 100644
index 0000000..9935f71
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/LightShaderParam.h
@@ -0,0 +1,83 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "MathUtil.h"
+
+#define MAX_LIGHTS 4
+
+// shader parameter for light
+struct LightParam
+{
+ int m_enable;
+ atcore_float3 m_dir;
+
+ int m_useShadows;
+ atcore_float3 m_color;
+
+ atcore_float3 m_ambientColor;
+ int m_isEnvLight;
+
+ int m_lhs;
+ int _reserved1;
+ int _reserved2;
+ int _reserved3;
+
+ float m_depthBias;
+ float m_depthGain;
+ int m_useEnvMap;
+ float m_intensity;
+
+ atcore_float4x4 m_viewMatrix;
+ atcore_float4x4 m_lightMatrix;
+
+public:
+ LightParam()
+ {
+ m_dir = gfsdk_makeFloat3(-1.0f, -1.0f, -1.0f);
+ m_enable = 0;
+ m_useShadows = false;
+ m_isEnvLight = 0;
+ m_useEnvMap = 0;
+
+ m_depthBias = 1.0f;
+ m_depthGain = 1.0f;
+
+ m_color = gfsdk_makeFloat3(1.0f, 1.0f, 1.0f);
+ m_ambientColor = gfsdk_makeFloat3(0.0f, 0.0f, 0.0f);
+ }
+};
+
+
+// light shader block in c-buffer
+struct LightShaderParam
+{
+ LightParam m_lightParam[MAX_LIGHTS];
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/MeshShaderParam.h b/tools/ArtistTools/source/CoreLib/Render/MeshShaderParam.h
new file mode 100644
index 0000000..5dce51d
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/MeshShaderParam.h
@@ -0,0 +1,142 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "MathUtil.h"
+#include "LightShaderParam.h"
+
+// same layout as the constant buffer used in body shader
+#define MAX_BONE_MATRICES 512
+
+// shared struct for mesh shader cbuffer and material access
+struct MeshShaderParam
+{
+ atcore_float4x4 m_ViewProjection;
+ atcore_float4x4 m_BodyTransformation;
+
+ LightShaderParam m_lightParam;
+
+ atcore_float3 m_eyePosition;
+ float m_specularShininess;
+
+ int m_useDiffuseTextures;
+ int m_useSpecularTextures;
+ int m_useNormalTextures;
+ int m_useTextures;
+
+
+ atcore_float4 m_ambientColor;
+ atcore_float4 m_diffuseColor;
+ atcore_float4 m_specularColor;
+
+ int m_wireFrame;
+ int m_useLighting;
+ int m_wireFrameOver;
+ float m_unitScale;
+
+ int m_useDQs;
+ int m_diffuseChannel;
+ int m_flatNormal;
+ int m_usePinPos;
+
+ atcore_float4x4 m_boneMatrices[MAX_BONE_MATRICES];
+ atcore_dualquaternion m_boneDQs[MAX_BONE_MATRICES];
+
+ MeshShaderParam()
+ {
+ m_specularShininess = 30.0f;
+
+ m_ambientColor = gfsdk_makeFloat4(0.0f, 0.0f, 0.0f, 1.0f);
+ m_diffuseColor = gfsdk_makeFloat4(1.0f, 1.0f, 1.0f, 1.0f);
+ m_specularColor = gfsdk_makeFloat4(0.0f, 0.0f, 0.0f, 0.0f);
+
+ m_useDiffuseTextures = true;
+ m_useSpecularTextures = true;
+ m_useNormalTextures = true;
+ m_useTextures = true;
+
+ m_wireFrame = false;
+ m_wireFrameOver = false;
+ m_useLighting = true;
+ m_unitScale = 1.0f;
+
+ m_useDQs = false;
+ m_flatNormal = false;
+
+ m_usePinPos = false;
+
+ memset(m_boneMatrices, 0, sizeof(atcore_float4x4) * MAX_BONE_MATRICES);
+ memset(m_boneDQs, 0, sizeof(atcore_dualquaternion) * MAX_BONE_MATRICES);
+ }
+};
+
+// struct for mesh shadow shader cbuffer
+struct MeshShadowShaderParam
+{
+ atcore_float4x4 m_ViewProjection;
+ atcore_float4x4 m_ViewMatrix;
+ atcore_float4x4 m_BodyTransformation;
+
+ int m_useDQs;
+ int m_usePinPos;
+ float _reserved_[2];
+
+ atcore_float4x4 m_boneMatrices[MAX_BONE_MATRICES];
+ atcore_dualquaternion m_boneDQs[MAX_BONE_MATRICES];
+
+ MeshShadowShaderParam()
+ {
+ m_useDQs = false;
+ m_usePinPos = false;
+
+ memset(m_boneMatrices, 0, sizeof(atcore_float4x4) * MAX_BONE_MATRICES);
+ memset(m_boneDQs, 0, sizeof(atcore_dualquaternion) * MAX_BONE_MATRICES);
+ }
+};
+
+struct SimpleShaderParam
+{
+ atcore_float4x4 world;
+ atcore_float4x4 view;
+ atcore_float4x4 projection;
+ atcore_float4 color;
+
+ int useVertexColor;
+ int dummy2;
+ int dummy3;
+ int dummy4;
+};
+
+struct ShadowVizParam
+{
+ float m_zNear;
+ float m_zFar;
+ float _align1;
+ float _align2;
+}; \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Render/ShadowMap.cpp b/tools/ArtistTools/source/CoreLib/Render/ShadowMap.cpp
new file mode 100644
index 0000000..72b90be
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/ShadowMap.cpp
@@ -0,0 +1,36 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "ShadowMap.h"
+
+#include "RenderPlugin.h"
+
+/////////////////////////////////////////////////////////////////////////
+ShadowMap* ShadowMap::Create(int resolution)
+{
+ return RenderPlugin::Instance()->CreateShadowMap(resolution);
+}
diff --git a/tools/ArtistTools/source/CoreLib/Render/ShadowMap.h b/tools/ArtistTools/source/CoreLib/Render/ShadowMap.h
new file mode 100644
index 0000000..9a62b06
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/ShadowMap.h
@@ -0,0 +1,48 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "d3d11.h"
+
+class GPUShaderResource;
+
+struct ShadowMap
+{
+public:
+ static ShadowMap* ShadowMap::Create(int resolution);
+ virtual ~ShadowMap() {}
+
+ virtual void Release() = 0;
+ virtual void BeginRendering(float clearDepth) = 0;
+ virtual void EndRendering() = 0;
+
+ virtual GPUShaderResource* GetShadowSRV() = 0;
+};
+
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.cpp b/tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.cpp
new file mode 100644
index 0000000..0dfb169
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.cpp
@@ -0,0 +1,493 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#include "SimpleRenderable.h"
+
+#include "RenderInterface.h"
+
+#include <vector>
+
+#include "Nv.h"
+
+static std::vector<SimpleRenderable*> g_SimpleShapes;
+
+struct DefaultVertexType
+{
+ atcore_float3 pos;
+ atcore_float4 color;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+SimpleRenderable::SimpleRenderable()
+ : m_pVertexBuffer(NV_NULL)
+ , m_numIndices(0)
+ , m_numVertices(0)
+{
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+SimpleRenderable::~SimpleRenderable()
+{
+ Free();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleRenderable::Free()
+{
+ SAFE_RELEASE(m_pVertexBuffer);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleRenderable::Initialize()
+{
+ //////////////////////////////////////////////////////////////////////////////
+ // create icon shape
+ g_SimpleShapes.resize(NUM_SHAPE_TYPES);
+
+ g_SimpleShapes[GROUND_YUP] = new SimpleRenderable;
+ g_SimpleShapes[GROUND_YUP]->InitGroundGeometry(false);
+
+ g_SimpleShapes[GROUND_ZUP] = new SimpleRenderable;
+ g_SimpleShapes[GROUND_ZUP]->InitGroundGeometry(true);
+
+ g_SimpleShapes[AXIS_YUP] = new SimpleRenderable;
+ g_SimpleShapes[AXIS_YUP]->InitAxisGeometry(false);
+
+ g_SimpleShapes[AXIS_ZUP] = new SimpleRenderable;
+ g_SimpleShapes[AXIS_ZUP]->InitAxisGeometry(true);
+
+ g_SimpleShapes[WIND_YUP] = new SimpleRenderable;
+ g_SimpleShapes[WIND_YUP]->InitWindGeometry();
+
+ g_SimpleShapes[WIND_ZUP] = new SimpleRenderable;
+ g_SimpleShapes[WIND_ZUP]->InitWindGeometry();
+
+ g_SimpleShapes[LIGHT] = new SimpleRenderable;
+ g_SimpleShapes[LIGHT]->InitLightGeometry();
+
+ g_SimpleShapes[LIGHT_RAY] = new SimpleRenderable;
+ g_SimpleShapes[LIGHT_RAY]->InitLightRayGeometry();
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void SimpleRenderable::Draw(SHAPE_TYPE t, bool depthTest)
+{
+ if (t >= g_SimpleShapes.size())
+ return;
+
+ g_SimpleShapes[t]->Draw(depthTest);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void SimpleRenderable::Shutdown()
+{
+ for (int i = 0; i < g_SimpleShapes.size(); i++)
+ {
+ if (g_SimpleShapes[i])
+ {
+ g_SimpleShapes[i]->Free();
+ delete g_SimpleShapes[i];
+ }
+ }
+
+ g_SimpleShapes.clear();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleRenderable::InitGroundGeometry(bool zUP)
+{
+ const int nSeed = 10;
+ const int nRow = nSeed * 2 + 1;
+ const int nLines = nRow * 2;
+ const float fLen = 25.0f;
+ const float fSpace = fLen/nSeed;
+ float groundHeight = 0.0f;
+
+ const atcore_float4 color1 = gfsdk_makeFloat4(0.65, 0.65, 0.65, 1.0f);
+ const atcore_float4 color2 = gfsdk_makeFloat4(0.1f, 0.1f, 0.1f, 1.0f);
+
+ DWORD offset;
+
+ const int numVerts = nLines * 2;
+ DefaultVertexType* buf = new DefaultVertexType[numVerts];
+ DefaultVertexType* pData = buf;
+
+ //build ground lines/verts
+ for(int i = 0; i < nSeed; i++)
+ {
+ if ( zUP )
+ {
+ // lines parallel to y
+ pData->pos = gfsdk_makeFloat3(-fSpace * (i+1), -fLen, groundHeight);
+ pData->color = color1;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(-fSpace * (i+1), fLen, groundHeight);
+ pData->color = color1;
+ pData++;
+
+ // lines parallel to y
+ pData->pos = gfsdk_makeFloat3(fSpace * (i+1), -fLen, groundHeight);
+ pData->color = color1;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(fSpace * (i+1), fLen, groundHeight);
+ pData->color = color1;
+ pData++;
+
+ // line x
+ pData->pos = gfsdk_makeFloat3(-fLen, -fSpace * (i+1), groundHeight);
+ pData->color = color1;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(fLen, -fSpace * (i+1), groundHeight);
+ pData->color = color1;
+ pData++;
+
+ // line x
+ pData->pos = gfsdk_makeFloat3(-fLen, fSpace * (i+1), groundHeight);
+ pData->color = color1;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(fLen, fSpace * (i+1), groundHeight);
+ pData->color = color1;
+ pData++;
+ }
+ else
+ {
+ // lines parallel to z
+ pData->pos = gfsdk_makeFloat3(-fSpace * (i+1), groundHeight, -fLen);
+ pData->color = color1;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(-fSpace * (i+1), groundHeight, fLen);
+ pData->color = color1;
+ pData++;
+
+ // lines parallel to z
+ pData->pos = gfsdk_makeFloat3(fSpace * (i+1), groundHeight, -fLen);
+ pData->color = color1;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(fSpace * (i+1), groundHeight, fLen);
+ pData->color = color1;
+ pData++;
+
+ // line x
+ pData->pos = gfsdk_makeFloat3(-fLen, groundHeight, -fSpace * (i+1));
+ pData->color = color1;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(fLen, groundHeight, -fSpace * (i+1));
+ pData->color = color1;
+ pData++;
+
+ // line x
+ pData->pos = gfsdk_makeFloat3(-fLen, groundHeight, fSpace * (i+1));
+ pData->color = color1;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(fLen, groundHeight, fSpace * (i+1));
+ pData->color = color1;
+ pData++;
+ }
+ }
+
+ if ( zUP )
+ {
+ // line y
+ pData->pos = gfsdk_makeFloat3(-fLen, 0.0f, groundHeight);
+ pData->color = color2;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(fLen, 0.0f, groundHeight);
+ pData->color = color2;
+ pData++;
+
+ // line x
+ pData->pos = gfsdk_makeFloat3(0.0f, -fLen, groundHeight);
+ pData->color = color2;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(0.0f, fLen, groundHeight);
+ pData->color = color2;
+ pData++;
+ }
+ else
+ {
+ // line z
+ pData->pos = gfsdk_makeFloat3(-fLen, groundHeight, 0.0f);
+ pData->color = color2;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(fLen, groundHeight, 0.0f);
+ pData->color = color2;
+ pData++;
+
+ // line x
+ pData->pos = gfsdk_makeFloat3(0.0f, groundHeight, -fLen);
+ pData->color = color2;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(0.0f, groundHeight, fLen);
+ pData->color = color2;
+ pData++;
+ }
+
+ int bufBytes = sizeof(DefaultVertexType) * numVerts;
+
+ m_pVertexBuffer = RenderInterface::CreateVertexBuffer(bufBytes, buf);
+
+ m_numVertices = numVerts;
+
+ return (NV_NULL != m_pVertexBuffer);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleRenderable::InitAxisGeometry(bool zUP)
+{
+ const atcore_float4 colorRed = gfsdk_makeFloat4(1.0f, 0, 0, 1.0f);
+ const atcore_float4 colorGreen = gfsdk_makeFloat4(0, 1.0f, 0, 1.0f);
+ const atcore_float4 colorBlue = gfsdk_makeFloat4(0, 0, 1.0f, 1.0f);
+ const float dist = 1.0f;
+ const int numVerts = 3 * 2;
+ DefaultVertexType* buf = new DefaultVertexType[numVerts];
+ DefaultVertexType* pData = buf;
+
+ {
+ // x axis
+ pData->pos = gfsdk_makeFloat3(0, 0, 0);
+ pData->color = colorRed;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(dist, 0, 0);
+ pData->color = colorRed;
+ pData++;
+
+ // y axis
+ pData->pos = gfsdk_makeFloat3(0, 0, 0);
+ pData->color = colorGreen;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(0, dist, 0);
+ pData->color = colorGreen;
+ pData++;
+
+ // z axis
+ pData->pos = gfsdk_makeFloat3(0, 0, 0);
+ pData->color = colorBlue;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(0, 0, dist);
+ pData->color = colorBlue;
+ pData++;
+ }
+
+ int bufBytes = sizeof(DefaultVertexType) * numVerts;
+
+ m_pVertexBuffer = RenderInterface::CreateVertexBuffer(bufBytes, buf);
+
+ m_numVertices = numVerts;
+
+ return (NV_NULL != m_pVertexBuffer);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleRenderable::InitLightGeometry()
+{
+ // The following geometry data are generated by external/ObjLoad tool
+#include "GeometryData/LightGeometryData.h"
+ const atcore_float4 colorYellow = gfsdk_makeFloat4(1.0f, 1.0f, 0, 1.0f);
+ const int numVerts = num_faces*3*2;
+ DefaultVertexType* buf = new DefaultVertexType[numVerts];
+ DefaultVertexType* pData = buf;
+
+ const float modelScale = 0.25f;
+ for (int fi = 0; fi < num_faces; ++fi)
+ {
+ float* v0 = &vertices[(fi*3+0)*8];
+ float* v1 = &vertices[(fi*3+1)*8];
+ float* v2 = &vertices[(fi*3+2)*8];
+
+ // flip Y
+ v0[2] *= -1;
+ v1[2] *= -1;
+ v2[2] *= -1;
+
+ // line 0
+ pData->pos = modelScale * gfsdk_makeFloat3(v0[0], v0[1], v0[2]);
+ pData->color = colorYellow;
+ pData++;
+
+ pData->pos = modelScale * gfsdk_makeFloat3(v1[0], v1[1], v1[2]);
+ pData->color = colorYellow;
+ pData++;
+
+ // line 1
+ pData->pos = modelScale * gfsdk_makeFloat3(v1[0], v1[1], v1[2]);
+ pData->color = colorYellow;
+ pData++;
+
+ pData->pos = modelScale * gfsdk_makeFloat3(v2[0], v2[1], v2[2]);
+ pData->color = colorYellow;
+ pData++;
+
+ // line 2
+ pData->pos = modelScale * gfsdk_makeFloat3(v2[0], v2[1], v2[2]);
+ pData->color = colorYellow;
+ pData++;
+
+ pData->pos = modelScale * gfsdk_makeFloat3(v0[0], v0[1], v0[2]);
+ pData->color = colorYellow;
+ pData++;
+ }
+
+ int bufBytes = sizeof(DefaultVertexType) * numVerts;
+
+ m_pVertexBuffer = RenderInterface::CreateVertexBuffer(bufBytes, buf);
+
+ m_numVertices = numVerts;
+
+ return (NV_NULL != m_pVertexBuffer);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleRenderable::InitLightRayGeometry()
+{
+ const atcore_float4 colorRed = gfsdk_makeFloat4(1.0f, 0, 0, 1.0f);
+ const int numVerts = 2;
+ DefaultVertexType* buf = new DefaultVertexType[numVerts];
+ DefaultVertexType* pData = buf;
+
+ pData->pos = gfsdk_makeFloat3(0, 0, 0);
+ pData->color = colorRed;
+ pData++;
+
+ pData->pos = gfsdk_makeFloat3(0, 0, 0);
+ pData->color = colorRed;
+ pData++;
+
+ int bufBytes = sizeof(DefaultVertexType) * numVerts;
+
+ m_pVertexBuffer = RenderInterface::CreateVertexBuffer(bufBytes, buf);
+
+ m_numVertices = numVerts;
+
+ return (NV_NULL != m_pVertexBuffer);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleRenderable::InitWindGeometry()
+{
+ // The following geometry data are generated by external/ObjLoad tool
+#include "GeometryData/WindGeometryData.h"
+ const atcore_float4 colorBlue = gfsdk_makeFloat4(0, 0, 1.0f, 1.0f);
+ const int numVerts = num_faces*3*2;
+ DefaultVertexType* buf = new DefaultVertexType[numVerts];
+ DefaultVertexType* pData = buf;
+
+ const float modelScale = 0.5f;
+ for (int fi = 0; fi < num_faces; ++fi)
+ {
+ float* v0 = &vertices[(fi*3+0)*8];
+ float* v1 = &vertices[(fi*3+1)*8];
+ float* v2 = &vertices[(fi*3+2)*8];
+
+ pData->pos = modelScale * gfsdk_makeFloat3(v0[0], v0[1], v0[2]);
+ pData->color = colorBlue;
+ pData++;
+
+ pData->pos = modelScale * gfsdk_makeFloat3(v1[0], v1[1], v1[2]);
+ pData->color = colorBlue;
+ pData++;
+
+ pData->pos = modelScale * gfsdk_makeFloat3(v1[0], v1[1], v1[2]);
+ pData->color = colorBlue;
+ pData++;
+
+ pData->pos = modelScale * gfsdk_makeFloat3(v2[0], v2[1], v2[2]);
+ pData->color = colorBlue;
+ pData++;
+
+ pData->pos = modelScale * gfsdk_makeFloat3(v2[0], v2[1], v2[2]);
+ pData->color = colorBlue;
+ pData++;
+
+ pData->pos = modelScale * gfsdk_makeFloat3(v0[0], v0[1], v0[2]);
+ pData->color = colorBlue;
+ pData++;
+ }
+
+ int bufBytes = sizeof(DefaultVertexType) * numVerts;
+
+ m_pVertexBuffer = RenderInterface::CreateVertexBuffer(bufBytes, buf);
+
+ m_numVertices = numVerts;
+
+ return (NV_NULL != m_pVertexBuffer);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleRenderable::Draw(bool depthTest)
+{
+ RenderInterface::ApplyPrimitiveTopologyLine();
+
+ RenderInterface::ApplyShader(RenderInterface::SHADER_TYPE_SIMPLE_COLOR);
+ RenderInterface::DrawLineList(m_pVertexBuffer, m_numVertices, sizeof(DefaultVertexType));
+
+ RenderInterface::FlushDX12();
+ RenderInterface::ApplyPrimitiveTopologyTriangle();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleRenderable::DrawLine(const atcore_float3& from, const atcore_float3& to)
+{
+ SimpleRenderable* pShape = g_SimpleShapes[LIGHT_RAY];
+
+ DefaultVertexType buf[2];
+ DefaultVertexType* pData = buf;
+
+ // start position
+ pData->pos = from;
+ pData->color = gfsdk_makeFloat4(1.0f, 1.0f, 0, 1.0f);
+ pData++;
+
+ // end position
+ pData->pos = to;
+ pData->color = gfsdk_makeFloat4(1.0f, 1.0f, 0, 1.0f);
+ pData++;
+
+ RenderInterface::CopyToDevice(pShape->m_pVertexBuffer, buf, 2 * sizeof(DefaultVertexType));
+
+ pShape->Draw(true);
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.h b/tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.h
new file mode 100644
index 0000000..c43c07d
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.h
@@ -0,0 +1,75 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#pragma once
+
+#include "MathUtil.h"
+
+class GPUBufferResource;
+
+class SimpleRenderable
+{
+public:
+ enum SHAPE_TYPE
+ {
+ GROUND_YUP,
+ GROUND_ZUP,
+ AXIS_YUP,
+ AXIS_ZUP,
+ WIND_YUP,
+ WIND_ZUP,
+ LIGHT,
+ LIGHT_RAY,
+ NUM_SHAPE_TYPES
+ };
+
+ static bool Initialize();
+ static void Shutdown();
+ static void Draw(SHAPE_TYPE t, bool depthTest = true);
+ static void DrawLine(const atcore_float3& from, const atcore_float3& to);
+
+protected:
+ GPUBufferResource* m_pVertexBuffer;
+
+ unsigned int m_numVertices;
+ unsigned int m_numIndices;
+
+ SimpleRenderable();
+ ~SimpleRenderable();
+
+ bool InitGroundGeometry(bool zUp);
+ bool InitAxisGeometry(bool zUp);
+ bool InitLightGeometry();
+ bool InitLightRayGeometry();
+ bool InitWindGeometry();
+
+ void Draw(bool depthTest = true);
+
+ void Free();
+
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Scene/Camera.cpp b/tools/ArtistTools/source/CoreLib/Scene/Camera.cpp
new file mode 100644
index 0000000..74d93f4
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/Camera.cpp
@@ -0,0 +1,867 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#include "Camera.h"
+
+//#define USE_D3DX9MATH
+#ifdef USE_D3DX9MATH
+#include <d3dx9math.h> // TODO - remove d3dx reference (quaternion funcs)
+
+#pragma comment(lib, "d3dx9.lib")
+#define MAKEVECTOR3 D3DXVECTOR3
+#else
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#define FLOAT float
+#define D3DXVECTOR3 atcore_float3
+#define D3DXMATRIX atcore_float4x4
+#define D3DXQUATERNION atcore_float4
+
+#define MAKEVECTOR3 gfsdk_makeFloat3
+
+#define D3DXToRadian( degree ) ((degree) * 0.01745329251994329547)
+
+D3DXQUATERNION * D3DXQuaternionIdentity(
+ __inout D3DXQUATERNION *pOut
+ )
+{
+ *pOut = gfsdk_makeFloat4(0, 0, 0, 1);
+ return pOut;
+}
+
+D3DXQUATERNION * D3DXQuaternionNormalize(
+ __inout D3DXQUATERNION *pOut,
+ __in const D3DXQUATERNION *pQ
+ )
+{
+ gfsdk_normalize(*pOut);
+ return pOut;
+}
+
+D3DXQUATERNION * D3DXQuaternionRotationAxis(
+ __inout D3DXQUATERNION *pOut,
+ __in const D3DXVECTOR3 *pV,
+ __in FLOAT Angle
+ )
+{
+ FLOAT s = sin(Angle * 0.5);
+
+ FLOAT x = pV->x * s;
+ FLOAT y = pV->y * s;
+ FLOAT z = pV->z * s;
+ FLOAT w = cos(Angle * 0.5);
+
+ *pOut = gfsdk_makeFloat4(x, y, z, w);
+ return pOut;
+}
+
+D3DXQUATERNION * D3DXQuaternionMultiply(
+ __inout D3DXQUATERNION *pOut,
+ __in const D3DXQUATERNION *pQ1,
+ __in const D3DXQUATERNION *pQ2
+ )
+{
+ gfsdk_normalize(*pQ1);
+ gfsdk_normalize(*pQ2);
+
+ FLOAT px = pQ2->x;
+ FLOAT py = pQ2->y;
+ FLOAT pz = pQ2->z;
+ FLOAT pw = pQ2->w;
+
+ FLOAT qx = pQ1->x;
+ FLOAT qy = pQ1->y;
+ FLOAT qz = pQ1->z;
+ FLOAT qw = pQ1->w;
+
+ FLOAT x = pw * qx + px * qw + py * qz - pz * qy;
+ FLOAT y = pw * qy + py * qw + pz * qx - px * qz;
+ FLOAT z = pw * qz + pz * qw + px * qy - py * qx;
+ FLOAT w = pw * qw - px * qx - py * qy - pz * qz;
+
+ *pOut = gfsdk_makeFloat4(x, y, z, w);
+ gfsdk_normalize(*pOut);
+ return pOut;
+}
+
+D3DXMATRIX * D3DXMatrixLookAtLH(
+ __inout D3DXMATRIX *pOut,
+ __in const D3DXVECTOR3 *pEye,
+ __in const D3DXVECTOR3 *pAt,
+ __in const D3DXVECTOR3 *pUp
+ )
+{
+ /*
+ zaxis = normal(At - Eye)
+ xaxis = normal(cross(Up, zaxis))
+ yaxis = cross(zaxis, xaxis)
+
+ xaxis.x yaxis.x zaxis.x 0
+ xaxis.y yaxis.y zaxis.y 0
+ xaxis.z yaxis.z zaxis.z 0
+ -dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1
+ */
+
+ D3DXVECTOR3 zaxis = *pAt - *pEye;
+ gfsdk_normalize(zaxis);
+ D3DXVECTOR3 xaxis = gfsdk_cross(*pUp, zaxis);
+ gfsdk_normalize(xaxis);
+ D3DXVECTOR3 yaxis = gfsdk_cross(zaxis, xaxis);
+
+ gfsdk_makeIdentity(*pOut);
+ pOut->_11 = zaxis.x;
+ pOut->_21 = zaxis.y;
+ pOut->_31 = zaxis.z;
+ pOut->_12 = yaxis.x;
+ pOut->_22 = yaxis.y;
+ pOut->_32 = yaxis.z;
+ pOut->_13 = zaxis.x;
+ pOut->_23 = zaxis.y;
+ pOut->_33 = zaxis.z;
+ pOut->_41 = -gfsdk_dot(xaxis, *pEye);
+ pOut->_42 = -gfsdk_dot(yaxis, *pEye);
+ pOut->_43 = -gfsdk_dot(zaxis, *pEye);
+ return pOut;
+}
+
+D3DXMATRIX * D3DXMatrixLookAtRH(
+ __inout D3DXMATRIX *pOut,
+ __in const D3DXVECTOR3 *pEye,
+ __in const D3DXVECTOR3 *pAt,
+ __in const D3DXVECTOR3 *pUp
+ )
+{
+ /*
+ zaxis = normal(Eye - At)
+ xaxis = normal(cross(Up, zaxis))
+ yaxis = cross(zaxis, xaxis)
+
+ xaxis.x yaxis.x zaxis.x 0
+ xaxis.y yaxis.y zaxis.y 0
+ xaxis.z yaxis.z zaxis.z 0
+ -dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1
+ */
+
+ D3DXVECTOR3 zaxis = *pEye - *pAt;
+ gfsdk_normalize(zaxis);
+ D3DXVECTOR3 xaxis = gfsdk_cross(*pUp, zaxis);
+ gfsdk_normalize(xaxis);
+ D3DXVECTOR3 yaxis = gfsdk_cross(zaxis, xaxis);
+
+ gfsdk_makeIdentity(*pOut);
+ pOut->_11 = xaxis.x;
+ pOut->_21 = xaxis.y;
+ pOut->_31 = xaxis.z;
+ pOut->_12 = yaxis.x;
+ pOut->_22 = yaxis.y;
+ pOut->_32 = yaxis.z;
+ pOut->_13 = zaxis.x;
+ pOut->_23 = zaxis.y;
+ pOut->_33 = zaxis.z;
+ pOut->_41 = -gfsdk_dot(xaxis, *pEye);
+ pOut->_42 = -gfsdk_dot(yaxis, *pEye);
+ pOut->_43 = gfsdk_dot(zaxis, *pEye);
+ return pOut;
+}
+
+D3DXMATRIX * D3DXMatrixPerspectiveFovLH(
+ __inout D3DXMATRIX *pOut,
+ __in FLOAT fovy,
+ __in FLOAT Aspect,
+ __in FLOAT zn,
+ __in FLOAT zf
+ )
+{
+ /*
+ cot(fovY/2) 0 0 0
+ 0 cot(fovY/2)/aspect 0 0
+ 0 0 zf/(zf-zn) 1
+ 0 0 -zn*zf/(zf-zn) 0
+ */
+
+ memset(pOut, 0, sizeof(D3DXMATRIX));
+ FLOAT cosHalfFovy = 1 / tan(fovy * 0.5);
+ pOut->_11 = cosHalfFovy;
+ pOut->_22 = cosHalfFovy / Aspect;
+ pOut->_33 = zf / (zf - zn);
+ pOut->_34 = 1;
+ pOut->_43 = -zn*zf / (zf - zn);
+ return pOut;
+}
+
+D3DXMATRIX * D3DXMatrixPerspectiveFovRH(
+ __inout D3DXMATRIX *pOut,
+ __in FLOAT fovy,
+ __in FLOAT Aspect,
+ __in FLOAT zn,
+ __in FLOAT zf
+ )
+{
+ /*
+ cot(fovY/2)/aspect 0 0 0
+ 0 cot(fovY/2) 0 0
+ 0 0 zf/(zn-zf) -1
+ 0 0 zn*zf/(zn-zf) 0
+ */
+
+ memset(pOut, 0, sizeof(D3DXMATRIX));
+ FLOAT cosHalfFovy = 1 / tan(fovy * 0.5);
+ pOut->_11 = cosHalfFovy / Aspect;
+ pOut->_22 = cosHalfFovy;
+ pOut->_33 = zf / (zn - zf);
+ pOut->_34 = -1;
+ pOut->_43 = zn*zf / (zn - zf);
+ return pOut;
+}
+
+D3DXMATRIX * D3DXMatrixOrthoLH(
+ __inout D3DXMATRIX *pOut,
+ __in FLOAT w,
+ __in FLOAT h,
+ __in FLOAT zn,
+ __in FLOAT zf
+ )
+{
+ /*
+ 2/w 0 0 0
+ 0 2/h 0 0
+ 0 0 1/(zf-zn) 0
+ 0 0 zn/(zn-zf) 1
+ */
+
+ gfsdk_makeIdentity(*pOut);
+ pOut->_11 = 2 / w;
+ pOut->_22 = 2 / h;
+ pOut->_33 = 1 / (zf - zn);
+ pOut->_43 = zn / (zn - zf);
+ return pOut;
+}
+
+D3DXMATRIX * D3DXMatrixOrthoRH(
+ __inout D3DXMATRIX *pOut,
+ __in FLOAT w,
+ __in FLOAT h,
+ __in FLOAT zn,
+ __in FLOAT zf
+ )
+{
+ /*
+ 2/w 0 0 0
+ 0 2/h 0 0
+ 0 0 1/(zn-zf) 0
+ 0 0 zn/(zn-zf) 1
+ */
+
+ gfsdk_makeIdentity(*pOut);
+ pOut->_11 = 2 / w;
+ pOut->_22 = 2 / h;
+ pOut->_33 = 1 / (zn - zf);
+ pOut->_43 = zn / (zn - zf);
+ return pOut;
+}
+
+D3DXQUATERNION * D3DXQuaternionRotationMatrix(
+ __inout D3DXQUATERNION *pOut,
+ __in const D3DXMATRIX *pM
+ )
+{
+ FLOAT fourXSquaredMinus1 = pM->_11 - pM->_22 - pM->_33;
+ FLOAT fourYSquaredMinus1 = pM->_22 - pM->_11 - pM->_33;
+ FLOAT fourZSquaredMinus1 = pM->_33 - pM->_11 - pM->_22;
+ FLOAT fourWSquaredMinus1 = pM->_11 + pM->_22 + pM->_33;
+
+ int biggestIndex = 0;
+ FLOAT fourBiggestSquaredMinus1 = fourWSquaredMinus1;
+ if (fourXSquaredMinus1 > fourBiggestSquaredMinus1)
+ {
+ fourBiggestSquaredMinus1 = fourXSquaredMinus1;
+ biggestIndex = 1;
+ }
+ if (fourYSquaredMinus1 > fourBiggestSquaredMinus1)
+ {
+ fourBiggestSquaredMinus1 = fourYSquaredMinus1;
+ biggestIndex = 2;
+ }
+ if (fourZSquaredMinus1 > fourBiggestSquaredMinus1)
+ {
+ fourBiggestSquaredMinus1 = fourZSquaredMinus1;
+ biggestIndex = 3;
+ }
+
+ FLOAT biggestVal = sqrt(fourBiggestSquaredMinus1 + 1) * 0.5;
+ FLOAT mult = 0.25 / biggestVal;
+
+ D3DXQuaternionIdentity(pOut);
+ switch (biggestIndex)
+ {
+ case 0:
+ pOut->w = biggestVal;
+ pOut->x = (pM->_23 - pM->_32) * mult;
+ pOut->y = (pM->_31 - pM->_13) * mult;
+ pOut->z = (pM->_12 - pM->_21) * mult;
+ break;
+ case 1:
+ pOut->w = (pM->_23 - pM->_32) * mult;
+ pOut->x = biggestVal;
+ pOut->y = (pM->_12 + pM->_21) * mult;
+ pOut->z = (pM->_31 + pM->_13) * mult;
+ break;
+ case 2:
+ pOut->w = (pM->_31 - pM->_13) * mult;
+ pOut->x = (pM->_12 + pM->_21) * mult;
+ pOut->y = biggestVal;
+ pOut->z = (pM->_23 + pM->_32) * mult;
+ break;
+ case 3:
+ pOut->w = (pM->_12 - pM->_21) * mult;
+ pOut->x = (pM->_31 + pM->_13) * mult;
+ pOut->y = (pM->_23 + pM->_32) * mult;
+ pOut->z = biggestVal;
+ break;
+ default:
+ break;
+ }
+ return pOut;
+}
+
+D3DXMATRIX * D3DXMatrixRotationQuaternion(
+ __inout D3DXMATRIX *pOut,
+ __in const D3DXQUATERNION *pQ
+ )
+{
+ gfsdk_makeIdentity(*pOut);
+ FLOAT qxx = (pQ->x * pQ->x);
+ FLOAT qyy = (pQ->y * pQ->y);
+ FLOAT qzz = (pQ->z * pQ->z);
+ FLOAT qxz = (pQ->x * pQ->z);
+ FLOAT qxy = (pQ->x * pQ->y);
+ FLOAT qyz = (pQ->y * pQ->z);
+ FLOAT qwx = (pQ->w * pQ->x);
+ FLOAT qwy = (pQ->w * pQ->y);
+ FLOAT qwz = (pQ->w * pQ->z);
+ pOut->_11 = 1 - 2 * (qyy + qzz);
+ pOut->_12 = 2 * (qxy + qwz);
+ pOut->_13 = 2 * (qxz - qwy);
+ pOut->_21 = 2 * (qxy - qwz);
+ pOut->_22 = 1 - 2 * (qxx + qzz);
+ pOut->_23 = 2 * (qyz + qwx);
+ pOut->_31 = 2 * (qxz + qwy);
+ pOut->_32 = 2 * (qyz - qwx);
+ pOut->_33 = 1 - 2 * (qxx + qyy);
+ return pOut;
+}
+#endif // USE_D3DX9MATH
+
+Camera::Camera(bool zup, bool lhs)
+ :
+ _zup(zup),
+ _lhs(lhs),
+ _isPerspective(true)
+{
+
+ D3DXQuaternionIdentity((D3DXQUATERNION*)&_orientation);
+
+ gfsdk_makeIdentity(_viewMatrix);
+ gfsdk_makeIdentity(_projectionMatrix);
+
+ _fov = (75.0f / 360.0f) * 3.141592653589793;
+}
+
+Camera::~Camera()
+{
+}
+
+void
+Camera::Init(bool zup, bool lhs)
+{
+ _lhs = lhs;
+ _zup = zup;
+}
+
+atcore_float3 Camera::GetUp() const
+{
+ atcore_float3 up;
+
+ if (IsYUp())
+ up = gfsdk_makeFloat3(0.0f, 1.0f, 0.0f);
+ else
+ up = gfsdk_makeFloat3(0.0f, 0.0f, 1.0f);
+
+ return up;
+}
+
+void Camera::SetDefaults()
+{
+ atcore_float3 eye;
+ atcore_float3 at = gfsdk_makeFloat3(0.0f, 0.0f, 0.0f);
+
+ if (IsYUp())
+ {
+ if (_lhs)
+ eye = gfsdk_makeFloat3(0.0f, 60.0f, -120.0f);
+ else
+ eye = gfsdk_makeFloat3(0.0f, 60.0f, 120.0f);
+ }
+ else // zup
+ {
+ if (_lhs)
+ eye = gfsdk_makeFloat3(0.0f, 120.0f, 60.0f);
+ else
+ eye = gfsdk_makeFloat3(0.0f, -120.0f, 60.0f);
+ }
+
+ atcore_float3 up = GetUp();
+
+ LookAt(eye, at, up);
+}
+
+// Build a look at matrix, and calculate the major axis and rotation component.
+void Camera::LookAt(const atcore_float3& eye, const atcore_float3& at, const atcore_float3& up)
+{
+ if (_lhs)
+ D3DXMatrixLookAtLH((D3DXMATRIX*)&_viewMatrix, (D3DXVECTOR3*)&eye, (D3DXVECTOR3*)&at, (D3DXVECTOR3*)&up);
+ else
+ D3DXMatrixLookAtRH((D3DXMATRIX*)&_viewMatrix, (D3DXVECTOR3*)&eye, (D3DXVECTOR3*)&at, (D3DXVECTOR3*)&up);
+
+ _eye = eye;
+ _at = at;
+
+ atcore_float3 dir = at - eye;
+ _lookDistance = gfsdk_length(dir);
+
+ D3DXQuaternionRotationMatrix((D3DXQUATERNION*)&_orientation, (D3DXMATRIX*)&_viewMatrix);
+ BuildViewMatrix();
+}
+
+void Camera::SetEye(const atcore_float3& eye)
+{
+ _eye = eye;
+ _lookDistance = gfsdk_distance(_eye, _at);
+}
+
+void Camera::SetAt(const atcore_float3& at)
+{
+ _at = at;
+ _lookDistance = gfsdk_distance(_eye, _at);
+}
+
+void Camera::SetViewMatrix(const atcore_float3& xAxis, const atcore_float3& yAxis, const atcore_float3& zAxis)
+{
+ _viewMatrix._11 = xAxis.x; _viewMatrix._21 = xAxis.y; _viewMatrix._31 = xAxis.z;
+ _viewMatrix._12 = yAxis.x; _viewMatrix._22 = yAxis.y; _viewMatrix._32 = yAxis.z;
+ _viewMatrix._13 = zAxis.x; _viewMatrix._23 = zAxis.y; _viewMatrix._33 = zAxis.z;
+
+ D3DXQuaternionRotationMatrix((D3DXQUATERNION*)&_orientation, (D3DXMATRIX*)&_viewMatrix);
+ D3DXQuaternionNormalize((D3DXQUATERNION*)&_orientation, (D3DXQUATERNION*)&_orientation);
+
+ atcore_float3 _viewDirection = _lhs ? -1.0f * zAxis : zAxis;
+
+ _eye = _at + _viewDirection * _lookDistance;
+
+ _viewMatrix._41 = - gfsdk_dot(xAxis,_eye);
+ _viewMatrix._42 = - gfsdk_dot(yAxis,_eye);
+ _viewMatrix._43 = - gfsdk_dot(zAxis,_eye);
+}
+
+// Build a perspective matrix
+void Camera::Perspective()
+{
+ _isPerspective = true;
+
+ if (_lhs)
+ D3DXMatrixPerspectiveFovLH( (D3DXMATRIX*)&_projectionMatrix, _fov, _aspectRatio, _znear, _zfar);
+ else
+ D3DXMatrixPerspectiveFovRH( (D3DXMATRIX*)&_projectionMatrix, _fov, _aspectRatio, _znear, _zfar);
+
+}
+
+void Camera::Ortho(float width, float height, float znear, float zfar)
+{
+ if (_lhs)
+ D3DXMatrixOrthoLH( (D3DXMATRIX*)&_projectionMatrix, width, height, znear, zfar);
+ else
+ D3DXMatrixOrthoRH( (D3DXMATRIX*)&_projectionMatrix, width, height, znear, zfar);
+
+ _znear = znear;
+ _zfar = zfar;
+ _width = width;
+ _height = height;
+ _isPerspective = false;
+}
+
+// Dolly towards the viewpoint
+void Camera::Dolly(float zoom)
+{
+ if (_isPerspective)
+ {
+ atcore_float3 offset = _eye - _at;
+
+ _lookDistance = gfsdk_length(offset);
+
+ gfsdk_normalize(offset);
+
+ float zoomFactor = zoom * _lookDistance;
+
+ _lookDistance += zoomFactor;
+
+ _eye = _lookDistance * offset + _at;
+
+ BuildViewMatrix();
+ }
+ else
+ {
+ _width += zoom * 4.0f;
+ _height += zoom * 4.0f;
+
+ D3DXMatrixOrthoRH( (D3DXMATRIX*)&_projectionMatrix, _width, _height, _znear, _zfar);
+
+ }
+}
+
+// Orbit around the viewpoint
+void Camera::Orbit(const atcore_float2& delta)
+{
+
+ float heading = D3DXToRadian(delta.x);
+ float pitch = D3DXToRadian(delta.y);
+
+ if (_lhs)
+ {
+ heading *= -1.0f;
+ pitch *= -1.0f;
+ }
+
+ D3DXQUATERNION rot;
+
+ D3DXVECTOR3 yAxis = MAKEVECTOR3(0.0f, 0.0f, 1.0f);
+ if (IsYUp()) // change up axis if Y is the up axis (for maya)
+ {
+ yAxis = MAKEVECTOR3( 0.0f, 1.0f, 0.0f );
+ }
+
+ D3DXVECTOR3 xAxis = MAKEVECTOR3(1.0f, 0.0f, 0.0f);
+ if (heading != 0.0f)
+ {
+ D3DXQuaternionRotationAxis(&rot, &yAxis, heading);
+ D3DXQuaternionMultiply((D3DXQUATERNION*)&_orientation, &rot, (D3DXQUATERNION*)&_orientation);
+ }
+
+ if (pitch != 0.0f)
+ {
+ D3DXQuaternionRotationAxis(&rot, &xAxis, pitch);
+ D3DXQuaternionMultiply((D3DXQUATERNION*)&_orientation, (D3DXQUATERNION*)&_orientation, &rot);
+ }
+ BuildViewMatrix();
+
+}
+
+// Orbit around the model's center for HAIR-188
+void Camera::OrbitLight(const atcore_float2& delta)
+{
+
+ float heading = D3DXToRadian(delta.x);
+ float pitch = D3DXToRadian(delta.y);
+
+ if (_lhs)
+ {
+ heading *= -1.0f;
+ pitch *= -1.0f;
+ }
+
+ D3DXQUATERNION rot;
+
+ D3DXVECTOR3 yAxis = MAKEVECTOR3(0.0f, 0.0f, 1.0f);
+ if (IsYUp()) // change up axis if Y is the up axis (for maya)
+ {
+ yAxis = MAKEVECTOR3( 0.0f, 1.0f, 0.0f );
+ }
+
+ D3DXVECTOR3 xAxis = MAKEVECTOR3(1.0f, 0.0f, 0.0f);
+ if (heading != 0.0f)
+ {
+ D3DXQuaternionRotationAxis(&rot, &yAxis, heading);
+ D3DXQuaternionMultiply((D3DXQUATERNION*)&_orientation, &rot, (D3DXQUATERNION*)&_orientation);
+ }
+
+ if (pitch != 0.0f)
+ {
+ D3DXQuaternionRotationAxis(&rot, &xAxis, pitch);
+ D3DXQuaternionMultiply((D3DXQUATERNION*)&_orientation, &rot, (D3DXQUATERNION*)&_orientation);
+ }
+ BuildViewMatrix();
+
+}
+
+void Camera::Pan(const atcore_float2& delta)
+{
+ //Scale the movement by the current view
+ //float depth = depthRange.y - depthRange.x;
+
+ atcore_float3 viewDir = GetEye() - GetAt();
+ float depth = gfsdk_length(viewDir);
+ if (depth <= 0.0f)
+ depth = 1.0f;
+
+ atcore_float3 xAxis = GetXAxis();
+ atcore_float3 yAxis = GetYAxis();
+
+ if (_isPerspective)
+ {
+ float fov2 = ((float)-tan(0.5 * _fov) * (depth));
+ atcore_float2 newDelta = fov2 * delta;
+
+ _at = _at + (-1.0f * yAxis * newDelta.y) + (xAxis * newDelta.x);
+ }
+ else
+ {
+ atcore_float2 newDelta = depth * delta;
+ _at = _at + (yAxis * newDelta.y) + (-1.0f * xAxis * newDelta.x);
+ }
+
+
+ BuildViewMatrix();
+}
+
+atcore_float3 Camera::GetXAxis() const
+{
+ return gfsdk_makeFloat3(_viewMatrix._11, _viewMatrix._21, _viewMatrix._31);
+
+}
+
+atcore_float3 Camera::GetYAxis() const
+{
+ return gfsdk_makeFloat3(_viewMatrix._12, _viewMatrix._22, _viewMatrix._32);
+}
+
+atcore_float3 Camera::GetZAxis() const
+{
+ return gfsdk_makeFloat3(_viewMatrix._13, _viewMatrix._23, _viewMatrix._33);
+}
+
+atcore_float3 Camera::GetViewDirection() const
+{
+ atcore_float3 zAxis = GetZAxis();
+ return _lhs ? -1.0f * zAxis : zAxis;
+}
+
+// Reconstruct the view matrix from the current orientation and eye/look direction.
+void Camera::BuildViewMatrix()
+{
+ // Reconstruct the view matrix.
+ D3DXQuaternionNormalize((D3DXQUATERNION*)&_orientation, (D3DXQUATERNION*)&_orientation);
+ D3DXMatrixRotationQuaternion((D3DXMATRIX*)&_viewMatrix, (D3DXQUATERNION*)&_orientation);
+
+ atcore_float3 xAxis = GetXAxis();
+ atcore_float3 yAxis = GetYAxis();
+ atcore_float3 zAxis = GetZAxis();
+
+ atcore_float3 viewDirection = GetViewDirection();
+
+ _eye = _at + viewDirection * _lookDistance;
+
+ _viewMatrix._41 = - gfsdk_dot(xAxis,_eye);
+ _viewMatrix._42 = - gfsdk_dot(yAxis,_eye);
+ _viewMatrix._43 = - gfsdk_dot(zAxis,_eye);
+}
+
+// Set Z Up or Y Up.
+void Camera::ResetUpDir(bool zup)
+{
+ if (zup == _zup)
+ return;
+
+ _zup = zup;
+
+ atcore_float3 eye = GetEye();
+ atcore_float3 at = GetAt();
+ atcore_float3 up;
+
+ if (IsYUp())
+ {
+ // Swap eye z and y
+ float temp = eye.y;
+ eye.y = eye.z;
+ eye.z = -temp;
+ // Swap at z and y
+ temp = at.y;
+ at.y = at.z;
+ at.z = -temp;
+
+ // Set up dir
+ up = gfsdk_makeFloat3(0.0f, 1.0f, 0.0f);
+ }
+ else
+ {
+ // Swap eye z and y
+ float temp = eye.y;
+ eye.y = -eye.z;
+ eye.z = temp;
+ // Swap at z and y
+ temp = at.y;
+ at.y = -at.z;
+ at.z = temp;
+
+ // Set up dir
+ up = gfsdk_makeFloat3(0.0f, 0.0f, 1.0f);
+ }
+ LookAt(eye, at, up);
+ BuildViewMatrix();
+}
+
+// Set Z Up or Y Up.
+void Camera::ResetLhs(bool lhs)
+{
+ if (lhs == _lhs)
+ return;
+
+ _lhs = lhs;
+
+ atcore_float3 eye = GetEye();
+ atcore_float3 at = GetAt();
+
+ if (_zup)
+ {
+ eye.y *= -1;
+ at.y *= -1;
+ }
+ else
+ {
+ eye.z *= -1;
+ at.z *= -1;
+ }
+
+ if (_isPerspective)
+ Perspective();
+ else
+ Ortho(_width, _height, _znear, _zfar);
+
+ atcore_float3 up = GetUp();
+
+ LookAt(eye, at, up);
+ BuildViewMatrix();
+}
+
+void Camera::FitBounds(const atcore_float3& center, const atcore_float3& extents)
+{
+ SetAt(center);
+ // set center first to get eye
+ BuildViewMatrix();
+ if (_isPerspective)
+ {
+ float size = extents.x;
+ size = max(size, extents.y);
+ size = max(size, extents.z);
+ atcore_float3 eye = GetEye();
+
+ atcore_float3 dir = eye - center;
+ gfsdk_normalize(dir);
+ float distance = size / tanf(_fov/2.f);
+
+ eye = center + distance * dir;
+
+ SetEye(eye);
+ BuildViewMatrix();
+ }
+}
+
+#ifndef NV_ARTISTTOOLS
+#include "ProjectParams.h"
+#endif // NV_ARTISTTOOLS
+
+bool Camera::LoadParameters(void* ptr)
+{
+#ifndef NV_ARTISTTOOLS
+ nvidia::parameterized::HairProjectParametersNS::Camera_Type* param =
+ static_cast<nvidia::parameterized::HairProjectParametersNS::Camera_Type*>(ptr);
+
+ _zup = param->flags == 1;
+ _fov = param->fov;
+ _aspectRatio = param->aspectRatio;
+ _znear = param->znear;
+ _zfar = param->zfar;
+ _isPerspective = param->isPerspective;
+ memcpy(&_eye, &param->eye, sizeof(_eye));
+ memcpy(&_at, &param->at, sizeof(_at));
+ _lookDistance = param->lookDistance;
+ memcpy(&_orientation, &param->orientation, sizeof(_orientation));
+ memcpy(&_viewMatrix, &param->viewMatrix, sizeof(_viewMatrix));
+ memcpy(&_projectionMatrix, &param->projectionMatrix, sizeof(_projectionMatrix));
+#else
+ CoreLib::Inst()->Camera_LoadParameters(ptr, this);
+#endif // NV_ARTISTTOOLS
+ return true;
+}
+
+bool Camera::SaveParameters(void *ptr)
+{
+#ifndef NV_ARTISTTOOLS
+ nvidia::parameterized::HairProjectParametersNS::Camera_Type* outParam =
+ static_cast<nvidia::parameterized::HairProjectParametersNS::Camera_Type*>(ptr);
+
+ outParam->flags = (_zup ? 1 : 2);
+ outParam->fov = _fov;
+ outParam->aspectRatio = _aspectRatio;
+ outParam->znear = _znear;
+ outParam->zfar = _zfar;
+ outParam->width = 0;
+ outParam->height = 0;
+ outParam->isPerspective = _isPerspective;
+ memcpy(&outParam->eye, &_eye, sizeof(outParam->eye));
+ memcpy(&outParam->at, &_at, sizeof(outParam->at));
+ outParam->lookDistance = _lookDistance;
+ memcpy(&outParam->orientation, &_orientation, sizeof(outParam->orientation));
+ memcpy(&outParam->viewMatrix, &_viewMatrix, sizeof(outParam->viewMatrix));
+ memcpy(&outParam->projectionMatrix, &_projectionMatrix, sizeof(outParam->projectionMatrix));
+#else
+ CoreLib::Inst()->Camera_SaveParameters(ptr, this);
+#endif // NV_ARTISTTOOLS
+ return true;
+}
+
+void Camera::getScreenCoord(float x, float y, float z, int &sx, int &sy)
+{
+ atcore_float4x4 view = (atcore_float4x4&)GetViewMatrix();
+ atcore_float4x4 projection = (atcore_float4x4&)GetProjectionMatrix();
+
+ atcore_float4x4 viewProjection = view * projection;
+
+ atcore_float4 vp = gfsdk_transform(viewProjection, gfsdk_makeFloat4(x, y, z, 1.0f));
+
+ float nx = vp.x / vp.w;
+ float ny = vp.y / vp.w;
+
+ float w = GetWidth();
+ float h = GetHeight();
+
+ sx = w * (0.5f + 0.5f * nx);
+ sy = h * (0.5f - 0.5f * ny);
+
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Scene/Camera.h b/tools/ArtistTools/source/CoreLib/Scene/Camera.h
new file mode 100644
index 0000000..23fb0c6
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/Camera.h
@@ -0,0 +1,128 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "MathUtil.h"
+
+class CORELIB_EXPORT Camera
+{
+public:
+
+ // YUp default
+ Camera(bool zUp = false, bool lhs = false);
+ ~Camera();
+
+ void Init(bool zup, bool lhs);
+ void LookAt(const atcore_float3& eye, const atcore_float3& target, const atcore_float3& up);
+ void Perspective();
+ void Ortho(float width, float height, float znear, float zfar);
+ void Dolly(float zoom);
+ void Orbit(const atcore_float2& delta);
+ void OrbitLight(const atcore_float2& delta); // special for HAIR-188
+ void Pan(const atcore_float2& delta);
+
+ void getScreenCoord(float x, float y, float z, int &sx, int &sy);
+
+ float GetZNear() { return _znear; }
+ float GetZFar() { return _zfar; }
+
+ const atcore_float3& GetAt() const { return _at; }
+ const atcore_float3& GetEye() const { return _eye; }
+
+ float GetWidth() const { return _width; }
+ float GetHeight() const { return _height; }
+
+ void SetFOV(float fov) { _fov = fov; }
+ void SetAspetRatio(float aspect) { _aspectRatio = aspect; }
+ void SetZNear(float znear) { _znear = znear; }
+ void SetZFar(float zfar) { _zfar = zfar; }
+
+ void SetSize(int w, int h) { _width = w; _height = h; }
+
+ atcore_float3 GetXAxis() const;
+ atcore_float3 GetYAxis() const;
+ atcore_float3 GetZAxis() const;
+
+ atcore_float3 GetViewDirection() const;
+
+ void SetViewMatrix(const atcore_float3& xAxis, const atcore_float3& yAxis, const atcore_float3& zAxis);
+
+ float GetLookDistance() const { return _lookDistance; }
+ atcore_float3 GetUp() const;
+
+ void SetEye(const atcore_float3& eye);
+ void SetAt(const atcore_float3& at);
+
+ atcore_float2 GetZRange() const { return gfsdk_makeFloat2(_znear, _zfar); }
+
+ const atcore_float4x4& GetProjectionMatrix() const { return _projectionMatrix; }
+ const atcore_float4x4& GetViewMatrix() const { return _viewMatrix; }
+
+ // Change Up Dir and reset internal eye and at.
+ void ResetUpDir(bool zup);
+ void ResetLhs(bool lhs);
+
+ bool IsYUp() const { return _zup == false; }
+ bool UseLHS() const { return _lhs; }
+
+ bool LoadParameters(void* param);
+ bool SaveParameters(void* outParam);
+
+ void BuildViewMatrix();
+
+ void SetDefaults();
+
+ void FitBounds(const atcore_float3& center, const atcore_float3& extents);
+
+
+//private:
+ // coordinate axis
+ bool _zup;
+ bool _lhs;
+
+ // Perspective
+ bool _isPerspective;
+ float _fov;
+ float _aspectRatio;
+
+ float _znear;
+ float _zfar;
+ float _width;
+ float _height;
+
+ float _lookDistance;
+
+ atcore_float3 _eye;
+ atcore_float3 _at;
+
+ atcore_float4 _orientation;
+ atcore_float4x4 _viewMatrix;
+ atcore_float4x4 _projectionMatrix;
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Scene/Gamepad.cpp b/tools/ArtistTools/source/CoreLib/Scene/Gamepad.cpp
new file mode 100644
index 0000000..01e3323
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/Gamepad.cpp
@@ -0,0 +1,1310 @@
+#include <windows.h>
+#include <SDL.h>
+#include <QtWidgets/QApplication>
+#include <QtCore/QDir>
+#include <QtCore/QDirIterator>
+#include <QtCore/QString>
+#include <QtCore/QList>
+
+#include "Gamepad.h"
+
+#include "Camera.h"
+#include "SimpleScene.h"
+#include "AppMainWindow.h"
+#include "DisplayLightPanel.h"
+#include "DisplayScenePanel.h"
+
+#include "DXUT.h"
+//#include "D3D11RendererWindow.h"
+#include "sdkmisc.h"
+#include "GlobalSettings.h"
+#include "Light.h"
+#include "DisplayPreferencesPanel.h"
+#include "ViewerOutput.h"
+#include "D3DWidget.h"
+#include <stdarg.h>
+#include <vector>
+#include <string>
+
+#ifndef NV_ARTISTTOOLS
+#include "BlastToolbar.h"
+#include "DisplayVisualizersPanel.h"
+#include "FurCharacter.h"
+#include "HairParams.h"
+#endif // NV_ARTISTTOOLS
+
+const bool bSaveLogToDisk = true;
+bool bDefaultDemoMode = false;
+
+static QList<QString> demoProjects;
+
+static int curentPrjIdx = -1;
+static int iQuitState = 0;
+
+static std::string strAppDir;
+
+SimpleScene* theScene = NV_NULL;
+
+bool bUseOldLightCam = false, bUseOldSceneCam = false;
+
+enum ButtonState
+{
+ BUTTON_NOTHING,
+ BUTTON_DOWN,
+ BUTTON_HOLDING,
+ BUTTON_UP,
+};
+
+class GamepadHandler
+{
+public:
+ GamepadHandler()
+ :joystick(0)
+ {
+ }
+
+ ~GamepadHandler()
+ {
+ DisConnect();
+ }
+
+ void DisConnect()
+ {
+ if(joystick)
+ {
+ SDL_JoystickClose(joystick);
+ joystick = NV_NULL;
+ }
+ }
+
+ void Process();
+
+ inline ButtonState ButtonState(int button)
+ {
+ if (button >= 0 && button < iButtonState.size())
+ {
+ if (iButtonState[button] && iButtonStateOld[button] == 0)
+ return BUTTON_DOWN;
+ else if (iButtonState[button] && iButtonStateOld[button])
+ return BUTTON_HOLDING;
+ else if (iButtonState[button] == 0 && iButtonStateOld[button])
+ return BUTTON_UP;
+ }
+ return BUTTON_NOTHING;
+ }
+
+ inline int AxisChange(int idx)
+ {
+ if (idx >= 0 && idx < iAxisState.size())
+ {
+ return (iAxisState[idx] - iAxisStateAtBegin[idx]);
+ }
+ return 0;
+ }
+
+ const char* pjsName;
+ int numAxis;
+ int numTrackballs;
+ int numPov;
+ int numButtons;
+
+ std::vector<int> bKeyHolding;
+ std::vector<int> iAxisStateAtBegin;
+ std::vector<int> iAxisStateOld;
+ std::vector<int> iAxisState;
+ std::vector<int> iButtonStateOld;
+ std::vector<int> iButtonState;
+
+ SDL_Joystick* joystick;
+ SDL_JoystickGUID jsGuid;
+};
+
+std::vector<GamepadHandler> gHandlers;
+
+//
+// Gamepad thresholds taken from XINPUT API
+//
+//#define GAMEPAD_LEFT_THUMB_DEADZONE 7849
+//#define GAMEPAD_RIGHT_THUMB_DEADZONE 8689
+//#define GAMEPAD_TRIGGER_THRESHOLD 30
+
+#define GAMEPAD_BUMPER_DEADZONE 9000
+inline int ClampAxis(int value)
+{
+ if((value>GAMEPAD_BUMPER_DEADZONE) || (value<-GAMEPAD_BUMPER_DEADZONE))
+ return value;
+ return 0;
+}
+
+std::vector<std::string> keylog;
+
+void LogAdd(const char *fmt,...)
+{
+ if(bSaveLogToDisk)
+ {
+ static char logBuf[2048];
+ va_list arg;
+ va_start( arg, fmt );
+ vsprintf(logBuf, fmt, arg);
+ va_end(arg);
+ keylog.push_back(logBuf);
+ }
+}
+
+void SaveLog()
+{
+ if(keylog.size())
+ {
+ std::string fn = strAppDir + "\\buttonLog.txt";
+ FILE* fp = fopen(fn.c_str(), "w+");
+ if(fp)
+ {
+ for(int i = 0; i < keylog.size(); ++i)
+ {
+ std::string& info = keylog[i];
+ fputs(info.c_str(), fp);
+ fputs("\n", fp);
+ }
+ fclose(fp);
+ }
+ }
+}
+
+//XBOX 360 AXIS
+static int AXIS_LS_X = 0;
+static int AXIS_LS_Y = 1;
+static int AXIS_RS_X = 2;
+static int AXIS_RS_Y = 3;
+static int AXIS_LT = 4;
+static int AXIS_RT = 5;
+
+// XBox 360 Key codes
+static int GAMEPAD_KEY_DPAD_UP = 0;
+static int GAMEPAD_KEY_DPAD_DOWN = 1;
+static int GAMEPAD_KEY_DPAD_LEFT = 2;
+static int GAMEPAD_KEY_DPAD_RIGHT = 3;
+static int GAMEPAD_KEY_START = 4;
+static int GAMEPAD_KEY_BACK = 5;
+static int GAMEPAD_KEY_LS = 6;
+static int GAMEPAD_KEY_RS = 7;
+static int GAMEPAD_KEY_LEFT_BUMP = 8;
+static int GAMEPAD_KEY_RIGHT_BUMP = 9;
+static int GAMEPAD_KEY_A = 10;
+static int GAMEPAD_KEY_B = 11;
+static int GAMEPAD_KEY_X = 12;
+static int GAMEPAD_KEY_Y = 13;
+
+double GetSeconds()
+{
+ static LARGE_INTEGER lastTime;
+ static LARGE_INTEGER freq;
+ static bool first = true;
+
+ if (first)
+ {
+ QueryPerformanceCounter(&lastTime);
+ QueryPerformanceFrequency(&freq);
+
+ first = false;
+ }
+
+ static double time = 0.0;
+
+ LARGE_INTEGER t;
+ QueryPerformanceCounter(&t);
+
+ __int64 delta = t.QuadPart-lastTime.QuadPart;
+ double deltaSeconds = double(delta) / double(freq.QuadPart);
+
+ time += deltaSeconds;
+
+ lastTime = t;
+
+ return time;
+
+}
+
+Gamepad::Gamepad()
+{
+}
+
+Gamepad::~Gamepad()
+{
+}
+
+Gamepad& Gamepad::Instance()
+{
+ static Gamepad gmpad;
+ return gmpad;
+}
+
+void ChangeMode()
+{
+ AppMainWindow::Inst().shortcut_expert();
+}
+
+void ToggleSimulation()
+{
+#ifndef NV_ARTISTTOOLS
+ BlastToolbar* toolbar = AppMainWindow::Inst().GetMainToolbar();
+ toolbar->on_btnEnableSimulation_clicked();
+ // read simulation state; have to call it twice to avoid change it.
+ GlobalSettings::Inst().toggleSimulation();
+
+ bool anim = GlobalSettings::Inst().toggleSimulation();
+ DisplayFurVisualizersPanel* furPanel = AppMainWindow::Inst().GetFurVisualizersPanel();
+ if(furPanel)
+ {
+ furPanel->on_btnShowHair_stateChanged(anim);
+ furPanel->updateValues();
+ }
+#else
+ CoreLib::Inst()->Gamepad_ToggleSimulation();
+#endif // NV_ARTISTTOOLS
+}
+
+void StartAnimation()
+{
+#ifndef NV_ARTISTTOOLS
+ GlobalSettings::Inst().toggleSimulation();
+ bool simulating = GlobalSettings::Inst().toggleSimulation(); // call it twice to get right state
+
+ GlobalSettings::Inst().toggleAnimation();
+ bool animating = GlobalSettings::Inst().toggleAnimation(); // call it twice to get right state
+
+ BlastToolbar* toolbar = AppMainWindow::Inst().GetMainToolbar();
+ if(!simulating)
+ toolbar->on_btnEnableSimulation_clicked();
+
+ if(!animating)
+ toolbar->on_btnPlayAnimation_clicked();
+
+ // reset animation
+ //toolbar->on_btnResetAnimation_clicked();
+#else
+ CoreLib::Inst()->Gamepad_StartAnimation();
+#endif // NV_ARTISTTOOLS
+}
+
+void ButtonAPressed()
+{
+ // Play/Pause the animation
+ Gamepad::PlayPauseAnimation();
+}
+
+void ButtonBPressed()
+{
+ // Stops and re-starts animation
+ Gamepad::ResetAnimation();
+}
+
+void Gamepad::ShowProjectName()
+{
+ bool bExpertMode = AppMainWindow::IsExpertMode();
+ // need change title
+ char msg[1024];
+ // show title
+ if(curentPrjIdx != -1)
+ {
+ QString fn = demoProjects.at(curentPrjIdx);
+ sprintf(msg, "Blast Viewer - %s %s", fn.toUtf8().data(), (bExpertMode ? "Demo Mode" : ""));
+ AppMainWindow::Inst().setWindowTitle(msg);
+ }
+ else
+ {
+ if (bExpertMode)
+ {
+ sprintf(msg, "Blast Viewer - Expert Mode");
+ }
+ else
+ {
+ sprintf(msg, "Blast Viewer");
+ }
+ AppMainWindow::Inst().setWindowTitle(msg);
+ }
+}
+
+void LoadSamples(bool bNext)
+{
+ bUseOldLightCam = bUseOldSceneCam = false;
+ int prjCount = demoProjects.size();
+ if(prjCount==0)
+ {
+ DisplayPreferencesPanel* pPanel = AppMainWindow::Inst().GetDisplayPreferencesPanel();
+ if (pPanel)
+ {
+ pPanel->assignPlayPlaylistToGamepad();
+ }
+ if (0)
+ {
+ static int iLimitSampleCount = 20;
+ QString appDir = strAppDir.c_str();
+ QString projectPath;
+ // load from a specific file first
+ QString fn = appDir + "\\samples.txt";
+ FILE* fp = fopen(fn.toUtf8().data(), "r");
+ if (fp)
+ {
+ char Line[1024], FileName[2014];
+ while (fgets(Line, sizeof(Line), fp) != NV_NULL)
+ {
+ QString t = QString(Line).trimmed();
+ if (t.length() == 0)
+ continue;
+ QString fn = t.toLower();
+ std::string strFN = fn.toUtf8().data();
+ const char* ptest = strstr(strFN.c_str(), ".furproj");
+ if (ptest)
+ {
+ const char* pchar = strchr(strFN.c_str(), ':');
+ if (pchar)
+ {
+ demoProjects.append(fn);
+ }
+ else
+ {
+ const char* pFirst = strFN.c_str();
+ if (pFirst[0] == '/' || pFirst[0] == '\\')
+ {
+ fn = appDir + fn;
+ demoProjects.append(fn);
+ }
+ else
+ {
+ fn = appDir + QString("/") + fn;
+ demoProjects.append(fn);
+ }
+ }
+ }
+ }
+ fclose(fp);
+ }
+ }
+ if(0)
+ {
+ QString appDir = strAppDir.c_str();
+ QString projectPath;
+ // search some relative folders
+ QDir dirTmp(appDir);
+ if(dirTmp.cd("./media"))
+ projectPath = dirTmp.absolutePath();
+ else if(dirTmp.cd("../media"))
+ projectPath = dirTmp.absolutePath();
+ else if(dirTmp.cd("../../media"))
+ projectPath = dirTmp.absolutePath();
+ else if(dirTmp.cd("../../media"))
+ projectPath = dirTmp.absolutePath();
+ if(!projectPath.isEmpty())
+ {
+ QStringList filters;
+ filters<<QString("*.furproj");
+ QDirIterator dir_iterator(projectPath, filters, QDir::Files | QDir::NoSymLinks,QDirIterator::Subdirectories);
+ while(dir_iterator.hasNext())
+ {
+ dir_iterator.next();
+ QFileInfo file_info = dir_iterator.fileInfo();
+ QString absolute_file_path = file_info.absoluteFilePath();
+ demoProjects.append(absolute_file_path);
+ //if(demoProjects.size()>iLimitSampleCount)
+ // break;
+ }
+ }
+ else
+ {
+ const char* msg = "Fail to find any Blast projects!";
+ viewer_msg(msg);
+ }
+ }
+ prjCount = demoProjects.size();
+ }
+ if(prjCount)
+ {
+ if (bNext)
+ {
+ ++curentPrjIdx;
+ if (curentPrjIdx >= prjCount)
+ curentPrjIdx = 0;
+ }
+ else
+ {
+ --curentPrjIdx;
+ if (curentPrjIdx < 0)
+ curentPrjIdx = prjCount - 1;
+ }
+ // load sample
+ QString fn = demoProjects[curentPrjIdx];
+ AppMainWindow::Inst().openProject(fn);
+ }
+ Gamepad::ShowProjectName();
+}
+
+void StartButtonPressed()
+{
+ Gamepad& gp = Gamepad::Instance();
+ gp.ShowUsage();
+}
+
+void BackButtonPressed()
+{
+ Gamepad::DemoEscape();
+ return;
+
+ ++iQuitState;
+ switch(iQuitState)
+ {
+ case 0:
+ // do nothing
+ break;
+ case 1:
+ {
+ AppMainWindow::Inst().startProgress();
+ AppMainWindow::Inst().setProgressMaximum(2);
+ AppMainWindow::Inst().setProgress("Press Back again to quit. Press other buttons to cancel it.", 1);
+ }
+ break;
+ case 2:
+ {
+ AppMainWindow::Inst().setProgress("Quitting...", 2);
+ //AppMainWindow::Inst().close();
+ Gamepad::DemoEscape();
+ }
+ break;
+ default:
+ iQuitState = 0;
+ break;
+ }
+}
+
+void Gamepad::HandleJoySticks()
+{
+ int numJoysticks = SDL_NumJoysticks();
+ int numUsedJoysticks = gHandlers.size();
+ if (numUsedJoysticks != numJoysticks)
+ {
+ gHandlers.clear();
+ }
+ if(numUsedJoysticks < 1)
+ {
+ //static int iSkipCount = 0;
+ //if (++iSkipCount >= 60)
+ //{
+ // iSkipCount = 0;
+ static int iDoOnce = 1;
+ if (iDoOnce)
+ {
+ iDoOnce = 0;
+
+ Initialize();
+ numJoysticks = SDL_NumJoysticks();
+ for (int i = 0; i < numJoysticks; ++i)
+ {
+ SDL_Joystick* joystick = SDL_JoystickOpen(i);
+ if (joystick)
+ {
+ numUsedJoysticks = gHandlers.size();
+ gHandlers.resize(numUsedJoysticks + 1);
+ GamepadHandler& handler = gHandlers[numUsedJoysticks];
+ handler.joystick = joystick;
+ handler.pjsName = SDL_JoystickName(joystick);
+ handler.numAxis = SDL_JoystickNumAxes(joystick);
+ handler.numTrackballs = SDL_JoystickNumBalls(joystick);
+ handler.numPov = SDL_JoystickNumHats(joystick);
+ handler.numButtons = SDL_JoystickNumButtons(joystick);
+ handler.jsGuid = SDL_JoystickGetGUID(joystick);
+
+ LogAdd("Device Name: %s", handler.pjsName);
+ LogAdd("Num of Axis: %d", handler.numAxis);
+ LogAdd("Num of Trackballs: %d", handler.numTrackballs);
+ LogAdd("Num of POV: %d", handler.numPov);
+ LogAdd("Num of Buttons: %d", handler.numButtons);
+ LogAdd("Initial Axis States:");
+
+ handler.iAxisState.resize(handler.numAxis);
+ handler.iAxisStateAtBegin.resize(handler.numAxis);
+ handler.iAxisStateOld.resize(handler.numAxis);
+
+ handler.iButtonState.resize(handler.numButtons);
+ handler.iButtonStateOld.resize(handler.numButtons);
+
+ if (handler.numAxis == 6)
+ {
+ // XBOX 360 has 6 axis
+ AXIS_LS_X = 0;
+ AXIS_LS_Y = 1;
+ AXIS_RS_X = 2;
+ AXIS_RS_Y = 3;
+ AXIS_LT = 4;
+ AXIS_RT = 5;
+
+ GAMEPAD_KEY_DPAD_UP = 0;
+ GAMEPAD_KEY_DPAD_DOWN = 1;
+ GAMEPAD_KEY_DPAD_LEFT = 2;
+ GAMEPAD_KEY_DPAD_RIGHT = 3;
+ GAMEPAD_KEY_START = 4;
+ GAMEPAD_KEY_BACK = 5;
+ GAMEPAD_KEY_LS = 6;
+ GAMEPAD_KEY_RS = 7;
+ GAMEPAD_KEY_LEFT_BUMP = 8;
+ GAMEPAD_KEY_RIGHT_BUMP = 9;
+ GAMEPAD_KEY_A = 10;
+ GAMEPAD_KEY_B = 11;
+ GAMEPAD_KEY_X = 12;
+ GAMEPAD_KEY_Y = 13;
+ }
+ else if (handler.numAxis == 5)
+ {
+ // Betop has 5 axis when xbox mode
+ AXIS_LS_X = 0;
+ AXIS_LS_Y = 1;
+ AXIS_RS_X = 3;
+ AXIS_RS_Y = 4;
+ AXIS_LT = 2;
+ AXIS_RT = 2;
+
+ GAMEPAD_KEY_DPAD_UP = 10; // POV
+ GAMEPAD_KEY_DPAD_DOWN = 11; // POV
+ GAMEPAD_KEY_DPAD_LEFT = 12; // POV
+ GAMEPAD_KEY_DPAD_RIGHT = 13; // POV
+ GAMEPAD_KEY_START = 7;
+ GAMEPAD_KEY_BACK = 6;
+ GAMEPAD_KEY_LS = 8;
+ GAMEPAD_KEY_RS = 9;
+ GAMEPAD_KEY_LEFT_BUMP = 4;
+ GAMEPAD_KEY_RIGHT_BUMP = 5;
+ GAMEPAD_KEY_A = 0;
+ GAMEPAD_KEY_B = 1;
+ GAMEPAD_KEY_X = 2;
+ GAMEPAD_KEY_Y = 3;
+
+ if (handler.numPov == 1)
+ {
+ // BETOP xbox mode
+ handler.iButtonState.resize(handler.numButtons + 4); // POV fake buttons
+ handler.iButtonStateOld.resize(handler.numButtons + 4);
+ for (int i = GAMEPAD_KEY_DPAD_UP; i <= GAMEPAD_KEY_DPAD_RIGHT; ++i)
+ {
+ handler.iButtonStateOld[i] = handler.iButtonState[i] = 0;
+ }
+ }
+ }
+ for (int i = 0; i < handler.numAxis; ++i)
+ {
+ int value = ClampAxis(SDL_JoystickGetAxis(handler.joystick, i));
+ handler.iAxisStateAtBegin[i] = handler.iAxisStateOld[i] = handler.iAxisState[i] = value;
+ LogAdd("Axis %d State %d", i, value);
+ }
+ LogAdd("Initial Button States:");
+ for (int i = 0; i < handler.numButtons; ++i)
+ {
+ int state = SDL_JoystickGetButton(handler.joystick, i);
+ handler.iButtonStateOld[i] = handler.iButtonState[i] = state;
+ LogAdd("Button %d State %d", i, state);
+ }
+ if (handler.numPov == 1)
+ {
+ LogAdd("Initial POV Button States:");
+ Uint8 pov = SDL_JoystickGetHat(joystick, 0);
+ char msg[512];
+ sprintf(msg, "POV State: %d", pov);
+ viewer_msg(msg);
+ LogAdd(msg);
+ // BETOP xbox mode
+ handler.iButtonState.resize(handler.numButtons + 4); // POV fake buttons
+ handler.iButtonStateOld.resize(handler.numButtons + 4);
+ for (int i = GAMEPAD_KEY_DPAD_UP; i <= GAMEPAD_KEY_DPAD_RIGHT; ++i)
+ {
+ handler.iButtonStateOld[i] = handler.iButtonState[i] = 0;
+ LogAdd("POV Button %d State %d", i, 0);
+ }
+ }
+ SDL_JoystickEventState(SDL_IGNORE);
+ }
+ }
+ }
+ }
+ else
+ {
+ ManualReadGamepad();
+ }
+}
+
+bool Gamepad::Initialize()
+{
+ if (strAppDir.size() < 1)
+ {
+ strAppDir = qApp->applicationDirPath().toUtf8().data();
+ }
+
+ SDL_Quit();
+ // init SDL
+ // my Gamepad does not work with SDL_INIT_EVERYTHING. Just init the ones we use.
+ int ret = SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS);
+ return (ret == 0);
+}
+
+void Gamepad::Free()
+{
+ if (bSaveLogToDisk)
+ {
+ SaveLog();
+ }
+
+ if(int count = gHandlers.size())
+ {
+ for(int i = 0; i<count; ++i)
+ gHandlers[i].DisConnect();
+ }
+ SDL_Quit();
+}
+
+void ShowUsageInViewport()
+{
+ bool bDemoMode = AppMainWindow::IsExpertMode();
+ if(bDemoMode && bDefaultDemoMode)
+ {
+ int w = theScene->GetCamera()->GetWidth();
+ int h = theScene->GetCamera()->GetHeight();
+ //CDXUTTextHelper* pTxtHelper = theScene->GetRenderWindow()->GetTextHelper();
+
+ //pTxtHelper->Begin();
+ //pTxtHelper->SetInsertionPos(w/5, h-80);
+ //pTxtHelper->SetForegroundColor(D3DXCOLOR(1.0f, 1.0f, 0.0f, 0.8f));
+
+ //pTxtHelper->DrawTextLine(L"Start: Load a sample Back: Quit Demo");
+ //pTxtHelper->DrawTextLine(L"A: Stop/Restart Animation B: Pause/Continue Animation X: Start/Pause Simulation Y: Demo/Export Switch");
+ //pTxtHelper->DrawTextLine(L"Left Stick: Zoom In/Out Right Stick: Control Camera Cross/Trigger: Scene HUD and Stats On/Off");
+ //pTxtHelper->DrawTextLine(L"RB & LS: Wind Direction RB & RS: Wind Strength LB & LS: Light Control");
+ //pTxtHelper->End();
+ }
+}
+
+void Gamepad::ShowUsage()
+{
+ viewer_msg("Start: Show Gamepad Usage");
+ viewer_msg("Back: Quit the Blast Viewer");
+ viewer_msg("LBump: Load previous demo RBump: Load next sample");
+ viewer_msg("B: Reset Animation A: Play/Pause Animation");
+ viewer_msg("Y: Demo View On/Off X: Show/Hide the selected Hair");
+ viewer_msg("LStick: Zoom in and out RStick: Rotate the camera");
+ viewer_msg("D-Pad Up: Show/Hide HUD D-Pad Left: Show/Hide Stats");
+ viewer_msg("RTrigger & LStick: Wind Direction RTrigger & RStick: Wind Strength");
+ viewer_msg("LTrigger & LStick: Move Light");
+}
+
+
+void Gamepad::ResetScene()
+{
+#ifndef NV_ARTISTTOOLS
+ BlastToolbar* toolbar = AppMainWindow::Inst().GetMainToolbar();
+
+ GlobalSettings::Inst().toggleSimulation();
+ bool bSimulating = GlobalSettings::Inst().toggleSimulation(); // call it twice to get right state
+ if(bSimulating)
+ {
+ toolbar->on_btnEnableSimulation_clicked(); // stop simulation when stop animation
+ }
+
+ DisplayFurVisualizersPanel* furPanel = AppMainWindow::Inst().GetFurVisualizersPanel();
+ if(furPanel)
+ {
+ furPanel->on_btnShowHair_stateChanged(true); // show hair
+ furPanel->updateValues();
+ }
+
+ GlobalSettings::Inst().toggleAnimation();
+ bool anim = GlobalSettings::Inst().toggleAnimation(); // call it twice to get right state
+ if(anim)
+ {
+ toolbar->on_btnPlayAnimation_clicked(); // stop animation
+ }
+
+ toolbar->on_btnResetAnimation_clicked(); // reset animation
+
+ toolbar->on_spinWindStrength_valueChanged(0.0f);
+ toolbar->updateValues();
+#else
+ CoreLib::Inst()->Gamepad_ResetScene();
+#endif // NV_ARTISTTOOLS
+
+ Light* pLight = NV_NULL;
+ pLight = Light::GetFirstSelectedLight();
+
+ static Camera oldLightCam, oldSceneCam;
+ // restore old camera
+ if(bUseOldSceneCam)
+ {
+ *(theScene->GetCamera()) = oldSceneCam;
+ //theScene->FitCamera();
+ }
+ else
+ {
+ oldSceneCam = *theScene->GetCamera();
+ bUseOldSceneCam = true;
+ }
+ // restore light camera
+ if(pLight)
+ {
+ //pLight->FitBounds(true);
+ if(bUseOldLightCam)
+ {
+// pLight->getCamera() = oldLightCam;
+ }
+ else
+ {
+// oldLightCam = pLight->getCamera();
+// pLight->FitBounds();
+ bUseOldLightCam = true;
+ }
+ }
+ theScene->SetProjectModified(true);
+}
+
+bool Gamepad::IsDemoMode()
+{
+ return AppMainWindow::IsExpertMode();
+}
+
+void Gamepad::SetDemoProjects(QList<QString>& projects)
+{
+ demoProjects = projects;
+}
+
+void Gamepad::Process()
+{
+ if (AppMainWindow::IsExpertMode() == false)
+ {
+ static bool bFirstTime = true;
+ if (bFirstTime)
+ {
+ bFirstTime = false;
+ DisplayPreferencesPanel* pPanel = AppMainWindow::Inst().GetDisplayPreferencesPanel();
+ if (pPanel)
+ {
+ pPanel->runDemoCommandline();
+ return;
+ }
+ }
+ }
+
+ HandleJoySticks();
+
+ if (theScene == 0)
+ {
+ theScene = SimpleScene::Inst();
+ return;
+ }
+
+ //ShowUsageInViewport();
+}
+
+
+void Gamepad::ManualReadGamepad()
+{
+ SDL_JoystickUpdate();
+ if(int count = gHandlers.size())
+ {
+ for(int i = 0; i < count; ++i)
+ gHandlers[i].Process();
+ }
+}
+
+void GamepadHandler::Process()
+{
+ for(int i = 0; i < numAxis; ++i)
+ {
+ int value = ClampAxis(SDL_JoystickGetAxis(joystick, i));
+ iAxisState[i] = value;
+ if(iAxisStateOld[i] != value)
+ {
+ char msg[512];
+ sprintf(msg, "Axis changes: %d %d", i, value);
+#ifdef _DEBUG
+ viewer_msg(msg);
+#endif
+ LogAdd(msg);
+ }
+ }
+
+ bool bCancelQuit = false;
+ for(int i = 0; i < numButtons; ++i)
+ {
+ int state = SDL_JoystickGetButton(joystick, i);
+ iButtonState[i] = state;
+ if(iButtonStateOld[i] != state)
+ {
+ char msg[512];
+ sprintf(msg, "Button changes: %d %d (%d)", i, state, iButtonStateOld[i]);
+#ifdef _DEBUG
+ viewer_msg(msg);
+#endif
+ LogAdd(msg);
+ }
+ if(i != GAMEPAD_KEY_BACK && ButtonState(i) == BUTTON_UP)
+ {
+ //bCancelQuit = true;
+ }
+ }
+
+ if (numPov == 1)
+ {
+ // BETOP xbox mode
+ Uint8 pov = SDL_JoystickGetHat(joystick, 0);
+ switch (pov)
+ {
+ case SDL_HAT_UP:
+ iButtonState[GAMEPAD_KEY_DPAD_UP] = 1;
+ break;
+ case SDL_HAT_RIGHT:
+ iButtonState[GAMEPAD_KEY_DPAD_RIGHT] = 1;
+ break;
+ case SDL_HAT_DOWN:
+ iButtonState[GAMEPAD_KEY_DPAD_DOWN] = 1;
+ break;
+ case SDL_HAT_LEFT:
+ iButtonState[GAMEPAD_KEY_DPAD_LEFT] = 1;
+ break;
+ case SDL_HAT_RIGHTUP:
+ iButtonState[GAMEPAD_KEY_DPAD_RIGHT] = 1;
+ iButtonState[GAMEPAD_KEY_DPAD_UP] = 1;
+ break;
+ case SDL_HAT_RIGHTDOWN:
+ iButtonState[GAMEPAD_KEY_DPAD_RIGHT] = 1;
+ iButtonState[GAMEPAD_KEY_DPAD_DOWN] = 1;
+ break;
+ case SDL_HAT_LEFTUP:
+ iButtonState[GAMEPAD_KEY_DPAD_LEFT] = 1;
+ iButtonState[GAMEPAD_KEY_DPAD_UP] = 1;
+ break;
+ case SDL_HAT_LEFTDOWN:
+ iButtonState[GAMEPAD_KEY_DPAD_LEFT] = 1;
+ iButtonState[GAMEPAD_KEY_DPAD_DOWN] = 1;
+ break;
+ default:
+ for (int i = GAMEPAD_KEY_DPAD_UP; i <= GAMEPAD_KEY_DPAD_RIGHT; ++i)
+ {
+ iButtonState[i] = 0;
+ }
+ }
+ if (pov != SDL_HAT_CENTERED)
+ {
+ char msg[512];
+ sprintf(msg, "POV State: %d", pov);
+ viewer_msg(msg);
+ LogAdd(msg);
+ for (int i = GAMEPAD_KEY_DPAD_UP; i <= GAMEPAD_KEY_DPAD_RIGHT; ++i)
+ {
+ if (ButtonState(i) == BUTTON_DOWN)
+ {
+ sprintf(msg, "POV Button Down: %d", i);
+ viewer_msg(msg);
+ LogAdd(msg);
+ }
+ }
+ }
+ }
+
+ //bool bLeftBump = iButtonState[GAMEPAD_KEY_LEFT_BUMP], bRightBump = iButtonState[GAMEPAD_KEY_RIGHT_BUMP];
+ bool bLeftTrigger = false, bRightTrigger = false;
+ double currentTime = GetSeconds(); // real elapsed frame time
+ static double lastJoyTime = currentTime;
+
+ if(ButtonState(GAMEPAD_KEY_BACK) == BUTTON_UP)
+ {
+ BackButtonPressed();
+ }
+ if(iQuitState && bCancelQuit)
+ {
+ AppMainWindow::Inst().setProgress("Cancel quitting.", 2);
+ iQuitState = 0;
+ }
+ else
+ {
+ bCancelQuit = false;
+ }
+
+ if(!bCancelQuit)
+ {
+ if(ButtonState(GAMEPAD_KEY_START) == BUTTON_UP)
+ {
+ StartButtonPressed();
+ }
+ if (ButtonState(GAMEPAD_KEY_RIGHT_BUMP) == BUTTON_UP)
+ {
+ // next proj
+ Gamepad::DemoNext();
+ }
+ if (ButtonState(GAMEPAD_KEY_LEFT_BUMP) == BUTTON_UP)
+ {
+ // prev proj
+ Gamepad::DemoPrev();
+ }
+ if (ButtonState(GAMEPAD_KEY_B) == BUTTON_UP)
+ {
+ viewer_msg("B Pressed");
+ ButtonBPressed();
+ }
+ if(ButtonState(GAMEPAD_KEY_A) == BUTTON_UP)
+ {
+ viewer_msg("A Pressed");
+ ButtonAPressed();
+ }
+ if (ButtonState(GAMEPAD_KEY_Y) == BUTTON_UP)
+ {
+ viewer_msg("Y Pressed");
+ ChangeMode();
+ }
+ if(ButtonState(GAMEPAD_KEY_X) == BUTTON_UP)
+ {
+ viewer_msg("X Pressed");
+#ifndef NV_ARTISTTOOLS
+ // Show/hide selected hair
+ bool v = false;
+ theScene->GetFurCharacter().GetHairParam(HAIR_PARAMS_DRAW_RENDER_HAIRS, &v);
+ DisplayFurVisualizersPanel* furPanel = AppMainWindow::Inst().GetFurVisualizersPanel();
+ if (furPanel)
+ {
+ furPanel->on_btnShowHair_stateChanged(!v);
+ }
+#else
+ CoreLib::Inst()->GamepadHandler_ShowHair();
+#endif // NV_ARTISTTOOLS
+ }
+ if(ButtonState(GAMEPAD_KEY_DPAD_LEFT) == BUTTON_DOWN)
+ {
+ // Show/Hide Stats
+ Gamepad::ShowHideStats();
+ }
+ if(ButtonState(GAMEPAD_KEY_DPAD_RIGHT) == BUTTON_DOWN)
+ {
+ }
+ if(ButtonState(GAMEPAD_KEY_DPAD_UP) == BUTTON_DOWN)
+ {
+ // show/hide HUD
+ Gamepad::ShowHideHud();
+ }
+ if(ButtonState(GAMEPAD_KEY_DPAD_DOWN) == BUTTON_DOWN)
+ {
+ }
+ }
+
+ //const float g_dt = 1.0f/120.0f; // the time delta used for simulation
+ if (numAxis == 6)
+ {
+ // XBOX 360 has 6 axis
+ int iLTChange = AxisChange(AXIS_LT);
+ int iRTChange = AxisChange(AXIS_RT);
+ if (iLTChange > 30000)
+ {
+ bLeftTrigger = true;
+ }
+ if (iRTChange > 30000)
+ {
+ bRightTrigger = true;
+ }
+ }
+ else if(numAxis == 5)
+ {
+ // Betop has 5 axis when x360 mode
+ int iLTChange = AxisChange(AXIS_LT);
+ int iRTChange = AxisChange(AXIS_RT);
+ if (iLTChange>15000)
+ {
+ bLeftTrigger = true;
+ }
+ if (iRTChange < -15000)
+ {
+ bRightTrigger = true;
+ }
+ }
+ if (1)
+ {
+ static float zoomSpeed = 0.1f;
+ static float rotateSpeed = 2.5f;
+
+ float deltaTime = (currentTime - lastJoyTime);
+ lastJoyTime = currentTime;
+
+ const float jsFactor = 1.0f/32768.0f;
+ int iLSX = AxisChange(AXIS_LS_X);
+ int iLSY = AxisChange(AXIS_LS_Y);
+ if(iLSX != 0 || iLSY != 0)
+ {
+ // left stick
+ float forceLSX = iLSX * jsFactor;
+ float forceLSY = iLSY * jsFactor;
+ if(bLeftTrigger || bRightTrigger)
+ {
+ if(bRightTrigger)
+ {
+ // wind direction
+ atcore_float3 direct = gfsdk_makeFloat3(forceLSX, forceLSY, 0.1f);
+ gfsdk_normalize(direct);
+
+ GlobalSettings::Inst().m_windDir = direct;
+ theScene->SetProjectModified(true);
+ }
+ if(bLeftTrigger)
+ {
+ // light direction
+ {
+ Light* pLight = Light::GetFirstSelectedLight();
+ if (pLight)
+ {
+ atcore_float2 delta = gfsdk_makeFloat2(forceLSX, forceLSY);
+ delta = 10.0f * delta;
+ pLight->Orbit(delta); // unit is in degree(s)
+ theScene->SetProjectModified(true);
+ }
+ }
+ }
+ }
+ else
+ {
+ if(iLSY != 0)
+ {
+ // zoom in/out
+ theScene->GetCamera()->Dolly(zoomSpeed * forceLSY);
+ theScene->SetProjectModified(true);
+ }
+ }
+ }
+ int iRSX = AxisChange(AXIS_RS_X);
+ int iRSY = AxisChange(AXIS_RS_Y);
+ if(iRSX != 0 || iRSY != 0)
+ {
+ float forceX = iRSX * jsFactor;
+ float forceY = iRSY * jsFactor;
+ if(bRightTrigger)
+ {
+ if (iRSX != 0)
+ {
+ // wind strength, Press right to increase. Press left to decrease
+ static float windStrength = 0.0f;
+ static float fStep = 0.1f;
+ if (iRSX > 0)
+ windStrength += fStep;
+ else
+ windStrength -= fStep;
+ if (windStrength > 10.0f)
+ windStrength = 10.0f;
+ if (windStrength < 0.0f)
+ windStrength = 0.0f;
+
+#ifndef NV_ARTISTTOOLS
+ BlastToolbar* toolbar = AppMainWindow::Inst().GetMainToolbar();
+ toolbar->on_spinWindStrength_valueChanged(windStrength);
+ toolbar->updateValues();
+#else
+ CoreLib::Inst()->GamepadHandler_SpinWindStrength(windStrength);
+#endif // NV_ARTISTTOOLS
+ }
+ }
+ else
+ {
+ // rotate camera
+ atcore_float2 moveRightStick = gfsdk_makeFloat2(forceX, forceY);
+ theScene->GetCamera()->Orbit(moveRightStick*rotateSpeed);
+ theScene->SetProjectModified(true);
+ }
+ }
+ }
+ //if(numAxis>5)
+ //{
+ //// XBOX 360 has 6 axis
+ //if((iAxisState[4]>=0) && (iAxisStateOld[4]<0))
+ //{
+ // bool bShow = ! GlobalSettings::Inst().m_showHUD;
+ // DisplayScenePanel* pspanel = AppMainWindow::Inst().GetDisplayScenePanel();
+ // if(pspanel)
+ // {
+ // pspanel->on_btnShowHUD_stateChanged(bShow);
+ // pspanel->on_btnComputeStats_stateChanged(false);
+ // }
+ //}
+ //if((iAxisState[5]>=0) && (iAxisStateOld[5]<0))
+ //{
+ // bool bShow = ! GlobalSettings::Inst().m_computeStatistics;
+ // DisplayScenePanel* pspanel = AppMainWindow::Inst().GetDisplayScenePanel();
+ // if(pspanel)
+ // {
+ // DisplayScenePanel* pspanel = AppMainWindow::Inst().GetDisplayScenePanel();
+ // if(pspanel)
+ // {
+ // // HUD controls stats
+ // pspanel->on_btnComputeStats_stateChanged(bShow);
+ // pspanel->on_btnShowHUD_stateChanged(bShow);
+ // }
+ // }
+ //}
+ //}
+ for(int i = 0; i < numAxis; ++i)
+ {
+ //if(iAxisStateOld[i] != iAxisState[i])
+ //{
+ // char msg[512];
+ // sprintf(msg, "Axis: %d %d", i, iAxisState[i]);
+ // viewer_msg(msg);
+ //}
+ iAxisStateOld[i] = iAxisState[i];
+ }
+
+ for(int i = 0; i < numButtons; ++i)
+ {
+ iButtonStateOld[i] = iButtonState[i];
+ }
+
+ if (numPov == 1)
+ {
+ for (int i = GAMEPAD_KEY_DPAD_UP; i <= GAMEPAD_KEY_DPAD_RIGHT; ++i)
+ {
+ iButtonStateOld[i] = iButtonState[i];
+ }
+ }
+}
+
+//void Gamepad::ClearStates()
+//{
+// for(int i = 0; i < iStateSize; ++i)
+// {
+// bKeyHolding[i] = 0;
+//
+// iAxisStateOld[i] = 0;
+// iAxisState[i] = 0;
+// iButtonStateOld[i] = 0;
+// iButtonState[i] = 0;
+// }
+//}
+
+void Gamepad::ShowHideHud()
+{
+ static bool bShowHud = true;
+ DisplayScenePanel* pspanel = AppMainWindow::Inst().GetDisplayScenePanel();
+ if (pspanel)
+ {
+ // HUD controls stats
+ pspanel->on_btnShowHUD_stateChanged(bShowHud);
+ pspanel->on_btnComputeStats_stateChanged(false);
+ bShowHud = !bShowHud;
+ }
+}
+
+void Gamepad::ShowHideStats()
+{
+ static bool bShowStats = true;
+ DisplayScenePanel* pspanel = AppMainWindow::Inst().GetDisplayScenePanel();
+ if (pspanel)
+ {
+ // HUD controls stats
+ pspanel->on_btnComputeStats_stateChanged(bShowStats);
+ pspanel->on_btnShowHUD_stateChanged(bShowStats);
+ bShowStats = !bShowStats;
+ }
+}
+
+void Gamepad::QuitApp()
+{
+ AppMainWindow::Inst().close();
+}
+
+void Gamepad::ResetAnimation()
+{
+#ifndef NV_ARTISTTOOLS
+ GlobalSettings::Inst().toggleSimulation();
+ bool simulating = GlobalSettings::Inst().toggleSimulation(); // call it twice to get right state
+
+ GlobalSettings::Inst().toggleAnimation();
+ bool animating = GlobalSettings::Inst().toggleAnimation(); // call it twice to get right state
+
+ BlastToolbar* toolbar = AppMainWindow::Inst().GetMainToolbar();
+ if (!simulating)
+ {
+ toolbar->on_btnEnableSimulation_clicked();
+ }
+ if (!animating)
+ {
+ toolbar->on_btnPlayAnimation_clicked();
+ }
+ toolbar->on_btnResetAnimation_clicked();
+#else
+ CoreLib::Inst()->Gamepad_ResetAnimation();
+#endif // NV_ARTISTTOOLS
+}
+
+void Gamepad::PlayPauseAnimation()
+{
+#ifndef NV_ARTISTTOOLS
+ GlobalSettings::Inst().toggleSimulation();
+ bool simulating = GlobalSettings::Inst().toggleSimulation(); // call it twice to get right state
+
+ GlobalSettings::Inst().toggleAnimation();
+ bool animating = GlobalSettings::Inst().toggleAnimation(); // call it twice to get right state
+
+ BlastToolbar* toolbar = AppMainWindow::Inst().GetMainToolbar();
+ if (simulating != animating)
+ {
+ toolbar->on_btnEnableSimulation_clicked();
+ }
+ toolbar->on_btnEnableSimulation_clicked();
+ toolbar->on_btnPlayAnimation_clicked();
+#else
+ CoreLib::Inst()->Gamepad_PlayPauseAnimation();
+#endif // NV_ARTISTTOOLS
+}
+
+void Gamepad::DemoModeOnOff()
+{
+ ChangeMode();
+}
+
+void Gamepad::DemoNext()
+{
+ LoadSamples(true);
+ StartAnimation();
+}
+
+void Gamepad::DemoPrev()
+{
+ LoadSamples(false);
+ StartAnimation();
+}
+
+void Gamepad::SetDemoMode(bool onOff)
+{
+ //if (AppMainWindow::IsExpertMode() != onOff)
+ //{
+ // ChangeMode();
+ //}
+ if (onOff)
+ {
+ curentPrjIdx = -1; // make it start from first demo
+ DemoNext();
+
+ // turn off FPS display
+ GlobalSettings::Inst().m_showFPS = false;
+ }
+ else
+ {
+ ShowUsage();
+ }
+ ChangeMode();
+}
+
+void Gamepad::DemoEscape()
+{
+ if (AppMainWindow::IsExpertMode())
+ {
+ ChangeMode();
+ // hide HUD if it is on. for GWDCC - 393 Blast Viewer - play list stats
+ DisplayScenePanel* pspanel = AppMainWindow::Inst().GetDisplayScenePanel();
+ if (pspanel)
+ {
+ // HUD controls stats
+ pspanel->on_btnShowHUD_stateChanged(false);
+ pspanel->on_btnComputeStats_stateChanged(false);
+ }
+ }
+ //else
+ //{
+ // QuitApp();
+ //}
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Scene/Gamepad.h b/tools/ArtistTools/source/CoreLib/Scene/Gamepad.h
new file mode 100644
index 0000000..46d45ba
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/Gamepad.h
@@ -0,0 +1,68 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+class SimpleScene;
+
+class Gamepad
+{
+public:
+ Gamepad();
+ ~Gamepad();
+
+ static Gamepad& Instance();
+
+ void Process();
+ bool Initialize();
+ void Free();
+
+ bool IsDemoMode();
+
+ void SetDemoProjects(QList<QString>& projects);
+
+ static void DemoNext();
+ static void DemoPrev();
+ static void ShowProjectName();
+ static void ShowHideHud();
+ static void ShowHideStats();
+ static void QuitApp();
+ static void ResetAnimation();
+ static void PlayPauseAnimation();
+ static void DemoModeOnOff();
+ static void DemoEscape();
+ static void SetDemoMode(bool onOff);
+ static void ShowUsage();
+
+private:
+ void ResetScene();
+ void ManualReadGamepad();
+
+ void HandleJoySticks();
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.cpp b/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.cpp
new file mode 100644
index 0000000..1903d32
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.cpp
@@ -0,0 +1,319 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#include "GlobalSettings.h"
+#include <QtCore/QTimer>
+#include "Settings.h"
+#include "Shlwapi.h"
+
+static GlobalSettings g_settings;
+static QTimer g_frameTimer(NV_NULL);
+
+////////////////////////////////////////////////////////////////////////////////////////////
+GlobalSettings::GlobalSettings()
+{
+ Init();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+GlobalSettings& GlobalSettings::Inst()
+{
+ return g_settings;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+QTimer& GlobalSettings::GetFrameTimer()
+{
+ return g_frameTimer;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+const char* GlobalSettings::MakeFileName(const char* path, const char* name)
+{
+ static char filename[MAX_PATH];
+ PathCombineA(filename, path, name);
+ return filename;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+void
+GlobalSettings::Init()
+{
+ m_animate = false;
+ m_simulate = true;
+ m_simulateStep = false;
+ m_firstFrame = true;
+ m_resetAnimationOnLoop = true;
+
+ m_animationFps = 24.0f;
+ m_repeatAnimation = true;
+ m_frameTime = 0.0f;
+ m_animationSpeed = 1.0f;
+ m_playStopped = false;
+ m_currentBoneIndex = 0;
+
+ m_simulationFrameCalc.init(0, 1.0f / 60.0f);
+ m_simulationFps = 60.0f;
+ m_timeStep = 0.0f;
+
+ m_visualizeWind = false;
+ m_showGraphicsMesh = true;
+ m_showWireframe = false;
+ m_showHUD = false;
+ m_visualizeBoneNames = false;
+
+ m_computeStatistics = false;
+ m_computeProfile = false;
+ m_previewLOD = false;
+ m_renderStyle = MESH_RENDER_TEXTURED;
+
+ m_sceneLoaded = false;
+ m_useDQ = false;
+ m_zup = false;
+ m_lhs = false;
+
+ m_sceneUnitIndex = SCENE_UNIT_CENTIMETER; // default to use cm
+
+ m_showGrid = true;
+ m_showAxis = true;
+
+ m_fovAngle = 75.0f;
+
+ m_loadTextures = true;
+ m_loadMaterials = true;
+ m_loadGroom = true;
+ m_loadCollision = true;
+ m_loadConstraints = true;
+
+ m_msaaOption = 0;
+
+ m_windDir.x = 0;
+ m_windDir.y = -1.0f;
+ m_windDir.z = 0.5f;
+ m_windStrength = 0.0f;
+ m_windNoise = 0.0f;
+
+ m_frameStartTime = 0.0f;
+ m_frameEndTime = 100.0f;
+
+ m_animationIndex = 0;
+
+ m_lockRootBone = false;
+
+ m_controlTextureOption = 0;
+ m_showSkinnedMeshOnly = false;
+
+ m_useLighting = true;
+ m_showFPS = true;
+
+ m_renderFrameCnt = 0;
+ m_renderFps = 60.0f;
+
+ m_projectFileDir = "";
+ m_projectFileName = "";
+ m_backgroundTextureFilePath = "";
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool GlobalSettings::toggleSimulation()
+{
+ m_simulate = !m_simulate;
+ m_simulateStep = false;
+
+ return m_simulate;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void GlobalSettings::stepSimulation()
+{
+ m_simulateStep = true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void GlobalSettings::setRenderFps(float fps)
+{
+ m_renderFps = fps;
+
+ OptionValue* option = nullptr;
+
+ option = AppSettings::Inst().GetOptionValue("User/PerfMode");
+ if (option)
+ {
+ if (option->Value.Bool == OA_TRUE)
+ {
+ g_frameTimer.setInterval(0);
+ }
+ else
+ g_frameTimer.setInterval((int)(1000 / fps));
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void GlobalSettings::setSimulationFps(float fps)
+{
+ m_simulationFps = fps;
+ m_simulationFrameCalc.setTimeStep(1.0f/ fps);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void GlobalSettings::resetAnimation()
+{
+ m_frameTime = m_frameStartTime;
+ m_firstFrame = m_resetAnimationOnLoop ? true : false;
+ m_playStopped = false;
+ m_simulateStep = true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void GlobalSettings::toggleAnimationRepeat()
+{
+ m_repeatAnimation = !m_repeatAnimation;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool GlobalSettings::toggleAnimation()
+{
+ m_animate = !m_animate;
+
+ if (m_animate && m_playStopped)
+ resetAnimation();
+
+ return m_animate;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void GlobalSettings::stepAnimation()
+{
+ if (!m_sceneLoaded)
+ return;
+
+ if (m_repeatAnimation)
+ m_playStopped = false;
+
+ if (!m_playStopped)
+ m_frameTime += m_animationSpeed * m_animationFps * m_timeStep;
+
+ if (m_frameTime > m_frameEndTime)
+ {
+ if (m_repeatAnimation)
+ resetAnimation();
+ else
+ {
+ m_frameTime = m_frameEndTime;
+ m_playStopped = true;
+ m_animate = false;
+ }
+ }
+
+ if (!m_animate)
+ {
+ stepSimulation();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void GlobalSettings::setSceneUnitIndex(int i)
+{
+ if (i < 0)
+ return;
+
+ if (i >= SCENE_UNIT_END)
+ return;
+
+ m_sceneUnitIndex = i;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+float GlobalSettings::getSceneUnitInCentimeters()
+{
+ float unit = 1.0f;
+
+ switch (m_sceneUnitIndex)
+ {
+ case SCENE_UNIT_CENTIMETER:
+ unit = 1.0f;
+ break;
+ case SCENE_UNIT_METER:
+ unit = 100.0f;
+ break;
+ case SCENE_UNIT_INCH:
+ unit = 2.54f;
+ break;
+ case SCENE_UNIT_DECIMETER:
+ unit = 10.0f;
+ break;
+ }
+
+ return unit;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+atcore_float3 GlobalSettings::getGravityDir()
+{
+ atcore_float3 gravityDir;
+
+ if (m_zup)
+ {
+ gravityDir.x = 0.0f;
+ gravityDir.y = 0.0f;
+ gravityDir.z = -1.0f;
+ }
+ else
+ {
+ gravityDir.x = 0.0f;
+ gravityDir.y = -1.0f;
+ gravityDir.z = 0.0f;
+ }
+
+ return gravityDir;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+std::string GlobalSettings::getAbsoluteFilePath()
+{
+ return m_projectFileDir + "\\" + m_projectFileName;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+std::string GlobalSettings::getAbsoluteFilePath(const char* fileName)
+{
+ return m_projectFileDir + "\\" + fileName;
+}
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QDir>
+
+///////////////////////////////////////////////////////////////////////////////
+std::string GlobalSettings::getRelativePath(const char* filePath)
+{
+ QDir projectDir(m_projectFileDir.c_str());
+ QByteArray relPath = projectDir.relativeFilePath(filePath).toLocal8Bit();
+
+ return (const char*)relPath;
+}
diff --git a/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.h b/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.h
new file mode 100644
index 0000000..c83143b
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.h
@@ -0,0 +1,173 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "MathUtil.h"
+#include <string>
+
+#include <Nv/Common/Animation/NvCoFrameCalculator.h>
+
+class QTimer;
+
+enum
+{
+ MESH_RENDER_WIREFRAME,
+ MESH_RENDER_FLAT,
+ MESH_RENDER_SHADED,
+ MESH_RENDER_TEXTURED,
+ MESH_RENDER_END,
+};
+
+enum
+{
+ SCENE_UNIT_UNKNOWN,
+ SCENE_UNIT_CENTIMETER,
+ SCENE_UNIT_METER,
+ SCENE_UNIT_INCH,
+ SCENE_UNIT_DECIMETER,
+ SCENE_UNIT_END,
+};
+
+//////////////////////////////////////////////////////////////////////////////////////
+// Placeholder for all the global settings used in hairworks viewer.
+// This stores all simple options that are not part of hair instance descriptor
+// such as animation logic in UI, scene settings, scene visualization options etc.
+//////////////////////////////////////////////////////////////////////////////////////
+class CORELIB_EXPORT GlobalSettings
+{
+public:
+ GlobalSettings();
+
+ void Init();
+ static GlobalSettings& Inst();
+ static QTimer& GetFrameTimer();
+ static const char* MakeFileName(const char* path, const char* name);
+
+public:
+
+ // animation settings
+ bool m_animate;
+ float m_animationFps;
+ int m_animationIndex;
+ float m_animationSpeed;
+ int m_currentBoneIndex;
+ bool m_firstFrame;
+ float m_frameTime;
+ float m_frameStartTime;
+ float m_frameEndTime;
+ bool m_lockRootBone;
+ bool m_playStopped;
+ bool m_repeatAnimation;
+ bool m_resetAnimationOnLoop;
+
+ bool m_simulate;
+ bool m_simulateStep;
+
+ float m_timeStep;
+ NvCo::FrameCalculator m_simulationFrameCalc;
+ float m_simulationFps;
+
+ // scene settings
+ bool m_useDQ;
+ bool m_zup;
+ bool m_lhs;
+ bool m_sceneLoaded;
+ int m_sceneUnitIndex;
+ std::string m_backgroundTextureFilePath;
+
+ // statistics and profiling
+ bool m_computeStatistics;
+ bool m_computeProfile;
+
+ // render option
+ float m_fovAngle;
+ bool m_useLighting;
+ int m_msaaOption;
+ int m_renderFrameCnt;
+ float m_renderFps;
+
+ // viusialization
+ int m_controlTextureOption;
+ bool m_previewLOD;
+ int m_renderStyle;
+ bool m_showAxis;
+ bool m_showHUD;
+ bool m_showFPS;
+ bool m_showGraphicsMesh;
+ bool m_showGrid;
+ bool m_showWireframe;
+ bool m_showSkinnedMeshOnly;
+ bool m_visualizeShadowMap;
+ bool m_visualizeWind;
+ bool m_visualizeBoneNames;
+
+ // global wind
+ atcore_float3 m_windDir;
+ float m_windStrength;
+ float m_windNoise;
+
+ // import settings
+ bool m_loadTextures;
+ bool m_loadMaterials;
+ bool m_loadGroom;
+ bool m_loadCollision;
+ bool m_loadConstraints;
+
+ // file path
+ std::string m_projectFileDir;
+ std::string m_projectFileName;
+
+ // convenience access functions
+public:
+
+ bool isBindPose() { return m_animationIndex == 0; }
+ float getSceneUnitInCentimeters();
+ void setSceneUnitIndex(int i);
+
+ void setTimeStep(float timeStep) { m_timeStep = timeStep; }
+
+ bool toggleSimulation();
+ void stepSimulation();
+
+ void setRenderFps(float fps);
+ void setSimulationFps(float fps);
+
+ void resetAnimation();
+ void stepAnimation();
+ bool toggleAnimation();
+ void toggleAnimationRepeat();
+ void getAnimationRange( float& start, float& end);
+
+ std::string getAbsoluteFilePath();
+ std::string getAbsoluteFilePath(const char* fileName);
+ std::string getRelativePath(const char* filePath);
+
+ atcore_float3 getGravityDir();
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Scene/Light.cpp b/tools/ArtistTools/source/CoreLib/Scene/Light.cpp
new file mode 100644
index 0000000..e18314e
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/Light.cpp
@@ -0,0 +1,744 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "Light.h"
+
+#include "GlobalSettings.h"
+#include "ShadowMap.h"
+#include "SimpleRenderable.h"
+#include "MeshShaderParam.h"
+
+#include "RenderInterface.h"
+
+//////////////////////////////////////////////////////////////////////////////
+inline int GetShadowMapResolution(int index)
+{
+ switch (index)
+ {
+ case 0: // default
+ return 2048;
+ break;
+ case 1:
+ return 4096;
+ break;
+ case 2:
+ return 1024;
+ break;
+ case 3:
+ return 512;
+ break;
+ case 4:
+ return 8192;
+ break;
+ case 5:
+ return 16384;
+ break;
+ }
+
+ return 1024;
+}
+
+namespace
+{
+ std::vector<Light> g_Lights;
+ static bool g_LinkLightOption = false;
+ std::string m_envTextureFilePath;
+ GPUShaderResource* m_pEnvTextureSRV;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+Light::Light()
+{
+ m_enable = true;
+ m_useShadows = false;
+ m_visualize = false;
+ m_isEnvLight = false;
+ m_useEnvMap = false;
+
+ m_selected = false;
+
+ m_color = gfsdk_makeFloat3(1.0f, 1.0f, 1.0f);
+ m_intensity = 1.0f;
+
+ m_pShadowMap = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+Light::~Light()
+{
+ if (m_pShadowMap)
+ {
+ delete m_pShadowMap;
+ m_pShadowMap = 0;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool Light::UseLHS() const {
+ return m_lightCamera.UseLHS();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+GPUShaderResource* Light::GetShadowSRV()
+{
+ if (!m_pShadowMap)
+ return 0;
+
+ return m_pShadowMap->GetShadowSRV();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::SetShadowMapResolution(int index)
+{
+ if (m_shadowMapResolutionIndex == index)
+ return;
+
+ m_lightMapResolution = GetShadowMapResolution(index);
+
+ if (m_pShadowMap)
+ {
+ m_pShadowMap->Release();
+ delete m_pShadowMap;
+ }
+
+ m_pShadowMap = ShadowMap::Create(m_lightMapResolution);
+
+ float minZ = 1.0f;
+ float maxZ = 10000.0f; // should calculate dynamically
+
+ m_lightCamera.Ortho(m_lightMapResolution, m_lightMapResolution, minZ, maxZ);
+
+ m_shadowMapResolutionIndex = index;
+
+ FitBounds();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::Init()
+{
+ m_shadowMapResolutionIndex = 2;
+ m_lightMapResolution = GetShadowMapResolution(m_shadowMapResolutionIndex);
+
+ m_pShadowMap = ShadowMap::Create(m_lightMapResolution);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::Release()
+{
+ if (m_pShadowMap)
+ {
+ delete m_pShadowMap;
+ m_pShadowMap = 0;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::InitCamera(const atcore_float3& from, const atcore_float3& lookAt)
+{
+ m_lightCamera.Init(false, false);
+
+// atcore_float3 up = gfsdk_makeFloat3(0.0f, 1.0f, 0.0f);
+ atcore_float3 up = gfsdk_makeFloat3(0.0f, 0.0f, 1.0f);
+
+ m_lightCamera.LookAt(from, lookAt, up);
+
+ float minZ = 1.0f;
+ float maxZ = 10000.0f; // should calculate dynamically
+
+ m_lightCamera.Ortho(m_lightMapResolution, m_lightMapResolution, minZ, maxZ);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+atcore_float3
+Light::getLightDirection() const
+{
+ return (atcore_float3&)m_lightCamera.GetViewDirection();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::SetBounds(atcore_float3* bbCenter, atcore_float3* bbExtents)
+{
+ if (bbCenter)
+ m_bbCenter = *bbCenter;
+ if (bbExtents)
+ m_bbExtent = *bbExtents;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::FitBounds(bool updateCenter)
+{
+ ////////////////////////////////////////////////////////
+ atcore_float3 bbCenter = m_bbCenter;
+ atcore_float3 bbExtents =m_bbExtent;
+
+ ////////////////////////////////////////////////////////////////////////
+ if (updateCenter)
+ {
+ atcore_float3 lightPos = m_lightCamera.GetEye();
+ atcore_float3 lightAt = m_lightCamera.GetAt();
+
+ atcore_float3 disp = bbCenter - lightAt;
+
+ lightAt = lightAt + disp;
+ lightPos = lightPos + disp;
+
+ m_lightCamera.SetEye(lightPos);
+ m_lightCamera.SetAt(lightAt);
+ m_lightCamera.BuildViewMatrix();
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ float size = bbExtents.x;
+
+ size = max(size, bbExtents.y);
+ size = max(size, bbExtents.z);
+
+ atcore_float4x4 view = m_lightCamera.GetViewMatrix();
+
+ atcore_float3 c = gfsdk_transformCoord(view, bbCenter);
+
+ size *= 3.0f;
+
+ float minZ = c.z - size;
+ float maxZ = c.z + size;
+
+ float orthoW = size;
+ float orthoH = size;
+
+ if (m_lightCamera.UseLHS())
+ m_lightCamera.Ortho(orthoW, orthoH, minZ, maxZ);
+ else // rhs camera flips Z
+ m_lightCamera.Ortho(orthoW, orthoH, -maxZ, -minZ);
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::resetUpDir(bool zup)
+{
+ m_lightCamera.ResetUpDir(zup);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::resetLhs(bool lhs)
+{
+ m_lightCamera.ResetLhs(lhs);
+ FitBounds();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::Orbit(const atcore_float2& delta)
+{
+ m_lightCamera.OrbitLight(gfsdk_makeFloat2(-delta.x, delta.y));
+
+ FitBounds();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::Pan(const atcore_float2& delta, const atcore_float3& axisX, const atcore_float3& axisY)
+{
+ atcore_float3 lightPos = m_lightCamera.GetEye();
+ atcore_float3 lightAt = m_lightCamera.GetAt();
+ atcore_float3 lightDir = m_lightCamera.GetZAxis();
+
+ float depth = GetDistance();
+
+ atcore_float2 newDelta = depth * delta;
+
+ atcore_float3 disp = -1.0f * axisY * newDelta.y + axisX * newDelta.x;
+
+ lightAt = lightAt + disp;
+ lightPos = lightPos + disp;
+
+ m_lightCamera.SetEye(lightPos);
+ m_lightCamera.SetAt(lightAt);
+ m_lightCamera.BuildViewMatrix();
+
+ FitBounds();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+float Light::GetDistance() const
+{
+ return m_lightCamera.GetLookDistance();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool Light::SetDistance(float newdistance)
+{
+ atcore_float3 lightPos = m_lightCamera.GetEye();
+ atcore_float3 lightAt = m_lightCamera.GetAt();
+ atcore_float3 lightDir = m_lightCamera.GetZAxis();
+
+ lightPos = lightAt + newdistance * lightDir;
+
+ m_lightCamera.SetEye(lightPos);
+ m_lightCamera.BuildViewMatrix();
+
+ FitBounds();
+
+ return true;
+}
+//////////////////////////////////////////////////////////////////////////////
+void Light::BeginShadowMapRendering()
+{
+ if (!m_pShadowMap) return;
+
+ float clearDepth = m_lightCamera.UseLHS() ? FLT_MAX : -FLT_MAX;
+ m_pShadowMap->BeginRendering(clearDepth);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::EndShadowMapRendering()
+{
+ if (!m_pShadowMap) return;
+
+ m_pShadowMap->EndRendering();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+atcore_float4x4 Light::GetViewMatrix() const
+{
+ return m_lightCamera.GetViewMatrix();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+atcore_float4x4 Light::GetProjectionMatrix() const
+{
+ return m_lightCamera.GetProjectionMatrix();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+atcore_float4x4 Light::GetLightMatrix() const
+{
+ atcore_float4x4 view = m_lightCamera.GetViewMatrix();
+ atcore_float4x4 projection = m_lightCamera.GetProjectionMatrix();
+
+ float mClip2Tex[] = {
+ 0.5, 0, 0, 0,
+ 0, -0.5, 0, 0,
+ 0, 0, 1, 0,
+ 0.5, 0.5, 0, 1
+ };
+ atcore_float4x4 clip2Tex = (atcore_float4x4&)mClip2Tex;
+
+ atcore_float4x4 viewProjection = view * projection;
+
+ atcore_float4x4 lightMatrix = viewProjection * clip2Tex;
+
+ return lightMatrix;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void Light::FillLightShaderParam(LightShaderParam &param)
+{
+ const std::vector<Light> &lights = g_Lights;
+
+ for (int i = 0; i < lights.size(); i++)
+ {
+ if (i >= 4)
+ break;
+
+ LightParam& lparam = param.m_lightParam[i];
+ memset(&lparam, 0, sizeof(LightParam));
+
+ const Light& light= lights[i];
+
+ lparam.m_enable = light.m_enable;
+ lparam.m_useShadows = light.m_useShadows;
+
+ lparam.m_dir = light.getLightDirection();
+ lparam.m_intensity = light.m_intensity;
+ lparam.m_color = light.m_color;
+ lparam.m_isEnvLight = light.m_isEnvLight;
+ lparam.m_useEnvMap = light.m_isEnvLight && (m_pEnvTextureSRV != 0);
+
+ float sceneUnit = GlobalSettings::Inst().getSceneUnitInCentimeters();
+ lparam.m_depthBias = (sceneUnit > 0.0f) ? 1.0f / sceneUnit : 1.0f;
+
+ if (light.UseLHS())
+ {
+ lparam.m_depthBias *= -1.0f;
+ lparam.m_depthGain = -1.0f;
+ lparam.m_lhs = true;
+ }
+ else
+ {
+ lparam.m_depthGain = 1.0f;
+ lparam.m_lhs = false;
+ }
+
+ lparam.m_viewMatrix = light.GetViewMatrix();
+ lparam.m_lightMatrix = light.GetLightMatrix();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::draw(Camera* pCamera)
+{
+ atcore_float3 lightPos = m_lightCamera.GetEye();
+ atcore_float3 lightAt = m_lightCamera.GetAt();
+
+ atcore_float4 color = gfsdk_makeFloat4(m_color.x, m_color.y, m_color.z, 1);
+ if (m_enable == false)
+ color = gfsdk_makeFloat4(0.5, 0.5, 0.5, 1);
+
+ // draw light shape
+ atcore_float4x4 lightMat = gfsdk_transpose(m_lightCamera.GetViewMatrix());
+ gfsdk_setPosition(lightMat, lightPos);
+
+ SimpleShaderParam param;
+ {
+ param.world = lightMat;
+ param.view = pCamera->GetViewMatrix();
+ param.projection = pCamera->GetProjectionMatrix();
+ param.useVertexColor = false;
+ param.color = color;
+ }
+
+ RenderInterface::CopyShaderParam(RenderInterface::SHADER_TYPE_SIMPLE_COLOR,
+ (void*)&param, sizeof(SimpleShaderParam) );
+
+ SimpleRenderable::Draw(SimpleRenderable::LIGHT);
+
+ // draw light ray
+ gfsdk_makeIdentity(param.world);
+ RenderInterface::CopyShaderParam(RenderInterface::SHADER_TYPE_SIMPLE_COLOR,
+ (void*)&param, sizeof(SimpleShaderParam) );
+
+ SimpleRenderable::DrawLine(lightAt, lightPos);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool Light::loadParameters(NvParameterized::Handle& handle)
+{
+#ifndef NV_ARTISTTOOLS
+ NvParameterized::NvParameters* params = static_cast<NvParameterized::NvParameters*>(handle.getInterface());
+ size_t offset = 0;
+ nvidia::parameterized::HairProjectParametersNS::Light_Type* param = nullptr;
+ params->getVarPtr(handle, (void*&)param, offset);
+
+ m_enable = param->enable;
+ m_useShadows = param->useShadows;
+ m_visualize = param->visualize;
+ m_intensity = param->intensity;
+
+ memcpy(&m_color, &param->color, sizeof(atcore_float3));
+
+ atcore_float3 axisX, axisY, axisZ, lightPos;
+ memcpy(&axisX, &param->lightAxisX, sizeof(atcore_float3));
+ memcpy(&axisY, &param->lightAxisY, sizeof(atcore_float3));
+ memcpy(&axisZ, &param->lightAxisZ, sizeof(atcore_float3));
+ memcpy(&lightPos, &param->lightPos, sizeof(atcore_float3));
+
+ this->SetShadowMapResolution(param->shadowMapResolution);
+
+ m_lightCamera.SetEye(lightPos);
+ m_lightCamera.SetViewMatrix(axisX, axisY, axisZ);
+ m_lightCamera.BuildViewMatrix();
+#else
+ CoreLib::Inst()->Light_loadParameters(handle, this);
+#endif // NV_ARTISTTOOLS
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool Light::saveParameters(NvParameterized::Handle& handle)
+{
+#ifndef NV_ARTISTTOOLS
+ NvParameterized::NvParameters* params = static_cast<NvParameterized::NvParameters*>(handle.getInterface());
+ size_t offset = 0;
+ nvidia::parameterized::HairProjectParametersNS::Light_Type* param = nullptr;
+ params->getVarPtr(handle, (void*&)param, offset);
+
+ param->enable = m_enable;
+ param->useShadows = m_useShadows;
+ param->visualize = m_visualize;
+ param->intensity = m_intensity;
+
+ param->shadowMapResolution = m_shadowMapResolutionIndex;
+
+ memcpy(&param->color, &m_color, sizeof(atcore_float3));
+
+ {
+ atcore_float3 axisX = m_lightCamera.GetXAxis();
+ atcore_float3 axisY = m_lightCamera.GetYAxis();
+ atcore_float3 axisZ = m_lightCamera.GetZAxis();
+ atcore_float3 lightPos = m_lightCamera.GetEye();
+
+ memcpy(&param->lightAxisX, &axisX, sizeof(atcore_float3));
+ memcpy(&param->lightAxisY, &axisY, sizeof(atcore_float3));
+ memcpy(&param->lightAxisZ, &axisZ, sizeof(atcore_float3));
+ memcpy(&param->lightPos, &lightPos, sizeof(atcore_float3));
+ }
+#else
+ CoreLib::Inst()->Light_saveParameters(handle, this);
+#endif // NV_ARTISTTOOLS
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool Light::SetEnvTextureFromFilePath(const char* textureFilePath)
+{
+ Light* pLight = Light::GetFirstSelectedLight();
+ if (!pLight || !pLight->m_isEnvLight)
+ return false;
+
+ m_envTextureFilePath = (textureFilePath) ? textureFilePath : "";
+
+ SAFE_RELEASE(m_pEnvTextureSRV);
+ if ((!textureFilePath) && (strlen(textureFilePath) > 0))
+ m_pEnvTextureSRV = RenderInterface::CreateTextureResource(textureFilePath);
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+const std::string& Light::GetEnvTextureFilePath()
+{
+ return m_envTextureFilePath;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+GPUShaderResource* Light::GetEnvTextureSRV()
+{
+ return m_pEnvTextureSRV;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+GPUShaderResource* Light::GetShadowSRV(int i)
+{
+ if ((i >= 3) || (i < 0))
+ return 0;
+
+ return g_Lights[i].GetShadowSRV();
+}
+
+bool Light::GetLinkLightOption()
+{
+ return g_LinkLightOption;
+}
+
+void Light::SetLinkLightOption(bool val)
+{
+ g_LinkLightOption = val;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+std::vector<Light>& Light::GetDefaultLights()
+{
+ return g_Lights;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+Light* Light::GetFirstSelectedLight()
+{
+ for (int i = 0; i < g_Lights.size(); i++)
+ {
+ if (g_Lights[i].m_selected)
+ return &g_Lights[i];
+ }
+
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+Light* Light::GetLight(int index)
+{
+ if (index < 0)
+ return 0;
+ if (index >= g_Lights.size())
+ return 0;
+
+ return &g_Lights[index];
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::Initialize()
+{
+ g_Lights.resize(4);
+
+ Light& keyLight = g_Lights[0];
+ Light& fillLight = g_Lights[1];
+ Light& rimLight = g_Lights[2];
+ Light& envLight = g_Lights[3];
+
+ atcore_float3 lookAt = gfsdk_makeFloat3(0.0f, 0.0f, 0.0f);
+
+ keyLight.m_selected = true;
+ keyLight.m_enable = true;
+ keyLight.m_color = gfsdk_makeFloat3(1, 1, 1);
+ keyLight.m_useShadows = true;
+ keyLight.m_isEnvLight = false;
+ keyLight.InitCamera(gfsdk_makeFloat3(100.0f, 25.0f, 0.0f), lookAt);
+ keyLight.m_name = "Key Light";
+
+ fillLight.m_enable = false;
+ fillLight.m_color = gfsdk_makeFloat3(0.5, 0.5, 0.5);
+ fillLight.m_useShadows = false;
+ fillLight.m_isEnvLight = false;
+ fillLight.InitCamera(gfsdk_makeFloat3(-100.0f, 0.0f, 25.0f), lookAt);
+ fillLight.m_name = "Fill Light";
+
+ rimLight.m_enable = false;
+ rimLight.m_color = gfsdk_makeFloat3(0.25, 0.25, 0.25);
+ rimLight.m_useShadows = false;
+ rimLight.m_isEnvLight = false;
+ rimLight.InitCamera(gfsdk_makeFloat3(0.0f, 100.0f, -25.0f), lookAt);
+ rimLight.m_name = "Rim Light";
+
+ envLight.m_enable = false;
+ envLight.m_color = gfsdk_makeFloat3(0.25, 0.25, 0.25);
+ envLight.m_useShadows = false;
+ envLight.m_isEnvLight = true;
+ envLight.InitCamera(gfsdk_makeFloat3(0.0f, 0.0f, 0.0f), lookAt);
+ envLight.m_name = "Env Light";
+
+ for (int i = 0; i < g_Lights.size(); i++)
+ g_Lights[i].Init();
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::Shutdown()
+{
+ for (int i = 0; i < g_Lights.size(); i++)
+ g_Lights[i].Release();
+
+ g_Lights.clear();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::FitLightCameras(atcore_float3& center, atcore_float3& extent)
+{
+ for (int i = 0; i < g_Lights.size(); i++)
+ {
+ if (g_LinkLightOption && (i == FILL_LIGHT || i == RIM_LIGHT))
+ continue;
+
+ Light& light = g_Lights[i];
+ light.SetBounds(&center, &extent);
+ light.FitBounds(true);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::ResetUpDir(bool zup)
+{
+ for (int i = 0; i < g_Lights.size(); i++)
+ {
+ Light& li = g_Lights[i];
+ li.resetUpDir(zup);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::ResetLhs(bool lhs)
+{
+ for (int i = 0; i < g_Lights.size(); i++)
+ {
+ Light& li = g_Lights[i];
+ li.resetLhs(lhs);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::DrawLights(Camera* pCamera)
+{
+ for (int i = 0; i < g_Lights.size(); i++)
+ {
+ Light& light = g_Lights[i];
+ if (light.m_visualize)
+ light.draw(pCamera);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void Light::RenderShadowMap()
+{
+ Light* pLight = Light::GetFirstSelectedLight();
+ if (pLight)
+ {
+ float zNear = pLight->m_lightCamera.GetZNear();
+ float zFar = pLight->m_lightCamera.GetZFar();
+
+ if (pLight->UseLHS())
+ RenderInterface::RenderShadowMap(pLight->GetShadowSRV(), zNear, zFar);
+ else
+ RenderInterface::RenderShadowMap(pLight->GetShadowSRV(), -zFar, -zNear);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool Light::LoadParameters(NvParameterized::Handle& handle)
+{
+ // load lights
+ NvParameterized::Handle lightsHandle(handle);
+ if (handle.getChildHandle(handle.getInterface(), "lights", lightsHandle) == NvParameterized::ERROR_NONE)
+ {
+ int numLights = 0;
+ lightsHandle.getArraySize(numLights);
+ if (numLights > g_Lights.size())
+ numLights = g_Lights.size();
+
+ for (int idx = 0; idx < numLights; ++idx)
+ {
+ NvParameterized::Handle lightHandle(lightsHandle);
+ if (lightsHandle.getChildHandle(idx, lightHandle) == NvParameterized::ERROR_NONE)
+ {
+ g_Lights[idx].loadParameters(lightHandle);
+ }
+ }
+ }
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool Light::SaveParameters(NvParameterized::Handle& outHandle)
+{
+ NvParameterized::Handle lightsHandle(outHandle);
+ if (outHandle.getChildHandle(outHandle.getInterface(), "lights", lightsHandle) == NvParameterized::ERROR_NONE)
+ {
+ int numLights = (int)g_Lights.size();
+
+ lightsHandle.resizeArray(numLights);
+
+ for (int idx = 0; idx < numLights; ++idx)
+ {
+ NvParameterized::Handle lightHandle(outHandle);
+ if (lightsHandle.getChildHandle(idx, lightHandle) == NvParameterized::ERROR_NONE)
+ {
+ g_Lights[idx].saveParameters(lightHandle);
+ }
+ }
+ }
+ return true;
+}
+
+// END OF STATIC FUNCTIONS
+
diff --git a/tools/ArtistTools/source/CoreLib/Scene/Light.h b/tools/ArtistTools/source/CoreLib/Scene/Light.h
new file mode 100644
index 0000000..bbe4ef3
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/Light.h
@@ -0,0 +1,152 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "MathUtil.h"
+#ifndef NV_ARTISTTOOLS
+#include "ProjectParams.h"
+#else
+#include "NvParametersTypes.h"
+#ifndef NV_PARAMETERIZED_ONLY_LAYOUTS
+#include "NvParameterized.h"
+#include "NvParameters.h"
+#include "NvParameterizedTraits.h"
+#include "NvTraitsInternal.h"
+#endif
+#endif // NV_ARTISTTOOLS
+#include "Camera.h"
+
+#include <string>
+#include <vector>
+
+#include "LightShaderParam.h"
+
+class GPUShaderResource;
+class ShadowMap;
+
+/////////////////////////////////////////////////////////////////////////
+// Utility class for light object
+/////////////////////////////////////////////////////////////////////////
+class CORELIB_EXPORT Light
+{
+public:
+ bool m_enable;
+ bool m_useShadows;
+ bool m_visualize;
+ bool m_isEnvLight;
+ bool m_useEnvMap;
+
+ bool m_selected;
+
+ float m_intensity;
+ atcore_float3 m_color;
+
+ std::string m_name;
+ int m_shadowMapResolutionIndex;
+ int m_lightMapResolution;
+
+ // public API to access 4 lights
+ static std::vector<Light>& GetDefaultLights();
+ static Light* GetLight(int index);
+ static Light* GetFirstSelectedLight();
+
+ static void Initialize();
+ static void Shutdown();
+ static void FitLightCameras(atcore_float3& center, atcore_float3& extent);
+ static void ResetUpDir(bool zup);
+ static void ResetLhs(bool lhs);
+ static void DrawLights(Camera* pCamera);
+ static void FillLightShaderParam(LightShaderParam &param);
+ static bool LoadParameters(NvParameterized::Handle& handle);
+ static bool SaveParameters(NvParameterized::Handle& outHandle);
+ static void RenderShadowMap();
+
+ static bool SetEnvTextureFromFilePath(const char* textureFilePath);
+ static const std::string & GetEnvTextureFilePath();
+ static GPUShaderResource* GetEnvTextureSRV();
+ static GPUShaderResource* GetShadowSRV(int);
+
+ static bool GetLinkLightOption();
+ static void SetLinkLightOption(bool val);
+
+public:
+ Light();
+ ~Light();
+
+ enum
+ {
+ KEY_LIGHT,
+ FILL_LIGHT,
+ RIM_LIGHT,
+ ENV_LIGHT,
+ };
+
+ void Orbit(const atcore_float2& delta);
+ void Pan(const atcore_float2& delta, const atcore_float3& axisX, const atcore_float3& axisY);
+
+ bool UseLHS() const;
+
+ float GetDistance() const;
+ bool SetDistance(float newdistsance);
+
+ void SetShadowMapResolution(int option);
+ void BeginShadowMapRendering();
+ void EndShadowMapRendering();
+
+ GPUShaderResource* GetShadowSRV();
+
+ atcore_float4x4 GetViewMatrix() const;
+ atcore_float4x4 GetProjectionMatrix() const;
+ atcore_float4x4 GetLightMatrix() const;
+
+protected:
+ void Init();
+ void Release();
+
+ bool loadParameters(NvParameterized::Handle& handle);
+ bool saveParameters(NvParameterized::Handle& outHandle);
+
+ void SetBounds(atcore_float3* center, atcore_float3* extents = 0);
+ void FitBounds(bool updateCenter = false);
+
+ atcore_float3 getLightDirection() const;
+ void InitCamera(const atcore_float3& from, const atcore_float3& lookAt);
+
+ void draw(Camera* pCamera);
+ void resetUpDir(bool zup);
+ void resetLhs(bool zup);
+
+public:
+
+ Camera m_lightCamera;
+ ShadowMap* m_pShadowMap;
+
+ atcore_float3 m_bbCenter;
+ atcore_float3 m_bbExtent;
+};
diff --git a/tools/ArtistTools/source/CoreLib/Scene/MeshData.cpp b/tools/ArtistTools/source/CoreLib/Scene/MeshData.cpp
new file mode 100644
index 0000000..295ac7f
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/MeshData.cpp
@@ -0,0 +1,108 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "MeshData.h"
+
+#include "AnimUtil.h"
+#include "RenderResources.h"
+
+///////////////////////////////////////////////////////////////////////////////
+void CreateCPUResource(MeshData* pMeshData, const MeshDesc &meshDesc)
+{
+ if (!pMeshData)
+ return;
+
+ pMeshData->m_NumVertices = meshDesc.m_NumVertices;
+ pMeshData->m_NumIndices = meshDesc.m_NumTriangles * 3;
+
+ int numIndices = pMeshData->m_NumIndices;
+
+ pMeshData->m_pIndices = new NvUInt32[numIndices];
+ pMeshData->m_pMeshVertices = new MeshData::MeshVertex[numIndices];
+
+ NvUInt32* pVertUsed = new NvUInt32[meshDesc.m_NumVertices];
+ memset(pVertUsed, meshDesc.m_NumVertices, sizeof(NvUInt32) * meshDesc.m_NumVertices);
+ for (NvUInt32 i = 0; i < numIndices; i++)
+ {
+ NvUInt32 vidx = pMeshData->m_pIndices[i] = meshDesc.m_pIndices[i];
+
+ MeshData::MeshVertex&v = pMeshData->m_pMeshVertices[i];
+
+ v.pos = meshDesc.m_pVertices[vidx];
+ v.vertexNormal = meshDesc.m_pVertexNormals[i];
+ v.faceNormal = meshDesc.m_pFaceNormals[i];
+ v.tangent = meshDesc.m_pTangents[i];
+ v.texcoord = meshDesc.m_pTexCoords[i];
+ v.vertexId = (float)vidx;
+ pVertUsed[vidx] = i;
+ }
+ int numUniqueIndices = 0;
+ for (NvUInt32 i = 0; i < meshDesc.m_NumVertices; i++)
+ {
+ if (meshDesc.m_NumVertices != pVertUsed[i])
+ ++numUniqueIndices;
+ }
+ pMeshData->m_NumUniqueIndices = numUniqueIndices;
+ pMeshData->m_pUniqueIndices = new NvUInt32[numUniqueIndices];
+ for (NvUInt32 i = 0, idx = 0; i < meshDesc.m_NumVertices; i++)
+ {
+ if (meshDesc.m_NumVertices != pVertUsed[i])
+ {
+ pMeshData->m_pUniqueIndices[idx++] = pVertUsed[i];
+ }
+ }
+ delete[] pVertUsed;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+MeshData* MeshData::Create(MeshDesc &meshDesc, SkinData& skinData)
+{
+ MeshData* pMeshData = new MeshData;
+
+ CreateCPUResource(pMeshData, meshDesc);
+
+ pMeshData->m_GPUMeshResources = GPUMeshResources::Create(pMeshData, skinData);
+
+ return pMeshData;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void MeshData::Release()
+{
+ if (m_pMeshVertices)
+ delete [] m_pMeshVertices;
+
+ if (m_pIndices)
+ delete [] m_pIndices;
+
+ if (m_pUniqueIndices)
+ delete[] m_pUniqueIndices;
+
+ m_GPUMeshResources->Release();
+ delete m_GPUMeshResources;
+ m_GPUMeshResources = NULL;
+}
diff --git a/tools/ArtistTools/source/CoreLib/Scene/MeshData.h b/tools/ArtistTools/source/CoreLib/Scene/MeshData.h
new file mode 100644
index 0000000..f05207e
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/MeshData.h
@@ -0,0 +1,74 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "MathUtil.h"
+
+#include "RenderResources.h"
+
+class MeshDesc;
+class SkinData;
+
+//////////////////////////////////////////////////////////////////////////////////////
+// Helper for rendering graphics mesh
+//////////////////////////////////////////////////////////////////////////////////////
+class CORELIB_EXPORT MeshData
+{
+public:
+
+ struct MeshVertex
+ {
+ atcore_float3 pos;
+ atcore_float3 vertexNormal;
+ atcore_float3 faceNormal;
+ atcore_float3 tangent;
+ atcore_float2 texcoord;
+ float vertexId;
+ };
+
+public:
+ static MeshData* Create(MeshDesc &meshDesc, SkinData& skinData);
+ void Release();
+
+public:
+ int m_NumVertices;
+ int m_NumIndices;
+
+ MeshVertex* m_pMeshVertices;
+ NvUInt32* m_pIndices;
+
+ // m_pUniqueIndices and m_NumUniqueIndices are used to boost bounding calculation in FurMesh.cpp
+ NvUInt32* m_pUniqueIndices;
+ NvUInt32 m_NumUniqueIndices;
+
+ // gpu resources
+ GPUMeshResources* m_GPUMeshResources;
+};
+
+
diff --git a/tools/ArtistTools/source/CoreLib/Scene/Mouse.cpp b/tools/ArtistTools/source/CoreLib/Scene/Mouse.cpp
new file mode 100644
index 0000000..f321157
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/Mouse.cpp
@@ -0,0 +1,105 @@
+
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+
+#include "Mouse.h"
+
+//#include "windows.h"
+
+Mouse::Mouse()
+{
+}
+
+Mouse::~Mouse()
+{
+ Free();
+}
+
+bool Mouse::Initialize(HINSTANCE hInstance, HWND hWnd)
+{
+ /*
+ if (FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION,
+ IID_IDirectInput8, reinterpret_cast<void**>(&_pDirectInput), 0)))
+ return false;
+
+ if (FAILED(_pDirectInput->CreateDevice(GUID_SysMouse, &_pDevice, 0)))
+ return false;
+
+ if (FAILED(_pDevice->SetDataFormat(&c_dfDIMouse)))
+ return false;
+
+ if (FAILED(_pDevice->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
+ return false;
+
+ if (FAILED(_pDevice->Acquire()))
+ return false;
+ */
+ return true;
+}
+
+void Mouse::Free()
+{
+ /*
+ if (_pDevice)
+ {
+ _pDevice->Unacquire();
+ _pDevice = NULL;
+ }
+
+ _pDirectInput = NULL;
+ */
+}
+
+void Mouse::Update()
+{
+ /*
+ if (!_pDirectInput || !_pDevice)
+ {
+ return;
+ }
+
+ HRESULT hr;
+
+ while (true)
+ {
+ hr = _pDevice->GetDeviceState(sizeof(DIMOUSESTATE), &_mouseState);
+
+ if (FAILED(hr))
+ {
+ if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED)
+ {
+ if (FAILED(_pDevice->Acquire()))
+ return;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ */
+}
diff --git a/tools/ArtistTools/source/CoreLib/Scene/Mouse.h b/tools/ArtistTools/source/CoreLib/Scene/Mouse.h
new file mode 100644
index 0000000..3cbd598
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/Mouse.h
@@ -0,0 +1,103 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+/*
+#define DIRECTINPUT_VERSION 0x0800
+#include <dinput.h>
+*/
+#include "windows.h"
+#include "MathUtil.h"
+
+class Mouse
+{
+public:
+ Mouse();
+ ~Mouse();
+
+ /*
+ enum Button
+ {
+ LEFT = 0x00,
+ RIGHT = 0x01,
+ MIDDLE = 0x02
+ };
+
+ bool IsButtonPressed(Button button) const
+ {
+ if (_mouseState.rgbButtons[button] & 0x80)
+ return true;
+ return false;
+ }
+ */
+ void SetPosition(atcore_float2 position)
+ {
+ m_Position = position;
+ }
+
+ atcore_float2 GetDelta() const
+ {
+ return m_Delta;
+ }
+
+ void SetDelta(atcore_float2 position)
+ {
+ m_Delta = gfsdk_makeFloat2(
+ static_cast<float>(position.x - m_Position.x),
+ static_cast<float>(position.y - m_Position.y));
+ m_Position = position;
+ }
+
+ float GetDeltaWheel() const
+ {
+ if (m_DeltaWheel > 0)
+ return 1.0f;
+ else if (m_DeltaWheel < 0)
+ return -1.0f;
+ else
+ return 0.0f;
+ }
+
+ void SetDeltaWheel(float deltaWheel)
+ {
+ m_DeltaWheel = deltaWheel;
+ }
+
+ void Update();
+ bool Initialize(HINSTANCE hInstance, HWND hWnd);
+ void Free();
+ /*
+ IDirectInput8* _pDirectInput;
+ IDirectInputDevice8* _pDevice;
+ DIMOUSESTATE _mouseState;
+ */
+ atcore_float2 m_Position;
+ atcore_float2 m_Delta;
+ float m_DeltaWheel;
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.cpp b/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.cpp
new file mode 100644
index 0000000..a633770
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.cpp
@@ -0,0 +1,1312 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#include "SimpleScene.h"
+
+#include "AppMainWindow.h"
+#include "Automate.h"
+#include "Backdoor.h"
+#include "Gamepad.h"
+#include "GlobalSettings.h"
+#include "Light.h"
+#include "Mouse.h"
+#include "SimpleRenderable.h"
+#include "Stats.h"
+#include "CorelibUtils.h"
+//#include "Timer.h"
+#include "ViewerOutput.h"
+
+#include "FoundationHolder.h"
+
+#include <NvAllocatorCallback.h>
+#include <NvErrorCallback.h>
+#include <NsAlignedMalloc.h>
+#include <NsVersionNumber.h>
+
+#include <Nv/Common/NvCoMemoryAllocator.h>
+
+#include "RenderInterface.h"
+#include "DeviceManager.h"
+
+#ifndef NV_ARTISTTOOLS
+#include "FurCharacter.h"
+#include "FurRenderer.h"
+#include "ProjectParams.h"
+#include "HairInstance.h"
+#include "HairSDK.h"
+
+namespace { // anonymous
+
+class ErrorCallback: public nvidia::NvErrorCallback
+{
+ public:
+ void reportError(nvidia::NvErrorCode::Enum code, const char* message, const char* file, int line) NV_OVERRIDE
+ {
+ if (code & (nvidia::NvErrorCode::eDEBUG_WARNING | nvidia::NvErrorCode::ePERF_WARNING))
+ {
+ viewer_warn("%s", message);
+ return;
+ }
+ viewer_err("%s", message);
+ if (code != nvidia::NvErrorCode::eNO_ERROR)
+ {
+ viewer_err("%s", message);
+ }
+ }
+};
+
+class AllocatorCallback: public nvidia::NvAllocatorCallback
+{
+ public:
+
+ void* allocate(size_t size, const char* typeName, const char* filename, int line) NV_OVERRIDE
+ {
+ return NvCo::MemoryAllocator::getInstance()->simpleAllocate(size);
+ }
+
+ void deallocate(void* ptr) NV_OVERRIDE
+ {
+ NvCo::MemoryAllocator::getInstance()->simpleDeallocate(ptr);
+ }
+};
+
+} // namespace anonymous
+
+static AllocatorCallback s_allocator;
+static ErrorCallback s_error;
+
+// global singletons (can't create more than one instance)
+struct ProjectParamsContext* g_projectParamsContext = 0;
+
+class CustomLogger : public NvCo::Logger
+{
+public:
+ virtual void log(NvCo::LogSeverity::Enum severity, const char* message, const char* functionName, const char* file, int line) NV_OVERRIDE
+ {
+ using namespace NvCo;
+
+ switch (severity)
+ {
+ default:
+ case LogSeverity::FATAL_ERROR:
+ case LogSeverity::NON_FATAL_ERROR:
+ viewer_err("%s", message);
+ break;
+ case LogSeverity::WARNING:
+ viewer_warn("%s", message);
+ break;
+ case LogSeverity::INFO:
+ viewer_info("%s", message);
+ break;
+ case LogSeverity::DEBUG_INFO:
+ viewer_msg("%s", message);
+ break;
+ }
+ }
+ virtual void flush() NV_OVERRIDE {}
+};
+
+CustomLogger g_logHandler;
+#else
+#include "GPUProfiler.h"
+#include "MeshShaderParam.h"
+#include <Nv\Common\NvCoLogger.h>
+#endif // NV_ARTISTTOOLS
+
+Gamepad& theGamepad = Gamepad::Instance();
+Mouse g_mouse;
+Timer g_fpsTimer;
+Backdoor* g_pBackdoor;
+
+///////////////////////////////////////////////////////////////////////////////
+SimpleScene* SimpleScene::Inst()
+{
+ static SimpleScene scene;
+ return &scene;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+SimpleScene::SimpleScene()
+ :
+ m_pCamera(0),
+ m_pWindCamera(0),
+ m_isProjectModified(false),
+ m_isFurModified(false),
+ m_isSceneLoading(false)
+{
+#ifndef NV_ARTISTTOOLS
+ m_pFurCharacter = new FurCharacter;
+#endif // NV_ARTISTTOOLS
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleScene::Initialize( HWND hWnd, int backdoor)
+{
+ g_fpsTimer.Start();
+
+ if(!InitCameraMouse(hWnd))
+ return false;
+
+// if (!SimpleRenderable::Initialize())
+// return false;
+
+ Light::Initialize();
+
+ //nvidia::shdfnd::initializeSharedFoundation(NV_FOUNDATION_VERSION, s_allocator, s_error);
+
+ FoundationHolder::GetFoundation();
+
+ GPUProfiler_Initialize();
+
+
+ if (backdoor == 1) // master mode
+ g_pBackdoor = createBackdoor("BACKDOOR_SERVER","BACKDOOR_CLIENT");
+
+ SetFurModified(false);
+ SetProjectModified(false);
+
+#ifndef NV_ARTISTTOOLS
+ if (!InitializeBlastSDK(&g_logHandler, backdoor))
+ return false;
+
+ g_projectParamsContext = CreateProjectParamsContext();
+ if (!g_projectParamsContext) return false;
+
+ {
+ NvHair::Sdk* hairSdk = GetHairSDK();
+ if (hairSdk)
+ {
+ const NvHair::BuildInfo& buildInfo = GetHairSDK()->getBuildInfo();
+
+ viewer_info(GetHairSDK()->getBuildInfo().m_buildString);
+
+ char releaseVersion[100] = "Blast Release:";
+ buildInfo.m_versionToStringFunc(buildInfo.m_releaseVersion, releaseVersion + strlen(releaseVersion));
+
+ viewer_info(releaseVersion);
+ }
+ }
+#else
+ CoreLib::Inst()->SimpleScene_Initialize(backdoor);
+#endif // NV_ARTISTTOOLS
+
+ AppMainWindow::Inst().updateUI();
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleScene::Shutdown()
+{
+#ifndef SAFE_DELETE
+#define SAFE_DELETE(x) {if(x!=NV_NULL){delete x;x=NV_NULL;}}
+#endif
+
+ SAFE_DELETE(m_pCamera);
+ SAFE_DELETE(m_pWindCamera);
+
+ GPUProfiler_Shutdown();
+
+ SimpleRenderable::Shutdown();
+ Light::Shutdown();
+
+ if (g_pBackdoor)
+ {
+ g_pBackdoor->release();
+ g_pBackdoor = nullptr;
+ }
+
+#ifndef NV_ARTISTTOOLS
+ GetFurCharacter().Clear();
+
+ ShutdownBlastSDK();
+
+ if (g_projectParamsContext)
+ {
+ ReleaseProjectParamsContext(g_projectParamsContext);
+ g_projectParamsContext = nullptr;
+ }
+#else
+ CoreLib::Inst()->SimpleScene_Shutdown();
+#endif // NV_ARTISTTOOLS
+
+ RenderInterface::Shutdown();
+
+ nvidia::shdfnd::terminateSharedFoundation();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleScene::Clear()
+{
+ GlobalSettings::Inst().m_sceneLoaded = false;
+ GlobalSettings::Inst().m_firstFrame = true;
+
+#ifndef NV_ARTISTTOOLS
+ GetFurCharacter().Clear();
+#else
+ CoreLib::Inst()->SimpleScene_Clear();
+#endif // NV_ARTISTTOOLS
+
+ m_cameraBookmarks.clear();
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleScene::InitCameraMouse(HWND hAppWnd)
+{
+ // default camera pose settings
+ m_pCamera = new Camera(GlobalSettings::Inst().m_zup, false);
+ m_pCamera->SetDefaults();
+
+ // init wind camera
+ {
+ m_pWindCamera = new Camera(false);
+ m_pWindCamera->SetDefaults();
+
+ GlobalSettings::Inst().m_windDir = m_pWindCamera->GetZAxis();
+ }
+
+ // init mouse
+ g_mouse.Initialize(::GetModuleHandle(NV_NULL), (HWND)hAppWnd/*_hWidget*/);
+
+ theGamepad.Initialize();
+ return true;
+}
+
+float SimpleScene::NextTimeStep()
+{
+ static LONGLONG g_lastRenderTicks = 0;
+
+ // Work out the timestep
+ LONGLONG ticks = g_fpsTimer.GetTicksElapsed();
+ LONGLONG deltaTicks = ticks - g_lastRenderTicks;
+ g_lastRenderTicks = ticks;
+
+ float timeStep = deltaTicks / float(g_fpsTimer.GetTicksPerSecond());
+
+ const float maxTimeStep = 0.1f;
+
+ timeStep = (timeStep < 0.0f) ? 0.0f : timeStep;
+ timeStep = (timeStep > maxTimeStep) ? maxTimeStep : timeStep;
+
+ return timeStep;
+}
+
+Timer& SimpleScene::GetTimer()
+{
+ return g_fpsTimer;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleScene::Draw()
+{
+ CoreLib* pCore = CoreLib::Inst();
+ pCore->D3DWidget_paintEvent(NULL);
+#ifndef NV_ARTISTTOOLS
+#else
+ //pCore->SimpleScene_Draw_DX12();
+
+ //RenderInterface::SwitchToDX11();
+
+ //pCore->SimpleScene_Draw_DX11();
+
+ //RenderInterface::FlushDX11();
+#endif
+ // present current window
+ //RenderInterface::PresentRenderWindow();
+ return;
+
+ if (IsSceneLoading())
+ return;
+
+ GlobalSettings& globalSettings = GlobalSettings::Inst();
+
+ // draw background
+ RenderInterface::ClearRenderWindow(0.35f, 0.35f, 0.35f);
+ RenderInterface::RenderBackgroundTexture();
+
+ globalSettings.setTimeStep(NextTimeStep());
+ //globalSettings.setTimeStep(1.0f/60.0f);
+
+ // increment frame timer
+ if (globalSettings.m_animate)
+ {
+ globalSettings.stepAnimation();
+ }
+
+ if (globalSettings.m_playStopped)
+ AppMainWindow::Inst().updateMainToolbar();
+
+ // update camera
+ UpdateCamera();
+
+ // draw lights
+ Light::DrawLights(m_pCamera);
+
+ // show ground grid
+ if (globalSettings.m_showGrid)
+ DrawGround();
+
+ // draw wind icon
+ if (globalSettings.m_visualizeWind)
+ DrawWind();
+
+ // draw axis lines
+ if (globalSettings.m_showAxis)
+ DrawAxis();
+
+ // handle game pad
+ theGamepad.Process();
+
+ // visualize shadow map
+ if (GlobalSettings::Inst().m_visualizeShadowMap)
+ Light::RenderShadowMap();
+
+#ifndef NV_ARTISTTOOLS
+ // init profiler stats
+ FurRenderer::ResetFrameTimer();
+ // the main loop to simulate and render hairs and meshes
+ FurRenderer::UpdateFrame();
+ FurRenderer::Render(m_pCamera);
+
+ RenderInterface::SwitchToDX11();
+ // draw bone name for first hair (hacky, needs to go into SDK)
+ HairInstance* pInstance = GetFurCharacter().GetFirstSelectedHairInstance();
+ if (pInstance && globalSettings.m_visualizeBoneNames)
+ pInstance->DrawBoneNames(m_pCamera);
+
+ // draw HUD.
+ FurRenderer::DrawHUD();
+ RenderInterface::FlushDX11();
+#else
+ CoreLib::Inst()->SimpleScene_Draw_DX12();
+
+ RenderInterface::SwitchToDX11();
+
+ CoreLib::Inst()->SimpleScene_Draw_DX11();
+
+ RenderInterface::FlushDX11();
+
+#endif // NV_ARTISTTOOLS
+
+ // present current window
+ RenderInterface::PresentRenderWindow();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleScene::Timeout()
+{
+ if (m_pCamera == nullptr)
+ {
+ // this could be called when quiting. have to check nullptr
+ return;
+ }
+
+ g_mouse.Update();
+
+ if (IsAutomateMode())
+ {
+ AutomateRun();
+ }
+
+ Draw();
+
+ if (g_pBackdoor)
+ {
+ int argc;
+ const char **argv = g_pBackdoor->getInput(argc);
+ if (argc > 0)
+ {
+ char message[1024];
+ strcpy(message,"");
+ for (int i = 0; i < argc; i++)
+ {
+ strcat(message, argv[i]);
+ strcat(message," ");
+ }
+
+ viewer_info("Message received: %s", message);
+ }
+ }
+
+}
+
+#include <Shlwapi.h>
+#include <FbxUtil.h>
+
+///////////////////////////////////////////////////////////////////////////////
+bool
+SimpleScene::LoadSceneFromFbx(const char* dir, const char* fbxName)
+{
+ return CoreLib::Inst()->SimpleScene_LoadSceneFromFbx(dir, fbxName);
+
+ /*
+ GlobalSettings& globalSettings = GlobalSettings::Inst();
+
+ char fbxFilePath[MAX_PATH];
+
+ float sceneUnit = globalSettings.getSceneUnitInCentimeters();
+
+ PathCombineA(fbxFilePath, dir, fbxName);
+
+ AppMainWindow::Inst().setProgress("Initializing FBX loader", 0);
+ FbxUtil::Initialize(fbxFilePath, sceneUnit);
+
+ char rootBoneName[MAX_PATH];
+ int upAxis = 0;
+
+ FbxUtil::GetGlobalSettings(
+ &globalSettings.m_frameStartTime,
+ &globalSettings.m_frameEndTime,
+ &globalSettings.m_animationFps,
+ &upAxis, rootBoneName);
+
+ if (upAxis == 1)
+ SimpleScene::Inst()->ResetUpDir(false);
+ else if (upAxis = 2)
+ SimpleScene::Inst()->ResetUpDir(true);
+
+#ifndef NV_ARTISTTOOLS
+ SimpleScene::Inst()->GetFurCharacter().LoadMeshFromFbx(dir, fbxName);
+#else
+ CoreLib::Inst()->SimpleScene_LoadSceneFromFbx(dir, fbxName);
+#endif // NV_ARTISTTOOLS
+
+ FbxUtil::Release();
+
+ globalSettings.m_sceneLoaded = true;
+ globalSettings.m_animationIndex = 1;
+ globalSettings.m_firstFrame = true;
+
+ //globalSettings.m_currentBoneIndex = findBoneByName(rootBoneName);
+ globalSettings.resetAnimation();
+
+ return true;
+ */
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleScene::LoadProject(const char* dir, const char* file)
+{
+ GlobalSettings& globalSettings = GlobalSettings::Inst();
+
+ globalSettings.m_projectFileDir = dir;
+ globalSettings.m_projectFileName = file;
+
+#ifndef NV_ARTISTTOOLS
+ nvidia::parameterized::HairProjectParametersNS::ParametersStruct params;
+ if (!ProjectParamsLoad(g_projectParamsContext, globalSettings.getAbsoluteFilePath().c_str(), this))
+ return false;
+#else
+ CoreLib::Inst()->SimpleScene_LoadProject(dir, file);
+#endif // NV_ARTISTTOOLS
+
+ SetProjectModified(false);
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleScene::LoadParameters(NvParameterized::Interface* iface)
+{
+ m_isSceneLoading = true;
+
+ AppMainWindow::Inst().startProgress();
+
+#ifndef NV_ARTISTTOOLS
+ nvidia::parameterized::HairProjectParameters* params = static_cast<nvidia::parameterized::HairProjectParameters*>(iface);
+
+ nvidia::parameterized::HairProjectParametersNS::ParametersStruct& srcDesc = params->parameters();
+
+ if (m_pCamera)
+ {
+ m_pCamera->LoadParameters(&srcDesc.camera);
+ }
+
+ LoadCameraBookmarks(iface);
+
+ if (m_pWindCamera)
+ {
+ m_pWindCamera->LoadParameters(&srcDesc.windCamera);
+ }
+
+ GlobalSettings& globalSettings = GlobalSettings::Inst();
+
+ // Load scene settings
+ globalSettings.m_repeatAnimation = srcDesc.scene.repeatAnimation;
+ globalSettings.m_animationSpeed = srcDesc.scene.animationSpeed;
+ globalSettings.m_showGrid = srcDesc.scene.showGrid;
+ globalSettings.m_showAxis = srcDesc.scene.showAxis;
+ globalSettings.m_zup = srcDesc.scene.upAxis == 1;
+ globalSettings.m_sceneUnitIndex = srcDesc.scene.sceneUnitIndex;
+
+ // Load renderer settings
+ NvParameterized::Handle handle(iface);
+
+ // Load fbx paths
+ if (iface->getParameterHandle("fbxFilePaths", handle) == NvParameterized::ERROR_NONE)
+ {
+ int arraySize;
+ handle.getArraySize(arraySize);
+ char** strArray = new char*[arraySize];
+ handle.getParamStringArray(strArray, arraySize);
+ for (int idx = 0; idx < arraySize; ++idx)
+ {
+ LoadSceneFromFbx(
+ globalSettings.m_projectFileDir.c_str(),
+ strArray[idx]);
+ }
+ delete [] strArray;
+ }
+
+ // get general fur renderer settings
+ if (iface->getParameterHandle("renderer", handle) == NvParameterized::ERROR_NONE)
+ FurRenderer::LoadParameters(handle);
+
+ // get fur character mesh setting
+ if (false == GetFurCharacter().LoadMeshParameters(handle))
+ return false;
+
+ // Load apx paths (hair instances)
+ if (iface->getParameterHandle("apxFilePaths", handle) == NvParameterized::ERROR_NONE)
+ {
+ if (false == GetFurCharacter().LoadHairParameters(handle))
+ return false;
+ }
+#else
+ CoreLib::Inst()->SimpleScene_LoadParameters(iface);
+#endif // NV_ARTISTTOOLS
+
+ m_isSceneLoading = false;
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleScene::SaveProject(const char* dir, const char* file)
+{
+ GlobalSettings& globalSettings = GlobalSettings::Inst();
+
+ globalSettings.m_projectFileDir = dir;
+ globalSettings.m_projectFileName = file;
+
+ std::string saveFilePath = globalSettings.getAbsoluteFilePath();
+
+ std::string tempFilePath = utils::GetTempFilePath();
+
+#ifndef NV_ARTISTTOOLS
+ if (ProjectParamsSave(g_projectParamsContext, tempFilePath.c_str(), this))
+ {
+ if (!utils::RenameFile(tempFilePath.c_str(), saveFilePath.c_str(), true /* overwrite */))
+ {
+ return false;
+ }
+ SetProjectModified(false);
+ return true;
+ }
+#else
+ return CoreLib::Inst()->SimpleScene_SaveProject(dir, file);
+#endif // NV_ARTISTTOOLS
+
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleScene::LoadBackgroundTextureFile()
+{
+ QString texName = AppMainWindow::Inst().OpenTextureFile();
+
+ return RenderInterface::LoadBackgroundTexture(texName.toLocal8Bit());
+}
+
+//////////////////////////////////////////////////////////////////////////
+void SimpleScene::ClearBackgroundTexture()
+{
+ RenderInterface::ClearBackgroundTexture();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// slots and handlers / mouse / camera
+
+void SimpleScene::Resize( int w, int h )
+{
+ RenderInterface::ResizeRenderWindow(w,h);
+
+ m_pCamera->SetSize(w,h);
+
+ UpdateCamera();
+
+ SetProjectModified(true);
+}
+
+void SimpleScene::onMouseDown(atcore_float2 position)
+{
+ g_mouse.SetPosition(position);
+}
+
+void SimpleScene::onMouseUp(atcore_float2 position)
+{
+}
+
+void SimpleScene::onMouseMove(atcore_float2 position)
+{
+ g_mouse.SetDelta(position);
+}
+
+void SimpleScene::onMouseWheel(float deltaWheel)
+{
+ g_mouse.SetDeltaWheel(deltaWheel);
+}
+
+QString SimpleScene::createBookmark()
+{
+ QString bookmark = _generateBookmarkName();
+ m_cameraBookmarks.append(CameraBookmark(bookmark, *m_pCamera));
+ return bookmark;
+}
+
+void SimpleScene::removeBookmark(const QString& name)
+{
+ int bookmarksCount = m_cameraBookmarks.size();
+ for (int i = 0; i < bookmarksCount; ++i)
+ {
+ const CameraBookmark& bookmark = m_cameraBookmarks[i];
+ if (bookmark.name == name)
+ {
+ m_cameraBookmarks.removeAt(i);
+ break;
+ }
+ }
+}
+
+void SimpleScene::activateBookmark(const QString& name)
+{
+ int bookmarksCount = m_cameraBookmarks.size();
+ for (int i = 0; i < bookmarksCount; ++i)
+ {
+ const CameraBookmark& bookmark = m_cameraBookmarks[i];
+ if (bookmark.name == name)
+ {
+ *m_pCamera = bookmark.camera;
+ break;
+ }
+ }
+}
+
+void SimpleScene::renameBookmark(const QString& oldName, const QString& newName)
+{
+ int bookmarksCount = m_cameraBookmarks.size();
+ for (int i = 0; i < bookmarksCount; ++i)
+ {
+ CameraBookmark& bookmark = m_cameraBookmarks[i];
+ if (bookmark.name == oldName)
+ {
+ bookmark.name = newName;
+ break;
+ }
+ }
+}
+
+QList<QString> SimpleScene::getBookmarkNames()
+{
+ QList<QString> names;
+ int bookmarksCount = m_cameraBookmarks.size();
+ for (int i = 0; i < bookmarksCount; ++i)
+ {
+ const CameraBookmark& bookmark = m_cameraBookmarks[i];
+ names.append(bookmark.name);
+ }
+
+ return names;
+}
+
+void SimpleScene::Drag( char type )
+{
+ g_mouse.Update();
+
+ switch(type)
+ {
+ case 'R': RotateCamera(); break;
+ case 'Z': ZoomCamera(); break;
+ case 'P': PanCamera(); break;
+ case 'L': RotateLightDirection(); break;
+ case 'W': RotateWindDirection(); break;
+
+ case 'K': PanLight(); break;
+ }
+ SetProjectModified(true);
+}
+
+void SimpleScene::WheelZoom()
+{
+ WheelZoomCamera();
+ SetProjectModified(true);
+}
+
+void SimpleScene::PanCamera()
+{
+ if (g_mouse.GetDelta().x != 0.0f || g_mouse.GetDelta().y != 0.0f)
+ {
+ int w = m_pCamera->GetWidth();
+ int h = m_pCamera->GetHeight();
+
+ atcore_float2 delta = g_mouse.GetDelta() * 2.0f;
+ delta.x /= (float)(w);
+ delta.y /= (float)(h);
+ m_pCamera->Pan(delta);
+ }
+ SetProjectModified(true);
+}
+
+void SimpleScene::ZoomCamera()
+{
+ float dz = (- g_mouse.GetDelta().y);
+
+ if (dz != 0.0f)
+ {
+ dz *= 5.0f / m_pCamera->GetHeight();
+
+ m_pCamera->Dolly(dz);
+ }
+ SetProjectModified(true);
+}
+
+void SimpleScene::WheelZoomCamera()
+{
+ float dz = - g_mouse.GetDeltaWheel() ;
+
+ if (dz != 0.0f)
+ {
+ dz /= 5.0f;
+
+ m_pCamera->Dolly(dz);
+ }
+ SetProjectModified(true);
+}
+
+void SimpleScene::RotateCamera()
+{
+ if (g_mouse.GetDelta().x != 0.0f || g_mouse.GetDelta().y != 0.0f)
+ {
+ m_pCamera->Orbit(g_mouse.GetDelta() * 0.125f);
+ }
+ SetProjectModified(true);
+}
+
+void SimpleScene::RotateLightDirection()
+{
+ if (g_mouse.GetDelta().x != 0.0f || g_mouse.GetDelta().y != 0.0f)
+ {
+ atcore_float2 delta = g_mouse.GetDelta() * 0.5f;
+ delta.y *= -1.0f;
+
+ if (Light::GetLinkLightOption())
+ {
+ Light* pKeyLight = Light::GetLight(Light::KEY_LIGHT);
+ Light* pFillLight = Light::GetLight(Light::FILL_LIGHT);
+ Light* pRimLight = Light::GetLight(Light::RIM_LIGHT);
+ if (pKeyLight->m_selected)
+ {
+ pKeyLight->Orbit(delta);
+ pFillLight->Orbit(delta);
+ pRimLight->Orbit(delta);
+ }
+ else
+ {
+ if (pFillLight->m_selected)
+ {
+ pFillLight->Orbit(delta);
+ }
+
+ if (pRimLight->m_selected)
+ {
+ pRimLight->Orbit(delta);
+ }
+ }
+
+ Light* pEnvLight = Light::GetLight(Light::ENV_LIGHT);
+ if (pEnvLight->m_selected)
+ {
+ pEnvLight->Orbit(delta);
+ }
+ }
+ else
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ Light* pLight = Light::GetLight(i);
+ if (!pLight)
+ continue;
+
+ if (pLight->m_selected)
+ {
+ pLight->Orbit(delta);
+ }
+ }
+ }
+ }
+ SetProjectModified(true);
+}
+
+void SimpleScene::PanLight()
+{
+ if (g_mouse.GetDelta().x != 0.0f || g_mouse.GetDelta().y != 0.0f)
+ {
+ int w = m_pCamera->GetWidth();
+ int h = m_pCamera->GetHeight();
+
+ atcore_float2 delta = g_mouse.GetDelta() * 2.0f;
+ delta.x /= (float)(w);
+ delta.y /= (float)(h);
+
+ for (int i = 0; i < 4; i++)
+ {
+ Light* pLight = Light::GetLight(i);
+ if (!pLight)
+ continue;
+
+ if (pLight->m_selected)
+ pLight->Pan(delta, m_pCamera->GetXAxis(), m_pCamera->GetYAxis());
+ }
+ }
+ SetProjectModified(true);
+}
+
+void SimpleScene::RotateWindDirection()
+{
+ if (g_mouse.GetDelta().x != 0.0f || g_mouse.GetDelta().y != 0.0f)
+ {
+ m_pWindCamera->Orbit(g_mouse.GetDelta() * 0.5f);
+
+ GlobalSettings::Inst().m_windDir = m_pWindCamera->GetZAxis();
+ }
+
+ SetProjectModified(true);
+}
+
+QString SimpleScene::_generateBookmarkName()
+{
+ QString name;
+ for (int i = 1; ; i++)
+ {
+ name = QString("View%1").arg(i, 2, 10, QChar('0'));
+ int found = -1;
+ int bookmarksCount = m_cameraBookmarks.size();
+ for (int j = 0; j < bookmarksCount; ++j)
+ {
+ const CameraBookmark& bookmark = m_cameraBookmarks[j];
+ if (bookmark.name == name)
+ {
+ found = j;
+ break;
+ }
+ }
+
+ if (-1 == found)
+ break;
+ }
+ return name;
+}
+
+void SimpleScene::UpdateCamera()
+{
+ if (!m_pCamera)
+ return;
+
+ float sceneUnit = GlobalSettings::Inst().getSceneUnitInCentimeters() ;
+ float fov = (GlobalSettings::Inst().m_fovAngle / 360.0f) * 3.141592653589793;
+
+ m_pCamera->SetFOV(fov);
+
+ int w = m_pCamera->GetWidth();
+ int h = m_pCamera->GetHeight();
+
+ float aspect = ((float)(w) / (float)(h));
+
+ float minZ = 1.0f;
+ float maxZ = 10000.0f; // should calculate dynamically
+
+ if (sceneUnit != 0.0f)
+ {
+ minZ /= sceneUnit;
+ maxZ /= sceneUnit;
+ }
+
+ m_pCamera->SetAspetRatio(aspect);
+ m_pCamera->SetZFar(maxZ);
+ m_pCamera->SetZNear(minZ);
+
+ m_pCamera->Perspective();
+}
+
+void SimpleScene::FitCamera()
+{
+ if (!m_pCamera)
+ return;
+
+ atcore_float3 center, extents;
+
+#ifndef NV_ARTISTTOOLS
+ if (m_pFurCharacter)
+ m_pFurCharacter->ComputeBounds(center, extents, false);
+#else
+ CoreLib::Inst()->SimpleScene_FitCamera(center, extents);
+#endif // NV_ARTISTTOOLS
+
+ m_pCamera->FitBounds(center, extents);
+}
+
+void SimpleScene::ResetUpDir(bool zup)
+{
+ m_pCamera->ResetUpDir(zup);
+ m_pWindCamera->ResetUpDir(zup);
+ Light::ResetUpDir(zup);
+
+ GlobalSettings::Inst().m_zup = zup;
+
+ SetProjectModified(true);
+}
+
+void SimpleScene::ResetLhs(bool lhs)
+{
+ m_pCamera->ResetLhs(lhs);
+ m_pWindCamera->ResetLhs(lhs);
+ Light::ResetLhs(lhs);
+
+ GlobalSettings::Inst().m_lhs = lhs;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleScene::SaveParameters(NvParameterized::Interface* iface)
+{
+#ifndef NV_ARTISTTOOLS
+ nvidia::parameterized::HairProjectParameters* params = static_cast<nvidia::parameterized::HairProjectParameters*>(iface);
+ nvidia::parameterized::HairProjectParametersNS::ParametersStruct& targetDesc = params->parameters();
+
+ if (m_pCamera)
+ m_pCamera->SaveParameters(&targetDesc.camera);
+
+ SaveCameraBookmarks(iface);
+
+ if (m_pWindCamera)
+ m_pWindCamera->SaveParameters(&targetDesc.windCamera);
+
+ // Save scene settings
+ GlobalSettings& globalSettings = GlobalSettings::Inst();
+
+ targetDesc.scene.repeatAnimation = globalSettings.m_repeatAnimation;
+ targetDesc.scene.animationSpeed = globalSettings.m_animationSpeed;
+ targetDesc.scene.showGrid = globalSettings.m_showGrid;
+ targetDesc.scene.showAxis = globalSettings.m_showAxis;
+
+ targetDesc.scene.upAxis = (globalSettings.m_zup) ? 1 : 2;
+ targetDesc.scene.sceneUnitIndex = globalSettings.m_sceneUnitIndex;
+
+ FurCharacter& character = GetFurCharacter();
+ NvParameterized::Handle handle(iface);
+
+ // Save renderer settings
+ if (iface->getParameterHandle("renderer", handle) == NvParameterized::ERROR_NONE)
+ {
+ FurRenderer::SaveParameters(handle);
+ character.SaveMeshParameters(handle);
+ }
+
+ if (iface->getParameterHandle("renderer.textureFilePath", handle) == NvParameterized::ERROR_NONE)
+ {
+ std::string textureFilePath = globalSettings.getRelativePath(globalSettings.m_backgroundTextureFilePath.c_str());
+ handle.setParamString(textureFilePath.c_str());
+ }
+
+ // save hair path
+ if (iface->getParameterHandle("apxFilePaths", handle) == NvParameterized::ERROR_NONE)
+ character.SaveHairParameters(handle);
+#else
+ CoreLib::Inst()->SimpleScene_SaveParameters(iface);
+#endif // NV_ARTISTTOOLS
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleScene::LoadCameraBookmarks(NvParameterized::Interface* iface)
+{
+#ifndef NV_ARTISTTOOLS
+ nvidia::parameterized::HairProjectParameters* params = static_cast<nvidia::parameterized::HairProjectParameters*>(iface);
+ nvidia::parameterized::HairProjectParametersNS::ParametersStruct& srcDesc = params->parameters();
+ nvidia::parameterized::HairProjectParametersNS::CameraBookmark_DynamicArray1D_Type& bookmarks = srcDesc.cameraBookmarks;
+
+ NvParameterized::Handle cameraBookmarksHandle(iface);
+ if (iface->getParameterHandle("cameraBookmarks", cameraBookmarksHandle) != NvParameterized::ERROR_NONE)
+ return false;
+
+ int numCameraBookmarks = 0;
+ cameraBookmarksHandle.getArraySize(numCameraBookmarks);
+ for (int idx = 0; idx < numCameraBookmarks; ++idx)
+ {
+ NvParameterized::Handle cameraBookmarkHandle(cameraBookmarksHandle);
+ if (cameraBookmarksHandle.getChildHandle(idx, cameraBookmarkHandle) == NvParameterized::ERROR_NONE)
+ {
+ CameraBookmark cameraBookmark;
+ cameraBookmark.camera.LoadParameters((void*)&(bookmarks.buf[idx].camera));
+ cameraBookmark.camera.SetSize(m_pCamera->GetWidth(), m_pCamera->GetHeight());
+ cameraBookmark.name = bookmarks.buf[idx].name.buf;
+ m_cameraBookmarks.append(cameraBookmark);
+ }
+ }
+#else
+ CoreLib::Inst()->SimpleScene_LoadCameraBookmarks(iface);
+#endif // NV_ARTISTTOOLS
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool SimpleScene::SaveCameraBookmarks(NvParameterized::Interface* iface)
+{
+#ifndef NV_ARTISTTOOLS
+ nvidia::parameterized::HairProjectParameters* params = static_cast<nvidia::parameterized::HairProjectParameters*>(iface);
+ nvidia::parameterized::HairProjectParametersNS::ParametersStruct& srcDesc = params->parameters();
+ nvidia::parameterized::HairProjectParametersNS::CameraBookmark_DynamicArray1D_Type& bookmarks = srcDesc.cameraBookmarks;
+
+ NvParameterized::Handle cameraBookmarksHandle(iface);
+ if (iface->getParameterHandle("cameraBookmarks", cameraBookmarksHandle) != NvParameterized::ERROR_NONE)
+ return false;
+
+ int numCameraBookmarks = m_cameraBookmarks.size();
+ cameraBookmarksHandle.resizeArray(numCameraBookmarks);
+
+ for (int idx = 0; idx < numCameraBookmarks; ++idx)
+ {
+ NvParameterized::Handle cameraBookmarkHandle(cameraBookmarksHandle);
+ if (cameraBookmarksHandle.getChildHandle(idx, cameraBookmarkHandle) == NvParameterized::ERROR_NONE)
+ {
+ NvParameterized::Handle tempHandle(cameraBookmarkHandle);
+ CameraBookmark& bookmark = m_cameraBookmarks[idx];
+
+ if (ParamGetChild(cameraBookmarkHandle, tempHandle, "name"))
+ {
+ tempHandle.setParamString(bookmark.name.toStdString().c_str());
+ }
+
+ bookmark.camera.SaveParameters((void*)&(bookmarks.buf[idx].camera));
+ }
+ }
+#else
+ CoreLib::Inst()->SimpleScene_SaveCameraBookmarks(iface);
+#endif // NV_ARTISTTOOLS
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleScene::sendParam(const char *str, NvFloat32 v)
+{
+ if (g_pBackdoor)
+ {
+ char message[1024];
+ sprintf(message, "%s %f", str, v);
+// viewer_info(message);
+ g_pBackdoor->send("%s", message);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleScene::sendParam(const char *str, NvUInt32 v)
+{
+ if (g_pBackdoor)
+ {
+ char message[1024];
+ sprintf(message, "%s %d", str, v);
+// viewer_info(message);
+ g_pBackdoor->send("%s", message);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleScene::sendParam(const char *str, atcore_float3 v)
+{
+ if (g_pBackdoor)
+ {
+ char message[1024];
+ sprintf(message, "%s %f %f %f", str, v.x, v.y, v.z);
+// viewer_info(message);
+ g_pBackdoor->send("%s", message);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleScene::sendParam(const char *str, atcore_float4 v)
+{
+ if (g_pBackdoor)
+ {
+ char message[1024];
+ sprintf(message, "%s %f %f %f %f", str, v.x, v.y, v.z, v.w);
+// viewer_info(message);
+ g_pBackdoor->send("%s", message);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleScene::sendParam(const char *str, NvBoolean v)
+{
+ if (g_pBackdoor)
+ {
+ char message[1024];
+ sprintf(message, "%s %d", str, int(v));
+// viewer_info(message);
+ g_pBackdoor->send("%s", message);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleScene::DrawGround()
+{
+ bool zup = GlobalSettings::Inst().m_zup;
+
+ SimpleShaderParam param;
+ {
+ param.useVertexColor = true;
+ gfsdk_makeIdentity(param.world);
+ param.view = m_pCamera->GetViewMatrix();
+ param.projection = m_pCamera->GetProjectionMatrix();
+ }
+ RenderInterface::CopyShaderParam(RenderInterface::SHADER_TYPE_SIMPLE_COLOR,
+ (void*)&param, sizeof(SimpleShaderParam) );
+
+ SimpleRenderable::Draw(
+ zup ? SimpleRenderable::GROUND_ZUP :
+ SimpleRenderable::GROUND_YUP, false);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleScene::DrawWind()
+{
+ // Convert camera axis into world matrix
+ atcore_float4x4 windMat = gfsdk_transpose(m_pWindCamera->GetViewMatrix());
+
+ // Extract rotation axis from the view matrix
+ atcore_float4x4 viewMat = m_pCamera->GetViewMatrix();
+ if (m_pCamera->UseLHS())
+ gfsdk_setPosition(viewMat, gfsdk_makeFloat3(0, 0, 80));
+ else
+ gfsdk_setPosition(viewMat, gfsdk_makeFloat3(0, 0, -80));
+
+ SimpleShaderParam param;
+ {
+ param.useVertexColor = true;
+ param.world = windMat;
+ param.view = viewMat;
+ param.projection = m_pCamera->GetProjectionMatrix();
+ }
+ RenderInterface::CopyShaderParam(RenderInterface::SHADER_TYPE_SIMPLE_COLOR,
+ (void*)&param, sizeof(SimpleShaderParam) );
+
+ int targetWidth = m_pCamera->GetWidth();
+ int targetHeight = m_pCamera->GetHeight();
+ float aspectRatio = (float)targetWidth / (float)targetHeight;
+
+ // Wind view size
+ const int srcHeight = 64;
+ const int srcWidth = aspectRatio*srcHeight;
+ const int originX = 64;
+
+ RenderInterface::Viewport savedVP, vp;
+ RenderInterface::GetViewport(savedVP);
+
+ // set the viewport transform
+ {
+ vp.TopLeftX = originX + ( (srcWidth > srcHeight) ? (srcHeight - srcWidth)/2.0f : 0);
+ vp.TopLeftY = targetHeight-srcHeight;
+ vp.Width = (float)srcWidth;
+ vp.Height = (float)srcHeight;
+ vp.MinDepth = 0.0f;
+ vp.MaxDepth = 1.0f;
+ }
+
+ RenderInterface::SetViewport(vp);
+
+ bool zUP = GlobalSettings::Inst().m_zup;
+ SimpleRenderable::Draw(zUP ?
+ SimpleRenderable::WIND_ZUP :
+ SimpleRenderable::WIND_YUP, false);
+
+ // Restore states
+ RenderInterface::SetViewport(savedVP);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SimpleScene::DrawAxis()
+{
+ // Extract rotation axis from the view matrix
+ atcore_float4x4 viewMat = m_pCamera->GetViewMatrix();
+ if (m_pCamera->UseLHS())
+ gfsdk_setPosition(viewMat, gfsdk_makeFloat3(0, 0, 4));
+ else
+ gfsdk_setPosition(viewMat, gfsdk_makeFloat3(0, 0, -4));
+
+ SimpleShaderParam param;
+ {
+ param.useVertexColor = true;
+ gfsdk_makeIdentity(param.world);
+ param.view = viewMat;
+ param.projection = m_pCamera->GetProjectionMatrix();
+ }
+ RenderInterface::CopyShaderParam(RenderInterface::SHADER_TYPE_SIMPLE_COLOR,
+ (void*)&param, sizeof(SimpleShaderParam) );
+
+ int targetWidth = m_pCamera->GetWidth();
+ int targetHeight = m_pCamera->GetHeight();
+ float aspectRatio = (float)targetWidth / (float)targetHeight;
+
+ // Axis view size
+ const int srcHeight = 64;
+ const int srcWidth = aspectRatio*srcHeight;
+
+ RenderInterface::Viewport savedVP, vp;
+ RenderInterface::GetViewport(savedVP);
+
+ // set the viewport transform
+ {
+ vp.TopLeftX = (srcWidth > srcHeight) ? (srcHeight - srcWidth)/2.0f : 0; // To make it like a square view
+ vp.TopLeftY = targetHeight-srcHeight;
+ vp.Width = (float)srcWidth;
+ vp.Height = (float)srcHeight;
+ vp.MinDepth = 0.0f;
+ vp.MaxDepth = 1.0f;
+ }
+
+ RenderInterface::SetViewport(vp);
+
+ bool zUP = GlobalSettings::Inst().m_zup;
+ SimpleRenderable::Draw(zUP ?
+ SimpleRenderable::AXIS_ZUP :
+ SimpleRenderable::AXIS_YUP, false);
+
+ RenderInterface::SetViewport(savedVP);
+}
diff --git a/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.h b/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.h
new file mode 100644
index 0000000..8d01970
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.h
@@ -0,0 +1,184 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include <Windows.h>
+#include "MathUtil.h"
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include "Camera.h"
+#include "Timer.h"
+class FurCharacter;
+
+class DeviceManager;
+class SampleManager;
+
+namespace NvParameterized
+{
+ class Interface;
+}
+
+struct CameraBookmark
+{
+ CameraBookmark()
+ {
+ }
+ CameraBookmark(const QString& inName, const Camera& inCamera)
+ : name(inName)
+ , camera(inCamera)
+ {
+ }
+ QString name;
+ Camera camera;
+};
+
+//////////////////////////////////////////////////////////////////////////////////////
+// This scene object does the followings
+// - handles the overall project settings load/save
+// - owns and calls FurRenderer's draw functions
+// - owns and handle main camera and mouse callbacks
+// - owns and handles backdoor communication with the SDK and game engines
+//////////////////////////////////////////////////////////////////////////////////////
+class CORELIB_EXPORT SimpleScene
+{
+public:
+ SimpleScene();
+
+ static SimpleScene* Inst();
+
+ // prepare shaders, manage objects
+ bool Initialize(HWND hWnd, int backdoor = 0);
+
+ bool LoadProject(const char* dir, const char* file);
+ bool SaveProject(const char* dir, const char* file);
+ bool LoadParameters(NvParameterized::Interface* iface);
+ bool SaveParameters(NvParameterized::Interface* iface);
+ bool LoadCameraBookmarks(NvParameterized::Interface* iface);
+ bool SaveCameraBookmarks(NvParameterized::Interface* iface);
+ bool Clear();
+
+ bool LoadSceneFromFbx(const char* dir, const char* fbxName);
+
+ bool IsUpdatingUI() { return m_isUpdatingUI; }
+ void setIsUpdatingUI(bool b) { m_isUpdatingUI = b;}
+ bool IsSceneLoading() { return m_isSceneLoading; }
+
+ Camera* GetCamera() { return m_pCamera; }
+ FurCharacter& GetFurCharacter() { return *m_pFurCharacter; }
+ void SetFurCharacter(FurCharacter* pFurCharacter) { m_pFurCharacter = pFurCharacter; }
+
+ DeviceManager& GetDeviceManager() { return *m_pDeviceManager; }
+ void SetDeviceManager(DeviceManager* pDeviceManager) { m_pDeviceManager = pDeviceManager; }
+ SampleManager& GetSampleManager() { return *m_pSampleManager; }
+ void SetSampleManager(SampleManager* pSampleManager) { m_pSampleManager = pSampleManager; }
+
+ void ResetUpDir(bool zup);
+ void ResetLhs(bool lhs);
+
+ bool LoadBackgroundTextureFile();
+ void ClearBackgroundTexture();
+
+ // backdoor
+ void sendParam(const char *str, NvFloat32 v);
+ void sendParam(const char *str, NvUInt32 v);
+ void sendParam(const char *str, atcore_float3 v);
+ void sendParam(const char *str, atcore_float4 v);
+ void sendParam(const char *str, NvBoolean v);
+
+ bool IsFurModified() const { return m_isFurModified; }
+ bool IsProjectModified() const { return m_isProjectModified; }
+ void SetFurModified(bool isModified) { m_isFurModified = isModified; }
+ void SetProjectModified(bool isModified) { m_isProjectModified = isModified; }
+
+ void UpdateCamera();
+ void FitCamera();
+
+ void Draw();
+ void Timeout();
+ void Resize(int w, int h);
+ void Drag(char type);
+ void WheelZoom();
+ void Shutdown();
+
+ void onMouseDown(atcore_float2 position);
+ void onMouseUp(atcore_float2 position);
+ void onMouseMove(atcore_float2 position);
+ void onMouseWheel(float deltaWheel);
+
+ QString createBookmark();
+ void removeBookmark(const QString& name);
+ void activateBookmark(const QString& name);
+ void renameBookmark(const QString& oldName, const QString& newName);
+ QList<QString> getBookmarkNames();
+
+ static float NextTimeStep();
+
+ Timer& GetTimer();
+
+private:
+ // initialize scene components
+ bool InitCameraMouse(HWND hAppWnd);
+ bool InitFurSDK();
+
+ void DrawGround();
+ void DrawAxis();
+ void DrawHUD();
+ void DrawWind();
+
+ // camera / mouse
+ void PanCamera();
+ void ZoomCamera();
+ void WheelZoomCamera();
+ void RotateCamera();
+
+ void RotateLightDirection();
+ void PanLight();
+
+ void RotateWindDirection();
+
+ QString _generateBookmarkName();
+
+public:
+
+ Camera* m_pCamera;
+ Camera* m_pWindCamera;
+
+ QList<CameraBookmark> m_cameraBookmarks;
+
+ FurCharacter* m_pFurCharacter;
+
+ DeviceManager* m_pDeviceManager;
+ SampleManager* m_pSampleManager;
+
+ bool m_isProjectModified;
+ bool m_isFurModified;
+ bool m_isSceneLoading;
+ bool m_isUpdatingUI;
+};
+
diff --git a/tools/ArtistTools/source/CoreLib/Utils/Automate.cpp b/tools/ArtistTools/source/CoreLib/Utils/Automate.cpp
new file mode 100644
index 0000000..6c7d551
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/Automate.cpp
@@ -0,0 +1,530 @@
+#include <windows.h>
+
+#include <QtWidgets/QApplication>
+
+#include "AppMainWindow.h"
+//#include "SimpleScene.h"
+
+#include "OpenAutomate.h"
+#include "Automate.h"
+#include "Settings.h"
+
+//#define OPEN_CONSOLE
+#ifdef OPEN_CONSOLE
+#include <Windows.h>
+#endif
+
+#include <cassert>
+#include <string>
+
+#include <Nv/Common/NvCoCommon.h>
+
+#define KEYSTR ("Software\\OpenAutomate\\RegisteredApps\\NVIDIA\\FurViewer\\v1.0\\")
+
+const oaChar *Benchmarks[] = {
+ "HairBall",
+ "Teapot",
+ "Manjaladon",
+ "WitcherHorse",
+ NV_NULL
+};
+oaInt NumBenchmarks = 1;
+
+static void ParseArgs(int argc, char *argv[]);
+
+static void OAMainLoop(const char *opt);
+static bool RegisterAppItself();
+static int RunApp(QApplication& a);
+static void GetAllOptions(void);
+static void GetCurrentOptions(void);
+
+static bool g_isAutomateMode = false;
+static int InstallModeFlag = 0;
+static char *OAOpt = NV_NULL;
+
+bool AutomateInstallApp()
+{
+ return RegisterAppItself();
+}
+
+static bool RegisterAppItself()
+{
+ char exePath[MAX_PATH];
+ if(!GetExePath(exePath))
+ {
+ fprintf(stderr, "Cannot get exe path\r\n");
+ return false;
+ }
+
+ HKEY hKey;
+ DWORD dwRes = RegOpenKeyExA(
+ HKEY_LOCAL_MACHINE,
+ KEYSTR,
+ 0,
+ KEY_WRITE | KEY_READ,
+ &hKey);
+
+ DWORD dwSize = MAX_PATH;
+ char buf[MAX_PATH];
+ if(dwRes == ERROR_SUCCESS)
+ {
+ dwRes = RegQueryValueExA(
+ hKey,
+ "INSTALL_ROOT_PATH",
+ NV_NULL,
+ NV_NULL,
+ (LPBYTE)buf,
+ &dwSize);
+ if(dwRes == ERROR_SUCCESS && !lstrcmpiA(buf, exePath))
+ {
+ RegCloseKey(hKey);
+ return true;
+ }
+ }
+ else
+ {
+ dwRes = RegCreateKeyExA(
+ HKEY_LOCAL_MACHINE,
+ KEYSTR,
+ 0,
+ NV_NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_WRITE, NV_NULL,
+ &hKey,
+ &dwSize);
+ if(ERROR_SUCCESS != dwRes)
+ {
+ RegCloseKey(hKey);
+ return false;
+ }
+ }
+
+ bool bRet = false;
+ do
+ {
+ dwRes = RegSetValueExA(
+ hKey,
+ "INSTALL_ROOT_PATH",
+ 0,
+ REG_SZ,
+ (BYTE*)exePath,
+ (DWORD)strlen(exePath));
+ if(ERROR_SUCCESS != dwRes)
+ {
+ fprintf(stderr, "Write INSTALL_ROOT_PATH Failed\r\n");
+ break;
+ }
+
+#ifdef _WIN64
+#ifdef _DEBUG
+ strcat(exePath, "FurViewer.win64.D.exe");
+#else
+ strcat(exePath, "FurViewer.win64.exe");
+#endif
+#else
+#ifdef _DEBUG
+ strcat(exePath, "FurViewer.win32.D.exe");
+#else
+ strcat(exePath, "FurViewer.win32.exe");
+#endif
+#endif
+
+ dwRes = RegSetValueExA(
+ hKey,
+ "ENTRY_EXE",
+ 0,
+ REG_SZ,
+ (BYTE*)exePath,
+ (DWORD)strlen(exePath));
+ if(ERROR_SUCCESS != dwRes)
+ {
+ fprintf(stderr, "Write ENTRY_EXE Failed\r\n");
+ break;
+ }
+
+ ZeroMemory(buf, sizeof(buf));
+ SYSTEMTIME tm;
+ GetLocalTime(&tm);
+ sprintf(
+ buf,
+ "%04d-%02d-%02d %02d:%02d:%02d",
+ tm.wYear,
+ tm.wMonth,
+ tm.wDay,
+ tm.wHour,
+ tm.wMinute,
+ tm.wSecond);
+ dwRes = RegSetValueExA(
+ hKey,
+ "INSTALL_DATETIME",
+ 0,
+ REG_SZ,
+ (BYTE*)buf,
+ (DWORD)strlen(buf));
+ if(ERROR_SUCCESS != dwRes)
+ {
+ fprintf(stderr, "Write INSTALL_DATETIME Failed\r\n");
+ break;
+ }
+
+ dwRes = RegSetValueExA(
+ hKey,
+ "REGION",
+ 0,
+ REG_SZ,
+ (BYTE*)"en_US",
+ (DWORD)strlen("en_US"));
+ if(ERROR_SUCCESS != dwRes)
+ {
+ fprintf(stderr, "Write REGION Failed\r\n");
+ break;
+ }
+
+ bRet = true;
+ } while(0);
+
+ RegCloseKey(hKey);
+ return bRet;
+}
+
+static const char *FormatDataType(oaOptionDataType value_type)
+{
+ switch(value_type)
+ {
+ case OA_TYPE_STRING:
+ return "String";
+ case OA_TYPE_INT:
+ return "Int";
+ case OA_TYPE_FLOAT:
+ return "Float";
+ case OA_TYPE_ENUM:
+ return "Enum";
+ case OA_TYPE_BOOL:
+ return "Bool";
+ default:
+ return "Unknown";
+ }
+}
+
+static const char *FormatCompareOp(oaComparisonOpType op_value)
+{
+ switch(op_value)
+ {
+ case OA_COMP_OP_EQUAL:
+ return "Equal";
+ case OA_COMP_OP_NOT_EQUAL:
+ return "NotEqual";
+ case OA_COMP_OP_GREATER:
+ return "Greater";
+ case OA_COMP_OP_LESS:
+ return "Less";
+ case OA_COMP_OP_GREATER_OR_EQUAL:
+ return "GreaterOrEqual";
+ case OA_COMP_OP_LESS_OR_EQUAL:
+ return "LessOrEqual";
+ default:
+ return "Unknown";
+ }
+}
+
+static void ConvertOAValue(oaOptionDataType value_type,
+ const oaValue *value,
+ char *result)
+{
+ switch(value_type)
+ {
+ case OA_TYPE_STRING:
+ case OA_TYPE_ENUM:
+ if (value->String) strcpy(result, value->String);
+ else result[0] = '\0';
+ break;
+ case OA_TYPE_INT:
+ sprintf(result, "%d", value->Int);
+ break;
+ case OA_TYPE_FLOAT:
+ sprintf(result, "%f", value->Float);
+ break;
+ case OA_TYPE_BOOL:
+ sprintf(result, "%1d", value->Bool);
+ break;
+ default:
+ return;
+ }
+}
+
+static void PrintOptions(const oaNamedOption *option)
+{
+ char buf[MAX_PATH];
+ ConvertOAValue(option->DataType, &option->Value, buf);
+
+ fprintf(stderr, "name=%s,type=%s,value=%s\r\n", option->Name, FormatDataType(option->DataType), buf);
+ if(option->MaxValue.Int && option->MinValue.Int)
+ {
+ fprintf(stderr," numsteps=%d", option->NumSteps);
+ ConvertOAValue(option->DataType, &option->MinValue, buf);
+ fprintf(stderr, "minvalue=%s", buf);
+ ConvertOAValue(option->DataType, &option->MaxValue, buf);
+ fprintf(stderr,"maxvalue=%s\r\n", buf);
+ }
+
+ if(option->Dependency.ParentName)
+ {
+ ConvertOAValue(option->Dependency.ComparisonValType, &option->Dependency.ComparisonVal, buf);
+ fprintf(stderr, " parentname=%s,comparisionop=%s,comparisiontype=%s,comparisionvalue=%s\r\n",
+ option->Dependency.ParentName,
+ FormatCompareOp(option->Dependency.ComparisonOp),
+ FormatDataType(option->Dependency.ComparisonValType),
+ buf);
+ }
+}
+
+#if (0) // Remove this!
+int main(int argc, char *argv[])
+{
+ SetConsoleTitleA("OA - simple application");
+ ParseArgs(argc, argv);
+
+ AppSettings::Inst().InitOptions();
+
+ if(InstallModeFlag)
+ {
+ InstallApp();
+ }
+ else if(OAModeFlag)
+ {
+ OAMainLoop(OAOpt);
+ }
+ else
+ {
+ RunApp();
+ }
+
+ return(0);
+}
+#endif
+
+void GetAllOptions(void)
+{
+ fprintf(stderr, "All Options: \r\n");
+ for(oaInt i=0; i < AppSettings::Inst().GetNumOptions(); ++i)
+ {
+ oaNamedOption* option = AppSettings::Inst().GetOption(i);
+ if (!strcmp(option->Name, "User/ProjectPath"))
+ continue;
+ if (!strcmp(option->Name, "User/FurAssetPath"))
+ continue;
+ PrintOptions(AppSettings::Inst().GetOption(i));
+ oaAddOption(AppSettings::Inst().GetOption(i));
+ }
+}
+
+void GetCurrentOptions(void)
+{
+ fprintf(stderr, "Current Options: \r\n");
+
+ std::map<std::string, OptionValue>::const_iterator Iter = AppSettings::Inst().GetCurrentOptionMap()->begin();
+
+ oaNamedOption option;
+ oaInitOption(&option);
+
+ for(; Iter != AppSettings::Inst().GetCurrentOptionMap()->end(); ++Iter)
+ {
+ if (!strcmp(Iter->second.Name, "User/ProjectPath"))
+ continue;
+ if (!strcmp(Iter->second.Name, "User/FurAssetPath"))
+ continue;
+
+ option.Name = Iter->second.Name;
+ option.Value = Iter->second.Value;
+ option.DataType = Iter->second.Type;
+ PrintOptions(&option);
+
+ oaAddOptionValue(Iter->second.Name,
+ Iter->second.Type,
+ &Iter->second.Value);
+ }
+}
+
+void SetOptions(void)
+{
+ oaNamedOption *Option;
+
+ fprintf(stderr, "Set Options: \r\n");
+ while ((Option = oaGetNextOption()) != NV_NULL)
+ {
+ /*
+ * Set option value to persist for subsequent runs of the game
+ * to the given value. Option->Name will be the name of the value,
+ * and Option->Value will contain the appropriate value.
+ */
+ PrintOptions(Option);
+ AppSettings::Inst().SetOptionValue(Option->Name, Option->DataType, &Option->Value);
+ }
+
+ AppSettings::Inst().WriteOptionsFile();
+}
+
+void GetBenchmarks(void)
+{
+ /* foreach known available benchmark call oaAddBenchmark() with a unique string identifying it */
+ for(oaInt i=0; i < NumBenchmarks; ++i)
+ oaAddBenchmark(Benchmarks[i]);
+}
+
+void RunBenchmark(const oaChar *benchmark_name)
+{
+ oaValue Val;
+ int i;
+
+ bool FoundBenchmark = false;
+ for(i=0; i < NumBenchmarks; ++i)
+ if(!strcmp(Benchmarks[i], benchmark_name))
+ {
+ FoundBenchmark = true;
+ break;
+ }
+
+ /* Check if the requested benchark is valid */
+ if(!FoundBenchmark)
+ {
+ char Msg[1024];
+ sprintf(Msg, "'%s' is not a valid benchmark.", benchmark_name);
+ OA_RAISE_ERROR(INVALID_BENCHMARK, benchmark_name);
+ }
+
+ /* Setup everything to run the benchmark */
+
+ /* oaStartBenchmark() must be called right before the first frame */
+ oaStartBenchmark();
+
+ /*
+ * Run the benchmark, and call oaDisplayFrame() right before the final
+ * present call for each frame
+ */
+ //for(i=0; i < 50; ++i)
+ //{
+ // SLEEP(20);
+
+ // oaValue FrameValue;
+ // FrameValue.Int = i;
+ // oaValue OtherInt;
+ // OtherInt.Int = i+1000;
+ // oaChar str[100];
+ // sprintf(str, "frame number: %d\00", i);
+ // oaValue Str;
+ // Str.String = str;
+
+ // oaAddFrameValue("FrameCount", OA_TYPE_INT, &FrameValue);
+ // oaAddFrameValue("OtherInt", OA_TYPE_INT, &OtherInt);
+ // oaAddFrameValue("String", OA_TYPE_STRING, &Str);
+
+ // oaDisplayFrame((oaFloat)(i * 20) / (oaFloat)1000);
+ //}
+ {
+// SimpleScene* scene = SimpleScene::Inst();
+ AppMainWindow::Inst().menu_clearScene();
+ }
+
+ /* Return some result values */
+ Val.Int = 18249;
+ oaAddResultValue("Score", OA_TYPE_INT, &Val);
+
+ Val.Float = 29.14;
+ oaAddResultValue("Some other score", OA_TYPE_FLOAT, &Val);
+
+ /* oaStartBenchmark() must be called right after the last frame */
+ oaEndBenchmark();
+}
+
+int AutomateInit(const char* opt)
+{
+ oaVersion Version;
+ if (!oaInit((const oaString)opt, &Version))
+ {
+ Error("OA did not initialize properly.");
+ return 1;
+ }
+ g_isAutomateMode = true;
+ return 0;
+}
+
+void AutomateRun()
+{
+ oaCommand Command;
+
+ oaInitCommand(&Command);
+ switch(oaGetNextCommand(&Command))
+ {
+ /* No more commands, exit program */
+ case OA_CMD_EXIT:
+ AppMainWindow::Inst().close();
+ return;
+
+ /* Run as normal */
+ case OA_CMD_RUN:
+ break;
+
+ /* Enumerate all in-game options */
+ case OA_CMD_GET_ALL_OPTIONS:
+ GetAllOptions();
+ break;
+
+ /* Return the option values currently set */
+ case OA_CMD_GET_CURRENT_OPTIONS:
+ GetCurrentOptions();
+ break;
+
+ /* Set all in-game options */
+ case OA_CMD_SET_OPTIONS:
+ SetOptions();
+ break;
+
+ /* Enumerate all known benchmarks */
+ case OA_CMD_GET_BENCHMARKS:
+ GetBenchmarks();
+ break;
+
+ /* Run benchmark */
+ case OA_CMD_RUN_BENCHMARK:
+ RunBenchmark(Command.BenchmarkName);
+ break;
+ }
+}
+
+bool IsAutomateMode()
+{
+ return g_isAutomateMode;
+}
+
+bool GetAutomateInstallModeOption(int argc, char* argv[])
+{
+ for (int idx = 1; idx < argc; ++idx)
+ {
+ if (!strcmp(argv[idx], "-install"))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+std::string GetAutomateOption(int argc, char* argv[])
+{
+ for (int idx = 1; idx < argc; ++idx)
+ {
+ if (!strcmp(argv[idx], "-openautomate"))
+ {
+ if ((idx + 1) < argc)
+ {
+ return argv[idx+1];
+ }
+ else
+ {
+ Error("-openautomate option must have an argument.");
+ return "";
+ }
+ }
+ }
+ return "";
+}
diff --git a/tools/ArtistTools/source/CoreLib/Utils/Automate.h b/tools/ArtistTools/source/CoreLib/Utils/Automate.h
new file mode 100644
index 0000000..6f5de4f
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/Automate.h
@@ -0,0 +1,23 @@
+
+// Wrapper functions for OpenAutomate
+
+// Add application info into registry key for Automate
+// Return true if succeeded
+bool AutomateInstallApp();
+
+// Initialize OpenAutomate with its command line option. No need to cleanup
+int AutomateInit(const char* opt);
+
+// Call this function when the application is idle when IsAutomateMode() is true
+void AutomateRun();
+
+// Returns true if automate mode is initialized by AutomateInit() call
+bool IsAutomateMode();
+
+// Utility function to parse the command line option for OpenAutomate
+// Returns OpenAutomate option if it has. If not, returns empty string
+std::string GetAutomateOption(int argc, char* argv[]);
+
+// Returns true if it has "-install" in the command line option
+bool GetAutomateInstallModeOption(int argc, char* argv[]);
+
diff --git a/tools/ArtistTools/source/CoreLib/Utils/CoreLibUtils.h b/tools/ArtistTools/source/CoreLib/Utils/CoreLibUtils.h
new file mode 100644
index 0000000..6decd0c
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/CoreLibUtils.h
@@ -0,0 +1,65 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#pragma once
+
+#include <QtCore/QFile>
+#include <QtCore/QTemporaryFile>
+
+namespace utils {
+
+inline std::string GetTempFilePath()
+{
+ QByteArray tempFilePath;
+ QTemporaryFile tempFile;
+ // temp file will be automatically deleted after this function
+ tempFile.open();
+ tempFilePath = tempFile.fileName().toLocal8Bit();
+ return std::string(tempFilePath);
+}
+
+inline bool RenameFile(const char* srcFilePath, const char* targetFilePath, bool isOvewrite = false)
+{
+ if (QFile::exists(targetFilePath))
+ {
+ if (isOvewrite == false) return false;
+ if (!QFile::remove(targetFilePath)) return false;
+ }
+ return QFile::rename(srcFilePath, targetFilePath);
+}
+
+inline bool CopyFile(const char* srcFilePath, const char* targetFilePath, bool isOverwrite = false)
+{
+ if (QFile::exists(targetFilePath))
+ {
+ if (isOverwrite == false) return false;
+ if (!QFile::remove(targetFilePath)) return false;
+ }
+ return QFile::copy(srcFilePath, targetFilePath);
+}
+
+} // end of utils
diff --git a/tools/ArtistTools/source/CoreLib/Utils/MathUtil.cpp b/tools/ArtistTools/source/CoreLib/Utils/MathUtil.cpp
new file mode 100644
index 0000000..bdb3a77
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/MathUtil.cpp
@@ -0,0 +1,327 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// This file contains wrapper functions to make hair lib easy to setup and use
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#include "MathUtil.h"
+#include <string.h>
+
+////////////////////////////////////////////////////////////////////////////////////////
+void gfsdk_makeIdentity(atcore_float4x4& transform)
+{
+ memset(&transform, 0, sizeof(atcore_float4x4));
+ transform._11 = 1.0f;
+ transform._22 = 1.0f;
+ transform._33 = 1.0f;
+ transform._44 = 1.0f;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+void gfsdk_makeTranslation(atcore_float4x4& m, const atcore_float3& t)
+{
+ gfsdk_makeIdentity(m);
+ m._41 = t.x;
+ m._42 = t.y;
+ m._43 = t.z;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+void gfsdk_makeScale(atcore_float4x4& m, const atcore_float3& s)
+{
+ gfsdk_makeIdentity(m);
+ m._11 = s.x;
+ m._12 = s.y;
+ m._13 = s.z;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void gfsdk_makeRotation(atcore_float4x4& m, const atcore_float4& q)
+{
+ gfsdk_makeIdentity(m);
+
+ const float x = q.x;
+ const float y = q.y;
+ const float z = q.z;
+ const float w = q.w;
+
+ const float x2 = x + x;
+ const float y2 = y + y;
+ const float z2 = z + z;
+
+ const float xx = x2*x;
+ const float yy = y2*y;
+ const float zz = z2*z;
+
+ const float xy = x2*y;
+ const float xz = x2*z;
+ const float xw = x2*w;
+
+ const float yz = y2*z;
+ const float yw = y2*w;
+ const float zw = z2*w;
+
+ m._11 = 1.0f - yy - zz;
+ m._12 = xy + zw;
+ m._13 = xz - yw;
+
+ m._21 = xy - zw;
+ m._22 = 1.0f - xx - zz;
+ m._23 = yz + xw;
+
+ m._31 = xz + yw;
+ m._32 = yz - xw;
+ m._33 = 1.0f - xx - yy;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+atcore_float4x4 gfsdk_makeTransform(const atcore_float4& q, const atcore_float3& t, const atcore_float3 &s)
+{
+ atcore_float4x4 m;
+
+ gfsdk_makeRotation(m, q);
+
+ m._11 *= s.x; m._12 *= s.x; m._13 *= s.x;
+ m._21 *= s.y; m._22 *= s.y; m._23 *= s.y;
+ m._31 *= s.z; m._32 *= s.z; m._33 *= s.z;
+
+ m._41 = t.x;
+ m._42 = t.y;
+ m._43 = t.z;
+
+ return m;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+atcore_float4 gfsdk_getRotation(const atcore_float4x4& sm)
+{
+ atcore_float4x4 m = sm;
+
+ gfsdk_orthonormalize(m);
+
+ atcore_float4 q;
+
+ float x,y,z,w;
+
+ float tr = m._11 + m._22 + m._33, h;
+ if(tr >= 0)
+ {
+ h = sqrt(tr +1);
+ w = float(0.5) * h;
+ h = float(0.5) / h;
+
+ x = (m._23 - m._32) * h;
+ y = (m._31 - m._13) * h;
+ z = (m._12 - m._21) * h;
+ }
+ else
+ {
+ float max = m._11;
+ int i = 0;
+ if (m._22 > m._11)
+ {
+ i = 1;
+ max = m._22;
+ }
+ if (m._33 > max)
+ i = 2;
+ switch (i)
+ {
+ case 0:
+ h = sqrt((m._11 - (m._22 + m._33)) + 1);
+ x = float(0.5) * h;
+ h = float(0.5) / h;
+
+ y = (m._21 + m._12) * h;
+ z = (m._13 + m._31) * h;
+ w = (m._23 - m._32) * h;
+ break;
+ case 1:
+ h = sqrt((m._22 - (m._33 + m._11)) + 1);
+ y = float(0.5) * h;
+ h = float(0.5) / h;
+
+ z = (m._32 + m._23) * h;
+ x = (m._21 + m._12) * h;
+ w = (m._31 - m._13) * h;
+ break;
+ case 2:
+ h = sqrt((m._33 - (m._11 + m._22)) + 1);
+ z = float(0.5) * h;
+ h = float(0.5) / h;
+
+ x = (m._13 + m._31) * h;
+ y = (m._32 + m._23) * h;
+ w = (m._12 - m._21) * h;
+ break;
+ default: // Make compiler happy
+ x = y = z = w = 0;
+ break;
+ }
+ }
+
+ return gfsdk_makeFloat4(x,y,z,w);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+atcore_float4x4 gfsdk_lerp(atcore_float4x4& start, atcore_float4x4& end, float t)
+{
+ atcore_float4 sq = gfsdk_getRotation(start);
+ atcore_float4 eq = gfsdk_getRotation(end);
+ atcore_float3 st = gfsdk_getTranslation(start);
+ atcore_float3 et = gfsdk_getTranslation(end);
+
+ atcore_float3 ss = gfsdk_getScale(start);
+ atcore_float3 es = gfsdk_getScale(end);
+ atcore_float3 s = gfsdk_lerp(ss, es, t);
+
+ atcore_dualquaternion sdq = gfsdk_makeDQ(sq, st);
+ atcore_dualquaternion edq = gfsdk_makeDQ(eq, et);
+
+ atcore_dualquaternion dq = gfsdk_lerp(sdq, edq, t);
+
+ atcore_float4 gr = getRotation(dq);
+ atcore_float3 gt = getTranslation(dq);
+
+ return gfsdk_makeTransform(gr, gt, s);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+atcore_float4x4 operator*(const atcore_float4x4& in1, const atcore_float4x4& in2)
+{
+#define MATRIX_SUM(OUT, IN1, IN2, ROW, COL) OUT._##ROW##COL = IN1._##ROW##1 * IN2._1##COL + IN1._##ROW##2 * IN2._2##COL + IN1._##ROW##3 * IN2._3##COL + IN1._##ROW##4 * IN2._4##COL;
+
+ atcore_float4x4 out;
+
+ MATRIX_SUM(out, in1, in2, 1, 1);
+ MATRIX_SUM(out, in1, in2, 1, 2);
+ MATRIX_SUM(out, in1, in2, 1, 3);
+ MATRIX_SUM(out, in1, in2, 1, 4);
+
+ MATRIX_SUM(out, in1, in2, 2, 1);
+ MATRIX_SUM(out, in1, in2, 2, 2);
+ MATRIX_SUM(out, in1, in2, 2, 3);
+ MATRIX_SUM(out, in1, in2, 2, 4);
+
+ MATRIX_SUM(out, in1, in2, 3, 1);
+ MATRIX_SUM(out, in1, in2, 3, 2);
+ MATRIX_SUM(out, in1, in2, 3, 3);
+ MATRIX_SUM(out, in1, in2, 3, 4);
+
+ MATRIX_SUM(out, in1, in2, 4, 1);
+ MATRIX_SUM(out, in1, in2, 4, 2);
+ MATRIX_SUM(out, in1, in2, 4, 3);
+ MATRIX_SUM(out, in1, in2, 4, 4);
+
+#undef MATRIX_SUM
+
+ return out;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+float
+gfsdk_getDeterminant(const atcore_float4x4& m)
+{
+ const float* matrix = (const float*)&m;
+
+ atcore_float3 p0 = gfsdk_makeFloat3(matrix[0*4+0], matrix[0*4+1], matrix[0*4+2]);
+ atcore_float3 p1 = gfsdk_makeFloat3(matrix[1*4+0], matrix[1*4+1], matrix[1*4+2]);
+ atcore_float3 p2 = gfsdk_makeFloat3(matrix[2*4+0], matrix[2*4+1], matrix[2*4+2]);
+
+ atcore_float3 tempv = gfsdk_cross(p1,p2);
+
+ return gfsdk_dot(p0, tempv);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+atcore_float4x4
+gfsdk_getSubMatrix(int ki,int kj, const atcore_float4x4& m)
+{
+ atcore_float4x4 out;
+ gfsdk_makeIdentity(out);
+
+ float* pDst = (float*)&out;
+ const float* matrix = (const float*)&m;
+
+ int row, col;
+ int dstCol = 0, dstRow = 0;
+
+ for ( col = 0; col < 4; col++ )
+ {
+ if ( col == kj )
+ {
+ continue;
+ }
+ for ( dstRow = 0, row = 0; row < 4; row++ )
+ {
+ if ( row == ki )
+ {
+ continue;
+ }
+ pDst[dstCol*4+dstRow] = matrix[col*4+row];
+ dstRow++;
+ }
+ dstCol++;
+ }
+
+ return out;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+atcore_float4x4 gfsdk_inverse(const atcore_float4x4& m)
+{
+ atcore_float4x4 im;
+
+ float* inverse_matrix = (float*)&im;
+
+ float det = gfsdk_getDeterminant(m);
+ det = 1.0f / det;
+ for (int i = 0; i < 4; i++ )
+ {
+ for (int j = 0; j < 4; j++ )
+ {
+ int sign = 1 - ( ( i + j ) % 2 ) * 2;
+
+ atcore_float4x4 subMat = gfsdk_getSubMatrix(i, j, m);
+ float subDeterminant = gfsdk_getDeterminant(subMat);
+
+ inverse_matrix[i*4+j] = ( subDeterminant * sign ) * det;
+ }
+ }
+
+ return im;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+atcore_dualquaternion gfsdk_makeDQ(const atcore_float4x4& m)
+{
+ atcore_float4 q = gfsdk_getRotation(m);
+ atcore_float3 t = gfsdk_getTranslation(m);
+
+ return gfsdk_makeDQ(q, t);
+}
diff --git a/tools/ArtistTools/source/CoreLib/Utils/MathUtil.h b/tools/ArtistTools/source/CoreLib/Utils/MathUtil.h
new file mode 100644
index 0000000..7b7a2a5
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/MathUtil.h
@@ -0,0 +1,557 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+#pragma once
+
+#include "corelib_global.h"
+#include "CoreLib.h"
+#include "math.h"
+#include "float.h"
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline float gfsdk_lerp(float v1, float v2, float t)
+{
+ return (1.0f - t) * v1 + t * v2;
+}
+
+inline float gfsdk_min(float x, float y) {
+ return (x < y) ? x : y;
+}
+
+inline float gfsdk_max(float x, float y) {
+ return (x > y) ? x : y;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float2 gfsdk_makeFloat2(float x, float y)
+{
+ atcore_float2 v;
+ v.x = x;
+ v.y = y;
+ return v;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float2 operator*(float s, const atcore_float2 &p)
+{
+ return gfsdk_makeFloat2(s * p.x, s * p.y);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float2 operator*(const atcore_float2 &p, float s)
+{
+ return gfsdk_makeFloat2(s * p.x, s * p.y);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 gfsdk_makeFloat3(float x, float y, float z)
+{
+ atcore_float3 v;
+ v.x = x;
+ v.y = y;
+ v.z = z;
+ return v;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 operator+(const atcore_float3 &p0, const atcore_float3 &p1)
+{
+ return gfsdk_makeFloat3(p0.x + p1.x, p0.y + p1.y, p0.z + p1.z);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3& operator+=(atcore_float3 &v, const atcore_float3 & v1)
+{
+ v.x += v1.x; v.y += v1.y; v.z += v1.z;
+ return v;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 operator-(const atcore_float3 &p0, const atcore_float3 &p1)
+{
+ return gfsdk_makeFloat3(p0.x - p1.x, p0.y - p1.y, p0.z - p1.z);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3& operator-=(atcore_float3 &v, const atcore_float3 & v1)
+{
+ v.x -= v1.x; v.y -= v1.y; v.z -= v1.z;
+ return v;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 operator*(float s, const atcore_float3 &p)
+{
+ return gfsdk_makeFloat3(s * p.x, s * p.y, s * p.z);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 operator*(const atcore_float3 &p, float s)
+{
+ return gfsdk_makeFloat3(s * p.x, s * p.y, s * p.z);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline float gfsdk_dot(const atcore_float3& v0, const atcore_float3 &v1) {
+ return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline float gfsdk_lengthSquared(const atcore_float3& v) {
+ return gfsdk_dot(v,v);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline float gfsdk_length(const atcore_float3 &v) {
+ return sqrt(gfsdk_lengthSquared(v));
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline float gfsdk_distance(const atcore_float3 &v1, const atcore_float3 &v2) {
+ return gfsdk_length(v2-v1);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline const atcore_float3& gfsdk_normalize(atcore_float3 &v) {
+ float l = gfsdk_length(v);
+ if (l != 0) { v.x /= l; v.y /= l; v.z /= l; }
+ return v;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 gfsdk_cross(const atcore_float3& v1, const atcore_float3& v2)
+{
+ return gfsdk_makeFloat3(
+ v1.y * v2.z - v1.z * v2.y,
+ v1.z * v2.x - v1.x * v2.z,
+ v1.x * v2.y - v1.y * v2.x);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 gfsdk_lerp(const atcore_float3& v1, const atcore_float3& v2, float t)
+{
+ return gfsdk_makeFloat3(gfsdk_lerp(v1.x, v2.x, t), gfsdk_lerp(v1.y, v2.y, t), gfsdk_lerp(v1.z, v2.z, t));
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 gfsdk_min(const atcore_float3& v1, const atcore_float3 &v2)
+{
+ return gfsdk_makeFloat3(
+ gfsdk_min(v1.x, v2.x),
+ gfsdk_min(v1.y, v2.y),
+ gfsdk_min(v1.z, v2.z)
+ );
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 gfsdk_max(const atcore_float3& v1, const atcore_float3 &v2)
+{
+ return gfsdk_makeFloat3(
+ gfsdk_max(v1.x, v2.x),
+ gfsdk_max(v1.y, v2.y),
+ gfsdk_max(v1.z, v2.z)
+ );
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline float gfsdk_min(const atcore_float3 &v)
+{
+ return gfsdk_min(gfsdk_min(v.x, v.y), v.z);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline float gfsdk_max(const atcore_float3 &v)
+{
+ return gfsdk_max(gfsdk_max(v.x, v.y), v.z);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// float4
+////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float4 gfsdk_makeFloat4(float x = 0.0f, float y = 0.0f, float z = 0.0f, float w = 0.0f)
+{
+ atcore_float4 v;
+ v.x = x;
+ v.y = y;
+ v.z = z;
+ v.w = w;
+ return v;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float4 gfsdk_makeFloat4(const atcore_float3& v, float w)
+{
+ return gfsdk_makeFloat4(v.x, v.y, v.z, w);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float4& operator+=(atcore_float4 &v, const atcore_float4 & v1)
+{
+ v.x += v1.x; v.y += v1.y; v.z += v1.z; v.w += v1.w;
+ return v;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float4 operator*(float s, const atcore_float4 &p)
+{
+ return gfsdk_makeFloat4(s * p.x, s * p.y, s * p.z, s * p.w);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float4 operator*(const atcore_float4 &p, float s)
+{
+ return gfsdk_makeFloat4(s * p.x, s * p.y, s * p.z, s * p.w);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline float gfsdk_dot(const atcore_float4& v0, const atcore_float4 &v1) {
+ return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z + v0.w * v1.w;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline float gfsdk_lengthSquared(const atcore_float4& v) {
+ return gfsdk_dot(v,v);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline float gfsdk_length(const atcore_float4 &v) {
+ return sqrt(gfsdk_lengthSquared(v));
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline const atcore_float4 gfsdk_normalize(const atcore_float4 &v) {
+ atcore_float4 nv = v;
+
+ float l = gfsdk_length(nv);
+ if (l > FLT_EPSILON)
+ {
+ const float s = 1.0f / l;
+
+ nv.x *= s;
+ nv.y *= s;
+ nv.z *= s;
+ nv.w *= s;
+ }
+
+ return nv;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float4 gfsdk_lerp(const atcore_float4& v1, const atcore_float4& v2, float t)
+{
+ return gfsdk_makeFloat4(
+ gfsdk_lerp(v1.x, v2.x, t),
+ gfsdk_lerp(v1.y, v2.y, t),
+ gfsdk_lerp(v1.z, v2.z, t),
+ gfsdk_lerp(v1.w, v2.w, t)
+ );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// quaternion
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+inline atcore_float4 gfsdk_quaternionConjugate(const atcore_float4& in)
+{
+ return gfsdk_makeFloat4(-in.x, -in.y, -in.z, in.w);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_float4 gfsdk_quaternionMultiply(const atcore_float4& q0, const atcore_float4& q1)
+{
+ atcore_float4 q;
+
+ const float tx = q0.w * q1.x + q0.x * q1.w + q0.y * q1.z - q0.z * q1.y;
+ const float ty = q0.w * q1.y + q0.y * q1.w + q0.z * q1.x - q0.x * q1.z;
+ const float tz = q0.w * q1.z + q0.z * q1.w + q0.x * q1.y - q0.y * q1.x;
+
+ q.w = q0.w * q1.w - q0.x * q1.x - q0.y * q1.y - q0.z * q1.z;
+ q.x = tx;
+ q.y = ty;
+ q.z = tz;
+
+ return q;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// 4x4 matrix
+////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////////
+CORELIB_EXPORT void gfsdk_makeIdentity(atcore_float4x4& transform);
+CORELIB_EXPORT void gfsdk_makeTranslation(atcore_float4x4& m, const atcore_float3& t);
+CORELIB_EXPORT void gfsdk_makeScale(atcore_float4x4& m, const atcore_float3& s);
+CORELIB_EXPORT void gfsdk_makeRotation(atcore_float4x4& m, const atcore_float4& q);
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float4x4& operator*=(atcore_float4x4& m, float s)
+{
+ float* data = (float*)&m;
+ for (int i = 0; i < 16; i++)
+ data[i] *= s;
+
+ return m;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline void gfsdk_setPosition(atcore_float4x4&m, const atcore_float3& v)
+{
+ m._41 = v.x;
+ m._42 = v.y;
+ m._43 = v.z;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float4x4 gfsdk_transpose(const atcore_float4x4& m)
+{
+ atcore_float4x4 om;
+
+ om._11 = m._11; om._12 = m._21; om._13 = m._31; om._14 = m._41;
+ om._21 = m._12; om._22 = m._22; om._23 = m._32; om._24 = m._42;
+ om._31 = m._13; om._32 = m._23; om._33 = m._33; om._34 = m._43;
+ om._41 = m._14; om._42 = m._24; om._43 = m._34; om._44 = m._44;
+
+ return om;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+inline atcore_float4x4& operator+=(atcore_float4x4& m1, const atcore_float4x4& m2)
+{
+ float* data1 = (float*)&m1;
+ float* data2 = (float*)&m2;
+
+ for (int i = 0; i < 16; i++)
+ data1[i] += data2[i];
+
+ return m1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_float4 gfsdk_transform(const atcore_float4x4 &m, atcore_float4 op)
+{
+ atcore_float4 p;
+
+ p.x = op.x * m._11 + op.y * m._21 + op.z * m._31 + op.w * m._41;
+ p.y = op.x * m._12 + op.y * m._22 + op.z * m._32 + op.w * m._42;
+ p.z = op.x * m._13 + op.y * m._23 + op.z * m._33 + op.w * m._43;
+ p.w = op.x * m._14 + op.y * m._24 + op.z * m._34 + op.w * m._44;
+
+ return p;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 gfsdk_transformCoord(const atcore_float4x4 &m, atcore_float3 op)
+{
+ atcore_float3 p;
+
+ p.x = op.x * m._11 + op.y * m._21 + op.z * m._31 + m._41;
+ p.y = op.x * m._12 + op.y * m._22 + op.z * m._32 + m._42;
+ p.z = op.x * m._13 + op.y * m._23 + op.z * m._33 + m._43;
+
+ return p;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 gfsdk_transformVector(const atcore_float4x4 &m, atcore_float3 op)
+{
+ atcore_float3 p;
+
+ p.x = op.x * m._11 + op.y * m._21 + op.z * m._31;
+ p.y = op.x * m._12 + op.y * m._22 + op.z * m._32;
+ p.z = op.x * m._13 + op.y * m._23 + op.z * m._33;
+
+ return p;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 gfsdk_getScale(const atcore_float4x4& m)
+{
+ atcore_float3 ax = gfsdk_makeFloat3(m._11, m._12, m._13);
+ atcore_float3 ay = gfsdk_makeFloat3(m._21, m._22, m._23);
+ atcore_float3 az = gfsdk_makeFloat3(m._31, m._32, m._33);
+
+ return gfsdk_makeFloat3(gfsdk_length(ax), gfsdk_length(ay), gfsdk_length(az));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 gfsdk_getTranslation(const atcore_float4x4& m)
+{
+ return gfsdk_makeFloat3(m._41, m._42, m._43);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline void gfsdk_setTranslation(atcore_float4x4& m, const atcore_float3 &v)
+{
+ m._41 = v.x;
+ m._42 = v.y;
+ m._43 = v.z;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline const atcore_float4x4& gfsdk_orthonormalize(atcore_float4x4& m)
+{
+ atcore_float3 ax = gfsdk_makeFloat3(m._11, m._12, m._13);
+ atcore_float3 ay = gfsdk_makeFloat3(m._21, m._22, m._23);
+ atcore_float3 az = gfsdk_makeFloat3(m._31, m._32, m._33);
+
+ gfsdk_normalize(ax);
+ gfsdk_normalize(ay);
+ gfsdk_normalize(az);
+
+ m._11 = ax.x; m._12 = ax.y; m._13 = ax.z;
+ m._21 = ay.x; m._22 = ay.y; m._23 = ay.z;
+ m._31 = az.x; m._32 = az.y; m._33 = az.z;
+
+ return m;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+CORELIB_EXPORT atcore_float4x4 gfsdk_lerp(atcore_float4x4& start, atcore_float4x4& end, float t);
+
+////////////////////////////////////////////////////////////////////////////////
+CORELIB_EXPORT atcore_float4 gfsdk_getRotation(const atcore_float4x4& m);
+
+////////////////////////////////////////////////////////////////////////////////
+CORELIB_EXPORT atcore_float4x4 gfsdk_makeTransform(const atcore_float4& q, const atcore_float3& t, const atcore_float3 &s);
+
+////////////////////////////////////////////////////////////////////////////////
+CORELIB_EXPORT atcore_float4x4 operator*(const atcore_float4x4& in1, const atcore_float4x4& in2);
+
+////////////////////////////////////////////////////////////////////////////////
+CORELIB_EXPORT atcore_float4x4 gfsdk_inverse(const atcore_float4x4& m);
+
+////////////////////////////////////////////////////////////////////////////////
+// dual quaternion
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_dualquaternion gfsdk_makeDQ(const atcore_float4& q, const atcore_float3& t)
+{
+ atcore_dualquaternion dq;
+
+ dq.q0 = gfsdk_normalize(q);
+ dq.q1 = gfsdk_quaternionMultiply(gfsdk_makeFloat4(t, 0), dq.q0) * 0.5f;
+
+ return dq;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+atcore_dualquaternion gfsdk_makeDQ(const atcore_float4x4& m);
+
+////////////////////////////////////////////////////////////////////////////////
+inline const atcore_dualquaternion& gfsdk_normalize(atcore_dualquaternion & dq)
+{
+ float mag = gfsdk_dot( dq.q0, dq.q0);
+ float deLen = 1.0f / sqrt(mag+FLT_EPSILON);
+
+ dq.q0 = dq.q0 * deLen;
+ dq.q1 = dq.q1 * deLen;
+
+ return dq;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_dualquaternion operator*(float s, const atcore_dualquaternion & dq)
+{
+ return atcore_dualquaternion(s * dq.q0, s * dq.q1);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_dualquaternion operator*(const atcore_dualquaternion & dq, float s)
+{
+ return atcore_dualquaternion(s * dq.q0, s * dq.q1);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_dualquaternion& operator+=(atcore_dualquaternion &dq, const atcore_dualquaternion & dq2)
+{
+ // hemispherization
+ float sign = (gfsdk_dot(dq.q0, dq2.q0) < -FLT_EPSILON) ? -1.0f: 1.0f;
+
+ dq.q0 += sign * dq2.q0;
+ dq.q1 += sign * dq2.q1;
+
+ return dq;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_dualquaternion gfsdk_lerp(const atcore_dualquaternion &dq1, const atcore_dualquaternion & dq2, float t)
+{
+ atcore_dualquaternion dq = dq1 * (1.0f - t);
+
+ float sign = (gfsdk_dot(dq1.q0, dq2.q0) < -FLT_EPSILON) ? -1.0f: 1.0f;
+
+ dq += (t * sign) * dq2;
+ gfsdk_normalize(dq);
+
+ return dq;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 gfsdk_transformCoord(const atcore_dualquaternion& dq, const atcore_float3 &vecIn)
+{
+ atcore_float3 d0 = gfsdk_makeFloat3(dq.q0.x, dq.q0.y, dq.q0.z);
+ atcore_float3 de = gfsdk_makeFloat3(dq.q1.x, dq.q1.y, dq.q1.z);
+ float a0 = dq.q0.w;
+ float ae = dq.q1.w;
+
+ atcore_float3 temp = gfsdk_cross( d0, vecIn ) + a0 * vecIn;
+ atcore_float3 temp2 = 2.0f * (a0 * de - ae * d0 + gfsdk_cross(d0, de));
+
+ return vecIn + temp2 + 2.0f * gfsdk_cross( d0, temp);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 gfsdk_transformVector(const atcore_dualquaternion& dq, const atcore_float3 &vecIn)
+{
+ atcore_float3 d0 = gfsdk_makeFloat3(dq.q0.x, dq.q0.y, dq.q0.z);
+ atcore_float3 de = gfsdk_makeFloat3(dq.q1.x, dq.q1.y, dq.q1.z);
+ float a0 = dq.q0.w;
+ float ae = dq.q1.w;
+
+ atcore_float3 temp = gfsdk_cross( d0, vecIn ) + a0 * vecIn;
+ return vecIn + 2.0f * gfsdk_cross( d0, temp);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_float4 getRotation(const atcore_dualquaternion& dq)
+{
+ return dq.q0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+inline atcore_float3 getTranslation(const atcore_dualquaternion& dq)
+{
+ atcore_float4 dual = 2.0f * dq.q1;
+ atcore_float4 t = gfsdk_quaternionMultiply(dual, gfsdk_quaternionConjugate( dq.q0 ));
+
+ return gfsdk_makeFloat3(t.x, t.y, t.z);
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Utils/Profiler.cpp b/tools/ArtistTools/source/CoreLib/Utils/Profiler.cpp
new file mode 100644
index 0000000..aab4de3
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/Profiler.cpp
@@ -0,0 +1,82 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "nvToolsExt.h"
+#include <stdlib.h> // for rand()
+
+void ProfilerRangePush(const char* name) {
+ unsigned int color = 0xFF000000 | ((rand()%256) << 16) | ((rand()%256) << 8) | (rand()%256);
+ // Zero the structure
+ nvtxEventAttributes_t event_attrib = {0};
+ // Set the version and the size information
+ event_attrib.version = NVTX_VERSION;
+ event_attrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
+ // Configure the attributes. 0 is the default for all attributes
+ event_attrib.colorType = NVTX_COLOR_ARGB;
+ event_attrib.color = color;
+ event_attrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
+ event_attrib.message.ascii = name;
+ nvtxRangePushEx(&event_attrib);
+}
+
+void ProfilerRangePush(const char* name, unsigned int color) {
+ // Zero the structure
+ nvtxEventAttributes_t event_attrib = {0};
+ // Set the version and the size information
+ event_attrib.version = NVTX_VERSION;
+ event_attrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
+ // Configure the attributes. 0 is the default for all attributes
+ event_attrib.colorType = NVTX_COLOR_ARGB;
+ event_attrib.color = color;
+ event_attrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
+ event_attrib.message.ascii = name;
+ nvtxRangePushEx(&event_attrib);
+}
+
+void ProfilerRangePop() {
+ nvtxRangePop();
+}
+
+#include "Profiler.h"
+
+ScopedProfiler::ScopedProfiler(const char* name)
+{
+ ProfilerRangePush(name);
+}
+
+ScopedProfiler::ScopedProfiler(const char* name, unsigned int color)
+{
+ ProfilerRangePush(name, color);
+}
+
+ScopedProfiler::~ScopedProfiler()
+{
+ ProfilerRangePop();
+}
diff --git a/tools/ArtistTools/source/CoreLib/Utils/Profiler.h b/tools/ArtistTools/source/CoreLib/Utils/Profiler.h
new file mode 100644
index 0000000..5f00175
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/Profiler.h
@@ -0,0 +1,51 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "corelib_global.h"
+
+// name - the name to be displayed
+void ProfilerRangePush(const char* name);
+
+// name - the name to be displayed
+// color - ARGB color. ex) 0xFFFF0000 = Red, 0xFF0000FF = Blue
+void ProfilerRangePush(const char* name, unsigned int color);
+
+void ProfilerRangePop();
+
+struct CORELIB_EXPORT ScopedProfiler
+{
+ ScopedProfiler(const char* name);
+
+ ScopedProfiler(const char* name, unsigned int color);
+
+ ~ScopedProfiler();
+};
+
+#define FUNCTION_PROFILER() ScopedProfiler _scoped_function_profiler(__FUNCTION__);
diff --git a/tools/ArtistTools/source/CoreLib/Utils/Settings.cpp b/tools/ArtistTools/source/CoreLib/Utils/Settings.cpp
new file mode 100644
index 0000000..5445bef
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/Settings.cpp
@@ -0,0 +1,767 @@
+/*******************************************************************************
+* NVIDIA Corporation
+* Software License Agreement - OpenAutomate SDK
+*
+* IMPORTANT - READ BEFORE COPYING, INSTALLING OR USING
+* Do not use or load the OpenAutomate SDK and any associated materials
+* provided by NVIDIA on NVIDIA�s website (collectively, the "Software")
+* until You have carefully read the following terms and conditions. By
+* loading or using the Software, You agree to fully comply with the terms
+* and conditions of this Software License Agreement ("Agreement") by and
+* between NVIDIA Corporation, a Delaware corporation with its principal
+* place of business at 2701 San Tomas Expressway, Santa Clara, California
+* 95050 U.S.A. ("NVIDIA"), and You. If You do not wish to so agree, do not
+* install or use the Software.
+*
+* For the purposes of this Agreement:
+*
+* "Licensee," "You" and/or "Your" shall mean, collectively and
+* individually, Original Equipment Manufacturers, Independent Hardware
+* Vendors, Independent Software Vendors, and End-Users of the Software
+* pursuant to the terms and conditions of this Agreement.
+*
+* "Derivative Works" shall mean derivatives of the Software created by You
+* or a third party on Your behalf, which term shall include: (a) for
+* copyrightable or copyrighted material, any translation, abridgement,
+* revision or other form in which an existing work may be recast,
+* transformed or adapted; (b) for work protected by topography or mask
+* right, any translation, abridgement, revision or other form in which an
+* existing work may be recast, transformed or adapted; (c) for patentable
+* or patented material, any Improvement; and (d) for material protected by
+* trade secret, any new material derived from or employing such existing
+* trade secret.
+*
+* "Excluded License" is any license that requires as a condition of use,
+* modification and/or distribution of software subject to the Excluded
+* License, that such software or other software distributed and/or
+* combined with such software be (i) disclosed or distributed in source
+* code form, (ii) licensed for the purpose of making derivative works, or
+* (iii) redistributable at no charge.
+*
+* SECTION 1 - GRANT OF LICENSE.
+* NVIDIA agrees to provide the Software and any associated materials
+* pursuant to the terms and conditions of this Agreement. Subject to the
+* terms of this Agreement, NVIDIA grants to You a nonexclusive,
+* transferable, worldwide, revocable, limited, royalty-free, fully paid-up
+* license under NVIDIA�s copyrights to
+*
+* (a) install, deploy, use, have used execute, reproduce, display,
+* perform, run, modify the source code of the Software, or to prepare and
+* have prepared Derivative Works thereof the Software for Your own
+* internal development, testing and maintenance purposes to incorporate
+* the Software or Derivative Works thereof, in part or whole, into Your
+* software applications;
+*
+* (b) to transfer, distribute and sublicense the Software (in its
+* unmodified form as delivered to You by NVIDIA pursuant to this
+* Agreement) in any medium or technology for Your sublicensees to
+* incorporate the Software or Derivative Works thereof, in part or whole,
+* into their respective software applications; and
+*
+* (c) to transfer, distribute and sublicense Derivative Works (in object
+* code only) of the Software (i)_as incorporated in Your application
+* software in any medium or technology; and (ii) certified as OpenAutomate
+* Compatible Software.
+*
+* You may exercise your license rights pursuant to Subsection 1(b) and (c)
+* above pursuant to the terms and conditions of any form of end-user
+* software license agreement of Your choice, including but not limited to
+* an Excluded License.
+*
+* In the event NVIDIA certifies Your application software, incorporating
+* the Derivative Works (in object code only) of the Software, as
+* OpenAutomate compatible ("OpenAutomate Compatible Software"), NVIDIA
+* grants You a nonexclusive, worldwide, revocable, paid-up license to use
+* the name and trademark to "OpenAutomate Compatible" solely for the
+* purposes of identifying and/or marketing Your application software as
+* OpenAutomate Compatible Software; provided that Licensee fully complies
+* with the following:
+*
+* (x) Licensee agrees that it is strictly prohibited from using the name
+* and trademark of "OpenAutomate Compatible" if Your application software
+* is not OpenAutomate Compatible Software;
+*
+* (y) if NVIDIA objects to Your improper use of the "OpenAutomate
+* Compatible" name and trademark, You will take all reasonable steps
+* necessary to resolve NVIDIA�s objections. NVIDIA may reasonably monitor
+* the quality of Your application software bearing the "OpenAutomate
+* Compatible" name or trademark pursuant to this Agreement; and
+*
+* (z) any goodwill attached to NVIDIA�s trademarks, service marks, or
+* trade names belong to NVIDIA and this Agreement does not grant You any
+* right to use them.
+*
+* If You are not the final manufacturer or vendor of a computer system or
+* software program incorporating the Software, or if Your Contractors (as
+* defined below), affiliates or subsidiaries need to exercise any, some or
+* all of the license grant described above herein to the Software on Your
+* behalf, then You may transfer a copy of the Software, (and related
+* end-user documentation) to such recipient for use in accordance with the
+* terms of this Agreement, provided such recipient agrees to be fully
+* bound by the terms hereof. Except as expressly permitted in this
+* Agreement, Unless otherwise authorized in the Agreement, You shall not
+* otherwise assign, sublicense, lease, or in any other way transfer or
+* disclose Software to any third party. Unless otherwise authorized in the
+* Agreement, You shall not reverse- compile, disassemble,
+* reverse-engineer, or in any manner attempt to derive the source code of
+* the Software from the object code portions of the Software.
+*
+* Except as expressly stated in this Agreement, no license or right is
+* granted to You directly or by implication, inducement, estoppel or
+* otherwise. NVIDIA shall have the right to inspect or have an independent
+* auditor inspect Your relevant records to verify Your compliance with the
+* terms and conditions of this Agreement.
+*
+* SECTION 2 - CONFIDENTIALITY.
+* If applicable, any exchange of Confidential Information (as defined in
+* the NDA) shall be made pursuant to the terms and conditions of a
+* separately signed Non-Disclosure Agreement ("NDA") by and between NVIDIA
+* and You. For the sake of clarity, You agree that the Software is
+* Confidential Information of NVIDIA.
+*
+* If You wish to have a third party consultant or subcontractor
+* ("Contractor") perform work on Your behalf which involves access to or
+* use of Software, You shall obtain a written confidentiality agreement
+* from the Contractor which contains terms and obligations with respect to
+* access to or use of Software no less restrictive than those set forth in
+* this Agreement and excluding any distribution or sublicense rights, and
+* use for any other purpose than permitted in this Agreement. Otherwise,
+* You shall not disclose the terms or existence of this Agreement or use
+* NVIDIA's name in any publications, advertisements, or other
+* announcements without NVIDIA's prior written consent. Unless otherwise
+* provided in this Agreement, You do not have any rights to use any NVIDIA
+* trademarks or logos.
+*
+* SECTION 3 - OWNERSHIP OF SOFTWARE AND INTELLECTUAL PROPERTY RIGHTS.
+* All rights, title and interest to all copies of the Software remain with
+* NVIDIA, subsidiaries, licensors, or its suppliers. The Software is
+* copyrighted and protected by the laws of the United States and other
+* countries, and international treaty provisions. You may not remove any
+* copyright notices from the Software. NVIDIA may make changes to the
+* Software, or to items referenced therein, at any time and without
+* notice, but is not obligated to support or update the Software. Except
+* as otherwise expressly provided, NVIDIA grants no express or implied
+* right under any NVIDIA patents, copyrights, trademarks, or other
+* intellectual property rights.
+*
+* All rights, title and interest in the Derivative Works of the Software
+* remain with You subject to the underlying license from NVIDIA to the
+* Software. In Your sole discretion, You may grant NVIDIA, upon NVIDIA�s
+* request for such a license described herein, an irrevocable, perpetual,
+* nonexclusive, worldwide, royalty-free paid-up license to make, have
+* made, use, have used, sell, license, distribute, sublicense or otherwise
+* transfer Derivative Works created by You that add functionality or
+* improvement to the Software.
+*
+* You has no obligation to give NVIDIA any suggestions, comments or other
+* feedback ("Feedback") relating to the Software. However, NVIDIA may use
+* and include any Feedback that You voluntarily provide to improve the
+* Software or other related NVIDIA technologies. Accordingly, if You
+* provide Feedback, You agree NVIDIA and its licensees may freely use,
+* reproduce, license, distribute, and otherwise commercialize the Feedback
+* in the Software or other related technologies without the payment of any
+* royalties or fees.
+*
+* You may transfer the Software only if the recipient agrees to be fully
+* bound by these terms and conditions of this Agreement.
+*
+* SECTION 4 - NO WARRANTIES.
+* THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY
+* OF ANY KIND, INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT,
+* OR FITNESS FOR A PARTICULAR PURPOSE. NVIDIA does not warrant or assume
+* responsibility for the accuracy or completeness of any information,
+* text, graphics, links or other items contained within the Software.
+* NVIDIA does not represent that errors or other defects will be
+* identified or corrected.
+*
+* SECTION 5 - LIMITATION OF LIABILITY.
+* EXCEPT WITH RESPECT TO THE MISUSE OF THE OTHER PARTY�S INTELLECTUAL
+* PROPERTY OR DISCLOSURE OF THE OTHER PARTY�S CONFIDENTIAL INFORMATION IN
+* BREACH OF THIS AGREEMENT, IN NO EVENT SHALL NVIDIA, SUBSIDIARIES,
+* LICENSORS, OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER
+* (INCLUDING, WITHOUT LIMITATION, INDIRECT, LOST PROFITS, CONSEQUENTIAL,
+* BUSINESS INTERRUPTION OR LOST INFORMATION) ARISING OUT OF THE USE OF OR
+* INABILITY TO USE THE SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS PROHIBIT EXCLUSION OR
+* LIMITATION OF LIABILITY FOR IMPLIED WARRANTIES OR CONSEQUENTIAL OR
+* INCIDENTAL DAMAGES, SO THE ABOVE LIMITATION MAY NOT APPLY TO YOU. YOU
+* MAY ALSO HAVE OTHER LEGAL RIGHTS THAT VARY FROM JURISDICTION TO
+* JURISDICTION. NOTWITHSTANDING THE FOREGOING, NVIDIA�S AGGREGATE
+* LIABILITY ARISING OUT OF THIS AGREEMENT SHALL NOT EXCEED ONE HUNDRED
+* UNITED STATES DOLLARS (USD$100).
+*
+* SECTION 6 - TERM.
+* This Agreement and the licenses granted hereunder shall be effective as
+* of the date You download the applicable Software ("Effective Date") and
+* continue for a period of one (1) year ("Initial Term") respectively,
+* unless terminated earlier in accordance with the "Termination" provision
+* of this Agreement. Unless either party notifies the other party of its
+* intent to terminate this Agreement at least three (3) months prior to
+* the end of the Initial Term or the applicable renewal period, this
+* Agreement will be automatically renewed for one (1) year renewal periods
+* thereafter, unless terminated in accordance with the "Termination"
+* provision of this Agreement.
+*
+* SECTION 7 - TERMINATION.
+* NVIDIA may terminate this Agreement at any time if You violate its
+* terms. Upon termination, You will immediately destroy the Software or
+* return all copies of the Software to NVIDIA, and certify to NVIDIA in
+* writing that such actions have been completed. Upon termination or
+* expiration of this Agreement the license grants to Licensee shall
+* terminate, except that sublicenses rightfully granted by Licensee under
+* this Agreement in connection with Section 1(b) and (c) of this Agreement
+* provided by Licensee prior to the termination or expiration of this
+* Agreement shall survive in accordance with their respective form of
+* license terms and conditions.
+*
+* SECTION 8 - MISCELLANEOUS.
+*
+* SECTION 8.1 - SURVIVAL.
+* Those provisions in this Agreement, which by their nature need to
+* survive the termination or expiration of this Agreement, shall survive
+* termination or expiration of the Agreement, including but not limited to
+* Sections 2, 3, 4, 5, 7, and 8.
+*
+* SECTION 8.2 - APPLICABLE LAWS.
+* Claims arising under this Agreement shall be governed by the laws of
+* Delaware, excluding its principles of conflict of laws and the United
+* Nations Convention on Contracts for the Sale of Goods. The state and/or
+* federal courts residing in Santa Clara County, California shall have
+* exclusive jurisdiction over any dispute or claim arising out of this
+* Agreement. You may not export the Software in violation of applicable
+* export laws and regulations.
+*
+* SECTION 8.3 - AMENDMENT.
+* The Agreement shall not be modified except by a written agreement that
+* names this Agreement and any provision to be modified, is dated
+* subsequent to the Effective Date, and is signed by duly authorized
+* representatives of both parties.
+*
+* SECTION 8.4 - NO WAIVER.
+* No failure or delay on the part of either party in the exercise of any
+* right, power or remedy under this Agreement or under law, or to insist
+* upon or enforce performance by the other party of any of the provisions
+* of this Agreement or under law, shall operate as a waiver thereof, nor
+* shall any single or partial exercise of any right, power or remedy
+* preclude other or further exercise thereof, or the exercise of any other
+* right, power or remedy; rather the provision, right, or remedy shall be
+* and remain in full force and effect.
+*
+* SECTION 8.5 - NO ASSIGNMENT.
+* This Agreement and Licensee�s rights and obligations herein, may not be
+* assigned, subcontracted, delegated, or otherwise transferred by Licensee
+* without NVIDIA�s prior written consent, and any attempted assignment,
+* subcontract, delegation, or transfer in violation of the foregoing will
+* be null and void. The terms of this Agreement shall be binding upon
+* Licensee�s assignees.
+*
+* SECTION 8.6 - GOVERNMENT RESTRICTED RIGHTS.
+* The parties acknowledge that the Software is subject to U.S. export
+* control laws and regulations. The parties agree to comply with all
+* applicable international and national laws that apply to the Software,
+* including the U.S. Export Administration Regulations, as well as
+* end-user, end-use and destination restrictions issued by U.S. and other
+* governments.
+*
+* The Software has been developed entirely at private expense and is
+* commercial computer software provided with RESTRICTED RIGHTS. Use,
+* duplication or disclosure of the Software by the U.S. Government or a
+* U.S. Government subcontractor is subject to the restrictions set forth
+* in the Agreement under which the Software was obtained pursuant to DFARS
+* 227.7202-3(a) or as set forth in subparagraphs (c)(1) and (2) of the
+* Commercial Computer Software - Restricted Rights clause at FAR
+* 52.227-19, as applicable. Contractor/manufacturer is NVIDIA, 2701 San
+* Tomas Expressway, Santa Clara, CA 95050. Use of the Software by the
+* Government constitutes acknowledgment of NVIDIA's proprietary rights
+* therein.
+*
+* SECTION 8.7 - INDEPENDENT CONTRACTORS.
+* Licensee�s relationship to NVIDIA is that of an independent contractor,
+* and neither party is an agent or partner of the other. Licensee will
+* not have, and will not represent to any third party that it has, any
+* authority to act on behalf of NVIDIA.
+*
+* SECTION 8.8 - SEVERABILITY.
+* If for any reason a court of competent jurisdiction finds any provision
+* of this Agreement, or portion thereof, to be unenforceable, that
+* provision of the Agreement will be enforced to the maximum extent
+* permissible so as to affect the intent of the parties, and the remainder
+* of this Agreement will continue in full force and effect. This Agreement
+* has been negotiated by the parties and their respective counsel and will
+* be interpreted fairly in accordance with its terms and without any
+* strict construction in favor of or against either party.
+*
+* SECTION 8.9 - ENTIRE AGREEMENT.
+* This Agreement and NDA constitute the entire agreement between the
+* parties with respect to the subject matter contemplated herein, and
+* merges all prior and contemporaneous communications.
+*
+******************************************************************************/
+
+
+#include "settings.h"
+#include "Nv.h"
+
+char OptionsFileName[] = "FurViewerOptions.txt";
+//std::vector<void *> AllocBlocks;
+
+using namespace std;
+
+void Error(const char *fmt, ...);
+static int HexCharToInt(unsigned char c);
+bool GetExePath(char* exe_path);
+static int Hex2BytesToInt(const unsigned char *buf);
+static oaFloat StrToFloat(const char *buf);
+static void WriteFloat(FILE *fp, oaFloat val);
+static void StripNewLine(char *str);
+void *Alloc(size_t n);
+char *StrDup(const char *str);
+
+bool GetExePath(char* exe_path)
+{
+#if WIN32
+ char delim = '\\';
+#else
+ char delim = '/';
+#endif
+
+ DWORD dwRet;
+ dwRet = GetModuleFileNameA(NV_NULL, exe_path, MAX_PATH);
+ if ( dwRet == 0 )
+ {
+ exe_path[0] = '\0';
+ return false;
+ }
+
+ int i;
+ for ( i = dwRet; i > 0; i-- )
+ {
+ if ( exe_path[i-1] == delim )
+ break;
+ }
+ exe_path[i] = '\0';
+
+ return true;
+}
+
+void Error(const char *fmt, ...)
+{
+ va_list AP;
+ va_start(AP, fmt);
+
+ char msg[1024];
+ //fprintf(msg, "ERROR: ");
+ //vfprintf(msg, fmt, AP);
+ //fprintf(msg, "\n");
+ sprintf(msg, fmt, AP);
+ OutputDebugStringA(msg);
+ assert(0);
+// exit(-1);
+}
+
+static int HexCharToInt(unsigned char c)
+{
+ if(c >= '0' && c <= '9')
+ return((int)(c - '0'));
+
+ c = tolower(c);
+ if(c >= 'a' && c <= 'f')
+ return((int)(c - 'a' + 10));
+
+ return(0);
+}
+
+static int Hex2BytesToInt(const unsigned char *buf)
+{
+ return(HexCharToInt(buf[0]) << 4 | HexCharToInt(buf[1]));
+}
+
+static oaFloat StrToFloat(const char *buf)
+{
+ size_t Len = strlen(buf);
+ if(Len != sizeof(oaFloat) * 2)
+ return(0.0);
+
+ oaFloat Ret;
+ unsigned char *Buf = (unsigned char *)&Ret;
+ for(int i=0; i < sizeof(oaFloat); ++i)
+ {
+ Buf[i] = Hex2BytesToInt((const unsigned char *)buf);
+ buf += 2;
+ }
+
+ return(Ret);
+}
+
+static void WriteFloat(FILE *fp, oaFloat val)
+{
+ unsigned char *Buf = (unsigned char *)&val;
+ for(int i=0; i < sizeof(oaFloat); ++i)
+ fprintf(fp, "%02x", Buf[i]);
+}
+
+static void StripNewLine(char *str)
+{
+ size_t StrLen = strlen(str);
+ if(StrLen == 0)
+ return;
+
+ for(size_t i=StrLen-1; i >= 0; --i)
+ if(str[i] == '\n')
+ {
+ str[i] = 0;
+ break;
+ }
+}
+
+void *Alloc(size_t n)
+{
+ void *Ret = malloc(n);
+ assert(n != 0);
+
+ //AllocBlocks.push_back(Ret);
+ return(Ret);
+}
+
+char *StrDup(const char *str)
+{
+ assert(str != NV_NULL);
+ char *Ret = strdup(str);
+
+ //AllocBlocks.push_back(Ret);
+ return(Ret);
+}
+
+AppSettings::AppSettings()
+{
+ int NumOptions = 0;
+}
+
+AppSettings::~AppSettings()
+{
+ Cleanup();
+}
+
+void AppSettings::InitOptions(void)
+{
+ {
+ oaNamedOption *Option;
+
+ // Resolution (enum)
+ Option = &Options[NumOptions++];
+ oaInitOption(Option);
+ Option->Name = "User/Resolution";
+ Option->DataType = OA_TYPE_ENUM;
+ Option->Value.Enum = "640x480";
+
+ Options[NumOptions] = *Option;
+ Option = &Options[NumOptions++];
+ Option->Value.Enum = "1024x768";
+
+ Options[NumOptions] = *Option;
+ Option = &Options[NumOptions++];
+ Option->Value.Enum = "1200x768";
+
+ Options[NumOptions] = *Option;
+ Option = &Options[NumOptions++];
+ Option->Value.Enum = "1600x1200";
+
+ // AA (enum)
+ Option = &Options[NumOptions++];
+ oaInitOption(Option);
+
+ Option->Name = "User/AA";
+ Option->DataType = OA_TYPE_ENUM;
+ Option->Value.Enum = "Off";
+
+ Options[NumOptions] = *Option;
+ Option = &Options[NumOptions++];
+ Option->Value.Enum = "2X";
+
+ Options[NumOptions] = *Option;
+ Option = &Options[NumOptions++];
+ Option->Value.Enum = "4X";
+
+ Options[NumOptions] = *Option;
+ Option = &Options[NumOptions++];
+ Option->Value.Enum = "8X";
+
+ // device id (int)
+ Option = &Options[NumOptions++];
+ oaInitOption(Option);
+ Option->Name = "User/Device";
+ Option->DataType = OA_TYPE_INT;
+
+ Option->Value.Int = -1; // when -1 to choose a good GPU
+
+ //Backdoor (enum)
+ Option = &Options[NumOptions++];
+ oaInitOption(Option);
+ Option->Name = "User/Backdoor";
+ Option->DataType = OA_TYPE_STRING;
+ Option->Value.String = "";
+
+ // HideUI (bool)
+ Option = &Options[NumOptions++];
+ oaInitOption(Option);
+ Option->Name = "User/HideUI";
+ Option->DataType = OA_TYPE_BOOL;
+
+ Option->Value.Bool = OA_FALSE;
+
+ // Perf mode (bool)
+ Option = &Options[NumOptions++];
+ oaInitOption(Option);
+ Option->Name = "User/PerfMode";
+ Option->DataType = OA_TYPE_BOOL;
+
+ Option->Value.Bool = OA_FALSE;
+
+ // Play (bool)
+ Option = &Options[NumOptions++];
+ oaInitOption(Option);
+ Option->Name = "User/Play";
+ Option->DataType = OA_TYPE_BOOL;
+
+ Option->Value.Bool = OA_FALSE;
+
+ // ProjectPath (string)
+ Option = &Options[NumOptions++];
+ oaInitOption(Option);
+ Option->Name = "User/ProjectPath";
+ Option->DataType = OA_TYPE_STRING;
+ Option->Value.String = "";
+
+ // FurAssetPath (string)
+ Option = &Options[NumOptions++];
+ oaInitOption(Option);
+ Option->Name = "User/FurAssetPath";
+ Option->DataType = OA_TYPE_STRING;
+ Option->Value.String = "";
+
+ // FurDemoPlaylist (string)
+ Option = &Options[NumOptions++];
+ oaInitOption(Option);
+ Option->Name = "User/FurDemoPlaylist";
+ Option->DataType = OA_TYPE_STRING;
+ Option->Value.String = "";
+
+ //Option = &Options[NumOptions++];
+ //oaInitOption(Option);
+ //Option->Name = "r2_slight_fade";
+ //Option->DataType = OA_TYPE_FLOAT;
+ //Option->MinValue.Float = 0.0;
+ //Option->MaxValue.Float = 100.0;
+ //Option->NumSteps = 200;
+ }
+
+ //****************************************************************************
+ //*** Init OptionValues
+ //****************************************************************************
+
+ // Initialize default options
+ for(int i=0; i < NumOptions; ++i)
+ {
+ string Name(Options[i].Name);
+ OptionValueMap[Name].Name = Options[i].Name;
+ OptionValueMap[Name].Type = Options[i].DataType;
+ OptionValueMap[Name].Value = Options[i].Value;
+ }
+
+ InitDefaultOptions();
+ ///////////////////////////////////////////////////////
+ // Load any persistent options if they've been previously set
+ ReadOptionsFile();
+}
+
+void AppSettings::InitDefaultOptions(void)
+{
+ oaValue Value;
+
+ Value.Enum = "1200x768";
+ SetOptionValue("User/Resolution", OA_TYPE_ENUM, &Value);
+
+ Value.Enum = "8X";
+ SetOptionValue("User/AA", OA_TYPE_ENUM, &Value);
+}
+
+void AppSettings::SetOptionValue(const char *name,
+ oaOptionDataType type,
+ const oaValue *value)
+{
+ string Name(name);
+ assert(OptionValueMap.find(Name) != OptionValueMap.end());
+ assert(OptionValueMap[Name].Type == type);
+
+ switch(type)
+ {
+ case OA_TYPE_STRING:
+ OptionValueMap[Name].Value.String = StrDup(value->String);
+ break;
+
+ case OA_TYPE_ENUM:
+ OptionValueMap[Name].Value.Enum = StrDup(value->Enum);
+ break;
+
+ default:
+ OptionValueMap[Name].Value = *value;
+ }
+}
+
+void AppSettings::ReadOptionsFile(void)
+{
+ char optionFile[MAX_PATH] = "";
+ if(!GetExePath(optionFile))
+ {
+ fprintf(stderr, "Cannot get exe path\r\n");
+ }
+ strcat(optionFile, OptionsFileName);
+
+
+ FILE *FP = fopen(optionFile, "rb");
+ if(!FP)
+ return;
+
+ fprintf(stderr, "FurViewer: Reading options file \"%s\".\n",
+ optionFile);
+ fflush(stderr);
+
+ char Line[1024] = "";
+ int LineNum = 1;
+ while (fgets(Line, sizeof(Line), FP) != NV_NULL)
+ {
+ StripNewLine(Line);
+ if(Line[0] == 0)
+ continue;
+
+ char *Name = strtok(Line, "\t");
+ char *Value = strtok(NV_NULL, "");
+
+ if(!Name || !Value)
+ {
+ //Error("Invalid format in options file \"%s\" on line %d\n",
+ //OptionsFileName,
+ //LineNum);
+ continue;
+ }
+
+ map<string, OptionValue>::const_iterator OptVal =
+ OptionValueMap.find(string(Name));
+
+ if(OptVal == OptionValueMap.end())
+ Error("Unknown option \"%s\" defined in options file \"%s\" on line %d.",
+ Name,
+ OptionsFileName,
+ LineNum);
+
+ SetOptionValue(Name, OptVal->second.Type, Value);
+
+ LineNum++;
+ }
+
+ fclose(FP);
+}
+
+void AppSettings::Cleanup(void)
+{
+ //vector<void *>::iterator Iter = AllocBlocks.begin();
+ //for(; Iter != AllocBlocks.end(); Iter++)
+ // free(*Iter);
+
+ //AllocBlocks.clear();
+}
+
+
+void AppSettings::WriteOptionsFile(FILE *fp)
+{
+ map<string, OptionValue>::const_iterator Iter = OptionValueMap.begin();
+ for(; Iter != OptionValueMap.end(); ++Iter)
+ {
+ fprintf(fp, "%s\t", Iter->second.Name);
+ switch(Iter->second.Type)
+ {
+ case OA_TYPE_INT:
+ fprintf(fp, "%d", Iter->second.Value.Int);
+ break;
+
+ case OA_TYPE_BOOL:
+ fprintf(fp, "%d", (int)Iter->second.Value.Bool);
+ break;
+
+ case OA_TYPE_FLOAT:
+ WriteFloat(fp, Iter->second.Value.Float);
+ break;
+
+ case OA_TYPE_STRING:
+ fprintf(fp, "%s", Iter->second.Value.String);
+ break;
+
+ case OA_TYPE_ENUM:
+ fprintf(fp, "%s", Iter->second.Value.Enum);
+ break;
+
+ }
+
+ fprintf(fp, "\n");
+ }
+}
+
+void AppSettings::WriteOptionsFile(void)
+{
+ char optionFile[MAX_PATH] = "";
+ if(!GetExePath(optionFile))
+ {
+ fprintf(stderr, "Cannot get exe path\r\n");
+ }
+ strcat(optionFile, OptionsFileName);
+
+ fprintf(stderr, "FurViewer: Writing options file \"%s\".\n",
+ optionFile);
+ fflush(stderr);
+
+ FILE *FP = fopen(optionFile, "wb");
+ if(!FP)
+ Error("Couldn't open \"%s\" for write.\n", optionFile);
+
+ WriteOptionsFile(FP);
+
+ fclose(FP);
+}
+
+void AppSettings::SetOptionValue(const char *name,
+ oaOptionDataType type,
+ const char *value)
+{
+ assert(name != NV_NULL);
+ assert(type != OA_TYPE_INVALID);
+ assert(value != NV_NULL);
+
+ oaValue Value;
+ switch(type)
+ {
+ case OA_TYPE_INT:
+ Value.Int = atoi(value);
+ break;
+
+ case OA_TYPE_FLOAT:
+ Value.Float = StrToFloat(value);
+ break;
+
+ case OA_TYPE_BOOL:
+ Value.Bool = atoi(value) ? OA_TRUE : OA_FALSE;
+ break;
+
+ case OA_TYPE_STRING:
+ Value.String = (oaString)value;
+ break;
+
+ case OA_TYPE_ENUM:
+ Value.Enum = (oaString)value;
+ break;
+ }
+
+ SetOptionValue(name, type, &Value);
+}
+
+
+
diff --git a/tools/ArtistTools/source/CoreLib/Utils/Settings.h b/tools/ArtistTools/source/CoreLib/Utils/Settings.h
new file mode 100644
index 0000000..a845732
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/Settings.h
@@ -0,0 +1,392 @@
+/*******************************************************************************
+* NVIDIA Corporation
+* Software License Agreement - OpenAutomate SDK
+*
+* IMPORTANT - READ BEFORE COPYING, INSTALLING OR USING
+* Do not use or load the OpenAutomate SDK and any associated materials
+* provided by NVIDIA on NVIDIA�s website (collectively, the "Software")
+* until You have carefully read the following terms and conditions. By
+* loading or using the Software, You agree to fully comply with the terms
+* and conditions of this Software License Agreement ("Agreement") by and
+* between NVIDIA Corporation, a Delaware corporation with its principal
+* place of business at 2701 San Tomas Expressway, Santa Clara, California
+* 95050 U.S.A. ("NVIDIA"), and You. If You do not wish to so agree, do not
+* install or use the Software.
+*
+* For the purposes of this Agreement:
+*
+* "Licensee," "You" and/or "Your" shall mean, collectively and
+* individually, Original Equipment Manufacturers, Independent Hardware
+* Vendors, Independent Software Vendors, and End-Users of the Software
+* pursuant to the terms and conditions of this Agreement.
+*
+* "Derivative Works" shall mean derivatives of the Software created by You
+* or a third party on Your behalf, which term shall include: (a) for
+* copyrightable or copyrighted material, any translation, abridgement,
+* revision or other form in which an existing work may be recast,
+* transformed or adapted; (b) for work protected by topography or mask
+* right, any translation, abridgement, revision or other form in which an
+* existing work may be recast, transformed or adapted; (c) for patentable
+* or patented material, any Improvement; and (d) for material protected by
+* trade secret, any new material derived from or employing such existing
+* trade secret.
+*
+* "Excluded License" is any license that requires as a condition of use,
+* modification and/or distribution of software subject to the Excluded
+* License, that such software or other software distributed and/or
+* combined with such software be (i) disclosed or distributed in source
+* code form, (ii) licensed for the purpose of making derivative works, or
+* (iii) redistributable at no charge.
+*
+* SECTION 1 - GRANT OF LICENSE.
+* NVIDIA agrees to provide the Software and any associated materials
+* pursuant to the terms and conditions of this Agreement. Subject to the
+* terms of this Agreement, NVIDIA grants to You a nonexclusive,
+* transferable, worldwide, revocable, limited, royalty-free, fully paid-up
+* license under NVIDIA�s copyrights to
+*
+* (a) install, deploy, use, have used execute, reproduce, display,
+* perform, run, modify the source code of the Software, or to prepare and
+* have prepared Derivative Works thereof the Software for Your own
+* internal development, testing and maintenance purposes to incorporate
+* the Software or Derivative Works thereof, in part or whole, into Your
+* software applications;
+*
+* (b) to transfer, distribute and sublicense the Software (in its
+* unmodified form as delivered to You by NVIDIA pursuant to this
+* Agreement) in any medium or technology for Your sublicensees to
+* incorporate the Software or Derivative Works thereof, in part or whole,
+* into their respective software applications; and
+*
+* (c) to transfer, distribute and sublicense Derivative Works (in object
+* code only) of the Software (i)_as incorporated in Your application
+* software in any medium or technology; and (ii) certified as OpenAutomate
+* Compatible Software.
+*
+* You may exercise your license rights pursuant to Subsection 1(b) and (c)
+* above pursuant to the terms and conditions of any form of end-user
+* software license agreement of Your choice, including but not limited to
+* an Excluded License.
+*
+* In the event NVIDIA certifies Your application software, incorporating
+* the Derivative Works (in object code only) of the Software, as
+* OpenAutomate compatible ("OpenAutomate Compatible Software"), NVIDIA
+* grants You a nonexclusive, worldwide, revocable, paid-up license to use
+* the name and trademark to "OpenAutomate Compatible" solely for the
+* purposes of identifying and/or marketing Your application software as
+* OpenAutomate Compatible Software; provided that Licensee fully complies
+* with the following:
+*
+* (x) Licensee agrees that it is strictly prohibited from using the name
+* and trademark of "OpenAutomate Compatible" if Your application software
+* is not OpenAutomate Compatible Software;
+*
+* (y) if NVIDIA objects to Your improper use of the "OpenAutomate
+* Compatible" name and trademark, You will take all reasonable steps
+* necessary to resolve NVIDIA�s objections. NVIDIA may reasonably monitor
+* the quality of Your application software bearing the "OpenAutomate
+* Compatible" name or trademark pursuant to this Agreement; and
+*
+* (z) any goodwill attached to NVIDIA�s trademarks, service marks, or
+* trade names belong to NVIDIA and this Agreement does not grant You any
+* right to use them.
+*
+* If You are not the final manufacturer or vendor of a computer system or
+* software program incorporating the Software, or if Your Contractors (as
+* defined below), affiliates or subsidiaries need to exercise any, some or
+* all of the license grant described above herein to the Software on Your
+* behalf, then You may transfer a copy of the Software, (and related
+* end-user documentation) to such recipient for use in accordance with the
+* terms of this Agreement, provided such recipient agrees to be fully
+* bound by the terms hereof. Except as expressly permitted in this
+* Agreement, Unless otherwise authorized in the Agreement, You shall not
+* otherwise assign, sublicense, lease, or in any other way transfer or
+* disclose Software to any third party. Unless otherwise authorized in the
+* Agreement, You shall not reverse- compile, disassemble,
+* reverse-engineer, or in any manner attempt to derive the source code of
+* the Software from the object code portions of the Software.
+*
+* Except as expressly stated in this Agreement, no license or right is
+* granted to You directly or by implication, inducement, estoppel or
+* otherwise. NVIDIA shall have the right to inspect or have an independent
+* auditor inspect Your relevant records to verify Your compliance with the
+* terms and conditions of this Agreement.
+*
+* SECTION 2 - CONFIDENTIALITY.
+* If applicable, any exchange of Confidential Information (as defined in
+* the NDA) shall be made pursuant to the terms and conditions of a
+* separately signed Non-Disclosure Agreement ("NDA") by and between NVIDIA
+* and You. For the sake of clarity, You agree that the Software is
+* Confidential Information of NVIDIA.
+*
+* If You wish to have a third party consultant or subcontractor
+* ("Contractor") perform work on Your behalf which involves access to or
+* use of Software, You shall obtain a written confidentiality agreement
+* from the Contractor which contains terms and obligations with respect to
+* access to or use of Software no less restrictive than those set forth in
+* this Agreement and excluding any distribution or sublicense rights, and
+* use for any other purpose than permitted in this Agreement. Otherwise,
+* You shall not disclose the terms or existence of this Agreement or use
+* NVIDIA's name in any publications, advertisements, or other
+* announcements without NVIDIA's prior written consent. Unless otherwise
+* provided in this Agreement, You do not have any rights to use any NVIDIA
+* trademarks or logos.
+*
+* SECTION 3 - OWNERSHIP OF SOFTWARE AND INTELLECTUAL PROPERTY RIGHTS.
+* All rights, title and interest to all copies of the Software remain with
+* NVIDIA, subsidiaries, licensors, or its suppliers. The Software is
+* copyrighted and protected by the laws of the United States and other
+* countries, and international treaty provisions. You may not remove any
+* copyright notices from the Software. NVIDIA may make changes to the
+* Software, or to items referenced therein, at any time and without
+* notice, but is not obligated to support or update the Software. Except
+* as otherwise expressly provided, NVIDIA grants no express or implied
+* right under any NVIDIA patents, copyrights, trademarks, or other
+* intellectual property rights.
+*
+* All rights, title and interest in the Derivative Works of the Software
+* remain with You subject to the underlying license from NVIDIA to the
+* Software. In Your sole discretion, You may grant NVIDIA, upon NVIDIA�s
+* request for such a license described herein, an irrevocable, perpetual,
+* nonexclusive, worldwide, royalty-free paid-up license to make, have
+* made, use, have used, sell, license, distribute, sublicense or otherwise
+* transfer Derivative Works created by You that add functionality or
+* improvement to the Software.
+*
+* You has no obligation to give NVIDIA any suggestions, comments or other
+* feedback ("Feedback") relating to the Software. However, NVIDIA may use
+* and include any Feedback that You voluntarily provide to improve the
+* Software or other related NVIDIA technologies. Accordingly, if You
+* provide Feedback, You agree NVIDIA and its licensees may freely use,
+* reproduce, license, distribute, and otherwise commercialize the Feedback
+* in the Software or other related technologies without the payment of any
+* royalties or fees.
+*
+* You may transfer the Software only if the recipient agrees to be fully
+* bound by these terms and conditions of this Agreement.
+*
+* SECTION 4 - NO WARRANTIES.
+* THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY
+* OF ANY KIND, INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT,
+* OR FITNESS FOR A PARTICULAR PURPOSE. NVIDIA does not warrant or assume
+* responsibility for the accuracy or completeness of any information,
+* text, graphics, links or other items contained within the Software.
+* NVIDIA does not represent that errors or other defects will be
+* identified or corrected.
+*
+* SECTION 5 - LIMITATION OF LIABILITY.
+* EXCEPT WITH RESPECT TO THE MISUSE OF THE OTHER PARTY�S INTELLECTUAL
+* PROPERTY OR DISCLOSURE OF THE OTHER PARTY�S CONFIDENTIAL INFORMATION IN
+* BREACH OF THIS AGREEMENT, IN NO EVENT SHALL NVIDIA, SUBSIDIARIES,
+* LICENSORS, OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER
+* (INCLUDING, WITHOUT LIMITATION, INDIRECT, LOST PROFITS, CONSEQUENTIAL,
+* BUSINESS INTERRUPTION OR LOST INFORMATION) ARISING OUT OF THE USE OF OR
+* INABILITY TO USE THE SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS PROHIBIT EXCLUSION OR
+* LIMITATION OF LIABILITY FOR IMPLIED WARRANTIES OR CONSEQUENTIAL OR
+* INCIDENTAL DAMAGES, SO THE ABOVE LIMITATION MAY NOT APPLY TO YOU. YOU
+* MAY ALSO HAVE OTHER LEGAL RIGHTS THAT VARY FROM JURISDICTION TO
+* JURISDICTION. NOTWITHSTANDING THE FOREGOING, NVIDIA�S AGGREGATE
+* LIABILITY ARISING OUT OF THIS AGREEMENT SHALL NOT EXCEED ONE HUNDRED
+* UNITED STATES DOLLARS (USD$100).
+*
+* SECTION 6 - TERM.
+* This Agreement and the licenses granted hereunder shall be effective as
+* of the date You download the applicable Software ("Effective Date") and
+* continue for a period of one (1) year ("Initial Term") respectively,
+* unless terminated earlier in accordance with the "Termination" provision
+* of this Agreement. Unless either party notifies the other party of its
+* intent to terminate this Agreement at least three (3) months prior to
+* the end of the Initial Term or the applicable renewal period, this
+* Agreement will be automatically renewed for one (1) year renewal periods
+* thereafter, unless terminated in accordance with the "Termination"
+* provision of this Agreement.
+*
+* SECTION 7 - TERMINATION.
+* NVIDIA may terminate this Agreement at any time if You violate its
+* terms. Upon termination, You will immediately destroy the Software or
+* return all copies of the Software to NVIDIA, and certify to NVIDIA in
+* writing that such actions have been completed. Upon termination or
+* expiration of this Agreement the license grants to Licensee shall
+* terminate, except that sublicenses rightfully granted by Licensee under
+* this Agreement in connection with Section 1(b) and (c) of this Agreement
+* provided by Licensee prior to the termination or expiration of this
+* Agreement shall survive in accordance with their respective form of
+* license terms and conditions.
+*
+* SECTION 8 - MISCELLANEOUS.
+*
+* SECTION 8.1 - SURVIVAL.
+* Those provisions in this Agreement, which by their nature need to
+* survive the termination or expiration of this Agreement, shall survive
+* termination or expiration of the Agreement, including but not limited to
+* Sections 2, 3, 4, 5, 7, and 8.
+*
+* SECTION 8.2 - APPLICABLE LAWS.
+* Claims arising under this Agreement shall be governed by the laws of
+* Delaware, excluding its principles of conflict of laws and the United
+* Nations Convention on Contracts for the Sale of Goods. The state and/or
+* federal courts residing in Santa Clara County, California shall have
+* exclusive jurisdiction over any dispute or claim arising out of this
+* Agreement. You may not export the Software in violation of applicable
+* export laws and regulations.
+*
+* SECTION 8.3 - AMENDMENT.
+* The Agreement shall not be modified except by a written agreement that
+* names this Agreement and any provision to be modified, is dated
+* subsequent to the Effective Date, and is signed by duly authorized
+* representatives of both parties.
+*
+* SECTION 8.4 - NO WAIVER.
+* No failure or delay on the part of either party in the exercise of any
+* right, power or remedy under this Agreement or under law, or to insist
+* upon or enforce performance by the other party of any of the provisions
+* of this Agreement or under law, shall operate as a waiver thereof, nor
+* shall any single or partial exercise of any right, power or remedy
+* preclude other or further exercise thereof, or the exercise of any other
+* right, power or remedy; rather the provision, right, or remedy shall be
+* and remain in full force and effect.
+*
+* SECTION 8.5 - NO ASSIGNMENT.
+* This Agreement and Licensee�s rights and obligations herein, may not be
+* assigned, subcontracted, delegated, or otherwise transferred by Licensee
+* without NVIDIA�s prior written consent, and any attempted assignment,
+* subcontract, delegation, or transfer in violation of the foregoing will
+* be null and void. The terms of this Agreement shall be binding upon
+* Licensee�s assignees.
+*
+* SECTION 8.6 - GOVERNMENT RESTRICTED RIGHTS.
+* The parties acknowledge that the Software is subject to U.S. export
+* control laws and regulations. The parties agree to comply with all
+* applicable international and national laws that apply to the Software,
+* including the U.S. Export Administration Regulations, as well as
+* end-user, end-use and destination restrictions issued by U.S. and other
+* governments.
+*
+* The Software has been developed entirely at private expense and is
+* commercial computer software provided with RESTRICTED RIGHTS. Use,
+* duplication or disclosure of the Software by the U.S. Government or a
+* U.S. Government subcontractor is subject to the restrictions set forth
+* in the Agreement under which the Software was obtained pursuant to DFARS
+* 227.7202-3(a) or as set forth in subparagraphs (c)(1) and (2) of the
+* Commercial Computer Software - Restricted Rights clause at FAR
+* 52.227-19, as applicable. Contractor/manufacturer is NVIDIA, 2701 San
+* Tomas Expressway, Santa Clara, CA 95050. Use of the Software by the
+* Government constitutes acknowledgment of NVIDIA's proprietary rights
+* therein.
+*
+* SECTION 8.7 - INDEPENDENT CONTRACTORS.
+* Licensee�s relationship to NVIDIA is that of an independent contractor,
+* and neither party is an agent or partner of the other. Licensee will
+* not have, and will not represent to any third party that it has, any
+* authority to act on behalf of NVIDIA.
+*
+* SECTION 8.8 - SEVERABILITY.
+* If for any reason a court of competent jurisdiction finds any provision
+* of this Agreement, or portion thereof, to be unenforceable, that
+* provision of the Agreement will be enforced to the maximum extent
+* permissible so as to affect the intent of the parties, and the remainder
+* of this Agreement will continue in full force and effect. This Agreement
+* has been negotiated by the parties and their respective counsel and will
+* be interpreted fairly in accordance with its terms and without any
+* strict construction in favor of or against either party.
+*
+* SECTION 8.9 - ENTIRE AGREEMENT.
+* This Agreement and NDA constitute the entire agreement between the
+* parties with respect to the subject matter contemplated herein, and
+* merges all prior and contemporaneous communications.
+*
+******************************************************************************/
+
+
+#ifndef _SETTINGS_H
+#define _SETTINGS_H
+
+#include <assert.h>
+#include <ctype.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <vector>
+#include <map>
+#include <string>
+#include <conio.h>
+#include <OpenAutomate.h>
+
+#include "corelib_global.h"
+
+#if WIN32
+# include <windows.h>
+# define SLEEP(ms) Sleep(ms)
+#else
+# include <unistd.h>
+# define SLEEP(ms) usleep(1000 * (ms))
+#endif
+
+void Error(const char *fmt, ...);
+bool GetExePath(char* exe_path);
+
+struct OptionValue
+{
+ const char *Name;
+ oaOptionDataType Type;
+ oaValue Value;
+};
+
+class CORELIB_EXPORT AppSettings
+{
+public:
+ AppSettings();
+ ~AppSettings();
+
+ static AppSettings& Inst()
+ {
+ static AppSettings s_inst;
+ return s_inst;
+ }
+
+ void InitOptions();
+
+ void WriteOptionsFile();
+
+ void SetOptionValue(const char *name,
+ oaOptionDataType type,
+ const oaValue *value);
+
+ int GetNumOptions(){return NumOptions;}
+
+ oaNamedOption* GetOption(int i){return &Options[i];}
+
+ OptionValue* GetOptionValue(char* opt_name)
+ {
+ return &OptionValueMap[opt_name];
+ }
+
+ std::map<std::string, OptionValue>* GetCurrentOptionMap()
+ {
+ return &OptionValueMap;
+ }
+
+private:
+
+ void Cleanup();
+
+ void InitDefaultOptions();
+
+ void ReadOptionsFile();
+
+ void WriteOptionsFile(FILE *fp);
+
+ void SetOptionValue(const char *name,
+ oaOptionDataType type,
+ const char *value);
+
+ oaNamedOption Options[128];
+ std::map<std::string, OptionValue> OptionValueMap;
+
+ int NumOptions;
+};
+
+#endif \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Utils/Stats.cpp b/tools/ArtistTools/source/CoreLib/Utils/Stats.cpp
new file mode 100644
index 0000000..d52aa14
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/Stats.cpp
@@ -0,0 +1,76 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+///////////////////////////////////////////////////////////////////////////////
+#include "Stats.h"
+
+void Stats::reset()
+{
+ m_totalRenderTime = 0.0f;
+ m_shadowRenderTime = 0.0f;
+ m_meshRenderTime = 0.0f;
+ m_hairRenderTime = 0.0f;
+ m_hairStatsTime = 0.0f;
+ m_totalUpdateTime = 0.0f;
+ m_meshSkinningTime = 0.0f;
+ m_hairSkinningTime = 0.0f;
+ m_hairSimulationTime = 0.0f;
+ m_queryTime = 0.0f;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void Stats::add(const Stats& toAdd)
+{
+ m_totalRenderTime += toAdd.m_totalRenderTime;
+ m_shadowRenderTime += toAdd.m_shadowRenderTime;
+ m_meshRenderTime += toAdd.m_meshRenderTime;
+ m_hairRenderTime += toAdd.m_hairRenderTime;
+ m_hairStatsTime += toAdd.m_hairStatsTime;
+
+ m_totalUpdateTime += toAdd.m_totalUpdateTime;
+ m_meshSkinningTime += toAdd.m_meshSkinningTime;
+ m_hairSkinningTime += toAdd.m_hairSkinningTime;
+ m_hairSimulationTime += toAdd.m_hairSimulationTime;
+
+ m_queryTime += toAdd.m_queryTime;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void Stats::average(float numFrames)
+{
+ m_totalRenderTime /= numFrames;
+ m_shadowRenderTime /= numFrames;
+ m_meshRenderTime /= numFrames;
+ m_hairRenderTime /= numFrames;
+ m_hairStatsTime /= numFrames;
+ m_totalUpdateTime /= numFrames;
+ m_meshSkinningTime /= numFrames;
+ m_hairSkinningTime /= numFrames;
+ m_hairSimulationTime /= numFrames;
+ m_queryTime /= numFrames;
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Utils/Stats.h b/tools/ArtistTools/source/CoreLib/Utils/Stats.h
new file mode 100644
index 0000000..fb22e57
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/Stats.h
@@ -0,0 +1,54 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include "corelib_global.h"
+
+// scene statistics
+struct CORELIB_EXPORT Stats
+{
+ double m_totalRenderTime;
+ double m_shadowRenderTime;
+ double m_meshRenderTime;
+ double m_hairRenderTime;
+ double m_hairStatsTime;
+
+ double m_totalUpdateTime;
+ double m_meshSkinningTime;
+ double m_hairSkinningTime;
+ double m_hairSimulationTime;
+
+ double m_queryTime;
+
+ Stats() { reset(); }
+
+ void reset();
+ void add(const Stats& toAdd);
+ void average(float numFrames);
+}; \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Utils/Timer.cpp b/tools/ArtistTools/source/CoreLib/Utils/Timer.cpp
new file mode 100644
index 0000000..2161989
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/Timer.cpp
@@ -0,0 +1,80 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#include "Timer.h"
+
+Timer::Timer(bool isStartNow)
+{
+ ::QueryPerformanceFrequency(&m_ticksPerSecond);
+ Reset(isStartNow);
+}
+
+void Timer::Reset(bool isStartNow)
+{
+ m_isPaused = true;
+ m_totalPausedTime.QuadPart = 0;
+ m_lastPausedTime.QuadPart = 0;
+ if (isStartNow)
+ {
+ Start();
+ }
+}
+
+void Timer::Start()
+{
+ if (m_isPaused)
+ {
+ LARGE_INTEGER timeNow;
+ ::QueryPerformanceCounter(&timeNow);
+ m_totalPausedTime.QuadPart += timeNow.QuadPart - m_lastPausedTime.QuadPart;
+ m_isPaused = false;
+ }
+}
+
+void Timer::Pause()
+{
+ if (!m_isPaused)
+ {
+ m_isPaused = true;
+ ::QueryPerformanceCounter(&m_lastPausedTime);
+ }
+}
+
+LONGLONG Timer::GetTicksElapsed() const
+{
+ LARGE_INTEGER timeNow;
+ if (m_isPaused)
+ {
+ timeNow = m_lastPausedTime;
+ }
+ else
+ {
+ ::QueryPerformanceCounter(&timeNow);
+ }
+ return (timeNow.QuadPart - m_totalPausedTime.QuadPart);
+}
diff --git a/tools/ArtistTools/source/CoreLib/Utils/Timer.h b/tools/ArtistTools/source/CoreLib/Utils/Timer.h
new file mode 100644
index 0000000..c14ff97
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/Timer.h
@@ -0,0 +1,68 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+
+#include "corelib_global.h"
+
+class CORELIB_EXPORT Timer
+{
+public:
+ Timer(bool isStartNow = false);
+ void Start();
+ void Reset(bool isStartNow = false);
+ void Pause();
+ bool IsRunning() const
+ {
+ return !m_isPaused;
+ }
+ double GetTimeInMilliSeconds() const
+ {
+ return double(GetTicksElapsed()*1000.0) / GetTicksPerSecond();
+ }
+ double GetTimeInSeconds() const
+ {
+ return double(GetTicksElapsed()) / GetTicksPerSecond();
+ }
+
+public:
+ bool m_isPaused;
+
+ // Get time ticks elapsed
+ LONGLONG GetTicksElapsed() const;
+ // Get the timer frequency. Time tick count per second
+ LONGLONG GetTicksPerSecond() const {
+ return m_ticksPerSecond.QuadPart;
+ }
+ LARGE_INTEGER m_ticksPerSecond;
+ LARGE_INTEGER m_lastPausedTime;
+ LARGE_INTEGER m_totalPausedTime;
+};
diff --git a/tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.cpp b/tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.cpp
new file mode 100644
index 0000000..d5486bc
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.cpp
@@ -0,0 +1,75 @@
+#include <windows.h>
+#include "ViewerOutput.h"
+
+ViewerOutput& ViewerOutput::Inst()
+{
+ static ViewerOutput inst;
+ return inst;
+}
+
+void ViewerOutput::RegisterPrinter( FrontPrinter* printer )
+{
+ if(!printer) return;
+
+ _printers.insert(printer);
+}
+
+void ViewerOutput::UnRegisterPrinter( FrontPrinter* printer )
+{
+ if(!printer) return;
+
+ auto itr = _printers.find(printer);
+ if(itr != _printers.end())
+ _printers.erase(itr);
+}
+
+void ViewerOutput::print( FrontPrinter::Effect e, unsigned long color, const char* fmt, ... )
+{
+ va_list args;
+ va_start(args, fmt);
+
+ vsprintf_s(_buf, MAX_BUFFER_SIZE, fmt, args);
+
+ va_end(args);
+
+ for (auto itr = _printers.begin(); itr != _printers.end(); ++itr)
+ {
+ (*itr)->print(_buf, color, e);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+ViewerStream::~ViewerStream()
+{
+ flush();
+}
+
+ViewerStream& ViewerStream::flush()
+{
+ this->std::ostream::flush();
+
+ if(_buffer.size() == 0)
+ return (*this);
+
+ ViewerOutput::Inst().print(_effect, _color, _buffer.buf);
+ _buffer.reset();
+
+ return (*this);
+}
+
+ViewerStream::ViewerStreamBuf::ViewerStreamBuf()
+{
+ reset();
+}
+
+std::streamsize ViewerStream::ViewerStreamBuf::size()
+{
+ return (pptr() - pbase());
+}
+
+void ViewerStream::ViewerStreamBuf::reset()
+{
+ memset(buf, 0, sizeof(buf));
+ setp(buf, buf + FURVIEWER_MAX_OUTPUT_CHAR);
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.h b/tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.h
new file mode 100644
index 0000000..b1fb9f7
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.h
@@ -0,0 +1,136 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#include <set>
+
+#include "corelib_global.h"
+
+/*
+ * !! CAUSION:
+ * Not thread safe, should only output messages in the MAIN thread!
+ * Otherwise, cannot guarantee the Qt Gui behavior.
+ */
+
+// DON'T TRY TO WRITE CHARS MORE THAN THE FURVIEWER_MAX_OUTPUT_CHAR
+#define FURVIEWER_MAX_OUTPUT_CHAR 2048
+
+// c-style print
+#define viewer_msg(fmt, ...) ViewerOutput::Inst().print(FrontPrinter::NONE, 0, fmt, ##__VA_ARGS__)
+#define viewer_warn(fmt, ...) ViewerOutput::Inst().print(FrontPrinter::NONE, RGB(255,200,020), fmt, ##__VA_ARGS__)
+#define viewer_info(fmt, ...) ViewerOutput::Inst().print(FrontPrinter::NONE, RGB(118,185,000), fmt, ##__VA_ARGS__)
+#define viewer_err(fmt, ...) ViewerOutput::Inst().print(FrontPrinter::NONE, RGB(255,000,000), fmt, ##__VA_ARGS__)
+#define viewer_fatal(fmt, ...) ViewerOutput::Inst().print(FrontPrinter::BOLD, RGB(255,000,000), fmt, ##__VA_ARGS__)
+
+// c++ style output stream
+#define viewer_stream_msg ViewerStream(FrontPrinter::NONE, 0)
+#define viewer_stream_warn ViewerStream(FrontPrinter::NONE, RGB(255,200,020))
+#define viewer_stream_info ViewerStream(FrontPrinter::NONE, RGB(118,185,000))
+#define viewer_stream_err ViewerStream(FrontPrinter::NONE, RGB(255,000,000))
+#define viewer_stream_fatal ViewerStream(FrontPrinter::NONE, RGB(255,000,000))
+
+
+//////////////////////////////////////////////////////////////////////////
+// implementation
+//////////////////////////////////////////////////////////////////////////
+class FrontPrinter
+{
+public:
+ enum Effect
+ {
+ NONE = 0x0,
+ BOLD = 0x1,
+ ITALIC = 0x2,
+ UNDERLINE = 0x4
+ };
+
+ virtual void print(const char* txt, unsigned long color = 0, Effect e = NONE) = 0;
+};
+
+class CORELIB_EXPORT ViewerOutput
+{
+public:
+ static ViewerOutput& Inst();
+
+ void RegisterPrinter(FrontPrinter* printer);
+ void UnRegisterPrinter(FrontPrinter* printer);
+
+ void print(FrontPrinter::Effect e, unsigned long color, const char* fmt, ...);
+
+private:
+ enum {MAX_BUFFER_SIZE = FURVIEWER_MAX_OUTPUT_CHAR + 1};
+
+ char _buf[MAX_BUFFER_SIZE];
+
+ std::set<FrontPrinter*> _printers;
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+// stream to support c++ style output
+
+#include <streambuf>
+#include <sstream>
+
+class ViewerStream : public std::ostream
+{
+public:
+ explicit ViewerStream(FrontPrinter::Effect e, unsigned long color)
+ : std::ostream(&_buffer)
+ , _effect(e)
+ , _color(color)
+ {}
+
+ ~ViewerStream();
+
+ ViewerStream& flush();
+
+private:
+
+ class ViewerStreamBuf : public std::streambuf
+ {
+ public:
+ enum
+ {
+ STATIC_BUFFER_SIZE = FURVIEWER_MAX_OUTPUT_CHAR + 1,
+ };
+
+ ViewerStreamBuf();
+
+ void reset();
+ std::streamsize size();
+
+ // fixed stack buffer
+ char buf[STATIC_BUFFER_SIZE];
+ };
+
+ ViewerStreamBuf _buffer;
+ FrontPrinter::Effect _effect;
+ unsigned long _color;
+};
diff --git a/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp b/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp
new file mode 100644
index 0000000..3a85d8b
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp
@@ -0,0 +1,1448 @@
+#include <QtWidgets/QShortcut>
+#include <QtWidgets/QAction>
+#include <QtWidgets/QMenu>
+#include <QtWidgets/QFileDialog>
+#include <QtWidgets/QMessageBox>
+#include <QtGui/QDesktopServices>
+#include <QtWidgets/QScrollBar>
+#include <QtWidgets/QGraphicsEllipseItem>
+#include <QtWidgets/QGraphicsView>
+#include <QtWidgets/QProgressDialog>
+
+#include <Windows.h>
+
+#include "AppMainWindow.h"
+#include "ExpandablePanel.h"
+
+#include "D3DWidget.h"
+
+#include "DisplayMeshesPanel.h"
+
+#include "DisplayPreferencesPanel.h"
+#include "DisplayScenePanel.h"
+#include "DisplayLightPanel.h"
+#include "ui_DisplayPreferencesPanel.h"
+#include "ui_DisplayScenePanel.h"
+#include "ui_DisplayLightPanel.h"
+#include "CameraBookmarksDialog.h"
+
+#include "SimpleScene.h"
+#include "GlobalSettings.h"
+
+#include "ViewerOutput.h"
+#include "Gamepad.h"
+#if USE_CURVE_EDITOR
+#include "CurveEditorMainWindow.h"
+#endif
+#ifndef NV_ARTISTTOOLS
+#include "ui_AppMainToolbar.h"
+#include "ui_AssetControlPanel.h"
+#include "ui_GeneralAttributesPanel.h"
+#include "ui_PhysicalMaterialsPanel.h"
+#include "ui_StyleMaterialsPanel.h"
+#include "ui_GraphicalMaterialsPanel.h"
+#include "BlastToolbar.h"
+#include "AssetControlPanel.h"
+#include "GraphicalMaterialPanel.h"
+#include "PhysicalMaterialPanel.h"
+#include "StyleMaterialPanel.h"
+#include "GeneralAttributePanel.h"
+#include "MaterialSetPanel.h"
+#include "LodPanel.h"
+#include "DisplayVisualizersPanel.h"
+#include "ui_DisplayVisualizersPanel.h"
+#include "DisplayMeshMaterialsPanel.h"
+#include "FurCharacter.h"
+#include "HairParams.h"
+#include "AboutDialog.h"
+#else
+#endif // NV_ARTISTTOOLS
+
+class MsgPrinter : public FrontPrinter
+{
+public:
+ MsgPrinter(QTextBrowser* browser):_browser(browser)
+ {
+
+ }
+
+ void print(const char* txt, unsigned long color /* = 0 */, Effect e /* = NONE */)
+ {
+ if(color == 0 && e == FrontPrinter::NONE)
+ {
+ _browser->insertPlainText(QString(txt)+"\n");
+ }
+ else
+ {
+ // output html text
+ QString surfix;
+ QString postfix;
+ surfix.reserve(64);
+ postfix.reserve(64);
+ if(e & FrontPrinter::BOLD)
+ {
+ surfix = surfix + "<b>";
+ postfix= postfix + "</b>";
+ }
+ else if(e & FrontPrinter::UNDERLINE)
+ {
+ surfix = surfix + "<u>";
+ postfix= QString("</u>") + postfix;
+ }
+ else if(e & FrontPrinter::ITALIC)
+ {
+ surfix = surfix + "<i>";
+ postfix= QString("</i>") + postfix;
+ }
+
+ if(color != 0)
+ {
+ int r = GetRValue(color);
+ int g = GetGValue(color);
+ int b = GetBValue(color);
+
+ surfix = QString("<div style=\"color:rgb(%1,%2,%3);\">").arg(r).arg(g).arg(b) + surfix;
+ postfix= postfix + QString("</div><br />");
+ }
+
+ QString html = surfix + QString(txt) + postfix;
+ _browser->insertHtml(html);
+ }
+ // auto scroll to the bottom
+ QScrollBar *sb = _browser->verticalScrollBar();
+ if (sb) sb->setValue(sb->maximum());
+ }
+
+private:
+ QTextBrowser* _browser;
+};
+
+int AppMainWindow::_connectionMode = 0;
+bool AppMainWindow::_expertMode = false;
+AppMainWindow* gAppMainWindow = NV_NULL;
+
+void CreateAppMainWindow()
+{
+ gAppMainWindow = new AppMainWindow;
+}
+
+void ReleaseAppMainWindow()
+{
+ delete gAppMainWindow;
+ gAppMainWindow = NV_NULL;
+}
+
+AppMainWindow& AppMainWindow::Inst()
+{
+ return *gAppMainWindow;
+}
+
+AppMainWindow::AppMainWindow(QWidget *parent, Qt::WindowFlags flags)
+ : QMainWindow(parent, flags)
+ , _bookmarksMenu(0)
+ ,_displayMeshesPanel(0)
+ , _displayPreferencesPanel(0)
+ , _displayScenePanel(0)
+ ,_displayLightPanel(0)
+#if USE_CURVE_EDITOR
+ ,_curveEditorInitizlized(false)
+ , _curveEditorMainWindow(nullptr)
+#endif
+ ,_bookmarkActionGroup(0)
+ ,_actionAddBookmark(0)
+ ,_actionEditBookmarks(0)
+{
+ setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
+ setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
+
+ ui.setupUi(this);
+ //ui.dockOutputWindow->hide();
+
+#ifndef NV_ARTISTTOOLS
+ _mainToolbar = 0;
+ _physicalMaterialPanel = 0;
+ _styleMaterialPanel = 0;
+ _graphicalMaterialPanel = 0;
+ _displayFurVisualizersPanel = 0;
+ _assetControlPanel = 0;
+ _generalAttributePanel = 0;
+ _lodPanel = 0;
+ _displayMeshMaterialsPanel;
+#if USE_MATERIAL_SET
+ _materialSetPanel = 0;
+#endif
+#else
+ CoreLib::Inst()->AppMainWindow_AppMainWindow();
+#endif // NV_ARTISTTOOLS
+
+ _progressDialog.close(); // prevent show one empty progress dialog when it runs.
+
+ m_bGizmoWithLocal = false;
+}
+
+void AppMainWindow::InitUI()
+{
+ _d3dWidget = new D3DWidget(this);
+ _d3dWidget->setMinimumSize(200, 200);
+ ui.renderLayout->addWidget(_d3dWidget);
+
+ InitShortCuts();
+ InitMenuItems();
+ InitToolbar();
+ InitPluginTab();
+ InitMainTab();
+
+ InitMouseSchemes();
+
+ updateUI();
+
+ if (_connectionMode == 1) // master mode
+ ui.sideBarTab->removeTab(1);
+
+ if (_connectionMode == 2)
+ ui.sideBarTab->removeTab(0);
+
+
+ QString defFilePath;
+
+ QString appDir = qApp->applicationDirPath();
+ QDir dir(appDir);
+ if (dir.cd("../../media"))
+ defFilePath = dir.absolutePath();
+
+ _lastFilePath = defFilePath;
+
+ _navigationStyle = 0;
+
+ // initialize the message printer
+ _printer = new MsgPrinter(this->ui.outputWindow);
+ ViewerOutput::Inst().RegisterPrinter(_printer);
+
+#ifndef NV_ARTISTTOOLS
+
+ viewer_info(
+ "<a href=\"https://developer.nvidia.com/hairworks\" style=\"color:rgb(118,180,0);\">NVIDIA Blast Version v"
+ NV_HAIR_RELEASE_VERSION_STRING
+ "</a>");
+
+#else
+ CoreLib::Inst()->AppMainWindow_InitUI();
+#endif // NV_ARTISTTOOLS
+}
+
+AppMainWindow::~AppMainWindow()
+{
+}
+
+void AppMainWindow::setConnectionMode(int m)
+{
+ _connectionMode = m;
+}
+
+void AppMainWindow::startProgress()
+{
+ _progressDialog.setWindowModality(Qt::WindowModal);
+ _progressDialog.show();
+}
+
+void AppMainWindow::setProgress(const char* label, int progress)
+{
+ _progressDialog.setLabelText(label);
+ if (progress >= 0)
+ _progressDialog.setValue(progress);
+
+ _progressDialog.update();
+}
+
+void AppMainWindow::endProgress()
+{
+ _progressDialog.close();
+}
+
+void AppMainWindow::quit()
+{
+ emit aboutToQuit();
+}
+
+void AppMainWindow::setProgressMaximum(int m)
+{
+ _progressDialog.setMaximum(m);
+}
+
+void AppMainWindow::InitMenuItems()
+{
+ QMenuBar* menu = ui.menuBar;
+ QAction* act = NV_NULL;
+
+ // file sub-menu
+ QMenu* fileMenu = menu->addMenu("&File");
+
+ if (_connectionMode != 1)
+ {
+ act = new QAction("Clear scene", this);
+ act->setShortcut(QKeySequence::New);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_clearScene()));
+ fileMenu->addAction(act);
+
+ fileMenu->addSeparator();
+
+ act = new QAction("Open fbx file", this);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_openfbx()));
+ fileMenu->addAction(act);
+
+ fileMenu->addSeparator();
+
+#ifndef NV_ARTISTTOOLS
+ fileMenu->addSeparator();
+ act = new QAction("Open project file", this);
+ act->setShortcut(QKeySequence::Open);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_openProject()));
+ fileMenu->addAction(act);
+
+ act = new QAction("Save project file", this);
+ act->setShortcut(QKeySequence::Save);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_saveProject()));
+ fileMenu->addAction(act);
+
+ act = new QAction("Save project file as...", this);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_saveProjectAs()));
+ fileMenu->addAction(act);
+
+ fileMenu->addSeparator();
+
+ act = new QAction("&Open hair file", this);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_openHair()));
+ fileMenu->addAction(act);
+
+ act = new QAction("&Save hair file", this);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_saveHair()));
+ fileMenu->addAction(act);
+
+ act = new QAction("Save hair file as...", this);
+ act->setShortcut(QKeySequence::SaveAs);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_saveHairAs()));
+ fileMenu->addAction(act);
+
+ act = new QAction("Save all hairs...", this);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_saveAllHairs()));
+ fileMenu->addAction(act);
+
+ fileMenu->addSeparator();
+#else
+ CoreLib::Inst()->AppMainWindow_InitMenuItems(ui.menuBar);
+#endif // NV_ARTISTTOOLS
+ }
+
+ act = new QAction("E&xit", this);
+ act->setShortcut(QKeySequence::Quit);
+ connect(act, SIGNAL(triggered()), this, SLOT(close()));
+ fileMenu->addAction(act);
+
+ // view submenu
+ QMenu* viewMenu = menu->addMenu("&View");
+ act = new QAction("Bookmarks", this);
+ //connect(act, SIGNAL(triggered()), this, SLOT(menu_showOutput()));
+ viewMenu->addAction(act);
+ _bookmarksMenu = new QMenu("Bookmarks", this);
+ connect(_bookmarksMenu, SIGNAL(triggered(QAction*)), this, SLOT(menu_bookmarkTriggered(QAction*)));
+ act->setMenu(_bookmarksMenu);
+ act = new QAction("Add Bookmark", this);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_addBookmark()));
+ _bookmarksMenu->addAction(act);
+ _actionAddBookmark = act;
+ act = new QAction("Edit Bookmarks", this);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_editBookmarks()));
+ _bookmarksMenu->addAction(act);
+ _actionEditBookmarks = act;
+ _bookmarksMenu->addSeparator();
+ _bookmarkActionGroup = new QActionGroup(this);
+
+ // window submenu
+ QMenu* windowMenu = menu->addMenu("&Window");
+ act = new QAction("Output", this);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_showOutput()));
+ windowMenu->addAction(act);
+
+ act = new QAction("Attribute Editor", this);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_showAttributeEditor()));
+ windowMenu->addAction(act);
+
+#if USE_CURVE_EDITOR
+ act = new QAction("Curve Editor", this);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_showCurveEditor()));
+ windowMenu->addAction(act);
+#endif
+
+ // help submenu
+ QMenu* helpMenu = menu->addMenu("&Help");
+
+ act = new QAction("Documentation", this);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_opendoc()));
+ helpMenu->addAction(act);
+
+ act = new QAction("&About", this);
+ connect(act, SIGNAL(triggered()), this, SLOT(menu_about()));
+ helpMenu->addAction(act);
+}
+
+void AppMainWindow::InitToolbar()
+{
+ if (_connectionMode != 1)
+ {
+#ifndef NV_ARTISTTOOLS
+ _mainToolbar = new BlastToolbar(ui.centralWidget);
+ ui.verticalLayout->insertWidget(0, _mainToolbar);
+ connect(_mainToolbar->getUI().btnFileOpen, SIGNAL(clicked()), this, SLOT(menu_openProject()));
+#else
+ CoreLib::Inst()->AppMainWindow_InitToolbar(ui.centralWidget, ui.verticalLayout);
+#endif // NV_ARTISTTOOLS
+ }
+}
+
+void AppMainWindow::InitPluginTab()
+{
+#ifndef NV_ARTISTTOOLS
+ QWidget *tabFur;
+ QGridLayout *gridLayout;
+ QFrame *furMaterialEditorArea;
+ QVBoxLayout *furMaterialEditorAreaLayout;
+ QScrollArea *furScrollArea;
+ QWidget *furScrollAreaContents;
+ QVBoxLayout *furScrollAreaLayout;
+ QSpacerItem *verticalSpacer;
+
+ tabFur = new QWidget();
+ tabFur->setObjectName(QStringLiteral("tabFur"));
+ gridLayout = new QGridLayout(tabFur);
+ gridLayout->setSpacing(6);
+ gridLayout->setContentsMargins(11, 11, 11, 11);
+ gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setContentsMargins(0, 0, 0, 0);
+ furMaterialEditorArea = new QFrame(tabFur);
+ furMaterialEditorArea->setObjectName(QStringLiteral("furMaterialEditorArea"));
+ furMaterialEditorAreaLayout = new QVBoxLayout(furMaterialEditorArea);
+ furMaterialEditorAreaLayout->setSpacing(6);
+ furMaterialEditorAreaLayout->setContentsMargins(11, 11, 11, 11);
+ furMaterialEditorAreaLayout->setObjectName(QStringLiteral("furMaterialEditorAreaLayout"));
+ furMaterialEditorAreaLayout->setContentsMargins(2, 2, 2, 2);
+
+ gridLayout->addWidget(furMaterialEditorArea, 1, 0, 1, 1);
+
+ furScrollArea = new QScrollArea(tabFur);
+ furScrollArea->setObjectName(QStringLiteral("furScrollArea"));
+ furScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ furScrollArea->setWidgetResizable(true);
+ furScrollAreaContents = new QWidget();
+ furScrollAreaContents->setObjectName(QStringLiteral("furScrollAreaContents"));
+ furScrollAreaContents->setGeometry(QRect(0, 0, 359, 481));
+ furScrollAreaLayout = new QVBoxLayout(furScrollAreaContents);
+ furScrollAreaLayout->setSpacing(3);
+ furScrollAreaLayout->setContentsMargins(11, 11, 11, 11);
+ furScrollAreaLayout->setObjectName(QStringLiteral("furScrollAreaLayout"));
+ furScrollAreaLayout->setContentsMargins(2, 2, 2, 2);
+ verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
+
+ furScrollAreaLayout->addItem(verticalSpacer);
+
+ furScrollArea->setWidget(furScrollAreaContents);
+
+ gridLayout->addWidget(furScrollArea, 0, 0, 1, 1);
+
+ ui.sideBarTab->addTab(tabFur, QString());
+
+ ui.sideBarTab->setTabText(ui.sideBarTab->indexOf(tabFur), QApplication::translate("AppMainWindowClass", "Hair", 0));
+
+ ExpandablePanel* panel = 0;
+ int pannelCnt = 0;
+
+ if (_connectionMode == 0)
+ {
+ panel = new ExpandablePanel(furScrollAreaContents, false);
+ _generalAttributePanel = new GeneralAttributePanel(panel);
+ panel->AddContent(_generalAttributePanel);
+ furScrollAreaLayout->insertWidget(pannelCnt++, panel);
+ panel->SetTitle("Asset Selection");
+
+ panel = new ExpandablePanel(furScrollAreaContents, false);
+ _assetControlPanel = new AssetControlPanel(panel);
+ panel->AddContent(_assetControlPanel);
+ furScrollAreaLayout->insertWidget(pannelCnt++, panel);
+ panel->SetTitle("General Settings");
+
+ }
+
+ panel = new ExpandablePanel(furScrollAreaContents);
+ _displayFurVisualizersPanel = new DisplayFurVisualizersPanel(panel);
+ panel->AddContent(_displayFurVisualizersPanel);
+ furScrollAreaLayout->insertWidget(pannelCnt++, panel);
+ panel->SetTitle("Visualization");
+
+ panel = new ExpandablePanel(furScrollAreaContents);
+ _physicalMaterialPanel = new PhysicalMaterialPanel(panel);
+ panel->AddContent(_physicalMaterialPanel);
+ furScrollAreaLayout->insertWidget(pannelCnt++, panel);
+ panel->SetTitle("Physical");
+
+ panel = new ExpandablePanel(furScrollAreaContents);
+ _styleMaterialPanel = new StyleMaterialPanel(panel);
+ panel->AddContent(_styleMaterialPanel);
+ furScrollAreaLayout->insertWidget(pannelCnt++, panel);
+ panel->SetTitle("Style");
+
+ panel = new ExpandablePanel(furScrollAreaContents);
+ _graphicalMaterialPanel = new GraphicalMaterialPanel(panel);
+ panel->AddContent(_graphicalMaterialPanel);
+ furScrollAreaLayout->insertWidget(pannelCnt++, panel);
+ panel->SetTitle("Graphics");
+
+ panel = new ExpandablePanel(furScrollAreaContents);
+ _lodPanel = new LodPanel(panel);
+ panel->AddContent(_lodPanel);
+ furScrollAreaLayout->insertWidget(pannelCnt++, panel);
+ panel->SetTitle("Level Of Detail");
+
+#if USE_MATERIAL_SET
+ panel = new ExpandablePanel(furScrollAreaContents);
+ _materialSetPanel = new MaterialSetPanel(panel);
+ panel->AddContent(_materialSetPanel);
+ furScrollAreaLayout->insertWidget(pannelCnt++, panel);
+ panel->SetTitle("Control Texture Channels");
+ //_materialSetPanel->hide();
+ //panel->SetCollapsed(true);
+#else
+ ui.furMaterialEditorAreaLayout->setEnabled(false);
+#endif
+#else
+ CoreLib::Inst()->AppMainWindow_InitPluginTab(ui.sideBarTab);
+#endif // NV_ARTISTTOOLS
+
+#if USE_CURVE_EDITOR
+ _curveEditorMainWindow = new nvidia::CurveEditor::CurveEditorMainWindow( this);//nullptr);
+ _curveEditorMainWindow->setResampleEnabled(false);
+ ui.dockWidgetCurveEditor->setWidget(_curveEditorMainWindow);
+ ui.dockWidgetCurveEditor->setWindowTitle(tr("Curve Editor"));
+
+ connect(_curveEditorMainWindow, SIGNAL(CurveAttributeChanged(nvidia::CurveEditor::CurveAttribute*)), this, SLOT(onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute*)));
+ connect(_curveEditorMainWindow, SIGNAL(ColorAttributeChanged(nvidia::CurveEditor::ColorAttribute*)), this, SLOT(onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute*)));
+ connect(_curveEditorMainWindow, SIGNAL(ReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute*, bool, int)), this, SLOT(onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute*, bool, int)));
+//#else
+// ui.furCurveEditorAreaLayout->setEnabled(false);
+#endif
+}
+
+void AppMainWindow::InitMainTab()
+{
+ int idx = 0;
+
+ if (_connectionMode != 1)
+ {
+ ExpandablePanel* panel = new ExpandablePanel(ui.displayScrollAreaContents);
+ _displayPreferencesPanel = new DisplayPreferencesPanel(panel);
+ panel->AddContent(_displayPreferencesPanel);
+ ui.displayScrollAreaLayout->insertWidget(idx++, panel);
+ panel->SetTitle("Preferences");
+
+ panel = new ExpandablePanel(ui.displayScrollAreaContents);
+ _displayScenePanel = new DisplayScenePanel(panel);
+ panel->AddContent(_displayScenePanel);
+ ui.displayScrollAreaLayout->insertWidget(idx++, panel);
+ panel->SetTitle("Scene");
+
+ panel = new ExpandablePanel(ui.displayScrollAreaContents);
+ _displayLightPanel = new DisplayLightPanel(panel);
+ panel->AddContent(_displayLightPanel);
+ ui.displayScrollAreaLayout->insertWidget(idx++, panel);
+ panel->SetTitle("Light");
+
+ panel = new ExpandablePanel(ui.displayScrollAreaContents);
+ _displayMeshesPanel = new DisplayMeshesPanel(panel);
+ panel->AddContent(_displayMeshesPanel);
+ ui.displayScrollAreaLayout->insertWidget(idx++, panel);
+ panel->SetTitle("Display Meshes");
+ }
+
+ if (_connectionMode != 1)
+ {
+#ifndef NV_ARTISTTOOLS
+ ExpandablePanel* panel = new ExpandablePanel(ui.displayScrollAreaContents);
+ _displayMeshMaterialsPanel = new DisplayMeshMaterialsPanel(panel);
+ panel->AddContent(_displayMeshMaterialsPanel);
+ ui.displayScrollAreaLayout->insertWidget(idx++, panel);
+ panel->SetTitle("Display Mesh Materials");
+#else
+ CoreLib::Inst()->AppMainWindow_InitMainTab(ui.displayScrollAreaContents, ui.displayScrollAreaLayout, idx);
+#endif // NV_ARTISTTOOLS
+ }
+}
+
+void AppMainWindow::InitShortCuts()
+{
+ QShortcut* shortCut;
+ shortCut = new QShortcut(QKeySequence(Qt::Key_F), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_frameall()));
+
+ shortCut = new QShortcut(QKeySequence(Qt::Key_H), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_hud()));
+
+ shortCut = new QShortcut(QKeySequence(Qt::Key_G), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_statistics()));
+
+ shortCut = new QShortcut(QKeySequence(Qt::Key_Space), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_pause()));
+
+ shortCut = new QShortcut(QKeySequence(Qt::Key_B), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_reset()));
+
+ shortCut = new QShortcut(QKeySequence(Qt::Key_Escape), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_escape()));
+
+ shortCut = new QShortcut(QKeySequence(Qt::Key_V), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_expert()));
+
+ shortCut = new QShortcut(QKeySequence("Ctrl+X"), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_expert()));
+
+ shortCut = new QShortcut(QKeySequence(Qt::Key_D), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(demo_next()));
+
+ shortCut = new QShortcut(QKeySequence(Qt::Key_Right), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(demo_next()));
+
+ shortCut = new QShortcut(QKeySequence(Qt::Key_A), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(demo_prev()));
+
+ shortCut = new QShortcut(QKeySequence(Qt::Key_Left), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(demo_prev()));
+
+ shortCut = new QShortcut(QKeySequence(Qt::Key_F2), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_output()));
+
+ shortCut = new QShortcut(QKeySequence("Ctrl+F"), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_fitcamera()));
+}
+
+//////////////////////////////////////////////////////////////////////////
+void AppMainWindow::updateBookmarkMenu()
+{
+ // clear old menu items of camera bookmarks
+ while (_bookmarkActionGroup->actions().size() > 0)
+ {
+ QAction* act = _bookmarkActionGroup->actions()[0];
+ _bookmarkActionGroup->removeAction(act);
+ delete act;
+ }
+ _bookmarksMenu->clear();
+ _bookmarksMenu->addAction(_actionAddBookmark);
+ _bookmarksMenu->addAction(_actionEditBookmarks);
+ _bookmarksMenu->addSeparator();
+
+ QList<QString> bookmarks = SimpleScene::Inst()->getBookmarkNames();
+ int numBookmarks = bookmarks.size();
+ for (int i = 0; i < numBookmarks; ++i)
+ {
+ QString bookmark = bookmarks[i];
+
+ QAction* act = new QAction(bookmark, this);
+ act->setCheckable(true);
+ _bookmarksMenu->addAction(act);
+ _bookmarkActionGroup->addAction(act);
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////////
+void AppMainWindow::updateUI()
+{
+ if (_bookmarksMenu && _bookmarkActionGroup)
+ {
+ updateBookmarkMenu();
+ }
+
+#ifndef NV_ARTISTTOOLS
+ if (_mainToolbar)
+ _mainToolbar->updateValues();
+
+ if (_graphicalMaterialPanel)
+ _graphicalMaterialPanel->updateValues();
+
+ if (_physicalMaterialPanel)
+ _physicalMaterialPanel->updateValues();
+
+ if (_styleMaterialPanel)
+ _styleMaterialPanel->updateValues();
+
+ if (_displayFurVisualizersPanel)
+ _displayFurVisualizersPanel->updateValues();
+
+ if (_lodPanel)
+ _lodPanel->updateValues();
+
+ if (_generalAttributePanel)
+ _generalAttributePanel->updateValues();
+
+ if (_assetControlPanel)
+ _assetControlPanel->updateValues();
+
+ if (_displayMeshMaterialsPanel)
+ _displayMeshMaterialsPanel->updateValues();
+
+#if USE_MATERIAL_SET
+ if (_materialSetPanel)
+ _materialSetPanel->updateValues();
+#endif
+#else
+ CoreLib::Inst()->AppMainWindow_updateUI();
+#endif // NV_ARTISTTOOLS
+
+ if (_displayPreferencesPanel)
+ _displayPreferencesPanel->updateValues();
+
+ if (_displayScenePanel)
+ _displayScenePanel->updateValues();
+
+ if (_displayLightPanel)
+ _displayLightPanel->updateValues();
+
+ if (_displayMeshesPanel)
+ _displayMeshesPanel->updateValues();
+
+#if USE_CURVE_EDITOR
+ if (_curveEditorMainWindow)
+ UpdateCurveEditor();
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////
+void AppMainWindow::updatePluginUI()
+{
+ SimpleScene::Inst()->setIsUpdatingUI(true);
+
+#ifndef NV_ARTISTTOOLS
+ if (_graphicalMaterialPanel)
+ _graphicalMaterialPanel->updateValues();
+
+ if (_physicalMaterialPanel)
+ _physicalMaterialPanel->updateValues();
+
+ if (_styleMaterialPanel)
+ _styleMaterialPanel->updateValues();
+
+ if (_lodPanel)
+ _lodPanel->updateValues();
+
+ if (_displayFurVisualizersPanel)
+ _displayFurVisualizersPanel->updateValues();
+
+ if (_generalAttributePanel)
+ _generalAttributePanel->updateValues();
+
+ if (_assetControlPanel)
+ _assetControlPanel->updateValues();
+
+#if USE_MATERIAL_SET
+ if (_materialSetPanel)
+ _materialSetPanel->updateValues();
+#endif
+#else
+ CoreLib::Inst()->AppMainWindow_updatePluginUI();
+#endif // NV_ARTISTTOOLS
+
+#if USE_CURVE_EDITOR
+ if (_curveEditorMainWindow)
+ UpdateCurveEditor();
+#endif
+
+ SimpleScene::Inst()->setIsUpdatingUI(false);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// event handlers
+
+
+//////////////////////////////////////////////////////////////////////////
+// event handlers
+bool AppMainWindow::openProject(QString fileName)
+{
+ if (!fileName.isEmpty())
+ {
+ QFileInfo fileInfo(fileName);
+ QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit();
+ QByteArray file= fileInfo.fileName().toLocal8Bit();
+
+ if (SimpleScene::Inst()->LoadProject(dir, file) == false)
+ {
+ QMessageBox messageBox;
+ messageBox.critical(0,"Error","File open error!");
+ messageBox.setFixedSize(500,200);
+
+ AppMainWindow::Inst().endProgress();
+ char message[1024];
+ sprintf(message, "Failed to open project file(\"%s\")", (const char*)file);
+ viewer_err(message);
+ return false;
+ }
+
+ AppMainWindow::Inst().endProgress();
+ _lastFilePath = fileInfo.absoluteDir().absolutePath();
+
+ updateUI();
+ return true;
+ }
+ return false;
+}
+
+void AppMainWindow::processDragAndDrop(QString fname)
+{
+ openProject(fname);
+}
+
+void AppMainWindow::removeBookmark(const QString& name)
+{
+ QList<QAction*> bookmarks = _bookmarkActionGroup->actions();
+ int bookmarkCount = bookmarks.size();
+ for (int i = 0; i < bookmarkCount; ++i)
+ {
+ QAction* act = bookmarks.at(i);
+ if (act->text() == name)
+ {
+ _bookmarkActionGroup->removeAction(act);
+ _bookmarksMenu->removeAction(act);
+ delete act;
+ }
+ }
+}
+
+void AppMainWindow::renameBookmark(const QString& oldName, const QString& newName)
+{
+ QList<QAction*> bookmarks = _bookmarkActionGroup->actions();
+ int bookmarkCount = bookmarks.size();
+ for (int i = 0; i < bookmarkCount; ++i)
+ {
+ QAction* act = bookmarks.at(i);
+ if (act->text() == oldName)
+ {
+ act->setText(newName);
+ }
+ }
+}
+
+#if USE_CURVE_EDITOR
+void AppMainWindow::UpdateCurveEditor()
+{
+#ifndef NV_ARTISTTOOLS
+ _curveEditorMainWindow->setCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetCurveAttributes());
+ _curveEditorMainWindow->setColorCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetColorAttributes());
+#else
+ CoreLib::Inst()->AppMainWindow_UpdateCurveEditor();
+#endif // NV_ARTISTTOOLS
+
+ _curveEditorMainWindow->update();
+}
+
+void AppMainWindow::ShowCurveEditor(int paramId)
+{
+#ifndef NV_ARTISTTOOLS
+ _curveEditorMainWindow->setCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetCurveAttributes());
+ _curveEditorMainWindow->setColorCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetColorAttributes());
+ if (HAIR_PARAMS_ROOT_COLOR == paramId || HAIR_PARAMS_TIP_COLOR == paramId)
+ {
+ std::vector<nvidia::CurveEditor::ColorAttribute*> attributes = SimpleScene::Inst()->GetFurCharacter().GetColorAttributesByParamId(paramId);
+ _curveEditorMainWindow->setSelectedColorAttribute(attributes.size() > 0 ? attributes[0] : nullptr);
+ }
+ else
+ _curveEditorMainWindow->setSelectedCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetCurveAttributesByParamId(paramId));
+
+#else
+ CoreLib::Inst()->AppMainWindow_ShowCurveEditor(paramId);
+#endif // NV_ARTISTTOOLS
+
+ _curveEditorMainWindow->update();
+}
+#endif
+
+void AppMainWindow::menu_clearScene()
+{
+ SimpleScene::Inst()->Clear();
+ updateUI();
+}
+
+bool AppMainWindow::menu_openfbx()
+{
+ /*
+ QString lastDir = _lastFilePath;
+ QString fileName = QFileDialog::getOpenFileName(this, "Open FBX File", lastDir, "FBX File (*.fbx)");
+ if (!fileName.isEmpty())
+ {
+ QFileInfo fileInfo(fileName);
+ QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit();
+ QByteArray file= fileInfo.fileName().toLocal8Bit();
+
+ if (SimpleScene::Inst()->LoadSceneFromFbx(dir, file) == false)
+ {
+ QMessageBox messageBox;
+ messageBox.critical(0,"Error","File open error!");
+ messageBox.setFixedSize(500,200);
+
+ AppMainWindow::Inst().endProgress();
+
+ char message[1024];
+ sprintf(message, "Failed to open fbx file(\"%s\")", (const char*)file);
+ viewer_err(message);
+
+ return false;
+ }
+
+ AppMainWindow::Inst().endProgress();
+
+ _lastFilePath = fileInfo.absoluteDir().absolutePath();
+
+ updateUI();
+
+ return true;
+ }
+ return true;
+ */
+
+ // dir and file will get in blast open asset dialog
+ return SimpleScene::Inst()->LoadSceneFromFbx("", "");
+}
+
+void AppMainWindow::menu_addBookmark()
+{
+ QString bookmark = SimpleScene::Inst()->createBookmark();
+
+ QAction* act = new QAction(bookmark, this);
+ act->setCheckable(true);
+ _bookmarksMenu->addAction(act);
+ _bookmarkActionGroup->addAction(act);
+ act->setChecked(true);
+}
+
+void AppMainWindow::menu_editBookmarks()
+{
+ CameraBookmarksDialog dlg(this);
+ dlg.exec();
+}
+
+void AppMainWindow::menu_bookmarkTriggered(QAction* act)
+{
+ if (_actionAddBookmark != act && _actionEditBookmarks != act)
+ {
+ SimpleScene::Inst()->activateBookmark(act->text());
+ }
+}
+
+void AppMainWindow::menu_showOutput()
+{
+ bool bVisibal = ui.dockOutputWindow->isVisible();
+ ui.dockOutputWindow->setVisible(!bVisibal);
+}
+
+void AppMainWindow::menu_showAttributeEditor()
+{
+ bool bVisibal = ui.dockWidget->isVisible();
+ ui.dockWidget->setVisible(!bVisibal);
+}
+#if USE_CURVE_EDITOR
+void AppMainWindow::menu_showCurveEditor()
+{
+ bool bVisibal = ui.dockWidgetCurveEditor->isVisible();
+ ui.dockWidgetCurveEditor->setVisible(!bVisibal);
+}
+#endif
+void AppMainWindow::menu_about()
+{
+ qDebug("%s", __FUNCTION__);
+#ifndef NV_ARTISTTOOLS
+ AboutDialog::ShowAboutDialog();
+#else
+ CoreLib::Inst()->AppMainWindow_menu_about();
+#endif // NV_ARTISTTOOLS
+}
+
+void AppMainWindow::menu_opendoc()
+{
+ qDebug("%s", __FUNCTION__);
+
+#ifndef NV_ARTISTTOOLS
+ QString appDir = QApplication::applicationDirPath();
+ QString docsFile = QFileInfo(appDir + "/../../docs/User_Guide/Nvidia Blast.chm").absoluteFilePath();
+
+ QUrl docsUrl = QUrl::fromLocalFile(docsFile);
+ QUrl url = QUrl::fromUserInput(QString("http://docs.nvidia.com/gameworks/content/artisttools/hairworks/index.html"));
+ QDesktopServices::openUrl(url);
+#else
+ CoreLib::Inst()->AppMainWindow_menu_opendoc();
+#endif // NV_ARTISTTOOLS
+}
+
+void AppMainWindow::shortcut_frameall()
+{
+ qDebug("ShortCut_F: frame all");
+}
+
+void AppMainWindow::shortcut_hud()
+{
+ Gamepad::ShowHideHud();
+ qDebug("ShortCut_S: statistics on/off");
+}
+
+void AppMainWindow::shortcut_statistics()
+{
+ Gamepad::ShowHideStats();
+ qDebug("ShortCut_S: statistics on/off");
+}
+
+void AppMainWindow::shortcut_reset()
+{
+ Gamepad::ResetAnimation();
+}
+
+void AppMainWindow::shortcut_pause()
+{
+ //_mainToolbar->on_btnPlayAnimation_clicked(); // this one has some delay
+ //qDebug("ShortCut_Space: play/pause simualtion");
+ Gamepad::PlayPauseAnimation();
+}
+
+bool AppMainWindow::IsExpertMode()
+{
+ return _expertMode;
+}
+
+void AppMainWindow::demo_next()
+{
+ Gamepad::DemoNext();
+}
+
+void AppMainWindow::demo_prev()
+{
+ Gamepad::DemoPrev();
+}
+
+void AppMainWindow::shortcut_escape()
+{
+ Gamepad::DemoEscape();
+}
+
+void AppMainWindow::shortcut_expert()
+{
+ qDebug("ShortCut_F: expert mode on/off");
+
+ _expertMode = !_expertMode;
+ bool mode = !_expertMode;
+
+ ui.menuBar->setVisible(mode);
+ ui.dockWidget->setVisible(mode);
+ ui.dockOutputWindow->setVisible(mode);
+#if USE_CURVE_EDITOR
+ ui.dockWidgetCurveEditor->setVisible(mode);
+#endif
+ ui.statusBar->setVisible(mode);
+
+#ifndef NV_ARTISTTOOLS
+ if (_mainToolbar)
+ _mainToolbar->setVisible(mode);
+#else
+ CoreLib::Inst()->AppMainWindow_shortcut_expert(mode);
+#endif // NV_ARTISTTOOLS
+
+ //bool bDemoMode = AppMainWindow::IsExpertMode();
+ bool bMaxSized = AppMainWindow::Inst().isMaximized();
+ if (!bMaxSized)
+ {
+ // resize before change to demo mode
+ AppMainWindow::Inst().showMaximized();
+ }
+
+ _d3dWidget->update();
+ Gamepad::ShowProjectName();
+}
+
+void AppMainWindow::shortcut_output()
+{
+ ui.dockOutputWindow->show();
+ _d3dWidget->update();
+}
+
+void AppMainWindow::shortcut_meshmat()
+{
+}
+
+void AppMainWindow::shortcut_fitcamera()
+{
+ qDebug("ShortCut_Ctrl+F: fit camera");
+ SimpleScene::Inst()->FitCamera();
+}
+
+#if USE_CURVE_EDITOR
+void AppMainWindow::onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute)
+{
+#ifndef NV_ARTISTTOOLS
+ SimpleScene::Inst()->GetFurCharacter().updateCurveAttribute(attribute);
+#else
+ CoreLib::Inst()->AppMainWindow_onCurveAttributeChanged(attribute);
+#endif // NV_ARTISTTOOLS
+}
+
+void AppMainWindow::onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute)
+{
+#ifndef NV_ARTISTTOOLS
+ SimpleScene::Inst()->GetFurCharacter().updateColorAttribute(attribute);
+ _graphicalMaterialPanel->updateValues();
+#else
+ CoreLib::Inst()->AppMainWindow_onColorAttributeChanged(attribute);
+#endif // NV_ARTISTTOOLS
+}
+
+void AppMainWindow::onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex)
+{
+#ifndef NV_ARTISTTOOLS
+ SimpleScene::Inst()->GetFurCharacter().reloadColorAttributeTexture(attribute, reloadColorTex, selectedCtrlPntIndex);
+#else
+ CoreLib::Inst()->AppMainWindow_onReloadColorAttributeTexture(attribute, reloadColorTex, selectedCtrlPntIndex);
+#endif // NV_ARTISTTOOLS
+}
+#endif
+
+/*
+ Maya Scheme:
+ ALT + LMB -> Rotate
+ ALT + MMB -> Pan
+ ALT + RMB -> Zoom
+
+ M-wheel -> Zoom
+
+ 3dsMax Scheme:
+ ALT + MMB -> Rotate
+ N/A + MMB -> Pan
+ ALT + SHFT + MMB -> Zoom
+
+ M-wheel -> Zoom
+*/
+
+void AppMainWindow::InitMouseSchemes()
+{
+ ShortCut alt_lmb = qMakePair(Qt::KeyboardModifiers(Qt::AltModifier), Qt::MouseButtons(Qt::LeftButton));
+ ShortCut alt_mmb = qMakePair(Qt::KeyboardModifiers(Qt::AltModifier), Qt::MouseButtons(Qt::MiddleButton));
+ ShortCut alt_rmb = qMakePair(Qt::KeyboardModifiers(Qt::AltModifier), Qt::MouseButtons(Qt::RightButton));
+ ShortCut non_mmb = qMakePair(Qt::KeyboardModifiers(Qt::NoModifier), Qt::MouseButtons(Qt::MiddleButton));
+ ShortCut alt_shft_mmb = qMakePair(Qt::KeyboardModifiers(Qt::AltModifier|Qt::ShiftModifier), Qt::MouseButtons(Qt::MiddleButton));
+
+ _mayaScheme[alt_lmb] = 'R';
+ _mayaScheme[alt_mmb] = 'P';
+ _mayaScheme[alt_rmb] = 'Z';
+
+ _maxScheme[alt_mmb] = 'R';
+ _maxScheme[non_mmb] = 'P';
+ _maxScheme[alt_shft_mmb] = 'Z';
+}
+
+char AppMainWindow::TestMouseScheme( Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons )
+{
+ char op = TestDragCamera(modifiers, buttons);
+
+ if (op != 0)
+ return op;
+
+ if (modifiers == Qt::KeyboardModifier(Qt::ControlModifier))
+ {
+ if (buttons == Qt::MouseButton(Qt::LeftButton))
+ return 'L';
+ else if (buttons == Qt::MouseButton(Qt::MiddleButton))
+ return 'K';
+ }
+
+ if (modifiers == Qt::KeyboardModifier(Qt::ShiftModifier))
+ return 'W';
+
+ return 0;
+}
+
+char AppMainWindow::TestDragCamera( Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons )
+{
+ if(modifiers != Qt::NoModifier && modifiers != Qt::AltModifier) return 0;
+
+ ShortCut input = qMakePair(modifiers, buttons);
+
+ int scheme = _navigationStyle;
+
+ // !! MUST MATCH THE ORDER OF ITEMS IN 'cbNavigationStyle'
+ const int MAYA_SCHEME = 0;
+ const int MAX_SCHEME = 1;
+ if(scheme == MAYA_SCHEME)
+ {
+ auto itr = _mayaScheme.find(input);
+ if(itr != _mayaScheme.end()) return itr.value();
+ }
+ else
+ {
+ auto itr = _maxScheme.find(input);
+ if(itr != _maxScheme.end()) return itr.value();
+ }
+ return 0;
+}
+
+QString AppMainWindow::OpenTextureFile(QString title)
+{
+ QString lastDir = _lastFilePath;
+ QString titleStr = "Open Texture File";
+ if(!title.isEmpty())
+ titleStr = title;
+
+ QString fileName = QFileDialog::getOpenFileName(this, titleStr, lastDir, "Images (*.dds *.png *.bmp *.jpg *.tga)");
+ if(!fileName.isEmpty())
+ {
+ QFileInfo fileInfo(fileName);
+ _lastFilePath = fileInfo.absoluteDir().absolutePath();
+ }
+
+ return fileName;
+}
+
+void AppMainWindow::closeEvent (QCloseEvent *event)
+{
+ ViewerOutput::Inst().UnRegisterPrinter(_printer);
+
+ if (1)
+ {
+#if USE_CURVE_EDITOR
+ _curveEditorMainWindow->setParent(NULL);
+#endif
+ event->accept();
+ emit aboutToQuit();
+ return;
+ }
+ if (SimpleScene::Inst()->IsProjectModified() || SimpleScene::Inst()->IsFurModified())
+ {
+ QMessageBox::StandardButton resBtn = QMessageBox::warning(
+ this, tr("Blast Viewer"),
+ tr("Save changes?\n"),
+ QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes,
+ QMessageBox::Yes);
+ switch (resBtn)
+ {
+ case QMessageBox::Yes:
+#ifndef NV_ARTISTTOOLS
+ if (!menu_saveHair())
+ {
+ event->ignore();
+ return;
+ }
+ if (!menu_saveProject())
+ {
+ event->ignore();
+ return;
+ }
+#else
+ if (!CoreLib::Inst()->AppMainWindow_closeEvent(event))
+ {
+ event->ignore();
+ return;
+ }
+#endif // NV_ARTISTTOOLS
+ break;
+ case QMessageBox::No:
+ break;
+ default:
+ event->ignore();
+ return;
+ }
+ }
+ event->accept();
+ emit aboutToQuit();
+}
+
+void AppMainWindow::updateMainToolbar()
+{
+#ifndef NV_ARTISTTOOLS
+ if (_mainToolbar)
+ _mainToolbar->updateValues();
+#else
+ CoreLib::Inst()->AppMainWindow_updateMainToolbar();
+#endif // NV_ARTISTTOOLS
+}
+
+#ifndef NV_ARTISTTOOLS
+bool AppMainWindow::menu_openProject()
+{
+ QString lastDir = _lastFilePath;
+ QString fileName = QFileDialog::getOpenFileName(this, "Open Hair Project File", lastDir, "Hair Project File (*.furproj)");
+
+ return openProject(fileName);
+}
+
+bool AppMainWindow::menu_saveProject()
+{
+ char message[1024];
+
+ std::string projectFilePath = GlobalSettings::Inst().getAbsoluteFilePath();
+ if (projectFilePath != "")
+ {
+ if (SimpleScene::Inst()->SaveProject(
+ GlobalSettings::Inst().m_projectFileDir.c_str(),
+ GlobalSettings::Inst().m_projectFileName.c_str()
+ ) == false)
+ {
+ QMessageBox messageBox;
+
+ sprintf(message, "Project file %s could not be saved!", (const char*)projectFilePath.c_str());
+ messageBox.critical(0, "Error", message);
+ messageBox.setFixedSize(500, 200);
+ char message[1024];
+ sprintf(message, "Failed to save project file(\"%s\")", (const char*)projectFilePath.c_str());
+ viewer_err(message);
+ return false;
+ }
+
+ sprintf(message, "Project file %s was saved.", (const char*)projectFilePath.c_str());
+
+ /*
+ QMessageBox messageBox;
+ messageBox.information(0, "Info", message);
+ messageBox.setFixedSize(500,200);
+ */
+ viewer_msg(message);
+ return true;
+ }
+ else
+ {
+ return menu_saveProjectAs();
+ }
+ return false;
+}
+
+bool AppMainWindow::menu_saveProjectAs()
+{
+ char message[1024];
+
+ QString lastDir = _lastFilePath;
+ QString fileName = QFileDialog::getSaveFileName(this, "Save Hair Project File", lastDir, "Hair Project File (*.furproj)");
+ if (!fileName.isEmpty())
+ {
+ QFileInfo fileInfo(fileName);
+ QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit();
+ QByteArray file = fileInfo.fileName().toLocal8Bit();
+
+ if (SimpleScene::Inst()->SaveProject(dir, file) == false)
+ {
+ QMessageBox messageBox;
+ sprintf(message, "Project file %s could not be saved!", (const char*)file);
+ messageBox.critical(0, "Error", message);
+ messageBox.setFixedSize(500, 200);
+ return false;
+ }
+
+ sprintf(message, "Project file %s was saved.", (const char*)file);
+
+ /*
+ QMessageBox messageBox;
+ messageBox.information(0, "Info", message);
+ messageBox.setFixedSize(500,200);
+ */
+
+ viewer_msg(message);
+
+ _lastFilePath = fileInfo.absoluteDir().absolutePath();
+ return true;
+ }
+ return false;
+}
+
+bool AppMainWindow::menu_openHair()
+{
+ AppMainWindow& window = AppMainWindow::Inst();
+ QString lastDir = window._lastFilePath;
+ QString fileName = QFileDialog::getOpenFileName(&window, "Open Hair File", lastDir, "Apex Hair File (*.apx;*.apb)");
+ if (!fileName.isEmpty())
+ {
+ QFileInfo fileInfo(fileName);
+ QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit();
+ QByteArray file = fileInfo.fileName().toLocal8Bit();
+
+ if (SimpleScene::Inst()->GetFurCharacter().LoadHairAsset(dir, file) == false)
+ {
+ QMessageBox messageBox;
+ messageBox.critical(0, "Error", "File open error!");
+ messageBox.setFixedSize(500, 200);
+ char message[1024];
+ sprintf(message, "Failed to open hair file(\"%s\")", (const char*)file);
+ viewer_err(message);
+ return false;
+ }
+
+ window._lastFilePath = fileInfo.absoluteDir().absolutePath();
+
+ window.updateUI();
+ return true;
+ }
+
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// event handlers
+bool AppMainWindow::menu_importHair()
+{
+ AppMainWindow& window = AppMainWindow::Inst();
+ QString lastDir = window._lastFilePath;
+ QString fileName = QFileDialog::getOpenFileName(&window, "Import Hair File", lastDir, "Apex Hair File (*.apx;*.apb)");
+ if (!fileName.isEmpty())
+ {
+ QFileInfo fileInfo(fileName);
+ QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit();
+ QByteArray file = fileInfo.fileName().toLocal8Bit();
+
+ if (SimpleScene::Inst()->GetFurCharacter().ImportSelectedHairAsset(dir, file) == false)
+ {
+ QMessageBox messageBox;
+ messageBox.critical(0, "Error", "File open error!");
+ messageBox.setFixedSize(500, 200);
+ char message[1024];
+ sprintf(message, "Failed to import hair file(\"%s\")", (const char*)file);
+ viewer_err(message);
+ return false;
+ }
+
+ window._lastFilePath = fileInfo.absoluteDir().absolutePath();
+
+ window.updateUI();
+ return true;
+ }
+ return false;
+}
+
+
+bool AppMainWindow::menu_saveHair()
+{
+ return SimpleScene::Inst()->GetFurCharacter().SaveHairAsset();
+}
+
+bool AppMainWindow::menu_saveHairAs()
+{
+ AppMainWindow& window = AppMainWindow::Inst();
+ QString lastDir = window._lastFilePath;
+ QString fileName = QFileDialog::getSaveFileName(&window, "Save as", lastDir, "Apex Hair File (*.apx;*.apb)");
+ if (!fileName.isEmpty())
+ {
+ QFileInfo fileInfo(fileName);
+ QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit();
+ QByteArray file = fileInfo.fileName().toLocal8Bit();
+
+ if (SimpleScene::Inst()->GetFurCharacter().SaveHairAssetAs(dir, file))
+ {
+ window.updateUI();
+ }
+
+ window._lastFilePath = fileInfo.absoluteDir().absolutePath();
+ return true;
+ }
+ return false;
+}
+
+bool AppMainWindow::menu_saveAllHairs()
+{
+ return SimpleScene::Inst()->GetFurCharacter().SaveAllHairs();
+}
+#endif // NV_ARTISTTOOLS \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h b/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h
new file mode 100644
index 0000000..4183fc2
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h
@@ -0,0 +1,208 @@
+#ifndef APPMAINWINDOW_H
+#define APPMAINWINDOW_H
+
+#include <QtWidgets/QMainWindow>
+#include <QtWidgets/QProgressDialog>
+
+#include "ui_AppMainWindow.h"
+#include "UIGlobal.h"
+
+class StyleMaterialPanel;
+class AssetControlPanel;
+class PhysicalMaterialPanel;
+class GraphicalMaterialPanel;
+class DisplayFurVisualizersPanel;
+class GeneralAttributePanel;
+class BlastToolbar;
+class LodPanel;
+class DisplayMeshesPanel;
+class DisplayPreferencesPanel;
+class DisplayScenePanel;
+class DisplayLightPanel;
+class DisplayMeshMaterialsPanel;
+
+#if USE_CURVE_EDITOR
+namespace nvidia {
+namespace CurveEditor {
+
+class CurveEditorMainWindow;
+class CurveAttribute;
+class ColorAttribute;
+
+} // namespace CurveEditor
+} // namespace nvidia
+#endif
+
+#if USE_MATERIAL_SET
+class MaterialSetPanel;
+#endif
+
+class D3DWidget;
+class MsgPrinter;
+class AppMainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ AppMainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ ~AppMainWindow();
+
+ CORELIB_EXPORT static AppMainWindow& Inst();
+
+ CORELIB_EXPORT void InitUI();
+ CORELIB_EXPORT void updateUI();
+ CORELIB_EXPORT void updatePluginUI();
+
+ static bool IsExpertMode();
+
+ D3DWidget* GetRenderWidget() {return _d3dWidget;}
+ char TestMouseScheme(Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons);
+
+ CORELIB_EXPORT QString OpenTextureFile(QString title = "");
+
+ void setNavigationStyle(int index) { _navigationStyle = index; }
+ int getNavigationStyle() { return _navigationStyle; }
+
+ void closeEvent (QCloseEvent *event);
+
+ CORELIB_EXPORT void startProgress();
+ CORELIB_EXPORT void setProgressMaximum(int m);
+ CORELIB_EXPORT void setProgress(const char* label, int progress = -1);
+ CORELIB_EXPORT void endProgress();
+ CORELIB_EXPORT void quit();
+
+ CORELIB_EXPORT void updateMainToolbar();
+ CORELIB_EXPORT void processDragAndDrop(QString fname);
+ CORELIB_EXPORT bool openProject(QString fileName);
+
+ CORELIB_EXPORT static void setConnectionMode(int);
+
+ DisplayMeshesPanel* GetDisplayMeshesPanel() { return _displayMeshesPanel; }
+ DisplayPreferencesPanel* GetDisplayPreferencesPanel() { return _displayPreferencesPanel; }
+ DisplayScenePanel* GetDisplayScenePanel() { return _displayScenePanel; }
+ DisplayLightPanel* GetDisplayLightPanel() { return _displayLightPanel; }
+
+ void removeBookmark(const QString& name);
+ void renameBookmark(const QString& oldName, const QString& newName);
+
+#if USE_CURVE_EDITOR
+ CORELIB_EXPORT nvidia::CurveEditor::CurveEditorMainWindow* GetCurveEditorMainWindow() { return _curveEditorMainWindow; }
+ CORELIB_EXPORT void UpdateCurveEditor();
+ CORELIB_EXPORT void ShowCurveEditor(int paramId);
+#endif
+
+ inline QString GetFilePath() { return _lastFilePath; }
+signals:
+ void aboutToQuit();
+
+ public slots:
+ CORELIB_EXPORT void menu_clearScene();
+ CORELIB_EXPORT bool menu_openfbx();
+ CORELIB_EXPORT void menu_addBookmark();
+ CORELIB_EXPORT void menu_editBookmarks();
+ CORELIB_EXPORT void menu_bookmarkTriggered(QAction* act);
+ CORELIB_EXPORT void menu_showOutput();
+ CORELIB_EXPORT void menu_showAttributeEditor();
+ CORELIB_EXPORT void menu_about();
+ CORELIB_EXPORT void menu_opendoc();
+ CORELIB_EXPORT void shortcut_frameall();
+ CORELIB_EXPORT void shortcut_hud();
+ CORELIB_EXPORT void shortcut_statistics();
+ CORELIB_EXPORT void shortcut_pause();
+ CORELIB_EXPORT void shortcut_reset();
+ CORELIB_EXPORT void shortcut_escape();
+ CORELIB_EXPORT void shortcut_expert();
+ CORELIB_EXPORT void demo_next();
+ CORELIB_EXPORT void demo_prev();
+ CORELIB_EXPORT void shortcut_output();
+ CORELIB_EXPORT void shortcut_meshmat();
+ CORELIB_EXPORT void shortcut_fitcamera();
+
+#if USE_CURVE_EDITOR
+ CORELIB_EXPORT void menu_showCurveEditor();
+ CORELIB_EXPORT void onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute);
+ CORELIB_EXPORT void onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute);
+ CORELIB_EXPORT void onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex);
+#endif
+
+private:
+ char TestDragCamera(Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons);
+
+public:
+ void InitMenuItems();
+ void InitToolbar();
+ void InitPluginTab();
+ void InitMainTab();
+ void InitMouseSchemes();
+ void InitShortCuts();
+ void updateBookmarkMenu();
+
+ Ui::AppMainWindowClass ui;
+
+ D3DWidget* _d3dWidget;
+ QMenu* _bookmarksMenu;
+
+ DisplayMeshesPanel* _displayMeshesPanel;
+ DisplayPreferencesPanel* _displayPreferencesPanel;
+ DisplayScenePanel* _displayScenePanel;
+ DisplayLightPanel* _displayLightPanel;
+
+
+#if USE_CURVE_EDITOR
+ bool _curveEditorInitizlized;
+ nvidia::CurveEditor::CurveEditorMainWindow* _curveEditorMainWindow;
+#endif
+
+ typedef QPair<Qt::KeyboardModifiers, Qt::MouseButtons> ShortCut;
+ QMap<ShortCut, char> _mayaScheme;
+ QMap<ShortCut, char> _maxScheme;
+ QActionGroup* _bookmarkActionGroup;
+ QAction* _actionAddBookmark;
+ QAction* _actionEditBookmarks;
+
+ QString _lastFilePath;
+
+ int _navigationStyle;
+
+ MsgPrinter* _printer;
+
+ QProgressDialog _progressDialog;
+
+
+ static bool _expertMode;
+
+ CORELIB_EXPORT static int _connectionMode;
+
+#ifndef NV_ARTISTTOOLS
+ BlastToolbar* GetMainToolbar() { return _mainToolbar; }
+ DisplayFurVisualizersPanel* GetFurVisualizersPanel() { return _displayFurVisualizersPanel; }
+
+public slots:
+ bool menu_openProject();
+ bool menu_saveProject();
+ bool menu_saveProjectAs();
+ bool menu_openHair();
+ bool menu_importHair();
+ bool menu_saveHair();
+ bool menu_saveHairAs();
+ bool menu_saveAllHairs();
+
+private:
+ BlastToolbar* _mainToolbar;
+ AssetControlPanel* _assetControlPanel;
+ GeneralAttributePanel* _generalAttributePanel;
+ DisplayFurVisualizersPanel* _displayFurVisualizersPanel;
+ StyleMaterialPanel* _styleMaterialPanel;
+ PhysicalMaterialPanel* _physicalMaterialPanel;
+ GraphicalMaterialPanel* _graphicalMaterialPanel;
+ LodPanel* _lodPanel;
+ DisplayMeshMaterialsPanel* _displayMeshMaterialsPanel;
+#if USE_MATERIAL_SET
+ MaterialSetPanel* _materialSetPanel;
+#endif
+#endif // NV_ARTISTTOOLS
+
+ bool m_bGizmoWithLocal;
+};
+
+#endif // APPMAINWINDOW_H
diff --git a/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.cpp b/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.cpp
new file mode 100644
index 0000000..445067a
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.cpp
@@ -0,0 +1,106 @@
+#include "CameraBookmarksDialog.h"
+#include "SimpleScene.h"
+#include "AppMainWindow.h"
+#include <QtWidgets/QMessageBox>
+
+CameraBookmarksDialog::CameraBookmarksDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ ui.setupUi(this);
+
+ ui.buttonBox->button(QDialogButtonBox::Ok)->setFixedWidth(64);
+ ui.buttonBox->button(QDialogButtonBox::Cancel)->setFixedWidth(64);
+ ui.buttonBox->button(QDialogButtonBox::Ok)->setFixedHeight(23);
+ ui.buttonBox->button(QDialogButtonBox::Cancel)->setFixedHeight(23);
+ setWindowFlags(windowFlags()&~Qt::WindowContextHelpButtonHint);
+
+ QObject::connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept()));
+ QObject::connect(ui.buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject()));
+
+ ui.editBookmarkName->setEnabled(false);
+ ui.btnRename->setEnabled(false);
+ ui.btnDelete->setEnabled(false);
+
+ _fillListWidget();
+}
+
+CameraBookmarksDialog::~CameraBookmarksDialog()
+{
+
+}
+
+void CameraBookmarksDialog::on_listWidgetBookmarks_itemSelectionChanged()
+{
+ if (ui.listWidgetBookmarks->selectedItems().size() == 0)
+ {
+ ui.editBookmarkName->setEnabled(false);
+ ui.btnRename->setEnabled(false);
+ ui.btnDelete->setEnabled(false);
+ }
+ else
+ {
+ QListWidgetItem* item = ui.listWidgetBookmarks->selectedItems().at(0);
+ ui.editBookmarkName->setEnabled(true);
+ ui.btnRename->setEnabled(true);
+ ui.btnDelete->setEnabled(true);
+
+ ui.editBookmarkName->setText(item->text());
+ }
+}
+
+void CameraBookmarksDialog::on_editBookmarkName_textChanged(QString val)
+{
+
+}
+
+void CameraBookmarksDialog::on_btnRename_clicked()
+{
+ if (ui.editBookmarkName->text().isEmpty())
+ {
+ QListWidgetItem* item = ui.listWidgetBookmarks->selectedItems().at(0);
+ ui.editBookmarkName->setText(item->text());
+ }
+ else
+ {
+ if (_isNameConflict(ui.editBookmarkName->text()))
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("The new name is conflict with name of other camera bookmark!"));
+ return;
+ }
+
+ QListWidgetItem* item = ui.listWidgetBookmarks->selectedItems().at(0);
+ SimpleScene::Inst()->renameBookmark(item->text(), ui.editBookmarkName->text());
+ AppMainWindow::Inst().renameBookmark(item->text(), ui.editBookmarkName->text());
+ item->setText(ui.editBookmarkName->text());
+ }
+
+}
+
+void CameraBookmarksDialog::on_btnDelete_clicked()
+{
+ QListWidgetItem* item = ui.listWidgetBookmarks->selectedItems().at(0);
+ SimpleScene::Inst()->removeBookmark(item->text());
+ AppMainWindow::Inst().removeBookmark(item->text());
+ ui.listWidgetBookmarks->takeItem(ui.listWidgetBookmarks->row(item));
+ delete item;
+
+}
+
+void CameraBookmarksDialog::_fillListWidget()
+{
+ QList<QString> bookmarks = SimpleScene::Inst()->getBookmarkNames();
+ ui.listWidgetBookmarks->addItems(bookmarks);
+}
+
+bool CameraBookmarksDialog::_isNameConflict(const QString& name)
+{
+ QList<QString> bookmarks = SimpleScene::Inst()->getBookmarkNames();
+ int bookmarkCount = bookmarks.size();
+ for (int i = 0; i < bookmarkCount; ++i)
+ {
+ if (bookmarks.at(i) == name)
+ return true;
+ }
+
+ return false;
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.h b/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.h
new file mode 100644
index 0000000..13caa42
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.h
@@ -0,0 +1,31 @@
+#ifndef CAMERABOOKMARKSDIALOG_H
+#define CAMERABOOKMARKSDIALOG_H
+
+#include <QtWidgets/QDialog>
+#include "ui_CameraBookmarksDialog.h"
+
+#include "corelib_global.h"
+
+class CameraBookmarksDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ CameraBookmarksDialog(QWidget *parent = 0);
+ ~CameraBookmarksDialog();
+
+private slots:
+CORELIB_EXPORT void on_listWidgetBookmarks_itemSelectionChanged();
+CORELIB_EXPORT void on_editBookmarkName_textChanged(QString val);
+CORELIB_EXPORT void on_btnRename_clicked();
+CORELIB_EXPORT void on_btnDelete_clicked();
+
+private:
+ void _fillListWidget();
+ bool _isNameConflict(const QString& name);
+
+private:
+ Ui::CameraBookmarksDialog ui;
+};
+
+#endif // CAMERABOOKMARKSDIALOG_H
diff --git a/tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp b/tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp
new file mode 100644
index 0000000..69be706
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp
@@ -0,0 +1,151 @@
+#include <QtGui/QResizeEvent>
+#include <QtGui/QMouseEvent>
+#include <QtCore/QTimer>
+#include <QtCore/QMimeData>
+
+#include "D3DWidget.h"
+#include "AppMainWindow.h"
+#include "SimpleScene.h"
+
+D3DWidget::D3DWidget( QWidget* parent )
+ : QWidget(parent, Qt::MSWindowsOwnDC) // Same settings as used in Qt's QGLWidget
+{
+ // same settings as used in QGLWidget to avoid 'white flickering'
+ setAttribute(Qt::WA_PaintOnScreen);
+ setAttribute(Qt::WA_NoSystemBackground);
+
+ // to get rid of 'black flickering'
+ setAttribute(Qt::WA_OpaquePaintEvent, true);
+
+ QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ sizePolicy.setHorizontalStretch(0);
+ sizePolicy.setVerticalStretch(0);
+ setSizePolicy(sizePolicy);
+
+ _appWindow = qobject_cast<AppMainWindow*>(parent);
+ this->setAcceptDrops(true);
+
+ setMouseTracking(true);
+}
+
+void D3DWidget::dragEnterEvent(QDragEnterEvent *e)
+{
+ CoreLib::Inst()->D3DWidget_dragEnterEvent(e);
+ e->acceptProposedAction();
+}
+
+void D3DWidget::dragMoveEvent(QDragMoveEvent *e)
+{
+ CoreLib::Inst()->D3DWidget_dragMoveEvent(e);
+ e->acceptProposedAction();
+}
+
+void D3DWidget::dragLeaveEvent(QDragLeaveEvent *e)
+{
+ CoreLib::Inst()->D3DWidget_dragLeaveEvent(e);
+ //e->acceptProposedAction();
+}
+
+void D3DWidget::dropEvent(QDropEvent *e)
+{
+ CoreLib::Inst()->D3DWidget_dropEvent(e);
+
+ const QMimeData* data = e->mimeData();
+ QString name = data->objectName();
+
+ bool hasUrls = data->hasUrls();
+ if (!hasUrls)
+ return;
+
+ QList<QUrl> urlList = data->urls();
+ QString text;
+ for (int i = 0; i < urlList.size() && i < 32; ++i) {
+ QString url = urlList.at(i).toLocalFile();
+ text += url;
+ }
+
+ e->acceptProposedAction();
+
+ AppMainWindow::Inst().processDragAndDrop(text);
+}
+
+void D3DWidget::paintEvent( QPaintEvent* e )
+{
+ CoreLib::Inst()->D3DWidget_paintEvent(e);
+
+ SimpleScene::Inst()->Draw();
+}
+
+void D3DWidget::Shutdown()
+{
+ SimpleScene::Inst()->Shutdown();
+}
+
+void D3DWidget::Timeout()
+{
+ SimpleScene::Inst()->Timeout();
+}
+
+void D3DWidget::resizeEvent( QResizeEvent* e )
+{
+ int w = e->size().width();
+ int h = e->size().height();
+ // resize calls D3D11RenderWindow::Resize
+ SimpleScene::Inst()->Resize(w,h);
+ // D3DWidget_resizeEvent calls resize in DeviceManager
+ CoreLib::Inst()->D3DWidget_resizeEvent(e);
+}
+
+void D3DWidget::mouseMoveEvent( QMouseEvent* e )
+{
+ CoreLib::Inst()->D3DWidget_mouseMoveEvent(e);
+
+ atcore_float2 pos = gfsdk_makeFloat2(e->x(), e->y());
+ SimpleScene::Inst()->onMouseMove(pos);
+
+ Q_ASSERT(_appWindow != NV_NULL);
+ char mode = _appWindow->TestMouseScheme(e->modifiers(), e->buttons());
+
+ if(mode == 0) return;
+ SimpleScene::Inst()->Drag(mode);
+}
+
+void D3DWidget::wheelEvent(QWheelEvent* e)
+{
+ CoreLib::Inst()->D3DWidget_wheelEvent(e);
+
+ SimpleScene::Inst()->onMouseWheel(e->delta());
+ SimpleScene::Inst()->WheelZoom();
+}
+
+void D3DWidget::mousePressEvent( QMouseEvent* e )
+{
+ CoreLib::Inst()->D3DWidget_mousePressEvent(e);
+
+ atcore_float2 pos = gfsdk_makeFloat2(e->x(), e->y());
+ SimpleScene::Inst()->onMouseDown(pos);
+}
+
+void D3DWidget::mouseReleaseEvent( QMouseEvent* e )
+{
+ CoreLib::Inst()->D3DWidget_mouseReleaseEvent(e);
+
+ atcore_float2 pos = gfsdk_makeFloat2(e->x(), e->y());
+ SimpleScene::Inst()->onMouseUp(pos);
+}
+
+void D3DWidget::keyPressEvent( QKeyEvent* e )
+{
+ CoreLib::Inst()->D3DWidget_keyPressEvent(e);
+}
+
+void D3DWidget::keyReleaseEvent( QKeyEvent* e )
+{
+ CoreLib::Inst()->D3DWidget_keyReleaseEvent(e);
+}
+
+void D3DWidget::contextMenuEvent(QContextMenuEvent *e)
+{
+ CoreLib::Inst()->D3DWidget_contextMenuEvent(e);
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Window/D3DWidget.h b/tools/ArtistTools/source/CoreLib/Window/D3DWidget.h
new file mode 100644
index 0000000..0de9a1e
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/D3DWidget.h
@@ -0,0 +1,51 @@
+#ifndef D3DWidget_h__
+#define D3DWidget_h__
+
+#include <QtWidgets/QWidget>
+#include "Nv.h"
+
+#include "corelib_global.h"
+
+class AppMainWindow;
+class D3DWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+
+ D3DWidget(QWidget* parent);
+ virtual ~D3DWidget(){}
+
+signals:
+ void DropSignal();
+
+public slots:
+CORELIB_EXPORT void Timeout();
+CORELIB_EXPORT void Shutdown();
+
+protected:
+ // return NULL to ignore system painter
+ virtual QPaintEngine *paintEngine() const { return NV_NULL; }
+
+ // QWidget events
+ virtual void resizeEvent(QResizeEvent* e);
+ virtual void paintEvent(QPaintEvent* e);
+ virtual void mousePressEvent(QMouseEvent* e);
+ virtual void mouseReleaseEvent(QMouseEvent* e);
+ virtual void mouseMoveEvent(QMouseEvent* e);
+ virtual void wheelEvent ( QWheelEvent * e);
+ virtual void keyPressEvent(QKeyEvent* e);
+ virtual void keyReleaseEvent(QKeyEvent* e);
+
+ virtual void dragEnterEvent(QDragEnterEvent *e);
+ virtual void dragMoveEvent(QDragMoveEvent *e);
+ virtual void dragLeaveEvent(QDragLeaveEvent *e);
+ virtual void dropEvent(QDropEvent *e);
+
+ virtual void contextMenuEvent(QContextMenuEvent *e);
+
+private:
+ AppMainWindow* _appWindow;
+};
+
+#endif // D3DWidget_h__
diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.cpp b/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.cpp
new file mode 100644
index 0000000..ec267a3
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.cpp
@@ -0,0 +1,263 @@
+#include "AppMainWindow.h"
+#include "DisplayLightPanel.h"
+
+#include "Light.h"
+#include "GlobalSettings.h"
+
+#include <QtWidgets/QColorDialog>
+#include <QtCore/QFileInfo>
+
+DisplayLightPanel::DisplayLightPanel(QWidget* parent)
+ :
+ QWidget(parent)
+{
+ ui.setupUi(this);
+ _isUpdatingUI = false;
+
+ ConfigSpinBox<SlideSpinBoxF>(ui.spinLightDistance, 0.0, 1000.0, 0.1);
+ ConfigSpinBox<SlideSpinBoxF>(ui.spinLightIntensity, 0.0, 5.0, 0.01);
+
+ ui.btnLightColorTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png"));
+ ui.btnLightColorTex->setIconSize(QSize(12,12));
+ ui.btnLightColorTexReload->setIcon(QIcon(":/AppMainWindow/images/Refresh_icon.png"));
+ ui.btnLightColorTexClear->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png"));
+
+ connect(ui.listSelectedLight, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged()));
+}
+
+void DisplayLightPanel::onListSelectionChanged()
+{
+ if (_isUpdatingUI)
+ return;
+
+ int numSelected = ui.listSelectedLight->selectedItems().count();
+
+ // change selection only when there is something selected
+ if (numSelected > 0)
+ {
+ int numItems = ui.listSelectedLight->count();
+ {
+ for (int i = 0; i < numItems; i++)
+ {
+ bool selected = ui.listSelectedLight->item(i)->isSelected();
+ Light::GetLight(i)->m_selected = selected;
+ }
+ }
+ }
+
+ updateUI();
+}
+
+void DisplayLightPanel::on_cbShadowMapResolution_currentIndexChanged( int index )
+{
+ for (int i = 0; i < 4; i++)
+ {
+ Light* pLight = Light::GetLight(i);
+ if (!pLight || !pLight->m_selected)
+ continue;
+
+ pLight->SetShadowMapResolution(index);
+ }
+}
+
+void DisplayLightPanel::on_btnLightUseShadow_stateChanged(int state)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ Light* pLight = Light::GetLight(i);
+ if (!pLight || !pLight->m_selected)
+ continue;
+
+ pLight->m_useShadows = state;
+ }
+}
+
+void DisplayLightPanel::on_btnVisualizeLight_stateChanged(int state)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ Light* pLight = Light::GetLight(i);
+ if (!pLight || !pLight->m_selected)
+ continue;
+
+ pLight->m_visualize = state;
+ }
+}
+
+void DisplayLightPanel::on_btnLightEnable_stateChanged(int state)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ Light* pLight = Light::GetLight(i);
+ if (!pLight || !pLight->m_selected)
+ continue;
+
+ pLight->m_enable = state;
+ }
+}
+
+void DisplayLightPanel::on_btnLinkLightEnable_stateChanged(int state)
+{
+ Light::SetLinkLightOption(state != 0 ? true : false);
+}
+
+void DisplayLightPanel::on_spinLightDistance_valueChanged(double v)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ Light* pLight = Light::GetLight(i);
+ if (!pLight || !pLight->m_selected)
+ continue;
+
+ pLight->SetDistance(v);
+ }
+}
+
+void DisplayLightPanel::on_spinLightIntensity_valueChanged(double v)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ Light* pLight = Light::GetLight(i);
+ if (!pLight || !pLight->m_selected)
+ continue;
+
+ pLight->m_intensity = v;
+ }
+}
+
+void DisplayLightPanel::on_btnVisualizeShadowMap_stateChanged(int state)
+{
+ GlobalSettings::Inst().m_visualizeShadowMap = state;
+}
+
+void DisplayLightPanel::setButtonColor(QPushButton *button, float r, float g, float b)
+{
+ QColor specColor;
+ specColor.setRgbF(r,g,b);
+ QString specBtnStyle = QString("background-color: rgb(%1,%2,%3);")
+ .arg(specColor.red())
+ .arg(specColor.green())
+ .arg(specColor.blue());
+ button->setStyleSheet(specBtnStyle);
+}
+
+
+static bool getNewColor(atcore_float3& color)
+{
+ QColor currentColor;
+ currentColor.setRgbF(color.x, color.y, color.z);
+
+ QColor newColor = QColorDialog::getColor(currentColor, NV_NULL);
+ if(newColor.isValid())
+ {
+ qreal r,g,b;
+ newColor.getRgbF(&r, &g, &b);
+
+ color.x = r;
+ color.y = g;
+ color.z = b;
+ return true;
+ }
+
+ return false;
+}
+
+void DisplayLightPanel::on_btnLightColor_clicked()
+{
+ Light* pLight = Light::GetFirstSelectedLight();
+
+ atcore_float3 color = pLight->m_color;
+
+ if (getNewColor(color))
+ setButtonColor(ui.btnLightColor, color.x, color.y, color.z);
+
+ for (int i = 0; i < 4; i++)
+ {
+ Light* pLight = Light::GetLight(i);
+ if (!pLight || !pLight->m_selected)
+ continue;
+
+ pLight->m_color = color;
+ }
+}
+
+inline void SetTextureIcon(QPushButton* pButton, bool enabled)
+{
+ if (enabled)
+ pButton->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png"));
+ else
+ pButton->setIcon(QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png"));
+}
+
+void DisplayLightPanel::on_btnLightColorTex_clicked()
+{
+ QString texName = AppMainWindow::Inst().OpenTextureFile();
+ QFileInfo fileInfo(texName);
+ QByteArray ba = fileInfo.absoluteFilePath().toLocal8Bit();
+
+ if (Light::SetEnvTextureFromFilePath((const char*)ba))
+ SetTextureIcon(ui.btnLightColorTex, Light::GetEnvTextureFilePath().empty());
+}
+
+void DisplayLightPanel::on_btnLightColorTexReload_clicked()
+{
+ std::string path = Light::GetEnvTextureFilePath();
+ if (Light::SetEnvTextureFromFilePath(path.c_str()))
+ SetTextureIcon(ui.btnLightColorTex, Light::GetEnvTextureFilePath().empty());
+}
+
+void DisplayLightPanel::on_btnLightColorTexClear_clicked()
+{
+ Light::SetEnvTextureFromFilePath(nullptr);
+ SetTextureIcon(ui.btnLightColorTex, Light::GetEnvTextureFilePath().empty());
+}
+
+void DisplayLightPanel::updateUI()
+{
+ Light* pLight = Light::GetFirstSelectedLight();
+ if (!pLight)
+ return;
+
+ atcore_float3& color = pLight->m_color;
+ setButtonColor(ui.btnLightColor, color.x, color.y, color.z);
+
+ ui.btnVisualizeLight->setChecked(pLight->m_visualize);
+
+ ui.spinLightDistance->setValue(pLight->GetDistance());
+ ui.spinLightIntensity->setValue(pLight->m_intensity);
+
+ ui.btnLightUseShadow->setChecked(pLight->m_useShadows);
+ ui.btnLightEnable->setChecked(pLight->m_enable);
+
+ ui.btnVisualizeShadowMap->setChecked(GlobalSettings::Inst().m_visualizeShadowMap);
+
+ ui.cbShadowMapResolution->setCurrentIndex(pLight->m_shadowMapResolutionIndex);
+
+ ui.btnLinkLightEnable->setChecked(Light::GetLinkLightOption());
+
+ SetTextureIcon(ui.btnLightColorTex, Light::GetEnvTextureFilePath().empty());
+}
+
+void DisplayLightPanel::updateValues()
+{
+ _isUpdatingUI = true;
+
+ ui.listSelectedLight->clear();
+ for (int i = 0; i < 4; i++)
+ {
+ Light* pLight = Light::GetLight(i);
+ if (!pLight)
+ continue;
+
+ const char* lightName = pLight->m_name.c_str();
+ bool selected = pLight->m_selected;
+
+ ui.listSelectedLight->addItem(lightName);
+ ui.listSelectedLight->item(i)->setSelected(selected);
+ }
+ ui.listSelectedLight->setSelectionMode(QAbstractItemView::ExtendedSelection);
+
+ updateUI();
+
+ _isUpdatingUI = false;
+}
diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.h b/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.h
new file mode 100644
index 0000000..e22eae4
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.h
@@ -0,0 +1,47 @@
+#ifndef DisplayLightPanel_h__
+#define DisplayLightPanel_h__
+
+#include <QtWidgets/QWidget>
+#include "ui_DisplayLightPanel.h"
+
+#include "corelib_global.h"
+
+class DisplayLightPanel : public QWidget
+{
+ Q_OBJECT
+
+public:
+ DisplayLightPanel(QWidget* parent);
+
+ public:
+ CORELIB_EXPORT void updateValues();
+
+ public slots:
+ CORELIB_EXPORT void onListSelectionChanged();
+
+ CORELIB_EXPORT void on_spinLightDistance_valueChanged(double v);
+ CORELIB_EXPORT void on_spinLightIntensity_valueChanged(double v);
+
+ CORELIB_EXPORT void on_btnLightUseShadow_stateChanged(int state);
+ CORELIB_EXPORT void on_btnVisualizeLight_stateChanged(int state);
+ CORELIB_EXPORT void on_btnLightEnable_stateChanged(int state);
+ CORELIB_EXPORT void on_btnLinkLightEnable_stateChanged(int state);
+
+ CORELIB_EXPORT void on_btnLightColor_clicked();
+ CORELIB_EXPORT void on_btnLightColorTex_clicked();
+ CORELIB_EXPORT void on_btnLightColorTexReload_clicked();
+ CORELIB_EXPORT void on_btnLightColorTexClear_clicked();
+
+ CORELIB_EXPORT void on_btnVisualizeShadowMap_stateChanged(int state);
+
+ CORELIB_EXPORT void on_cbShadowMapResolution_currentIndexChanged(int index);
+
+private:
+ Ui::DisplayLightPanel ui;
+ bool _isUpdatingUI;
+ void setButtonColor(QPushButton *button, float r, float g, float b);
+
+ void updateUI();
+};
+
+#endif
diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.cpp b/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.cpp
new file mode 100644
index 0000000..67ca141
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.cpp
@@ -0,0 +1,177 @@
+#include "DisplayMeshesPanel.h"
+
+#include <QtWidgets/QGridLayout>
+#include <QtWidgets/QHBoxLayout>
+#include <QtWidgets/QPushButton>
+
+#include "AppMainWindow.h"
+
+#include "SimpleScene.h"
+
+#ifndef NV_ARTISTTOOLS
+#include "FurCharacter.h"
+#else
+#endif // NV_ARTISTTOOLS
+
+//////////////////////////////////////////////////////////////////////////
+// DisplayMeshItem
+
+StateViewItem::StateViewItem( QWidget* parent, unsigned int id, MeshViewState view /*= VS_VISIABLE*/ )
+ : _id(id)
+{
+ static QIcon iconVisible(":/AppMainWindow/images/visibilityToggle_visible.png");
+ static QIcon iconNotVisible(":/AppMainWindow/images/visibilityToggle_notVisible.png");
+
+ _parent = qobject_cast<DisplayMeshesPanel*>(parent);
+
+ _layout = new QHBoxLayout(this);
+ _layout->setObjectName(QString::fromUtf8("boxLayout"));
+ _layout->setMargin(0);
+
+ this->setLayout(_layout);
+
+ _btn = new QPushButton(this);
+
+ _btn->setObjectName(QString::fromUtf8("btnToggleView"));
+ QSizePolicy sizePolicy1(QSizePolicy::Ignored, QSizePolicy::Fixed);
+ sizePolicy1.setHorizontalStretch(0);
+ sizePolicy1.setVerticalStretch(0);
+ sizePolicy1.setHeightForWidth(_btn->sizePolicy().hasHeightForWidth());
+ _btn->setSizePolicy(sizePolicy1);
+ _btn->setMinimumSize(QSize(16, 16));
+ _btn->setMaximumSize(QSize(16, 16));
+ _btn->setAutoFillBackground(false);
+ _btn->setCheckable(true);
+ _btn->setChecked(view == VS_VISIABLE);
+ _btn->setIcon( (view == VS_VISIABLE) ? iconVisible : iconNotVisible);
+
+ _layout->addWidget(_btn);
+
+ _spacer = new QSpacerItem(20, 40, QSizePolicy::Expanding, QSizePolicy::Ignored);
+ _layout->addItem(_spacer);
+
+ QMetaObject::connectSlotsByName(this);
+}
+
+void StateViewItem::on_btnToggleView_clicked()
+{
+ static QIcon iconVisible(":/AppMainWindow/images/visibilityToggle_visible.png");
+ static QIcon iconNotVisible(":/AppMainWindow/images/visibilityToggle_notVisible.png");
+
+ bool bVis = _btn->isChecked();
+ _btn->setIcon(bVis ? iconVisible : iconNotVisible);
+
+ _parent->EmitToggleSignal(_id, bVis);
+
+ qDebug("%s", __FUNCTION__);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+DisplayMeshesPanel::DisplayMeshesPanel( QWidget* parent )
+ :QFrame(parent)
+{
+ _layout = new QGridLayout(this);
+ _layout->setObjectName(QString::fromUtf8("gridLayout"));
+
+ this->setLayout(_layout);
+
+ //QString styleSheet =
+ // "QPushButton#btnToggleView:checked {border:2px solid gray; background:rgb(118,180,0);} \n" \
+ // "QPushButton#btnToggleView:pressed {border:2px solid gray; background:rgb(118,180,0);}";
+ //setStyleSheet(styleSheet);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+void DisplayMeshesPanel::updateValues()
+{
+ ClearItems();
+
+#ifndef NV_ARTISTTOOLS
+ FurCharacter& character = SimpleScene::Inst()->GetFurCharacter();
+ int nMesh = character.GetMeshCount();
+ for (int i = 0; i < nMesh; ++i)
+ {
+ bool used = character.GetMeshUsed(i);
+ if (!used)
+ continue;
+
+ const char* name = character.GetMeshName(i);
+ bool visible = character.GetMeshVisible(i);
+
+ StateViewItem::MeshViewState visState = visible ? StateViewItem::VS_VISIABLE : StateViewItem::VS_INVISIBLE;
+
+ AddMeshItem(QString(name), i, visState);
+ }
+#else
+ CoreLib::Inst()->DisplayMeshesPanel_updateValues();
+#endif // NV_ARTISTTOOLS
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+void DisplayMeshesPanel::AddMeshItem( QString name, unsigned int id, StateViewItem::MeshViewState view )
+{
+ StateViewItem* item;
+ item = new StateViewItem(this, id, view);
+
+ QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ sizePolicy1.setHorizontalStretch(0);
+ sizePolicy1.setVerticalStretch(0);
+
+ QLabel* label = new QLabel(name, this);
+ label->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+ label->setSizePolicy(sizePolicy1);
+
+ int row = _items.size();
+ _layout->addWidget(label, row, 0, 1, 1);
+
+ _layout->addWidget(item, row, 1, 1, 1);
+
+ Q_ASSERT(_items.find(id) == _items.end());
+
+ ItemUI ui;
+ ui.label = label;
+ ui.viewItem = item;
+ _items[id] = ui;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+void DisplayMeshesPanel::EmitToggleSignal( unsigned int id, bool visible )
+{
+ emit MeshViewSignal(id, visible);
+
+#ifndef NV_ARTISTTOOLS
+ FurCharacter& character = SimpleScene::Inst()->GetFurCharacter();
+ character.SetMeshVisible(id, visible);
+#else
+ CoreLib::Inst()->DisplayMeshesPanel_EmitToggleSignal(id, visible);
+#endif // NV_ARTISTTOOLS
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+void DisplayMeshesPanel::RemoveMeshItem( unsigned int id )
+{
+ if(_items.find(id) != _items.end())
+ {
+ ItemUI ui = _items[id];
+ delete ui.label;
+ delete ui.viewItem;
+ _items.remove(id);
+ }
+ else
+ {
+ Q_ASSERT("Mesh item doesn't exist!!");
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+void DisplayMeshesPanel::ClearItems()
+{
+ Q_FOREACH(ItemUI ui, _items)
+ {
+ delete ui.label;
+ delete ui.viewItem;
+ }
+
+ _items.clear();
+}
diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.h b/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.h
new file mode 100644
index 0000000..ecc5b49
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.h
@@ -0,0 +1,80 @@
+#ifndef DisplayMeshesPanel_h__
+#define DisplayMeshesPanel_h__
+
+#include <QtWidgets/QFrame>
+#include <QtCore/QMap>
+#ifndef NV_ARTISTTOOLS
+#include "ui_LodPanel.h"
+#else
+#include <QtWidgets/QLabel>
+#endif // NV_ARTISTTOOLS
+
+#include "corelib_global.h"
+
+class QPushButton;
+class QGridLayout;
+class QHBoxLayout;
+class QSpacerItem;
+
+class DisplayMeshesPanel;
+class StateViewItem : public QWidget
+{
+ Q_OBJECT
+
+public:
+ enum MeshViewState
+ {
+ VS_INVISIBLE = 0,
+ VS_VISIABLE = 1,
+ };
+
+ StateViewItem(QWidget* parent, unsigned int id, MeshViewState view = VS_VISIABLE);
+
+ public slots:
+ CORELIB_EXPORT void on_btnToggleView_clicked();
+
+private:
+ unsigned int _id;
+
+ QHBoxLayout* _layout;
+ QPushButton* _btn;
+ QSpacerItem* _spacer;
+
+ DisplayMeshesPanel* _parent;
+};
+
+class DisplayMeshesPanel : public QFrame
+{
+ Q_OBJECT
+
+public:
+ DisplayMeshesPanel(QWidget* parent);
+
+ void updateValues();
+
+ // client code should make sure the 'id' is unique!
+ CORELIB_EXPORT void AddMeshItem(QString name, unsigned int id, StateViewItem::MeshViewState view = StateViewItem::VS_VISIABLE);
+ CORELIB_EXPORT void RemoveMeshItem(unsigned int id);
+ CORELIB_EXPORT void ClearItems();
+
+signals:
+ void MeshViewSignal(unsigned int id, bool visible);
+
+protected:
+ virtual void EmitToggleSignal(unsigned int id, bool visible);
+
+private:
+ QGridLayout* _layout;
+
+ struct ItemUI
+ {
+ StateViewItem* viewItem;
+ QLabel* label;
+ };
+
+ QMap<unsigned int, ItemUI> _items;
+
+ friend class StateViewItem;
+};
+
+#endif // GraphicalMaterialPanel_h__
diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp b/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp
new file mode 100644
index 0000000..fe4b808
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp
@@ -0,0 +1,906 @@
+#include "DisplayPreferencesPanel.h"
+
+#include "AppMainWindow.h"
+
+#include "SimpleScene.h"
+#include "GlobalSettings.h"
+#include <QtWidgets/QInputDialog>
+#include <QtWidgets/QMessageBox>
+#include <QtWidgets/QFileDialog>
+
+#include "PlaylistParams.h"
+//#include <Nv/Blast/NvHairCommon.h>
+#include "NvParameterized.h"
+#include "XmlSerializer.h"
+#include "NsFileBuffer.h"
+#include "NvTraits.h"
+#include "NsMemoryBuffer.h"
+#include "ViewerOutput.h"
+#include "Settings.h"
+
+#include "Gamepad.h"
+
+const QString sPlaylistExt = "plist";
+bool bRefreshingComboBox = false;
+
+DisplayPreferencesPanel::DisplayPreferencesPanel(QWidget* parent)
+ :
+ QWidget(parent)
+ , idxCurrentPlaylist(-1)
+ , idxCurrentProj(-1)
+ , playlistProjectsDirty(false)
+{
+ ui.setupUi(this);
+
+ ui.btnBackgroundTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png"));
+ ui.btnBackgroundTex->setIconSize(QSize(12,12));
+ ui.btnBackgroundTexClear->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png"));
+
+ ui.btnPlaylistsRename->setIcon(QIcon(":/AppMainWindow/images/EditWrench.png"));
+ ui.btnPlaylistsAdd->setIcon(QIcon(":/AppMainWindow/images/Add.png"));
+ ui.btnPlaylistsReload->setIcon(QIcon(":/AppMainWindow/images/refreshReload.png"));
+ ui.btnPlaylistsRemove->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png"));
+
+ ui.btnPlaylistAddProj->setIcon(QIcon(":/AppMainWindow/images/Add.png"));
+ ui.btnPlaylistRemoveProj->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png"));
+ ui.btnPlaylistProjGoUp->setIcon(QIcon(":/AppMainWindow/images/Up.png"));
+ ui.btnPlaylistProjGoDown->setIcon(QIcon(":/AppMainWindow/images/Down.png"));
+
+ ui.btnPlaylistsPlay->setIcon(QIcon(":/AppMainWindow/images/playlist.png"));
+
+ //QObject::connect(ui.listWidgetPlaylist, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(playlistDoubleClicked(QListWidgetItem*)));
+
+ ConfigSpinBox<SlideSpinBoxF>(ui.spinCameraFOV, 5.0, 180.0, 1.0);
+}
+
+DisplayPreferencesPanel::~DisplayPreferencesPanel()
+{
+}
+
+void DisplayPreferencesPanel::on_spinRenderPlayRateFPS_valueChanged(double v)
+{
+ GlobalSettings::Inst().setRenderFps((float)v);
+}
+
+void DisplayPreferencesPanel::on_spinSimulationRateFPS_valueChanged(double v)
+{
+ GlobalSettings::Inst().setSimulationFps((float)v);
+}
+
+void DisplayPreferencesPanel::on_spinCameraFOV_valueChanged(double v)
+{
+ GlobalSettings::Inst().m_fovAngle = v;
+}
+
+void DisplayPreferencesPanel::on_cbAntialiasing_currentIndexChanged( int index )
+{
+ GlobalSettings::Inst().m_msaaOption = index;
+}
+
+void DisplayPreferencesPanel::on_cbUpAxis_currentIndexChanged( int index )
+{
+ switch (index)
+ {
+ case 0: // y up
+ SimpleScene::Inst()->ResetUpDir(false);
+ break;
+ case 1: // z up
+ SimpleScene::Inst()->ResetUpDir(true);
+ break;
+ }
+ SimpleScene::Inst()->SetProjectModified(true);
+}
+
+void DisplayPreferencesPanel::on_cbHandedness_currentIndexChanged( int index )
+{
+ switch (index)
+ {
+ case 0: // rhs
+ SimpleScene::Inst()->ResetLhs(false);
+ break;
+ case 1: // lhs
+ SimpleScene::Inst()->ResetLhs(true);
+ break;
+ }
+ SimpleScene::Inst()->SetProjectModified(true);
+}
+
+void DisplayPreferencesPanel::on_cbSceneUnit_currentIndexChanged( int index )
+{
+ GlobalSettings::Inst().m_sceneUnitIndex = index;
+}
+
+void DisplayPreferencesPanel::on_cbNavigationStyle_currentIndexChanged( int index )
+{
+ AppMainWindow::Inst().setNavigationStyle(index);
+}
+
+void DisplayPreferencesPanel::on_btnBackgroundTex_clicked()
+{
+ if (SimpleScene::Inst()->LoadBackgroundTextureFile())
+ ui.btnBackgroundTex->setIcon(QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png"));
+ else
+ ui.btnBackgroundTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png"));
+
+ updateValues();
+ SimpleScene::Inst()->SetProjectModified(true);
+}
+
+void DisplayPreferencesPanel::on_btnBackgroundTexClear_clicked()
+{
+ SimpleScene::Inst()->ClearBackgroundTexture();
+ ui.btnBackgroundTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png"));
+ updateValues();
+}
+
+void DisplayPreferencesPanel::updateValues()
+{
+ GlobalSettings& globalSettings = GlobalSettings::Inst();
+
+ ui.spinRenderPlayRateFPS->setValue(globalSettings.m_renderFps);
+ ui.spinSimulationRateFPS->setValue(globalSettings.m_simulationFps);
+ ui.cbUpAxis->setCurrentIndex(globalSettings.m_zup);
+ ui.cbHandedness->setCurrentIndex(globalSettings.m_lhs);
+ ui.spinCameraFOV->setValue(globalSettings.m_fovAngle);
+ ui.cbSceneUnit->setCurrentIndex(globalSettings.m_sceneUnitIndex);
+ ui.cbNavigationStyle->setCurrentIndex(AppMainWindow::Inst().getNavigationStyle());
+ ui.cbAntialiasing->setCurrentIndex(globalSettings.m_msaaOption);
+
+ savePlaylistProjects();
+ reloadComboxBoxPlaylists();
+
+ //// sync playlist to gamepad
+ //static bool bOnce = true;
+ //if (bOnce)
+ //{
+ // bOnce = false;
+ // assignPlayPlaylistToGamepad(0);
+ //}
+}
+
+void DisplayPreferencesPanel::reloadComboxBoxPlaylists()
+{
+ playlistsLoader.loadPlaylistsFromMediaPath();
+ // set playlist combo box
+ //idxCurrentPlaylist = ui.cbPlaylists->currentIndex();
+ bRefreshingComboBox = true;
+ ui.cbPlaylists->clear();
+ int count = playlistsLoader.playlists.size();
+ for (int i = 0; i < count; ++i)
+ {
+ QFileInfo& fi = playlistsLoader.playlists[i];
+ std::string fn = fi.fileName().toUtf8().data();
+ ui.cbPlaylists->addItem(fi.fileName());
+ }
+ bRefreshingComboBox = false;
+ if (idxCurrentPlaylist > count || idxCurrentPlaylist < 0)
+ idxCurrentPlaylist = 0;
+
+ ui.cbPlaylists->setCurrentIndex(idxCurrentPlaylist);
+
+ // refresh project list
+ reloadListboxPorjectsFromPlayist();
+}
+
+void DisplayPreferencesPanel::runDemoCommandline()
+{
+ // run demos if command line asks
+ static bool once = true;
+ if (once)
+ {
+ once = false;
+ std::string demoPlaylist = AppSettings::Inst().GetOptionValue("User/FurDemoPlaylist")->Value.String;
+ if (demoPlaylist.size() > 1)
+ {
+ QString demoList = QString(demoPlaylist.c_str()).toUpper();
+ int count = playlistsLoader.playlists.size();
+ for (int i = 0; i < count; ++i)
+ {
+ QFileInfo& fi = playlistsLoader.playlists[i];
+ QString fname = fi.fileName().toUpper();
+ if (fname == demoList)
+ {
+ idxCurrentPlaylist = i;
+ ui.cbPlaylists->setCurrentIndex(idxCurrentPlaylist);
+ playPlaylist(idxCurrentPlaylist);
+ return;
+ }
+ }
+ viewer_msg(QString("Cannot find playlist, " + demoList).toUtf8().data());
+ }
+ }
+}
+
+void DisplayPreferencesPanel::reloadListboxPorjectsFromPlayist()
+{
+ int count = playlistsLoader.getProjectsInPlaylist(idxCurrentPlaylist, playlistProjects);
+ refreshListboxPorjects();
+}
+
+void DisplayPreferencesPanel::savePlaylistProjects()
+{
+ if (playlistProjectsDirty)
+ {
+ playlistsLoader.saveProjectsInPlaylist(idxCurrentPlaylist, playlistProjects);
+ playlistProjectsDirty = false;
+ }
+}
+
+void DisplayPreferencesPanel::refreshListboxPorjects()
+{
+ int count = playlistProjects.size();
+ ui.listWidgetPlaylist->clear();
+ ui.listWidgetPlaylist->setSortingEnabled(false);
+ ui.listWidgetPlaylist->setSelectionMode(QAbstractItemView::SingleSelection);
+ QStringList tips;
+ for (int i = 0; i < count; ++i)
+ {
+ QString fullName = playlistsLoader.convertToAbsoluteFilePath(playlistProjects[i]);
+ QFileInfo fi(fullName);
+ tips.append(fi.absoluteFilePath());
+ std::string tmp = fi.absoluteFilePath().toUtf8().data();
+ ui.listWidgetPlaylist->addItem(fi.fileName());
+ }
+ ui.listWidgetPlaylist->setTips(tips);
+ if (idxCurrentProj > count || idxCurrentProj < 0)
+ {
+ idxCurrentProj = 0;
+ }
+ ui.listWidgetPlaylist->setCurrentRow(idxCurrentProj);
+}
+
+void DisplayPreferencesPanel::SelectPlayList(QString& name)
+{
+ QString newName = name.toUpper();
+ int count = playlistsLoader.playlists.size();
+ for (int i = 0; i < count; ++i)
+ {
+ QFileInfo& fi = playlistsLoader.playlists[i];
+ if (fi.baseName().toUpper() == newName)
+ {
+ ui.cbPlaylists->setCurrentIndex(i);
+ break;
+ }
+ }
+}
+
+void DisplayPreferencesPanel::on_cbPlaylists_currentIndexChanged(int index)
+{
+ savePlaylistProjects();
+ if (!bRefreshingComboBox)
+ {
+ idxCurrentPlaylist = ui.cbPlaylists->currentIndex();
+ reloadListboxPorjectsFromPlayist();
+ }
+}
+
+void DisplayPreferencesPanel::SelectProject(QString& name)
+{
+ QString newName = name.toUpper();
+ std::string strNew = newName.toUtf8().data();
+ int count = playlistProjects.size();
+ for (int i = 0; i < count; ++i)
+ {
+ QString& str = playlistProjects[i];
+ //QFileInfo fi(str);
+ //std::string stmp = fi.absoluteFilePath().toUtf8().data();
+ //if (fi.absoluteFilePath().toUpper() == newName)
+ if (str.toUpper() == newName)
+ {
+ ui.listWidgetPlaylist->setCurrentRow(i);
+ break;
+ }
+ }
+}
+
+void DisplayPreferencesPanel::on_listWidgetPlaylist_itemSelectionChanged()
+{
+ idxCurrentProj = ui.listWidgetPlaylist->currentRow();
+}
+
+void DisplayPreferencesPanel::on_listWidgetPlaylist_itemDoubleClicked(QListWidgetItem* pItem)
+{
+ idxCurrentProj = ui.listWidgetPlaylist->currentRow();
+ if (idxCurrentProj < 0)
+ return;
+ QString fn = playlistProjects[idxCurrentProj];
+ QString fullname = PlaylistsLoader::convertToAbsoluteFilePath(fn);
+ AppMainWindow::Inst().openProject(fullname);
+ char msg[1024];
+ sprintf(msg, "Blast Viewer - %s", fullname.toUtf8().data());
+ AppMainWindow::Inst().setWindowTitle(msg);
+}
+
+void DisplayPreferencesPanel::on_btnPlaylistsRename_clicked()
+{
+ idxCurrentPlaylist = ui.cbPlaylists->currentIndex();
+ if (idxCurrentPlaylist < 0)
+ return;
+
+ QFileInfo& fi = playlistsLoader.playlists[idxCurrentPlaylist];
+ bool isOK = false;
+ QString newBaseName = QInputDialog::getText(NULL, "Rename Playlist - " + fi.fileName(),
+ "Input a new name for the playlist, " + fi.fileName(), QLineEdit::Normal,
+ fi.baseName(), &isOK);
+ if (isOK)
+ {
+ bool ok = playlistsLoader.rename(idxCurrentPlaylist, newBaseName);
+ if (ok)
+ {
+ reloadComboxBoxPlaylists();
+ SelectPlayList(newBaseName);
+ }
+ else
+ {
+ QMessageBox::warning(this, "Fail to rename a playlist",
+ "Fail to rename a playlist. The failure could relate to name duplication or hardware failure.",
+ QMessageBox::Close);
+ }
+ }
+}
+
+void DisplayPreferencesPanel::on_btnPlaylistsAdd_clicked()
+{
+ savePlaylistProjects();
+
+ bool isOK = false;
+ QString sInput = QInputDialog::getText(NULL, "Create New Playlist", "Input a name for the new playlist.", QLineEdit::Normal, "", &isOK);
+ if (isOK)
+ {
+ QString newName = sInput.trimmed();
+ bool ok = playlistsLoader.add(newName);
+ if (ok)
+ {
+ reloadComboxBoxPlaylists();
+ // select the new one
+ SelectPlayList(newName);
+ }
+ else
+ {
+ QMessageBox::warning(this, "Fail to add new playlist",
+ "Fail to add new playlist. The failure could relate to name duplication or hardware failure.",
+ QMessageBox::Close);
+ }
+ }
+}
+
+void DisplayPreferencesPanel::on_btnPlaylistsReload_clicked()
+{
+ savePlaylistProjects();
+ reloadComboxBoxPlaylists();
+}
+
+void DisplayPreferencesPanel::on_btnPlaylistsRemove_clicked()
+{
+ savePlaylistProjects();
+ idxCurrentPlaylist = ui.cbPlaylists->currentIndex();
+ if (idxCurrentPlaylist < 0)
+ return;
+
+ bool ok = playlistsLoader.remove(idxCurrentPlaylist);
+ if (ok)
+ {
+ reloadComboxBoxPlaylists();
+ }
+ else
+ {
+ QMessageBox::warning(this, "Fail to remove a playlist",
+ "Fail to remove a playlist. The failure could relate to hardware.",
+ QMessageBox::Close);
+ }
+}
+
+void DisplayPreferencesPanel::on_btnPlaylistAddProj_clicked()
+{
+ static QString lastPath;
+ if (lastPath.size() < 1)
+ {
+ lastPath = PlaylistsLoader::mediaPath;
+ }
+ QString fileNameInput = QFileDialog::getOpenFileName(this, "Open Hair Project File", lastPath, "Hair Project File (*.furproj)");
+ if (!QFile::exists(fileNameInput))
+ return;
+ std::string tmp = fileNameInput.toUtf8().data();
+ QString fileName = PlaylistsLoader::convertToSaveingFilePath(fileNameInput);
+ if (fileName.size() < 1)
+ {
+ return;
+ }
+ lastPath = QFileInfo(fileNameInput).absolutePath();
+ std::string tmp2 = fileName.toUtf8().data();
+ playlistProjects.append(fileName);
+ refreshListboxPorjects();
+ //QFileInfo fi(fileName);
+ SelectProject(fileName);// fi.absoluteFilePath());
+ playlistProjectsDirty = true;
+}
+
+void DisplayPreferencesPanel::on_btnPlaylistProjGoUp_clicked()
+{
+ idxCurrentProj = ui.listWidgetPlaylist->currentRow();
+ if (idxCurrentProj <= 0)
+ return;
+
+ QString tmp = playlistProjects[idxCurrentProj];
+ playlistProjects[idxCurrentProj] = playlistProjects[idxCurrentProj - 1];
+ playlistProjects[idxCurrentProj - 1] = tmp;
+
+ refreshListboxPorjects();
+ SelectProject(tmp);
+
+ playlistProjectsDirty = true;
+}
+
+void DisplayPreferencesPanel::on_btnPlaylistProjGoDown_clicked()
+{
+ int count = playlistProjects.size();
+ idxCurrentProj = ui.listWidgetPlaylist->currentRow();
+ if (idxCurrentProj < 0 || idxCurrentProj>= count -1)
+ return;
+
+ QString tmp = playlistProjects[idxCurrentProj];
+ playlistProjects[idxCurrentProj] = playlistProjects[idxCurrentProj + 1];
+ playlistProjects[idxCurrentProj + 1] = tmp;
+
+ refreshListboxPorjects();
+ SelectProject(tmp);
+
+ playlistProjectsDirty = true;
+}
+
+void DisplayPreferencesPanel::on_btnPlaylistRemoveProj_clicked()
+{
+ int count = playlistProjects.size();
+ idxCurrentProj = ui.listWidgetPlaylist->currentRow();
+ if (idxCurrentProj < 0 || idxCurrentProj >= count)
+ {
+ return;
+ }
+
+ playlistProjects.removeAt(idxCurrentProj);
+
+ refreshListboxPorjects();
+ playlistProjectsDirty = true;
+}
+
+void DisplayPreferencesPanel::assignPlayPlaylistToGamepad(int idx)
+{
+ if (idx == -1)
+ idx = idxCurrentPlaylist;
+ int count = playlistsLoader.getProjectsInPlaylist(idx, playlistProjects);
+ if (count < 1)
+ {
+ viewer_msg("Playlist is empty.");
+ return;
+ }
+ QList<QString> files;
+ for (int i = 0; i < count; ++i)
+ {
+ QString fname = PlaylistsLoader::convertToAbsoluteFilePath(playlistProjects[i]);
+ if (fname.size() > 0)
+ {
+ files.append(fname);
+ }
+ }
+
+ Gamepad& theGamepad = Gamepad::Instance();
+ theGamepad.SetDemoProjects(files);
+}
+
+void DisplayPreferencesPanel::playPlaylist(int idx)
+{
+ assignPlayPlaylistToGamepad(idx);
+ Gamepad& theGamepad = Gamepad::Instance();
+ theGamepad.SetDemoMode(true);
+}
+
+void DisplayPreferencesPanel::on_btnPlaylistsPlay_clicked()
+{
+ savePlaylistProjects();
+
+ idxCurrentPlaylist = ui.cbPlaylists->currentIndex();
+ if (idxCurrentPlaylist < 0)
+ {
+ viewer_msg("No available playlists.");
+ return;
+ }
+ playPlaylist(idxCurrentPlaylist);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+using namespace nvidia;
+using namespace nvidia::parameterized;
+
+QString PlaylistsLoader::projectPath;
+QString PlaylistsLoader::mediaPath;
+
+#include "FoundationHolder.h"
+
+struct PlaylistParamsContext
+{
+ //nvidia::NvFoundation* mFoundation;
+ NvParameterized::Traits* mTraits;
+ PlaylistParamsFactory* mPlaylistParamsFactory;
+};
+
+PlaylistsLoader::PlaylistsLoader()
+ :pContext(nullptr)
+{
+}
+
+PlaylistsLoader::~PlaylistsLoader()
+{
+}
+
+void PlaylistsLoader::CreatePlaylistParamsContext()
+{
+ if (pContext)
+ return;
+
+ PlaylistParamsContext* context = new PlaylistParamsContext;
+ //context->mFoundation = FoundationHolder::GetFoundation();
+ FoundationHolder::GetFoundation();
+ //assert(context->mFoundation != NV_NULL);
+
+ context->mTraits = NvParameterized::createTraits();
+ context->mPlaylistParamsFactory = new PlaylistParamsFactory;
+ context->mTraits->registerFactory(*context->mPlaylistParamsFactory);
+ pContext = context;
+}
+
+void PlaylistsLoader::ReleasePlaylistParamsContext()
+{
+ if (pContext)
+ {
+ pContext->mTraits->release();
+ delete pContext->mPlaylistParamsFactory;
+ delete pContext;
+ pContext = nullptr;
+ }
+}
+
+void PlaylistsLoader::loadPlaylistsFromMediaPath()
+{
+ if (projectPath.isEmpty())
+ {
+ QString appDir = qApp->applicationDirPath();
+ QDir dirTmp(appDir);
+ if (dirTmp.cd("./media/playlists"))
+ projectPath = dirTmp.absolutePath();
+ else if (dirTmp.cd("../media/playlists"))
+ projectPath = dirTmp.absolutePath();
+ else if (dirTmp.cd("../../media/playlists"))
+ projectPath = dirTmp.absolutePath();
+ else if (dirTmp.cd("../../media"))
+ {
+ bool ok = dirTmp.mkdir("playlists");
+ if (dirTmp.cd("playlists"))
+ {
+ projectPath = dirTmp.absolutePath();
+ }
+ }
+ if (!projectPath.isEmpty())
+ {
+ if (dirTmp.cd(".."))
+ {
+ mediaPath = dirTmp.absolutePath();
+ }
+ else
+ {
+ mediaPath = projectPath + "/..";
+ }
+ }
+ }
+ if (!projectPath.isEmpty())
+ {
+ playlists.clear();
+
+ QStringList filters;
+ filters << (QString("*.") + sPlaylistExt);
+ QDirIterator dir_iterator(projectPath, filters, QDir::Files | QDir::NoSymLinks, QDirIterator::NoIteratorFlags); //QDirIterator::Subdirectories
+ while (dir_iterator.hasNext())
+ {
+ dir_iterator.next();
+ QFileInfo file_info = dir_iterator.fileInfo();
+ std::string absolute_file_path = file_info.absoluteFilePath().toUtf8().data();
+ playlists.append(file_info);
+ }
+ }
+}
+
+bool PlaylistsLoader::rename(int idx, QString& newBaseName)
+{
+ int count = playlists.size();
+ if (idx >= 0 && idx < count)
+ {
+ QFileInfo& finfo = playlists[idx];
+ QString fn = finfo.baseName().toUpper();
+ QString fnNew = newBaseName.toUpper();
+ if (fn != fnNew)
+ {
+ QFileInfo nfi(projectPath, newBaseName + "." + sPlaylistExt);
+ QString fullNewName = nfi.absoluteFilePath();
+ std::string fntmp = fullNewName.toUtf8().data();
+ bool exist = QFile::exists(fullNewName);
+ if (exist)
+ {
+ return false;
+ }
+ bool ok = QFile::rename(finfo.absoluteFilePath(), fullNewName);
+ if (ok)
+ {
+ finfo.setFile(fullNewName);
+ exist = QFile::exists(fullNewName);
+ if (!exist)
+ {
+ return false;
+ }
+ }
+ return ok;
+ }
+ return true;
+ }
+ return false;
+}
+
+bool PlaylistsLoader::remove(int idx)
+{
+ int count = playlists.size();
+ if (idx >= 0 && idx < count)
+ {
+ QFileInfo& finfo = playlists[idx];
+ std::string fn = finfo.fileName().toUtf8().data();
+ bool ok = QFile::remove(finfo.absoluteFilePath());
+ if (ok)
+ {
+ playlists.removeAt(idx);
+ }
+ return ok;
+ }
+ return false;
+}
+
+bool PlaylistsLoader::saveProjectsInPlaylist(int idx, QList<QString>& projects)
+{
+ int count = playlists.size();
+ if (idx < 0 || idx >= count)
+ return false;
+
+ CreatePlaylistParamsContext();
+ if (!pContext)
+ return false;
+
+ std::string tempFilePath = playlists[idx].absoluteFilePath().toUtf8().data();
+ NvParameterized::XmlSerializer serializer(pContext->mTraits);
+ NvFileBuf* stream = new NvFileBufferBase(tempFilePath.c_str(), NvFileBuf::OPEN_WRITE_ONLY);
+ if (!stream || !stream->isOpen())
+ {
+ // file open error
+ if (stream) stream->release();
+ return false;
+ }
+ NvParameterized::Traits* traits = pContext->mTraits;
+ int numObjects = 0;
+ const int kMaxObjects = 1;
+ NvParameterized::Interface* objects[kMaxObjects];
+
+ PlaylistParams* params = new PlaylistParams(traits);
+ objects[numObjects++] = params;
+ NvParameterized::Interface* iface = static_cast<NvParameterized::Interface*>(params);
+
+ if (1)
+ {
+ nvidia::parameterized::PlaylistParams* params = static_cast<nvidia::parameterized::PlaylistParams*>(iface);
+ nvidia::parameterized::PlaylistParamsNS::ParametersStruct& targetDesc = params->parameters();
+
+ NvParameterized::Handle handle(iface);
+ if (iface->getParameterHandle("furprojFilePaths", handle) == NvParameterized::ERROR_NONE)
+ {
+ int num = projects.size();
+
+ std::vector<std::string> strArray;
+ const char** strOutput = new const char*[num];
+
+ for (int i = 0; i < num; i++)
+ {
+ std::string proj = projects[i].toUtf8().data();
+ strArray.push_back(proj);
+ strOutput[i] = strArray[i].c_str();
+ }
+
+ handle.resizeArray(num);
+ handle.setParamStringArray(strOutput, num);
+
+ delete[] strOutput;
+ }
+ }
+
+ NV_ASSERT(numObjects <= kMaxObjects);
+ NvParameterized::Serializer::ErrorType serError = NvParameterized::Serializer::ERROR_NONE;
+ bool isUpdate = false;
+ serError = serializer.serialize(*stream, (const NvParameterized::Interface**)&objects[0], numObjects, isUpdate);
+ for (int idx = 0; idx < numObjects; ++idx)
+ {
+ delete objects[idx];
+ }
+ stream->release();
+ ReleasePlaylistParamsContext();
+ return true;
+}
+
+QString PlaylistsLoader::convertToAbsoluteFilePath(QString& filePath)
+{
+ QString fname;
+ bool bCanBeRelativePath = false;
+ bool bAbsPath = (filePath.indexOf(':') >= 0);
+ if (bAbsPath)
+ {
+ if (QFile::exists(filePath))
+ {
+ fname = filePath;
+ }
+ else
+ {
+ viewer_msg(QString(filePath + " does not exist.").toUtf8().data());
+ }
+ std::string tmp2 = fname.toUtf8().data();
+ return fname;
+ }
+ else
+ {
+ QFileInfo fi(mediaPath + "/" + filePath);
+ fname = fi.absoluteFilePath();
+ if (!QFile::exists(fname))
+ {
+ viewer_msg(QString(filePath + " does not exist.").toUtf8().data());
+ fname = "";
+ }
+ std::string tmp2 = fname.toUtf8().data();
+ return fname;
+ }
+}
+
+QString PlaylistsLoader::convertToSaveingFilePath(QString& filePath)
+{
+ QString fname;
+ bool bCanBeRelativePath = false;
+ bool bAbsPath = (filePath.indexOf(':') >= 0);
+ if (bAbsPath)
+ {
+ if (QFile::exists(filePath))
+ {
+ QFileInfo fi(filePath);
+ int pos = fi.absoluteFilePath().indexOf(mediaPath, Qt::CaseInsensitive);
+ if (pos >= 0)
+ {
+ // convert to relative path
+ fname = filePath.right(filePath.size() - (pos + mediaPath.size() + 1));
+ }
+ else
+ {
+ fname = fi.absoluteFilePath();
+ }
+ }
+ else
+ {
+ fname = "";
+ viewer_msg(QString(filePath + " does not exist.").toUtf8().data());
+ }
+ std::string tmp = fname.toUtf8().data();
+ return fname;
+ }
+ // do more try
+ QString tag = "media";
+ int pos = filePath.indexOf(tag, Qt::CaseInsensitive);
+ if (pos >= 0)
+ {
+ fname = filePath.right(filePath.size() - (pos + tag.size() + 1));
+ }
+ else
+ {
+ fname = filePath;
+ }
+ QFileInfo fi(mediaPath + "/" + fname);
+ std::string tmp = fi.absoluteFilePath().toUtf8().data();
+ if (!QFile::exists(fi.absoluteFilePath()))
+ {
+ viewer_msg(QString(filePath + " does not exist.").toUtf8().data());
+ fname = "";
+ }
+ std::string tmp2 = fname.toUtf8().data();
+ return fname;
+}
+
+int PlaylistsLoader::getProjectsInPlaylist(int idx, QList<QString>& projects)
+{
+ projects.clear();
+
+ int count = playlists.size();
+ if (idx < 0 || idx >= count)
+ return 0;
+
+ CreatePlaylistParamsContext();
+ if (!pContext)
+ return 0;
+
+ std::string tempFilePath = playlists[idx].absoluteFilePath().toUtf8().data();
+ NvFileBuf* stream = new NvFileBufferBase(tempFilePath.c_str(), NvFileBuf::OPEN_READ_ONLY);
+ if (!stream || !stream->isOpen())
+ {
+ // file open error
+ if (stream)
+ stream->release();
+ return 0;
+ }
+
+ NvParameterized::Serializer::DeserializedData data;
+ NvParameterized::Serializer::ErrorType serError = NvParameterized::Serializer::ERROR_NONE;
+ NvParameterized::XmlSerializer serializer(pContext->mTraits);
+ bool isUpdated = false;
+ serError = serializer.deserialize(*stream, data, isUpdated);
+ if (data.size() < 1)
+ {
+ if (stream)
+ stream->release();
+ return 0;
+ }
+
+ for (int idx = 0; idx < (int)data.size(); ++idx)
+ {
+ NvParameterized::Interface* iface = data[idx];
+ if (::strcmp(iface->className(), PlaylistParams::staticClassName()) == 0)
+ {
+ nvidia::parameterized::PlaylistParams* params = static_cast<nvidia::parameterized::PlaylistParams*>(iface);
+ nvidia::parameterized::PlaylistParamsNS::ParametersStruct& srcDesc = params->parameters();
+ NvParameterized::Handle handle(iface);
+ if (iface->getParameterHandle("furprojFilePaths", handle) == NvParameterized::ERROR_NONE)
+ {
+ int arraySize;
+ handle.getArraySize(arraySize);
+ char** strArray = new char*[arraySize];
+ handle.getParamStringArray(strArray, arraySize);
+ for (int idx = 0; idx < arraySize; ++idx)
+ {
+ QString fileName = PlaylistsLoader::convertToSaveingFilePath(QString(strArray[idx]));
+ if (fileName.size() > 0)
+ {
+ std::string tmp = fileName.toUtf8().data();
+ projects.append(fileName);
+ }
+ }
+ delete[] strArray;
+ }
+ }
+ }
+ stream->release();
+ ReleasePlaylistParamsContext();
+ return projects.size();
+}
+
+bool PlaylistsLoader::add(QString& name)
+{
+ int count = playlists.size();
+ for (int i = 0; i < count; ++i)
+ {
+ QFileInfo& fi = playlists[i];
+ if (fi.baseName().toUpper() == name.toUpper())
+ {
+ return false;
+ }
+ }
+ QFileInfo nfi(projectPath, name + "." + sPlaylistExt);
+ QFile newFile(nfi.absoluteFilePath());
+ if (newFile.exists())
+ {
+ return false;
+ }
+ newFile.open(QIODevice::WriteOnly);
+ newFile.close();
+ bool exist = QFile::exists(nfi.absoluteFilePath());
+ if (!exist)
+ {
+ return false;
+ }
+ playlists.append(nfi);
+ return true;
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.h b/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.h
new file mode 100644
index 0000000..eb57b12
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.h
@@ -0,0 +1,100 @@
+#ifndef DisplayPreferencesPanel_h__
+#define DisplayPreferencesPanel_h__
+
+#include <QtWidgets/QWidget>
+#include <QtCore/QDir>
+#include <QtCore/QDirIterator>
+#include "TipListView.h"
+#include "ui_DisplayPreferencesPanel.h"
+
+#include "corelib_global.h"
+
+struct PlaylistParamsContext;
+
+class PlaylistsLoader
+{
+public:
+ PlaylistsLoader();
+ ~PlaylistsLoader();
+
+ void loadPlaylistsFromMediaPath();
+ bool rename(int idx, QString& newName);
+ bool remove(int idx);
+ bool add(QString& name);
+ bool saveProjectsInPlaylist(int idx, QList<QString>& projects);
+ int getProjectsInPlaylist(int idx, QList<QString>& projects);
+
+ static QString convertToSaveingFilePath(QString& filePath);
+ static QString convertToAbsoluteFilePath(QString& filePath);
+
+ QList<QFileInfo> playlists;
+ static QString projectPath;
+ static QString mediaPath;
+
+private:
+ void CreatePlaylistParamsContext();
+ void ReleasePlaylistParamsContext();
+ PlaylistParamsContext* pContext;
+};
+
+class DisplayPreferencesPanel : public QWidget
+{
+ Q_OBJECT
+
+public:
+ DisplayPreferencesPanel(QWidget* parent);
+ ~DisplayPreferencesPanel();
+
+ public:
+ void updateValues();
+
+ public slots:
+ CORELIB_EXPORT void on_spinRenderPlayRateFPS_valueChanged(double v);
+ CORELIB_EXPORT void on_spinSimulationRateFPS_valueChanged(double v);
+ CORELIB_EXPORT void on_spinCameraFOV_valueChanged(double v);
+
+ CORELIB_EXPORT void on_cbSceneUnit_currentIndexChanged(int index);
+ CORELIB_EXPORT void on_cbAntialiasing_currentIndexChanged(int index);
+ CORELIB_EXPORT void on_cbUpAxis_currentIndexChanged(int index);
+ CORELIB_EXPORT void on_cbHandedness_currentIndexChanged(int index);
+ CORELIB_EXPORT void on_cbNavigationStyle_currentIndexChanged(int index);
+ CORELIB_EXPORT void on_btnBackgroundTex_clicked();
+ CORELIB_EXPORT void on_btnBackgroundTexClear_clicked();
+
+ CORELIB_EXPORT void on_cbPlaylists_currentIndexChanged(int index);
+ CORELIB_EXPORT void SelectPlayList(QString& name);
+ CORELIB_EXPORT void on_listWidgetPlaylist_itemSelectionChanged();
+ CORELIB_EXPORT void on_listWidgetPlaylist_itemDoubleClicked(QListWidgetItem* pItem);
+ CORELIB_EXPORT void SelectProject(QString& name);
+
+ CORELIB_EXPORT void on_btnPlaylistsRename_clicked();
+ CORELIB_EXPORT void on_btnPlaylistsAdd_clicked();
+ CORELIB_EXPORT void on_btnPlaylistsReload_clicked();
+ CORELIB_EXPORT void on_btnPlaylistsRemove_clicked();
+
+ CORELIB_EXPORT void on_btnPlaylistAddProj_clicked();
+ CORELIB_EXPORT void on_btnPlaylistProjGoUp_clicked();
+ CORELIB_EXPORT void on_btnPlaylistProjGoDown_clicked();
+ CORELIB_EXPORT void on_btnPlaylistRemoveProj_clicked();
+
+ CORELIB_EXPORT void on_btnPlaylistsPlay_clicked();
+ CORELIB_EXPORT void assignPlayPlaylistToGamepad(int idx = -1);
+ CORELIB_EXPORT void playPlaylist(int idx);
+
+ CORELIB_EXPORT void reloadComboxBoxPlaylists();
+ CORELIB_EXPORT void refreshListboxPorjects();
+ CORELIB_EXPORT void reloadListboxPorjectsFromPlayist();
+ CORELIB_EXPORT void savePlaylistProjects();
+
+ CORELIB_EXPORT void runDemoCommandline();
+
+private:
+ Ui::DisplayPreferencesPanel ui;
+ PlaylistsLoader playlistsLoader;
+ QList<QString> playlistProjects;
+ bool playlistProjectsDirty;
+ int idxCurrentPlaylist;
+ int idxCurrentProj;
+};
+
+#endif // DisplayScene_h__
diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp b/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp
new file mode 100644
index 0000000..b118b6b
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp
@@ -0,0 +1,93 @@
+#include "DisplayScenePanel.h"
+
+#include "AppMainWindow.h"
+
+#include "SimpleScene.h"
+#include "GlobalSettings.h"
+
+DisplayScenePanel::DisplayScenePanel(QWidget* parent)
+ :
+ QWidget(parent)
+{
+ ui.setupUi(this);
+}
+
+void DisplayScenePanel::on_btnVisualizeWind_stateChanged(int state)
+{
+ GlobalSettings::Inst().m_visualizeWind = state;
+}
+
+void DisplayScenePanel::on_btnShowGrid_stateChanged(int state)
+{
+ GlobalSettings::Inst().m_showGrid = state;
+}
+
+void DisplayScenePanel::on_btnShowAxis_stateChanged(int state)
+{
+ GlobalSettings::Inst().m_showAxis = state;
+}
+
+void DisplayScenePanel::on_btnShowWireframe_stateChanged(int state)
+{
+ GlobalSettings::Inst().m_showWireframe = state;
+}
+
+void DisplayScenePanel::on_btnUseLighting_stateChanged(int state)
+{
+ GlobalSettings::Inst().m_useLighting = state;
+}
+
+void DisplayScenePanel::on_cbRenderType_currentIndexChanged(int index)
+{
+ GlobalSettings::Inst().m_renderStyle = index;
+}
+
+void DisplayScenePanel::on_btnShowHUD_stateChanged(int state)
+{
+ GlobalSettings::Inst().m_showHUD = state;
+}
+
+void DisplayScenePanel::on_btnComputeStats_stateChanged(int state)
+{
+ GlobalSettings::Inst().m_computeStatistics = state;
+}
+
+void DisplayScenePanel::on_btnComputeProfile_stateChanged(int state)
+{
+ GlobalSettings::Inst().m_computeProfile = state;
+}
+
+void DisplayScenePanel::on_btnShowGraphicsMesh_stateChanged(int state)
+{
+ GlobalSettings::Inst().m_showGraphicsMesh = state;
+}
+
+void DisplayScenePanel::on_btnShowSkinnedOnly_stateChanged(int state)
+{
+ GlobalSettings::Inst().m_showSkinnedMeshOnly = state;
+ AppMainWindow::Inst().updateUI();
+}
+
+void DisplayScenePanel::on_btnSkinningDQ_stateChanged(int state)
+{
+ GlobalSettings::Inst().m_useDQ = state;
+}
+
+void DisplayScenePanel::on_checkBoxGizmoWithLocal_stateChanged(int state)
+{
+ AppMainWindow::Inst().m_bGizmoWithLocal = state;
+}
+
+void DisplayScenePanel::updateValues()
+{
+ GlobalSettings& globalSettings = GlobalSettings::Inst();
+
+ ui.btnShowGrid->setChecked(globalSettings.m_showGrid);
+ ui.btnShowAxis->setChecked(globalSettings.m_showAxis);
+ ui.cbRenderType->setCurrentIndex(globalSettings.m_renderStyle);
+ ui.btnShowHUD->setChecked(globalSettings.m_showHUD);
+ ui.btnComputeStats->setChecked(globalSettings.m_computeStatistics);
+ ui.btnUseLighting->setChecked(globalSettings.m_useLighting);
+ ui.btnShowGraphicsMesh->setChecked( globalSettings.m_showGraphicsMesh);
+ ui.btnShowSkinnedOnly->setChecked( globalSettings.m_showSkinnedMeshOnly);
+}
diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h b/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h
new file mode 100644
index 0000000..6614eca
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h
@@ -0,0 +1,39 @@
+#ifndef DisplayScenePanel_h__
+#define DisplayScenePanel_h__
+
+#include <QtWidgets/QWidget>
+#include "ui_DisplayScenePanel.h"
+
+#include "corelib_global.h"
+
+class DisplayScenePanel : public QWidget
+{
+ Q_OBJECT
+
+public:
+ DisplayScenePanel(QWidget* parent);
+
+ public:
+ void updateValues();
+
+ public slots:
+ CORELIB_EXPORT void on_btnVisualizeWind_stateChanged(int state);
+ CORELIB_EXPORT void on_btnShowGrid_stateChanged(int state);
+ CORELIB_EXPORT void on_btnShowAxis_stateChanged(int state);
+ CORELIB_EXPORT void on_cbRenderType_currentIndexChanged(int index);
+ CORELIB_EXPORT void on_btnShowWireframe_stateChanged(int state);
+ CORELIB_EXPORT void on_btnShowHUD_stateChanged(int state);
+ CORELIB_EXPORT void on_btnComputeStats_stateChanged(int state);
+ CORELIB_EXPORT void on_btnComputeProfile_stateChanged(int state);
+ CORELIB_EXPORT void on_btnUseLighting_stateChanged(int state);
+ CORELIB_EXPORT void on_btnShowGraphicsMesh_stateChanged(int state);
+ CORELIB_EXPORT void on_btnShowSkinnedOnly_stateChanged(int state);
+ CORELIB_EXPORT void on_btnSkinningDQ_stateChanged(int state);
+ CORELIB_EXPORT void on_checkBoxGizmoWithLocal_stateChanged(int state);
+
+
+private:
+ Ui::DisplayScenePanel ui;
+};
+
+#endif // DisplayScene_h__
diff --git a/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.cpp b/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.cpp
new file mode 100644
index 0000000..0fe96d1
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.cpp
@@ -0,0 +1,190 @@
+#include <QtWidgets/QLabel>
+#include <QtGui/QImage>
+#include <QtWidgets/QVBoxLayout>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QPaintEvent>
+#include <QtGui/QPainter>
+#include <QtGui/QPainterPath>
+#include "ExpandablePanel.h"
+#include "Nv.h"
+
+static QImage S_TriangleRight;
+static QImage S_TriangleDown;
+
+void InitTriangleResources(int w, int h)
+{
+ S_TriangleRight = QImage(w, h, QImage::Format_ARGB32);
+ S_TriangleDown = QImage(w, h, QImage::Format_ARGB32);
+
+ S_TriangleRight.fill(QColor(0, 0, 0, 0));
+ S_TriangleDown.fill(QColor(0, 0, 0, 0));
+
+ QPainter painter(&S_TriangleRight);
+ painter.setRenderHints(QPainter::Antialiasing,true);
+
+ QPainterPath path;
+ path.moveTo(0, 0);
+ path.lineTo(w, h>>1);
+ path.lineTo(0, h);
+ path.lineTo(0, 0);
+ painter.setPen(Qt::NoPen);
+ painter.fillPath(path, QBrush(QColor(50, 50, 50)));
+
+ // a painter cannot switch device?
+ QPainter painter2(&S_TriangleDown);
+ painter2.setRenderHint(QPainter::Antialiasing,true);
+ path = QPainterPath(); // trick to clear up a path
+ path.moveTo(0, 0);
+ path.lineTo(w, 0);
+ path.lineTo(w>>1, h);
+ path.lineTo(0, 0);
+ painter2.setPen(Qt::NoPen);
+ painter2.fillPath(path, QBrush(QColor(50, 50, 50)));
+}
+
+class TitleLabelImpl : public TitleLabel
+{
+ enum
+ {
+ IMAGE_H = 10,
+ IMAGE_W = 10,
+ FIXED_H = 20,
+ };
+
+public:
+ TitleLabelImpl(QWidget* parent, bool collapsed)
+ : TitleLabel(parent)
+ , _collapsed(collapsed)
+ {
+ QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ sizePolicy.setHorizontalStretch(0);
+ sizePolicy.setVerticalStretch(0);
+ sizePolicy.setHeightForWidth(this->sizePolicy().hasHeightForWidth());
+ this->setSizePolicy(sizePolicy);
+ this->setMinimumSize(QSize(0, FIXED_H));
+ this->setMaximumSize(QSize(16777215, FIXED_H));
+ //this->setStyleSheet(QString::fromUtf8("background:rgb(219,219,219);border:1px solid rgb(185,185,185);"));
+ this->setFrameShape(QFrame::NoFrame);
+ this->setFrameShadow(QFrame::Plain);
+ this->setTextFormat(Qt::AutoText);
+ this->setScaledContents(false);
+ this->setAlignment(Qt::AlignCenter);
+
+ if(S_TriangleDown.isNull() || S_TriangleRight.isNull())
+ InitTriangleResources(IMAGE_W, IMAGE_H);
+ }
+
+ void paintEvent(QPaintEvent * e)
+ {
+ QLabel::paintEvent(e);
+
+ QPainter painter(this);
+ painter.setRenderHints(QPainter::Antialiasing,true);
+
+ const int L = 10;
+ const int T = (FIXED_H - IMAGE_H)/2;
+ QRect rc(L, T, IMAGE_W, IMAGE_H);
+
+ // [later] transform the painter should also work;
+ // but i don't get the expected results, so have to use two images
+ if(_collapsed)
+ painter.drawImage(rc, S_TriangleRight);
+ else
+ painter.drawImage(rc, S_TriangleDown);
+
+ }
+
+ bool Collapsed() {return _collapsed;}
+ void SetCollapsed(bool b)
+ {
+ _collapsed = b;
+ this->update();
+ }
+
+protected:
+ virtual void mousePressEvent(QMouseEvent* e)
+ {
+ if(e->buttons() == Qt::LeftButton)
+ {
+ _collapsed = !_collapsed;
+ this->update();
+ emit LPressSignal();
+ }
+ }
+
+private:
+ bool _collapsed;
+};
+
+ExpandablePanel::ExpandablePanel(QWidget* parent, bool collapsed)
+ : QFrame(parent)
+ , _pContent(NV_NULL)
+{
+ //_pContent = new QWidget(this);
+ Init(collapsed);
+}
+
+ExpandablePanel::ExpandablePanel( QWidget* content, QWidget* parent /*= 0*/ )
+ : QFrame(parent)
+ , _pContent(content)
+{
+ Init();
+}
+
+ExpandablePanel::~ExpandablePanel()
+{
+
+}
+
+void ExpandablePanel::SetCollapsed(bool b)
+{
+ if (_pTitle)
+ _pTitle->SetCollapsed(b);
+}
+
+void ExpandablePanel::Init(bool collapsed)
+{
+ setAutoFillBackground(true);
+ setFrameShape(QFrame::StyledPanel);
+ setFrameShadow(QFrame::Sunken);
+ _pMainLayout = new QVBoxLayout(this);
+ _pMainLayout->setSpacing(2);
+ _pMainLayout->setContentsMargins(0, 0, 0, 0);
+ _pMainLayout->setObjectName(QString::fromUtf8("mainLayout"));
+
+ _pTitle = new TitleLabelImpl(this, collapsed);
+ _pTitle->setText("TitleLabel");
+ _pMainLayout->addWidget(_pTitle);
+
+ connect(_pTitle, SIGNAL(LPressSignal()), this, SLOT(TitlePress()));
+
+ if(_pContent)
+ _pMainLayout->addWidget(_pContent);
+}
+
+void ExpandablePanel::SetTitle( const QString& title )
+{
+ _pTitle->setText(title);
+}
+
+void ExpandablePanel::TitlePress()
+{
+ if(_pTitle->Collapsed())
+ {
+ _pContent->hide();
+ }
+ else // expanded
+ {
+ _pContent->show();
+ }
+}
+
+void ExpandablePanel::AddContent( QWidget* content )
+{
+ // only support one widget as content right now
+ if (_pContent != NV_NULL) return;
+
+ _pMainLayout->addWidget(content);
+ _pContent = content;
+}
+
diff --git a/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.h b/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.h
new file mode 100644
index 0000000..ba3018d
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.h
@@ -0,0 +1,51 @@
+#ifndef ExpandablePanel_h__
+#define ExpandablePanel_h__
+
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QFrame>
+#include <QtWidgets/QLabel>
+
+#include "corelib_global.h"
+
+class TitleLabelImpl;
+class QString;
+class QVBoxLayout;
+
+class TitleLabel : public QLabel
+{
+ Q_OBJECT
+
+public:
+ TitleLabel(QWidget* parent):QLabel(parent){}
+
+signals:
+ void LPressSignal();
+};
+
+class ExpandablePanel : public QFrame
+{
+ Q_OBJECT
+
+public:
+ CORELIB_EXPORT explicit ExpandablePanel(QWidget* parent, bool collapsed = false);
+ explicit ExpandablePanel(QWidget* content, QWidget* parent);
+ virtual ~ExpandablePanel();
+
+ CORELIB_EXPORT void SetTitle(const QString& title);
+ void SetCollapsed(bool b);
+ QWidget* Content() {return _pContent;}
+ CORELIB_EXPORT void AddContent(QWidget* content);
+
+public slots:
+CORELIB_EXPORT void TitlePress();
+
+private:
+ void Init(bool collapsed = false);
+
+private:
+ QVBoxLayout* _pMainLayout;
+ TitleLabelImpl* _pTitle;
+ QWidget* _pContent;
+};
+
+#endif // ExpandablePanel_h__
diff --git a/tools/ArtistTools/source/CoreLib/Window/OutputWindow.cpp b/tools/ArtistTools/source/CoreLib/Window/OutputWindow.cpp
new file mode 100644
index 0000000..08867e3
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/OutputWindow.cpp
@@ -0,0 +1,22 @@
+#include "AppMainWindow.h"
+#include "OutputWindow.h"
+
+#include <QtGUI/QContextMenuEvent>
+
+OutputWindow::OutputWindow(QWidget* parent)
+ :
+ QTextBrowser(parent)
+{
+ ui.setupUi(this);
+}
+
+void OutputWindow::contextMenuEvent(QContextMenuEvent *event)
+{
+ QMenu *menu = createStandardContextMenu();
+
+ QAction* act = new QAction("&Clear All", this);
+ connect(act, SIGNAL(triggered()), this, SLOT(clear()));
+ menu->addAction(act);
+ menu->exec(event->globalPos());
+ delete menu;
+}
diff --git a/tools/ArtistTools/source/CoreLib/Window/OutputWindow.h b/tools/ArtistTools/source/CoreLib/Window/OutputWindow.h
new file mode 100644
index 0000000..5d19bb6
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/OutputWindow.h
@@ -0,0 +1,22 @@
+#ifndef OutputWindow_h__
+#define OutputWindow_h__
+
+#include <QtWidgets/QTextBrowser>
+#include "ui_OutputWindow.h"
+
+#include "UIGlobal.h"
+
+class CORELIB_EXPORT OutputWindow : public QTextBrowser
+{
+ Q_OBJECT
+
+public:
+ OutputWindow(QWidget* parent);
+
+ void contextMenuEvent(QContextMenuEvent *event);
+
+private:
+ Ui::OutputWindow ui;
+};
+
+#endif // DisplayScene_h__
diff --git a/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.cpp b/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.cpp
new file mode 100644
index 0000000..b127f1c
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.cpp
@@ -0,0 +1,17 @@
+#include "SlideSpinBox.h"
+
+void SlideSpinBoxSlots::timeout()
+{
+ //qDebug("%s", __FUNCTION__);
+ this->_cb->on_timeout();
+}
+
+void ConfigSpinBoxInt(SlideSpinBoxInt* spinBox, int minv, int maxv, int step)
+{
+ spinBox->blockSignals(true);
+ spinBox->setRange(minv, maxv);
+ spinBox->setSingleStep(step);
+ spinBox->AutoConfigDragRange();
+ spinBox->setKeyboardTracking(false);
+ spinBox->blockSignals(false);
+}
diff --git a/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.h b/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.h
new file mode 100644
index 0000000..eeb7626
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.h
@@ -0,0 +1,284 @@
+#ifndef SlideSpinBox_h__
+#define SlideSpinBox_h__
+
+#include <QtWidgets/QStyle>
+#include <QtWidgets/QStyleOptionSpinBox>
+#include <QtWidgets/QAbstractSpinBox>
+#include <QtGui/QMouseEvent>
+#include <QtCore/QTimer>
+#include <QtWidgets/QDoubleSpinBox>
+#include <QtWidgets/QSpinBox>
+
+#include "corelib_global.h"
+
+/*
+ A Lesson: never use a template to sub-class QWidgets!
+ Qt doesn't moc template widget classes;
+ So we have to use a specific 'slots-callback' pair to let the moc system work...
+ */
+class SlideSpinBoxCallback
+{
+public:
+ virtual void on_timeout() = 0;
+};
+
+class SlideSpinBoxSlots : public QObject
+{
+ Q_OBJECT
+
+public:
+ SlideSpinBoxSlots(SlideSpinBoxCallback* cb)
+ : _cb (cb)
+ {}
+
+ public slots:
+ CORELIB_EXPORT void timeout();
+
+private:
+ SlideSpinBoxCallback* _cb;
+};
+
+template<typename SpinWidget, typename ValueType>
+class SlideSpinBox : public SpinWidget, public SlideSpinBoxCallback
+{
+
+public:
+ void on_timeout()
+ {
+ //qDebug("%s", __FUNCTION__);
+ EmitDragValueChanged();
+ }
+
+public:
+ typedef ValueType value_type;
+
+ SlideSpinBox(QWidget* parent = 0)
+ : SpinWidget(parent)
+ , _dragRange(DEFAULT_DRAG_RANGE)
+ {
+ setAccelerated(true);
+
+ ResetCustState();
+
+ _pSlots = new SlideSpinBoxSlots(this);
+
+ _dragTimer.setParent(this);
+ _dragTimer.setInterval(DRAG_TIMER_INTERVAL);
+ _dragTimer.setSingleShot(true);
+ connect(&_dragTimer, SIGNAL(timeout()), _pSlots, SLOT(timeout()));
+ }
+
+ ~SlideSpinBox()
+ {
+ delete _pSlots;
+ }
+
+ void SetDragRange(int range)
+ {
+ if(range < MIN_DRAG_RANGE)
+ range = MIN_DRAG_RANGE;
+ else if(range > MAX_DRAG_RANGE)
+ range = MAX_DRAG_RANGE;
+
+ _dragRange = range;
+ }
+
+ void AutoConfigDragRange()
+ {
+ ValueType minv = this->minimum();
+ ValueType maxv = this->maximum();
+
+ double vrange = maxv - minv;
+ double step = 1.0;
+
+ if(vrange <= 1.0)
+ {
+ step = 0.01;
+ }
+ else if(vrange <= 10.0)
+ {
+ step = 0.1;
+ }
+
+ double pixelError = 2.0;
+ double dragRange = vrange * pixelError / step;
+
+ SetDragRange((int)dragRange);
+ }
+
+protected:
+ void mouseMoveEvent ( QMouseEvent * event )
+ {
+ if(!_dragBegin)
+ {
+ QAbstractSpinBox::mouseMoveEvent(event);
+ return;
+ }
+
+ if(!_dragging)
+ {
+ _dragging = true;
+ _cursor = this->cursor();
+
+ this->setCursor(Qt::SizeVerCursor);
+ }
+
+ //if(_dragging)
+ //{
+ // _dragTimer.start(); // always restart, we only need the timeout event;
+ //}
+
+ event->accept();
+ DragValue(event->pos());
+ }
+
+ void mousePressEvent( QMouseEvent * event )
+ {
+ if(event->button() == Qt::LeftButton)
+ {
+ SetupCustState(event);
+ }
+
+ if(_dragging)
+ blockSignals(true);
+ QAbstractSpinBox::mousePressEvent(event);
+ if(_dragging)
+ blockSignals(false);
+ }
+
+ void mouseReleaseEvent( QMouseEvent * event )
+ {
+ if(_dragging)
+ {
+ setCursor(_cursor);
+ _dragTimer.stop();
+ }
+
+ QAbstractSpinBox::mouseReleaseEvent(event);
+ //if(_dragBegin)
+ // EmitDragValueChanged();
+
+ ResetCustState();
+ }
+
+ void timerEvent(QTimerEvent *event)
+ {
+ if(_dragging)
+ {
+ // stop timer event to disable acceleration/auto-stepping
+ event->ignore();
+ return;
+ }
+
+ event->accept();
+
+ if(_dragBegin) blockSignals(true);
+ QAbstractSpinBox::timerEvent(event);
+ if(_dragBegin) blockSignals(false);
+ }
+
+private:
+ enum
+ {
+ MIN_DRAG_RANGE = 50,
+ MAX_DRAG_RANGE = 500,
+
+ DEFAULT_DRAG_RANGE = 100,
+
+ DRAG_TIMER_INTERVAL= 30, // in msec
+ };
+
+ bool SetupCustState(QMouseEvent* event)
+ {
+ QStyleOptionSpinBox opt;
+ this->initStyleOption(&opt);
+ QStyle::SubControl hitControl = this->style()->hitTestComplexControl(QStyle::CC_SpinBox, &opt, event->pos());
+ if(hitControl != QStyle::SC_SpinBoxUp && hitControl != QStyle::SC_SpinBoxDown)
+ return false;
+
+ _pressPosition = event->pos();
+ _dragging = false;
+ _dragBegin = true;
+ _pressValue = this->value();
+ _dragValue = this->value();
+
+ return true;
+ }
+
+ void ResetCustState()
+ {
+ _dragBegin = false;
+ _dragging = false;
+ }
+
+ void DragValue(const QPoint& pos)
+ {
+ ValueType valueRange = this->maximum() - this->minimum();
+
+ double dh = (double)(_pressPosition.y() - pos.y());
+ double dv = valueRange * dh / (double)_dragRange;
+ ValueType v = _pressValue + (ValueType)dv;
+
+ //blockSignals(true);
+ setValue(v);
+ //blockSignals(false);
+ }
+
+ void EmitDragValueChanged()
+ {
+ //if(this->value() != _pressValue) // value are always bound by qt (and decimal settings)
+ if(this->value() != _dragValue)
+ {
+ _dragValue = this->value();
+ emit valueChanged(this->value());
+ }
+ }
+
+ int _dragRange;
+
+ QPoint _pressPosition;
+ ValueType _pressValue;
+ ValueType _dragValue;
+
+ bool _dragging;
+ bool _dragBegin;
+ QCursor _cursor;
+
+ QTimer _dragTimer;
+ SlideSpinBoxSlots* _pSlots;
+};
+
+typedef SlideSpinBox<QDoubleSpinBox, double> SlideSpinBoxF;
+typedef SlideSpinBox<QSpinBox, int> SlideSpinBoxInt;
+
+template<typename CustSpinBox>
+class ConfigSpinBox
+{
+public:
+ typedef typename CustSpinBox::value_type ValueType;
+
+ ConfigSpinBox(CustSpinBox* spinBox, ValueType minv, ValueType maxv, ValueType step = (ValueType)1)
+ {
+ spinBox->blockSignals(true);
+ spinBox->setRange(minv, maxv);
+ spinBox->setSingleStep(step);
+ spinBox->AutoConfigDragRange();
+ spinBox->setKeyboardTracking(false);
+ SpecificConfig<ValueType>(spinBox);
+ spinBox->blockSignals(false);
+ }
+
+ template<typename T>
+ void SpecificConfig(CustSpinBox* spinBox){}
+
+ template<>
+ void SpecificConfig<double>(CustSpinBox* spinBox)
+ {
+ spinBox->setDecimals(2.0);
+ }
+};
+
+#include "corelib_global.h"
+CORELIB_EXPORT void ConfigSpinBoxInt(SlideSpinBoxInt* spinBox, int minv, int maxv, int step = (int)1);
+
+#endif // SlideSpinBox_h__
diff --git a/tools/ArtistTools/source/CoreLib/Window/SlideSpinBoxInt.h b/tools/ArtistTools/source/CoreLib/Window/SlideSpinBoxInt.h
new file mode 100644
index 0000000..393adee
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/SlideSpinBoxInt.h
@@ -0,0 +1,15 @@
+#ifndef SlideSpinBoxInt_h__
+#define SlideSpinBoxInt_h__
+
+#include <QtWidgets/QStyle>
+#include <QtWidgets/QStyleOptionSpinBox>
+#include <QtWidgets/QAbstractSpinBox>
+#include <QtGui/QMouseEvent>
+#include <QtCore/QTimer>
+#include <QtWidgets/QDoubleSpinBox>
+#include <QtWidgets/QSpinBox>
+#include <SlideSpinBox.h>
+
+// use this header as a trick to make moc work right
+
+#endif // SlideSpinBoxInt_h__
diff --git a/tools/ArtistTools/source/CoreLib/Window/TipListView.cpp b/tools/ArtistTools/source/CoreLib/Window/TipListView.cpp
new file mode 100644
index 0000000..b91fd3e
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/TipListView.cpp
@@ -0,0 +1,42 @@
+#include "TipListView.h"
+#include <QtWidgets/QToolTip>
+#include <QtCore/QEvent>
+#include <QtGUI/QEvent.h>
+
+
+TipListView::TipListView(QWidget* parent)
+ :QListWidget(parent)
+{
+}
+
+void TipListView::setTips(QStringList& tips)
+{
+ mTips = tips;
+}
+
+bool TipListView::event(QEvent *evt)
+{
+ if (evt->type() == QEvent::ToolTip)
+ {
+ if (mTips.size() > 0)
+ {
+ QHelpEvent *helpEvent = (QHelpEvent *)(evt);
+ const QPoint& pos = helpEvent->pos();
+ QListWidgetItem* pItem = itemAt(pos);
+ int index = 0, num = count();
+ for (int i = 0; i < num; ++i)
+ {
+ QListWidgetItem* pi = item(i);
+ if (pi == pItem && mTips.size() > i)
+ {
+ QToolTip::showText(helpEvent->globalPos(), mTips[i]);
+ return true;
+ }
+ }
+ }
+ //QToolTip::hideText();
+ //evt->ignore();
+ //return true;
+ }
+ return QListWidget::event(evt);
+}
diff --git a/tools/ArtistTools/source/CoreLib/Window/TipListView.h b/tools/ArtistTools/source/CoreLib/Window/TipListView.h
new file mode 100644
index 0000000..6913baa
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/TipListView.h
@@ -0,0 +1,26 @@
+#ifndef TipListView_h__
+#define TipListView_h__
+
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QListWidget>
+#include <QtCore/QEvent>
+
+#include "corelib_global.h"
+
+class TipListView : public QListWidget
+{
+ Q_OBJECT
+
+public:
+ TipListView(QWidget* parent = 0);
+
+ void setTips(QStringList& tips);
+
+protected:
+ bool event(QEvent *);
+private:
+
+ QStringList mTips;
+
+};
+#endif // TipListView_h__
diff --git a/tools/ArtistTools/source/CoreLib/Window/UIGlobal.h b/tools/ArtistTools/source/CoreLib/Window/UIGlobal.h
new file mode 100644
index 0000000..3d50132
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Window/UIGlobal.h
@@ -0,0 +1,37 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#pragma once
+
+#define USE_MATERIAL_SET 1
+#define USE_CURVE_EDITOR 0
+#define USE_TEXTURE_BRIGHTNESS 0
+
+#define USE_INTERNAL_GRAPHICAL_MATERIAL 0
+
+#include "corelib_global.h" \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/corelib_global.h b/tools/ArtistTools/source/CoreLib/corelib_global.h
new file mode 100644
index 0000000..b3c0016
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/corelib_global.h
@@ -0,0 +1,20 @@
+#ifndef CORELIB_GLOBAL_H
+#define CORELIB_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+#include <Nv/NvBlastCommon.h>
+
+#ifdef CORELIB_LIB
+# define CORELIB_EXPORT Q_DECL_EXPORT
+#else
+# define CORELIB_EXPORT Q_DECL_IMPORT
+#endif
+
+#pragma warning(disable:4018)
+#pragma warning(disable:4099)
+#pragma warning(disable:4101)
+#pragma warning(disable:4267)
+#pragma warning(disable:4273)
+#pragma warning(disable:4996)
+
+#endif // CORELIB_GLOBAL_H