parent
a7ac577d15
commit
645eda8fd4
@ -1,20 +0,0 @@
|
||||
|
||||
Short term:
|
||||
- Improve quality of fast compressors.
|
||||
- More accelerated compressors.
|
||||
- Accelerate mipmap generation.
|
||||
- Generic RGB pixel format conversion.
|
||||
- Do not assume that alpha is used for transparency.
|
||||
|
||||
Longer term:
|
||||
- support for DXT1a format.
|
||||
- support for correct cubemap filtering.
|
||||
- support for correct cubemap borders and atlas borders. (Crytek request)
|
||||
- support for 3d textures & 3d compression.
|
||||
- Add support for occlusion map, horizon map & bent normal map generation.
|
||||
- Add support for accurate normal map mipmap computation. Using lighting integrals.
|
||||
- Add support for YCoCg and JPEG-LS color transforms. Add high quality DXT5-RGB compression.
|
||||
- Add full support for mirror wrap mode.
|
||||
- Generation of cone maps for relief mapping.
|
||||
- Add min/max box mipmap filters.
|
||||
|
@ -1,129 +1,129 @@
|
||||
#
|
||||
# Try to find nVidia's Cg compiler, runtime libraries, and include path.
|
||||
# Once done this will define
|
||||
#
|
||||
# CG_FOUND =system has NVidia Cg and it can be used.
|
||||
# CG_INCLUDE_PATH = directory where cg.h resides
|
||||
# CG_LIBRARY = full path to libCg.so (Cg.DLL on win32)
|
||||
# CG_GL_LIBRARY = full path to libCgGL.so (CgGL.dll on win32)
|
||||
# CG_COMPILER = full path to cgc (cgc.exe on win32)
|
||||
#
|
||||
|
||||
# On OSX default to using the framework version of Cg.
|
||||
|
||||
IF (APPLE)
|
||||
INCLUDE(${CMAKE_ROOT}/Modules/CMakeFindFrameworks.cmake)
|
||||
SET(CG_FRAMEWORK_INCLUDES)
|
||||
CMAKE_FIND_FRAMEWORKS(Cg)
|
||||
IF (Cg_FRAMEWORKS)
|
||||
FOREACH(dir ${Cg_FRAMEWORKS})
|
||||
SET(CG_FRAMEWORK_INCLUDES ${CG_FRAMEWORK_INCLUDES}
|
||||
${dir}/Headers ${dir}/PrivateHeaders)
|
||||
ENDFOREACH(dir)
|
||||
|
||||
# Find the include dir
|
||||
FIND_PATH(CG_INCLUDE_PATH cg.h
|
||||
${CG_FRAMEWORK_INCLUDES}
|
||||
)
|
||||
|
||||
# Since we are using Cg framework, we must link to it.
|
||||
# Note, we use weak linking, so that it works even when Cg is not available.
|
||||
SET(CG_LIBRARY "-weak_framework Cg" CACHE STRING "Cg library")
|
||||
SET(CG_GL_LIBRARY "-weak_framework Cg" CACHE STRING "Cg GL library")
|
||||
ENDIF (Cg_FRAMEWORKS)
|
||||
FIND_PROGRAM(CG_COMPILER cgc
|
||||
/usr/bin
|
||||
/usr/local/bin
|
||||
DOC "The Cg compiler"
|
||||
)
|
||||
ELSE (APPLE)
|
||||
IF (WIN32)
|
||||
FIND_PROGRAM( CG_COMPILER cgc
|
||||
$ENV{CG_BIN_PATH}
|
||||
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/bin
|
||||
$ENV{PROGRAMFILES}/Cg
|
||||
${PROJECT_SOURCE_DIR}/../Cg
|
||||
DOC "The Cg Compiler"
|
||||
)
|
||||
IF (CG_COMPILER)
|
||||
GET_FILENAME_COMPONENT(CG_COMPILER_DIR ${CG_COMPILER} PATH)
|
||||
GET_FILENAME_COMPONENT(CG_COMPILER_SUPER_DIR ${CG_COMPILER_DIR} PATH)
|
||||
ELSE (CG_COMPILER)
|
||||
SET (CG_COMPILER_DIR .)
|
||||
SET (CG_COMPILER_SUPER_DIR ..)
|
||||
ENDIF (CG_COMPILER)
|
||||
FIND_PATH( CG_INCLUDE_PATH Cg/cg.h
|
||||
$ENV{CG_INC_PATH}
|
||||
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/include
|
||||
$ENV{PROGRAMFILES}/Cg
|
||||
${PROJECT_SOURCE_DIR}/../Cg
|
||||
${CG_COMPILER_SUPER_DIR}/include
|
||||
${CG_COMPILER_DIR}
|
||||
DOC "The directory where Cg/cg.h resides"
|
||||
)
|
||||
FIND_LIBRARY( CG_LIBRARY
|
||||
NAMES Cg
|
||||
PATHS
|
||||
$ENV{CG_LIB_PATH}
|
||||
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/lib
|
||||
$ENV{PROGRAMFILES}/Cg
|
||||
${PROJECT_SOURCE_DIR}/../Cg
|
||||
${CG_COMPILER_SUPER_DIR}/lib
|
||||
${CG_COMPILER_DIR}
|
||||
DOC "The Cg runtime library"
|
||||
)
|
||||
FIND_LIBRARY( CG_GL_LIBRARY
|
||||
NAMES CgGL
|
||||
PATHS
|
||||
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/lib
|
||||
$ENV{PROGRAMFILES}/Cg
|
||||
${PROJECT_SOURCE_DIR}/../Cg
|
||||
${CG_COMPILER_SUPER_DIR}/lib
|
||||
${CG_COMPILER_DIR}
|
||||
DOC "The Cg runtime library"
|
||||
)
|
||||
ELSE (WIN32)
|
||||
FIND_PROGRAM( CG_COMPILER cgc
|
||||
/usr/bin
|
||||
/usr/local/bin
|
||||
DOC "The Cg Compiler"
|
||||
)
|
||||
GET_FILENAME_COMPONENT(CG_COMPILER_DIR "${CG_COMPILER}" PATH)
|
||||
GET_FILENAME_COMPONENT(CG_COMPILER_SUPER_DIR "${CG_COMPILER_DIR}" PATH)
|
||||
FIND_PATH( CG_INCLUDE_PATH Cg/cg.h
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
${CG_COMPILER_SUPER_DIR}/include
|
||||
DOC "The directory where Cg/cg.h resides"
|
||||
)
|
||||
FIND_LIBRARY( CG_LIBRARY Cg
|
||||
PATHS
|
||||
/usr/lib64
|
||||
/usr/lib
|
||||
/usr/local/lib64
|
||||
/usr/local/lib
|
||||
${CG_COMPILER_SUPER_DIR}/lib64
|
||||
${CG_COMPILER_SUPER_DIR}/lib
|
||||
DOC "The Cg runtime library"
|
||||
)
|
||||
SET(CG_LIBRARY ${CG_LIBRARY} -lpthread)
|
||||
FIND_LIBRARY( CG_GL_LIBRARY CgGL
|
||||
PATHS
|
||||
/usr/lib64
|
||||
/usr/lib
|
||||
/usr/local/lib64
|
||||
/usr/local/lib
|
||||
${CG_COMPILER_SUPER_DIR}/lib64
|
||||
${CG_COMPILER_SUPER_DIR}/lib
|
||||
DOC "The Cg runtime library"
|
||||
)
|
||||
ENDIF (WIN32)
|
||||
ENDIF (APPLE)
|
||||
|
||||
IF (CG_INCLUDE_PATH)
|
||||
SET( CG_FOUND 1 CACHE STRING "Set to 1 if CG is found, 0 otherwise")
|
||||
ELSE (CG_INCLUDE_PATH)
|
||||
SET( CG_FOUND 0 CACHE STRING "Set to 1 if CG is found, 0 otherwise")
|
||||
ENDIF (CG_INCLUDE_PATH)
|
||||
|
||||
MARK_AS_ADVANCED( CG_FOUND )
|
||||
#
|
||||
# Try to find NVIDIA's Cg compiler, runtime libraries, and include path.
|
||||
# Once done this will define
|
||||
#
|
||||
# CG_FOUND =system has NVIDIA Cg and it can be used.
|
||||
# CG_INCLUDE_PATH = directory where cg.h resides
|
||||
# CG_LIBRARY = full path to libCg.so (Cg.DLL on win32)
|
||||
# CG_GL_LIBRARY = full path to libCgGL.so (CgGL.dll on win32)
|
||||
# CG_COMPILER = full path to cgc (cgc.exe on win32)
|
||||
#
|
||||
|
||||
# On OSX default to using the framework version of Cg.
|
||||
|
||||
IF (APPLE)
|
||||
INCLUDE(${CMAKE_ROOT}/Modules/CMakeFindFrameworks.cmake)
|
||||
SET(CG_FRAMEWORK_INCLUDES)
|
||||
CMAKE_FIND_FRAMEWORKS(Cg)
|
||||
IF (Cg_FRAMEWORKS)
|
||||
FOREACH(dir ${Cg_FRAMEWORKS})
|
||||
SET(CG_FRAMEWORK_INCLUDES ${CG_FRAMEWORK_INCLUDES}
|
||||
${dir}/Headers ${dir}/PrivateHeaders)
|
||||
ENDFOREACH(dir)
|
||||
|
||||
# Find the include dir
|
||||
FIND_PATH(CG_INCLUDE_PATH cg.h
|
||||
${CG_FRAMEWORK_INCLUDES}
|
||||
)
|
||||
|
||||
# Since we are using Cg framework, we must link to it.
|
||||
# Note, we use weak linking, so that it works even when Cg is not available.
|
||||
SET(CG_LIBRARY "-weak_framework Cg" CACHE STRING "Cg library")
|
||||
SET(CG_GL_LIBRARY "-weak_framework Cg" CACHE STRING "Cg GL library")
|
||||
ENDIF (Cg_FRAMEWORKS)
|
||||
FIND_PROGRAM(CG_COMPILER cgc
|
||||
/usr/bin
|
||||
/usr/local/bin
|
||||
DOC "The Cg compiler"
|
||||
)
|
||||
ELSE (APPLE)
|
||||
IF (WIN32)
|
||||
FIND_PROGRAM( CG_COMPILER cgc
|
||||
$ENV{CG_BIN_PATH}
|
||||
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/bin
|
||||
$ENV{PROGRAMFILES}/Cg
|
||||
${PROJECT_SOURCE_DIR}/../Cg
|
||||
DOC "The Cg Compiler"
|
||||
)
|
||||
IF (CG_COMPILER)
|
||||
GET_FILENAME_COMPONENT(CG_COMPILER_DIR ${CG_COMPILER} PATH)
|
||||
GET_FILENAME_COMPONENT(CG_COMPILER_SUPER_DIR ${CG_COMPILER_DIR} PATH)
|
||||
ELSE (CG_COMPILER)
|
||||
SET (CG_COMPILER_DIR .)
|
||||
SET (CG_COMPILER_SUPER_DIR ..)
|
||||
ENDIF (CG_COMPILER)
|
||||
FIND_PATH( CG_INCLUDE_PATH Cg/cg.h
|
||||
$ENV{CG_INC_PATH}
|
||||
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/include
|
||||
$ENV{PROGRAMFILES}/Cg
|
||||
${PROJECT_SOURCE_DIR}/../Cg
|
||||
${CG_COMPILER_SUPER_DIR}/include
|
||||
${CG_COMPILER_DIR}
|
||||
DOC "The directory where Cg/cg.h resides"
|
||||
)
|
||||
FIND_LIBRARY( CG_LIBRARY
|
||||
NAMES Cg
|
||||
PATHS
|
||||
$ENV{CG_LIB_PATH}
|
||||
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/lib
|
||||
$ENV{PROGRAMFILES}/Cg
|
||||
${PROJECT_SOURCE_DIR}/../Cg
|
||||
${CG_COMPILER_SUPER_DIR}/lib
|
||||
${CG_COMPILER_DIR}
|
||||
DOC "The Cg runtime library"
|
||||
)
|
||||
FIND_LIBRARY( CG_GL_LIBRARY
|
||||
NAMES CgGL
|
||||
PATHS
|
||||
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/lib
|
||||
$ENV{PROGRAMFILES}/Cg
|
||||
${PROJECT_SOURCE_DIR}/../Cg
|
||||
${CG_COMPILER_SUPER_DIR}/lib
|
||||
${CG_COMPILER_DIR}
|
||||
DOC "The Cg runtime library"
|
||||
)
|
||||
ELSE (WIN32)
|
||||
FIND_PROGRAM( CG_COMPILER cgc
|
||||
/usr/bin
|
||||
/usr/local/bin
|
||||
DOC "The Cg Compiler"
|
||||
)
|
||||
GET_FILENAME_COMPONENT(CG_COMPILER_DIR "${CG_COMPILER}" PATH)
|
||||
GET_FILENAME_COMPONENT(CG_COMPILER_SUPER_DIR "${CG_COMPILER_DIR}" PATH)
|
||||
FIND_PATH( CG_INCLUDE_PATH Cg/cg.h
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
${CG_COMPILER_SUPER_DIR}/include
|
||||
DOC "The directory where Cg/cg.h resides"
|
||||
)
|
||||
FIND_LIBRARY( CG_LIBRARY Cg
|
||||
PATHS
|
||||
/usr/lib64
|
||||
/usr/lib
|
||||
/usr/local/lib64
|
||||
/usr/local/lib
|
||||
${CG_COMPILER_SUPER_DIR}/lib64
|
||||
${CG_COMPILER_SUPER_DIR}/lib
|
||||
DOC "The Cg runtime library"
|
||||
)
|
||||
SET(CG_LIBRARY ${CG_LIBRARY} -lpthread)
|
||||
FIND_LIBRARY( CG_GL_LIBRARY CgGL
|
||||
PATHS
|
||||
/usr/lib64
|
||||
/usr/lib
|
||||
/usr/local/lib64
|
||||
/usr/local/lib
|
||||
${CG_COMPILER_SUPER_DIR}/lib64
|
||||
${CG_COMPILER_SUPER_DIR}/lib
|
||||
DOC "The Cg runtime library"
|
||||
)
|
||||
ENDIF (WIN32)
|
||||
ENDIF (APPLE)
|
||||
|
||||
IF (CG_INCLUDE_PATH)
|
||||
SET( CG_FOUND 1 CACHE STRING "Set to 1 if CG is found, 0 otherwise")
|
||||
ELSE (CG_INCLUDE_PATH)
|
||||
SET( CG_FOUND 0 CACHE STRING "Set to 1 if CG is found, 0 otherwise")
|
||||
ENDIF (CG_INCLUDE_PATH)
|
||||
|
||||
MARK_AS_ADVANCED( CG_FOUND )
|
||||
|
@ -0,0 +1,32 @@
|
||||
|
||||
IF (WIN32)
|
||||
|
||||
FIND_PATH(DX10_INCLUDE_PATH D3D10.h
|
||||
PATHS
|
||||
"$ENV{DXSDK_DIR}/Include"
|
||||
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK/Include"
|
||||
DOC "The directory where D3D10.h resides")
|
||||
|
||||
FIND_LIBRARY(D3D10_LIBRARY d3d10.lib
|
||||
PATHS
|
||||
"$ENV{DXSDK_DIR}/Lib/x86"
|
||||
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK/Lib/x86"
|
||||
DOC "The directory where d3d10.lib resides")
|
||||
|
||||
FIND_LIBRARY(D3DX10_LIBRARY d3dx10.lib
|
||||
PATHS
|
||||
"$ENV{DXSDK_DIR}/Lib/x86"
|
||||
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK/Lib/x86"
|
||||
DOC "The directory where d3dx10.lib resides")
|
||||
|
||||
SET(DX10_LIBRARIES D3D10_LIBRARY D3DX10_LIBRARY)
|
||||
|
||||
ENDIF (WIN32)
|
||||
|
||||
IF (DX10_INCLUDE_PATH)
|
||||
SET( DX10_FOUND 1 CACHE STRING "Set to 1 if CG is found, 0 otherwise")
|
||||
ELSE (DX10_INCLUDE_PATH)
|
||||
SET( DX10_FOUND 0 CACHE STRING "Set to 1 if CG is found, 0 otherwise")
|
||||
ENDIF (DX10_INCLUDE_PATH)
|
||||
|
||||
MARK_AS_ADVANCED( DX10_FOUND )
|
@ -0,0 +1,67 @@
|
||||
|
||||
|
||||
|
||||
IF (WIN32)
|
||||
|
||||
# Maya plugins can only be compiled with msvc
|
||||
IF (MSVC)
|
||||
|
||||
FIND_PATH(MAYA_INCLUDE_PATH maya/MTypes.h
|
||||
PATHS
|
||||
"$ENV{PROGRAMFILES}/Autodesk/Maya8.5/include"
|
||||
"$ENV{MAYA_LOCATION}/include"
|
||||
DOC "The directory where MTypes.h resides")
|
||||
|
||||
# Find maya version!
|
||||
|
||||
FIND_LIBRARY(MAYA_FOUNDATION_LIBRARY Foundation
|
||||
PATHS
|
||||
"$ENV{PROGRAMFILES}/Autodesk/Maya8.5/lib"
|
||||
"$ENV{MAYA_LOCATION}/lib"
|
||||
DOC "The directory where Foundation.lib resides")
|
||||
|
||||
FIND_LIBRARY(MAYA_OPENMAYA_LIBRARY OpenMaya
|
||||
PATHS
|
||||
"$ENV{PROGRAMFILES}/Autodesk/Maya8.5/lib"
|
||||
"$ENV{MAYA_LOCATION}/lib"
|
||||
DOC "The directory where OpenMaya.lib resides")
|
||||
|
||||
FIND_LIBRARY(MAYA_OPENMAYAANIM_LIBRARY OpenMayaAnim
|
||||
PATHS
|
||||
"$ENV{PROGRAMFILES}/Autodesk/Maya8.5/lib"
|
||||
"$ENV{MAYA_LOCATION}/lib"
|
||||
DOC "The directory where OpenMayaAnim.lib resides")
|
||||
|
||||
SET(MAYA_LIBRARIES
|
||||
${MAYA_FOUNDATION_LIBRARY}
|
||||
${MAYA_OPENMAYA_LIBRARY}
|
||||
${MAYA_OPENMAYAANIM_LIBRARY})
|
||||
|
||||
SET(MAYA_EXTENSION ".mll")
|
||||
|
||||
ENDIF (MSVC)
|
||||
ELSE (WIN32)
|
||||
|
||||
# On linux, check gcc version.
|
||||
|
||||
# OSX and Linux
|
||||
|
||||
FIND_PATH(MAYA_INCLUDE_PATH maya/MTypes.h
|
||||
PATHS
|
||||
/usr/autodesk/maya/include
|
||||
$ENV{MAYA_LOCATION}/include
|
||||
DOC "The directory where MTypes.h resides")
|
||||
|
||||
# TODO
|
||||
|
||||
ENDIF (WIN32)
|
||||
|
||||
|
||||
|
||||
IF (MAYA_INCLUDE_PATH)
|
||||
SET( MAYA_FOUND 1 CACHE STRING "Set to 1 if Maya is found, 0 otherwise")
|
||||
ELSE (MAYA_INCLUDE_PATH)
|
||||
SET( MAYA_FOUND 0 CACHE STRING "Set to 1 if Maya is found, 0 otherwise")
|
||||
ENDIF (MAYA_INCLUDE_PATH)
|
||||
|
||||
MARK_AS_ADVANCED( MAYA_FOUND )
|
@ -0,0 +1,55 @@
|
||||
#
|
||||
# Try to find OpenEXR's libraries, and include path.
|
||||
# Once done this will define:
|
||||
#
|
||||
# OPENEXR_FOUND = OpenEXR found.
|
||||
# OPENEXR_INCLUDE_PATH = OpenEXR include directory.
|
||||
# OPENEXR_LIBRARIES = libraries that are needed to use OpenEXR.
|
||||
#
|
||||
|
||||
|
||||
IF (WIN32)
|
||||
ELSE (WIN32)
|
||||
|
||||
FIND_PATH(OPENEXR_INCLUDE_PATH ImfRgbaFile.h
|
||||
/usr/include
|
||||
/usr/local/include)
|
||||
|
||||
FIND_LIBRARY(OPENEXR_HALF_LIBRARY
|
||||
NAMES Half
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib)
|
||||
|
||||
FIND_LIBRARY(OPENEXR_IEX_LIBRARY
|
||||
NAMES Iex
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib)
|
||||
|
||||
FIND_LIBRARY(OPENEXR_IMATH_LIBRARY
|
||||
NAMES Imath
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib)
|
||||
|
||||
FIND_LIBRARY(OPENEXR_ILMIMF_LIBRARY
|
||||
NAMES IlmImf
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib)
|
||||
|
||||
ENDIF (WIN32)
|
||||
|
||||
IF (OPENEXR_INCLUDE_DIR AND OPENEXR_IMATH_LIBRARY AND OPENEXR_ILMIMF_LIBRARY AND OPENEXR_IEX_LIBRARY AND OPENEXR_HALF_LIBRARY)
|
||||
SET(OPENEXR_FOUND TRUE)
|
||||
SET(OPENEXR_LIBRARIES ${OPENEXR_IMATH_LIBRARY} ${OPENEXR_ILMIMF_LIBRARY} ${OPENEXR_IEX_LIBRARY} ${OPENEXR_HALF_LIBRARY} CACHE STRING "The libraries needed to use OpenEXR")
|
||||
ENDIF (OPENEXR_INCLUDE_DIR AND OPENEXR_IMATH_LIBRARY AND OPENEXR_ILMIMF_LIBRARY AND OPENEXR_IEX_LIBRARY AND OPENEXR_HALF_LIBRARY)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
OPENEXR_INCLUDE_DIR
|
||||
OPENEXR_LIBRARIES
|
||||
OPENEXR_ILMIMF_LIBRARY
|
||||
OPENEXR_IMATH_LIBRARY
|
||||
OPENEXR_IEX_LIBRARY
|
||||
OPENEXR_HALF_LIBRARY)
|
@ -0,0 +1,128 @@
|
||||
// This code is in the public domain -- castanyo@yahoo.es
|
||||
|
||||
#ifndef NV_MATH_QUATERNION_H
|
||||
#define NV_MATH_QUATERNION_H
|
||||
|
||||
#include <nvmath/nvmath.h>
|
||||
#include <nvmath/Vector.h>
|
||||
|
||||
namespace nv
|
||||
{
|
||||
|
||||
class NVMATH_CLASS Quaternion
|
||||
{
|
||||
public:
|
||||
typedef Quaternion const & Arg;
|
||||
|
||||
Quaternion();
|
||||
explicit Quaternion(zero_t);
|
||||
Quaternion(float x, float y, float z, float w);
|
||||
Quaternion(Vector4::Arg v);
|
||||
|
||||
const Quaternion & operator=(Quaternion::Arg v);
|
||||
|
||||
scalar x() const;
|
||||
scalar y() const;
|
||||
scalar z() const;
|
||||
scalar w() const;
|
||||
|
||||
const Vector4 & asVector() const;
|
||||
Vector4 & asVector();
|
||||
|
||||
private:
|
||||
Vector4 q;
|
||||
};
|
||||
|
||||
inline Quaternion::Quaternion() {}
|
||||
inline Quaternion::Quaternion(zero_t) : q(zero) {}
|
||||
inline Quaternion::Quaternion(float x, float y, float z, float w) : q(x, y, z, w) {}
|
||||
inline Quaternion::Quaternion(Vector4::Arg v) : q(v) {}
|
||||
|
||||
inline const Quaternion & Quaternion::operator=(Quaternion::Arg v) { q = v.q; return *this; }
|
||||
|
||||
inline scalar Quaternion::x() const { return q.x(); }
|
||||
inline scalar Quaternion::y() const { return q.y(); }
|
||||
inline scalar Quaternion::z() const { return q.z(); }
|
||||
inline scalar Quaternion::w() const { return q.w(); }
|
||||
|
||||
inline const Vector4 & Quaternion::asVector() const { return q; }
|
||||
inline Vector4 & Quaternion::asVector() { return q; }
|
||||
|
||||
|
||||
inline Quaternion mul(Quaternion::Arg a, Quaternion::Arg b)
|
||||
{
|
||||
// @@ Efficient SIMD implementation?
|
||||
return Quaternion(
|
||||
+ a.x() * b.w() + a.y()*b.z() - a.z()*b.y() + a.w()*b.x(),
|
||||
- a.x() * b.z() + a.y()*b.w() + a.z()*b.x() + a.w()*b.y(),
|
||||
+ a.x() * b.y() - a.y()*b.x() + a.z()*b.w() + a.w()*b.z(),
|
||||
- a.x() * b.x() - a.y()*b.y() - a.z()*b.z() + a.w()*b.w());
|
||||
}
|
||||
|
||||
inline Quaternion scale(Quaternion::Arg q, float s)
|
||||
{
|
||||
return scale(q.asVector(), s);
|
||||
}
|
||||
inline Quaternion operator *(Quaternion::Arg q, float s)
|
||||
{
|
||||
return scale(q, s);
|
||||
}
|
||||
inline Quaternion operator *(float s, Quaternion::Arg q)
|
||||
{
|
||||
return scale(q, s);
|
||||
}
|
||||
|
||||
inline Quaternion scale(Quaternion::Arg q, Vector4::Arg s)
|
||||
{
|
||||
return scale(q.asVector(), s);
|
||||
}
|
||||
inline Quaternion operator *(Quaternion::Arg q, Vector4::Arg s)
|
||||
{
|
||||
return scale(q, s);
|
||||
}
|
||||
inline Quaternion operator *(Vector4::Arg s, Quaternion::Arg q)
|
||||
{
|
||||
return scale(q, s);
|
||||
}
|
||||
|
||||
inline Quaternion conjugate(Quaternion::Arg q)
|
||||
{
|
||||
return q * Vector4(-1, -1, -1, 1);
|
||||
}
|
||||
|
||||
inline float length(Quaternion::Arg q)
|
||||
{
|
||||
return length(q.asVector());
|
||||
}
|
||||
|
||||
inline bool isNormalized(Quaternion::Arg q, float epsilon = NV_NORMAL_EPSILON)
|
||||
{
|
||||
return equal(length(q), 1, epsilon);
|
||||
}
|
||||
|
||||
inline Quaternion normalize(Quaternion::Arg q, float epsilon = NV_EPSILON)
|
||||
{
|
||||
float l = length(q);
|
||||
nvDebugCheck(!isZero(l, epsilon));
|
||||
Quaternion n = scale(q, 1.0f / l);
|
||||
nvDebugCheck(isNormalized(n));
|
||||
return n;
|
||||
}
|
||||
|
||||
inline Quaternion inverse(Quaternion::Arg q)
|
||||
{
|
||||
return conjugate(normalize(q));
|
||||
}
|
||||
|
||||
/// Create a rotation quaternion for @a angle alpha around normal vector @a v.
|
||||
inline Quaternion axisAngle(Vector3::Arg v, float alpha)
|
||||
{
|
||||
float s = sinf(alpha * 0.5f);
|
||||
float c = cosf(alpha * 0.5f);
|
||||
return Quaternion(Vector4(v * s, c));
|
||||
}
|
||||
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_MATH_QUATERNION_H
|
@ -0,0 +1,226 @@
|
||||
/********************************************************/
|
||||
/* AABB-triangle overlap test code */
|
||||
/* by Tomas Akenine-Möller */
|
||||
/* Function: int triBoxOverlap(float boxcenter[3], */
|
||||
/* float boxhalfsize[3],float triverts[3][3]); */
|
||||
/* History: */
|
||||
/* 2001-03-05: released the code in its first version */
|
||||
/* 2001-06-18: changed the order of the tests, faster */
|
||||
/* */
|
||||
/* Acknowledgement: Many thanks to Pierre Terdiman for */
|
||||
/* suggestions and discussions on how to optimize code. */
|
||||
/* Thanks to David Hunt for finding a ">="-bug! */
|
||||
/********************************************************/
|
||||
|
||||
#include <nvmath/Vector.h>
|
||||
//#include <nvmath/Triangle.h>
|
||||
|
||||
using namespace nv;
|
||||
|
||||
#define X 0
|
||||
#define Y 1
|
||||
#define Z 2
|
||||
|
||||
#define FINDMINMAX(x0,x1,x2,min,max) \
|
||||
min = max = x0; \
|
||||
if(x1<min) min=x1;\
|
||||
if(x1>max) max=x1;\
|
||||
if(x2<min) min=x2;\
|
||||
if(x2>max) max=x2;
|
||||
|
||||
|
||||
static bool planeBoxOverlap(Vector3::Arg normal, Vector3::Arg vert, Vector3::Arg maxbox) // -NJMP-
|
||||
{
|
||||
Vector3 vmin, vmax;
|
||||
|
||||
float signs[3] = {1, 1, 1};
|
||||
if (normal.x() <= 0.0f) signs[0] = -1;
|
||||
if (normal.y() <= 0.0f) signs[1] = -1;
|
||||
if (normal.z() <= 0.0f) signs[2] = -1;
|
||||
|
||||
Vector3 sign(signs[0], signs[1], signs[2]);
|
||||
vmin = -scale(sign, maxbox) - vert;
|
||||
vmax = scale(sign, maxbox) - vert;
|
||||
|
||||
if (dot(normal, vmin) > 0.0f) return false;
|
||||
if (dot(normal, vmax) >= 0.0f) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*======================== X-tests ========================*/
|
||||
#define AXISTEST_X01(a, b, fa, fb) \
|
||||
p0 = a*v0.y() - b*v0.z(); \
|
||||
p2 = a*v2.y() - b*v2.z(); \
|
||||
if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \
|
||||
rad = fa * boxhalfsize.y() + fb * boxhalfsize.z(); \
|
||||
if(min>rad || max<-rad) return false;
|
||||
|
||||
#define AXISTEST_X2(a, b, fa, fb) \
|
||||
p0 = a*v0.y() - b*v0.z(); \
|
||||
p1 = a*v1.y() - b*v1.z(); \
|
||||
if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \
|
||||
rad = fa * boxhalfsize.y() + fb * boxhalfsize.z(); \
|
||||
if(min>rad || max<-rad) return false;
|
||||
|
||||
/*======================== Y-tests ========================*/
|
||||
#define AXISTEST_Y02(a, b, fa, fb) \
|
||||
p0 = -a*v0.x() + b*v0.z(); \
|
||||
p2 = -a*v2.x() + b*v2.z(); \
|
||||
if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \
|
||||
rad = fa * boxhalfsize.x() + fb * boxhalfsize.z(); \
|
||||
if(min>rad || max<-rad) return false;
|
||||
|
||||
#define AXISTEST_Y1(a, b, fa, fb) \
|
||||
p0 = -a*v0.x() + b*v0.z(); \
|
||||
p1 = -a*v1.x() + b*v1.z(); \
|
||||
if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \
|
||||
rad = fa * boxhalfsize.x() + fb * boxhalfsize.z(); \
|
||||
if(min>rad || max<-rad) return false;
|
||||
|
||||
/*======================== Z-tests ========================*/
|
||||
|
||||
#define AXISTEST_Z12(a, b, fa, fb) \
|
||||
p1 = a*v1.x() - b*v1.y(); \
|
||||
p2 = a*v2.x() - b*v2.y(); \
|
||||
if(p2<p1) {min=p2; max=p1;} else {min=p1; max=p2;} \
|
||||
rad = fa * boxhalfsize.x() + fb * boxhalfsize.y(); \
|
||||
if(min>rad || max<-rad) return false;
|
||||
|
||||
#define AXISTEST_Z0(a, b, fa, fb) \
|
||||
p0 = a*v0.x() - b*v0.y(); \
|
||||
p1 = a*v1.x() - b*v1.y(); \
|
||||
if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \
|
||||
rad = fa * boxhalfsize.x() + fb * boxhalfsize.y(); \
|
||||
if(min>rad || max<-rad) return false;
|
||||
|
||||
|
||||
bool triBoxOverlap(Vector3::Arg boxcenter, Vector3::Arg boxhalfsize, const Vector3 * triverts)
|
||||
{
|
||||
// use separating axis theorem to test overlap between triangle and box
|
||||
// need to test for overlap in these directions:
|
||||
// 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle
|
||||
// we do not even need to test these)
|
||||
// 2) normal of the triangle
|
||||
// 3) crossproduct(edge from tri, {x,y,z}-directin)
|
||||
// this gives 3x3=9 more tests
|
||||
Vector3 v0, v1, v2;
|
||||
float min, max, p0, p1, p2, rad, fex, fey, fez;
|
||||
Vector3 normal, e0, e1, e2;
|
||||
|
||||
// This is the fastest branch on Sun.
|
||||
// move everything so that the boxcenter is in (0,0,0)
|
||||
v0 = triverts[0] - boxcenter;
|
||||
v1 = triverts[1] - boxcenter;
|
||||
v2 = triverts[2] - boxcenter;
|
||||
|
||||
// Compute triangle edges.
|
||||
e0 = v1 - v0; // tri edge 0
|
||||
e1 = v2 - v1; // tri edge 1
|
||||
e2 = v0 - v2; // tri edge 2
|
||||
|
||||
// Bullet 3:
|
||||
// test the 9 tests first (this was faster)
|
||||
fex = fabsf(e0.x());
|
||||
fey = fabsf(e0.y());
|
||||
fez = fabsf(e0.z());
|
||||
AXISTEST_X01(e0.z(), e0.y(), fez, fey);
|
||||
AXISTEST_Y02(e0.z(), e0.x(), fez, fex);
|
||||
AXISTEST_Z12(e0.y(), e0.x(), fey, fex);
|
||||
|
||||
fex = fabsf(e1.x());
|
||||
fey = fabsf(e1.y());
|
||||
fez = fabsf(e1.z());
|
||||
AXISTEST_X01(e1.z(), e1.y(), fez, fey);
|
||||
AXISTEST_Y02(e1.z(), e1.x(), fez, fex);
|
||||
AXISTEST_Z0(e1.y(), e1.x(), fey, fex);
|
||||
|
||||
fex = fabsf(e2.x());
|
||||
fey = fabsf(e2.y());
|
||||
fez = fabsf(e2.z());
|
||||
AXISTEST_X2(e2.z(), e2.y(), fez, fey);
|
||||
AXISTEST_Y1(e2.z(), e2.x(), fez, fex);
|
||||
AXISTEST_Z12(e2.y(), e2.x(), fey, fex);
|
||||
|
||||
// Bullet 1:
|
||||
// first test overlap in the {x,y,z}-directions
|
||||
// find min, max of the triangle each direction, and test for overlap in
|
||||
// that direction -- this is equivalent to testing a minimal AABB around
|
||||
// the triangle against the AABB
|
||||
|
||||
// test in X-direction
|
||||
FINDMINMAX(v0.x(), v1.x(), v2.x(), min, max);
|
||||
if(min > boxhalfsize.x() || max < -boxhalfsize.x()) return false;
|
||||
|
||||
// test in Y-direction
|
||||
FINDMINMAX(v0.y(), v1.y(), v2.y(), min, max);
|
||||
if(min > boxhalfsize.y() || max < -boxhalfsize.y()) return false;
|
||||
|
||||
// test in Z-direction
|
||||
FINDMINMAX(v0.z(), v1.z(), v2.z(), min, max);
|
||||
if(min > boxhalfsize.z() || max < -boxhalfsize.z()) return false;
|
||||
|
||||
// Bullet 2:
|
||||
// test if the box intersects the plane of the triangle
|
||||
// compute plane equation of triangle: normal*x+d=0
|
||||
normal = cross(e0, e1);
|
||||
|
||||
return planeBoxOverlap(normal, v0, boxhalfsize);
|
||||
}
|
||||
|
||||
|
||||
bool triBoxOverlapNoBounds(Vector3::Arg boxcenter, Vector3::Arg boxhalfsize, const Vector3 * triverts)
|
||||
{
|
||||
// use separating axis theorem to test overlap between triangle and box
|
||||
// need to test for overlap in these directions:
|
||||
// 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle
|
||||
// we do not even need to test these)
|
||||
// 2) normal of the triangle
|
||||
// 3) crossproduct(edge from tri, {x,y,z}-directin)
|
||||
// this gives 3x3=9 more tests
|
||||
Vector3 v0, v1, v2;
|
||||
float min, max, p0, p1, p2, rad, fex, fey, fez;
|
||||
Vector3 normal, e0, e1, e2;
|
||||
|
||||
// This is the fastest branch on Sun.
|
||||
// move everything so that the boxcenter is in (0,0,0)
|
||||
v0 = triverts[0] - boxcenter;
|
||||
v1 = triverts[1] - boxcenter;
|
||||
v2 = triverts[2] - boxcenter;
|
||||
|
||||
// Compute triangle edges.
|
||||
e0 = v1 - v0; // tri edge 0
|
||||
e1 = v2 - v1; // tri edge 1
|
||||
e2 = v0 - v2; // tri edge 2
|
||||
|
||||
// Bullet 3:
|
||||
// test the 9 tests first (this was faster)
|
||||
fex = fabsf(e0.x());
|
||||
fey = fabsf(e0.y());
|
||||
fez = fabsf(e0.z());
|
||||
AXISTEST_X01(e0.z(), e0.y(), fez, fey);
|
||||
AXISTEST_Y02(e0.z(), e0.x(), fez, fex);
|
||||
AXISTEST_Z12(e0.y(), e0.x(), fey, fex);
|
||||
|
||||
fex = fabsf(e1.x());
|
||||
fey = fabsf(e1.y());
|
||||
fez = fabsf(e1.z());
|
||||
AXISTEST_X01(e1.z(), e1.y(), fez, fey);
|
||||
AXISTEST_Y02(e1.z(), e1.x(), fez, fex);
|
||||
AXISTEST_Z0(e1.y(), e1.x(), fey, fex);
|
||||
|
||||
fex = fabsf(e2.x());
|
||||
fey = fabsf(e2.y());
|
||||
fez = fabsf(e2.z());
|
||||
AXISTEST_X2(e2.z(), e2.y(), fez, fey);
|
||||
AXISTEST_Y1(e2.z(), e2.x(), fez, fex);
|
||||
AXISTEST_Z12(e2.y(), e2.x(), fey, fex);
|
||||
|
||||
// Bullet 2:
|
||||
// test if the box intersects the plane of the triangle
|
||||
// compute plane equation of triangle: normal*x+d=0
|
||||
normal = cross(e0, e1);
|
||||
|
||||
return planeBoxOverlap(normal, v0, boxhalfsize);
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
// This code is in the public domain -- Ignacio Castaño <castanyo@yahoo.es>
|
||||
|
||||
#include <nvmath/Triangle.h>
|
||||
|
||||
using namespace nv;
|
||||
|
||||
|
||||
/// Tomas Möller, barycentric ray-triangle test.
|
||||
bool Triangle::TestRay_Moller(Vector3::Arg orig, Vector3::Arg dir, float * out_t, float * out_u, float * out_v)
|
||||
{
|
||||
Vector3 e1, e2, tvec, pvec, qvec;
|
||||
float det, inv_det;
|
||||
|
||||
// find vectors for two edges sharing vert0
|
||||
e1 = v[1] - v[0];
|
||||
e2 = v[2] - v[0];
|
||||
|
||||
// begin calculating determinant - also used to calculate U parameter
|
||||
pvec = cross(dir, e2);
|
||||
|
||||
// if determinant is near zero, ray lies in plane of triangle
|
||||
det = dot(e1, pvec);
|
||||
if (det < -NV_EPSILON) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculate distance from vert0 to ray origin
|
||||
tvec = orig - v[0];
|
||||
|
||||
// calculate U parameter and test bounds
|
||||
float u = dot(tvec, pvec);
|
||||
if( u < 0.0f || u > det ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepare to test V parameter
|
||||
qvec = cross(tvec, e1);
|
||||
|
||||
// calculate V parameter and test bounds
|
||||
float v = dot(dir, qvec);
|
||||
if (v < 0.0f || u + v > det) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculate t, scale parameters, ray intersects triangle
|
||||
inv_det = 1.0f / det;
|
||||
*out_t = dot(e2, qvec) * inv_det;
|
||||
*out_u = u * inv_det; // v
|
||||
*out_v = v * inv_det; // 1-(u+v)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
// IC: This code is adapted from my Pi.MathLib code, based on Moller-Trumbore triangle test.
|
||||
FXVector3 edge1, edge2, pvec, tvec, qvec;
|
||||
|
||||
edge1 = tri.V1 - tri.V0;
|
||||
edge2 = tri.V2 - tri.V0;
|
||||
|
||||
pvec.Cross(ray.Direction, edge2);
|
||||
|
||||
float det = FXVector3.Dot(edge1, pvec);
|
||||
|
||||
// calculate distance from vert0 to ray origin.
|
||||
FXVector3 tvec = ray.Origin - vert0;
|
||||
|
||||
if( det < 0 )
|
||||
{
|
||||
// calculate U parameter and test bounds.
|
||||
float u = FXVector3.Dot(tvec, pvec);
|
||||
if (u > 0.0 || u < det)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepare to test V parameter.
|
||||
qvec.Cross(tvec, edge1);
|
||||
|
||||
// calculate V parameter and test bounds.
|
||||
float v = FXVector3.Dot(dir, qvec);
|
||||
|
||||
return v <= 0.0 && u + v >= det;
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate U parameter and test bounds.
|
||||
float u = FXVector3.Dot(tvec, pvec);
|
||||
if (u < 0.0 || u > det)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepare to test V parameter.
|
||||
qvec.Cross(tvec, edge1);
|
||||
|
||||
// calculate V parameter and test bounds.
|
||||
float v = FXVector3.Dot(dir, qvec);
|
||||
|
||||
return v >= 0.0 && u + v <= det;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Dan Sunday, parametric ray-triangle test.
|
||||
*/
|
||||
// Output: *I = intersection point (when it exists)
|
||||
// Return: -1 = triangle is degenerate (a segment or point)
|
||||
// 0 = disjoint (no intersect)
|
||||
// 1 = intersect in unique point I1
|
||||
// 2 = are in the same plane
|
||||
bool RayTriangleTest( const Vec3 &p0, const Vec3 &p1,
|
||||
const Vec3 &v0, const Vec3 &v1, const Vec3 &v2, const Vec3 &n,
|
||||
Vec3 &I ) {
|
||||
Vec3 u, v; // triangle vectors
|
||||
Vec3 dir, w0, w; // ray vectors
|
||||
float r, a, b; // params to calc ray-plane intersect
|
||||
|
||||
// get triangle edge vectors and plane normal
|
||||
u.Sub( v1, v0 );
|
||||
v.Sub( v2, v0 );
|
||||
|
||||
dir.Sub( p1, p0 ); // ray direction vector
|
||||
w0.Sub( p0, v0 );
|
||||
a = Vec3DotProduct( n, w0 );
|
||||
b = Vec3DotProduct( n, dir );
|
||||
|
||||
if( fabs(b) < TI_EPSILON ) // ray is parallel to triangle plane
|
||||
return false;
|
||||
|
||||
|
||||
// get intersect point of ray with triangle plane
|
||||
r = -a / b;
|
||||
if( r < 0.0f ) // ray goes away from triangle
|
||||
return false; // => no intersect
|
||||
|
||||
// for a segment, also test if (r > 1.0) => no intersect
|
||||
|
||||
I.Mad( p0, dir, r ); // intersect point of ray and plane
|
||||
|
||||
// is I inside T?
|
||||
float uu, uv, vv, wu, wv, D;
|
||||
uu = Vec3DotProduct( u, u );
|
||||
uv = Vec3DotProduct( u, v );
|
||||
vv = Vec3DotProduct( v, v );
|
||||
w = I - v0;
|
||||
wu = Vec3DotProduct( w, u );
|
||||
wv = Vec3DotProduct( w, v );
|
||||
D = uv * uv - uu * vv;
|
||||
|
||||
// get and test parametric coords
|
||||
float s, t;
|
||||
s = (uv * wv - vv * wu) / D;
|
||||
if( s<0.0 || s > 1.0) // I is outside T
|
||||
return false;
|
||||
t = (uv * wu - uu * wv) / D;
|
||||
if( t<0.0 || (s + t) > 1.0) // I is outside T
|
||||
return false;
|
||||
|
||||
return true; // I is in T
|
||||
}
|
||||
|
||||
|
||||
#endif // 0
|
@ -0,0 +1,149 @@
|
||||
// This code is in the public domain -- Ignacio Castaño <castanyo@yahoo.es>
|
||||
|
||||
#ifndef NV_MATH_TRIANGLE_H
|
||||
#define NV_MATH_TRIANGLE_H
|
||||
|
||||
|
||||
#include <nvmath/nvmath.h>
|
||||
#include <nvmath/Vector.h>
|
||||
#include <nvmath/Box.h>
|
||||
//#include <nvmath/Plane.h>
|
||||
|
||||
namespace nv
|
||||
{
|
||||
|
||||
// Tomas Akenine-Möller box-triangle test.
|
||||
NVMATH_API bool triBoxOverlap(Vector3::Arg boxcenter, Vector3::Arg boxhalfsize, const Vector3 * restrict triverts);
|
||||
NVMATH_API bool triBoxOverlapNoBounds(Vector3::Arg boxcenter, Vector3::Arg boxhalfsize, const Vector3 * restrict triverts);
|
||||
|
||||
|
||||
/// Triangle class with three vertices.
|
||||
class Triangle
|
||||
{
|
||||
public:
|
||||
Triangle() {};
|
||||
|
||||
Triangle(const Vector3 & v0, const Vector3 & v1, const Vector3 & v2)
|
||||
{
|
||||
v[0] = v0;
|
||||
v[1] = v1;
|
||||
v[2] = v2;
|
||||
}
|
||||
|
||||
/// Get the bounds of the triangle.
|
||||
Box bounds() const {
|
||||
Box bounds;
|
||||
bounds.clearBounds();
|
||||
bounds.addPointToBounds(v[0]);
|
||||
bounds.addPointToBounds(v[1]);
|
||||
bounds.addPointToBounds(v[2]);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
/*
|
||||
/// Get barycentric coordinates of the given point in this triangle.
|
||||
Vector3 barycentricCoordinates(Vector3::Arg p)
|
||||
{
|
||||
Vector3 bar;
|
||||
|
||||
// p must lie in the triangle plane.
|
||||
Plane plane;
|
||||
plane.set(v[0], v[1], v[2]);
|
||||
nvCheck( equalf(plane.Distance(p), 0.0f) );
|
||||
|
||||
Vector3 n;
|
||||
|
||||
// Compute signed area of triangle <v0, v1, p>
|
||||
n = cross(v[1] - v[0], p - v[0]);
|
||||
bar.x = length(n);
|
||||
if (dot(n, plane.vector) < 0) {
|
||||
bar->x = -bar->x;
|
||||
}
|
||||
|
||||
// Compute signed area of triangle <v1, v2, p>
|
||||
n = cross(v[2] - v[1], p - v[1]);
|
||||
bar->y = length(cross(e, d));
|
||||
if (dot(n, plane.vector) < 0) {
|
||||
bar->y = -bar->y;
|
||||
}
|
||||
|
||||
// Compute signed area of triangle <v2, v0, p>
|
||||
n = cross(v[0] - v[2], p - v[2]);
|
||||
bar->z = length(n);
|
||||
if (dot(n, plane.vector) < 0) {
|
||||
bar->z = -bar->z;
|
||||
}
|
||||
|
||||
// We cannot just do this because we need the signed areas.
|
||||
// bar->x = Vector3Area(e0, d0);
|
||||
// bar->y = Vector3Area(e1, d1);
|
||||
// bar->z = Vector3Area(e2, d2);
|
||||
|
||||
// bar->x = Vector3TripleProduct(v[1], v[2], p);
|
||||
// bar->y = Vector3TripleProduct(v[2], v[0], p);
|
||||
// bar->z = Vector3TripleProduct(v[0], v[1], p);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
// Moller ray triangle test.
|
||||
bool TestRay_Moller(const Vector3 & orig, const Vector3 & dir, float * out_t, float * out_u, float * out_v);
|
||||
|
||||
Vector3 v[3];
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/** A planar triangle. */
|
||||
class Triangle2 {
|
||||
public:
|
||||
|
||||
Triangle2() {};
|
||||
Triangle2(const Vec2 & v0, const Vec2 & v1, const Vec2 & v2) {
|
||||
v[0] = v0;
|
||||
v[1] = v1;
|
||||
v[2] = v2;
|
||||
}
|
||||
|
||||
/** Get the barycentric coordinates of the given point for this triangle.
|
||||
* http://stevehollasch.com/cgindex/math/barycentric.html
|
||||
*/
|
||||
void GetBarycentricCoordinates(const Vec2 & p, Vector3 * bar) const {
|
||||
float denom = 1.0f / (v[1].x - v[0].x) * (v[2].y - v[0].y) - (v[2].x - v[0].x) * (v[1].y - v[0].y);
|
||||
bar->x = ((v[1].x - p.x) * (v[2].y - p.y) - (v[2].x - p.x) * (v[1].y - p.y)) * denom;
|
||||
bar->y = ((v[2].x - p.x) * (v[0].y - p.y) - (v[0].x - p.x) * (v[2].y - p.y)) * denom;
|
||||
//bar->z = ((v[0].x - p.x) * (v[1].y - p.y) - (v[1].x - p.x) * (v[0].y - p.y)) * denom;
|
||||
bar->z = 1 - bar->x - bar->y;
|
||||
}
|
||||
|
||||
|
||||
Vec2 v[3];
|
||||
};
|
||||
|
||||
#endif // 0
|
||||
|
||||
|
||||
inline bool overlap(const Triangle & t, const Box & b)
|
||||
{
|
||||
Vector3 center = b.center();
|
||||
Vector3 extents = b.extents();
|
||||
return triBoxOverlap(center, extents, t.v);
|
||||
}
|
||||
|
||||
inline bool Overlap(const Box & b, const Triangle & t)
|
||||
{
|
||||
return overlap(t, b);
|
||||
}
|
||||
|
||||
|
||||
inline bool overlapNoBounds(const Triangle & t, const Box & b)
|
||||
{
|
||||
Vector3 center = b.center();
|
||||
Vector3 extents = b.extents();
|
||||
return triBoxOverlapNoBounds(center, extents, t.v);
|
||||
}
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_MATH_TRIANGLE_H
|
Loading…
Reference in New Issue