diff options
Diffstat (limited to 'tools/ArtistTools/source/CoreLib/Scene')
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/Camera.cpp | 867 | ||||
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/Camera.h | 128 | ||||
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/Gamepad.cpp | 1310 | ||||
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/Gamepad.h | 68 | ||||
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.cpp | 319 | ||||
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.h | 173 | ||||
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/Light.cpp | 744 | ||||
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/Light.h | 152 | ||||
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/MeshData.cpp | 108 | ||||
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/MeshData.h | 74 | ||||
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/Mouse.cpp | 105 | ||||
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/Mouse.h | 103 | ||||
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/SimpleScene.cpp | 1312 | ||||
| -rw-r--r-- | tools/ArtistTools/source/CoreLib/Scene/SimpleScene.h | 184 |
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, ¶m->eye, sizeof(_eye)); + memcpy(&_at, ¶m->at, sizeof(_at)); + _lookDistance = param->lookDistance; + memcpy(&_orientation, ¶m->orientation, sizeof(_orientation)); + memcpy(&_viewMatrix, ¶m->viewMatrix, sizeof(_viewMatrix)); + memcpy(&_projectionMatrix, ¶m->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 ¶m) +{ + 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*)¶m, sizeof(SimpleShaderParam) ); + + SimpleRenderable::Draw(SimpleRenderable::LIGHT); + + // draw light ray + gfsdk_makeIdentity(param.world); + RenderInterface::CopyShaderParam(RenderInterface::SHADER_TYPE_SIMPLE_COLOR, + (void*)¶m, 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, ¶m->color, sizeof(atcore_float3)); + + atcore_float3 axisX, axisY, axisZ, lightPos; + memcpy(&axisX, ¶m->lightAxisX, sizeof(atcore_float3)); + memcpy(&axisY, ¶m->lightAxisY, sizeof(atcore_float3)); + memcpy(&axisZ, ¶m->lightAxisZ, sizeof(atcore_float3)); + memcpy(&lightPos, ¶m->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(¶m->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(¶m->lightAxisX, &axisX, sizeof(atcore_float3)); + memcpy(¶m->lightAxisY, &axisY, sizeof(atcore_float3)); + memcpy(¶m->lightAxisZ, &axisZ, sizeof(atcore_float3)); + memcpy(¶m->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(¢er, &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 ¶m); + 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*)¶m, 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*)¶m, 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*)¶m, 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; +}; + |