mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-12 03:02:30 +00:00
feat(gx): add directxmath for MinGW
This commit is contained in:
parent
0d09dee4b3
commit
3e77eb935a
51 changed files with 49251 additions and 12 deletions
257
vendor/directxmath-3.19.0/Stereo3D/Stereo3DMatrixHelper.cpp
vendored
Normal file
257
vendor/directxmath-3.19.0/Stereo3D/Stereo3DMatrixHelper.cpp
vendored
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
//-------------------------------------------------------------------------------------
|
||||
// Stereo3DMatrixHelper.cpp -- SIMD C++ Math helper for Stereo 3D matricies
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
#include "Stereo3DMatrixHelper.h"
|
||||
|
||||
using namespace DirectX;
|
||||
|
||||
namespace
|
||||
{
|
||||
inline bool StereoProjectionHelper
|
||||
(
|
||||
const STEREO_PARAMETERS& stereoParameters,
|
||||
_Out_ float* fVirtualProjection,
|
||||
_Out_ float* zNearWidth,
|
||||
_Out_ float* zNearHeight,
|
||||
float FovAngleY,
|
||||
float AspectRatio,
|
||||
float NearZ
|
||||
)
|
||||
{
|
||||
// note that most people have difficulty fusing images into 3D
|
||||
// if the separation equals even just the human average. by
|
||||
// reducing the separation (interocular distance) by 1/2, we
|
||||
// guarantee a larger subset of people will see full 3D
|
||||
|
||||
// the conservative setting should always be used. the only problem
|
||||
// with the conservative setting is that the 3D effect will be less
|
||||
// impressive on smaller screens (which makes sense, since your eye
|
||||
// cannot be tricked as easily based on the smaller fov). to simulate
|
||||
// the effect of a larger screen, use the liberal settings (debug only)
|
||||
|
||||
// Conservative Settings: * max acuity angle: 0.8f degrees * interoc distance: 1.25 inches
|
||||
|
||||
// Liberal Settings: * max acuity angle: 1.6f degrees * interoc distance: 2.5f inches
|
||||
|
||||
// maximum visual accuity angle allowed is 3.2 degrees for
|
||||
// a physical scene, and 1.6 degrees for a virtual one.
|
||||
// thus we cannot allow an object to appear any closer to
|
||||
// the viewer than 1.6 degrees (divided by two for most
|
||||
// half-angle calculations)
|
||||
|
||||
static const float fMaxStereoDistance = 780; // inches (should be between 10 and 20m)
|
||||
static const float fMaxVisualAcuityAngle = 1.6f * (XM_PI / 180.0f); // radians
|
||||
static const float fInterocularDistance = 1.25f; // inches
|
||||
|
||||
float fDisplayHeight = stereoParameters.fDisplaySizeInches / sqrtf(AspectRatio * AspectRatio + 1.0f);
|
||||
float fDisplayWidth = fDisplayHeight * AspectRatio;
|
||||
float fHalfInterocular = 0.5f * fInterocularDistance * stereoParameters.fStereoExaggerationFactor;
|
||||
float fHalfPixelWidth = fDisplayWidth / stereoParameters.fPixelResolutionWidth * 0.5f;
|
||||
float fHalfMaximumAcuityAngle = fMaxVisualAcuityAngle * 0.5f * stereoParameters.fStereoExaggerationFactor;
|
||||
// float fHalfWidth = fDisplayWidth * 0.5f;
|
||||
|
||||
float fMaxSeparationAcuityAngle = atanf(fHalfInterocular / fMaxStereoDistance);
|
||||
float fMaxSeparationDistance = fHalfPixelWidth / tanf(fMaxSeparationAcuityAngle);
|
||||
float fRefinedMaxStereoDistance = fMaxStereoDistance - fMaxSeparationDistance;
|
||||
float fFovHalfAngle = FovAngleY / 2.0f;
|
||||
|
||||
bool ComfortableResult = true;
|
||||
if (fRefinedMaxStereoDistance < 0.0f || fMaxSeparationDistance > 0.1f * fMaxStereoDistance)
|
||||
{
|
||||
// Pixel resolution is too low to offer a comfortable stereo experience
|
||||
ComfortableResult = false;
|
||||
}
|
||||
|
||||
float fRefinedMaxSeparationAcuityAngle = atanf(fHalfInterocular / (fRefinedMaxStereoDistance));
|
||||
float fPhysicalZNearDistance = fHalfInterocular / tanf(fHalfMaximumAcuityAngle);
|
||||
// float fScalingFactor = fHalfMaximumAcuityAngle / atanf(fHalfInterocular / stereoParameters.fViewerDistanceInches);
|
||||
|
||||
float fNearZSeparation = tanf(fRefinedMaxSeparationAcuityAngle) * (fRefinedMaxStereoDistance - fPhysicalZNearDistance);
|
||||
// float fNearZSeparation2 = fHalfInterocular * (fRefinedMaxStereoDistance - fPhysicalZNearDistance) / fRefinedMaxStereoDistance;
|
||||
|
||||
(*zNearHeight) = cosf(fFovHalfAngle) / sinf(fFovHalfAngle);
|
||||
(*zNearWidth) = (*zNearHeight) / AspectRatio;
|
||||
(*fVirtualProjection) = (fNearZSeparation * NearZ * (*zNearWidth * 4.0f)) / (2.0f * NearZ);
|
||||
|
||||
return ComfortableResult;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void DirectX::StereoCreateDefaultParameters
|
||||
(
|
||||
STEREO_PARAMETERS& stereoParameters
|
||||
)
|
||||
{
|
||||
// Default assumption is 1920x1200 resolution, a 22" LCD monitor, and a 2' viewing distance
|
||||
stereoParameters.fViewerDistanceInches = 24.0f;
|
||||
stereoParameters.fPixelResolutionWidth = 1920.0f;
|
||||
stereoParameters.fPixelResolutionHeight = 1200.0f;
|
||||
stereoParameters.fDisplaySizeInches = 22.0f;
|
||||
|
||||
stereoParameters.fStereoSeparationFactor = 1.0f;
|
||||
stereoParameters.fStereoExaggerationFactor = 1.0f;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
XMMATRIX DirectX::StereoProjectionFovLH
|
||||
(
|
||||
_In_opt_ const STEREO_PARAMETERS* pStereoParameters,
|
||||
STEREO_CHANNEL Channel,
|
||||
float FovAngleY,
|
||||
float AspectRatio,
|
||||
float NearZ,
|
||||
float FarZ,
|
||||
STEREO_MODE StereoMode
|
||||
)
|
||||
{
|
||||
assert(Channel == STEREO_CHANNEL_LEFT || Channel == STEREO_CHANNEL_RIGHT);
|
||||
assert(StereoMode == STEREO_MODE_NORMAL || StereoMode == STEREO_MODE_INVERTED);
|
||||
assert(!XMScalarNearEqual(FovAngleY, 0.0f, 0.00001f * 2.0f));
|
||||
assert(!XMScalarNearEqual(AspectRatio, 0.0f, 0.00001f));
|
||||
assert(!XMScalarNearEqual(FarZ, NearZ, 0.00001f));
|
||||
|
||||
STEREO_PARAMETERS DefaultParameters = {};
|
||||
if (pStereoParameters == nullptr)
|
||||
{
|
||||
StereoCreateDefaultParameters(DefaultParameters);
|
||||
pStereoParameters = &DefaultParameters;
|
||||
}
|
||||
|
||||
assert(pStereoParameters->fStereoSeparationFactor >= 0.0f && pStereoParameters->fStereoSeparationFactor <= 1.0f);
|
||||
assert(pStereoParameters->fStereoExaggerationFactor >= 1.0f && pStereoParameters->fStereoExaggerationFactor <= 2.0f);
|
||||
|
||||
float fVirtualProjection = 0.0f;
|
||||
float zNearWidth = 0.0f;
|
||||
float zNearHeight = 0.0f;
|
||||
StereoProjectionHelper(*pStereoParameters, &fVirtualProjection, &zNearWidth, &zNearHeight, FovAngleY, AspectRatio, NearZ);
|
||||
|
||||
fVirtualProjection *= pStereoParameters->fStereoSeparationFactor; // incorporate developer defined bias
|
||||
|
||||
//
|
||||
// By applying a translation, we are forcing our cameras to be parallel
|
||||
//
|
||||
|
||||
float fInvertedAngle = atanf(fVirtualProjection / (2.0f * NearZ));
|
||||
|
||||
XMMATRIX proj = XMMatrixPerspectiveFovLH(FovAngleY, AspectRatio, NearZ, FarZ);
|
||||
|
||||
XMMATRIX patchedProjection;
|
||||
if (Channel == STEREO_CHANNEL_LEFT)
|
||||
{
|
||||
if (StereoMode > STEREO_MODE_NORMAL)
|
||||
{
|
||||
XMMATRIX rots = XMMatrixRotationY(fInvertedAngle);
|
||||
XMMATRIX trans = XMMatrixTranslation(-fVirtualProjection, 0, 0);
|
||||
patchedProjection = XMMatrixMultiply(XMMatrixMultiply(rots, trans), proj);
|
||||
}
|
||||
else
|
||||
{
|
||||
XMMATRIX trans = XMMatrixTranslation(-fVirtualProjection, 0, 0);
|
||||
patchedProjection = XMMatrixMultiply(trans, proj);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (StereoMode > STEREO_MODE_NORMAL)
|
||||
{
|
||||
XMMATRIX rots = XMMatrixRotationY(-fInvertedAngle);
|
||||
XMMATRIX trans = XMMatrixTranslation(fVirtualProjection, 0, 0);
|
||||
patchedProjection = XMMatrixMultiply(XMMatrixMultiply(rots, trans), proj);
|
||||
}
|
||||
else
|
||||
{
|
||||
XMMATRIX trans = XMMatrixTranslation(fVirtualProjection, 0, 0);
|
||||
patchedProjection = XMMatrixMultiply(trans, proj);
|
||||
}
|
||||
}
|
||||
|
||||
return patchedProjection;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
XMMATRIX DirectX::StereoProjectionFovRH
|
||||
(
|
||||
_In_opt_ const STEREO_PARAMETERS* pStereoParameters,
|
||||
STEREO_CHANNEL Channel,
|
||||
float FovAngleY,
|
||||
float AspectRatio,
|
||||
float NearZ,
|
||||
float FarZ,
|
||||
STEREO_MODE StereoMode
|
||||
)
|
||||
{
|
||||
assert(Channel == STEREO_CHANNEL_LEFT || Channel == STEREO_CHANNEL_RIGHT);
|
||||
assert(StereoMode == STEREO_MODE_NORMAL || StereoMode == STEREO_MODE_INVERTED);
|
||||
assert(!XMScalarNearEqual(FovAngleY, 0.0f, 0.00001f * 2.0f));
|
||||
assert(!XMScalarNearEqual(AspectRatio, 0.0f, 0.00001f));
|
||||
assert(!XMScalarNearEqual(FarZ, NearZ, 0.00001f));
|
||||
|
||||
STEREO_PARAMETERS DefaultParameters = {};
|
||||
if (pStereoParameters == nullptr)
|
||||
{
|
||||
StereoCreateDefaultParameters(DefaultParameters);
|
||||
pStereoParameters = &DefaultParameters;
|
||||
}
|
||||
|
||||
assert(pStereoParameters->fStereoSeparationFactor >= 0.0f && pStereoParameters->fStereoSeparationFactor <= 1.0f);
|
||||
assert(pStereoParameters->fStereoExaggerationFactor >= 1.0f && pStereoParameters->fStereoExaggerationFactor <= 2.0f);
|
||||
|
||||
float fVirtualProjection = 0.0f;
|
||||
float zNearWidth = 0.0f;
|
||||
float zNearHeight = 0.0f;
|
||||
StereoProjectionHelper(*pStereoParameters, &fVirtualProjection, &zNearWidth, &zNearHeight, FovAngleY, AspectRatio, NearZ);
|
||||
|
||||
fVirtualProjection *= pStereoParameters->fStereoSeparationFactor; // incorporate developer defined bias
|
||||
|
||||
//
|
||||
// By applying a translation, we are forcing our cameras to be parallel
|
||||
//
|
||||
|
||||
float fInvertedAngle = atanf(fVirtualProjection / (2.0f * NearZ));
|
||||
|
||||
XMMATRIX proj = XMMatrixPerspectiveFovRH(FovAngleY, AspectRatio, NearZ, FarZ);
|
||||
|
||||
//
|
||||
// By applying a translation, we are forcing our cameras to be parallel
|
||||
//
|
||||
|
||||
XMMATRIX patchedProjection;
|
||||
if (Channel == STEREO_CHANNEL_LEFT)
|
||||
{
|
||||
if (StereoMode > STEREO_MODE_NORMAL)
|
||||
{
|
||||
XMMATRIX rots = XMMatrixRotationY(fInvertedAngle);
|
||||
XMMATRIX trans = XMMatrixTranslation(-fVirtualProjection, 0, 0);
|
||||
patchedProjection = XMMatrixMultiply(XMMatrixMultiply(rots, trans), proj);
|
||||
}
|
||||
else
|
||||
{
|
||||
XMMATRIX trans = XMMatrixTranslation(-fVirtualProjection, 0, 0);
|
||||
patchedProjection = XMMatrixMultiply(trans, proj);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (StereoMode > STEREO_MODE_NORMAL)
|
||||
{
|
||||
XMMATRIX rots = XMMatrixRotationY(-fInvertedAngle);
|
||||
XMMATRIX trans = XMMatrixTranslation(fVirtualProjection, 0, 0);
|
||||
patchedProjection = XMMatrixMultiply(XMMatrixMultiply(rots, trans), proj);
|
||||
}
|
||||
else
|
||||
{
|
||||
XMMATRIX trans = XMMatrixTranslation(fVirtualProjection, 0, 0);
|
||||
patchedProjection = XMMatrixMultiply(trans, proj);
|
||||
}
|
||||
}
|
||||
|
||||
return patchedProjection;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue