aboutsummaryrefslogtreecommitdiff
path: root/tools/ArtistTools/source/CoreLib/Scene
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ArtistTools/source/CoreLib/Scene')
-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
14 files changed, 5647 insertions, 0 deletions
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;
+};
+