diff --git a/Extras/PhysicsEffects/CMakeLists.txt b/Extras/PhysicsEffects/CMakeLists.txt new file mode 100644 index 000000000..23cbe9701 --- /dev/null +++ b/Extras/PhysicsEffects/CMakeLists.txt @@ -0,0 +1,344 @@ +cmake_minimum_required(VERSION 2.4.3) +set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) + +#this line has to appear before 'PROJECT' in order to be able to disable incremental linking +SET(MSVC_INCREMENTAL_DEFAULT ON) + +PROJECT(PHYSICS_EFFECTS) +SET(PHYSICS_EFFECTS_VERSION 2.0) + +SET(BULLET_VERSION 2.80) + +SET(BULLET_PHYSICS_SOURCE_DIR "../..") + +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + +INCLUDE_DIRECTORIES( ${PHYSICS_EFFECTS_SOURCE_DIR}/include ) + +IF (NOT CMAKE_BUILD_TYPE) +# SET(CMAKE_BUILD_TYPE "Debug") + SET(CMAKE_BUILD_TYPE "Release") +ENDIF (NOT CMAKE_BUILD_TYPE) + +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG") +#MESSAGE("CMAKE_CXX_FLAGS_DEBUG="+${CMAKE_CXX_FLAGS_DEBUG}) + +OPTION(USE_DOUBLE_PRECISION "Use double precision" OFF) +OPTION(USE_GRAPHICAL_BENCHMARK "Use Graphical Benchmark" ON) +OPTION(USE_MULTITHREADED_BENCHMARK "Use Multithreaded Benchmark" OFF) + +ADD_DEFINITIONS(-DPFX_USE_FREE_VECTORMATH) + +IF (USE_MULTITHREADED_BENCHMARK) + ADD_DEFINITIONS(-DUSE_PARALLEL_SOLVER_BENCHMARK -DUSE_PARALLEL_DISPATCHER_BENCHMARK) +ENDIF() + +OPTION(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC Runtime Library DLL (/MD or /MDd)" ON) +OPTION(USE_MSVC_INCREMENTAL_LINKING "Use MSVC Incremental Linking" OFF) + +OPTION(USE_CUSTOM_VECTOR_MATH "Use custom vectormath library" OFF) + +IF (USE_CUSTOM_VECTOR_MATH) + ADD_DEFINITIONS(-DUSE_SYSTEM_VECTORMATH) + IF(WIN32) + SET (VECTOR_MATH_INCLUDE ${BULLET_PHYSICS_SOURCE_DIR}/src/vectormath/sse CACHE PATH "Vector Math library include path.") + ELSE(WIN32) + SET (VECTOR_MATH_INCLUDE ${BULLET_PHYSICS_SOURCE_DIR}/src/vectormath/scalar CACHE PATH "Vector Math library include path.") + ENDIF(WIN32) +ENDIF(USE_CUSTOM_VECTOR_MATH) + +IF (MSVC) + FIND_PATH(DIRECTX_SDK_BASE_DIR Include/D3D11.h PATH $ENV{DXSDK_DIR} ) + IF(DIRECTX_SDK_BASE_DIR) + OPTION(USE_DX11 "Use DirectX 11" ON) + ELSE() + OPTION(USE_DX11 "Use DirectX 11" OFF) + ENDIF() +ENDIF(MSVC) + + +#SET(CMAKE_EXE_LINKER_FLAGS_INIT "/STACK:10000000 /INCREMENTAL:NO") +#SET(CMAKE_EXE_LINKER_FLAGS "/STACK:10000000 /INCREMENTAL:NO") + +#MESSAGE("MSVC_INCREMENTAL_YES_FLAG"+${MSVC_INCREMENTAL_YES_FLAG}) + + +IF(MSVC) + IF (NOT USE_MSVC_INCREMENTAL_LINKING) + #MESSAGE("MSVC_INCREMENTAL_DEFAULT"+${MSVC_INCREMENTAL_DEFAULT}) + SET( MSVC_INCREMENTAL_YES_FLAG "/INCREMENTAL:NO") + + STRING(REPLACE "INCREMENTAL:YES" "INCREMENTAL:NO" replacementFlags ${CMAKE_EXE_LINKER_FLAGS_DEBUG}) + SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "/INCREMENTAL:NO ${replacementFlags}" ) + MESSAGE("CMAKE_EXE_LINKER_FLAGS_DEBUG=${CMAKE_EXE_LINKER_FLAGS_DEBUG}") + +# STRING(REPLACE "INCREMENTAL:YES" "INCREMENTAL:NO" replacementFlags2 ${CMAKE_EXE_LINKER_FLAGS}) +# SET(CMAKE_EXE_LINKER_FLAGS ${replacementFlag2}) +# STRING(REPLACE "INCREMENTAL:YES" "" replacementFlags3 ${CMAKE_EXTRA_LINK_FLAGS}) +# SET(CMAKE_EXTRA_LINK_FLAGS ${replacementFlag3}) + + + STRING(REPLACE "INCREMENTAL:YES" "INCREMENTAL:NO" replacementFlags3 ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}) + SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO ${replacementFlags3}) + SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/INCREMENTAL:NO ${replacementFlags3}" ) + + ENDIF (NOT USE_MSVC_INCREMENTAL_LINKING) + + IF (NOT USE_MSVC_RUNTIME_LIBRARY_DLL) + #We statically link to reduce dependancies + FOREACH(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + IF(${flag_var} MATCHES "/MD") + STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + ENDIF(${flag_var} MATCHES "/MD") + IF(${flag_var} MATCHES "/MDd") + STRING(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}") + ENDIF(${flag_var} MATCHES "/MDd") + ENDFOREACH(flag_var) + ENDIF (NOT USE_MSVC_RUNTIME_LIBRARY_DLL) + + OPTION(USE_MSVC_SSE "Use MSVC /arch:sse option" ON) + IF (USE_MSVC_SSE) + ADD_DEFINITIONS(/arch:SSE) + ENDIF() + OPTION(USE_MSVC_FAST_FLOATINGPOINT "Use MSVC /fp:fast option" ON) + IF (USE_MSVC_FAST_FLOATINGPOINT) + ADD_DEFINITIONS(/fp:fast) + ENDIF() +ENDIF(MSVC) + + + +IF (WIN32) +OPTION(INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES "Create MSVC projectfiles that can be distributed" OFF) + +IF (INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + SET (LIBRARY_OUTPUT_PATH ${BULLET_PHYSICS_SOURCE_DIR}/lib CACHE PATH "Single output directory for building all libraries.") + SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BULLET_PHYSICS_SOURCE_DIR}) + SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${BULLET_PHYSICS_SOURCE_DIR}) + SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${BULLET_PHYSICS_SOURCE_DIR}) + SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${BULLET_PHYSICS_SOURCE_DIR}) + SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${BULLET_PHYSICS_SOURCE_DIR}) +ELSE() + SET (LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib CACHE PATH "Single output directory for building all libraries.") +ENDIF() + +OPTION(INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES "Create MSVC projectfiles with relative paths" OFF) +OPTION(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES "Add MSVC postfix for executable names (_Debug)" OFF) + +IF(MSVC) + FIND_PATH(AMD_OPENCL_BASE_DIR include/CL/cl.h PATH $ENV{ATISTREAMSDKROOT} ) + IF(AMD_OPENCL_BASE_DIR) + #AMD adds an extras slash at the end of the ATISTREAMSDKROOT variable + SET(AMD_OPENCL_INCLUDES ${AMD_OPENCL_BASE_DIR}/include ) + MESSAGE(${AMD_OPENCL_INCLUDES}) + IF (CMAKE_CL_64) + SET(CMAKE_ATISTREAMSDK_LIBPATH ${AMD_OPENCL_BASE_DIR}/lib/x86_64 ) + ELSE(CMAKE_CL_64) + SET(CMAKE_ATISTREAMSDK_LIBPATH ${AMD_OPENCL_BASE_DIR}/lib/x86 ) + ENDIF(CMAKE_CL_64) + OPTION(BUILD_AMD_OPENCL_DEMOS "Build OpenCL demos for AMD (GPU or CPU)" ON) + ELSE() + OPTION(BUILD_AMD_OPENCL_DEMOS "Build OpenCL demos for AMD (GPU or CPU)" OFF) + ENDIF() + + FIND_PATH(NVIDIA_OPENCL_BASE_DIR OpenCL/common/inc/CL/cl.h PATH $ENV{NVSDKCOMPUTE_ROOT} ) + IF(NVIDIA_OPENCL_BASE_DIR) + SET(NVIDIA_OPENCL_INCLUDES ${NVIDIA_OPENCL_BASE_DIR}/OpenCL/common/inc ) + MESSAGE(${NVIDIA_OPENCL_INCLUDES}) + IF (CMAKE_CL_64) + SET(CMAKE_NVSDKCOMPUTE_LIBPATH ${NVIDIA_OPENCL_BASE_DIR}/OpenCL/common/lib/x64 ) + ELSE(CMAKE_CL_64) + SET(CMAKE_NVSDKCOMPUTE_LIBPATH ${NVIDIA_OPENCL_BASE_DIR}/OpenCL/common/lib/Win32 ) + ENDIF(CMAKE_CL_64) + SET(NVIDIA_OPENCL_LIBRARIES ${CMAKE_NVSDKCOMPUTE_LIBPATH}/OpenCL.lib) + + OPTION(BUILD_NVIDIA_OPENCL_DEMOS "Build OpenCL demos for NVidia (GPU)" ON) + ELSE() + OPTION(BUILD_NVIDIA_OPENCL_DEMOS "Build OpenCL demos for NVidia (GPU)" OFF) + ENDIF() +ENDIF() + + + +IF (INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES) +SET(CMAKE_SUPPRESS_REGENERATION 1) +SET(CMAKE_USE_RELATIVE_PATHS 1) +ENDIF(INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES) + +ENDIF (WIN32) + +IF (MSVC OR APPLE) + OPTION(BUILD_MINICL_OPENCL_DEMOS "Build OpenCL demos for MiniCL (Generic CPU)" ON) +ELSE() + OPTION(BUILD_MINICL_OPENCL_DEMOS "Build OpenCL demos for MiniCL (Generic CPU)" OFF) + + FIND_PATH(NVIDIA_OPENCL_INCLUDES CL/cl.h) + FIND_LIBRARY(NVIDIA_OPENCL_LIBRARIES OpenCL PATH /usr/lib /usr/local/lib) + IF (NVIDIA_OPENCL_INCLUDES AND NVIDIA_OPENCL_LIBRARIES) + MESSAGE("OPENCL FOUND") + MESSAGE(${NVIDIA_OPENCL_LIBRARIES}) + OPTION(BUILD_NVIDIA_OPENCL_DEMOS "Build OpenCL demos for NVidia (GPU)" ON) + ELSE () + MESSAGE("OPENCL NOT FOUND") + OPTION(BUILD_NVIDIA_OPENCL_DEMOS "Build OpenCL demos for NVidia (GPU)" OFF) + ENDIF () +ENDIF() + +OPTION(BUILD_CPU_DEMOS "Build original Bullet CPU demos" ON) + + + +OPTION(INTERNAL_UPDATE_SERIALIZATION_STRUCTURES "Internal update serialization structures" OFF) +IF (INTERNAL_UPDATE_SERIALIZATION_STRUCTURES) +ADD_DEFINITIONS( -DBT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES) +ENDIF (INTERNAL_UPDATE_SERIALIZATION_STRUCTURES) + +IF (USE_DOUBLE_PRECISION) +ADD_DEFINITIONS( -DBT_USE_DOUBLE_PRECISION) +ENDIF (USE_DOUBLE_PRECISION) + +IF(USE_GRAPHICAL_BENCHMARK) +ADD_DEFINITIONS( -DUSE_GRAPHICAL_BENCHMARK) +ENDIF (USE_GRAPHICAL_BENCHMARK) + +IF (WIN32) +OPTION(USE_GLUT "Use Glut" ON) +ADD_DEFINITIONS( -D_IRR_STATIC_LIB_ ) +ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS ) +ADD_DEFINITIONS( -D_CRT_SECURE_NO_DEPRECATE ) +ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS ) + +IF (USE_GLUT AND MSVC) + string (REPLACE "/D_WINDOWS" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + remove_definitions(-D_WINDOWS ) +ENDIF() + + + +ELSE(WIN32) +OPTION(USE_GLUT "Use Glut" ON) +ENDIF(WIN32) + + +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + + +# This is the shortcut to finding GLU, GLUT and OpenGL if they are properly installed on your system +# This should be the case. + +FIND_PACKAGE(OpenGL) +IF (OPENGL_FOUND) + MESSAGE("OPENGL FOUND") + MESSAGE(${OPENGL_LIBRARIES}) +ELSE (OPENGL_FOUND) + MESSAGE("OPENGL NOT FOUND") + SET(OPENGL_gl_LIBRARY opengl32) + SET(OPENGL_glu_LIBRARY glu32) +ENDIF (OPENGL_FOUND) + +# ADD_DEFINITIONS(-DBT_USE_FREEGLUT) + +FIND_PACKAGE(GLU) + +IF (USE_GLUT) + FIND_PACKAGE(GLUT) + IF (GLUT_FOUND) + MESSAGE("GLUT FOUND") + MESSAGE(${GLUT_glut_LIBRARY}) + ELSE (GLUT_FOUND) + IF (MINGW) + MESSAGE ("GLUT NOT FOUND not found, trying to use MINGW glut32") + SET(GLUT_glut_LIBRARY glut32) + #TODO add better GLUT detection for MinGW + SET(GLUT_FOUND TRUE) + ENDIF (MINGW) + IF (MSVC) + SET(GLUT_FOUND TRUE) + IF (CMAKE_CL_64) + message("Win64 using Glut/glut64.lib") + SET(GLUT_glut_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glut64.lib) + ELSE(CMAKE_CL_64) + message("Win32 using Glut/glut32.lib") + SET(GLUT_glut_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glut32.lib) + ENDIF (CMAKE_CL_64) + INCLUDE_DIRECTORIES(${BULLET_PHYSICS_SOURCE_DIR}/Glut) + ELSE() + MESSAGE("GLUT NOT FOUND") + ENDIF (MSVC) + ENDIF (GLUT_FOUND) + + IF(NOT WIN32) + # This is added for linux. This should always work if everything is installed and working fine. + INCLUDE_DIRECTORIES(/usr/include /usr/local/include) + ENDIF() +ENDIF(USE_GLUT) + + +OPTION(BUILD_DEMOS "Set when you want to build the demos" ON) +IF(BUILD_DEMOS) + IF(EXISTS ${PHYSICS_EFFECTS_SOURCE_DIR}/sample AND IS_DIRECTORY ${PHYSICS_EFFECTS_SOURCE_DIR}/sample) + SUBDIRS(sample) + ENDIF() +ENDIF(BUILD_DEMOS) + +# "Demos_ps3") +IF (MSVC) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF(EXISTS ${PHYSICS_EFFECTS_SOURCE_DIR}/Demos_ps3 AND IS_DIRECTORY ${PHYSICS_EFFECTS_SOURCE_DIR}/Demos_ps3) + MESSAGE("Demos_ps3 found") + SUBDIRS(Demos_ps3) + ENDIF() + ENDIF() +ENDIF(MSVC) + + +#OPTION(BUILD_EXTRAS "Set when you want to build the extras" OFF) +#IF(BUILD_EXTRAS) +# SUBDIRS(Extras) +#ENDIF(BUILD_EXTRAS) + +#Maya Dynamica plugin is moved to http://dynamica.googlecode.com + +SUBDIRS(src) + +IF("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles") + OPTION(INSTALL_LIBS "Set when you want to install libraries" OFF) +ELSE() + IF(APPLE AND FRAMEWORK) + OPTION(INSTALL_LIBS "Set when you want to install libraries" ON) + ELSE() +#by default, don't enable the 'INSTALL' option for Xcode and MSVC projectfiles + OPTION(INSTALL_LIBS "Set when you want to install libraries" OFF) + ENDIF() +ENDIF() + +IF(INSTALL_LIBS) + SET (LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" ) + SET (LIB_DESTINATION "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE STRING "Library directory name") + ## the following are directories where stuff will be installed to + SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include/bullet/" CACHE PATH "The subdirectory to the header prefix") + SET(PKGCONFIG_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/pkgconfig/" CACHE STRING "Base directory for pkgconfig files") + IF(NOT WIN32) + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/bullet.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/bullet.pc @ONLY) + INSTALL( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/bullet.pc + DESTINATION + ${PKGCONFIG_INSTALL_PREFIX}) + ENDIF(NOT WIN32) +ENDIF(INSTALL_LIBS) + +#INSTALL of other files requires CMake 2.6 +IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + OPTION(INSTALL_EXTRA_LIBS "Set when you want extra libraries installed" OFF) +ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + +OPTION(BUILD_UNIT_TESTS "Build Unit Tests" OFF) + +IF (BUILD_UNIT_TESTS) + SUBDIRS(UnitTests) +ENDIF() diff --git a/Extras/PhysicsEffects/README_Android.txt b/Extras/PhysicsEffects/README_Android.txt new file mode 100644 index 000000000..68a1136eb --- /dev/null +++ b/Extras/PhysicsEffects/README_Android.txt @@ -0,0 +1,42 @@ +This file set contains new files, and changes to existing files, that will enable PhysicsEffects +and several sample apps to be built and run on Android devices. The Android projects are +a mix of Java and C++ code. The code has been tested using Android NDK r5c. Build files +are provided for the NDK and ANT. Here are some instructions on how +to update the baseline PhysicsEffects branch of Bullet to support Android using the provided +files: + +1. For Windows platforms, download and install Cygwin (if it is not already installed) +2. Download and install the Android SDK. +3. Download and install the Android NDK. (The files provided have been tested with NDK r5c.) + +4. Set up these new environment variables: + + BULLET_PFX_ROOT_CYGWIN = path to your PhysicsEffects folder, for example: + BULLET_PFX_ROOT_CYGWIN=/cygdrive/d/tools/Bullet/branches/PhysicsEffects + + CYGWIN_ROOT = path to where Cygwin is installed (Windows-style path) + ANDROID_NDK_ROOT = path to where the Android NDK is installed + +5. Open a Cygwin console. Browse to the PhysicsEffects/project/Android + folder. Then, for each package, starting with PfxLibrary, go into the + package folder and run the ndk-build command. For example: + + /PhysicsEffects/project/Android/PfxLibrary> /cygwin/d/tools/android-ndk-r5c/ndk-build + + Build every package using ndk-build. + + (It is possible to configure Eclipse to use ndk-build, but that is somewhat + tedious to do.) + +6. For each application package (PfxApp*) after running ndk-build use + ant compile + ant debug + + If your Android device is connected and setup, you can also run the app using + ant install + +7. If you run the app, you can interact with the touch interface: + + - Tap the screen to change scenes + - Pinch the screen to zoom in/out + - Drag the screen to rotate the camera diff --git a/Extras/PhysicsEffects/build/premake4.lua b/Extras/PhysicsEffects/build/premake4.lua new file mode 100644 index 000000000..e12e9aa0b --- /dev/null +++ b/Extras/PhysicsEffects/build/premake4.lua @@ -0,0 +1,33 @@ +solution "MySolution" + + configurations {"Debug", "Release"} + configuration "Release" + flags { "Optimize", "StaticRuntime", "NoRTTI", "NoExceptions"} + configuration "Debug" + flags { "Symbols", "StaticRuntime" , "NoRTTI", "NoExceptions"} + platforms {"x32", "x64"} + configuration "x32" + libdirs {"$(ATISTREAMSDKROOT)/lib/x86"} + configuration "x64" + libdirs {"$(ATISTREAMSDKROOT)/lib/x86_64"} + targetsuffix "_64" + + configuration {"x64", "debug"} + targetsuffix "_x64_debug" + configuration {"x64", "release"} + targetsuffix "_x64" + configuration {"x32", "debug"} + targetsuffix "_debug" + + + language "C++" + location "build" + targetdir "bin" + + include "../src/base_level" + include "../src/low_level" + include "../src/util" + + include "../sample/api_physics_effects/0_console" + include "../sample/api_physics_effects/1_simple" + include "../sample/api_physics_effects/2_stable" \ No newline at end of file diff --git a/Extras/PhysicsEffects/build/vs2008.bat b/Extras/PhysicsEffects/build/vs2008.bat new file mode 100644 index 000000000..89a4b9d9e --- /dev/null +++ b/Extras/PhysicsEffects/build/vs2008.bat @@ -0,0 +1,2 @@ +..\..\..\msvc\premake4 clean +..\..\..\msvc\premake4 vs2008 diff --git a/Extras/PhysicsEffects/include/BulletPhysicsEffects/btBulletPhysicsEffectsWorld.cpp b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btBulletPhysicsEffectsWorld.cpp new file mode 100644 index 000000000..90752fc93 --- /dev/null +++ b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btBulletPhysicsEffectsWorld.cpp @@ -0,0 +1,479 @@ +/* +Physics Effects Copyright(C) 2011 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "btBulletPhysicsEffectsWorld.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +#include "BulletDynamics/ConstraintSolver/btContactConstraint.h" +#include "LinearMath/btAabbUtil2.h" +#include "BulletMultiThreaded/SequentialThreadSupport.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "LinearMath/btIDebugDraw.h" +#include "LinearMath/btQuickprof.h" + +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" + +#include "BulletDynamics/ConstraintSolver/btConstraintSolver.h" + + +#include "BulletPhysicsEffects/btLowLevelData.h" +#include +#include +#include "btLowLevelBroadphase.h" + + +#include "BulletCollision/CollisionShapes/btCompoundShape.h"//required for shape conversion +#include "BulletCollision/CollisionShapes/btConvexHullShape.h"//required for shape conversion +#include "BulletCollision/CollisionShapes/btCylinderShape.h"//required for shape conversion +#include "BulletCollision/CollisionShapes/btSphereShape.h"//required for shape conversion +#include "BulletCollision/CollisionShapes/btCapsuleShape.h"//required for shape conversion +#include "BulletCollision/CollisionShapes/btBoxShape.h"//required for shape conversion +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" +#include "BulletMultiThreaded/vectormath2bullet.h" + +#ifdef _WIN32 +#include "BulletMultiThreaded/Win32ThreadSupport.h" +#endif + + +#ifdef USE_PE_GATHER_SCATTER_SPURS_TASK +#include "SpuDispatch/BulletPEGatherScatterSpursSupport.h" +#include "SpuDispatch/SpuPEGatherScatterTaskProcess.h" +#endif + + +btBulletPhysicsEffectsWorld::btBulletPhysicsEffectsWorld(btLowLevelData* lowLevelData, btDispatcher* dispatcher,btLowLevelBroadphase* broadphase,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration, btThreadSupportInterface* threadSupport) +:btDiscreteDynamicsWorld(dispatcher,broadphase,constraintSolver,collisionConfiguration), +m_lowLevelData(lowLevelData) +{ + +#ifdef USE_PE_GATHER_SCATTER_SPURS_TASK + int numGatherScatterSpus = threadSupport->getNumTasks(); + m_PEGatherScatterProcess = new SpuPEGatherScatterTaskProcess(threadSupport,numGatherScatterSpus); +#endif //USE_PE_GATHER_SCATTER_SPURS_TASK + + m_lowLevelStates.resize(broadphase->m_maxHandles);//or use expandNonInitializing? + m_lowLevelBodies.resize(broadphase->m_maxHandles); + m_lowLevelSolverBodies.resize(broadphase->m_maxHandles); + m_lowLevelCollidables.resize(broadphase->m_maxHandles); + + m_lowLevelData->m_states = &m_lowLevelStates[0]; + m_lowLevelData->m_collidables = &m_lowLevelCollidables[0]; + m_lowLevelData->m_bodies = &m_lowLevelBodies[0]; + m_lowLevelData->m_solverBodies = &m_lowLevelSolverBodies[0]; + m_lowLevelData->m_numRigidBodies = broadphase->m_maxHandles; + +} + +btBulletPhysicsEffectsWorld::~btBulletPhysicsEffectsWorld() +{ +#ifdef USE_PE_GATHER_SCATTER_SPURS_TASK + delete m_PEGatherScatterProcess; +#endif + +} + + + +void btBulletPhysicsEffectsWorld::integrateTransforms(btScalar timeStep) +{ + ///integrate transforms +#ifdef USE_PE_GATHER_SCATTER_SPURS_TASK + if (getDispatchInfo().m_enableSPU) + { + BT_PROFILE("integrateTransformsSPU"); + int numRemainingObjects = m_nonStaticRigidBodies.size(); + + int batchSize = PARALLEL_BATCH_SIZE; + int startIndex = 0; + while (numRemainingObjects>0) + { + int currentBatchSize = numRemainingObjects > batchSize? batchSize : numRemainingObjects; + + //issue and flush is likely to be called every frame, move the construction and deletion out of the inner loop (at construction/init etc) + m_PEGatherScatterProcess->issueTask( + CMD_SAMPLE_INTEGRATE_BODIES, + &m_nonStaticRigidBodies[0], + 0, + 0, + startIndex, + currentBatchSize); + numRemainingObjects -= currentBatchSize; + startIndex += currentBatchSize; + } + + m_PEGatherScatterProcess->flush(); + } else +#endif //USE_PE_GATHER_SCATTER_SPURS_TASK + { +// BT_PROFILE("integrateTransforms"); + btDiscreteDynamicsWorld::integrateTransforms(timeStep); + } +} + + +void btBulletPhysicsEffectsWorld::predictUnconstraintMotion(btScalar timeStep) +{ +#ifdef USE_PE_GATHER_SCATTER_SPURS_TASK + if (getDispatchInfo().m_enableSPU) + { + BT_PROFILE("predictUnconstraintMotionSPU"); + int numRemainingObjects = m_nonStaticRigidBodies.size(); + + int batchSize = PARALLEL_BATCH_SIZE; + int startIndex=0; + while (numRemainingObjects>0) + { + int currentBatchSize = numRemainingObjects > batchSize? batchSize : numRemainingObjects; + + //issue and flush is likely to be called every frame, move the construction and deletion out of the inner loop (at construction/init etc) + m_PEGatherScatterProcess->issueTask( + CMD_SAMPLE_PREDICT_MOTION_BODIES, + &m_nonStaticRigidBodies[0], + 0, + 0, + startIndex, + currentBatchSize); + numRemainingObjects -= currentBatchSize; + startIndex += currentBatchSize; + } + + m_PEGatherScatterProcess->flush(); + } + else +#endif //USE_PE_GATHER_SCATTER_SPURS_TASK + { + btDiscreteDynamicsWorld::predictUnconstraintMotion( timeStep); + } + + for ( int i=0;isetHitFraction(1.f); + + if (body->isActive() && (!body->isStaticOrKinematicObject())) + { + syncRigidBodyState(body); + } + } +} + + + +void btBulletPhysicsEffectsWorld::solveConstraints(btContactSolverInfo& solverInfo) +{ + BT_PROFILE("solveConstraints"); + + btCollisionDispatcher* disp = (btCollisionDispatcher*) getDispatcher(); + int numBodies = getNumCollisionObjects(); + + btPersistentManifold** manifolds = disp->getInternalManifoldPointer(); + + int numManifolds = disp->getNumManifolds(); + + + if ((getNumCollisionObjects()>0) && (numManifolds + m_constraints.size()>0)) + { + + btCollisionObject** bodies = numBodies ? &getCollisionObjectArray()[0] : 0; + btTypedConstraint** constraints = m_constraints.size() ? &m_constraints[0] : 0; + + getConstraintSolver()->solveGroup( bodies,numBodies, disp->getInternalManifoldPointer(),numManifolds, constraints, m_constraints.size() ,m_solverInfo,m_debugDrawer,m_stackAlloc,disp); + } +} + + +void btBulletPhysicsEffectsWorld::calculateSimulationIslands() +{ + +} + +static void convertShape(btCollisionShape* bulletShape, btAlignedObjectArray& shapes) +{ + switch (bulletShape->getShapeType()) + { + case BOX_SHAPE_PROXYTYPE: + { + btBoxShape* boxshape = (btBoxShape*)bulletShape; + sce::PhysicsEffects::PfxBox box(boxshape->getHalfExtentsWithMargin().getX(),boxshape->getHalfExtentsWithMargin().getY(),boxshape->getHalfExtentsWithMargin().getZ()); + sce::PhysicsEffects::PfxShape& shape = shapes.expand(); + shape.reset(); + shape.setBox(box); + break; + } + + case TRIANGLE_MESH_SHAPE_PROXYTYPE: + { + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*) bulletShape; + + int numSubParts = trimesh->getMeshInterface()->getNumSubParts(); + btAssert(numSubParts>0); + + for (int i=0;igetMeshInterface()->getLockedVertexIndexBase(&vertexBase,numVerts,vertexType,vertexStride,&indexBase,indexStride,numFaces,indexType,i); + + sce::PhysicsEffects::PfxCreateLargeTriMeshParam param; + btAssert(param.flag&SCE_PFX_MESH_FLAG_16BIT_INDEX); + unsigned short int* copyIndices = new unsigned short int[numFaces*3]; + switch (indexType) + { + case PHY_UCHAR: + { + for (int p=0;pgetRadius()); + sce::PhysicsEffects::PfxShape& shape = shapes.expand(); + shape.reset(); + shape.setSphere(sphere); + break; + } + case CAPSULE_SHAPE_PROXYTYPE: + { + btCapsuleShape* capsuleshape= (btCapsuleShape*)bulletShape;//assume btCapsuleShapeX for now + sce::PhysicsEffects::PfxCapsule capsule(capsuleshape->getHalfHeight(),capsuleshape->getRadius()); + sce::PhysicsEffects::PfxShape& shape = shapes.expand(); + shape.reset(); + shape.setCapsule(capsule); + break; + } + case CYLINDER_SHAPE_PROXYTYPE: + { + btCylinderShape* cylindershape= (btCylinderShape*)bulletShape;//assume btCylinderShapeX for now + sce::PhysicsEffects::PfxCylinder cylinder(cylindershape->getHalfExtentsWithMargin()[0],cylindershape->getRadius()); + sce::PhysicsEffects::PfxShape& shape = shapes.expand(); + shape.reset(); + shape.setCylinder(cylinder); + break; + } + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btConvexHullShape* convexHullShape = (btConvexHullShape*)bulletShape; + + sce::PhysicsEffects::PfxConvexMesh* convex = new sce::PhysicsEffects::PfxConvexMesh(); + convex->m_numVerts = convexHullShape->getNumPoints(); + convex->m_numIndices = 0;//todo for ray intersection test support + + for (int i=0;im_numVerts;i++) + { + convex->m_verts[i].setX(convexHullShape->getPoints()[i].getX()); + convex->m_verts[i].setY(convexHullShape->getPoints()[i].getY()); + convex->m_verts[i].setZ(convexHullShape->getPoints()[i].getZ()); + } + + convex->updateAABB(); + sce::PhysicsEffects::PfxShape& shape = shapes.expand(); + shape.reset(); + shape.setConvexMesh(convex); + break; + } + case COMPOUND_SHAPE_PROXYTYPE: + { + btCompoundShape* compound = (btCompoundShape*) bulletShape; + + for (int s=0;sgetNumChildShapes();s++) + { + convertShape(compound->getChildShape(s),shapes); + + sce::PhysicsEffects::PfxMatrix3 rotMat = getVmMatrix3(compound->getChildTransform(s).getBasis()); + sce::PhysicsEffects::PfxVector3 translate = getVmVector3(compound->getChildTransform(s).getOrigin()); + sce::PhysicsEffects::PfxTransform3 childtransform(rotMat,translate); + shapes[shapes.size()-1].setOffsetTransform(childtransform); + } + + break; + } + + + default: + { + btAssert(0); + } + }; + +} + +void btBulletPhysicsEffectsWorld::createStateAndCollidable(btRigidBody* body) +{ + + int objectIndex = body->getBroadphaseProxy()->m_uniqueId; + btAssert(objectIndex>=0); + //btAssert(objectIndexreset(); + pfxbody->reset(); + pfxcollidable->reset(); + + + + pfxbody->setFriction(body->getFriction()); + pfxbody->setRestitution(body->getRestitution()); + + if (body->getInvMass()) + { + btScalar mass = 1.f/body->getInvMass(); + pfxbody->setMass(mass); + Vectormath::Aos::Matrix3 inertiaInv = inertiaInv.identity(); + inertiaInv.setElem(0,0,body->getInvInertiaDiagLocal().getX()); + inertiaInv.setElem(1,1,body->getInvInertiaDiagLocal().getY()); + inertiaInv.setElem(2,2,body->getInvInertiaDiagLocal().getZ()); + pfxbody->setInertiaInv(inertiaInv); + pfxstate->setMotionType(sce::PhysicsEffects::kPfxMotionTypeActive); + } else + { + pfxstate->setMotionType(sce::PhysicsEffects::kPfxMotionTypeFixed); + } + + btAlignedObjectArray shapes; + + convertShape(body->getCollisionShape(), shapes); + + btAssert(shapes.size()>0); + + if (shapes.size()==1) + { + pfxcollidable->addShape(shapes[0]); + pfxcollidable->finish(); + } else + { + if (shapes.size()>1) + { + sce::PhysicsEffects::PfxUInt16* ints=new sce::PhysicsEffects::PfxUInt16[shapes.size()]; + sce::PhysicsEffects::PfxShape* pfxshapes = new sce::PhysicsEffects::PfxShape[shapes.size()]; + int p; + for (p=0;preset(pfxshapes,ints,shapes.size()); + + for (p=0;paddShape(pfxshapes[p]); + } + + pfxcollidable->finish(); + } + } + pfxstate->setRigidBodyId(objectIndex); + + syncRigidBodyState(body); + + +} + + + +void btBulletPhysicsEffectsWorld::syncRigidBodyState(btRigidBody* body) +{ + int objectIndex = body->getBroadphaseProxy()->m_uniqueId; + sce::PhysicsEffects::PfxRigidState* pfxstate = &m_lowLevelStates[objectIndex]; + + pfxstate->setPosition(sce::PhysicsEffects::PfxVector3(body->getWorldTransform().getOrigin()[0],body->getWorldTransform().getOrigin()[1],body->getWorldTransform().getOrigin()[2])); + sce::PhysicsEffects::PfxQuat rot(body->getOrientation().getX(),body->getOrientation().getY(),body->getOrientation().getZ(),body->getOrientation().getW()); + pfxstate->setOrientation(rot); + +} + + + +void btBulletPhysicsEffectsWorld::addRigidBody(btRigidBody* body) +{ + + btDiscreteDynamicsWorld::addRigidBody(body); + + //create a state and collidable + + createStateAndCollidable(body); + + + + + +// m_lowLevelData->m_numRigidBodies++; +// btAssert(m_lowLevelData->m_numRigidBodiesm_maxNumRigidBodies); + +} + +void btBulletPhysicsEffectsWorld::addRigidBody(btRigidBody* body, short group, short mask) +{ + btDiscreteDynamicsWorld::addRigidBody(body,group,mask); + +} + +void btBulletPhysicsEffectsWorld::removeRigidBody(btRigidBody* body) +{ + btDiscreteDynamicsWorld::removeRigidBody(body); + +// m_lowLevelData->m_numRigidBodies--; +// btAssert(m_lowLevelData->m_numRigidBodies>=0); +} + diff --git a/Extras/PhysicsEffects/include/BulletPhysicsEffects/btBulletPhysicsEffectsWorld.h b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btBulletPhysicsEffectsWorld.h new file mode 100644 index 000000000..d6ffe349d --- /dev/null +++ b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btBulletPhysicsEffectsWorld.h @@ -0,0 +1,79 @@ +/* +Physics Effects Copyright(C) 2011 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + + #ifndef _BT_PARALLEL_DYNAMICS_WORLD_H +#define _BT_PARALLEL_DYNAMICS_WORLD_H + +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" +#include "physics_effects/base_level/rigidbody/pfx_rigid_body.h" +#include "physics_effects/base_level/rigidbody/pfx_rigid_state.h" +#include "physics_effects/base_level/collision/pfx_collidable.h" +#include "physics_effects/base_level/solver/pfx_solver_body.h" + +//#define USE_PE_GATHER_SCATTER_SPURS_TASK 1 + + +class btThreadSupportInterface; +class SpuPEGatherScatterTaskProcess; +struct CellSpurs; +class SpuBatchRaycaster; +struct btLowLevelBroadphase; + +#define PARALLEL_BATCH_SIZE 64 + + +///btBulletPhysicsEffectsWorld adds parallel processing for integration/motion prediction +class btBulletPhysicsEffectsWorld : public btDiscreteDynamicsWorld +{ + +protected: + btAlignedObjectArray m_lowLevelStates; + btAlignedObjectArray m_lowLevelBodies; + btAlignedObjectArray m_lowLevelSolverBodies; + btAlignedObjectArray m_lowLevelCollidables; + + //PfxSolverBody solverBodies[NUM_RIGIDBODIES]; + + class SpuPEGatherScatterTaskProcess* m_PEGatherScatterProcess; + + struct btLowLevelData* m_lowLevelData; + + void createStateAndCollidable(btRigidBody* body); + + void syncRigidBodyState(btRigidBody* body); +public: + + btBulletPhysicsEffectsWorld(struct btLowLevelData* lowLevelData, btDispatcher* dispatcher,btLowLevelBroadphase* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration, btThreadSupportInterface* threadSupport); + + virtual ~btBulletPhysicsEffectsWorld(); + + virtual void predictUnconstraintMotion(btScalar timeStep); + + virtual void integrateTransforms(btScalar timeStep); + + virtual void solveConstraints(btContactSolverInfo& solverInfo); + + virtual void calculateSimulationIslands(); + + virtual void addRigidBody(btRigidBody* body); + + virtual void addRigidBody(btRigidBody* body, short group, short mask); + + virtual void removeRigidBody(btRigidBody* body); + + +}; +#endif //_BT_PARALLEL_DYNAMICS_WORLD_H \ No newline at end of file diff --git a/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelBroadphase.cpp b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelBroadphase.cpp new file mode 100644 index 000000000..ff05ed698 --- /dev/null +++ b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelBroadphase.cpp @@ -0,0 +1,431 @@ +/* +Physics Effects Copyright(C) 2011 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "btLowLevelBroadphase.h" + + +#include "BulletMultiThreaded/PlatformDefinitions.h" +#include "BulletCollision/NarrowphaseCollision/btPersistentManifold.h" + +// Include base level headers +#include "physics_effects/base_level/pfx_base_level_include.h" + +// Include low level headers +#include "physics_effects/low_level/broadphase/pfx_broadphase.h" + +#include "physics_effects/low_level/sort/pfx_parallel_sort.h" + +#include "BulletMultiThreaded/vectormath2bullet.h" + +#include "physics_effects/base_level/base/pfx_vec_utils.h" +#include "physics_effects/base_level/collision/pfx_aabb.h" +#include "physics_effects/base_level/rigidbody/pfx_rigid_state.h" +#include "btLowLevelData.h" + +using namespace sce::PhysicsEffects; + +//E Temporary buffers +#define POOL_BYTES (5*1024*1024) +unsigned char SCE_PFX_ALIGNED(128) poolBuff[POOL_BYTES]; + +//E Stack allocator for temporary buffers +PfxHeapManager pool(poolBuff,POOL_BYTES); + + +/////////////////////////////////////////////////////////////////////////////// +// Broadphase + + + + + +// +btLowLevelBroadphase::btLowLevelBroadphase(btLowLevelData* lowLevelData, btOverlappingPairCache* paircache, int maxProxies) +:m_lowLevelData(lowLevelData) +{ + + m_guidGenerator = 1; + m_releasepaircache = (paircache!=0)?false:true; + m_paircache = paircache? paircache : new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache(); + m_clientData.m_bp = this; + m_clientData.m_dispatcher = 0; + + + m_broadphaseAabbMin.setValue(1e30,1e30,1e30); + m_broadphaseAabbMax.setValue(-1e30,-1e30,-1e30); + + // allocate handles buffer and put all handles on free list + m_pHandlesRawPtr = btAlignedAlloc(sizeof(btLowLevelBroadphaseProxy)*maxProxies,16); + m_pHandles = new(m_pHandlesRawPtr) btLowLevelBroadphaseProxy[maxProxies]; + m_maxHandles = maxProxies; + m_numHandles = 0; + m_firstFreeHandle = 0; + m_LastHandleIndex = -1; + + + { + for (int i = m_firstFreeHandle; i < maxProxies; i++) + { + m_pHandles[i].SetNextFree(i + 1); + m_pHandles[i].m_uniqueId = i;//start from zero, so we can re-use the uid for body ID + } + m_pHandles[maxProxies - 1].SetNextFree(0); + + } + +} + +// +btLowLevelBroadphase::~btLowLevelBroadphase() +{ + if(m_releasepaircache) + { + m_paircache->~btOverlappingPairCache(); + btAlignedFree(m_paircache); + } +} + + +btBroadphaseProxy* btLowLevelBroadphase::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* /*dispatcher*/,void* multiSapProxy) +{ + if (m_numHandles >= m_maxHandles) + { + btAssert(0); + return 0; //should never happen, but don't let the game crash ;-) + } + btAssert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]); + + int newHandleIndex = allocHandle(); + btLowLevelBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex])btLowLevelBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy); + m_uid2ptr.insert(proxy->m_uniqueId,proxy); + return proxy; +} + +void btLowLevelBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg,btDispatcher* dispatcher) +{ + m_uid2ptr.remove(proxyOrg->m_uniqueId); + + btLowLevelBroadphaseProxy* proxy0 = static_cast(proxyOrg); + freeHandle(proxy0); + + m_paircache->removeOverlappingPairsContainingProxy(proxyOrg,dispatcher); + + //validate(); + +} + +void btLowLevelBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const +{ + const btLowLevelBroadphaseProxy* sbp = getLowLevelProxyFromProxy(proxy); + aabbMin = sbp->m_aabbMin; + aabbMax = sbp->m_aabbMax; +} + +void btLowLevelBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/) +{ + btLowLevelBroadphaseProxy* sbp = getLowLevelProxyFromProxy(proxy); + sbp->m_aabbMin = aabbMin; + sbp->m_aabbMax = aabbMax; +} + + +bool btLowLevelBroadphase::aabbOverlap(btLowLevelBroadphaseProxy* proxy0,btLowLevelBroadphaseProxy* proxy1) +{ + return proxy0->m_aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] && + proxy0->m_aabbMin[1] <= proxy1->m_aabbMax[1] && proxy1->m_aabbMin[1] <= proxy0->m_aabbMax[1] && + proxy0->m_aabbMin[2] <= proxy1->m_aabbMax[2] && proxy1->m_aabbMin[2] <= proxy0->m_aabbMax[2]; + +} + + +PfxBroadphasePair* btLowLevelBroadphase::getCurrentPairs() +{ + return &m_lowLevelData->m_pairsBuff[m_lowLevelData->m_pairSwap][0]; +} + +const PfxBroadphasePair* btLowLevelBroadphase::getCurrentPairs() const +{ + return &m_lowLevelData->m_pairsBuff[m_lowLevelData->m_pairSwap][0]; +} + +int btLowLevelBroadphase::getNumCurrentPairs() const +{ + return m_lowLevelData->m_numPairs[m_lowLevelData->m_pairSwap]; +} + +void btLowLevelBroadphase::broadphase(PfxSortData32* proxies, int numRigidBodies, int axis, btDispatcher* dispatcher) +{ + m_lowLevelData->m_pairSwap = 1-m_lowLevelData->m_pairSwap; + + unsigned int &numPreviousPairs = m_lowLevelData->m_numPairs[1-m_lowLevelData->m_pairSwap]; + unsigned int &numCurrentPairs = m_lowLevelData->m_numPairs[m_lowLevelData->m_pairSwap]; + PfxBroadphasePair *previousPairs = &m_lowLevelData->m_pairsBuff[1-m_lowLevelData->m_pairSwap][0]; + PfxBroadphasePair *currentPairs = &m_lowLevelData->m_pairsBuff[m_lowLevelData->m_pairSwap][0]; + + + //E Create broadpahse proxies + { +// for(int i=0;im_maxPairs); + findPairsParam.pairBuff = pool.allocate(findPairsParam.pairBytes); + findPairsParam.workBytes = pfxGetWorkBytesOfFindPairs(m_lowLevelData->m_maxPairs); + findPairsParam.workBuff = pool.allocate(findPairsParam.workBytes); + findPairsParam.proxies = proxies; + findPairsParam.numProxies = numRigidBodies; + findPairsParam.maxPairs = m_lowLevelData->m_maxPairs; + findPairsParam.axis = axis; + + PfxFindPairsResult findPairsResult; + + + int ret = pfxFindPairs(findPairsParam,findPairsResult); + if(ret != SCE_PFX_OK) + SCE_PFX_PRINTF("pfxFindPairs failed %d\n",ret); + + pool.deallocate(findPairsParam.workBuff); + + //E Decompose overlapped pairs into 3 arrays + PfxDecomposePairsParam decomposePairsParam; + decomposePairsParam.pairBytes = pfxGetPairBytesOfDecomposePairs(numPreviousPairs,findPairsResult.numPairs); + decomposePairsParam.pairBuff = pool.allocate(decomposePairsParam.pairBytes); + decomposePairsParam.workBytes = pfxGetWorkBytesOfDecomposePairs(numPreviousPairs,findPairsResult.numPairs); + decomposePairsParam.workBuff = pool.allocate(decomposePairsParam.workBytes); + decomposePairsParam.previousPairs = previousPairs; + decomposePairsParam.numPreviousPairs = numPreviousPairs; + decomposePairsParam.currentPairs = findPairsResult.pairs; // Set pairs from pfxFindPairs() + decomposePairsParam.numCurrentPairs = findPairsResult.numPairs; // Set the number of pairs from pfxFindPairs() + + PfxDecomposePairsResult decomposePairsResult; + + ret = pfxDecomposePairs(decomposePairsParam,decomposePairsResult); + if(ret != SCE_PFX_OK) + SCE_PFX_PRINTF("pfxDecomposePairs failed %d\n",ret); + + pool.deallocate(decomposePairsParam.workBuff); + + PfxBroadphasePair *outNewPairs = decomposePairsResult.outNewPairs; + PfxBroadphasePair *outKeepPairs = decomposePairsResult.outKeepPairs; + PfxBroadphasePair *outRemovePairs = decomposePairsResult.outRemovePairs; + PfxUInt32 numOutNewPairs = decomposePairsResult.numOutNewPairs; + PfxUInt32 numOutKeepPairs = decomposePairsResult.numOutKeepPairs; + PfxUInt32 numOutRemovePairs = decomposePairsResult.numOutRemovePairs; + + for (int i=0;iremoveOverlappingPair(proxyA,proxyB,dispatcher); + + //free low level contacts + m_lowLevelData->m_contactIdPool[m_lowLevelData->m_numContactIdPool++] = pfxGetContactId(outRemovePairs[i]); + + } + + for (int i=0;iaddOverlappingPair(proxyA,proxyB); + + //initialize low level contacts + int cId = 0; + if(m_lowLevelData->m_numContactIdPool > 0) { + cId = m_lowLevelData->m_contactIdPool[--m_lowLevelData->m_numContactIdPool]; + } + else { + cId = m_lowLevelData->m_numContacts++; + } + if(cId >= m_lowLevelData->m_maxContacts) { + cId = 0; + } + SCE_PFX_ASSERT(cId < m_lowLevelData->m_maxContacts); + pfxSetContactId(outNewPairs[i],cId); + PfxContactManifold &contact = m_lowLevelData->m_contacts[cId]; + int sz = sizeof(PfxContactManifold); + int sz2 = sizeof(btPersistentManifold); + int sz3 = 4*3*sizeof(btConstraintRow); + contact.reset(pfxGetObjectIdA(outNewPairs[i]),pfxGetObjectIdB(outNewPairs[i])); + contact.setCompositeFriction(0.1f); + btpair->m_internalTmpValue = cId; + } + + + //E Merge 'new' and 'keep' pairs + numCurrentPairs = 0; + for(PfxUInt32 i=0;im_aabbMin); + PfxVector3 maxRig = getVmVector3(bulletProxy->m_aabbMax); + + PfxVecInt3 aabbMin,aabbMax; + pfxConvertCoordWorldToLocal(worldCenter,worldExtent,minRig,maxRig,aabbMin,aabbMax); + + pfxSetXMin(proxy,aabbMin.getX()); + pfxSetXMax(proxy,aabbMax.getX()); + pfxSetYMin(proxy,aabbMin.getY()); + pfxSetYMax(proxy,aabbMax.getY()); + pfxSetZMin(proxy,aabbMin.getZ()); + pfxSetZMax(proxy,aabbMax.getZ()); + pfxSetKey(proxy,aabbMin.get(axis)); + pfxSetObjectId(proxy,rigidbodyId); + pfxSetMotionMask(proxy, kPfxMotionTypeActive); + pfxSetSelf(proxy,bulletProxy->m_collisionFilterGroup); + pfxSetTarget(proxy,bulletProxy->m_collisionFilterMask); + + return ret; +} + +void btLowLevelBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) +{ + + //set the broadphase proxies + + btAlignedObjectArray proxies; + proxies.reserve(m_LastHandleIndex); + + //E Find the axis along which all rigid bodies are most widely positioned + int axis = 0; + int i; + PfxVector3 s(0.0f),s2(0.0f); + + PfxVector3 worldMin(-1000);//PFX_FLT_MAX); + PfxVector3 worldMax(1000);//-PFX_FLT_MAX); + + int numRigidBodies = 0; + for (i=0; i <= m_LastHandleIndex; i++) + { + btLowLevelBroadphaseProxy* proxy0 = &m_pHandles[i]; + if(!proxy0->m_clientObject) + { + continue; + } + + PfxVector3 pe_pos = getVmVector3(0.5f*(proxy0->m_aabbMax+proxy0->m_aabbMin)); + PfxVector3 pe_min = getVmVector3(proxy0->m_aabbMin); + PfxVector3 pe_max = getVmVector3(proxy0->m_aabbMax); + numRigidBodies++; + //worldMin = minPerElem(worldMin,pe_min); + //worldMax = maxPerElem(worldMax,pe_max); + + s += pe_pos; + s2 += mulPerElem(pe_pos,pe_pos); + } + + + if (numRigidBodies) + { + PfxVector3 v = s2 - mulPerElem(s,s) / (float)numRigidBodies; + if(v[1] > v[0]) + axis = 1; + if(v[2] > v[axis]) + axis = 2; + } + + PfxVector3 worldCenter = 0.5f*(worldMax+worldMin); + PfxVector3 worldExtent = 0.5f*(worldMax-worldMin); + + for (i=0; i <= m_LastHandleIndex; i++) + { + btLowLevelBroadphaseProxy* proxy0 = &m_pHandles[i]; + if(!proxy0->m_clientObject) + { + continue; + } + + PfxBroadphaseProxy& proxy = proxies.expandNonInitializing(); + MyUpdateBroadphaseProxy(proxy,proxy0->m_uniqueId,proxy0,worldCenter,worldExtent,axis); + + } + + //find pairs, and call 'addOverlappingPair' for new pairs and 'removeOverlappingPair' for removed pairs + broadphase(&proxies[0],proxies.size(),axis, dispatcher); +} + + +// +btOverlappingPairCache* btLowLevelBroadphase::getOverlappingPairCache() +{ + return(m_paircache); +} + +// +const btOverlappingPairCache* btLowLevelBroadphase::getOverlappingPairCache() const +{ + return(m_paircache); +} + + +void btLowLevelBroadphase::getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const +{ + aabbMin = m_broadphaseAabbMin; + aabbMax = m_broadphaseAabbMax; +} + +void btLowLevelBroadphase::printStats() +{ +} + +void btLowLevelBroadphase::setNumTasks(int numTasks) +{ +} diff --git a/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelBroadphase.h b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelBroadphase.h new file mode 100644 index 000000000..eb2dccfd0 --- /dev/null +++ b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelBroadphase.h @@ -0,0 +1,182 @@ +/* +Physics Effects Copyright(C) 2011 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +///btLowLevelBroadphase implementation +#ifndef BT_LOW_LEVEL_BROADPHASE_H +#define BT_LOW_LEVEL_BROADPHASE_H + +#include "BulletCollision/BroadphaseCollision/btDbvt.h" +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" + +#include "physics_effects/base_level/broadphase/pfx_broadphase_pair.h" +#include "LinearMath/btHashMap.h" + +struct btLowLevelBroadphase; +struct btLowLevelData; + +namespace sce +{ + namespace PhysicsEffects + { + struct PfxSortData32; + }; +}; + +struct btMyClientData +{ + btDispatcher* m_dispatcher; + btLowLevelBroadphase* m_bp; +}; + +struct btLowLevelBroadphaseProxy : public btBroadphaseProxy +{ + int m_nextFree; + +// int m_handleId; + + + btLowLevelBroadphaseProxy() {}; + + btLowLevelBroadphaseProxy(const btVector3& minpt,const btVector3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,void* multiSapProxy) + :btBroadphaseProxy(minpt,maxpt,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy) + { + (void)shapeType; + } + + + SIMD_FORCE_INLINE void SetNextFree(int next) {m_nextFree = next;} + SIMD_FORCE_INLINE int GetNextFree() const {return m_nextFree;} + + + + +}; + +///btLowLevelBroadphase is a binding between Open Physics low-level broadphase and Bullet, through the btBroadphaseInterface + +struct btLowLevelBroadphase : btBroadphaseInterface +{ + + int m_numHandles; // number of active handles + int m_maxHandles; // max number of handles + int m_LastHandleIndex; + + btLowLevelBroadphaseProxy* m_pHandles; // handles pool + + void* m_pHandlesRawPtr; + int m_firstFreeHandle; // free handles list + + btOverlappingPairCache* m_paircache; // Pair cache + bool m_releasepaircache; // Release pair cache on delete + int m_guidGenerator; + btVector3 m_broadphaseAabbMin; + btVector3 m_broadphaseAabbMax; + + btMyClientData m_clientData; + + btLowLevelData* m_lowLevelData; + btHashMap m_uid2ptr; + + + int allocHandle() + { + btAssert(m_numHandles < m_maxHandles); + int freeHandle = m_firstFreeHandle; + m_firstFreeHandle = m_pHandles[freeHandle].GetNextFree(); + m_numHandles++; + if(freeHandle > m_LastHandleIndex) + { + m_LastHandleIndex = freeHandle; + } + return freeHandle; + } + + void freeHandle(btLowLevelBroadphaseProxy* proxy) + { + int handle = int(proxy-m_pHandles); + btAssert(handle >= 0 && handle < m_maxHandles); + if(handle == m_LastHandleIndex) + { + m_LastHandleIndex--; + } + proxy->SetNextFree(m_firstFreeHandle); + m_firstFreeHandle = handle; + + proxy->m_clientObject = 0; + + m_numHandles--; + } + + inline btLowLevelBroadphaseProxy* getLowLevelProxyFromProxy(btBroadphaseProxy* proxy) + { + btLowLevelBroadphaseProxy* proxy0 = static_cast(proxy); + return proxy0; + } + + inline const btLowLevelBroadphaseProxy* getLowLevelProxyFromProxy(btBroadphaseProxy* proxy) const + { + const btLowLevelBroadphaseProxy* proxy0 = static_cast(proxy); + return proxy0; + } + + + + inline bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) + { + btLowLevelBroadphaseProxy* p0 = getLowLevelProxyFromProxy(proxy0); + btLowLevelBroadphaseProxy* p1 = getLowLevelProxyFromProxy(proxy1); + return aabbOverlap(p0,p1); + } + + static bool aabbOverlap(btLowLevelBroadphaseProxy* proxy0,btLowLevelBroadphaseProxy* proxy1); + + void broadphase(sce::PhysicsEffects::PfxSortData32* proxies, int numRigidBodies, int axis, btDispatcher* dispatcher); + + sce::PhysicsEffects::PfxBroadphasePair* getCurrentPairs(); + const sce::PhysicsEffects::PfxBroadphasePair* getCurrentPairs() const; + int getNumCurrentPairs() const; + + + + /* Methods */ + btLowLevelBroadphase(btLowLevelData* lowLevelData, btOverlappingPairCache* paircache, int maxProxies = 16384);//,class PfxAllocator* allocator,class PfxStackAllocator* stackPool,void* spursInstance); + virtual ~btLowLevelBroadphase(); + + /* btBroadphaseInterface Implementation */ + btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy); + void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); + virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) + { + } + + virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) + { + } + + + virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; + void calculateOverlappingPairs(btDispatcher* dispatcher); + btOverlappingPairCache* getOverlappingPairCache(); + const btOverlappingPairCache* getOverlappingPairCache() const; + void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const; + virtual void printStats(); + + virtual void setNumTasks(int numTasks); + +}; + +#endif diff --git a/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelCollisionDispatcher.cpp b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelCollisionDispatcher.cpp new file mode 100644 index 000000000..76fe85774 Binary files /dev/null and b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelCollisionDispatcher.cpp differ diff --git a/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelCollisionDispatcher.h b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelCollisionDispatcher.h new file mode 100644 index 000000000..98b12145b --- /dev/null +++ b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelCollisionDispatcher.h @@ -0,0 +1,127 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef BT_LOW_LEVEL_COLLISION__DISPATCHER_H +#define BT_LOW_LEVEL_COLLISION__DISPATCHER_H + +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +struct btLowLevelBroadphase;//struct instead of class? +struct btLowLevelData; +///Tuning value to optimized SPU utilization +///Too small value means Task overhead is large compared to computation (too fine granularity) +///Too big value might render some SPUs are idle, while a few other SPUs are doing all work. +//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 8 +//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 16 +//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 64 +#define SPU_BATCHSIZE_BROADPHASE_PAIRS 128 +//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 256 +//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 512 +//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 1024 +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" + +class btLowLevelCollisionAlgorithm : public btCollisionAlgorithm +{ + btPersistentManifold* m_manifold; + +public: + + btLowLevelCollisionAlgorithm() + :m_manifold(0) + { + } + + btLowLevelCollisionAlgorithm(btPersistentManifold* manifold, btCollisionDispatcher* dispatcher) + :m_manifold(manifold) + { + m_dispatcher = dispatcher; + } + virtual ~btLowLevelCollisionAlgorithm() + { + if (m_manifold) + m_dispatcher->releaseManifold(m_manifold); + } + virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) + { + btAssert(0); + } + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) + { + btAssert(0); + return 0.f; + } + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + manifoldArray.push_back(m_manifold); + } + +}; + + +///btLowLevelCollisionDispatcher can use SPU to gather and calculate collision detection +///Time of Impact, Closest Points and Penetration Depth. +class btLowLevelCollisionDispatcher : public btCollisionDispatcher +{ + + btLowLevelData* m_lowLevelData; + + btAlignedObjectArray m_manifoldArray; + btAlignedObjectArray m_algorithms; + +protected: + + void collision(); + +public: + + + btLowLevelCollisionDispatcher (btLowLevelData* lowLevelData, btCollisionConfiguration* collisionConfiguration, int maxNumManifolds); + + virtual ~btLowLevelCollisionDispatcher(); + + bool supportsDispatchPairOnSpu(int proxyType0,int proxyType1); + + virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) ; + + + + virtual btPersistentManifold* getNewManifold(void* b0,void* b1) + { + btAssert(0); + return 0; + } + virtual void releaseManifold(btPersistentManifold* manifold); + + + virtual void* allocateCollisionAlgorithm(int size) + { + btAssert(0); + return 0; + } + + virtual void freeCollisionAlgorithm(void* ptr) + { + + } + + + +}; + + + +#endif //BT_LOW_LEVEL_COLLISION__DISPATCHER_H + + diff --git a/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelConstraintSolver.cpp b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelConstraintSolver.cpp new file mode 100644 index 000000000..7770da119 --- /dev/null +++ b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelConstraintSolver.cpp @@ -0,0 +1,1410 @@ +/* + Copyright (C) 2010 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + + +#include "btLowLevelConstraintSolver.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" + +#include "LinearMath/btQuickprof.h" +#include "BulletMultiThreaded/btThreadSupportInterface.h" + +#include "vecmath/vmInclude.h" + +#include "BulletMultiThreaded/HeapManager.h" + +#include "BulletMultiThreaded/PlatformDefinitions.h" + +//#include "PfxSimdUtils.h" +#include "LinearMath/btScalar.h" + +#include "BulletMultiThreaded/TrbStateVec.h" + + + +///////////////// + + +#define TMP_BUFF_BYTES (15*1024*1024) +unsigned char ATTRIBUTE_ALIGNED128(tmp_buff[TMP_BUFF_BYTES]); + + +static SIMD_FORCE_INLINE vmVector3 btReadVector3(const double* p) +{ + float tmp[3] = {float(p[0]),float(p[1]),float(p[2])}; + vmVector3 v; + loadXYZ(v, tmp); + return v; +} + +static SIMD_FORCE_INLINE vmQuat btReadQuat(const double* p) +{ + float tmp[4] = {float(p[0]),float(p[1]),float(p[2]),float(p[4])}; + vmQuat vq; + loadXYZW(vq, tmp); + return vq; +} + +static SIMD_FORCE_INLINE void btStoreVector3(const vmVector3 &src, double* p) +{ + float tmp[3]; + vmVector3 v = src; + storeXYZ(v, tmp); + p[0] = tmp[0]; + p[1] = tmp[1]; + p[2] = tmp[2]; +} + + +static SIMD_FORCE_INLINE vmVector3 btReadVector3(const float* p) +{ + vmVector3 v; + loadXYZ(v, p); + return v; +} + +static SIMD_FORCE_INLINE vmQuat btReadQuat(const float* p) +{ + vmQuat vq; + loadXYZW(vq, p); + return vq; +} + +static SIMD_FORCE_INLINE void btStoreVector3(const vmVector3 &src, float* p) +{ + vmVector3 v = src; + storeXYZ(v, p); +} + + + + + +// Project Gauss Seidel or the equivalent Sequential Impulse + inline void resolveSingleConstraintRowGeneric(PfxSolverBody& body1,PfxSolverBody& body2,const btSolverConstraint& c) +{ + + btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm; + const btScalar deltaVel1Dotn = c.m_contactNormal.dot((btVector3&)body1.m_deltaLinearVelocity) + c.m_relpos1CrossNormal.dot((btVector3&)body1.m_deltaAngularVelocity); + const btScalar deltaVel2Dotn = -c.m_contactNormal.dot((btVector3&)body2.m_deltaLinearVelocity) + c.m_relpos2CrossNormal.dot((btVector3&)body2.m_deltaAngularVelocity); + +// const btScalar delta_rel_vel = deltaVel1Dotn-deltaVel2Dotn; + deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv; + deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv; + + const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse; + if (sum < c.m_lowerLimit) + { + deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse; + c.m_appliedImpulse = c.m_lowerLimit; + } + else if (sum > c.m_upperLimit) + { + deltaImpulse = c.m_upperLimit-c.m_appliedImpulse; + c.m_appliedImpulse = c.m_upperLimit; + } + else + { + c.m_appliedImpulse = sum; + } + + + if (body1.m_massInv) + { + btVector3 linearComponent = c.m_contactNormal*body1.m_massInv; + ((btVector3&)body1.m_deltaLinearVelocity) += linearComponent*deltaImpulse; + ((btVector3&)body1.m_deltaAngularVelocity) += c.m_angularComponentA*(btVector3(deltaImpulse,deltaImpulse,deltaImpulse));//*m_angularFactor); + } + + if (body2.m_massInv) + { + btVector3 linearComponent = -c.m_contactNormal*body2.m_massInv; + ((btVector3&)body2.m_deltaLinearVelocity) += linearComponent*deltaImpulse; + ((btVector3&)body2.m_deltaAngularVelocity) += c.m_angularComponentB*((btVector3(deltaImpulse,deltaImpulse,deltaImpulse)));//*m_angularFactor); + } + + //body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse); + //body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse); + +} + + +static SIMD_FORCE_INLINE +void pfxSolveLinearConstraintRow(btConstraintRow &constraint, + vmVector3 &deltaLinearVelocityA,vmVector3 &deltaAngularVelocityA, + float massInvA,const vmMatrix3 &inertiaInvA,const vmVector3 &rA, + vmVector3 &deltaLinearVelocityB,vmVector3 &deltaAngularVelocityB, + float massInvB,const vmMatrix3 &inertiaInvB,const vmVector3 &rB) +{ + const vmVector3 normal(btReadVector3(constraint.m_normal)); + btScalar deltaImpulse = constraint.m_rhs; + vmVector3 dVA = deltaLinearVelocityA + cross(deltaAngularVelocityA,rA); + vmVector3 dVB = deltaLinearVelocityB + cross(deltaAngularVelocityB,rB); + deltaImpulse -= constraint.m_jacDiagInv * dot(normal,dVA-dVB); + btScalar oldImpulse = constraint.m_accumImpulse; + constraint.m_accumImpulse = btClamped(oldImpulse + deltaImpulse,constraint.m_lowerLimit,constraint.m_upperLimit); + deltaImpulse = constraint.m_accumImpulse - oldImpulse; + deltaLinearVelocityA += deltaImpulse * massInvA * normal; + deltaAngularVelocityA += deltaImpulse * inertiaInvA * cross(rA,normal); + deltaLinearVelocityB -= deltaImpulse * massInvB * normal; + deltaAngularVelocityB -= deltaImpulse * inertiaInvB * cross(rB,normal); + +} + +void btSolveContactConstraint( + btConstraintRow &constraintResponse, + btConstraintRow &constraintFriction1, + btConstraintRow &constraintFriction2, + const vmVector3 &contactPointA, + const vmVector3 &contactPointB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + float friction + ) +{ + vmVector3 rA = rotate(solverBodyA.m_orientation,contactPointA); + vmVector3 rB = rotate(solverBodyB.m_orientation,contactPointB); + + pfxSolveLinearConstraintRow(constraintResponse, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); + + float mf = friction*fabsf(constraintResponse.m_accumImpulse); + constraintFriction1.m_lowerLimit = -mf; + constraintFriction1.m_upperLimit = mf; + constraintFriction2.m_lowerLimit = -mf; + constraintFriction2.m_upperLimit = mf; + + pfxSolveLinearConstraintRow(constraintFriction1, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); + + pfxSolveLinearConstraintRow(constraintFriction2, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); +} + + +void CustomSolveConstraintsTaskParallel( + const PfxParallelGroup *contactParallelGroup,const PfxParallelBatch *contactParallelBatches, + PfxConstraintPair *contactPairs,uint32_t numContactPairs, + btPersistentManifold* offsetContactManifolds__, + const PfxParallelGroup *jointParallelGroup,const PfxParallelBatch *jointParallelBatches, + PfxConstraintPair *jointPairs,uint32_t numJointPairs, + TrbState *offsetRigStates, + PfxSolverBody *offsetSolverBodies, + uint32_t numRigidBodies, + int iteration,unsigned int taskId,unsigned int numTasks,btBarrier *barrier) +{ + + PfxSolverBody staticBody; + staticBody.m_massInv = 0.f; + staticBody.m_deltaAngularVelocity=vmVector3(0,0,0); + staticBody.m_deltaLinearVelocity =vmVector3(0,0,0); + + + for(int k=0;knumPhases;phaseId++) { + for(uint32_t batchId=0;batchIdnumBatches[phaseId];batchId++) { + uint32_t numPairs = jointParallelGroup->numPairs[phaseId*SCE_PFX_MAX_SOLVER_BATCHES+batchId]; + if(batchId%numTasks == taskId && numPairs > 0) { + const PfxParallelBatch &batch = jointParallelBatches[phaseId*SCE_PFX_MAX_SOLVER_BATCHES+batchId]; + for(uint32_t i=0;isync(); + } + + // Contact + for(uint32_t phaseId=0;phaseIdnumPhases;phaseId++) { + for(uint32_t batchId=0;batchIdnumBatches[phaseId];batchId++) { + uint32_t numPairs = contactParallelGroup->numPairs[phaseId*SCE_PFX_MAX_SOLVER_BATCHES+batchId]; + if(batchId%numTasks == taskId && numPairs > 0) { + const PfxParallelBatch &batch = contactParallelBatches[phaseId*SCE_PFX_MAX_SOLVER_BATCHES+batchId]; + for(uint32_t i=0;isync(); + } + } +} + +void CustomPostSolverTask( + TrbState *states, + PfxSolverBody *solverBodies, + uint32_t numRigidBodies) +{ + for(uint32_t i=0;i 0.707f) { + // choose p in y-z plane + float a = n[1]*n[1] + n[2]*n[2]; + float k = 1.0f/sqrtf(a); + p[0] = 0; + p[1] = -n[2]*k; + p[2] = n[1]*k; + // set q = n x p + q[0] = a*k; + q[1] = -n[0]*p[2]; + q[2] = n[0]*p[1]; + } + else { + // choose p in x-y plane + float a = n[0]*n[0] + n[1]*n[1]; + float k = 1.0f/sqrtf(a); + p[0] = -n[1]*k; + p[1] = n[0]*k; + p[2] = 0; + // set q = n x p + q[0] = -n[2]*p[1]; + q[1] = n[2]*p[0]; + q[2] = a*k; + } +} + + + +#define PFX_CONTACT_SLOP 0.001f + +void btSetupContactConstraint( + btConstraintRow &constraintResponse, + btConstraintRow &constraintFriction1, + btConstraintRow &constraintFriction2, + float penetrationDepth, + float restitution, + float friction, + const vmVector3 &contactNormal, + const vmVector3 &contactPointA, + const vmVector3 &contactPointB, + const TrbState &stateA, + const TrbState &stateB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + float separateBias, + float timeStep + ) +{ + vmVector3 rA = rotate(solverBodyA.m_orientation,contactPointA); + vmVector3 rB = rotate(solverBodyB.m_orientation,contactPointB); + + vmMatrix3 K = vmMatrix3::scale(vmVector3(solverBodyA.m_massInv + solverBodyB.m_massInv)) - + crossMatrix(rA) * solverBodyA.m_inertiaInv * crossMatrix(rA) - + crossMatrix(rB) * solverBodyB.m_inertiaInv * crossMatrix(rB); + + vmVector3 vA = stateA.getLinearVelocity() + cross(stateA.getAngularVelocity(),rA); + vmVector3 vB = stateB.getLinearVelocity() + cross(stateB.getAngularVelocity(),rB); + vmVector3 vAB = vA-vB; + + vmVector3 tangent1,tangent2; + btPlaneSpace1(contactNormal,tangent1,tangent2); + +// constraintResponse.m_accumImpulse = 0.f; +// constraintFriction1.m_accumImpulse = 0.f; +// constraintFriction2.m_accumImpulse = 0.f; + + // Contact Constraint + { + vmVector3 normal = contactNormal; + + float denom = dot(K*normal,normal); + + constraintResponse.m_rhs = -(1.0f+restitution)*dot(vAB,normal); // velocity error + constraintResponse.m_rhs -= (separateBias * btMin(0.0f,penetrationDepth+PFX_CONTACT_SLOP)) / timeStep; // position error + constraintResponse.m_rhs /= denom; + constraintResponse.m_jacDiagInv = 1.0f/denom; + constraintResponse.m_lowerLimit = 0.0f; + constraintResponse.m_upperLimit = SIMD_INFINITY; + btStoreVector3(normal,constraintResponse.m_normal); + } + + // Friction Constraint 1 + { + vmVector3 normal = tangent1; + + float denom = dot(K*normal,normal); + + constraintFriction1.m_jacDiagInv = 1.0f/denom; + constraintFriction1.m_rhs = -dot(vAB,normal); + constraintFriction1.m_rhs *= constraintFriction1.m_jacDiagInv; + constraintFriction1.m_lowerLimit = 0.0f; + constraintFriction1.m_upperLimit = SIMD_INFINITY; + btStoreVector3(normal,constraintFriction1.m_normal); + } + + // Friction Constraint 2 + { + vmVector3 normal = tangent2; + + float denom = dot(K*normal,normal); + + constraintFriction2.m_jacDiagInv = 1.0f/denom; + constraintFriction2.m_rhs = -dot(vAB,normal); + constraintFriction2.m_rhs *= constraintFriction2.m_jacDiagInv; + constraintFriction2.m_lowerLimit = 0.0f; + constraintFriction2.m_upperLimit = SIMD_INFINITY; + btStoreVector3(normal,constraintFriction2.m_normal); + } +} + + +void CustomSetupContactConstraintsTask( + PfxConstraintPair *contactPairs,uint32_t numContactPairs, + TrbState *offsetRigStates, + PfxSolverBody *offsetSolverBodies, + uint32_t numRigidBodies, + float separateBias, + float timeStep) +{ + for(uint32_t i=0;iio); + btCriticalSection* criticalsection = io->setupContactConstraints.criticalSection; + + + //CustomCriticalSection *criticalsection = &io->m_cs; + switch(io->cmd) { + + case PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS: + CustomSolveConstraintsTaskParallel( + io->solveConstraints.contactParallelGroup, + io->solveConstraints.contactParallelBatches, + io->solveConstraints.contactPairs, + io->solveConstraints.numContactPairs, + io->solveConstraints.offsetContactManifolds, + + io->solveConstraints.jointParallelGroup, + io->solveConstraints.jointParallelBatches, + io->solveConstraints.jointPairs, + io->solveConstraints.numJointPairs, + + io->solveConstraints.offsetRigStates, + io->solveConstraints.offsetSolverBodies, + io->solveConstraints.numRigidBodies, + io->solveConstraints.iteration, + + io->solveConstraints.taskId, + io->maxTasks1, + io->solveConstraints.barrier + ); + break; + + case PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER: + CustomPostSolverTask( io->postSolver.states,io->postSolver.solverBodies, io->postSolver.numRigidBodies); + break; + + + case PFX_CONSTRAINT_SOLVER_CMD_SETUP_CONTACT_CONSTRAINTS: + { + bool empty = false; + while(!empty) { + int start,batch; + + criticalsection->lock(); + + start = (int)criticalsection->getSharedParam(0); + batch = (int)criticalsection->getSharedParam(1); + + //PFX_PRINTF("taskId %d start %d num %d\n",arg->taskId,start,batch); + + // ̃obt@Zbg + int nextStart = start + batch; + int rest = btMax((int)io->setupContactConstraints.numContactPairs1 - nextStart,0); + int nextBatch = (rest > batch)?batch:rest; + + criticalsection->setSharedParam(0,nextStart); + criticalsection->setSharedParam(1,nextBatch); + + criticalsection->unlock(); + + if(batch > 0) { + CustomSetupContactConstraintsTask( + io->setupContactConstraints.offsetContactPairs+start,batch, +// io->setupContactConstraints.offsetContactManifolds, + io->setupContactConstraints.offsetRigStates, +// io->setupContactConstraints.offsetRigBodies, + io->setupContactConstraints.offsetSolverBodies, + io->setupContactConstraints.numRigidBodies, + io->setupContactConstraints.separateBias, + io->setupContactConstraints.timeStep); + } + else { + empty = true; + } + } + } + break; + + default: + { + btAssert(0); + } + } + +} + + +void CustomSetupContactConstraintsNew( + PfxConstraintPair *contactPairs1,uint32_t numContactPairs, + btPersistentManifold *offsetContactManifolds, + TrbState *offsetRigStates, + PfxSolverBody *offsetSolverBodies, + uint32_t numRigidBodies, + float separationBias, + float timeStep, + class btThreadSupportInterface* threadSupport, + btCriticalSection* criticalSection, + btConstraintSolverIO *io + ) +{ + int maxTasks = threadSupport->getNumTasks(); + + int div = (int)maxTasks * 4; + int batch = ((int)numContactPairs + div - 1) / div; +#ifdef __PPU__ + BulletPE2ConstraintSolverSpursSupport* spursThread = (BulletPE2ConstraintSolverSpursSupport*) threadSupport; +#endif + if (criticalSection) + { + criticalSection->setSharedParam(0,0); + criticalSection->setSharedParam(1,btMin(batch,64)); // batched number + } else + { +#ifdef __PPU__ + spursThread->setSharedParam(0,0); + spursThread->setSharedParam(1,btMin(batch,64)); // batched number +#endif //__PPU__ + } + + for(int t=0;tgetBarrierAddress(); + io[t].criticalsectionAddr2 = (unsigned int)spursThread->getCriticalSectionAddress(); +#endif + + +//#define SEQUENTIAL_SETUP +#ifdef SEQUENTIAL_SETUP + CustomSetupContactConstraintsTask(contactPairs1,numContactPairs,offsetRigStates,offsetSolverBodies,numRigidBodies,separationBias,timeStep); +#else + threadSupport->sendRequest(1,(ppu_address_t)&io[t],t); +#endif + + } +#ifndef SEQUENTIAL_SETUP + unsigned int arg0,arg1; + for(int t=0;twaitForResponse(&arg0,&arg1); + } +#endif //SEQUENTIAL_SETUP + +} + + +void CustomSplitConstraints( + PfxConstraintPair *pairs,uint32_t numPairs, + PfxParallelGroup &group,PfxParallelBatch *batches, + uint32_t numTasks, + uint32_t numRigidBodies, + void *poolBuff, + uint32_t poolBytes + ) +{ + HeapManager pool((unsigned char*)poolBuff,poolBytes); + + // Xe[g`FbNprbgtOe[u + int bufSize = sizeof(uint8_t)*numRigidBodies; + bufSize = ((bufSize+127)>>7)<<7; // 128 bytes alignment + uint8_t *bodyTable = (uint8_t*)pool.allocate(bufSize,HeapManager::ALIGN128); + + // yA`FbNprbgtOe[u + uint32_t *pairTable; + size_t allocSize = sizeof(uint32_t)*((numPairs+31)/32); + pairTable = (uint32_t*)pool.allocate(allocSize); + memset(pairTable,0,allocSize); + + // ڕWƂ镪 + uint32_t targetCount = btMax(uint32_t(SCE_PFX_MIN_SOLVER_PAIRS),btMin(numPairs / (numTasks*2),uint32_t(SCE_PFX_MAX_SOLVER_PAIRS))); + uint32_t startIndex = 0; + + uint32_t phaseId; + uint32_t batchId; + uint32_t totalCount=0; + + uint32_t maxBatches = btMin(numTasks,uint32_t(SCE_PFX_MAX_SOLVER_BATCHES)); + + for(phaseId=0;phaseId>5; + uint32_t maskP = 1L << (i & 31); + + //pair is already assigned to a phase/batch + if(pairTable[idxP] & maskP) { + continue; + } + + uint32_t idxA = pfxGetObjectIdA(pairs[i]); + uint32_t idxB = pfxGetObjectIdB(pairs[i]); + + // ƂANeBułȂA܂͏Փ˓_ÕyA͓o^Ώۂ͂ + if(!pfxGetActive(pairs[i]) || pfxGetNumConstraints(pairs[i]) == 0 || + ((pfxGetMotionMaskA(pairs[i])&PFX_MOTION_MASK_STATIC) && (pfxGetMotionMaskB(pairs[i])&PFX_MOTION_MASK_STATIC)) ) { + if(startIndexCheck) + startIndex++; + //assign pair -> skip it because it has no constraints + pairTable[idxP] |= maskP; + totalCount++; + continue; + } + + // ˑ̃`FbN + if( (bodyTable[idxA] != batchId && bodyTable[idxA] != 0xff) || + (bodyTable[idxB] != batchId && bodyTable[idxB] != 0xff) ) { + startIndexCheck = false; + //bodies of the pair are already assigned to another batch within this phase + continue; + } + + // ˑe[uɓo^ + if(pfxGetMotionMaskA(pairs[i])&PFX_MOTION_MASK_DYNAMIC) + bodyTable[idxA] = batchId; + if(pfxGetMotionMaskB(pairs[i])&PFX_MOTION_MASK_DYNAMIC) + bodyTable[idxB] = batchId; + + if(startIndexCheck) + startIndex++; + + pairTable[idxP] |= maskP; + //add the pair 'i' to the current batch + batch.pairIndices[pairId++] = i; + pairCount++; + } + + group.numPairs[phaseId*SCE_PFX_MAX_SOLVER_BATCHES+batchId] = (uint16_t)pairId; + totalCount += pairCount; + } + + group.numBatches[phaseId] = batchId; + } + + group.numPhases = phaseId; + + pool.clear(); +} + + + +void CustomSolveConstraintsParallel( + PfxConstraintPair *contactPairs,uint32_t numContactPairs, + + PfxConstraintPair *jointPairs,uint32_t numJointPairs, + + TrbState *offsetRigStates, + PfxSolverBody *offsetSolverBodies, + uint32_t numRigidBodies, + struct btConstraintSolverIO* io, + class btThreadSupportInterface* threadSupport, + int iteration, + void* poolBuf, + int poolBytes, + class btBarrier* barrier) + { + + int maxTasks = threadSupport->getNumTasks(); +// config.taskManager->setTaskEntry(PFX_SOLVER_ENTRY); + + HeapManager pool((unsigned char*)poolBuf,poolBytes); + + { + PfxParallelGroup *cgroup = (PfxParallelGroup*)pool.allocate(sizeof(PfxParallelGroup)); + PfxParallelBatch *cbatches = (PfxParallelBatch*)pool.allocate(sizeof(PfxParallelBatch)*(SCE_PFX_MAX_SOLVER_PHASES*SCE_PFX_MAX_SOLVER_BATCHES),128); + PfxParallelGroup *jgroup = (PfxParallelGroup*)pool.allocate(sizeof(PfxParallelGroup)); + PfxParallelBatch *jbatches = (PfxParallelBatch*)pool.allocate(sizeof(PfxParallelBatch)*(SCE_PFX_MAX_SOLVER_PHASES*SCE_PFX_MAX_SOLVER_BATCHES),128); + + uint32_t tmpBytes = poolBytes - 2 * (sizeof(PfxParallelGroup) + sizeof(PfxParallelBatch)*(SCE_PFX_MAX_SOLVER_PHASES*SCE_PFX_MAX_SOLVER_BATCHES) + 128); + void *tmpBuff = pool.allocate(tmpBytes); + + { + BT_PROFILE("CustomSplitConstraints"); + CustomSplitConstraints(contactPairs,numContactPairs,*cgroup,cbatches,maxTasks,numRigidBodies,tmpBuff,tmpBytes); + CustomSplitConstraints(jointPairs,numJointPairs,*jgroup,jbatches,maxTasks,numRigidBodies,tmpBuff,tmpBytes); + } + + { + BT_PROFILE("PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS"); +//#define SOLVE_SEQUENTIAL +#ifdef SOLVE_SEQUENTIAL + CustomSolveConstraintsTask( + io->solveConstraints.contactParallelGroup, + io->solveConstraints.contactParallelBatches, + io->solveConstraints.contactPairs, + io->solveConstraints.numContactPairs, + io->solveConstraints.offsetContactManifolds, + + io->solveConstraints.jointParallelGroup, + io->solveConstraints.jointParallelBatches, + io->solveConstraints.jointPairs, + io->solveConstraints.numJointPairs, + io->solveConstraints.offsetJoints, + + io->solveConstraints.offsetRigStates, + io->solveConstraints.offsetSolverBodies, + io->solveConstraints.numRigidBodies, + io->solveConstraints.iteration,0,1,0);//arg->taskId,1,0);//,arg->maxTasks,arg->barrier); +#else + for(int t=0;tgetBarrierAddress(); + io[t].criticalsectionAddr2 = (unsigned int)spursThread->getCriticalSectionAddress(); +#endif + + threadSupport->sendRequest(1,(ppu_address_t)&io[t],t); + } + + unsigned int arg0,arg1; + for(int t=0;twaitForResponse(&arg0,&arg1); + } +#endif + } + pool.clear(); + } + + { + BT_PROFILE("PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER"); + int batch = ((int)numRigidBodies + maxTasks - 1) / maxTasks; + int rest = (int)numRigidBodies; + int start = 0; + + for(int t=0;t 0 ? batch : rest; + io[t].cmd = PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER; + io[t].postSolver.states = offsetRigStates + start; + io[t].postSolver.solverBodies = offsetSolverBodies + start; + io[t].postSolver.numRigidBodies = (uint32_t)num; + io[t].maxTasks1 = maxTasks; +#ifdef __PPU__ + BulletPE2ConstraintSolverSpursSupport* spursThread = (BulletPE2ConstraintSolverSpursSupport*) threadSupport; + io[t].barrierAddr2 = (unsigned int)spursThread->getBarrierAddress(); + io[t].criticalsectionAddr2 = (unsigned int)spursThread->getCriticalSectionAddress(); +#endif + +#ifdef SOLVE_SEQUENTIAL + CustomPostSolverTask( io[t].postSolver.states,io[t].postSolver.solverBodies, io[t].postSolver.numRigidBodies); +#else + threadSupport->sendRequest(1,(ppu_address_t)&io[t],t); +#endif + rest -= num; + start += num; + } + + unsigned int arg0,arg1; + for(int t=0;twaitForResponse(&arg0,&arg1); +#endif + } + } + +} + + + +void BPE_customConstraintSolverSequentialNew(unsigned int new_num, PfxBroadphasePair *new_pairs1 , + TrbState* states,int numRigidBodies, + struct PfxSolverBody* solverBodies, + btPersistentManifold* contacts, + PfxConstraintPair* jointPairs, unsigned int numJoints, + float separateBias, + float timeStep, + int iteration, + btThreadSupportInterface* solverThreadSupport, + btCriticalSection* criticalSection, + struct btConstraintSolverIO* solverIO, + btBarrier* barrier + ) +{ + + { + BT_PROFILE("pfxSetupConstraints"); + + for(uint32_t i=0;i m_mystates; + btAlignedObjectArray m_mysolverbodies; + btAlignedObjectArray m_mypairs; + btAlignedObjectArray m_jointPairs; + +}; + + +btConstraintSolverIO* createSolverIO(int numThreads) +{ + return new btConstraintSolverIO[numThreads]; +} + +btLowLevelConstraintSolver::btLowLevelConstraintSolver(btThreadSupportInterface* solverThreadSupport) +{ + + m_solverThreadSupport = solverThreadSupport;//createSolverThreadSupport(maxNumThreads); + m_solverIO = createSolverIO(m_solverThreadSupport->getNumTasks()); + + m_barrier = m_solverThreadSupport->createBarrier(); + m_criticalSection = m_solverThreadSupport->createCriticalSection(); + + m_memoryCache = new btParallelSolverMemoryCache(); +} + +btLowLevelConstraintSolver::~btLowLevelConstraintSolver() +{ + delete m_memoryCache; + delete m_solverIO; +} + + + +btScalar btLowLevelConstraintSolver::solveGroup(btCollisionObject** bodies1,int numRigidBodies,btPersistentManifold** manifoldPtr,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher) +{ + +/* int sz = sizeof(PfxSolverBody); + int sz2 = sizeof(vmVector3); + int sz3 = sizeof(vmMatrix3); + int sz4 = sizeof(vmQuat); + int sz5 = sizeof(btConstraintRow); + int sz6 = sizeof(btSolverConstraint); + int sz7 = sizeof(TrbState); +*/ + + + m_memoryCache->m_mysolverbodies.resize(numRigidBodies); + m_memoryCache->m_mystates.resize(numRigidBodies); + + { + BT_PROFILE("create states and solver bodies"); + for (int i=0;isetCompanionId(i); + + PfxSolverBody& solverBody = m_memoryCache->m_mysolverbodies[i]; + btRigidBody* rb = btRigidBody::upcast(obj); + TrbState& state = m_memoryCache->m_mystates[i]; + + state.reset(); + const btQuaternion& orgOri = obj->getWorldTransform().getRotation(); + vmQuat orn(orgOri.getX(),orgOri.getY(),orgOri.getZ(),orgOri.getW()); + state.setPosition((vmVector3&) obj->getWorldTransform().getOrigin()); + state.setOrientation(orn); + state.setPosition(state.getPosition()); + state.setRigidBodyId(i); + state.setAngularDamping(0); + state.setLinearDamping(0); + + + solverBody.m_orientation = state.getOrientation(); + solverBody.m_deltaLinearVelocity = vmVector3(0.0f); + solverBody.m_deltaAngularVelocity = vmVector3(0.0f); +#ifdef SOLVERBODY_FRICTION + solverBody.friction = obj->getFriction(); + solverBody.restitution = obj->getRestitution(); +#endif //SOLVERBODY_FRICTION + state.resetSleepCount(); + + //if(state.getMotionMask()&PFX_MOTION_MASK_DYNAMIC) { + if (rb && (rb->getInvMass()>0.f)) + { + state.setAngularVelocity(vmVector3(rb->getAngularVelocity().getX(),rb->getAngularVelocity().getY(),rb->getAngularVelocity().getZ())); + state.setLinearVelocity(vmVector3(rb->getLinearVelocity().getX(),rb->getLinearVelocity().getY(),rb->getLinearVelocity().getZ())); + + state.setMotionType(PfxMotionTypeActive); + vmMatrix3 ori(solverBody.m_orientation); + vmMatrix3 localInvInertia = vmMatrix3::identity(); + localInvInertia.setCol(0,vmVector3(rb->getInvInertiaDiagLocal().getX(),0,0)); + localInvInertia.setCol(1,vmVector3(0, rb->getInvInertiaDiagLocal().getY(),0)); + localInvInertia.setCol(2,vmVector3(0,0, rb->getInvInertiaDiagLocal().getZ())); + + solverBody.m_massInv = rb->getInvMass(); + solverBody.m_inertiaInv = ori * localInvInertia * transpose(ori); + } else + { + state.setAngularVelocity(vmVector3(0)); + state.setLinearVelocity(vmVector3(0)); + + state.setMotionType(PfxMotionTypeFixed); + m_memoryCache->m_mysolverbodies[i].m_massInv = 0.f; + m_memoryCache->m_mysolverbodies[i].m_inertiaInv = vmMatrix3(0.0f); + } + + } + } + + + + int totalPoints = 0; +#ifndef USE_C_ARRAYS + m_memoryCache->m_mypairs.resize(numManifolds); + m_memoryCache->m_jointPairs.resize(numConstraints); +#endif//USE_C_ARRAYS + + int actualNumManifolds= 0; + { + BT_PROFILE("convert manifolds"); + for (int i1=0;i1getNumContacts()>0) + { + btPersistentManifold* m = manifoldPtr[i1]; + btCollisionObject* obA = (btCollisionObject*)m->getBody0(); + btCollisionObject* obB = (btCollisionObject*)m->getBody1(); + bool obAisActive = !obA->isStaticOrKinematicObject() && obA->isActive(); + bool obBisActive = !obB->isStaticOrKinematicObject() && obB->isActive(); + + if (!obAisActive && !obBisActive) + continue; + + + //int contactId = i1;//actualNumManifolds; + + PfxBroadphasePair& pair = m_memoryCache->m_mypairs[actualNumManifolds]; + //init those + float compFric = obA->getFriction()*obB->getFriction();//@todo + int idA = obA->getCompanionId(); + int idB = obB->getCompanionId(); + + m->m_companionIdA = idA; + m->m_companionIdB = idB; + + + // if ((mysolverbodies[idA].m_massInv!=0)&&(mysolverbodies[idB].m_massInv!=0)) + // continue; + int numPosPoints=0; + for (int p=0;pgetNumContacts();p++) + { + //btManifoldPoint& pt = m->getContactPoint(p); + //float dist = pt.getDistance(); + //if (dist<0.001) + numPosPoints++; + } + + + numPosPoints = numPosPoints; + totalPoints+=numPosPoints; + pfxSetObjectIdA(pair,idA); + pfxSetObjectIdB(pair,idB); + pfxSetMotionMaskA(pair,m_memoryCache->m_mystates[idA].getMotionMask()); + pfxSetMotionMaskB(pair,m_memoryCache->m_mystates[idB].getMotionMask()); + pfxSetActive(pair,numPosPoints>0); + + pfxSetBroadphaseFlag(pair,0); + pfxSetContactId(pair,(uint32_t)m);//contactId); + pfxSetNumConstraints(pair,numPosPoints);//manifoldPtr[i]->getNumContacts()); + actualNumManifolds++; + } + + } + } + + PfxConstraintPair* jointPairs=0; + jointPairs = numConstraints? &m_memoryCache->m_jointPairs[0]:0; + int actualNumJoints=0; + + + //if (1) + { + BT_PROFILE("convert constraints"); + { + + int totalNumRows = 0; + int i; + + m_tmpConstraintSizesPool.resize(numConstraints); + //calculate the total number of contraint rows + for (i=0;igetInfo1(&info1); + totalNumRows += info1.m_numConstraintRows; + } + m_tmpSolverNonContactConstraintPool.resize(totalNumRows); + + + ///setup the btSolverConstraints + int currentRow = 0; + + for (i=0;igetRigidBodyA(); + btRigidBody& rbB = constraint->getRigidBodyB(); + + + int j; + for ( j=0;jm_contactNormal; + info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal; + info2.m_J2linearAxis = 0; + info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal; + info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this + ///the size of btSolverConstraint needs be a multiple of btScalar + btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint)); + info2.m_constraintError = ¤tConstraintRow->m_rhs; + currentConstraintRow->m_cfm = infoGlobal.m_globalCfm; + info2.cfm = ¤tConstraintRow->m_cfm; + info2.m_lowerLimit = ¤tConstraintRow->m_lowerLimit; + info2.m_upperLimit = ¤tConstraintRow->m_upperLimit; + info2.m_numIterations = infoGlobal.m_numIterations; + constraints[i]->getInfo2(&info2); + + int idA = constraint->getRigidBodyA().getCompanionId(); + int idB = constraint->getRigidBodyB().getCompanionId(); + + + ///finalize the constraint setup + for ( j=0;jgetRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor(); + } + { + const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal; + solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor(); + } + + { + btVector3 iMJlA = solverConstraint.m_contactNormal*rbA.getInvMass(); + btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal; + btVector3 iMJlB = solverConstraint.m_contactNormal*rbB.getInvMass();//sign of normal? + btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal; + + btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal); + sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal); + sum += iMJlB.dot(solverConstraint.m_contactNormal); + sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal); + + solverConstraint.m_jacDiagABInv = btScalar(1.)/sum; + } + + + ///fix rhs + ///todo: add force/torque accelerators + { + btScalar rel_vel; + btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rbA.getLinearVelocity()) + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity()); + btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rbB.getLinearVelocity()) + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity()); + + rel_vel = vel1Dotn+vel2Dotn; + + btScalar restitution = 0.f; + btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2 + btScalar velocityError = restitution - rel_vel;// * damping; + btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; + btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv; + solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; + solverConstraint.m_appliedImpulse = 0.f; + + } + } + + PfxConstraintPair& pair = jointPairs[actualNumJoints]; + + int numConstraintRows= info1.m_numConstraintRows; + pfxSetNumConstraints(pair,numConstraintRows); + + + + pfxSetObjectIdA(pair,idA); + pfxSetObjectIdB(pair,idB); + //is this needed? + pfxSetMotionMaskA(pair,m_memoryCache->m_mystates[idA].getMotionMask()); + pfxSetMotionMaskB(pair,m_memoryCache->m_mystates[idB].getMotionMask()); + + pfxSetActive(pair,true); + pfxSetContactId(pair,(uint32_t)currentConstraintRow);//contactId); + actualNumJoints++; + + + } + currentRow+=m_tmpConstraintSizesPool[i].m_numConstraintRows; + } + } + } + + + + float separateBias=0.1;//info.m_erp;//or m_erp2? + float timeStep=infoGlobal.m_timeStep; + int iteration=infoGlobal.m_numIterations; + + //create a pair for each constraints, copy over info etc + + + + + + { + BT_PROFILE("compute num contacts"); + int totalContacts =0; + + for (int i=0;im_mypairs[i]; + totalContacts += pfxGetNumConstraints(*pair); + } + //printf("numManifolds = %d\n",numManifolds); + //printf("totalContacts=%d\n",totalContacts); + } + + + +// printf("actualNumManifolds=%d\n",actualNumManifolds); + { + BT_PROFILE("BPE_customConstraintSolverSequentialNew"); + if (numRigidBodies>0 && (actualNumManifolds+actualNumJoints)>0) + { +// PFX_PRINTF("num points = %d\n",totalPoints); +// PFX_PRINTF("num points PFX = %d\n",total); + + BPE_customConstraintSolverSequentialNew( + actualNumManifolds, + &m_memoryCache->m_mypairs[0], + &m_memoryCache->m_mystates[0],numRigidBodies, + &m_memoryCache->m_mysolverbodies[0], + 0,//manifoldArray, + jointPairs,actualNumJoints,separateBias,timeStep,iteration, + m_solverThreadSupport,m_criticalSection,m_solverIO,m_barrier); + } + } + + //copy results back to bodies + { + BT_PROFILE("copy back"); + for (int i=0;im_mystates[i]; + if (rb && (rb->getInvMass()>0.f)) + { + rb->setLinearVelocity(btVector3(state.getLinearVelocity().getX(),state.getLinearVelocity().getY(),state.getLinearVelocity().getZ())); + rb->setAngularVelocity(btVector3(state.getAngularVelocity().getX(),state.getAngularVelocity().getY(),state.getAngularVelocity().getZ())); + } + } + } + + + return 0.f; +} diff --git a/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelConstraintSolver.h b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelConstraintSolver.h new file mode 100644 index 000000000..e9b1f2759 --- /dev/null +++ b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelConstraintSolver.h @@ -0,0 +1,130 @@ +/* + Copyright (C) 2010 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef __BT_LOW_LEVEL_CONSTRAINT_SOLVER_H +#define __BT_LOW_LEVEL_CONSTRAINT_SOLVER_H + +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" + + + + +#include "LinearMath/btScalar.h" +#include "BulletMultiThreaded/PlatformDefinitions.h" +#include "physics_effects/low_level/pfx_low_level_include.h" +#include "../src/low_level/solver/pfx_parallel_group.h" + +using namespace sce::PhysicsEffects; + + +class btPersistentManifold; + +enum { + PFX_CONSTRAINT_SOLVER_CMD_SETUP_SOLVER_BODIES, + PFX_CONSTRAINT_SOLVER_CMD_SETUP_CONTACT_CONSTRAINTS, + PFX_CONSTRAINT_SOLVER_CMD_SETUP_JOINT_CONSTRAINTS, + PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS, + PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER +}; + + +struct PfxSetupContactConstraintsIO { + PfxConstraintPair *offsetContactPairs; + uint32_t numContactPairs1; + class TrbState *offsetRigStates; + struct PfxSolverBody *offsetSolverBodies; + uint32_t numRigidBodies; + float separateBias; + float timeStep; + class btCriticalSection* criticalSection; +}; + + + +struct PfxSolveConstraintsIO { + PfxParallelGroup *contactParallelGroup; + PfxParallelBatch *contactParallelBatches; + PfxConstraintPair *contactPairs; + uint32_t numContactPairs; + btPersistentManifold *offsetContactManifolds; + PfxParallelGroup *jointParallelGroup; + PfxParallelBatch *jointParallelBatches; + PfxConstraintPair *jointPairs; + uint32_t numJointPairs; + TrbState *offsetRigStates; + PfxSolverBody *offsetSolverBodies; + uint32_t numRigidBodies; + uint32_t iteration; + + uint32_t taskId; + + class btBarrier* barrier; + +}; + +struct PfxPostSolverIO { + TrbState *states; + PfxSolverBody *solverBodies; + uint32_t numRigidBodies; +}; + +ATTRIBUTE_ALIGNED16(struct) btConstraintSolverIO { + uint8_t cmd; + union { + PfxSetupContactConstraintsIO setupContactConstraints; + PfxSolveConstraintsIO solveConstraints; + PfxPostSolverIO postSolver; + }; + + //SPU only + uint32_t barrierAddr2; + uint32_t criticalsectionAddr2; + uint32_t maxTasks1; +}; + + + + +void SolverThreadFunc(void* userPtr,void* lsMemory); +void* SolverlsMemoryFunc(); +///The btLowLevelConstraintSolver performs computations on constraint rows in parallel +///Using the cross-platform threading it supports Windows, Linux, Mac OSX and PlayStation 3 Cell SPUs +class btLowLevelConstraintSolver : public btSequentialImpulseConstraintSolver +{ + +protected: + struct btParallelSolverMemoryCache* m_memoryCache; + + class btThreadSupportInterface* m_solverThreadSupport; + + struct btConstraintSolverIO* m_solverIO; + class btBarrier* m_barrier; + class btCriticalSection* m_criticalSection; + + +public: + + btLowLevelConstraintSolver(class btThreadSupportInterface* solverThreadSupport); + + virtual ~btLowLevelConstraintSolver(); + + virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher); + +}; + + + +#endif //__BT_LOW_LEVEL_CONSTRAINT_SOLVER_H \ No newline at end of file diff --git a/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelConstraintSolver2.cpp b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelConstraintSolver2.cpp new file mode 100644 index 000000000..e879da46e --- /dev/null +++ b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelConstraintSolver2.cpp @@ -0,0 +1,190 @@ +/* + Copyright (C) 2010 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + + +#include "btLowLevelConstraintSolver2.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" + +#include "LinearMath/btQuickprof.h" +#include "BulletMultiThreaded/btThreadSupportInterface.h" +#include "BulletMultiThreaded/HeapManager.h" +#include "BulletMultiThreaded/PlatformDefinitions.h" +#include "BulletPhysicsEffects/btLowLevelData.h" +#include "BulletMultiThreaded/vectormath2bullet.h" +//#include "PfxSimdUtils.h" +#include "LinearMath/btScalar.h" +#include "BulletMultiThreaded/HeapManager.h" + + + +///////////////// + + +#define TMP_BUFF_BYTES (15*1024*1024) +static unsigned char ATTRIBUTE_ALIGNED128(tmp_buff[TMP_BUFF_BYTES]); + + + + +btLowLevelConstraintSolver2::btLowLevelConstraintSolver2(btLowLevelData* lowLevelData) +:m_lowLevelData(lowLevelData) +{ + +} + +btLowLevelConstraintSolver2::~btLowLevelConstraintSolver2() +{ + +} + + +static void solveConstraints(btLowLevelData* lowLevelData, btScalar timeStep, btScalar separateBias, int iteration) +{ + PfxPerfCounter pc; + HeapManager pool((unsigned char*)tmp_buff,TMP_BUFF_BYTES); + + unsigned int numCurrentPairs = lowLevelData->m_numPairs[lowLevelData->m_pairSwap]; + PfxBroadphasePair *currentPairs = lowLevelData->m_pairsBuff[lowLevelData->m_pairSwap]; + + pc.countBegin("setup solver bodies"); + { + PfxSetupSolverBodiesParam param; + param.states = lowLevelData->m_states; + param.bodies = lowLevelData->m_bodies; + param.solverBodies = lowLevelData->m_solverBodies; + param.numRigidBodies = lowLevelData->m_numRigidBodies; + + int ret = pfxSetupSolverBodies(param); + if(ret != SCE_PFX_OK) + SCE_PFX_PRINTF("pfxSetupSolverBodies failed %d\n",ret); + } + pc.countEnd(); + + pc.countBegin("setup contact constraints"); + { + PfxSetupContactConstraintsParam param; + param.contactPairs = currentPairs; + param.numContactPairs = numCurrentPairs; + param.offsetContactManifolds = lowLevelData->m_contacts; + param.offsetRigidStates = lowLevelData->m_states; + param.offsetRigidBodies = lowLevelData->m_bodies; + param.offsetSolverBodies = lowLevelData->m_solverBodies; + param.numRigidBodies = lowLevelData->m_numRigidBodies; + param.timeStep = timeStep; + param.separateBias = separateBias; + + int ret = pfxSetupContactConstraints(param); + if(ret != SCE_PFX_OK) SCE_PFX_PRINTF("pfxSetupJointConstraints failed %d\n",ret); + } + pc.countEnd(); +#if 0 + pc.countBegin("setup joint constraints"); + { + PfxSetupJointConstraintsParam param; + param.jointPairs = 0;//jointPairs; + param.numJointPairs = 0;//numJoints; + param.offsetJoints = 0;//joints; + param.offsetRigidStates = lowLevelData->m_states; + param.offsetRigidBodies = lowLevelData->m_bodies; + param.offsetSolverBodies = lowLevelData->m_solverBodies; + param.numRigidBodies = lowLevelData->m_numRigidBodies; + param.timeStep = timeStep; + + for(int i=0;im_numRigidBodies,numCurrentPairs,0);//numJoints); + param.workBuff = pool.allocate(param.workBytes); + param.contactPairs = currentPairs; + param.numContactPairs = numCurrentPairs; + param.offsetContactManifolds = lowLevelData->m_contacts; + param.jointPairs = 0;//jointPairs; + param.numJointPairs = 0;//numJoints; + param.offsetJoints = 0;//joints; + param.offsetRigidStates = lowLevelData->m_states; + param.offsetSolverBodies = lowLevelData->m_solverBodies; + param.numRigidBodies = lowLevelData->m_numRigidBodies; + param.iteration = iteration; + + int ret = pfxSolveConstraints(param); + if(ret != SCE_PFX_OK) SCE_PFX_PRINTF("pfxSolveConstraints failed %d\n",ret); + + pool.deallocate(param.workBuff); + } + pc.countEnd(); + + + //pc.printCount(); +} + + + +btScalar btLowLevelConstraintSolver2::solveGroup(btCollisionObject** bodies1,int numRigidBodies,btPersistentManifold** manifoldPtr,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher) +{ + + //copy velocity from BT to PE + { + BT_PROFILE("copy back"); + for (int i=0;igetInvMass()>0.f)) + { + int objectIndex = rb->getBroadphaseProxy()->m_uniqueId; + sce::PhysicsEffects::PfxRigidState& state = m_lowLevelData->m_states[objectIndex]; + + state.setLinearVelocity(getVmVector3(rb->getLinearVelocity())); + state.setAngularVelocity(getVmVector3(rb->getAngularVelocity())); + + } + } + } + + btScalar separateBias = 0.1f; + solveConstraints(m_lowLevelData, infoGlobal.m_timeStep, separateBias, infoGlobal.m_numIterations); + + + //copy resulting velocity back from PE to BT + { + BT_PROFILE("copy back"); + for (int i=0;igetInvMass()>0.f)) + { + int objectIndex = rb->getBroadphaseProxy()->m_uniqueId; + sce::PhysicsEffects::PfxRigidState& state = m_lowLevelData->m_states[objectIndex]; + + rb->setLinearVelocity(btVector3(state.getLinearVelocity().getX(),state.getLinearVelocity().getY(),state.getLinearVelocity().getZ())); + rb->setAngularVelocity(btVector3(state.getAngularVelocity().getX(),state.getAngularVelocity().getY(),state.getAngularVelocity().getZ())); + } + } + } + + return 0.f; +} diff --git a/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelConstraintSolver2.h b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelConstraintSolver2.h new file mode 100644 index 000000000..6fa3921ff --- /dev/null +++ b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelConstraintSolver2.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2010 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef __BT_LOW_LEVEL_CONSTRAINT_SOLVER2_H +#define __BT_LOW_LEVEL_CONSTRAINT_SOLVER2_H + +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" + + + + +#include "LinearMath/btScalar.h" +#include "BulletMultiThreaded/PlatformDefinitions.h" +#include "physics_effects/low_level/pfx_low_level_include.h" +#include "../src/low_level/solver/pfx_parallel_group.h" + +using namespace sce::PhysicsEffects; + + +class btPersistentManifold; +struct btLowLevelData; + +class btLowLevelConstraintSolver2 : public btSequentialImpulseConstraintSolver +{ + +protected: + + btLowLevelData* m_lowLevelData; + +public: + + btLowLevelConstraintSolver2(btLowLevelData* lowLevelData); + + virtual ~btLowLevelConstraintSolver2(); + + virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher); + +}; + + + +#endif //__BT_LOW_LEVEL_CONSTRAINT_SOLVER2_H \ No newline at end of file diff --git a/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelData.cpp b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelData.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelData.h b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelData.h new file mode 100644 index 000000000..949299cff Binary files /dev/null and b/Extras/PhysicsEffects/include/BulletPhysicsEffects/btLowLevelData.h differ diff --git a/Extras/PhysicsEffects/include/physics_effects.h b/Extras/PhysicsEffects/include/physics_effects.h new file mode 100644 index 000000000..e270c470c --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects.h @@ -0,0 +1,23 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PHYSICS_EFFECTS_H +#define _SCE_PHYSICS_EFFECTS_H + +#include "physics_effects/low_level/pfx_low_level_include.h" +#include "physics_effects/util/pfx_util_include.h" + +#endif // __PHYSICS_EFFECTS_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_common.h b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_common.h new file mode 100644 index 000000000..c40b733bd --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_common.h @@ -0,0 +1,181 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_COMMON_H +#define _SCE_PFX_COMMON_H + +// Include common headers +#ifdef _WIN32 + #include + #include + #include +#else + #include + #include +#endif + +#include +#include +#include + +#if defined(_WIN32) + #include "pfx_vectormath_include.win32.h" +#else + #include "pfx_vectormath_include.h" +#endif + +namespace sce { +namespace PhysicsEffects { +// Basic Types +#if defined(_WIN32) + typedef char PfxInt8; + typedef unsigned char PfxUInt8; + typedef short PfxInt16; + typedef unsigned short PfxUInt16; + typedef int PfxInt32; + typedef unsigned int PfxUInt32; + typedef long long PfxInt64; + typedef unsigned long long PfxUInt64; +#else + typedef int8_t PfxInt8; + typedef uint8_t PfxUInt8; + typedef int16_t PfxInt16; + typedef uint16_t PfxUInt16; + typedef int32_t PfxInt32; + typedef uint32_t PfxUInt32; + typedef int64_t PfxInt64; + typedef uint64_t PfxUInt64; +#endif + +typedef bool PfxBool; +typedef float PfxFloat; +} //namespace PhysicsEffects +} //namespace sce + +// Debug Print +#ifdef _WIN32 +static void pfxOutputDebugString(const char *str, ...) +{ + char strDebug[1024]={0}; + va_list argList; + va_start(argList, str); + vsprintf_s(strDebug,str,argList); + OutputDebugStringA(strDebug); + va_end(argList); +} +#endif + +#if defined(_DEBUG) + #if defined(_WIN32) + #define SCE_PFX_DPRINT pfxOutputDebugString + #else + #define SCE_PFX_DPRINT(...) printf(__VA_ARGS__) + #endif +#else + #ifdef _WIN32 + #define SCE_PFX_DPRINT + #else + #define SCE_PFX_DPRINT(...) + #endif +#endif + +// Printf +#if defined(_WIN32) + #define SCE_PFX_PRINTF pfxOutputDebugString +#else +// ARA begin insert new code + #ifdef __ANDROID__ + #include + #define SCE_PFX_PRINTF(...) __android_log_print(ANDROID_LOG_VERBOSE, "SCE_PFX_PRINTF", __VA_ARGS__) + #else + #define SCE_PFX_PRINTF(...) printf(__VA_ARGS__) + #endif +// ARA end, old baseline code block was: +// #define SCE_PFX_PRINTF(...) printf(__VA_ARGS__) +// +#endif + +#define SCE_PFX_UNLIKELY(a) (a) +#define SCE_PFX_LIKELY(a) (a) + +// Inline +#if defined(_MSC_VER) + #define SCE_PFX_FORCE_INLINE __forceinline +#elif defined(__SNC__) || defined(__GNUC__) + #define SCE_PFX_FORCE_INLINE inline __attribute__((always_inline)) +#endif + +// Assert +#define SCE_PFX_HALT() abort() + +#ifdef _DEBUG + #define SCE_PFX_ASSERT(test) {if(!(test)){SCE_PFX_PRINTF("Assert "__FILE__ ":%u ("#test")\n", __LINE__);SCE_PFX_HALT();}} + #define SCE_PFX_ASSERT_MSG(test,msg) {if(!(test)){SCE_PFX_PRINTF("Assert " msg " " __FILE__ ":%u ("#test")\n",__LINE__);SCE_PFX_HALT();}} +#else + #define SCE_PFX_ASSERT(test) + #define SCE_PFX_ASSERT_MSG(test,msg) +#endif + +#define SCE_PFX_ALWAYS_ASSERT(test) {if(!(test)){SCE_PFX_PRINTF("Assert "__FILE__ ":%u ("#test")\n", __LINE__);SCE_PFX_HALT();}} +#define SCE_PFX_ALWAYS_ASSERT_MSG(test,msg) {if(!(test)){SCE_PFX_PRINTF("Assert:" msg " " __FILE__ ":%u ("#test")\n",__LINE__);SCE_PFX_HALT();}} + +// Aligned +#if defined(_MSC_VER) + #define SCE_PFX_ALIGNED(alignment) __declspec(align(alignment)) +#elif defined(__SNC__) || defined(__GNUC__) + #define SCE_PFX_ALIGNED(alignment) __attribute__((__aligned__((alignment)))) +#endif + +// Etc +#define SCE_PFX_MIN(a,b) (((a)<(b))?(a):(b)) +#define SCE_PFX_MAX(a,b) (((a)>(b))?(a):(b)) +#define SCE_PFX_CLAMP(v,a,b) SCE_PFX_MAX(a,SCE_PFX_MIN(v,b)) +#define SCE_PFX_SWAP(type, x, y) do {type t; t=x; x=y; y=t; } while (0) +#define SCE_PFX_SQR(a) ((a)*(a)) + +#define SCE_PFX_ALIGN16(count,size) ((((((count) * (size)) + 15) & (~15)) + (size)-1) / (size)) +#define SCE_PFX_ALIGN128(count,size) ((((((count) * (size)) + 127) & (~127)) + (size)-1) / (size)) + +#define SCE_PFX_AVAILABLE_BYTES_ALIGN16(ptr,bytes) (bytes-((uintptr_t)(ptr)&0x0f)) +#define SCE_PFX_AVAILABLE_BYTES_ALIGN128(ptr,bytes) (bytes-((uintptr_t)(ptr)&0x7f)) + +#define SCE_PFX_BYTES_ALIGN16(bytes) (((bytes)+15)&(~15)) +#define SCE_PFX_BYTES_ALIGN128(bytes) (((bytes)+127)&(~127)) + +#define SCE_PFX_PTR_ALIGN16(ptr) (((uintptr_t)(ptr)+15)&(~15)) +#define SCE_PFX_PTR_ALIGN128(ptr) (((uintptr_t)(ptr)+127)&(~127)) + +#define SCE_PFX_PTR_IS_ALIGNED16(ptr) (((uintptr_t)(ptr)&0x0f)==0) +#define SCE_PFX_PTR_IS_ALIGNED128(ptr) (((uintptr_t)(ptr)&0x7f)==0) + +#define SCE_PFX_GET_POINTER(offset,stride,id) ((uintptr_t)(offset)+(stride)*(id)) + +#define SCE_PFX_FLT_MAX 1e+38f +#define SCE_PFX_PI 3.14159265358979f + +#define SCE_PFX_RANGE_CHECK(val,minVal,maxVal) (((val)>=(minVal))&&((val)<=(maxVal))) + +#define SCE_PFX_IS_RUNNING_ON_64BIT_ENV() ( ( sizeof(void*)==8 )? true : false ) + +#if defined(__SNC__) || defined(__GNUC__) + #define SCE_PFX_PADDING(count,bytes) PfxUInt8 padding##count[bytes]; +#else + #define SCE_PFX_PADDING(count,bytes) +#endif + +#include "pfx_error_code.h" + +#endif // _SCE_PFX_COMMON_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_error_code.h b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_error_code.h new file mode 100644 index 000000000..ca117b79c --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_error_code.h @@ -0,0 +1,30 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_ERROR_CODE_H +#define _SCE_PFX_ERROR_CODE_H + +#define SCE_PFX_OK 0 +#define SCE_PFX_ERR_INVALID_VALUE 0x80880001 +#define SCE_PFX_ERR_INVALID_ALIGN 0x80880002 +#define SCE_PFX_ERR_OUT_OF_BUFFER 0x80880003 +#define SCE_PFX_ERR_OUT_OF_MAX_PAIRS 0x80880004 +#define SCE_PFX_ERR_OUT_OF_RANGE 0x80880005 +#define SCE_PFX_ERR_OUT_OF_WORLD 0x80880006 +#define SCE_PFX_ERR_INVALID_FLAG 0x80880007 + +#endif // _SCE_PFX_ERROR_CODE_H + diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_heap_manager.h b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_heap_manager.h new file mode 100644 index 000000000..10ad5afce --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_heap_manager.h @@ -0,0 +1,141 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_HEAP_MANAGER_H +#define _SCE_PFX_HEAP_MANAGER_H + +#include "pfx_common.h" + +//J プールされたメモリを管理するスタックのサイズ +//E Size of a stack which used to manage pool memory +#define SCE_PFX_HEAP_STACK_SIZE 64 + +#define SCE_PFX_MIN_ALLOC_SIZE 16 + +#define SCE_PFX_ALLOC_BYTES_ALIGN16(bytes) SCE_PFX_MAX(16,SCE_PFX_BYTES_ALIGN16(bytes)) +#define SCE_PFX_ALLOC_BYTES_ALIGN128(bytes) SCE_PFX_MAX(128,SCE_PFX_BYTES_ALIGN128(bytes)) + +#if defined (_WIN64) || defined (__LP64__) + #define SCE_PFX_ALIGN_MASK_16 0xfffffffffffffff0 + #define SCE_PFX_ALIGN_MASK_128 0xffffffffffffff80 +#else + #define SCE_PFX_ALIGN_MASK_16 0xfffffff0 + #define SCE_PFX_ALIGN_MASK_128 0xffffff80 +#endif + +/////////////////////////////////////////////////////////////////////////////// +// PfxHeapManager + +//J <補足> +//J メモリはスタックで管理されています。取得した順と逆に開放する必要があります。 +//J メモリを一気に開放したい場合はclear()を呼び出してください。 +//J 最小割り当てサイズはSCE_PFX_MIN_ALLOC_SIZEで定義されます。 + +//E +//E Memory is managed as a stack, so deallocate() needs to be called in reverse order. +//E Use clear() to deallocate all allocated memory at once. +//E SCE_PFX_MIN_ALLOC_SIZE defines the smallest amount of buffer. + +namespace sce { +namespace PhysicsEffects { + +class PfxHeapManager +{ +private: + PfxUInt8 *m_heap; + PfxUInt8 *m_poolStack[SCE_PFX_HEAP_STACK_SIZE]; + PfxInt32 m_heapBytes; + PfxInt32 m_curStack; + PfxInt32 m_rest; + +public: + enum {ALIGN16=16,ALIGN128=128}; + + PfxHeapManager(PfxUInt8 *buf,PfxInt32 bytes) + { + m_heap = buf; + m_heapBytes = bytes; + clear(); + } + + ~PfxHeapManager() + { + } + + PfxInt32 getAllocated() + { + return (PfxInt32)(m_poolStack[m_curStack]-m_heap); + } + + PfxInt32 getRest() + { + return m_heapBytes-getAllocated(); + } + + void *allocate(size_t bytes,PfxInt32 alignment = ALIGN16) + { + SCE_PFX_ALWAYS_ASSERT(m_curStack +#endif +// ARA end + +//J パフォーマンス測定する場合はPFX_USE_PERFCOUNTERを定義 +//J ブックマークを使用する場合はPFX_USE_BOOKMARKを定義 + +//E Define SCE_PFX_USE_PERFCOUNTER to check performance +//E Define SCE_PFX_USE_BOOKMARK to use bookmark + + +#define SCE_PFX_MAX_PERF_STR 32 +#define SCE_PFX_MAX_PERF_COUNT 20 + +//#define SCE_PFX_USE_PERFCOUNTER +//#define SCE_PFX_USE_BOOKMARK + +namespace sce { +namespace PhysicsEffects { +#ifdef SCE_PFX_USE_PERFCOUNTER + +class PfxPerfCounter +{ +private: + int m_count,m_strCount; + char m_str[SCE_PFX_MAX_PERF_COUNT][SCE_PFX_MAX_PERF_STR]; + float m_freq; + + SCE_PFX_PADDING(1,4) +#ifdef _WIN32 + LONGLONG m_cnt[SCE_PFX_MAX_PERF_COUNT*2]; +#else +// ARA begin insert new code + timespec m_cnt[SCE_PFX_MAX_PERF_COUNT*2]; +// ARA end +#endif + + void count(int i) + { +#ifdef _WIN32 + QueryPerformanceCounter( (LARGE_INTEGER *)&m_cnt[i] ); +#else +// ARA begin insert new code + clock_gettime(CLOCK_MONOTONIC, &m_cnt[i]); +// ARA end +#endif + } + +public: + PfxPerfCounter() + { +#ifdef _WIN32 + LARGE_INTEGER sPerfCountFreq; + QueryPerformanceFrequency(&sPerfCountFreq); + m_freq = (float)sPerfCountFreq.QuadPart; +#else +// ARA begin insert new code + m_freq = 1000000000.0f; // clock_gettime reports time in nanoseconds (though accuracy is platform dependent) +// ARA end +#endif + resetCount(); + } + + ~PfxPerfCounter() + { + //printCount(); + } + + void countBegin(const char *name) + { + SCE_PFX_ASSERT(m_strCount < SCE_PFX_MAX_PERF_COUNT); + strncpy(m_str[m_strCount],name,SCE_PFX_MAX_PERF_STR-1); + m_str[m_strCount][SCE_PFX_MAX_PERF_STR-1] = 0x00; + m_strCount++; + count(m_count++); + } + + void countEnd() + { + count(m_count++); + } + + void resetCount() + { + m_strCount = 0; + m_count = 0; + } + + float getCountTime(int i) + { +#if _WIN32 + return (float)(m_cnt[i+1]-m_cnt[i]) / m_freq * 1000.0f; +#else +// ARA begin insert new code + return float(m_cnt[i+1].tv_sec - m_cnt[i].tv_sec) + + (float(m_cnt[i+1].tv_nsec - m_cnt[i].tv_nsec) / m_freq); +// ARA end +#endif +} + + void printCount() + { + if(m_count%2 != 0) countEnd(); + SCE_PFX_PRINTF("*** PfxPerfCounter results ***\n"); + float total = 0.0f; + for(int i=0;i+1>1],getCountTime(i),getCountTime(i)/total*100.0f); + } + SCE_PFX_PRINTF(" -- Total %fms\n",total); + } +}; + +#else /* SCE_PFX_USE_PERFCOUNTER */ + +class PfxPerfCounter +{ +public: + PfxPerfCounter() {} + ~PfxPerfCounter() {} + void countBegin(const char *name) {(void) name;} + void countEnd() {} + void resetCount() {} + float getCountTime(int i) {(void)i;return 0.0f;} + void printCount() {} +}; + +#endif /* SCE_PFX_USE_PERFCOUNTER */ + +#define pfxInsertBookmark(bookmark) + +#ifdef SCE_PFX_USE_BOOKMARK + #define SCE_PFX_PUSH_MARKER(name) + #define SCE_PFX_POP_MARKER() +#else + #define SCE_PFX_PUSH_MARKER(name) + #define SCE_PFX_POP_MARKER() +#endif + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_PERF_COUNTER_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_vec_int3.h b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_vec_int3.h new file mode 100644 index 000000000..2c588bf20 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_vec_int3.h @@ -0,0 +1,166 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_VEC_INT3_H +#define _SCE_PFX_VEC_INT3_H + +#include "pfx_common.h" + + + +namespace sce { +namespace PhysicsEffects { + +class SCE_PFX_ALIGNED(16) PfxVecInt3 +{ +private: +PfxInt32 m_x,m_y,m_z,m_w; + +public: +PfxVecInt3() {m_x=m_y=m_z=m_w=0;} +PfxVecInt3(const PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG vec) {m_x=(PfxInt32)vec[0];m_y=(PfxInt32)vec[1];m_z=(PfxInt32)vec[2];m_w=0;} +PfxVecInt3(PfxFloat fx,PfxFloat fy,PfxFloat fz) {m_x=(PfxInt32)fx;m_y=(PfxInt32)fy;m_z=(PfxInt32)fz;m_w=0;} +PfxVecInt3(PfxInt32 iv) {m_x=m_y=m_z=iv;m_w=0;} +PfxVecInt3(PfxInt32 ix,PfxInt32 iy,PfxInt32 iz) {m_x=ix;m_y=iy;m_z=iz;m_w=0;} + + inline PfxVecInt3 &operator =( const PfxVecInt3 &vec); + +inline PfxInt32 get(PfxInt32 i) const {return *(&m_x+i);} +inline PfxInt32 getX() const {return m_x;} +inline PfxInt32 getY() const {return m_y;} +inline PfxInt32 getZ() const {return m_z;} +inline void set(PfxInt32 i,PfxInt32 v) {*(&m_x+i) = v;} +inline void setX(PfxInt32 v) {m_x = v;} +inline void setY(PfxInt32 v) {m_y = v;} +inline void setZ(PfxInt32 v) {m_z = v;} + + inline const PfxVecInt3 operator +( const PfxVecInt3 & vec ) const; + inline const PfxVecInt3 operator -( const PfxVecInt3 & vec ) const; + inline const PfxVecInt3 operator *( PfxInt32 scalar ) const; + inline const PfxVecInt3 operator /( PfxInt32 scalar ) const; + + inline PfxVecInt3 & operator +=( const PfxVecInt3 & vec ); + inline PfxVecInt3 & operator -=( const PfxVecInt3 & vec ); + inline PfxVecInt3 & operator *=( PfxInt32 scalar ); + inline PfxVecInt3 & operator /=( PfxInt32 scalar ); + + inline const PfxVecInt3 operator -() const; + +operator PfxVector3() const +{ + return PfxVector3((PfxFloat)m_x,(PfxFloat)m_y,(PfxFloat)m_z); +} +}; + +inline PfxVecInt3 &PfxVecInt3::operator =( const PfxVecInt3 &vec) +{ + m_x = vec.m_x; + m_y = vec.m_y; + m_z = vec.m_z; + return *this; +} + +inline const PfxVecInt3 PfxVecInt3::operator +( const PfxVecInt3 & vec ) const +{ + return PfxVecInt3(m_x+vec.m_x, m_y+vec.m_y, m_z+vec.m_z); +} + +inline const PfxVecInt3 PfxVecInt3::operator -( const PfxVecInt3 & vec ) const +{ + return PfxVecInt3(m_x-vec.m_x, m_y-vec.m_y, m_z-vec.m_z); +} + +inline const PfxVecInt3 PfxVecInt3::operator *( PfxInt32 scalar ) const +{ + return PfxVecInt3(m_x*scalar, m_y*scalar, m_z*scalar); +} + +inline const PfxVecInt3 PfxVecInt3::operator /( PfxInt32 scalar ) const +{ + return PfxVecInt3(m_x/scalar, m_y/scalar, m_z/scalar); +} + +inline PfxVecInt3 &PfxVecInt3::operator +=( const PfxVecInt3 & vec ) +{ + *this = *this + vec; + return *this; +} + +inline PfxVecInt3 &PfxVecInt3::operator -=( const PfxVecInt3 & vec ) +{ + *this = *this - vec; + return *this; +} + +inline PfxVecInt3 &PfxVecInt3::operator *=( PfxInt32 scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline PfxVecInt3 &PfxVecInt3::operator /=( PfxInt32 scalar ) +{ + *this = *this / scalar; + return *this; +} + +inline const PfxVecInt3 PfxVecInt3::operator -() const +{ +return PfxVecInt3(-m_x,-m_y,-m_z); +} + +inline const PfxVecInt3 operator *( PfxInt32 scalar, const PfxVecInt3 & vec ) +{ + return vec * scalar; +} + +inline const PfxVecInt3 mulPerElem( const PfxVecInt3 & vec0, const PfxVecInt3 & vec1 ) +{ +return PfxVecInt3(vec0.getX()*vec1.getX(), vec0.getY()*vec1.getY(), vec0.getZ()*vec1.getZ()); +} + +inline const PfxVecInt3 divPerElem( const PfxVecInt3 & vec0, const PfxVecInt3 & vec1 ) +{ +return PfxVecInt3(vec0.getX()/vec1.getX(), vec0.getY()/vec1.getY(), vec0.getZ()/vec1.getZ()); +} + +inline const PfxVecInt3 absPerElem( const PfxVecInt3 & vec ) +{ +return PfxVecInt3(abs(vec.getX()), abs(vec.getY()), abs(vec.getZ())); +} + +inline const PfxVecInt3 maxPerElem( const PfxVecInt3 & vec0, const PfxVecInt3 & vec1 ) +{ + return PfxVecInt3( + (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ() + ); +} + +inline const PfxVecInt3 minPerElem( const PfxVecInt3 & vec0, const PfxVecInt3 & vec1 ) +{ + return PfxVecInt3( + (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ() + ); +} +} //namespace PhysicsEffects +} //namespace sce + + +#endif // _SCE_PFX_VEC_INT3_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_vec_utils.h b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_vec_utils.h new file mode 100644 index 000000000..2b50db5df --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_vec_utils.h @@ -0,0 +1,181 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_VEC_UTILS_H +#define _SCE_PFX_VEC_UTILS_H + +#include "pfx_common.h" +#include "pfx_vec_int3.h" + +namespace sce { +namespace PhysicsEffects { +static SCE_PFX_FORCE_INLINE PfxVector3 pfxReadVector3(const PfxFloat* fptr) +{ + PfxVector3 v; + +loadXYZ(v, fptr); + + return v; +} + +static SCE_PFX_FORCE_INLINE PfxPoint3 pfxReadPoint3(const PfxFloat* fptr) +{ + PfxPoint3 v; + +loadXYZ(v, fptr); + + return v; +} + +static SCE_PFX_FORCE_INLINE PfxQuat pfxReadQuat(const PfxFloat* fptr) +{ + PfxQuat vq; + +loadXYZW(vq, fptr); + + return vq; +} + +static SCE_PFX_FORCE_INLINE void pfxStoreVector3(const PfxVector3 &src, PfxFloat* fptr) +{ +storeXYZ(src, fptr); +} + +static SCE_PFX_FORCE_INLINE void pfxStorePoint3(const PfxPoint3 &src, PfxFloat* fptr) +{ +storeXYZ(src, fptr); +} + +static SCE_PFX_FORCE_INLINE void pfxStoreQuat(const PfxQuat &src, PfxFloat* fptr) +{ +storeXYZW(src, fptr); +} + +} // namespace PhysicsEffects +} // namespace sce + +namespace sce { +namespace PhysicsEffects { +static SCE_PFX_FORCE_INLINE +void pfxGetPlaneSpace(const PfxVector3& n, PfxVector3& fptr, PfxVector3& q) +{ + if(fabsf(n[2]) > 0.707f) { + // choose fptr in y-z plane + PfxFloat a = n[1]*n[1] + n[2]*n[2]; + PfxFloat k = 1.0f/sqrtf(a); + fptr[0] = 0; + fptr[1] = -n[2]*k; + fptr[2] = n[1]*k; + // set q = n x fptr + q[0] = a*k; + q[1] = -n[0]*fptr[2]; + q[2] = n[0]*fptr[1]; + } + else { + // choose fptr in x-y plane + PfxFloat a = n[0]*n[0] + n[1]*n[1]; + PfxFloat k = 1.0f/sqrtf(a); + fptr[0] = -n[1]*k; + fptr[1] = n[0]*k; + fptr[2] = 0; + // set q = n x fptr + q[0] = -n[2]*fptr[1]; + q[1] = n[2]*fptr[0]; + q[2] = a*k; + } +} + +static SCE_PFX_FORCE_INLINE +void pfxGetRotationAngleAndAxis(const PfxQuat &unitQuat,PfxFloat &angle,PfxVector3 &axis) +{ + const PfxFloat epsilon=0.00001f; + + if(fabsf(unitQuat.getW()) < 1.0f-epsilon && lengthSqr(unitQuat.getXYZ()) > epsilon) { + PfxFloat angleHalf = acosf(unitQuat.getW()); + PfxFloat sinAngleHalf = sinf(angleHalf); + + if(fabsf(sinAngleHalf) > 1.0e-10f) { + axis = unitQuat.getXYZ()/sinAngleHalf; + } else { + axis = unitQuat.getXYZ(); + } + angle = 2.0f*angleHalf; + } else { + angle = 0.0f; + axis = PfxVector3(1.0f, 0.0f, 0.0f); + } +} + +static SCE_PFX_FORCE_INLINE +PfxFloat pfxSafeAtan2(PfxFloat y,PfxFloat x) +{ + if(SCE_PFX_SQR(x) < 0.000001f || SCE_PFX_SQR(y) < 0.000001f) { + return 0.0f; + } + return atan2f(y,x); +} + +static SCE_PFX_FORCE_INLINE +PfxVector3 pfxSafeNormalize(const PfxVector3 &vec) +{ + float lenSqr = lengthSqr( vec ); + + if( lenSqr > 0.000001f ) { + return normalize(vec); + }else { + return PfxVector3( 1.0f, 0.0f, 0.0f ); + } +} + +static SCE_PFX_FORCE_INLINE +PfxVecInt3 pfxConvertCoordWorldToLocal(const PfxVector3 &coord,const PfxVector3 ¢er,const PfxVector3 &half) +{ + const PfxVector3 sz(65535.0f); + PfxVector3 q = divPerElem(coord - center + half,2.0f*half); + q = minPerElem(maxPerElem(q,PfxVector3(0.0f)),PfxVector3(1.0f)); // clamp 0.0 - 1.0 + q = mulPerElem(q,sz); + return PfxVecInt3(q); +} + +static SCE_PFX_FORCE_INLINE +void pfxConvertCoordWorldToLocal( + const PfxVector3 ¢er,const PfxVector3 &half, + const PfxVector3 &coordMin,const PfxVector3 &coordMax, + PfxVecInt3 &localMin,PfxVecInt3 &localMax) +{ + const PfxVector3 sz(65535.0f); + PfxVector3 qmin = divPerElem(coordMin - center + half,2.0f*half); + qmin = minPerElem(maxPerElem(qmin,PfxVector3(0.0f)),PfxVector3(1.0f)); // clamp 0.0 - 1.0 + qmin = mulPerElem(qmin,sz); + + PfxVector3 qmax = divPerElem(coordMax - center + half,2.0f*half); + qmax = minPerElem(maxPerElem(qmax,PfxVector3(0.0f)),PfxVector3(1.0f)); // clamp 0.0 - 1.0 + qmax = mulPerElem(qmax,sz); +localMin = PfxVecInt3(floorf(qmin[0]),floorf(qmin[1]),floorf(qmin[2])); +localMax = PfxVecInt3(ceilf(qmax[0]),ceilf(qmax[1]),ceilf(qmax[2])); +} + +static SCE_PFX_FORCE_INLINE +PfxVector3 pfxConvertCoordLocalToWorld(const PfxVecInt3 &coord,const PfxVector3 ¢er,const PfxVector3 &half) +{ + PfxVector3 sz(65535.0f),vcoord(coord); + PfxVector3 q = divPerElem(vcoord,sz); + return mulPerElem(q,2.0f*half) + center - half; +} +} // namespace PhysicsEffects +} // namespace sce + +#endif // _SCE_PFX_VEC_UTILS_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_vectormath_include.h b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_vectormath_include.h new file mode 100644 index 000000000..1cd3590d0 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_vectormath_include.h @@ -0,0 +1,101 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_VECTORMATH_INCLUDE_H +#define _SCE_PFX_VECTORMATH_INCLUDE_H + +// If you want to use the free/open sourced vectormath, you need to +// put codes in the include/vecmath folder and set following define. +#define SCE_PFX_USE_FREE_VECTORMATH + +// If you want to use vectomath with SIMD, +// following define is needed. +//#define SCE_PFX_USE_SIMD_VECTORMATH + +// This option enables to replace original implementation with +// vector geometry library. +//#define SCE_PFX_USE_GEOMETRY + +// vectormath include +#ifdef SCE_PFX_USE_FREE_VECTORMATH + // ARA begin insert new code + #if defined(SCE_PFX_USE_SIMD_VECTORMATH) && defined(__ANDROID__) && defined(__ARM_NEON__) + // For Android targets supporting NEON instructions, + // use NEON-optimized vector math library + #include "../../../vecmath/neon/vectormath_aos.h" + #include "../../../vecmath/neon/floatInVec.h" + #else + // ARA end + // use standard free vector math library + #include "../../../vecmath/std/vectormath_aos.h" + #include "../../../vecmath/std/floatInVec.h" + // ARA begin insert new code + #endif + // ARA end + #define SCE_VECTORMATH_AOS_VECTOR_ARG + #define SCE_VECTORMATH_AOS_MATRIX_ARG + + namespace sce { + namespace PhysicsEffects { + typedef Vectormath::Aos::Point3 PfxPoint3; + typedef Vectormath::Aos::Vector3 PfxVector3; + typedef Vectormath::Aos::Vector4 PfxVector4; + typedef Vectormath::Aos::Quat PfxQuat; + typedef Vectormath::Aos::Matrix3 PfxMatrix3; + typedef Vectormath::Aos::Matrix4 PfxMatrix4; + typedef Vectormath::Aos::Transform3 PfxTransform3; + typedef Vectormath::floatInVec PfxFloatInVec; + typedef Vectormath::boolInVec PfxBoolInVec; + } //namespace PhysicsEffects + } //namespace sce +#else + #include + #define SCE_GEOMETRY_USE_SCALAR_MATH + #define SCE_VECTORMATH_AOS_VECTOR_ARG SCE_VECTORMATH_SCALAR_AOS_VECTOR_ARG + #define SCE_VECTORMATH_AOS_MATRIX_ARG SCE_VECTORMATH_SCALAR_AOS_MATRIX_ARG + + namespace sce { + namespace PhysicsEffects { + typedef sce::Vectormath::Scalar::Aos::Point3 PfxPoint3; + typedef sce::Vectormath::Scalar::Aos::Vector3 PfxVector3; + typedef sce::Vectormath::Scalar::Aos::Vector4 PfxVector4; + typedef sce::Vectormath::Scalar::Aos::Quat PfxQuat; + typedef sce::Vectormath::Scalar::Aos::Matrix3 PfxMatrix3; + typedef sce::Vectormath::Scalar::Aos::Matrix4 PfxMatrix4; + typedef sce::Vectormath::Scalar::Aos::Transform3 PfxTransform3; + typedef sce::Vectormath::Scalar::floatInVec PfxFloatInVec; + typedef sce::Vectormath::Scalar::boolInVec PfxBoolInVec; + } //namespace PhysicsEffects + } //namespace sce + + #ifdef SCE_PFX_USE_GEOMETRY + #include + namespace sce { + namespace PhysicsEffects { + typedef sce::Geometry::Aos::Line PfxGeomLine; + typedef sce::Geometry::Aos::Segment PfxGeomSegment; + typedef sce::Geometry::Aos::Plane PfxGeomPlane; + typedef sce::Geometry::Aos::Sphere PfxGeomSphere; + typedef sce::Geometry::Aos::Capsule PfxGeomCapsule; + typedef sce::Geometry::Aos::Bounds PfxGeomBounds; + typedef sce::Geometry::Aos::Aabb PfxGeomAabb; + typedef sce::Geometry::Aos::Obb PfxGeomObb; + } //namespace PhysicsEffects + } //namespace sce + #endif +#endif + +#endif // _SCE_PFX_VECTORMATH_INCLUDE_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_vectormath_include.win32.h b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_vectormath_include.win32.h new file mode 100644 index 000000000..4d5673a82 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/base/pfx_vectormath_include.win32.h @@ -0,0 +1,116 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_VECTORMATH_INCLUDE_WIN32_H +#define _SCE_PFX_VECTORMATH_INCLUDE_WIN32_H + +// If you want to use the free/open sourced vectormath, you need to +// put codes in the include/vecmath folder and set following define. +#define SCE_PFX_USE_FREE_VECTORMATH + +// If you want to use vectomath with SIMD, +// following define is needed. +// #define SCE_PFX_USE_SIMD_VECTORMATH + +// This option enables to replace original implementation with +// vector geometry library. +//#define SCE_PFX_USE_GEOMETRY + +// vectormath include +#ifdef SCE_PFX_USE_FREE_VECTORMATH + #ifdef SCE_PFX_USE_SIMD_VECTORMATH + #include "../../../vecmath/sse/vectormath_aos.h" + #include "../../../vecmath/sse/floatInVec.h" + #define SCE_VECTORMATH_AOS_VECTOR_ARG & + #define SCE_VECTORMATH_AOS_MATRIX_ARG & + #else + #include "../../../vecmath/std/vectormath_aos.h" + #include "../../../vecmath/std/floatInVec.h" + #define SCE_VECTORMATH_AOS_VECTOR_ARG + #define SCE_VECTORMATH_AOS_MATRIX_ARG + #endif + + namespace sce { + namespace PhysicsEffects { + typedef Vectormath::Aos::Point3 PfxPoint3; + typedef Vectormath::Aos::Vector3 PfxVector3; + typedef Vectormath::Aos::Vector4 PfxVector4; + typedef Vectormath::Aos::Quat PfxQuat; + typedef Vectormath::Aos::Matrix3 PfxMatrix3; + typedef Vectormath::Aos::Matrix4 PfxMatrix4; + typedef Vectormath::Aos::Transform3 PfxTransform3; + typedef Vectormath::floatInVec PfxFloatInVec; + typedef Vectormath::boolInVec PfxBoolInVec; + } //namespace PhysicsEffects + } //namespace sce +#else + #include + + #ifdef SCE_PFX_USE_SIMD_VECTORMATH + #define SCE_VECTORMATH_AOS_VECTOR_ARG SCE_VECTORMATH_SIMD_AOS_VECTOR_ARG + #define SCE_VECTORMATH_AOS_MATRIX_ARG SCE_VECTORMATH_SIMD_AOS_MATRIX_ARG + + namespace sce { + namespace PhysicsEffects { + typedef sce::Vectormath::Simd::Aos::Point3 PfxPoint3; + typedef sce::Vectormath::Simd::Aos::Vector3 PfxVector3; + typedef sce::Vectormath::Simd::Aos::Vector4 PfxVector4; + typedef sce::Vectormath::Simd::Aos::Quat PfxQuat; + typedef sce::Vectormath::Simd::Aos::Matrix3 PfxMatrix3; + typedef sce::Vectormath::Simd::Aos::Matrix4 PfxMatrix4; + typedef sce::Vectormath::Simd::Aos::Transform3 PfxTransform3; + typedef sce::Vectormath::Simd::floatInVec PfxFloatInVec; + typedef sce::Vectormath::Simd::boolInVec PfxBoolInVec; + } //namespace PhysicsEffects + } //namespace sce + #else + #define SCE_GEOMETRY_USE_SCALAR_MATH + #define SCE_VECTORMATH_AOS_VECTOR_ARG SCE_VECTORMATH_SCALAR_AOS_VECTOR_ARG + #define SCE_VECTORMATH_AOS_MATRIX_ARG SCE_VECTORMATH_SCALAR_AOS_MATRIX_ARG + + namespace sce { + namespace PhysicsEffects { + typedef sce::Vectormath::Scalar::Aos::Point3 PfxPoint3; + typedef sce::Vectormath::Scalar::Aos::Vector3 PfxVector3; + typedef sce::Vectormath::Scalar::Aos::Vector4 PfxVector4; + typedef sce::Vectormath::Scalar::Aos::Quat PfxQuat; + typedef sce::Vectormath::Scalar::Aos::Matrix3 PfxMatrix3; + typedef sce::Vectormath::Scalar::Aos::Matrix4 PfxMatrix4; + typedef sce::Vectormath::Scalar::Aos::Transform3 PfxTransform3; + typedef sce::Vectormath::Scalar::floatInVec PfxFloatInVec; + typedef sce::Vectormath::Scalar::boolInVec PfxBoolInVec; + } //namespace PhysicsEffects + } //namespace sce + #endif +#endif + +#ifdef SCE_PFX_USE_GEOMETRY +#include +namespace sce { +namespace PhysicsEffects { +typedef sce::Geometry::Aos::Line PfxGeomLine; +typedef sce::Geometry::Aos::Segment PfxGeomSegment; +typedef sce::Geometry::Aos::Plane PfxGeomPlane; +typedef sce::Geometry::Aos::Sphere PfxGeomSphere; +typedef sce::Geometry::Aos::Capsule PfxGeomCapsule; +typedef sce::Geometry::Aos::Bounds PfxGeomBounds; +typedef sce::Geometry::Aos::Aabb PfxGeomAabb; +typedef sce::Geometry::Aos::Obb PfxGeomObb; +} //namespace PhysicsEffects +} //namespace sce +#endif + +#endif // _SCE_PFX_VECTORMATH_INCLUDE_WIN32_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/broadphase/pfx_broadphase_pair.h b/Extras/PhysicsEffects/include/physics_effects/base_level/broadphase/pfx_broadphase_pair.h new file mode 100644 index 000000000..5fe10d945 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/broadphase/pfx_broadphase_pair.h @@ -0,0 +1,46 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_BROADPHASE_PAIR_H +#define _SCE_PFX_BROADPHASE_PAIR_H + +#include "../sort/pfx_sort_data.h" + +namespace sce { +namespace PhysicsEffects { + +typedef PfxSortData16 PfxBroadphasePair; + +SCE_PFX_FORCE_INLINE void pfxSetObjectIdA(PfxBroadphasePair &pair,PfxUInt16 i) {pair.set16(0,i);} +SCE_PFX_FORCE_INLINE void pfxSetObjectIdB(PfxBroadphasePair &pair,PfxUInt16 i) {pair.set16(1,i);} +SCE_PFX_FORCE_INLINE void pfxSetMotionMaskA(PfxBroadphasePair &pair,PfxUInt8 i) {pair.set8(4,i);} +SCE_PFX_FORCE_INLINE void pfxSetMotionMaskB(PfxBroadphasePair &pair,PfxUInt8 i) {pair.set8(5,i);} +SCE_PFX_FORCE_INLINE void pfxSetBroadphaseFlag(PfxBroadphasePair &pair,PfxUInt8 f) {pair.set8(6,(pair.get8(6)&0xf0)|(f&0x0f));} +SCE_PFX_FORCE_INLINE void pfxSetActive(PfxBroadphasePair &pair,PfxBool b) {pair.set8(6,(pair.get8(6)&0x0f)|((b?1:0)<<4));} +SCE_PFX_FORCE_INLINE void pfxSetContactId(PfxBroadphasePair &pair,PfxUInt32 i) {pair.set32(2,i);} + +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetObjectIdA(const PfxBroadphasePair &pair) {return pair.get16(0);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetObjectIdB(const PfxBroadphasePair &pair) {return pair.get16(1);} +SCE_PFX_FORCE_INLINE PfxUInt8 pfxGetMotionMaskA(const PfxBroadphasePair &pair) {return pair.get8(4);} +SCE_PFX_FORCE_INLINE PfxUInt8 pfxGetMotionMaskB(const PfxBroadphasePair &pair) {return pair.get8(5);} +SCE_PFX_FORCE_INLINE PfxUInt8 pfxGetBroadphaseFlag(const PfxBroadphasePair &pair) {return pair.get8(6)&0x0f;} +SCE_PFX_FORCE_INLINE PfxBool pfxGetActive(const PfxBroadphasePair &pair) {return (pair.get8(6)>>4)!=0;} +SCE_PFX_FORCE_INLINE PfxUInt32 pfxGetContactId(const PfxBroadphasePair &pair) {return pair.get32(2);} + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_BROADPHASE_PAIR_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/broadphase/pfx_broadphase_proxy.h b/Extras/PhysicsEffects/include/physics_effects/base_level/broadphase/pfx_broadphase_proxy.h new file mode 100644 index 000000000..a0b062957 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/broadphase/pfx_broadphase_proxy.h @@ -0,0 +1,42 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_BROADPHASE_PROXY_H +#define _SCE_PFX_BROADPHASE_PROXY_H + +namespace sce { +namespace PhysicsEffects { + +typedef PfxSortData32 PfxBroadphaseProxy; + +//J AABBパラメータはPfxAabbと共通 +//E PfxBroadphaseProxy shares AABB parameters with PfxAabb32 + +SCE_PFX_FORCE_INLINE void pfxSetObjectId(PfxBroadphaseProxy &proxy,PfxUInt16 i) {proxy.set16(6,i);} +SCE_PFX_FORCE_INLINE void pfxSetMotionMask(PfxBroadphaseProxy &proxy,PfxUInt8 i) {proxy.set8(14,i);} +SCE_PFX_FORCE_INLINE void pfxSetProxyFlag(PfxBroadphaseProxy &proxy,PfxUInt8 i) {proxy.set8(15,i);} +SCE_PFX_FORCE_INLINE void pfxSetSelf(PfxBroadphaseProxy &proxy,PfxUInt32 i) {proxy.set32(5,i);} +SCE_PFX_FORCE_INLINE void pfxSetTarget(PfxBroadphaseProxy &proxy,PfxUInt32 i) {proxy.set32(6,i);} + +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetObjectId(const PfxBroadphaseProxy &proxy) {return proxy.get16(6);} +SCE_PFX_FORCE_INLINE PfxUInt8 pfxGetMotionMask(const PfxBroadphaseProxy &proxy) {return proxy.get8(14);} +SCE_PFX_FORCE_INLINE PfxUInt8 pfxGetProxyFlag(const PfxBroadphaseProxy &proxy) {return proxy.get8(15);} +SCE_PFX_FORCE_INLINE PfxUInt32 pfxGetSelf(const PfxBroadphaseProxy &proxy) {return proxy.get32(5);} +SCE_PFX_FORCE_INLINE PfxUInt32 pfxGetTarget(const PfxBroadphaseProxy &proxy) {return proxy.get32(6);} + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_BROADPHASE_PROXY_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/broadphase/pfx_update_broadphase_proxy.h b/Extras/PhysicsEffects/include/physics_effects/base_level/broadphase/pfx_update_broadphase_proxy.h new file mode 100644 index 000000000..941d595cc --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/broadphase/pfx_update_broadphase_proxy.h @@ -0,0 +1,80 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_UPDATE_BROADPHASE_PROXY_H +#define _SCE_PFX_UPDATE_BROADPHASE_PROXY_H + +#include "pfx_broadphase_pair.h" +#include "pfx_broadphase_proxy.h" +#include "../rigidbody/pfx_rigid_state.h" +#include "../collision/pfx_collidable.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// Update Broadphase Proxy + +//E For single axis +//J 単一軸に対して作成 +PfxInt32 pfxUpdateBroadphaseProxy( + PfxBroadphaseProxy &proxy, + const PfxRigidState &state, + const PfxCollidable &coll, + const PfxVector3 &worldCenter, + const PfxVector3 &worldExtent, + PfxUInt32 axis); + +PfxInt32 pfxUpdateBroadphaseProxy( + PfxBroadphaseProxy &proxy, + const PfxRigidState &state, + const PfxVector3 &objectCenter, + const PfxVector3 &objectHalf, + const PfxVector3 &worldCenter, + const PfxVector3 &worldExtent, + PfxUInt32 axis); + +//E For all axes +//J 全軸に対して作成 +PfxInt32 pfxUpdateBroadphaseProxy( + PfxBroadphaseProxy &proxyX, + PfxBroadphaseProxy &proxyY, + PfxBroadphaseProxy &proxyZ, + PfxBroadphaseProxy &proxyXb, + PfxBroadphaseProxy &proxyYb, + PfxBroadphaseProxy &proxyZb, + const PfxRigidState &state, + const PfxCollidable &coll, + const PfxVector3 &worldCenter, + const PfxVector3 &worldExtent); + +PfxInt32 pfxUpdateBroadphaseProxy( + PfxBroadphaseProxy &proxyX, + PfxBroadphaseProxy &proxyY, + PfxBroadphaseProxy &proxyZ, + PfxBroadphaseProxy &proxyXb, + PfxBroadphaseProxy &proxyYb, + PfxBroadphaseProxy &proxyZb, + const PfxRigidState &state, + const PfxVector3 &objectCenter, + const PfxVector3 &objectHalf, + const PfxVector3 &worldCenter, + const PfxVector3 &worldExtent); + +} // namespace PhysicsEffects +} // namespace sce + +#endif // _SCE_PFX_UPDATE_BROADPHASE_PROXY_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_aabb.h b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_aabb.h new file mode 100644 index 000000000..dc238eb7e --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_aabb.h @@ -0,0 +1,124 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_AABB_H +#define _SCE_PFX_AABB_H + +#include "../sort/pfx_sort_data.h" + +namespace sce { +namespace PhysicsEffects { + +typedef PfxSortData16 PfxAabb16; +typedef PfxSortData32 PfxAabb32; + +SCE_PFX_FORCE_INLINE void pfxSetXMin(PfxAabb16& aabb,PfxUInt16 i) {aabb.set16(0,i);} +SCE_PFX_FORCE_INLINE void pfxSetXMax(PfxAabb16& aabb,PfxUInt16 i) {aabb.set16(1,i);} +SCE_PFX_FORCE_INLINE void pfxSetYMin(PfxAabb16& aabb,PfxUInt16 i) {aabb.set16(2,i);} +SCE_PFX_FORCE_INLINE void pfxSetYMax(PfxAabb16& aabb,PfxUInt16 i) {aabb.set16(3,i);} +SCE_PFX_FORCE_INLINE void pfxSetZMin(PfxAabb16& aabb,PfxUInt16 i) {aabb.set16(4,i);} +SCE_PFX_FORCE_INLINE void pfxSetZMax(PfxAabb16& aabb,PfxUInt16 i) {aabb.set16(5,i);} +SCE_PFX_FORCE_INLINE void pfxSetXYZMin(PfxAabb16 &aabb,PfxUInt16 i,int axis) {aabb.set16(axis<<1,i);} +SCE_PFX_FORCE_INLINE void pfxSetXYZMax(PfxAabb16 &aabb,PfxUInt16 i,int axis) {aabb.set16((axis<<1)+1,i);} + +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetXMin(const PfxAabb16& aabb) {return aabb.get16(0);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetXMax(const PfxAabb16& aabb) {return aabb.get16(1);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetYMin(const PfxAabb16& aabb) {return aabb.get16(2);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetYMax(const PfxAabb16& aabb) {return aabb.get16(3);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetZMin(const PfxAabb16& aabb) {return aabb.get16(4);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetZMax(const PfxAabb16& aabb) {return aabb.get16(5);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetXYZMin(const PfxAabb16 &aabb,int axis) {return aabb.get16(axis<<1);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetXYZMax(const PfxAabb16 &aabb,int axis) {return aabb.get16((axis<<1)+1);} + +SCE_PFX_FORCE_INLINE void pfxSetXMin(PfxAabb32& aabb,PfxUInt16 i) {aabb.set16(0,i);} +SCE_PFX_FORCE_INLINE void pfxSetXMax(PfxAabb32& aabb,PfxUInt16 i) {aabb.set16(1,i);} +SCE_PFX_FORCE_INLINE void pfxSetYMin(PfxAabb32& aabb,PfxUInt16 i) {aabb.set16(2,i);} +SCE_PFX_FORCE_INLINE void pfxSetYMax(PfxAabb32& aabb,PfxUInt16 i) {aabb.set16(3,i);} +SCE_PFX_FORCE_INLINE void pfxSetZMin(PfxAabb32& aabb,PfxUInt16 i) {aabb.set16(4,i);} +SCE_PFX_FORCE_INLINE void pfxSetZMax(PfxAabb32& aabb,PfxUInt16 i) {aabb.set16(5,i);} +SCE_PFX_FORCE_INLINE void pfxSetXYZMin(PfxAabb32 &aabb,PfxUInt16 i,int axis) {aabb.set16(axis<<1,i);} +SCE_PFX_FORCE_INLINE void pfxSetXYZMax(PfxAabb32 &aabb,PfxUInt16 i,int axis) {aabb.set16((axis<<1)+1,i);} + +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetXMin(const PfxAabb32& aabb) {return aabb.get16(0);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetXMax(const PfxAabb32& aabb) {return aabb.get16(1);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetYMin(const PfxAabb32& aabb) {return aabb.get16(2);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetYMax(const PfxAabb32& aabb) {return aabb.get16(3);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetZMin(const PfxAabb32& aabb) {return aabb.get16(4);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetZMax(const PfxAabb32& aabb) {return aabb.get16(5);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetXYZMin(const PfxAabb32 &aabb,int axis) {return aabb.get16(axis<<1);} +SCE_PFX_FORCE_INLINE PfxUInt16 pfxGetXYZMax(const PfxAabb32 &aabb,int axis) {return aabb.get16((axis<<1)+1);} + + +#define SCE_PFX_TEST_AABB(aabbA,aabbB) \ +if(pfxGetXMax(aabbA) < pfxGetXMin(aabbB) || pfxGetXMin(aabbA) > pfxGetXMax(aabbB)) return false;\ +if(pfxGetYMax(aabbA) < pfxGetYMin(aabbB) || pfxGetYMin(aabbA) > pfxGetYMax(aabbB)) return false;\ +if(pfxGetZMax(aabbA) < pfxGetZMin(aabbB) || pfxGetZMin(aabbA) > pfxGetZMax(aabbB)) return false;\ +return true; + +SCE_PFX_FORCE_INLINE +bool pfxTestAabb(const PfxAabb16 &aabbA,const PfxAabb16 &aabbB) +{ +SCE_PFX_TEST_AABB(aabbA,aabbB) +} + +SCE_PFX_FORCE_INLINE +bool pfxTestAabb(const PfxAabb32 &aabbA,const PfxAabb32 &aabbB) +{ +SCE_PFX_TEST_AABB(aabbA,aabbB) +} + +SCE_PFX_FORCE_INLINE +bool pfxTestAabb(const PfxAabb32 &aabbA,const PfxAabb16 &aabbB) +{ +SCE_PFX_TEST_AABB(aabbA,aabbB) +} + +SCE_PFX_FORCE_INLINE +bool pfxTestAabb(const PfxAabb16 &aabbA,const PfxAabb32 &aabbB) +{ +SCE_PFX_TEST_AABB(aabbA,aabbB) +} + + +SCE_PFX_FORCE_INLINE +PfxAabb16 pfxMergeAabb(const PfxAabb16 &aabbA,const PfxAabb16 &aabbB) +{ + PfxAabb16 aabb = aabbA; + pfxSetXMin(aabb,SCE_PFX_MIN(pfxGetXMin(aabbA),pfxGetXMin(aabbB))); + pfxSetXMax(aabb,SCE_PFX_MAX(pfxGetXMax(aabbA),pfxGetXMax(aabbB))); + pfxSetYMin(aabb,SCE_PFX_MIN(pfxGetYMin(aabbA),pfxGetYMin(aabbB))); + pfxSetYMax(aabb,SCE_PFX_MAX(pfxGetYMax(aabbA),pfxGetYMax(aabbB))); + pfxSetZMin(aabb,SCE_PFX_MIN(pfxGetZMin(aabbA),pfxGetZMin(aabbB))); + pfxSetZMax(aabb,SCE_PFX_MAX(pfxGetZMax(aabbA),pfxGetZMax(aabbB))); + return aabb; +} + +SCE_PFX_FORCE_INLINE +PfxAabb32 pfxMergeAabb(const PfxAabb32 &aabbA,const PfxAabb32 &aabbB) +{ + PfxAabb32 aabb = aabbA; + pfxSetXMin(aabb,SCE_PFX_MIN(pfxGetXMin(aabbA),pfxGetXMin(aabbB))); + pfxSetXMax(aabb,SCE_PFX_MAX(pfxGetXMax(aabbA),pfxGetXMax(aabbB))); + pfxSetYMin(aabb,SCE_PFX_MIN(pfxGetYMin(aabbA),pfxGetYMin(aabbB))); + pfxSetYMax(aabb,SCE_PFX_MAX(pfxGetYMax(aabbA),pfxGetYMax(aabbB))); + pfxSetZMin(aabb,SCE_PFX_MIN(pfxGetZMin(aabbA),pfxGetZMin(aabbB))); + pfxSetZMax(aabb,SCE_PFX_MAX(pfxGetZMax(aabbA),pfxGetZMax(aabbB))); + return aabb; +} +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_AABB_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_box.h b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_box.h new file mode 100644 index 000000000..4de797686 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_box.h @@ -0,0 +1,61 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_BOX_H +#define _SCE_PFX_BOX_H + +#include "../base/pfx_common.h" + +namespace sce{ +namespace PhysicsEffects{ +struct PfxBox { + PfxVector3 m_half; + + inline PfxBox() {} + inline PfxBox(const PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG half); + inline PfxBox(PfxFloat hx, PfxFloat hy, PfxFloat hz); + + inline void set(const PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG half); + inline void set(PfxFloat hx, PfxFloat hy, PfxFloat hz); +}; + +inline +PfxBox::PfxBox(const PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG half) +{ + set(half); +} + +inline +PfxBox::PfxBox(PfxFloat hx, PfxFloat hy, PfxFloat hz) +{ + set(hx, hy, hz); +} + +inline +void PfxBox::set(const PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG half) +{ + m_half = half; +} + +inline +void PfxBox::set(PfxFloat hx, PfxFloat hy, PfxFloat hz) +{ + m_half = PfxVector3(hx, hy, hz); +} +} // namespace PhysicsEffects +} // namespace sce + +#endif // _SCE_PFX_BOX_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_capsule.h b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_capsule.h new file mode 100644 index 000000000..a1c1af574 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_capsule.h @@ -0,0 +1,53 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CAPSULE_H +#define _SCE_PFX_CAPSULE_H + +#include "../base/pfx_common.h" + +namespace sce { +namespace PhysicsEffects { + +struct PfxCapsule +{ + PfxFloat m_halfLen; + PfxFloat m_radius; + + PfxCapsule() {} + PfxCapsule(PfxFloat halfLength, PfxFloat radius); + + void set(PfxFloat halfLength, PfxFloat radius); +}; + +inline +PfxCapsule::PfxCapsule(PfxFloat halfLength, PfxFloat radius) +{ + m_halfLen = halfLength; + m_radius = radius; +} + +inline +void PfxCapsule::set(PfxFloat halfLength, PfxFloat radius) +{ + m_halfLen = halfLength; + m_radius = radius; +} + +} // namespace PhysicsEffects +} // namespace sce + +#endif // _SCE_PFX_CAPSULE_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_collidable.h b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_collidable.h new file mode 100644 index 000000000..7f65eeb32 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_collidable.h @@ -0,0 +1,74 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_COLLIDABLE_H +#define _SCE_PFX_COLLIDABLE_H + +#include "pfx_shape.h" + +namespace sce { +namespace PhysicsEffects { + +#define SCE_PFX_NUMPRIMS 64 + +/////////////////////////////////////////////////////////////////////////////// +// Collidable Object + +class SCE_PFX_ALIGNED(128) PfxCollidable +{ +friend class PfxShapeIterator; + +private: + PfxShape *m_shapeBase; + PfxUInt16 m_shapeIds[SCE_PFX_NUMPRIMS]; + PfxUInt8 m_numShapes; + PfxUInt8 m_maxShapes; + SCE_PFX_PADDING(1,2) + PfxFloat m_center[3]; // AABB center (Local) + PfxFloat m_half[3]; // AABB half (Local) + PfxShape m_defShape; + SCE_PFX_PADDING(2,32) + + inline PfxShape &getNewShape(); + +public: + inline void reset(); + inline void reset(PfxShape *base,PfxUInt16 *ids,int n=1); + + void finish(); + + void addShape(const PfxShape &shape); + + inline PfxUInt32 getNumShapes() const; + const PfxShape& getDefShape() const {return m_defShape;} + PfxShape& getDefShape() {return m_defShape;} + + inline PfxUInt16 getShapeId(int i) const; + + inline const PfxShape& getShape(int i) const; + inline PfxShape& getShape(int i); + + inline PfxVector3 getHalf() const; + inline PfxVector3 getCenter() const; +}; + +#include "pfx_collidable_implementation.h" + +} // namespace PhysicsEffects +} // namespace sce + +#endif // _SCE_PFX_COLLIDABLE_H + diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_collidable_implementation.h b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_collidable_implementation.h new file mode 100644 index 000000000..0e434f6dd --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_collidable_implementation.h @@ -0,0 +1,114 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_COLLIDABLE_IMPLEMENTATION_H +#define _SCE_PFX_COLLIDABLE_IMPLEMENTATION_H + +inline +void PfxCollidable::reset() +{ + m_shapeBase = NULL; + m_numShapes = 0; + m_maxShapes = 1; + m_center[0] = 0.0f; + m_center[1] = 0.0f; + m_center[2] = 0.0f; + m_half[0] = 0.0f; + m_half[1] = 0.0f; + m_half[2] = 0.0f; +} + +inline +void PfxCollidable::reset(PfxShape *base,PfxUInt16 *ids,int n) +{ + m_shapeBase = base; + m_numShapes = 0; + m_maxShapes = n; + for(int i=0;i0); + return m_shapeIds[i-1]; +} + +inline +const PfxShape& PfxCollidable::getShape(int i) const +{ + SCE_PFX_ASSERT(i0) { + return m_shapeBase[m_shapeIds[i-1]]; + } + else { + return m_defShape; + } +} + +inline +PfxShape& PfxCollidable::getShape(int i) +{ + SCE_PFX_ASSERT(i0) { + return m_shapeBase[m_shapeIds[i-1]]; + } + else { + return m_defShape; + } +} + +inline +PfxShape &PfxCollidable::getNewShape() +{ + SCE_PFX_ASSERT(m_numShapes<=m_maxShapes); + if(m_numShapes == 0) { + m_numShapes++; + return m_defShape; + } + else { + m_numShapes++; + return m_shapeBase[m_shapeIds[m_numShapes-2]]; + } +} + +inline +PfxVector3 PfxCollidable::getHalf() const +{ + return pfxReadVector3(m_half); +} + +inline +PfxVector3 PfxCollidable::getCenter() const +{ + return pfxReadVector3(m_center); +} + +#endif // _SCE_PFX_COLLIDABLE_IMPLEMENTATION_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_contact_manifold.h b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_contact_manifold.h new file mode 100644 index 000000000..f257974a4 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_contact_manifold.h @@ -0,0 +1,135 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_MANIFOLD_H +#define _SCE_PFX_CONTACT_MANIFOLD_H + +#include "../base/pfx_common.h" +#include "../base/pfx_vec_utils.h" +#include "pfx_sub_data.h" +#include "../solver/pfx_constraint_row.h" + +namespace sce { +namespace PhysicsEffects { + +#define SCE_PFX_NUMCONTACTS_PER_BODIES 4 + +/////////////////////////////////////////////////////////////////////////////// +// Contact Point + +struct PfxContactPoint +{ + PfxUInt8 m_duration; + PfxUInt8 m_shapeIdA; + PfxUInt8 m_shapeIdB; + SCE_PFX_PADDING(1,1) + PfxSubData m_subData; + PfxFloat m_distance; + PfxFloat m_localPointA[3]; + PfxFloat m_localPointB[3]; + SCE_PFX_PADDING(2,8) + PfxConstraintRow m_constraintRow[3]; + + void reset() + { + m_duration = 0; + m_shapeIdA = m_shapeIdB = 0; + m_subData = PfxSubData(); + m_distance = SCE_PFX_FLT_MAX; + m_constraintRow[0].m_accumImpulse = 0.0f; + m_constraintRow[1].m_accumImpulse = 0.0f; + m_constraintRow[2].m_accumImpulse = 0.0f; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// Contact Manifold + +//J 同一ペアの衝突が続く限り保持されるコンタクト情報 +//E PfxContactManifold keeps contact information until two rigid bodies are separated. + +class SCE_PFX_ALIGNED(128) PfxContactManifold +{ +private: + PfxUInt16 m_rigidBodyIdA,m_rigidBodyIdB; + PfxUInt16 m_duration; + PfxUInt16 m_numContacts; + PfxFloat m_compositeFriction; + PfxUInt32 m_internalFlag; + PfxContactPoint m_contactPoints[SCE_PFX_NUMCONTACTS_PER_BODIES]; + void *m_userData; + PfxUInt32 m_userParam[4]; + SCE_PFX_PADDING(1,28) + + int findNearestContactPoint(const PfxPoint3 &newPoint,const PfxVector3 &newNormal); + int sort4ContactPoints(const PfxPoint3 &newPoint,PfxFloat newDistance); + +public: + // Internal method + PfxFloat getCompositeFriction() const {return m_compositeFriction;} + void setCompositeFriction(PfxFloat f) {m_compositeFriction = f;} + + PfxUInt32 getInternalFlag() const {return m_internalFlag;} + void setInternalFlag(PfxUInt32 f) {m_internalFlag = f;} + +public: + void reset(PfxUInt16 rigidBodyIdA,PfxUInt16 rigidBodyIdB) + { + m_userData = 0; + m_userParam[0] = m_userParam[1] = m_userParam[2] = m_userParam[3] = 0; + m_numContacts = 0; + m_duration = 0; + m_rigidBodyIdA = rigidBodyIdA; + m_rigidBodyIdB = rigidBodyIdB; + } + + void addContactPoint( + PfxFloat newDistance, + const PfxVector3 &newNormal, // world coords + const PfxPoint3 &newPointA, // local coords to the objectA + const PfxPoint3 &newPointB, // local coords to the objectB + PfxSubData subData); + + void addContactPoint(const PfxContactPoint &cp); + + void removeContactPoint(int i) + { + SCE_PFX_ASSERT(i>=0&&i pfxGetXMax(m_aabbList[islandId])) return false; + if(aabbMaxL.getY() < pfxGetYMin(m_aabbList[islandId]) || aabbMinL.getY() > pfxGetYMax(m_aabbList[islandId])) return false; + if(aabbMaxL.getZ() < pfxGetZMin(m_aabbList[islandId]) || aabbMinL.getZ() > pfxGetZMax(m_aabbList[islandId])) return false; + + return true; +} + +inline +PfxVecInt3 PfxLargeTriMesh::getLocalPosition(const PfxVector3 &worldPosition) const +{ + const PfxVector3 sz(65535.0f); + PfxVector3 tmp = divPerElem(worldPosition+m_half,2.0f*m_half); + tmp = mulPerElem(sz,minPerElem(maxPerElem(tmp,PfxVector3(0.0f)),PfxVector3(1.0f))); // clamp 0.0 - 1.0 + return PfxVecInt3(tmp); +} + +inline +void PfxLargeTriMesh::getLocalPosition( + const PfxVector3 &worldMinPosition,const PfxVector3 &worldMaxPosition, + PfxVecInt3 &localMinPosition,PfxVecInt3 &localMaxPosition) const +{ + const PfxVector3 sz(65535.0f); + PfxVector3 qmin = divPerElem(worldMinPosition+m_half,2.0f*m_half); + qmin = mulPerElem(sz,minPerElem(maxPerElem(qmin,PfxVector3(0.0f)),PfxVector3(1.0f))); // clamp 0.0 - 1.0 + + PfxVector3 qmax = divPerElem(worldMaxPosition+m_half,2.0f*m_half); + qmax = mulPerElem(sz,minPerElem(maxPerElem(qmax,PfxVector3(0.0f)),PfxVector3(1.0f))); // clamp 0.0 - 1.0 + +localMinPosition = PfxVecInt3(floorf(qmin[0]),floorf(qmin[1]),floorf(qmin[2])); +localMaxPosition = PfxVecInt3(ceilf(qmax[0]),ceilf(qmax[1]),ceilf(qmax[2])); +} + +inline +PfxVector3 PfxLargeTriMesh::getWorldPosition(const PfxVecInt3 &localPosition) const +{ + PfxVector3 sz(65535.0f),lp(localPosition); + PfxVector3 tmp = divPerElem(lp,sz); + return mulPerElem(tmp,2.0f*m_half) - m_half; +} + +} // namespace PhysicsEffects +} // namespace sce + +#endif // _SCE_PFX_LARGE_TRI_MESH_H \ No newline at end of file diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_ray.h b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_ray.h new file mode 100644 index 000000000..92fc3f258 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_ray.h @@ -0,0 +1,59 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_RAY_H +#define _SCE_PFX_RAY_H + +#include "../base/pfx_common.h" +#include "pfx_sub_data.h" + +namespace sce { +namespace PhysicsEffects { + +#define SCE_PFX_RAY_FACET_MODE_FRONT_ONLY 0 +#define SCE_PFX_RAY_FACET_MODE_BACK_ONLY 1 +#define SCE_PFX_RAY_FACET_MODE_FRONT_AND_BACK 2 + +struct SCE_PFX_ALIGNED(16) PfxRayInput +{ + PfxVector3 m_startPosition; + PfxVector3 m_direction; + PfxUInt32 m_contactFilterSelf; + PfxUInt32 m_contactFilterTarget; + PfxUInt8 m_facetMode; + SCE_PFX_PADDING(1,7) + + void reset() + { + m_contactFilterSelf = m_contactFilterTarget = 0xffffffff; + m_facetMode = SCE_PFX_RAY_FACET_MODE_FRONT_ONLY; + } +}; + +struct SCE_PFX_ALIGNED(16) PfxRayOutput +{ + PfxVector3 m_contactPoint; + PfxVector3 m_contactNormal; + PfxFloat m_variable; + PfxUInt16 m_objectId; + PfxUInt8 m_shapeId; + PfxBool m_contactFlag : 1; + PfxSubData m_subData; +}; +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_RAY_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_shape.h b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_shape.h new file mode 100644 index 000000000..b4f9c2a0d --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_shape.h @@ -0,0 +1,118 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_SHAPE_H +#define _SCE_PFX_SHAPE_H + +#include "../base/pfx_common.h" +#include "../base/pfx_vec_utils.h" +#include "pfx_box.h" +#include "pfx_sphere.h" +#include "pfx_capsule.h" +#include "pfx_cylinder.h" +#include "pfx_tri_mesh.h" +#include "pfx_large_tri_mesh.h" + +namespace sce { +namespace PhysicsEffects { + +enum ePfxShapeType +{ + kPfxShapeSphere = 0, + kPfxShapeBox, + kPfxShapeCapsule, + kPfxShapeCylinder, + kPfxShapeConvexMesh, + kPfxShapeLargeTriMesh, + kPfxShapeReserved0, + kPfxShapeReserved1, + kPfxShapeReserved2, + kPfxShapeUser0, + kPfxShapeUser1, + kPfxShapeUser2, + kPfxShapeCount // =12 +}; + +class SCE_PFX_ALIGNED(16) PfxShape +{ +friend class PfxCollidable; + +private: + union { + PfxFloat m_vecDataF[3]; + PfxUInt32 m_vecDataI[3]; + void *m_vecDataPtr[2]; + }; + PfxUInt8 m_type; + SCE_PFX_PADDING(1,3) + PfxFloat m_offsetPosition[3]; + PfxFloat m_offsetOrientation[4]; + PfxUInt32 m_contactFilterSelf; + PfxUInt32 m_contactFilterTarget; + SCE_PFX_PADDING(2,12) + +public: + inline void reset(); + + // Shape + inline void setBox(PfxBox SCE_VECTORMATH_AOS_VECTOR_ARG box); + inline void setCapsule(PfxCapsule capsule); + inline void setCylinder(PfxCylinder cylinder); + inline void setSphere(PfxSphere sphere); + inline void setConvexMesh(const PfxConvexMesh *convexMesh); + inline void setLargeTriMesh(const PfxLargeTriMesh *largeMesh); + + inline PfxUInt8 getType() const; + inline PfxBox getBox()const ; + inline PfxCapsule getCapsule() const; + inline PfxCylinder getCylinder() const; + inline PfxSphere getSphere() const; + inline const PfxConvexMesh* getConvexMesh() const; + inline const PfxLargeTriMesh* getLargeTriMesh() const; + + // Offset + inline void setOffsetTransform(const PfxTransform3 & xfrm); + inline void setOffsetOrientation(const PfxQuat SCE_VECTORMATH_AOS_VECTOR_ARG rot) {return pfxStoreQuat(rot,m_offsetOrientation);} + inline void setOffsetPosition(const PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG pos) {return pfxStoreVector3(pos,m_offsetPosition);} + + inline PfxTransform3 getOffsetTransform() const; + inline PfxVector3 getOffsetPosition() const {return pfxReadVector3(m_offsetPosition);} + inline PfxQuat getOffsetOrientation() const {return pfxReadQuat(m_offsetOrientation);} + + // Raw data access + inline void setDataFloat(int i,PfxFloat v) {m_vecDataF[i]=v;} + inline void setDataInteger(int i,PfxUInt32 v) {m_vecDataI[i]=v;} + + inline PfxFloat getDataFloat(int i) const {return m_vecDataF[i];} + inline PfxUInt32 getDataInteger(int i) const {return m_vecDataI[i];} + + // Contact Filter + PfxUInt32 getContactFilterSelf() const {return m_contactFilterSelf;} + void setContactFilterSelf(PfxUInt32 filter) {m_contactFilterSelf = filter;} + + PfxUInt32 getContactFilterTarget() const {return m_contactFilterTarget;} + void setContactFilterTarget(PfxUInt32 filter) {m_contactFilterTarget = filter;} + + // Bouding Volume + void getAabb(PfxVector3 &aabbMin,PfxVector3 &aabbMax) const; +}; + +#include "pfx_shape_implementation.h" + +} // namespace PhysicsEffects +} // namespace sce + +#endif // _SCE_PFX_SHAPE_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_shape_implementation.h b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_shape_implementation.h new file mode 100644 index 000000000..8996141c3 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_shape_implementation.h @@ -0,0 +1,145 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_SHAPE_IMPLEMENTATION_H +#define _SCE_PFX_SHAPE_IMPLEMENTATION_H + +inline +void PfxShape::reset() +{ + m_type = kPfxShapeSphere; + m_offsetPosition[0] = m_offsetPosition[1] = m_offsetPosition[2]= 0.0f; + m_offsetOrientation[0] = m_offsetOrientation[1] = m_offsetOrientation[2]= 0.0f; + m_offsetOrientation[3] = 1.0f; + m_contactFilterSelf = m_contactFilterTarget = 0xffffffff; +} + +inline +void PfxShape::setBox(PfxBox SCE_VECTORMATH_AOS_VECTOR_ARG box) +{ + m_vecDataF[0] = box.m_half[0]; + m_vecDataF[1] = box.m_half[1]; + m_vecDataF[2] = box.m_half[2]; + m_type = kPfxShapeBox; +} + +inline +void PfxShape::setCapsule(PfxCapsule capsule) +{ + m_vecDataF[0] = capsule.m_halfLen; + m_vecDataF[1] = capsule.m_radius; + m_vecDataF[2] = 0.0f; + m_type = kPfxShapeCapsule; +} + +inline +void PfxShape::setCylinder(PfxCylinder cylinder) +{ + m_vecDataF[0] = cylinder.m_halfLen; + m_vecDataF[1] = cylinder.m_radius; + m_vecDataF[2] = 0.0f; + m_type = kPfxShapeCylinder; +} + +inline +void PfxShape::setSphere(PfxSphere sphere) +{ + m_vecDataF[0] = sphere.m_radius; + m_vecDataF[1] = 0.0f; + m_vecDataF[2] = 0.0f; + m_type = kPfxShapeSphere; +} + +inline +void PfxShape::setConvexMesh(const PfxConvexMesh *convexMesh) +{ + m_vecDataPtr[0] = (void*)convexMesh; + m_vecDataPtr[1] = NULL; + m_type = kPfxShapeConvexMesh; +} + +inline +void PfxShape::setLargeTriMesh(const PfxLargeTriMesh *largeMesh) +{ + m_vecDataPtr[0] = (void*)largeMesh; + m_vecDataPtr[1] = NULL; + m_type = kPfxShapeLargeTriMesh; +} + +inline +void PfxShape::setOffsetTransform(const PfxTransform3 & xfrm) +{ + setOffsetOrientation(PfxQuat(xfrm.getUpper3x3())); + setOffsetPosition(xfrm.getTranslation()); +} + +inline +PfxUInt8 PfxShape::getType() const +{ + return m_type; +} + +inline +PfxBox PfxShape::getBox() const +{ + SCE_PFX_ALWAYS_ASSERT(m_type==kPfxShapeBox); + return PfxBox(m_vecDataF[0],m_vecDataF[1],m_vecDataF[2]); +} + +inline +PfxCapsule PfxShape::getCapsule() const +{ + SCE_PFX_ALWAYS_ASSERT(m_type==kPfxShapeCapsule); + return PfxCapsule(m_vecDataF[0], m_vecDataF[1]); +} + +inline +PfxCylinder PfxShape::getCylinder() const +{ + SCE_PFX_ALWAYS_ASSERT(m_type==kPfxShapeCylinder); + return PfxCylinder(m_vecDataF[0], m_vecDataF[1]); +} + +inline +PfxSphere PfxShape::getSphere() const +{ + SCE_PFX_ALWAYS_ASSERT(m_type==kPfxShapeSphere); + return PfxSphere(m_vecDataF[0]); +} + +inline +const PfxConvexMesh *PfxShape::getConvexMesh() const +{ + SCE_PFX_ALWAYS_ASSERT(m_type==kPfxShapeConvexMesh); + SCE_PFX_ALWAYS_ASSERT(m_vecDataPtr[0]!=NULL); + return (PfxConvexMesh*)m_vecDataPtr[0]; +} + +inline +const PfxLargeTriMesh *PfxShape::getLargeTriMesh() const +{ + SCE_PFX_ALWAYS_ASSERT(m_type==kPfxShapeLargeTriMesh); + SCE_PFX_ALWAYS_ASSERT(m_vecDataPtr[0]!=NULL); + return (PfxLargeTriMesh*)m_vecDataPtr[0]; +} + +inline +PfxTransform3 PfxShape::getOffsetTransform() const +{ + return PfxTransform3(getOffsetOrientation(),getOffsetPosition()); +} + +#endif // _SCE_PFX_SHAPE_IMPLEMENTATION_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_shape_iterator.h b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_shape_iterator.h new file mode 100644 index 000000000..7a0a3005c --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_shape_iterator.h @@ -0,0 +1,58 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_SHAPE_ITERATOR_H +#define _SCE_PFX_SHAPE_ITERATOR_H + +#include "pfx_collidable.h" + + +namespace sce { +namespace PhysicsEffects { + +class PfxShapeIterator +{ +private: +PfxUInt32 m_numShapes; +PfxShape *m_shapeBase; +const PfxUInt16 *m_shapeIds; +const PfxShape *m_curShape; +PfxUInt32 m_index; + +public: +PfxShapeIterator(const PfxCollidable &coll) : m_shapeIds(coll.m_shapeIds) +{ + m_numShapes = coll.m_numShapes; + m_shapeBase = coll.m_shapeBase; + m_index = 0; + m_curShape = &coll.m_defShape; +} + +~PfxShapeIterator() {} + +inline PfxShapeIterator& operator++() +{ + m_curShape = &m_shapeBase[m_shapeIds[m_index++]]; + return *this; +} + +const PfxShape& operator*() const {return *m_curShape;} +}; + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_SHAPE_ITERATOR_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_sphere.h b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_sphere.h new file mode 100644 index 000000000..477d7f9c8 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_sphere.h @@ -0,0 +1,49 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_SPHERE_H +#define _SCE_PFX_SPHERE_H + +#include "../base/pfx_common.h" + +namespace sce { +namespace PhysicsEffects { + +struct PfxSphere { + PfxFloat m_radius; + + PfxSphere() {} + PfxSphere( PfxFloat radius ); + + void set( PfxFloat radius ); +}; + +inline +PfxSphere::PfxSphere( PfxFloat radius ) +{ + m_radius = radius; +} + +inline +void PfxSphere::set( PfxFloat radius ) +{ + m_radius = radius; +} + +} // namespace PhysicsEffects +} // namespace sce + +#endif // _SCE_PFX_SPHERE_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_sub_data.h b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_sub_data.h new file mode 100644 index 000000000..82f5c0cc9 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_sub_data.h @@ -0,0 +1,63 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_SUB_DATA_H +#define _SCE_PFX_SUB_DATA_H + +namespace sce { +namespace PhysicsEffects { + +struct PfxSubData { + enum { + NONE = 0, + MESH_INFO + }; + + union { + struct { + PfxUInt8 m_type; + SCE_PFX_PADDING(1,1) + + struct { + PfxUInt8 islandId; + PfxUInt8 facetId; + PfxUInt16 s; + PfxUInt16 t; + + } m_facetLocal; + }; + PfxUInt32 param[2]; + }; + + PfxSubData() + { + param[0] = param[1] = 0; + } + + void setIslandId(PfxUInt8 i) {m_facetLocal.islandId = i;} + void setFacetId(PfxUInt8 i) {m_facetLocal.facetId = i;} + void setFacetLocalS(PfxFloat s) {m_facetLocal.s = (PfxUInt16)(s * 65535.0f);} + void setFacetLocalT(PfxFloat t) {m_facetLocal.t = (PfxUInt16)(t * 65535.0f);} + + PfxUInt8 getIslandId() {return m_facetLocal.islandId;} + PfxUInt8 getFacetId() {return m_facetLocal.facetId;} + PfxFloat getFacetLocalS() {return m_facetLocal.s / 65535.0f;} + PfxFloat getFacetLocalT() {return m_facetLocal.t / 65535.0f;} +}; + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_SUB_DATA_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_tri_mesh.h b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_tri_mesh.h new file mode 100644 index 000000000..2370afe02 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/collision/pfx_tri_mesh.h @@ -0,0 +1,154 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_TRI_MESH_H +#define _SCE_PFX_TRI_MESH_H + +#include "../base/pfx_common.h" +#include "../base/pfx_vec_utils.h" +#include "pfx_aabb.h" + +namespace sce { +namespace PhysicsEffects { + +//J メッシュのリソース制限 +//E Define some limitations of a triangle mesh +#define SCE_PFX_NUMMESHFACETS 64 +#define SCE_PFX_NUMMESHEDGES 192 +#define SCE_PFX_NUMMESHVERTICES 128 + +//J エッジの角 +//E Edge types +#define SCE_PFX_EDGE_FLAT 0 +#define SCE_PFX_EDGE_CONVEX 1 +#define SCE_PFX_EDGE_CONCAVE 2 + +/////////////////////////////////////////////////////////////////////////////// +// Edge +struct PfxEdge +{ + PfxUInt8 m_vertId[2]; + PfxUInt8 m_angleType; + PfxUInt8 m_tilt; +}; + +inline +bool operator ==(const PfxEdge &e1,const PfxEdge &e2) +{ + return (e1.m_vertId[0] == e2.m_vertId[0] && e1.m_vertId[1] == e2.m_vertId[1]) || + (e1.m_vertId[1] == e2.m_vertId[0] && e1.m_vertId[0] == e2.m_vertId[1]); +} + +/////////////////////////////////////////////////////////////////////////////// +// Facet + +struct PfxFacet +{ + PfxFloat m_normal[3]; + PfxFloat m_thickness; + PfxUInt8 m_group; + PfxUInt8 m_vertIds[3]; + PfxUInt8 m_edgeIds[3]; + PfxUInt8 m_userData; + PfxFloat m_half[3]; + PfxFloat m_center[3]; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Mesh + +struct SCE_PFX_ALIGNED(16) PfxTriMesh +{ + PfxUInt8 m_numVerts; + PfxUInt8 m_numEdges; + PfxUInt8 m_numFacets; + PfxUInt8 m_reserved; + PfxFacet m_facets[SCE_PFX_NUMMESHFACETS]; + PfxEdge m_edges[SCE_PFX_NUMMESHEDGES]; + SCE_PFX_PADDING(1,12) + PfxVector3 m_verts[SCE_PFX_NUMMESHVERTICES]; + PfxVector3 m_half; + + PfxTriMesh() + { + m_numVerts = m_numEdges = m_numFacets = 0; + } + + inline void updateAABB(); +}; + +inline +void PfxTriMesh::updateAABB() +{ + PfxVector3 halfMax(0); + + for(PfxUInt8 i=0;i0.0f?1.0f/mass:0.0f;} + + const PfxMatrix3& getInertia() const {return m_inertia;} + void setInertia(const PfxMatrix3 SCE_VECTORMATH_AOS_MATRIX_ARG inertia) {m_inertia = inertia;m_inertiaInv = inverse(inertia);} + + PfxFloat getRestitution() const {return m_restitution;} + void setRestitution(PfxFloat restitution) {m_restitution = restitution;} + + PfxFloat getFriction() const {return m_friction;} + void setFriction(PfxFloat friction) {m_friction = friction;} +}; + +inline +void PfxRigidBody::reset() +{ + m_mass = 0.0f; + m_restitution = 0.2f; + m_friction = 0.6f; +} + +} // namespace PhysicsEffects +} // namespace sce + +#endif // _SCE_PFX_RIGID_BODY_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/rigidbody/pfx_rigid_state.h b/Extras/PhysicsEffects/include/physics_effects/base_level/rigidbody/pfx_rigid_state.h new file mode 100644 index 000000000..356b67ed5 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/rigidbody/pfx_rigid_state.h @@ -0,0 +1,196 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_RIGID_STATE_H +#define _SCE_PFX_RIGID_STATE_H + +#include "../base/pfx_common.h" +#include "../base/pfx_vec_utils.h" + +namespace sce { +namespace PhysicsEffects { + +// Motion Type +enum ePfxMotionType { + kPfxMotionTypeFixed = 0, + kPfxMotionTypeActive, + kPfxMotionTypeKeyframe, + kPfxMotionTypeOneWay, + kPfxMotionTypeTrigger, + kPfxMotionTypeCount +}; + +#define SCE_PFX_MOTION_MASK_DYNAMIC(motion) ((1<<(motion))&0x0a) // Active,OneWay +#define SCE_PFX_MOTION_MASK_STATIC(motion) ((1<<(motion))&0x95) // Fixed,Keyframe +#define SCE_PFX_MOTION_MASK_CAN_SLEEP(motion) ((1<<(motion))&0x0e) // Can sleep + +#define SCE_PFX_MOTION_MASK_SLEEPING 0x80 // Is sleeping +#define SCE_PFX_MOTION_MASK_TYPE 0x7f // Motion Type + +class SCE_PFX_ALIGNED(128) PfxRigidState +{ +private: + union { + struct { + PfxUInt8 m_useSleep : 1; + PfxUInt8 m_sleeping : 1; + PfxUInt8 m_reserved1 : 1; + PfxUInt8 m_reserved2 : 1; + PfxUInt8 m_reserved3 : 1; + PfxUInt8 m_reserved4 : 1; + PfxUInt8 m_reserved5 : 1; + PfxUInt8 m_reserved6 : 1; + }; + PfxUInt8 m_flags; + }; + PfxUInt8 m_motionType; + PfxUInt16 m_sleepCount; + PfxUInt16 m_rigidBodyId; + + SCE_PFX_PADDING(1,2) + + PfxUInt32 m_contactFilterSelf; + PfxUInt32 m_contactFilterTarget; + + PfxFloat m_linearDamping; + PfxFloat m_angularDamping; + + PfxFloat m_maxLinearVelocity; + PfxFloat m_maxAngularVelocity; + + PfxVector3 m_position; + PfxQuat m_orientation; + PfxVector3 m_linearVelocity; + PfxVector3 m_angularVelocity; + + void *m_userData; + PfxUInt32 m_userParam[4]; + + SCE_PFX_PADDING(2,12) + +public: + inline void reset(); + + PfxUInt16 getRigidBodyId() const {return m_rigidBodyId;} + void setRigidBodyId(PfxUInt16 i) {m_rigidBodyId = i;} + + PfxUInt32 getContactFilterSelf() const {return m_contactFilterSelf;} + void setContactFilterSelf(PfxUInt32 filter) {m_contactFilterSelf = filter;} + + PfxUInt32 getContactFilterTarget() const {return m_contactFilterTarget;} + void setContactFilterTarget(PfxUInt32 filter) {m_contactFilterTarget = filter;} + + ePfxMotionType getMotionType() const {return (ePfxMotionType)m_motionType;} + void setMotionType(ePfxMotionType t) {SCE_PFX_ALWAYS_ASSERT(t 0.0f); + + setLinearVelocity((pos - getPosition()) / timeStep); +} + +inline +void PfxRigidState::moveOrientation(const PfxQuat &rot,PfxFloat timeStep) +{ + if(getMotionType()!=kPfxMotionTypeKeyframe) return; + + SCE_PFX_ASSERT(timeStep > 0.0f); + + PfxQuat ori1 = getOrientation(); + PfxQuat ori2 = rot; + + if(dot(ori2,ori1) < 0.0f) { + ori2 = -rot; + } + + PfxQuat dq = ( ori2 - ori1 ) / timeStep; + dq = dq * 2.0f * conj(ori1); + PfxVector3 omega = dq.getXYZ(); + + setAngularVelocity(omega); +} +} // namespace PhysicsEffects +} // namespace sce +#endif // _SCE_PFX_RIGID_STATE_H + diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_constraint_pair.h b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_constraint_pair.h new file mode 100644 index 000000000..2663df97d --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_constraint_pair.h @@ -0,0 +1,39 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONSTRAINT_PAIR_H +#define _SCE_PFX_CONSTRAINT_PAIR_H + +#include "../sort/pfx_sort_data.h" +#include "../broadphase/pfx_broadphase_pair.h" + +namespace sce { +namespace PhysicsEffects { + +typedef PfxSortData16 PfxConstraintPair; + +//J PfxBroadphasePairと共通 +//E Same as PfxBroadphasePair + +SCE_PFX_FORCE_INLINE void pfxSetConstraintId(PfxConstraintPair &pair,PfxUInt32 i) {pair.set32(2,i);} +SCE_PFX_FORCE_INLINE void pfxSetNumConstraints(PfxConstraintPair &pair,PfxUInt8 n) {pair.set8(7,n);} + +SCE_PFX_FORCE_INLINE PfxUInt32 pfxGetConstraintId(const PfxConstraintPair &pair) {return pair.get32(2);} +SCE_PFX_FORCE_INLINE PfxUInt8 pfxGetNumConstraints(const PfxConstraintPair &pair) {return pair.get8(7);} + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_CONSTRAINT_PAIR_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_constraint_row.h b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_constraint_row.h new file mode 100644 index 000000000..b5ae65638 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_constraint_row.h @@ -0,0 +1,40 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONSTRAINT_ROW_H +#define _SCE_PFX_CONSTRAINT_ROW_H + +#include "../base/pfx_vec_utils.h" + +namespace sce { +namespace PhysicsEffects { + + +#include "../base/pfx_common.h" + +//E Don't change following order of parameters +struct SCE_PFX_ALIGNED(16) PfxConstraintRow { + PfxFloat m_normal[3]; + PfxFloat m_rhs; + PfxFloat m_jacDiagInv; + PfxFloat m_lowerLimit; + PfxFloat m_upperLimit; + PfxFloat m_accumImpulse; +}; + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_CONSTRAINT_ROW_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_contact_constraint.h b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_contact_constraint.h new file mode 100644 index 000000000..d1b5cebba --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_contact_constraint.h @@ -0,0 +1,59 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_CONSTRAINT_H +#define _SCE_PFX_CONTACT_CONSTRAINT_H + +#include "../rigidbody/pfx_rigid_state.h" +#include "pfx_constraint_row.h" +#include "pfx_solver_body.h" + +namespace sce { +namespace PhysicsEffects { + +void pfxSetupContactConstraint( + PfxConstraintRow &constraintResponse, + PfxConstraintRow &constraintFriction1, + PfxConstraintRow &constraintFriction2, + PfxFloat penetrationDepth, + PfxFloat restitution, + PfxFloat friction, + const PfxVector3 &contactNormal, + const PfxVector3 &contactPointA, + const PfxVector3 &contactPointB, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + PfxFloat separateBias, + PfxFloat timeStep + ); + +void pfxSolveContactConstraint( + PfxConstraintRow &constraintResponse, + PfxConstraintRow &constraintFriction1, + PfxConstraintRow &constraintFriction2, + const PfxVector3 &contactPointA, + const PfxVector3 &contactPointB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + PfxFloat friction + ); + + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_CONTACT_CONSTRAINT_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_integrate.h b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_integrate.h new file mode 100644 index 000000000..4253182cc --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_integrate.h @@ -0,0 +1,121 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_INTEGRATE_H_ +#define _SCE_PFX_INTEGRATE_H_ + +#include "../base/pfx_common.h" +#include "../rigidbody/pfx_rigid_body.h" +#include "../rigidbody/pfx_rigid_state.h" + +namespace sce { +namespace PhysicsEffects { + +template +static SCE_PFX_FORCE_INLINE T pfxRungeKutta(const T &deriv,PfxFloat dt) +{ + T k0, k1, k2, k3; + k0 = deriv * dt; + k1 = (deriv + k0 * 0.5f) * dt; + k2 = (deriv + k1 * 0.5f) * dt; + k3 = (deriv + k2) * dt; + return (k0 + k1*2.0f + k2*2.0f + k3) / 6.0f; +} + +#define SCE_PFX_MOTION_MASK_INTEGRATE ((1< state.getMaxLinearVelocity()) + { + nv = normalize( nv ) * state.getMaxLinearVelocity(); + } + if(length(nw) > state.getMaxAngularVelocity()) + { + nw = normalize( nw ) * state.getMaxAngularVelocity(); + } + + state.setLinearVelocity(nv); + state.setAngularVelocity(nw); +} +} //namespace PhysicsEffects +} //namespace sce + +#endif /* _SCE_PFX_INTEGRATE_H_ */ diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint.h b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint.h new file mode 100644 index 000000000..1c2be0799 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint.h @@ -0,0 +1,90 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_JOINT_H +#define _SCE_PFX_JOINT_H + +#include "../rigidbody/pfx_rigid_state.h" +#include "pfx_joint_constraint.h" +#include "pfx_constraint_pair.h" + +namespace sce { +namespace PhysicsEffects { + +// Joint Type +enum ePfxJointType { + kPfxJointBall = 0, + kPfxJointSwingtwist, + kPfxJointHinge, + kPfxJointSlider, + kPfxJointFix, + kPfxJointUniversal, + kPfxJointAnimation, + kPfxJointReserved0, + kPfxJointReserved1, + kPfxJointReserved2, + kPfxJointUser0, + kPfxJointUser1, + kPfxJointUser2, + kPfxJointUser3, + kPfxJointUser4, + kPfxJointCount // = 15 +}; + +// Joint Structure +struct SCE_PFX_ALIGNED(128) PfxJoint { + PfxUInt8 m_active; + PfxUInt8 m_numConstraints; + PfxUInt8 m_type; + SCE_PFX_PADDING(1,1) + PfxUInt16 m_rigidBodyIdA; + PfxUInt16 m_rigidBodyIdB; + SCE_PFX_PADDING(2,8) + PfxJointConstraint m_constraints[6]; + void *m_userData; + SCE_PFX_PADDING(3,12) + PfxVector3 m_param[4]; // Used by some joints for specific features + PfxVector3 m_anchorA; + PfxVector3 m_anchorB; + PfxMatrix3 m_frameA; + PfxMatrix3 m_frameB; + SCE_PFX_PADDING(4,32) +}; + +SCE_PFX_FORCE_INLINE +void pfxUpdateJointPairs( + PfxConstraintPair &pair, + PfxUInt32 jointId, + const PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB + ) +{ + SCE_PFX_ALWAYS_ASSERT(stateA.getRigidBodyId()==joint.m_rigidBodyIdA); + SCE_PFX_ALWAYS_ASSERT(stateB.getRigidBodyId()==joint.m_rigidBodyIdB); + pfxSetObjectIdA(pair,stateA.getRigidBodyId()); + pfxSetObjectIdB(pair,stateB.getRigidBodyId()); + pfxSetMotionMaskA(pair,stateA.getMotionMask()); + pfxSetMotionMaskB(pair,stateB.getMotionMask()); + pfxSetConstraintId(pair,jointId); + pfxSetNumConstraints(pair,joint.m_numConstraints); + pfxSetActive(pair,joint.m_active>0); +} +} //namespace PhysicsEffects +} //namespace sce + + +#endif // _PFX_JOINT_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_ball.h b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_ball.h new file mode 100644 index 000000000..f18ec8cdc --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_ball.h @@ -0,0 +1,62 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_JOINT_BALL_H +#define _SCE_PFX_JOINT_BALL_H + +#include "pfx_joint.h" +#include "pfx_solver_body.h" + +namespace sce { +namespace PhysicsEffects { + +struct PfxBallJointInitParam { + PfxVector3 anchorPoint; + + PfxBallJointInitParam() + { + anchorPoint = PfxVector3(0.0f); + } +}; + +PfxInt32 pfxInitializeBallJoint( + PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + const PfxBallJointInitParam ¶m); + +void pfxSetupBallJoint( + PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + PfxFloat timeStep); + +void pfxWarmStartBallJoint( + PfxJoint &joint, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB); + +void pfxSolveBallJoint( + PfxJoint &joint, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_JOINT_BALL_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_constraint.h b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_constraint.h new file mode 100644 index 000000000..2d4b10fb1 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_constraint.h @@ -0,0 +1,67 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_JOINT_CONSTRAINT_H +#define _SCE_PFX_JOINT_CONSTRAINT_H + +#include "../base/pfx_common.h" +#include "../base/pfx_vec_utils.h" +#include "pfx_constraint_row.h" + +namespace sce { +namespace PhysicsEffects { + +// Lock type +#define SCE_PFX_JOINT_LOCK_FREE 0 +#define SCE_PFX_JOINT_LOCK_LIMIT 1 +#define SCE_PFX_JOINT_LOCK_FIX 2 + +// Slop +#define SCE_PFX_JOINT_LINEAR_SLOP 0.01f +#define SCE_PFX_JOINT_ANGULAR_SLOP 0.01f + +///////////////////////////////////////////////////////////////////////////////// Joint Constraint + +struct PfxJointConstraint { + PfxInt8 m_lock; + PfxInt8 m_warmStarting; + SCE_PFX_PADDING(1,2) + PfxFloat m_movableLowerLimit; + PfxFloat m_movableUpperLimit; + PfxFloat m_bias; + PfxFloat m_weight; + PfxFloat m_damping; + PfxFloat m_maxImpulse; + SCE_PFX_PADDING(2,4) + PfxConstraintRow m_constraintRow; + + void reset() + { + m_lock = SCE_PFX_JOINT_LOCK_FIX; + m_warmStarting = 0; + m_movableLowerLimit = 0.0f; + m_movableUpperLimit = 0.0f; + m_bias = 0.2f; + m_weight = 1.0f; + m_damping = 0.0f; + m_maxImpulse = SCE_PFX_FLT_MAX; + memset(&m_constraintRow,0,sizeof(PfxConstraintRow)); + } +}; +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_JOINT_CONSTRAINT_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_fix.h b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_fix.h new file mode 100644 index 000000000..7d4408253 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_fix.h @@ -0,0 +1,49 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_JOINT_FIX_H +#define _SCE_PFX_JOINT_FIX_H + +#include "pfx_joint.h" +#include "pfx_solver_body.h" + +namespace sce { +namespace PhysicsEffects { + +struct PfxFixJointInitParam { + PfxVector3 anchorPoint; + + PfxFixJointInitParam() + { + anchorPoint = PfxVector3(0.0f); + } +}; + +PfxInt32 pfxInitializeFixJoint( + PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + const PfxFixJointInitParam ¶m); + +// pfxSetupFixJoint = pfxSetupSwingTwistJoint + +// pfxWarmStartFixJoint = pfxWarmStartSwingTwistJoint + +// pfxSolveFixJoint = pfxSolveSwingTwistJoint +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_JOINT_FIX_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_hinge.h b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_hinge.h new file mode 100644 index 000000000..357f47e57 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_hinge.h @@ -0,0 +1,56 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_JOINT_HINGE_H_ +#define _SCE_PFX_JOINT_HINGE_H_ + +#include "pfx_joint.h" +#include "pfx_solver_body.h" + +namespace sce { +namespace PhysicsEffects { + +struct PfxHingeJointInitParam { + PfxVector3 anchorPoint; + PfxVector3 axis; + PfxFloat lowerAngle; + PfxFloat upperAngle; + SCE_PFX_PADDING(1,8) + + PfxHingeJointInitParam() + { + anchorPoint = PfxVector3(0.0f); + axis = PfxVector3(1.0f,0.0f,0.0f); + lowerAngle = 0.0f; + upperAngle = 0.0f; + } +}; + +PfxInt32 pfxInitializeHingeJoint( + PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + const PfxHingeJointInitParam ¶m); + +// pfxSetupHingeJoint = pfxSetupSwingTwistJoint + +// pfxWarmStartHingeJoint = pfxWarmStartSwingTwistJoint + +// pfxSolveHingeJoint = pfxSolveSwingTwistJoint + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_JOINT_HINGE_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_slider.h b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_slider.h new file mode 100644 index 000000000..23b576921 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_slider.h @@ -0,0 +1,57 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_JOINT_SLIDER_H +#define _SCE_PFX_JOINT_SLIDER_H + +#include "pfx_joint.h" +#include "pfx_solver_body.h" + +namespace sce { +namespace PhysicsEffects { + +struct PfxSliderJointInitParam { + PfxVector3 anchorPoint; + PfxVector3 direction; + PfxFloat lowerDistance; + PfxFloat upperDistance; + SCE_PFX_PADDING(1,8) + + PfxSliderJointInitParam() + { + anchorPoint = PfxVector3(0.0f); + direction = PfxVector3(1.0f,0.0f,0.0f); + lowerDistance = 0.0f; + upperDistance = 0.0f; + } +}; + +PfxInt32 pfxInitializeSliderJoint( + PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + const PfxSliderJointInitParam ¶m); + +// pfxSetupSliderJoint = pfxSetupSwingTwistJoint + +// pfxWarmStartSliderJoint = pfxWarmStartSwingTwistJoint + +// pfxSolveSliderJoint = pfxSolveSwingTwistJoint + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_JOINT_SLIDER_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_swing_twist.h b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_swing_twist.h new file mode 100644 index 000000000..de0774dd6 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_swing_twist.h @@ -0,0 +1,70 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_JOINT_SWING_TWIST_H +#define _SCE_PFX_JOINT_SWING_TWIST_H + +#include "pfx_joint.h" +#include "pfx_solver_body.h" +namespace sce { +namespace PhysicsEffects { + +struct PfxSwingTwistJointInitParam { + PfxVector3 anchorPoint; + PfxVector3 twistAxis; + PfxFloat twistLowerAngle; + PfxFloat twistUpperAngle; + PfxFloat swingLowerAngle; + PfxFloat swingUpperAngle; + + PfxSwingTwistJointInitParam() + { + anchorPoint = PfxVector3(0.0f); + twistAxis = PfxVector3(1.0f,0.0f,0.0f); + twistLowerAngle = -0.26f; + twistUpperAngle = 0.26f; + swingLowerAngle = 0.0f; + swingUpperAngle = 0.7f; + } +}; + +PfxInt32 pfxInitializeSwingTwistJoint( + PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + const PfxSwingTwistJointInitParam ¶m); + +void pfxSetupSwingTwistJoint( + PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + PfxFloat timeStep); + +void pfxWarmStartSwingTwistJoint( + PfxJoint &joint, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB); + +void pfxSolveSwingTwistJoint( + PfxJoint &joint, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB); + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_JOINT_SWING_TWIST_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_universal.h b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_universal.h new file mode 100644 index 000000000..7e9148d45 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_joint_universal.h @@ -0,0 +1,65 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_JOINT_UNIVERSAL_H +#define _SCE_PFX_JOINT_UNIVERSAL_H + +#include "pfx_joint.h" +#include "pfx_solver_body.h" + +namespace sce { +namespace PhysicsEffects { + +struct PfxUniversalJointInitParam { + PfxVector3 anchorPoint; + PfxVector3 axis; + PfxFloat swing1LowerAngle; + PfxFloat swing1UpperAngle; + PfxFloat swing2LowerAngle; + PfxFloat swing2UpperAngle; + + PfxUniversalJointInitParam() + { + anchorPoint = PfxVector3(0.0f); + axis = PfxVector3(1.0f,0.0f,0.0f); + swing1LowerAngle = -0.7f; + swing1UpperAngle = 0.7f; + swing2LowerAngle = -0.7f; + swing2UpperAngle = 0.7f; + } +}; + +PfxInt32 pfxInitializeUniversalJoint( + PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + const PfxUniversalJointInitParam ¶m); + +void pfxSetupUniversalJoint( + PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + PfxFloat timeStep); + +// pfxWarmStartUniversalJoint = pfxWarmStartSwingTwistJoint + +// pfxSolveUniversalJoint = pfxSolveSwingTwistJoint + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_JOINT_UNIVERSAL_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_solver_body.h b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_solver_body.h new file mode 100644 index 000000000..f26370d49 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/solver/pfx_solver_body.h @@ -0,0 +1,37 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_SOLVER_BODY_H +#define _SCE_PFX_SOLVER_BODY_H + +#include "../base/pfx_common.h" + +namespace sce { +namespace PhysicsEffects { + +struct SCE_PFX_ALIGNED(128) PfxSolverBody { + PfxVector3 m_deltaLinearVelocity; + PfxVector3 m_deltaAngularVelocity; + PfxQuat m_orientation; + PfxMatrix3 m_inertiaInv; + PfxFloat m_massInv; + PfxUInt32 m_motionType; + SCE_PFX_PADDING(1,24) +}; + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_SOLVER_BODY_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/sort/pfx_sort.h b/Extras/PhysicsEffects/include/physics_effects/base_level/sort/pfx_sort.h new file mode 100644 index 000000000..346910c28 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/sort/pfx_sort.h @@ -0,0 +1,33 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_SORT_H +#define _SCE_PFX_SORT_H + +#include "pfx_sort_data.h" +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// Single Sort + +void pfxSort(PfxSortData16 *data,PfxSortData16 *buff,unsigned int n); +void pfxSort(PfxSortData32 *data,PfxSortData32 *buff,unsigned int n); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_SORT_H diff --git a/Extras/PhysicsEffects/include/physics_effects/base_level/sort/pfx_sort_data.h b/Extras/PhysicsEffects/include/physics_effects/base_level/sort/pfx_sort_data.h new file mode 100644 index 000000000..b048d1720 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/base_level/sort/pfx_sort_data.h @@ -0,0 +1,82 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_SORT_DATA_H +#define _SCE_PFX_SORT_DATA_H + +#include "../base/pfx_common.h" + + + +namespace sce { +namespace PhysicsEffects { + +#define SCE_PFX_SENTINEL_KEY 0xffffffff + +struct SCE_PFX_ALIGNED(16) PfxSortData16 { + union { + PfxUInt8 i8data[16]; + PfxUInt16 i16data[8]; + PfxUInt32 i32data[4]; + }; + +void set8(int slot,PfxUInt8 data) {i8data[slot] = data;} +void set16(int slot,PfxUInt16 data) {i16data[slot] = data;} +void set32(int slot,PfxUInt32 data) {i32data[slot] = data;} +PfxUInt8 get8(int slot) const {return i8data[slot];} +PfxUInt16 get16(int slot) const {return i16data[slot];} +PfxUInt32 get32(int slot) const {return i32data[slot];} +}; + +struct SCE_PFX_ALIGNED(16) PfxSortData32 { + union { + PfxUInt8 i8data[32]; + PfxUInt16 i16data[16]; + PfxUInt32 i32data[8]; + }; + +void set8(int slot,PfxUInt8 data) {i8data[slot] = data;} +void set16(int slot,PfxUInt16 data) {i16data[slot] = data;} +void set32(int slot,PfxUInt32 data) {i32data[slot] = data;} +PfxUInt8 get8(int slot) const {return i8data[slot];} +PfxUInt16 get16(int slot) const {return i16data[slot];} +PfxUInt32 get32(int slot) const {return i32data[slot];} +}; + +SCE_PFX_FORCE_INLINE +void pfxSetKey(PfxSortData16 &sortData,PfxUInt32 key) {sortData.set32(3,key);} + +SCE_PFX_FORCE_INLINE +PfxUInt32 pfxGetKey(const PfxSortData16 &sortData) {return sortData.get32(3);} + +SCE_PFX_FORCE_INLINE +void pfxSetKey(PfxSortData32 &sortData,PfxUInt32 key) {sortData.set32(7,key);} + +SCE_PFX_FORCE_INLINE +PfxUInt32 pfxGetKey(const PfxSortData32 &sortData) {return sortData.get32(7);} + +SCE_PFX_FORCE_INLINE +PfxUInt32 pfxCreateUniqueKey(PfxUInt32 i,PfxUInt32 j) +{ + PfxUInt32 minIdx = SCE_PFX_MIN(i,j); + PfxUInt32 maxIdx = SCE_PFX_MAX(i,j); + return (maxIdx<<16)|(minIdx&0xffff); +} + +} // namespace PhysicsEffects +} // namespace sce + +#endif // _SCE_PFX_SORT_DATA_H diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/broadphase/pfx_broadphase.h b/Extras/PhysicsEffects/include/physics_effects/low_level/broadphase/pfx_broadphase.h new file mode 100644 index 000000000..18832d7bc --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/broadphase/pfx_broadphase.h @@ -0,0 +1,124 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_BROADPHASE_H_ +#define _SCE_PFX_BROADPHASE_H_ + +#include "../../base_level/broadphase/pfx_broadphase_pair.h" +#include "../../base_level/broadphase/pfx_broadphase_proxy.h" +#include "../../base_level/rigidbody/pfx_rigid_state.h" +#include "../../base_level/collision/pfx_collidable.h" +#include "../task/pfx_task_manager.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// Update Broadphase Proxies + +#define SCE_PFX_OUT_OF_WORLD_BEHAVIOR_FIX_MOTION 0x01 +#define SCE_PFX_OUT_OF_WORLD_BEHAVIOR_REMOVE_PROXY 0x02 + +struct PfxUpdateBroadphaseProxiesParam { + void *workBuff; + PfxUInt32 workBytes; + PfxBroadphaseProxy *proxiesX; + PfxBroadphaseProxy *proxiesY; + PfxBroadphaseProxy *proxiesZ; + PfxBroadphaseProxy *proxiesXb; + PfxBroadphaseProxy *proxiesYb; + PfxBroadphaseProxy *proxiesZb; + PfxRigidState *offsetRigidStates; + PfxCollidable *offsetCollidables; + PfxUInt32 numRigidBodies; + PfxUInt32 outOfWorldBehavior; + PfxVector3 worldCenter; + PfxVector3 worldExtent; + + PfxUpdateBroadphaseProxiesParam() : outOfWorldBehavior(0) {} +}; + +struct PfxUpdateBroadphaseProxiesResult { + PfxInt32 numOutOfWorldProxies; +}; + +PfxUInt32 pfxGetWorkBytesOfUpdateBroadphaseProxies(PfxUInt32 numRigidBodies); + +PfxUInt32 pfxGetWorkBytesOfUpdateBroadphaseProxies(PfxUInt32 numRigidBodies,PfxUInt32 maxTasks); + +PfxInt32 pfxUpdateBroadphaseProxies(PfxUpdateBroadphaseProxiesParam ¶m,PfxUpdateBroadphaseProxiesResult &result); + +PfxInt32 pfxUpdateBroadphaseProxies(PfxUpdateBroadphaseProxiesParam ¶m,PfxUpdateBroadphaseProxiesResult &result,PfxTaskManager *taskManager); + +/////////////////////////////////////////////////////////////////////////////// +// Find Pairs + +struct PfxFindPairsParam { + void *workBuff; + PfxUInt32 workBytes; + void *pairBuff; + PfxUInt32 pairBytes; + PfxBroadphaseProxy *proxies; + PfxUInt32 numProxies; + PfxUInt32 maxPairs; + int axis; +}; + +struct PfxFindPairsResult { + PfxBroadphasePair *pairs; + PfxUInt32 numPairs; +}; + +PfxUInt32 pfxGetWorkBytesOfFindPairs(PfxUInt32 maxPairs,PfxUInt32 maxTasks=1); +PfxUInt32 pfxGetPairBytesOfFindPairs(PfxUInt32 maxPairs); + +PfxInt32 pfxFindPairs(PfxFindPairsParam ¶m,PfxFindPairsResult &result); + +PfxInt32 pfxFindPairs(PfxFindPairsParam ¶m,PfxFindPairsResult &result,PfxTaskManager *taskManager); + +/////////////////////////////////////////////////////////////////////////////// +// Decompose Pairs + +struct PfxDecomposePairsParam { + void *workBuff; + PfxUInt32 workBytes; + void *pairBuff; + PfxUInt32 pairBytes; + PfxBroadphasePair *previousPairs; + PfxUInt32 numPreviousPairs; + PfxBroadphasePair *currentPairs; + PfxUInt32 numCurrentPairs; +}; + +struct PfxDecomposePairsResult { + PfxBroadphasePair *outNewPairs; + PfxUInt32 numOutNewPairs; + PfxBroadphasePair *outKeepPairs; + PfxUInt32 numOutKeepPairs; + PfxBroadphasePair *outRemovePairs; + PfxUInt32 numOutRemovePairs; +}; + +PfxUInt32 pfxGetWorkBytesOfDecomposePairs(PfxUInt32 numPreviousPairs,PfxUInt32 numCurrentPairs,int maxTasks=1); +PfxUInt32 pfxGetPairBytesOfDecomposePairs(PfxUInt32 numPreviousPairs,PfxUInt32 numCurrentPairs); + +PfxInt32 pfxDecomposePairs(PfxDecomposePairsParam ¶m,PfxDecomposePairsResult &result); + +PfxInt32 pfxDecomposePairs(PfxDecomposePairsParam ¶m,PfxDecomposePairsResult &result,PfxTaskManager *taskManager); + +} //namespace PhysicsEffects +} //namespace sce +#endif /* _SCE_PFX_BROADPHASE_H_ */ diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_batched_ray_cast.h b/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_batched_ray_cast.h new file mode 100644 index 000000000..5ecb90c4f --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_batched_ray_cast.h @@ -0,0 +1,38 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_BATCHED_RAY_CAST_H +#define _SCE_PFX_BATCHED_RAY_CAST_H + +#include "../../base_level/rigidbody/pfx_rigid_state.h" +#include "../../base_level/collision/pfx_collidable.h" +#include "../../base_level/broadphase/pfx_broadphase_proxy.h" +#include "../task/pfx_task_manager.h" +#include "pfx_ray_cast.h" + +/////////////////////////////////////////////////////////////////////////////// +// Batched RayCast +namespace sce { +namespace PhysicsEffects { + +void pfxCastRays(PfxRayInput *rayInputs,PfxRayOutput *rayOutputs,int numRays,PfxRayCastParam ¶m); + +void pfxCastRays(PfxRayInput *rayInputs,PfxRayOutput *rayOutputs,int numRays,PfxRayCastParam ¶m,PfxTaskManager *taskManager); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_BATCHED_RAY_CAST_H diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_collision_detection.h b/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_collision_detection.h new file mode 100644 index 000000000..3838fb92a --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_collision_detection.h @@ -0,0 +1,48 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_COLLISION_DETECTION_H_ +#define _SCE_PFX_COLLISION_DETECTION_H_ + +#include "../../base_level/rigidbody/pfx_rigid_state.h" +#include "../../base_level/collision/pfx_collidable.h" +#include "../../base_level/collision/pfx_contact_manifold.h" +#include "../../base_level/solver/pfx_constraint_pair.h" +#include "../task/pfx_task_manager.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// Detect Collision + +struct PfxDetectCollisionParam { + PfxConstraintPair *contactPairs; + PfxUInt32 numContactPairs; + PfxContactManifold *offsetContactManifolds; + PfxRigidState *offsetRigidStates; + PfxCollidable *offsetCollidables; + PfxUInt32 numRigidBodies; +}; + +PfxInt32 pfxDetectCollision(PfxDetectCollisionParam ¶m); + +PfxInt32 pfxDetectCollision(PfxDetectCollisionParam ¶m,PfxTaskManager *taskManager); + +} //namespace PhysicsEffects +} //namespace sce + +#endif /* _SCE_PFX_COLLISION_DETECTION_H_ */ diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_island_generation.h b/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_island_generation.h new file mode 100644 index 000000000..cb01d255b --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_island_generation.h @@ -0,0 +1,78 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_ISLAND_GENERATION_H_ +#define _SCE_PFX_ISLAND_GENERATION_H_ + +#include "../../base_level/solver/pfx_constraint_pair.h" +#include "../task/pfx_task_manager.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// Island Generation + +struct PfxIsland; +struct PfxIslandUnit; + +struct PfxGenerateIslandParam { + void *islandBuff; + PfxUInt32 islandBytes; + PfxConstraintPair *pairs; + PfxUInt32 numPairs; + PfxUInt32 numObjects; +}; + +struct PfxGenerateIslandResult { + PfxIsland *island; +}; + +//J アイランド情報を使い終わるまでislandBuffを破棄しないでください +//E Keep islandBuff while the island is used +PfxUInt32 pfxGetIslandBytesOfGenerateIsland(PfxUInt32 numObjects); + +PfxInt32 pfxGenerateIsland(PfxGenerateIslandParam ¶m,PfxGenerateIslandResult &result); + +//E Access to island information +//J アイランド情報へのアクセス + +//E Get the number of islands +//J アイランド数を取得する +PfxUInt32 pfxGetNumIslands(const PfxIsland *islands); + +//E Get a island unit in a island +//J 指定したアイランドに含まれるユニット(剛体)にアクセス +PfxIslandUnit *pfxGetFirstUnitInIsland(const PfxIsland *islands,PfxUInt32 islandId); +PfxIslandUnit *pfxGetNextUnitInIsland(const PfxIslandUnit *islandUnit); +PfxUInt32 pfxGetUnitId(const PfxIslandUnit *islandUnit); + +//E Get an index of an island which includes a specific unit +//J 指定したユニット(剛体)のアイランドインデックスを取得する +PfxUInt32 pfxGetIslandId(const PfxIsland *islands,PfxUInt32 unitId); + +//E Add pairs and construct islands +//J アイランドにペアを追加する +PfxInt32 pfxAppendPairs(PfxIsland *island,PfxConstraintPair *pairs,PfxUInt32 numPairs); + +//E Reset islands +//J アイランドリセット +void pfxResetIsland(PfxIsland *island); + +} //namespace PhysicsEffects +} //namespace sce + +#endif /* _SCE_PFX_ISLAND_GENERATION_H_ */ diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_ray_cast.h b/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_ray_cast.h new file mode 100644 index 000000000..3bfba4054 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_ray_cast.h @@ -0,0 +1,50 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_RAY_CAST_H +#define _SCE_PFX_RAY_CAST_H + +#include "../../base_level/rigidbody/pfx_rigid_state.h" +#include "../../base_level/collision/pfx_collidable.h" +#include "../../base_level/collision/pfx_ray.h" +#include "../../base_level/broadphase/pfx_broadphase_proxy.h" + +/////////////////////////////////////////////////////////////////////////////// +// RayCast + +namespace sce { +namespace PhysicsEffects { + +struct PfxRayCastParam { + PfxRigidState *offsetRigidStates; + PfxCollidable *offsetCollidables; + PfxBroadphaseProxy *proxiesX; + PfxBroadphaseProxy *proxiesY; + PfxBroadphaseProxy *proxiesZ; + PfxBroadphaseProxy *proxiesXb; + PfxBroadphaseProxy *proxiesYb; + PfxBroadphaseProxy *proxiesZb; + PfxUInt32 numProxies; + SCE_PFX_PADDING(1,12) + PfxVector3 rangeCenter; + PfxVector3 rangeExtent; +}; + +void pfxCastSingleRay(const PfxRayInput &rayInput,PfxRayOutput &rayOutput,const PfxRayCastParam ¶m); + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_RAY_CAST_H diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_refresh_contacts.h b/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_refresh_contacts.h new file mode 100644 index 000000000..10cf10438 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/collision/pfx_refresh_contacts.h @@ -0,0 +1,46 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_REFRESH_CONTACTS_H +#define _SCE_PFX_REFRESH_CONTACTS_H + +#include "../../base_level/rigidbody/pfx_rigid_state.h" +#include "../../base_level/solver/pfx_constraint_pair.h" +#include "../../base_level/collision/pfx_contact_manifold.h" +#include "../task/pfx_task_manager.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// Refresh Contacts + +struct PfxRefreshContactsParam { + PfxConstraintPair *contactPairs; + PfxUInt32 numContactPairs; + PfxContactManifold *offsetContactManifolds; + PfxRigidState *offsetRigidStates; + PfxUInt32 numRigidBodies; +}; + +PfxInt32 pfxRefreshContacts(PfxRefreshContactsParam ¶m); + +PfxInt32 pfxRefreshContacts(PfxRefreshContactsParam ¶m,PfxTaskManager *taskManager); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_REFRESH_CONTACTS_H diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/pfx_low_level_include.h b/Extras/PhysicsEffects/include/physics_effects/low_level/pfx_low_level_include.h new file mode 100644 index 000000000..5b513c71e --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/pfx_low_level_include.h @@ -0,0 +1,46 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_LOW_LEVEL_INCLUDE_H +#define _SCE_PFX_LOW_LEVEL_INCLUDE_H + +/////////////////////////////////////////////////////////////////////////////// +// Physics Effects Low Level Headers + +// Include base level headers +#include "../base_level/pfx_base_level_include.h" + +// Include low level headers +#include "broadphase/pfx_broadphase.h" + +#include "collision/pfx_collision_detection.h" +#include "collision/pfx_refresh_contacts.h" +#include "collision/pfx_batched_ray_cast.h" +#include "collision/pfx_ray_cast.h" +#include "collision/pfx_island_generation.h" + +#include "solver/pfx_constraint_solver.h" +#include "solver/pfx_update_rigid_states.h" + +#include "sort/pfx_parallel_sort.h" + +// ARA begin insert new code +#ifdef USE_PTHREADS +#include "task/pfx_pthreads.h" +#endif +// ARA end + +#endif // _SCE_PFX_LOW_LEVEL_INCLUDE_H diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/solver/pfx_constraint_solver.h b/Extras/PhysicsEffects/include/physics_effects/low_level/solver/pfx_constraint_solver.h new file mode 100644 index 000000000..64837d495 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/solver/pfx_constraint_solver.h @@ -0,0 +1,123 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONSTRAINT_SOLVER_H +#define _SCE_PFX_CONSTRAINT_SOLVER_H + +#include "../../base_level/rigidbody/pfx_rigid_body.h" +#include "../../base_level/rigidbody/pfx_rigid_state.h" +#include "../../base_level/solver/pfx_solver_body.h" +#include "../../base_level/solver/pfx_constraint_pair.h" +#include "../../base_level/solver/pfx_joint.h" +#include "../../base_level/collision/pfx_contact_manifold.h" + +#include "../task/pfx_task_manager.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// Setup Solver Bodies + +struct PfxSetupSolverBodiesParam { + PfxRigidState *states; + PfxRigidBody *bodies; + PfxSolverBody *solverBodies; + PfxUInt32 numRigidBodies; +}; + +PfxInt32 pfxSetupSolverBodies(PfxSetupSolverBodiesParam ¶m); + +PfxInt32 pfxSetupSolverBodies(PfxSetupSolverBodiesParam ¶m,PfxTaskManager *taskManager); + +/////////////////////////////////////////////////////////////////////////////// +// Setup Constraints + +struct PfxSetupContactConstraintsParam { + PfxConstraintPair *contactPairs; + PfxUInt32 numContactPairs; + PfxContactManifold *offsetContactManifolds; + PfxRigidState *offsetRigidStates; + PfxRigidBody *offsetRigidBodies; + PfxSolverBody *offsetSolverBodies; + PfxUInt32 numRigidBodies; + PfxFloat timeStep; + PfxFloat separateBias; + + PfxSetupContactConstraintsParam() + { + timeStep = 0.016f; + separateBias = 0.2f; + } +}; + +PfxInt32 pfxSetupContactConstraints(PfxSetupContactConstraintsParam ¶m); + +PfxInt32 pfxSetupContactConstraints(PfxSetupContactConstraintsParam ¶m,PfxTaskManager *taskManager); + +struct PfxSetupJointConstraintsParam { + PfxConstraintPair *jointPairs; + PfxUInt32 numJointPairs; + PfxJoint *offsetJoints; + PfxRigidState *offsetRigidStates; + PfxRigidBody *offsetRigidBodies; + PfxSolverBody *offsetSolverBodies; + PfxUInt32 numRigidBodies; + PfxFloat timeStep; + + PfxSetupJointConstraintsParam() + { + timeStep = 0.016f; + } +}; + +PfxInt32 pfxSetupJointConstraints(PfxSetupJointConstraintsParam ¶m); + +PfxInt32 pfxSetupJointConstraints(PfxSetupJointConstraintsParam ¶m,PfxTaskManager *taskManager); + +/////////////////////////////////////////////////////////////////////////////// +// Solve Constraints + +struct PfxSolveConstraintsParam { + void *workBuff; + PfxUInt32 workBytes; + PfxConstraintPair *contactPairs; + PfxUInt32 numContactPairs; + PfxContactManifold *offsetContactManifolds; + PfxConstraintPair *jointPairs; + PfxUInt32 numJointPairs; + PfxJoint *offsetJoints; + PfxRigidState *offsetRigidStates; + PfxSolverBody *offsetSolverBodies; + PfxUInt32 numRigidBodies; + PfxUInt32 iteration; + + PfxSolveConstraintsParam() + { + iteration = 5; + } +}; + +PfxUInt32 pfxGetWorkBytesOfSolveConstraints(PfxUInt32 numRigidBodies,PfxUInt32 numContactPairs,PfxUInt32 numJointPairs,PfxUInt32 maxTasks=1); + +PfxInt32 pfxSolveConstraints(PfxSolveConstraintsParam ¶m); + +PfxInt32 pfxSolveConstraints(PfxSolveConstraintsParam ¶m,PfxTaskManager *taskManager); + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_CONSTRAINT_SOLVER_H + diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/solver/pfx_joint_constraint_func.h b/Extras/PhysicsEffects/include/physics_effects/low_level/solver/pfx_joint_constraint_func.h new file mode 100644 index 000000000..d8e6d4e6e --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/solver/pfx_joint_constraint_func.h @@ -0,0 +1,69 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_JOINT_CONSTRAINT_FUNC_H_ +#define _SCE_PFX_JOINT_CONSTRAINT_FUNC_H_ + +#include "../../base_level/rigidbody/pfx_rigid_state.h" +#include "../../base_level/solver/pfx_solver_body.h" +#include "../../base_level/solver/pfx_joint.h" +#include "../../base_level/solver/pfx_joint_constraint.h" + +namespace sce { +namespace PhysicsEffects { +/////////////////////////////////////////////////////////////////////////////// +// Setup Joint Constraint Func + +typedef void (*PfxSetupJointConstraintFunc)( + PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + PfxFloat timeStep); + +PfxSetupJointConstraintFunc pfxGetSetupJointConstraintFunc(PfxUInt8 jointType); + +int pfxSetSetupJointConstraintFunc(PfxUInt8 jointType,PfxSetupJointConstraintFunc func); + +/////////////////////////////////////////////////////////////////////////////// +// Warm Start Joint Constraint Func + +typedef void (*PfxWarmStartJointConstraintFunc)( + PfxJoint &joint, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB); + +PfxWarmStartJointConstraintFunc pfxGetWarmStartJointConstraintFunc(PfxUInt8 jointType); + +int pfxSetWarmStartJointConstraintFunc(PfxUInt8 jointType,PfxWarmStartJointConstraintFunc func); + +/////////////////////////////////////////////////////////////////////////////// +// Solve Joint Constraint Func + +typedef void (*PfxSolveJointConstraintFunc)( + PfxJoint &joint, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB); + +PfxSolveJointConstraintFunc pfxGetSolveJointConstraintFunc(PfxUInt8 jointType); + +int pfxSetSolveJointConstraintFunc(PfxUInt8 jointType,PfxSolveJointConstraintFunc func); + +} //namespace PhysicsEffects +} //namespace sce + +#endif /* _PFX_JOINT_CONSTRAINT_FUNC_H_ */ diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/solver/pfx_update_rigid_states.h b/Extras/PhysicsEffects/include/physics_effects/low_level/solver/pfx_update_rigid_states.h new file mode 100644 index 000000000..b16a81eb2 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/solver/pfx_update_rigid_states.h @@ -0,0 +1,45 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_UPDATE_RIGID_STATES_H_ +#define _SCE_PFX_UPDATE_RIGID_STATES_H_ + +#include "../../base_level/rigidbody/pfx_rigid_body.h" +#include "../../base_level/rigidbody/pfx_rigid_state.h" + +#include "../task/pfx_task_manager.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// Update Rigid Body States + +struct PfxUpdateRigidStatesParam { + PfxRigidState *states; + PfxRigidBody *bodies; + PfxUInt32 numRigidBodies; + PfxFloat timeStep; +}; + +PfxInt32 pfxUpdateRigidStates(PfxUpdateRigidStatesParam ¶m); + +PfxInt32 pfxUpdateRigidStates(PfxUpdateRigidStatesParam ¶m,PfxTaskManager *taskManager); + +} //namespace PhysicsEffects +} //namespace sce + +#endif /* _SCE_PFX_UPDATE_RIGID_STATES_H_ */ diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/sort/pfx_parallel_sort.h b/Extras/PhysicsEffects/include/physics_effects/low_level/sort/pfx_parallel_sort.h new file mode 100644 index 000000000..66d3b1575 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/sort/pfx_parallel_sort.h @@ -0,0 +1,40 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_PARALLEL_SORT_H +#define _SCE_PFX_PARALLEL_SORT_H + +#include "../../base_level/sort/pfx_sort_data.h" +#include "../task/pfx_task_manager.h" + +/////////////////////////////////////////////////////////////////////////////// +// Parallel Sort +namespace sce { +namespace PhysicsEffects { + +PfxInt32 pfxParallelSort(PfxSortData16 *data,PfxUInt32 numData,void *workBuff,PfxUInt32 workBytes); + +PfxInt32 pfxParallelSort(PfxSortData32 *data,PfxUInt32 numData,void *workBuff,PfxUInt32 workBytes); + +PfxInt32 pfxParallelSort(PfxSortData16 *data,PfxUInt32 numData,void *workBuff,PfxUInt32 workBytes, + PfxTaskManager *taskManager); + +PfxInt32 pfxParallelSort(PfxSortData32 *data,PfxUInt32 numData,void *workBuff,PfxUInt32 workBytes, + PfxTaskManager *taskManager); + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_PARALLEL_SORT_H diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/task/pfx_pthreads.h b/Extras/PhysicsEffects/include/physics_effects/low_level/task/pfx_pthreads.h new file mode 100644 index 000000000..3b38faefa --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/task/pfx_pthreads.h @@ -0,0 +1,55 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _SCE_PFX_PTHREADS_H +#define _SCE_PFX_PTHREADS_H + +#include "../../base_level/base/pfx_common.h" +#include + +namespace sce { +namespace PhysicsEffects { + +class PfxBarrier; +class PfxCriticalSection; +class PfxTaskManager; + +#define SCE_PFX_CHECK_PTHREADS_OUTCOME(result) \ + if(0 != result) \ + { \ + SCE_PFX_PRINTF("pthreads problem at line %i in file %s: %i %d\n", __LINE__, __FILE__, result, errno); \ + } + +PfxBarrier *PfxCreateBarrierPthreads(int n); +PfxCriticalSection *PfxCreateCriticalSectionPthreads(); +PfxTaskManager *PfxCreateTaskManagerPthreads(PfxUInt32 numTasks,PfxUInt32 maxTasks,void *workBuff,PfxUInt32 workBytes); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_PTHREADS_H diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/task/pfx_sync_components.h b/Extras/PhysicsEffects/include/physics_effects/low_level/task/pfx_sync_components.h new file mode 100644 index 000000000..1f64672f3 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/task/pfx_sync_components.h @@ -0,0 +1,53 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_SYNC_COMPONENTS_H +#define _SCE_PFX_SYNC_COMPONENTS_H + +#include "../../base_level/base/pfx_common.h" + +//J スレッド間の同期をとるための同期コンポネント +//E Components for threads sychronization +namespace sce { +namespace PhysicsEffects { + +class PfxBarrier { +public: + PfxBarrier() {} + virtual ~PfxBarrier() {} + + virtual void sync() = 0; + virtual void setMaxCount(int n) = 0; + virtual int getMaxCount() = 0; +}; + +class PfxCriticalSection { +public: + PfxCriticalSection() {} + virtual ~PfxCriticalSection() {} + +PfxUInt32 m_commonBuff[32]; + + virtual PfxUInt32 getSharedParam(int i) = 0; + virtual void setSharedParam(int i,PfxUInt32 p) = 0; + + virtual void lock() = 0; + virtual void unlock() = 0; +}; + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_SYNC_COMPONENTS_H diff --git a/Extras/PhysicsEffects/include/physics_effects/low_level/task/pfx_task_manager.h b/Extras/PhysicsEffects/include/physics_effects/low_level/task/pfx_task_manager.h new file mode 100644 index 000000000..5f398c1d1 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/low_level/task/pfx_task_manager.h @@ -0,0 +1,96 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_TASK_MANAGER_H +#define _SCE_PFX_TASK_MANAGER_H + +#include "../../base_level/base/pfx_common.h" +#include "../../base_level/base/pfx_heap_manager.h" +#include "pfx_sync_components.h" + +#define SCE_PFX_IO_BUFF_BYTES 1048576 +namespace sce { +namespace PhysicsEffects { + +//J 並列処理するためのタスクマネージャクラス +//E Task manager class for parallel computation + +struct PfxTaskArg +{ + int taskId; + int maxTasks; + PfxBarrier *barrier; + PfxCriticalSection *criticalSection; + void *io; + PfxUInt32 data[4]; +}; + +typedef void (*PfxTaskEntry)(PfxTaskArg *arg); + +class PfxTaskManager +{ +protected: + PfxUInt32 m_numTasks; + PfxUInt32 m_maxTasks; + SCE_PFX_PADDING(1,4) + PfxUInt8 SCE_PFX_ALIGNED(16) m_ioBuff[SCE_PFX_IO_BUFF_BYTES]; + PfxHeapManager m_pool; + PfxHeapManager m_ioPool; + PfxTaskEntry m_taskEntry; + PfxTaskArg *m_taskArg; + SCE_PFX_PADDING(2,8) + + PfxTaskManager() : m_pool(NULL,0),m_ioPool(NULL,0) {} + +public: + void *allocate(size_t bytes) {return m_ioPool.allocate(bytes);} + void deallocate(void *p) {m_ioPool.deallocate(p);} + void clearPool() {m_ioPool.clear();} + + virtual PfxUInt32 getSharedParam(int i) = 0; + virtual void setSharedParam(int i,PfxUInt32 p) = 0; + + virtual void startTask(int taskId,void *io,PfxUInt32 data1,PfxUInt32 data2,PfxUInt32 data3,PfxUInt32 data4) = 0; + virtual void waitTask(int &taskId,PfxUInt32 &data1,PfxUInt32 &data2,PfxUInt32 &data3,PfxUInt32 &data4) = 0; + + virtual void setTaskEntry(void *entry) {m_taskEntry = (PfxTaskEntry)entry;} + +public: + PfxTaskManager(PfxUInt32 numTasks,PfxUInt32 maxTasks,void *workBuff,PfxUInt32 workBytes) + : m_pool((unsigned char*)workBuff,workBytes),m_ioPool(m_ioBuff,SCE_PFX_IO_BUFF_BYTES) + { + SCE_PFX_ASSERT(numTasks>0); + SCE_PFX_ASSERT(numTasks<=maxTasks); + m_numTasks = numTasks; + m_maxTasks = maxTasks; + m_taskArg = (PfxTaskArg*)m_pool.allocate(sizeof(PfxTaskArg)*m_maxTasks); + } + + virtual ~PfxTaskManager() + { + m_pool.clear(); + } + + virtual PfxUInt32 getNumTasks() const {return m_numTasks;} + virtual void setNumTasks(PfxUInt32 tasks) {m_numTasks = SCE_PFX_MIN(tasks,m_maxTasks);} + + virtual void initialize() = 0; + virtual void finalize() = 0; +}; + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_TASK_MANAGER_H \ No newline at end of file diff --git a/Extras/PhysicsEffects/include/physics_effects/util/pfx_mass.h b/Extras/PhysicsEffects/include/physics_effects/util/pfx_mass.h new file mode 100644 index 000000000..14d70d40a --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/util/pfx_mass.h @@ -0,0 +1,60 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +/////////////////////////////////////////////////////////////////////////////// +//E Mass , Inertia tensor calculation +//J 質量・慣性テンソルの算出 + +#ifndef _SCE_PFX_MASS_H +#define _SCE_PFX_MASS_H + +#include "../base_level/base/pfx_common.h" + +namespace sce { +namespace PhysicsEffects { + +// Box +PfxFloat pfxCalcMassBox(PfxFloat density,const PfxVector3 &halfExtent); +PfxMatrix3 pfxCalcInertiaBox(const PfxVector3 &halfExtent,PfxFloat mass); + +// Sphere +PfxFloat pfxCalcMassSphere(PfxFloat density,PfxFloat radius); +PfxMatrix3 pfxCalcInertiaSphere(PfxFloat radius,PfxFloat mass); + +// Cylinder +PfxFloat pfxCalcMassCylinder(PfxFloat density,PfxFloat halfLength,PfxFloat radius); +PfxMatrix3 pfxCalcInertiaCylinderX(PfxFloat halfLength,PfxFloat radius,PfxFloat mass); +PfxMatrix3 pfxCalcInertiaCylinderY(PfxFloat halfLength,PfxFloat radius,PfxFloat mass); +PfxMatrix3 pfxCalcInertiaCylinderZ(PfxFloat halfLength,PfxFloat radius,PfxFloat mass); + +/////////////////////////////////////////////////////////////////////////////// +//E Mass convertion +//J 質量の移動・回転・合成 + +// translation +//E returns translated inertia tensor +//J 移動後の慣性テンソルを返します +PfxMatrix3 pfxMassTranslate(PfxFloat mass,const PfxMatrix3 &inertia,const PfxVector3 &translation); + +// rotation +//E returns rotated inertia tensor +//J 回転後の慣性テンソルを返します +PfxMatrix3 pfxMassRotate(const PfxMatrix3 &inertia,const PfxMatrix3 &rotate); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_MASS_H diff --git a/Extras/PhysicsEffects/include/physics_effects/util/pfx_mesh_creator.h b/Extras/PhysicsEffects/include/physics_effects/util/pfx_mesh_creator.h new file mode 100644 index 000000000..f481dd1e4 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/util/pfx_mesh_creator.h @@ -0,0 +1,96 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_MESH_CREATOR_H +#define _SCE_PFX_MESH_CREATOR_H + +#include "../base_level/collision/pfx_large_tri_mesh.h" + +namespace sce { +namespace PhysicsEffects { + +//J フラグに指定する値 +//E Specify these values to a flag parameter +#define SCE_PFX_MESH_FLAG_NORMAL_FLIP 0x01 +#define SCE_PFX_MESH_FLAG_16BIT_INDEX 0x02 +#define SCE_PFX_MESH_FLAG_32BIT_INDEX 0x04 +#define SCE_PFX_MESH_FLAG_AUTO_ELIMINATION 0x08 +#define SCE_PFX_MESH_FLAG_AUTO_THICKNESS 0x10 + +/////////////////////////////////////////////////////////////////////////////// +// Convex Mesh + +struct PfxCreateConvexMeshParam { + PfxUInt32 flag; + PfxFloat *verts; + PfxUInt32 numVerts; + void *triangles; + PfxUInt32 numTriangles; + PfxUInt32 vertexStrideBytes; + PfxUInt32 triangleStrideBytes; + + PfxCreateConvexMeshParam() + { + flag = SCE_PFX_MESH_FLAG_16BIT_INDEX|SCE_PFX_MESH_FLAG_AUTO_ELIMINATION; + verts = NULL; + triangles = NULL; + numVerts = 0; + numTriangles = 0; + vertexStrideBytes = sizeof(PfxFloat)*3; + triangleStrideBytes = sizeof(PfxUInt16)*3; + } +}; + +PfxInt32 pfxCreateConvexMesh(PfxConvexMesh &convex,const PfxCreateConvexMeshParam ¶m); + +/////////////////////////////////////////////////////////////////////////////// +// Large Mesh + +struct PfxCreateLargeTriMeshParam { + PfxUInt32 flag; + PfxFloat *verts; + PfxUInt32 numVerts; + void *triangles; + PfxUInt32 numTriangles; + PfxUInt32 vertexStrideBytes; + PfxUInt32 triangleStrideBytes; + PfxUInt32 numFacetsLimit; + PfxFloat islandsRatio; + PfxFloat defaultThickness; + + PfxCreateLargeTriMeshParam() + { + flag = SCE_PFX_MESH_FLAG_16BIT_INDEX|SCE_PFX_MESH_FLAG_AUTO_ELIMINATION; + verts = NULL; + triangles = NULL; + numVerts = 0; + numTriangles = 0; + vertexStrideBytes = sizeof(PfxFloat)*3; + triangleStrideBytes = sizeof(PfxUInt16)*3; + numFacetsLimit = 15; + islandsRatio = 0.2f; + defaultThickness = 0.025f; + } +}; + +PfxInt32 pfxCreateLargeTriMesh(PfxLargeTriMesh &lmesh,const PfxCreateLargeTriMeshParam ¶m); + +void pfxReleaseLargeTriMesh(PfxLargeTriMesh &lmesh); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_MESH_CREATOR_H diff --git a/Extras/PhysicsEffects/include/physics_effects/util/pfx_util_include.h b/Extras/PhysicsEffects/include/physics_effects/util/pfx_util_include.h new file mode 100644 index 000000000..0e637b222 --- /dev/null +++ b/Extras/PhysicsEffects/include/physics_effects/util/pfx_util_include.h @@ -0,0 +1,26 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_UTIL_INCLUDE_H +#define _SCE_PFX_UTIL_INCLUDE_H + +/////////////////////////////////////////////////////////////////////////////// +// Physics Effects Utility Headers + +#include "pfx_mass.h" +#include "pfx_mesh_creator.h" + +#endif // _SCE_PFX_UTIL_INCLUDE_H diff --git a/Extras/PhysicsEffects/include/vecmath/neon/boolInVec.h b/Extras/PhysicsEffects/include/vecmath/neon/boolInVec.h new file mode 100644 index 000000000..7ea380f91 --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/neon/boolInVec.h @@ -0,0 +1,238 @@ +/* + Copyright (C) 2006-2010 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _BOOLINVEC_SCALAR_H +#define _BOOLINVEC_SCALAR_H + +#include +namespace Vectormath { + +class floatInVec; + +//-------------------------------------------------------------------------------------------------- +// boolInVec class +// + +class boolInVec +{ +private: + unsigned int mData; + +public: + // Default constructor; does no initialization + // + inline boolInVec( ) { }; + + // Construct from a value converted from float + // + inline boolInVec(floatInVec vec); + + // Explicit cast from bool + // + explicit inline boolInVec(bool scalar); + + // Explicit cast to bool + // + inline bool getAsBool() const; + +#ifndef _VECTORMATH_NO_SCALAR_CAST + // Implicit cast to bool + // + inline operator bool() const; +#endif + + // Boolean negation operator + // + inline const boolInVec operator ! () const; + + // Assignment operator + // + inline boolInVec& operator = (boolInVec vec); + + // Boolean and assignment operator + // + inline boolInVec& operator &= (boolInVec vec); + + // Boolean exclusive or assignment operator + // + inline boolInVec& operator ^= (boolInVec vec); + + // Boolean or assignment operator + // + inline boolInVec& operator |= (boolInVec vec); + +}; + +// Equal operator +// +inline const boolInVec operator == (boolInVec vec0, boolInVec vec1); + +// Not equal operator +// +inline const boolInVec operator != (boolInVec vec0, boolInVec vec1); + +// And operator +// +inline const boolInVec operator & (boolInVec vec0, boolInVec vec1); + +// Exclusive or operator +// +inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1); + +// Or operator +// +inline const boolInVec operator | (boolInVec vec0, boolInVec vec1); + +// Conditionally select between two values +// +inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1); + + +} // namespace Vectormath + + +//-------------------------------------------------------------------------------------------------- +// boolInVec implementation +// + +#include "floatInVec.h" + +namespace Vectormath { + +inline +boolInVec::boolInVec(floatInVec vec) +{ + *this = (vec != floatInVec(0.0f)); +} + +inline +boolInVec::boolInVec(bool scalar) +{ + mData = -(int)scalar; +} + +inline +bool +boolInVec::getAsBool() const +{ + return (mData > 0); +} + +#ifndef _VECTORMATH_NO_SCALAR_CAST +inline +boolInVec::operator bool() const +{ + return getAsBool(); +} +#endif + +inline +const boolInVec +boolInVec::operator ! () const +{ + return boolInVec(!mData); +} + +inline +boolInVec& +boolInVec::operator = (boolInVec vec) +{ + mData = vec.mData; + return *this; +} + +inline +boolInVec& +boolInVec::operator &= (boolInVec vec) +{ + *this = *this & vec; + return *this; +} + +inline +boolInVec& +boolInVec::operator ^= (boolInVec vec) +{ + *this = *this ^ vec; + return *this; +} + +inline +boolInVec& +boolInVec::operator |= (boolInVec vec) +{ + *this = *this | vec; + return *this; +} + +inline +const boolInVec +operator == (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() == vec1.getAsBool()); +} + +inline +const boolInVec +operator != (boolInVec vec0, boolInVec vec1) +{ + return !(vec0 == vec1); +} + +inline +const boolInVec +operator & (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() & vec1.getAsBool()); +} + +inline +const boolInVec +operator | (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() | vec1.getAsBool()); +} + +inline +const boolInVec +operator ^ (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() ^ vec1.getAsBool()); +} + +inline +const boolInVec +select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1) +{ + return (select_vec1.getAsBool() == 0) ? vec0 : vec1; +} + +} // namespace Vectormath + +#endif // boolInVec_h diff --git a/Extras/PhysicsEffects/include/vecmath/neon/floatInVec.h b/Extras/PhysicsEffects/include/vecmath/neon/floatInVec.h new file mode 100644 index 000000000..1aa2ee1cc --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/neon/floatInVec.h @@ -0,0 +1,357 @@ +/* + Copyright (C) 2006-2010 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _FLOATINVEC__SCALAR_H +#define _FLOATINVEC__SCALAR_H + +#include +namespace Vectormath { + +class boolInVec; + +//-------------------------------------------------------------------------------------------------- +// floatInVec class +// + +// A class representing a scalar float value contained in a vector register +// This class does not support fastmath +class floatInVec +{ +private: + float mData; + +public: + // Default constructor; does no initialization + // + inline floatInVec( ) { }; + + // Construct from a value converted from bool + // + inline floatInVec(boolInVec vec); + + // Explicit cast from float + // + explicit inline floatInVec(float scalar); + + // Explicit cast to float + // + inline float getAsFloat() const; + +#ifndef _VECTORMATH_NO_SCALAR_CAST + // Implicit cast to float + // + inline operator float() const; +#endif + + // Post increment (add 1.0f) + // + inline const floatInVec operator ++ (int); + + // Post decrement (subtract 1.0f) + // + inline const floatInVec operator -- (int); + + // Pre increment (add 1.0f) + // + inline floatInVec& operator ++ (); + + // Pre decrement (subtract 1.0f) + // + inline floatInVec& operator -- (); + + // Negation operator + // + inline const floatInVec operator - () const; + + // Assignment operator + // + inline floatInVec& operator = (floatInVec vec); + + // Multiplication assignment operator + // + inline floatInVec& operator *= (floatInVec vec); + + // Division assignment operator + // + inline floatInVec& operator /= (floatInVec vec); + + // Addition assignment operator + // + inline floatInVec& operator += (floatInVec vec); + + // Subtraction assignment operator + // + inline floatInVec& operator -= (floatInVec vec); + +}; + +// Multiplication operator +// +inline const floatInVec operator * (floatInVec vec0, floatInVec vec1); + +// Division operator +// +inline const floatInVec operator / (floatInVec vec0, floatInVec vec1); + +// Addition operator +// +inline const floatInVec operator + (floatInVec vec0, floatInVec vec1); + +// Subtraction operator +// +inline const floatInVec operator - (floatInVec vec0, floatInVec vec1); + +// Less than operator +// +inline const boolInVec operator < (floatInVec vec0, floatInVec vec1); + +// Less than or equal operator +// +inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1); + +// Greater than operator +// +inline const boolInVec operator > (floatInVec vec0, floatInVec vec1); + +// Greater than or equal operator +// +inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1); + +// Equal operator +// +inline const boolInVec operator == (floatInVec vec0, floatInVec vec1); + +// Not equal operator +// +inline const boolInVec operator != (floatInVec vec0, floatInVec vec1); + +// Conditionally select between two values +// +inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1); + + +} // namespace Vectormath + + +//-------------------------------------------------------------------------------------------------- +// floatInVec implementation +// + +#include "boolInVec.h" + +namespace Vectormath { + +inline +floatInVec::floatInVec(boolInVec vec) +{ + mData = float(vec.getAsBool()); +} + +inline +floatInVec::floatInVec(float scalar) +{ + mData = scalar; +} + +inline +float +floatInVec::getAsFloat() const +{ + return mData; +} + +#ifndef _VECTORMATH_NO_SCALAR_CAST +inline +floatInVec::operator float() const +{ + return getAsFloat(); +} +#endif + +inline +const floatInVec +floatInVec::operator ++ (int) +{ + float olddata = mData; + operator ++(); + return floatInVec(olddata); +} + +inline +const floatInVec +floatInVec::operator -- (int) +{ + float olddata = mData; + operator --(); + return floatInVec(olddata); +} + +inline +floatInVec& +floatInVec::operator ++ () +{ + *this += floatInVec(1.0f); + return *this; +} + +inline +floatInVec& +floatInVec::operator -- () +{ + *this -= floatInVec(1.0f); + return *this; +} + +inline +const floatInVec +floatInVec::operator - () const +{ + return floatInVec(-mData); +} + +inline +floatInVec& +floatInVec::operator = (floatInVec vec) +{ + mData = vec.mData; + return *this; +} + +inline +floatInVec& +floatInVec::operator *= (floatInVec vec) +{ + *this = *this * vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator /= (floatInVec vec) +{ + *this = *this / vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator += (floatInVec vec) +{ + *this = *this + vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator -= (floatInVec vec) +{ + *this = *this - vec; + return *this; +} + +inline +const floatInVec +operator * (floatInVec vec0, floatInVec vec1) +{ + return floatInVec(vec0.getAsFloat() * vec1.getAsFloat()); +} + +inline +const floatInVec +operator / (floatInVec num, floatInVec den) +{ + return floatInVec(num.getAsFloat() / den.getAsFloat()); +} + +inline +const floatInVec +operator + (floatInVec vec0, floatInVec vec1) +{ + return floatInVec(vec0.getAsFloat() + vec1.getAsFloat()); +} + +inline +const floatInVec +operator - (floatInVec vec0, floatInVec vec1) +{ + return floatInVec(vec0.getAsFloat() - vec1.getAsFloat()); +} + +inline +const boolInVec +operator < (floatInVec vec0, floatInVec vec1) +{ + return boolInVec(vec0.getAsFloat() < vec1.getAsFloat()); +} + +inline +const boolInVec +operator <= (floatInVec vec0, floatInVec vec1) +{ + return !(vec0 > vec1); +} + +inline +const boolInVec +operator > (floatInVec vec0, floatInVec vec1) +{ + return boolInVec(vec0.getAsFloat() > vec1.getAsFloat()); +} + +inline +const boolInVec +operator >= (floatInVec vec0, floatInVec vec1) +{ + return !(vec0 < vec1); +} + +inline +const boolInVec +operator == (floatInVec vec0, floatInVec vec1) +{ + return boolInVec(vec0.getAsFloat() == vec1.getAsFloat()); +} + +inline +const boolInVec +operator != (floatInVec vec0, floatInVec vec1) +{ + return !(vec0 == vec1); +} + +inline +const floatInVec +select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1) +{ + return (select_vec1.getAsBool() == 0) ? vec0 : vec1; +} + +} // namespace Vectormath + +#endif // floatInVec_h diff --git a/Extras/PhysicsEffects/include/vecmath/neon/mat_aos.h b/Extras/PhysicsEffects/include/vecmath/neon/mat_aos.h new file mode 100644 index 000000000..32a6bbe43 --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/neon/mat_aos.h @@ -0,0 +1,1645 @@ +/* + Copyright (C) 2006-2010 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _VECTORMATH_MAT_AOS_CPP__SCALAR_H +#define _VECTORMATH_MAT_AOS_CPP__SCALAR_H + +// ARA begin insert new code +#include "vectormath_neon_assembly_prototypes.h" +// ARA end + +namespace Vectormath { +namespace Aos { + +//----------------------------------------------------------------------------- +// Constants + +#define _VECTORMATH_PI_OVER_2 1.570796327f + +//----------------------------------------------------------------------------- +// Definitions + +inline Matrix3::Matrix3( const Matrix3 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; +} + +inline Matrix3::Matrix3( float scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); +} + +inline Matrix3::Matrix3( const Quat & unitQuat ) +{ + float qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; + qx = unitQuat.getX(); + qy = unitQuat.getY(); + qz = unitQuat.getZ(); + qw = unitQuat.getW(); + qx2 = ( qx + qx ); + qy2 = ( qy + qy ); + qz2 = ( qz + qz ); + qxqx2 = ( qx * qx2 ); + qxqy2 = ( qx * qy2 ); + qxqz2 = ( qx * qz2 ); + qxqw2 = ( qw * qx2 ); + qyqy2 = ( qy * qy2 ); + qyqz2 = ( qy * qz2 ); + qyqw2 = ( qw * qy2 ); + qzqz2 = ( qz * qz2 ); + qzqw2 = ( qw * qz2 ); + mCol0 = Vector3( ( ( 1.0f - qyqy2 ) - qzqz2 ), ( qxqy2 + qzqw2 ), ( qxqz2 - qyqw2 ) ); + mCol1 = Vector3( ( qxqy2 - qzqw2 ), ( ( 1.0f - qxqx2 ) - qzqz2 ), ( qyqz2 + qxqw2 ) ); + mCol2 = Vector3( ( qxqz2 + qyqw2 ), ( qyqz2 - qxqw2 ), ( ( 1.0f - qxqx2 ) - qyqy2 ) ); +} + +inline Matrix3::Matrix3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; +} + +inline Matrix3 & Matrix3::setCol0( const Vector3 & _col0 ) +{ + mCol0 = _col0; + return *this; +} + +inline Matrix3 & Matrix3::setCol1( const Vector3 & _col1 ) +{ + mCol1 = _col1; + return *this; +} + +inline Matrix3 & Matrix3::setCol2( const Vector3 & _col2 ) +{ + mCol2 = _col2; + return *this; +} + +inline Matrix3 & Matrix3::setCol( int col, const Vector3 & vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +inline Matrix3 & Matrix3::setRow( int row, const Vector3 & vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + return *this; +} + +inline Matrix3 & Matrix3::setElem( int col, int row, float val ) +{ + Vector3 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +inline float Matrix3::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +inline const Vector3 Matrix3::getCol0( ) const +{ + return mCol0; +} + +inline const Vector3 Matrix3::getCol1( ) const +{ + return mCol1; +} + +inline const Vector3 Matrix3::getCol2( ) const +{ + return mCol2; +} + +inline const Vector3 Matrix3::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +inline const Vector3 Matrix3::getRow( int row ) const +{ + return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); +} + +inline Vector3 & Matrix3::operator []( int col ) +{ + return *(&mCol0 + col); +} + +inline const Vector3 Matrix3::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +inline Matrix3 & Matrix3::operator =( const Matrix3 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + return *this; +} + +inline const Matrix3 transpose( const Matrix3 & mat ) +{ + return Matrix3( + Vector3( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX() ), + Vector3( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY() ), + Vector3( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ() ) + ); +} + +inline const Matrix3 inverse( const Matrix3 & mat ) +{ + Vector3 tmp0, tmp1, tmp2; + float detinv; + tmp0 = cross( mat.getCol1(), mat.getCol2() ); + tmp1 = cross( mat.getCol2(), mat.getCol0() ); + tmp2 = cross( mat.getCol0(), mat.getCol1() ); + detinv = ( 1.0f / dot( mat.getCol2(), tmp2 ) ); + return Matrix3( + Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ), + Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ), + Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ) + ); +} + +inline float determinant( const Matrix3 & mat ) +{ + return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); +} + +inline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const +{ + return Matrix3( + ( mCol0 + mat.mCol0 ), + ( mCol1 + mat.mCol1 ), + ( mCol2 + mat.mCol2 ) + ); +} + +inline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const +{ + return Matrix3( + ( mCol0 - mat.mCol0 ), + ( mCol1 - mat.mCol1 ), + ( mCol2 - mat.mCol2 ) + ); +} + +inline Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) +{ + *this = *this + mat; + return *this; +} + +inline Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) +{ + *this = *this - mat; + return *this; +} + +inline const Matrix3 Matrix3::operator -( ) const +{ + return Matrix3( + ( -mCol0 ), + ( -mCol1 ), + ( -mCol2 ) + ); +} + +inline const Matrix3 absPerElem( const Matrix3 & mat ) +{ + return Matrix3( + absPerElem( mat.getCol0() ), + absPerElem( mat.getCol1() ), + absPerElem( mat.getCol2() ) + ); +} + +inline const Matrix3 Matrix3::operator *( float scalar ) const +{ + return Matrix3( + ( mCol0 * scalar ), + ( mCol1 * scalar ), + ( mCol2 * scalar ) + ); +} + +inline Matrix3 & Matrix3::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Matrix3 operator *( float scalar, const Matrix3 & mat ) +{ + return mat * scalar; +} + +inline const Vector3 Matrix3::operator *( const Vector3 & vec ) const +{ + return Vector3( + ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), + ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), + ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ); +} + +// ARA begin insert new code +inline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const +{ + Matrix3 __attribute__((__aligned__((64)))) result; + pfxMatrix3Matrix3ProductNEON(*this, mat, result); + return(result); +} +// ARA end + +// ARA begin insert new code +inline Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) +{ + pfxMatrix3Matrix3ProductNEON(*this, mat, *this); + return *this; +} +// ARA end + +inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) +{ + return Matrix3( + mulPerElem( mat0.getCol0(), mat1.getCol0() ), + mulPerElem( mat0.getCol1(), mat1.getCol1() ), + mulPerElem( mat0.getCol2(), mat1.getCol2() ) + ); +} + +inline const Matrix3 Matrix3::identity( ) +{ + return Matrix3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ) + ); +} + +inline const Matrix3 Matrix3::rotationX( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix3( + Vector3::xAxis( ), + Vector3( 0.0f, c, s ), + Vector3( 0.0f, -s, c ) + ); +} + +inline const Matrix3 Matrix3::rotationY( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix3( + Vector3( c, 0.0f, -s ), + Vector3::yAxis( ), + Vector3( s, 0.0f, c ) + ); +} + +inline const Matrix3 Matrix3::rotationZ( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix3( + Vector3( c, s, 0.0f ), + Vector3( -s, c, 0.0f ), + Vector3::zAxis( ) + ); +} + +inline const Matrix3 Matrix3::rotationZYX( const Vector3 & radiansXYZ ) +{ + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf( radiansXYZ.getX() ); + cX = cosf( radiansXYZ.getX() ); + sY = sinf( radiansXYZ.getY() ); + cY = cosf( radiansXYZ.getY() ); + sZ = sinf( radiansXYZ.getZ() ); + cZ = cosf( radiansXYZ.getZ() ); + tmp0 = ( cZ * sY ); + tmp1 = ( sZ * sY ); + return Matrix3( + Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), + Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), + Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ) + ); +} + +inline const Matrix3 Matrix3::rotation( float radians, const Vector3 & unitVec ) +{ + float x, y, z, s, c, oneMinusC, xy, yz, zx; + s = sinf( radians ); + c = cosf( radians ); + x = unitVec.getX(); + y = unitVec.getY(); + z = unitVec.getZ(); + xy = ( x * y ); + yz = ( y * z ); + zx = ( z * x ); + oneMinusC = ( 1.0f - c ); + return Matrix3( + Vector3( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ) ), + Vector3( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ) ), + Vector3( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ) ) + ); +} + +inline const Matrix3 Matrix3::rotation( const Quat & unitQuat ) +{ + return Matrix3( unitQuat ); +} + +inline const Matrix3 Matrix3::scale( const Vector3 & scaleVec ) +{ + return Matrix3( + Vector3( scaleVec.getX(), 0.0f, 0.0f ), + Vector3( 0.0f, scaleVec.getY(), 0.0f ), + Vector3( 0.0f, 0.0f, scaleVec.getZ() ) + ); +} + +inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ) +{ + return Matrix3( + ( mat.getCol0() * scaleVec.getX( ) ), + ( mat.getCol1() * scaleVec.getY( ) ), + ( mat.getCol2() * scaleVec.getZ( ) ) + ); +} + +inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ) +{ + return Matrix3( + mulPerElem( mat.getCol0(), scaleVec ), + mulPerElem( mat.getCol1(), scaleVec ), + mulPerElem( mat.getCol2(), scaleVec ) + ); +} + +inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ) +{ + return Matrix3( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Matrix3 & mat ) +{ + print( mat.getRow( 0 ) ); + print( mat.getRow( 1 ) ); + print( mat.getRow( 2 ) ); +} + +inline void print( const Matrix3 & mat, const char * name ) +{ + printf("%s:\n", name); + print( mat ); +} + +#endif + +inline Matrix4::Matrix4( const Matrix4 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; +} + +inline Matrix4::Matrix4( float scalar ) +{ + mCol0 = Vector4( scalar ); + mCol1 = Vector4( scalar ); + mCol2 = Vector4( scalar ); + mCol3 = Vector4( scalar ); +} + +inline Matrix4::Matrix4( const Transform3 & mat ) +{ + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( mat.getCol3(), 1.0f ); +} + +inline Matrix4::Matrix4( const Vector4 & _col0, const Vector4 & _col1, const Vector4 & _col2, const Vector4 & _col3 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; +} + +inline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 & translateVec ) +{ + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( translateVec, 1.0f ); +} + +inline Matrix4::Matrix4( const Quat & unitQuat, const Vector3 & translateVec ) +{ + Matrix3 mat; + mat = Matrix3( unitQuat ); + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( translateVec, 1.0f ); +} + +inline Matrix4 & Matrix4::setCol0( const Vector4 & _col0 ) +{ + mCol0 = _col0; + return *this; +} + +inline Matrix4 & Matrix4::setCol1( const Vector4 & _col1 ) +{ + mCol1 = _col1; + return *this; +} + +inline Matrix4 & Matrix4::setCol2( const Vector4 & _col2 ) +{ + mCol2 = _col2; + return *this; +} + +inline Matrix4 & Matrix4::setCol3( const Vector4 & _col3 ) +{ + mCol3 = _col3; + return *this; +} + +inline Matrix4 & Matrix4::setCol( int col, const Vector4 & vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +inline Matrix4 & Matrix4::setRow( int row, const Vector4 & vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + mCol3.setElem( row, vec.getElem( 3 ) ); + return *this; +} + +inline Matrix4 & Matrix4::setElem( int col, int row, float val ) +{ + Vector4 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +inline float Matrix4::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +inline const Vector4 Matrix4::getCol0( ) const +{ + return mCol0; +} + +inline const Vector4 Matrix4::getCol1( ) const +{ + return mCol1; +} + +inline const Vector4 Matrix4::getCol2( ) const +{ + return mCol2; +} + +inline const Vector4 Matrix4::getCol3( ) const +{ + return mCol3; +} + +inline const Vector4 Matrix4::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +inline const Vector4 Matrix4::getRow( int row ) const +{ + return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); +} + +inline Vector4 & Matrix4::operator []( int col ) +{ + return *(&mCol0 + col); +} + +inline const Vector4 Matrix4::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +inline Matrix4 & Matrix4::operator =( const Matrix4 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; + return *this; +} + +inline const Matrix4 transpose( const Matrix4 & mat ) +{ + return Matrix4( + Vector4( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX() ), + Vector4( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY() ), + Vector4( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ() ), + Vector4( mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW() ) + ); +} + +inline const Matrix4 inverse( const Matrix4 & mat ) +{ + Vector4 res0, res1, res2, res3; + float mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv; + mA = mat.getCol0().getX(); + mB = mat.getCol0().getY(); + mC = mat.getCol0().getZ(); + mD = mat.getCol0().getW(); + mE = mat.getCol1().getX(); + mF = mat.getCol1().getY(); + mG = mat.getCol1().getZ(); + mH = mat.getCol1().getW(); + mI = mat.getCol2().getX(); + mJ = mat.getCol2().getY(); + mK = mat.getCol2().getZ(); + mL = mat.getCol2().getW(); + mM = mat.getCol3().getX(); + mN = mat.getCol3().getY(); + mO = mat.getCol3().getZ(); + mP = mat.getCol3().getW(); + tmp0 = ( ( mK * mD ) - ( mC * mL ) ); + tmp1 = ( ( mO * mH ) - ( mG * mP ) ); + tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); + tmp3 = ( ( mF * mO ) - ( mN * mG ) ); + tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); + tmp5 = ( ( mN * mH ) - ( mF * mP ) ); + res0.setX( ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ) ); + res0.setY( ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ) ); + res0.setZ( ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ) ); + res0.setW( ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ) ); + detInv = ( 1.0f / ( ( ( ( mA * res0.getX() ) + ( mE * res0.getY() ) ) + ( mI * res0.getZ() ) ) + ( mM * res0.getW() ) ) ); + res1.setX( ( mI * tmp1 ) ); + res1.setY( ( mM * tmp0 ) ); + res1.setZ( ( mA * tmp1 ) ); + res1.setW( ( mE * tmp0 ) ); + res3.setX( ( mI * tmp3 ) ); + res3.setY( ( mM * tmp2 ) ); + res3.setZ( ( mA * tmp3 ) ); + res3.setW( ( mE * tmp2 ) ); + res2.setX( ( mI * tmp5 ) ); + res2.setY( ( mM * tmp4 ) ); + res2.setZ( ( mA * tmp5 ) ); + res2.setW( ( mE * tmp4 ) ); + tmp0 = ( ( mI * mB ) - ( mA * mJ ) ); + tmp1 = ( ( mM * mF ) - ( mE * mN ) ); + tmp2 = ( ( mI * mD ) - ( mA * mL ) ); + tmp3 = ( ( mM * mH ) - ( mE * mP ) ); + tmp4 = ( ( mI * mC ) - ( mA * mK ) ); + tmp5 = ( ( mM * mG ) - ( mE * mO ) ); + res2.setX( ( ( ( mL * tmp1 ) - ( mJ * tmp3 ) ) + res2.getX() ) ); + res2.setY( ( ( ( mP * tmp0 ) - ( mN * tmp2 ) ) + res2.getY() ) ); + res2.setZ( ( ( ( mB * tmp3 ) - ( mD * tmp1 ) ) - res2.getZ() ) ); + res2.setW( ( ( ( mF * tmp2 ) - ( mH * tmp0 ) ) - res2.getW() ) ); + res3.setX( ( ( ( mJ * tmp5 ) - ( mK * tmp1 ) ) + res3.getX() ) ); + res3.setY( ( ( ( mN * tmp4 ) - ( mO * tmp0 ) ) + res3.getY() ) ); + res3.setZ( ( ( ( mC * tmp1 ) - ( mB * tmp5 ) ) - res3.getZ() ) ); + res3.setW( ( ( ( mG * tmp0 ) - ( mF * tmp4 ) ) - res3.getW() ) ); + res1.setX( ( ( ( mK * tmp3 ) - ( mL * tmp5 ) ) - res1.getX() ) ); + res1.setY( ( ( ( mO * tmp2 ) - ( mP * tmp4 ) ) - res1.getY() ) ); + res1.setZ( ( ( ( mD * tmp5 ) - ( mC * tmp3 ) ) + res1.getZ() ) ); + res1.setW( ( ( ( mH * tmp4 ) - ( mG * tmp2 ) ) + res1.getW() ) ); + return Matrix4( + ( res0 * detInv ), + ( res1 * detInv ), + ( res2 * detInv ), + ( res3 * detInv ) + ); +} + +inline const Matrix4 affineInverse( const Matrix4 & mat ) +{ + Transform3 affineMat; + affineMat.setCol0( mat.getCol0().getXYZ( ) ); + affineMat.setCol1( mat.getCol1().getXYZ( ) ); + affineMat.setCol2( mat.getCol2().getXYZ( ) ); + affineMat.setCol3( mat.getCol3().getXYZ( ) ); + return Matrix4( inverse( affineMat ) ); +} + +inline const Matrix4 orthoInverse( const Matrix4 & mat ) +{ + Transform3 affineMat; + affineMat.setCol0( mat.getCol0().getXYZ( ) ); + affineMat.setCol1( mat.getCol1().getXYZ( ) ); + affineMat.setCol2( mat.getCol2().getXYZ( ) ); + affineMat.setCol3( mat.getCol3().getXYZ( ) ); + return Matrix4( orthoInverse( affineMat ) ); +} + +inline float determinant( const Matrix4 & mat ) +{ + float dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; + mA = mat.getCol0().getX(); + mB = mat.getCol0().getY(); + mC = mat.getCol0().getZ(); + mD = mat.getCol0().getW(); + mE = mat.getCol1().getX(); + mF = mat.getCol1().getY(); + mG = mat.getCol1().getZ(); + mH = mat.getCol1().getW(); + mI = mat.getCol2().getX(); + mJ = mat.getCol2().getY(); + mK = mat.getCol2().getZ(); + mL = mat.getCol2().getW(); + mM = mat.getCol3().getX(); + mN = mat.getCol3().getY(); + mO = mat.getCol3().getZ(); + mP = mat.getCol3().getW(); + tmp0 = ( ( mK * mD ) - ( mC * mL ) ); + tmp1 = ( ( mO * mH ) - ( mG * mP ) ); + tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); + tmp3 = ( ( mF * mO ) - ( mN * mG ) ); + tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); + tmp5 = ( ( mN * mH ) - ( mF * mP ) ); + dx = ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ); + dy = ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ); + dz = ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ); + dw = ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ); + return ( ( ( ( mA * dx ) + ( mE * dy ) ) + ( mI * dz ) ) + ( mM * dw ) ); +} + +inline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const +{ + return Matrix4( + ( mCol0 + mat.mCol0 ), + ( mCol1 + mat.mCol1 ), + ( mCol2 + mat.mCol2 ), + ( mCol3 + mat.mCol3 ) + ); +} + +inline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const +{ + return Matrix4( + ( mCol0 - mat.mCol0 ), + ( mCol1 - mat.mCol1 ), + ( mCol2 - mat.mCol2 ), + ( mCol3 - mat.mCol3 ) + ); +} + +inline Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) +{ + *this = *this + mat; + return *this; +} + +inline Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) +{ + *this = *this - mat; + return *this; +} + +inline const Matrix4 Matrix4::operator -( ) const +{ + return Matrix4( + ( -mCol0 ), + ( -mCol1 ), + ( -mCol2 ), + ( -mCol3 ) + ); +} + +inline const Matrix4 absPerElem( const Matrix4 & mat ) +{ + return Matrix4( + absPerElem( mat.getCol0() ), + absPerElem( mat.getCol1() ), + absPerElem( mat.getCol2() ), + absPerElem( mat.getCol3() ) + ); +} + +inline const Matrix4 Matrix4::operator *( float scalar ) const +{ + return Matrix4( + ( mCol0 * scalar ), + ( mCol1 * scalar ), + ( mCol2 * scalar ), + ( mCol3 * scalar ) + ); +} + +inline Matrix4 & Matrix4::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Matrix4 operator *( float scalar, const Matrix4 & mat ) +{ + return mat * scalar; +} + +inline const Vector4 Matrix4::operator *( const Vector4 & vec ) const +{ + return Vector4( + ( ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ) + ( mCol3.getX() * vec.getW() ) ), + ( ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ) + ( mCol3.getY() * vec.getW() ) ), + ( ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ( mCol3.getZ() * vec.getW() ) ), + ( ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) + ( mCol3.getW() * vec.getW() ) ) + ); +} + +inline const Vector4 Matrix4::operator *( const Vector3 & vec ) const +{ + return Vector4( + ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), + ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), + ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ), + ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) + ); +} + +inline const Vector4 Matrix4::operator *( const Point3 & pnt ) const +{ + return Vector4( + ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), + ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), + ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ), + ( ( ( ( mCol0.getW() * pnt.getX() ) + ( mCol1.getW() * pnt.getY() ) ) + ( mCol2.getW() * pnt.getZ() ) ) + mCol3.getW() ) + ); +} + +// ARA begin insert new code +inline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const +{ + Matrix4 __attribute__((__aligned__((64)))) result; + pfxMatrix4Matrix4ProductNEON(*this, mat, result); + return(result); +} +// ARA end + +// ARA begin insert new code +inline Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) +{ + pfxMatrix4Matrix4ProductNEON(*this, mat, *this); + return *this; +} +// ARA end + +inline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const +{ + return Matrix4( + ( *this * tfrm.getCol0() ), + ( *this * tfrm.getCol1() ), + ( *this * tfrm.getCol2() ), + ( *this * Point3( tfrm.getCol3() ) ) + ); +} + +inline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) +{ + *this = *this * tfrm; + return *this; +} + +inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) +{ + return Matrix4( + mulPerElem( mat0.getCol0(), mat1.getCol0() ), + mulPerElem( mat0.getCol1(), mat1.getCol1() ), + mulPerElem( mat0.getCol2(), mat1.getCol2() ), + mulPerElem( mat0.getCol3(), mat1.getCol3() ) + ); +} + +inline const Matrix4 Matrix4::identity( ) +{ + return Matrix4( + Vector4::xAxis( ), + Vector4::yAxis( ), + Vector4::zAxis( ), + Vector4::wAxis( ) + ); +} + +inline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) +{ + mCol0.setXYZ( mat3.getCol0() ); + mCol1.setXYZ( mat3.getCol1() ); + mCol2.setXYZ( mat3.getCol2() ); + return *this; +} + +inline const Matrix3 Matrix4::getUpper3x3( ) const +{ + return Matrix3( + mCol0.getXYZ( ), + mCol1.getXYZ( ), + mCol2.getXYZ( ) + ); +} + +inline Matrix4 & Matrix4::setTranslation( const Vector3 & translateVec ) +{ + mCol3.setXYZ( translateVec ); + return *this; +} + +inline const Vector3 Matrix4::getTranslation( ) const +{ + return mCol3.getXYZ( ); +} + +inline const Matrix4 Matrix4::rotationX( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix4( + Vector4::xAxis( ), + Vector4( 0.0f, c, s, 0.0f ), + Vector4( 0.0f, -s, c, 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotationY( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix4( + Vector4( c, 0.0f, -s, 0.0f ), + Vector4::yAxis( ), + Vector4( s, 0.0f, c, 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotationZ( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix4( + Vector4( c, s, 0.0f, 0.0f ), + Vector4( -s, c, 0.0f, 0.0f ), + Vector4::zAxis( ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotationZYX( const Vector3 & radiansXYZ ) +{ + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf( radiansXYZ.getX() ); + cX = cosf( radiansXYZ.getX() ); + sY = sinf( radiansXYZ.getY() ); + cY = cosf( radiansXYZ.getY() ); + sZ = sinf( radiansXYZ.getZ() ); + cZ = cosf( radiansXYZ.getZ() ); + tmp0 = ( cZ * sY ); + tmp1 = ( sZ * sY ); + return Matrix4( + Vector4( ( cZ * cY ), ( sZ * cY ), -sY, 0.0f ), + Vector4( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ), 0.0f ), + Vector4( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ), 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotation( float radians, const Vector3 & unitVec ) +{ + float x, y, z, s, c, oneMinusC, xy, yz, zx; + s = sinf( radians ); + c = cosf( radians ); + x = unitVec.getX(); + y = unitVec.getY(); + z = unitVec.getZ(); + xy = ( x * y ); + yz = ( y * z ); + zx = ( z * x ); + oneMinusC = ( 1.0f - c ); + return Matrix4( + Vector4( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ), 0.0f ), + Vector4( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ), 0.0f ), + Vector4( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ), 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotation( const Quat & unitQuat ) +{ + return Matrix4( Transform3::rotation( unitQuat ) ); +} + +inline const Matrix4 Matrix4::scale( const Vector3 & scaleVec ) +{ + return Matrix4( + Vector4( scaleVec.getX(), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, scaleVec.getY(), 0.0f, 0.0f ), + Vector4( 0.0f, 0.0f, scaleVec.getZ(), 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ) +{ + return Matrix4( + ( mat.getCol0() * scaleVec.getX( ) ), + ( mat.getCol1() * scaleVec.getY( ) ), + ( mat.getCol2() * scaleVec.getZ( ) ), + mat.getCol3() + ); +} + +inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ) +{ + Vector4 scale4; + scale4 = Vector4( scaleVec, 1.0f ); + return Matrix4( + mulPerElem( mat.getCol0(), scale4 ), + mulPerElem( mat.getCol1(), scale4 ), + mulPerElem( mat.getCol2(), scale4 ), + mulPerElem( mat.getCol3(), scale4 ) + ); +} + +inline const Matrix4 Matrix4::translation( const Vector3 & translateVec ) +{ + return Matrix4( + Vector4::xAxis( ), + Vector4::yAxis( ), + Vector4::zAxis( ), + Vector4( translateVec, 1.0f ) + ); +} + +inline const Matrix4 Matrix4::lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ) +{ + Matrix4 m4EyeFrame; + Vector3 v3X, v3Y, v3Z; + v3Y = normalize( upVec ); + v3Z = normalize( ( eyePos - lookAtPos ) ); + v3X = normalize( cross( v3Y, v3Z ) ); + v3Y = cross( v3Z, v3X ); + m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); + return orthoInverse( m4EyeFrame ); +} + +inline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar ) +{ + float f, rangeInv; + f = tanf( ( (float)( _VECTORMATH_PI_OVER_2 ) - ( 0.5f * fovyRadians ) ) ); + rangeInv = ( 1.0f / ( zNear - zFar ) ); + return Matrix4( + Vector4( ( f / aspect ), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, f, 0.0f, 0.0f ), + Vector4( 0.0f, 0.0f, ( ( zNear + zFar ) * rangeInv ), -1.0f ), + Vector4( 0.0f, 0.0f, ( ( ( zNear * zFar ) * rangeInv ) * 2.0f ), 0.0f ) + ); +} + +inline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ) +{ + float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; + sum_rl = ( right + left ); + sum_tb = ( top + bottom ); + sum_nf = ( zNear + zFar ); + inv_rl = ( 1.0f / ( right - left ) ); + inv_tb = ( 1.0f / ( top - bottom ) ); + inv_nf = ( 1.0f / ( zNear - zFar ) ); + n2 = ( zNear + zNear ); + return Matrix4( + Vector4( ( n2 * inv_rl ), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, ( n2 * inv_tb ), 0.0f, 0.0f ), + Vector4( ( sum_rl * inv_rl ), ( sum_tb * inv_tb ), ( sum_nf * inv_nf ), -1.0f ), + Vector4( 0.0f, 0.0f, ( ( n2 * inv_nf ) * zFar ), 0.0f ) + ); +} + +inline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar ) +{ + float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; + sum_rl = ( right + left ); + sum_tb = ( top + bottom ); + sum_nf = ( zNear + zFar ); + inv_rl = ( 1.0f / ( right - left ) ); + inv_tb = ( 1.0f / ( top - bottom ) ); + inv_nf = ( 1.0f / ( zNear - zFar ) ); + return Matrix4( + Vector4( ( inv_rl + inv_rl ), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, ( inv_tb + inv_tb ), 0.0f, 0.0f ), + Vector4( 0.0f, 0.0f, ( inv_nf + inv_nf ), 0.0f ), + Vector4( ( -sum_rl * inv_rl ), ( -sum_tb * inv_tb ), ( sum_nf * inv_nf ), 1.0f ) + ); +} + +inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ) +{ + return Matrix4( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ), + select( mat0.getCol3(), mat1.getCol3(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Matrix4 & mat ) +{ + print( mat.getRow( 0 ) ); + print( mat.getRow( 1 ) ); + print( mat.getRow( 2 ) ); + print( mat.getRow( 3 ) ); +} + +inline void print( const Matrix4 & mat, const char * name ) +{ + printf("%s:\n", name); + print( mat ); +} + +#endif + +inline Transform3::Transform3( const Transform3 & tfrm ) +{ + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; +} + +inline Transform3::Transform3( float scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); + mCol3 = Vector3( scalar ); +} + +inline Transform3::Transform3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2, const Vector3 & _col3 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; +} + +inline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ) +{ + this->setUpper3x3( tfrm ); + this->setTranslation( translateVec ); +} + +inline Transform3::Transform3( const Quat & unitQuat, const Vector3 & translateVec ) +{ + this->setUpper3x3( Matrix3( unitQuat ) ); + this->setTranslation( translateVec ); +} + +inline Transform3 & Transform3::setCol0( const Vector3 & _col0 ) +{ + mCol0 = _col0; + return *this; +} + +inline Transform3 & Transform3::setCol1( const Vector3 & _col1 ) +{ + mCol1 = _col1; + return *this; +} + +inline Transform3 & Transform3::setCol2( const Vector3 & _col2 ) +{ + mCol2 = _col2; + return *this; +} + +inline Transform3 & Transform3::setCol3( const Vector3 & _col3 ) +{ + mCol3 = _col3; + return *this; +} + +inline Transform3 & Transform3::setCol( int col, const Vector3 & vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +inline Transform3 & Transform3::setRow( int row, const Vector4 & vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + mCol3.setElem( row, vec.getElem( 3 ) ); + return *this; +} + +inline Transform3 & Transform3::setElem( int col, int row, float val ) +{ + Vector3 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +inline float Transform3::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +inline const Vector3 Transform3::getCol0( ) const +{ + return mCol0; +} + +inline const Vector3 Transform3::getCol1( ) const +{ + return mCol1; +} + +inline const Vector3 Transform3::getCol2( ) const +{ + return mCol2; +} + +inline const Vector3 Transform3::getCol3( ) const +{ + return mCol3; +} + +inline const Vector3 Transform3::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +inline const Vector4 Transform3::getRow( int row ) const +{ + return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); +} + +inline Vector3 & Transform3::operator []( int col ) +{ + return *(&mCol0 + col); +} + +inline const Vector3 Transform3::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +inline Transform3 & Transform3::operator =( const Transform3 & tfrm ) +{ + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; + return *this; +} + +inline const Transform3 inverse( const Transform3 & tfrm ) +{ + Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2; + float detinv; + tmp0 = cross( tfrm.getCol1(), tfrm.getCol2() ); + tmp1 = cross( tfrm.getCol2(), tfrm.getCol0() ); + tmp2 = cross( tfrm.getCol0(), tfrm.getCol1() ); + detinv = ( 1.0f / dot( tfrm.getCol2(), tmp2 ) ); + inv0 = Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ); + inv1 = Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ); + inv2 = Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ); + return Transform3( + inv0, + inv1, + inv2, + Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) + ); +} + +// ARA begin insert new code +inline const Transform3 orthoInverse( const Transform3 & tfrm ) +{ + Transform3 __attribute__((__aligned__((64)))) result; + pfxTransform3OrthoInverseNEON(tfrm, result); + return(result); +} +// ARA end + +inline const Transform3 absPerElem( const Transform3 & tfrm ) +{ + return Transform3( + absPerElem( tfrm.getCol0() ), + absPerElem( tfrm.getCol1() ), + absPerElem( tfrm.getCol2() ), + absPerElem( tfrm.getCol3() ) + ); +} + +// ARA begin insert new code +inline const Vector3 Transform3::operator *( const Vector3 & vec ) const +{ + Vector3 __attribute__((__aligned__((64)))) result; + pfxTransform3Vector3MultiplyNEON(*this, vec, result); + return(result); +} +// ARA end + +inline const Point3 Transform3::operator *( const Point3 & pnt ) const +{ + return Point3( + ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), + ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), + ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ) + ); +} + +inline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const +{ + return Transform3( + ( *this * tfrm.mCol0 ), + ( *this * tfrm.mCol1 ), + ( *this * tfrm.mCol2 ), + Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) + ); +} + +inline Transform3 & Transform3::operator *=( const Transform3 & tfrm ) +{ + *this = *this * tfrm; + return *this; +} + +inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) +{ + return Transform3( + mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), + mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), + mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), + mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) + ); +} + +inline const Transform3 Transform3::identity( ) +{ + return Transform3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ), + Vector3( 0.0f ) + ); +} + +inline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) +{ + mCol0 = tfrm.getCol0(); + mCol1 = tfrm.getCol1(); + mCol2 = tfrm.getCol2(); + return *this; +} + +inline const Matrix3 Transform3::getUpper3x3( ) const +{ + return Matrix3( mCol0, mCol1, mCol2 ); +} + +inline Transform3 & Transform3::setTranslation( const Vector3 & translateVec ) +{ + mCol3 = translateVec; + return *this; +} + +inline const Vector3 Transform3::getTranslation( ) const +{ + return mCol3; +} + +inline const Transform3 Transform3::rotationX( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Transform3( + Vector3::xAxis( ), + Vector3( 0.0f, c, s ), + Vector3( 0.0f, -s, c ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotationY( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Transform3( + Vector3( c, 0.0f, -s ), + Vector3::yAxis( ), + Vector3( s, 0.0f, c ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotationZ( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Transform3( + Vector3( c, s, 0.0f ), + Vector3( -s, c, 0.0f ), + Vector3::zAxis( ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotationZYX( const Vector3 & radiansXYZ ) +{ + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf( radiansXYZ.getX() ); + cX = cosf( radiansXYZ.getX() ); + sY = sinf( radiansXYZ.getY() ); + cY = cosf( radiansXYZ.getY() ); + sZ = sinf( radiansXYZ.getZ() ); + cZ = cosf( radiansXYZ.getZ() ); + tmp0 = ( cZ * sY ); + tmp1 = ( sZ * sY ); + return Transform3( + Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), + Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), + Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotation( float radians, const Vector3 & unitVec ) +{ + return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) ); +} + +inline const Transform3 Transform3::rotation( const Quat & unitQuat ) +{ + return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) ); +} + +inline const Transform3 Transform3::scale( const Vector3 & scaleVec ) +{ + return Transform3( + Vector3( scaleVec.getX(), 0.0f, 0.0f ), + Vector3( 0.0f, scaleVec.getY(), 0.0f ), + Vector3( 0.0f, 0.0f, scaleVec.getZ() ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ) +{ + return Transform3( + ( tfrm.getCol0() * scaleVec.getX( ) ), + ( tfrm.getCol1() * scaleVec.getY( ) ), + ( tfrm.getCol2() * scaleVec.getZ( ) ), + tfrm.getCol3() + ); +} + +inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ) +{ + return Transform3( + mulPerElem( tfrm.getCol0(), scaleVec ), + mulPerElem( tfrm.getCol1(), scaleVec ), + mulPerElem( tfrm.getCol2(), scaleVec ), + mulPerElem( tfrm.getCol3(), scaleVec ) + ); +} + +inline const Transform3 Transform3::translation( const Vector3 & translateVec ) +{ + return Transform3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ), + translateVec + ); +} + +inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ) +{ + return Transform3( + select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), + select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), + select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), + select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Transform3 & tfrm ) +{ + print( tfrm.getRow( 0 ) ); + print( tfrm.getRow( 1 ) ); + print( tfrm.getRow( 2 ) ); +} + +inline void print( const Transform3 & tfrm, const char * name ) +{ + printf("%s:\n", name); + print( tfrm ); +} + +#endif + +inline Quat::Quat( const Matrix3 & tfrm ) +{ + float trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; + int negTrace, ZgtX, ZgtY, YgtX; + int largestXorY, largestYorZ, largestZorX; + + xx = tfrm.getCol0().getX(); + yx = tfrm.getCol0().getY(); + zx = tfrm.getCol0().getZ(); + xy = tfrm.getCol1().getX(); + yy = tfrm.getCol1().getY(); + zy = tfrm.getCol1().getZ(); + xz = tfrm.getCol2().getX(); + yz = tfrm.getCol2().getY(); + zz = tfrm.getCol2().getZ(); + + trace = ( ( xx + yy ) + zz ); + + negTrace = ( trace < 0.0f ); + ZgtX = zz > xx; + ZgtY = zz > yy; + YgtX = yy > xx; + largestXorY = ( !ZgtX || !ZgtY ) && negTrace; + largestYorZ = ( YgtX || ZgtX ) && negTrace; + largestZorX = ( ZgtY || !YgtX ) && negTrace; + + if ( largestXorY ) + { + zz = -zz; + xy = -xy; + } + if ( largestYorZ ) + { + xx = -xx; + yz = -yz; + } + if ( largestZorX ) + { + yy = -yy; + zx = -zx; + } + + radicand = ( ( ( xx + yy ) + zz ) + 1.0f ); + scale = ( 0.5f * ( 1.0f / sqrtf( radicand ) ) ); + + tmpx = ( ( zy - yz ) * scale ); + tmpy = ( ( xz - zx ) * scale ); + tmpz = ( ( yx - xy ) * scale ); + tmpw = ( radicand * scale ); + qx = tmpx; + qy = tmpy; + qz = tmpz; + qw = tmpw; + + if ( largestXorY ) + { + qx = tmpw; + qy = tmpz; + qz = tmpy; + qw = tmpx; + } + if ( largestYorZ ) + { + tmpx = qx; + tmpz = qz; + qx = qy; + qy = tmpx; + qz = qw; + qw = tmpz; + } + + mX = qx; + mY = qy; + mZ = qz; + mW = qw; +} + +inline const Matrix3 outer( const Vector3 & tfrm0, const Vector3 & tfrm1 ) +{ + return Matrix3( + ( tfrm0 * tfrm1.getX( ) ), + ( tfrm0 * tfrm1.getY( ) ), + ( tfrm0 * tfrm1.getZ( ) ) + ); +} + +inline const Matrix4 outer( const Vector4 & tfrm0, const Vector4 & tfrm1 ) +{ + return Matrix4( + ( tfrm0 * tfrm1.getX( ) ), + ( tfrm0 * tfrm1.getY( ) ), + ( tfrm0 * tfrm1.getZ( ) ), + ( tfrm0 * tfrm1.getW( ) ) + ); +} + +inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ) +{ + return Vector3( + ( ( ( vec.getX() * mat.getCol0().getX() ) + ( vec.getY() * mat.getCol0().getY() ) ) + ( vec.getZ() * mat.getCol0().getZ() ) ), + ( ( ( vec.getX() * mat.getCol1().getX() ) + ( vec.getY() * mat.getCol1().getY() ) ) + ( vec.getZ() * mat.getCol1().getZ() ) ), + ( ( ( vec.getX() * mat.getCol2().getX() ) + ( vec.getY() * mat.getCol2().getY() ) ) + ( vec.getZ() * mat.getCol2().getZ() ) ) + ); +} + +inline const Matrix3 crossMatrix( const Vector3 & vec ) +{ + return Matrix3( + Vector3( 0.0f, vec.getZ(), -vec.getY() ), + Vector3( -vec.getZ(), 0.0f, vec.getX() ), + Vector3( vec.getY(), -vec.getX(), 0.0f ) + ); +} + +inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ) +{ + return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); +} + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/Extras/PhysicsEffects/include/vecmath/neon/quat_aos.h b/Extras/PhysicsEffects/include/vecmath/neon/quat_aos.h new file mode 100644 index 000000000..6a4a0f212 --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/neon/quat_aos.h @@ -0,0 +1,446 @@ +/* + Copyright (C) 2006-2010 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _VECTORMATH_QUAT_AOS_CPP_H +#define _VECTORMATH_QUAT_AOS_CPP_H + +//----------------------------------------------------------------------------- +// Definitions + +#ifndef _VECTORMATH_INTERNAL_FUNCTIONS +#define _VECTORMATH_INTERNAL_FUNCTIONS + +#endif + +namespace Vectormath { +namespace Aos { + +inline Quat::Quat( const Quat & quat ) +{ + mX = quat.mX; + mY = quat.mY; + mZ = quat.mZ; + mW = quat.mW; +} + +inline Quat::Quat( float _x, float _y, float _z, float _w ) +{ + mX = _x; + mY = _y; + mZ = _z; + mW = _w; +} + +inline Quat::Quat( const Vector3 & xyz, float _w ) +{ + this->setXYZ( xyz ); + this->setW( _w ); +} + +inline Quat::Quat( const Vector4 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + mW = vec.getW(); +} + +inline Quat::Quat( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; + mW = scalar; +} + +inline const Quat Quat::identity( ) +{ + return Quat( 0.0f, 0.0f, 0.0f, 1.0f ); +} + +inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ) +{ + return ( quat0 + ( ( quat1 - quat0 ) * t ) ); +} + +inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ) +{ + Quat start; + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot( unitQuat0, unitQuat1 ); + if ( cosAngle < 0.0f ) { + cosAngle = -cosAngle; + start = ( -unitQuat0 ); + } else { + start = unitQuat0; + } + if ( cosAngle < _VECTORMATH_SLERP_TOL ) { + angle = acosf( cosAngle ); + recipSinAngle = ( 1.0f / sinf( angle ) ); + scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); + scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); + } else { + scale0 = ( 1.0f - t ); + scale1 = t; + } + return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) ); +} + +inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ) +{ + Quat tmp0, tmp1; + tmp0 = slerp( t, unitQuat0, unitQuat3 ); + tmp1 = slerp( t, unitQuat1, unitQuat2 ); + return slerp( ( ( 2.0f * t ) * ( 1.0f - t ) ), tmp0, tmp1 ); +} + +inline void loadXYZW( Quat & quat, const float * fptr ) +{ + quat = Quat( fptr[0], fptr[1], fptr[2], fptr[3] ); +} + +inline void storeXYZW( const Quat & quat, float * fptr ) +{ + fptr[0] = quat.getX(); + fptr[1] = quat.getY(); + fptr[2] = quat.getZ(); + fptr[3] = quat.getW(); +} + +inline Quat & Quat::operator =( const Quat & quat ) +{ + mX = quat.mX; + mY = quat.mY; + mZ = quat.mZ; + mW = quat.mW; + return *this; +} + +inline Quat & Quat::setXYZ( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + return *this; +} + +inline const Vector3 Quat::getXYZ( ) const +{ + return Vector3( mX, mY, mZ ); +} + +inline Quat & Quat::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Quat::getX( ) const +{ + return mX; +} + +inline Quat & Quat::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Quat::getY( ) const +{ + return mY; +} + +inline Quat & Quat::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Quat::getZ( ) const +{ + return mZ; +} + +inline Quat & Quat::setW( float _w ) +{ + mW = _w; + return *this; +} + +inline float Quat::getW( ) const +{ + return mW; +} + +inline Quat & Quat::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Quat::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Quat::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Quat::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Quat Quat::operator +( const Quat & quat ) const +{ + return Quat( + ( mX + quat.mX ), + ( mY + quat.mY ), + ( mZ + quat.mZ ), + ( mW + quat.mW ) + ); +} + +inline const Quat Quat::operator -( const Quat & quat ) const +{ + return Quat( + ( mX - quat.mX ), + ( mY - quat.mY ), + ( mZ - quat.mZ ), + ( mW - quat.mW ) + ); +} + +inline const Quat Quat::operator *( float scalar ) const +{ + return Quat( + ( mX * scalar ), + ( mY * scalar ), + ( mZ * scalar ), + ( mW * scalar ) + ); +} + +inline Quat & Quat::operator +=( const Quat & quat ) +{ + *this = *this + quat; + return *this; +} + +inline Quat & Quat::operator -=( const Quat & quat ) +{ + *this = *this - quat; + return *this; +} + +inline Quat & Quat::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Quat Quat::operator /( float scalar ) const +{ + return Quat( + ( mX / scalar ), + ( mY / scalar ), + ( mZ / scalar ), + ( mW / scalar ) + ); +} + +inline Quat & Quat::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +inline const Quat Quat::operator -( ) const +{ + return Quat( + -mX, + -mY, + -mZ, + -mW + ); +} + +inline const Quat operator *( float scalar, const Quat & quat ) +{ + return quat * scalar; +} + +inline float dot( const Quat & quat0, const Quat & quat1 ) +{ + float result; + result = ( quat0.getX() * quat1.getX() ); + result = ( result + ( quat0.getY() * quat1.getY() ) ); + result = ( result + ( quat0.getZ() * quat1.getZ() ) ); + result = ( result + ( quat0.getW() * quat1.getW() ) ); + return result; +} + +inline float norm( const Quat & quat ) +{ + float result; + result = ( quat.getX() * quat.getX() ); + result = ( result + ( quat.getY() * quat.getY() ) ); + result = ( result + ( quat.getZ() * quat.getZ() ) ); + result = ( result + ( quat.getW() * quat.getW() ) ); + return result; +} + +inline float length( const Quat & quat ) +{ + return ::sqrtf( norm( quat ) ); +} + +inline const Quat normalize( const Quat & quat ) +{ + float lenSqr, lenInv; + lenSqr = norm( quat ); + lenInv = ( 1.0f / sqrtf( lenSqr ) ); + return Quat( + ( quat.getX() * lenInv ), + ( quat.getY() * lenInv ), + ( quat.getZ() * lenInv ), + ( quat.getW() * lenInv ) + ); +} + +inline const Quat Quat::rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ) +{ + float cosHalfAngleX2, recipCosHalfAngleX2; + cosHalfAngleX2 = sqrtf( ( 2.0f * ( 1.0f + dot( unitVec0, unitVec1 ) ) ) ); + recipCosHalfAngleX2 = ( 1.0f / cosHalfAngleX2 ); + return Quat( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), ( cosHalfAngleX2 * 0.5f ) ); +} + +inline const Quat Quat::rotation( float radians, const Vector3 & unitVec ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( ( unitVec * s ), c ); +} + +inline const Quat Quat::rotationX( float radians ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( s, 0.0f, 0.0f, c ); +} + +inline const Quat Quat::rotationY( float radians ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( 0.0f, s, 0.0f, c ); +} + +inline const Quat Quat::rotationZ( float radians ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( 0.0f, 0.0f, s, c ); +} + +inline const Quat Quat::operator *( const Quat & quat ) const +{ + return Quat( + ( ( ( ( mW * quat.mX ) + ( mX * quat.mW ) ) + ( mY * quat.mZ ) ) - ( mZ * quat.mY ) ), + ( ( ( ( mW * quat.mY ) + ( mY * quat.mW ) ) + ( mZ * quat.mX ) ) - ( mX * quat.mZ ) ), + ( ( ( ( mW * quat.mZ ) + ( mZ * quat.mW ) ) + ( mX * quat.mY ) ) - ( mY * quat.mX ) ), + ( ( ( ( mW * quat.mW ) - ( mX * quat.mX ) ) - ( mY * quat.mY ) ) - ( mZ * quat.mZ ) ) + ); +} + +inline Quat & Quat::operator *=( const Quat & quat ) +{ + *this = *this * quat; + return *this; +} + +inline const Vector3 rotate( const Quat & quat, const Vector3 & vec ) +{ + float tmpX, tmpY, tmpZ, tmpW; + tmpX = ( ( ( quat.getW() * vec.getX() ) + ( quat.getY() * vec.getZ() ) ) - ( quat.getZ() * vec.getY() ) ); + tmpY = ( ( ( quat.getW() * vec.getY() ) + ( quat.getZ() * vec.getX() ) ) - ( quat.getX() * vec.getZ() ) ); + tmpZ = ( ( ( quat.getW() * vec.getZ() ) + ( quat.getX() * vec.getY() ) ) - ( quat.getY() * vec.getX() ) ); + tmpW = ( ( ( quat.getX() * vec.getX() ) + ( quat.getY() * vec.getY() ) ) + ( quat.getZ() * vec.getZ() ) ); + return Vector3( + ( ( ( ( tmpW * quat.getX() ) + ( tmpX * quat.getW() ) ) - ( tmpY * quat.getZ() ) ) + ( tmpZ * quat.getY() ) ), + ( ( ( ( tmpW * quat.getY() ) + ( tmpY * quat.getW() ) ) - ( tmpZ * quat.getX() ) ) + ( tmpX * quat.getZ() ) ), + ( ( ( ( tmpW * quat.getZ() ) + ( tmpZ * quat.getW() ) ) - ( tmpX * quat.getY() ) ) + ( tmpY * quat.getX() ) ) + ); +} + +inline const Quat conj( const Quat & quat ) +{ + return Quat( -quat.getX(), -quat.getY(), -quat.getZ(), quat.getW() ); +} + +inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ) +{ + return Quat( + ( select1 )? quat1.getX() : quat0.getX(), + ( select1 )? quat1.getY() : quat0.getY(), + ( select1 )? quat1.getZ() : quat0.getZ(), + ( select1 )? quat1.getW() : quat0.getW() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Quat & quat ) +{ + printf( "( %f %f %f %f )\n", quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); +} + +inline void print( const Quat & quat, const char * name ) +{ + printf( "%s: ( %f %f %f %f )\n", name, quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); +} + +#endif + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/Extras/PhysicsEffects/include/vecmath/neon/vec_aos.h b/Extras/PhysicsEffects/include/vecmath/neon/vec_aos.h new file mode 100644 index 000000000..3772deab3 --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/neon/vec_aos.h @@ -0,0 +1,1526 @@ +/* + Copyright (C) 2006-2010 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _VECTORMATH_VEC_AOS_CPP_H +#define _VECTORMATH_VEC_AOS_CPP_H + +// ARA begin insert new code +#include "vectormath_neon_assembly_prototypes.h" +// ARA end + +//----------------------------------------------------------------------------- +// Constants + +#define _VECTORMATH_SLERP_TOL 0.999f + +//----------------------------------------------------------------------------- +// Definitions + +#ifndef _VECTORMATH_INTERNAL_FUNCTIONS +#define _VECTORMATH_INTERNAL_FUNCTIONS + +#endif + +namespace Vectormath { +namespace Aos { + +inline Vector3::Vector3( const Vector3 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; +// ARA begin insert new code + d = 0.0f; +// ARA end +} + +inline Vector3::Vector3( float _x, float _y, float _z ) +{ + mX = _x; + mY = _y; + mZ = _z; +// ARA begin insert new code + d = 0.0f; +// ARA end +} + +inline Vector3::Vector3( const Point3 & pnt ) +{ + mX = pnt.getX(); + mY = pnt.getY(); + mZ = pnt.getZ(); +// ARA begin insert new code + d = 0.0f; +// ARA end +} + +inline Vector3::Vector3( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; +// ARA begin insert new code + d = 0.0f; +// ARA end +} + +inline const Vector3 Vector3::xAxis( ) +{ + return Vector3( 1.0f, 0.0f, 0.0f ); +} + +inline const Vector3 Vector3::yAxis( ) +{ + return Vector3( 0.0f, 1.0f, 0.0f ); +} + +inline const Vector3 Vector3::zAxis( ) +{ + return Vector3( 0.0f, 0.0f, 1.0f ); +} + +inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ) +{ + return ( vec0 + ( ( vec1 - vec0 ) * t ) ); +} + +inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ) +{ + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot( unitVec0, unitVec1 ); + if ( cosAngle < _VECTORMATH_SLERP_TOL ) { + angle = acosf( cosAngle ); + recipSinAngle = ( 1.0f / sinf( angle ) ); + scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); + scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); + } else { + scale0 = ( 1.0f - t ); + scale1 = t; + } + return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); +} + +inline void loadXYZ( Vector3 & vec, const float * fptr ) +{ + vec = Vector3( fptr[0], fptr[1], fptr[2] ); +} + +inline void storeXYZ( const Vector3 & vec, float * fptr ) +{ + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); +} + +inline void loadHalfFloats( Vector3 & vec, const unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); + + if (exponent == 0) { + // zero + mantissa = 0; + + } else if (exponent == 31) { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + + } else { + exponent += 127 - 15; + mantissa <<= 13; + } + + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } +} + +inline void storeHalfFloats( const Vector3 & vec, unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + Data32 d; + d.f32 = vec[i]; + + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + + if (exponent == 0) { + // zero or denorm -> zero + mantissa = 0; + + } else if (exponent == 255 && mantissa != 0) { + // nan -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent >= 127 - 15 + 31) { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent <= 127 - 15) { + // underflow -> zero + exponent = 0; + mantissa = 0; + + } else { + exponent -= 127 - 15; + mantissa >>= 13; + } + + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } +} + +inline Vector3 & Vector3::operator =( const Vector3 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + return *this; +} + +inline Vector3 & Vector3::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Vector3::getX( ) const +{ + return mX; +} + +inline Vector3 & Vector3::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Vector3::getY( ) const +{ + return mY; +} + +inline Vector3 & Vector3::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Vector3::getZ( ) const +{ + return mZ; +} + +inline Vector3 & Vector3::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Vector3::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Vector3::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Vector3::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Vector3 Vector3::operator +( const Vector3 & vec ) const +{ + return Vector3( + ( mX + vec.mX ), + ( mY + vec.mY ), + ( mZ + vec.mZ ) + ); +} + +inline const Vector3 Vector3::operator -( const Vector3 & vec ) const +{ + return Vector3( + ( mX - vec.mX ), + ( mY - vec.mY ), + ( mZ - vec.mZ ) + ); +} + +inline const Point3 Vector3::operator +( const Point3 & pnt ) const +{ + return Point3( + ( mX + pnt.getX() ), + ( mY + pnt.getY() ), + ( mZ + pnt.getZ() ) + ); +} + +inline const Vector3 Vector3::operator *( float scalar ) const +{ + return Vector3( + ( mX * scalar ), + ( mY * scalar ), + ( mZ * scalar ) + ); +} + +inline Vector3 & Vector3::operator +=( const Vector3 & vec ) +{ + *this = *this + vec; + return *this; +} + +inline Vector3 & Vector3::operator -=( const Vector3 & vec ) +{ + *this = *this - vec; + return *this; +} + +inline Vector3 & Vector3::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Vector3 Vector3::operator /( float scalar ) const +{ + return Vector3( + ( mX / scalar ), + ( mY / scalar ), + ( mZ / scalar ) + ); +} + +inline Vector3 & Vector3::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +inline const Vector3 Vector3::operator -( ) const +{ + return Vector3( + -mX, + -mY, + -mZ + ); +} + +inline const Vector3 operator *( float scalar, const Vector3 & vec ) +{ + return vec * scalar; +} + +inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( vec0.getX() * vec1.getX() ), + ( vec0.getY() * vec1.getY() ), + ( vec0.getZ() * vec1.getZ() ) + ); +} + +inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( vec0.getX() / vec1.getX() ), + ( vec0.getY() / vec1.getY() ), + ( vec0.getZ() / vec1.getZ() ) + ); +} + +inline const Vector3 recipPerElem( const Vector3 & vec ) +{ + return Vector3( + ( 1.0f / vec.getX() ), + ( 1.0f / vec.getY() ), + ( 1.0f / vec.getZ() ) + ); +} + +inline const Vector3 sqrtPerElem( const Vector3 & vec ) +{ + return Vector3( + sqrtf( vec.getX() ), + sqrtf( vec.getY() ), + sqrtf( vec.getZ() ) + ); +} + +inline const Vector3 rsqrtPerElem( const Vector3 & vec ) +{ + return Vector3( + ( 1.0f / sqrtf( vec.getX() ) ), + ( 1.0f / sqrtf( vec.getY() ) ), + ( 1.0f / sqrtf( vec.getZ() ) ) + ); +} + +inline const Vector3 absPerElem( const Vector3 & vec ) +{ + return Vector3( + fabsf( vec.getX() ), + fabsf( vec.getY() ), + fabsf( vec.getZ() ) + ); +} + +inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), + ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), + ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ) + ); +} + +inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ() + ); +} + +inline float maxElem( const Vector3 & vec ) +{ + float result; + result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() > result)? vec.getZ() : result; + return result; +} + +inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ() + ); +} + +inline float minElem( const Vector3 & vec ) +{ + float result; + result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() < result)? vec.getZ() : result; + return result; +} + +inline float sum( const Vector3 & vec ) +{ + float result; + result = ( vec.getX() + vec.getY() ); + result = ( result + vec.getZ() ); + return result; +} + +// ARA begin insert new code +inline float dot( const Vector3 & vec0, const Vector3 & vec1 ) +{ +#if 1 // pure assembly + + float __attribute__((__aligned__((64)))) result[2]; // space for 2 floats since neon vst1.32 wants to store a double register + pfxVector3DotProductNEON(vec0, vec1, result); + return(result[0]); + +#else // inline assembly + // Note that this inline assembly does NOT work correctly though it is *identical* to the dedicated assembly + // version and has (in theory) properly assigned register constraints and clobbers. In fact, it produces a + // correct numerical result, but gcc seems to not properly manage registers and this causes trouble downstream. + // Forum discussions indicate gcc is not great at supporting inline assembly using NEON registers. Even the + // two different but theoretically equivalent clobber lists produce different simulation results! + float __attribute__((__aligned__((64)))) result[2]; // space for 2 floats since neon vst1.32 wants to store a double register + asm volatile + ( + // Note this code is explicitly using register q0-q2 (and corresponding d/s registers) + // so that we can avoid the need to preserve them. We are applying instructions directly + // to s registers, which prevents us from using q8 and above, and would rather not + // use registers that gcc expects us to preserve, to avoid the cost of doing that. + "vld1.32 {d0,d1}, [%1] @ input = d0,d1\n\t" + "vld1.32 {d2,d3}, [%0] @ input = d2,d3\n\t" + "vmul.f32 d4, d0, d2 @ d4 = \n\t" + "vpadd.f32 d4, d4, d4 @ d4 = \n\t" + "vmla.f32 s8, s2, s6 @ s8 = = d18,d19\n\t" + "vld1.32 {d16,d17}, [%0] @ input = d16,d17\n\t" + "vtrn.32 d18,d19 @ q9 = = d18,d19\n\t" + "vrev64.32 d16,d16 @ q8 = = d16,d17\n\t" + "vrev64.32 d18,d18 @ q9 = = d18,d19\n\t" + "vtrn.32 d16,d17 @ q8 = = d16,d17\n\t" + "vmul.f32 q10, q8, q9 @ q10 = \n\t" + "vtrn.32 d18,d19 @ q9 = = d18,d19\n\t" + "vrev64.32 d16,d16 @ q8 = = d16,d17\n\t" + "vrev64.32 d18,d18 @ q9 = = d18,d19\n\t" + "vtrn.32 d16,d17 @ q8 = = d16,d17\n\t" + "vmls.f32 q10, q8, q9 @ q10 = \n\t" + "vst1.32 {q10}, [%2]\n\t" + : // NO explicit outputs! + : "r" (&vec0), "r" (&vec1), "r" (&result) //inputs. output indirectly stored in result + : "memory", "q8", "q9", "q10" // clobbers + ); + return result; +#endif +} +// ARA end + +inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ) +{ + return Vector3( + ( select1 )? vec1.getX() : vec0.getX(), + ( select1 )? vec1.getY() : vec0.getY(), + ( select1 )? vec1.getZ() : vec0.getZ() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Vector3 & vec ) +{ + printf( "( %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ() ); +} + +inline void print( const Vector3 & vec, const char * name ) +{ + printf( "%s: ( %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ() ); +} + +#endif + +inline Vector4::Vector4( const Vector4 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + mW = vec.mW; +} + +inline Vector4::Vector4( float _x, float _y, float _z, float _w ) +{ + mX = _x; + mY = _y; + mZ = _z; + mW = _w; +} + +inline Vector4::Vector4( const Vector3 & xyz, float _w ) +{ + this->setXYZ( xyz ); + this->setW( _w ); +} + +inline Vector4::Vector4( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + mW = 0.0f; +} + +inline Vector4::Vector4( const Point3 & pnt ) +{ + mX = pnt.getX(); + mY = pnt.getY(); + mZ = pnt.getZ(); + mW = 1.0f; +} + +inline Vector4::Vector4( const Quat & quat ) +{ + mX = quat.getX(); + mY = quat.getY(); + mZ = quat.getZ(); + mW = quat.getW(); +} + +inline Vector4::Vector4( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; + mW = scalar; +} + +inline const Vector4 Vector4::xAxis( ) +{ + return Vector4( 1.0f, 0.0f, 0.0f, 0.0f ); +} + +inline const Vector4 Vector4::yAxis( ) +{ + return Vector4( 0.0f, 1.0f, 0.0f, 0.0f ); +} + +inline const Vector4 Vector4::zAxis( ) +{ + return Vector4( 0.0f, 0.0f, 1.0f, 0.0f ); +} + +inline const Vector4 Vector4::wAxis( ) +{ + return Vector4( 0.0f, 0.0f, 0.0f, 1.0f ); +} + +inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ) +{ + return ( vec0 + ( ( vec1 - vec0 ) * t ) ); +} + +inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ) +{ + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot( unitVec0, unitVec1 ); + if ( cosAngle < _VECTORMATH_SLERP_TOL ) { + angle = acosf( cosAngle ); + recipSinAngle = ( 1.0f / sinf( angle ) ); + scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); + scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); + } else { + scale0 = ( 1.0f - t ); + scale1 = t; + } + return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); +} + +inline void loadXYZW( Vector4 & vec, const float * fptr ) +{ + vec = Vector4( fptr[0], fptr[1], fptr[2], fptr[3] ); +} + +inline void storeXYZW( const Vector4 & vec, float * fptr ) +{ + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); + fptr[3] = vec.getW(); +} + +inline void loadHalfFloats( Vector4 & vec, const unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 4; i++) { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); + + if (exponent == 0) { + // zero + mantissa = 0; + + } else if (exponent == 31) { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + + } else { + exponent += 127 - 15; + mantissa <<= 13; + } + + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } +} + +inline void storeHalfFloats( const Vector4 & vec, unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 4; i++) { + Data32 d; + d.f32 = vec[i]; + + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + + if (exponent == 0) { + // zero or denorm -> zero + mantissa = 0; + + } else if (exponent == 255 && mantissa != 0) { + // nan -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent >= 127 - 15 + 31) { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent <= 127 - 15) { + // underflow -> zero + exponent = 0; + mantissa = 0; + + } else { + exponent -= 127 - 15; + mantissa >>= 13; + } + + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } +} + +inline Vector4 & Vector4::operator =( const Vector4 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + mW = vec.mW; + return *this; +} + +inline Vector4 & Vector4::setXYZ( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + return *this; +} + +inline const Vector3 Vector4::getXYZ( ) const +{ + return Vector3( mX, mY, mZ ); +} + +inline Vector4 & Vector4::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Vector4::getX( ) const +{ + return mX; +} + +inline Vector4 & Vector4::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Vector4::getY( ) const +{ + return mY; +} + +inline Vector4 & Vector4::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Vector4::getZ( ) const +{ + return mZ; +} + +inline Vector4 & Vector4::setW( float _w ) +{ + mW = _w; + return *this; +} + +inline float Vector4::getW( ) const +{ + return mW; +} + +inline Vector4 & Vector4::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Vector4::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Vector4::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Vector4::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Vector4 Vector4::operator +( const Vector4 & vec ) const +{ + return Vector4( + ( mX + vec.mX ), + ( mY + vec.mY ), + ( mZ + vec.mZ ), + ( mW + vec.mW ) + ); +} + +inline const Vector4 Vector4::operator -( const Vector4 & vec ) const +{ + return Vector4( + ( mX - vec.mX ), + ( mY - vec.mY ), + ( mZ - vec.mZ ), + ( mW - vec.mW ) + ); +} + +inline const Vector4 Vector4::operator *( float scalar ) const +{ + return Vector4( + ( mX * scalar ), + ( mY * scalar ), + ( mZ * scalar ), + ( mW * scalar ) + ); +} + +inline Vector4 & Vector4::operator +=( const Vector4 & vec ) +{ + *this = *this + vec; + return *this; +} + +inline Vector4 & Vector4::operator -=( const Vector4 & vec ) +{ + *this = *this - vec; + return *this; +} + +inline Vector4 & Vector4::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Vector4 Vector4::operator /( float scalar ) const +{ + return Vector4( + ( mX / scalar ), + ( mY / scalar ), + ( mZ / scalar ), + ( mW / scalar ) + ); +} + +inline Vector4 & Vector4::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +inline const Vector4 Vector4::operator -( ) const +{ + return Vector4( + -mX, + -mY, + -mZ, + -mW + ); +} + +inline const Vector4 operator *( float scalar, const Vector4 & vec ) +{ + return vec * scalar; +} + +inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + ( vec0.getX() * vec1.getX() ), + ( vec0.getY() * vec1.getY() ), + ( vec0.getZ() * vec1.getZ() ), + ( vec0.getW() * vec1.getW() ) + ); +} + +inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + ( vec0.getX() / vec1.getX() ), + ( vec0.getY() / vec1.getY() ), + ( vec0.getZ() / vec1.getZ() ), + ( vec0.getW() / vec1.getW() ) + ); +} + +inline const Vector4 recipPerElem( const Vector4 & vec ) +{ + return Vector4( + ( 1.0f / vec.getX() ), + ( 1.0f / vec.getY() ), + ( 1.0f / vec.getZ() ), + ( 1.0f / vec.getW() ) + ); +} + +inline const Vector4 sqrtPerElem( const Vector4 & vec ) +{ + return Vector4( + sqrtf( vec.getX() ), + sqrtf( vec.getY() ), + sqrtf( vec.getZ() ), + sqrtf( vec.getW() ) + ); +} + +inline const Vector4 rsqrtPerElem( const Vector4 & vec ) +{ + return Vector4( + ( 1.0f / sqrtf( vec.getX() ) ), + ( 1.0f / sqrtf( vec.getY() ) ), + ( 1.0f / sqrtf( vec.getZ() ) ), + ( 1.0f / sqrtf( vec.getW() ) ) + ); +} + +inline const Vector4 absPerElem( const Vector4 & vec ) +{ + return Vector4( + fabsf( vec.getX() ), + fabsf( vec.getY() ), + fabsf( vec.getZ() ), + fabsf( vec.getW() ) + ); +} + +inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), + ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), + ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ), + ( vec1.getW() < 0.0f )? -fabsf( vec0.getW() ) : fabsf( vec0.getW() ) + ); +} + +inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ(), + (vec0.getW() > vec1.getW())? vec0.getW() : vec1.getW() + ); +} + +inline float maxElem( const Vector4 & vec ) +{ + float result; + result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() > result)? vec.getZ() : result; + result = (vec.getW() > result)? vec.getW() : result; + return result; +} + +inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ(), + (vec0.getW() < vec1.getW())? vec0.getW() : vec1.getW() + ); +} + +inline float minElem( const Vector4 & vec ) +{ + float result; + result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() < result)? vec.getZ() : result; + result = (vec.getW() < result)? vec.getW() : result; + return result; +} + +inline float sum( const Vector4 & vec ) +{ + float result; + result = ( vec.getX() + vec.getY() ); + result = ( result + vec.getZ() ); + result = ( result + vec.getW() ); + return result; +} + +// ARA begin insert new code +inline float dot( const Vector4 & vec0, const Vector4 & vec1 ) +{ + float __attribute__((__aligned__((64)))) result[2]; // space for 2 floats since neon vst1.32 wants to store a double register + pfxVector4DotProductNEON(vec0, vec1, result); + return(result[0]); +} +// ARA end + +inline float lengthSqr( const Vector4 & vec ) +{ + float result; + result = ( vec.getX() * vec.getX() ); + result = ( result + ( vec.getY() * vec.getY() ) ); + result = ( result + ( vec.getZ() * vec.getZ() ) ); + result = ( result + ( vec.getW() * vec.getW() ) ); + return result; +} + +inline float length( const Vector4 & vec ) +{ + return ::sqrtf( lengthSqr( vec ) ); +} + +inline const Vector4 normalize( const Vector4 & vec ) +{ + float lenSqr, lenInv; + lenSqr = lengthSqr( vec ); + lenInv = ( 1.0f / sqrtf( lenSqr ) ); + return Vector4( + ( vec.getX() * lenInv ), + ( vec.getY() * lenInv ), + ( vec.getZ() * lenInv ), + ( vec.getW() * lenInv ) + ); +} + +inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ) +{ + return Vector4( + ( select1 )? vec1.getX() : vec0.getX(), + ( select1 )? vec1.getY() : vec0.getY(), + ( select1 )? vec1.getZ() : vec0.getZ(), + ( select1 )? vec1.getW() : vec0.getW() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Vector4 & vec ) +{ + printf( "( %f %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); +} + +inline void print( const Vector4 & vec, const char * name ) +{ + printf( "%s: ( %f %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); +} + +#endif + +inline Point3::Point3( const Point3 & pnt ) +{ + mX = pnt.mX; + mY = pnt.mY; + mZ = pnt.mZ; +// ARA begin insert new code + d = 0.0f; +// ARA end +} + +inline Point3::Point3( float _x, float _y, float _z ) +{ + mX = _x; + mY = _y; + mZ = _z; +// ARA begin insert new code + d = 0.0f; +// ARA end +} + +inline Point3::Point3( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); +// ARA begin insert new code + d = 0.0f; +// ARA end +} + +inline Point3::Point3( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; +// ARA begin insert new code + d = 0.0f; +// ARA end +} + +inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ) +{ + return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); +} + +inline void loadXYZ( Point3 & pnt, const float * fptr ) +{ + pnt = Point3( fptr[0], fptr[1], fptr[2] ); +} + +inline void storeXYZ( const Point3 & pnt, float * fptr ) +{ + fptr[0] = pnt.getX(); + fptr[1] = pnt.getY(); + fptr[2] = pnt.getZ(); +} + +inline void loadHalfFloats( Point3 & vec, const unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); + + if (exponent == 0) { + // zero + mantissa = 0; + + } else if (exponent == 31) { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + + } else { + exponent += 127 - 15; + mantissa <<= 13; + } + + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } +} + +inline void storeHalfFloats( const Point3 & vec, unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + Data32 d; + d.f32 = vec[i]; + + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + + if (exponent == 0) { + // zero or denorm -> zero + mantissa = 0; + + } else if (exponent == 255 && mantissa != 0) { + // nan -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent >= 127 - 15 + 31) { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent <= 127 - 15) { + // underflow -> zero + exponent = 0; + mantissa = 0; + + } else { + exponent -= 127 - 15; + mantissa >>= 13; + } + + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } +} + +inline Point3 & Point3::operator =( const Point3 & pnt ) +{ + mX = pnt.mX; + mY = pnt.mY; + mZ = pnt.mZ; + return *this; +} + +inline Point3 & Point3::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Point3::getX( ) const +{ + return mX; +} + +inline Point3 & Point3::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Point3::getY( ) const +{ + return mY; +} + +inline Point3 & Point3::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Point3::getZ( ) const +{ + return mZ; +} + +inline Point3 & Point3::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Point3::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Point3::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Point3::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Vector3 Point3::operator -( const Point3 & pnt ) const +{ + return Vector3( + ( mX - pnt.mX ), + ( mY - pnt.mY ), + ( mZ - pnt.mZ ) + ); +} + +inline const Point3 Point3::operator +( const Vector3 & vec ) const +{ + return Point3( + ( mX + vec.getX() ), + ( mY + vec.getY() ), + ( mZ + vec.getZ() ) + ); +} + +inline const Point3 Point3::operator -( const Vector3 & vec ) const +{ + return Point3( + ( mX - vec.getX() ), + ( mY - vec.getY() ), + ( mZ - vec.getZ() ) + ); +} + +inline Point3 & Point3::operator +=( const Vector3 & vec ) +{ + *this = *this + vec; + return *this; +} + +inline Point3 & Point3::operator -=( const Vector3 & vec ) +{ + *this = *this - vec; + return *this; +} + +inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + ( pnt0.getX() * pnt1.getX() ), + ( pnt0.getY() * pnt1.getY() ), + ( pnt0.getZ() * pnt1.getZ() ) + ); +} + +inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + ( pnt0.getX() / pnt1.getX() ), + ( pnt0.getY() / pnt1.getY() ), + ( pnt0.getZ() / pnt1.getZ() ) + ); +} + +inline const Point3 recipPerElem( const Point3 & pnt ) +{ + return Point3( + ( 1.0f / pnt.getX() ), + ( 1.0f / pnt.getY() ), + ( 1.0f / pnt.getZ() ) + ); +} + +inline const Point3 sqrtPerElem( const Point3 & pnt ) +{ + return Point3( + sqrtf( pnt.getX() ), + sqrtf( pnt.getY() ), + sqrtf( pnt.getZ() ) + ); +} + +inline const Point3 rsqrtPerElem( const Point3 & pnt ) +{ + return Point3( + ( 1.0f / sqrtf( pnt.getX() ) ), + ( 1.0f / sqrtf( pnt.getY() ) ), + ( 1.0f / sqrtf( pnt.getZ() ) ) + ); +} + +inline const Point3 absPerElem( const Point3 & pnt ) +{ + return Point3( + fabsf( pnt.getX() ), + fabsf( pnt.getY() ), + fabsf( pnt.getZ() ) + ); +} + +inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + ( pnt1.getX() < 0.0f )? -fabsf( pnt0.getX() ) : fabsf( pnt0.getX() ), + ( pnt1.getY() < 0.0f )? -fabsf( pnt0.getY() ) : fabsf( pnt0.getY() ), + ( pnt1.getZ() < 0.0f )? -fabsf( pnt0.getZ() ) : fabsf( pnt0.getZ() ) + ); +} + +inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + (pnt0.getX() > pnt1.getX())? pnt0.getX() : pnt1.getX(), + (pnt0.getY() > pnt1.getY())? pnt0.getY() : pnt1.getY(), + (pnt0.getZ() > pnt1.getZ())? pnt0.getZ() : pnt1.getZ() + ); +} + +inline float maxElem( const Point3 & pnt ) +{ + float result; + result = (pnt.getX() > pnt.getY())? pnt.getX() : pnt.getY(); + result = (pnt.getZ() > result)? pnt.getZ() : result; + return result; +} + +inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + (pnt0.getX() < pnt1.getX())? pnt0.getX() : pnt1.getX(), + (pnt0.getY() < pnt1.getY())? pnt0.getY() : pnt1.getY(), + (pnt0.getZ() < pnt1.getZ())? pnt0.getZ() : pnt1.getZ() + ); +} + +inline float minElem( const Point3 & pnt ) +{ + float result; + result = (pnt.getX() < pnt.getY())? pnt.getX() : pnt.getY(); + result = (pnt.getZ() < result)? pnt.getZ() : result; + return result; +} + +inline float sum( const Point3 & pnt ) +{ + float result; + result = ( pnt.getX() + pnt.getY() ); + result = ( result + pnt.getZ() ); + return result; +} + +inline const Point3 scale( const Point3 & pnt, float scaleVal ) +{ + return mulPerElem( pnt, Point3( scaleVal ) ); +} + +inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ) +{ + return mulPerElem( pnt, Point3( scaleVec ) ); +} + +inline float projection( const Point3 & pnt, const Vector3 & unitVec ) +{ + float result; + result = ( pnt.getX() * unitVec.getX() ); + result = ( result + ( pnt.getY() * unitVec.getY() ) ); + result = ( result + ( pnt.getZ() * unitVec.getZ() ) ); + return result; +} + +inline float distSqrFromOrigin( const Point3 & pnt ) +{ + return lengthSqr( Vector3( pnt ) ); +} + +inline float distFromOrigin( const Point3 & pnt ) +{ + return length( Vector3( pnt ) ); +} + +inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return lengthSqr( ( pnt1 - pnt0 ) ); +} + +inline float dist( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return length( ( pnt1 - pnt0 ) ); +} + +inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ) +{ + return Point3( + ( select1 )? pnt1.getX() : pnt0.getX(), + ( select1 )? pnt1.getY() : pnt0.getY(), + ( select1 )? pnt1.getZ() : pnt0.getZ() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Point3 & pnt ) +{ + printf( "( %f %f %f )\n", pnt.getX(), pnt.getY(), pnt.getZ() ); +} + +inline void print( const Point3 & pnt, const char * name ) +{ + printf( "%s: ( %f %f %f )\n", name, pnt.getX(), pnt.getY(), pnt.getZ() ); +} + +#endif + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/Extras/PhysicsEffects/include/vecmath/neon/vectormath_aos.h b/Extras/PhysicsEffects/include/vecmath/neon/vectormath_aos.h new file mode 100644 index 000000000..d884e8727 --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/neon/vectormath_aos.h @@ -0,0 +1,1893 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _VECTORMATH_AOS_CPP_SCALAR_H +#define _VECTORMATH_AOS_CPP_SCALAR_H + +#include + +#ifdef _VECTORMATH_DEBUG +#include +#endif + +namespace Vectormath { + +namespace Aos { + +//----------------------------------------------------------------------------- +// Forward Declarations +// + +class Vector3; +class Vector4; +class Point3; +class Quat; +class Matrix3; +class Matrix4; +class Transform3; + +// A 3-D vector in array-of-structures format +// +class Vector3 +{ + float mX; + float mY; + float mZ; +// ARA begin code change +// Removed #ifndef __GNUC__ condition + float d; +// ARA end + +public: + // Default constructor; does no initialization + // + // ARA begin insert new code + // Added explicit initialization of d = 0.0f; + inline Vector3( ) { d = 0.0f; }; + // ARA end + + // Copy a 3-D vector + // + inline Vector3( const Vector3 & vec ); + + // Construct a 3-D vector from x, y, and z elements + // + inline Vector3( float x, float y, float z ); + + // Copy elements from a 3-D point into a 3-D vector + // + explicit inline Vector3( const Point3 & pnt ); + + // Set all elements of a 3-D vector to the same scalar value + // + explicit inline Vector3( float scalar ); + + // Assign one 3-D vector to another + // + inline Vector3 & operator =( const Vector3 & vec ); + + // Set the x element of a 3-D vector + // + inline Vector3 & setX( float x ); + + // Set the y element of a 3-D vector + // + inline Vector3 & setY( float y ); + + // Set the z element of a 3-D vector + // + inline Vector3 & setZ( float z ); + + // Get the x element of a 3-D vector + // + inline float getX( ) const; + + // Get the y element of a 3-D vector + // + inline float getY( ) const; + + // Get the z element of a 3-D vector + // + inline float getZ( ) const; + + // Set an x, y, or z element of a 3-D vector by index + // + inline Vector3 & setElem( int idx, float value ); + + // Get an x, y, or z element of a 3-D vector by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Add two 3-D vectors + // + inline const Vector3 operator +( const Vector3 & vec ) const; + + // Subtract a 3-D vector from another 3-D vector + // + inline const Vector3 operator -( const Vector3 & vec ) const; + + // Add a 3-D vector to a 3-D point + // + inline const Point3 operator +( const Point3 & pnt ) const; + + // Multiply a 3-D vector by a scalar + // + inline const Vector3 operator *( float scalar ) const; + + // Divide a 3-D vector by a scalar + // + inline const Vector3 operator /( float scalar ) const; + + // Perform compound assignment and addition with a 3-D vector + // + inline Vector3 & operator +=( const Vector3 & vec ); + + // Perform compound assignment and subtraction by a 3-D vector + // + inline Vector3 & operator -=( const Vector3 & vec ); + + // Perform compound assignment and multiplication by a scalar + // + inline Vector3 & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + inline Vector3 & operator /=( float scalar ); + + // Negate all elements of a 3-D vector + // + inline const Vector3 operator -( ) const; + + // Construct x axis + // + static inline const Vector3 xAxis( ); + + // Construct y axis + // + static inline const Vector3 yAxis( ); + + // Construct z axis + // + static inline const Vector3 zAxis( ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply a 3-D vector by a scalar +// +inline const Vector3 operator *( float scalar, const Vector3 & vec ); + +// Multiply two 3-D vectors per element +// +inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Divide two 3-D vectors per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Compute the reciprocal of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +inline const Vector3 recipPerElem( const Vector3 & vec ); + +// Compute the square root of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function sqrtf4. +// +inline const Vector3 sqrtPerElem( const Vector3 & vec ); + +// Compute the reciprocal square root of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function rsqrtf4. +// +inline const Vector3 rsqrtPerElem( const Vector3 & vec ); + +// Compute the absolute value of a 3-D vector per element +// +inline const Vector3 absPerElem( const Vector3 & vec ); + +// Copy sign from one 3-D vector to another, per element +// +inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Maximum of two 3-D vectors per element +// +inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Minimum of two 3-D vectors per element +// +inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Maximum element of a 3-D vector +// +inline float maxElem( const Vector3 & vec ); + +// Minimum element of a 3-D vector +// +inline float minElem( const Vector3 & vec ); + +// Compute the sum of all elements of a 3-D vector +// +inline float sum( const Vector3 & vec ); + +// Compute the dot product of two 3-D vectors +// +inline float dot( const Vector3 & vec0, const Vector3 & vec1 ); + +// Compute the square of the length of a 3-D vector +// +inline float lengthSqr( const Vector3 & vec ); + +// Compute the length of a 3-D vector +// +inline float length( const Vector3 & vec ); + +// Normalize a 3-D vector +// NOTE: +// The result is unpredictable when all elements of vec are at or near zero. +// +inline const Vector3 normalize( const Vector3 & vec ); + +// Compute cross product of two 3-D vectors +// +inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ); + +// Outer product of two 3-D vectors +// +inline const Matrix3 outer( const Vector3 & vec0, const Vector3 & vec1 ); + +// Pre-multiply a row vector by a 3x3 matrix +// +inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ); + +// Cross-product matrix of a 3-D vector +// +inline const Matrix3 crossMatrix( const Vector3 & vec ); + +// Create cross-product matrix and multiply +// NOTE: +// Faster than separately creating a cross-product matrix and multiplying. +// +inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ); + +// Linear interpolation between two 3-D vectors +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ); + +// Spherical linear interpolation between two 3-D vectors +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ); + +// Conditionally select between two 3-D vectors +// +inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ); + +// Load x, y, and z elements from the first three words of a float array. +// +// +inline void loadXYZ( Vector3 & vec, const float * fptr ); + +// Store x, y, and z elements of a 3-D vector in the first three words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZ( const Vector3 & vec, float * fptr ); + +// Load three-half-floats as a 3-D vector +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. +// +inline void loadHalfFloats( Vector3 & vec, const unsigned short * hfptr ); + +// Store a 3-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// +inline void storeHalfFloats( const Vector3 & vec, unsigned short * hfptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3-D vector +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector3 & vec ); + +// Print a 3-D vector and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector3 & vec, const char * name ); + +#endif + +// A 4-D vector in array-of-structures format +// +class Vector4 +{ + float mX; + float mY; + float mZ; + float mW; + +public: + // Default constructor; does no initialization + // + inline Vector4( ) { }; + + // Copy a 4-D vector + // + inline Vector4( const Vector4 & vec ); + + // Construct a 4-D vector from x, y, z, and w elements + // + inline Vector4( float x, float y, float z, float w ); + + // Construct a 4-D vector from a 3-D vector and a scalar + // + inline Vector4( const Vector3 & xyz, float w ); + + // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 + // + explicit inline Vector4( const Vector3 & vec ); + + // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 + // + explicit inline Vector4( const Point3 & pnt ); + + // Copy elements from a quaternion into a 4-D vector + // + explicit inline Vector4( const Quat & quat ); + + // Set all elements of a 4-D vector to the same scalar value + // + explicit inline Vector4( float scalar ); + + // Assign one 4-D vector to another + // + inline Vector4 & operator =( const Vector4 & vec ); + + // Set the x, y, and z elements of a 4-D vector + // NOTE: + // This function does not change the w element. + // + inline Vector4 & setXYZ( const Vector3 & vec ); + + // Get the x, y, and z elements of a 4-D vector + // + inline const Vector3 getXYZ( ) const; + + // Set the x element of a 4-D vector + // + inline Vector4 & setX( float x ); + + // Set the y element of a 4-D vector + // + inline Vector4 & setY( float y ); + + // Set the z element of a 4-D vector + // + inline Vector4 & setZ( float z ); + + // Set the w element of a 4-D vector + // + inline Vector4 & setW( float w ); + + // Get the x element of a 4-D vector + // + inline float getX( ) const; + + // Get the y element of a 4-D vector + // + inline float getY( ) const; + + // Get the z element of a 4-D vector + // + inline float getZ( ) const; + + // Get the w element of a 4-D vector + // + inline float getW( ) const; + + // Set an x, y, z, or w element of a 4-D vector by index + // + inline Vector4 & setElem( int idx, float value ); + + // Get an x, y, z, or w element of a 4-D vector by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Add two 4-D vectors + // + inline const Vector4 operator +( const Vector4 & vec ) const; + + // Subtract a 4-D vector from another 4-D vector + // + inline const Vector4 operator -( const Vector4 & vec ) const; + + // Multiply a 4-D vector by a scalar + // + inline const Vector4 operator *( float scalar ) const; + + // Divide a 4-D vector by a scalar + // + inline const Vector4 operator /( float scalar ) const; + + // Perform compound assignment and addition with a 4-D vector + // + inline Vector4 & operator +=( const Vector4 & vec ); + + // Perform compound assignment and subtraction by a 4-D vector + // + inline Vector4 & operator -=( const Vector4 & vec ); + + // Perform compound assignment and multiplication by a scalar + // + inline Vector4 & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + inline Vector4 & operator /=( float scalar ); + + // Negate all elements of a 4-D vector + // + inline const Vector4 operator -( ) const; + + // Construct x axis + // + static inline const Vector4 xAxis( ); + + // Construct y axis + // + static inline const Vector4 yAxis( ); + + // Construct z axis + // + static inline const Vector4 zAxis( ); + + // Construct w axis + // + static inline const Vector4 wAxis( ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply a 4-D vector by a scalar +// +inline const Vector4 operator *( float scalar, const Vector4 & vec ); + +// Multiply two 4-D vectors per element +// +inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Divide two 4-D vectors per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Compute the reciprocal of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +inline const Vector4 recipPerElem( const Vector4 & vec ); + +// Compute the square root of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function sqrtf4. +// +inline const Vector4 sqrtPerElem( const Vector4 & vec ); + +// Compute the reciprocal square root of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function rsqrtf4. +// +inline const Vector4 rsqrtPerElem( const Vector4 & vec ); + +// Compute the absolute value of a 4-D vector per element +// +inline const Vector4 absPerElem( const Vector4 & vec ); + +// Copy sign from one 4-D vector to another, per element +// +inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Maximum of two 4-D vectors per element +// +inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Minimum of two 4-D vectors per element +// +inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Maximum element of a 4-D vector +// +inline float maxElem( const Vector4 & vec ); + +// Minimum element of a 4-D vector +// +inline float minElem( const Vector4 & vec ); + +// Compute the sum of all elements of a 4-D vector +// +inline float sum( const Vector4 & vec ); + +// Compute the dot product of two 4-D vectors +// +inline float dot( const Vector4 & vec0, const Vector4 & vec1 ); + +// Compute the square of the length of a 4-D vector +// +inline float lengthSqr( const Vector4 & vec ); + +// Compute the length of a 4-D vector +// +inline float length( const Vector4 & vec ); + +// Normalize a 4-D vector +// NOTE: +// The result is unpredictable when all elements of vec are at or near zero. +// +inline const Vector4 normalize( const Vector4 & vec ); + +// Outer product of two 4-D vectors +// +inline const Matrix4 outer( const Vector4 & vec0, const Vector4 & vec1 ); + +// Linear interpolation between two 4-D vectors +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ); + +// Spherical linear interpolation between two 4-D vectors +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ); + +// Conditionally select between two 4-D vectors +// +inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ); + +// Load x, y, z, and w elements from the first four words of a float array. +// +// +inline void loadXYZW( Vector4 & vec, const float * fptr ); + +// Store x, y, z, and w elements of a 4-D vector in the first four words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZW( const Vector4 & vec, float * fptr ); + +// Load four-half-floats as a 4-D vector +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. +// +inline void loadHalfFloats( Vector4 & vec, const unsigned short * hfptr ); + +// Store a 4-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// +inline void storeHalfFloats( const Vector4 & vec, unsigned short * hfptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 4-D vector +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector4 & vec ); + +// Print a 4-D vector and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector4 & vec, const char * name ); + +#endif + +// A 3-D point in array-of-structures format +// +class Point3 +{ + float mX; + float mY; + float mZ; +// ARA begin code change +// Removed #ifndef __GNUC__ condition + float d; +// ARA end + +public: + // Default constructor; does no initialization + // + // ARA begin insert new code + // Added explicit initialization of d = 0.0f; + inline Point3( ) { d = 0.0f; }; + // ARA end + + // Copy a 3-D point + // + inline Point3( const Point3 & pnt ); + + // Construct a 3-D point from x, y, and z elements + // + inline Point3( float x, float y, float z ); + + // Copy elements from a 3-D vector into a 3-D point + // + explicit inline Point3( const Vector3 & vec ); + + // Set all elements of a 3-D point to the same scalar value + // + explicit inline Point3( float scalar ); + + // Assign one 3-D point to another + // + inline Point3 & operator =( const Point3 & pnt ); + + // Set the x element of a 3-D point + // + inline Point3 & setX( float x ); + + // Set the y element of a 3-D point + // + inline Point3 & setY( float y ); + + // Set the z element of a 3-D point + // + inline Point3 & setZ( float z ); + + // Get the x element of a 3-D point + // + inline float getX( ) const; + + // Get the y element of a 3-D point + // + inline float getY( ) const; + + // Get the z element of a 3-D point + // + inline float getZ( ) const; + + // Set an x, y, or z element of a 3-D point by index + // + inline Point3 & setElem( int idx, float value ); + + // Get an x, y, or z element of a 3-D point by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Subtract a 3-D point from another 3-D point + // + inline const Vector3 operator -( const Point3 & pnt ) const; + + // Add a 3-D point to a 3-D vector + // + inline const Point3 operator +( const Vector3 & vec ) const; + + // Subtract a 3-D vector from a 3-D point + // + inline const Point3 operator -( const Vector3 & vec ) const; + + // Perform compound assignment and addition with a 3-D vector + // + inline Point3 & operator +=( const Vector3 & vec ); + + // Perform compound assignment and subtraction by a 3-D vector + // + inline Point3 & operator -=( const Vector3 & vec ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply two 3-D points per element +// +inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Divide two 3-D points per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Compute the reciprocal of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +inline const Point3 recipPerElem( const Point3 & pnt ); + +// Compute the square root of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function sqrtf4. +// +inline const Point3 sqrtPerElem( const Point3 & pnt ); + +// Compute the reciprocal square root of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function rsqrtf4. +// +inline const Point3 rsqrtPerElem( const Point3 & pnt ); + +// Compute the absolute value of a 3-D point per element +// +inline const Point3 absPerElem( const Point3 & pnt ); + +// Copy sign from one 3-D point to another, per element +// +inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Maximum of two 3-D points per element +// +inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Minimum of two 3-D points per element +// +inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Maximum element of a 3-D point +// +inline float maxElem( const Point3 & pnt ); + +// Minimum element of a 3-D point +// +inline float minElem( const Point3 & pnt ); + +// Compute the sum of all elements of a 3-D point +// +inline float sum( const Point3 & pnt ); + +// Apply uniform scale to a 3-D point +// +inline const Point3 scale( const Point3 & pnt, float scaleVal ); + +// Apply non-uniform scale to a 3-D point +// +inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ); + +// Scalar projection of a 3-D point on a unit-length 3-D vector +// +inline float projection( const Point3 & pnt, const Vector3 & unitVec ); + +// Compute the square of the distance of a 3-D point from the coordinate-system origin +// +inline float distSqrFromOrigin( const Point3 & pnt ); + +// Compute the distance of a 3-D point from the coordinate-system origin +// +inline float distFromOrigin( const Point3 & pnt ); + +// Compute the square of the distance between two 3-D points +// +inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ); + +// Compute the distance between two 3-D points +// +inline float dist( const Point3 & pnt0, const Point3 & pnt1 ); + +// Linear interpolation between two 3-D points +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ); + +// Conditionally select between two 3-D points +// +inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ); + +// Load x, y, and z elements from the first three words of a float array. +// +// +inline void loadXYZ( Point3 & pnt, const float * fptr ); + +// Store x, y, and z elements of a 3-D point in the first three words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZ( const Point3 & pnt, float * fptr ); + +// Load three-half-floats as a 3-D point +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. +// +inline void loadHalfFloats( Point3 & pnt, const unsigned short * hfptr ); + +// Store a 3-D point as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// +inline void storeHalfFloats( const Point3 & pnt, unsigned short * hfptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3-D point +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Point3 & pnt ); + +// Print a 3-D point and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Point3 & pnt, const char * name ); + +#endif + +// A quaternion in array-of-structures format +// +class Quat +{ + float mX; + float mY; + float mZ; + float mW; + +public: + // Default constructor; does no initialization + // + inline Quat( ) { }; + + // Copy a quaternion + // + inline Quat( const Quat & quat ); + + // Construct a quaternion from x, y, z, and w elements + // + inline Quat( float x, float y, float z, float w ); + + // Construct a quaternion from a 3-D vector and a scalar + // + inline Quat( const Vector3 & xyz, float w ); + + // Copy elements from a 4-D vector into a quaternion + // + explicit inline Quat( const Vector4 & vec ); + + // Convert a rotation matrix to a unit-length quaternion + // + explicit inline Quat( const Matrix3 & rotMat ); + + // Set all elements of a quaternion to the same scalar value + // + explicit inline Quat( float scalar ); + + // Assign one quaternion to another + // + inline Quat & operator =( const Quat & quat ); + + // Set the x, y, and z elements of a quaternion + // NOTE: + // This function does not change the w element. + // + inline Quat & setXYZ( const Vector3 & vec ); + + // Get the x, y, and z elements of a quaternion + // + inline const Vector3 getXYZ( ) const; + + // Set the x element of a quaternion + // + inline Quat & setX( float x ); + + // Set the y element of a quaternion + // + inline Quat & setY( float y ); + + // Set the z element of a quaternion + // + inline Quat & setZ( float z ); + + // Set the w element of a quaternion + // + inline Quat & setW( float w ); + + // Get the x element of a quaternion + // + inline float getX( ) const; + + // Get the y element of a quaternion + // + inline float getY( ) const; + + // Get the z element of a quaternion + // + inline float getZ( ) const; + + // Get the w element of a quaternion + // + inline float getW( ) const; + + // Set an x, y, z, or w element of a quaternion by index + // + inline Quat & setElem( int idx, float value ); + + // Get an x, y, z, or w element of a quaternion by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Add two quaternions + // + inline const Quat operator +( const Quat & quat ) const; + + // Subtract a quaternion from another quaternion + // + inline const Quat operator -( const Quat & quat ) const; + + // Multiply two quaternions + // + inline const Quat operator *( const Quat & quat ) const; + + // Multiply a quaternion by a scalar + // + inline const Quat operator *( float scalar ) const; + + // Divide a quaternion by a scalar + // + inline const Quat operator /( float scalar ) const; + + // Perform compound assignment and addition with a quaternion + // + inline Quat & operator +=( const Quat & quat ); + + // Perform compound assignment and subtraction by a quaternion + // + inline Quat & operator -=( const Quat & quat ); + + // Perform compound assignment and multiplication by a quaternion + // + inline Quat & operator *=( const Quat & quat ); + + // Perform compound assignment and multiplication by a scalar + // + inline Quat & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + inline Quat & operator /=( float scalar ); + + // Negate all elements of a quaternion + // + inline const Quat operator -( ) const; + + // Construct an identity quaternion + // + static inline const Quat identity( ); + + // Construct a quaternion to rotate between two unit-length 3-D vectors + // NOTE: + // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. + // + static inline const Quat rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ); + + // Construct a quaternion to rotate around a unit-length 3-D vector + // + static inline const Quat rotation( float radians, const Vector3 & unitVec ); + + // Construct a quaternion to rotate around the x axis + // + static inline const Quat rotationX( float radians ); + + // Construct a quaternion to rotate around the y axis + // + static inline const Quat rotationY( float radians ); + + // Construct a quaternion to rotate around the z axis + // + static inline const Quat rotationZ( float radians ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply a quaternion by a scalar +// +inline const Quat operator *( float scalar, const Quat & quat ); + +// Compute the conjugate of a quaternion +// +inline const Quat conj( const Quat & quat ); + +// Use a unit-length quaternion to rotate a 3-D vector +// +inline const Vector3 rotate( const Quat & unitQuat, const Vector3 & vec ); + +// Compute the dot product of two quaternions +// +inline float dot( const Quat & quat0, const Quat & quat1 ); + +// Compute the norm of a quaternion +// +inline float norm( const Quat & quat ); + +// Compute the length of a quaternion +// +inline float length( const Quat & quat ); + +// Normalize a quaternion +// NOTE: +// The result is unpredictable when all elements of quat are at or near zero. +// +inline const Quat normalize( const Quat & quat ); + +// Linear interpolation between two quaternions +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ); + +// Spherical linear interpolation between two quaternions +// NOTE: +// Interpolates along the shortest path between orientations. +// Does not clamp t between 0 and 1. +// +inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ); + +// Spherical quadrangle interpolation +// +inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ); + +// Conditionally select between two quaternions +// +inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ); + +// Load x, y, z, and w elements from the first four words of a float array. +// +// +inline void loadXYZW( Quat & quat, const float * fptr ); + +// Store x, y, z, and w elements of a quaternion in the first four words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZW( const Quat & quat, float * fptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a quaternion +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Quat & quat ); + +// Print a quaternion and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Quat & quat, const char * name ); + +#endif + +// A 3x3 matrix in array-of-structures format +// +class Matrix3 +{ + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + +public: + // Default constructor; does no initialization + // + inline Matrix3( ) { }; + + // Copy a 3x3 matrix + // + inline Matrix3( const Matrix3 & mat ); + + // Construct a 3x3 matrix containing the specified columns + // + inline Matrix3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2 ); + + // Construct a 3x3 rotation matrix from a unit-length quaternion + // + explicit inline Matrix3( const Quat & unitQuat ); + + // Set all elements of a 3x3 matrix to the same scalar value + // + explicit inline Matrix3( float scalar ); + + // Assign one 3x3 matrix to another + // + inline Matrix3 & operator =( const Matrix3 & mat ); + + // Set column 0 of a 3x3 matrix + // + inline Matrix3 & setCol0( const Vector3 & col0 ); + + // Set column 1 of a 3x3 matrix + // + inline Matrix3 & setCol1( const Vector3 & col1 ); + + // Set column 2 of a 3x3 matrix + // + inline Matrix3 & setCol2( const Vector3 & col2 ); + + // Get column 0 of a 3x3 matrix + // + inline const Vector3 getCol0( ) const; + + // Get column 1 of a 3x3 matrix + // + inline const Vector3 getCol1( ) const; + + // Get column 2 of a 3x3 matrix + // + inline const Vector3 getCol2( ) const; + + // Set the column of a 3x3 matrix referred to by the specified index + // + inline Matrix3 & setCol( int col, const Vector3 & vec ); + + // Set the row of a 3x3 matrix referred to by the specified index + // + inline Matrix3 & setRow( int row, const Vector3 & vec ); + + // Get the column of a 3x3 matrix referred to by the specified index + // + inline const Vector3 getCol( int col ) const; + + // Get the row of a 3x3 matrix referred to by the specified index + // + inline const Vector3 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + inline Vector3 & operator []( int col ); + + // Subscripting operator to get a column + // + inline const Vector3 operator []( int col ) const; + + // Set the element of a 3x3 matrix referred to by column and row indices + // + inline Matrix3 & setElem( int col, int row, float val ); + + // Get the element of a 3x3 matrix referred to by column and row indices + // + inline float getElem( int col, int row ) const; + + // Add two 3x3 matrices + // + inline const Matrix3 operator +( const Matrix3 & mat ) const; + + // Subtract a 3x3 matrix from another 3x3 matrix + // + inline const Matrix3 operator -( const Matrix3 & mat ) const; + + // Negate all elements of a 3x3 matrix + // + inline const Matrix3 operator -( ) const; + + // Multiply a 3x3 matrix by a scalar + // + inline const Matrix3 operator *( float scalar ) const; + + // Multiply a 3x3 matrix by a 3-D vector + // + inline const Vector3 operator *( const Vector3 & vec ) const; + + // Multiply two 3x3 matrices + // + inline const Matrix3 operator *( const Matrix3 & mat ) const; + + // Perform compound assignment and addition with a 3x3 matrix + // + inline Matrix3 & operator +=( const Matrix3 & mat ); + + // Perform compound assignment and subtraction by a 3x3 matrix + // + inline Matrix3 & operator -=( const Matrix3 & mat ); + + // Perform compound assignment and multiplication by a scalar + // + inline Matrix3 & operator *=( float scalar ); + + // Perform compound assignment and multiplication by a 3x3 matrix + // + inline Matrix3 & operator *=( const Matrix3 & mat ); + + // Construct an identity 3x3 matrix + // + static inline const Matrix3 identity( ); + + // Construct a 3x3 matrix to rotate around the x axis + // + static inline const Matrix3 rotationX( float radians ); + + // Construct a 3x3 matrix to rotate around the y axis + // + static inline const Matrix3 rotationY( float radians ); + + // Construct a 3x3 matrix to rotate around the z axis + // + static inline const Matrix3 rotationZ( float radians ); + + // Construct a 3x3 matrix to rotate around the x, y, and z axes + // + static inline const Matrix3 rotationZYX( const Vector3 & radiansXYZ ); + + // Construct a 3x3 matrix to rotate around a unit-length 3-D vector + // + static inline const Matrix3 rotation( float radians, const Vector3 & unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Matrix3 rotation( const Quat & unitQuat ); + + // Construct a 3x3 matrix to perform scaling + // + static inline const Matrix3 scale( const Vector3 & scaleVec ); + +}; +// Multiply a 3x3 matrix by a scalar +// +inline const Matrix3 operator *( float scalar, const Matrix3 & mat ); + +// Append (post-multiply) a scale transformation to a 3x3 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 3x3 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ); + +// Multiply two 3x3 matrices per element +// +inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); + +// Compute the absolute value of a 3x3 matrix per element +// +inline const Matrix3 absPerElem( const Matrix3 & mat ); + +// Transpose of a 3x3 matrix +// +inline const Matrix3 transpose( const Matrix3 & mat ); + +// Compute the inverse of a 3x3 matrix +// NOTE: +// Result is unpredictable when the determinant of mat is equal to or near 0. +// +inline const Matrix3 inverse( const Matrix3 & mat ); + +// Determinant of a 3x3 matrix +// +inline float determinant( const Matrix3 & mat ); + +// Conditionally select between two 3x3 matrices +// +inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3x3 matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix3 & mat ); + +// Print a 3x3 matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix3 & mat, const char * name ); + +#endif + +// A 4x4 matrix in array-of-structures format +// +class Matrix4 +{ + Vector4 mCol0; + Vector4 mCol1; + Vector4 mCol2; + Vector4 mCol3; + +public: + // Default constructor; does no initialization + // + inline Matrix4( ) { }; + + // Copy a 4x4 matrix + // + inline Matrix4( const Matrix4 & mat ); + + // Construct a 4x4 matrix containing the specified columns + // + inline Matrix4( const Vector4 & col0, const Vector4 & col1, const Vector4 & col2, const Vector4 & col3 ); + + // Construct a 4x4 matrix from a 3x4 transformation matrix + // + explicit inline Matrix4( const Transform3 & mat ); + + // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector + // + inline Matrix4( const Matrix3 & mat, const Vector3 & translateVec ); + + // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector + // + inline Matrix4( const Quat & unitQuat, const Vector3 & translateVec ); + + // Set all elements of a 4x4 matrix to the same scalar value + // + explicit inline Matrix4( float scalar ); + + // Assign one 4x4 matrix to another + // + inline Matrix4 & operator =( const Matrix4 & mat ); + + // Set the upper-left 3x3 submatrix + // NOTE: + // This function does not change the bottom row elements. + // + inline Matrix4 & setUpper3x3( const Matrix3 & mat3 ); + + // Get the upper-left 3x3 submatrix of a 4x4 matrix + // + inline const Matrix3 getUpper3x3( ) const; + + // Set translation component + // NOTE: + // This function does not change the bottom row elements. + // + inline Matrix4 & setTranslation( const Vector3 & translateVec ); + + // Get the translation component of a 4x4 matrix + // + inline const Vector3 getTranslation( ) const; + + // Set column 0 of a 4x4 matrix + // + inline Matrix4 & setCol0( const Vector4 & col0 ); + + // Set column 1 of a 4x4 matrix + // + inline Matrix4 & setCol1( const Vector4 & col1 ); + + // Set column 2 of a 4x4 matrix + // + inline Matrix4 & setCol2( const Vector4 & col2 ); + + // Set column 3 of a 4x4 matrix + // + inline Matrix4 & setCol3( const Vector4 & col3 ); + + // Get column 0 of a 4x4 matrix + // + inline const Vector4 getCol0( ) const; + + // Get column 1 of a 4x4 matrix + // + inline const Vector4 getCol1( ) const; + + // Get column 2 of a 4x4 matrix + // + inline const Vector4 getCol2( ) const; + + // Get column 3 of a 4x4 matrix + // + inline const Vector4 getCol3( ) const; + + // Set the column of a 4x4 matrix referred to by the specified index + // + inline Matrix4 & setCol( int col, const Vector4 & vec ); + + // Set the row of a 4x4 matrix referred to by the specified index + // + inline Matrix4 & setRow( int row, const Vector4 & vec ); + + // Get the column of a 4x4 matrix referred to by the specified index + // + inline const Vector4 getCol( int col ) const; + + // Get the row of a 4x4 matrix referred to by the specified index + // + inline const Vector4 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + inline Vector4 & operator []( int col ); + + // Subscripting operator to get a column + // + inline const Vector4 operator []( int col ) const; + + // Set the element of a 4x4 matrix referred to by column and row indices + // + inline Matrix4 & setElem( int col, int row, float val ); + + // Get the element of a 4x4 matrix referred to by column and row indices + // + inline float getElem( int col, int row ) const; + + // Add two 4x4 matrices + // + inline const Matrix4 operator +( const Matrix4 & mat ) const; + + // Subtract a 4x4 matrix from another 4x4 matrix + // + inline const Matrix4 operator -( const Matrix4 & mat ) const; + + // Negate all elements of a 4x4 matrix + // + inline const Matrix4 operator -( ) const; + + // Multiply a 4x4 matrix by a scalar + // + inline const Matrix4 operator *( float scalar ) const; + + // Multiply a 4x4 matrix by a 4-D vector + // + inline const Vector4 operator *( const Vector4 & vec ) const; + + // Multiply a 4x4 matrix by a 3-D vector + // + inline const Vector4 operator *( const Vector3 & vec ) const; + + // Multiply a 4x4 matrix by a 3-D point + // + inline const Vector4 operator *( const Point3 & pnt ) const; + + // Multiply two 4x4 matrices + // + inline const Matrix4 operator *( const Matrix4 & mat ) const; + + // Multiply a 4x4 matrix by a 3x4 transformation matrix + // + inline const Matrix4 operator *( const Transform3 & tfrm ) const; + + // Perform compound assignment and addition with a 4x4 matrix + // + inline Matrix4 & operator +=( const Matrix4 & mat ); + + // Perform compound assignment and subtraction by a 4x4 matrix + // + inline Matrix4 & operator -=( const Matrix4 & mat ); + + // Perform compound assignment and multiplication by a scalar + // + inline Matrix4 & operator *=( float scalar ); + + // Perform compound assignment and multiplication by a 4x4 matrix + // + inline Matrix4 & operator *=( const Matrix4 & mat ); + + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + inline Matrix4 & operator *=( const Transform3 & tfrm ); + + // Construct an identity 4x4 matrix + // + static inline const Matrix4 identity( ); + + // Construct a 4x4 matrix to rotate around the x axis + // + static inline const Matrix4 rotationX( float radians ); + + // Construct a 4x4 matrix to rotate around the y axis + // + static inline const Matrix4 rotationY( float radians ); + + // Construct a 4x4 matrix to rotate around the z axis + // + static inline const Matrix4 rotationZ( float radians ); + + // Construct a 4x4 matrix to rotate around the x, y, and z axes + // + static inline const Matrix4 rotationZYX( const Vector3 & radiansXYZ ); + + // Construct a 4x4 matrix to rotate around a unit-length 3-D vector + // + static inline const Matrix4 rotation( float radians, const Vector3 & unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Matrix4 rotation( const Quat & unitQuat ); + + // Construct a 4x4 matrix to perform scaling + // + static inline const Matrix4 scale( const Vector3 & scaleVec ); + + // Construct a 4x4 matrix to perform translation + // + static inline const Matrix4 translation( const Vector3 & translateVec ); + + // Construct viewing matrix based on eye position, position looked at, and up direction + // + static inline const Matrix4 lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ); + + // Construct a perspective projection matrix + // + static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar ); + + // Construct a perspective projection matrix based on frustum + // + static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar ); + + // Construct an orthographic projection matrix + // + static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar ); + +}; +// Multiply a 4x4 matrix by a scalar +// +inline const Matrix4 operator *( float scalar, const Matrix4 & mat ); + +// Append (post-multiply) a scale transformation to a 4x4 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 4x4 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ); + +// Multiply two 4x4 matrices per element +// +inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); + +// Compute the absolute value of a 4x4 matrix per element +// +inline const Matrix4 absPerElem( const Matrix4 & mat ); + +// Transpose of a 4x4 matrix +// +inline const Matrix4 transpose( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix +// NOTE: +// Result is unpredictable when the determinant of mat is equal to or near 0. +// +inline const Matrix4 inverse( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. The result is unpredictable when the determinant of mat is equal to or near 0. +// +inline const Matrix4 affineInverse( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. +// +inline const Matrix4 orthoInverse( const Matrix4 & mat ); + +// Determinant of a 4x4 matrix +// +inline float determinant( const Matrix4 & mat ); + +// Conditionally select between two 4x4 matrices +// +inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 4x4 matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix4 & mat ); + +// Print a 4x4 matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix4 & mat, const char * name ); + +#endif + +// A 3x4 transformation matrix in array-of-structures format +// +class Transform3 +{ + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + Vector3 mCol3; + +public: + // Default constructor; does no initialization + // + inline Transform3( ) { }; + + // Copy a 3x4 transformation matrix + // + inline Transform3( const Transform3 & tfrm ); + + // Construct a 3x4 transformation matrix containing the specified columns + // + inline Transform3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2, const Vector3 & col3 ); + + // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector + // + inline Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ); + + // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector + // + inline Transform3( const Quat & unitQuat, const Vector3 & translateVec ); + + // Set all elements of a 3x4 transformation matrix to the same scalar value + // + explicit inline Transform3( float scalar ); + + // Assign one 3x4 transformation matrix to another + // + inline Transform3 & operator =( const Transform3 & tfrm ); + + // Set the upper-left 3x3 submatrix + // + inline Transform3 & setUpper3x3( const Matrix3 & mat3 ); + + // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix + // + inline const Matrix3 getUpper3x3( ) const; + + // Set translation component + // + inline Transform3 & setTranslation( const Vector3 & translateVec ); + + // Get the translation component of a 3x4 transformation matrix + // + inline const Vector3 getTranslation( ) const; + + // Set column 0 of a 3x4 transformation matrix + // + inline Transform3 & setCol0( const Vector3 & col0 ); + + // Set column 1 of a 3x4 transformation matrix + // + inline Transform3 & setCol1( const Vector3 & col1 ); + + // Set column 2 of a 3x4 transformation matrix + // + inline Transform3 & setCol2( const Vector3 & col2 ); + + // Set column 3 of a 3x4 transformation matrix + // + inline Transform3 & setCol3( const Vector3 & col3 ); + + // Get column 0 of a 3x4 transformation matrix + // + inline const Vector3 getCol0( ) const; + + // Get column 1 of a 3x4 transformation matrix + // + inline const Vector3 getCol1( ) const; + + // Get column 2 of a 3x4 transformation matrix + // + inline const Vector3 getCol2( ) const; + + // Get column 3 of a 3x4 transformation matrix + // + inline const Vector3 getCol3( ) const; + + // Set the column of a 3x4 transformation matrix referred to by the specified index + // + inline Transform3 & setCol( int col, const Vector3 & vec ); + + // Set the row of a 3x4 transformation matrix referred to by the specified index + // + inline Transform3 & setRow( int row, const Vector4 & vec ); + + // Get the column of a 3x4 transformation matrix referred to by the specified index + // + inline const Vector3 getCol( int col ) const; + + // Get the row of a 3x4 transformation matrix referred to by the specified index + // + inline const Vector4 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + inline Vector3 & operator []( int col ); + + // Subscripting operator to get a column + // + inline const Vector3 operator []( int col ) const; + + // Set the element of a 3x4 transformation matrix referred to by column and row indices + // + inline Transform3 & setElem( int col, int row, float val ); + + // Get the element of a 3x4 transformation matrix referred to by column and row indices + // + inline float getElem( int col, int row ) const; + + // Multiply a 3x4 transformation matrix by a 3-D vector + // + inline const Vector3 operator *( const Vector3 & vec ) const; + + // Multiply a 3x4 transformation matrix by a 3-D point + // + inline const Point3 operator *( const Point3 & pnt ) const; + + // Multiply two 3x4 transformation matrices + // + inline const Transform3 operator *( const Transform3 & tfrm ) const; + + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + inline Transform3 & operator *=( const Transform3 & tfrm ); + + // Construct an identity 3x4 transformation matrix + // + static inline const Transform3 identity( ); + + // Construct a 3x4 transformation matrix to rotate around the x axis + // + static inline const Transform3 rotationX( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the y axis + // + static inline const Transform3 rotationY( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the z axis + // + static inline const Transform3 rotationZ( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes + // + static inline const Transform3 rotationZYX( const Vector3 & radiansXYZ ); + + // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector + // + static inline const Transform3 rotation( float radians, const Vector3 & unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Transform3 rotation( const Quat & unitQuat ); + + // Construct a 3x4 transformation matrix to perform scaling + // + static inline const Transform3 scale( const Vector3 & scaleVec ); + + // Construct a 3x4 transformation matrix to perform translation + // + static inline const Transform3 translation( const Vector3 & translateVec ); + +}; +// Append (post-multiply) a scale transformation to a 3x4 transformation matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ); + +// Multiply two 3x4 transformation matrices per element +// +inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); + +// Compute the absolute value of a 3x4 transformation matrix per element +// +inline const Transform3 absPerElem( const Transform3 & tfrm ); + +// Inverse of a 3x4 transformation matrix +// NOTE: +// Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. +// +inline const Transform3 inverse( const Transform3 & tfrm ); + +// Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. +// +inline const Transform3 orthoInverse( const Transform3 & tfrm ); + +// Conditionally select between two 3x4 transformation matrices +// +inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3x4 transformation matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Transform3 & tfrm ); + +// Print a 3x4 transformation matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Transform3 & tfrm, const char * name ); + +#endif + +} // namespace Aos +} // namespace Vectormath + +#include "vec_aos.h" +#include "quat_aos.h" +#include "mat_aos.h" + +#endif diff --git a/Extras/PhysicsEffects/include/vecmath/neon/vectormath_neon_assembly_implementations.S b/Extras/PhysicsEffects/include/vecmath/neon/vectormath_neon_assembly_implementations.S new file mode 100644 index 000000000..c4c6d121c --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/neon/vectormath_neon_assembly_implementations.S @@ -0,0 +1,310 @@ +@ +@ Applied Research Associates Inc. (c)2011 +@ +@ Redistribution and use in source and binary forms, +@ with or without modification, are permitted provided that the +@ following conditions are met: +@ * Redistributions of source code must retain the above copyright +@ notice, this list of conditions and the following disclaimer. +@ * Redistributions in binary form must reproduce the above copyright +@ notice, this list of conditions and the following disclaimer in the +@ documentation and/or other materials provided with the distribution. +@ * Neither the name of the Applied Research Associates Inc nor the names +@ of its contributors may be used to endorse or promote products derived +@ from this software without specific prior written permission. +@ +@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +@ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +@ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +@ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +@ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +@ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +@ POSSIBILITY OF SUCH DAMAGE. +@ +@---------------------------------------------------------------- +@ +@ This file contains ARM/NEON assembly versions of some vectormath +@ atomic functions. We have implemented here instead of inline assembly +@ because we have found gcc 4.4.3 to be too inconsistent and inadequate +@ to properly support either NEON intrinsics or inline assembly. (See +@ the inline assembly version of the vector3 dot product, which is +@ contained in vec_aos.h but compiled out, for an example of a simple +@ inline assembly function that wreaks havok if used.) +@ +@ Note that the certain NEON registers must be preserved across +@ function calls according to the following document: +@ +@ "Procedure Call Standard for the ARM? Architecture," ARM document +@ number ARM IHI 0042D, current through ABI release 2.08, +@ 16th October, 2009, section 5.1.2.1 +@ +@ The registers are: q4-q7 (and their double-word and single word +@ counterparts) +@ +@ These functions preserve all non-scratch general purpose registers +@ as well as the ones listed, and so we do not need to have extra +@ code to do the register preservation +@ + .syntax unified + .arch armv7-a + .fpu neon + .thumb + .text + .align 2 + +@---------------------------------------------------------------- +@ pfxVector3DotProductNEON +@ +@ Vector3 dot product, result stored directly to memory +@ +@ Result stored in memory pointed to by r2. r2 must point to +@ memory sufficient to store two 32 bit floats, though only the +@ first value is of interest +@---------------------------------------------------------------- + .global pfxVector3DotProductNEON + .thumb_func +pfxVector3DotProductNEON: + .fnstart + vld1.32 {d0,d1}, [r1] @ input = d0,d1\n\t" + vld1.32 {d2,d3}, [r0] @ input = d2,d3\n\t" + vmul.f32 d4, d0, d2 @ d4 = \n\t" + vpadd.f32 d4, d4, d4 @ d4 = \n\t" + vmla.f32 s8, s2, s6 @ s8 = + vld1.32 {d18,d19}, [r1] @ input + vmul.f32 d14, d16, d18 @ d14= + @ non-fused multiple accumulate + vmla.f32 d14, d17, d19 @ d14=d14+= + @ fused multiple accumulate - listed here for reference but we use vmla above + @ instead since the fused version is not recognized by GNU assembler (as part + @ of the gcc 4.4.3 Android distribution) + @ vfma.f32 {d14}, d17, d19 @ d14=d14+= + vpadd.f32 d14, d14, d14 @ add the two halves of d14 together, same result in each lane + vst1.32 {d14}, [r2] + bx lr + .fnend + +@---------------------------------------------------------------- +@ pfxVector3CrossProductNEON +@ +@ Vector3 cross product, result stored directly to memory +@ +@ Result stored in memory pointed to by r2. r2 must point to +@ memory sufficient to store four 32 bit floats, though only the +@ first 3 values are of interest +@---------------------------------------------------------------- + .global pfxVector3CrossProductNEON + .thumb_func +pfxVector3CrossProductNEON: + .fnstart + vld1.32 {d18,d19}, [r1] @ input = d18,d19 + vld1.32 {d16,d17}, [r0] @ input = d16,d17 + @ rearrange inputs into convenient order + vtrn.32 d18,d19 @ q9 = = d18,d19 + vrev64.32 d16,d16 @ q8 = = d16,d17 + vrev64.32 d18,d18 @ q9 = = d18,d19 + vtrn.32 d16,d17 @ q8 = = d16,d17 + @ perform first half of cross product using rearranged inputs + vmul.f32 q10, q8, q9 @ q10 = + @ rearrange inputs again + vtrn.32 d18,d19 @ q9 = = d18,d19 + vrev64.32 d16,d16 @ q8 = = d16,d17 + vrev64.32 d18,d18 @ q9 = = d18,d19 + vtrn.32 d16,d17 @ q8 = = d16,d17 + @ perform last half of cross product using rearranged inputs + vmls.f32 q10, q8, q9 @ q10 = + @ and store the result + vst1.32 {q10}, [r2] + bx lr + .fnend + +@---------------------------------------------------------------- +@ pfxMatrix3Matrix3ProductNEON +@ +@ Matrix3 * Matrix3 product, result stored directly to memory +@ +@ Result stored in memory pointed to by r2. r2 must point to +@ memory sufficient to store 12 32-bit floats. The reason for +@ 12 rather than 9 is that each column vector actually has +@ 4 32-bit floats rather than just 3....since NEON works with +@ double and quad vectors. +@ +@ Note that, since the inputs are loaded into registers then +@ never used again, r2 can point to one of the inputs, e.g., +@ result can be stored back out to one of the input memory +@ locations. +@---------------------------------------------------------------- + .global pfxMatrix3Matrix3ProductNEON + .thumb_func +pfxMatrix3Matrix3ProductNEON: + .fnstart + vld1.32 {d16-d19}, [r0]! @ load first eight elements of matrix 0 + vld1.32 {d20-d21}, [r0] @ load second eight elements of matrix 0 + vld1.32 {d0-d3}, [r1]! @ load first eight elements of matrix 1 + vld1.32 {d4-d5}, [r1] @ load second eight elements of matrix 1 + vmul.f32 q12, q8, d0[0] @ rslt col0 = (mat0 col0) * (mat1 col0 elt0) + vmul.f32 q13, q8, d2[0] @ rslt col1 = (mat0 col0) * (mat1 col1 elt0) + vmul.f32 q14, q8, d4[0] @ rslt col2 = (mat0 col0) * (mat1 col2 elt0) + vmla.f32 q12, q9, d0[1] @ rslt col0 += (mat0 col1) * (mat1 col0 elt1) + vmla.f32 q13, q9, d2[1] @ rslt col1 += (mat0 col1) * (mat1 col1 elt1) + vmla.f32 q14, q9, d4[1] @ rslt col2 += (mat0 col1) * (mat1 col2 elt1) + vmla.f32 q12, q10, d1[0] @ rslt col0 += (mat0 col2) * (mat1 col0 elt2) + vmla.f32 q13, q10, d3[0] @ rslt col1 += (mat0 col2) * (mat1 col1 elt2) + vmla.f32 q14, q10, d5[0] @ rslt col2 += (mat0 col2) * (mat1 col2 elt2) + vst1.32 {d24-d27}, [r2]! @ store first eight elements of result (each column has an extra float as stored) + vst1.32 {d28-d29}, [r2] @ store last four elements of result (each column has an extra float as stored) + bx lr + .fnend + +@---------------------------------------------------------------- +@ pfxMatrix4Matrix4ProductNEON +@ +@ Matrix4 * Matrix4 product, result stored directly to memory +@ +@ Result stored in memory pointed to by r2. r2 must point to +@ memory sufficient to store 16 32 bit floats. +@ +@ Note that, since the inputs are loaded into registers then +@ never used again, r2 can point to one of the inputs, e.g., +@ result can be stored back out to one of the input memory +@ locations. +@---------------------------------------------------------------- + .global pfxMatrix4Matrix4ProductNEON + .thumb_func +pfxMatrix4Matrix4ProductNEON: + .fnstart + vld1.32 {d16-d19}, [r0]! @ load first eight elements of matrix 0 + vld1.32 {d20-d23}, [r0] @ load second eight elements of matrix 0 + vld1.32 {d0-d3}, [r1]! @ load first eight elements of matrix 1 + vld1.32 {d4-d7}, [r1] @ load second eight elements of matrix 1 + vmul.f32 q12, q8, d0[0] @ rslt col0 = (mat0 col0) * (mat1 col0 elt0) + vmul.f32 q13, q8, d2[0] @ rslt col1 = (mat0 col0) * (mat1 col1 elt0) + vmul.f32 q14, q8, d4[0] @ rslt col2 = (mat0 col0) * (mat1 col2 elt0) + vmul.f32 q15, q8, d6[0] @ rslt col3 = (mat0 col0) * (mat1 col3 elt0) + vmla.f32 q12, q9, d0[1] @ rslt col0 += (mat0 col1) * (mat1 col0 elt1) + vmla.f32 q13, q9, d2[1] @ rslt col1 += (mat0 col1) * (mat1 col1 elt1) + vmla.f32 q14, q9, d4[1] @ rslt col2 += (mat0 col1) * (mat1 col2 elt1) + vmla.f32 q15, q9, d6[1] @ rslt col3 += (mat0 col1) * (mat1 col3 elt1) + vmla.f32 q12, q10, d1[0] @ rslt col0 += (mat0 col2) * (mat1 col0 elt2) + vmla.f32 q13, q10, d3[0] @ rslt col1 += (mat0 col2) * (mat1 col1 elt2) + vmla.f32 q14, q10, d5[0] @ rslt col2 += (mat0 col2) * (mat1 col2 elt2) + vmla.f32 q15, q10, d7[0] @ rslt col3 += (mat0 col2) * (mat1 col2 elt2) + vmla.f32 q12, q11, d1[1] @ rslt col0 += (mat0 col3) * (mat1 col0 elt3) + vmla.f32 q13, q11, d3[1] @ rslt col1 += (mat0 col3) * (mat1 col1 elt3) + vmla.f32 q14, q11, d5[1] @ rslt col2 += (mat0 col3) * (mat1 col2 elt3) + vmla.f32 q15, q11, d7[1] @ rslt col3 += (mat0 col3) * (mat1 col3 elt3) + vst1.32 {d24-d27}, [r2]! @ store first eight elements of result + vst1.32 {d28-d31}, [r2] @ store second eight elements of result + bx lr + .fnend + +@---------------------------------------------------------------- +@ pfxTransform3OrthoInverseNEON +@ +@ Computes the ortho inverse of a Transform 3. +@ +@ Result stored in memory pointed to by r1. r1 must point to +@ memory sufficient to store 16 32 bit floats. +@ +@ Note that, since the inputs are loaded into registers then +@ never used again, r1 can point to one of the inputs, e.g., +@ result can be stored back out to one of the input memory +@ locations. +@ +@ Note that this expects the inputs to have 4 floats per row, +@ (to be consistent with NEON quad vector), and the last float +@ in each row should be 0.0 for the math to work out. +@---------------------------------------------------------------- + .global pfxTransform3OrthoInverseNEON + .thumb_func +pfxTransform3OrthoInverseNEON: + .fnstart + @ direct load the first column of the ortho inverse result + vld1.f32 d0[0], [r0]! + vld1.f32 d2[0], [r0]! + vld1.f32 d4[0], [r0]! + vld1.f32 d1[1], [r0]! + + @ direct load the second column of the ortho inverse result + vld1.f32 d0[1], [r0]! + vld1.f32 d2[1], [r0]! + vld1.f32 d4[1], [r0]! + vld1.f32 d3[1], [r0]! + + @ direct load the third column of the ortho inverse result + vld1.f32 d1[0], [r0]! + vld1.f32 d3[0], [r0]! + + vst1.f32 {d0-d3}, [r1]! @ store first eight elements of result (1st two columns) + + vld1.f32 d5[0], [r0]! + vld1.f32 d5[1], [r0]! + + vst1.f32 {d4-d5}, [r1]! @ store next four elements of result (3rd column) + + @ move q0 into q8 so we can reuse q0 to load fourth column + @ of input. We do this to avoid using q4-q7 (which have to + @ be preserved during the function call)....needed to work + @ around some limitation rules that prevent us from accessing + @ single s registers associated with q8 and above. + vmov.f32 q8, q0 + + @ direct load the last column of the input + vld1.f32 {q0}, [r0] + + @ prepare the last column of the output + vmul.f32 q3, q8, d0[0] @ multiply result column 1 by x coord of input column 3 + vmla.f32 q3, q1, d0[1] @ multiply result column 2 by y coord of input column 3 and add + vmla.f32 q3, q2, d1[0] @ multiply result column 3 by z coord of input column 3 and add + vneg.f32 q3, q3 @ negate final column + + vst1.f32 {q3}, [r1] @ store last four elements of result (4th column) + + bx lr + .fnend + +@---------------------------------------------------------------- +@ pfxTransform3Vector3MultiplyNEON +@ +@ Computes the product of a Transform3 and a Vector3, e.g., it +@ applies the transform to the vector. +@ +@ Result stored in memory pointed to by r2. r2 must point to +@ memory sufficient to store 4 32-bit floats. +@---------------------------------------------------------------- + .global pfxTransform3Vector3MultiplyNEON + .thumb_func +pfxTransform3Vector3MultiplyNEON: + .fnstart + + vld1.32 {d16-d19}, [r0]! @ load first eight elements of transform matrix + vld1.32 {d20-d21}, [r0] @ load second eight elements of transform matrix + vld1.32 {d0-d1}, [r1] @ load the four elements of vector3 (last one is just padding) + vmul.f32 q12, q8, d0[0] @ rslt col0 = (mat0 col0) * (mat1 col0 elt0) + vmla.f32 q12, q9, d0[1] @ rslt col0 += (mat0 col1) * (mat1 col0 elt1) + vmla.f32 q12, q10, d1[0] @ rslt col0 += (mat0 col2) * (mat1 col0 elt2) + vst1.32 {d24-d25}, [r2] @ store four elements of result (last one is padding) + + bx lr + .fnend diff --git a/Extras/PhysicsEffects/include/vecmath/neon/vectormath_neon_assembly_prototypes.h b/Extras/PhysicsEffects/include/vecmath/neon/vectormath_neon_assembly_prototypes.h new file mode 100644 index 000000000..e3a9286d2 --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/neon/vectormath_neon_assembly_prototypes.h @@ -0,0 +1,57 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _VECTORMATH_NEON_ASSEMBLY_PROTOTYPES_H +#define _VECTORMATH_NEON_ASSEMBLY_PROTOTYPES_H + +// Prototypes for NEON assembly implementations +extern "C" +{ + // NEON assembly implementations of Vector3 functions + void pfxVector3DotProductNEON(const Vectormath::Aos::Vector3 &vec0, const Vectormath::Aos::Vector3 &vec1, float *result); + void pfxVector3CrossProductNEON(const Vectormath::Aos::Vector3 &vec0, const Vectormath::Aos::Vector3 &vec1, + Vectormath::Aos::Vector3 &result); + + // NEON assembly implementations of Matrix3 functions + void pfxMatrix3Matrix3ProductNEON(const Vectormath::Aos::Matrix3 &mat0, const Vectormath::Aos::Matrix3 &mat1, + Vectormath::Aos::Matrix3 &result); + + // NEON assembly implementations of Transform3 functions + void pfxTransform3OrthoInverseNEON(const Vectormath::Aos::Transform3 &trn, Vectormath::Aos::Transform3 &result); + void pfxTransform3Vector3MultiplyNEON(const Vectormath::Aos::Transform3 &trn, const Vectormath::Aos::Vector3 &vec, + Vectormath::Aos::Vector3 &result); + + // NEON assembly implementations of Vector4 functions + void pfxVector4DotProductNEON(const Vectormath::Aos::Vector4 &vec0, const Vectormath::Aos::Vector4 &vec1, float *result); + + // NEON assembly implementations of Matrix4 functions + void pfxMatrix4Matrix4ProductNEON(const Vectormath::Aos::Matrix4 &mat0, const Vectormath::Aos::Matrix4 &mat1, + Vectormath::Aos::Matrix4 &result); +} + +#endif // _VECTORMATH_NEON_ASSEMBLY_PROTOTYPES_H diff --git a/Extras/PhysicsEffects/include/vecmath/sse/boolInVec.h b/Extras/PhysicsEffects/include/vecmath/sse/boolInVec.h new file mode 100644 index 000000000..d18cb15ce --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/sse/boolInVec.h @@ -0,0 +1,247 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _BOOLINVEC_H +#define _BOOLINVEC_H + +#include + +namespace Vectormath { + +class floatInVec; + +//-------------------------------------------------------------------------------------------------- +// boolInVec class +// + +class boolInVec +{ + private: + __m128 mData; + + inline boolInVec(__m128 vec); + public: + inline boolInVec() {} + + // matches standard type conversions + // + inline boolInVec(const floatInVec &vec); + + // explicit cast from bool + // + explicit inline boolInVec(bool scalar); + +#ifdef _VECTORMATH_NO_SCALAR_CAST + // explicit cast to bool + // + inline bool getAsBool() const; +#else + // implicit cast to bool + // + inline operator bool() const; +#endif + + // get vector data + // bool value is splatted across all word slots of vector as 0 (false) or -1 (true) + // + inline __m128 get128() const; + + // operators + // + inline const boolInVec operator ! () const; + inline boolInVec& operator = (const boolInVec &vec); + inline boolInVec& operator &= (const boolInVec &vec); + inline boolInVec& operator ^= (const boolInVec &vec); + inline boolInVec& operator |= (const boolInVec &vec); + + // friend functions + // + friend inline const boolInVec operator == (const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec operator != (const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec operator < (const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator <= (const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator > (const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator >= (const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator == (const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator != (const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator & (const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec operator ^ (const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec operator | (const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1); +}; + +//-------------------------------------------------------------------------------------------------- +// boolInVec functions +// + +// operators +// +inline const boolInVec operator == (const boolInVec &vec0, const boolInVec &vec1); +inline const boolInVec operator != (const boolInVec &vec0, const boolInVec &vec1); +inline const boolInVec operator & (const boolInVec &vec0, const boolInVec &vec1); +inline const boolInVec operator ^ (const boolInVec &vec0, const boolInVec &vec1); +inline const boolInVec operator | (const boolInVec &vec0, const boolInVec &vec1); + +// select between vec0 and vec1 using boolInVec. +// false selects vec0, true selects vec1 +// +inline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1); + +} // namespace Vectormath + +//-------------------------------------------------------------------------------------------------- +// boolInVec implementation +// + +#include "floatInVec.h" + +namespace Vectormath { + +inline +boolInVec::boolInVec(__m128 vec) +{ + mData = vec; +} + +inline +boolInVec::boolInVec(const floatInVec &vec) +{ + *this = (vec != floatInVec(0.0f)); +} + +inline +boolInVec::boolInVec(bool scalar) +{ + unsigned int mask = -(int)scalar; + mData = _mm_set1_ps(*(float *)&mask); // TODO: Union +} + +#ifdef _VECTORMATH_NO_SCALAR_CAST +inline +bool +boolInVec::getAsBool() const +#else +inline +boolInVec::operator bool() const +#endif +{ + return *(bool *)&mData; +} + +inline +__m128 +boolInVec::get128() const +{ + return mData; +} + +inline +const boolInVec +boolInVec::operator ! () const +{ + return boolInVec(_mm_andnot_ps(mData, _mm_cmpneq_ps(_mm_setzero_ps(),_mm_setzero_ps()))); +} + +inline +boolInVec& +boolInVec::operator = (const boolInVec &vec) +{ + mData = vec.mData; + return *this; +} + +inline +boolInVec& +boolInVec::operator &= (const boolInVec &vec) +{ + *this = *this & vec; + return *this; +} + +inline +boolInVec& +boolInVec::operator ^= (const boolInVec &vec) +{ + *this = *this ^ vec; + return *this; +} + +inline +boolInVec& +boolInVec::operator |= (const boolInVec &vec) +{ + *this = *this | vec; + return *this; +} + +inline +const boolInVec +operator == (const boolInVec &vec0, const boolInVec &vec1) +{ + return boolInVec(_mm_cmpeq_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator != (const boolInVec &vec0, const boolInVec &vec1) +{ + return boolInVec(_mm_cmpneq_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator & (const boolInVec &vec0, const boolInVec &vec1) +{ + return boolInVec(_mm_and_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator | (const boolInVec &vec0, const boolInVec &vec1) +{ + return boolInVec(_mm_or_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator ^ (const boolInVec &vec0, const boolInVec &vec1) +{ + return boolInVec(_mm_xor_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1) +{ + return boolInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128())); +} + +} // namespace Vectormath + +#endif // boolInVec_h diff --git a/Extras/PhysicsEffects/include/vecmath/sse/floatInVec.h b/Extras/PhysicsEffects/include/vecmath/sse/floatInVec.h new file mode 100644 index 000000000..6443865b1 --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/sse/floatInVec.h @@ -0,0 +1,340 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _FLOATINVEC_H +#define _FLOATINVEC_H + +#include +#include + +namespace Vectormath { + +class boolInVec; + +//-------------------------------------------------------------------------------------------------- +// floatInVec class +// + +class floatInVec +{ + private: + __m128 mData; + + public: + inline floatInVec(__m128 vec); + + inline floatInVec() {} + + // matches standard type conversions + // + inline floatInVec(const boolInVec &vec); + + // construct from a slot of __m128 + // + inline floatInVec(__m128 vec, int slot); + + // explicit cast from float + // + explicit inline floatInVec(float scalar); + +#ifdef _VECTORMATH_NO_SCALAR_CAST + // explicit cast to float + // + inline float getAsFloat() const; +#else + // implicit cast to float + // + inline operator float() const; +#endif + + // get vector data + // float value is splatted across all word slots of vector + // + inline __m128 get128() const; + + // operators + // + inline const floatInVec operator ++ (int); + inline const floatInVec operator -- (int); + inline floatInVec& operator ++ (); + inline floatInVec& operator -- (); + inline const floatInVec operator - () const; + inline floatInVec& operator = (const floatInVec &vec); + inline floatInVec& operator *= (const floatInVec &vec); + inline floatInVec& operator /= (const floatInVec &vec); + inline floatInVec& operator += (const floatInVec &vec); + inline floatInVec& operator -= (const floatInVec &vec); + + // friend functions + // + friend inline const floatInVec operator * (const floatInVec &vec0, const floatInVec &vec1); + friend inline const floatInVec operator / (const floatInVec &vec0, const floatInVec &vec1); + friend inline const floatInVec operator + (const floatInVec &vec0, const floatInVec &vec1); + friend inline const floatInVec operator - (const floatInVec &vec0, const floatInVec &vec1); + friend inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, boolInVec select_vec1); +}; + +//-------------------------------------------------------------------------------------------------- +// floatInVec functions +// + +// operators +// +inline const floatInVec operator * (const floatInVec &vec0, const floatInVec &vec1); +inline const floatInVec operator / (const floatInVec &vec0, const floatInVec &vec1); +inline const floatInVec operator + (const floatInVec &vec0, const floatInVec &vec1); +inline const floatInVec operator - (const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator < (const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator <= (const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator > (const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator >= (const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator == (const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator != (const floatInVec &vec0, const floatInVec &vec1); + +// select between vec0 and vec1 using boolInVec. +// false selects vec0, true selects vec1 +// +inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, const boolInVec &select_vec1); + +} // namespace Vectormath + +//-------------------------------------------------------------------------------------------------- +// floatInVec implementation +// + +#include "boolInVec.h" + +namespace Vectormath { + +inline +floatInVec::floatInVec(__m128 vec) +{ + mData = vec; +} + +inline +floatInVec::floatInVec(const boolInVec &vec) +{ + mData = vec_sel(_mm_setzero_ps(), _mm_set1_ps(1.0f), vec.get128()); +} + +inline +floatInVec::floatInVec(__m128 vec, int slot) +{ + SSEFloat v; + v.m128 = vec; + mData = _mm_set1_ps(v.f[slot]); +} + +inline +floatInVec::floatInVec(float scalar) +{ + mData = _mm_set1_ps(scalar); +} + +#ifdef _VECTORMATH_NO_SCALAR_CAST +inline +float +floatInVec::getAsFloat() const +#else +inline +floatInVec::operator float() const +#endif +{ + return *((float *)&mData); +} + +inline +__m128 +floatInVec::get128() const +{ + return mData; +} + +inline +const floatInVec +floatInVec::operator ++ (int) +{ + __m128 olddata = mData; + operator ++(); + return floatInVec(olddata); +} + +inline +const floatInVec +floatInVec::operator -- (int) +{ + __m128 olddata = mData; + operator --(); + return floatInVec(olddata); +} + +inline +floatInVec& +floatInVec::operator ++ () +{ + *this += floatInVec(_mm_set1_ps(1.0f)); + return *this; +} + +inline +floatInVec& +floatInVec::operator -- () +{ + *this -= floatInVec(_mm_set1_ps(1.0f)); + return *this; +} + +inline +const floatInVec +floatInVec::operator - () const +{ + return floatInVec(_mm_sub_ps(_mm_setzero_ps(), mData)); +} + +inline +floatInVec& +floatInVec::operator = (const floatInVec &vec) +{ + mData = vec.mData; + return *this; +} + +inline +floatInVec& +floatInVec::operator *= (const floatInVec &vec) +{ + *this = *this * vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator /= (const floatInVec &vec) +{ + *this = *this / vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator += (const floatInVec &vec) +{ + *this = *this + vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator -= (const floatInVec &vec) +{ + *this = *this - vec; + return *this; +} + +inline +const floatInVec +operator * (const floatInVec &vec0, const floatInVec &vec1) +{ + return floatInVec(_mm_mul_ps(vec0.get128(), vec1.get128())); +} + +inline +const floatInVec +operator / (const floatInVec &num, const floatInVec &den) +{ + return floatInVec(_mm_div_ps(num.get128(), den.get128())); +} + +inline +const floatInVec +operator + (const floatInVec &vec0, const floatInVec &vec1) +{ + return floatInVec(_mm_add_ps(vec0.get128(), vec1.get128())); +} + +inline +const floatInVec +operator - (const floatInVec &vec0, const floatInVec &vec1) +{ + return floatInVec(_mm_sub_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator < (const floatInVec &vec0, const floatInVec &vec1) +{ + return boolInVec(_mm_cmpgt_ps(vec1.get128(), vec0.get128())); +} + +inline +const boolInVec +operator <= (const floatInVec &vec0, const floatInVec &vec1) +{ + return boolInVec(_mm_cmpge_ps(vec1.get128(), vec0.get128())); +} + +inline +const boolInVec +operator > (const floatInVec &vec0, const floatInVec &vec1) +{ + return boolInVec(_mm_cmpgt_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator >= (const floatInVec &vec0, const floatInVec &vec1) +{ + return boolInVec(_mm_cmpge_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator == (const floatInVec &vec0, const floatInVec &vec1) +{ + return boolInVec(_mm_cmpeq_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator != (const floatInVec &vec0, const floatInVec &vec1) +{ + return boolInVec(_mm_cmpneq_ps(vec0.get128(), vec1.get128())); +} + +inline +const floatInVec +select(const floatInVec &vec0, const floatInVec &vec1, const boolInVec &select_vec1) +{ + return floatInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128())); +} + +} // namespace Vectormath + +#endif // floatInVec_h diff --git a/Extras/PhysicsEffects/include/vecmath/sse/mat_aos.h b/Extras/PhysicsEffects/include/vecmath/sse/mat_aos.h new file mode 100644 index 000000000..fe6aa62b9 --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/sse/mat_aos.h @@ -0,0 +1,2190 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef _VECTORMATH_MAT_AOS_CPP_H +#define _VECTORMATH_MAT_AOS_CPP_H + +namespace Vectormath { +namespace Aos { + +//----------------------------------------------------------------------------- +// Constants +// for shuffles, words are labeled [x,y,z,w] [a,b,c,d] + +#define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B }) +#define _VECTORMATH_PERM_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_D }) +#define _VECTORMATH_PERM_XZBX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_CXXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_YAXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C }) +#define _VECTORMATH_PERM_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W, _VECTORMATH_PERM_Z }) +#define _VECTORMATH_PERM_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_D }) +#define _VECTORMATH_PERM_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y }) +#define _VECTORMATH_PERM_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C }) +#define _VECTORMATH_PERM_ZAYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_BZXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_XZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A }) +#define _VECTORMATH_PERM_ZXXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_B }) +#define _VECTORMATH_PERM_YXXC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_C }) +#define _VECTORMATH_PERM_BBYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PI_OVER_2 1.570796327f + +//----------------------------------------------------------------------------- +// Definitions + +VECTORMATH_FORCE_INLINE Matrix3::Matrix3( const Matrix3 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; +} + +VECTORMATH_FORCE_INLINE Matrix3::Matrix3( float scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); +} + +VECTORMATH_FORCE_INLINE Matrix3::Matrix3( const floatInVec &scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); +} + +VECTORMATH_FORCE_INLINE Matrix3::Matrix3( const Quat &unitQuat ) +{ + __m128 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2; + __m128 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; + VM_ATTRIBUTE_ALIGN16 unsigned int sx[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int sz[4] = {0, 0, 0xffffffff, 0}; + __m128 select_x = _mm_load_ps((float *)sx); + __m128 select_z = _mm_load_ps((float *)sz); + + xyzw_2 = _mm_add_ps( unitQuat.get128(), unitQuat.get128() ); + wwww = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,3,3,3) ); + yzxw = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,0,2,1) ); + zxyw = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,1,0,2) ); + yzxw_2 = _mm_shuffle_ps( xyzw_2, xyzw_2, _MM_SHUFFLE(3,0,2,1) ); + zxyw_2 = _mm_shuffle_ps( xyzw_2, xyzw_2, _MM_SHUFFLE(3,1,0,2) ); + + tmp0 = _mm_mul_ps( yzxw_2, wwww ); // tmp0 = 2yw, 2zw, 2xw, 2w2 + tmp1 = _mm_sub_ps( _mm_set1_ps(1.0f), _mm_mul_ps(yzxw, yzxw_2) ); // tmp1 = 1 - 2y2, 1 - 2z2, 1 - 2x2, 1 - 2w2 + tmp2 = _mm_mul_ps( yzxw, xyzw_2 ); // tmp2 = 2xy, 2yz, 2xz, 2w2 + tmp0 = _mm_add_ps( _mm_mul_ps(zxyw, xyzw_2), tmp0 ); // tmp0 = 2yw + 2zx, 2zw + 2xy, 2xw + 2yz, 2w2 + 2w2 + tmp1 = _mm_sub_ps( tmp1, _mm_mul_ps(zxyw, zxyw_2) ); // tmp1 = 1 - 2y2 - 2z2, 1 - 2z2 - 2x2, 1 - 2x2 - 2y2, 1 - 2w2 - 2w2 + tmp2 = _mm_sub_ps( tmp2, _mm_mul_ps(zxyw_2, wwww) ); // tmp2 = 2xy - 2zw, 2yz - 2xw, 2xz - 2yw, 2w2 -2w2 + + tmp3 = vec_sel( tmp0, tmp1, select_x ); + tmp4 = vec_sel( tmp1, tmp2, select_x ); + tmp5 = vec_sel( tmp2, tmp0, select_x ); + mCol0 = Vector3( vec_sel( tmp3, tmp2, select_z ) ); + mCol1 = Vector3( vec_sel( tmp4, tmp0, select_z ) ); + mCol2 = Vector3( vec_sel( tmp5, tmp1, select_z ) ); +} + +VECTORMATH_FORCE_INLINE Matrix3::Matrix3( const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setCol0( const Vector3 &_col0 ) +{ + mCol0 = _col0; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setCol1( const Vector3 &_col1 ) +{ + mCol1 = _col1; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setCol2( const Vector3 &_col2 ) +{ + mCol2 = _col2; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setCol( int col, const Vector3 &vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setRow( int row, const Vector3 &vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setElem( int col, int row, float val ) +{ + (*this)[col].setElem(row, val); + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setElem( int col, int row, const floatInVec &val ) +{ + Vector3 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Matrix3::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol0( ) const +{ + return mCol0; +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol1( ) const +{ + return mCol1; +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol2( ) const +{ + return mCol2; +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getRow( int row ) const +{ + return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Matrix3::operator []( int col ) +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator =( const Matrix3 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix3 transpose( const Matrix3 & mat ) +{ + __m128 tmp0, tmp1, res0, res1, res2; + tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); + tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); + res0 = vec_mergeh( tmp0, mat.getCol1().get128() ); + //res1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + res1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2)); + res1 = vec_sel(res1, mat.getCol1().get128(), select_y); + //res2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX ); + res2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0)); + res2 = vec_sel(res2, vec_splat(mat.getCol1().get128(), 2), select_y); + return Matrix3( + Vector3( res0 ), + Vector3( res1 ), + Vector3( res2 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 inverse( const Matrix3 & mat ) +{ + __m128 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2; + tmp2 = _vmathVfCross( mat.getCol0().get128(), mat.getCol1().get128() ); + tmp0 = _vmathVfCross( mat.getCol1().get128(), mat.getCol2().get128() ); + tmp1 = _vmathVfCross( mat.getCol2().get128(), mat.getCol0().get128() ); + dot = _vmathVfDot3( tmp2, mat.getCol2().get128() ); + dot = vec_splat( dot, 0 ); + invdet = recipf4( dot ); + tmp3 = vec_mergeh( tmp0, tmp2 ); + tmp4 = vec_mergel( tmp0, tmp2 ); + inv0 = vec_mergeh( tmp3, tmp1 ); + //inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + inv1 = _mm_shuffle_ps( tmp3, tmp3, _MM_SHUFFLE(0,3,2,2)); + inv1 = vec_sel(inv1, tmp1, select_y); + //inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); + inv2 = _mm_shuffle_ps( tmp4, tmp4, _MM_SHUFFLE(0,1,1,0)); + inv2 = vec_sel(inv2, vec_splat(tmp1, 2), select_y); + inv0 = vec_mul( inv0, invdet ); + inv1 = vec_mul( inv1, invdet ); + inv2 = vec_mul( inv2, invdet ); + return Matrix3( + Vector3( inv0 ), + Vector3( inv1 ), + Vector3( inv2 ) + ); +} + +VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix3 & mat ) +{ + return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const +{ + return Matrix3( + ( mCol0 + mat.mCol0 ), + ( mCol1 + mat.mCol1 ), + ( mCol2 + mat.mCol2 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const +{ + return Matrix3( + ( mCol0 - mat.mCol0 ), + ( mCol1 - mat.mCol1 ), + ( mCol2 - mat.mCol2 ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) +{ + *this = *this + mat; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) +{ + *this = *this - mat; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator -( ) const +{ + return Matrix3( + ( -mCol0 ), + ( -mCol1 ), + ( -mCol2 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 absPerElem( const Matrix3 & mat ) +{ + return Matrix3( + absPerElem( mat.getCol0() ), + absPerElem( mat.getCol1() ), + absPerElem( mat.getCol2() ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator *( float scalar ) const +{ + return *this * floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator *( const floatInVec &scalar ) const +{ + return Matrix3( + ( mCol0 * scalar ), + ( mCol1 * scalar ), + ( mCol2 * scalar ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator *=( float scalar ) +{ + return *this *= floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator *=( const floatInVec &scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix3 operator *( float scalar, const Matrix3 & mat ) +{ + return floatInVec(scalar) * mat; +} + +VECTORMATH_FORCE_INLINE const Matrix3 operator *( const floatInVec &scalar, const Matrix3 & mat ) +{ + return mat * scalar; +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::operator *( const Vector3 &vec ) const +{ + __m128 res; + __m128 xxxx, yyyy, zzzz; + xxxx = vec_splat( vec.get128(), 0 ); + yyyy = vec_splat( vec.get128(), 1 ); + zzzz = vec_splat( vec.get128(), 2 ); + res = vec_mul( mCol0.get128(), xxxx ); + res = vec_madd( mCol1.get128(), yyyy, res ); + res = vec_madd( mCol2.get128(), zzzz, res ); + return Vector3( res ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const +{ + return Matrix3( + ( *this * mat.mCol0 ), + ( *this * mat.mCol1 ), + ( *this * mat.mCol2 ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) +{ + *this = *this * mat; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) +{ + return Matrix3( + mulPerElem( mat0.getCol0(), mat1.getCol0() ), + mulPerElem( mat0.getCol1(), mat1.getCol1() ), + mulPerElem( mat0.getCol2(), mat1.getCol2() ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::identity( ) +{ + return Matrix3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationX( float radians ) +{ + return rotationX( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationX( const floatInVec &radians ) +{ + __m128 s, c, res1, res2; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res1 = vec_sel( zero, c, select_y ); + res1 = vec_sel( res1, s, select_z ); + res2 = vec_sel( zero, negatef4(s), select_y ); + res2 = vec_sel( res2, c, select_z ); + return Matrix3( + Vector3::xAxis( ), + Vector3( res1 ), + Vector3( res2 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationY( float radians ) +{ + return rotationY( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationY( const floatInVec &radians ) +{ + __m128 s, c, res0, res2; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res0 = vec_sel( zero, c, select_x ); + res0 = vec_sel( res0, negatef4(s), select_z ); + res2 = vec_sel( zero, s, select_x ); + res2 = vec_sel( res2, c, select_z ); + return Matrix3( + Vector3( res0 ), + Vector3::yAxis( ), + Vector3( res2 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationZ( float radians ) +{ + return rotationZ( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationZ( const floatInVec &radians ) +{ + __m128 s, c, res0, res1; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res0 = vec_sel( zero, c, select_x ); + res0 = vec_sel( res0, s, select_y ); + res1 = vec_sel( zero, negatef4(s), select_x ); + res1 = vec_sel( res1, c, select_y ); + return Matrix3( + Vector3( res0 ), + Vector3( res1 ), + Vector3::zAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationZYX( const Vector3 &radiansXYZ ) +{ + __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; + angles = Vector4( radiansXYZ, 0.0f ).get128(); + sincosf4( angles, &s, &c ); + negS = negatef4( s ); + Z0 = vec_mergel( c, s ); + Z1 = vec_mergel( negS, c ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_xyz[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0}; + Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) ); + Y0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) ); + Y1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) ); + X0 = vec_splat( s, 0 ); + X1 = vec_splat( c, 0 ); + tmp = vec_mul( Z0, Y1 ); + return Matrix3( + Vector3( vec_mul( Z0, Y0 ) ), + Vector3( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ), + Vector3( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotation( float radians, const Vector3 &unitVec ) +{ + return rotation( floatInVec(radians), unitVec ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotation( const floatInVec &radians, const Vector3 &unitVec ) +{ + __m128 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; + axis = unitVec.get128(); + sincosf4( radians.get128(), &s, &c ); + xxxx = vec_splat( axis, 0 ); + yyyy = vec_splat( axis, 1 ); + zzzz = vec_splat( axis, 2 ); + oneMinusC = vec_sub( _mm_set1_ps(1.0f), c ); + axisS = vec_mul( axis, s ); + negAxisS = negatef4( axisS ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + //tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); + tmp0 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,2,0) ); + tmp0 = vec_sel(tmp0, vec_splat(negAxisS, 1), select_z); + //tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); + tmp1 = vec_sel( vec_splat(axisS, 0), vec_splat(negAxisS, 2), select_x ); + //tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); + tmp2 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,0,1) ); + tmp2 = vec_sel(tmp2, vec_splat(negAxisS, 0), select_y); + tmp0 = vec_sel( tmp0, c, select_x ); + tmp1 = vec_sel( tmp1, c, select_y ); + tmp2 = vec_sel( tmp2, c, select_z ); + return Matrix3( + Vector3( vec_madd( vec_mul( axis, xxxx ), oneMinusC, tmp0 ) ), + Vector3( vec_madd( vec_mul( axis, yyyy ), oneMinusC, tmp1 ) ), + Vector3( vec_madd( vec_mul( axis, zzzz ), oneMinusC, tmp2 ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotation( const Quat &unitQuat ) +{ + return Matrix3( unitQuat ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::scale( const Vector3 &scaleVec ) +{ + __m128 zero = _mm_setzero_ps(); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + return Matrix3( + Vector3( vec_sel( zero, scaleVec.get128(), select_x ) ), + Vector3( vec_sel( zero, scaleVec.get128(), select_y ) ), + Vector3( vec_sel( zero, scaleVec.get128(), select_z ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 appendScale( const Matrix3 & mat, const Vector3 &scaleVec ) +{ + return Matrix3( + ( mat.getCol0() * scaleVec.getX( ) ), + ( mat.getCol1() * scaleVec.getY( ) ), + ( mat.getCol2() * scaleVec.getZ( ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 prependScale( const Vector3 &scaleVec, const Matrix3 & mat ) +{ + return Matrix3( + mulPerElem( mat.getCol0(), scaleVec ), + mulPerElem( mat.getCol1(), scaleVec ), + mulPerElem( mat.getCol2(), scaleVec ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ) +{ + return Matrix3( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, const boolInVec &select1 ) +{ + return Matrix3( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat ) +{ + print( mat.getRow( 0 ) ); + print( mat.getRow( 1 ) ); + print( mat.getRow( 2 ) ); +} + +VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat, const char * name ) +{ + printf("%s:\n", name); + print( mat ); +} + +#endif + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Matrix4 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; +} + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( float scalar ) +{ + mCol0 = Vector4( scalar ); + mCol1 = Vector4( scalar ); + mCol2 = Vector4( scalar ); + mCol3 = Vector4( scalar ); +} + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const floatInVec &scalar ) +{ + mCol0 = Vector4( scalar ); + mCol1 = Vector4( scalar ); + mCol2 = Vector4( scalar ); + mCol3 = Vector4( scalar ); +} + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Transform3 & mat ) +{ + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( mat.getCol3(), 1.0f ); +} + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Vector4 &_col0, const Vector4 &_col1, const Vector4 &_col2, const Vector4 &_col3 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; +} + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Matrix3 & mat, const Vector3 &translateVec ) +{ + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( translateVec, 1.0f ); +} + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Quat &unitQuat, const Vector3 &translateVec ) +{ + Matrix3 mat; + mat = Matrix3( unitQuat ); + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( translateVec, 1.0f ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol0( const Vector4 &_col0 ) +{ + mCol0 = _col0; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol1( const Vector4 &_col1 ) +{ + mCol1 = _col1; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol2( const Vector4 &_col2 ) +{ + mCol2 = _col2; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol3( const Vector4 &_col3 ) +{ + mCol3 = _col3; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol( int col, const Vector4 &vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setRow( int row, const Vector4 &vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + mCol3.setElem( row, vec.getElem( 3 ) ); + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setElem( int col, int row, float val ) +{ + (*this)[col].setElem(row, val); + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setElem( int col, int row, const floatInVec &val ) +{ + Vector4 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Matrix4::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol0( ) const +{ + return mCol0; +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol1( ) const +{ + return mCol1; +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol2( ) const +{ + return mCol2; +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol3( ) const +{ + return mCol3; +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getRow( int row ) const +{ + return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Matrix4::operator []( int col ) +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator =( const Matrix4 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix4 transpose( const Matrix4 & mat ) +{ + __m128 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3; + tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); + tmp1 = vec_mergeh( mat.getCol1().get128(), mat.getCol3().get128() ); + tmp2 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); + tmp3 = vec_mergel( mat.getCol1().get128(), mat.getCol3().get128() ); + res0 = vec_mergeh( tmp0, tmp1 ); + res1 = vec_mergel( tmp0, tmp1 ); + res2 = vec_mergeh( tmp2, tmp3 ); + res3 = vec_mergel( tmp2, tmp3 ); + return Matrix4( + Vector4( res0 ), + Vector4( res1 ), + Vector4( res2 ), + Vector4( res3 ) + ); +} + +// TODO: Tidy +static VM_ATTRIBUTE_ALIGN16 const unsigned int _vmathPNPN[4] = {0x00000000, 0x80000000, 0x00000000, 0x80000000}; +static VM_ATTRIBUTE_ALIGN16 const unsigned int _vmathNPNP[4] = {0x80000000, 0x00000000, 0x80000000, 0x00000000}; +static VM_ATTRIBUTE_ALIGN16 const float _vmathZERONE[4] = {1.0f, 0.0f, 0.0f, 1.0f}; + +VECTORMATH_FORCE_INLINE const Matrix4 inverse( const Matrix4 & mat ) +{ + __m128 Va,Vb,Vc; + __m128 r1,r2,r3,tt,tt2; + __m128 sum,Det,RDet; + __m128 trns0,trns1,trns2,trns3; + + __m128 _L1 = mat.getCol0().get128(); + __m128 _L2 = mat.getCol1().get128(); + __m128 _L3 = mat.getCol2().get128(); + __m128 _L4 = mat.getCol3().get128(); + // Calculating the minterms for the first line. + + // _mm_ror_ps is just a macro using _mm_shuffle_ps(). + tt = _L4; tt2 = _mm_ror_ps(_L3,1); + Vc = _mm_mul_ps(tt2,_mm_ror_ps(tt,0)); // V3'dot V4 + Va = _mm_mul_ps(tt2,_mm_ror_ps(tt,2)); // V3'dot V4" + Vb = _mm_mul_ps(tt2,_mm_ror_ps(tt,3)); // V3' dot V4^ + + r1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2)); // V3" dot V4^ - V3^ dot V4" + r2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0)); // V3^ dot V4' - V3' dot V4^ + r3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1)); // V3' dot V4" - V3" dot V4' + + tt = _L2; + Va = _mm_ror_ps(tt,1); sum = _mm_mul_ps(Va,r1); + Vb = _mm_ror_ps(tt,2); sum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2)); + Vc = _mm_ror_ps(tt,3); sum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3)); + + // Calculating the determinant. + Det = _mm_mul_ps(sum,_L1); + Det = _mm_add_ps(Det,_mm_movehl_ps(Det,Det)); + + const __m128 Sign_PNPN = _mm_load_ps((float *)_vmathPNPN); + const __m128 Sign_NPNP = _mm_load_ps((float *)_vmathNPNP); + + __m128 mtL1 = _mm_xor_ps(sum,Sign_PNPN); + + // Calculating the minterms of the second line (using previous results). + tt = _mm_ror_ps(_L1,1); sum = _mm_mul_ps(tt,r1); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); + __m128 mtL2 = _mm_xor_ps(sum,Sign_NPNP); + + // Testing the determinant. + Det = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1)); + + // Calculating the minterms of the third line. + tt = _mm_ror_ps(_L1,1); + Va = _mm_mul_ps(tt,Vb); // V1' dot V2" + Vb = _mm_mul_ps(tt,Vc); // V1' dot V2^ + Vc = _mm_mul_ps(tt,_L2); // V1' dot V2 + + r1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2)); // V1" dot V2^ - V1^ dot V2" + r2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0)); // V1^ dot V2' - V1' dot V2^ + r3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1)); // V1' dot V2" - V1" dot V2' + + tt = _mm_ror_ps(_L4,1); sum = _mm_mul_ps(tt,r1); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); + __m128 mtL3 = _mm_xor_ps(sum,Sign_PNPN); + + // Dividing is FASTER than rcp_nr! (Because rcp_nr causes many register-memory RWs). + RDet = _mm_div_ss(_mm_load_ss((float *)&_vmathZERONE), Det); // TODO: just 1.0f? + RDet = _mm_shuffle_ps(RDet,RDet,0x00); + + // Devide the first 12 minterms with the determinant. + mtL1 = _mm_mul_ps(mtL1, RDet); + mtL2 = _mm_mul_ps(mtL2, RDet); + mtL3 = _mm_mul_ps(mtL3, RDet); + + // Calculate the minterms of the forth line and devide by the determinant. + tt = _mm_ror_ps(_L3,1); sum = _mm_mul_ps(tt,r1); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); + __m128 mtL4 = _mm_xor_ps(sum,Sign_NPNP); + mtL4 = _mm_mul_ps(mtL4, RDet); + + // Now we just have to transpose the minterms matrix. + trns0 = _mm_unpacklo_ps(mtL1,mtL2); + trns1 = _mm_unpacklo_ps(mtL3,mtL4); + trns2 = _mm_unpackhi_ps(mtL1,mtL2); + trns3 = _mm_unpackhi_ps(mtL3,mtL4); + _L1 = _mm_movelh_ps(trns0,trns1); + _L2 = _mm_movehl_ps(trns1,trns0); + _L3 = _mm_movelh_ps(trns2,trns3); + _L4 = _mm_movehl_ps(trns3,trns2); + + return Matrix4( + Vector4( _L1 ), + Vector4( _L2 ), + Vector4( _L3 ), + Vector4( _L4 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 affineInverse( const Matrix4 & mat ) +{ + Transform3 affineMat; + affineMat.setCol0( mat.getCol0().getXYZ( ) ); + affineMat.setCol1( mat.getCol1().getXYZ( ) ); + affineMat.setCol2( mat.getCol2().getXYZ( ) ); + affineMat.setCol3( mat.getCol3().getXYZ( ) ); + return Matrix4( inverse( affineMat ) ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 orthoInverse( const Matrix4 & mat ) +{ + Transform3 affineMat; + affineMat.setCol0( mat.getCol0().getXYZ( ) ); + affineMat.setCol1( mat.getCol1().getXYZ( ) ); + affineMat.setCol2( mat.getCol2().getXYZ( ) ); + affineMat.setCol3( mat.getCol3().getXYZ( ) ); + return Matrix4( orthoInverse( affineMat ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix4 & mat ) +{ + __m128 Va,Vb,Vc; + __m128 r1,r2,r3,tt,tt2; + __m128 sum,Det; + + __m128 _L1 = mat.getCol0().get128(); + __m128 _L2 = mat.getCol1().get128(); + __m128 _L3 = mat.getCol2().get128(); + __m128 _L4 = mat.getCol3().get128(); + // Calculating the minterms for the first line. + + // _mm_ror_ps is just a macro using _mm_shuffle_ps(). + tt = _L4; tt2 = _mm_ror_ps(_L3,1); + Vc = _mm_mul_ps(tt2,_mm_ror_ps(tt,0)); // V3' dot V4 + Va = _mm_mul_ps(tt2,_mm_ror_ps(tt,2)); // V3' dot V4" + Vb = _mm_mul_ps(tt2,_mm_ror_ps(tt,3)); // V3' dot V4^ + + r1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2)); // V3" dot V4^ - V3^ dot V4" + r2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0)); // V3^ dot V4' - V3' dot V4^ + r3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1)); // V3' dot V4" - V3" dot V4' + + tt = _L2; + Va = _mm_ror_ps(tt,1); sum = _mm_mul_ps(Va,r1); + Vb = _mm_ror_ps(tt,2); sum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2)); + Vc = _mm_ror_ps(tt,3); sum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3)); + + // Calculating the determinant. + Det = _mm_mul_ps(sum,_L1); + Det = _mm_add_ps(Det,_mm_movehl_ps(Det,Det)); + + // Calculating the minterms of the second line (using previous results). + tt = _mm_ror_ps(_L1,1); sum = _mm_mul_ps(tt,r1); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); + + // Testing the determinant. + Det = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1)); + return floatInVec(Det, 0); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const +{ + return Matrix4( + ( mCol0 + mat.mCol0 ), + ( mCol1 + mat.mCol1 ), + ( mCol2 + mat.mCol2 ), + ( mCol3 + mat.mCol3 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const +{ + return Matrix4( + ( mCol0 - mat.mCol0 ), + ( mCol1 - mat.mCol1 ), + ( mCol2 - mat.mCol2 ), + ( mCol3 - mat.mCol3 ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) +{ + *this = *this + mat; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) +{ + *this = *this - mat; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator -( ) const +{ + return Matrix4( + ( -mCol0 ), + ( -mCol1 ), + ( -mCol2 ), + ( -mCol3 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 absPerElem( const Matrix4 & mat ) +{ + return Matrix4( + absPerElem( mat.getCol0() ), + absPerElem( mat.getCol1() ), + absPerElem( mat.getCol2() ), + absPerElem( mat.getCol3() ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator *( float scalar ) const +{ + return *this * floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator *( const floatInVec &scalar ) const +{ + return Matrix4( + ( mCol0 * scalar ), + ( mCol1 * scalar ), + ( mCol2 * scalar ), + ( mCol3 * scalar ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator *=( float scalar ) +{ + return *this *= floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator *=( const floatInVec &scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix4 operator *( float scalar, const Matrix4 & mat ) +{ + return floatInVec(scalar) * mat; +} + +VECTORMATH_FORCE_INLINE const Matrix4 operator *( const floatInVec &scalar, const Matrix4 & mat ) +{ + return mat * scalar; +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator *( const Vector4 &vec ) const +{ + return Vector4( + _mm_add_ps( + _mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(0,0,0,0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(1,1,1,1)))), + _mm_add_ps(_mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(2,2,2,2))), _mm_mul_ps(mCol3.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(3,3,3,3))))) + ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator *( const Vector3 &vec ) const +{ + return Vector4( + _mm_add_ps( + _mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(0,0,0,0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(1,1,1,1)))), + _mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(2,2,2,2)))) + ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator *( const Point3 &pnt ) const +{ + return Vector4( + _mm_add_ps( + _mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(0,0,0,0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(1,1,1,1)))), + _mm_add_ps(_mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(2,2,2,2))), mCol3.get128())) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const +{ + return Matrix4( + ( *this * mat.mCol0 ), + ( *this * mat.mCol1 ), + ( *this * mat.mCol2 ), + ( *this * mat.mCol3 ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) +{ + *this = *this * mat; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const +{ + return Matrix4( + ( *this * tfrm.getCol0() ), + ( *this * tfrm.getCol1() ), + ( *this * tfrm.getCol2() ), + ( *this * Point3( tfrm.getCol3() ) ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) +{ + *this = *this * tfrm; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) +{ + return Matrix4( + mulPerElem( mat0.getCol0(), mat1.getCol0() ), + mulPerElem( mat0.getCol1(), mat1.getCol1() ), + mulPerElem( mat0.getCol2(), mat1.getCol2() ), + mulPerElem( mat0.getCol3(), mat1.getCol3() ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::identity( ) +{ + return Matrix4( + Vector4::xAxis( ), + Vector4::yAxis( ), + Vector4::zAxis( ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) +{ + mCol0.setXYZ( mat3.getCol0() ); + mCol1.setXYZ( mat3.getCol1() ); + mCol2.setXYZ( mat3.getCol2() ); + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix4::getUpper3x3( ) const +{ + return Matrix3( + mCol0.getXYZ( ), + mCol1.getXYZ( ), + mCol2.getXYZ( ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setTranslation( const Vector3 &translateVec ) +{ + mCol3.setXYZ( translateVec ); + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix4::getTranslation( ) const +{ + return mCol3.getXYZ( ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationX( float radians ) +{ + return rotationX( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationX( const floatInVec &radians ) +{ + __m128 s, c, res1, res2; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res1 = vec_sel( zero, c, select_y ); + res1 = vec_sel( res1, s, select_z ); + res2 = vec_sel( zero, negatef4(s), select_y ); + res2 = vec_sel( res2, c, select_z ); + return Matrix4( + Vector4::xAxis( ), + Vector4( res1 ), + Vector4( res2 ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationY( float radians ) +{ + return rotationY( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationY( const floatInVec &radians ) +{ + __m128 s, c, res0, res2; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res0 = vec_sel( zero, c, select_x ); + res0 = vec_sel( res0, negatef4(s), select_z ); + res2 = vec_sel( zero, s, select_x ); + res2 = vec_sel( res2, c, select_z ); + return Matrix4( + Vector4( res0 ), + Vector4::yAxis( ), + Vector4( res2 ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationZ( float radians ) +{ + return rotationZ( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationZ( const floatInVec &radians ) +{ + __m128 s, c, res0, res1; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res0 = vec_sel( zero, c, select_x ); + res0 = vec_sel( res0, s, select_y ); + res1 = vec_sel( zero, negatef4(s), select_x ); + res1 = vec_sel( res1, c, select_y ); + return Matrix4( + Vector4( res0 ), + Vector4( res1 ), + Vector4::zAxis( ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationZYX( const Vector3 &radiansXYZ ) +{ + __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; + angles = Vector4( radiansXYZ, 0.0f ).get128(); + sincosf4( angles, &s, &c ); + negS = negatef4( s ); + Z0 = vec_mergel( c, s ); + Z1 = vec_mergel( negS, c ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_xyz[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0}; + Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) ); + Y0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) ); + Y1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) ); + X0 = vec_splat( s, 0 ); + X1 = vec_splat( c, 0 ); + tmp = vec_mul( Z0, Y1 ); + return Matrix4( + Vector4( vec_mul( Z0, Y0 ) ), + Vector4( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ), + Vector4( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotation( float radians, const Vector3 &unitVec ) +{ + return rotation( floatInVec(radians), unitVec ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotation( const floatInVec &radians, const Vector3 &unitVec ) +{ + __m128 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; + axis = unitVec.get128(); + sincosf4( radians.get128(), &s, &c ); + xxxx = vec_splat( axis, 0 ); + yyyy = vec_splat( axis, 1 ); + zzzz = vec_splat( axis, 2 ); + oneMinusC = vec_sub( _mm_set1_ps(1.0f), c ); + axisS = vec_mul( axis, s ); + negAxisS = negatef4( axisS ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + //tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); + tmp0 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,2,0) ); + tmp0 = vec_sel(tmp0, vec_splat(negAxisS, 1), select_z); + //tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); + tmp1 = vec_sel( vec_splat(axisS, 0), vec_splat(negAxisS, 2), select_x ); + //tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); + tmp2 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,0,1) ); + tmp2 = vec_sel(tmp2, vec_splat(negAxisS, 0), select_y); + tmp0 = vec_sel( tmp0, c, select_x ); + tmp1 = vec_sel( tmp1, c, select_y ); + tmp2 = vec_sel( tmp2, c, select_z ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_xyz[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0}; + axis = vec_and( axis, _mm_load_ps( (float *)select_xyz ) ); + tmp0 = vec_and( tmp0, _mm_load_ps( (float *)select_xyz ) ); + tmp1 = vec_and( tmp1, _mm_load_ps( (float *)select_xyz ) ); + tmp2 = vec_and( tmp2, _mm_load_ps( (float *)select_xyz ) ); + return Matrix4( + Vector4( vec_madd( vec_mul( axis, xxxx ), oneMinusC, tmp0 ) ), + Vector4( vec_madd( vec_mul( axis, yyyy ), oneMinusC, tmp1 ) ), + Vector4( vec_madd( vec_mul( axis, zzzz ), oneMinusC, tmp2 ) ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotation( const Quat &unitQuat ) +{ + return Matrix4( Transform3::rotation( unitQuat ) ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::scale( const Vector3 &scaleVec ) +{ + __m128 zero = _mm_setzero_ps(); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + return Matrix4( + Vector4( vec_sel( zero, scaleVec.get128(), select_x ) ), + Vector4( vec_sel( zero, scaleVec.get128(), select_y ) ), + Vector4( vec_sel( zero, scaleVec.get128(), select_z ) ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 appendScale( const Matrix4 & mat, const Vector3 &scaleVec ) +{ + return Matrix4( + ( mat.getCol0() * scaleVec.getX( ) ), + ( mat.getCol1() * scaleVec.getY( ) ), + ( mat.getCol2() * scaleVec.getZ( ) ), + mat.getCol3() + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 prependScale( const Vector3 &scaleVec, const Matrix4 & mat ) +{ + Vector4 scale4; + scale4 = Vector4( scaleVec, 1.0f ); + return Matrix4( + mulPerElem( mat.getCol0(), scale4 ), + mulPerElem( mat.getCol1(), scale4 ), + mulPerElem( mat.getCol2(), scale4 ), + mulPerElem( mat.getCol3(), scale4 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::translation( const Vector3 &translateVec ) +{ + return Matrix4( + Vector4::xAxis( ), + Vector4::yAxis( ), + Vector4::zAxis( ), + Vector4( translateVec, 1.0f ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::lookAt( const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec ) +{ + Matrix4 m4EyeFrame; + Vector3 v3X, v3Y, v3Z; + v3Y = normalize( upVec ); + v3Z = normalize( ( eyePos - lookAtPos ) ); + v3X = normalize( cross( v3Y, v3Z ) ); + v3Y = cross( v3Z, v3X ); + m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); + return orthoInverse( m4EyeFrame ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar ) +{ + float f, rangeInv; + __m128 zero, col0, col1, col2, col3; + union { __m128 v; float s[4]; } tmp; + f = tanf( _VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f ); + rangeInv = 1.0f / ( zNear - zFar ); + zero = _mm_setzero_ps(); + tmp.v = zero; + tmp.s[0] = f / aspect; + col0 = tmp.v; + tmp.v = zero; + tmp.s[1] = f; + col1 = tmp.v; + tmp.v = zero; + tmp.s[2] = ( zNear + zFar ) * rangeInv; + tmp.s[3] = -1.0f; + col2 = tmp.v; + tmp.v = zero; + tmp.s[2] = zNear * zFar * rangeInv * 2.0f; + col3 = tmp.v; + return Matrix4( + Vector4( col0 ), + Vector4( col1 ), + Vector4( col2 ), + Vector4( col3 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ) +{ + /* function implementation based on code from STIDC SDK: */ + /* -------------------------------------------------------------- */ + /* PLEASE DO NOT MODIFY THIS SECTION */ + /* This prolog section is automatically generated. */ + /* */ + /* (C)Copyright */ + /* Sony Computer Entertainment, Inc., */ + /* Toshiba Corporation, */ + /* International Business Machines Corporation, */ + /* 2001,2002. */ + /* S/T/I Confidential Information */ + /* -------------------------------------------------------------- */ + __m128 lbf, rtn; + __m128 diff, sum, inv_diff; + __m128 diagonal, column, near2; + __m128 zero = _mm_setzero_ps(); + union { __m128 v; float s[4]; } l, f, r, n, b, t; // TODO: Union? + l.s[0] = left; + f.s[0] = zFar; + r.s[0] = right; + n.s[0] = zNear; + b.s[0] = bottom; + t.s[0] = top; + lbf = vec_mergeh( l.v, f.v ); + rtn = vec_mergeh( r.v, n.v ); + lbf = vec_mergeh( lbf, b.v ); + rtn = vec_mergeh( rtn, t.v ); + diff = vec_sub( rtn, lbf ); + sum = vec_add( rtn, lbf ); + inv_diff = recipf4( diff ); + near2 = vec_splat( n.v, 0 ); + near2 = vec_add( near2, near2 ); + diagonal = vec_mul( near2, inv_diff ); + column = vec_mul( sum, inv_diff ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_w[4] = {0, 0, 0, 0xffffffff}; + return Matrix4( + Vector4( vec_sel( zero, diagonal, select_x ) ), + Vector4( vec_sel( zero, diagonal, select_y ) ), + Vector4( vec_sel( column, _mm_set1_ps(-1.0f), select_w ) ), + Vector4( vec_sel( zero, vec_mul( diagonal, vec_splat( f.v, 0 ) ), select_z ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar ) +{ + /* function implementation based on code from STIDC SDK: */ + /* -------------------------------------------------------------- */ + /* PLEASE DO NOT MODIFY THIS SECTION */ + /* This prolog section is automatically generated. */ + /* */ + /* (C)Copyright */ + /* Sony Computer Entertainment, Inc., */ + /* Toshiba Corporation, */ + /* International Business Machines Corporation, */ + /* 2001,2002. */ + /* S/T/I Confidential Information */ + /* -------------------------------------------------------------- */ + __m128 lbf, rtn; + __m128 diff, sum, inv_diff, neg_inv_diff; + __m128 diagonal, column; + __m128 zero = _mm_setzero_ps(); + union { __m128 v; float s[4]; } l, f, r, n, b, t; + l.s[0] = left; + f.s[0] = zFar; + r.s[0] = right; + n.s[0] = zNear; + b.s[0] = bottom; + t.s[0] = top; + lbf = vec_mergeh( l.v, f.v ); + rtn = vec_mergeh( r.v, n.v ); + lbf = vec_mergeh( lbf, b.v ); + rtn = vec_mergeh( rtn, t.v ); + diff = vec_sub( rtn, lbf ); + sum = vec_add( rtn, lbf ); + inv_diff = recipf4( diff ); + neg_inv_diff = negatef4( inv_diff ); + diagonal = vec_add( inv_diff, inv_diff ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_w[4] = {0, 0, 0, 0xffffffff}; + column = vec_mul( sum, vec_sel( neg_inv_diff, inv_diff, select_z ) ); // TODO: no madds with zero + return Matrix4( + Vector4( vec_sel( zero, diagonal, select_x ) ), + Vector4( vec_sel( zero, diagonal, select_y ) ), + Vector4( vec_sel( zero, diagonal, select_z ) ), + Vector4( vec_sel( column, _mm_set1_ps(1.0f), select_w ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ) +{ + return Matrix4( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ), + select( mat0.getCol3(), mat1.getCol3(), select1 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, const boolInVec &select1 ) +{ + return Matrix4( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ), + select( mat0.getCol3(), mat1.getCol3(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat ) +{ + print( mat.getRow( 0 ) ); + print( mat.getRow( 1 ) ); + print( mat.getRow( 2 ) ); + print( mat.getRow( 3 ) ); +} + +VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat, const char * name ) +{ + printf("%s:\n", name); + print( mat ); +} + +#endif + +VECTORMATH_FORCE_INLINE Transform3::Transform3( const Transform3 & tfrm ) +{ + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; +} + +VECTORMATH_FORCE_INLINE Transform3::Transform3( float scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); + mCol3 = Vector3( scalar ); +} + +VECTORMATH_FORCE_INLINE Transform3::Transform3( const floatInVec &scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); + mCol3 = Vector3( scalar ); +} + +VECTORMATH_FORCE_INLINE Transform3::Transform3( const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2, const Vector3 &_col3 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; +} + +VECTORMATH_FORCE_INLINE Transform3::Transform3( const Matrix3 & tfrm, const Vector3 &translateVec ) +{ + this->setUpper3x3( tfrm ); + this->setTranslation( translateVec ); +} + +VECTORMATH_FORCE_INLINE Transform3::Transform3( const Quat &unitQuat, const Vector3 &translateVec ) +{ + this->setUpper3x3( Matrix3( unitQuat ) ); + this->setTranslation( translateVec ); +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol0( const Vector3 &_col0 ) +{ + mCol0 = _col0; + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol1( const Vector3 &_col1 ) +{ + mCol1 = _col1; + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol2( const Vector3 &_col2 ) +{ + mCol2 = _col2; + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol3( const Vector3 &_col3 ) +{ + mCol3 = _col3; + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol( int col, const Vector3 &vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setRow( int row, const Vector4 &vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + mCol3.setElem( row, vec.getElem( 3 ) ); + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setElem( int col, int row, float val ) +{ + (*this)[col].setElem(row, val); + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setElem( int col, int row, const floatInVec &val ) +{ + Vector3 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Transform3::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol0( ) const +{ + return mCol0; +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol1( ) const +{ + return mCol1; +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol2( ) const +{ + return mCol2; +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol3( ) const +{ + return mCol3; +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE const Vector4 Transform3::getRow( int row ) const +{ + return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Transform3::operator []( int col ) +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::operator =( const Transform3 & tfrm ) +{ + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; + return *this; +} + +VECTORMATH_FORCE_INLINE const Transform3 inverse( const Transform3 & tfrm ) +{ + __m128 inv0, inv1, inv2, inv3; + __m128 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet; + __m128 xxxx, yyyy, zzzz; + tmp2 = _vmathVfCross( tfrm.getCol0().get128(), tfrm.getCol1().get128() ); + tmp0 = _vmathVfCross( tfrm.getCol1().get128(), tfrm.getCol2().get128() ); + tmp1 = _vmathVfCross( tfrm.getCol2().get128(), tfrm.getCol0().get128() ); + inv3 = negatef4( tfrm.getCol3().get128() ); + dot = _vmathVfDot3( tmp2, tfrm.getCol2().get128() ); + dot = vec_splat( dot, 0 ); + invdet = recipf4( dot ); + tmp3 = vec_mergeh( tmp0, tmp2 ); + tmp4 = vec_mergel( tmp0, tmp2 ); + inv0 = vec_mergeh( tmp3, tmp1 ); + xxxx = vec_splat( inv3, 0 ); + //inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + inv1 = _mm_shuffle_ps( tmp3, tmp3, _MM_SHUFFLE(0,3,2,2)); + inv1 = vec_sel(inv1, tmp1, select_y); + //inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); + inv2 = _mm_shuffle_ps( tmp4, tmp4, _MM_SHUFFLE(0,1,1,0)); + inv2 = vec_sel(inv2, vec_splat(tmp1, 2), select_y); + yyyy = vec_splat( inv3, 1 ); + zzzz = vec_splat( inv3, 2 ); + inv3 = vec_mul( inv0, xxxx ); + inv3 = vec_madd( inv1, yyyy, inv3 ); + inv3 = vec_madd( inv2, zzzz, inv3 ); + inv0 = vec_mul( inv0, invdet ); + inv1 = vec_mul( inv1, invdet ); + inv2 = vec_mul( inv2, invdet ); + inv3 = vec_mul( inv3, invdet ); + return Transform3( + Vector3( inv0 ), + Vector3( inv1 ), + Vector3( inv2 ), + Vector3( inv3 ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 orthoInverse( const Transform3 & tfrm ) +{ + __m128 inv0, inv1, inv2, inv3; + __m128 tmp0, tmp1; + __m128 xxxx, yyyy, zzzz; + tmp0 = vec_mergeh( tfrm.getCol0().get128(), tfrm.getCol2().get128() ); + tmp1 = vec_mergel( tfrm.getCol0().get128(), tfrm.getCol2().get128() ); + inv3 = negatef4( tfrm.getCol3().get128() ); + inv0 = vec_mergeh( tmp0, tfrm.getCol1().get128() ); + xxxx = vec_splat( inv3, 0 ); + //inv1 = vec_perm( tmp0, tfrm.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + inv1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2)); + inv1 = vec_sel(inv1, tfrm.getCol1().get128(), select_y); + //inv2 = vec_perm( tmp1, tfrm.getCol1().get128(), _VECTORMATH_PERM_XCYX ); + inv2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0)); + inv2 = vec_sel(inv2, vec_splat(tfrm.getCol1().get128(), 2), select_y); + yyyy = vec_splat( inv3, 1 ); + zzzz = vec_splat( inv3, 2 ); + inv3 = vec_mul( inv0, xxxx ); + inv3 = vec_madd( inv1, yyyy, inv3 ); + inv3 = vec_madd( inv2, zzzz, inv3 ); + return Transform3( + Vector3( inv0 ), + Vector3( inv1 ), + Vector3( inv2 ), + Vector3( inv3 ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 absPerElem( const Transform3 & tfrm ) +{ + return Transform3( + absPerElem( tfrm.getCol0() ), + absPerElem( tfrm.getCol1() ), + absPerElem( tfrm.getCol2() ), + absPerElem( tfrm.getCol3() ) + ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::operator *( const Vector3 &vec ) const +{ + __m128 res; + __m128 xxxx, yyyy, zzzz; + xxxx = vec_splat( vec.get128(), 0 ); + yyyy = vec_splat( vec.get128(), 1 ); + zzzz = vec_splat( vec.get128(), 2 ); + res = vec_mul( mCol0.get128(), xxxx ); + res = vec_madd( mCol1.get128(), yyyy, res ); + res = vec_madd( mCol2.get128(), zzzz, res ); + return Vector3( res ); +} + +VECTORMATH_FORCE_INLINE const Point3 Transform3::operator *( const Point3 &pnt ) const +{ + __m128 tmp0, tmp1, res; + __m128 xxxx, yyyy, zzzz; + xxxx = vec_splat( pnt.get128(), 0 ); + yyyy = vec_splat( pnt.get128(), 1 ); + zzzz = vec_splat( pnt.get128(), 2 ); + tmp0 = vec_mul( mCol0.get128(), xxxx ); + tmp1 = vec_mul( mCol1.get128(), yyyy ); + tmp0 = vec_madd( mCol2.get128(), zzzz, tmp0 ); + tmp1 = vec_add( mCol3.get128(), tmp1 ); + res = vec_add( tmp0, tmp1 ); + return Point3( res ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::operator *( const Transform3 & tfrm ) const +{ + return Transform3( + ( *this * tfrm.mCol0 ), + ( *this * tfrm.mCol1 ), + ( *this * tfrm.mCol2 ), + Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) + ); +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::operator *=( const Transform3 & tfrm ) +{ + *this = *this * tfrm; + return *this; +} + +VECTORMATH_FORCE_INLINE const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) +{ + return Transform3( + mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), + mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), + mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), + mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::identity( ) +{ + return Transform3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ), + Vector3( 0.0f ) + ); +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) +{ + mCol0 = tfrm.getCol0(); + mCol1 = tfrm.getCol1(); + mCol2 = tfrm.getCol2(); + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix3 Transform3::getUpper3x3( ) const +{ + return Matrix3( mCol0, mCol1, mCol2 ); +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setTranslation( const Vector3 &translateVec ) +{ + mCol3 = translateVec; + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getTranslation( ) const +{ + return mCol3; +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationX( float radians ) +{ + return rotationX( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationX( const floatInVec &radians ) +{ + __m128 s, c, res1, res2; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res1 = vec_sel( zero, c, select_y ); + res1 = vec_sel( res1, s, select_z ); + res2 = vec_sel( zero, negatef4(s), select_y ); + res2 = vec_sel( res2, c, select_z ); + return Transform3( + Vector3::xAxis( ), + Vector3( res1 ), + Vector3( res2 ), + Vector3( _mm_setzero_ps() ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationY( float radians ) +{ + return rotationY( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationY( const floatInVec &radians ) +{ + __m128 s, c, res0, res2; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res0 = vec_sel( zero, c, select_x ); + res0 = vec_sel( res0, negatef4(s), select_z ); + res2 = vec_sel( zero, s, select_x ); + res2 = vec_sel( res2, c, select_z ); + return Transform3( + Vector3( res0 ), + Vector3::yAxis( ), + Vector3( res2 ), + Vector3( 0.0f ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationZ( float radians ) +{ + return rotationZ( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationZ( const floatInVec &radians ) +{ + __m128 s, c, res0, res1; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + __m128 zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res0 = vec_sel( zero, c, select_x ); + res0 = vec_sel( res0, s, select_y ); + res1 = vec_sel( zero, negatef4(s), select_x ); + res1 = vec_sel( res1, c, select_y ); + return Transform3( + Vector3( res0 ), + Vector3( res1 ), + Vector3::zAxis( ), + Vector3( 0.0f ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationZYX( const Vector3 &radiansXYZ ) +{ + __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; + angles = Vector4( radiansXYZ, 0.0f ).get128(); + sincosf4( angles, &s, &c ); + negS = negatef4( s ); + Z0 = vec_mergel( c, s ); + Z1 = vec_mergel( negS, c ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_xyz[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0}; + Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) ); + Y0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) ); + Y1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) ); + X0 = vec_splat( s, 0 ); + X1 = vec_splat( c, 0 ); + tmp = vec_mul( Z0, Y1 ); + return Transform3( + Vector3( vec_mul( Z0, Y0 ) ), + Vector3( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ), + Vector3( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ), + Vector3( 0.0f ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotation( float radians, const Vector3 &unitVec ) +{ + return rotation( floatInVec(radians), unitVec ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotation( const floatInVec &radians, const Vector3 &unitVec ) +{ + return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotation( const Quat &unitQuat ) +{ + return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::scale( const Vector3 &scaleVec ) +{ + __m128 zero = _mm_setzero_ps(); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + return Transform3( + Vector3( vec_sel( zero, scaleVec.get128(), select_x ) ), + Vector3( vec_sel( zero, scaleVec.get128(), select_y ) ), + Vector3( vec_sel( zero, scaleVec.get128(), select_z ) ), + Vector3( 0.0f ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 appendScale( const Transform3 & tfrm, const Vector3 &scaleVec ) +{ + return Transform3( + ( tfrm.getCol0() * scaleVec.getX( ) ), + ( tfrm.getCol1() * scaleVec.getY( ) ), + ( tfrm.getCol2() * scaleVec.getZ( ) ), + tfrm.getCol3() + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 prependScale( const Vector3 &scaleVec, const Transform3 & tfrm ) +{ + return Transform3( + mulPerElem( tfrm.getCol0(), scaleVec ), + mulPerElem( tfrm.getCol1(), scaleVec ), + mulPerElem( tfrm.getCol2(), scaleVec ), + mulPerElem( tfrm.getCol3(), scaleVec ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::translation( const Vector3 &translateVec ) +{ + return Transform3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ), + translateVec + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ) +{ + return Transform3( + select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), + select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), + select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), + select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, const boolInVec &select1 ) +{ + return Transform3( + select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), + select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), + select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), + select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm ) +{ + print( tfrm.getRow( 0 ) ); + print( tfrm.getRow( 1 ) ); + print( tfrm.getRow( 2 ) ); +} + +VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm, const char * name ) +{ + printf("%s:\n", name); + print( tfrm ); +} + +#endif + +VECTORMATH_FORCE_INLINE Quat::Quat( const Matrix3 & tfrm ) +{ + __m128 res; + __m128 col0, col1, col2; + __m128 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff; + __m128 zy_xz_yx, yz_zx_xy, sum, diff; + __m128 radicand, invSqrt, scale; + __m128 res0, res1, res2, res3; + __m128 xx, yy, zz; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_w[4] = {0, 0, 0, 0xffffffff}; + + col0 = tfrm.getCol0().get128(); + col1 = tfrm.getCol1().get128(); + col2 = tfrm.getCol2().get128(); + + /* four cases: */ + /* trace > 0 */ + /* else */ + /* xx largest diagonal element */ + /* yy largest diagonal element */ + /* zz largest diagonal element */ + + /* compute quaternion for each case */ + + xx_yy = vec_sel( col0, col1, select_y ); + //xx_yy_zz_xx = vec_perm( xx_yy, col2, _VECTORMATH_PERM_XYCX ); + //yy_zz_xx_yy = vec_perm( xx_yy, col2, _VECTORMATH_PERM_YCXY ); + //zz_xx_yy_zz = vec_perm( xx_yy, col2, _VECTORMATH_PERM_CXYC ); + xx_yy_zz_xx = _mm_shuffle_ps( xx_yy, xx_yy, _MM_SHUFFLE(0,0,1,0) ); + xx_yy_zz_xx = vec_sel( xx_yy_zz_xx, col2, select_z ); // TODO: Ck + yy_zz_xx_yy = _mm_shuffle_ps( xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(1,0,2,1) ); + zz_xx_yy_zz = _mm_shuffle_ps( xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(2,1,0,2) ); + + diagSum = vec_add( vec_add( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); + diagDiff = vec_sub( vec_sub( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); + radicand = vec_add( vec_sel( diagDiff, diagSum, select_w ), _mm_set1_ps(1.0f) ); + // invSqrt = rsqrtf4( radicand ); + invSqrt = newtonrapson_rsqrt4( radicand ); + + + + zy_xz_yx = vec_sel( col0, col1, select_z ); // zy_xz_yx = 00 01 12 03 + //zy_xz_yx = vec_perm( zy_xz_yx, col2, _VECTORMATH_PERM_ZAYX ); + zy_xz_yx = _mm_shuffle_ps( zy_xz_yx, zy_xz_yx, _MM_SHUFFLE(0,1,2,2) ); // zy_xz_yx = 12 12 01 00 + zy_xz_yx = vec_sel( zy_xz_yx, vec_splat(col2, 0), select_y ); // zy_xz_yx = 12 20 01 00 + yz_zx_xy = vec_sel( col0, col1, select_x ); // yz_zx_xy = 10 01 02 03 + //yz_zx_xy = vec_perm( yz_zx_xy, col2, _VECTORMATH_PERM_BZXX ); + yz_zx_xy = _mm_shuffle_ps( yz_zx_xy, yz_zx_xy, _MM_SHUFFLE(0,0,2,0) ); // yz_zx_xy = 10 02 10 10 + yz_zx_xy = vec_sel( yz_zx_xy, vec_splat(col2, 1), select_x ); // yz_zx_xy = 21 02 10 10 + + sum = vec_add( zy_xz_yx, yz_zx_xy ); + diff = vec_sub( zy_xz_yx, yz_zx_xy ); + + scale = vec_mul( invSqrt, _mm_set1_ps(0.5f) ); + + //res0 = vec_perm( sum, diff, _VECTORMATH_PERM_XZYA ); + res0 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,1,2,0) ); + res0 = vec_sel( res0, vec_splat(diff, 0), select_w ); // TODO: Ck + //res1 = vec_perm( sum, diff, _VECTORMATH_PERM_ZXXB ); + res1 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,0,0,2) ); + res1 = vec_sel( res1, vec_splat(diff, 1), select_w ); // TODO: Ck + //res2 = vec_perm( sum, diff, _VECTORMATH_PERM_YXXC ); + res2 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,0,0,1) ); + res2 = vec_sel( res2, vec_splat(diff, 2), select_w ); // TODO: Ck + res3 = diff; + res0 = vec_sel( res0, radicand, select_x ); + res1 = vec_sel( res1, radicand, select_y ); + res2 = vec_sel( res2, radicand, select_z ); + res3 = vec_sel( res3, radicand, select_w ); + res0 = vec_mul( res0, vec_splat( scale, 0 ) ); + res1 = vec_mul( res1, vec_splat( scale, 1 ) ); + res2 = vec_mul( res2, vec_splat( scale, 2 ) ); + res3 = vec_mul( res3, vec_splat( scale, 3 ) ); + + /* determine case and select answer */ + + xx = vec_splat( col0, 0 ); + yy = vec_splat( col1, 1 ); + zz = vec_splat( col2, 2 ); + res = vec_sel( res0, res1, vec_cmpgt( yy, xx ) ); + res = vec_sel( res, res2, vec_and( vec_cmpgt( zz, xx ), vec_cmpgt( zz, yy ) ) ); + res = vec_sel( res, res3, vec_cmpgt( vec_splat( diagSum, 0 ), _mm_setzero_ps() ) ); + mVec128 = res; +} + +VECTORMATH_FORCE_INLINE const Matrix3 outer( const Vector3 &tfrm0, const Vector3 &tfrm1 ) +{ + return Matrix3( + ( tfrm0 * tfrm1.getX( ) ), + ( tfrm0 * tfrm1.getY( ) ), + ( tfrm0 * tfrm1.getZ( ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 outer( const Vector4 &tfrm0, const Vector4 &tfrm1 ) +{ + return Matrix4( + ( tfrm0 * tfrm1.getX( ) ), + ( tfrm0 * tfrm1.getY( ) ), + ( tfrm0 * tfrm1.getZ( ) ), + ( tfrm0 * tfrm1.getW( ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Vector3 rowMul( const Vector3 &vec, const Matrix3 & mat ) +{ + __m128 tmp0, tmp1, mcol0, mcol1, mcol2, res; + __m128 xxxx, yyyy, zzzz; + tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); + tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); + xxxx = vec_splat( vec.get128(), 0 ); + mcol0 = vec_mergeh( tmp0, mat.getCol1().get128() ); + //mcol1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + mcol1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2)); + mcol1 = vec_sel(mcol1, mat.getCol1().get128(), select_y); + //mcol2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX ); + mcol2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0)); + mcol2 = vec_sel(mcol2, vec_splat(mat.getCol1().get128(), 2), select_y); + yyyy = vec_splat( vec.get128(), 1 ); + res = vec_mul( mcol0, xxxx ); + zzzz = vec_splat( vec.get128(), 2 ); + res = vec_madd( mcol1, yyyy, res ); + res = vec_madd( mcol2, zzzz, res ); + return Vector3( res ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 crossMatrix( const Vector3 &vec ) +{ + __m128 neg, res0, res1, res2; + neg = negatef4( vec.get128() ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + //res0 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_XZBX ); + res0 = _mm_shuffle_ps( vec.get128(), vec.get128(), _MM_SHUFFLE(0,2,2,0) ); + res0 = vec_sel(res0, vec_splat(neg, 1), select_z); + //res1 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_CXXX ); + res1 = vec_sel(vec_splat(vec.get128(), 0), vec_splat(neg, 2), select_x); + //res2 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_YAXX ); + res2 = _mm_shuffle_ps( vec.get128(), vec.get128(), _MM_SHUFFLE(0,0,1,1) ); + res2 = vec_sel(res2, vec_splat(neg, 0), select_y); + VM_ATTRIBUTE_ALIGN16 unsigned int filter_x[4] = {0, 0xffffffff, 0xffffffff, 0xffffffff}; + VM_ATTRIBUTE_ALIGN16 unsigned int filter_y[4] = {0xffffffff, 0, 0xffffffff, 0xffffffff}; + VM_ATTRIBUTE_ALIGN16 unsigned int filter_z[4] = {0xffffffff, 0xffffffff, 0, 0xffffffff}; + res0 = vec_and( res0, _mm_load_ps((float *)filter_x ) ); + res1 = vec_and( res1, _mm_load_ps((float *)filter_y ) ); + res2 = vec_and( res2, _mm_load_ps((float *)filter_z ) ); // TODO: Use selects? + return Matrix3( + Vector3( res0 ), + Vector3( res1 ), + Vector3( res2 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 crossMatrixMul( const Vector3 &vec, const Matrix3 & mat ) +{ + return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); +} + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/Extras/PhysicsEffects/include/vecmath/sse/quat_aos.h b/Extras/PhysicsEffects/include/vecmath/sse/quat_aos.h new file mode 100644 index 000000000..d7091ecf8 --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/sse/quat_aos.h @@ -0,0 +1,579 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef _VECTORMATH_QUAT_AOS_CPP_H +#define _VECTORMATH_QUAT_AOS_CPP_H + +//----------------------------------------------------------------------------- +// Definitions + +#ifndef _VECTORMATH_INTERNAL_FUNCTIONS +#define _VECTORMATH_INTERNAL_FUNCTIONS + +#endif + +namespace Vectormath { +namespace Aos { + +VECTORMATH_FORCE_INLINE void Quat::set128(vec_float4 vec) +{ + mVec128 = vec; +} + +VECTORMATH_FORCE_INLINE Quat::Quat( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z, const floatInVec &_w ) +{ + mVec128 = _mm_unpacklo_ps( + _mm_unpacklo_ps( _x.get128(), _z.get128() ), + _mm_unpacklo_ps( _y.get128(), _w.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Quat::Quat( const Vector3 &xyz, float _w ) +{ + mVec128 = xyz.get128(); + _vmathVfSetElement(mVec128, _w, 3); +} + + + +VECTORMATH_FORCE_INLINE Quat::Quat(const Quat& quat) +{ + mVec128 = quat.get128(); +} + +VECTORMATH_FORCE_INLINE Quat::Quat( float _x, float _y, float _z, float _w ) +{ + mVec128 = _mm_setr_ps(_x, _y, _z, _w); +} + + + + + +VECTORMATH_FORCE_INLINE Quat::Quat( const Vector3 &xyz, const floatInVec &_w ) +{ + mVec128 = xyz.get128(); + mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); +} + +VECTORMATH_FORCE_INLINE Quat::Quat( const Vector4 &vec ) +{ + mVec128 = vec.get128(); +} + +VECTORMATH_FORCE_INLINE Quat::Quat( float scalar ) +{ + mVec128 = floatInVec(scalar).get128(); +} + +VECTORMATH_FORCE_INLINE Quat::Quat( const floatInVec &scalar ) +{ + mVec128 = scalar.get128(); +} + +VECTORMATH_FORCE_INLINE Quat::Quat( __m128 vf4 ) +{ + mVec128 = vf4; +} + +VECTORMATH_FORCE_INLINE const Quat Quat::identity( ) +{ + return Quat( _VECTORMATH_UNIT_0001 ); +} + +VECTORMATH_FORCE_INLINE const Quat lerp( float t, const Quat &quat0, const Quat &quat1 ) +{ + return lerp( floatInVec(t), quat0, quat1 ); +} + +VECTORMATH_FORCE_INLINE const Quat lerp( const floatInVec &t, const Quat &quat0, const Quat &quat1 ) +{ + return ( quat0 + ( ( quat1 - quat0 ) * t ) ); +} + +VECTORMATH_FORCE_INLINE const Quat slerp( float t, const Quat &unitQuat0, const Quat &unitQuat1 ) +{ + return slerp( floatInVec(t), unitQuat0, unitQuat1 ); +} + +VECTORMATH_FORCE_INLINE const Quat slerp( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1 ) +{ + Quat start; + vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; + __m128 selectMask; + cosAngle = _vmathVfDot4( unitQuat0.get128(), unitQuat1.get128() ); + selectMask = (__m128)vec_cmpgt( _mm_setzero_ps(), cosAngle ); + cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask ); + start = Quat( vec_sel( unitQuat0.get128(), negatef4( unitQuat0.get128() ), selectMask ) ); + selectMask = (__m128)vec_cmpgt( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle ); + angle = acosf4( cosAngle ); + tttt = t.get128(); + oneMinusT = vec_sub( _mm_set1_ps(1.0f), tttt ); + angles = vec_mergeh( _mm_set1_ps(1.0f), tttt ); + angles = vec_mergeh( angles, oneMinusT ); + angles = vec_madd( angles, angle, _mm_setzero_ps() ); + sines = sinf4( angles ); + scales = _mm_div_ps( sines, vec_splat( sines, 0 ) ); + scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); + scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); + return Quat( vec_madd( start.get128(), scale0, vec_mul( unitQuat1.get128(), scale1 ) ) ); +} + +VECTORMATH_FORCE_INLINE const Quat squad( float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ) +{ + return squad( floatInVec(t), unitQuat0, unitQuat1, unitQuat2, unitQuat3 ); +} + +VECTORMATH_FORCE_INLINE const Quat squad( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ) +{ + return slerp( ( ( floatInVec(2.0f) * t ) * ( floatInVec(1.0f) - t ) ), slerp( t, unitQuat0, unitQuat3 ), slerp( t, unitQuat1, unitQuat2 ) ); +} + +VECTORMATH_FORCE_INLINE __m128 Quat::get128( ) const +{ + return mVec128; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator =( const Quat &quat ) +{ + mVec128 = quat.mVec128; + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setXYZ( const Vector3 &vec ) +{ + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; + mVec128 = vec_sel( vec.get128(), mVec128, sw ); + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 Quat::getXYZ( ) const +{ + return Vector3( mVec128 ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setX( float _x ) +{ + _vmathVfSetElement(mVec128, _x, 0); + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setX( const floatInVec &_x ) +{ + mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Quat::getX( ) const +{ + return floatInVec( mVec128, 0 ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setY( float _y ) +{ + _vmathVfSetElement(mVec128, _y, 1); + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setY( const floatInVec &_y ) +{ + mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Quat::getY( ) const +{ + return floatInVec( mVec128, 1 ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setZ( float _z ) +{ + _vmathVfSetElement(mVec128, _z, 2); + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setZ( const floatInVec &_z ) +{ + mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Quat::getZ( ) const +{ + return floatInVec( mVec128, 2 ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setW( float _w ) +{ + _vmathVfSetElement(mVec128, _w, 3); + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setW( const floatInVec &_w ) +{ + mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Quat::getW( ) const +{ + return floatInVec( mVec128, 3 ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setElem( int idx, float value ) +{ + _vmathVfSetElement(mVec128, value, idx); + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setElem( int idx, const floatInVec &value ) +{ + mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Quat::getElem( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE VecIdx Quat::operator []( int idx ) +{ + return VecIdx( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const floatInVec Quat::operator []( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator +( const Quat &quat ) const +{ + return Quat( _mm_add_ps( mVec128, quat.mVec128 ) ); +} + + +VECTORMATH_FORCE_INLINE const Quat Quat::operator -( const Quat &quat ) const +{ + return Quat( _mm_sub_ps( mVec128, quat.mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator *( float scalar ) const +{ + return *this * floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator *( const floatInVec &scalar ) const +{ + return Quat( _mm_mul_ps( mVec128, scalar.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator +=( const Quat &quat ) +{ + *this = *this + quat; + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator -=( const Quat &quat ) +{ + *this = *this - quat; + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator *=( const floatInVec &scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator /( float scalar ) const +{ + return *this / floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator /( const floatInVec &scalar ) const +{ + return Quat( _mm_div_ps( mVec128, scalar.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator /=( const floatInVec &scalar ) +{ + *this = *this / scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator -( ) const +{ + return Quat(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Quat operator *( float scalar, const Quat &quat ) +{ + return floatInVec(scalar) * quat; +} + +VECTORMATH_FORCE_INLINE const Quat operator *( const floatInVec &scalar, const Quat &quat ) +{ + return quat * scalar; +} + +VECTORMATH_FORCE_INLINE const floatInVec dot( const Quat &quat0, const Quat &quat1 ) +{ + return floatInVec( _vmathVfDot4( quat0.get128(), quat1.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec norm( const Quat &quat ) +{ + return floatInVec( _vmathVfDot4( quat.get128(), quat.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec length( const Quat &quat ) +{ + return floatInVec( _mm_sqrt_ps(_vmathVfDot4( quat.get128(), quat.get128() )), 0 ); +} + +VECTORMATH_FORCE_INLINE const Quat normalize( const Quat &quat ) +{ + vec_float4 dot =_vmathVfDot4( quat.get128(), quat.get128()); + return Quat( _mm_mul_ps( quat.get128(), newtonrapson_rsqrt4( dot ) ) ); +} + + +VECTORMATH_FORCE_INLINE const Quat Quat::rotation( const Vector3 &unitVec0, const Vector3 &unitVec1 ) +{ + Vector3 crossVec; + __m128 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res; + cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() ); + cosAngleX2Plus2 = vec_madd( cosAngle, _mm_set1_ps(2.0f), _mm_set1_ps(2.0f) ); + recipCosHalfAngleX2 = _mm_rsqrt_ps( cosAngleX2Plus2 ); + cosHalfAngleX2 = vec_mul( recipCosHalfAngleX2, cosAngleX2Plus2 ); + crossVec = cross( unitVec0, unitVec1 ); + res = vec_mul( crossVec.get128(), recipCosHalfAngleX2 ); + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; + res = vec_sel( res, vec_mul( cosHalfAngleX2, _mm_set1_ps(0.5f) ), sw ); + return Quat( res ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotation( float radians, const Vector3 &unitVec ) +{ + return rotation( floatInVec(radians), unitVec ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotation( const floatInVec &radians, const Vector3 &unitVec ) +{ + __m128 s, c, angle, res; + angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); + sincosf4( angle, &s, &c ); + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; + res = vec_sel( vec_mul( unitVec.get128(), s ), c, sw ); + return Quat( res ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotationX( float radians ) +{ + return rotationX( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotationX( const floatInVec &radians ) +{ + __m128 s, c, angle, res; + angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); + sincosf4( angle, &s, &c ); + VM_ATTRIBUTE_ALIGN16 unsigned int xsw[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int wsw[4] = {0, 0, 0, 0xffffffff}; + res = vec_sel( _mm_setzero_ps(), s, xsw ); + res = vec_sel( res, c, wsw ); + return Quat( res ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotationY( float radians ) +{ + return rotationY( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotationY( const floatInVec &radians ) +{ + __m128 s, c, angle, res; + angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); + sincosf4( angle, &s, &c ); + VM_ATTRIBUTE_ALIGN16 unsigned int ysw[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int wsw[4] = {0, 0, 0, 0xffffffff}; + res = vec_sel( _mm_setzero_ps(), s, ysw ); + res = vec_sel( res, c, wsw ); + return Quat( res ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotationZ( float radians ) +{ + return rotationZ( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotationZ( const floatInVec &radians ) +{ + __m128 s, c, angle, res; + angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); + sincosf4( angle, &s, &c ); + VM_ATTRIBUTE_ALIGN16 unsigned int zsw[4] = {0, 0, 0xffffffff, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int wsw[4] = {0, 0, 0, 0xffffffff}; + res = vec_sel( _mm_setzero_ps(), s, zsw ); + res = vec_sel( res, c, wsw ); + return Quat( res ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator *( const Quat &quat ) const +{ + __m128 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3; + __m128 product, l_wxyz, r_wxyz, xy, qw; + ldata = mVec128; + rdata = quat.mVec128; + tmp0 = _mm_shuffle_ps( ldata, ldata, _MM_SHUFFLE(3,0,2,1) ); + tmp1 = _mm_shuffle_ps( rdata, rdata, _MM_SHUFFLE(3,1,0,2) ); + tmp2 = _mm_shuffle_ps( ldata, ldata, _MM_SHUFFLE(3,1,0,2) ); + tmp3 = _mm_shuffle_ps( rdata, rdata, _MM_SHUFFLE(3,0,2,1) ); + qv = vec_mul( vec_splat( ldata, 3 ), rdata ); + qv = vec_madd( vec_splat( rdata, 3 ), ldata, qv ); + qv = vec_madd( tmp0, tmp1, qv ); + qv = vec_nmsub( tmp2, tmp3, qv ); + product = vec_mul( ldata, rdata ); + l_wxyz = vec_sld( ldata, ldata, 12 ); + r_wxyz = vec_sld( rdata, rdata, 12 ); + qw = vec_nmsub( l_wxyz, r_wxyz, product ); + xy = vec_madd( l_wxyz, r_wxyz, product ); + qw = vec_sub( qw, vec_sld( xy, xy, 8 ) ); + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; + return Quat( vec_sel( qv, qw, sw ) ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator *=( const Quat &quat ) +{ + *this = *this * quat; + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 rotate( const Quat &quat, const Vector3 &vec ) +{ __m128 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res; + qdata = quat.get128(); + vdata = vec.get128(); + tmp0 = _mm_shuffle_ps( qdata, qdata, _MM_SHUFFLE(3,0,2,1) ); + tmp1 = _mm_shuffle_ps( vdata, vdata, _MM_SHUFFLE(3,1,0,2) ); + tmp2 = _mm_shuffle_ps( qdata, qdata, _MM_SHUFFLE(3,1,0,2) ); + tmp3 = _mm_shuffle_ps( vdata, vdata, _MM_SHUFFLE(3,0,2,1) ); + wwww = vec_splat( qdata, 3 ); + qv = vec_mul( wwww, vdata ); + qv = vec_madd( tmp0, tmp1, qv ); + qv = vec_nmsub( tmp2, tmp3, qv ); + product = vec_mul( qdata, vdata ); + qw = vec_madd( vec_sld( qdata, qdata, 4 ), vec_sld( vdata, vdata, 4 ), product ); + qw = vec_add( vec_sld( product, product, 8 ), qw ); + tmp1 = _mm_shuffle_ps( qv, qv, _MM_SHUFFLE(3,1,0,2) ); + tmp3 = _mm_shuffle_ps( qv, qv, _MM_SHUFFLE(3,0,2,1) ); + res = vec_mul( vec_splat( qw, 0 ), qdata ); + res = vec_madd( wwww, qv, res ); + res = vec_madd( tmp0, tmp1, res ); + res = vec_nmsub( tmp2, tmp3, res ); + return Vector3( res ); +} + +VECTORMATH_FORCE_INLINE const Quat conj( const Quat &quat ) +{ + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0x80000000,0x80000000,0x80000000,0}; + return Quat( vec_xor( quat.get128(), _mm_load_ps((float *)sw) ) ); +} + +VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, bool select1 ) +{ + return select( quat0, quat1, boolInVec(select1) ); +} + +//VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, const boolInVec &select1 ) +//{ +// return Quat( vec_sel( quat0.get128(), quat1.get128(), select1.get128() ) ); +//} + +VECTORMATH_FORCE_INLINE void loadXYZW(Quat& quat, const float* fptr) +{ +#ifdef USE_SSE3_LDDQU + quat = Quat( SSEFloat(_mm_lddqu_si128((const __m128i*)((float*)(fptr)))).m128 ); +#else + SSEFloat fl; + fl.f[0] = fptr[0]; + fl.f[1] = fptr[1]; + fl.f[2] = fptr[2]; + fl.f[3] = fptr[3]; + quat = Quat( fl.m128); +#endif + + +} + +VECTORMATH_FORCE_INLINE void storeXYZW(const Quat& quat, float* fptr) +{ + fptr[0] = quat.getX(); + fptr[1] = quat.getY(); + fptr[2] = quat.getZ(); + fptr[3] = quat.getW(); +// _mm_storeu_ps((float*)quat.get128(),fptr); +} + + + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Quat &quat ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = quat.get128(); + printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); +} + +VECTORMATH_FORCE_INLINE void print( const Quat &quat, const char * name ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = quat.get128(); + printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); +} + +#endif + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/Extras/PhysicsEffects/include/vecmath/sse/vec_aos.h b/Extras/PhysicsEffects/include/vecmath/sse/vec_aos.h new file mode 100644 index 000000000..05ebac55a --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/sse/vec_aos.h @@ -0,0 +1,1455 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _VECTORMATH_VEC_AOS_CPP_H +#define _VECTORMATH_VEC_AOS_CPP_H + +//----------------------------------------------------------------------------- +// Constants +// for permutes words are labeled [x,y,z,w] [a,b,c,d] + +#define _VECTORMATH_PERM_X 0x00010203 +#define _VECTORMATH_PERM_Y 0x04050607 +#define _VECTORMATH_PERM_Z 0x08090a0b +#define _VECTORMATH_PERM_W 0x0c0d0e0f +#define _VECTORMATH_PERM_A 0x10111213 +#define _VECTORMATH_PERM_B 0x14151617 +#define _VECTORMATH_PERM_C 0x18191a1b +#define _VECTORMATH_PERM_D 0x1c1d1e1f +#define _VECTORMATH_PERM_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A } +#define _VECTORMATH_PERM_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_W } +#define _VECTORMATH_PERM_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W } +#define _VECTORMATH_PERM_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B } +#define _VECTORMATH_PERM_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B, _VECTORMATH_PERM_C } +#define _VECTORMATH_PERM_XYAW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_W } +#define _VECTORMATH_PERM_XAZW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W } +#define _VECTORMATH_MASK_0xF000 (vec_uint4){ 0xffffffff, 0, 0, 0 } +#define _VECTORMATH_MASK_0x0F00 (vec_uint4){ 0, 0xffffffff, 0, 0 } +#define _VECTORMATH_MASK_0x00F0 (vec_uint4){ 0, 0, 0xffffffff, 0 } +#define _VECTORMATH_MASK_0x000F (vec_uint4){ 0, 0, 0, 0xffffffff } +#define _VECTORMATH_UNIT_1000 _mm_setr_ps(1.0f,0.0f,0.0f,0.0f) // (__m128){ 1.0f, 0.0f, 0.0f, 0.0f } +#define _VECTORMATH_UNIT_0100 _mm_setr_ps(0.0f,1.0f,0.0f,0.0f) // (__m128){ 0.0f, 1.0f, 0.0f, 0.0f } +#define _VECTORMATH_UNIT_0010 _mm_setr_ps(0.0f,0.0f,1.0f,0.0f) // (__m128){ 0.0f, 0.0f, 1.0f, 0.0f } +#define _VECTORMATH_UNIT_0001 _mm_setr_ps(0.0f,0.0f,0.0f,1.0f) // (__m128){ 0.0f, 0.0f, 0.0f, 1.0f } +#define _VECTORMATH_SLERP_TOL 0.999f +//_VECTORMATH_SLERP_TOLF + +//----------------------------------------------------------------------------- +// Definitions + +#ifndef _VECTORMATH_INTERNAL_FUNCTIONS +#define _VECTORMATH_INTERNAL_FUNCTIONS + +#define _vmath_shufps(a, b, immx, immy, immz, immw) _mm_shuffle_ps(a, b, _MM_SHUFFLE(immw, immz, immy, immx)) +static VECTORMATH_FORCE_INLINE __m128 _vmathVfDot3( __m128 vec0, __m128 vec1 ) +{ + __m128 result = _mm_mul_ps( vec0, vec1); + return _mm_add_ps( vec_splat( result, 0 ), _mm_add_ps( vec_splat( result, 1 ), vec_splat( result, 2 ) ) ); +} + +static VECTORMATH_FORCE_INLINE __m128 _vmathVfDot4( __m128 vec0, __m128 vec1 ) +{ + __m128 result = _mm_mul_ps(vec0, vec1); + return _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(0,0,0,0)), + _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(1,1,1,1)), + _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(2,2,2,2)), _mm_shuffle_ps(result, result, _MM_SHUFFLE(3,3,3,3))))); +} + +static VECTORMATH_FORCE_INLINE __m128 _vmathVfCross( __m128 vec0, __m128 vec1 ) +{ + __m128 tmp0, tmp1, tmp2, tmp3, result; + tmp0 = _mm_shuffle_ps( vec0, vec0, _MM_SHUFFLE(3,0,2,1) ); + tmp1 = _mm_shuffle_ps( vec1, vec1, _MM_SHUFFLE(3,1,0,2) ); + tmp2 = _mm_shuffle_ps( vec0, vec0, _MM_SHUFFLE(3,1,0,2) ); + tmp3 = _mm_shuffle_ps( vec1, vec1, _MM_SHUFFLE(3,0,2,1) ); + result = vec_mul( tmp0, tmp1 ); + result = vec_nmsub( tmp2, tmp3, result ); + return result; +} +/* +static VECTORMATH_FORCE_INLINE vec_uint4 _vmathVfToHalfFloatsUnpacked(__m128 v) +{ +#if 0 + vec_int4 bexp; + vec_uint4 mant, sign, hfloat; + vec_uint4 notZero, isInf; + const vec_uint4 hfloatInf = (vec_uint4)(0x00007c00u); + const vec_uint4 mergeMant = (vec_uint4)(0x000003ffu); + const vec_uint4 mergeSign = (vec_uint4)(0x00008000u); + + sign = vec_sr((vec_uint4)v, (vec_uint4)16); + mant = vec_sr((vec_uint4)v, (vec_uint4)13); + bexp = vec_and(vec_sr((vec_int4)v, (vec_uint4)23), (vec_int4)0xff); + + notZero = (vec_uint4)vec_cmpgt(bexp, (vec_int4)112); + isInf = (vec_uint4)vec_cmpgt(bexp, (vec_int4)142); + + bexp = _mm_add_ps(bexp, (vec_int4)-112); + bexp = vec_sl(bexp, (vec_uint4)10); + + hfloat = vec_sel((vec_uint4)bexp, mant, mergeMant); + hfloat = vec_sel((vec_uint4)(0), hfloat, notZero); + hfloat = vec_sel(hfloat, hfloatInf, isInf); + hfloat = vec_sel(hfloat, sign, mergeSign); + + return hfloat; +#else + assert(0); + return _mm_setzero_ps(); +#endif +} + +static VECTORMATH_FORCE_INLINE vec_ushort8 _vmath2VfToHalfFloats(__m128 u, __m128 v) +{ +#if 0 + vec_uint4 hfloat_u, hfloat_v; + const vec_uchar16 pack = (vec_uchar16){2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31}; + hfloat_u = _vmathVfToHalfFloatsUnpacked(u); + hfloat_v = _vmathVfToHalfFloatsUnpacked(v); + return (vec_ushort8)vec_perm(hfloat_u, hfloat_v, pack); +#else + assert(0); + return _mm_setzero_si128(); +#endif +} +*/ + +static VECTORMATH_FORCE_INLINE __m128 _vmathVfInsert(__m128 dst, __m128 src, int slot) +{ + SSEFloat s; + s.m128 = src; + SSEFloat d; + d.m128 = dst; + d.f[slot] = s.f[slot]; + return d.m128; +} + +#define _vmathVfSetElement(vec, scalar, slot) ((float *)&(vec))[slot] = scalar + +static VECTORMATH_FORCE_INLINE __m128 _vmathVfSplatScalar(float scalar) +{ + return _mm_set1_ps(scalar); +} + +#endif + +namespace Vectormath { +namespace Aos { + + +#ifdef _VECTORMATH_NO_SCALAR_CAST +VECTORMATH_FORCE_INLINE VecIdx::operator floatInVec() const +{ + return floatInVec(ref, i); +} + +VECTORMATH_FORCE_INLINE float VecIdx::getAsFloat() const +#else +VECTORMATH_FORCE_INLINE VecIdx::operator float() const +#endif +{ + return ((float *)&ref)[i]; +} + +VECTORMATH_FORCE_INLINE float VecIdx::operator =( float scalar ) +{ + _vmathVfSetElement(ref, scalar, i); + return scalar; +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator =( const floatInVec &scalar ) +{ + ref = _vmathVfInsert(ref, scalar.get128(), i); + return scalar; +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator =( const VecIdx& scalar ) +{ + return *this = floatInVec(scalar.ref, scalar.i); +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator *=( float scalar ) +{ + return *this *= floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator *=( const floatInVec &scalar ) +{ + return *this = floatInVec(ref, i) * scalar; +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator /=( float scalar ) +{ + return *this /= floatInVec(scalar); +} + +inline floatInVec VecIdx::operator /=( const floatInVec &scalar ) +{ + return *this = floatInVec(ref, i) / scalar; +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator +=( float scalar ) +{ + return *this += floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator +=( const floatInVec &scalar ) +{ + return *this = floatInVec(ref, i) + scalar; +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator -=( float scalar ) +{ + return *this -= floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator -=( const floatInVec &scalar ) +{ + return *this = floatInVec(ref, i) - scalar; +} + +VECTORMATH_FORCE_INLINE Vector3::Vector3(const Vector3& vec) +{ + set128(vec.get128()); +} + +VECTORMATH_FORCE_INLINE void Vector3::set128(vec_float4 vec) +{ + mVec128 = vec; +} + + +VECTORMATH_FORCE_INLINE Vector3::Vector3( float _x, float _y, float _z ) +{ + mVec128 = _mm_setr_ps(_x, _y, _z, 0.0f); +} + +VECTORMATH_FORCE_INLINE Vector3::Vector3( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z ) +{ + __m128 xz = _mm_unpacklo_ps( _x.get128(), _z.get128() ); + mVec128 = _mm_unpacklo_ps( xz, _y.get128() ); +} + +VECTORMATH_FORCE_INLINE Vector3::Vector3( const Point3 &pnt ) +{ + mVec128 = pnt.get128(); +} + +VECTORMATH_FORCE_INLINE Vector3::Vector3( float scalar ) +{ + mVec128 = floatInVec(scalar).get128(); +} + +VECTORMATH_FORCE_INLINE Vector3::Vector3( const floatInVec &scalar ) +{ + mVec128 = scalar.get128(); +} + +VECTORMATH_FORCE_INLINE Vector3::Vector3( __m128 vf4 ) +{ + mVec128 = vf4; +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::xAxis( ) +{ + return Vector3( _VECTORMATH_UNIT_1000 ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::yAxis( ) +{ + return Vector3( _VECTORMATH_UNIT_0100 ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::zAxis( ) +{ + return Vector3( _VECTORMATH_UNIT_0010 ); +} + +VECTORMATH_FORCE_INLINE const Vector3 lerp( float t, const Vector3 &vec0, const Vector3 &vec1 ) +{ + return lerp( floatInVec(t), vec0, vec1 ); +} + +VECTORMATH_FORCE_INLINE const Vector3 lerp( const floatInVec &t, const Vector3 &vec0, const Vector3 &vec1 ) +{ + return ( vec0 + ( ( vec1 - vec0 ) * t ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 slerp( float t, const Vector3 &unitVec0, const Vector3 &unitVec1 ) +{ + return slerp( floatInVec(t), unitVec0, unitVec1 ); +} + +VECTORMATH_FORCE_INLINE const Vector3 slerp( const floatInVec &t, const Vector3 &unitVec0, const Vector3 &unitVec1 ) +{ + __m128 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; + cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() ); + __m128 selectMask = _mm_cmpgt_ps( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle ); + angle = acosf4( cosAngle ); + tttt = t.get128(); + oneMinusT = _mm_sub_ps( _mm_set1_ps(1.0f), tttt ); + angles = _mm_unpacklo_ps( _mm_set1_ps(1.0f), tttt ); // angles = 1, t, 1, t + angles = _mm_unpacklo_ps( angles, oneMinusT ); // angles = 1, 1-t, t, 1-t + angles = _mm_mul_ps( angles, angle ); + sines = sinf4( angles ); + scales = _mm_div_ps( sines, vec_splat( sines, 0 ) ); + scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); + scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); + return Vector3( vec_madd( unitVec0.get128(), scale0, _mm_mul_ps( unitVec1.get128(), scale1 ) ) ); +} + +VECTORMATH_FORCE_INLINE __m128 Vector3::get128( ) const +{ + return mVec128; +} + +VECTORMATH_FORCE_INLINE void loadXYZ(Point3& vec, const float* fptr) +{ +#ifdef USE_SSE3_LDDQU + vec = Point3( SSEFloat(_mm_lddqu_si128((const __m128i*)((float*)(fptr)))).m128 ); +#else + SSEFloat fl; + fl.f[0] = fptr[0]; + fl.f[1] = fptr[1]; + fl.f[2] = fptr[2]; + fl.f[3] = fptr[3]; + vec = Point3( fl.m128); +#endif //USE_SSE3_LDDQU + +} + + + +VECTORMATH_FORCE_INLINE void loadXYZ(Vector3& vec, const float* fptr) +{ +#ifdef USE_SSE3_LDDQU + vec = Vector3( SSEFloat(_mm_lddqu_si128((const __m128i*)((float*)(fptr)))).m128 ); +#else + SSEFloat fl; + fl.f[0] = fptr[0]; + fl.f[1] = fptr[1]; + fl.f[2] = fptr[2]; + fl.f[3] = fptr[3]; + vec = Vector3( fl.m128); +#endif //USE_SSE3_LDDQU + +} + +VECTORMATH_FORCE_INLINE void storeXYZ( const Vector3 &vec, __m128 * quad ) +{ + __m128 dstVec = *quad; + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; // TODO: Centralize + dstVec = vec_sel(vec.get128(), dstVec, sw); + *quad = dstVec; +} + +VECTORMATH_FORCE_INLINE void storeXYZ(const Point3& vec, float* fptr) +{ + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); +} + +VECTORMATH_FORCE_INLINE void storeXYZ(const Vector3& vec, float* fptr) +{ + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); +} + + +VECTORMATH_FORCE_INLINE void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const __m128 * threeQuads ) +{ + const float *quads = (float *)threeQuads; + vec0 = Vector3( _mm_load_ps(quads) ); + vec1 = Vector3( _mm_loadu_ps(quads + 3) ); + vec2 = Vector3( _mm_loadu_ps(quads + 6) ); + vec3 = Vector3( _mm_loadu_ps(quads + 9) ); +} + +VECTORMATH_FORCE_INLINE void storeXYZArray( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, __m128 * threeQuads ) +{ + __m128 xxxx = _mm_shuffle_ps( vec1.get128(), vec1.get128(), _MM_SHUFFLE(0, 0, 0, 0) ); + __m128 zzzz = _mm_shuffle_ps( vec2.get128(), vec2.get128(), _MM_SHUFFLE(2, 2, 2, 2) ); + VM_ATTRIBUTE_ALIGN16 unsigned int xsw[4] = {0, 0, 0, 0xffffffff}; + VM_ATTRIBUTE_ALIGN16 unsigned int zsw[4] = {0xffffffff, 0, 0, 0}; + threeQuads[0] = vec_sel( vec0.get128(), xxxx, xsw ); + threeQuads[1] = _mm_shuffle_ps( vec1.get128(), vec2.get128(), _MM_SHUFFLE(1, 0, 2, 1) ); + threeQuads[2] = vec_sel( _mm_shuffle_ps( vec3.get128(), vec3.get128(), _MM_SHUFFLE(2, 1, 0, 3) ), zzzz, zsw ); +} +/* +VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, const Vector3 &vec4, const Vector3 &vec5, const Vector3 &vec6, const Vector3 &vec7, vec_ushort8 * threeQuads ) +{ + assert(0); +#if 0 + __m128 xyz0[3]; + __m128 xyz1[3]; + storeXYZArray( vec0, vec1, vec2, vec3, xyz0 ); + storeXYZArray( vec4, vec5, vec6, vec7, xyz1 ); + threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); + threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); + threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); +#endif +} +*/ +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator =( const Vector3 &vec ) +{ + mVec128 = vec.mVec128; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setX( float _x ) +{ + _vmathVfSetElement(mVec128, _x, 0); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setX( const floatInVec &_x ) +{ + mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector3::getX( ) const +{ + return floatInVec( mVec128, 0 ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setY( float _y ) +{ + _vmathVfSetElement(mVec128, _y, 1); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setY( const floatInVec &_y ) +{ + mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector3::getY( ) const +{ + return floatInVec( mVec128, 1 ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setZ( float _z ) +{ + _vmathVfSetElement(mVec128, _z, 2); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setZ( const floatInVec &_z ) +{ + mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector3::getZ( ) const +{ + return floatInVec( mVec128, 2 ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setElem( int idx, float value ) +{ + _vmathVfSetElement(mVec128, value, idx); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setElem( int idx, const floatInVec &value ) +{ + mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector3::getElem( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE VecIdx Vector3::operator []( int idx ) +{ + return VecIdx( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector3::operator []( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator +( const Vector3 &vec ) const +{ + return Vector3( _mm_add_ps( mVec128, vec.mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator -( const Vector3 &vec ) const +{ + return Vector3( _mm_sub_ps( mVec128, vec.mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 Vector3::operator +( const Point3 &pnt ) const +{ + return Point3( _mm_add_ps( mVec128, pnt.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator *( float scalar ) const +{ + return *this * floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator *( const floatInVec &scalar ) const +{ + return Vector3( _mm_mul_ps( mVec128, scalar.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator +=( const Vector3 &vec ) +{ + *this = *this + vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator -=( const Vector3 &vec ) +{ + *this = *this - vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator *=( const floatInVec &scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator /( float scalar ) const +{ + return *this / floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator /( const floatInVec &scalar ) const +{ + return Vector3( _mm_div_ps( mVec128, scalar.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator /=( const floatInVec &scalar ) +{ + *this = *this / scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator -( ) const +{ + //return Vector3(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) ); + + VM_ATTRIBUTE_ALIGN16 static const int array[] = {0x80000000, 0x80000000, 0x80000000, 0x80000000}; + __m128 NEG_MASK = SSEFloat(*(const vec_float4*)array).vf; + return Vector3(_mm_xor_ps(get128(),NEG_MASK)); +} + +VECTORMATH_FORCE_INLINE const Vector3 operator *( float scalar, const Vector3 &vec ) +{ + return floatInVec(scalar) * vec; +} + +VECTORMATH_FORCE_INLINE const Vector3 operator *( const floatInVec &scalar, const Vector3 &vec ) +{ + return vec * scalar; +} + +VECTORMATH_FORCE_INLINE const Vector3 mulPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +{ + return Vector3( _mm_mul_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 divPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +{ + return Vector3( _mm_div_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 recipPerElem( const Vector3 &vec ) +{ + return Vector3( _mm_rcp_ps( vec.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 absPerElem( const Vector3 &vec ) +{ + return Vector3( fabsf4( vec.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 copySignPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +{ + __m128 vmask = toM128(0x7fffffff); + return Vector3( _mm_or_ps( + _mm_and_ps ( vmask, vec0.get128() ), // Value + _mm_andnot_ps( vmask, vec1.get128() ) ) ); // Signs +} + +VECTORMATH_FORCE_INLINE const Vector3 maxPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +{ + return Vector3( _mm_max_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector3 &vec ) +{ + return floatInVec( _mm_max_ps( _mm_max_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 minPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +{ + return Vector3( _mm_min_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector3 &vec ) +{ + return floatInVec( _mm_min_ps( _mm_min_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector3 &vec ) +{ + return floatInVec( _mm_add_ps( _mm_add_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector3 &vec0, const Vector3 &vec1 ) +{ + return floatInVec( _vmathVfDot3( vec0.get128(), vec1.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector3 &vec ) +{ + return floatInVec( _vmathVfDot3( vec.get128(), vec.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec length( const Vector3 &vec ) +{ + return floatInVec( _mm_sqrt_ps(_vmathVfDot3( vec.get128(), vec.get128() )), 0 ); +} + + +VECTORMATH_FORCE_INLINE const Vector3 normalizeApprox( const Vector3 &vec ) +{ + return Vector3( _mm_mul_ps( vec.get128(), _mm_rsqrt_ps( _vmathVfDot3( vec.get128(), vec.get128() ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 normalize( const Vector3 &vec ) +{ + return Vector3( _mm_mul_ps( vec.get128(), newtonrapson_rsqrt4( _vmathVfDot3( vec.get128(), vec.get128() ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 cross( const Vector3 &vec0, const Vector3 &vec1 ) +{ + return Vector3( _vmathVfCross( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, bool select1 ) +{ + return select( vec0, vec1, boolInVec(select1) ); +} + + +VECTORMATH_FORCE_INLINE const Vector4 select(const Vector4& vec0, const Vector4& vec1, const boolInVec& select1) +{ + return Vector4(vec_sel(vec0.get128(), vec1.get128(), select1.get128())); +} + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Vector3 &vec ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = vec.get128(); + printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); +} + +VECTORMATH_FORCE_INLINE void print( const Vector3 &vec, const char * name ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = vec.get128(); + printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); +} + +#endif + +VECTORMATH_FORCE_INLINE Vector4::Vector4( float _x, float _y, float _z, float _w ) +{ + mVec128 = _mm_setr_ps(_x, _y, _z, _w); + } + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z, const floatInVec &_w ) +{ + mVec128 = _mm_unpacklo_ps( + _mm_unpacklo_ps( _x.get128(), _z.get128() ), + _mm_unpacklo_ps( _y.get128(), _w.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const Vector3 &xyz, float _w ) +{ + mVec128 = xyz.get128(); + _vmathVfSetElement(mVec128, _w, 3); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const Vector3 &xyz, const floatInVec &_w ) +{ + mVec128 = xyz.get128(); + mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const Vector3 &vec ) +{ + mVec128 = vec.get128(); + mVec128 = _vmathVfInsert(mVec128, _mm_setzero_ps(), 3); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const Point3 &pnt ) +{ + mVec128 = pnt.get128(); + mVec128 = _vmathVfInsert(mVec128, _mm_set1_ps(1.0f), 3); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const Quat &quat ) +{ + mVec128 = quat.get128(); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( float scalar ) +{ + mVec128 = floatInVec(scalar).get128(); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const floatInVec &scalar ) +{ + mVec128 = scalar.get128(); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( __m128 vf4 ) +{ + mVec128 = vf4; +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::xAxis( ) +{ + return Vector4( _VECTORMATH_UNIT_1000 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::yAxis( ) +{ + return Vector4( _VECTORMATH_UNIT_0100 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::zAxis( ) +{ + return Vector4( _VECTORMATH_UNIT_0010 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::wAxis( ) +{ + return Vector4( _VECTORMATH_UNIT_0001 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 lerp( float t, const Vector4 &vec0, const Vector4 &vec1 ) +{ + return lerp( floatInVec(t), vec0, vec1 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 lerp( const floatInVec &t, const Vector4 &vec0, const Vector4 &vec1 ) +{ + return ( vec0 + ( ( vec1 - vec0 ) * t ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 slerp( float t, const Vector4 &unitVec0, const Vector4 &unitVec1 ) +{ + return slerp( floatInVec(t), unitVec0, unitVec1 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 slerp( const floatInVec &t, const Vector4 &unitVec0, const Vector4 &unitVec1 ) +{ + __m128 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; + cosAngle = _vmathVfDot4( unitVec0.get128(), unitVec1.get128() ); + __m128 selectMask = _mm_cmpgt_ps( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle ); + angle = acosf4( cosAngle ); + tttt = t.get128(); + oneMinusT = _mm_sub_ps( _mm_set1_ps(1.0f), tttt ); + angles = _mm_unpacklo_ps( _mm_set1_ps(1.0f), tttt ); // angles = 1, t, 1, t + angles = _mm_unpacklo_ps( angles, oneMinusT ); // angles = 1, 1-t, t, 1-t + angles = _mm_mul_ps( angles, angle ); + sines = sinf4( angles ); + scales = _mm_div_ps( sines, vec_splat( sines, 0 ) ); + scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); + scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); + return Vector4( vec_madd( unitVec0.get128(), scale0, _mm_mul_ps( unitVec1.get128(), scale1 ) ) ); +} + +VECTORMATH_FORCE_INLINE __m128 Vector4::get128( ) const +{ + return mVec128; +} +/* +VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector4 &vec0, const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3, vec_ushort8 * twoQuads ) +{ + twoQuads[0] = _vmath2VfToHalfFloats(vec0.get128(), vec1.get128()); + twoQuads[1] = _vmath2VfToHalfFloats(vec2.get128(), vec3.get128()); +} +*/ +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator =( const Vector4 &vec ) +{ + mVec128 = vec.mVec128; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setXYZ( const Vector3 &vec ) +{ + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; + mVec128 = vec_sel( vec.get128(), mVec128, sw ); + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector4::getXYZ( ) const +{ + return Vector3( mVec128 ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setX( float _x ) +{ + _vmathVfSetElement(mVec128, _x, 0); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setX( const floatInVec &_x ) +{ + mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getX( ) const +{ + return floatInVec( mVec128, 0 ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setY( float _y ) +{ + _vmathVfSetElement(mVec128, _y, 1); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setY( const floatInVec &_y ) +{ + mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getY( ) const +{ + return floatInVec( mVec128, 1 ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setZ( float _z ) +{ + _vmathVfSetElement(mVec128, _z, 2); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setZ( const floatInVec &_z ) +{ + mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getZ( ) const +{ + return floatInVec( mVec128, 2 ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setW( float _w ) +{ + _vmathVfSetElement(mVec128, _w, 3); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setW( const floatInVec &_w ) +{ + mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getW( ) const +{ + return floatInVec( mVec128, 3 ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setElem( int idx, float value ) +{ + _vmathVfSetElement(mVec128, value, idx); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setElem( int idx, const floatInVec &value ) +{ + mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getElem( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE VecIdx Vector4::operator []( int idx ) +{ + return VecIdx( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector4::operator []( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator +( const Vector4 &vec ) const +{ + return Vector4( _mm_add_ps( mVec128, vec.mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator -( const Vector4 &vec ) const +{ + return Vector4( _mm_sub_ps( mVec128, vec.mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator *( float scalar ) const +{ + return *this * floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator *( const floatInVec &scalar ) const +{ + return Vector4( _mm_mul_ps( mVec128, scalar.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator +=( const Vector4 &vec ) +{ + *this = *this + vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator -=( const Vector4 &vec ) +{ + *this = *this - vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator *=( const floatInVec &scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator /( float scalar ) const +{ + return *this / floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator /( const floatInVec &scalar ) const +{ + return Vector4( _mm_div_ps( mVec128, scalar.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator /=( const floatInVec &scalar ) +{ + *this = *this / scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator -( ) const +{ + return Vector4(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 operator *( float scalar, const Vector4 &vec ) +{ + return floatInVec(scalar) * vec; +} + +VECTORMATH_FORCE_INLINE const Vector4 operator *( const floatInVec &scalar, const Vector4 &vec ) +{ + return vec * scalar; +} + +VECTORMATH_FORCE_INLINE const Vector4 mulPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +{ + return Vector4( _mm_mul_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 divPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +{ + return Vector4( _mm_div_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 recipPerElem( const Vector4 &vec ) +{ + return Vector4( _mm_rcp_ps( vec.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 absPerElem( const Vector4 &vec ) +{ + return Vector4( fabsf4( vec.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 copySignPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +{ + __m128 vmask = toM128(0x7fffffff); + return Vector4( _mm_or_ps( + _mm_and_ps ( vmask, vec0.get128() ), // Value + _mm_andnot_ps( vmask, vec1.get128() ) ) ); // Signs +} + +VECTORMATH_FORCE_INLINE const Vector4 maxPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +{ + return Vector4( _mm_max_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector4 &vec ) +{ + return floatInVec( _mm_max_ps( + _mm_max_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), + _mm_max_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 minPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +{ + return Vector4( _mm_min_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector4 &vec ) +{ + return floatInVec( _mm_min_ps( + _mm_min_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), + _mm_min_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector4 &vec ) +{ + return floatInVec( _mm_add_ps( + _mm_add_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), + _mm_add_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector4 &vec0, const Vector4 &vec1 ) +{ + return floatInVec( _vmathVfDot4( vec0.get128(), vec1.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector4 &vec ) +{ + return floatInVec( _vmathVfDot4( vec.get128(), vec.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec length( const Vector4 &vec ) +{ + return floatInVec( _mm_sqrt_ps(_vmathVfDot4( vec.get128(), vec.get128() )), 0 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 normalizeApprox( const Vector4 &vec ) +{ + return Vector4( _mm_mul_ps( vec.get128(), _mm_rsqrt_ps( _vmathVfDot4( vec.get128(), vec.get128() ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 normalize( const Vector4 &vec ) +{ + return Vector4( _mm_mul_ps( vec.get128(), newtonrapson_rsqrt4( _vmathVfDot4( vec.get128(), vec.get128() ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, bool select1 ) +{ + return select( vec0, vec1, boolInVec(select1) ); +} + + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Vector4 &vec ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = vec.get128(); + printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); +} + +VECTORMATH_FORCE_INLINE void print( const Vector4 &vec, const char * name ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = vec.get128(); + printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); +} + +#endif + +VECTORMATH_FORCE_INLINE Point3::Point3( float _x, float _y, float _z ) +{ + mVec128 = _mm_setr_ps(_x, _y, _z, 0.0f); +} + +VECTORMATH_FORCE_INLINE Point3::Point3( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z ) +{ + mVec128 = _mm_unpacklo_ps( _mm_unpacklo_ps( _x.get128(), _z.get128() ), _y.get128() ); +} + +VECTORMATH_FORCE_INLINE Point3::Point3( const Vector3 &vec ) +{ + mVec128 = vec.get128(); +} + +VECTORMATH_FORCE_INLINE Point3::Point3( float scalar ) +{ + mVec128 = floatInVec(scalar).get128(); +} + +VECTORMATH_FORCE_INLINE Point3::Point3( const floatInVec &scalar ) +{ + mVec128 = scalar.get128(); +} + +VECTORMATH_FORCE_INLINE Point3::Point3( __m128 vf4 ) +{ + mVec128 = vf4; +} + +VECTORMATH_FORCE_INLINE const Point3 lerp( float t, const Point3 &pnt0, const Point3 &pnt1 ) +{ + return lerp( floatInVec(t), pnt0, pnt1 ); +} + +VECTORMATH_FORCE_INLINE const Point3 lerp( const floatInVec &t, const Point3 &pnt0, const Point3 &pnt1 ) +{ + return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); +} + +VECTORMATH_FORCE_INLINE __m128 Point3::get128( ) const +{ + return mVec128; +} + +VECTORMATH_FORCE_INLINE void storeXYZ( const Point3 &pnt, __m128 * quad ) +{ + __m128 dstVec = *quad; + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; // TODO: Centralize + dstVec = vec_sel(pnt.get128(), dstVec, sw); + *quad = dstVec; +} + +VECTORMATH_FORCE_INLINE void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const __m128 * threeQuads ) +{ + const float *quads = (float *)threeQuads; + pnt0 = Point3( _mm_load_ps(quads) ); + pnt1 = Point3( _mm_loadu_ps(quads + 3) ); + pnt2 = Point3( _mm_loadu_ps(quads + 6) ); + pnt3 = Point3( _mm_loadu_ps(quads + 9) ); +} + +VECTORMATH_FORCE_INLINE void storeXYZArray( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, __m128 * threeQuads ) +{ + __m128 xxxx = _mm_shuffle_ps( pnt1.get128(), pnt1.get128(), _MM_SHUFFLE(0, 0, 0, 0) ); + __m128 zzzz = _mm_shuffle_ps( pnt2.get128(), pnt2.get128(), _MM_SHUFFLE(2, 2, 2, 2) ); + VM_ATTRIBUTE_ALIGN16 unsigned int xsw[4] = {0, 0, 0, 0xffffffff}; + VM_ATTRIBUTE_ALIGN16 unsigned int zsw[4] = {0xffffffff, 0, 0, 0}; + threeQuads[0] = vec_sel( pnt0.get128(), xxxx, xsw ); + threeQuads[1] = _mm_shuffle_ps( pnt1.get128(), pnt2.get128(), _MM_SHUFFLE(1, 0, 2, 1) ); + threeQuads[2] = vec_sel( _mm_shuffle_ps( pnt3.get128(), pnt3.get128(), _MM_SHUFFLE(2, 1, 0, 3) ), zzzz, zsw ); +} +/* +VECTORMATH_FORCE_INLINE void storeHalfFloats( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, const Point3 &pnt4, const Point3 &pnt5, const Point3 &pnt6, const Point3 &pnt7, vec_ushort8 * threeQuads ) +{ +#if 0 + __m128 xyz0[3]; + __m128 xyz1[3]; + storeXYZArray( pnt0, pnt1, pnt2, pnt3, xyz0 ); + storeXYZArray( pnt4, pnt5, pnt6, pnt7, xyz1 ); + threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); + threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); + threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); +#else + assert(0); +#endif +} +*/ +VECTORMATH_FORCE_INLINE Point3 & Point3::operator =( const Point3 &pnt ) +{ + mVec128 = pnt.mVec128; + return *this; +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setX( float _x ) +{ + _vmathVfSetElement(mVec128, _x, 0); + return *this; +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setX( const floatInVec &_x ) +{ + mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Point3::getX( ) const +{ + return floatInVec( mVec128, 0 ); +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setY( float _y ) +{ + _vmathVfSetElement(mVec128, _y, 1); + return *this; +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setY( const floatInVec &_y ) +{ + mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Point3::getY( ) const +{ + return floatInVec( mVec128, 1 ); +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setZ( float _z ) +{ + _vmathVfSetElement(mVec128, _z, 2); + return *this; +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setZ( const floatInVec &_z ) +{ + mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Point3::getZ( ) const +{ + return floatInVec( mVec128, 2 ); +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setElem( int idx, float value ) +{ + _vmathVfSetElement(mVec128, value, idx); + return *this; +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setElem( int idx, const floatInVec &value ) +{ + mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Point3::getElem( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE VecIdx Point3::operator []( int idx ) +{ + return VecIdx( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const floatInVec Point3::operator []( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Point3::operator -( const Point3 &pnt ) const +{ + return Vector3( _mm_sub_ps( mVec128, pnt.mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 Point3::operator +( const Vector3 &vec ) const +{ + return Point3( _mm_add_ps( mVec128, vec.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 Point3::operator -( const Vector3 &vec ) const +{ + return Point3( _mm_sub_ps( mVec128, vec.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::operator +=( const Vector3 &vec ) +{ + *this = *this + vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::operator -=( const Vector3 &vec ) +{ + *this = *this - vec; + return *this; +} + +VECTORMATH_FORCE_INLINE const Point3 mulPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +{ + return Point3( _mm_mul_ps( pnt0.get128(), pnt1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 divPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +{ + return Point3( _mm_div_ps( pnt0.get128(), pnt1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 recipPerElem( const Point3 &pnt ) +{ + return Point3( _mm_rcp_ps( pnt.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 absPerElem( const Point3 &pnt ) +{ + return Point3( fabsf4( pnt.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 copySignPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +{ + __m128 vmask = toM128(0x7fffffff); + return Point3( _mm_or_ps( + _mm_and_ps ( vmask, pnt0.get128() ), // Value + _mm_andnot_ps( vmask, pnt1.get128() ) ) ); // Signs +} + +VECTORMATH_FORCE_INLINE const Point3 maxPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +{ + return Point3( _mm_max_ps( pnt0.get128(), pnt1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Point3 &pnt ) +{ + return floatInVec( _mm_max_ps( _mm_max_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 minPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +{ + return Point3( _mm_min_ps( pnt0.get128(), pnt1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec minElem( const Point3 &pnt ) +{ + return floatInVec( _mm_min_ps( _mm_min_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec sum( const Point3 &pnt ) +{ + return floatInVec( _mm_add_ps( _mm_add_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, float scaleVal ) +{ + return scale( pnt, floatInVec( scaleVal ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const floatInVec &scaleVal ) +{ + return mulPerElem( pnt, Point3( scaleVal ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const Vector3 &scaleVec ) +{ + return mulPerElem( pnt, Point3( scaleVec ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec projection( const Point3 &pnt, const Vector3 &unitVec ) +{ + return floatInVec( _vmathVfDot3( pnt.get128(), unitVec.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec distSqrFromOrigin( const Point3 &pnt ) +{ + return lengthSqr( Vector3( pnt ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec distFromOrigin( const Point3 &pnt ) +{ + return length( Vector3( pnt ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec distSqr( const Point3 &pnt0, const Point3 &pnt1 ) +{ + return lengthSqr( ( pnt1 - pnt0 ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec dist( const Point3 &pnt0, const Point3 &pnt1 ) +{ + return length( ( pnt1 - pnt0 ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, bool select1 ) +{ + return select( pnt0, pnt1, boolInVec(select1) ); +} + +VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, const boolInVec &select1 ) +{ + return Point3( vec_sel( pnt0.get128(), pnt1.get128(), select1.get128() ) ); +} + + + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Point3 &pnt ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = pnt.get128(); + printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); +} + +VECTORMATH_FORCE_INLINE void print( const Point3 &pnt, const char * name ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = pnt.get128(); + printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); +} + +#endif + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/Extras/PhysicsEffects/include/vecmath/sse/vecidx_aos.h b/Extras/PhysicsEffects/include/vecmath/sse/vecidx_aos.h new file mode 100644 index 000000000..32e837a52 --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/sse/vecidx_aos.h @@ -0,0 +1,80 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _VECTORMATH_VECIDX_AOS_H +#define _VECTORMATH_VECIDX_AOS_H + + +#include "floatInVec.h" + +namespace Vectormath { +namespace Aos { + +//----------------------------------------------------------------------------- +// VecIdx +// Used in setting elements of Vector3, Vector4, Point3, or Quat with the +// subscripting operator. +// + +VM_ATTRIBUTE_ALIGNED_CLASS16 (class) VecIdx +{ +private: + __m128 &ref; + int i; +public: + inline VecIdx( __m128& vec, int idx ): ref(vec) { i = idx; } + + // implicitly casts to float unless _VECTORMATH_NO_SCALAR_CAST defined + // in which case, implicitly casts to floatInVec, and one must call + // getAsFloat to convert to float. + // +#ifdef _VECTORMATH_NO_SCALAR_CAST + inline operator floatInVec() const; + inline float getAsFloat() const; +#else + inline operator float() const; +#endif + + inline float operator =( float scalar ); + inline floatInVec operator =( const floatInVec &scalar ); + inline floatInVec operator =( const VecIdx& scalar ); + inline floatInVec operator *=( float scalar ); + inline floatInVec operator *=( const floatInVec &scalar ); + inline floatInVec operator /=( float scalar ); + inline floatInVec operator /=( const floatInVec &scalar ); + inline floatInVec operator +=( float scalar ); + inline floatInVec operator +=( const floatInVec &scalar ); + inline floatInVec operator -=( float scalar ); + inline floatInVec operator -=( const floatInVec &scalar ); +}; + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/Extras/PhysicsEffects/include/vecmath/sse/vectormath_aos.h b/Extras/PhysicsEffects/include/vecmath/sse/vectormath_aos.h new file mode 100644 index 000000000..b802810df --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/sse/vectormath_aos.h @@ -0,0 +1,2547 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef _VECTORMATH_AOS_CPP_SSE_H +#define _VECTORMATH_AOS_CPP_SSE_H + +#include +#include +#include +#include + +#define Vector3Ref Vector3& +#define QuatRef Quat& +#define Matrix3Ref Matrix3& + +#if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) + #define USE_SSE3_LDDQU + + #define VM_ATTRIBUTE_ALIGNED_CLASS16(a) __declspec(align(16)) a + #define VM_ATTRIBUTE_ALIGN16 __declspec(align(16)) + #define VECTORMATH_FORCE_INLINE __forceinline +#else + #define VM_ATTRIBUTE_ALIGNED_CLASS16(a) a __attribute__ ((aligned (16))) + #define VM_ATTRIBUTE_ALIGN16 __attribute__ ((aligned (16))) + #define VECTORMATH_FORCE_INLINE inline + #ifdef __SSE3__ + #define USE_SSE3_LDDQU + #endif //__SSE3__ +#endif//_WIN32 + + +#ifdef USE_SSE3_LDDQU +#include //_mm_lddqu_si128 +#endif //USE_SSE3_LDDQU + + +// TODO: Tidy +typedef __m128 vec_float4; +typedef __m128 vec_uint4; +typedef __m128 vec_int4; +typedef __m128i vec_uchar16; +typedef __m128i vec_ushort8; + +#define vec_splat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e)) + +#define _mm_ror_ps(vec,i) \ + (((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(i+3)%4,(unsigned char)(i+2)%4,(unsigned char)(i+1)%4,(unsigned char)(i+0)%4))) : (vec)) +#define _mm_rol_ps(vec,i) \ + (((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(7-i)%4,(unsigned char)(6-i)%4,(unsigned char)(5-i)%4,(unsigned char)(4-i)%4))) : (vec)) + +#define vec_sld(vec,vec2,x) _mm_ror_ps(vec, ((x)/4)) + +#define _mm_abs_ps(vec) _mm_andnot_ps(_MASKSIGN_,vec) +#define _mm_neg_ps(vec) _mm_xor_ps(_MASKSIGN_,vec) + +#define vec_madd(a, b, c) _mm_add_ps(c, _mm_mul_ps(a, b) ) + +union SSEFloat +{ + __m128i vi; + __m128 m128; + __m128 vf; + unsigned int ui[4]; + unsigned short s[8]; + float f[4]; + SSEFloat(__m128 v) : m128(v) {} + SSEFloat(__m128i v) : vi(v) {} + SSEFloat() {}//uninitialized +}; + +static VECTORMATH_FORCE_INLINE __m128 vec_sel(__m128 a, __m128 b, __m128 mask) +{ + return _mm_or_ps(_mm_and_ps(mask, b), _mm_andnot_ps(mask, a)); +} +static VECTORMATH_FORCE_INLINE __m128 vec_sel(__m128 a, __m128 b, const unsigned int *_mask) +{ + return vec_sel(a, b, _mm_load_ps((float *)_mask)); +} +static VECTORMATH_FORCE_INLINE __m128 vec_sel(__m128 a, __m128 b, unsigned int _mask) +{ + return vec_sel(a, b, _mm_set1_ps(*(float *)&_mask)); +} + +static VECTORMATH_FORCE_INLINE __m128 toM128(unsigned int x) +{ + return _mm_set1_ps( *(float *)&x ); +} + +static VECTORMATH_FORCE_INLINE __m128 fabsf4(__m128 x) +{ + return _mm_and_ps( x, toM128( 0x7fffffff ) ); +} +/* +union SSE64 +{ + __m128 m128; + struct + { + __m64 m01; + __m64 m23; + } m64; +}; + +static VECTORMATH_FORCE_INLINE __m128 vec_cts(__m128 x, int a) +{ + assert(a == 0); // Only 2^0 supported + (void)a; + SSE64 sse64; + sse64.m64.m01 = _mm_cvttps_pi32(x); + sse64.m64.m23 = _mm_cvttps_pi32(_mm_ror_ps(x,2)); + _mm_empty(); + return sse64.m128; +} + +static VECTORMATH_FORCE_INLINE __m128 vec_ctf(__m128 x, int a) +{ + assert(a == 0); // Only 2^0 supported + (void)a; + SSE64 sse64; + sse64.m128 = x; + __m128 result =_mm_movelh_ps( + _mm_cvt_pi2ps(_mm_setzero_ps(), sse64.m64.m01), + _mm_cvt_pi2ps(_mm_setzero_ps(), sse64.m64.m23)); + _mm_empty(); + return result; +} +*/ +static VECTORMATH_FORCE_INLINE __m128 vec_cts(__m128 x, int a) +{ + assert(a == 0); // Only 2^0 supported + (void)a; + __m128i result = _mm_cvtps_epi32(x); + return (__m128 &)result; +} + +static VECTORMATH_FORCE_INLINE __m128 vec_ctf(__m128 x, int a) +{ + assert(a == 0); // Only 2^0 supported + (void)a; + return _mm_cvtepi32_ps((__m128i &)x); +} + +#define vec_nmsub(a,b,c) _mm_sub_ps( c, _mm_mul_ps( a, b ) ) +#define vec_sub(a,b) _mm_sub_ps( a, b ) +#define vec_add(a,b) _mm_add_ps( a, b ) +#define vec_mul(a,b) _mm_mul_ps( a, b ) +#define vec_xor(a,b) _mm_xor_ps( a, b ) +#define vec_and(a,b) _mm_and_ps( a, b ) +#define vec_cmpeq(a,b) _mm_cmpeq_ps( a, b ) +#define vec_cmpgt(a,b) _mm_cmpgt_ps( a, b ) + +#define vec_mergeh(a,b) _mm_unpacklo_ps( a, b ) +#define vec_mergel(a,b) _mm_unpackhi_ps( a, b ) + +#define vec_andc(a,b) _mm_andnot_ps( b, a ) + +#define sqrtf4(x) _mm_sqrt_ps( x ) +#define rsqrtf4(x) _mm_rsqrt_ps( x ) +#define recipf4(x) _mm_rcp_ps( x ) +#define negatef4(x) _mm_sub_ps( _mm_setzero_ps(), x ) + +static VECTORMATH_FORCE_INLINE __m128 newtonrapson_rsqrt4( const __m128 v ) +{ +#define _half4 _mm_setr_ps(.5f,.5f,.5f,.5f) +#define _three _mm_setr_ps(3.f,3.f,3.f,3.f) +const __m128 approx = _mm_rsqrt_ps( v ); +const __m128 muls = _mm_mul_ps(_mm_mul_ps(v, approx), approx); +return _mm_mul_ps(_mm_mul_ps(_half4, approx), _mm_sub_ps(_three, muls) ); +} + +static VECTORMATH_FORCE_INLINE __m128 acosf4(__m128 x) +{ + __m128 xabs = fabsf4(x); + __m128 select = _mm_cmplt_ps( x, _mm_setzero_ps() ); + __m128 t1 = sqrtf4(vec_sub(_mm_set1_ps(1.0f), xabs)); + + /* Instruction counts can be reduced if the polynomial was + * computed entirely from nested (dependent) fma's. However, + * to reduce the number of pipeline stalls, the polygon is evaluated + * in two halves (hi amd lo). + */ + __m128 xabs2 = _mm_mul_ps(xabs, xabs); + __m128 xabs4 = _mm_mul_ps(xabs2, xabs2); + __m128 hi = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0012624911f), + xabs, _mm_set1_ps(0.0066700901f)), + xabs, _mm_set1_ps(-0.0170881256f)), + xabs, _mm_set1_ps( 0.0308918810f)); + __m128 lo = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0501743046f), + xabs, _mm_set1_ps(0.0889789874f)), + xabs, _mm_set1_ps(-0.2145988016f)), + xabs, _mm_set1_ps( 1.5707963050f)); + + __m128 result = vec_madd(hi, xabs4, lo); + + // Adjust the result if x is negactive. + return vec_sel( + vec_mul(t1, result), // Positive + vec_nmsub(t1, result, _mm_set1_ps(3.1415926535898f)), // Negative + select); +} + +static VECTORMATH_FORCE_INLINE __m128 sinf4(vec_float4 x) +{ + +// +// Common constants used to evaluate sinf4/cosf4/tanf4 +// +#define _SINCOS_CC0 -0.0013602249f +#define _SINCOS_CC1 0.0416566950f +#define _SINCOS_CC2 -0.4999990225f +#define _SINCOS_SC0 -0.0001950727f +#define _SINCOS_SC1 0.0083320758f +#define _SINCOS_SC2 -0.1666665247f + +#define _SINCOS_KC1 1.57079625129f +#define _SINCOS_KC2 7.54978995489e-8f + + vec_float4 xl,xl2,xl3,res; + + // Range reduction using : xl = angle * TwoOverPi; + // + xl = vec_mul(x, _mm_set1_ps(0.63661977236f)); + + // Find the quadrant the angle falls in + // using: q = (int) (ceil(abs(xl))*sign(xl)) + // + vec_int4 q = vec_cts(xl,0); + + // Compute an offset based on the quadrant that the angle falls in + // + vec_int4 offset = _mm_and_ps(q,toM128(0x3)); + + // Remainder in range [-pi/4..pi/4] + // + vec_float4 qf = vec_ctf(q,0); + xl = vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC2),vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC1),x)); + + // Compute x^2 and x^3 + // + xl2 = vec_mul(xl,xl); + xl3 = vec_mul(xl2,xl); + + // Compute both the sin and cos of the angles + // using a polynomial expression: + // cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and + // sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2) + // + + vec_float4 cx = + vec_madd( + vec_madd( + vec_madd(_mm_set1_ps(_SINCOS_CC0),xl2,_mm_set1_ps(_SINCOS_CC1)),xl2,_mm_set1_ps(_SINCOS_CC2)),xl2,_mm_set1_ps(1.0f)); + vec_float4 sx = + vec_madd( + vec_madd( + vec_madd(_mm_set1_ps(_SINCOS_SC0),xl2,_mm_set1_ps(_SINCOS_SC1)),xl2,_mm_set1_ps(_SINCOS_SC2)),xl3,xl); + + // Use the cosine when the offset is odd and the sin + // when the offset is even + // + res = vec_sel(cx,sx,vec_cmpeq(vec_and(offset, + toM128(0x1)), + _mm_setzero_ps())); + + // Flip the sign of the result when (offset mod 4) = 1 or 2 + // + return vec_sel( + vec_xor(toM128(0x80000000U), res), // Negative + res, // Positive + vec_cmpeq(vec_and(offset,toM128(0x2)),_mm_setzero_ps())); +} + +static VECTORMATH_FORCE_INLINE void sincosf4(vec_float4 x, vec_float4* s, vec_float4* c) +{ + vec_float4 xl,xl2,xl3; + vec_int4 offsetSin, offsetCos; + + // Range reduction using : xl = angle * TwoOverPi; + // + xl = vec_mul(x, _mm_set1_ps(0.63661977236f)); + + // Find the quadrant the angle falls in + // using: q = (int) (ceil(abs(xl))*sign(xl)) + // + //vec_int4 q = vec_cts(vec_add(xl,vec_sel(_mm_set1_ps(0.5f),xl,(0x80000000))),0); + vec_int4 q = vec_cts(xl,0); + + // Compute the offset based on the quadrant that the angle falls in. + // Add 1 to the offset for the cosine. + // + offsetSin = vec_and(q,toM128((int)0x3)); + __m128i temp = _mm_add_epi32(_mm_set1_epi32(1),(__m128i &)offsetSin); + offsetCos = (__m128 &)temp; + + // Remainder in range [-pi/4..pi/4] + // + vec_float4 qf = vec_ctf(q,0); + xl = vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC2),vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC1),x)); + + // Compute x^2 and x^3 + // + xl2 = vec_mul(xl,xl); + xl3 = vec_mul(xl2,xl); + + // Compute both the sin and cos of the angles + // using a polynomial expression: + // cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and + // sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2) + // + vec_float4 cx = + vec_madd( + vec_madd( + vec_madd(_mm_set1_ps(_SINCOS_CC0),xl2,_mm_set1_ps(_SINCOS_CC1)),xl2,_mm_set1_ps(_SINCOS_CC2)),xl2,_mm_set1_ps(1.0f)); + vec_float4 sx = + vec_madd( + vec_madd( + vec_madd(_mm_set1_ps(_SINCOS_SC0),xl2,_mm_set1_ps(_SINCOS_SC1)),xl2,_mm_set1_ps(_SINCOS_SC2)),xl3,xl); + + // Use the cosine when the offset is odd and the sin + // when the offset is even + // + vec_uint4 sinMask = (vec_uint4)vec_cmpeq(vec_and(offsetSin,toM128(0x1)),_mm_setzero_ps()); + vec_uint4 cosMask = (vec_uint4)vec_cmpeq(vec_and(offsetCos,toM128(0x1)),_mm_setzero_ps()); + *s = vec_sel(cx,sx,sinMask); + *c = vec_sel(cx,sx,cosMask); + + // Flip the sign of the result when (offset mod 4) = 1 or 2 + // + sinMask = vec_cmpeq(vec_and(offsetSin,toM128(0x2)),_mm_setzero_ps()); + cosMask = vec_cmpeq(vec_and(offsetCos,toM128(0x2)),_mm_setzero_ps()); + + *s = vec_sel((vec_float4)vec_xor(toM128(0x80000000),(vec_uint4)*s),*s,sinMask); + *c = vec_sel((vec_float4)vec_xor(toM128(0x80000000),(vec_uint4)*c),*c,cosMask); +} + +#include "vecidx_aos.h" +#include "floatInVec.h" +#include "boolInVec.h" + +#ifdef _VECTORMATH_DEBUG +#include +#endif +namespace Vectormath { + +namespace Aos { + +//----------------------------------------------------------------------------- +// Forward Declarations +// + +class Vector3; +class Vector4; +class Point3; +class Quat; +class Matrix3; +class Matrix4; +class Transform3; + +// A 3-D vector in array-of-structures format +// +class Vector3 +{ + __m128 mVec128; + + VECTORMATH_FORCE_INLINE void set128(vec_float4 vec); + + VECTORMATH_FORCE_INLINE vec_float4& get128Ref(); + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Vector3( ) { }; + + // Default copy constructor + // + VECTORMATH_FORCE_INLINE Vector3(const Vector3& vec); + + // Construct a 3-D vector from x, y, and z elements + // + VECTORMATH_FORCE_INLINE Vector3( float x, float y, float z ); + + // Construct a 3-D vector from x, y, and z elements (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3( const floatInVec &x, const floatInVec &y, const floatInVec &z ); + + // Copy elements from a 3-D point into a 3-D vector + // + explicit VECTORMATH_FORCE_INLINE Vector3( const Point3 &pnt ); + + // Set all elements of a 3-D vector to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Vector3( float scalar ); + + // Set all elements of a 3-D vector to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Vector3( const floatInVec &scalar ); + + // Set vector float data in a 3-D vector + // + explicit VECTORMATH_FORCE_INLINE Vector3( __m128 vf4 ); + + // Get vector float data from a 3-D vector + // + VECTORMATH_FORCE_INLINE __m128 get128( ) const; + + // Assign one 3-D vector to another + // + VECTORMATH_FORCE_INLINE Vector3 & operator =( const Vector3 &vec ); + + // Set the x element of a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 & setX( float x ); + + // Set the y element of a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 & setY( float y ); + + // Set the z element of a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 & setZ( float z ); + + // Set the x element of a 3-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 & setX( const floatInVec &x ); + + // Set the y element of a 3-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 & setY( const floatInVec &y ); + + // Set the z element of a 3-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 & setZ( const floatInVec &z ); + + // Get the x element of a 3-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getX( ) const; + + // Get the y element of a 3-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getY( ) const; + + // Get the z element of a 3-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const; + + // Set an x, y, or z element of a 3-D vector by index + // + VECTORMATH_FORCE_INLINE Vector3 & setElem( int idx, float value ); + + // Set an x, y, or z element of a 3-D vector by index (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 & setElem( int idx, const floatInVec &value ); + + // Get an x, y, or z element of a 3-D vector by index + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + VECTORMATH_FORCE_INLINE VecIdx operator []( int idx ); + + // Subscripting operator to get an element + // + VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const; + + // Add two 3-D vectors + // + VECTORMATH_FORCE_INLINE const Vector3 operator +( const Vector3 &vec ) const; + + // Subtract a 3-D vector from another 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 operator -( const Vector3 &vec ) const; + + // Add a 3-D vector to a 3-D point + // + VECTORMATH_FORCE_INLINE const Point3 operator +( const Point3 &pnt ) const; + + // Multiply a 3-D vector by a scalar + // + VECTORMATH_FORCE_INLINE const Vector3 operator *( float scalar ) const; + + // Divide a 3-D vector by a scalar + // + VECTORMATH_FORCE_INLINE const Vector3 operator /( float scalar ) const; + + // Multiply a 3-D vector by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Vector3 operator *( const floatInVec &scalar ) const; + + // Divide a 3-D vector by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Vector3 operator /( const floatInVec &scalar ) const; + + // Perform compound assignment and addition with a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 & operator +=( const Vector3 &vec ); + + // Perform compound assignment and subtraction by a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 & operator -=( const Vector3 &vec ); + + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Vector3 & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + VECTORMATH_FORCE_INLINE Vector3 & operator /=( float scalar ); + + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 & operator *=( const floatInVec &scalar ); + + // Perform compound assignment and division by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 & operator /=( const floatInVec &scalar ); + + // Negate all elements of a 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 operator -( ) const; + + // Construct x axis + // + static VECTORMATH_FORCE_INLINE const Vector3 xAxis( ); + + // Construct y axis + // + static VECTORMATH_FORCE_INLINE const Vector3 yAxis( ); + + // Construct z axis + // + static VECTORMATH_FORCE_INLINE const Vector3 zAxis( ); + +}; + +// Multiply a 3-D vector by a scalar +// +VECTORMATH_FORCE_INLINE const Vector3 operator *( float scalar, const Vector3 &vec ); + +// Multiply a 3-D vector by a scalar (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Vector3 operator *( const floatInVec &scalar, const Vector3 &vec ); + +// Multiply two 3-D vectors per element +// +VECTORMATH_FORCE_INLINE const Vector3 mulPerElem( const Vector3 &vec0, const Vector3 &vec1 ); + +// Divide two 3-D vectors per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +VECTORMATH_FORCE_INLINE const Vector3 divPerElem( const Vector3 &vec0, const Vector3 &vec1 ); + +// Compute the reciprocal of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +VECTORMATH_FORCE_INLINE const Vector3 recipPerElem( const Vector3 &vec ); + +// Compute the absolute value of a 3-D vector per element +// +VECTORMATH_FORCE_INLINE const Vector3 absPerElem( const Vector3 &vec ); + +// Copy sign from one 3-D vector to another, per element +// +VECTORMATH_FORCE_INLINE const Vector3 copySignPerElem( const Vector3 &vec0, const Vector3 &vec1 ); + +// Maximum of two 3-D vectors per element +// +VECTORMATH_FORCE_INLINE const Vector3 maxPerElem( const Vector3 &vec0, const Vector3 &vec1 ); + +// Minimum of two 3-D vectors per element +// +VECTORMATH_FORCE_INLINE const Vector3 minPerElem( const Vector3 &vec0, const Vector3 &vec1 ); + +// Maximum element of a 3-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector3 &vec ); + +// Minimum element of a 3-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector3 &vec ); + +// Compute the sum of all elements of a 3-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector3 &vec ); + +// Compute the dot product of two 3-D vectors +// +VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector3 &vec0, const Vector3 &vec1 ); + +// Compute the square of the length of a 3-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector3 &vec ); + +// Compute the length of a 3-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec length( const Vector3 &vec ); + +// Normalize a 3-D vector +// NOTE: +// The result is unpredictable when all elements of vec are at or near zero. +// +VECTORMATH_FORCE_INLINE const Vector3 normalize( const Vector3 &vec ); + +// Compute cross product of two 3-D vectors +// +VECTORMATH_FORCE_INLINE const Vector3 cross( const Vector3 &vec0, const Vector3 &vec1 ); + +// Outer product of two 3-D vectors +// +VECTORMATH_FORCE_INLINE const Matrix3 outer( const Vector3 &vec0, const Vector3 &vec1 ); + +// Pre-multiply a row vector by a 3x3 matrix +// NOTE: +// Slower than column post-multiply. +// +VECTORMATH_FORCE_INLINE const Vector3 rowMul( const Vector3 &vec, const Matrix3 & mat ); + +// Cross-product matrix of a 3-D vector +// +VECTORMATH_FORCE_INLINE const Matrix3 crossMatrix( const Vector3 &vec ); + +// Create cross-product matrix and multiply +// NOTE: +// Faster than separately creating a cross-product matrix and multiplying. +// +VECTORMATH_FORCE_INLINE const Matrix3 crossMatrixMul( const Vector3 &vec, const Matrix3 & mat ); + +// Linear interpolation between two 3-D vectors +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector3 lerp( float t, const Vector3 &vec0, const Vector3 &vec1 ); + +// Linear interpolation between two 3-D vectors (scalar data contained in vector data type) +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector3 lerp( const floatInVec &t, const Vector3 &vec0, const Vector3 &vec1 ); + +// Spherical linear interpolation between two 3-D vectors +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector3 slerp( float t, const Vector3 &unitVec0, const Vector3 &unitVec1 ); + +// Spherical linear interpolation between two 3-D vectors (scalar data contained in vector data type) +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector3 slerp( const floatInVec &t, const Vector3 &unitVec0, const Vector3 &unitVec1 ); + +// Conditionally select between two 3-D vectors +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, bool select1 ); + +// Conditionally select between two 3-D vectors (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, const boolInVec &select1 ); + +// Store x, y, and z elements of 3-D vector in first three words of a quadword, preserving fourth word +// +VECTORMATH_FORCE_INLINE void storeXYZ( const Vector3 &vec, __m128 * quad ); + +// Load four three-float 3-D vectors, stored in three quadwords +// +VECTORMATH_FORCE_INLINE void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const __m128 * threeQuads ); + +// Store four 3-D vectors in three quadwords +// +VECTORMATH_FORCE_INLINE void storeXYZArray( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, __m128 * threeQuads ); + +// Store eight 3-D vectors as half-floats +// +VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, const Vector3 &vec4, const Vector3 &vec5, const Vector3 &vec6, const Vector3 &vec7, vec_ushort8 * threeQuads ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3-D vector +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Vector3 &vec ); + +// Print a 3-D vector and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Vector3 &vec, const char * name ); + +#endif + +// A 4-D vector in array-of-structures format +// +class Vector4 +{ + __m128 mVec128; + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Vector4( ) { }; + + // Construct a 4-D vector from x, y, z, and w elements + // + VECTORMATH_FORCE_INLINE Vector4( float x, float y, float z, float w ); + + // Construct a 4-D vector from x, y, z, and w elements (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4( const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w ); + + // Construct a 4-D vector from a 3-D vector and a scalar + // + VECTORMATH_FORCE_INLINE Vector4( const Vector3 &xyz, float w ); + + // Construct a 4-D vector from a 3-D vector and a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4( const Vector3 &xyz, const floatInVec &w ); + + // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 + // + explicit VECTORMATH_FORCE_INLINE Vector4( const Vector3 &vec ); + + // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 + // + explicit VECTORMATH_FORCE_INLINE Vector4( const Point3 &pnt ); + + // Copy elements from a quaternion into a 4-D vector + // + explicit VECTORMATH_FORCE_INLINE Vector4( const Quat &quat ); + + // Set all elements of a 4-D vector to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Vector4( float scalar ); + + // Set all elements of a 4-D vector to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Vector4( const floatInVec &scalar ); + + // Set vector float data in a 4-D vector + // + explicit VECTORMATH_FORCE_INLINE Vector4( __m128 vf4 ); + + // Get vector float data from a 4-D vector + // + VECTORMATH_FORCE_INLINE __m128 get128( ) const; + + // Assign one 4-D vector to another + // + VECTORMATH_FORCE_INLINE Vector4 & operator =( const Vector4 &vec ); + + // Set the x, y, and z elements of a 4-D vector + // NOTE: + // This function does not change the w element. + // + VECTORMATH_FORCE_INLINE Vector4 & setXYZ( const Vector3 &vec ); + + // Get the x, y, and z elements of a 4-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 getXYZ( ) const; + + // Set the x element of a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 & setX( float x ); + + // Set the y element of a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 & setY( float y ); + + // Set the z element of a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 & setZ( float z ); + + // Set the w element of a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 & setW( float w ); + + // Set the x element of a 4-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & setX( const floatInVec &x ); + + // Set the y element of a 4-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & setY( const floatInVec &y ); + + // Set the z element of a 4-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & setZ( const floatInVec &z ); + + // Set the w element of a 4-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & setW( const floatInVec &w ); + + // Get the x element of a 4-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getX( ) const; + + // Get the y element of a 4-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getY( ) const; + + // Get the z element of a 4-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const; + + // Get the w element of a 4-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getW( ) const; + + // Set an x, y, z, or w element of a 4-D vector by index + // + VECTORMATH_FORCE_INLINE Vector4 & setElem( int idx, float value ); + + // Set an x, y, z, or w element of a 4-D vector by index (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & setElem( int idx, const floatInVec &value ); + + // Get an x, y, z, or w element of a 4-D vector by index + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + VECTORMATH_FORCE_INLINE VecIdx operator []( int idx ); + + // Subscripting operator to get an element + // + VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const; + + // Add two 4-D vectors + // + VECTORMATH_FORCE_INLINE const Vector4 operator +( const Vector4 &vec ) const; + + // Subtract a 4-D vector from another 4-D vector + // + VECTORMATH_FORCE_INLINE const Vector4 operator -( const Vector4 &vec ) const; + + // Multiply a 4-D vector by a scalar + // + VECTORMATH_FORCE_INLINE const Vector4 operator *( float scalar ) const; + + // Divide a 4-D vector by a scalar + // + VECTORMATH_FORCE_INLINE const Vector4 operator /( float scalar ) const; + + // Multiply a 4-D vector by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Vector4 operator *( const floatInVec &scalar ) const; + + // Divide a 4-D vector by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Vector4 operator /( const floatInVec &scalar ) const; + + // Perform compound assignment and addition with a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 & operator +=( const Vector4 &vec ); + + // Perform compound assignment and subtraction by a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 & operator -=( const Vector4 &vec ); + + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Vector4 & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + VECTORMATH_FORCE_INLINE Vector4 & operator /=( float scalar ); + + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & operator *=( const floatInVec &scalar ); + + // Perform compound assignment and division by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & operator /=( const floatInVec &scalar ); + + // Negate all elements of a 4-D vector + // + VECTORMATH_FORCE_INLINE const Vector4 operator -( ) const; + + // Construct x axis + // + static VECTORMATH_FORCE_INLINE const Vector4 xAxis( ); + + // Construct y axis + // + static VECTORMATH_FORCE_INLINE const Vector4 yAxis( ); + + // Construct z axis + // + static VECTORMATH_FORCE_INLINE const Vector4 zAxis( ); + + // Construct w axis + // + static VECTORMATH_FORCE_INLINE const Vector4 wAxis( ); + +}; + +// Multiply a 4-D vector by a scalar +// +VECTORMATH_FORCE_INLINE const Vector4 operator *( float scalar, const Vector4 &vec ); + +// Multiply a 4-D vector by a scalar (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Vector4 operator *( const floatInVec &scalar, const Vector4 &vec ); + +// Multiply two 4-D vectors per element +// +VECTORMATH_FORCE_INLINE const Vector4 mulPerElem( const Vector4 &vec0, const Vector4 &vec1 ); + +// Divide two 4-D vectors per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +VECTORMATH_FORCE_INLINE const Vector4 divPerElem( const Vector4 &vec0, const Vector4 &vec1 ); + +// Compute the reciprocal of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +VECTORMATH_FORCE_INLINE const Vector4 recipPerElem( const Vector4 &vec ); + +// Compute the absolute value of a 4-D vector per element +// +VECTORMATH_FORCE_INLINE const Vector4 absPerElem( const Vector4 &vec ); + +// Copy sign from one 4-D vector to another, per element +// +VECTORMATH_FORCE_INLINE const Vector4 copySignPerElem( const Vector4 &vec0, const Vector4 &vec1 ); + +// Maximum of two 4-D vectors per element +// +VECTORMATH_FORCE_INLINE const Vector4 maxPerElem( const Vector4 &vec0, const Vector4 &vec1 ); + +// Minimum of two 4-D vectors per element +// +VECTORMATH_FORCE_INLINE const Vector4 minPerElem( const Vector4 &vec0, const Vector4 &vec1 ); + +// Maximum element of a 4-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector4 &vec ); + +// Minimum element of a 4-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector4 &vec ); + +// Compute the sum of all elements of a 4-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector4 &vec ); + +// Compute the dot product of two 4-D vectors +// +VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector4 &vec0, const Vector4 &vec1 ); + +// Compute the square of the length of a 4-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector4 &vec ); + +// Compute the length of a 4-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec length( const Vector4 &vec ); + +// Normalize a 4-D vector +// NOTE: +// The result is unpredictable when all elements of vec are at or near zero. +// +VECTORMATH_FORCE_INLINE const Vector4 normalize( const Vector4 &vec ); + +// Outer product of two 4-D vectors +// +VECTORMATH_FORCE_INLINE const Matrix4 outer( const Vector4 &vec0, const Vector4 &vec1 ); + +// Linear interpolation between two 4-D vectors +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector4 lerp( float t, const Vector4 &vec0, const Vector4 &vec1 ); + +// Linear interpolation between two 4-D vectors (scalar data contained in vector data type) +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector4 lerp( const floatInVec &t, const Vector4 &vec0, const Vector4 &vec1 ); + +// Spherical linear interpolation between two 4-D vectors +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector4 slerp( float t, const Vector4 &unitVec0, const Vector4 &unitVec1 ); + +// Spherical linear interpolation between two 4-D vectors (scalar data contained in vector data type) +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector4 slerp( const floatInVec &t, const Vector4 &unitVec0, const Vector4 &unitVec1 ); + +// Conditionally select between two 4-D vectors +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, bool select1 ); + +// Conditionally select between two 4-D vectors (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, const boolInVec &select1 ); + +// Store four 4-D vectors as half-floats +// +VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector4 &vec0, const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3, vec_ushort8 * twoQuads ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 4-D vector +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Vector4 &vec ); + +// Print a 4-D vector and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Vector4 &vec, const char * name ); + +#endif + +// A 3-D point in array-of-structures format +// +class Point3 +{ + __m128 mVec128; + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Point3( ) { }; + + // Construct a 3-D point from x, y, and z elements + // + VECTORMATH_FORCE_INLINE Point3( float x, float y, float z ); + + // Construct a 3-D point from x, y, and z elements (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3( const floatInVec &x, const floatInVec &y, const floatInVec &z ); + + // Copy elements from a 3-D vector into a 3-D point + // + explicit VECTORMATH_FORCE_INLINE Point3( const Vector3 &vec ); + + // Set all elements of a 3-D point to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Point3( float scalar ); + + // Set all elements of a 3-D point to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Point3( const floatInVec &scalar ); + + // Set vector float data in a 3-D point + // + explicit VECTORMATH_FORCE_INLINE Point3( __m128 vf4 ); + + // Get vector float data from a 3-D point + // + VECTORMATH_FORCE_INLINE __m128 get128( ) const; + + // Assign one 3-D point to another + // + VECTORMATH_FORCE_INLINE Point3 & operator =( const Point3 &pnt ); + + // Set the x element of a 3-D point + // + VECTORMATH_FORCE_INLINE Point3 & setX( float x ); + + // Set the y element of a 3-D point + // + VECTORMATH_FORCE_INLINE Point3 & setY( float y ); + + // Set the z element of a 3-D point + // + VECTORMATH_FORCE_INLINE Point3 & setZ( float z ); + + // Set the x element of a 3-D point (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3 & setX( const floatInVec &x ); + + // Set the y element of a 3-D point (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3 & setY( const floatInVec &y ); + + // Set the z element of a 3-D point (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3 & setZ( const floatInVec &z ); + + // Get the x element of a 3-D point + // + VECTORMATH_FORCE_INLINE const floatInVec getX( ) const; + + // Get the y element of a 3-D point + // + VECTORMATH_FORCE_INLINE const floatInVec getY( ) const; + + // Get the z element of a 3-D point + // + VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const; + + // Set an x, y, or z element of a 3-D point by index + // + VECTORMATH_FORCE_INLINE Point3 & setElem( int idx, float value ); + + // Set an x, y, or z element of a 3-D point by index (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3 & setElem( int idx, const floatInVec &value ); + + // Get an x, y, or z element of a 3-D point by index + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + VECTORMATH_FORCE_INLINE VecIdx operator []( int idx ); + + // Subscripting operator to get an element + // + VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const; + + // Subtract a 3-D point from another 3-D point + // + VECTORMATH_FORCE_INLINE const Vector3 operator -( const Point3 &pnt ) const; + + // Add a 3-D point to a 3-D vector + // + VECTORMATH_FORCE_INLINE const Point3 operator +( const Vector3 &vec ) const; + + // Subtract a 3-D vector from a 3-D point + // + VECTORMATH_FORCE_INLINE const Point3 operator -( const Vector3 &vec ) const; + + // Perform compound assignment and addition with a 3-D vector + // + VECTORMATH_FORCE_INLINE Point3 & operator +=( const Vector3 &vec ); + + // Perform compound assignment and subtraction by a 3-D vector + // + VECTORMATH_FORCE_INLINE Point3 & operator -=( const Vector3 &vec ); + +}; + +// Multiply two 3-D points per element +// +VECTORMATH_FORCE_INLINE const Point3 mulPerElem( const Point3 &pnt0, const Point3 &pnt1 ); + +// Divide two 3-D points per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +VECTORMATH_FORCE_INLINE const Point3 divPerElem( const Point3 &pnt0, const Point3 &pnt1 ); + +// Compute the reciprocal of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +VECTORMATH_FORCE_INLINE const Point3 recipPerElem( const Point3 &pnt ); + +// Compute the absolute value of a 3-D point per element +// +VECTORMATH_FORCE_INLINE const Point3 absPerElem( const Point3 &pnt ); + +// Copy sign from one 3-D point to another, per element +// +VECTORMATH_FORCE_INLINE const Point3 copySignPerElem( const Point3 &pnt0, const Point3 &pnt1 ); + +// Maximum of two 3-D points per element +// +VECTORMATH_FORCE_INLINE const Point3 maxPerElem( const Point3 &pnt0, const Point3 &pnt1 ); + +// Minimum of two 3-D points per element +// +VECTORMATH_FORCE_INLINE const Point3 minPerElem( const Point3 &pnt0, const Point3 &pnt1 ); + +// Maximum element of a 3-D point +// +VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Point3 &pnt ); + +// Minimum element of a 3-D point +// +VECTORMATH_FORCE_INLINE const floatInVec minElem( const Point3 &pnt ); + +// Compute the sum of all elements of a 3-D point +// +VECTORMATH_FORCE_INLINE const floatInVec sum( const Point3 &pnt ); + +// Apply uniform scale to a 3-D point +// +VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, float scaleVal ); + +// Apply uniform scale to a 3-D point (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const floatInVec &scaleVal ); + +// Apply non-uniform scale to a 3-D point +// +VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const Vector3 &scaleVec ); + +// Scalar projection of a 3-D point on a unit-length 3-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec projection( const Point3 &pnt, const Vector3 &unitVec ); + +// Compute the square of the distance of a 3-D point from the coordinate-system origin +// +VECTORMATH_FORCE_INLINE const floatInVec distSqrFromOrigin( const Point3 &pnt ); + +// Compute the distance of a 3-D point from the coordinate-system origin +// +VECTORMATH_FORCE_INLINE const floatInVec distFromOrigin( const Point3 &pnt ); + +// Compute the square of the distance between two 3-D points +// +VECTORMATH_FORCE_INLINE const floatInVec distSqr( const Point3 &pnt0, const Point3 &pnt1 ); + +// Compute the distance between two 3-D points +// +VECTORMATH_FORCE_INLINE const floatInVec dist( const Point3 &pnt0, const Point3 &pnt1 ); + +// Linear interpolation between two 3-D points +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Point3 lerp( float t, const Point3 &pnt0, const Point3 &pnt1 ); + +// Linear interpolation between two 3-D points (scalar data contained in vector data type) +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Point3 lerp( const floatInVec &t, const Point3 &pnt0, const Point3 &pnt1 ); + +// Conditionally select between two 3-D points +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, bool select1 ); + +// Conditionally select between two 3-D points (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, const boolInVec &select1 ); + +// Store x, y, and z elements of 3-D point in first three words of a quadword, preserving fourth word +// +VECTORMATH_FORCE_INLINE void storeXYZ( const Point3 &pnt, __m128 * quad ); + +// Load four three-float 3-D points, stored in three quadwords +// +VECTORMATH_FORCE_INLINE void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const __m128 * threeQuads ); + +// Store four 3-D points in three quadwords +// +VECTORMATH_FORCE_INLINE void storeXYZArray( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, __m128 * threeQuads ); + +// Store eight 3-D points as half-floats +// +VECTORMATH_FORCE_INLINE void storeHalfFloats( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, const Point3 &pnt4, const Point3 &pnt5, const Point3 &pnt6, const Point3 &pnt7, vec_ushort8 * threeQuads ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3-D point +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Point3 &pnt ); + +// Print a 3-D point and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Point3 &pnt, const char * name ); + +#endif + +// A quaternion in array-of-structures format +// +class Quat +{ + __m128 mVec128; + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Quat( ) { }; + + VECTORMATH_FORCE_INLINE Quat(const Quat& quat); + + // Construct a quaternion from x, y, z, and w elements + // + VECTORMATH_FORCE_INLINE Quat( float x, float y, float z, float w ); + + // Construct a quaternion from x, y, z, and w elements (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat( const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w ); + + // Construct a quaternion from a 3-D vector and a scalar + // + VECTORMATH_FORCE_INLINE Quat( const Vector3 &xyz, float w ); + + // Construct a quaternion from a 3-D vector and a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat( const Vector3 &xyz, const floatInVec &w ); + + // Copy elements from a 4-D vector into a quaternion + // + explicit VECTORMATH_FORCE_INLINE Quat( const Vector4 &vec ); + + // Convert a rotation matrix to a unit-length quaternion + // + explicit VECTORMATH_FORCE_INLINE Quat( const Matrix3 & rotMat ); + + // Set all elements of a quaternion to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Quat( float scalar ); + + // Set all elements of a quaternion to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Quat( const floatInVec &scalar ); + + // Set vector float data in a quaternion + // + explicit VECTORMATH_FORCE_INLINE Quat( __m128 vf4 ); + + // Get vector float data from a quaternion + // + VECTORMATH_FORCE_INLINE __m128 get128( ) const; + + // Set a quaterion from vector float data + // + VECTORMATH_FORCE_INLINE void set128(vec_float4 vec); + + // Assign one quaternion to another + // + VECTORMATH_FORCE_INLINE Quat & operator =( const Quat &quat ); + + // Set the x, y, and z elements of a quaternion + // NOTE: + // This function does not change the w element. + // + VECTORMATH_FORCE_INLINE Quat & setXYZ( const Vector3 &vec ); + + // Get the x, y, and z elements of a quaternion + // + VECTORMATH_FORCE_INLINE const Vector3 getXYZ( ) const; + + // Set the x element of a quaternion + // + VECTORMATH_FORCE_INLINE Quat & setX( float x ); + + // Set the y element of a quaternion + // + VECTORMATH_FORCE_INLINE Quat & setY( float y ); + + // Set the z element of a quaternion + // + VECTORMATH_FORCE_INLINE Quat & setZ( float z ); + + // Set the w element of a quaternion + // + VECTORMATH_FORCE_INLINE Quat & setW( float w ); + + // Set the x element of a quaternion (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & setX( const floatInVec &x ); + + // Set the y element of a quaternion (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & setY( const floatInVec &y ); + + // Set the z element of a quaternion (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & setZ( const floatInVec &z ); + + // Set the w element of a quaternion (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & setW( const floatInVec &w ); + + // Get the x element of a quaternion + // + VECTORMATH_FORCE_INLINE const floatInVec getX( ) const; + + // Get the y element of a quaternion + // + VECTORMATH_FORCE_INLINE const floatInVec getY( ) const; + + // Get the z element of a quaternion + // + VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const; + + // Get the w element of a quaternion + // + VECTORMATH_FORCE_INLINE const floatInVec getW( ) const; + + // Set an x, y, z, or w element of a quaternion by index + // + VECTORMATH_FORCE_INLINE Quat & setElem( int idx, float value ); + + // Set an x, y, z, or w element of a quaternion by index (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & setElem( int idx, const floatInVec &value ); + + // Get an x, y, z, or w element of a quaternion by index + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + VECTORMATH_FORCE_INLINE VecIdx operator []( int idx ); + + // Subscripting operator to get an element + // + VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const; + + // Add two quaternions + // + VECTORMATH_FORCE_INLINE const Quat operator +( const Quat &quat ) const; + + // Subtract a quaternion from another quaternion + // + VECTORMATH_FORCE_INLINE const Quat operator -( const Quat &quat ) const; + + // Multiply two quaternions + // + VECTORMATH_FORCE_INLINE const Quat operator *( const Quat &quat ) const; + + // Multiply a quaternion by a scalar + // + VECTORMATH_FORCE_INLINE const Quat operator *( float scalar ) const; + + // Divide a quaternion by a scalar + // + VECTORMATH_FORCE_INLINE const Quat operator /( float scalar ) const; + + // Multiply a quaternion by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Quat operator *( const floatInVec &scalar ) const; + + // Divide a quaternion by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Quat operator /( const floatInVec &scalar ) const; + + // Perform compound assignment and addition with a quaternion + // + VECTORMATH_FORCE_INLINE Quat & operator +=( const Quat &quat ); + + // Perform compound assignment and subtraction by a quaternion + // + VECTORMATH_FORCE_INLINE Quat & operator -=( const Quat &quat ); + + // Perform compound assignment and multiplication by a quaternion + // + VECTORMATH_FORCE_INLINE Quat & operator *=( const Quat &quat ); + + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Quat & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + VECTORMATH_FORCE_INLINE Quat & operator /=( float scalar ); + + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & operator *=( const floatInVec &scalar ); + + // Perform compound assignment and division by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & operator /=( const floatInVec &scalar ); + + // Negate all elements of a quaternion + // + VECTORMATH_FORCE_INLINE const Quat operator -( ) const; + + // Construct an identity quaternion + // + static VECTORMATH_FORCE_INLINE const Quat identity( ); + + // Construct a quaternion to rotate between two unit-length 3-D vectors + // NOTE: + // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. + // + static VECTORMATH_FORCE_INLINE const Quat rotation( const Vector3 &unitVec0, const Vector3 &unitVec1 ); + + // Construct a quaternion to rotate around a unit-length 3-D vector + // + static VECTORMATH_FORCE_INLINE const Quat rotation( float radians, const Vector3 &unitVec ); + + // Construct a quaternion to rotate around a unit-length 3-D vector (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Quat rotation( const floatInVec &radians, const Vector3 &unitVec ); + + // Construct a quaternion to rotate around the x axis + // + static VECTORMATH_FORCE_INLINE const Quat rotationX( float radians ); + + // Construct a quaternion to rotate around the y axis + // + static VECTORMATH_FORCE_INLINE const Quat rotationY( float radians ); + + // Construct a quaternion to rotate around the z axis + // + static VECTORMATH_FORCE_INLINE const Quat rotationZ( float radians ); + + // Construct a quaternion to rotate around the x axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Quat rotationX( const floatInVec &radians ); + + // Construct a quaternion to rotate around the y axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Quat rotationY( const floatInVec &radians ); + + // Construct a quaternion to rotate around the z axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Quat rotationZ( const floatInVec &radians ); + +}; + +// Multiply a quaternion by a scalar +// +VECTORMATH_FORCE_INLINE const Quat operator *( float scalar, const Quat &quat ); + +// Multiply a quaternion by a scalar (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Quat operator *( const floatInVec &scalar, const Quat &quat ); + +// Compute the conjugate of a quaternion +// +VECTORMATH_FORCE_INLINE const Quat conj( const Quat &quat ); + +// Use a unit-length quaternion to rotate a 3-D vector +// +VECTORMATH_FORCE_INLINE const Vector3 rotate( const Quat &unitQuat, const Vector3 &vec ); + +// Compute the dot product of two quaternions +// +VECTORMATH_FORCE_INLINE const floatInVec dot( const Quat &quat0, const Quat &quat1 ); + +// Compute the norm of a quaternion +// +VECTORMATH_FORCE_INLINE const floatInVec norm( const Quat &quat ); + +// Compute the length of a quaternion +// +VECTORMATH_FORCE_INLINE const floatInVec length( const Quat &quat ); + +// Normalize a quaternion +// NOTE: +// The result is unpredictable when all elements of quat are at or near zero. +// +VECTORMATH_FORCE_INLINE const Quat normalize( const Quat &quat ); + +// Linear interpolation between two quaternions +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Quat lerp( float t, const Quat &quat0, const Quat &quat1 ); + +// Linear interpolation between two quaternions (scalar data contained in vector data type) +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Quat lerp( const floatInVec &t, const Quat &quat0, const Quat &quat1 ); + +// Spherical linear interpolation between two quaternions +// NOTE: +// Interpolates along the shortest path between orientations. +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Quat slerp( float t, const Quat &unitQuat0, const Quat &unitQuat1 ); + +// Spherical linear interpolation between two quaternions (scalar data contained in vector data type) +// NOTE: +// Interpolates along the shortest path between orientations. +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Quat slerp( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1 ); + +// Spherical quadrangle interpolation +// +VECTORMATH_FORCE_INLINE const Quat squad( float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ); + +// Spherical quadrangle interpolation (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Quat squad( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ); + +// Conditionally select between two quaternions +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, bool select1 ); + +// Conditionally select between two quaternions (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, const boolInVec &select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a quaternion +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Quat &quat ); + +// Print a quaternion and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Quat &quat, const char * name ); + +#endif + +// A 3x3 matrix in array-of-structures format +// +class Matrix3 +{ + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Matrix3( ) { }; + + // Copy a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3( const Matrix3 & mat ); + + // Construct a 3x3 matrix containing the specified columns + // + VECTORMATH_FORCE_INLINE Matrix3( const Vector3 &col0, const Vector3 &col1, const Vector3 &col2 ); + + // Construct a 3x3 rotation matrix from a unit-length quaternion + // + explicit VECTORMATH_FORCE_INLINE Matrix3( const Quat &unitQuat ); + + // Set all elements of a 3x3 matrix to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Matrix3( float scalar ); + + // Set all elements of a 3x3 matrix to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Matrix3( const floatInVec &scalar ); + + // Assign one 3x3 matrix to another + // + VECTORMATH_FORCE_INLINE Matrix3 & operator =( const Matrix3 & mat ); + + // Set column 0 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 & setCol0( const Vector3 &col0 ); + + // Set column 1 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 & setCol1( const Vector3 &col1 ); + + // Set column 2 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 & setCol2( const Vector3 &col2 ); + + // Get column 0 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol0( ) const; + + // Get column 1 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol1( ) const; + + // Get column 2 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol2( ) const; + + // Set the column of a 3x3 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Matrix3 & setCol( int col, const Vector3 &vec ); + + // Set the row of a 3x3 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Matrix3 & setRow( int row, const Vector3 &vec ); + + // Get the column of a 3x3 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector3 getCol( int col ) const; + + // Get the row of a 3x3 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector3 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + VECTORMATH_FORCE_INLINE Vector3 & operator []( int col ); + + // Subscripting operator to get a column + // + VECTORMATH_FORCE_INLINE const Vector3 operator []( int col ) const; + + // Set the element of a 3x3 matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE Matrix3 & setElem( int col, int row, float val ); + + // Set the element of a 3x3 matrix referred to by column and row indices (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Matrix3 & setElem( int col, int row, const floatInVec &val ); + + // Get the element of a 3x3 matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int col, int row ) const; + + // Add two 3x3 matrices + // + VECTORMATH_FORCE_INLINE const Matrix3 operator +( const Matrix3 & mat ) const; + + // Subtract a 3x3 matrix from another 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Matrix3 operator -( const Matrix3 & mat ) const; + + // Negate all elements of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Matrix3 operator -( ) const; + + // Multiply a 3x3 matrix by a scalar + // + VECTORMATH_FORCE_INLINE const Matrix3 operator *( float scalar ) const; + + // Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Matrix3 operator *( const floatInVec &scalar ) const; + + // Multiply a 3x3 matrix by a 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 operator *( const Vector3 &vec ) const; + + // Multiply two 3x3 matrices + // + VECTORMATH_FORCE_INLINE const Matrix3 operator *( const Matrix3 & mat ) const; + + // Perform compound assignment and addition with a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 & operator +=( const Matrix3 & mat ); + + // Perform compound assignment and subtraction by a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 & operator -=( const Matrix3 & mat ); + + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Matrix3 & operator *=( float scalar ); + + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Matrix3 & operator *=( const floatInVec &scalar ); + + // Perform compound assignment and multiplication by a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 & operator *=( const Matrix3 & mat ); + + // Construct an identity 3x3 matrix + // + static VECTORMATH_FORCE_INLINE const Matrix3 identity( ); + + // Construct a 3x3 matrix to rotate around the x axis + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationX( float radians ); + + // Construct a 3x3 matrix to rotate around the y axis + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationY( float radians ); + + // Construct a 3x3 matrix to rotate around the z axis + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationZ( float radians ); + + // Construct a 3x3 matrix to rotate around the x axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationX( const floatInVec &radians ); + + // Construct a 3x3 matrix to rotate around the y axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationY( const floatInVec &radians ); + + // Construct a 3x3 matrix to rotate around the z axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationZ( const floatInVec &radians ); + + // Construct a 3x3 matrix to rotate around the x, y, and z axes + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationZYX( const Vector3 &radiansXYZ ); + + // Construct a 3x3 matrix to rotate around a unit-length 3-D vector + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotation( float radians, const Vector3 &unitVec ); + + // Construct a 3x3 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotation( const floatInVec &radians, const Vector3 &unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotation( const Quat &unitQuat ); + + // Construct a 3x3 matrix to perform scaling + // + static VECTORMATH_FORCE_INLINE const Matrix3 scale( const Vector3 &scaleVec ); + +}; +// Multiply a 3x3 matrix by a scalar +// +VECTORMATH_FORCE_INLINE const Matrix3 operator *( float scalar, const Matrix3 & mat ); + +// Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Matrix3 operator *( const floatInVec &scalar, const Matrix3 & mat ); + +// Append (post-multiply) a scale transformation to a 3x3 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +VECTORMATH_FORCE_INLINE const Matrix3 appendScale( const Matrix3 & mat, const Vector3 &scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 3x3 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +VECTORMATH_FORCE_INLINE const Matrix3 prependScale( const Vector3 &scaleVec, const Matrix3 & mat ); + +// Multiply two 3x3 matrices per element +// +VECTORMATH_FORCE_INLINE const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); + +// Compute the absolute value of a 3x3 matrix per element +// +VECTORMATH_FORCE_INLINE const Matrix3 absPerElem( const Matrix3 & mat ); + +// Transpose of a 3x3 matrix +// +VECTORMATH_FORCE_INLINE const Matrix3 transpose( const Matrix3 & mat ); + +// Compute the inverse of a 3x3 matrix +// NOTE: +// Result is unpredictable when the determinant of mat is equal to or near 0. +// +VECTORMATH_FORCE_INLINE const Matrix3 inverse( const Matrix3 & mat ); + +// Determinant of a 3x3 matrix +// +VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix3 & mat ); + +// Conditionally select between two 3x3 matrices +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ); + +// Conditionally select between two 3x3 matrices (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, const boolInVec &select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3x3 matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat ); + +// Print a 3x3 matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat, const char * name ); + +#endif + +// A 4x4 matrix in array-of-structures format +// +class Matrix4 +{ + Vector4 mCol0; + Vector4 mCol1; + Vector4 mCol2; + Vector4 mCol3; + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Matrix4( ) { }; + + // Copy a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4( const Matrix4 & mat ); + + // Construct a 4x4 matrix containing the specified columns + // + VECTORMATH_FORCE_INLINE Matrix4( const Vector4 &col0, const Vector4 &col1, const Vector4 &col2, const Vector4 &col3 ); + + // Construct a 4x4 matrix from a 3x4 transformation matrix + // + explicit VECTORMATH_FORCE_INLINE Matrix4( const Transform3 & mat ); + + // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector + // + VECTORMATH_FORCE_INLINE Matrix4( const Matrix3 & mat, const Vector3 &translateVec ); + + // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector + // + VECTORMATH_FORCE_INLINE Matrix4( const Quat &unitQuat, const Vector3 &translateVec ); + + // Set all elements of a 4x4 matrix to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Matrix4( float scalar ); + + // Set all elements of a 4x4 matrix to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Matrix4( const floatInVec &scalar ); + + // Assign one 4x4 matrix to another + // + VECTORMATH_FORCE_INLINE Matrix4 & operator =( const Matrix4 & mat ); + + // Set the upper-left 3x3 submatrix + // NOTE: + // This function does not change the bottom row elements. + // + VECTORMATH_FORCE_INLINE Matrix4 & setUpper3x3( const Matrix3 & mat3 ); + + // Get the upper-left 3x3 submatrix of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Matrix3 getUpper3x3( ) const; + + // Set translation component + // NOTE: + // This function does not change the bottom row elements. + // + VECTORMATH_FORCE_INLINE Matrix4 & setTranslation( const Vector3 &translateVec ); + + // Get the translation component of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getTranslation( ) const; + + // Set column 0 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & setCol0( const Vector4 &col0 ); + + // Set column 1 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & setCol1( const Vector4 &col1 ); + + // Set column 2 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & setCol2( const Vector4 &col2 ); + + // Set column 3 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & setCol3( const Vector4 &col3 ); + + // Get column 0 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector4 getCol0( ) const; + + // Get column 1 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector4 getCol1( ) const; + + // Get column 2 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector4 getCol2( ) const; + + // Get column 3 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector4 getCol3( ) const; + + // Set the column of a 4x4 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Matrix4 & setCol( int col, const Vector4 &vec ); + + // Set the row of a 4x4 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Matrix4 & setRow( int row, const Vector4 &vec ); + + // Get the column of a 4x4 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector4 getCol( int col ) const; + + // Get the row of a 4x4 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector4 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + VECTORMATH_FORCE_INLINE Vector4 & operator []( int col ); + + // Subscripting operator to get a column + // + VECTORMATH_FORCE_INLINE const Vector4 operator []( int col ) const; + + // Set the element of a 4x4 matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE Matrix4 & setElem( int col, int row, float val ); + + // Set the element of a 4x4 matrix referred to by column and row indices (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Matrix4 & setElem( int col, int row, const floatInVec &val ); + + // Get the element of a 4x4 matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int col, int row ) const; + + // Add two 4x4 matrices + // + VECTORMATH_FORCE_INLINE const Matrix4 operator +( const Matrix4 & mat ) const; + + // Subtract a 4x4 matrix from another 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Matrix4 operator -( const Matrix4 & mat ) const; + + // Negate all elements of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Matrix4 operator -( ) const; + + // Multiply a 4x4 matrix by a scalar + // + VECTORMATH_FORCE_INLINE const Matrix4 operator *( float scalar ) const; + + // Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Matrix4 operator *( const floatInVec &scalar ) const; + + // Multiply a 4x4 matrix by a 4-D vector + // + VECTORMATH_FORCE_INLINE const Vector4 operator *( const Vector4 &vec ) const; + + // Multiply a 4x4 matrix by a 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector4 operator *( const Vector3 &vec ) const; + + // Multiply a 4x4 matrix by a 3-D point + // + VECTORMATH_FORCE_INLINE const Vector4 operator *( const Point3 &pnt ) const; + + // Multiply two 4x4 matrices + // + VECTORMATH_FORCE_INLINE const Matrix4 operator *( const Matrix4 & mat ) const; + + // Multiply a 4x4 matrix by a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Matrix4 operator *( const Transform3 & tfrm ) const; + + // Perform compound assignment and addition with a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & operator +=( const Matrix4 & mat ); + + // Perform compound assignment and subtraction by a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & operator -=( const Matrix4 & mat ); + + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Matrix4 & operator *=( float scalar ); + + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Matrix4 & operator *=( const floatInVec &scalar ); + + // Perform compound assignment and multiplication by a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & operator *=( const Matrix4 & mat ); + + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & operator *=( const Transform3 & tfrm ); + + // Construct an identity 4x4 matrix + // + static VECTORMATH_FORCE_INLINE const Matrix4 identity( ); + + // Construct a 4x4 matrix to rotate around the x axis + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationX( float radians ); + + // Construct a 4x4 matrix to rotate around the y axis + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationY( float radians ); + + // Construct a 4x4 matrix to rotate around the z axis + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationZ( float radians ); + + // Construct a 4x4 matrix to rotate around the x axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationX( const floatInVec &radians ); + + // Construct a 4x4 matrix to rotate around the y axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationY( const floatInVec &radians ); + + // Construct a 4x4 matrix to rotate around the z axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationZ( const floatInVec &radians ); + + // Construct a 4x4 matrix to rotate around the x, y, and z axes + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationZYX( const Vector3 &radiansXYZ ); + + // Construct a 4x4 matrix to rotate around a unit-length 3-D vector + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotation( float radians, const Vector3 &unitVec ); + + // Construct a 4x4 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotation( const floatInVec &radians, const Vector3 &unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotation( const Quat &unitQuat ); + + // Construct a 4x4 matrix to perform scaling + // + static VECTORMATH_FORCE_INLINE const Matrix4 scale( const Vector3 &scaleVec ); + + // Construct a 4x4 matrix to perform translation + // + static VECTORMATH_FORCE_INLINE const Matrix4 translation( const Vector3 &translateVec ); + + // Construct viewing matrix based on eye, position looked at, and up direction + // + static VECTORMATH_FORCE_INLINE const Matrix4 lookAt( const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec ); + + // Construct a perspective projection matrix + // + static VECTORMATH_FORCE_INLINE const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar ); + + // Construct a perspective projection matrix based on frustum + // + static VECTORMATH_FORCE_INLINE const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar ); + + // Construct an orthographic projection matrix + // + static VECTORMATH_FORCE_INLINE const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar ); + +}; +// Multiply a 4x4 matrix by a scalar +// +VECTORMATH_FORCE_INLINE const Matrix4 operator *( float scalar, const Matrix4 & mat ); + +// Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Matrix4 operator *( const floatInVec &scalar, const Matrix4 & mat ); + +// Append (post-multiply) a scale transformation to a 4x4 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +VECTORMATH_FORCE_INLINE const Matrix4 appendScale( const Matrix4 & mat, const Vector3 &scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 4x4 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +VECTORMATH_FORCE_INLINE const Matrix4 prependScale( const Vector3 &scaleVec, const Matrix4 & mat ); + +// Multiply two 4x4 matrices per element +// +VECTORMATH_FORCE_INLINE const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); + +// Compute the absolute value of a 4x4 matrix per element +// +VECTORMATH_FORCE_INLINE const Matrix4 absPerElem( const Matrix4 & mat ); + +// Transpose of a 4x4 matrix +// +VECTORMATH_FORCE_INLINE const Matrix4 transpose( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix +// NOTE: +// Result is unpredictable when the determinant of mat is equal to or near 0. +// +VECTORMATH_FORCE_INLINE const Matrix4 inverse( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. The result is unpredictable when the determinant of mat is equal to or near 0. +// +VECTORMATH_FORCE_INLINE const Matrix4 affineInverse( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. +// +VECTORMATH_FORCE_INLINE const Matrix4 orthoInverse( const Matrix4 & mat ); + +// Determinant of a 4x4 matrix +// +VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix4 & mat ); + +// Conditionally select between two 4x4 matrices +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ); + +// Conditionally select between two 4x4 matrices (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, const boolInVec &select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 4x4 matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat ); + +// Print a 4x4 matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat, const char * name ); + +#endif + +// A 3x4 transformation matrix in array-of-structures format +// +class Transform3 +{ + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + Vector3 mCol3; + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Transform3( ) { }; + + // Copy a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3( const Transform3 & tfrm ); + + // Construct a 3x4 transformation matrix containing the specified columns + // + VECTORMATH_FORCE_INLINE Transform3( const Vector3 &col0, const Vector3 &col1, const Vector3 &col2, const Vector3 &col3 ); + + // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector + // + VECTORMATH_FORCE_INLINE Transform3( const Matrix3 & tfrm, const Vector3 &translateVec ); + + // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector + // + VECTORMATH_FORCE_INLINE Transform3( const Quat &unitQuat, const Vector3 &translateVec ); + + // Set all elements of a 3x4 transformation matrix to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Transform3( float scalar ); + + // Set all elements of a 3x4 transformation matrix to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Transform3( const floatInVec &scalar ); + + // Assign one 3x4 transformation matrix to another + // + VECTORMATH_FORCE_INLINE Transform3 & operator =( const Transform3 & tfrm ); + + // Set the upper-left 3x3 submatrix + // + VECTORMATH_FORCE_INLINE Transform3 & setUpper3x3( const Matrix3 & mat3 ); + + // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Matrix3 getUpper3x3( ) const; + + // Set translation component + // + VECTORMATH_FORCE_INLINE Transform3 & setTranslation( const Vector3 &translateVec ); + + // Get the translation component of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getTranslation( ) const; + + // Set column 0 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 & setCol0( const Vector3 &col0 ); + + // Set column 1 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 & setCol1( const Vector3 &col1 ); + + // Set column 2 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 & setCol2( const Vector3 &col2 ); + + // Set column 3 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 & setCol3( const Vector3 &col3 ); + + // Get column 0 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol0( ) const; + + // Get column 1 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol1( ) const; + + // Get column 2 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol2( ) const; + + // Get column 3 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol3( ) const; + + // Set the column of a 3x4 transformation matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Transform3 & setCol( int col, const Vector3 &vec ); + + // Set the row of a 3x4 transformation matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Transform3 & setRow( int row, const Vector4 &vec ); + + // Get the column of a 3x4 transformation matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector3 getCol( int col ) const; + + // Get the row of a 3x4 transformation matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector4 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + VECTORMATH_FORCE_INLINE Vector3 & operator []( int col ); + + // Subscripting operator to get a column + // + VECTORMATH_FORCE_INLINE const Vector3 operator []( int col ) const; + + // Set the element of a 3x4 transformation matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE Transform3 & setElem( int col, int row, float val ); + + // Set the element of a 3x4 transformation matrix referred to by column and row indices (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Transform3 & setElem( int col, int row, const floatInVec &val ); + + // Get the element of a 3x4 transformation matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int col, int row ) const; + + // Multiply a 3x4 transformation matrix by a 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 operator *( const Vector3 &vec ) const; + + // Multiply a 3x4 transformation matrix by a 3-D point + // + VECTORMATH_FORCE_INLINE const Point3 operator *( const Point3 &pnt ) const; + + // Multiply two 3x4 transformation matrices + // + VECTORMATH_FORCE_INLINE const Transform3 operator *( const Transform3 & tfrm ) const; + + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 & operator *=( const Transform3 & tfrm ); + + // Construct an identity 3x4 transformation matrix + // + static VECTORMATH_FORCE_INLINE const Transform3 identity( ); + + // Construct a 3x4 transformation matrix to rotate around the x axis + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationX( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the y axis + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationY( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the z axis + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationZ( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the x axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationX( const floatInVec &radians ); + + // Construct a 3x4 transformation matrix to rotate around the y axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationY( const floatInVec &radians ); + + // Construct a 3x4 transformation matrix to rotate around the z axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationZ( const floatInVec &radians ); + + // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationZYX( const Vector3 &radiansXYZ ); + + // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector + // + static VECTORMATH_FORCE_INLINE const Transform3 rotation( float radians, const Vector3 &unitVec ); + + // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Transform3 rotation( const floatInVec &radians, const Vector3 &unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static VECTORMATH_FORCE_INLINE const Transform3 rotation( const Quat &unitQuat ); + + // Construct a 3x4 transformation matrix to perform scaling + // + static VECTORMATH_FORCE_INLINE const Transform3 scale( const Vector3 &scaleVec ); + + // Construct a 3x4 transformation matrix to perform translation + // + static VECTORMATH_FORCE_INLINE const Transform3 translation( const Vector3 &translateVec ); + +}; +// Append (post-multiply) a scale transformation to a 3x4 transformation matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +VECTORMATH_FORCE_INLINE const Transform3 appendScale( const Transform3 & tfrm, const Vector3 &scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +VECTORMATH_FORCE_INLINE const Transform3 prependScale( const Vector3 &scaleVec, const Transform3 & tfrm ); + +// Multiply two 3x4 transformation matrices per element +// +VECTORMATH_FORCE_INLINE const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); + +// Compute the absolute value of a 3x4 transformation matrix per element +// +VECTORMATH_FORCE_INLINE const Transform3 absPerElem( const Transform3 & tfrm ); + +// Inverse of a 3x4 transformation matrix +// NOTE: +// Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. +// +VECTORMATH_FORCE_INLINE const Transform3 inverse( const Transform3 & tfrm ); + +// Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. +// +VECTORMATH_FORCE_INLINE const Transform3 orthoInverse( const Transform3 & tfrm ); + +// Conditionally select between two 3x4 transformation matrices +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ); + +// Conditionally select between two 3x4 transformation matrices (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, const boolInVec &select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3x4 transformation matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm ); + +// Print a 3x4 transformation matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm, const char * name ); + +#endif + +} // namespace Aos +} // namespace Vectormath + +#include "vec_aos.h" +#include "quat_aos.h" +#include "mat_aos.h" + +#endif diff --git a/Extras/PhysicsEffects/include/vecmath/std/boolInVec.h b/Extras/PhysicsEffects/include/vecmath/std/boolInVec.h new file mode 100644 index 000000000..7ea380f91 --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/std/boolInVec.h @@ -0,0 +1,238 @@ +/* + Copyright (C) 2006-2010 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _BOOLINVEC_SCALAR_H +#define _BOOLINVEC_SCALAR_H + +#include +namespace Vectormath { + +class floatInVec; + +//-------------------------------------------------------------------------------------------------- +// boolInVec class +// + +class boolInVec +{ +private: + unsigned int mData; + +public: + // Default constructor; does no initialization + // + inline boolInVec( ) { }; + + // Construct from a value converted from float + // + inline boolInVec(floatInVec vec); + + // Explicit cast from bool + // + explicit inline boolInVec(bool scalar); + + // Explicit cast to bool + // + inline bool getAsBool() const; + +#ifndef _VECTORMATH_NO_SCALAR_CAST + // Implicit cast to bool + // + inline operator bool() const; +#endif + + // Boolean negation operator + // + inline const boolInVec operator ! () const; + + // Assignment operator + // + inline boolInVec& operator = (boolInVec vec); + + // Boolean and assignment operator + // + inline boolInVec& operator &= (boolInVec vec); + + // Boolean exclusive or assignment operator + // + inline boolInVec& operator ^= (boolInVec vec); + + // Boolean or assignment operator + // + inline boolInVec& operator |= (boolInVec vec); + +}; + +// Equal operator +// +inline const boolInVec operator == (boolInVec vec0, boolInVec vec1); + +// Not equal operator +// +inline const boolInVec operator != (boolInVec vec0, boolInVec vec1); + +// And operator +// +inline const boolInVec operator & (boolInVec vec0, boolInVec vec1); + +// Exclusive or operator +// +inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1); + +// Or operator +// +inline const boolInVec operator | (boolInVec vec0, boolInVec vec1); + +// Conditionally select between two values +// +inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1); + + +} // namespace Vectormath + + +//-------------------------------------------------------------------------------------------------- +// boolInVec implementation +// + +#include "floatInVec.h" + +namespace Vectormath { + +inline +boolInVec::boolInVec(floatInVec vec) +{ + *this = (vec != floatInVec(0.0f)); +} + +inline +boolInVec::boolInVec(bool scalar) +{ + mData = -(int)scalar; +} + +inline +bool +boolInVec::getAsBool() const +{ + return (mData > 0); +} + +#ifndef _VECTORMATH_NO_SCALAR_CAST +inline +boolInVec::operator bool() const +{ + return getAsBool(); +} +#endif + +inline +const boolInVec +boolInVec::operator ! () const +{ + return boolInVec(!mData); +} + +inline +boolInVec& +boolInVec::operator = (boolInVec vec) +{ + mData = vec.mData; + return *this; +} + +inline +boolInVec& +boolInVec::operator &= (boolInVec vec) +{ + *this = *this & vec; + return *this; +} + +inline +boolInVec& +boolInVec::operator ^= (boolInVec vec) +{ + *this = *this ^ vec; + return *this; +} + +inline +boolInVec& +boolInVec::operator |= (boolInVec vec) +{ + *this = *this | vec; + return *this; +} + +inline +const boolInVec +operator == (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() == vec1.getAsBool()); +} + +inline +const boolInVec +operator != (boolInVec vec0, boolInVec vec1) +{ + return !(vec0 == vec1); +} + +inline +const boolInVec +operator & (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() & vec1.getAsBool()); +} + +inline +const boolInVec +operator | (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() | vec1.getAsBool()); +} + +inline +const boolInVec +operator ^ (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() ^ vec1.getAsBool()); +} + +inline +const boolInVec +select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1) +{ + return (select_vec1.getAsBool() == 0) ? vec0 : vec1; +} + +} // namespace Vectormath + +#endif // boolInVec_h diff --git a/Extras/PhysicsEffects/include/vecmath/std/floatInVec.h b/Extras/PhysicsEffects/include/vecmath/std/floatInVec.h new file mode 100644 index 000000000..1aa2ee1cc --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/std/floatInVec.h @@ -0,0 +1,357 @@ +/* + Copyright (C) 2006-2010 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _FLOATINVEC__SCALAR_H +#define _FLOATINVEC__SCALAR_H + +#include +namespace Vectormath { + +class boolInVec; + +//-------------------------------------------------------------------------------------------------- +// floatInVec class +// + +// A class representing a scalar float value contained in a vector register +// This class does not support fastmath +class floatInVec +{ +private: + float mData; + +public: + // Default constructor; does no initialization + // + inline floatInVec( ) { }; + + // Construct from a value converted from bool + // + inline floatInVec(boolInVec vec); + + // Explicit cast from float + // + explicit inline floatInVec(float scalar); + + // Explicit cast to float + // + inline float getAsFloat() const; + +#ifndef _VECTORMATH_NO_SCALAR_CAST + // Implicit cast to float + // + inline operator float() const; +#endif + + // Post increment (add 1.0f) + // + inline const floatInVec operator ++ (int); + + // Post decrement (subtract 1.0f) + // + inline const floatInVec operator -- (int); + + // Pre increment (add 1.0f) + // + inline floatInVec& operator ++ (); + + // Pre decrement (subtract 1.0f) + // + inline floatInVec& operator -- (); + + // Negation operator + // + inline const floatInVec operator - () const; + + // Assignment operator + // + inline floatInVec& operator = (floatInVec vec); + + // Multiplication assignment operator + // + inline floatInVec& operator *= (floatInVec vec); + + // Division assignment operator + // + inline floatInVec& operator /= (floatInVec vec); + + // Addition assignment operator + // + inline floatInVec& operator += (floatInVec vec); + + // Subtraction assignment operator + // + inline floatInVec& operator -= (floatInVec vec); + +}; + +// Multiplication operator +// +inline const floatInVec operator * (floatInVec vec0, floatInVec vec1); + +// Division operator +// +inline const floatInVec operator / (floatInVec vec0, floatInVec vec1); + +// Addition operator +// +inline const floatInVec operator + (floatInVec vec0, floatInVec vec1); + +// Subtraction operator +// +inline const floatInVec operator - (floatInVec vec0, floatInVec vec1); + +// Less than operator +// +inline const boolInVec operator < (floatInVec vec0, floatInVec vec1); + +// Less than or equal operator +// +inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1); + +// Greater than operator +// +inline const boolInVec operator > (floatInVec vec0, floatInVec vec1); + +// Greater than or equal operator +// +inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1); + +// Equal operator +// +inline const boolInVec operator == (floatInVec vec0, floatInVec vec1); + +// Not equal operator +// +inline const boolInVec operator != (floatInVec vec0, floatInVec vec1); + +// Conditionally select between two values +// +inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1); + + +} // namespace Vectormath + + +//-------------------------------------------------------------------------------------------------- +// floatInVec implementation +// + +#include "boolInVec.h" + +namespace Vectormath { + +inline +floatInVec::floatInVec(boolInVec vec) +{ + mData = float(vec.getAsBool()); +} + +inline +floatInVec::floatInVec(float scalar) +{ + mData = scalar; +} + +inline +float +floatInVec::getAsFloat() const +{ + return mData; +} + +#ifndef _VECTORMATH_NO_SCALAR_CAST +inline +floatInVec::operator float() const +{ + return getAsFloat(); +} +#endif + +inline +const floatInVec +floatInVec::operator ++ (int) +{ + float olddata = mData; + operator ++(); + return floatInVec(olddata); +} + +inline +const floatInVec +floatInVec::operator -- (int) +{ + float olddata = mData; + operator --(); + return floatInVec(olddata); +} + +inline +floatInVec& +floatInVec::operator ++ () +{ + *this += floatInVec(1.0f); + return *this; +} + +inline +floatInVec& +floatInVec::operator -- () +{ + *this -= floatInVec(1.0f); + return *this; +} + +inline +const floatInVec +floatInVec::operator - () const +{ + return floatInVec(-mData); +} + +inline +floatInVec& +floatInVec::operator = (floatInVec vec) +{ + mData = vec.mData; + return *this; +} + +inline +floatInVec& +floatInVec::operator *= (floatInVec vec) +{ + *this = *this * vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator /= (floatInVec vec) +{ + *this = *this / vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator += (floatInVec vec) +{ + *this = *this + vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator -= (floatInVec vec) +{ + *this = *this - vec; + return *this; +} + +inline +const floatInVec +operator * (floatInVec vec0, floatInVec vec1) +{ + return floatInVec(vec0.getAsFloat() * vec1.getAsFloat()); +} + +inline +const floatInVec +operator / (floatInVec num, floatInVec den) +{ + return floatInVec(num.getAsFloat() / den.getAsFloat()); +} + +inline +const floatInVec +operator + (floatInVec vec0, floatInVec vec1) +{ + return floatInVec(vec0.getAsFloat() + vec1.getAsFloat()); +} + +inline +const floatInVec +operator - (floatInVec vec0, floatInVec vec1) +{ + return floatInVec(vec0.getAsFloat() - vec1.getAsFloat()); +} + +inline +const boolInVec +operator < (floatInVec vec0, floatInVec vec1) +{ + return boolInVec(vec0.getAsFloat() < vec1.getAsFloat()); +} + +inline +const boolInVec +operator <= (floatInVec vec0, floatInVec vec1) +{ + return !(vec0 > vec1); +} + +inline +const boolInVec +operator > (floatInVec vec0, floatInVec vec1) +{ + return boolInVec(vec0.getAsFloat() > vec1.getAsFloat()); +} + +inline +const boolInVec +operator >= (floatInVec vec0, floatInVec vec1) +{ + return !(vec0 < vec1); +} + +inline +const boolInVec +operator == (floatInVec vec0, floatInVec vec1) +{ + return boolInVec(vec0.getAsFloat() == vec1.getAsFloat()); +} + +inline +const boolInVec +operator != (floatInVec vec0, floatInVec vec1) +{ + return !(vec0 == vec1); +} + +inline +const floatInVec +select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1) +{ + return (select_vec1.getAsBool() == 0) ? vec0 : vec1; +} + +} // namespace Vectormath + +#endif // floatInVec_h diff --git a/Extras/PhysicsEffects/include/vecmath/std/mat_aos.h b/Extras/PhysicsEffects/include/vecmath/std/mat_aos.h new file mode 100644 index 000000000..3a6d4843e --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/std/mat_aos.h @@ -0,0 +1,1643 @@ +/* + Copyright (C) 2006-2010 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _VECTORMATH_MAT_AOS_CPP__SCALAR_H +#define _VECTORMATH_MAT_AOS_CPP__SCALAR_H + +namespace Vectormath { +namespace Aos { + +//----------------------------------------------------------------------------- +// Constants + +#define _VECTORMATH_PI_OVER_2 1.570796327f + +//----------------------------------------------------------------------------- +// Definitions + +inline Matrix3::Matrix3( const Matrix3 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; +} + +inline Matrix3::Matrix3( float scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); +} + +inline Matrix3::Matrix3( const Quat & unitQuat ) +{ + float qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; + qx = unitQuat.getX(); + qy = unitQuat.getY(); + qz = unitQuat.getZ(); + qw = unitQuat.getW(); + qx2 = ( qx + qx ); + qy2 = ( qy + qy ); + qz2 = ( qz + qz ); + qxqx2 = ( qx * qx2 ); + qxqy2 = ( qx * qy2 ); + qxqz2 = ( qx * qz2 ); + qxqw2 = ( qw * qx2 ); + qyqy2 = ( qy * qy2 ); + qyqz2 = ( qy * qz2 ); + qyqw2 = ( qw * qy2 ); + qzqz2 = ( qz * qz2 ); + qzqw2 = ( qw * qz2 ); + mCol0 = Vector3( ( ( 1.0f - qyqy2 ) - qzqz2 ), ( qxqy2 + qzqw2 ), ( qxqz2 - qyqw2 ) ); + mCol1 = Vector3( ( qxqy2 - qzqw2 ), ( ( 1.0f - qxqx2 ) - qzqz2 ), ( qyqz2 + qxqw2 ) ); + mCol2 = Vector3( ( qxqz2 + qyqw2 ), ( qyqz2 - qxqw2 ), ( ( 1.0f - qxqx2 ) - qyqy2 ) ); +} + +inline Matrix3::Matrix3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; +} + +inline Matrix3 & Matrix3::setCol0( const Vector3 & _col0 ) +{ + mCol0 = _col0; + return *this; +} + +inline Matrix3 & Matrix3::setCol1( const Vector3 & _col1 ) +{ + mCol1 = _col1; + return *this; +} + +inline Matrix3 & Matrix3::setCol2( const Vector3 & _col2 ) +{ + mCol2 = _col2; + return *this; +} + +inline Matrix3 & Matrix3::setCol( int col, const Vector3 & vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +inline Matrix3 & Matrix3::setRow( int row, const Vector3 & vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + return *this; +} + +inline Matrix3 & Matrix3::setElem( int col, int row, float val ) +{ + Vector3 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +inline float Matrix3::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +inline const Vector3 Matrix3::getCol0( ) const +{ + return mCol0; +} + +inline const Vector3 Matrix3::getCol1( ) const +{ + return mCol1; +} + +inline const Vector3 Matrix3::getCol2( ) const +{ + return mCol2; +} + +inline const Vector3 Matrix3::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +inline const Vector3 Matrix3::getRow( int row ) const +{ + return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); +} + +inline Vector3 & Matrix3::operator []( int col ) +{ + return *(&mCol0 + col); +} + +inline const Vector3 Matrix3::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +inline Matrix3 & Matrix3::operator =( const Matrix3 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + return *this; +} + +inline const Matrix3 transpose( const Matrix3 & mat ) +{ + return Matrix3( + Vector3( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX() ), + Vector3( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY() ), + Vector3( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ() ) + ); +} + +inline const Matrix3 inverse( const Matrix3 & mat ) +{ + Vector3 tmp0, tmp1, tmp2; + float detinv; + tmp0 = cross( mat.getCol1(), mat.getCol2() ); + tmp1 = cross( mat.getCol2(), mat.getCol0() ); + tmp2 = cross( mat.getCol0(), mat.getCol1() ); + detinv = ( 1.0f / dot( mat.getCol2(), tmp2 ) ); + return Matrix3( + Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ), + Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ), + Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ) + ); +} + +inline float determinant( const Matrix3 & mat ) +{ + return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); +} + +inline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const +{ + return Matrix3( + ( mCol0 + mat.mCol0 ), + ( mCol1 + mat.mCol1 ), + ( mCol2 + mat.mCol2 ) + ); +} + +inline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const +{ + return Matrix3( + ( mCol0 - mat.mCol0 ), + ( mCol1 - mat.mCol1 ), + ( mCol2 - mat.mCol2 ) + ); +} + +inline Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) +{ + *this = *this + mat; + return *this; +} + +inline Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) +{ + *this = *this - mat; + return *this; +} + +inline const Matrix3 Matrix3::operator -( ) const +{ + return Matrix3( + ( -mCol0 ), + ( -mCol1 ), + ( -mCol2 ) + ); +} + +inline const Matrix3 absPerElem( const Matrix3 & mat ) +{ + return Matrix3( + absPerElem( mat.getCol0() ), + absPerElem( mat.getCol1() ), + absPerElem( mat.getCol2() ) + ); +} + +inline const Matrix3 Matrix3::operator *( float scalar ) const +{ + return Matrix3( + ( mCol0 * scalar ), + ( mCol1 * scalar ), + ( mCol2 * scalar ) + ); +} + +inline Matrix3 & Matrix3::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Matrix3 operator *( float scalar, const Matrix3 & mat ) +{ + return mat * scalar; +} + +inline const Vector3 Matrix3::operator *( const Vector3 & vec ) const +{ + return Vector3( + ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), + ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), + ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ); +} + +inline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const +{ + return Matrix3( + ( *this * mat.mCol0 ), + ( *this * mat.mCol1 ), + ( *this * mat.mCol2 ) + ); +} + +inline Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) +{ + *this = *this * mat; + return *this; +} + +inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) +{ + return Matrix3( + mulPerElem( mat0.getCol0(), mat1.getCol0() ), + mulPerElem( mat0.getCol1(), mat1.getCol1() ), + mulPerElem( mat0.getCol2(), mat1.getCol2() ) + ); +} + +inline const Matrix3 Matrix3::identity( ) +{ + return Matrix3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ) + ); +} + +inline const Matrix3 Matrix3::rotationX( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix3( + Vector3::xAxis( ), + Vector3( 0.0f, c, s ), + Vector3( 0.0f, -s, c ) + ); +} + +inline const Matrix3 Matrix3::rotationY( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix3( + Vector3( c, 0.0f, -s ), + Vector3::yAxis( ), + Vector3( s, 0.0f, c ) + ); +} + +inline const Matrix3 Matrix3::rotationZ( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix3( + Vector3( c, s, 0.0f ), + Vector3( -s, c, 0.0f ), + Vector3::zAxis( ) + ); +} + +inline const Matrix3 Matrix3::rotationZYX( const Vector3 & radiansXYZ ) +{ + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf( radiansXYZ.getX() ); + cX = cosf( radiansXYZ.getX() ); + sY = sinf( radiansXYZ.getY() ); + cY = cosf( radiansXYZ.getY() ); + sZ = sinf( radiansXYZ.getZ() ); + cZ = cosf( radiansXYZ.getZ() ); + tmp0 = ( cZ * sY ); + tmp1 = ( sZ * sY ); + return Matrix3( + Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), + Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), + Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ) + ); +} + +inline const Matrix3 Matrix3::rotation( float radians, const Vector3 & unitVec ) +{ + float x, y, z, s, c, oneMinusC, xy, yz, zx; + s = sinf( radians ); + c = cosf( radians ); + x = unitVec.getX(); + y = unitVec.getY(); + z = unitVec.getZ(); + xy = ( x * y ); + yz = ( y * z ); + zx = ( z * x ); + oneMinusC = ( 1.0f - c ); + return Matrix3( + Vector3( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ) ), + Vector3( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ) ), + Vector3( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ) ) + ); +} + +inline const Matrix3 Matrix3::rotation( const Quat & unitQuat ) +{ + return Matrix3( unitQuat ); +} + +inline const Matrix3 Matrix3::scale( const Vector3 & scaleVec ) +{ + return Matrix3( + Vector3( scaleVec.getX(), 0.0f, 0.0f ), + Vector3( 0.0f, scaleVec.getY(), 0.0f ), + Vector3( 0.0f, 0.0f, scaleVec.getZ() ) + ); +} + +inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ) +{ + return Matrix3( + ( mat.getCol0() * scaleVec.getX( ) ), + ( mat.getCol1() * scaleVec.getY( ) ), + ( mat.getCol2() * scaleVec.getZ( ) ) + ); +} + +inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ) +{ + return Matrix3( + mulPerElem( mat.getCol0(), scaleVec ), + mulPerElem( mat.getCol1(), scaleVec ), + mulPerElem( mat.getCol2(), scaleVec ) + ); +} + +inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ) +{ + return Matrix3( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Matrix3 & mat ) +{ + print( mat.getRow( 0 ) ); + print( mat.getRow( 1 ) ); + print( mat.getRow( 2 ) ); +} + +inline void print( const Matrix3 & mat, const char * name ) +{ + printf("%s:\n", name); + print( mat ); +} + +#endif + +inline Matrix4::Matrix4( const Matrix4 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; +} + +inline Matrix4::Matrix4( float scalar ) +{ + mCol0 = Vector4( scalar ); + mCol1 = Vector4( scalar ); + mCol2 = Vector4( scalar ); + mCol3 = Vector4( scalar ); +} + +inline Matrix4::Matrix4( const Transform3 & mat ) +{ + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( mat.getCol3(), 1.0f ); +} + +inline Matrix4::Matrix4( const Vector4 & _col0, const Vector4 & _col1, const Vector4 & _col2, const Vector4 & _col3 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; +} + +inline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 & translateVec ) +{ + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( translateVec, 1.0f ); +} + +inline Matrix4::Matrix4( const Quat & unitQuat, const Vector3 & translateVec ) +{ + Matrix3 mat; + mat = Matrix3( unitQuat ); + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( translateVec, 1.0f ); +} + +inline Matrix4 & Matrix4::setCol0( const Vector4 & _col0 ) +{ + mCol0 = _col0; + return *this; +} + +inline Matrix4 & Matrix4::setCol1( const Vector4 & _col1 ) +{ + mCol1 = _col1; + return *this; +} + +inline Matrix4 & Matrix4::setCol2( const Vector4 & _col2 ) +{ + mCol2 = _col2; + return *this; +} + +inline Matrix4 & Matrix4::setCol3( const Vector4 & _col3 ) +{ + mCol3 = _col3; + return *this; +} + +inline Matrix4 & Matrix4::setCol( int col, const Vector4 & vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +inline Matrix4 & Matrix4::setRow( int row, const Vector4 & vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + mCol3.setElem( row, vec.getElem( 3 ) ); + return *this; +} + +inline Matrix4 & Matrix4::setElem( int col, int row, float val ) +{ + Vector4 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +inline float Matrix4::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +inline const Vector4 Matrix4::getCol0( ) const +{ + return mCol0; +} + +inline const Vector4 Matrix4::getCol1( ) const +{ + return mCol1; +} + +inline const Vector4 Matrix4::getCol2( ) const +{ + return mCol2; +} + +inline const Vector4 Matrix4::getCol3( ) const +{ + return mCol3; +} + +inline const Vector4 Matrix4::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +inline const Vector4 Matrix4::getRow( int row ) const +{ + return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); +} + +inline Vector4 & Matrix4::operator []( int col ) +{ + return *(&mCol0 + col); +} + +inline const Vector4 Matrix4::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +inline Matrix4 & Matrix4::operator =( const Matrix4 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; + return *this; +} + +inline const Matrix4 transpose( const Matrix4 & mat ) +{ + return Matrix4( + Vector4( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX() ), + Vector4( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY() ), + Vector4( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ() ), + Vector4( mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW() ) + ); +} + +inline const Matrix4 inverse( const Matrix4 & mat ) +{ + Vector4 res0, res1, res2, res3; + float mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv; + mA = mat.getCol0().getX(); + mB = mat.getCol0().getY(); + mC = mat.getCol0().getZ(); + mD = mat.getCol0().getW(); + mE = mat.getCol1().getX(); + mF = mat.getCol1().getY(); + mG = mat.getCol1().getZ(); + mH = mat.getCol1().getW(); + mI = mat.getCol2().getX(); + mJ = mat.getCol2().getY(); + mK = mat.getCol2().getZ(); + mL = mat.getCol2().getW(); + mM = mat.getCol3().getX(); + mN = mat.getCol3().getY(); + mO = mat.getCol3().getZ(); + mP = mat.getCol3().getW(); + tmp0 = ( ( mK * mD ) - ( mC * mL ) ); + tmp1 = ( ( mO * mH ) - ( mG * mP ) ); + tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); + tmp3 = ( ( mF * mO ) - ( mN * mG ) ); + tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); + tmp5 = ( ( mN * mH ) - ( mF * mP ) ); + res0.setX( ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ) ); + res0.setY( ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ) ); + res0.setZ( ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ) ); + res0.setW( ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ) ); + detInv = ( 1.0f / ( ( ( ( mA * res0.getX() ) + ( mE * res0.getY() ) ) + ( mI * res0.getZ() ) ) + ( mM * res0.getW() ) ) ); + res1.setX( ( mI * tmp1 ) ); + res1.setY( ( mM * tmp0 ) ); + res1.setZ( ( mA * tmp1 ) ); + res1.setW( ( mE * tmp0 ) ); + res3.setX( ( mI * tmp3 ) ); + res3.setY( ( mM * tmp2 ) ); + res3.setZ( ( mA * tmp3 ) ); + res3.setW( ( mE * tmp2 ) ); + res2.setX( ( mI * tmp5 ) ); + res2.setY( ( mM * tmp4 ) ); + res2.setZ( ( mA * tmp5 ) ); + res2.setW( ( mE * tmp4 ) ); + tmp0 = ( ( mI * mB ) - ( mA * mJ ) ); + tmp1 = ( ( mM * mF ) - ( mE * mN ) ); + tmp2 = ( ( mI * mD ) - ( mA * mL ) ); + tmp3 = ( ( mM * mH ) - ( mE * mP ) ); + tmp4 = ( ( mI * mC ) - ( mA * mK ) ); + tmp5 = ( ( mM * mG ) - ( mE * mO ) ); + res2.setX( ( ( ( mL * tmp1 ) - ( mJ * tmp3 ) ) + res2.getX() ) ); + res2.setY( ( ( ( mP * tmp0 ) - ( mN * tmp2 ) ) + res2.getY() ) ); + res2.setZ( ( ( ( mB * tmp3 ) - ( mD * tmp1 ) ) - res2.getZ() ) ); + res2.setW( ( ( ( mF * tmp2 ) - ( mH * tmp0 ) ) - res2.getW() ) ); + res3.setX( ( ( ( mJ * tmp5 ) - ( mK * tmp1 ) ) + res3.getX() ) ); + res3.setY( ( ( ( mN * tmp4 ) - ( mO * tmp0 ) ) + res3.getY() ) ); + res3.setZ( ( ( ( mC * tmp1 ) - ( mB * tmp5 ) ) - res3.getZ() ) ); + res3.setW( ( ( ( mG * tmp0 ) - ( mF * tmp4 ) ) - res3.getW() ) ); + res1.setX( ( ( ( mK * tmp3 ) - ( mL * tmp5 ) ) - res1.getX() ) ); + res1.setY( ( ( ( mO * tmp2 ) - ( mP * tmp4 ) ) - res1.getY() ) ); + res1.setZ( ( ( ( mD * tmp5 ) - ( mC * tmp3 ) ) + res1.getZ() ) ); + res1.setW( ( ( ( mH * tmp4 ) - ( mG * tmp2 ) ) + res1.getW() ) ); + return Matrix4( + ( res0 * detInv ), + ( res1 * detInv ), + ( res2 * detInv ), + ( res3 * detInv ) + ); +} + +inline const Matrix4 affineInverse( const Matrix4 & mat ) +{ + Transform3 affineMat; + affineMat.setCol0( mat.getCol0().getXYZ( ) ); + affineMat.setCol1( mat.getCol1().getXYZ( ) ); + affineMat.setCol2( mat.getCol2().getXYZ( ) ); + affineMat.setCol3( mat.getCol3().getXYZ( ) ); + return Matrix4( inverse( affineMat ) ); +} + +inline const Matrix4 orthoInverse( const Matrix4 & mat ) +{ + Transform3 affineMat; + affineMat.setCol0( mat.getCol0().getXYZ( ) ); + affineMat.setCol1( mat.getCol1().getXYZ( ) ); + affineMat.setCol2( mat.getCol2().getXYZ( ) ); + affineMat.setCol3( mat.getCol3().getXYZ( ) ); + return Matrix4( orthoInverse( affineMat ) ); +} + +inline float determinant( const Matrix4 & mat ) +{ + float dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; + mA = mat.getCol0().getX(); + mB = mat.getCol0().getY(); + mC = mat.getCol0().getZ(); + mD = mat.getCol0().getW(); + mE = mat.getCol1().getX(); + mF = mat.getCol1().getY(); + mG = mat.getCol1().getZ(); + mH = mat.getCol1().getW(); + mI = mat.getCol2().getX(); + mJ = mat.getCol2().getY(); + mK = mat.getCol2().getZ(); + mL = mat.getCol2().getW(); + mM = mat.getCol3().getX(); + mN = mat.getCol3().getY(); + mO = mat.getCol3().getZ(); + mP = mat.getCol3().getW(); + tmp0 = ( ( mK * mD ) - ( mC * mL ) ); + tmp1 = ( ( mO * mH ) - ( mG * mP ) ); + tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); + tmp3 = ( ( mF * mO ) - ( mN * mG ) ); + tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); + tmp5 = ( ( mN * mH ) - ( mF * mP ) ); + dx = ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ); + dy = ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ); + dz = ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ); + dw = ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ); + return ( ( ( ( mA * dx ) + ( mE * dy ) ) + ( mI * dz ) ) + ( mM * dw ) ); +} + +inline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const +{ + return Matrix4( + ( mCol0 + mat.mCol0 ), + ( mCol1 + mat.mCol1 ), + ( mCol2 + mat.mCol2 ), + ( mCol3 + mat.mCol3 ) + ); +} + +inline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const +{ + return Matrix4( + ( mCol0 - mat.mCol0 ), + ( mCol1 - mat.mCol1 ), + ( mCol2 - mat.mCol2 ), + ( mCol3 - mat.mCol3 ) + ); +} + +inline Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) +{ + *this = *this + mat; + return *this; +} + +inline Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) +{ + *this = *this - mat; + return *this; +} + +inline const Matrix4 Matrix4::operator -( ) const +{ + return Matrix4( + ( -mCol0 ), + ( -mCol1 ), + ( -mCol2 ), + ( -mCol3 ) + ); +} + +inline const Matrix4 absPerElem( const Matrix4 & mat ) +{ + return Matrix4( + absPerElem( mat.getCol0() ), + absPerElem( mat.getCol1() ), + absPerElem( mat.getCol2() ), + absPerElem( mat.getCol3() ) + ); +} + +inline const Matrix4 Matrix4::operator *( float scalar ) const +{ + return Matrix4( + ( mCol0 * scalar ), + ( mCol1 * scalar ), + ( mCol2 * scalar ), + ( mCol3 * scalar ) + ); +} + +inline Matrix4 & Matrix4::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Matrix4 operator *( float scalar, const Matrix4 & mat ) +{ + return mat * scalar; +} + +inline const Vector4 Matrix4::operator *( const Vector4 & vec ) const +{ + return Vector4( + ( ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ) + ( mCol3.getX() * vec.getW() ) ), + ( ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ) + ( mCol3.getY() * vec.getW() ) ), + ( ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ( mCol3.getZ() * vec.getW() ) ), + ( ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) + ( mCol3.getW() * vec.getW() ) ) + ); +} + +inline const Vector4 Matrix4::operator *( const Vector3 & vec ) const +{ + return Vector4( + ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), + ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), + ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ), + ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) + ); +} + +inline const Vector4 Matrix4::operator *( const Point3 & pnt ) const +{ + return Vector4( + ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), + ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), + ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ), + ( ( ( ( mCol0.getW() * pnt.getX() ) + ( mCol1.getW() * pnt.getY() ) ) + ( mCol2.getW() * pnt.getZ() ) ) + mCol3.getW() ) + ); +} + +inline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const +{ + return Matrix4( + ( *this * mat.mCol0 ), + ( *this * mat.mCol1 ), + ( *this * mat.mCol2 ), + ( *this * mat.mCol3 ) + ); +} + +inline Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) +{ + *this = *this * mat; + return *this; +} + +inline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const +{ + return Matrix4( + ( *this * tfrm.getCol0() ), + ( *this * tfrm.getCol1() ), + ( *this * tfrm.getCol2() ), + ( *this * Point3( tfrm.getCol3() ) ) + ); +} + +inline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) +{ + *this = *this * tfrm; + return *this; +} + +inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) +{ + return Matrix4( + mulPerElem( mat0.getCol0(), mat1.getCol0() ), + mulPerElem( mat0.getCol1(), mat1.getCol1() ), + mulPerElem( mat0.getCol2(), mat1.getCol2() ), + mulPerElem( mat0.getCol3(), mat1.getCol3() ) + ); +} + +inline const Matrix4 Matrix4::identity( ) +{ + return Matrix4( + Vector4::xAxis( ), + Vector4::yAxis( ), + Vector4::zAxis( ), + Vector4::wAxis( ) + ); +} + +inline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) +{ + mCol0.setXYZ( mat3.getCol0() ); + mCol1.setXYZ( mat3.getCol1() ); + mCol2.setXYZ( mat3.getCol2() ); + return *this; +} + +inline const Matrix3 Matrix4::getUpper3x3( ) const +{ + return Matrix3( + mCol0.getXYZ( ), + mCol1.getXYZ( ), + mCol2.getXYZ( ) + ); +} + +inline Matrix4 & Matrix4::setTranslation( const Vector3 & translateVec ) +{ + mCol3.setXYZ( translateVec ); + return *this; +} + +inline const Vector3 Matrix4::getTranslation( ) const +{ + return mCol3.getXYZ( ); +} + +inline const Matrix4 Matrix4::rotationX( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix4( + Vector4::xAxis( ), + Vector4( 0.0f, c, s, 0.0f ), + Vector4( 0.0f, -s, c, 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotationY( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix4( + Vector4( c, 0.0f, -s, 0.0f ), + Vector4::yAxis( ), + Vector4( s, 0.0f, c, 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotationZ( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix4( + Vector4( c, s, 0.0f, 0.0f ), + Vector4( -s, c, 0.0f, 0.0f ), + Vector4::zAxis( ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotationZYX( const Vector3 & radiansXYZ ) +{ + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf( radiansXYZ.getX() ); + cX = cosf( radiansXYZ.getX() ); + sY = sinf( radiansXYZ.getY() ); + cY = cosf( radiansXYZ.getY() ); + sZ = sinf( radiansXYZ.getZ() ); + cZ = cosf( radiansXYZ.getZ() ); + tmp0 = ( cZ * sY ); + tmp1 = ( sZ * sY ); + return Matrix4( + Vector4( ( cZ * cY ), ( sZ * cY ), -sY, 0.0f ), + Vector4( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ), 0.0f ), + Vector4( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ), 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotation( float radians, const Vector3 & unitVec ) +{ + float x, y, z, s, c, oneMinusC, xy, yz, zx; + s = sinf( radians ); + c = cosf( radians ); + x = unitVec.getX(); + y = unitVec.getY(); + z = unitVec.getZ(); + xy = ( x * y ); + yz = ( y * z ); + zx = ( z * x ); + oneMinusC = ( 1.0f - c ); + return Matrix4( + Vector4( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ), 0.0f ), + Vector4( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ), 0.0f ), + Vector4( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ), 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotation( const Quat & unitQuat ) +{ + return Matrix4( Transform3::rotation( unitQuat ) ); +} + +inline const Matrix4 Matrix4::scale( const Vector3 & scaleVec ) +{ + return Matrix4( + Vector4( scaleVec.getX(), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, scaleVec.getY(), 0.0f, 0.0f ), + Vector4( 0.0f, 0.0f, scaleVec.getZ(), 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ) +{ + return Matrix4( + ( mat.getCol0() * scaleVec.getX( ) ), + ( mat.getCol1() * scaleVec.getY( ) ), + ( mat.getCol2() * scaleVec.getZ( ) ), + mat.getCol3() + ); +} + +inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ) +{ + Vector4 scale4; + scale4 = Vector4( scaleVec, 1.0f ); + return Matrix4( + mulPerElem( mat.getCol0(), scale4 ), + mulPerElem( mat.getCol1(), scale4 ), + mulPerElem( mat.getCol2(), scale4 ), + mulPerElem( mat.getCol3(), scale4 ) + ); +} + +inline const Matrix4 Matrix4::translation( const Vector3 & translateVec ) +{ + return Matrix4( + Vector4::xAxis( ), + Vector4::yAxis( ), + Vector4::zAxis( ), + Vector4( translateVec, 1.0f ) + ); +} + +inline const Matrix4 Matrix4::lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ) +{ + Matrix4 m4EyeFrame; + Vector3 v3X, v3Y, v3Z; + v3Y = normalize( upVec ); + v3Z = normalize( ( eyePos - lookAtPos ) ); + v3X = normalize( cross( v3Y, v3Z ) ); + v3Y = cross( v3Z, v3X ); + m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); + return orthoInverse( m4EyeFrame ); +} + +inline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar ) +{ + float f, rangeInv; + f = tanf( ( (float)( _VECTORMATH_PI_OVER_2 ) - ( 0.5f * fovyRadians ) ) ); + rangeInv = ( 1.0f / ( zNear - zFar ) ); + return Matrix4( + Vector4( ( f / aspect ), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, f, 0.0f, 0.0f ), + Vector4( 0.0f, 0.0f, ( ( zNear + zFar ) * rangeInv ), -1.0f ), + Vector4( 0.0f, 0.0f, ( ( ( zNear * zFar ) * rangeInv ) * 2.0f ), 0.0f ) + ); +} + +inline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ) +{ + float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; + sum_rl = ( right + left ); + sum_tb = ( top + bottom ); + sum_nf = ( zNear + zFar ); + inv_rl = ( 1.0f / ( right - left ) ); + inv_tb = ( 1.0f / ( top - bottom ) ); + inv_nf = ( 1.0f / ( zNear - zFar ) ); + n2 = ( zNear + zNear ); + return Matrix4( + Vector4( ( n2 * inv_rl ), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, ( n2 * inv_tb ), 0.0f, 0.0f ), + Vector4( ( sum_rl * inv_rl ), ( sum_tb * inv_tb ), ( sum_nf * inv_nf ), -1.0f ), + Vector4( 0.0f, 0.0f, ( ( n2 * inv_nf ) * zFar ), 0.0f ) + ); +} + +inline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar ) +{ + float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; + sum_rl = ( right + left ); + sum_tb = ( top + bottom ); + sum_nf = ( zNear + zFar ); + inv_rl = ( 1.0f / ( right - left ) ); + inv_tb = ( 1.0f / ( top - bottom ) ); + inv_nf = ( 1.0f / ( zNear - zFar ) ); + return Matrix4( + Vector4( ( inv_rl + inv_rl ), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, ( inv_tb + inv_tb ), 0.0f, 0.0f ), + Vector4( 0.0f, 0.0f, ( inv_nf + inv_nf ), 0.0f ), + Vector4( ( -sum_rl * inv_rl ), ( -sum_tb * inv_tb ), ( sum_nf * inv_nf ), 1.0f ) + ); +} + +inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ) +{ + return Matrix4( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ), + select( mat0.getCol3(), mat1.getCol3(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Matrix4 & mat ) +{ + print( mat.getRow( 0 ) ); + print( mat.getRow( 1 ) ); + print( mat.getRow( 2 ) ); + print( mat.getRow( 3 ) ); +} + +inline void print( const Matrix4 & mat, const char * name ) +{ + printf("%s:\n", name); + print( mat ); +} + +#endif + +inline Transform3::Transform3( const Transform3 & tfrm ) +{ + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; +} + +inline Transform3::Transform3( float scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); + mCol3 = Vector3( scalar ); +} + +inline Transform3::Transform3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2, const Vector3 & _col3 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; +} + +inline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ) +{ + this->setUpper3x3( tfrm ); + this->setTranslation( translateVec ); +} + +inline Transform3::Transform3( const Quat & unitQuat, const Vector3 & translateVec ) +{ + this->setUpper3x3( Matrix3( unitQuat ) ); + this->setTranslation( translateVec ); +} + +inline Transform3 & Transform3::setCol0( const Vector3 & _col0 ) +{ + mCol0 = _col0; + return *this; +} + +inline Transform3 & Transform3::setCol1( const Vector3 & _col1 ) +{ + mCol1 = _col1; + return *this; +} + +inline Transform3 & Transform3::setCol2( const Vector3 & _col2 ) +{ + mCol2 = _col2; + return *this; +} + +inline Transform3 & Transform3::setCol3( const Vector3 & _col3 ) +{ + mCol3 = _col3; + return *this; +} + +inline Transform3 & Transform3::setCol( int col, const Vector3 & vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +inline Transform3 & Transform3::setRow( int row, const Vector4 & vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + mCol3.setElem( row, vec.getElem( 3 ) ); + return *this; +} + +inline Transform3 & Transform3::setElem( int col, int row, float val ) +{ + Vector3 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +inline float Transform3::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +inline const Vector3 Transform3::getCol0( ) const +{ + return mCol0; +} + +inline const Vector3 Transform3::getCol1( ) const +{ + return mCol1; +} + +inline const Vector3 Transform3::getCol2( ) const +{ + return mCol2; +} + +inline const Vector3 Transform3::getCol3( ) const +{ + return mCol3; +} + +inline const Vector3 Transform3::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +inline const Vector4 Transform3::getRow( int row ) const +{ + return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); +} + +inline Vector3 & Transform3::operator []( int col ) +{ + return *(&mCol0 + col); +} + +inline const Vector3 Transform3::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +inline Transform3 & Transform3::operator =( const Transform3 & tfrm ) +{ + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; + return *this; +} + +inline const Transform3 inverse( const Transform3 & tfrm ) +{ + Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2; + float detinv; + tmp0 = cross( tfrm.getCol1(), tfrm.getCol2() ); + tmp1 = cross( tfrm.getCol2(), tfrm.getCol0() ); + tmp2 = cross( tfrm.getCol0(), tfrm.getCol1() ); + detinv = ( 1.0f / dot( tfrm.getCol2(), tmp2 ) ); + inv0 = Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ); + inv1 = Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ); + inv2 = Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ); + return Transform3( + inv0, + inv1, + inv2, + Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) + ); +} + +inline const Transform3 orthoInverse( const Transform3 & tfrm ) +{ + Vector3 inv0, inv1, inv2; + inv0 = Vector3( tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX() ); + inv1 = Vector3( tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY() ); + inv2 = Vector3( tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ() ); + return Transform3( + inv0, + inv1, + inv2, + Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) + ); +} + +inline const Transform3 absPerElem( const Transform3 & tfrm ) +{ + return Transform3( + absPerElem( tfrm.getCol0() ), + absPerElem( tfrm.getCol1() ), + absPerElem( tfrm.getCol2() ), + absPerElem( tfrm.getCol3() ) + ); +} + +inline const Vector3 Transform3::operator *( const Vector3 & vec ) const +{ + return Vector3( + ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), + ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), + ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ); +} + +inline const Point3 Transform3::operator *( const Point3 & pnt ) const +{ + return Point3( + ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), + ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), + ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ) + ); +} + +inline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const +{ + return Transform3( + ( *this * tfrm.mCol0 ), + ( *this * tfrm.mCol1 ), + ( *this * tfrm.mCol2 ), + Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) + ); +} + +inline Transform3 & Transform3::operator *=( const Transform3 & tfrm ) +{ + *this = *this * tfrm; + return *this; +} + +inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) +{ + return Transform3( + mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), + mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), + mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), + mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) + ); +} + +inline const Transform3 Transform3::identity( ) +{ + return Transform3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ), + Vector3( 0.0f ) + ); +} + +inline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) +{ + mCol0 = tfrm.getCol0(); + mCol1 = tfrm.getCol1(); + mCol2 = tfrm.getCol2(); + return *this; +} + +inline const Matrix3 Transform3::getUpper3x3( ) const +{ + return Matrix3( mCol0, mCol1, mCol2 ); +} + +inline Transform3 & Transform3::setTranslation( const Vector3 & translateVec ) +{ + mCol3 = translateVec; + return *this; +} + +inline const Vector3 Transform3::getTranslation( ) const +{ + return mCol3; +} + +inline const Transform3 Transform3::rotationX( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Transform3( + Vector3::xAxis( ), + Vector3( 0.0f, c, s ), + Vector3( 0.0f, -s, c ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotationY( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Transform3( + Vector3( c, 0.0f, -s ), + Vector3::yAxis( ), + Vector3( s, 0.0f, c ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotationZ( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Transform3( + Vector3( c, s, 0.0f ), + Vector3( -s, c, 0.0f ), + Vector3::zAxis( ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotationZYX( const Vector3 & radiansXYZ ) +{ + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf( radiansXYZ.getX() ); + cX = cosf( radiansXYZ.getX() ); + sY = sinf( radiansXYZ.getY() ); + cY = cosf( radiansXYZ.getY() ); + sZ = sinf( radiansXYZ.getZ() ); + cZ = cosf( radiansXYZ.getZ() ); + tmp0 = ( cZ * sY ); + tmp1 = ( sZ * sY ); + return Transform3( + Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), + Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), + Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotation( float radians, const Vector3 & unitVec ) +{ + return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) ); +} + +inline const Transform3 Transform3::rotation( const Quat & unitQuat ) +{ + return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) ); +} + +inline const Transform3 Transform3::scale( const Vector3 & scaleVec ) +{ + return Transform3( + Vector3( scaleVec.getX(), 0.0f, 0.0f ), + Vector3( 0.0f, scaleVec.getY(), 0.0f ), + Vector3( 0.0f, 0.0f, scaleVec.getZ() ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ) +{ + return Transform3( + ( tfrm.getCol0() * scaleVec.getX( ) ), + ( tfrm.getCol1() * scaleVec.getY( ) ), + ( tfrm.getCol2() * scaleVec.getZ( ) ), + tfrm.getCol3() + ); +} + +inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ) +{ + return Transform3( + mulPerElem( tfrm.getCol0(), scaleVec ), + mulPerElem( tfrm.getCol1(), scaleVec ), + mulPerElem( tfrm.getCol2(), scaleVec ), + mulPerElem( tfrm.getCol3(), scaleVec ) + ); +} + +inline const Transform3 Transform3::translation( const Vector3 & translateVec ) +{ + return Transform3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ), + translateVec + ); +} + +inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ) +{ + return Transform3( + select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), + select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), + select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), + select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Transform3 & tfrm ) +{ + print( tfrm.getRow( 0 ) ); + print( tfrm.getRow( 1 ) ); + print( tfrm.getRow( 2 ) ); +} + +inline void print( const Transform3 & tfrm, const char * name ) +{ + printf("%s:\n", name); + print( tfrm ); +} + +#endif + +inline Quat::Quat( const Matrix3 & tfrm ) +{ + float trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; + int negTrace, ZgtX, ZgtY, YgtX; + int largestXorY, largestYorZ, largestZorX; + + xx = tfrm.getCol0().getX(); + yx = tfrm.getCol0().getY(); + zx = tfrm.getCol0().getZ(); + xy = tfrm.getCol1().getX(); + yy = tfrm.getCol1().getY(); + zy = tfrm.getCol1().getZ(); + xz = tfrm.getCol2().getX(); + yz = tfrm.getCol2().getY(); + zz = tfrm.getCol2().getZ(); + + trace = ( ( xx + yy ) + zz ); + + negTrace = ( trace < 0.0f ); + ZgtX = zz > xx; + ZgtY = zz > yy; + YgtX = yy > xx; + largestXorY = ( !ZgtX || !ZgtY ) && negTrace; + largestYorZ = ( YgtX || ZgtX ) && negTrace; + largestZorX = ( ZgtY || !YgtX ) && negTrace; + + if ( largestXorY ) + { + zz = -zz; + xy = -xy; + } + if ( largestYorZ ) + { + xx = -xx; + yz = -yz; + } + if ( largestZorX ) + { + yy = -yy; + zx = -zx; + } + + radicand = ( ( ( xx + yy ) + zz ) + 1.0f ); + scale = ( 0.5f * ( 1.0f / sqrtf( radicand ) ) ); + + tmpx = ( ( zy - yz ) * scale ); + tmpy = ( ( xz - zx ) * scale ); + tmpz = ( ( yx - xy ) * scale ); + tmpw = ( radicand * scale ); + qx = tmpx; + qy = tmpy; + qz = tmpz; + qw = tmpw; + + if ( largestXorY ) + { + qx = tmpw; + qy = tmpz; + qz = tmpy; + qw = tmpx; + } + if ( largestYorZ ) + { + tmpx = qx; + tmpz = qz; + qx = qy; + qy = tmpx; + qz = qw; + qw = tmpz; + } + + mX = qx; + mY = qy; + mZ = qz; + mW = qw; +} + +inline const Matrix3 outer( const Vector3 & tfrm0, const Vector3 & tfrm1 ) +{ + return Matrix3( + ( tfrm0 * tfrm1.getX( ) ), + ( tfrm0 * tfrm1.getY( ) ), + ( tfrm0 * tfrm1.getZ( ) ) + ); +} + +inline const Matrix4 outer( const Vector4 & tfrm0, const Vector4 & tfrm1 ) +{ + return Matrix4( + ( tfrm0 * tfrm1.getX( ) ), + ( tfrm0 * tfrm1.getY( ) ), + ( tfrm0 * tfrm1.getZ( ) ), + ( tfrm0 * tfrm1.getW( ) ) + ); +} + +inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ) +{ + return Vector3( + ( ( ( vec.getX() * mat.getCol0().getX() ) + ( vec.getY() * mat.getCol0().getY() ) ) + ( vec.getZ() * mat.getCol0().getZ() ) ), + ( ( ( vec.getX() * mat.getCol1().getX() ) + ( vec.getY() * mat.getCol1().getY() ) ) + ( vec.getZ() * mat.getCol1().getZ() ) ), + ( ( ( vec.getX() * mat.getCol2().getX() ) + ( vec.getY() * mat.getCol2().getY() ) ) + ( vec.getZ() * mat.getCol2().getZ() ) ) + ); +} + +inline const Matrix3 crossMatrix( const Vector3 & vec ) +{ + return Matrix3( + Vector3( 0.0f, vec.getZ(), -vec.getY() ), + Vector3( -vec.getZ(), 0.0f, vec.getX() ), + Vector3( vec.getY(), -vec.getX(), 0.0f ) + ); +} + +inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ) +{ + return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); +} + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/Extras/PhysicsEffects/include/vecmath/std/quat_aos.h b/Extras/PhysicsEffects/include/vecmath/std/quat_aos.h new file mode 100644 index 000000000..6a4a0f212 --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/std/quat_aos.h @@ -0,0 +1,446 @@ +/* + Copyright (C) 2006-2010 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _VECTORMATH_QUAT_AOS_CPP_H +#define _VECTORMATH_QUAT_AOS_CPP_H + +//----------------------------------------------------------------------------- +// Definitions + +#ifndef _VECTORMATH_INTERNAL_FUNCTIONS +#define _VECTORMATH_INTERNAL_FUNCTIONS + +#endif + +namespace Vectormath { +namespace Aos { + +inline Quat::Quat( const Quat & quat ) +{ + mX = quat.mX; + mY = quat.mY; + mZ = quat.mZ; + mW = quat.mW; +} + +inline Quat::Quat( float _x, float _y, float _z, float _w ) +{ + mX = _x; + mY = _y; + mZ = _z; + mW = _w; +} + +inline Quat::Quat( const Vector3 & xyz, float _w ) +{ + this->setXYZ( xyz ); + this->setW( _w ); +} + +inline Quat::Quat( const Vector4 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + mW = vec.getW(); +} + +inline Quat::Quat( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; + mW = scalar; +} + +inline const Quat Quat::identity( ) +{ + return Quat( 0.0f, 0.0f, 0.0f, 1.0f ); +} + +inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ) +{ + return ( quat0 + ( ( quat1 - quat0 ) * t ) ); +} + +inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ) +{ + Quat start; + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot( unitQuat0, unitQuat1 ); + if ( cosAngle < 0.0f ) { + cosAngle = -cosAngle; + start = ( -unitQuat0 ); + } else { + start = unitQuat0; + } + if ( cosAngle < _VECTORMATH_SLERP_TOL ) { + angle = acosf( cosAngle ); + recipSinAngle = ( 1.0f / sinf( angle ) ); + scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); + scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); + } else { + scale0 = ( 1.0f - t ); + scale1 = t; + } + return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) ); +} + +inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ) +{ + Quat tmp0, tmp1; + tmp0 = slerp( t, unitQuat0, unitQuat3 ); + tmp1 = slerp( t, unitQuat1, unitQuat2 ); + return slerp( ( ( 2.0f * t ) * ( 1.0f - t ) ), tmp0, tmp1 ); +} + +inline void loadXYZW( Quat & quat, const float * fptr ) +{ + quat = Quat( fptr[0], fptr[1], fptr[2], fptr[3] ); +} + +inline void storeXYZW( const Quat & quat, float * fptr ) +{ + fptr[0] = quat.getX(); + fptr[1] = quat.getY(); + fptr[2] = quat.getZ(); + fptr[3] = quat.getW(); +} + +inline Quat & Quat::operator =( const Quat & quat ) +{ + mX = quat.mX; + mY = quat.mY; + mZ = quat.mZ; + mW = quat.mW; + return *this; +} + +inline Quat & Quat::setXYZ( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + return *this; +} + +inline const Vector3 Quat::getXYZ( ) const +{ + return Vector3( mX, mY, mZ ); +} + +inline Quat & Quat::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Quat::getX( ) const +{ + return mX; +} + +inline Quat & Quat::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Quat::getY( ) const +{ + return mY; +} + +inline Quat & Quat::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Quat::getZ( ) const +{ + return mZ; +} + +inline Quat & Quat::setW( float _w ) +{ + mW = _w; + return *this; +} + +inline float Quat::getW( ) const +{ + return mW; +} + +inline Quat & Quat::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Quat::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Quat::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Quat::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Quat Quat::operator +( const Quat & quat ) const +{ + return Quat( + ( mX + quat.mX ), + ( mY + quat.mY ), + ( mZ + quat.mZ ), + ( mW + quat.mW ) + ); +} + +inline const Quat Quat::operator -( const Quat & quat ) const +{ + return Quat( + ( mX - quat.mX ), + ( mY - quat.mY ), + ( mZ - quat.mZ ), + ( mW - quat.mW ) + ); +} + +inline const Quat Quat::operator *( float scalar ) const +{ + return Quat( + ( mX * scalar ), + ( mY * scalar ), + ( mZ * scalar ), + ( mW * scalar ) + ); +} + +inline Quat & Quat::operator +=( const Quat & quat ) +{ + *this = *this + quat; + return *this; +} + +inline Quat & Quat::operator -=( const Quat & quat ) +{ + *this = *this - quat; + return *this; +} + +inline Quat & Quat::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Quat Quat::operator /( float scalar ) const +{ + return Quat( + ( mX / scalar ), + ( mY / scalar ), + ( mZ / scalar ), + ( mW / scalar ) + ); +} + +inline Quat & Quat::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +inline const Quat Quat::operator -( ) const +{ + return Quat( + -mX, + -mY, + -mZ, + -mW + ); +} + +inline const Quat operator *( float scalar, const Quat & quat ) +{ + return quat * scalar; +} + +inline float dot( const Quat & quat0, const Quat & quat1 ) +{ + float result; + result = ( quat0.getX() * quat1.getX() ); + result = ( result + ( quat0.getY() * quat1.getY() ) ); + result = ( result + ( quat0.getZ() * quat1.getZ() ) ); + result = ( result + ( quat0.getW() * quat1.getW() ) ); + return result; +} + +inline float norm( const Quat & quat ) +{ + float result; + result = ( quat.getX() * quat.getX() ); + result = ( result + ( quat.getY() * quat.getY() ) ); + result = ( result + ( quat.getZ() * quat.getZ() ) ); + result = ( result + ( quat.getW() * quat.getW() ) ); + return result; +} + +inline float length( const Quat & quat ) +{ + return ::sqrtf( norm( quat ) ); +} + +inline const Quat normalize( const Quat & quat ) +{ + float lenSqr, lenInv; + lenSqr = norm( quat ); + lenInv = ( 1.0f / sqrtf( lenSqr ) ); + return Quat( + ( quat.getX() * lenInv ), + ( quat.getY() * lenInv ), + ( quat.getZ() * lenInv ), + ( quat.getW() * lenInv ) + ); +} + +inline const Quat Quat::rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ) +{ + float cosHalfAngleX2, recipCosHalfAngleX2; + cosHalfAngleX2 = sqrtf( ( 2.0f * ( 1.0f + dot( unitVec0, unitVec1 ) ) ) ); + recipCosHalfAngleX2 = ( 1.0f / cosHalfAngleX2 ); + return Quat( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), ( cosHalfAngleX2 * 0.5f ) ); +} + +inline const Quat Quat::rotation( float radians, const Vector3 & unitVec ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( ( unitVec * s ), c ); +} + +inline const Quat Quat::rotationX( float radians ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( s, 0.0f, 0.0f, c ); +} + +inline const Quat Quat::rotationY( float radians ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( 0.0f, s, 0.0f, c ); +} + +inline const Quat Quat::rotationZ( float radians ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( 0.0f, 0.0f, s, c ); +} + +inline const Quat Quat::operator *( const Quat & quat ) const +{ + return Quat( + ( ( ( ( mW * quat.mX ) + ( mX * quat.mW ) ) + ( mY * quat.mZ ) ) - ( mZ * quat.mY ) ), + ( ( ( ( mW * quat.mY ) + ( mY * quat.mW ) ) + ( mZ * quat.mX ) ) - ( mX * quat.mZ ) ), + ( ( ( ( mW * quat.mZ ) + ( mZ * quat.mW ) ) + ( mX * quat.mY ) ) - ( mY * quat.mX ) ), + ( ( ( ( mW * quat.mW ) - ( mX * quat.mX ) ) - ( mY * quat.mY ) ) - ( mZ * quat.mZ ) ) + ); +} + +inline Quat & Quat::operator *=( const Quat & quat ) +{ + *this = *this * quat; + return *this; +} + +inline const Vector3 rotate( const Quat & quat, const Vector3 & vec ) +{ + float tmpX, tmpY, tmpZ, tmpW; + tmpX = ( ( ( quat.getW() * vec.getX() ) + ( quat.getY() * vec.getZ() ) ) - ( quat.getZ() * vec.getY() ) ); + tmpY = ( ( ( quat.getW() * vec.getY() ) + ( quat.getZ() * vec.getX() ) ) - ( quat.getX() * vec.getZ() ) ); + tmpZ = ( ( ( quat.getW() * vec.getZ() ) + ( quat.getX() * vec.getY() ) ) - ( quat.getY() * vec.getX() ) ); + tmpW = ( ( ( quat.getX() * vec.getX() ) + ( quat.getY() * vec.getY() ) ) + ( quat.getZ() * vec.getZ() ) ); + return Vector3( + ( ( ( ( tmpW * quat.getX() ) + ( tmpX * quat.getW() ) ) - ( tmpY * quat.getZ() ) ) + ( tmpZ * quat.getY() ) ), + ( ( ( ( tmpW * quat.getY() ) + ( tmpY * quat.getW() ) ) - ( tmpZ * quat.getX() ) ) + ( tmpX * quat.getZ() ) ), + ( ( ( ( tmpW * quat.getZ() ) + ( tmpZ * quat.getW() ) ) - ( tmpX * quat.getY() ) ) + ( tmpY * quat.getX() ) ) + ); +} + +inline const Quat conj( const Quat & quat ) +{ + return Quat( -quat.getX(), -quat.getY(), -quat.getZ(), quat.getW() ); +} + +inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ) +{ + return Quat( + ( select1 )? quat1.getX() : quat0.getX(), + ( select1 )? quat1.getY() : quat0.getY(), + ( select1 )? quat1.getZ() : quat0.getZ(), + ( select1 )? quat1.getW() : quat0.getW() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Quat & quat ) +{ + printf( "( %f %f %f %f )\n", quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); +} + +inline void print( const Quat & quat, const char * name ) +{ + printf( "%s: ( %f %f %f %f )\n", name, quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); +} + +#endif + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/Extras/PhysicsEffects/include/vecmath/std/vec_aos.h b/Extras/PhysicsEffects/include/vecmath/std/vec_aos.h new file mode 100644 index 000000000..7dcd2526b --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/std/vec_aos.h @@ -0,0 +1,1439 @@ +/* + Copyright (C) 2006-2010 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _VECTORMATH_VEC_AOS_CPP_H +#define _VECTORMATH_VEC_AOS_CPP_H + +//----------------------------------------------------------------------------- +// Constants + +#define _VECTORMATH_SLERP_TOL 0.999f + +//----------------------------------------------------------------------------- +// Definitions + +#ifndef _VECTORMATH_INTERNAL_FUNCTIONS +#define _VECTORMATH_INTERNAL_FUNCTIONS + +#endif + +namespace Vectormath { +namespace Aos { + +inline Vector3::Vector3( const Vector3 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; +} + +inline Vector3::Vector3( float _x, float _y, float _z ) +{ + mX = _x; + mY = _y; + mZ = _z; +} + +inline Vector3::Vector3( const Point3 & pnt ) +{ + mX = pnt.getX(); + mY = pnt.getY(); + mZ = pnt.getZ(); +} + +inline Vector3::Vector3( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; +} + +inline const Vector3 Vector3::xAxis( ) +{ + return Vector3( 1.0f, 0.0f, 0.0f ); +} + +inline const Vector3 Vector3::yAxis( ) +{ + return Vector3( 0.0f, 1.0f, 0.0f ); +} + +inline const Vector3 Vector3::zAxis( ) +{ + return Vector3( 0.0f, 0.0f, 1.0f ); +} + +inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ) +{ + return ( vec0 + ( ( vec1 - vec0 ) * t ) ); +} + +inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ) +{ + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot( unitVec0, unitVec1 ); + if ( cosAngle < _VECTORMATH_SLERP_TOL ) { + angle = acosf( cosAngle ); + recipSinAngle = ( 1.0f / sinf( angle ) ); + scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); + scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); + } else { + scale0 = ( 1.0f - t ); + scale1 = t; + } + return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); +} + +inline void loadXYZ( Vector3 & vec, const float * fptr ) +{ + vec = Vector3( fptr[0], fptr[1], fptr[2] ); +} + +inline void storeXYZ( const Vector3 & vec, float * fptr ) +{ + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); +} + +inline void loadHalfFloats( Vector3 & vec, const unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); + + if (exponent == 0) { + // zero + mantissa = 0; + + } else if (exponent == 31) { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + + } else { + exponent += 127 - 15; + mantissa <<= 13; + } + + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } +} + +inline void storeHalfFloats( const Vector3 & vec, unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + Data32 d; + d.f32 = vec[i]; + + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + + if (exponent == 0) { + // zero or denorm -> zero + mantissa = 0; + + } else if (exponent == 255 && mantissa != 0) { + // nan -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent >= 127 - 15 + 31) { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent <= 127 - 15) { + // underflow -> zero + exponent = 0; + mantissa = 0; + + } else { + exponent -= 127 - 15; + mantissa >>= 13; + } + + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } +} + +inline Vector3 & Vector3::operator =( const Vector3 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + return *this; +} + +inline Vector3 & Vector3::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Vector3::getX( ) const +{ + return mX; +} + +inline Vector3 & Vector3::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Vector3::getY( ) const +{ + return mY; +} + +inline Vector3 & Vector3::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Vector3::getZ( ) const +{ + return mZ; +} + +inline Vector3 & Vector3::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Vector3::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Vector3::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Vector3::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Vector3 Vector3::operator +( const Vector3 & vec ) const +{ + return Vector3( + ( mX + vec.mX ), + ( mY + vec.mY ), + ( mZ + vec.mZ ) + ); +} + +inline const Vector3 Vector3::operator -( const Vector3 & vec ) const +{ + return Vector3( + ( mX - vec.mX ), + ( mY - vec.mY ), + ( mZ - vec.mZ ) + ); +} + +inline const Point3 Vector3::operator +( const Point3 & pnt ) const +{ + return Point3( + ( mX + pnt.getX() ), + ( mY + pnt.getY() ), + ( mZ + pnt.getZ() ) + ); +} + +inline const Vector3 Vector3::operator *( float scalar ) const +{ + return Vector3( + ( mX * scalar ), + ( mY * scalar ), + ( mZ * scalar ) + ); +} + +inline Vector3 & Vector3::operator +=( const Vector3 & vec ) +{ + *this = *this + vec; + return *this; +} + +inline Vector3 & Vector3::operator -=( const Vector3 & vec ) +{ + *this = *this - vec; + return *this; +} + +inline Vector3 & Vector3::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Vector3 Vector3::operator /( float scalar ) const +{ + return Vector3( + ( mX / scalar ), + ( mY / scalar ), + ( mZ / scalar ) + ); +} + +inline Vector3 & Vector3::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +inline const Vector3 Vector3::operator -( ) const +{ + return Vector3( + -mX, + -mY, + -mZ + ); +} + +inline const Vector3 operator *( float scalar, const Vector3 & vec ) +{ + return vec * scalar; +} + +inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( vec0.getX() * vec1.getX() ), + ( vec0.getY() * vec1.getY() ), + ( vec0.getZ() * vec1.getZ() ) + ); +} + +inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( vec0.getX() / vec1.getX() ), + ( vec0.getY() / vec1.getY() ), + ( vec0.getZ() / vec1.getZ() ) + ); +} + +inline const Vector3 recipPerElem( const Vector3 & vec ) +{ + return Vector3( + ( 1.0f / vec.getX() ), + ( 1.0f / vec.getY() ), + ( 1.0f / vec.getZ() ) + ); +} + +inline const Vector3 sqrtPerElem( const Vector3 & vec ) +{ + return Vector3( + sqrtf( vec.getX() ), + sqrtf( vec.getY() ), + sqrtf( vec.getZ() ) + ); +} + +inline const Vector3 rsqrtPerElem( const Vector3 & vec ) +{ + return Vector3( + ( 1.0f / sqrtf( vec.getX() ) ), + ( 1.0f / sqrtf( vec.getY() ) ), + ( 1.0f / sqrtf( vec.getZ() ) ) + ); +} + +inline const Vector3 absPerElem( const Vector3 & vec ) +{ + return Vector3( + fabsf( vec.getX() ), + fabsf( vec.getY() ), + fabsf( vec.getZ() ) + ); +} + +inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), + ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), + ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ) + ); +} + +inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ() + ); +} + +inline float maxElem( const Vector3 & vec ) +{ + float result; + result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() > result)? vec.getZ() : result; + return result; +} + +inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ() + ); +} + +inline float minElem( const Vector3 & vec ) +{ + float result; + result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() < result)? vec.getZ() : result; + return result; +} + +inline float sum( const Vector3 & vec ) +{ + float result; + result = ( vec.getX() + vec.getY() ); + result = ( result + vec.getZ() ); + return result; +} + +inline float dot( const Vector3 & vec0, const Vector3 & vec1 ) +{ + float result; + result = ( vec0.getX() * vec1.getX() ); + result = ( result + ( vec0.getY() * vec1.getY() ) ); + result = ( result + ( vec0.getZ() * vec1.getZ() ) ); + return result; +} + +inline float lengthSqr( const Vector3 & vec ) +{ + float result; + result = ( vec.getX() * vec.getX() ); + result = ( result + ( vec.getY() * vec.getY() ) ); + result = ( result + ( vec.getZ() * vec.getZ() ) ); + return result; +} + +inline float length( const Vector3 & vec ) +{ + return ::sqrtf( lengthSqr( vec ) ); +} + +inline const Vector3 normalize( const Vector3 & vec ) +{ + float lenSqr, lenInv; + lenSqr = lengthSqr( vec ); + lenInv = ( 1.0f / sqrtf( lenSqr ) ); + return Vector3( + ( vec.getX() * lenInv ), + ( vec.getY() * lenInv ), + ( vec.getZ() * lenInv ) + ); +} + +inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( ( vec0.getY() * vec1.getZ() ) - ( vec0.getZ() * vec1.getY() ) ), + ( ( vec0.getZ() * vec1.getX() ) - ( vec0.getX() * vec1.getZ() ) ), + ( ( vec0.getX() * vec1.getY() ) - ( vec0.getY() * vec1.getX() ) ) + ); +} + +inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ) +{ + return Vector3( + ( select1 )? vec1.getX() : vec0.getX(), + ( select1 )? vec1.getY() : vec0.getY(), + ( select1 )? vec1.getZ() : vec0.getZ() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Vector3 & vec ) +{ + printf( "( %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ() ); +} + +inline void print( const Vector3 & vec, const char * name ) +{ + printf( "%s: ( %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ() ); +} + +#endif + +inline Vector4::Vector4( const Vector4 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + mW = vec.mW; +} + +inline Vector4::Vector4( float _x, float _y, float _z, float _w ) +{ + mX = _x; + mY = _y; + mZ = _z; + mW = _w; +} + +inline Vector4::Vector4( const Vector3 & xyz, float _w ) +{ + this->setXYZ( xyz ); + this->setW( _w ); +} + +inline Vector4::Vector4( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + mW = 0.0f; +} + +inline Vector4::Vector4( const Point3 & pnt ) +{ + mX = pnt.getX(); + mY = pnt.getY(); + mZ = pnt.getZ(); + mW = 1.0f; +} + +inline Vector4::Vector4( const Quat & quat ) +{ + mX = quat.getX(); + mY = quat.getY(); + mZ = quat.getZ(); + mW = quat.getW(); +} + +inline Vector4::Vector4( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; + mW = scalar; +} + +inline const Vector4 Vector4::xAxis( ) +{ + return Vector4( 1.0f, 0.0f, 0.0f, 0.0f ); +} + +inline const Vector4 Vector4::yAxis( ) +{ + return Vector4( 0.0f, 1.0f, 0.0f, 0.0f ); +} + +inline const Vector4 Vector4::zAxis( ) +{ + return Vector4( 0.0f, 0.0f, 1.0f, 0.0f ); +} + +inline const Vector4 Vector4::wAxis( ) +{ + return Vector4( 0.0f, 0.0f, 0.0f, 1.0f ); +} + +inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ) +{ + return ( vec0 + ( ( vec1 - vec0 ) * t ) ); +} + +inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ) +{ + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot( unitVec0, unitVec1 ); + if ( cosAngle < _VECTORMATH_SLERP_TOL ) { + angle = acosf( cosAngle ); + recipSinAngle = ( 1.0f / sinf( angle ) ); + scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); + scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); + } else { + scale0 = ( 1.0f - t ); + scale1 = t; + } + return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); +} + +inline void loadXYZW( Vector4 & vec, const float * fptr ) +{ + vec = Vector4( fptr[0], fptr[1], fptr[2], fptr[3] ); +} + +inline void storeXYZW( const Vector4 & vec, float * fptr ) +{ + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); + fptr[3] = vec.getW(); +} + +inline void loadHalfFloats( Vector4 & vec, const unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 4; i++) { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); + + if (exponent == 0) { + // zero + mantissa = 0; + + } else if (exponent == 31) { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + + } else { + exponent += 127 - 15; + mantissa <<= 13; + } + + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } +} + +inline void storeHalfFloats( const Vector4 & vec, unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 4; i++) { + Data32 d; + d.f32 = vec[i]; + + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + + if (exponent == 0) { + // zero or denorm -> zero + mantissa = 0; + + } else if (exponent == 255 && mantissa != 0) { + // nan -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent >= 127 - 15 + 31) { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent <= 127 - 15) { + // underflow -> zero + exponent = 0; + mantissa = 0; + + } else { + exponent -= 127 - 15; + mantissa >>= 13; + } + + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } +} + +inline Vector4 & Vector4::operator =( const Vector4 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + mW = vec.mW; + return *this; +} + +inline Vector4 & Vector4::setXYZ( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + return *this; +} + +inline const Vector3 Vector4::getXYZ( ) const +{ + return Vector3( mX, mY, mZ ); +} + +inline Vector4 & Vector4::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Vector4::getX( ) const +{ + return mX; +} + +inline Vector4 & Vector4::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Vector4::getY( ) const +{ + return mY; +} + +inline Vector4 & Vector4::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Vector4::getZ( ) const +{ + return mZ; +} + +inline Vector4 & Vector4::setW( float _w ) +{ + mW = _w; + return *this; +} + +inline float Vector4::getW( ) const +{ + return mW; +} + +inline Vector4 & Vector4::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Vector4::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Vector4::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Vector4::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Vector4 Vector4::operator +( const Vector4 & vec ) const +{ + return Vector4( + ( mX + vec.mX ), + ( mY + vec.mY ), + ( mZ + vec.mZ ), + ( mW + vec.mW ) + ); +} + +inline const Vector4 Vector4::operator -( const Vector4 & vec ) const +{ + return Vector4( + ( mX - vec.mX ), + ( mY - vec.mY ), + ( mZ - vec.mZ ), + ( mW - vec.mW ) + ); +} + +inline const Vector4 Vector4::operator *( float scalar ) const +{ + return Vector4( + ( mX * scalar ), + ( mY * scalar ), + ( mZ * scalar ), + ( mW * scalar ) + ); +} + +inline Vector4 & Vector4::operator +=( const Vector4 & vec ) +{ + *this = *this + vec; + return *this; +} + +inline Vector4 & Vector4::operator -=( const Vector4 & vec ) +{ + *this = *this - vec; + return *this; +} + +inline Vector4 & Vector4::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Vector4 Vector4::operator /( float scalar ) const +{ + return Vector4( + ( mX / scalar ), + ( mY / scalar ), + ( mZ / scalar ), + ( mW / scalar ) + ); +} + +inline Vector4 & Vector4::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +inline const Vector4 Vector4::operator -( ) const +{ + return Vector4( + -mX, + -mY, + -mZ, + -mW + ); +} + +inline const Vector4 operator *( float scalar, const Vector4 & vec ) +{ + return vec * scalar; +} + +inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + ( vec0.getX() * vec1.getX() ), + ( vec0.getY() * vec1.getY() ), + ( vec0.getZ() * vec1.getZ() ), + ( vec0.getW() * vec1.getW() ) + ); +} + +inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + ( vec0.getX() / vec1.getX() ), + ( vec0.getY() / vec1.getY() ), + ( vec0.getZ() / vec1.getZ() ), + ( vec0.getW() / vec1.getW() ) + ); +} + +inline const Vector4 recipPerElem( const Vector4 & vec ) +{ + return Vector4( + ( 1.0f / vec.getX() ), + ( 1.0f / vec.getY() ), + ( 1.0f / vec.getZ() ), + ( 1.0f / vec.getW() ) + ); +} + +inline const Vector4 sqrtPerElem( const Vector4 & vec ) +{ + return Vector4( + sqrtf( vec.getX() ), + sqrtf( vec.getY() ), + sqrtf( vec.getZ() ), + sqrtf( vec.getW() ) + ); +} + +inline const Vector4 rsqrtPerElem( const Vector4 & vec ) +{ + return Vector4( + ( 1.0f / sqrtf( vec.getX() ) ), + ( 1.0f / sqrtf( vec.getY() ) ), + ( 1.0f / sqrtf( vec.getZ() ) ), + ( 1.0f / sqrtf( vec.getW() ) ) + ); +} + +inline const Vector4 absPerElem( const Vector4 & vec ) +{ + return Vector4( + fabsf( vec.getX() ), + fabsf( vec.getY() ), + fabsf( vec.getZ() ), + fabsf( vec.getW() ) + ); +} + +inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), + ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), + ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ), + ( vec1.getW() < 0.0f )? -fabsf( vec0.getW() ) : fabsf( vec0.getW() ) + ); +} + +inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ(), + (vec0.getW() > vec1.getW())? vec0.getW() : vec1.getW() + ); +} + +inline float maxElem( const Vector4 & vec ) +{ + float result; + result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() > result)? vec.getZ() : result; + result = (vec.getW() > result)? vec.getW() : result; + return result; +} + +inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ(), + (vec0.getW() < vec1.getW())? vec0.getW() : vec1.getW() + ); +} + +inline float minElem( const Vector4 & vec ) +{ + float result; + result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() < result)? vec.getZ() : result; + result = (vec.getW() < result)? vec.getW() : result; + return result; +} + +inline float sum( const Vector4 & vec ) +{ + float result; + result = ( vec.getX() + vec.getY() ); + result = ( result + vec.getZ() ); + result = ( result + vec.getW() ); + return result; +} + +inline float dot( const Vector4 & vec0, const Vector4 & vec1 ) +{ + float result; + result = ( vec0.getX() * vec1.getX() ); + result = ( result + ( vec0.getY() * vec1.getY() ) ); + result = ( result + ( vec0.getZ() * vec1.getZ() ) ); + result = ( result + ( vec0.getW() * vec1.getW() ) ); + return result; +} + +inline float lengthSqr( const Vector4 & vec ) +{ + float result; + result = ( vec.getX() * vec.getX() ); + result = ( result + ( vec.getY() * vec.getY() ) ); + result = ( result + ( vec.getZ() * vec.getZ() ) ); + result = ( result + ( vec.getW() * vec.getW() ) ); + return result; +} + +inline float length( const Vector4 & vec ) +{ + return ::sqrtf( lengthSqr( vec ) ); +} + +inline const Vector4 normalize( const Vector4 & vec ) +{ + float lenSqr, lenInv; + lenSqr = lengthSqr( vec ); + lenInv = ( 1.0f / sqrtf( lenSqr ) ); + return Vector4( + ( vec.getX() * lenInv ), + ( vec.getY() * lenInv ), + ( vec.getZ() * lenInv ), + ( vec.getW() * lenInv ) + ); +} + +inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ) +{ + return Vector4( + ( select1 )? vec1.getX() : vec0.getX(), + ( select1 )? vec1.getY() : vec0.getY(), + ( select1 )? vec1.getZ() : vec0.getZ(), + ( select1 )? vec1.getW() : vec0.getW() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Vector4 & vec ) +{ + printf( "( %f %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); +} + +inline void print( const Vector4 & vec, const char * name ) +{ + printf( "%s: ( %f %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); +} + +#endif + +inline Point3::Point3( const Point3 & pnt ) +{ + mX = pnt.mX; + mY = pnt.mY; + mZ = pnt.mZ; +} + +inline Point3::Point3( float _x, float _y, float _z ) +{ + mX = _x; + mY = _y; + mZ = _z; +} + +inline Point3::Point3( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); +} + +inline Point3::Point3( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; +} + +inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ) +{ + return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); +} + +inline void loadXYZ( Point3 & pnt, const float * fptr ) +{ + pnt = Point3( fptr[0], fptr[1], fptr[2] ); +} + +inline void storeXYZ( const Point3 & pnt, float * fptr ) +{ + fptr[0] = pnt.getX(); + fptr[1] = pnt.getY(); + fptr[2] = pnt.getZ(); +} + +inline void loadHalfFloats( Point3 & vec, const unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); + + if (exponent == 0) { + // zero + mantissa = 0; + + } else if (exponent == 31) { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + + } else { + exponent += 127 - 15; + mantissa <<= 13; + } + + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } +} + +inline void storeHalfFloats( const Point3 & vec, unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + Data32 d; + d.f32 = vec[i]; + + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + + if (exponent == 0) { + // zero or denorm -> zero + mantissa = 0; + + } else if (exponent == 255 && mantissa != 0) { + // nan -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent >= 127 - 15 + 31) { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent <= 127 - 15) { + // underflow -> zero + exponent = 0; + mantissa = 0; + + } else { + exponent -= 127 - 15; + mantissa >>= 13; + } + + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } +} + +inline Point3 & Point3::operator =( const Point3 & pnt ) +{ + mX = pnt.mX; + mY = pnt.mY; + mZ = pnt.mZ; + return *this; +} + +inline Point3 & Point3::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Point3::getX( ) const +{ + return mX; +} + +inline Point3 & Point3::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Point3::getY( ) const +{ + return mY; +} + +inline Point3 & Point3::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Point3::getZ( ) const +{ + return mZ; +} + +inline Point3 & Point3::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Point3::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Point3::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Point3::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Vector3 Point3::operator -( const Point3 & pnt ) const +{ + return Vector3( + ( mX - pnt.mX ), + ( mY - pnt.mY ), + ( mZ - pnt.mZ ) + ); +} + +inline const Point3 Point3::operator +( const Vector3 & vec ) const +{ + return Point3( + ( mX + vec.getX() ), + ( mY + vec.getY() ), + ( mZ + vec.getZ() ) + ); +} + +inline const Point3 Point3::operator -( const Vector3 & vec ) const +{ + return Point3( + ( mX - vec.getX() ), + ( mY - vec.getY() ), + ( mZ - vec.getZ() ) + ); +} + +inline Point3 & Point3::operator +=( const Vector3 & vec ) +{ + *this = *this + vec; + return *this; +} + +inline Point3 & Point3::operator -=( const Vector3 & vec ) +{ + *this = *this - vec; + return *this; +} + +inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + ( pnt0.getX() * pnt1.getX() ), + ( pnt0.getY() * pnt1.getY() ), + ( pnt0.getZ() * pnt1.getZ() ) + ); +} + +inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + ( pnt0.getX() / pnt1.getX() ), + ( pnt0.getY() / pnt1.getY() ), + ( pnt0.getZ() / pnt1.getZ() ) + ); +} + +inline const Point3 recipPerElem( const Point3 & pnt ) +{ + return Point3( + ( 1.0f / pnt.getX() ), + ( 1.0f / pnt.getY() ), + ( 1.0f / pnt.getZ() ) + ); +} + +inline const Point3 sqrtPerElem( const Point3 & pnt ) +{ + return Point3( + sqrtf( pnt.getX() ), + sqrtf( pnt.getY() ), + sqrtf( pnt.getZ() ) + ); +} + +inline const Point3 rsqrtPerElem( const Point3 & pnt ) +{ + return Point3( + ( 1.0f / sqrtf( pnt.getX() ) ), + ( 1.0f / sqrtf( pnt.getY() ) ), + ( 1.0f / sqrtf( pnt.getZ() ) ) + ); +} + +inline const Point3 absPerElem( const Point3 & pnt ) +{ + return Point3( + fabsf( pnt.getX() ), + fabsf( pnt.getY() ), + fabsf( pnt.getZ() ) + ); +} + +inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + ( pnt1.getX() < 0.0f )? -fabsf( pnt0.getX() ) : fabsf( pnt0.getX() ), + ( pnt1.getY() < 0.0f )? -fabsf( pnt0.getY() ) : fabsf( pnt0.getY() ), + ( pnt1.getZ() < 0.0f )? -fabsf( pnt0.getZ() ) : fabsf( pnt0.getZ() ) + ); +} + +inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + (pnt0.getX() > pnt1.getX())? pnt0.getX() : pnt1.getX(), + (pnt0.getY() > pnt1.getY())? pnt0.getY() : pnt1.getY(), + (pnt0.getZ() > pnt1.getZ())? pnt0.getZ() : pnt1.getZ() + ); +} + +inline float maxElem( const Point3 & pnt ) +{ + float result; + result = (pnt.getX() > pnt.getY())? pnt.getX() : pnt.getY(); + result = (pnt.getZ() > result)? pnt.getZ() : result; + return result; +} + +inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + (pnt0.getX() < pnt1.getX())? pnt0.getX() : pnt1.getX(), + (pnt0.getY() < pnt1.getY())? pnt0.getY() : pnt1.getY(), + (pnt0.getZ() < pnt1.getZ())? pnt0.getZ() : pnt1.getZ() + ); +} + +inline float minElem( const Point3 & pnt ) +{ + float result; + result = (pnt.getX() < pnt.getY())? pnt.getX() : pnt.getY(); + result = (pnt.getZ() < result)? pnt.getZ() : result; + return result; +} + +inline float sum( const Point3 & pnt ) +{ + float result; + result = ( pnt.getX() + pnt.getY() ); + result = ( result + pnt.getZ() ); + return result; +} + +inline const Point3 scale( const Point3 & pnt, float scaleVal ) +{ + return mulPerElem( pnt, Point3( scaleVal ) ); +} + +inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ) +{ + return mulPerElem( pnt, Point3( scaleVec ) ); +} + +inline float projection( const Point3 & pnt, const Vector3 & unitVec ) +{ + float result; + result = ( pnt.getX() * unitVec.getX() ); + result = ( result + ( pnt.getY() * unitVec.getY() ) ); + result = ( result + ( pnt.getZ() * unitVec.getZ() ) ); + return result; +} + +inline float distSqrFromOrigin( const Point3 & pnt ) +{ + return lengthSqr( Vector3( pnt ) ); +} + +inline float distFromOrigin( const Point3 & pnt ) +{ + return length( Vector3( pnt ) ); +} + +inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return lengthSqr( ( pnt1 - pnt0 ) ); +} + +inline float dist( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return length( ( pnt1 - pnt0 ) ); +} + +inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ) +{ + return Point3( + ( select1 )? pnt1.getX() : pnt0.getX(), + ( select1 )? pnt1.getY() : pnt0.getY(), + ( select1 )? pnt1.getZ() : pnt0.getZ() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Point3 & pnt ) +{ + printf( "( %f %f %f )\n", pnt.getX(), pnt.getY(), pnt.getZ() ); +} + +inline void print( const Point3 & pnt, const char * name ) +{ + printf( "%s: ( %f %f %f )\n", name, pnt.getX(), pnt.getY(), pnt.getZ() ); +} + +#endif + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/Extras/PhysicsEffects/include/vecmath/std/vectormath_aos.h b/Extras/PhysicsEffects/include/vecmath/std/vectormath_aos.h new file mode 100644 index 000000000..c1f39858c --- /dev/null +++ b/Extras/PhysicsEffects/include/vecmath/std/vectormath_aos.h @@ -0,0 +1,1885 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _VECTORMATH_AOS_CPP_SCALAR_H +#define _VECTORMATH_AOS_CPP_SCALAR_H + +#include + +#ifdef _VECTORMATH_DEBUG +#include +#endif + +namespace Vectormath { + +namespace Aos { + +//----------------------------------------------------------------------------- +// Forward Declarations +// + +class Vector3; +class Vector4; +class Point3; +class Quat; +class Matrix3; +class Matrix4; +class Transform3; + +// A 3-D vector in array-of-structures format +// +class Vector3 +{ + float mX; + float mY; + float mZ; +#ifndef __GNUC__ + float d; +#endif + +public: + // Default constructor; does no initialization + // + inline Vector3( ) { }; + + // Copy a 3-D vector + // + inline Vector3( const Vector3 & vec ); + + // Construct a 3-D vector from x, y, and z elements + // + inline Vector3( float x, float y, float z ); + + // Copy elements from a 3-D point into a 3-D vector + // + explicit inline Vector3( const Point3 & pnt ); + + // Set all elements of a 3-D vector to the same scalar value + // + explicit inline Vector3( float scalar ); + + // Assign one 3-D vector to another + // + inline Vector3 & operator =( const Vector3 & vec ); + + // Set the x element of a 3-D vector + // + inline Vector3 & setX( float x ); + + // Set the y element of a 3-D vector + // + inline Vector3 & setY( float y ); + + // Set the z element of a 3-D vector + // + inline Vector3 & setZ( float z ); + + // Get the x element of a 3-D vector + // + inline float getX( ) const; + + // Get the y element of a 3-D vector + // + inline float getY( ) const; + + // Get the z element of a 3-D vector + // + inline float getZ( ) const; + + // Set an x, y, or z element of a 3-D vector by index + // + inline Vector3 & setElem( int idx, float value ); + + // Get an x, y, or z element of a 3-D vector by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Add two 3-D vectors + // + inline const Vector3 operator +( const Vector3 & vec ) const; + + // Subtract a 3-D vector from another 3-D vector + // + inline const Vector3 operator -( const Vector3 & vec ) const; + + // Add a 3-D vector to a 3-D point + // + inline const Point3 operator +( const Point3 & pnt ) const; + + // Multiply a 3-D vector by a scalar + // + inline const Vector3 operator *( float scalar ) const; + + // Divide a 3-D vector by a scalar + // + inline const Vector3 operator /( float scalar ) const; + + // Perform compound assignment and addition with a 3-D vector + // + inline Vector3 & operator +=( const Vector3 & vec ); + + // Perform compound assignment and subtraction by a 3-D vector + // + inline Vector3 & operator -=( const Vector3 & vec ); + + // Perform compound assignment and multiplication by a scalar + // + inline Vector3 & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + inline Vector3 & operator /=( float scalar ); + + // Negate all elements of a 3-D vector + // + inline const Vector3 operator -( ) const; + + // Construct x axis + // + static inline const Vector3 xAxis( ); + + // Construct y axis + // + static inline const Vector3 yAxis( ); + + // Construct z axis + // + static inline const Vector3 zAxis( ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply a 3-D vector by a scalar +// +inline const Vector3 operator *( float scalar, const Vector3 & vec ); + +// Multiply two 3-D vectors per element +// +inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Divide two 3-D vectors per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Compute the reciprocal of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +inline const Vector3 recipPerElem( const Vector3 & vec ); + +// Compute the square root of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function sqrtf4. +// +inline const Vector3 sqrtPerElem( const Vector3 & vec ); + +// Compute the reciprocal square root of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function rsqrtf4. +// +inline const Vector3 rsqrtPerElem( const Vector3 & vec ); + +// Compute the absolute value of a 3-D vector per element +// +inline const Vector3 absPerElem( const Vector3 & vec ); + +// Copy sign from one 3-D vector to another, per element +// +inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Maximum of two 3-D vectors per element +// +inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Minimum of two 3-D vectors per element +// +inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Maximum element of a 3-D vector +// +inline float maxElem( const Vector3 & vec ); + +// Minimum element of a 3-D vector +// +inline float minElem( const Vector3 & vec ); + +// Compute the sum of all elements of a 3-D vector +// +inline float sum( const Vector3 & vec ); + +// Compute the dot product of two 3-D vectors +// +inline float dot( const Vector3 & vec0, const Vector3 & vec1 ); + +// Compute the square of the length of a 3-D vector +// +inline float lengthSqr( const Vector3 & vec ); + +// Compute the length of a 3-D vector +// +inline float length( const Vector3 & vec ); + +// Normalize a 3-D vector +// NOTE: +// The result is unpredictable when all elements of vec are at or near zero. +// +inline const Vector3 normalize( const Vector3 & vec ); + +// Compute cross product of two 3-D vectors +// +inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ); + +// Outer product of two 3-D vectors +// +inline const Matrix3 outer( const Vector3 & vec0, const Vector3 & vec1 ); + +// Pre-multiply a row vector by a 3x3 matrix +// +inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ); + +// Cross-product matrix of a 3-D vector +// +inline const Matrix3 crossMatrix( const Vector3 & vec ); + +// Create cross-product matrix and multiply +// NOTE: +// Faster than separately creating a cross-product matrix and multiplying. +// +inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ); + +// Linear interpolation between two 3-D vectors +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ); + +// Spherical linear interpolation between two 3-D vectors +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ); + +// Conditionally select between two 3-D vectors +// +inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ); + +// Load x, y, and z elements from the first three words of a float array. +// +// +inline void loadXYZ( Vector3 & vec, const float * fptr ); + +// Store x, y, and z elements of a 3-D vector in the first three words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZ( const Vector3 & vec, float * fptr ); + +// Load three-half-floats as a 3-D vector +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. +// +inline void loadHalfFloats( Vector3 & vec, const unsigned short * hfptr ); + +// Store a 3-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// +inline void storeHalfFloats( const Vector3 & vec, unsigned short * hfptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3-D vector +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector3 & vec ); + +// Print a 3-D vector and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector3 & vec, const char * name ); + +#endif + +// A 4-D vector in array-of-structures format +// +class Vector4 +{ + float mX; + float mY; + float mZ; + float mW; + +public: + // Default constructor; does no initialization + // + inline Vector4( ) { }; + + // Copy a 4-D vector + // + inline Vector4( const Vector4 & vec ); + + // Construct a 4-D vector from x, y, z, and w elements + // + inline Vector4( float x, float y, float z, float w ); + + // Construct a 4-D vector from a 3-D vector and a scalar + // + inline Vector4( const Vector3 & xyz, float w ); + + // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 + // + explicit inline Vector4( const Vector3 & vec ); + + // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 + // + explicit inline Vector4( const Point3 & pnt ); + + // Copy elements from a quaternion into a 4-D vector + // + explicit inline Vector4( const Quat & quat ); + + // Set all elements of a 4-D vector to the same scalar value + // + explicit inline Vector4( float scalar ); + + // Assign one 4-D vector to another + // + inline Vector4 & operator =( const Vector4 & vec ); + + // Set the x, y, and z elements of a 4-D vector + // NOTE: + // This function does not change the w element. + // + inline Vector4 & setXYZ( const Vector3 & vec ); + + // Get the x, y, and z elements of a 4-D vector + // + inline const Vector3 getXYZ( ) const; + + // Set the x element of a 4-D vector + // + inline Vector4 & setX( float x ); + + // Set the y element of a 4-D vector + // + inline Vector4 & setY( float y ); + + // Set the z element of a 4-D vector + // + inline Vector4 & setZ( float z ); + + // Set the w element of a 4-D vector + // + inline Vector4 & setW( float w ); + + // Get the x element of a 4-D vector + // + inline float getX( ) const; + + // Get the y element of a 4-D vector + // + inline float getY( ) const; + + // Get the z element of a 4-D vector + // + inline float getZ( ) const; + + // Get the w element of a 4-D vector + // + inline float getW( ) const; + + // Set an x, y, z, or w element of a 4-D vector by index + // + inline Vector4 & setElem( int idx, float value ); + + // Get an x, y, z, or w element of a 4-D vector by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Add two 4-D vectors + // + inline const Vector4 operator +( const Vector4 & vec ) const; + + // Subtract a 4-D vector from another 4-D vector + // + inline const Vector4 operator -( const Vector4 & vec ) const; + + // Multiply a 4-D vector by a scalar + // + inline const Vector4 operator *( float scalar ) const; + + // Divide a 4-D vector by a scalar + // + inline const Vector4 operator /( float scalar ) const; + + // Perform compound assignment and addition with a 4-D vector + // + inline Vector4 & operator +=( const Vector4 & vec ); + + // Perform compound assignment and subtraction by a 4-D vector + // + inline Vector4 & operator -=( const Vector4 & vec ); + + // Perform compound assignment and multiplication by a scalar + // + inline Vector4 & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + inline Vector4 & operator /=( float scalar ); + + // Negate all elements of a 4-D vector + // + inline const Vector4 operator -( ) const; + + // Construct x axis + // + static inline const Vector4 xAxis( ); + + // Construct y axis + // + static inline const Vector4 yAxis( ); + + // Construct z axis + // + static inline const Vector4 zAxis( ); + + // Construct w axis + // + static inline const Vector4 wAxis( ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply a 4-D vector by a scalar +// +inline const Vector4 operator *( float scalar, const Vector4 & vec ); + +// Multiply two 4-D vectors per element +// +inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Divide two 4-D vectors per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Compute the reciprocal of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +inline const Vector4 recipPerElem( const Vector4 & vec ); + +// Compute the square root of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function sqrtf4. +// +inline const Vector4 sqrtPerElem( const Vector4 & vec ); + +// Compute the reciprocal square root of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function rsqrtf4. +// +inline const Vector4 rsqrtPerElem( const Vector4 & vec ); + +// Compute the absolute value of a 4-D vector per element +// +inline const Vector4 absPerElem( const Vector4 & vec ); + +// Copy sign from one 4-D vector to another, per element +// +inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Maximum of two 4-D vectors per element +// +inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Minimum of two 4-D vectors per element +// +inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Maximum element of a 4-D vector +// +inline float maxElem( const Vector4 & vec ); + +// Minimum element of a 4-D vector +// +inline float minElem( const Vector4 & vec ); + +// Compute the sum of all elements of a 4-D vector +// +inline float sum( const Vector4 & vec ); + +// Compute the dot product of two 4-D vectors +// +inline float dot( const Vector4 & vec0, const Vector4 & vec1 ); + +// Compute the square of the length of a 4-D vector +// +inline float lengthSqr( const Vector4 & vec ); + +// Compute the length of a 4-D vector +// +inline float length( const Vector4 & vec ); + +// Normalize a 4-D vector +// NOTE: +// The result is unpredictable when all elements of vec are at or near zero. +// +inline const Vector4 normalize( const Vector4 & vec ); + +// Outer product of two 4-D vectors +// +inline const Matrix4 outer( const Vector4 & vec0, const Vector4 & vec1 ); + +// Linear interpolation between two 4-D vectors +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ); + +// Spherical linear interpolation between two 4-D vectors +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ); + +// Conditionally select between two 4-D vectors +// +inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ); + +// Load x, y, z, and w elements from the first four words of a float array. +// +// +inline void loadXYZW( Vector4 & vec, const float * fptr ); + +// Store x, y, z, and w elements of a 4-D vector in the first four words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZW( const Vector4 & vec, float * fptr ); + +// Load four-half-floats as a 4-D vector +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. +// +inline void loadHalfFloats( Vector4 & vec, const unsigned short * hfptr ); + +// Store a 4-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// +inline void storeHalfFloats( const Vector4 & vec, unsigned short * hfptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 4-D vector +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector4 & vec ); + +// Print a 4-D vector and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector4 & vec, const char * name ); + +#endif + +// A 3-D point in array-of-structures format +// +class Point3 +{ + float mX; + float mY; + float mZ; +#ifndef __GNUC__ + float d; +#endif + +public: + // Default constructor; does no initialization + // + inline Point3( ) { }; + + // Copy a 3-D point + // + inline Point3( const Point3 & pnt ); + + // Construct a 3-D point from x, y, and z elements + // + inline Point3( float x, float y, float z ); + + // Copy elements from a 3-D vector into a 3-D point + // + explicit inline Point3( const Vector3 & vec ); + + // Set all elements of a 3-D point to the same scalar value + // + explicit inline Point3( float scalar ); + + // Assign one 3-D point to another + // + inline Point3 & operator =( const Point3 & pnt ); + + // Set the x element of a 3-D point + // + inline Point3 & setX( float x ); + + // Set the y element of a 3-D point + // + inline Point3 & setY( float y ); + + // Set the z element of a 3-D point + // + inline Point3 & setZ( float z ); + + // Get the x element of a 3-D point + // + inline float getX( ) const; + + // Get the y element of a 3-D point + // + inline float getY( ) const; + + // Get the z element of a 3-D point + // + inline float getZ( ) const; + + // Set an x, y, or z element of a 3-D point by index + // + inline Point3 & setElem( int idx, float value ); + + // Get an x, y, or z element of a 3-D point by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Subtract a 3-D point from another 3-D point + // + inline const Vector3 operator -( const Point3 & pnt ) const; + + // Add a 3-D point to a 3-D vector + // + inline const Point3 operator +( const Vector3 & vec ) const; + + // Subtract a 3-D vector from a 3-D point + // + inline const Point3 operator -( const Vector3 & vec ) const; + + // Perform compound assignment and addition with a 3-D vector + // + inline Point3 & operator +=( const Vector3 & vec ); + + // Perform compound assignment and subtraction by a 3-D vector + // + inline Point3 & operator -=( const Vector3 & vec ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply two 3-D points per element +// +inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Divide two 3-D points per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Compute the reciprocal of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +inline const Point3 recipPerElem( const Point3 & pnt ); + +// Compute the square root of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function sqrtf4. +// +inline const Point3 sqrtPerElem( const Point3 & pnt ); + +// Compute the reciprocal square root of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function rsqrtf4. +// +inline const Point3 rsqrtPerElem( const Point3 & pnt ); + +// Compute the absolute value of a 3-D point per element +// +inline const Point3 absPerElem( const Point3 & pnt ); + +// Copy sign from one 3-D point to another, per element +// +inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Maximum of two 3-D points per element +// +inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Minimum of two 3-D points per element +// +inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Maximum element of a 3-D point +// +inline float maxElem( const Point3 & pnt ); + +// Minimum element of a 3-D point +// +inline float minElem( const Point3 & pnt ); + +// Compute the sum of all elements of a 3-D point +// +inline float sum( const Point3 & pnt ); + +// Apply uniform scale to a 3-D point +// +inline const Point3 scale( const Point3 & pnt, float scaleVal ); + +// Apply non-uniform scale to a 3-D point +// +inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ); + +// Scalar projection of a 3-D point on a unit-length 3-D vector +// +inline float projection( const Point3 & pnt, const Vector3 & unitVec ); + +// Compute the square of the distance of a 3-D point from the coordinate-system origin +// +inline float distSqrFromOrigin( const Point3 & pnt ); + +// Compute the distance of a 3-D point from the coordinate-system origin +// +inline float distFromOrigin( const Point3 & pnt ); + +// Compute the square of the distance between two 3-D points +// +inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ); + +// Compute the distance between two 3-D points +// +inline float dist( const Point3 & pnt0, const Point3 & pnt1 ); + +// Linear interpolation between two 3-D points +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ); + +// Conditionally select between two 3-D points +// +inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ); + +// Load x, y, and z elements from the first three words of a float array. +// +// +inline void loadXYZ( Point3 & pnt, const float * fptr ); + +// Store x, y, and z elements of a 3-D point in the first three words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZ( const Point3 & pnt, float * fptr ); + +// Load three-half-floats as a 3-D point +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. +// +inline void loadHalfFloats( Point3 & pnt, const unsigned short * hfptr ); + +// Store a 3-D point as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// +inline void storeHalfFloats( const Point3 & pnt, unsigned short * hfptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3-D point +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Point3 & pnt ); + +// Print a 3-D point and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Point3 & pnt, const char * name ); + +#endif + +// A quaternion in array-of-structures format +// +class Quat +{ + float mX; + float mY; + float mZ; + float mW; + +public: + // Default constructor; does no initialization + // + inline Quat( ) { }; + + // Copy a quaternion + // + inline Quat( const Quat & quat ); + + // Construct a quaternion from x, y, z, and w elements + // + inline Quat( float x, float y, float z, float w ); + + // Construct a quaternion from a 3-D vector and a scalar + // + inline Quat( const Vector3 & xyz, float w ); + + // Copy elements from a 4-D vector into a quaternion + // + explicit inline Quat( const Vector4 & vec ); + + // Convert a rotation matrix to a unit-length quaternion + // + explicit inline Quat( const Matrix3 & rotMat ); + + // Set all elements of a quaternion to the same scalar value + // + explicit inline Quat( float scalar ); + + // Assign one quaternion to another + // + inline Quat & operator =( const Quat & quat ); + + // Set the x, y, and z elements of a quaternion + // NOTE: + // This function does not change the w element. + // + inline Quat & setXYZ( const Vector3 & vec ); + + // Get the x, y, and z elements of a quaternion + // + inline const Vector3 getXYZ( ) const; + + // Set the x element of a quaternion + // + inline Quat & setX( float x ); + + // Set the y element of a quaternion + // + inline Quat & setY( float y ); + + // Set the z element of a quaternion + // + inline Quat & setZ( float z ); + + // Set the w element of a quaternion + // + inline Quat & setW( float w ); + + // Get the x element of a quaternion + // + inline float getX( ) const; + + // Get the y element of a quaternion + // + inline float getY( ) const; + + // Get the z element of a quaternion + // + inline float getZ( ) const; + + // Get the w element of a quaternion + // + inline float getW( ) const; + + // Set an x, y, z, or w element of a quaternion by index + // + inline Quat & setElem( int idx, float value ); + + // Get an x, y, z, or w element of a quaternion by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Add two quaternions + // + inline const Quat operator +( const Quat & quat ) const; + + // Subtract a quaternion from another quaternion + // + inline const Quat operator -( const Quat & quat ) const; + + // Multiply two quaternions + // + inline const Quat operator *( const Quat & quat ) const; + + // Multiply a quaternion by a scalar + // + inline const Quat operator *( float scalar ) const; + + // Divide a quaternion by a scalar + // + inline const Quat operator /( float scalar ) const; + + // Perform compound assignment and addition with a quaternion + // + inline Quat & operator +=( const Quat & quat ); + + // Perform compound assignment and subtraction by a quaternion + // + inline Quat & operator -=( const Quat & quat ); + + // Perform compound assignment and multiplication by a quaternion + // + inline Quat & operator *=( const Quat & quat ); + + // Perform compound assignment and multiplication by a scalar + // + inline Quat & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + inline Quat & operator /=( float scalar ); + + // Negate all elements of a quaternion + // + inline const Quat operator -( ) const; + + // Construct an identity quaternion + // + static inline const Quat identity( ); + + // Construct a quaternion to rotate between two unit-length 3-D vectors + // NOTE: + // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. + // + static inline const Quat rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ); + + // Construct a quaternion to rotate around a unit-length 3-D vector + // + static inline const Quat rotation( float radians, const Vector3 & unitVec ); + + // Construct a quaternion to rotate around the x axis + // + static inline const Quat rotationX( float radians ); + + // Construct a quaternion to rotate around the y axis + // + static inline const Quat rotationY( float radians ); + + // Construct a quaternion to rotate around the z axis + // + static inline const Quat rotationZ( float radians ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply a quaternion by a scalar +// +inline const Quat operator *( float scalar, const Quat & quat ); + +// Compute the conjugate of a quaternion +// +inline const Quat conj( const Quat & quat ); + +// Use a unit-length quaternion to rotate a 3-D vector +// +inline const Vector3 rotate( const Quat & unitQuat, const Vector3 & vec ); + +// Compute the dot product of two quaternions +// +inline float dot( const Quat & quat0, const Quat & quat1 ); + +// Compute the norm of a quaternion +// +inline float norm( const Quat & quat ); + +// Compute the length of a quaternion +// +inline float length( const Quat & quat ); + +// Normalize a quaternion +// NOTE: +// The result is unpredictable when all elements of quat are at or near zero. +// +inline const Quat normalize( const Quat & quat ); + +// Linear interpolation between two quaternions +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ); + +// Spherical linear interpolation between two quaternions +// NOTE: +// Interpolates along the shortest path between orientations. +// Does not clamp t between 0 and 1. +// +inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ); + +// Spherical quadrangle interpolation +// +inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ); + +// Conditionally select between two quaternions +// +inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ); + +// Load x, y, z, and w elements from the first four words of a float array. +// +// +inline void loadXYZW( Quat & quat, const float * fptr ); + +// Store x, y, z, and w elements of a quaternion in the first four words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZW( const Quat & quat, float * fptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a quaternion +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Quat & quat ); + +// Print a quaternion and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Quat & quat, const char * name ); + +#endif + +// A 3x3 matrix in array-of-structures format +// +class Matrix3 +{ + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + +public: + // Default constructor; does no initialization + // + inline Matrix3( ) { }; + + // Copy a 3x3 matrix + // + inline Matrix3( const Matrix3 & mat ); + + // Construct a 3x3 matrix containing the specified columns + // + inline Matrix3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2 ); + + // Construct a 3x3 rotation matrix from a unit-length quaternion + // + explicit inline Matrix3( const Quat & unitQuat ); + + // Set all elements of a 3x3 matrix to the same scalar value + // + explicit inline Matrix3( float scalar ); + + // Assign one 3x3 matrix to another + // + inline Matrix3 & operator =( const Matrix3 & mat ); + + // Set column 0 of a 3x3 matrix + // + inline Matrix3 & setCol0( const Vector3 & col0 ); + + // Set column 1 of a 3x3 matrix + // + inline Matrix3 & setCol1( const Vector3 & col1 ); + + // Set column 2 of a 3x3 matrix + // + inline Matrix3 & setCol2( const Vector3 & col2 ); + + // Get column 0 of a 3x3 matrix + // + inline const Vector3 getCol0( ) const; + + // Get column 1 of a 3x3 matrix + // + inline const Vector3 getCol1( ) const; + + // Get column 2 of a 3x3 matrix + // + inline const Vector3 getCol2( ) const; + + // Set the column of a 3x3 matrix referred to by the specified index + // + inline Matrix3 & setCol( int col, const Vector3 & vec ); + + // Set the row of a 3x3 matrix referred to by the specified index + // + inline Matrix3 & setRow( int row, const Vector3 & vec ); + + // Get the column of a 3x3 matrix referred to by the specified index + // + inline const Vector3 getCol( int col ) const; + + // Get the row of a 3x3 matrix referred to by the specified index + // + inline const Vector3 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + inline Vector3 & operator []( int col ); + + // Subscripting operator to get a column + // + inline const Vector3 operator []( int col ) const; + + // Set the element of a 3x3 matrix referred to by column and row indices + // + inline Matrix3 & setElem( int col, int row, float val ); + + // Get the element of a 3x3 matrix referred to by column and row indices + // + inline float getElem( int col, int row ) const; + + // Add two 3x3 matrices + // + inline const Matrix3 operator +( const Matrix3 & mat ) const; + + // Subtract a 3x3 matrix from another 3x3 matrix + // + inline const Matrix3 operator -( const Matrix3 & mat ) const; + + // Negate all elements of a 3x3 matrix + // + inline const Matrix3 operator -( ) const; + + // Multiply a 3x3 matrix by a scalar + // + inline const Matrix3 operator *( float scalar ) const; + + // Multiply a 3x3 matrix by a 3-D vector + // + inline const Vector3 operator *( const Vector3 & vec ) const; + + // Multiply two 3x3 matrices + // + inline const Matrix3 operator *( const Matrix3 & mat ) const; + + // Perform compound assignment and addition with a 3x3 matrix + // + inline Matrix3 & operator +=( const Matrix3 & mat ); + + // Perform compound assignment and subtraction by a 3x3 matrix + // + inline Matrix3 & operator -=( const Matrix3 & mat ); + + // Perform compound assignment and multiplication by a scalar + // + inline Matrix3 & operator *=( float scalar ); + + // Perform compound assignment and multiplication by a 3x3 matrix + // + inline Matrix3 & operator *=( const Matrix3 & mat ); + + // Construct an identity 3x3 matrix + // + static inline const Matrix3 identity( ); + + // Construct a 3x3 matrix to rotate around the x axis + // + static inline const Matrix3 rotationX( float radians ); + + // Construct a 3x3 matrix to rotate around the y axis + // + static inline const Matrix3 rotationY( float radians ); + + // Construct a 3x3 matrix to rotate around the z axis + // + static inline const Matrix3 rotationZ( float radians ); + + // Construct a 3x3 matrix to rotate around the x, y, and z axes + // + static inline const Matrix3 rotationZYX( const Vector3 & radiansXYZ ); + + // Construct a 3x3 matrix to rotate around a unit-length 3-D vector + // + static inline const Matrix3 rotation( float radians, const Vector3 & unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Matrix3 rotation( const Quat & unitQuat ); + + // Construct a 3x3 matrix to perform scaling + // + static inline const Matrix3 scale( const Vector3 & scaleVec ); + +}; +// Multiply a 3x3 matrix by a scalar +// +inline const Matrix3 operator *( float scalar, const Matrix3 & mat ); + +// Append (post-multiply) a scale transformation to a 3x3 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 3x3 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ); + +// Multiply two 3x3 matrices per element +// +inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); + +// Compute the absolute value of a 3x3 matrix per element +// +inline const Matrix3 absPerElem( const Matrix3 & mat ); + +// Transpose of a 3x3 matrix +// +inline const Matrix3 transpose( const Matrix3 & mat ); + +// Compute the inverse of a 3x3 matrix +// NOTE: +// Result is unpredictable when the determinant of mat is equal to or near 0. +// +inline const Matrix3 inverse( const Matrix3 & mat ); + +// Determinant of a 3x3 matrix +// +inline float determinant( const Matrix3 & mat ); + +// Conditionally select between two 3x3 matrices +// +inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3x3 matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix3 & mat ); + +// Print a 3x3 matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix3 & mat, const char * name ); + +#endif + +// A 4x4 matrix in array-of-structures format +// +class Matrix4 +{ + Vector4 mCol0; + Vector4 mCol1; + Vector4 mCol2; + Vector4 mCol3; + +public: + // Default constructor; does no initialization + // + inline Matrix4( ) { }; + + // Copy a 4x4 matrix + // + inline Matrix4( const Matrix4 & mat ); + + // Construct a 4x4 matrix containing the specified columns + // + inline Matrix4( const Vector4 & col0, const Vector4 & col1, const Vector4 & col2, const Vector4 & col3 ); + + // Construct a 4x4 matrix from a 3x4 transformation matrix + // + explicit inline Matrix4( const Transform3 & mat ); + + // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector + // + inline Matrix4( const Matrix3 & mat, const Vector3 & translateVec ); + + // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector + // + inline Matrix4( const Quat & unitQuat, const Vector3 & translateVec ); + + // Set all elements of a 4x4 matrix to the same scalar value + // + explicit inline Matrix4( float scalar ); + + // Assign one 4x4 matrix to another + // + inline Matrix4 & operator =( const Matrix4 & mat ); + + // Set the upper-left 3x3 submatrix + // NOTE: + // This function does not change the bottom row elements. + // + inline Matrix4 & setUpper3x3( const Matrix3 & mat3 ); + + // Get the upper-left 3x3 submatrix of a 4x4 matrix + // + inline const Matrix3 getUpper3x3( ) const; + + // Set translation component + // NOTE: + // This function does not change the bottom row elements. + // + inline Matrix4 & setTranslation( const Vector3 & translateVec ); + + // Get the translation component of a 4x4 matrix + // + inline const Vector3 getTranslation( ) const; + + // Set column 0 of a 4x4 matrix + // + inline Matrix4 & setCol0( const Vector4 & col0 ); + + // Set column 1 of a 4x4 matrix + // + inline Matrix4 & setCol1( const Vector4 & col1 ); + + // Set column 2 of a 4x4 matrix + // + inline Matrix4 & setCol2( const Vector4 & col2 ); + + // Set column 3 of a 4x4 matrix + // + inline Matrix4 & setCol3( const Vector4 & col3 ); + + // Get column 0 of a 4x4 matrix + // + inline const Vector4 getCol0( ) const; + + // Get column 1 of a 4x4 matrix + // + inline const Vector4 getCol1( ) const; + + // Get column 2 of a 4x4 matrix + // + inline const Vector4 getCol2( ) const; + + // Get column 3 of a 4x4 matrix + // + inline const Vector4 getCol3( ) const; + + // Set the column of a 4x4 matrix referred to by the specified index + // + inline Matrix4 & setCol( int col, const Vector4 & vec ); + + // Set the row of a 4x4 matrix referred to by the specified index + // + inline Matrix4 & setRow( int row, const Vector4 & vec ); + + // Get the column of a 4x4 matrix referred to by the specified index + // + inline const Vector4 getCol( int col ) const; + + // Get the row of a 4x4 matrix referred to by the specified index + // + inline const Vector4 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + inline Vector4 & operator []( int col ); + + // Subscripting operator to get a column + // + inline const Vector4 operator []( int col ) const; + + // Set the element of a 4x4 matrix referred to by column and row indices + // + inline Matrix4 & setElem( int col, int row, float val ); + + // Get the element of a 4x4 matrix referred to by column and row indices + // + inline float getElem( int col, int row ) const; + + // Add two 4x4 matrices + // + inline const Matrix4 operator +( const Matrix4 & mat ) const; + + // Subtract a 4x4 matrix from another 4x4 matrix + // + inline const Matrix4 operator -( const Matrix4 & mat ) const; + + // Negate all elements of a 4x4 matrix + // + inline const Matrix4 operator -( ) const; + + // Multiply a 4x4 matrix by a scalar + // + inline const Matrix4 operator *( float scalar ) const; + + // Multiply a 4x4 matrix by a 4-D vector + // + inline const Vector4 operator *( const Vector4 & vec ) const; + + // Multiply a 4x4 matrix by a 3-D vector + // + inline const Vector4 operator *( const Vector3 & vec ) const; + + // Multiply a 4x4 matrix by a 3-D point + // + inline const Vector4 operator *( const Point3 & pnt ) const; + + // Multiply two 4x4 matrices + // + inline const Matrix4 operator *( const Matrix4 & mat ) const; + + // Multiply a 4x4 matrix by a 3x4 transformation matrix + // + inline const Matrix4 operator *( const Transform3 & tfrm ) const; + + // Perform compound assignment and addition with a 4x4 matrix + // + inline Matrix4 & operator +=( const Matrix4 & mat ); + + // Perform compound assignment and subtraction by a 4x4 matrix + // + inline Matrix4 & operator -=( const Matrix4 & mat ); + + // Perform compound assignment and multiplication by a scalar + // + inline Matrix4 & operator *=( float scalar ); + + // Perform compound assignment and multiplication by a 4x4 matrix + // + inline Matrix4 & operator *=( const Matrix4 & mat ); + + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + inline Matrix4 & operator *=( const Transform3 & tfrm ); + + // Construct an identity 4x4 matrix + // + static inline const Matrix4 identity( ); + + // Construct a 4x4 matrix to rotate around the x axis + // + static inline const Matrix4 rotationX( float radians ); + + // Construct a 4x4 matrix to rotate around the y axis + // + static inline const Matrix4 rotationY( float radians ); + + // Construct a 4x4 matrix to rotate around the z axis + // + static inline const Matrix4 rotationZ( float radians ); + + // Construct a 4x4 matrix to rotate around the x, y, and z axes + // + static inline const Matrix4 rotationZYX( const Vector3 & radiansXYZ ); + + // Construct a 4x4 matrix to rotate around a unit-length 3-D vector + // + static inline const Matrix4 rotation( float radians, const Vector3 & unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Matrix4 rotation( const Quat & unitQuat ); + + // Construct a 4x4 matrix to perform scaling + // + static inline const Matrix4 scale( const Vector3 & scaleVec ); + + // Construct a 4x4 matrix to perform translation + // + static inline const Matrix4 translation( const Vector3 & translateVec ); + + // Construct viewing matrix based on eye position, position looked at, and up direction + // + static inline const Matrix4 lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ); + + // Construct a perspective projection matrix + // + static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar ); + + // Construct a perspective projection matrix based on frustum + // + static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar ); + + // Construct an orthographic projection matrix + // + static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar ); + +}; +// Multiply a 4x4 matrix by a scalar +// +inline const Matrix4 operator *( float scalar, const Matrix4 & mat ); + +// Append (post-multiply) a scale transformation to a 4x4 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 4x4 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ); + +// Multiply two 4x4 matrices per element +// +inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); + +// Compute the absolute value of a 4x4 matrix per element +// +inline const Matrix4 absPerElem( const Matrix4 & mat ); + +// Transpose of a 4x4 matrix +// +inline const Matrix4 transpose( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix +// NOTE: +// Result is unpredictable when the determinant of mat is equal to or near 0. +// +inline const Matrix4 inverse( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. The result is unpredictable when the determinant of mat is equal to or near 0. +// +inline const Matrix4 affineInverse( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. +// +inline const Matrix4 orthoInverse( const Matrix4 & mat ); + +// Determinant of a 4x4 matrix +// +inline float determinant( const Matrix4 & mat ); + +// Conditionally select between two 4x4 matrices +// +inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 4x4 matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix4 & mat ); + +// Print a 4x4 matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix4 & mat, const char * name ); + +#endif + +// A 3x4 transformation matrix in array-of-structures format +// +class Transform3 +{ + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + Vector3 mCol3; + +public: + // Default constructor; does no initialization + // + inline Transform3( ) { }; + + // Copy a 3x4 transformation matrix + // + inline Transform3( const Transform3 & tfrm ); + + // Construct a 3x4 transformation matrix containing the specified columns + // + inline Transform3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2, const Vector3 & col3 ); + + // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector + // + inline Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ); + + // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector + // + inline Transform3( const Quat & unitQuat, const Vector3 & translateVec ); + + // Set all elements of a 3x4 transformation matrix to the same scalar value + // + explicit inline Transform3( float scalar ); + + // Assign one 3x4 transformation matrix to another + // + inline Transform3 & operator =( const Transform3 & tfrm ); + + // Set the upper-left 3x3 submatrix + // + inline Transform3 & setUpper3x3( const Matrix3 & mat3 ); + + // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix + // + inline const Matrix3 getUpper3x3( ) const; + + // Set translation component + // + inline Transform3 & setTranslation( const Vector3 & translateVec ); + + // Get the translation component of a 3x4 transformation matrix + // + inline const Vector3 getTranslation( ) const; + + // Set column 0 of a 3x4 transformation matrix + // + inline Transform3 & setCol0( const Vector3 & col0 ); + + // Set column 1 of a 3x4 transformation matrix + // + inline Transform3 & setCol1( const Vector3 & col1 ); + + // Set column 2 of a 3x4 transformation matrix + // + inline Transform3 & setCol2( const Vector3 & col2 ); + + // Set column 3 of a 3x4 transformation matrix + // + inline Transform3 & setCol3( const Vector3 & col3 ); + + // Get column 0 of a 3x4 transformation matrix + // + inline const Vector3 getCol0( ) const; + + // Get column 1 of a 3x4 transformation matrix + // + inline const Vector3 getCol1( ) const; + + // Get column 2 of a 3x4 transformation matrix + // + inline const Vector3 getCol2( ) const; + + // Get column 3 of a 3x4 transformation matrix + // + inline const Vector3 getCol3( ) const; + + // Set the column of a 3x4 transformation matrix referred to by the specified index + // + inline Transform3 & setCol( int col, const Vector3 & vec ); + + // Set the row of a 3x4 transformation matrix referred to by the specified index + // + inline Transform3 & setRow( int row, const Vector4 & vec ); + + // Get the column of a 3x4 transformation matrix referred to by the specified index + // + inline const Vector3 getCol( int col ) const; + + // Get the row of a 3x4 transformation matrix referred to by the specified index + // + inline const Vector4 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + inline Vector3 & operator []( int col ); + + // Subscripting operator to get a column + // + inline const Vector3 operator []( int col ) const; + + // Set the element of a 3x4 transformation matrix referred to by column and row indices + // + inline Transform3 & setElem( int col, int row, float val ); + + // Get the element of a 3x4 transformation matrix referred to by column and row indices + // + inline float getElem( int col, int row ) const; + + // Multiply a 3x4 transformation matrix by a 3-D vector + // + inline const Vector3 operator *( const Vector3 & vec ) const; + + // Multiply a 3x4 transformation matrix by a 3-D point + // + inline const Point3 operator *( const Point3 & pnt ) const; + + // Multiply two 3x4 transformation matrices + // + inline const Transform3 operator *( const Transform3 & tfrm ) const; + + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + inline Transform3 & operator *=( const Transform3 & tfrm ); + + // Construct an identity 3x4 transformation matrix + // + static inline const Transform3 identity( ); + + // Construct a 3x4 transformation matrix to rotate around the x axis + // + static inline const Transform3 rotationX( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the y axis + // + static inline const Transform3 rotationY( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the z axis + // + static inline const Transform3 rotationZ( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes + // + static inline const Transform3 rotationZYX( const Vector3 & radiansXYZ ); + + // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector + // + static inline const Transform3 rotation( float radians, const Vector3 & unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Transform3 rotation( const Quat & unitQuat ); + + // Construct a 3x4 transformation matrix to perform scaling + // + static inline const Transform3 scale( const Vector3 & scaleVec ); + + // Construct a 3x4 transformation matrix to perform translation + // + static inline const Transform3 translation( const Vector3 & translateVec ); + +}; +// Append (post-multiply) a scale transformation to a 3x4 transformation matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ); + +// Multiply two 3x4 transformation matrices per element +// +inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); + +// Compute the absolute value of a 3x4 transformation matrix per element +// +inline const Transform3 absPerElem( const Transform3 & tfrm ); + +// Inverse of a 3x4 transformation matrix +// NOTE: +// Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. +// +inline const Transform3 inverse( const Transform3 & tfrm ); + +// Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. +// +inline const Transform3 orthoInverse( const Transform3 & tfrm ); + +// Conditionally select between two 3x4 transformation matrices +// +inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3x4 transformation matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Transform3 & tfrm ); + +// Print a 3x4 transformation matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Transform3 & tfrm, const char * name ); + +#endif + +} // namespace Aos +} // namespace Vectormath + +#include "vec_aos.h" +#include "quat_aos.h" +#include "mat_aos.h" + +#endif diff --git a/Extras/PhysicsEffects/physics_effects_license.txt b/Extras/PhysicsEffects/physics_effects_license.txt new file mode 100644 index 000000000..4b92572ad --- /dev/null +++ b/Extras/PhysicsEffects/physics_effects_license.txt @@ -0,0 +1,10 @@ +Copyright (c) 2010, Sony Computer Entertainment Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + Neither the name of the Sony Computer Entertainment Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/.classpath b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/.classpath new file mode 100644 index 000000000..98132ca43 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/.classpath @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/.cproject b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/.cproject new file mode 100644 index 000000000..16eca1494 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/.cproject @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/.externalToolBuilders/BuildSampleJNICode.launch b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/.externalToolBuilders/BuildSampleJNICode.launch new file mode 100644 index 000000000..381d02593 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/.externalToolBuilders/BuildSampleJNICode.launch @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/.project b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/.project new file mode 100644 index 000000000..de96cd774 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/.project @@ -0,0 +1,114 @@ + + + + PfxApp_1_Simple + + + PfxLibrary + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + auto,full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/BuildSampleJNICode.launch + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + + + src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + 1 + PFX_ROOT/project/Android/PfxApp_1_Simple/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + + + src/pfx/renderingsupport/PhysicsEffectsRenderer.java + 1 + PFX_ROOT/project/Android/PfxApp_1_Simple/src/pfx/renderingsupport/PhysicsEffectsRenderer.java + + + src/pfx/sample1/PfxApp_1_Simple.java + 1 + PFX_ROOT/project/Android/PfxApp_1_Simple/src/pfx/sample1/PfxApp_1_Simple.java + + + + + 1305070288951 + jni + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + 1305070295995 + src + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + + + PFX_ROOT + $%7BPARENT-3-PROJECT_LOC%7D + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/AndroidManifest.xml b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/AndroidManifest.xml new file mode 100644 index 000000000..f62261faf --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/AndroidManifest.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/build.xml b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/build.xml new file mode 100644 index 000000000..83988f374 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/build.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/default.properties b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/default.properties new file mode 100644 index 000000000..f4b4f1778 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-9 diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/jni/Android.mk b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/jni/Android.mk new file mode 100644 index 000000000..5560e779b --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/jni/Android.mk @@ -0,0 +1,138 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# NOTE: The local path here is defined based on an environment +# variable that points to the root of the Bullet/PhysicsEffects +# code base. The variable must be set in the Cygwin style, e.g., +# BULLET_PFX_ROOT_CYGWIN = /cygdrive/d/tools/PhysicsEffectsRootPath +# +# The reason for *not* just setting local path := $(call my-dir) +# is that we wish to access local source files that are *not* +# located in a "jni" subfolder and *not* located in a subfolder +# of the project folder. This enables us to have Eclipse and +# Android NDK projects that fit neatly into the Bullet/PhysicsEffects +# folder structure, enabling a multi platform code base, without +# forcing the "jni" and subfolder structure that Android SDK/NDK +# prefer for pure Android projects. +LOCAL_PATH:= $(BULLET_PFX_ROOT_CYGWIN) + +# Copy the shared static library, libpfxlibrary.a, into the build +include $(CLEAR_VARS) +LOCAL_MODULE := pfxlibrary +LOCAL_SRC_FILES := project/Android/PfxLibrary/obj/local/armeabi-v7a/libpfxlibrary.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +# Warning: do not enable SIMD vector math functions or NEON for running +# in the Android NDK emulator. NEON requires a physical device +# with NEON support. +# +# Note that in theory we can let LOCAL_ARM_NEON := true determine +# that the flags -mfpu=neon and -mfloat-abi=softfp should be applied. +# However, in practice we have seen one case where the ndk-build +# script "forgets" these flags for the occasional *.cpp file, thus +# causing those files to access the std definition of vectormath +# classes, which are completely different, including different size. +# So, we explicitly apply these flags to avoid having a broken +# build. +# +# Include -DSCE_PFX_USE_SIMD_VECTORMATH to build for ARM NEON SIMD +# intrinsics, and leave it off to use NEON for scalar math but without +# SIMD. + +LOCAL_CFLAGS := $(LOCAL_C_INCLUDES:%=-I%) -mfpu=neon -mfloat-abi=softfp -DSCE_PFX_USE_SIMD_VECTORMATH +# add the following #define to run standalone NEON speedup potential tests +# -DTEST_NEON_PERFORMANCE +# + +# apply these flags if needed +# -ffast-math -funsafe-math-optimizations + +# apply this to disable optimization +# TARGET_CFLAGS := $(TARGET_CFLAGS) -O0 + +# apply these 2 to turn on assembly output (*.c/*.cpp to *.s file) +# compile-cpp-source = $(eval $(call ev-compile-cpp-source,$1,$(1:%$(LOCAL_CPP_EXTENSION)=%.s))) +# TARGET_CFLAGS := $(TARGET_CFLAGS) -S + +# specify static libraries to link in +LOCAL_STATIC_LIBRARIES := pfxlibrary cpufeatures + +# Enable or disable NEON. Don't forget to apply, or not apply, -mfpu=neon and -mfloat-abi=softfp +# flags in addition, e.g., if this is true both of those need to be included in LOCAL_CFLAGS +# to avoid the possibility that ndk-build will "forget" to add them on some files +LOCAL_ARM_NEON := true +TARGET_CFLAGS := $(filter-out -ffpu=vfp,$(TARGET_CFLAGS)) + +LOCAL_MODULE := PfxApp_1_Simple +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)sample/api_physics_effects/1_simple \ + $(LOCAL_PATH)sample/api_physics_effects/common \ + $(LOCAL_PATH)sample/test_ARM_NEON_performance + +# +# The source files located in the test_ARM_NEON_performance folder are used +# to test the potential performance improvements of atomic vector math +# functions using ARM NEON instructions. Note that these are tested outside +# of the vectormath library, to avoid the overhead associated with that +# library. The assembly files contain pure NEON assembly code. +# +# The test_neon_solve_linear_constraint_row.cpp is not an atomic vector +# math operation. Rather it is a NEON assembly implementation of one of the +# leaf functions in the physics effects low level constraint solver. +# +LOCAL_SRC_FILES := \ + sample/api_physics_effects/common/jni/physicseffects-android.cpp \ + sample/api_physics_effects/1_simple/main.cpp \ + sample/api_physics_effects/1_simple/physics_func.cpp \ + sample/api_physics_effects/common/ctrl_func.android.cpp \ + sample/api_physics_effects/common/render_func.android.cpp \ + sample/api_physics_effects/common/perf_func.android.cpp \ + sample/test_ARM_NEON_performance/neon_dot_product.S \ + sample/test_ARM_NEON_performance/neon_cross_product.S \ + sample/test_ARM_NEON_performance/neon_matrix4_operator_multiply.S \ + sample/test_ARM_NEON_performance/neon_matrix3_operator_multiply.S \ + sample/test_ARM_NEON_performance/neon_orthoInverse_transform3.S \ + sample/test_ARM_NEON_performance/neon_transform3_operator_multiply.S \ + sample/test_ARM_NEON_performance/neon_transpose_matrix3.S \ + sample/test_ARM_NEON_performance/test_neon_cross_product.cpp \ + sample/test_ARM_NEON_performance/test_neon_dot_product.cpp \ + sample/test_ARM_NEON_performance/test_neon_matrix3_operator_multiply.cpp \ + sample/test_ARM_NEON_performance/test_neon_matrix4_operator_multiply.cpp \ + sample/test_ARM_NEON_performance/test_neon_orthoInverse_transform3.cpp \ + sample/test_ARM_NEON_performance/test_neon_transform3_operator_multiply.cpp \ + sample/test_ARM_NEON_performance/test_neon_transpose_matrix3.cpp \ + sample/test_ARM_NEON_performance/test_neon_solve_linear_constraint_row.cpp + +LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lGLESv1_CM -ldl -lm -llog + +include $(BUILD_SHARED_LIBRARY) + +$(call import-module,android/cpufeatures) + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/jni/Application.mk b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/jni/Application.mk new file mode 100644 index 000000000..2fb23fb62 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/jni/Application.mk @@ -0,0 +1,31 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +APP_MODULES := PfxApp_1_Simple +APP_ABI := armeabi-v7a +APP_OPTIM := release diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/local.properties b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/local.properties new file mode 100644 index 000000000..1659ad756 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/local.properties @@ -0,0 +1,10 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must *NOT* be checked in Version Control Systems, +# as it contains information specific to your local configuration. + +# location of the SDK. This is only used by Ant +# For customization when using a Version Control System, please read the +# header note. +sdk.dir=F:\\sdks\\Android\\android-sdk diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/proguard.cfg b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/proguard.cfg new file mode 100644 index 000000000..3e84fc735 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/proguard.cfg @@ -0,0 +1,36 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/drawable-hdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/drawable-hdpi/icon.png new file mode 100644 index 000000000..d7753923a Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/drawable-hdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/drawable-ldpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/drawable-ldpi/icon.png new file mode 100644 index 000000000..0871aa1eb Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/drawable-ldpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/drawable-mdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/drawable-mdpi/icon.png new file mode 100644 index 000000000..ff7be820f Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/drawable-mdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/layout/main.xml b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/layout/main.xml new file mode 100644 index 000000000..6c069664e --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/layout/main.xml @@ -0,0 +1,34 @@ + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/values/strings.xml b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/values/strings.xml new file mode 100644 index 000000000..2310f130f --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/res/values/strings.xml @@ -0,0 +1,31 @@ + + + + Pfx 1 Simple + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java new file mode 100644 index 000000000..ec83e64ce --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java @@ -0,0 +1,113 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import android.opengl.GLSurfaceView; +import android.content.Context; +import android.view.MotionEvent; + +/** + * Implementation of the OpenGL ES view window and creates/assigns a renderer. + * Handles touch events to allow the user to change scene on tap, move the camera + * around by touch based movement, and allows the user to zoom in and out by pinching. + * @author ahamilton + * + */ +public class PhysicsEffectsGLSurfaceView extends GLSurfaceView { + public PhysicsEffectsGLSurfaceView(Context context) { + super(context); + peRenderer = new PhysicsEffectsRenderer(); + setRenderer(peRenderer); + } + + float x1 = 0, x2, y1 = 0, y2; + long downTime; + + /** + * Function to process touch events for camera and scene control + * + */ + public boolean onTouchEvent(final MotionEvent event) { + switch(event.getAction()) { + case(MotionEvent.ACTION_DOWN): + x1 = event.getX(); + y1 = event.getY(); + downTime = event.getDownTime(); + break; + case(MotionEvent.ACTION_UP): + if(event.getEventTime() - downTime < 100) nativeSceneChange(); + break; + case(MotionEvent.ACTION_MOVE): { + if(event.getPointerCount() == 1){ + x2 = event.getX(); + y2 = event.getY(); + float dx = x2-x1; + float dy = y2-y1; + + // Use dx and dy to determine the direction + if(dx > 0) { + nativeCameraLeft(); + } else { + nativeCameraRight(); + } + if(dy > 0){ + nativeCameraUp(); + } else { + nativeCameraDown(); + } + x1=x2; + y1=y2; + } else if(event.getPointerCount() == 2){ + y2 = event.getY(); + + float dy = y2-y1; + + // Use dy to determine zoom + if(dy > 0){ + nativeCameraZoomIn(); + } else { + nativeCameraZoomOut(); + } + y1=y2; + } + } + } + return true; + } + + PhysicsEffectsRenderer peRenderer; + + private static native void nativeCameraUp(); + private static native void nativeCameraDown(); + private static native void nativeCameraLeft(); + private static native void nativeCameraRight(); + private static native void nativeCameraZoomOut(); + private static native void nativeCameraZoomIn(); + private static native void nativeSceneChange(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/src/pfx/renderingsupport/PhysicsEffectsRenderer.java b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/src/pfx/renderingsupport/PhysicsEffectsRenderer.java new file mode 100644 index 000000000..5ca66d4b5 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/src/pfx/renderingsupport/PhysicsEffectsRenderer.java @@ -0,0 +1,101 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.opengl.GLSurfaceView; +import android.util.Log; + +/** + * Implementation of the renderer. It calls the native physicseffects code + * to run on the init and drawframe allowing the sample to perform its simulation. + * @author ahamilton + * + */ +public class PhysicsEffectsRenderer implements GLSurfaceView.Renderer { + boolean startup = true; + boolean notEnded = true; + static long startuptime; + static long endtime; + int frameCounter; + + /** + * Initilize the physics simulation after the GL surface is created. + * + */ + public void onSurfaceCreated(GL10 gl, EGLConfig config) + { + Log.v("Init physics", "Initing physics"); + nativePhysicsEffectsInit(); + Log.v("Init physics", "Inited physics"); + } + + /** + * Set the viewport for a changed GL surface + * + */ + public void onSurfaceChanged(GL10 gl, int w, int h) + { + gl.glViewport(0, 0, w, h); + } + + /** + * Perform one simulation step and render the scene. + * + */ + public void onDrawFrame(GL10 gl) + { + if(startup){ + startup = false; + frameCounter = 0; + startuptime = System.currentTimeMillis(); + endtime = startuptime + 10000; // sets run time to be 30 seconds + } + + nativePhysicsEffectsSimulate(); + + frameCounter++; + long lCurrentTime = System.currentTimeMillis(); + if(lCurrentTime > endtime && notEnded) { + float fFrameRate = (1000.0f * (float)frameCounter) / ((float)lCurrentTime - startuptime); + Log.v("PHYSICS TIMING STUDY", "Number of Frames: " + Integer.toString(frameCounter)); + Log.v("PHYSICS TIMING STUDY", "Time ellapsed (milliseconds): " + Long.toString(lCurrentTime - startuptime)); + Log.v("PHYSICS TIMING STUDY", "Bullet Frame Rate: " + Float.toString(fFrameRate) + "fps"); + notEnded = false; + } + } + + private static native void nativePhysicsEffectsInit(); + private static native void nativePhysicsEffectsSimulate(); + private static native void nativePhysicsEffectsUpdate(); + private static native void nativePhysicsEffectsPhysStep(); + private static native void nativePhysicsEffectsRender(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/src/pfx/sample1/PfxApp_1_Simple.java b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/src/pfx/sample1/PfxApp_1_Simple.java new file mode 100644 index 000000000..00782cd15 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple/src/pfx/sample1/PfxApp_1_Simple.java @@ -0,0 +1,64 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.sample1; + +import pfx.renderingsupport.PhysicsEffectsGLSurfaceView; + +import android.app.Activity; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * When program loads it creates a OpenGl ES render window for + * the physics effects sample projects to run in and loads the complied + * physics effects libraries. + * @author ahamilton + * + */ +public class PfxApp_1_Simple extends Activity +{ + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + peGLView = new PhysicsEffectsGLSurfaceView(this); + setContentView(peGLView); + int numprocessors = Runtime.getRuntime().availableProcessors(); + Log.v("PFX THREADING", "Number of Processors: " + Integer.toString(numprocessors)); + } + + private GLSurfaceView peGLView; + + // This is where you specify which physics effects sample you would like to load + static + { + System.loadLibrary("PfxApp_1_Simple"); + } +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/.classpath b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/.classpath new file mode 100644 index 000000000..98132ca43 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/.classpath @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/.cproject b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/.cproject new file mode 100644 index 000000000..9ac8cbd3c --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/.cproject @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/.externalToolBuilders/BuildSampleJNICode.launch b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/.externalToolBuilders/BuildSampleJNICode.launch new file mode 100644 index 000000000..c8e7d6cdc --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/.externalToolBuilders/BuildSampleJNICode.launch @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/.project b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/.project new file mode 100644 index 000000000..d8a9d6139 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/.project @@ -0,0 +1,114 @@ + + + + PfxApp_1_Simple_Parallel + + + PfxLibrary + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + auto,full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/BuildSampleJNICode.launch + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + + + src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + 1 + PFX_ROOT/project/Android/PfxApp_1_Simple_Parallel/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + + + src/pfx/renderingsupport/PhysicsEffectsRenderer.java + 1 + PFX_ROOT/project/Android/PfxApp_1_Simple_Parallel/src/pfx/renderingsupport/PhysicsEffectsRenderer.java + + + src/pfx/sample1b/PfxApp_1_Simple_Parallel.java + 1 + PFX_ROOT/project/Android/PfxApp_1_Simple_Parallel/src/pfx/sample1b/PfxApp_1_Simple_Parallel.java + + + + + 1305070288951 + jni + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + 1305070295995 + src + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + + + PFX_ROOT + $%7BPARENT-3-PROJECT_LOC%7D + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/AndroidManifest.xml b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/AndroidManifest.xml new file mode 100644 index 000000000..416b89271 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/AndroidManifest.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/build.xml b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/build.xml new file mode 100644 index 000000000..0839f70e1 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/build.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/default.properties b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/default.properties new file mode 100644 index 000000000..f4b4f1778 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-9 diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/jni/Android.mk b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/jni/Android.mk new file mode 100644 index 000000000..21bb098c1 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/jni/Android.mk @@ -0,0 +1,109 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# NOTE: The local path here is defined based on an environment +# variable that points to the root of the Bullet/PhysicsEffects +# code base. The variable must be set in the Cygwin style, e.g., +# BULLET_PFX_ROOT_CYGWIN = /cygdrive/d/tools/PhysicsEffectsRootPath +# +# The reason for *not* just setting local path := $(call my-dir) +# is that we wish to access local source files that are *not* +# located in a "jni" subfolder and *not* located in a subfolder +# of the project folder. This enables us to have Eclipse and +# Android NDK projects that fit neatly into the Bullet/PhysicsEffects +# folder structure, enabling a multi platform code base, without +# forcing the "jni" and subfolder structure that Android SDK/NDK +# prefer for pure Android projects. +LOCAL_PATH:= $(BULLET_PFX_ROOT_CYGWIN) + +# Copy the shared static library, libpfxlibrary.a, into the build +include $(CLEAR_VARS) +LOCAL_MODULE := pfxlibrary +LOCAL_SRC_FILES := project/Android/PfxLibrary/obj/local/armeabi-v7a/libpfxlibrary.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +# Warning: do not enable SIMD vector math functions or NEON for running +# in the Android NDK emulator. NEON requires a physical device +# with NEON support. +# +# Note that in theory we can let LOCAL_ARM_NEON := true determine +# that the flags -mfpu=neon and -mfloat-abi=softfp should be applied. +# However, in practice we have seen one case where the ndk-build +# script "forgets" these flags for the occasional *.cpp file, thus +# causing those files to access the std definition of vectormath +# classes, which are completely different, including different size. +# So, we explicitly apply these flags to avoid having a broken +# build. +# +# Include -DSCE_PFX_USE_SIMD_VECTORMATH to build for ARM NEON SIMD +# intrinsics, and leave it off to use NEON for scalar math but without +# SIMD. + +LOCAL_CFLAGS := $(LOCAL_C_INCLUDES:%=-I%) -DUSE_PTHREADS -mfpu=neon -mfloat-abi=softfp -pthread -DSCE_PFX_USE_SIMD_VECTORMATH + +# apply these flags if needed +# -ffast-math -funsafe-math-optimizations + +# apply this to disable optimization +# TARGET_CFLAGS := $(TARGET_CFLAGS) -O0 + +# apply these 2 to turn on assembly output (*.c/*.cpp to *.s file) +# compile-cpp-source = $(eval $(call ev-compile-cpp-source,$1,$(1:%$(LOCAL_CPP_EXTENSION)=%.s))) +# TARGET_CFLAGS := $(TARGET_CFLAGS) -S + +# specify static libraries to link in +LOCAL_STATIC_LIBRARIES := pfxlibrary cpufeatures + +# Enable or disable NEON. Don't forget to apply, or not apply, -mfpu=neon and -mfloat-abi=softfp +# flags in addition, e.g., if this is true both of those need to be included in LOCAL_CFLAGS +# to avoid the possibility that ndk-build will "forget" to add them on some files +LOCAL_ARM_NEON := true +TARGET_CFLAGS := $(filter-out -ffpu=vfp,$(TARGET_CFLAGS)) + +LOCAL_MODULE := PfxApp_1_Simple_Parallel +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)sample/api_physics_effects/1_simple_parallel \ + $(LOCAL_PATH)sample/api_physics_effects/common \ + $(LOCAL_PATH)sample/test_ARM_NEON_performance + +LOCAL_SRC_FILES := \ + sample/api_physics_effects/common/jni/physicseffects-android.cpp \ + sample/api_physics_effects/1_simple_parallel/main.cpp \ + sample/api_physics_effects/1_simple_parallel/physics_func.cpp \ + sample/api_physics_effects/common/ctrl_func.android.cpp \ + sample/api_physics_effects/common/render_func.android.cpp \ + sample/api_physics_effects/common/perf_func.android.cpp + +LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lGLESv1_CM -ldl -lm -llog + +include $(BUILD_SHARED_LIBRARY) + +$(call import-module,android/cpufeatures) + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/jni/Application.mk b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/jni/Application.mk new file mode 100644 index 000000000..0187aba72 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/jni/Application.mk @@ -0,0 +1,31 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +APP_MODULES := PfxApp_1_Simple_Parallel +APP_ABI := armeabi-v7a +APP_OPTIM := release diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/local.properties b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/local.properties new file mode 100644 index 000000000..1659ad756 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/local.properties @@ -0,0 +1,10 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must *NOT* be checked in Version Control Systems, +# as it contains information specific to your local configuration. + +# location of the SDK. This is only used by Ant +# For customization when using a Version Control System, please read the +# header note. +sdk.dir=F:\\sdks\\Android\\android-sdk diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/proguard.cfg b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/proguard.cfg new file mode 100644 index 000000000..3e84fc735 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/proguard.cfg @@ -0,0 +1,36 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/drawable-hdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/drawable-hdpi/icon.png new file mode 100644 index 000000000..d7753923a Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/drawable-hdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/drawable-ldpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/drawable-ldpi/icon.png new file mode 100644 index 000000000..0871aa1eb Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/drawable-ldpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/drawable-mdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/drawable-mdpi/icon.png new file mode 100644 index 000000000..ff7be820f Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/drawable-mdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/layout/main.xml b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/layout/main.xml new file mode 100644 index 000000000..6c069664e --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/layout/main.xml @@ -0,0 +1,34 @@ + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/values/strings.xml b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/values/strings.xml new file mode 100644 index 000000000..945bf6f54 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/res/values/strings.xml @@ -0,0 +1,31 @@ + + + + Pfx 1 Simple Parallel + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java new file mode 100644 index 000000000..ec83e64ce --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java @@ -0,0 +1,113 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import android.opengl.GLSurfaceView; +import android.content.Context; +import android.view.MotionEvent; + +/** + * Implementation of the OpenGL ES view window and creates/assigns a renderer. + * Handles touch events to allow the user to change scene on tap, move the camera + * around by touch based movement, and allows the user to zoom in and out by pinching. + * @author ahamilton + * + */ +public class PhysicsEffectsGLSurfaceView extends GLSurfaceView { + public PhysicsEffectsGLSurfaceView(Context context) { + super(context); + peRenderer = new PhysicsEffectsRenderer(); + setRenderer(peRenderer); + } + + float x1 = 0, x2, y1 = 0, y2; + long downTime; + + /** + * Function to process touch events for camera and scene control + * + */ + public boolean onTouchEvent(final MotionEvent event) { + switch(event.getAction()) { + case(MotionEvent.ACTION_DOWN): + x1 = event.getX(); + y1 = event.getY(); + downTime = event.getDownTime(); + break; + case(MotionEvent.ACTION_UP): + if(event.getEventTime() - downTime < 100) nativeSceneChange(); + break; + case(MotionEvent.ACTION_MOVE): { + if(event.getPointerCount() == 1){ + x2 = event.getX(); + y2 = event.getY(); + float dx = x2-x1; + float dy = y2-y1; + + // Use dx and dy to determine the direction + if(dx > 0) { + nativeCameraLeft(); + } else { + nativeCameraRight(); + } + if(dy > 0){ + nativeCameraUp(); + } else { + nativeCameraDown(); + } + x1=x2; + y1=y2; + } else if(event.getPointerCount() == 2){ + y2 = event.getY(); + + float dy = y2-y1; + + // Use dy to determine zoom + if(dy > 0){ + nativeCameraZoomIn(); + } else { + nativeCameraZoomOut(); + } + y1=y2; + } + } + } + return true; + } + + PhysicsEffectsRenderer peRenderer; + + private static native void nativeCameraUp(); + private static native void nativeCameraDown(); + private static native void nativeCameraLeft(); + private static native void nativeCameraRight(); + private static native void nativeCameraZoomOut(); + private static native void nativeCameraZoomIn(); + private static native void nativeSceneChange(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/src/pfx/renderingsupport/PhysicsEffectsRenderer.java b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/src/pfx/renderingsupport/PhysicsEffectsRenderer.java new file mode 100644 index 000000000..5ca66d4b5 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/src/pfx/renderingsupport/PhysicsEffectsRenderer.java @@ -0,0 +1,101 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.opengl.GLSurfaceView; +import android.util.Log; + +/** + * Implementation of the renderer. It calls the native physicseffects code + * to run on the init and drawframe allowing the sample to perform its simulation. + * @author ahamilton + * + */ +public class PhysicsEffectsRenderer implements GLSurfaceView.Renderer { + boolean startup = true; + boolean notEnded = true; + static long startuptime; + static long endtime; + int frameCounter; + + /** + * Initilize the physics simulation after the GL surface is created. + * + */ + public void onSurfaceCreated(GL10 gl, EGLConfig config) + { + Log.v("Init physics", "Initing physics"); + nativePhysicsEffectsInit(); + Log.v("Init physics", "Inited physics"); + } + + /** + * Set the viewport for a changed GL surface + * + */ + public void onSurfaceChanged(GL10 gl, int w, int h) + { + gl.glViewport(0, 0, w, h); + } + + /** + * Perform one simulation step and render the scene. + * + */ + public void onDrawFrame(GL10 gl) + { + if(startup){ + startup = false; + frameCounter = 0; + startuptime = System.currentTimeMillis(); + endtime = startuptime + 10000; // sets run time to be 30 seconds + } + + nativePhysicsEffectsSimulate(); + + frameCounter++; + long lCurrentTime = System.currentTimeMillis(); + if(lCurrentTime > endtime && notEnded) { + float fFrameRate = (1000.0f * (float)frameCounter) / ((float)lCurrentTime - startuptime); + Log.v("PHYSICS TIMING STUDY", "Number of Frames: " + Integer.toString(frameCounter)); + Log.v("PHYSICS TIMING STUDY", "Time ellapsed (milliseconds): " + Long.toString(lCurrentTime - startuptime)); + Log.v("PHYSICS TIMING STUDY", "Bullet Frame Rate: " + Float.toString(fFrameRate) + "fps"); + notEnded = false; + } + } + + private static native void nativePhysicsEffectsInit(); + private static native void nativePhysicsEffectsSimulate(); + private static native void nativePhysicsEffectsUpdate(); + private static native void nativePhysicsEffectsPhysStep(); + private static native void nativePhysicsEffectsRender(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/src/pfx/sample1b/PfxApp_1_Simple_Parallel.java b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/src/pfx/sample1b/PfxApp_1_Simple_Parallel.java new file mode 100644 index 000000000..d73eba4db --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_1_Simple_Parallel/src/pfx/sample1b/PfxApp_1_Simple_Parallel.java @@ -0,0 +1,64 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.sample1b; + +import pfx.renderingsupport.PhysicsEffectsGLSurfaceView; + +import android.app.Activity; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * When program loads it creates a OpenGl ES render window for + * the physics effects sample projects to run in and loads the complied + * physics effects libraries. + * @author ahamilton + * + */ +public class PfxApp_1_Simple_Parallel extends Activity +{ + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + peGLView = new PhysicsEffectsGLSurfaceView(this); + setContentView(peGLView); + int numprocessors = Runtime.getRuntime().availableProcessors(); + Log.v("PFX THREADING", "Number of Processors: " + Integer.toString(numprocessors)); + } + + private GLSurfaceView peGLView; + + // This is where you specify which physics effects sample you would like to load + static + { + System.loadLibrary("PfxApp_1_Simple_Parallel"); + } +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/.classpath b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/.classpath new file mode 100644 index 000000000..98132ca43 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/.classpath @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/.externalToolBuilders/BuildSampleJNICode.launch b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/.externalToolBuilders/BuildSampleJNICode.launch new file mode 100644 index 000000000..8c0ed3941 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/.externalToolBuilders/BuildSampleJNICode.launch @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/.project b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/.project new file mode 100644 index 000000000..a45e1256d --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/.project @@ -0,0 +1,114 @@ + + + + PfxApp_2_Stable + + + PfxLibrary + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + auto,full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/BuildSampleJNICode.launch + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + + + src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + 1 + PFX_ROOT/project/Android/PfxApp_2_Stable/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + + + src/pfx/renderingsupport/PhysicsEffectsRenderer.java + 1 + PFX_ROOT/project/Android/PfxApp_2_Stable/src/pfx/renderingsupport/PhysicsEffectsRenderer.java + + + src/pfx/sample2/PfxApp_2_Stable.java + 1 + PFX_ROOT/project/Android/PfxApp_2_Stable/src/pfx/sample/PfxApp_2_Stable.java + + + + + 1305070288951 + jni + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + 1305070295995 + src + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + + + PFX_ROOT + $%7BPARENT-3-PROJECT_LOC%7D + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/AndroidManifest.xml b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/AndroidManifest.xml new file mode 100644 index 000000000..fbb33351f --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/AndroidManifest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/build.xml b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/build.xml new file mode 100644 index 000000000..45b1ef65a --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/build.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/default.properties b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/default.properties new file mode 100644 index 000000000..25c028059 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-10 diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/jni/Android.mk b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/jni/Android.mk new file mode 100644 index 000000000..4a5175d66 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/jni/Android.mk @@ -0,0 +1,107 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# NOTE: The local path here is defined based on an environment +# variable that points to the root of the Bullet/PhysicsEffects +# code base. The variable must be set in the Cygwin style, e.g., +# BULLET_PFX_ROOT_CYGWIN = /cygdrive/d/tools/PhysicsEffectsRootPath +# +# The reason for *not* just setting local path := $(call my-dir) +# is that we wish to access local source files that are *not* +# located in a "jni" subfolder and *not* located in a subfolder +# of the project folder. This enables us to have Eclipse and +# Android NDK projects that fit neatly into the Bullet/PhysicsEffects +# folder structure, enabling a multi platform code base, without +# forcing the "jni" and subfolder structure that Android SDK/NDK +# prefer for pure Android projects. +LOCAL_PATH:= $(BULLET_PFX_ROOT_CYGWIN) + +# Copy the shared static library, libpfxlibrary.a, into the build +include $(CLEAR_VARS) +LOCAL_MODULE := pfxlibrary +LOCAL_SRC_FILES := project/Android/PfxLibrary/obj/local/armeabi-v7a/libpfxlibrary.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +# Warning: do not enable SIMD vector math functions or NEON for running +# in the Android NDK emulator. NEON requires a physical device +# with NEON support. +# +# Note that in theory we can let LOCAL_ARM_NEON := true determine +# that the flags -mfpu=neon and -mfloat-abi=softfp should be applied. +# However, in practice we have seen one case where the ndk-build +# script "forgets" these flags for the occasional *.cpp file, thus +# causing those files to access the std definition of vectormath +# classes, which are completely different, including different size. +# So, we explicitly apply these flags to avoid having a broken +# build. +# +# Include -DSCE_PFX_USE_SIMD_VECTORMATH to build for ARM NEON SIMD +# intrinsics, and leave it off to use NEON for scalar math but without +# SIMD. + +LOCAL_CFLAGS := $(LOCAL_C_INCLUDES:%=-I%) -mfpu=neon -mfloat-abi=softfp -DSCE_PFX_USE_SIMD_VECTORMATH + +# apply these flags if needed +# -ffast-math -funsafe-math-optimizations + +# apply this to disable optimization +# TARGET_CFLAGS := $(TARGET_CFLAGS) -O0 + +# apply these 2 to turn on assembly output (*.c/*.cpp to *.s file) +# compile-cpp-source = $(eval $(call ev-compile-cpp-source,$1,$(1:%$(LOCAL_CPP_EXTENSION)=%.s))) +# TARGET_CFLAGS := $(TARGET_CFLAGS) -S + +# specify static libraries to link in +LOCAL_STATIC_LIBRARIES := pfxlibrary + +# Enable or disable NEON. Don't forget to apply, or not apply, -mfpu=neon and -mfloat-abi=softfp +# flags in addition, e.g., if this is true both of those need to be included in LOCAL_CFLAGS +# to avoid the possibility that ndk-build will "forget" to add them on some files +LOCAL_ARM_NEON := true +TARGET_CFLAGS := $(filter-out -ffpu=vfp,$(TARGET_CFLAGS)) + +LOCAL_MODULE := PfxApp_2_Stable +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)sample/api_physics_effects/2_stable \ + $(LOCAL_PATH)sample/api_physics_effects/common + +LOCAL_SRC_FILES := \ + sample/api_physics_effects/common/jni/physicseffects-android.cpp \ + sample/api_physics_effects/2_stable/main.cpp \ + sample/api_physics_effects/2_stable/physics_func.cpp \ + sample/api_physics_effects/common/ctrl_func.android.cpp \ + sample/api_physics_effects/common/render_func.android.cpp \ + sample/api_physics_effects/common/perf_func.android.cpp + +LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lGLESv1_CM -ldl -lm -llog + +include $(BUILD_SHARED_LIBRARY) + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/jni/Application.mk b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/jni/Application.mk new file mode 100644 index 000000000..77151c80c --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/jni/Application.mk @@ -0,0 +1,31 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +APP_MODULES := PfxApp_2_Stable +APP_ABI := armeabi-v7a +APP_OPTIM := release diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/local.properties b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/local.properties new file mode 100644 index 000000000..1659ad756 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/local.properties @@ -0,0 +1,10 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must *NOT* be checked in Version Control Systems, +# as it contains information specific to your local configuration. + +# location of the SDK. This is only used by Ant +# For customization when using a Version Control System, please read the +# header note. +sdk.dir=F:\\sdks\\Android\\android-sdk diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/proguard.cfg b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/proguard.cfg new file mode 100644 index 000000000..3e84fc735 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/proguard.cfg @@ -0,0 +1,36 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/drawable-hdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/drawable-hdpi/icon.png new file mode 100644 index 000000000..d7753923a Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/drawable-hdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/drawable-ldpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/drawable-ldpi/icon.png new file mode 100644 index 000000000..0871aa1eb Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/drawable-ldpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/drawable-mdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/drawable-mdpi/icon.png new file mode 100644 index 000000000..ff7be820f Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/drawable-mdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/layout/main.xml b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/layout/main.xml new file mode 100644 index 000000000..6c069664e --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/layout/main.xml @@ -0,0 +1,34 @@ + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/values/strings.xml b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/values/strings.xml new file mode 100644 index 000000000..e2114da8b --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/res/values/strings.xml @@ -0,0 +1,31 @@ + + + + Pfx 2 Stable + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java new file mode 100644 index 000000000..ec83e64ce --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java @@ -0,0 +1,113 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import android.opengl.GLSurfaceView; +import android.content.Context; +import android.view.MotionEvent; + +/** + * Implementation of the OpenGL ES view window and creates/assigns a renderer. + * Handles touch events to allow the user to change scene on tap, move the camera + * around by touch based movement, and allows the user to zoom in and out by pinching. + * @author ahamilton + * + */ +public class PhysicsEffectsGLSurfaceView extends GLSurfaceView { + public PhysicsEffectsGLSurfaceView(Context context) { + super(context); + peRenderer = new PhysicsEffectsRenderer(); + setRenderer(peRenderer); + } + + float x1 = 0, x2, y1 = 0, y2; + long downTime; + + /** + * Function to process touch events for camera and scene control + * + */ + public boolean onTouchEvent(final MotionEvent event) { + switch(event.getAction()) { + case(MotionEvent.ACTION_DOWN): + x1 = event.getX(); + y1 = event.getY(); + downTime = event.getDownTime(); + break; + case(MotionEvent.ACTION_UP): + if(event.getEventTime() - downTime < 100) nativeSceneChange(); + break; + case(MotionEvent.ACTION_MOVE): { + if(event.getPointerCount() == 1){ + x2 = event.getX(); + y2 = event.getY(); + float dx = x2-x1; + float dy = y2-y1; + + // Use dx and dy to determine the direction + if(dx > 0) { + nativeCameraLeft(); + } else { + nativeCameraRight(); + } + if(dy > 0){ + nativeCameraUp(); + } else { + nativeCameraDown(); + } + x1=x2; + y1=y2; + } else if(event.getPointerCount() == 2){ + y2 = event.getY(); + + float dy = y2-y1; + + // Use dy to determine zoom + if(dy > 0){ + nativeCameraZoomIn(); + } else { + nativeCameraZoomOut(); + } + y1=y2; + } + } + } + return true; + } + + PhysicsEffectsRenderer peRenderer; + + private static native void nativeCameraUp(); + private static native void nativeCameraDown(); + private static native void nativeCameraLeft(); + private static native void nativeCameraRight(); + private static native void nativeCameraZoomOut(); + private static native void nativeCameraZoomIn(); + private static native void nativeSceneChange(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/src/pfx/renderingsupport/PhysicsEffectsRenderer.java b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/src/pfx/renderingsupport/PhysicsEffectsRenderer.java new file mode 100644 index 000000000..5ca66d4b5 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/src/pfx/renderingsupport/PhysicsEffectsRenderer.java @@ -0,0 +1,101 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.opengl.GLSurfaceView; +import android.util.Log; + +/** + * Implementation of the renderer. It calls the native physicseffects code + * to run on the init and drawframe allowing the sample to perform its simulation. + * @author ahamilton + * + */ +public class PhysicsEffectsRenderer implements GLSurfaceView.Renderer { + boolean startup = true; + boolean notEnded = true; + static long startuptime; + static long endtime; + int frameCounter; + + /** + * Initilize the physics simulation after the GL surface is created. + * + */ + public void onSurfaceCreated(GL10 gl, EGLConfig config) + { + Log.v("Init physics", "Initing physics"); + nativePhysicsEffectsInit(); + Log.v("Init physics", "Inited physics"); + } + + /** + * Set the viewport for a changed GL surface + * + */ + public void onSurfaceChanged(GL10 gl, int w, int h) + { + gl.glViewport(0, 0, w, h); + } + + /** + * Perform one simulation step and render the scene. + * + */ + public void onDrawFrame(GL10 gl) + { + if(startup){ + startup = false; + frameCounter = 0; + startuptime = System.currentTimeMillis(); + endtime = startuptime + 10000; // sets run time to be 30 seconds + } + + nativePhysicsEffectsSimulate(); + + frameCounter++; + long lCurrentTime = System.currentTimeMillis(); + if(lCurrentTime > endtime && notEnded) { + float fFrameRate = (1000.0f * (float)frameCounter) / ((float)lCurrentTime - startuptime); + Log.v("PHYSICS TIMING STUDY", "Number of Frames: " + Integer.toString(frameCounter)); + Log.v("PHYSICS TIMING STUDY", "Time ellapsed (milliseconds): " + Long.toString(lCurrentTime - startuptime)); + Log.v("PHYSICS TIMING STUDY", "Bullet Frame Rate: " + Float.toString(fFrameRate) + "fps"); + notEnded = false; + } + } + + private static native void nativePhysicsEffectsInit(); + private static native void nativePhysicsEffectsSimulate(); + private static native void nativePhysicsEffectsUpdate(); + private static native void nativePhysicsEffectsPhysStep(); + private static native void nativePhysicsEffectsRender(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/src/pfx/sample2/PfxApp_2_Stable.java b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/src/pfx/sample2/PfxApp_2_Stable.java new file mode 100644 index 000000000..318754e03 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable/src/pfx/sample2/PfxApp_2_Stable.java @@ -0,0 +1,58 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.sample2; + +import pfx.renderingsupport.PhysicsEffectsGLSurfaceView; + +import android.app.Activity; +import android.opengl.GLSurfaceView; +import android.os.Bundle; + +/** + * When program loads it creates a OpenGl ES render window for + * the bullet sample projects to run in and loads the complied + * physics effects libraries. + * @author ahamilton + * + */ +public class PfxApp_2_Stable extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + peGLView = new PhysicsEffectsGLSurfaceView(this); + setContentView(peGLView); + } + + private GLSurfaceView peGLView; + + //This is where you specify which physics effects sample you would like to load + static { + System.loadLibrary("PfxApp_2_Stable"); + } +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/.classpath b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/.classpath new file mode 100644 index 000000000..98132ca43 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/.classpath @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/.externalToolBuilders/BuildSampleJNICode.launch b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/.externalToolBuilders/BuildSampleJNICode.launch new file mode 100644 index 000000000..37635faf3 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/.externalToolBuilders/BuildSampleJNICode.launch @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/.project b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/.project new file mode 100644 index 000000000..411ca1abe --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/.project @@ -0,0 +1,114 @@ + + + + PfxApp_2_Stable_Parallel + + + PfxLibrary + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + auto,full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/BuildSampleJNICode.launch + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + + + src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + 1 + PFX_ROOT/project/Android/PfxApp_2_Stable_Parallel/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + + + src/pfx/renderingsupport/PhysicsEffectsRenderer.java + 1 + PFX_ROOT/project/Android/PfxApp_2_Stable_Parallel/src/pfx/renderingsupport/PhysicsEffectsRenderer.java + + + src/pfx/sample2b/PfxApp_2_Stable_Parallel.java + 1 + PFX_ROOT/project/Android/PfxApp_2_Stable_Parallel/src/pfx/sample2b/PfxApp_2_Stable_Parallel.java + + + + + 1305070288951 + jni + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + 1305070295995 + src + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + + + PFX_ROOT + $%7BPARENT-3-PROJECT_LOC%7D + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/AndroidManifest.xml b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/AndroidManifest.xml new file mode 100644 index 000000000..ca47f66b5 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/AndroidManifest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/build.xml b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/build.xml new file mode 100644 index 000000000..15bf3cb60 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/build.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/default.properties b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/default.properties new file mode 100644 index 000000000..f4b4f1778 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-9 diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/jni/Android.mk b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/jni/Android.mk new file mode 100644 index 000000000..24cb431e2 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/jni/Android.mk @@ -0,0 +1,107 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# NOTE: The local path here is defined based on an environment +# variable that points to the root of the Bullet/PhysicsEffects +# code base. The variable must be set in the Cygwin style, e.g., +# BULLET_PFX_ROOT_CYGWIN = /cygdrive/d/tools/PhysicsEffectsRootPath +# +# The reason for *not* just setting local path := $(call my-dir) +# is that we wish to access local source files that are *not* +# located in a "jni" subfolder and *not* located in a subfolder +# of the project folder. This enables us to have Eclipse and +# Android NDK projects that fit neatly into the Bullet/PhysicsEffects +# folder structure, enabling a multi platform code base, without +# forcing the "jni" and subfolder structure that Android SDK/NDK +# prefer for pure Android projects. +LOCAL_PATH:= $(BULLET_PFX_ROOT_CYGWIN) + +# Copy the shared static library, libpfxlibrary.a, into the build +include $(CLEAR_VARS) +LOCAL_MODULE := pfxlibrary +LOCAL_SRC_FILES := project/Android/PfxLibrary/obj/local/armeabi-v7a/libpfxlibrary.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +# Warning: do not enable SIMD vector math functions or NEON for running +# in the Android NDK emulator. NEON requires a physical device +# with NEON support. +# +# Note that in theory we can let LOCAL_ARM_NEON := true determine +# that the flags -mfpu=neon and -mfloat-abi=softfp should be applied. +# However, in practice we have seen one case where the ndk-build +# script "forgets" these flags for the occasional *.cpp file, thus +# causing those files to access the std definition of vectormath +# classes, which are completely different, including different size. +# So, we explicitly apply these flags to avoid having a broken +# build. +# +# Include -DSCE_PFX_USE_SIMD_VECTORMATH to build for ARM NEON SIMD +# intrinsics, and leave it off to use NEON for scalar math but without +# SIMD. + +LOCAL_CFLAGS := $(LOCAL_C_INCLUDES:%=-I%) -DUSE_PTHREADS -mfpu=neon -mfloat-abi=softfp -pthread -DSCE_PFX_USE_SIMD_VECTORMATH + +# apply these flags if needed +# -ffast-math -funsafe-math-optimizations + +# apply this to disable optimization +# TARGET_CFLAGS := $(TARGET_CFLAGS) -O0 + +# apply these 2 to turn on assembly output (*.c/*.cpp to *.s file) +# compile-cpp-source = $(eval $(call ev-compile-cpp-source,$1,$(1:%$(LOCAL_CPP_EXTENSION)=%.s))) +# TARGET_CFLAGS := $(TARGET_CFLAGS) -S + +# specify static libraries to link in +LOCAL_STATIC_LIBRARIES := pfxlibrary + +# Enable or disable NEON. Don't forget to apply, or not apply, -mfpu=neon and -mfloat-abi=softfp +# flags in addition, e.g., if this is true both of those need to be included in LOCAL_CFLAGS +# to avoid the possibility that ndk-build will "forget" to add them on some files +LOCAL_ARM_NEON := true +TARGET_CFLAGS := $(filter-out -ffpu=vfp,$(TARGET_CFLAGS)) + +LOCAL_MODULE := PfxApp_2_Stable_Parallel +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)sample/api_physics_effects/2_stable_parallel \ + $(LOCAL_PATH)sample/api_physics_effects/common + +LOCAL_SRC_FILES := \ + sample/api_physics_effects/common/jni/physicseffects-android.cpp \ + sample/api_physics_effects/2_stable_parallel/main.cpp \ + sample/api_physics_effects/2_stable_parallel/physics_func.cpp \ + sample/api_physics_effects/common/ctrl_func.android.cpp \ + sample/api_physics_effects/common/render_func.android.cpp \ + sample/api_physics_effects/common/perf_func.android.cpp + +LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lGLESv1_CM -ldl -lm -llog + +include $(BUILD_SHARED_LIBRARY) + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/jni/Application.mk b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/jni/Application.mk new file mode 100644 index 000000000..acff843aa --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/jni/Application.mk @@ -0,0 +1,31 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +APP_MODULES := PfxApp_2_Stable_Parallel +APP_ABI := armeabi-v7a +APP_OPTIM := release diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/local.properties b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/local.properties new file mode 100644 index 000000000..1659ad756 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/local.properties @@ -0,0 +1,10 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must *NOT* be checked in Version Control Systems, +# as it contains information specific to your local configuration. + +# location of the SDK. This is only used by Ant +# For customization when using a Version Control System, please read the +# header note. +sdk.dir=F:\\sdks\\Android\\android-sdk diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/proguard.cfg b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/proguard.cfg new file mode 100644 index 000000000..3e84fc735 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/proguard.cfg @@ -0,0 +1,36 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/drawable-hdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/drawable-hdpi/icon.png new file mode 100644 index 000000000..d7753923a Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/drawable-hdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/drawable-ldpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/drawable-ldpi/icon.png new file mode 100644 index 000000000..0871aa1eb Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/drawable-ldpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/drawable-mdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/drawable-mdpi/icon.png new file mode 100644 index 000000000..ff7be820f Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/drawable-mdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/layout/main.xml b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/layout/main.xml new file mode 100644 index 000000000..6c069664e --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/layout/main.xml @@ -0,0 +1,34 @@ + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/values/strings.xml b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/values/strings.xml new file mode 100644 index 000000000..630b3001d --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/res/values/strings.xml @@ -0,0 +1,31 @@ + + + + Pfx 2 Stable Parallel + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java new file mode 100644 index 000000000..ec83e64ce --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java @@ -0,0 +1,113 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import android.opengl.GLSurfaceView; +import android.content.Context; +import android.view.MotionEvent; + +/** + * Implementation of the OpenGL ES view window and creates/assigns a renderer. + * Handles touch events to allow the user to change scene on tap, move the camera + * around by touch based movement, and allows the user to zoom in and out by pinching. + * @author ahamilton + * + */ +public class PhysicsEffectsGLSurfaceView extends GLSurfaceView { + public PhysicsEffectsGLSurfaceView(Context context) { + super(context); + peRenderer = new PhysicsEffectsRenderer(); + setRenderer(peRenderer); + } + + float x1 = 0, x2, y1 = 0, y2; + long downTime; + + /** + * Function to process touch events for camera and scene control + * + */ + public boolean onTouchEvent(final MotionEvent event) { + switch(event.getAction()) { + case(MotionEvent.ACTION_DOWN): + x1 = event.getX(); + y1 = event.getY(); + downTime = event.getDownTime(); + break; + case(MotionEvent.ACTION_UP): + if(event.getEventTime() - downTime < 100) nativeSceneChange(); + break; + case(MotionEvent.ACTION_MOVE): { + if(event.getPointerCount() == 1){ + x2 = event.getX(); + y2 = event.getY(); + float dx = x2-x1; + float dy = y2-y1; + + // Use dx and dy to determine the direction + if(dx > 0) { + nativeCameraLeft(); + } else { + nativeCameraRight(); + } + if(dy > 0){ + nativeCameraUp(); + } else { + nativeCameraDown(); + } + x1=x2; + y1=y2; + } else if(event.getPointerCount() == 2){ + y2 = event.getY(); + + float dy = y2-y1; + + // Use dy to determine zoom + if(dy > 0){ + nativeCameraZoomIn(); + } else { + nativeCameraZoomOut(); + } + y1=y2; + } + } + } + return true; + } + + PhysicsEffectsRenderer peRenderer; + + private static native void nativeCameraUp(); + private static native void nativeCameraDown(); + private static native void nativeCameraLeft(); + private static native void nativeCameraRight(); + private static native void nativeCameraZoomOut(); + private static native void nativeCameraZoomIn(); + private static native void nativeSceneChange(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/src/pfx/renderingsupport/PhysicsEffectsRenderer.java b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/src/pfx/renderingsupport/PhysicsEffectsRenderer.java new file mode 100644 index 000000000..5ca66d4b5 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/src/pfx/renderingsupport/PhysicsEffectsRenderer.java @@ -0,0 +1,101 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.opengl.GLSurfaceView; +import android.util.Log; + +/** + * Implementation of the renderer. It calls the native physicseffects code + * to run on the init and drawframe allowing the sample to perform its simulation. + * @author ahamilton + * + */ +public class PhysicsEffectsRenderer implements GLSurfaceView.Renderer { + boolean startup = true; + boolean notEnded = true; + static long startuptime; + static long endtime; + int frameCounter; + + /** + * Initilize the physics simulation after the GL surface is created. + * + */ + public void onSurfaceCreated(GL10 gl, EGLConfig config) + { + Log.v("Init physics", "Initing physics"); + nativePhysicsEffectsInit(); + Log.v("Init physics", "Inited physics"); + } + + /** + * Set the viewport for a changed GL surface + * + */ + public void onSurfaceChanged(GL10 gl, int w, int h) + { + gl.glViewport(0, 0, w, h); + } + + /** + * Perform one simulation step and render the scene. + * + */ + public void onDrawFrame(GL10 gl) + { + if(startup){ + startup = false; + frameCounter = 0; + startuptime = System.currentTimeMillis(); + endtime = startuptime + 10000; // sets run time to be 30 seconds + } + + nativePhysicsEffectsSimulate(); + + frameCounter++; + long lCurrentTime = System.currentTimeMillis(); + if(lCurrentTime > endtime && notEnded) { + float fFrameRate = (1000.0f * (float)frameCounter) / ((float)lCurrentTime - startuptime); + Log.v("PHYSICS TIMING STUDY", "Number of Frames: " + Integer.toString(frameCounter)); + Log.v("PHYSICS TIMING STUDY", "Time ellapsed (milliseconds): " + Long.toString(lCurrentTime - startuptime)); + Log.v("PHYSICS TIMING STUDY", "Bullet Frame Rate: " + Float.toString(fFrameRate) + "fps"); + notEnded = false; + } + } + + private static native void nativePhysicsEffectsInit(); + private static native void nativePhysicsEffectsSimulate(); + private static native void nativePhysicsEffectsUpdate(); + private static native void nativePhysicsEffectsPhysStep(); + private static native void nativePhysicsEffectsRender(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/src/pfx/sample2b/PfxApp_2_Stable_Parallel.java b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/src/pfx/sample2b/PfxApp_2_Stable_Parallel.java new file mode 100644 index 000000000..40ff1450a --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_2_Stable_Parallel/src/pfx/sample2b/PfxApp_2_Stable_Parallel.java @@ -0,0 +1,58 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.sample2b; + +import pfx.renderingsupport.PhysicsEffectsGLSurfaceView; + +import android.app.Activity; +import android.opengl.GLSurfaceView; +import android.os.Bundle; + +/** + * When program loads it creates a OpenGl ES render window for + * the bullet sample projects to run in and loads the complied + * physics effects libraries. + * @author ahamilton + * + */ +public class PfxApp_2_Stable_Parallel extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + peGLView = new PhysicsEffectsGLSurfaceView(this); + setContentView(peGLView); + } + + private GLSurfaceView peGLView; + + //This is where you specify which physics effects sample you would like to load + static { + System.loadLibrary("PfxApp_2_Stable_Parallel"); + } +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/.classpath b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/.classpath new file mode 100644 index 000000000..98132ca43 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/.classpath @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/.externalToolBuilders/BuildSampleJNICode.launch b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/.externalToolBuilders/BuildSampleJNICode.launch new file mode 100644 index 000000000..dfb6be45c --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/.externalToolBuilders/BuildSampleJNICode.launch @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/.project b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/.project new file mode 100644 index 000000000..b255ca0e6 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/.project @@ -0,0 +1,114 @@ + + + + PfxApp_3_Sleep + + + PfxLibrary + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + auto,full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/BuildSampleJNICode.launch + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + + + src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + 1 + PFX_ROOT/project/Android/PfxApp_3_Sleep/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + + + src/pfx/renderingsupport/PhysicsEffectsRenderer.java + 1 + PFX_ROOT/project/Android/PfxApp_3_Sleep/src/pfx/renderingsupport/PhysicsEffectsRenderer.java + + + src/pfx/sample3/PfxApp_3_Sleep.java + 1 + PFX_ROOT/project/Android/PfxApp_3_Sleep/src/pfx/sample/PfxApp_3_Sleep.java + + + + + 1305070288951 + jni + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + 1305070295995 + src + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + + + PFX_ROOT + $%7BPARENT-3-PROJECT_LOC%7D + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/AndroidManifest.xml b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/AndroidManifest.xml new file mode 100644 index 000000000..a07242c80 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/AndroidManifest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/build.xml b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/build.xml new file mode 100644 index 000000000..cab642bca --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/build.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/default.properties b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/default.properties new file mode 100644 index 000000000..25c028059 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-10 diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/jni/Android.mk b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/jni/Android.mk new file mode 100644 index 000000000..e92d914a6 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/jni/Android.mk @@ -0,0 +1,107 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# NOTE: The local path here is defined based on an environment +# variable that points to the root of the Bullet/PhysicsEffects +# code base. The variable must be set in the Cygwin style, e.g., +# BULLET_PFX_ROOT_CYGWIN = /cygdrive/d/tools/PhysicsEffectsRootPath +# +# The reason for *not* just setting local path := $(call my-dir) +# is that we wish to access local source files that are *not* +# located in a "jni" subfolder and *not* located in a subfolder +# of the project folder. This enables us to have Eclipse and +# Android NDK projects that fit neatly into the Bullet/PhysicsEffects +# folder structure, enabling a multi platform code base, without +# forcing the "jni" and subfolder structure that Android SDK/NDK +# prefer for pure Android projects. +LOCAL_PATH:= $(BULLET_PFX_ROOT_CYGWIN) + +# Copy the shared static library, libpfxlibrary.a, into the build +include $(CLEAR_VARS) +LOCAL_MODULE := pfxlibrary +LOCAL_SRC_FILES := project/Android/PfxLibrary/obj/local/armeabi-v7a/libpfxlibrary.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +# Warning: do not enable SIMD vector math functions or NEON for running +# in the Android NDK emulator. NEON requires a physical device +# with NEON support. +# +# Note that in theory we can let LOCAL_ARM_NEON := true determine +# that the flags -mfpu=neon and -mfloat-abi=softfp should be applied. +# However, in practice we have seen one case where the ndk-build +# script "forgets" these flags for the occasional *.cpp file, thus +# causing those files to access the std definition of vectormath +# classes, which are completely different, including different size. +# So, we explicitly apply these flags to avoid having a broken +# build. +# +# Include -DSCE_PFX_USE_SIMD_VECTORMATH to build for ARM NEON SIMD +# intrinsics, and leave it off to use NEON for scalar math but without +# SIMD. + +LOCAL_CFLAGS := $(LOCAL_C_INCLUDES:%=-I%) -mfpu=neon -mfloat-abi=softfp -DSCE_PFX_USE_SIMD_VECTORMATH + +# apply these flags if needed +# -ffast-math -funsafe-math-optimizations + +# apply this to disable optimization +# TARGET_CFLAGS := $(TARGET_CFLAGS) -O0 + +# apply these 2 to turn on assembly output (*.c/*.cpp to *.s file) +# compile-cpp-source = $(eval $(call ev-compile-cpp-source,$1,$(1:%$(LOCAL_CPP_EXTENSION)=%.s))) +# TARGET_CFLAGS := $(TARGET_CFLAGS) -S + +# specify static libraries to link in +LOCAL_STATIC_LIBRARIES := pfxlibrary + +# Enable or disable NEON. Don't forget to apply, or not apply, -mfpu=neon and -mfloat-abi=softfp +# flags in addition, e.g., if this is true both of those need to be included in LOCAL_CFLAGS +# to avoid the possibility that ndk-build will "forget" to add them on some files +LOCAL_ARM_NEON := true +TARGET_CFLAGS := $(filter-out -ffpu=vfp,$(TARGET_CFLAGS)) + +LOCAL_MODULE := PfxApp_3_Sleep +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)sample/api_physics_effects/3_sleep \ + $(LOCAL_PATH)sample/api_physics_effects/common + +LOCAL_SRC_FILES := \ + sample/api_physics_effects/common/jni/physicseffects-android.cpp \ + sample/api_physics_effects/3_sleep/main.cpp \ + sample/api_physics_effects/3_sleep/physics_func.cpp \ + sample/api_physics_effects/common/ctrl_func.android.cpp \ + sample/api_physics_effects/common/render_func.android.cpp \ + sample/api_physics_effects/common/perf_func.android.cpp + +LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lGLESv1_CM -ldl -lm -llog + +include $(BUILD_SHARED_LIBRARY) + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/jni/Application.mk b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/jni/Application.mk new file mode 100644 index 000000000..3fdd58bc6 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/jni/Application.mk @@ -0,0 +1,31 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +APP_MODULES := PfxApp_3_Sleep +APP_ABI := armeabi-v7a +APP_OPTIM := release diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/local.properties b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/local.properties new file mode 100644 index 000000000..1659ad756 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/local.properties @@ -0,0 +1,10 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must *NOT* be checked in Version Control Systems, +# as it contains information specific to your local configuration. + +# location of the SDK. This is only used by Ant +# For customization when using a Version Control System, please read the +# header note. +sdk.dir=F:\\sdks\\Android\\android-sdk diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/proguard.cfg b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/proguard.cfg new file mode 100644 index 000000000..3e84fc735 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/proguard.cfg @@ -0,0 +1,36 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/drawable-hdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/drawable-hdpi/icon.png new file mode 100644 index 000000000..d7753923a Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/drawable-hdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/drawable-ldpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/drawable-ldpi/icon.png new file mode 100644 index 000000000..0871aa1eb Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/drawable-ldpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/drawable-mdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/drawable-mdpi/icon.png new file mode 100644 index 000000000..ff7be820f Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/drawable-mdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/layout/main.xml b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/layout/main.xml new file mode 100644 index 000000000..6c069664e --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/layout/main.xml @@ -0,0 +1,34 @@ + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/values/strings.xml b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/values/strings.xml new file mode 100644 index 000000000..832910db4 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/res/values/strings.xml @@ -0,0 +1,31 @@ + + + + Pfx 3 Sleep + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java new file mode 100644 index 000000000..ec83e64ce --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java @@ -0,0 +1,113 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import android.opengl.GLSurfaceView; +import android.content.Context; +import android.view.MotionEvent; + +/** + * Implementation of the OpenGL ES view window and creates/assigns a renderer. + * Handles touch events to allow the user to change scene on tap, move the camera + * around by touch based movement, and allows the user to zoom in and out by pinching. + * @author ahamilton + * + */ +public class PhysicsEffectsGLSurfaceView extends GLSurfaceView { + public PhysicsEffectsGLSurfaceView(Context context) { + super(context); + peRenderer = new PhysicsEffectsRenderer(); + setRenderer(peRenderer); + } + + float x1 = 0, x2, y1 = 0, y2; + long downTime; + + /** + * Function to process touch events for camera and scene control + * + */ + public boolean onTouchEvent(final MotionEvent event) { + switch(event.getAction()) { + case(MotionEvent.ACTION_DOWN): + x1 = event.getX(); + y1 = event.getY(); + downTime = event.getDownTime(); + break; + case(MotionEvent.ACTION_UP): + if(event.getEventTime() - downTime < 100) nativeSceneChange(); + break; + case(MotionEvent.ACTION_MOVE): { + if(event.getPointerCount() == 1){ + x2 = event.getX(); + y2 = event.getY(); + float dx = x2-x1; + float dy = y2-y1; + + // Use dx and dy to determine the direction + if(dx > 0) { + nativeCameraLeft(); + } else { + nativeCameraRight(); + } + if(dy > 0){ + nativeCameraUp(); + } else { + nativeCameraDown(); + } + x1=x2; + y1=y2; + } else if(event.getPointerCount() == 2){ + y2 = event.getY(); + + float dy = y2-y1; + + // Use dy to determine zoom + if(dy > 0){ + nativeCameraZoomIn(); + } else { + nativeCameraZoomOut(); + } + y1=y2; + } + } + } + return true; + } + + PhysicsEffectsRenderer peRenderer; + + private static native void nativeCameraUp(); + private static native void nativeCameraDown(); + private static native void nativeCameraLeft(); + private static native void nativeCameraRight(); + private static native void nativeCameraZoomOut(); + private static native void nativeCameraZoomIn(); + private static native void nativeSceneChange(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/src/pfx/renderingsupport/PhysicsEffectsRenderer.java b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/src/pfx/renderingsupport/PhysicsEffectsRenderer.java new file mode 100644 index 000000000..5ca66d4b5 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/src/pfx/renderingsupport/PhysicsEffectsRenderer.java @@ -0,0 +1,101 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.opengl.GLSurfaceView; +import android.util.Log; + +/** + * Implementation of the renderer. It calls the native physicseffects code + * to run on the init and drawframe allowing the sample to perform its simulation. + * @author ahamilton + * + */ +public class PhysicsEffectsRenderer implements GLSurfaceView.Renderer { + boolean startup = true; + boolean notEnded = true; + static long startuptime; + static long endtime; + int frameCounter; + + /** + * Initilize the physics simulation after the GL surface is created. + * + */ + public void onSurfaceCreated(GL10 gl, EGLConfig config) + { + Log.v("Init physics", "Initing physics"); + nativePhysicsEffectsInit(); + Log.v("Init physics", "Inited physics"); + } + + /** + * Set the viewport for a changed GL surface + * + */ + public void onSurfaceChanged(GL10 gl, int w, int h) + { + gl.glViewport(0, 0, w, h); + } + + /** + * Perform one simulation step and render the scene. + * + */ + public void onDrawFrame(GL10 gl) + { + if(startup){ + startup = false; + frameCounter = 0; + startuptime = System.currentTimeMillis(); + endtime = startuptime + 10000; // sets run time to be 30 seconds + } + + nativePhysicsEffectsSimulate(); + + frameCounter++; + long lCurrentTime = System.currentTimeMillis(); + if(lCurrentTime > endtime && notEnded) { + float fFrameRate = (1000.0f * (float)frameCounter) / ((float)lCurrentTime - startuptime); + Log.v("PHYSICS TIMING STUDY", "Number of Frames: " + Integer.toString(frameCounter)); + Log.v("PHYSICS TIMING STUDY", "Time ellapsed (milliseconds): " + Long.toString(lCurrentTime - startuptime)); + Log.v("PHYSICS TIMING STUDY", "Bullet Frame Rate: " + Float.toString(fFrameRate) + "fps"); + notEnded = false; + } + } + + private static native void nativePhysicsEffectsInit(); + private static native void nativePhysicsEffectsSimulate(); + private static native void nativePhysicsEffectsUpdate(); + private static native void nativePhysicsEffectsPhysStep(); + private static native void nativePhysicsEffectsRender(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/src/pfx/sample3/PfxApp_3_Sleep.java b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/src/pfx/sample3/PfxApp_3_Sleep.java new file mode 100644 index 000000000..29e2b96d5 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_3_Sleep/src/pfx/sample3/PfxApp_3_Sleep.java @@ -0,0 +1,58 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.sample3; + +import pfx.renderingsupport.PhysicsEffectsGLSurfaceView; + +import android.app.Activity; +import android.opengl.GLSurfaceView; +import android.os.Bundle; + +/** + * When program loads it creates a OpenGl ES render window for + * the bullet sample projects to run in and loads the complied + * physics effects libraries. + * @author ahamilton + * + */ +public class PfxApp_3_Sleep extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + peGLView = new PhysicsEffectsGLSurfaceView(this); + setContentView(peGLView); + } + + private GLSurfaceView peGLView; + + //This is where you specify which physics effects sample you would like to load + static { + System.loadLibrary("PfxApp_3_Sleep"); + } +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/.classpath b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/.classpath new file mode 100644 index 000000000..98132ca43 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/.classpath @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/.externalToolBuilders/BuildSampleJNICode.launch b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/.externalToolBuilders/BuildSampleJNICode.launch new file mode 100644 index 000000000..66e0e1c64 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/.externalToolBuilders/BuildSampleJNICode.launch @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/.project b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/.project new file mode 100644 index 000000000..90be27d62 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/.project @@ -0,0 +1,114 @@ + + + + PfxApp_4_MotionType + + + PfxLibrary + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + auto,full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/BuildSampleJNICode.launch + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + + + src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + 1 + PFX_ROOT/project/Android/PfxApp_4_MotionType/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + + + src/pfx/renderingsupport/PhysicsEffectsRenderer.java + 1 + PFX_ROOT/project/Android/PfxApp_4_MotionType/src/pfx/renderingsupport/PhysicsEffectsRenderer.java + + + src/pfx/sample4/PfxApp_4_MotionType.java + 1 + PFX_ROOT/project/Android/PfxApp_4_MotionType/src/pfx/PfxApp_4_MotionType.java + + + + + 1305070288951 + jni + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + 1305070295995 + src + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + + + PFX_ROOT + $%7BPARENT-3-PROJECT_LOC%7D + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/AndroidManifest.xml b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/AndroidManifest.xml new file mode 100644 index 000000000..e49f9b6ca --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/AndroidManifest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/build.xml b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/build.xml new file mode 100644 index 000000000..bf58c3d9f --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/build.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/default.properties b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/default.properties new file mode 100644 index 000000000..f4b4f1778 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-9 diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/jni/Android.mk b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/jni/Android.mk new file mode 100644 index 000000000..1666da8c1 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/jni/Android.mk @@ -0,0 +1,107 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# NOTE: The local path here is defined based on an environment +# variable that points to the root of the Bullet/PhysicsEffects +# code base. The variable must be set in the Cygwin style, e.g., +# BULLET_PFX_ROOT_CYGWIN = /cygdrive/d/tools/PhysicsEffectsRootPath +# +# The reason for *not* just setting local path := $(call my-dir) +# is that we wish to access local source files that are *not* +# located in a "jni" subfolder and *not* located in a subfolder +# of the project folder. This enables us to have Eclipse and +# Android NDK projects that fit neatly into the Bullet/PhysicsEffects +# folder structure, enabling a multi platform code base, without +# forcing the "jni" and subfolder structure that Android SDK/NDK +# prefer for pure Android projects. +LOCAL_PATH:= $(BULLET_PFX_ROOT_CYGWIN) + +# Copy the shared static library, libpfxlibrary.a, into the build +include $(CLEAR_VARS) +LOCAL_MODULE := pfxlibrary +LOCAL_SRC_FILES := project/Android/PfxLibrary/obj/local/armeabi-v7a/libpfxlibrary.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +# Warning: do not enable SIMD vector math functions or NEON for running +# in the Android NDK emulator. NEON requires a physical device +# with NEON support. +# +# Note that in theory we can let LOCAL_ARM_NEON := true determine +# that the flags -mfpu=neon and -mfloat-abi=softfp should be applied. +# However, in practice we have seen one case where the ndk-build +# script "forgets" these flags for the occasional *.cpp file, thus +# causing those files to access the std definition of vectormath +# classes, which are completely different, including different size. +# So, we explicitly apply these flags to avoid having a broken +# build. +# +# Include -DSCE_PFX_USE_SIMD_VECTORMATH to build for ARM NEON SIMD +# intrinsics, and leave it off to use NEON for scalar math but without +# SIMD. + +LOCAL_CFLAGS := $(LOCAL_C_INCLUDES:%=-I%) -mfpu=neon -mfloat-abi=softfp -DSCE_PFX_USE_SIMD_VECTORMATH + +# apply these flags if needed +# -ffast-math -funsafe-math-optimizations + +# apply this to disable optimization +# TARGET_CFLAGS := $(TARGET_CFLAGS) -O0 + +# apply these 2 to turn on assembly output (*.c/*.cpp to *.s file) +# compile-cpp-source = $(eval $(call ev-compile-cpp-source,$1,$(1:%$(LOCAL_CPP_EXTENSION)=%.s))) +# TARGET_CFLAGS := $(TARGET_CFLAGS) -S + +# specify static libraries to link in +LOCAL_STATIC_LIBRARIES := pfxlibrary + +# Enable or disable NEON. Don't forget to apply, or not apply, -mfpu=neon and -mfloat-abi=softfp +# flags in addition, e.g., if this is true both of those need to be included in LOCAL_CFLAGS +# to avoid the possibility that ndk-build will "forget" to add them on some files +LOCAL_ARM_NEON := true +TARGET_CFLAGS := $(filter-out -ffpu=vfp,$(TARGET_CFLAGS)) + +LOCAL_MODULE := PfxApp_4_MotionType +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)sample/api_physics_effects/4_motion_type \ + $(LOCAL_PATH)sample/api_physics_effects/common + +LOCAL_SRC_FILES := \ + sample/api_physics_effects/common/jni/physicseffects-android.cpp \ + sample/api_physics_effects/4_motion_type/main.cpp \ + sample/api_physics_effects/4_motion_type/physics_func.cpp \ + sample/api_physics_effects/common/ctrl_func.android.cpp \ + sample/api_physics_effects/common/render_func.android.cpp \ + sample/api_physics_effects/common/perf_func.android.cpp + +LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lGLESv1_CM -ldl -lm -llog + +include $(BUILD_SHARED_LIBRARY) + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/jni/Application.mk b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/jni/Application.mk new file mode 100644 index 000000000..6f49a4bbe --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/jni/Application.mk @@ -0,0 +1,31 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +APP_MODULES := PfxApp_4_MotionType +APP_ABI := armeabi-v7a +APP_OPTIM := release diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/local.properties b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/local.properties new file mode 100644 index 000000000..1659ad756 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/local.properties @@ -0,0 +1,10 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must *NOT* be checked in Version Control Systems, +# as it contains information specific to your local configuration. + +# location of the SDK. This is only used by Ant +# For customization when using a Version Control System, please read the +# header note. +sdk.dir=F:\\sdks\\Android\\android-sdk diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/proguard.cfg b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/proguard.cfg new file mode 100644 index 000000000..3e84fc735 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/proguard.cfg @@ -0,0 +1,36 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/drawable-hdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/drawable-hdpi/icon.png new file mode 100644 index 000000000..d7753923a Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/drawable-hdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/drawable-ldpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/drawable-ldpi/icon.png new file mode 100644 index 000000000..0871aa1eb Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/drawable-ldpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/drawable-mdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/drawable-mdpi/icon.png new file mode 100644 index 000000000..ff7be820f Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/drawable-mdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/layout/main.xml b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/layout/main.xml new file mode 100644 index 000000000..6c069664e --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/layout/main.xml @@ -0,0 +1,34 @@ + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/values/strings.xml b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/values/strings.xml new file mode 100644 index 000000000..cdeb98a28 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/res/values/strings.xml @@ -0,0 +1,31 @@ + + + + Pfx 4 Motion Type + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java new file mode 100644 index 000000000..ec83e64ce --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java @@ -0,0 +1,113 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import android.opengl.GLSurfaceView; +import android.content.Context; +import android.view.MotionEvent; + +/** + * Implementation of the OpenGL ES view window and creates/assigns a renderer. + * Handles touch events to allow the user to change scene on tap, move the camera + * around by touch based movement, and allows the user to zoom in and out by pinching. + * @author ahamilton + * + */ +public class PhysicsEffectsGLSurfaceView extends GLSurfaceView { + public PhysicsEffectsGLSurfaceView(Context context) { + super(context); + peRenderer = new PhysicsEffectsRenderer(); + setRenderer(peRenderer); + } + + float x1 = 0, x2, y1 = 0, y2; + long downTime; + + /** + * Function to process touch events for camera and scene control + * + */ + public boolean onTouchEvent(final MotionEvent event) { + switch(event.getAction()) { + case(MotionEvent.ACTION_DOWN): + x1 = event.getX(); + y1 = event.getY(); + downTime = event.getDownTime(); + break; + case(MotionEvent.ACTION_UP): + if(event.getEventTime() - downTime < 100) nativeSceneChange(); + break; + case(MotionEvent.ACTION_MOVE): { + if(event.getPointerCount() == 1){ + x2 = event.getX(); + y2 = event.getY(); + float dx = x2-x1; + float dy = y2-y1; + + // Use dx and dy to determine the direction + if(dx > 0) { + nativeCameraLeft(); + } else { + nativeCameraRight(); + } + if(dy > 0){ + nativeCameraUp(); + } else { + nativeCameraDown(); + } + x1=x2; + y1=y2; + } else if(event.getPointerCount() == 2){ + y2 = event.getY(); + + float dy = y2-y1; + + // Use dy to determine zoom + if(dy > 0){ + nativeCameraZoomIn(); + } else { + nativeCameraZoomOut(); + } + y1=y2; + } + } + } + return true; + } + + PhysicsEffectsRenderer peRenderer; + + private static native void nativeCameraUp(); + private static native void nativeCameraDown(); + private static native void nativeCameraLeft(); + private static native void nativeCameraRight(); + private static native void nativeCameraZoomOut(); + private static native void nativeCameraZoomIn(); + private static native void nativeSceneChange(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/src/pfx/renderingsupport/PhysicsEffectsRenderer.java b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/src/pfx/renderingsupport/PhysicsEffectsRenderer.java new file mode 100644 index 000000000..5ca66d4b5 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/src/pfx/renderingsupport/PhysicsEffectsRenderer.java @@ -0,0 +1,101 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.opengl.GLSurfaceView; +import android.util.Log; + +/** + * Implementation of the renderer. It calls the native physicseffects code + * to run on the init and drawframe allowing the sample to perform its simulation. + * @author ahamilton + * + */ +public class PhysicsEffectsRenderer implements GLSurfaceView.Renderer { + boolean startup = true; + boolean notEnded = true; + static long startuptime; + static long endtime; + int frameCounter; + + /** + * Initilize the physics simulation after the GL surface is created. + * + */ + public void onSurfaceCreated(GL10 gl, EGLConfig config) + { + Log.v("Init physics", "Initing physics"); + nativePhysicsEffectsInit(); + Log.v("Init physics", "Inited physics"); + } + + /** + * Set the viewport for a changed GL surface + * + */ + public void onSurfaceChanged(GL10 gl, int w, int h) + { + gl.glViewport(0, 0, w, h); + } + + /** + * Perform one simulation step and render the scene. + * + */ + public void onDrawFrame(GL10 gl) + { + if(startup){ + startup = false; + frameCounter = 0; + startuptime = System.currentTimeMillis(); + endtime = startuptime + 10000; // sets run time to be 30 seconds + } + + nativePhysicsEffectsSimulate(); + + frameCounter++; + long lCurrentTime = System.currentTimeMillis(); + if(lCurrentTime > endtime && notEnded) { + float fFrameRate = (1000.0f * (float)frameCounter) / ((float)lCurrentTime - startuptime); + Log.v("PHYSICS TIMING STUDY", "Number of Frames: " + Integer.toString(frameCounter)); + Log.v("PHYSICS TIMING STUDY", "Time ellapsed (milliseconds): " + Long.toString(lCurrentTime - startuptime)); + Log.v("PHYSICS TIMING STUDY", "Bullet Frame Rate: " + Float.toString(fFrameRate) + "fps"); + notEnded = false; + } + } + + private static native void nativePhysicsEffectsInit(); + private static native void nativePhysicsEffectsSimulate(); + private static native void nativePhysicsEffectsUpdate(); + private static native void nativePhysicsEffectsPhysStep(); + private static native void nativePhysicsEffectsRender(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/src/pfx/sample4/PfxApp_4_MotionType.java b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/src/pfx/sample4/PfxApp_4_MotionType.java new file mode 100644 index 000000000..915561419 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_4_MotionType/src/pfx/sample4/PfxApp_4_MotionType.java @@ -0,0 +1,58 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.sample4; + +import pfx.renderingsupport.PhysicsEffectsGLSurfaceView; + +import android.app.Activity; +import android.opengl.GLSurfaceView; +import android.os.Bundle; + +/** + * When program loads it creates a OpenGl ES render window for + * the bullet sample projects to run in and loads the complied + * physics effects libraries. + * @author ahamilton + * + */ +public class PfxApp_4_MotionType extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + peGLView = new PhysicsEffectsGLSurfaceView(this); + setContentView(peGLView); + } + + private GLSurfaceView peGLView; + + //This is where you specify which physics effects sample you would like to load + static { + System.loadLibrary("PfxApp_4_MotionType"); + } +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/.classpath b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/.classpath new file mode 100644 index 000000000..98132ca43 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/.classpath @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/.externalToolBuilders/BuildSampleJNICode.launch b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/.externalToolBuilders/BuildSampleJNICode.launch new file mode 100644 index 000000000..ea5ac97f7 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/.externalToolBuilders/BuildSampleJNICode.launch @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/.project b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/.project new file mode 100644 index 000000000..f8f61f0df --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/.project @@ -0,0 +1,114 @@ + + + + PfxApp_5_Raycast + + + PfxLibrary + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + auto,full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/BuildSampleJNICode.launch + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + + + src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + 1 + PFX_ROOT/project/Android/PfxApp_5_Raycast/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + + + src/pfx/renderingsupport/PhysicsEffectsRenderer.java + 1 + PFX_ROOT/project/Android/PfxApp_5_Raycast/src/pfx/renderingsupport/PhysicsEffectsRenderer.java + + + src/pfx/sample5/PfxApp_5_Raycast.java + 1 + PFX_ROOT/project/Android/PfxApp_5_Raycast/src/pfx/sample/PfxApp_5_Raycast.java + + + + + 1305070288951 + jni + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + 1305070295995 + src + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + + + PFX_ROOT + $%7BPARENT-3-PROJECT_LOC%7D + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/AndroidManifest.xml b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/AndroidManifest.xml new file mode 100644 index 000000000..4fd40eed9 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/AndroidManifest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/build.xml b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/build.xml new file mode 100644 index 000000000..d0ad8b90a --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/build.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/default.properties b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/default.properties new file mode 100644 index 000000000..f4b4f1778 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-9 diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/jni/Android.mk b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/jni/Android.mk new file mode 100644 index 000000000..502d45569 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/jni/Android.mk @@ -0,0 +1,107 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# NOTE: The local path here is defined based on an environment +# variable that points to the root of the Bullet/PhysicsEffects +# code base. The variable must be set in the Cygwin style, e.g., +# BULLET_PFX_ROOT_CYGWIN = /cygdrive/d/tools/PhysicsEffectsRootPath +# +# The reason for *not* just setting local path := $(call my-dir) +# is that we wish to access local source files that are *not* +# located in a "jni" subfolder and *not* located in a subfolder +# of the project folder. This enables us to have Eclipse and +# Android NDK projects that fit neatly into the Bullet/PhysicsEffects +# folder structure, enabling a multi platform code base, without +# forcing the "jni" and subfolder structure that Android SDK/NDK +# prefer for pure Android projects. +LOCAL_PATH:= $(BULLET_PFX_ROOT_CYGWIN) + +# Copy the shared static library, libpfxlibrary.a, into the build +include $(CLEAR_VARS) +LOCAL_MODULE := pfxlibrary +LOCAL_SRC_FILES := project/Android/PfxLibrary/obj/local/armeabi-v7a/libpfxlibrary.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +# Warning: do not enable SIMD vector math functions or NEON for running +# in the Android NDK emulator. NEON requires a physical device +# with NEON support. +# +# Note that in theory we can let LOCAL_ARM_NEON := true determine +# that the flags -mfpu=neon and -mfloat-abi=softfp should be applied. +# However, in practice we have seen one case where the ndk-build +# script "forgets" these flags for the occasional *.cpp file, thus +# causing those files to access the std definition of vectormath +# classes, which are completely different, including different size. +# So, we explicitly apply these flags to avoid having a broken +# build. +# +# Include -DSCE_PFX_USE_SIMD_VECTORMATH to build for ARM NEON SIMD +# intrinsics, and leave it off to use NEON for scalar math but without +# SIMD. + +LOCAL_CFLAGS := $(LOCAL_C_INCLUDES:%=-I%) -mfpu=neon -mfloat-abi=softfp -DSCE_PFX_USE_SIMD_VECTORMATH + +# apply these flags if needed +# -ffast-math -funsafe-math-optimizations + +# apply this to disable optimization +# TARGET_CFLAGS := $(TARGET_CFLAGS) -O0 + +# apply these 2 to turn on assembly output (*.c/*.cpp to *.s file) +# compile-cpp-source = $(eval $(call ev-compile-cpp-source,$1,$(1:%$(LOCAL_CPP_EXTENSION)=%.s))) +# TARGET_CFLAGS := $(TARGET_CFLAGS) -S + +# specify static libraries to link in +LOCAL_STATIC_LIBRARIES := pfxlibrary + +# Enable or disable NEON. Don't forget to apply, or not apply, -mfpu=neon and -mfloat-abi=softfp +# flags in addition, e.g., if this is true both of those need to be included in LOCAL_CFLAGS +# to avoid the possibility that ndk-build will "forget" to add them on some files +LOCAL_ARM_NEON := true +TARGET_CFLAGS := $(filter-out -ffpu=vfp,$(TARGET_CFLAGS)) + +LOCAL_MODULE := PfxApp_5_Raycast +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)sample/api_physics_effects/5_raycast \ + $(LOCAL_PATH)sample/api_physics_effects/common + +LOCAL_SRC_FILES := \ + sample/api_physics_effects/common/jni/physicseffects-android.cpp \ + sample/api_physics_effects/5_raycast/main.cpp \ + sample/api_physics_effects/5_raycast/physics_func.cpp \ + sample/api_physics_effects/common/ctrl_func.android.cpp \ + sample/api_physics_effects/common/render_func.android.cpp \ + sample/api_physics_effects/common/perf_func.android.cpp + +LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lGLESv1_CM -ldl -lm -llog + +include $(BUILD_SHARED_LIBRARY) + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/jni/Application.mk b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/jni/Application.mk new file mode 100644 index 000000000..024f67813 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/jni/Application.mk @@ -0,0 +1,31 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +APP_MODULES := PfxApp_5_Raycast +APP_ABI := armeabi-v7a +APP_OPTIM := release diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/local.properties b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/local.properties new file mode 100644 index 000000000..1659ad756 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/local.properties @@ -0,0 +1,10 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must *NOT* be checked in Version Control Systems, +# as it contains information specific to your local configuration. + +# location of the SDK. This is only used by Ant +# For customization when using a Version Control System, please read the +# header note. +sdk.dir=F:\\sdks\\Android\\android-sdk diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/proguard.cfg b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/proguard.cfg new file mode 100644 index 000000000..3e84fc735 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/proguard.cfg @@ -0,0 +1,36 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/drawable-hdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/drawable-hdpi/icon.png new file mode 100644 index 000000000..d7753923a Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/drawable-hdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/drawable-ldpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/drawable-ldpi/icon.png new file mode 100644 index 000000000..0871aa1eb Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/drawable-ldpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/drawable-mdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/drawable-mdpi/icon.png new file mode 100644 index 000000000..ff7be820f Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/drawable-mdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/layout/main.xml b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/layout/main.xml new file mode 100644 index 000000000..6c069664e --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/layout/main.xml @@ -0,0 +1,34 @@ + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/values/strings.xml b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/values/strings.xml new file mode 100644 index 000000000..c3d96aa74 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/res/values/strings.xml @@ -0,0 +1,31 @@ + + + + Pfx 5 Raycast + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java new file mode 100644 index 000000000..ec83e64ce --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java @@ -0,0 +1,113 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import android.opengl.GLSurfaceView; +import android.content.Context; +import android.view.MotionEvent; + +/** + * Implementation of the OpenGL ES view window and creates/assigns a renderer. + * Handles touch events to allow the user to change scene on tap, move the camera + * around by touch based movement, and allows the user to zoom in and out by pinching. + * @author ahamilton + * + */ +public class PhysicsEffectsGLSurfaceView extends GLSurfaceView { + public PhysicsEffectsGLSurfaceView(Context context) { + super(context); + peRenderer = new PhysicsEffectsRenderer(); + setRenderer(peRenderer); + } + + float x1 = 0, x2, y1 = 0, y2; + long downTime; + + /** + * Function to process touch events for camera and scene control + * + */ + public boolean onTouchEvent(final MotionEvent event) { + switch(event.getAction()) { + case(MotionEvent.ACTION_DOWN): + x1 = event.getX(); + y1 = event.getY(); + downTime = event.getDownTime(); + break; + case(MotionEvent.ACTION_UP): + if(event.getEventTime() - downTime < 100) nativeSceneChange(); + break; + case(MotionEvent.ACTION_MOVE): { + if(event.getPointerCount() == 1){ + x2 = event.getX(); + y2 = event.getY(); + float dx = x2-x1; + float dy = y2-y1; + + // Use dx and dy to determine the direction + if(dx > 0) { + nativeCameraLeft(); + } else { + nativeCameraRight(); + } + if(dy > 0){ + nativeCameraUp(); + } else { + nativeCameraDown(); + } + x1=x2; + y1=y2; + } else if(event.getPointerCount() == 2){ + y2 = event.getY(); + + float dy = y2-y1; + + // Use dy to determine zoom + if(dy > 0){ + nativeCameraZoomIn(); + } else { + nativeCameraZoomOut(); + } + y1=y2; + } + } + } + return true; + } + + PhysicsEffectsRenderer peRenderer; + + private static native void nativeCameraUp(); + private static native void nativeCameraDown(); + private static native void nativeCameraLeft(); + private static native void nativeCameraRight(); + private static native void nativeCameraZoomOut(); + private static native void nativeCameraZoomIn(); + private static native void nativeSceneChange(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/src/pfx/renderingsupport/PhysicsEffectsRenderer.java b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/src/pfx/renderingsupport/PhysicsEffectsRenderer.java new file mode 100644 index 000000000..5ca66d4b5 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/src/pfx/renderingsupport/PhysicsEffectsRenderer.java @@ -0,0 +1,101 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.opengl.GLSurfaceView; +import android.util.Log; + +/** + * Implementation of the renderer. It calls the native physicseffects code + * to run on the init and drawframe allowing the sample to perform its simulation. + * @author ahamilton + * + */ +public class PhysicsEffectsRenderer implements GLSurfaceView.Renderer { + boolean startup = true; + boolean notEnded = true; + static long startuptime; + static long endtime; + int frameCounter; + + /** + * Initilize the physics simulation after the GL surface is created. + * + */ + public void onSurfaceCreated(GL10 gl, EGLConfig config) + { + Log.v("Init physics", "Initing physics"); + nativePhysicsEffectsInit(); + Log.v("Init physics", "Inited physics"); + } + + /** + * Set the viewport for a changed GL surface + * + */ + public void onSurfaceChanged(GL10 gl, int w, int h) + { + gl.glViewport(0, 0, w, h); + } + + /** + * Perform one simulation step and render the scene. + * + */ + public void onDrawFrame(GL10 gl) + { + if(startup){ + startup = false; + frameCounter = 0; + startuptime = System.currentTimeMillis(); + endtime = startuptime + 10000; // sets run time to be 30 seconds + } + + nativePhysicsEffectsSimulate(); + + frameCounter++; + long lCurrentTime = System.currentTimeMillis(); + if(lCurrentTime > endtime && notEnded) { + float fFrameRate = (1000.0f * (float)frameCounter) / ((float)lCurrentTime - startuptime); + Log.v("PHYSICS TIMING STUDY", "Number of Frames: " + Integer.toString(frameCounter)); + Log.v("PHYSICS TIMING STUDY", "Time ellapsed (milliseconds): " + Long.toString(lCurrentTime - startuptime)); + Log.v("PHYSICS TIMING STUDY", "Bullet Frame Rate: " + Float.toString(fFrameRate) + "fps"); + notEnded = false; + } + } + + private static native void nativePhysicsEffectsInit(); + private static native void nativePhysicsEffectsSimulate(); + private static native void nativePhysicsEffectsUpdate(); + private static native void nativePhysicsEffectsPhysStep(); + private static native void nativePhysicsEffectsRender(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/src/pfx/sample5/PfxApp_5_Raycast.java b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/src/pfx/sample5/PfxApp_5_Raycast.java new file mode 100644 index 000000000..2f8b31004 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_5_Raycast/src/pfx/sample5/PfxApp_5_Raycast.java @@ -0,0 +1,58 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.sample5; + +import pfx.renderingsupport.PhysicsEffectsGLSurfaceView; + +import android.app.Activity; +import android.opengl.GLSurfaceView; +import android.os.Bundle; + +/** + * When program loads it creates a OpenGl ES render window for + * the bullet sample projects to run in and loads the complied + * physics effects libraries. + * @author ahamilton + * + */ +public class PfxApp_5_Raycast extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + peGLView = new PhysicsEffectsGLSurfaceView(this); + setContentView(peGLView); + } + + private GLSurfaceView peGLView; + + //This is where you specify which physics effects sample you would like to load + static { + System.loadLibrary("PfxApp_5_Raycast"); + } +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/.classpath b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/.classpath new file mode 100644 index 000000000..98132ca43 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/.classpath @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/.externalToolBuilders/BuildSampleJNICode.launch b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/.externalToolBuilders/BuildSampleJNICode.launch new file mode 100644 index 000000000..59c20e3a8 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/.externalToolBuilders/BuildSampleJNICode.launch @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/.project b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/.project new file mode 100644 index 000000000..07e46eb54 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/.project @@ -0,0 +1,114 @@ + + + + PfxApp_6_Joint + + + PfxLibrary + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + auto,full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/BuildSampleJNICode.launch + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + + + src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + 1 + PFX_ROOT/project/Android/PfxApp_6_Joint/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java + + + src/pfx/renderingsupport/PhysicsEffectsRenderer.java + 1 + PFX_ROOT/project/Android/PfxApp_6_Joint/src/pfx/renderingsupport/PhysicsEffectsRenderer.java + + + src/pfx/sample6/PfxApp_6_Joint.java + 1 + PFX_ROOT/project/Android/PfxApp_6_Joint/src/pfx/sample/PfxApp_6_Joint.java + + + + + 1305070288951 + jni + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + 1305070295995 + src + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.svn + + + + + + PFX_ROOT + $%7BPARENT-3-PROJECT_LOC%7D + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/AndroidManifest.xml b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/AndroidManifest.xml new file mode 100644 index 000000000..f8eb60248 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/AndroidManifest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/build.xml b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/build.xml new file mode 100644 index 000000000..20c3a8aa7 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/build.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/default.properties b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/default.properties new file mode 100644 index 000000000..f4b4f1778 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-9 diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/jni/Android.mk b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/jni/Android.mk new file mode 100644 index 000000000..4b00f1323 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/jni/Android.mk @@ -0,0 +1,107 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# NOTE: The local path here is defined based on an environment +# variable that points to the root of the Bullet/PhysicsEffects +# code base. The variable must be set in the Cygwin style, e.g., +# BULLET_PFX_ROOT_CYGWIN = /cygdrive/d/tools/PhysicsEffectsRootPath +# +# The reason for *not* just setting local path := $(call my-dir) +# is that we wish to access local source files that are *not* +# located in a "jni" subfolder and *not* located in a subfolder +# of the project folder. This enables us to have Eclipse and +# Android NDK projects that fit neatly into the Bullet/PhysicsEffects +# folder structure, enabling a multi platform code base, without +# forcing the "jni" and subfolder structure that Android SDK/NDK +# prefer for pure Android projects. +LOCAL_PATH:= $(BULLET_PFX_ROOT_CYGWIN) + +# Copy the shared static library, libpfxlibrary.a, into the build +include $(CLEAR_VARS) +LOCAL_MODULE := pfxlibrary +LOCAL_SRC_FILES := project/Android/PfxLibrary/obj/local/armeabi-v7a/libpfxlibrary.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +# Warning: do not enable SIMD vector math functions or NEON for running +# in the Android NDK emulator. NEON requires a physical device +# with NEON support. +# +# Note that in theory we can let LOCAL_ARM_NEON := true determine +# that the flags -mfpu=neon and -mfloat-abi=softfp should be applied. +# However, in practice we have seen one case where the ndk-build +# script "forgets" these flags for the occasional *.cpp file, thus +# causing those files to access the std definition of vectormath +# classes, which are completely different, including different size. +# So, we explicitly apply these flags to avoid having a broken +# build. +# +# Include -DSCE_PFX_USE_SIMD_VECTORMATH to build for ARM NEON SIMD +# intrinsics, and leave it off to use NEON for scalar math but without +# SIMD. + +LOCAL_CFLAGS := $(LOCAL_C_INCLUDES:%=-I%) -mfpu=neon -mfloat-abi=softfp -DSCE_PFX_USE_SIMD_VECTORMATH + +# apply these flags if needed +# -ffast-math -funsafe-math-optimizations + +# apply this to disable optimization +# TARGET_CFLAGS := $(TARGET_CFLAGS) -O0 + +# apply these 2 to turn on assembly output (*.c/*.cpp to *.s file) +# compile-cpp-source = $(eval $(call ev-compile-cpp-source,$1,$(1:%$(LOCAL_CPP_EXTENSION)=%.s))) +# TARGET_CFLAGS := $(TARGET_CFLAGS) -S + +# specify static libraries to link in +LOCAL_STATIC_LIBRARIES := pfxlibrary + +# Enable or disable NEON. Don't forget to apply, or not apply, -mfpu=neon and -mfloat-abi=softfp +# flags in addition, e.g., if this is true both of those need to be included in LOCAL_CFLAGS +# to avoid the possibility that ndk-build will "forget" to add them on some files +LOCAL_ARM_NEON := true +TARGET_CFLAGS := $(filter-out -ffpu=vfp,$(TARGET_CFLAGS)) + +LOCAL_MODULE := PfxApp_6_Joint +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)sample/api_physics_effects/6_joint \ + $(LOCAL_PATH)sample/api_physics_effects/common + +LOCAL_SRC_FILES := \ + sample/api_physics_effects/common/jni/physicseffects-android.cpp \ + sample/api_physics_effects/6_joint/main.cpp \ + sample/api_physics_effects/6_joint/physics_func.cpp \ + sample/api_physics_effects/common/ctrl_func.android.cpp \ + sample/api_physics_effects/common/render_func.android.cpp \ + sample/api_physics_effects/common/perf_func.android.cpp + +LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lGLESv1_CM -ldl -lm -llog + +include $(BUILD_SHARED_LIBRARY) + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/jni/Application.mk b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/jni/Application.mk new file mode 100644 index 000000000..738b74a04 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/jni/Application.mk @@ -0,0 +1,31 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +APP_MODULES := PfxApp_6_Joint +APP_ABI := armeabi-v7a +APP_OPTIM := release diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/local.properties b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/local.properties new file mode 100644 index 000000000..1659ad756 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/local.properties @@ -0,0 +1,10 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must *NOT* be checked in Version Control Systems, +# as it contains information specific to your local configuration. + +# location of the SDK. This is only used by Ant +# For customization when using a Version Control System, please read the +# header note. +sdk.dir=F:\\sdks\\Android\\android-sdk diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/proguard.cfg b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/proguard.cfg new file mode 100644 index 000000000..3e84fc735 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/proguard.cfg @@ -0,0 +1,36 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/drawable-hdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/drawable-hdpi/icon.png new file mode 100644 index 000000000..d7753923a Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/drawable-hdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/drawable-ldpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/drawable-ldpi/icon.png new file mode 100644 index 000000000..0871aa1eb Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/drawable-ldpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/drawable-mdpi/icon.png b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/drawable-mdpi/icon.png new file mode 100644 index 000000000..ff7be820f Binary files /dev/null and b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/drawable-mdpi/icon.png differ diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/layout/main.xml b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/layout/main.xml new file mode 100644 index 000000000..6c069664e --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/layout/main.xml @@ -0,0 +1,34 @@ + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/values/strings.xml b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/values/strings.xml new file mode 100644 index 000000000..548a32fb2 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/res/values/strings.xml @@ -0,0 +1,31 @@ + + + + Pfx 6 Joint + diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java new file mode 100644 index 000000000..ec83e64ce --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/src/pfx/renderingsupport/PhysicsEffectsGLSurfaceView.java @@ -0,0 +1,113 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import android.opengl.GLSurfaceView; +import android.content.Context; +import android.view.MotionEvent; + +/** + * Implementation of the OpenGL ES view window and creates/assigns a renderer. + * Handles touch events to allow the user to change scene on tap, move the camera + * around by touch based movement, and allows the user to zoom in and out by pinching. + * @author ahamilton + * + */ +public class PhysicsEffectsGLSurfaceView extends GLSurfaceView { + public PhysicsEffectsGLSurfaceView(Context context) { + super(context); + peRenderer = new PhysicsEffectsRenderer(); + setRenderer(peRenderer); + } + + float x1 = 0, x2, y1 = 0, y2; + long downTime; + + /** + * Function to process touch events for camera and scene control + * + */ + public boolean onTouchEvent(final MotionEvent event) { + switch(event.getAction()) { + case(MotionEvent.ACTION_DOWN): + x1 = event.getX(); + y1 = event.getY(); + downTime = event.getDownTime(); + break; + case(MotionEvent.ACTION_UP): + if(event.getEventTime() - downTime < 100) nativeSceneChange(); + break; + case(MotionEvent.ACTION_MOVE): { + if(event.getPointerCount() == 1){ + x2 = event.getX(); + y2 = event.getY(); + float dx = x2-x1; + float dy = y2-y1; + + // Use dx and dy to determine the direction + if(dx > 0) { + nativeCameraLeft(); + } else { + nativeCameraRight(); + } + if(dy > 0){ + nativeCameraUp(); + } else { + nativeCameraDown(); + } + x1=x2; + y1=y2; + } else if(event.getPointerCount() == 2){ + y2 = event.getY(); + + float dy = y2-y1; + + // Use dy to determine zoom + if(dy > 0){ + nativeCameraZoomIn(); + } else { + nativeCameraZoomOut(); + } + y1=y2; + } + } + } + return true; + } + + PhysicsEffectsRenderer peRenderer; + + private static native void nativeCameraUp(); + private static native void nativeCameraDown(); + private static native void nativeCameraLeft(); + private static native void nativeCameraRight(); + private static native void nativeCameraZoomOut(); + private static native void nativeCameraZoomIn(); + private static native void nativeSceneChange(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/src/pfx/renderingsupport/PhysicsEffectsRenderer.java b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/src/pfx/renderingsupport/PhysicsEffectsRenderer.java new file mode 100644 index 000000000..5ca66d4b5 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/src/pfx/renderingsupport/PhysicsEffectsRenderer.java @@ -0,0 +1,101 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.renderingsupport; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.opengl.GLSurfaceView; +import android.util.Log; + +/** + * Implementation of the renderer. It calls the native physicseffects code + * to run on the init and drawframe allowing the sample to perform its simulation. + * @author ahamilton + * + */ +public class PhysicsEffectsRenderer implements GLSurfaceView.Renderer { + boolean startup = true; + boolean notEnded = true; + static long startuptime; + static long endtime; + int frameCounter; + + /** + * Initilize the physics simulation after the GL surface is created. + * + */ + public void onSurfaceCreated(GL10 gl, EGLConfig config) + { + Log.v("Init physics", "Initing physics"); + nativePhysicsEffectsInit(); + Log.v("Init physics", "Inited physics"); + } + + /** + * Set the viewport for a changed GL surface + * + */ + public void onSurfaceChanged(GL10 gl, int w, int h) + { + gl.glViewport(0, 0, w, h); + } + + /** + * Perform one simulation step and render the scene. + * + */ + public void onDrawFrame(GL10 gl) + { + if(startup){ + startup = false; + frameCounter = 0; + startuptime = System.currentTimeMillis(); + endtime = startuptime + 10000; // sets run time to be 30 seconds + } + + nativePhysicsEffectsSimulate(); + + frameCounter++; + long lCurrentTime = System.currentTimeMillis(); + if(lCurrentTime > endtime && notEnded) { + float fFrameRate = (1000.0f * (float)frameCounter) / ((float)lCurrentTime - startuptime); + Log.v("PHYSICS TIMING STUDY", "Number of Frames: " + Integer.toString(frameCounter)); + Log.v("PHYSICS TIMING STUDY", "Time ellapsed (milliseconds): " + Long.toString(lCurrentTime - startuptime)); + Log.v("PHYSICS TIMING STUDY", "Bullet Frame Rate: " + Float.toString(fFrameRate) + "fps"); + notEnded = false; + } + } + + private static native void nativePhysicsEffectsInit(); + private static native void nativePhysicsEffectsSimulate(); + private static native void nativePhysicsEffectsUpdate(); + private static native void nativePhysicsEffectsPhysStep(); + private static native void nativePhysicsEffectsRender(); +} diff --git a/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/src/pfx/sample6/PfxApp_6_Joint.java b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/src/pfx/sample6/PfxApp_6_Joint.java new file mode 100644 index 000000000..f2f3593f8 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxApp_6_Joint/src/pfx/sample6/PfxApp_6_Joint.java @@ -0,0 +1,58 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +package pfx.sample6; + +import pfx.renderingsupport.PhysicsEffectsGLSurfaceView; + +import android.app.Activity; +import android.opengl.GLSurfaceView; +import android.os.Bundle; + +/** + * When program loads it creates a OpenGl ES render window for + * the bullet sample projects to run in and loads the complied + * physics effects libraries. + * @author ahamilton + * + */ +public class PfxApp_6_Joint extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + peGLView = new PhysicsEffectsGLSurfaceView(this); + setContentView(peGLView); + } + + private GLSurfaceView peGLView; + + //This is where you specify which physics effects sample you would like to load + static { + System.loadLibrary("PfxApp_6_Joint"); + } +} diff --git a/Extras/PhysicsEffects/project/Android/PfxLibrary/.cproject b/Extras/PhysicsEffects/project/Android/PfxLibrary/.cproject new file mode 100644 index 000000000..362560c91 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxLibrary/.cproject @@ -0,0 +1,348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + make + + all + true + true + true + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxLibrary/.externalToolBuilders/PfxLibraryBuilder.launch b/Extras/PhysicsEffects/project/Android/PfxLibrary/.externalToolBuilders/PfxLibraryBuilder.launch new file mode 100644 index 000000000..5b0e3cea5 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxLibrary/.externalToolBuilders/PfxLibraryBuilder.launch @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxLibrary/.project b/Extras/PhysicsEffects/project/Android/PfxLibrary/.project new file mode 100644 index 000000000..08860167b --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxLibrary/.project @@ -0,0 +1,157 @@ + + + + PfxLibrary + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + ?children? + ?name?=outputEntries\|?children?=?name?=entry\\\\\\\|\\\|\|| + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/PfxLibraryBuilder.launch + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + include + 2 + PFX_ROOT/include + + + src + 2 + PFX_ROOT/src + + + + + 1304973509800 + include + 21 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.h + + + + 1304973468596 + src + 21 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.cpp + + + + + + PFX_ROOT + $%7BPARENT-3-PROJECT_LOC%7D + + + diff --git a/Extras/PhysicsEffects/project/Android/PfxLibrary/jni/Android.mk b/Extras/PhysicsEffects/project/Android/PfxLibrary/jni/Android.mk new file mode 100644 index 000000000..b342f5bd3 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxLibrary/jni/Android.mk @@ -0,0 +1,173 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# NOTE: The local path here is defined based on an environment +# variable that points to the root of the Bullet/PhysicsEffects +# code base. The variable must be set in the Cygwin style, e.g., +# BULLET_PFX_ROOT_CYGWIN = /cygdrive/d/tools/PhysicsEffectsRootPath +# +# The reason for *not* just setting local path := $(call my-dir) +# is that we wish to access local source files that are *not* +# located in a "jni" subfolder and *not* located in a subfolder +# of the project folder. This enables us to have Eclipse and +# Android NDK projects that fit neatly into the Bullet/PhysicsEffects +# folder structure, enabling a multi platform code base, without +# forcing the "jni" and subfolder structure that Android SDK/NDK +# prefer for pure Android projects. +LOCAL_PATH := $(BULLET_PFX_ROOT_CYGWIN) + +include $(CLEAR_VARS) +# Warning: do not enable SIMD vector math functions or NEON for running +# in the Android NDK emulator. NEON requires a physical device +# with NEON support. +# +# Note that in theory we can let LOCAL_ARM_NEON := true determine +# that the flags -mfpu=neon and -mfloat-abi=softfp should be applied. +# However, in practice we have seen one case where the ndk-build +# script "forgets" these flags for the occasional *.cpp file, thus +# causing those files to access the std definition of vectormath +# classes, which are completely different, including different size. +# So, we explicitly apply these flags to avoid having a broken +# build. +# +# Include -DSCE_PFX_USE_SIMD_VECTORMATH to build for ARM NEON SIMD +# intrinsics, and leave it off to use NEON for scalar math but without +# SIMD. +LOCAL_CFLAGS := $(LOCAL_C_INCLUDES:%=-I%) -DUSE_PTHREADS -mfpu=neon -mfloat-abi=softfp -pthread -DSCE_PFX_USE_SIMD_VECTORMATH + +# apply these flags if needed +# -ffast-math -funsafe-math-optimizations + +# apply this to disable optimization +# TARGET_CFLAGS := $(TARGET_CFLAGS) -O0 + +# apply these 2 to turn on assembly output (*.c/*.cpp to *.s file) +#compile-cpp-source = $(eval $(call ev-compile-cpp-source,$1,$(1:%$(LOCAL_CPP_EXTENSION)=%.s))) +#TARGET_CFLAGS := $(TARGET_CFLAGS) -S + +# Enable or disable NEON. Don't forget to apply, or not apply, -mfpu=neon and -mfloat-abi=softfp +# flags in addition, e.g., if this is true both of those need to be included in LOCAL_CFLAGS +# to avoid the possibility that ndk-build will "forget" to add them on some files +LOCAL_ARM_NEON := true +TARGET_CFLAGS := $(filter-out -ffpu=vfp,$(TARGET_CFLAGS)) + +# setup to build static library, libpfxlibrary.a +LOCAL_MODULE := libpfxlibrary +LOCAL_C_INCLUDES := \ + include \ + include/physics_effects/base_level \ + include/physics_effects/base_level/base \ + include/physics_effects/base_level/broadphase \ + include/physics_effects/base_level/collision \ + include/physics_effects/base_level/rigidbody \ + include/physics_effects/base_level/solver \ + include/physics_effects/base_level/sort \ + include/physics_effects/low_level \ + include/physics_effects/low_level/broadphase \ + include/physics_effects/low_level/collision \ + include/physics_effects/low_level/solver \ + include/physics_effects/low_level/sort \ + include/physics_effects/low_level/task \ + include/physics_effects/util \ + include/vecmath/neon \ + src/base_level/broadphase \ + src/base_level/collision \ + src/base_level/solver \ + src/base_level/sort \ + src/low_level/broadphase \ + src/low_level/collision \ + src/low_level/solver \ + src/low_level/sort \ + src/low_level/task \ + src/util \ + src + +# Note that vectormath_neon_assembly_implementations.S is needed here in order to compile, link, and use the +# NEON version of the vectormath library +LOCAL_SRC_FILES := \ + src/base_level/broadphase/pfx_update_broadphase_proxy.cpp \ + src/base_level/collision/pfx_collidable.cpp \ + src/base_level/collision/pfx_contact_box_box.cpp \ + src/base_level/collision/pfx_contact_box_capsule.cpp \ + src/base_level/collision/pfx_contact_box_sphere.cpp \ + src/base_level/collision/pfx_contact_cache.cpp \ + src/base_level/collision/pfx_contact_capsule_capsule.cpp \ + src/base_level/collision/pfx_contact_capsule_sphere.cpp \ + src/base_level/collision/pfx_contact_large_tri_mesh.cpp \ + src/base_level/collision/pfx_contact_manifold.cpp \ + src/base_level/collision/pfx_contact_sphere_sphere.cpp \ + src/base_level/collision/pfx_contact_tri_mesh_box.cpp \ + src/base_level/collision/pfx_contact_tri_mesh_capsule.cpp \ + src/base_level/collision/pfx_contact_tri_mesh_convex.cpp \ + src/base_level/collision/pfx_contact_tri_mesh_cylinder.cpp \ + src/base_level/collision/pfx_contact_tri_mesh_sphere.cpp \ + src/base_level/collision/pfx_gjk_solver.cpp \ + src/base_level/collision/pfx_gjk_support_func.cpp \ + src/base_level/collision/pfx_intersect_ray_box.cpp \ + src/base_level/collision/pfx_intersect_ray_capsule.cpp \ + src/base_level/collision/pfx_intersect_ray_convex.cpp \ + src/base_level/collision/pfx_intersect_ray_cylinder.cpp \ + src/base_level/collision/pfx_intersect_ray_large_tri_mesh.cpp \ + src/base_level/collision/pfx_intersect_ray_sphere.cpp \ + src/base_level/collision/pfx_shape.cpp \ + src/base_level/collision/pfx_simplex_solver.cpp \ + src/base_level/solver/pfx_contact_constraint.cpp \ + src/base_level/solver/pfx_joint_ball.cpp \ + src/base_level/solver/pfx_joint_fix.cpp \ + src/base_level/solver/pfx_joint_hinge.cpp \ + src/base_level/solver/pfx_joint_slider.cpp \ + src/base_level/solver/pfx_joint_swing_twist.cpp \ + src/base_level/solver/pfx_joint_universal.cpp \ + src/base_level/solver/pfx_constraint_row_solver_neon.cpp \ + src/base_level/sort/pfx_sort.cpp \ + src/low_level/broadphase/pfx_broadphase_single.cpp \ + src/low_level/collision/pfx_batched_ray_cast_single.cpp \ + src/low_level/collision/pfx_batched_ray_cast_parallel.cpp \ + src/low_level/collision/pfx_collision_detection_single.cpp \ + src/low_level/collision/pfx_collision_detection_parallel.cpp \ + src/low_level/collision/pfx_detect_collision_func.cpp \ + src/low_level/collision/pfx_intersect_ray_func.cpp \ + src/low_level/collision/pfx_island_generation.cpp \ + src/low_level/collision/pfx_ray_cast.cpp \ + src/low_level/collision/pfx_refresh_contacts_single.cpp \ + src/low_level/collision/pfx_refresh_contacts_parallel.cpp \ + src/low_level/solver/pfx_constraint_solver_single.cpp \ + src/low_level/solver/pfx_constraint_solver_parallel.cpp \ + src/low_level/solver/pfx_joint_constraint_func.cpp \ + src/low_level/solver/pfx_update_rigid_states_single.cpp \ + src/low_level/solver/pfx_update_rigid_states_parallel.cpp \ + src/low_level/sort/pfx_parallel_sort_single.cpp \ + src/low_level/task/pfx_task_manager_pthreads.cpp \ + src/low_level/task/pfx_sync_components_pthreads.cpp \ + src/util/pfx_mass.cpp \ + src/util/pfx_mesh_creator.cpp \ + include/vecmath/neon/vectormath_neon_assembly_implementations.S + +LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lGLESv1_CM -ldl -lm -llog + +include $(BUILD_STATIC_LIBRARY) diff --git a/Extras/PhysicsEffects/project/Android/PfxLibrary/jni/Application.mk b/Extras/PhysicsEffects/project/Android/PfxLibrary/jni/Application.mk new file mode 100644 index 000000000..6c3c6caa7 --- /dev/null +++ b/Extras/PhysicsEffects/project/Android/PfxLibrary/jni/Application.mk @@ -0,0 +1,31 @@ +# +# Applied Research Associates Inc. (c)2011 +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Applied Research Associates Inc nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +APP_MODULES := libpfxlibrary +APP_ABI := armeabi-v7a +APP_OPTIM := release diff --git a/Extras/PhysicsEffects/project/msvc2008_32/BulletCollision.vcproj b/Extras/PhysicsEffects/project/msvc2008_32/BulletCollision.vcproj new file mode 100644 index 000000000..79e0c880c --- /dev/null +++ b/Extras/PhysicsEffects/project/msvc2008_32/BulletCollision.vcproj @@ -0,0 +1,1206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/msvc2008_32/BulletDynamics.vcproj b/Extras/PhysicsEffects/project/msvc2008_32/BulletDynamics.vcproj new file mode 100644 index 000000000..cfc8b14df --- /dev/null +++ b/Extras/PhysicsEffects/project/msvc2008_32/BulletDynamics.vcproj @@ -0,0 +1,566 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/msvc2008_32/BulletMultiThreaded.vcproj b/Extras/PhysicsEffects/project/msvc2008_32/BulletMultiThreaded.vcproj new file mode 100644 index 000000000..baf77f873 --- /dev/null +++ b/Extras/PhysicsEffects/project/msvc2008_32/BulletMultiThreaded.vcproj @@ -0,0 +1,558 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/msvc2008_32/BulletSoftBody.vcproj b/Extras/PhysicsEffects/project/msvc2008_32/BulletSoftBody.vcproj new file mode 100644 index 000000000..e8f5c40fe --- /dev/null +++ b/Extras/PhysicsEffects/project/msvc2008_32/BulletSoftBody.vcproj @@ -0,0 +1,298 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/msvc2008_32/LinearMath.vcproj b/Extras/PhysicsEffects/project/msvc2008_32/LinearMath.vcproj new file mode 100644 index 000000000..28bc4258b --- /dev/null +++ b/Extras/PhysicsEffects/project/msvc2008_32/LinearMath.vcproj @@ -0,0 +1,478 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/msvc2008_32/MiniCL.vcproj b/Extras/PhysicsEffects/project/msvc2008_32/MiniCL.vcproj new file mode 100644 index 000000000..ccbd8fa55 --- /dev/null +++ b/Extras/PhysicsEffects/project/msvc2008_32/MiniCL.vcproj @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/project/physics_effects_lib.oss.sln b/Extras/PhysicsEffects/project/physics_effects_lib.oss.sln new file mode 100644 index 000000000..7b10ddcc4 --- /dev/null +++ b/Extras/PhysicsEffects/project/physics_effects_lib.oss.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "physics_effects_lib.oss", "physics_effects_lib.oss.vcproj", "{4908A1B7-06F4-4517-936A-D81D140004F7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Win32 Debug|Win32 = Win32 Debug|Win32 + Win32 Release|Win32 = Win32 Release|Win32 + Win64 Debug|Win32 = Win64 Debug|Win32 + Win64 Release|Win32 = Win64 Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win32 Debug|Win32.ActiveCfg = Win32 Debug|Win32 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win32 Debug|Win32.Build.0 = Win32 Debug|Win32 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win32 Release|Win32.ActiveCfg = Win32 Release|Win32 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win32 Release|Win32.Build.0 = Win32 Release|Win32 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win64 Debug|Win32.ActiveCfg = Win64 Debug|x64 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win64 Debug|Win32.Build.0 = Win64 Debug|x64 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win64 Release|Win32.ActiveCfg = Win64 Release|x64 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win64 Release|Win32.Build.0 = Win64 Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Extras/PhysicsEffects/project/physics_effects_lib.oss.vcproj b/Extras/PhysicsEffects/project/physics_effects_lib.oss.vcproj new file mode 100644 index 000000000..1ba888a9c --- /dev/null +++ b/Extras/PhysicsEffects/project/physics_effects_lib.oss.vcproj @@ -0,0 +1,1221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/sample/CMakeLists.txt b/Extras/PhysicsEffects/sample/CMakeLists.txt new file mode 100644 index 000000000..434caf200 --- /dev/null +++ b/Extras/PhysicsEffects/sample/CMakeLists.txt @@ -0,0 +1,3 @@ +SUBDIRS( + api_physics_effects +) diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/0_console/CMakeLists.txt b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/CMakeLists.txt new file mode 100644 index 000000000..3fabec5d7 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 2.4) + + +#this line has to appear before 'PROJECT' in order to be able to disable incremental linking +SET(MSVC_INCREMENTAL_DEFAULT ON) + +PROJECT(App_0_Console) + + +SET(App_0_Console_SRCS + main.cpp + physics_func.cpp + ../common/perf_func.win32.cpp +) + +SET(App_0_Console_HDRS + landscape.h + physics_func.h +) + +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/include +) + + +#ADD_DEFINITIONS(-DUNICODE) +#ADD_DEFINITIONS(-D_UNICODE) + +ADD_EXECUTABLE(App_0_Console + ${App_0_Console_SRCS} + ${App_0_Console_HDRS} +) +TARGET_LINK_LIBRARIES(App_0_Console + PfxLowLevel + PfxBaseLevel + PfxUtil +) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(App_0_Console PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(App_0_Console PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(App_0_Console PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF() + + + + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/0_console/barrel.h b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/barrel.h new file mode 100644 index 000000000..6574fa862 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/barrel.h @@ -0,0 +1,202 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define BarrelVtxCount 57 +#define BarrelIdxCount 180 + +static float BarrelVtx[] = { +0.0f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +-0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +0.0f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +-0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.957307f,-0.289072f,0.0f, +0.404509f,0.0f,-0.293893f, 0.809017f,0.0f,-0.587785f, +0.5f,0.0f,0.0f, 1.0f,0.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.774478f,-0.289072f,-0.562691f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +-0.154509f,0.0f,-0.475528f, -0.309017f,0.0f,-0.951057f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +-0.107853f,-0.5f,-0.331936f, -0.295824f,-0.289072f,-0.910453f, +-0.404509f,0.0f,-0.293893f, -0.809017f,0.0f,-0.587785f, +-0.282362f,-0.5f,-0.205148f, -0.774478f,-0.289072f,-0.562691f, +-0.5f,0.0f,0.0f, -1.0f,0.0f,0.0f, +-0.349018f,-0.5f,0.0f, -0.957307f,-0.289072f,0.0f, +-0.404508f,0.0f,0.293893f, -0.809017f,0.0f,0.587785f, +-0.282362f,-0.5f,0.205148f, -0.774478f,-0.289072f,0.562691f, +-0.154509f,0.0f,0.475528f, -0.309017f,0.0f,0.951056f, +-0.107853f,-0.5f,0.331936f, -0.295824f,-0.289072f,0.910453f, +0.154509f,0.0f,0.475528f, 0.309017f,0.0f,0.951056f, +0.107853f,-0.5f,0.331936f, 0.295824f,-0.289072f,0.910453f, +0.404509f,0.0f,0.293892f, 0.809017f,0.0f,0.587785f, +0.282362f,-0.5f,0.205148f, 0.774478f,-0.289072f,0.562691f, +0.282362f,0.5f,-0.205148f, 0.774478f,0.289072f,-0.562691f, +0.349018f,0.5f,0.0f, 0.957307f,0.289072f,0.0f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.107853f,0.5f,-0.331936f, -0.295824f,0.289072f,-0.910453f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.282362f,0.5f,-0.205148f, -0.774478f,0.289072f,-0.562691f, +-0.349018f,0.5f,0.0f, -0.957307f,0.289072f,0.0f, +-0.282362f,0.5f,0.205148f, -0.774478f,0.289072f,0.562691f, +-0.107853f,0.5f,0.331936f, -0.295824f,0.289072f,0.910453f, +0.107853f,0.5f,0.331936f, 0.295824f,0.289072f,0.910453f, +0.282362f,0.5f,0.205148f, 0.774478f,0.289072f,0.562691f, +}; + +static float BarrelTex[] = { +0.0f,0.5f, +0.0f,0.85f, +0.0f,0.75f, +0.0f,0.95f, +0.0f,0.05f, +0.0f,-0.05f, +0.0f,0.15f, +0.0f,0.25f, +0.0f,0.35f, +0.0f,0.45f, +0.0f,0.55f, +0.0f,0.65f, +1.0f,0.5f, +1.0f,0.75f, +1.0f,0.85f, +1.0f,0.95f, +1.0f,-0.05f, +1.0f,0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +0.0f,0.75f, +0.5f,0.85f, +0.5f,0.75f, +0.0f,0.85f, +0.5f,0.95f, +0.0f,0.95f, +0.0f,-0.05f, +0.5f,0.05f, +0.5f,-0.05f, +0.0f,0.05f, +0.5f,0.15f, +0.0f,0.15f, +0.5f,0.25f, +0.0f,0.25f, +0.5f,0.35f, +0.0f,0.35f, +0.5f,0.45f, +0.0f,0.45f, +0.5f,0.55f, +0.0f,0.55f, +0.5f,0.65f, +0.0f,0.65f, +1.0f,0.85f, +1.0f,0.75f, +1.0f,0.95f, +1.0f,0.05f, +1.0f,-0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +}; + +static unsigned short BarrelIdx[] = { +0,1,2, +0,3,1, +0,4,5, +0,6,4, +0,7,6, +0,8,7, +0,9,8, +0,10,9, +0,11,10, +0,2,11, +12,13,14, +12,14,15, +12,16,17, +12,17,18, +12,18,19, +12,19,20, +12,20,21, +12,21,22, +12,22,23, +12,23,13, +24,25,26, +24,27,25, +27,28,25, +27,29,28, +30,31,32, +30,33,31, +33,34,31, +33,35,34, +35,36,34, +35,37,36, +37,38,36, +37,39,38, +39,40,38, +39,41,40, +41,42,40, +41,43,42, +43,44,42, +43,45,44, +45,26,44, +45,24,26, +26,46,47, +26,25,46, +25,48,46, +25,28,48, +32,49,50, +32,31,49, +31,51,49, +31,34,51, +34,52,51, +34,36,52, +36,53,52, +36,38,53, +38,54,53, +38,40,54, +40,55,54, +40,42,55, +42,56,55, +42,44,56, +44,47,56, +44,26,47, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/0_console/landscape.h b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/landscape.h new file mode 100644 index 000000000..00f6cffd2 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/landscape.h @@ -0,0 +1,318 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define LargeMeshVtxCount 81 +#define LargeMeshIdxCount 384 + +static float LargeMeshVtx[] = { +-25.0f,-2.19407f,18.5625f, 0.232976f,0.967754f,0.0957829f, +-25.0f,0.0644502f,24.75f, 0.188094f,0.871343f,-0.45319f, +-18.75f,-4.50287f,18.5625f, -0.0716098f,0.995449f,0.0628767f, +-18.75f,-0.39999f,24.75f, -0.0602794f,0.895848f,-0.440253f, +-12.5f,-1.2166f,18.5625f, -0.269469f,0.961403f,0.0555879f, +-12.5f,-0.942431f,24.75f, -0.0997841f,0.993258f,0.0589987f, +-6.25f,1.93598f,18.5625f, -0.283933f,0.956351f,-0.0691025f, +-6.25f,-0.445954f,24.75f, -0.180725f,0.942766f,0.280233f, +0.0f,2.76983f,18.5625f, 0.171645f,0.984908f,0.0222501f, +0.0f,2.76642f,24.75f, 0.0784993f,0.995428f,-0.0544117f, +6.25f,-2.53736f,18.5625f, 0.248298f,0.965028f,0.0840741f, +6.25f,-0.915645f,24.75f, 0.164311f,0.945856f,-0.279926f, +12.5f,-1.60054f,18.5625f, -0.180435f,0.983586f,0.00115547f, +12.5f,0.831925f,24.75f, -0.0692495f,0.964821f,-0.253623f, +18.75f,-0.800282f,18.5625f, 0.10755f,0.951538f,0.288112f, +18.75f,-1.47284f,24.75f, 0.232178f,0.972664f,0.00429361f, +25.0f,-2.78379f,18.5625f, 0.1833f,0.937477f,0.295867f, +25.0f,-0.967508f,24.75f, -0.0773477f,0.956641f,-0.280812f, +-25.0f,-0.352038f,12.375f, -0.192222f,0.972435f,0.131987f, +-18.75f,0.681228f,12.375f, -0.107779f,0.962569f,0.248686f, +-12.5f,2.72065f,12.375f, 0.0520846f,0.993034f,0.105692f, +-6.25f,-1.78776f,12.375f, -0.0133223f,0.99674f,-0.0795754f, +0.0f,1.57707f,12.375f, -0.129025f,0.969662f,-0.207627f, +6.25f,0.424356f,12.375f, 0.180995f,0.97074f,0.157815f, +12.5f,0.283234f,12.375f, -0.16285f,0.973539f,0.160316f, +18.75f,2.57015f,12.375f, -0.165454f,0.978339f,0.124408f, +25.0f,3.07363f,12.375f, -0.00454559f,0.988151f,0.153417f, +-25.0f,-0.893751f,6.1875f, -0.0836251f,0.990084f,-0.112876f, +-18.75f,0.930932f,6.1875f, 0.00269413f,0.971838f,-0.235633f, +-12.5f,-0.684529f,6.1875f, -0.010319f,0.927048f,-0.3748f, +-6.25f,-0.661383f,6.1875f, 0.012265f,0.999875f,-0.00994222f, +0.0f,0.385718f,6.1875f, -0.15435f,0.984937f,-0.0779465f, +6.25f,0.589796f,6.1875f, 0.0241717f,0.999582f,-0.0158589f, +12.5f,0.47454f,6.1875f, -0.017184f,0.997953f,-0.0616073f, +18.75f,1.59939f,6.1875f, -0.0902706f,0.957309f,-0.274609f, +25.0f,1.13434f,6.1875f, 0.0346006f,0.957441f,-0.286547f, +-25.0f,0.74548f,0.0f, 0.329903f,0.930812f,0.157334f, +-18.75f,-2.47437f,0.0f, 0.247844f,0.968142f,0.0357041f, +-12.5f,-4.16309f,1.81975e-007f, -0.0623898f,0.997626f,-0.0291436f, +-6.25f,-0.700022f,0.0f, -0.217067f,0.974987f,-0.0477624f, +0.0f,-0.0957388f,0.0f, -0.117693f,0.990712f,-0.068098f, +6.25f,0.614077f,0.0f, -0.0713214f,0.997305f,0.01722f, +12.5f,0.299109f,0.0f, 0.218606f,0.968641f,0.118094f, +18.75f,-1.71753f,0.0f, 0.0339493f,0.985612f,-0.165579f, +25.0f,-1.12638f,0.0f, -0.0547573f,0.989177f,-0.136126f, +-25.0f,-0.403319f,-6.1875f, -0.1263f,0.989211f,-0.074223f, +-18.75f,-0.0730335f,-6.1875f, 0.0173428f,0.965382f,0.260261f, +-12.5f,-0.450125f,-6.1875f, 0.0658811f,0.875f,0.479619f, +-6.25f,-0.180204f,-6.1875f, 0.0116584f,0.981445f,0.19139f, +0.0f,-0.632679f,-6.1875f, -0.0557983f,0.993041f,-0.103716f, +6.25f,0.308409f,-6.1875f, -0.191898f,0.96766f,-0.163737f, +12.5f,2.5011f,-6.1875f, 0.0758397f,0.996403f,-0.0378189f, +18.75f,-1.69303f,-6.1875f, 0.16761f,0.974057f,0.15205f, +25.0f,-0.141349f,-6.1875f, -0.204846f,0.978471f,0.0251341f, +-25.0f,-1.10316f,-12.375f, -0.0350644f,0.993748f,-0.106001f, +-18.75f,1.06711f,-12.375f, -0.309806f,0.919244f,-0.242922f, +-12.5f,3.61544f,-12.375f, -0.0506281f,0.998702f,-0.00561657f, +-6.25f,1.6504f,-12.375f, 0.322294f,0.937465f,0.131477f, +0.0f,-1.60595f,-12.375f, 0.086016f,0.995916f,0.0274459f, +6.25f,-0.849859f,-12.375f, -0.0332811f,0.997087f,0.0686255f, +12.5f,-0.942201f,-12.375f, -0.153559f,0.982185f,-0.108312f, +18.75f,0.494873f,-12.375f, 0.0753195f,0.981472f,0.176181f, +25.0f,-0.333828f,-12.375f, 0.035057f,0.987194f,0.155624f, +-25.0f,2.1862f,-18.5625f, 0.612899f,0.782306f,0.111138f, +-18.75f,-3.38259f,-18.5625f, 0.0194078f,0.992789f,-0.118297f, +-12.5f,-0.880916f,-18.5625f, -0.282251f,0.949875f,-0.13443f, +-6.25f,0.818158f,-18.5625f, 0.1476f,0.981788f,-0.119612f, +0.0f,-1.48019f,-18.5625f, -0.044551f,0.996013f,-0.0772824f, +6.25f,1.47123f,-18.5625f, -0.117036f,0.97986f,0.161792f, +12.5f,0.164076f,-18.5625f, -0.0340355f,0.978993f,0.201034f, +18.75f,2.14568f,-18.5625f, -0.0439269f,0.994859f,0.0912435f, +25.0f,0.626506f,-18.5625f, 0.208015f,0.968592f,0.136229f, +-25.0f,0.296889f,-24.75f, 0.46973f,0.844327f,-0.257809f, +-18.75f,-3.18022f,-24.75f, -0.0226758f,0.998794f,-0.0435401f, +-12.5f,1.8927f,-24.75f, -0.202772f,0.919836f,0.335836f, +-6.25f,1.46387f,-24.75f, 0.224904f,0.955746f,0.189652f, +0.0f,-2.52726f,-24.75f, -0.0435882f,0.993572f,-0.10447f, +6.25f,1.30397f,-24.75f, -0.28646f,0.956525f,-0.0547707f, +12.5f,1.85812f,-24.75f, 0.0521949f,0.979796f,0.193067f, +18.75f,1.56331f,-24.75f, -0.0270784f,0.999629f,-0.00293115f, +25.0f,1.05366f,-24.75f, 0.161f,0.986887f,-0.0115473f, +}; + +static float LargeMeshTex[] = { +0.125f,0.0f, +0.0f,0.0f, +0.125f,0.125f, +0.0f,0.125f, +0.125f,0.25f, +0.0f,0.25f, +0.125f,0.375f, +0.0f,0.375f, +0.125f,0.5f, +0.0f,0.5f, +0.125f,0.625f, +0.0f,0.625f, +0.125f,0.75f, +0.0f,0.75f, +0.125f,0.875f, +0.0f,0.875f, +0.125f,1.0f, +0.0f,1.0f, +0.25f,0.0f, +0.25f,0.125f, +0.25f,0.25f, +0.25f,0.375f, +0.25f,0.5f, +0.25f,0.625f, +0.25f,0.75f, +0.25f,0.875f, +0.25f,1.0f, +0.375f,0.0f, +0.375f,0.125f, +0.375f,0.25f, +0.375f,0.375f, +0.375f,0.5f, +0.375f,0.625f, +0.375f,0.75f, +0.375f,0.875f, +0.375f,1.0f, +0.5f,0.0f, +0.5f,0.125f, +0.5f,0.25f, +0.5f,0.375f, +0.5f,0.5f, +0.5f,0.625f, +0.5f,0.75f, +0.5f,0.875f, +0.5f,1.0f, +0.625f,0.0f, +0.625f,0.125f, +0.625f,0.25f, +0.625f,0.375f, +0.625f,0.5f, +0.625f,0.625f, +0.625f,0.75f, +0.625f,0.875f, +0.625f,1.0f, +0.75f,0.0f, +0.75f,0.125f, +0.75f,0.25f, +0.75f,0.375f, +0.75f,0.5f, +0.75f,0.625f, +0.75f,0.75f, +0.75f,0.875f, +0.75f,1.0f, +0.875f,0.0f, +0.875f,0.125f, +0.875f,0.25f, +0.875f,0.375f, +0.875f,0.5f, +0.875f,0.625f, +0.875f,0.75f, +0.875f,0.875f, +0.875f,1.0f, +1.0f,0.0f, +1.0f,0.125f, +1.0f,0.25f, +1.0f,0.375f, +1.0f,0.5f, +1.0f,0.625f, +1.0f,0.75f, +1.0f,0.875f, +1.0f,1.0f, +}; + +static unsigned short LargeMeshIdx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +18,0,19, +2,19,0, +19,2,20, +4,20,2, +20,4,21, +6,21,4, +21,6,22, +8,22,6, +22,8,23, +10,23,8, +23,10,24, +12,24,10, +24,12,25, +14,25,12, +25,14,26, +16,26,14, +27,18,28, +19,28,18, +28,19,29, +20,29,19, +29,20,30, +21,30,20, +30,21,31, +22,31,21, +31,22,32, +23,32,22, +32,23,33, +24,33,23, +33,24,34, +25,34,24, +34,25,35, +26,35,25, +36,27,37, +28,37,27, +37,28,38, +29,38,28, +38,29,39, +30,39,29, +39,30,40, +31,40,30, +40,31,41, +32,41,31, +41,32,42, +33,42,32, +42,33,43, +34,43,33, +43,34,44, +35,44,34, +45,36,46, +37,46,36, +46,37,47, +38,47,37, +47,38,48, +39,48,38, +48,39,49, +40,49,39, +49,40,50, +41,50,40, +50,41,51, +42,51,41, +51,42,52, +43,52,42, +52,43,53, +44,53,43, +54,45,55, +46,55,45, +55,46,56, +47,56,46, +56,47,57, +48,57,47, +57,48,58, +49,58,48, +58,49,59, +50,59,49, +59,50,60, +51,60,50, +60,51,61, +52,61,51, +61,52,62, +53,62,52, +63,54,64, +55,64,54, +64,55,65, +56,65,55, +65,56,66, +57,66,56, +66,57,67, +58,67,57, +67,58,68, +59,68,58, +68,59,69, +60,69,59, +69,60,70, +61,70,60, +70,61,71, +62,71,61, +72,63,73, +64,73,63, +73,64,74, +65,74,64, +74,65,75, +66,75,65, +75,66,76, +67,76,66, +76,67,77, +68,77,67, +77,68,78, +69,78,68, +78,69,79, +70,79,69, +79,70,80, +71,80,70, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/0_console/main.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/main.cpp new file mode 100644 index 000000000..361c21055 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/main.cpp @@ -0,0 +1,44 @@ +/* +Physics Effects Copyright(C) 2011 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "physics_effects.h" +#include "physics_func.h" +#include "../common/perf_func.h" + +static int frameCount = 0; +static int sceneId = 2; + +int main() +{ + + perf_init(); + physics_init(); + + physics_create_scene(sceneId); + + frameCount = 0; + + //createScene(); + + while(frameCount<600) { + physics_simulate(); + perf_sync(); + } + + SCE_PFX_PRINTF("program complete\n"); + + return 0; +} diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/0_console/physics_func.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/physics_func.cpp new file mode 100644 index 000000000..250edac85 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/physics_func.cpp @@ -0,0 +1,861 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "physics_func.h" +#include "../common/perf_func.h" + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Data + +#define NUM_RIGIDBODIES 500 +#define NUM_JOINTS 500 +#define NUM_CONTACTS 4000 + +const float timeStep = 0.016f; +const float separateBias = 0.1f; +int iteration = 5; + +//J ワールドサイズ +//E World size +PfxVector3 worldCenter(0.0f); +PfxVector3 worldExtent(500.0f); + +//J 剛体 +//E Rigid body +PfxRigidState states[NUM_RIGIDBODIES]; +PfxRigidBody bodies[NUM_RIGIDBODIES]; +PfxCollidable collidables[NUM_RIGIDBODIES]; +PfxSolverBody solverBodies[NUM_RIGIDBODIES]; +int numRigidBodies = 0; + +//J 地形を表現するためのラージメッシュ +//E Large mesh for representing a landscape +#include "landscape.h" +PfxLargeTriMesh gLargeMesh; + +//J 凸メッシュ +//E Convex Mesh +#include "barrel.h" +PfxConvexMesh gConvex; + +//J プロキシ +//E Proxies +PfxBroadphaseProxy proxies[NUM_RIGIDBODIES]; + +//J ジョイント +//E Joint +PfxConstraintPair jointPairs[NUM_JOINTS]; +PfxJoint joints[NUM_JOINTS]; +int numJoints = 0; + +//J ペア +//E Pairs +unsigned int pairSwap; +unsigned int numPairs[2]; +PfxBroadphasePair pairsBuff[2][NUM_CONTACTS]; + +//J コンタクト +//E Contacts +PfxContactManifold contacts[NUM_CONTACTS]; +int numContacts; + +PfxUInt32 contactIdPool[NUM_CONTACTS]; +int numContactIdPool; + +//J 一時バッファ +//E Temporary buffers +#define POOL_BYTES (5*1024*1024) +unsigned char SCE_PFX_ALIGNED(128) poolBuff[POOL_BYTES]; + +//J 一時バッファ用スタックアロケータ +//E Stack allocator for temporary buffers +PfxHeapManager pool(poolBuff,POOL_BYTES); + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Function + +int frame = 0; + +void broadphase() +{ + pairSwap = 1-pairSwap; + + unsigned int &numPreviousPairs = numPairs[1-pairSwap]; + unsigned int &numCurrentPairs = numPairs[pairSwap]; + PfxBroadphasePair *previousPairs = pairsBuff[1-pairSwap]; + PfxBroadphasePair *currentPairs = pairsBuff[pairSwap]; + + //J 剛体が最も分散している軸を見つける + //E Find the axis along which all rigid bodies are most widely positioned + int axis = 0; + { + PfxVector3 s(0.0f),s2(0.0f); + for(int i=0;i v[0]) axis = 1; + if(v[2] > v[axis]) axis = 2; + } + + //J ブロードフェーズプロキシの更新 + //E Create broadpahse proxies + { + for(int i=0;i 0) { + cId = contactIdPool[--numContactIdPool]; + } + else { + cId = numContacts++; + } + if(cId >= NUM_CONTACTS) { + cId = 0; + } + SCE_PFX_ASSERT(cId < NUM_CONTACTS); + pfxSetContactId(outNewPairs[i],cId); + PfxContactManifold &contact = contacts[cId]; + contact.reset(pfxGetObjectIdA(outNewPairs[i]),pfxGetObjectIdB(outNewPairs[i])); + } + + //J 新規ペアと維持ペアを合成 + //E Merge 'new' and 'keep' pairs + numCurrentPairs = 0; + for(PfxUInt32 i=0;i 0) { + pfxReleaseLargeTriMesh(gLargeMesh); + } + + PfxInt32 ret = pfxCreateLargeTriMesh(gLargeMesh,param); + if(ret != SCE_PFX_OK) { + SCE_PFX_PRINTF("Can't create large mesh.\n"); + } + + int id = numRigidBodies++; + PfxShape shape; + shape.reset(); + shape.setLargeTriMesh(&gLargeMesh); + collidables[id].reset(); + collidables[id].addShape(shape); + collidables[id].finish(); + bodies[id].reset(); + states[id].reset(); + states[id].setPosition(PfxVector3(0.0f,-5.0f,0.0f)); + states[id].setOrientation(PfxQuat::rotationX(0.5f)*PfxQuat::rotationY(0.7f)); + states[id].setMotionType(kPfxMotionTypeFixed); + states[id].setRigidBodyId(id); +} + +void physics_create_scene(int sceneId) +{ + const int numScenes = 4; + int sid = sceneId % numScenes; + + numRigidBodies= 0; + pairSwap = 0; + numPairs[0] = 0; + numPairs[1] = 0; + numContacts = 0; + numContactIdPool = 0; + numJoints = 0; + frame = 0; + + switch(sid) { + case 0: // simple primitives + createSceneBoxGround(); + createScenePrimitives(); + break; + + case 1: // joints + createSceneBoxGround(); + createSceneJoints(); + break; + + case 2: // stacking + createSceneBoxGround(); + createSceneStacking(); + break; + + case 3: // landscape + createSceneLandscape(); + createScenePrimitives(); + break; + } + + SCE_PFX_PRINTF("----- Size of rigid body buffer ------\n"); + SCE_PFX_PRINTF(" size * num = total\n"); + SCE_PFX_PRINTF("PfxRigidState %5d * %5d = %5d bytes\n",sizeof(PfxRigidState),numRigidBodies,sizeof(PfxRigidState)*numRigidBodies); + SCE_PFX_PRINTF("PfxRigidBody %5d * %5d = %5d bytes\n",sizeof(PfxRigidBody),numRigidBodies,sizeof(PfxRigidBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxCollidable %5d * %5d = %5d bytes\n",sizeof(PfxCollidable),numRigidBodies,sizeof(PfxCollidable)*numRigidBodies); + SCE_PFX_PRINTF("PfxJoint %5d * %5d = %5d bytes\n",sizeof(PfxJoint),numJoints,sizeof(PfxJoint)*numJoints); + SCE_PFX_PRINTF("PfxSolverBody %5d * %5d = %5d bytes\n",sizeof(PfxSolverBody),numRigidBodies,sizeof(PfxSolverBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxBroadphaseProxy %5d * %5d = %5d bytes\n",sizeof(PfxBroadphaseProxy),numRigidBodies,sizeof(PfxBroadphaseProxy)*numRigidBodies); + SCE_PFX_PRINTF("PfxContactManifold %5d * %5d = %5d bytes\n",sizeof(PfxContactManifold),NUM_CONTACTS,sizeof(PfxContactManifold)*NUM_CONTACTS); + SCE_PFX_PRINTF("PfxBroadphasePair %5d * %5d = %5d bytes\n",sizeof(PfxBroadphasePair),NUM_CONTACTS,sizeof(PfxBroadphasePair)*NUM_CONTACTS); + + int totalBytes = + (sizeof(PfxRigidState) + sizeof(PfxRigidBody) + sizeof(PfxCollidable) + sizeof(PfxSolverBody) + sizeof(PfxBroadphaseProxy)) * numRigidBodies + + (sizeof(PfxContactManifold) + sizeof(PfxBroadphasePair)) * NUM_CONTACTS; + SCE_PFX_PRINTF("----------------------------------------------------------\n"); + SCE_PFX_PRINTF("Total %5d bytes\n",totalBytes); +} + +/////////////////////////////////////////////////////////////////////////////// +// Initialize / Finalize Engine + +bool physics_init() +{ + return true; +} + +void physics_release() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Pick + +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2) +{ + return PfxVector3(0.0f); +} + +void physics_pick_update(const PfxVector3 &p) +{ +} + +void physics_pick_end() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Get Information + +int physics_get_num_rigidbodies() +{ + return numRigidBodies; +} + +const PfxRigidState& physics_get_state(int id) +{ + return states[id]; +} + +const PfxRigidBody& physics_get_body(int id) +{ + return bodies[id]; +} + +const PfxCollidable& physics_get_collidable(int id) +{ + return collidables[id]; +} + +int physics_get_num_contacts() +{ + return numPairs[pairSwap]; +} + +const PfxContactManifold &physics_get_contact(int id) +{ + return contacts[pfxGetConstraintId(pairsBuff[pairSwap][id])]; +} diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/0_console/physics_func.h b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/physics_func.h new file mode 100644 index 000000000..0aa7e07de --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/physics_func.h @@ -0,0 +1,49 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef __PHYSICS_FUNC_H__ +#define __PHYSICS_FUNC_H__ + +#define SCE_PFX_USE_PERFCOUNTER + +#include "physics_effects.h" + +using namespace sce::PhysicsEffects; + +//E Simulation +//J シミュレーション +bool physics_init(); +void physics_release(); +void physics_create_scene(int sceneId); +void physics_simulate(); + +//E Picking +//J ピッキング +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2); +void physics_pick_update(const PfxVector3 &p); +void physics_pick_end(); + +//E Change parameters +//J パラメータの取得 +int physics_get_num_rigidbodies(); +const PfxRigidState& physics_get_state(int id); +const PfxRigidBody& physics_get_body(int id); +const PfxCollidable& physics_get_collidable(int id); + +int physics_get_num_contacts(); +const PfxContactManifold &physics_get_contact(int id); + +#endif /* __PHYSICS_FUNC_H__ */ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/0_console/premake4.lua b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/premake4.lua new file mode 100644 index 000000000..b8e18d6eb --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/0_console/premake4.lua @@ -0,0 +1,18 @@ + project "0_console_sample" + + kind "ConsoleApp" + targetdir "../../../bin" + includedirs {"../../../include"} + + links { + "physicseffects2_lowlevel", + "physicseffects2_baselevel", + "physicseffects2_util" + } + + files { + "main.cpp", + "physics_func.cpp", + "physics_func.h", + "../common/perf_func.win32.cpp" + } \ No newline at end of file diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/1_simple.windows.vcproj b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/1_simple.windows.vcproj new file mode 100644 index 000000000..3d211cb0d --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/1_simple.windows.vcproj @@ -0,0 +1,713 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/CMakeLists.txt b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/CMakeLists.txt new file mode 100644 index 000000000..6f38d21e2 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/CMakeLists.txt @@ -0,0 +1,77 @@ +cmake_minimum_required(VERSION 2.4) + + +#this line has to appear before 'PROJECT' in order to be able to disable incremental linking +SET(MSVC_INCREMENTAL_DEFAULT ON) + +PROJECT(App_1_Simple) + + +IF (NOT CMAKE_BUILD_TYPE) +# SET(CMAKE_BUILD_TYPE "Debug") + SET(CMAKE_BUILD_TYPE "Release") +ENDIF (NOT CMAKE_BUILD_TYPE) + + +OPTION(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC Runtime Library DLL (/MD or /MDd)" ON) +OPTION(USE_MSVC_INCREMENTAL_LINKING "Use MSVC Incremental Linking" OFF) + + +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + + +SET(App_1_Simple_SRCS + main.cpp + physics_func.cpp + ../common/ctrl_func.win32.cpp + ../common/perf_func.win32.cpp + ../common/render_func.win32.cpp +) + + +SET(App_1_Simple_HDRS + physics_func.h + landscape.h + barrel.h + ../common/render_func.h + ../common/common.h + ../common/ctrl_func.h + ../common/perf_func.h +) + + +INCLUDE_DIRECTORIES( + ${PHYSICS_EFFECTS_SOURCE_DIR}/include +# ${VECTOR_MATH_INCLUDE} +) + +#LINK_DIRECTORIES( +# +#) + +#ADD_DEFINITIONS(-DUNICODE) +#ADD_DEFINITIONS(-D_UNICODE) + +ADD_EXECUTABLE(App_1_Simple WIN32 + ${App_1_Simple_SRCS} + ${App_1_Simple_HDRS} +) +TARGET_LINK_LIBRARIES(App_1_Simple + PfxBaseLevel + PfxLowLevel + PfxUtil + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} +) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(App_1_Simple PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(App_1_Simple PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(App_1_Simple PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF() + + + + \ No newline at end of file diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/barrel.h b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/barrel.h new file mode 100644 index 000000000..6574fa862 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/barrel.h @@ -0,0 +1,202 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define BarrelVtxCount 57 +#define BarrelIdxCount 180 + +static float BarrelVtx[] = { +0.0f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +-0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +0.0f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +-0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.957307f,-0.289072f,0.0f, +0.404509f,0.0f,-0.293893f, 0.809017f,0.0f,-0.587785f, +0.5f,0.0f,0.0f, 1.0f,0.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.774478f,-0.289072f,-0.562691f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +-0.154509f,0.0f,-0.475528f, -0.309017f,0.0f,-0.951057f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +-0.107853f,-0.5f,-0.331936f, -0.295824f,-0.289072f,-0.910453f, +-0.404509f,0.0f,-0.293893f, -0.809017f,0.0f,-0.587785f, +-0.282362f,-0.5f,-0.205148f, -0.774478f,-0.289072f,-0.562691f, +-0.5f,0.0f,0.0f, -1.0f,0.0f,0.0f, +-0.349018f,-0.5f,0.0f, -0.957307f,-0.289072f,0.0f, +-0.404508f,0.0f,0.293893f, -0.809017f,0.0f,0.587785f, +-0.282362f,-0.5f,0.205148f, -0.774478f,-0.289072f,0.562691f, +-0.154509f,0.0f,0.475528f, -0.309017f,0.0f,0.951056f, +-0.107853f,-0.5f,0.331936f, -0.295824f,-0.289072f,0.910453f, +0.154509f,0.0f,0.475528f, 0.309017f,0.0f,0.951056f, +0.107853f,-0.5f,0.331936f, 0.295824f,-0.289072f,0.910453f, +0.404509f,0.0f,0.293892f, 0.809017f,0.0f,0.587785f, +0.282362f,-0.5f,0.205148f, 0.774478f,-0.289072f,0.562691f, +0.282362f,0.5f,-0.205148f, 0.774478f,0.289072f,-0.562691f, +0.349018f,0.5f,0.0f, 0.957307f,0.289072f,0.0f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.107853f,0.5f,-0.331936f, -0.295824f,0.289072f,-0.910453f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.282362f,0.5f,-0.205148f, -0.774478f,0.289072f,-0.562691f, +-0.349018f,0.5f,0.0f, -0.957307f,0.289072f,0.0f, +-0.282362f,0.5f,0.205148f, -0.774478f,0.289072f,0.562691f, +-0.107853f,0.5f,0.331936f, -0.295824f,0.289072f,0.910453f, +0.107853f,0.5f,0.331936f, 0.295824f,0.289072f,0.910453f, +0.282362f,0.5f,0.205148f, 0.774478f,0.289072f,0.562691f, +}; + +static float BarrelTex[] = { +0.0f,0.5f, +0.0f,0.85f, +0.0f,0.75f, +0.0f,0.95f, +0.0f,0.05f, +0.0f,-0.05f, +0.0f,0.15f, +0.0f,0.25f, +0.0f,0.35f, +0.0f,0.45f, +0.0f,0.55f, +0.0f,0.65f, +1.0f,0.5f, +1.0f,0.75f, +1.0f,0.85f, +1.0f,0.95f, +1.0f,-0.05f, +1.0f,0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +0.0f,0.75f, +0.5f,0.85f, +0.5f,0.75f, +0.0f,0.85f, +0.5f,0.95f, +0.0f,0.95f, +0.0f,-0.05f, +0.5f,0.05f, +0.5f,-0.05f, +0.0f,0.05f, +0.5f,0.15f, +0.0f,0.15f, +0.5f,0.25f, +0.0f,0.25f, +0.5f,0.35f, +0.0f,0.35f, +0.5f,0.45f, +0.0f,0.45f, +0.5f,0.55f, +0.0f,0.55f, +0.5f,0.65f, +0.0f,0.65f, +1.0f,0.85f, +1.0f,0.75f, +1.0f,0.95f, +1.0f,0.05f, +1.0f,-0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +}; + +static unsigned short BarrelIdx[] = { +0,1,2, +0,3,1, +0,4,5, +0,6,4, +0,7,6, +0,8,7, +0,9,8, +0,10,9, +0,11,10, +0,2,11, +12,13,14, +12,14,15, +12,16,17, +12,17,18, +12,18,19, +12,19,20, +12,20,21, +12,21,22, +12,22,23, +12,23,13, +24,25,26, +24,27,25, +27,28,25, +27,29,28, +30,31,32, +30,33,31, +33,34,31, +33,35,34, +35,36,34, +35,37,36, +37,38,36, +37,39,38, +39,40,38, +39,41,40, +41,42,40, +41,43,42, +43,44,42, +43,45,44, +45,26,44, +45,24,26, +26,46,47, +26,25,46, +25,48,46, +25,28,48, +32,49,50, +32,31,49, +31,51,49, +31,34,51, +34,52,51, +34,36,52, +36,53,52, +36,38,53, +38,54,53, +38,40,54, +40,55,54, +40,42,55, +42,56,55, +42,44,56, +44,47,56, +44,26,47, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/landscape.h b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/landscape.h new file mode 100644 index 000000000..00f6cffd2 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/landscape.h @@ -0,0 +1,318 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define LargeMeshVtxCount 81 +#define LargeMeshIdxCount 384 + +static float LargeMeshVtx[] = { +-25.0f,-2.19407f,18.5625f, 0.232976f,0.967754f,0.0957829f, +-25.0f,0.0644502f,24.75f, 0.188094f,0.871343f,-0.45319f, +-18.75f,-4.50287f,18.5625f, -0.0716098f,0.995449f,0.0628767f, +-18.75f,-0.39999f,24.75f, -0.0602794f,0.895848f,-0.440253f, +-12.5f,-1.2166f,18.5625f, -0.269469f,0.961403f,0.0555879f, +-12.5f,-0.942431f,24.75f, -0.0997841f,0.993258f,0.0589987f, +-6.25f,1.93598f,18.5625f, -0.283933f,0.956351f,-0.0691025f, +-6.25f,-0.445954f,24.75f, -0.180725f,0.942766f,0.280233f, +0.0f,2.76983f,18.5625f, 0.171645f,0.984908f,0.0222501f, +0.0f,2.76642f,24.75f, 0.0784993f,0.995428f,-0.0544117f, +6.25f,-2.53736f,18.5625f, 0.248298f,0.965028f,0.0840741f, +6.25f,-0.915645f,24.75f, 0.164311f,0.945856f,-0.279926f, +12.5f,-1.60054f,18.5625f, -0.180435f,0.983586f,0.00115547f, +12.5f,0.831925f,24.75f, -0.0692495f,0.964821f,-0.253623f, +18.75f,-0.800282f,18.5625f, 0.10755f,0.951538f,0.288112f, +18.75f,-1.47284f,24.75f, 0.232178f,0.972664f,0.00429361f, +25.0f,-2.78379f,18.5625f, 0.1833f,0.937477f,0.295867f, +25.0f,-0.967508f,24.75f, -0.0773477f,0.956641f,-0.280812f, +-25.0f,-0.352038f,12.375f, -0.192222f,0.972435f,0.131987f, +-18.75f,0.681228f,12.375f, -0.107779f,0.962569f,0.248686f, +-12.5f,2.72065f,12.375f, 0.0520846f,0.993034f,0.105692f, +-6.25f,-1.78776f,12.375f, -0.0133223f,0.99674f,-0.0795754f, +0.0f,1.57707f,12.375f, -0.129025f,0.969662f,-0.207627f, +6.25f,0.424356f,12.375f, 0.180995f,0.97074f,0.157815f, +12.5f,0.283234f,12.375f, -0.16285f,0.973539f,0.160316f, +18.75f,2.57015f,12.375f, -0.165454f,0.978339f,0.124408f, +25.0f,3.07363f,12.375f, -0.00454559f,0.988151f,0.153417f, +-25.0f,-0.893751f,6.1875f, -0.0836251f,0.990084f,-0.112876f, +-18.75f,0.930932f,6.1875f, 0.00269413f,0.971838f,-0.235633f, +-12.5f,-0.684529f,6.1875f, -0.010319f,0.927048f,-0.3748f, +-6.25f,-0.661383f,6.1875f, 0.012265f,0.999875f,-0.00994222f, +0.0f,0.385718f,6.1875f, -0.15435f,0.984937f,-0.0779465f, +6.25f,0.589796f,6.1875f, 0.0241717f,0.999582f,-0.0158589f, +12.5f,0.47454f,6.1875f, -0.017184f,0.997953f,-0.0616073f, +18.75f,1.59939f,6.1875f, -0.0902706f,0.957309f,-0.274609f, +25.0f,1.13434f,6.1875f, 0.0346006f,0.957441f,-0.286547f, +-25.0f,0.74548f,0.0f, 0.329903f,0.930812f,0.157334f, +-18.75f,-2.47437f,0.0f, 0.247844f,0.968142f,0.0357041f, +-12.5f,-4.16309f,1.81975e-007f, -0.0623898f,0.997626f,-0.0291436f, +-6.25f,-0.700022f,0.0f, -0.217067f,0.974987f,-0.0477624f, +0.0f,-0.0957388f,0.0f, -0.117693f,0.990712f,-0.068098f, +6.25f,0.614077f,0.0f, -0.0713214f,0.997305f,0.01722f, +12.5f,0.299109f,0.0f, 0.218606f,0.968641f,0.118094f, +18.75f,-1.71753f,0.0f, 0.0339493f,0.985612f,-0.165579f, +25.0f,-1.12638f,0.0f, -0.0547573f,0.989177f,-0.136126f, +-25.0f,-0.403319f,-6.1875f, -0.1263f,0.989211f,-0.074223f, +-18.75f,-0.0730335f,-6.1875f, 0.0173428f,0.965382f,0.260261f, +-12.5f,-0.450125f,-6.1875f, 0.0658811f,0.875f,0.479619f, +-6.25f,-0.180204f,-6.1875f, 0.0116584f,0.981445f,0.19139f, +0.0f,-0.632679f,-6.1875f, -0.0557983f,0.993041f,-0.103716f, +6.25f,0.308409f,-6.1875f, -0.191898f,0.96766f,-0.163737f, +12.5f,2.5011f,-6.1875f, 0.0758397f,0.996403f,-0.0378189f, +18.75f,-1.69303f,-6.1875f, 0.16761f,0.974057f,0.15205f, +25.0f,-0.141349f,-6.1875f, -0.204846f,0.978471f,0.0251341f, +-25.0f,-1.10316f,-12.375f, -0.0350644f,0.993748f,-0.106001f, +-18.75f,1.06711f,-12.375f, -0.309806f,0.919244f,-0.242922f, +-12.5f,3.61544f,-12.375f, -0.0506281f,0.998702f,-0.00561657f, +-6.25f,1.6504f,-12.375f, 0.322294f,0.937465f,0.131477f, +0.0f,-1.60595f,-12.375f, 0.086016f,0.995916f,0.0274459f, +6.25f,-0.849859f,-12.375f, -0.0332811f,0.997087f,0.0686255f, +12.5f,-0.942201f,-12.375f, -0.153559f,0.982185f,-0.108312f, +18.75f,0.494873f,-12.375f, 0.0753195f,0.981472f,0.176181f, +25.0f,-0.333828f,-12.375f, 0.035057f,0.987194f,0.155624f, +-25.0f,2.1862f,-18.5625f, 0.612899f,0.782306f,0.111138f, +-18.75f,-3.38259f,-18.5625f, 0.0194078f,0.992789f,-0.118297f, +-12.5f,-0.880916f,-18.5625f, -0.282251f,0.949875f,-0.13443f, +-6.25f,0.818158f,-18.5625f, 0.1476f,0.981788f,-0.119612f, +0.0f,-1.48019f,-18.5625f, -0.044551f,0.996013f,-0.0772824f, +6.25f,1.47123f,-18.5625f, -0.117036f,0.97986f,0.161792f, +12.5f,0.164076f,-18.5625f, -0.0340355f,0.978993f,0.201034f, +18.75f,2.14568f,-18.5625f, -0.0439269f,0.994859f,0.0912435f, +25.0f,0.626506f,-18.5625f, 0.208015f,0.968592f,0.136229f, +-25.0f,0.296889f,-24.75f, 0.46973f,0.844327f,-0.257809f, +-18.75f,-3.18022f,-24.75f, -0.0226758f,0.998794f,-0.0435401f, +-12.5f,1.8927f,-24.75f, -0.202772f,0.919836f,0.335836f, +-6.25f,1.46387f,-24.75f, 0.224904f,0.955746f,0.189652f, +0.0f,-2.52726f,-24.75f, -0.0435882f,0.993572f,-0.10447f, +6.25f,1.30397f,-24.75f, -0.28646f,0.956525f,-0.0547707f, +12.5f,1.85812f,-24.75f, 0.0521949f,0.979796f,0.193067f, +18.75f,1.56331f,-24.75f, -0.0270784f,0.999629f,-0.00293115f, +25.0f,1.05366f,-24.75f, 0.161f,0.986887f,-0.0115473f, +}; + +static float LargeMeshTex[] = { +0.125f,0.0f, +0.0f,0.0f, +0.125f,0.125f, +0.0f,0.125f, +0.125f,0.25f, +0.0f,0.25f, +0.125f,0.375f, +0.0f,0.375f, +0.125f,0.5f, +0.0f,0.5f, +0.125f,0.625f, +0.0f,0.625f, +0.125f,0.75f, +0.0f,0.75f, +0.125f,0.875f, +0.0f,0.875f, +0.125f,1.0f, +0.0f,1.0f, +0.25f,0.0f, +0.25f,0.125f, +0.25f,0.25f, +0.25f,0.375f, +0.25f,0.5f, +0.25f,0.625f, +0.25f,0.75f, +0.25f,0.875f, +0.25f,1.0f, +0.375f,0.0f, +0.375f,0.125f, +0.375f,0.25f, +0.375f,0.375f, +0.375f,0.5f, +0.375f,0.625f, +0.375f,0.75f, +0.375f,0.875f, +0.375f,1.0f, +0.5f,0.0f, +0.5f,0.125f, +0.5f,0.25f, +0.5f,0.375f, +0.5f,0.5f, +0.5f,0.625f, +0.5f,0.75f, +0.5f,0.875f, +0.5f,1.0f, +0.625f,0.0f, +0.625f,0.125f, +0.625f,0.25f, +0.625f,0.375f, +0.625f,0.5f, +0.625f,0.625f, +0.625f,0.75f, +0.625f,0.875f, +0.625f,1.0f, +0.75f,0.0f, +0.75f,0.125f, +0.75f,0.25f, +0.75f,0.375f, +0.75f,0.5f, +0.75f,0.625f, +0.75f,0.75f, +0.75f,0.875f, +0.75f,1.0f, +0.875f,0.0f, +0.875f,0.125f, +0.875f,0.25f, +0.875f,0.375f, +0.875f,0.5f, +0.875f,0.625f, +0.875f,0.75f, +0.875f,0.875f, +0.875f,1.0f, +1.0f,0.0f, +1.0f,0.125f, +1.0f,0.25f, +1.0f,0.375f, +1.0f,0.5f, +1.0f,0.625f, +1.0f,0.75f, +1.0f,0.875f, +1.0f,1.0f, +}; + +static unsigned short LargeMeshIdx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +18,0,19, +2,19,0, +19,2,20, +4,20,2, +20,4,21, +6,21,4, +21,6,22, +8,22,6, +22,8,23, +10,23,8, +23,10,24, +12,24,10, +24,12,25, +14,25,12, +25,14,26, +16,26,14, +27,18,28, +19,28,18, +28,19,29, +20,29,19, +29,20,30, +21,30,20, +30,21,31, +22,31,21, +31,22,32, +23,32,22, +32,23,33, +24,33,23, +33,24,34, +25,34,24, +34,25,35, +26,35,25, +36,27,37, +28,37,27, +37,28,38, +29,38,28, +38,29,39, +30,39,29, +39,30,40, +31,40,30, +40,31,41, +32,41,31, +41,32,42, +33,42,32, +42,33,43, +34,43,33, +43,34,44, +35,44,34, +45,36,46, +37,46,36, +46,37,47, +38,47,37, +47,38,48, +39,48,38, +48,39,49, +40,49,39, +49,40,50, +41,50,40, +50,41,51, +42,51,41, +51,42,52, +43,52,42, +52,43,53, +44,53,43, +54,45,55, +46,55,45, +55,46,56, +47,56,46, +56,47,57, +48,57,47, +57,48,58, +49,58,48, +58,49,59, +50,59,49, +59,50,60, +51,60,50, +60,51,61, +52,61,51, +61,52,62, +53,62,52, +63,54,64, +55,64,54, +64,55,65, +56,65,55, +65,56,66, +57,66,56, +66,57,67, +58,67,57, +67,58,68, +59,68,58, +68,59,69, +60,69,59, +69,60,70, +61,70,60, +70,61,71, +62,71,61, +72,63,73, +64,73,63, +73,64,74, +65,74,64, +74,65,75, +66,75,65, +75,66,76, +67,76,66, +76,67,77, +68,77,67, +77,68,78, +69,78,68, +78,69,79, +70,79,69, +79,70,80, +71,80,70, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/main.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/main.cpp new file mode 100644 index 000000000..5db906fb0 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/main.cpp @@ -0,0 +1,495 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../common/common.h" +#include "../common/ctrl_func.h" +#include "../common/render_func.h" +#include "../common/perf_func.h" +#include "physics_func.h" +#include "barrel.h" +#include "landscape.h" + +#ifdef _WIN32 + #include + #include +#endif + +// ARA begin insert new code +#ifdef __ANDROID__ + #include + #include + #include // used to check for presence of NEON on device + #ifdef __ARM_NEON__ + #include +#ifdef TEST_NEON_PERFORMANCE // define this to run NEON performance tests + #include "../../test_ARM_NEON_performance/test_neon.h" +#endif + #endif // __ARM_NEON__ +#endif // __ANDROID__ +// ARA end + +#define SAMPLE_NAME "api_physics_effects/1_simple" + +static bool s_isRunning = true; + +int sceneId = 0; +bool simulating = false; + +int landscapeMeshId; +int convexMeshId; + +void render(void) +{ + render_begin(); + + for(int i=0;i -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_DOWN)) { + angX += 0.05f; + if(angX < -1.4f) angX = -1.4f; + if(angX > -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_LEFT)) { + angY -= 0.05f; + } + + if(ctrl_button_pressed(BTN_RIGHT)) { + angY += 0.05f; + } + + if(ctrl_button_pressed(BTN_ZOOM_OUT)) { + r *= 1.1f; + if(r > 500.0f) r = 500.0f; + } + + if(ctrl_button_pressed(BTN_ZOOM_IN)) { + r *= 0.9f; + if(r < 1.0f) r = 1.0f; + } + + if(ctrl_button_pressed(BTN_SCENE_RESET) == BTN_STAT_DOWN) { + physics_create_scene(sceneId); + } + + if(ctrl_button_pressed(BTN_SCENE_NEXT) == BTN_STAT_DOWN) { + physics_create_scene(++sceneId); + } + + if(ctrl_button_pressed(BTN_SIMULATION) == BTN_STAT_DOWN) { + simulating = !simulating; + } + + if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_DOWN) { + simulating = true; + } + else if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_UP || ctrl_button_pressed(BTN_STEP) == BTN_STAT_KEEP) { + simulating = false; + } + + render_set_view_angle(angX,angY,r); +} + +#ifndef _WIN32 + +// ARA begin insert new code +#ifdef __ANDROID__ + +/////////////////////////////////////////////////////////////////////////////// +// sceneChange +// +/// This function is used to change the physics scene on Android devices +/////////////////////////////////////////////////////////////////////////////// +void sceneChange() +{ + physics_create_scene(sceneId++); +} + +#else // __ANDROID__ +// ARA end + +/////////////////////////////////////////////////////////////////////////////// +// Main + +int main(void) +{ + init(); + + physics_create_scene(sceneId); + + printf("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + while (s_isRunning) { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + + shutdown(); + + printf("## %s: FINISHED ##\n", SAMPLE_NAME); + + return 0; +} + +// ARA begin insert new code +#endif // __ANDROID__ +// ARA end + +#else // _WIN32 + +/////////////////////////////////////////////////////////////////////////////// +// WinMain + +extern HDC hDC; +extern HGLRC hRC; +HWND hWnd; +HINSTANCE hInstance; + +void releaseWindow() +{ + if(hRC) { + wglMakeCurrent(0,0); + wglDeleteContext(hRC); + } + + if(hDC) ReleaseDC(hWnd,hDC); + if(hWnd) DestroyWindow(hWnd); + + UnregisterClass(SAMPLE_NAME,hInstance); +} + +LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) { + case WM_SYSCOMMAND: + { + switch (wParam) { + case SC_SCREENSAVE: + case SC_MONITORPOWER: + return 0; + } + break; + } + + case WM_CLOSE: + PostQuitMessage(0); + return 0; + + case WM_SIZE: + render_resize(LOWORD(lParam),HIWORD(lParam)); + return 0; + } + + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + +bool createWindow(char* title, int width, int height) +{ + WNDCLASS wc; + RECT rect; + rect.left=0; + rect.right=width; + rect.top=0; + rect.bottom=height; + + hInstance = GetModuleHandle(NULL); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = SAMPLE_NAME; + + if(!RegisterClass(&wc)) { + return false; + } + + AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE); + + if(!(hWnd=CreateWindowEx(WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,SAMPLE_NAME,title, + WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, + 0,0,rect.right-rect.left,rect.bottom-rect.top, + NULL,NULL,hInstance,NULL))) { + releaseWindow(); + return false; + } + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 32, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, + 0, 0, 0, 0, + 32, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + if(!(hDC=GetDC(hWnd))) + { + releaseWindow(); + OutputDebugString(""); + return FALSE; + } + + int pixelformat; + + if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){ + OutputDebugString("ChoosePixelFormat Failed...."); + return FALSE; + } + + if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE){ + OutputDebugString("SetPixelFormat Failed...."); + return FALSE; + } + + if (!(hRC=wglCreateContext(hDC))){ + OutputDebugString("Creating HGLRC Failed...."); + return FALSE; + } + + // Set Vsync + //BOOL (WINAPI *wglSwapIntervalEXT)(int) = NULL; + + //if(strstr((char*)glGetString( GL_EXTENSIONS ),"WGL_EXT_swap_control")== 0) { + //} + //else { + //wglSwapIntervalEXT = (BOOL (WINAPI*)(int))wglGetProcAddress("wglSwapIntervalEXT"); + //if(wglSwapIntervalEXT) wglSwapIntervalEXT(1); + //} + + wglMakeCurrent(hDC,hRC); + + ShowWindow(hWnd,SW_SHOW); + SetForegroundWindow(hWnd); + SetFocus(hWnd); + + render_resize(width, height); + + glClearColor(0.0f,0.0f,0.0f,0.0f); + glClearDepth(1.0f); + + return TRUE; +} + +int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) +{ + if(!createWindow(SAMPLE_NAME,DISPLAY_WIDTH,DISPLAY_HEIGHT)) { + MessageBox(NULL,"Can't create gl window.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return 0; + } + + init(); + + physics_create_scene(sceneId); + + SCE_PFX_PRINTF("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + MSG msg; + while(s_isRunning) { + if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if(msg.message==WM_QUIT) { + s_isRunning = false; + } + else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + else { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + } + + shutdown(); + + SCE_PFX_PRINTF("## %s: FINISHED ##\n", SAMPLE_NAME); + + releaseWindow(); + return (msg.wParam); +} + +#endif diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/physics.png b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/physics.png new file mode 100644 index 000000000..641c4fc3e Binary files /dev/null and b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/physics.png differ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/physics_func.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/physics_func.cpp new file mode 100644 index 000000000..b45e331e0 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/physics_func.cpp @@ -0,0 +1,769 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "physics_func.h" +#include "../common/perf_func.h" + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Data + +#define NUM_RIGIDBODIES 500 +#define NUM_JOINTS 500 +#define NUM_CONTACTS 4000 + +const float timeStep = 0.016f; +const float separateBias = 0.1f; +int iteration = 5; + +//J ワールドサイズ +//E World size +PfxVector3 worldCenter(0.0f); +PfxVector3 worldExtent(500.0f); + +//J 剛体 +//E Rigid body +PfxRigidState states[NUM_RIGIDBODIES]; +PfxRigidBody bodies[NUM_RIGIDBODIES]; +PfxCollidable collidables[NUM_RIGIDBODIES]; +PfxSolverBody solverBodies[NUM_RIGIDBODIES]; +int numRigidBodies = 0; + +//J 地形を表現するためのラージメッシュ +//E Large mesh for representing a landscape +#include "landscape.h" +PfxLargeTriMesh gLargeMesh; + +//J 凸メッシュ +//E Convex Mesh +#include "barrel.h" +PfxConvexMesh gConvex; + +//J プロキシ +//E Proxies +PfxBroadphaseProxy proxies[NUM_RIGIDBODIES]; + +//J ジョイント +//E Joint +PfxConstraintPair jointPairs[NUM_JOINTS]; +PfxJoint joints[NUM_JOINTS]; +int numJoints = 0; + +//J ペア +//E Pairs +unsigned int numPairs; +PfxBroadphasePair pairs[NUM_CONTACTS]; + +//J コンタクト +//E Contacts +PfxContactManifold contacts[NUM_CONTACTS]; +int numContacts; + +//J 一時バッファ +//E Temporary buffers +#define POOL_BYTES (5*1024*1024) +unsigned char SCE_PFX_ALIGNED(128) poolBuff[POOL_BYTES]; + +//J 一時バッファ用スタックアロケータ +//E Stack allocator for temporary buffers +PfxHeapManager pool(poolBuff,POOL_BYTES); + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Function + +int frame = 0; + +void broadphase() +{ + //J 剛体が最も分散している軸を見つける + //E Find the axis along which all rigid bodies are most widely positioned + int axis = 0; + { + PfxVector3 s(0.0f),s2(0.0f); + for(int i=0;i v[0]) axis = 1; + if(v[2] > v[axis]) axis = 2; + } + + //J ブロードフェーズプロキシの更新 + //E Create broadpahse proxies + { + for(int i=0;i 0) { + pfxReleaseLargeTriMesh(gLargeMesh); + } + + PfxInt32 ret = pfxCreateLargeTriMesh(gLargeMesh,param); + if(ret != SCE_PFX_OK) { + SCE_PFX_PRINTF("Can't create large mesh.\n"); + } + + int id = numRigidBodies++; + PfxShape shape; + shape.reset(); + shape.setLargeTriMesh(&gLargeMesh); + collidables[id].reset(); + collidables[id].addShape(shape); + collidables[id].finish(); + bodies[id].reset(); + states[id].reset(); + states[id].setPosition(PfxVector3(0.0f,-5.0f,0.0f)); + states[id].setOrientation(PfxQuat::rotationX(0.5f)*PfxQuat::rotationY(0.7f)); + states[id].setMotionType(kPfxMotionTypeFixed); + states[id].setRigidBodyId(id); +} + +void physics_create_scene(int sceneId) +{ + const int numScenes = 4; + int sid = sceneId % numScenes; + + numRigidBodies= 0; + numPairs = 0; + numContacts = 0; + numJoints = 0; + frame = 0; + + switch(sid) { + case 0: // simple primitives + createSceneBoxGround(); + createScenePrimitives(); + break; + + case 1: // joints + createSceneBoxGround(); + createSceneJoints(); + break; + + case 2: // stacking + createSceneBoxGround(); + createSceneStacking(); + break; + + case 3: // landscape + createSceneLandscape(); + createScenePrimitives(); + break; + } + + SCE_PFX_PRINTF("----- Size of rigid body buffer ------\n"); + SCE_PFX_PRINTF(" size * num = total\n"); + SCE_PFX_PRINTF("PfxRigidState %5d * %5d = %5d bytes\n",sizeof(PfxRigidState),numRigidBodies,sizeof(PfxRigidState)*numRigidBodies); + SCE_PFX_PRINTF("PfxRigidBody %5d * %5d = %5d bytes\n",sizeof(PfxRigidBody),numRigidBodies,sizeof(PfxRigidBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxCollidable %5d * %5d = %5d bytes\n",sizeof(PfxCollidable),numRigidBodies,sizeof(PfxCollidable)*numRigidBodies); + SCE_PFX_PRINTF("PfxJoint %5d * %5d = %5d bytes\n",sizeof(PfxJoint),numJoints,sizeof(PfxJoint)*numJoints); + SCE_PFX_PRINTF("PfxSolverBody %5d * %5d = %5d bytes\n",sizeof(PfxSolverBody),numRigidBodies,sizeof(PfxSolverBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxBroadphaseProxy %5d * %5d = %5d bytes\n",sizeof(PfxBroadphaseProxy),numRigidBodies,sizeof(PfxBroadphaseProxy)*numRigidBodies); + SCE_PFX_PRINTF("PfxContactManifold %5d * %5d = %5d bytes\n",sizeof(PfxContactManifold),NUM_CONTACTS,sizeof(PfxContactManifold)*NUM_CONTACTS); + SCE_PFX_PRINTF("PfxBroadphasePair %5d * %5d = %5d bytes\n",sizeof(PfxBroadphasePair),NUM_CONTACTS,sizeof(PfxBroadphasePair)*NUM_CONTACTS); + + int totalBytes = + (sizeof(PfxRigidState) + sizeof(PfxRigidBody) + sizeof(PfxCollidable) + sizeof(PfxSolverBody) + sizeof(PfxBroadphaseProxy)) * numRigidBodies + + (sizeof(PfxContactManifold) + sizeof(PfxBroadphasePair)) * NUM_CONTACTS; + SCE_PFX_PRINTF("----------------------------------------------------------\n"); + SCE_PFX_PRINTF("Total %5d bytes\n",totalBytes); +} + +/////////////////////////////////////////////////////////////////////////////// +// Initialize / Finalize Engine + +bool physics_init() +{ + return true; +} + +void physics_release() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Pick + +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2) +{ + return PfxVector3(0.0f); +} + +void physics_pick_update(const PfxVector3 &p) +{ +} + +void physics_pick_end() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Get Information + +int physics_get_num_rigidbodies() +{ + return numRigidBodies; +} + +const PfxRigidState& physics_get_state(int id) +{ + return states[id]; +} + +const PfxRigidBody& physics_get_body(int id) +{ + return bodies[id]; +} + +const PfxCollidable& physics_get_collidable(int id) +{ + return collidables[id]; +} + +int physics_get_num_contacts() +{ + return numPairs; +} + +const PfxContactManifold &physics_get_contact(int id) +{ + return contacts[pfxGetConstraintId(pairs[id])]; +} + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/physics_func.h b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/physics_func.h new file mode 100644 index 000000000..0aa7e07de --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/physics_func.h @@ -0,0 +1,49 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef __PHYSICS_FUNC_H__ +#define __PHYSICS_FUNC_H__ + +#define SCE_PFX_USE_PERFCOUNTER + +#include "physics_effects.h" + +using namespace sce::PhysicsEffects; + +//E Simulation +//J シミュレーション +bool physics_init(); +void physics_release(); +void physics_create_scene(int sceneId); +void physics_simulate(); + +//E Picking +//J ピッキング +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2); +void physics_pick_update(const PfxVector3 &p); +void physics_pick_end(); + +//E Change parameters +//J パラメータの取得 +int physics_get_num_rigidbodies(); +const PfxRigidState& physics_get_state(int id); +const PfxRigidBody& physics_get_body(int id); +const PfxCollidable& physics_get_collidable(int id); + +int physics_get_num_contacts(); +const PfxContactManifold &physics_get_contact(int id); + +#endif /* __PHYSICS_FUNC_H__ */ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/premake4.lua b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/premake4.lua new file mode 100644 index 000000000..4bd42a3dc --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple/premake4.lua @@ -0,0 +1,22 @@ + project "1_simple" + + kind "WindowedApp" + targetdir "../../../bin" + includedirs {"../../../include"} + + links { + "physicseffects2_lowlevel", + "physicseffects2_baselevel", + "physicseffects2_util", + "opengl32" + } + + flags {"WinMain"} + + files { + "main.cpp", + "physics_func.cpp", + "../common/ctrl_func.win32.cpp", + "../common/perf_func.win32.cpp", + "../common/render_func.win32.cpp" + } \ No newline at end of file diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/barrel.h b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/barrel.h new file mode 100644 index 000000000..6574fa862 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/barrel.h @@ -0,0 +1,202 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define BarrelVtxCount 57 +#define BarrelIdxCount 180 + +static float BarrelVtx[] = { +0.0f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +-0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +0.0f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +-0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.957307f,-0.289072f,0.0f, +0.404509f,0.0f,-0.293893f, 0.809017f,0.0f,-0.587785f, +0.5f,0.0f,0.0f, 1.0f,0.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.774478f,-0.289072f,-0.562691f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +-0.154509f,0.0f,-0.475528f, -0.309017f,0.0f,-0.951057f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +-0.107853f,-0.5f,-0.331936f, -0.295824f,-0.289072f,-0.910453f, +-0.404509f,0.0f,-0.293893f, -0.809017f,0.0f,-0.587785f, +-0.282362f,-0.5f,-0.205148f, -0.774478f,-0.289072f,-0.562691f, +-0.5f,0.0f,0.0f, -1.0f,0.0f,0.0f, +-0.349018f,-0.5f,0.0f, -0.957307f,-0.289072f,0.0f, +-0.404508f,0.0f,0.293893f, -0.809017f,0.0f,0.587785f, +-0.282362f,-0.5f,0.205148f, -0.774478f,-0.289072f,0.562691f, +-0.154509f,0.0f,0.475528f, -0.309017f,0.0f,0.951056f, +-0.107853f,-0.5f,0.331936f, -0.295824f,-0.289072f,0.910453f, +0.154509f,0.0f,0.475528f, 0.309017f,0.0f,0.951056f, +0.107853f,-0.5f,0.331936f, 0.295824f,-0.289072f,0.910453f, +0.404509f,0.0f,0.293892f, 0.809017f,0.0f,0.587785f, +0.282362f,-0.5f,0.205148f, 0.774478f,-0.289072f,0.562691f, +0.282362f,0.5f,-0.205148f, 0.774478f,0.289072f,-0.562691f, +0.349018f,0.5f,0.0f, 0.957307f,0.289072f,0.0f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.107853f,0.5f,-0.331936f, -0.295824f,0.289072f,-0.910453f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.282362f,0.5f,-0.205148f, -0.774478f,0.289072f,-0.562691f, +-0.349018f,0.5f,0.0f, -0.957307f,0.289072f,0.0f, +-0.282362f,0.5f,0.205148f, -0.774478f,0.289072f,0.562691f, +-0.107853f,0.5f,0.331936f, -0.295824f,0.289072f,0.910453f, +0.107853f,0.5f,0.331936f, 0.295824f,0.289072f,0.910453f, +0.282362f,0.5f,0.205148f, 0.774478f,0.289072f,0.562691f, +}; + +static float BarrelTex[] = { +0.0f,0.5f, +0.0f,0.85f, +0.0f,0.75f, +0.0f,0.95f, +0.0f,0.05f, +0.0f,-0.05f, +0.0f,0.15f, +0.0f,0.25f, +0.0f,0.35f, +0.0f,0.45f, +0.0f,0.55f, +0.0f,0.65f, +1.0f,0.5f, +1.0f,0.75f, +1.0f,0.85f, +1.0f,0.95f, +1.0f,-0.05f, +1.0f,0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +0.0f,0.75f, +0.5f,0.85f, +0.5f,0.75f, +0.0f,0.85f, +0.5f,0.95f, +0.0f,0.95f, +0.0f,-0.05f, +0.5f,0.05f, +0.5f,-0.05f, +0.0f,0.05f, +0.5f,0.15f, +0.0f,0.15f, +0.5f,0.25f, +0.0f,0.25f, +0.5f,0.35f, +0.0f,0.35f, +0.5f,0.45f, +0.0f,0.45f, +0.5f,0.55f, +0.0f,0.55f, +0.5f,0.65f, +0.0f,0.65f, +1.0f,0.85f, +1.0f,0.75f, +1.0f,0.95f, +1.0f,0.05f, +1.0f,-0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +}; + +static unsigned short BarrelIdx[] = { +0,1,2, +0,3,1, +0,4,5, +0,6,4, +0,7,6, +0,8,7, +0,9,8, +0,10,9, +0,11,10, +0,2,11, +12,13,14, +12,14,15, +12,16,17, +12,17,18, +12,18,19, +12,19,20, +12,20,21, +12,21,22, +12,22,23, +12,23,13, +24,25,26, +24,27,25, +27,28,25, +27,29,28, +30,31,32, +30,33,31, +33,34,31, +33,35,34, +35,36,34, +35,37,36, +37,38,36, +37,39,38, +39,40,38, +39,41,40, +41,42,40, +41,43,42, +43,44,42, +43,45,44, +45,26,44, +45,24,26, +26,46,47, +26,25,46, +25,48,46, +25,28,48, +32,49,50, +32,31,49, +31,51,49, +31,34,51, +34,52,51, +34,36,52, +36,53,52, +36,38,53, +38,54,53, +38,40,54, +40,55,54, +40,42,55, +42,56,55, +42,44,56, +44,47,56, +44,26,47, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/landscape.h b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/landscape.h new file mode 100644 index 000000000..00f6cffd2 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/landscape.h @@ -0,0 +1,318 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define LargeMeshVtxCount 81 +#define LargeMeshIdxCount 384 + +static float LargeMeshVtx[] = { +-25.0f,-2.19407f,18.5625f, 0.232976f,0.967754f,0.0957829f, +-25.0f,0.0644502f,24.75f, 0.188094f,0.871343f,-0.45319f, +-18.75f,-4.50287f,18.5625f, -0.0716098f,0.995449f,0.0628767f, +-18.75f,-0.39999f,24.75f, -0.0602794f,0.895848f,-0.440253f, +-12.5f,-1.2166f,18.5625f, -0.269469f,0.961403f,0.0555879f, +-12.5f,-0.942431f,24.75f, -0.0997841f,0.993258f,0.0589987f, +-6.25f,1.93598f,18.5625f, -0.283933f,0.956351f,-0.0691025f, +-6.25f,-0.445954f,24.75f, -0.180725f,0.942766f,0.280233f, +0.0f,2.76983f,18.5625f, 0.171645f,0.984908f,0.0222501f, +0.0f,2.76642f,24.75f, 0.0784993f,0.995428f,-0.0544117f, +6.25f,-2.53736f,18.5625f, 0.248298f,0.965028f,0.0840741f, +6.25f,-0.915645f,24.75f, 0.164311f,0.945856f,-0.279926f, +12.5f,-1.60054f,18.5625f, -0.180435f,0.983586f,0.00115547f, +12.5f,0.831925f,24.75f, -0.0692495f,0.964821f,-0.253623f, +18.75f,-0.800282f,18.5625f, 0.10755f,0.951538f,0.288112f, +18.75f,-1.47284f,24.75f, 0.232178f,0.972664f,0.00429361f, +25.0f,-2.78379f,18.5625f, 0.1833f,0.937477f,0.295867f, +25.0f,-0.967508f,24.75f, -0.0773477f,0.956641f,-0.280812f, +-25.0f,-0.352038f,12.375f, -0.192222f,0.972435f,0.131987f, +-18.75f,0.681228f,12.375f, -0.107779f,0.962569f,0.248686f, +-12.5f,2.72065f,12.375f, 0.0520846f,0.993034f,0.105692f, +-6.25f,-1.78776f,12.375f, -0.0133223f,0.99674f,-0.0795754f, +0.0f,1.57707f,12.375f, -0.129025f,0.969662f,-0.207627f, +6.25f,0.424356f,12.375f, 0.180995f,0.97074f,0.157815f, +12.5f,0.283234f,12.375f, -0.16285f,0.973539f,0.160316f, +18.75f,2.57015f,12.375f, -0.165454f,0.978339f,0.124408f, +25.0f,3.07363f,12.375f, -0.00454559f,0.988151f,0.153417f, +-25.0f,-0.893751f,6.1875f, -0.0836251f,0.990084f,-0.112876f, +-18.75f,0.930932f,6.1875f, 0.00269413f,0.971838f,-0.235633f, +-12.5f,-0.684529f,6.1875f, -0.010319f,0.927048f,-0.3748f, +-6.25f,-0.661383f,6.1875f, 0.012265f,0.999875f,-0.00994222f, +0.0f,0.385718f,6.1875f, -0.15435f,0.984937f,-0.0779465f, +6.25f,0.589796f,6.1875f, 0.0241717f,0.999582f,-0.0158589f, +12.5f,0.47454f,6.1875f, -0.017184f,0.997953f,-0.0616073f, +18.75f,1.59939f,6.1875f, -0.0902706f,0.957309f,-0.274609f, +25.0f,1.13434f,6.1875f, 0.0346006f,0.957441f,-0.286547f, +-25.0f,0.74548f,0.0f, 0.329903f,0.930812f,0.157334f, +-18.75f,-2.47437f,0.0f, 0.247844f,0.968142f,0.0357041f, +-12.5f,-4.16309f,1.81975e-007f, -0.0623898f,0.997626f,-0.0291436f, +-6.25f,-0.700022f,0.0f, -0.217067f,0.974987f,-0.0477624f, +0.0f,-0.0957388f,0.0f, -0.117693f,0.990712f,-0.068098f, +6.25f,0.614077f,0.0f, -0.0713214f,0.997305f,0.01722f, +12.5f,0.299109f,0.0f, 0.218606f,0.968641f,0.118094f, +18.75f,-1.71753f,0.0f, 0.0339493f,0.985612f,-0.165579f, +25.0f,-1.12638f,0.0f, -0.0547573f,0.989177f,-0.136126f, +-25.0f,-0.403319f,-6.1875f, -0.1263f,0.989211f,-0.074223f, +-18.75f,-0.0730335f,-6.1875f, 0.0173428f,0.965382f,0.260261f, +-12.5f,-0.450125f,-6.1875f, 0.0658811f,0.875f,0.479619f, +-6.25f,-0.180204f,-6.1875f, 0.0116584f,0.981445f,0.19139f, +0.0f,-0.632679f,-6.1875f, -0.0557983f,0.993041f,-0.103716f, +6.25f,0.308409f,-6.1875f, -0.191898f,0.96766f,-0.163737f, +12.5f,2.5011f,-6.1875f, 0.0758397f,0.996403f,-0.0378189f, +18.75f,-1.69303f,-6.1875f, 0.16761f,0.974057f,0.15205f, +25.0f,-0.141349f,-6.1875f, -0.204846f,0.978471f,0.0251341f, +-25.0f,-1.10316f,-12.375f, -0.0350644f,0.993748f,-0.106001f, +-18.75f,1.06711f,-12.375f, -0.309806f,0.919244f,-0.242922f, +-12.5f,3.61544f,-12.375f, -0.0506281f,0.998702f,-0.00561657f, +-6.25f,1.6504f,-12.375f, 0.322294f,0.937465f,0.131477f, +0.0f,-1.60595f,-12.375f, 0.086016f,0.995916f,0.0274459f, +6.25f,-0.849859f,-12.375f, -0.0332811f,0.997087f,0.0686255f, +12.5f,-0.942201f,-12.375f, -0.153559f,0.982185f,-0.108312f, +18.75f,0.494873f,-12.375f, 0.0753195f,0.981472f,0.176181f, +25.0f,-0.333828f,-12.375f, 0.035057f,0.987194f,0.155624f, +-25.0f,2.1862f,-18.5625f, 0.612899f,0.782306f,0.111138f, +-18.75f,-3.38259f,-18.5625f, 0.0194078f,0.992789f,-0.118297f, +-12.5f,-0.880916f,-18.5625f, -0.282251f,0.949875f,-0.13443f, +-6.25f,0.818158f,-18.5625f, 0.1476f,0.981788f,-0.119612f, +0.0f,-1.48019f,-18.5625f, -0.044551f,0.996013f,-0.0772824f, +6.25f,1.47123f,-18.5625f, -0.117036f,0.97986f,0.161792f, +12.5f,0.164076f,-18.5625f, -0.0340355f,0.978993f,0.201034f, +18.75f,2.14568f,-18.5625f, -0.0439269f,0.994859f,0.0912435f, +25.0f,0.626506f,-18.5625f, 0.208015f,0.968592f,0.136229f, +-25.0f,0.296889f,-24.75f, 0.46973f,0.844327f,-0.257809f, +-18.75f,-3.18022f,-24.75f, -0.0226758f,0.998794f,-0.0435401f, +-12.5f,1.8927f,-24.75f, -0.202772f,0.919836f,0.335836f, +-6.25f,1.46387f,-24.75f, 0.224904f,0.955746f,0.189652f, +0.0f,-2.52726f,-24.75f, -0.0435882f,0.993572f,-0.10447f, +6.25f,1.30397f,-24.75f, -0.28646f,0.956525f,-0.0547707f, +12.5f,1.85812f,-24.75f, 0.0521949f,0.979796f,0.193067f, +18.75f,1.56331f,-24.75f, -0.0270784f,0.999629f,-0.00293115f, +25.0f,1.05366f,-24.75f, 0.161f,0.986887f,-0.0115473f, +}; + +static float LargeMeshTex[] = { +0.125f,0.0f, +0.0f,0.0f, +0.125f,0.125f, +0.0f,0.125f, +0.125f,0.25f, +0.0f,0.25f, +0.125f,0.375f, +0.0f,0.375f, +0.125f,0.5f, +0.0f,0.5f, +0.125f,0.625f, +0.0f,0.625f, +0.125f,0.75f, +0.0f,0.75f, +0.125f,0.875f, +0.0f,0.875f, +0.125f,1.0f, +0.0f,1.0f, +0.25f,0.0f, +0.25f,0.125f, +0.25f,0.25f, +0.25f,0.375f, +0.25f,0.5f, +0.25f,0.625f, +0.25f,0.75f, +0.25f,0.875f, +0.25f,1.0f, +0.375f,0.0f, +0.375f,0.125f, +0.375f,0.25f, +0.375f,0.375f, +0.375f,0.5f, +0.375f,0.625f, +0.375f,0.75f, +0.375f,0.875f, +0.375f,1.0f, +0.5f,0.0f, +0.5f,0.125f, +0.5f,0.25f, +0.5f,0.375f, +0.5f,0.5f, +0.5f,0.625f, +0.5f,0.75f, +0.5f,0.875f, +0.5f,1.0f, +0.625f,0.0f, +0.625f,0.125f, +0.625f,0.25f, +0.625f,0.375f, +0.625f,0.5f, +0.625f,0.625f, +0.625f,0.75f, +0.625f,0.875f, +0.625f,1.0f, +0.75f,0.0f, +0.75f,0.125f, +0.75f,0.25f, +0.75f,0.375f, +0.75f,0.5f, +0.75f,0.625f, +0.75f,0.75f, +0.75f,0.875f, +0.75f,1.0f, +0.875f,0.0f, +0.875f,0.125f, +0.875f,0.25f, +0.875f,0.375f, +0.875f,0.5f, +0.875f,0.625f, +0.875f,0.75f, +0.875f,0.875f, +0.875f,1.0f, +1.0f,0.0f, +1.0f,0.125f, +1.0f,0.25f, +1.0f,0.375f, +1.0f,0.5f, +1.0f,0.625f, +1.0f,0.75f, +1.0f,0.875f, +1.0f,1.0f, +}; + +static unsigned short LargeMeshIdx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +18,0,19, +2,19,0, +19,2,20, +4,20,2, +20,4,21, +6,21,4, +21,6,22, +8,22,6, +22,8,23, +10,23,8, +23,10,24, +12,24,10, +24,12,25, +14,25,12, +25,14,26, +16,26,14, +27,18,28, +19,28,18, +28,19,29, +20,29,19, +29,20,30, +21,30,20, +30,21,31, +22,31,21, +31,22,32, +23,32,22, +32,23,33, +24,33,23, +33,24,34, +25,34,24, +34,25,35, +26,35,25, +36,27,37, +28,37,27, +37,28,38, +29,38,28, +38,29,39, +30,39,29, +39,30,40, +31,40,30, +40,31,41, +32,41,31, +41,32,42, +33,42,32, +42,33,43, +34,43,33, +43,34,44, +35,44,34, +45,36,46, +37,46,36, +46,37,47, +38,47,37, +47,38,48, +39,48,38, +48,39,49, +40,49,39, +49,40,50, +41,50,40, +50,41,51, +42,51,41, +51,42,52, +43,52,42, +52,43,53, +44,53,43, +54,45,55, +46,55,45, +55,46,56, +47,56,46, +56,47,57, +48,57,47, +57,48,58, +49,58,48, +58,49,59, +50,59,49, +59,50,60, +51,60,50, +60,51,61, +52,61,51, +61,52,62, +53,62,52, +63,54,64, +55,64,54, +64,55,65, +56,65,55, +65,56,66, +57,66,56, +66,57,67, +58,67,57, +67,58,68, +59,68,58, +68,59,69, +60,69,59, +69,60,70, +61,70,60, +70,61,71, +62,71,61, +72,63,73, +64,73,63, +73,64,74, +65,74,64, +74,65,75, +66,75,65, +75,66,76, +67,76,66, +76,67,77, +68,77,67, +77,68,78, +69,78,68, +78,69,79, +70,79,69, +79,70,80, +71,80,70, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/main.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/main.cpp new file mode 100644 index 000000000..63b82cded --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/main.cpp @@ -0,0 +1,448 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../common/common.h" +#include "../common/ctrl_func.h" +#include "../common/render_func.h" +#include "../common/perf_func.h" +#include "physics_func.h" +#include "barrel.h" +#include "landscape.h" + +#ifdef _WIN32 + #include + #include +#endif + +// ARA begin insert new code +#ifdef __ANDROID__ + #include + #include +#endif // __ANDROID__ +// ARA end + +#define SAMPLE_NAME "api_physics_effects/1_simple" + +static bool s_isRunning = true; + +int sceneId = 0; +bool simulating = false; + +int landscapeMeshId; +int convexMeshId; + +void render(void) +{ + render_begin(); + + for(int i=0;i -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_DOWN)) { + angX += 0.05f; + if(angX < -1.4f) angX = -1.4f; + if(angX > -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_LEFT)) { + angY -= 0.05f; + } + + if(ctrl_button_pressed(BTN_RIGHT)) { + angY += 0.05f; + } + + if(ctrl_button_pressed(BTN_ZOOM_OUT)) { + r *= 1.1f; + if(r > 500.0f) r = 500.0f; + } + + if(ctrl_button_pressed(BTN_ZOOM_IN)) { + r *= 0.9f; + if(r < 1.0f) r = 1.0f; + } + + if(ctrl_button_pressed(BTN_SCENE_RESET) == BTN_STAT_DOWN) { + physics_create_scene(sceneId); + } + + if(ctrl_button_pressed(BTN_SCENE_NEXT) == BTN_STAT_DOWN) { + physics_create_scene(++sceneId); + } + + if(ctrl_button_pressed(BTN_SIMULATION) == BTN_STAT_DOWN) { + simulating = !simulating; + } + + if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_DOWN) { + simulating = true; + } + else if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_UP || ctrl_button_pressed(BTN_STEP) == BTN_STAT_KEEP) { + simulating = false; + } + + render_set_view_angle(angX,angY,r); +} + +#ifndef _WIN32 + +// ARA begin insert new code +#ifdef __ANDROID__ + +/////////////////////////////////////////////////////////////////////////////// +// sceneChange +// +/// This function is used to change the physics scene on Android devices +/////////////////////////////////////////////////////////////////////////////// +void sceneChange() +{ + physics_create_scene(sceneId++); +} + +#else // __ANDROID__ +// ARA end + +/////////////////////////////////////////////////////////////////////////////// +// Main + +int main(void) +{ + init(); + + physics_create_scene(sceneId); + + printf("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + while (s_isRunning) { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + + shutdown(); + + printf("## %s: FINISHED ##\n", SAMPLE_NAME); + + return 0; +} + +// ARA begin insert new code +#endif // __ANDROID__ +// ARA end + +#else // _WIN32 + +/////////////////////////////////////////////////////////////////////////////// +// WinMain + +extern HDC hDC; +extern HGLRC hRC; +HWND hWnd; +HINSTANCE hInstance; + +void releaseWindow() +{ + if(hRC) { + wglMakeCurrent(0,0); + wglDeleteContext(hRC); + } + + if(hDC) ReleaseDC(hWnd,hDC); + if(hWnd) DestroyWindow(hWnd); + + UnregisterClass(SAMPLE_NAME,hInstance); +} + +LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) { + case WM_SYSCOMMAND: + { + switch (wParam) { + case SC_SCREENSAVE: + case SC_MONITORPOWER: + return 0; + } + break; + } + + case WM_CLOSE: + PostQuitMessage(0); + return 0; + + case WM_SIZE: + render_resize(LOWORD(lParam),HIWORD(lParam)); + return 0; + } + + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + +bool createWindow(char* title, int width, int height) +{ + WNDCLASS wc; + RECT rect; + rect.left=0; + rect.right=width; + rect.top=0; + rect.bottom=height; + + hInstance = GetModuleHandle(NULL); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = SAMPLE_NAME; + + if(!RegisterClass(&wc)) { + return false; + } + + AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE); + + if(!(hWnd=CreateWindowEx(WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,SAMPLE_NAME,title, + WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, + 0,0,rect.right-rect.left,rect.bottom-rect.top, + NULL,NULL,hInstance,NULL))) { + releaseWindow(); + return false; + } + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 32, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, + 0, 0, 0, 0, + 32, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + if(!(hDC=GetDC(hWnd))) + { + releaseWindow(); + OutputDebugString(""); + return FALSE; + } + + int pixelformat; + + if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){ + OutputDebugString("ChoosePixelFormat Failed...."); + return FALSE; + } + + if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE){ + OutputDebugString("SetPixelFormat Failed...."); + return FALSE; + } + + if (!(hRC=wglCreateContext(hDC))){ + OutputDebugString("Creating HGLRC Failed...."); + return FALSE; + } + + // Set Vsync + //BOOL (WINAPI *wglSwapIntervalEXT)(int) = NULL; + + //if(strstr((char*)glGetString( GL_EXTENSIONS ),"WGL_EXT_swap_control")== 0) { + //} + //else { + //wglSwapIntervalEXT = (BOOL (WINAPI*)(int))wglGetProcAddress("wglSwapIntervalEXT"); + //if(wglSwapIntervalEXT) wglSwapIntervalEXT(1); + //} + + wglMakeCurrent(hDC,hRC); + + ShowWindow(hWnd,SW_SHOW); + SetForegroundWindow(hWnd); + SetFocus(hWnd); + + render_resize(width, height); + + glClearColor(0.0f,0.0f,0.0f,0.0f); + glClearDepth(1.0f); + + return TRUE; +} + +int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) +{ + if(!createWindow(SAMPLE_NAME,DISPLAY_WIDTH,DISPLAY_HEIGHT)) { + MessageBox(NULL,"Can't create gl window.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return 0; + } + + init(); + + physics_create_scene(sceneId); + + SCE_PFX_PRINTF("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + MSG msg; + while(s_isRunning) { + if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if(msg.message==WM_QUIT) { + s_isRunning = false; + } + else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + else { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + } + + shutdown(); + + SCE_PFX_PRINTF("## %s: FINISHED ##\n", SAMPLE_NAME); + + releaseWindow(); + return (msg.wParam); +} + +#endif diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/physics_func.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/physics_func.cpp new file mode 100644 index 000000000..7954c5443 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/physics_func.cpp @@ -0,0 +1,857 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "physics_func.h" +#include "../common/perf_func.h" + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Data + +#define NUM_RIGIDBODIES 1000 +#define NUM_JOINTS 500 +#define NUM_CONTACTS 4000 + +const float timeStep = 0.016f; +const float separateBias = 0.1f; +int iteration = 5; + +//J ??????? +//E World size +PfxVector3 worldCenter(0.0f); +PfxVector3 worldExtent(500.0f); + +//J ?? +//E Rigid body +PfxRigidState states[NUM_RIGIDBODIES]; +PfxRigidBody bodies[NUM_RIGIDBODIES]; +PfxCollidable collidables[NUM_RIGIDBODIES]; +PfxSolverBody solverBodies[NUM_RIGIDBODIES]; +int numRigidBodies = 0; + +//J ????????????????? +//E Large mesh for representing a landscape +#include "landscape.h" +PfxLargeTriMesh gLargeMesh; + +//J ????? +//E Convex Mesh +#include "barrel.h" +PfxConvexMesh gConvex; + +//J ???? +//E Proxies +PfxBroadphaseProxy proxies[NUM_RIGIDBODIES]; + +//J ????? +//E Joint +PfxConstraintPair jointPairs[NUM_JOINTS]; +PfxJoint joints[NUM_JOINTS]; +int numJoints = 0; + +//J ?? +//E Pairs +unsigned int numPairs; +PfxBroadphasePair pairs[NUM_CONTACTS]; + +//J ????? +//E Contacts +PfxContactManifold contacts[NUM_CONTACTS]; +int numContacts; + +//J ?????? +//E Temporary buffers +#define POOL_BYTES (5*1024*1024) +unsigned char SCE_PFX_ALIGNED(128) poolBuff[POOL_BYTES]; + +//J ???????????????? +//E Stack allocator for temporary buffers +PfxHeapManager pool(poolBuff,POOL_BYTES); + +// ARA begin insert new code +//E task manager for parallel demo +#define NUM_THREADS 2 +PfxTaskManager *taskManager = NULL; +//E need enough bytes for NUM_THREADS PfxTaskArg objects, with the space rounded up to fill a 16-bit aligned space +#define TASK_MANAGER_POOL_BYTES 1024 +unsigned char SCE_PFX_ALIGNED(16) taskPoolBuff[TASK_MANAGER_POOL_BYTES]; +// ARA end + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Function + +int frame = 0; + +void broadphase() +{ + //J ????????????????? + //E Find the axis along which all rigid bodies are most widely positioned + int axis = 0; + { + PfxVector3 s(0.0f),s2(0.0f); + for(int i=0;i v[0]) axis = 1; + if(v[2] > v[axis]) axis = 2; + } + + //J ??????????????? + //E Create broadpahse proxies + { + for(int i=0;i 0) { + pfxReleaseLargeTriMesh(gLargeMesh); + } + + PfxInt32 ret = pfxCreateLargeTriMesh(gLargeMesh,param); + if(ret != SCE_PFX_OK) { + SCE_PFX_PRINTF("Can't create large mesh.\n"); + } + + int id = numRigidBodies++; + PfxShape shape; + shape.reset(); + shape.setLargeTriMesh(&gLargeMesh); + collidables[id].reset(); + collidables[id].addShape(shape); + collidables[id].finish(); + bodies[id].reset(); + states[id].reset(); + states[id].setPosition(PfxVector3(0.0f,-5.0f,0.0f)); + states[id].setOrientation(PfxQuat::rotationX(0.5f)*PfxQuat::rotationY(0.7f)); + states[id].setMotionType(kPfxMotionTypeFixed); + states[id].setRigidBodyId(id); +} + +void physics_create_scene(int sceneId) +{ + const int numScenes = 4; + int sid = sceneId % numScenes; + + numRigidBodies= 0; + numPairs = 0; + numContacts = 0; + numJoints = 0; + frame = 0; + + switch(sid) { + case 0: // simple primitives + createSceneBoxGround(); + createScenePrimitives(); + break; + + case 1: // joints + createSceneBoxGround(); + createSceneJoints(); + break; + + case 2: // stacking + createSceneBoxGround(); + createSceneStacking(); + break; + + case 3: // landscape + createSceneLandscape(); + createScenePrimitives(); + break; + } + + SCE_PFX_PRINTF("----- Size of rigid body buffer ------\n"); + SCE_PFX_PRINTF(" size * num = total\n"); + SCE_PFX_PRINTF("PfxRigidState %5d * %5d = %5d bytes\n",sizeof(PfxRigidState),numRigidBodies,sizeof(PfxRigidState)*numRigidBodies); + SCE_PFX_PRINTF("PfxRigidBody %5d * %5d = %5d bytes\n",sizeof(PfxRigidBody),numRigidBodies,sizeof(PfxRigidBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxCollidable %5d * %5d = %5d bytes\n",sizeof(PfxCollidable),numRigidBodies,sizeof(PfxCollidable)*numRigidBodies); + SCE_PFX_PRINTF("PfxJoint %5d * %5d = %5d bytes\n",sizeof(PfxJoint),numJoints,sizeof(PfxJoint)*numJoints); + SCE_PFX_PRINTF("PfxSolverBody %5d * %5d = %5d bytes\n",sizeof(PfxSolverBody),numRigidBodies,sizeof(PfxSolverBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxBroadphaseProxy %5d * %5d = %5d bytes\n",sizeof(PfxBroadphaseProxy),numRigidBodies,sizeof(PfxBroadphaseProxy)*numRigidBodies); + SCE_PFX_PRINTF("PfxContactManifold %5d * %5d = %5d bytes\n",sizeof(PfxContactManifold),NUM_CONTACTS,sizeof(PfxContactManifold)*NUM_CONTACTS); + SCE_PFX_PRINTF("PfxBroadphasePair %5d * %5d = %5d bytes\n",sizeof(PfxBroadphasePair),NUM_CONTACTS,sizeof(PfxBroadphasePair)*NUM_CONTACTS); + + int totalBytes = + (sizeof(PfxRigidState) + sizeof(PfxRigidBody) + sizeof(PfxCollidable) + sizeof(PfxSolverBody) + sizeof(PfxBroadphaseProxy)) * numRigidBodies + + (sizeof(PfxContactManifold) + sizeof(PfxBroadphasePair)) * NUM_CONTACTS; + SCE_PFX_PRINTF("----------------------------------------------------------\n"); + SCE_PFX_PRINTF("Total %5d bytes\n",totalBytes); + +// ARA begin insert new code +#ifdef USE_PTHREADS + if (!taskManager) + { + taskManager = PfxCreateTaskManagerPthreads(NUM_THREADS, NUM_THREADS, taskPoolBuff, TASK_MANAGER_POOL_BYTES); + taskManager->initialize(); + } +#endif +// ARA end +} + +/////////////////////////////////////////////////////////////////////////////// +// Initialize / Finalize Engine + +bool physics_init() +{ + return true; +} + +void physics_release() +{ +// ARA begin insert new code + if (taskManager) + taskManager->finalize(); +// ARA end +} + +/////////////////////////////////////////////////////////////////////////////// +// Pick + +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2) +{ + return PfxVector3(0.0f); +} + +void physics_pick_update(const PfxVector3 &p) +{ +} + +void physics_pick_end() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Get Information + +int physics_get_num_rigidbodies() +{ + return numRigidBodies; +} + +const PfxRigidState& physics_get_state(int id) +{ + return states[id]; +} + +const PfxRigidBody& physics_get_body(int id) +{ + return bodies[id]; +} + +const PfxCollidable& physics_get_collidable(int id) +{ + return collidables[id]; +} + +int physics_get_num_contacts() +{ + return numPairs; +} + +const PfxContactManifold &physics_get_contact(int id) +{ + return contacts[pfxGetConstraintId(pairs[id])]; +} + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/physics_func.h b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/physics_func.h new file mode 100644 index 000000000..0a6d2fe78 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/1_simple_parallel/physics_func.h @@ -0,0 +1,49 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef __PHYSICS_FUNC_H__ +#define __PHYSICS_FUNC_H__ + +#define SCE_PFX_USE_PERFCOUNTER + +#include "physics_effects.h" + +using namespace sce::PhysicsEffects; + +//E Simulation +//J ???????? +bool physics_init(); +void physics_release(); +void physics_create_scene(int sceneId); +void physics_simulate(); + +//E Picking +//J ????? +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2); +void physics_pick_update(const PfxVector3 &p); +void physics_pick_end(); + +//E Change parameters +//J ???????? +int physics_get_num_rigidbodies(); +const PfxRigidState& physics_get_state(int id); +const PfxRigidBody& physics_get_body(int id); +const PfxCollidable& physics_get_collidable(int id); + +int physics_get_num_contacts(); +const PfxContactManifold &physics_get_contact(int id); + +#endif /* __PHYSICS_FUNC_H__ */ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/2_stable.winsows.vcproj b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/2_stable.winsows.vcproj new file mode 100644 index 000000000..791d0d6c4 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/2_stable.winsows.vcproj @@ -0,0 +1,713 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/CMakeLists.txt b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/CMakeLists.txt new file mode 100644 index 000000000..61076def8 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/CMakeLists.txt @@ -0,0 +1,77 @@ +cmake_minimum_required(VERSION 2.4) + + +#this line has to appear before 'PROJECT' in order to be able to disable incremental linking +SET(MSVC_INCREMENTAL_DEFAULT ON) + +PROJECT(App_2_Stable) + + +IF (NOT CMAKE_BUILD_TYPE) +# SET(CMAKE_BUILD_TYPE "Debug") + SET(CMAKE_BUILD_TYPE "Release") +ENDIF (NOT CMAKE_BUILD_TYPE) + + +OPTION(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC Runtime Library DLL (/MD or /MDd)" ON) +OPTION(USE_MSVC_INCREMENTAL_LINKING "Use MSVC Incremental Linking" OFF) + + +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + + +SET(App_2_Stable_SRCS + main.cpp + physics_func.cpp + ../common/ctrl_func.win32.cpp + ../common/perf_func.win32.cpp + ../common/render_func.win32.cpp +) + + +SET(App_2_Stable_HDRS + physics_func.h + landscape.h + barrel.h + ../common/render_func.h + ../common/common.h + ../common/ctrl_func.h + ../common/perf_func.h +) + + +INCLUDE_DIRECTORIES( + ${PHYSICS_EFFECTS_SOURCE_DIR}/include +# ${VECTOR_MATH_INCLUDE} +) + +#LINK_DIRECTORIES( +# +#) + +#ADD_DEFINITIONS(-DUNICODE) +#ADD_DEFINITIONS(-D_UNICODE) + +ADD_EXECUTABLE(App_2_Stable WIN32 + ${App_2_Stable_SRCS} + ${App_2_Stable_HDRS} +) +TARGET_LINK_LIBRARIES(App_2_Stable + PfxBaseLevel + PfxLowLevel + PfxUtil + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} +) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(App_2_Stable PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(App_2_Stable PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(App_2_Stable PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF() + + + + \ No newline at end of file diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/barrel.h b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/barrel.h new file mode 100644 index 000000000..6574fa862 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/barrel.h @@ -0,0 +1,202 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define BarrelVtxCount 57 +#define BarrelIdxCount 180 + +static float BarrelVtx[] = { +0.0f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +-0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +0.0f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +-0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.957307f,-0.289072f,0.0f, +0.404509f,0.0f,-0.293893f, 0.809017f,0.0f,-0.587785f, +0.5f,0.0f,0.0f, 1.0f,0.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.774478f,-0.289072f,-0.562691f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +-0.154509f,0.0f,-0.475528f, -0.309017f,0.0f,-0.951057f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +-0.107853f,-0.5f,-0.331936f, -0.295824f,-0.289072f,-0.910453f, +-0.404509f,0.0f,-0.293893f, -0.809017f,0.0f,-0.587785f, +-0.282362f,-0.5f,-0.205148f, -0.774478f,-0.289072f,-0.562691f, +-0.5f,0.0f,0.0f, -1.0f,0.0f,0.0f, +-0.349018f,-0.5f,0.0f, -0.957307f,-0.289072f,0.0f, +-0.404508f,0.0f,0.293893f, -0.809017f,0.0f,0.587785f, +-0.282362f,-0.5f,0.205148f, -0.774478f,-0.289072f,0.562691f, +-0.154509f,0.0f,0.475528f, -0.309017f,0.0f,0.951056f, +-0.107853f,-0.5f,0.331936f, -0.295824f,-0.289072f,0.910453f, +0.154509f,0.0f,0.475528f, 0.309017f,0.0f,0.951056f, +0.107853f,-0.5f,0.331936f, 0.295824f,-0.289072f,0.910453f, +0.404509f,0.0f,0.293892f, 0.809017f,0.0f,0.587785f, +0.282362f,-0.5f,0.205148f, 0.774478f,-0.289072f,0.562691f, +0.282362f,0.5f,-0.205148f, 0.774478f,0.289072f,-0.562691f, +0.349018f,0.5f,0.0f, 0.957307f,0.289072f,0.0f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.107853f,0.5f,-0.331936f, -0.295824f,0.289072f,-0.910453f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.282362f,0.5f,-0.205148f, -0.774478f,0.289072f,-0.562691f, +-0.349018f,0.5f,0.0f, -0.957307f,0.289072f,0.0f, +-0.282362f,0.5f,0.205148f, -0.774478f,0.289072f,0.562691f, +-0.107853f,0.5f,0.331936f, -0.295824f,0.289072f,0.910453f, +0.107853f,0.5f,0.331936f, 0.295824f,0.289072f,0.910453f, +0.282362f,0.5f,0.205148f, 0.774478f,0.289072f,0.562691f, +}; + +static float BarrelTex[] = { +0.0f,0.5f, +0.0f,0.85f, +0.0f,0.75f, +0.0f,0.95f, +0.0f,0.05f, +0.0f,-0.05f, +0.0f,0.15f, +0.0f,0.25f, +0.0f,0.35f, +0.0f,0.45f, +0.0f,0.55f, +0.0f,0.65f, +1.0f,0.5f, +1.0f,0.75f, +1.0f,0.85f, +1.0f,0.95f, +1.0f,-0.05f, +1.0f,0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +0.0f,0.75f, +0.5f,0.85f, +0.5f,0.75f, +0.0f,0.85f, +0.5f,0.95f, +0.0f,0.95f, +0.0f,-0.05f, +0.5f,0.05f, +0.5f,-0.05f, +0.0f,0.05f, +0.5f,0.15f, +0.0f,0.15f, +0.5f,0.25f, +0.0f,0.25f, +0.5f,0.35f, +0.0f,0.35f, +0.5f,0.45f, +0.0f,0.45f, +0.5f,0.55f, +0.0f,0.55f, +0.5f,0.65f, +0.0f,0.65f, +1.0f,0.85f, +1.0f,0.75f, +1.0f,0.95f, +1.0f,0.05f, +1.0f,-0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +}; + +static unsigned short BarrelIdx[] = { +0,1,2, +0,3,1, +0,4,5, +0,6,4, +0,7,6, +0,8,7, +0,9,8, +0,10,9, +0,11,10, +0,2,11, +12,13,14, +12,14,15, +12,16,17, +12,17,18, +12,18,19, +12,19,20, +12,20,21, +12,21,22, +12,22,23, +12,23,13, +24,25,26, +24,27,25, +27,28,25, +27,29,28, +30,31,32, +30,33,31, +33,34,31, +33,35,34, +35,36,34, +35,37,36, +37,38,36, +37,39,38, +39,40,38, +39,41,40, +41,42,40, +41,43,42, +43,44,42, +43,45,44, +45,26,44, +45,24,26, +26,46,47, +26,25,46, +25,48,46, +25,28,48, +32,49,50, +32,31,49, +31,51,49, +31,34,51, +34,52,51, +34,36,52, +36,53,52, +36,38,53, +38,54,53, +38,40,54, +40,55,54, +40,42,55, +42,56,55, +42,44,56, +44,47,56, +44,26,47, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/landscape.h b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/landscape.h new file mode 100644 index 000000000..00f6cffd2 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/landscape.h @@ -0,0 +1,318 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define LargeMeshVtxCount 81 +#define LargeMeshIdxCount 384 + +static float LargeMeshVtx[] = { +-25.0f,-2.19407f,18.5625f, 0.232976f,0.967754f,0.0957829f, +-25.0f,0.0644502f,24.75f, 0.188094f,0.871343f,-0.45319f, +-18.75f,-4.50287f,18.5625f, -0.0716098f,0.995449f,0.0628767f, +-18.75f,-0.39999f,24.75f, -0.0602794f,0.895848f,-0.440253f, +-12.5f,-1.2166f,18.5625f, -0.269469f,0.961403f,0.0555879f, +-12.5f,-0.942431f,24.75f, -0.0997841f,0.993258f,0.0589987f, +-6.25f,1.93598f,18.5625f, -0.283933f,0.956351f,-0.0691025f, +-6.25f,-0.445954f,24.75f, -0.180725f,0.942766f,0.280233f, +0.0f,2.76983f,18.5625f, 0.171645f,0.984908f,0.0222501f, +0.0f,2.76642f,24.75f, 0.0784993f,0.995428f,-0.0544117f, +6.25f,-2.53736f,18.5625f, 0.248298f,0.965028f,0.0840741f, +6.25f,-0.915645f,24.75f, 0.164311f,0.945856f,-0.279926f, +12.5f,-1.60054f,18.5625f, -0.180435f,0.983586f,0.00115547f, +12.5f,0.831925f,24.75f, -0.0692495f,0.964821f,-0.253623f, +18.75f,-0.800282f,18.5625f, 0.10755f,0.951538f,0.288112f, +18.75f,-1.47284f,24.75f, 0.232178f,0.972664f,0.00429361f, +25.0f,-2.78379f,18.5625f, 0.1833f,0.937477f,0.295867f, +25.0f,-0.967508f,24.75f, -0.0773477f,0.956641f,-0.280812f, +-25.0f,-0.352038f,12.375f, -0.192222f,0.972435f,0.131987f, +-18.75f,0.681228f,12.375f, -0.107779f,0.962569f,0.248686f, +-12.5f,2.72065f,12.375f, 0.0520846f,0.993034f,0.105692f, +-6.25f,-1.78776f,12.375f, -0.0133223f,0.99674f,-0.0795754f, +0.0f,1.57707f,12.375f, -0.129025f,0.969662f,-0.207627f, +6.25f,0.424356f,12.375f, 0.180995f,0.97074f,0.157815f, +12.5f,0.283234f,12.375f, -0.16285f,0.973539f,0.160316f, +18.75f,2.57015f,12.375f, -0.165454f,0.978339f,0.124408f, +25.0f,3.07363f,12.375f, -0.00454559f,0.988151f,0.153417f, +-25.0f,-0.893751f,6.1875f, -0.0836251f,0.990084f,-0.112876f, +-18.75f,0.930932f,6.1875f, 0.00269413f,0.971838f,-0.235633f, +-12.5f,-0.684529f,6.1875f, -0.010319f,0.927048f,-0.3748f, +-6.25f,-0.661383f,6.1875f, 0.012265f,0.999875f,-0.00994222f, +0.0f,0.385718f,6.1875f, -0.15435f,0.984937f,-0.0779465f, +6.25f,0.589796f,6.1875f, 0.0241717f,0.999582f,-0.0158589f, +12.5f,0.47454f,6.1875f, -0.017184f,0.997953f,-0.0616073f, +18.75f,1.59939f,6.1875f, -0.0902706f,0.957309f,-0.274609f, +25.0f,1.13434f,6.1875f, 0.0346006f,0.957441f,-0.286547f, +-25.0f,0.74548f,0.0f, 0.329903f,0.930812f,0.157334f, +-18.75f,-2.47437f,0.0f, 0.247844f,0.968142f,0.0357041f, +-12.5f,-4.16309f,1.81975e-007f, -0.0623898f,0.997626f,-0.0291436f, +-6.25f,-0.700022f,0.0f, -0.217067f,0.974987f,-0.0477624f, +0.0f,-0.0957388f,0.0f, -0.117693f,0.990712f,-0.068098f, +6.25f,0.614077f,0.0f, -0.0713214f,0.997305f,0.01722f, +12.5f,0.299109f,0.0f, 0.218606f,0.968641f,0.118094f, +18.75f,-1.71753f,0.0f, 0.0339493f,0.985612f,-0.165579f, +25.0f,-1.12638f,0.0f, -0.0547573f,0.989177f,-0.136126f, +-25.0f,-0.403319f,-6.1875f, -0.1263f,0.989211f,-0.074223f, +-18.75f,-0.0730335f,-6.1875f, 0.0173428f,0.965382f,0.260261f, +-12.5f,-0.450125f,-6.1875f, 0.0658811f,0.875f,0.479619f, +-6.25f,-0.180204f,-6.1875f, 0.0116584f,0.981445f,0.19139f, +0.0f,-0.632679f,-6.1875f, -0.0557983f,0.993041f,-0.103716f, +6.25f,0.308409f,-6.1875f, -0.191898f,0.96766f,-0.163737f, +12.5f,2.5011f,-6.1875f, 0.0758397f,0.996403f,-0.0378189f, +18.75f,-1.69303f,-6.1875f, 0.16761f,0.974057f,0.15205f, +25.0f,-0.141349f,-6.1875f, -0.204846f,0.978471f,0.0251341f, +-25.0f,-1.10316f,-12.375f, -0.0350644f,0.993748f,-0.106001f, +-18.75f,1.06711f,-12.375f, -0.309806f,0.919244f,-0.242922f, +-12.5f,3.61544f,-12.375f, -0.0506281f,0.998702f,-0.00561657f, +-6.25f,1.6504f,-12.375f, 0.322294f,0.937465f,0.131477f, +0.0f,-1.60595f,-12.375f, 0.086016f,0.995916f,0.0274459f, +6.25f,-0.849859f,-12.375f, -0.0332811f,0.997087f,0.0686255f, +12.5f,-0.942201f,-12.375f, -0.153559f,0.982185f,-0.108312f, +18.75f,0.494873f,-12.375f, 0.0753195f,0.981472f,0.176181f, +25.0f,-0.333828f,-12.375f, 0.035057f,0.987194f,0.155624f, +-25.0f,2.1862f,-18.5625f, 0.612899f,0.782306f,0.111138f, +-18.75f,-3.38259f,-18.5625f, 0.0194078f,0.992789f,-0.118297f, +-12.5f,-0.880916f,-18.5625f, -0.282251f,0.949875f,-0.13443f, +-6.25f,0.818158f,-18.5625f, 0.1476f,0.981788f,-0.119612f, +0.0f,-1.48019f,-18.5625f, -0.044551f,0.996013f,-0.0772824f, +6.25f,1.47123f,-18.5625f, -0.117036f,0.97986f,0.161792f, +12.5f,0.164076f,-18.5625f, -0.0340355f,0.978993f,0.201034f, +18.75f,2.14568f,-18.5625f, -0.0439269f,0.994859f,0.0912435f, +25.0f,0.626506f,-18.5625f, 0.208015f,0.968592f,0.136229f, +-25.0f,0.296889f,-24.75f, 0.46973f,0.844327f,-0.257809f, +-18.75f,-3.18022f,-24.75f, -0.0226758f,0.998794f,-0.0435401f, +-12.5f,1.8927f,-24.75f, -0.202772f,0.919836f,0.335836f, +-6.25f,1.46387f,-24.75f, 0.224904f,0.955746f,0.189652f, +0.0f,-2.52726f,-24.75f, -0.0435882f,0.993572f,-0.10447f, +6.25f,1.30397f,-24.75f, -0.28646f,0.956525f,-0.0547707f, +12.5f,1.85812f,-24.75f, 0.0521949f,0.979796f,0.193067f, +18.75f,1.56331f,-24.75f, -0.0270784f,0.999629f,-0.00293115f, +25.0f,1.05366f,-24.75f, 0.161f,0.986887f,-0.0115473f, +}; + +static float LargeMeshTex[] = { +0.125f,0.0f, +0.0f,0.0f, +0.125f,0.125f, +0.0f,0.125f, +0.125f,0.25f, +0.0f,0.25f, +0.125f,0.375f, +0.0f,0.375f, +0.125f,0.5f, +0.0f,0.5f, +0.125f,0.625f, +0.0f,0.625f, +0.125f,0.75f, +0.0f,0.75f, +0.125f,0.875f, +0.0f,0.875f, +0.125f,1.0f, +0.0f,1.0f, +0.25f,0.0f, +0.25f,0.125f, +0.25f,0.25f, +0.25f,0.375f, +0.25f,0.5f, +0.25f,0.625f, +0.25f,0.75f, +0.25f,0.875f, +0.25f,1.0f, +0.375f,0.0f, +0.375f,0.125f, +0.375f,0.25f, +0.375f,0.375f, +0.375f,0.5f, +0.375f,0.625f, +0.375f,0.75f, +0.375f,0.875f, +0.375f,1.0f, +0.5f,0.0f, +0.5f,0.125f, +0.5f,0.25f, +0.5f,0.375f, +0.5f,0.5f, +0.5f,0.625f, +0.5f,0.75f, +0.5f,0.875f, +0.5f,1.0f, +0.625f,0.0f, +0.625f,0.125f, +0.625f,0.25f, +0.625f,0.375f, +0.625f,0.5f, +0.625f,0.625f, +0.625f,0.75f, +0.625f,0.875f, +0.625f,1.0f, +0.75f,0.0f, +0.75f,0.125f, +0.75f,0.25f, +0.75f,0.375f, +0.75f,0.5f, +0.75f,0.625f, +0.75f,0.75f, +0.75f,0.875f, +0.75f,1.0f, +0.875f,0.0f, +0.875f,0.125f, +0.875f,0.25f, +0.875f,0.375f, +0.875f,0.5f, +0.875f,0.625f, +0.875f,0.75f, +0.875f,0.875f, +0.875f,1.0f, +1.0f,0.0f, +1.0f,0.125f, +1.0f,0.25f, +1.0f,0.375f, +1.0f,0.5f, +1.0f,0.625f, +1.0f,0.75f, +1.0f,0.875f, +1.0f,1.0f, +}; + +static unsigned short LargeMeshIdx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +18,0,19, +2,19,0, +19,2,20, +4,20,2, +20,4,21, +6,21,4, +21,6,22, +8,22,6, +22,8,23, +10,23,8, +23,10,24, +12,24,10, +24,12,25, +14,25,12, +25,14,26, +16,26,14, +27,18,28, +19,28,18, +28,19,29, +20,29,19, +29,20,30, +21,30,20, +30,21,31, +22,31,21, +31,22,32, +23,32,22, +32,23,33, +24,33,23, +33,24,34, +25,34,24, +34,25,35, +26,35,25, +36,27,37, +28,37,27, +37,28,38, +29,38,28, +38,29,39, +30,39,29, +39,30,40, +31,40,30, +40,31,41, +32,41,31, +41,32,42, +33,42,32, +42,33,43, +34,43,33, +43,34,44, +35,44,34, +45,36,46, +37,46,36, +46,37,47, +38,47,37, +47,38,48, +39,48,38, +48,39,49, +40,49,39, +49,40,50, +41,50,40, +50,41,51, +42,51,41, +51,42,52, +43,52,42, +52,43,53, +44,53,43, +54,45,55, +46,55,45, +55,46,56, +47,56,46, +56,47,57, +48,57,47, +57,48,58, +49,58,48, +58,49,59, +50,59,49, +59,50,60, +51,60,50, +60,51,61, +52,61,51, +61,52,62, +53,62,52, +63,54,64, +55,64,54, +64,55,65, +56,65,55, +65,56,66, +57,66,56, +66,57,67, +58,67,57, +67,58,68, +59,68,58, +68,59,69, +60,69,59, +69,60,70, +61,70,60, +70,61,71, +62,71,61, +72,63,73, +64,73,63, +73,64,74, +65,74,64, +74,65,75, +66,75,65, +75,66,76, +67,76,66, +76,67,77, +68,77,67, +77,68,78, +69,78,68, +78,69,79, +70,79,69, +79,70,80, +71,80,70, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/main.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/main.cpp new file mode 100644 index 000000000..e005c870e --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/main.cpp @@ -0,0 +1,448 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../common/common.h" +#include "../common/ctrl_func.h" +#include "../common/render_func.h" +#include "../common/perf_func.h" +#include "physics_func.h" +#include "barrel.h" +#include "landscape.h" + +#ifdef _WIN32 + #include + #include +#endif + +// ARA begin insert new code +#ifdef __ANDROID__ + #include + #include +#endif +// ARA end + +#define SAMPLE_NAME "api_physics_effects/2_stable" + +static bool s_isRunning = true; + +int sceneId = 2; +bool simulating = false; + +int landscapeMeshId; +int convexMeshId; + +void render(void) +{ + render_begin(); + + for(int i=0;i -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_DOWN)) { + angX += 0.05f; + if(angX < -1.4f) angX = -1.4f; + if(angX > -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_LEFT)) { + angY -= 0.05f; + } + + if(ctrl_button_pressed(BTN_RIGHT)) { + angY += 0.05f; + } + + if(ctrl_button_pressed(BTN_ZOOM_OUT)) { + r *= 1.1f; + if(r > 500.0f) r = 500.0f; + } + + if(ctrl_button_pressed(BTN_ZOOM_IN)) { + r *= 0.9f; + if(r < 1.0f) r = 1.0f; + } + + if(ctrl_button_pressed(BTN_SCENE_RESET) == BTN_STAT_DOWN) { + physics_create_scene(sceneId); + } + + if(ctrl_button_pressed(BTN_SCENE_NEXT) == BTN_STAT_DOWN) { + physics_create_scene(++sceneId); + } + + if(ctrl_button_pressed(BTN_SIMULATION) == BTN_STAT_DOWN) { + simulating = !simulating; + } + + if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_DOWN) { + simulating = true; + } + else if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_UP || ctrl_button_pressed(BTN_STEP) == BTN_STAT_KEEP) { + simulating = false; + } + + render_set_view_angle(angX,angY,r); +} + +#ifndef _WIN32 + +// ARA begin insert new code +#ifdef __ANDROID__ + +/////////////////////////////////////////////////////////////////////////////// +// sceneChange +// +/// This function is used to change the physics scene on Android devices +/////////////////////////////////////////////////////////////////////////////// +void sceneChange() +{ + physics_create_scene(sceneId++); +} + +#else // __ANDROID__ +// ARA end + +/////////////////////////////////////////////////////////////////////////////// +// Main + +int main(void) +{ + init(); + + physics_create_scene(sceneId); + + printf("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + while (s_isRunning) { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + + shutdown(); + + printf("## %s: FINISHED ##\n", SAMPLE_NAME); + + return 0; +} + +// ARA begin insert new code +#endif // __ANDROID__ +// ARA end + +#else // _WIN32 + +/////////////////////////////////////////////////////////////////////////////// +// WinMain + +extern HDC hDC; +extern HGLRC hRC; +HWND hWnd; +HINSTANCE hInstance; + +void releaseWindow() +{ + if(hRC) { + wglMakeCurrent(0,0); + wglDeleteContext(hRC); + } + + if(hDC) ReleaseDC(hWnd,hDC); + if(hWnd) DestroyWindow(hWnd); + + UnregisterClass(SAMPLE_NAME,hInstance); +} + +LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) { + case WM_SYSCOMMAND: + { + switch (wParam) { + case SC_SCREENSAVE: + case SC_MONITORPOWER: + return 0; + } + break; + } + + case WM_CLOSE: + PostQuitMessage(0); + return 0; + + case WM_SIZE: + render_resize(LOWORD(lParam),HIWORD(lParam)); + return 0; + } + + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + +bool createWindow(char* title, int width, int height) +{ + WNDCLASS wc; + RECT rect; + rect.left=0; + rect.right=width; + rect.top=0; + rect.bottom=height; + + hInstance = GetModuleHandle(NULL); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = SAMPLE_NAME; + + if(!RegisterClass(&wc)) { + return false; + } + + AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE); + + if(!(hWnd=CreateWindowEx(WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,SAMPLE_NAME,title, + WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, + 0,0,rect.right-rect.left,rect.bottom-rect.top, + NULL,NULL,hInstance,NULL))) { + releaseWindow(); + return false; + } + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 32, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, + 0, 0, 0, 0, + 32, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + if(!(hDC=GetDC(hWnd))) + { + releaseWindow(); + OutputDebugString(""); + return FALSE; + } + + int pixelformat; + + if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){ + OutputDebugString("ChoosePixelFormat Failed...."); + return FALSE; + } + + if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE){ + OutputDebugString("SetPixelFormat Failed...."); + return FALSE; + } + + if (!(hRC=wglCreateContext(hDC))){ + OutputDebugString("Creating HGLRC Failed...."); + return FALSE; + } + + // Set Vsync + //BOOL (WINAPI *wglSwapIntervalEXT)(int) = NULL; + + //if(strstr((char*)glGetString( GL_EXTENSIONS ),"WGL_EXT_swap_control")== 0) { + //} + //else { + //wglSwapIntervalEXT = (BOOL (WINAPI*)(int))wglGetProcAddress("wglSwapIntervalEXT"); + //if(wglSwapIntervalEXT) wglSwapIntervalEXT(1); + //} + + wglMakeCurrent(hDC,hRC); + + ShowWindow(hWnd,SW_SHOW); + SetForegroundWindow(hWnd); + SetFocus(hWnd); + + render_resize(width, height); + + glClearColor(0.0f,0.0f,0.0f,0.0f); + glClearDepth(1.0f); + + return TRUE; +} + +int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) +{ + if(!createWindow(SAMPLE_NAME,DISPLAY_WIDTH,DISPLAY_HEIGHT)) { + MessageBox(NULL,"Can't create gl window.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return 0; + } + + init(); + + physics_create_scene(sceneId); + + SCE_PFX_PRINTF("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + MSG msg; + while(s_isRunning) { + if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if(msg.message==WM_QUIT) { + s_isRunning = false; + } + else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + else { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + } + + shutdown(); + + SCE_PFX_PRINTF("## %s: FINISHED ##\n", SAMPLE_NAME); + + releaseWindow(); + return (msg.wParam); +} + +#endif diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/physics.png b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/physics.png new file mode 100644 index 000000000..483e6e806 Binary files /dev/null and b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/physics.png differ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/physics_func.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/physics_func.cpp new file mode 100644 index 000000000..7ed69e9da --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/physics_func.cpp @@ -0,0 +1,869 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "physics_func.h" +#include "../common/perf_func.h" + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Data + +#define NUM_RIGIDBODIES 5000 +#define NUM_JOINTS 5000 +#define NUM_CONTACTS 4000 + +const float timeStep = 0.016f; +const float separateBias = 0.1f; +int iteration = 5; + +//J ワールドサイズ +//E World size +PfxVector3 worldCenter(0.0f); +PfxVector3 worldExtent(500.0f); + +//J 剛体 +//E Rigid body +PfxRigidState states[NUM_RIGIDBODIES]; +PfxRigidBody bodies[NUM_RIGIDBODIES]; +PfxCollidable collidables[NUM_RIGIDBODIES]; +PfxSolverBody solverBodies[NUM_RIGIDBODIES]; +int numRigidBodies = 0; + +//J 地形を表現するためのラージメッシュ +//E Large mesh for representing a landscape +#include "landscape.h" +PfxLargeTriMesh gLargeMesh; + +//J 凸メッシュ +//E Convex Mesh +#include "barrel.h" +PfxConvexMesh gConvex; + +//J プロキシ +//E Proxies +PfxBroadphaseProxy proxies[NUM_RIGIDBODIES]; + +//J ジョイント +//E Joint +PfxConstraintPair jointPairs[NUM_JOINTS]; +PfxJoint joints[NUM_JOINTS]; +int numJoints = 0; + +//J ペア +//E Pairs +unsigned int pairSwap; +unsigned int numPairs[2]; +PfxBroadphasePair pairsBuff[2][NUM_CONTACTS]; + +//J コンタクト +//E Contacts +PfxContactManifold contacts[NUM_CONTACTS]; +int numContacts; + +PfxUInt32 contactIdPool[NUM_CONTACTS]; +int numContactIdPool; + +//J 一時バッファ +//E Temporary buffers +#define POOL_BYTES (5*1024*1024) +unsigned char SCE_PFX_ALIGNED(128) poolBuff[POOL_BYTES]; + +//J 一時バッファ用スタックアロケータ +//E Stack allocator for temporary buffers +PfxHeapManager pool(poolBuff,POOL_BYTES); + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Function + +int frame = 0; + +void broadphase() +{ + pairSwap = 1-pairSwap; + + unsigned int &numPreviousPairs = numPairs[1-pairSwap]; + unsigned int &numCurrentPairs = numPairs[pairSwap]; + PfxBroadphasePair *previousPairs = pairsBuff[1-pairSwap]; + PfxBroadphasePair *currentPairs = pairsBuff[pairSwap]; + + //J 剛体が最も分散している軸を見つける + //E Find the axis along which all rigid bodies are most widely positioned + int axis = 0; + { + PfxVector3 s(0.0f),s2(0.0f); + for(int i=0;i v[0]) axis = 1; + if(v[2] > v[axis]) axis = 2; + } + + //J ブロードフェーズプロキシの更新 + //E Create broadpahse proxies + { + for(int i=0;i 0) { + cId = contactIdPool[--numContactIdPool]; + } + else { + cId = numContacts++; + } + if(cId >= NUM_CONTACTS) { + cId = 0; + } + SCE_PFX_ASSERT(cId < NUM_CONTACTS); + pfxSetContactId(outNewPairs[i],cId); + PfxContactManifold &contact = contacts[cId]; + contact.reset(pfxGetObjectIdA(outNewPairs[i]),pfxGetObjectIdB(outNewPairs[i])); + } + + //J 新規ペアと維持ペアを合成 + //E Merge 'new' and 'keep' pairs + numCurrentPairs = 0; + for(PfxUInt32 i=0;i 0) { + pfxReleaseLargeTriMesh(gLargeMesh); + } + + PfxInt32 ret = pfxCreateLargeTriMesh(gLargeMesh,param); + if(ret != SCE_PFX_OK) { + SCE_PFX_PRINTF("Can't create large mesh.\n"); + } + + int id = numRigidBodies++; + PfxShape shape; + shape.reset(); + shape.setLargeTriMesh(&gLargeMesh); + collidables[id].reset(); + collidables[id].addShape(shape); + collidables[id].finish(); + bodies[id].reset(); + states[id].reset(); + states[id].setPosition(PfxVector3(0.0f,-5.0f,0.0f)); + states[id].setOrientation(PfxQuat::rotationX(0.5f)*PfxQuat::rotationY(0.7f)); + states[id].setMotionType(kPfxMotionTypeFixed); + states[id].setRigidBodyId(id); +} + +void physics_create_scene(int sceneId) +{ + const int numScenes = 4; + int sid = sceneId % numScenes; + + numRigidBodies= 0; + pairSwap = 0; + numPairs[0] = 0; + numPairs[1] = 0; + numContacts = 0; + numContactIdPool = 0; + numJoints = 0; + frame = 0; + + switch(sid) { + case 0: // simple primitives + createSceneBoxGround(); + createScenePrimitives(); + break; + + case 1: // joints + createSceneBoxGround(); + createSceneJoints(); + break; + + case 2: // stacking + createSceneBoxGround(); + createSceneStacking(); + break; + + case 3: // landscape + createSceneLandscape(); + createScenePrimitives(); + break; + } + + SCE_PFX_PRINTF("----- Size of rigid body buffer ------\n"); + SCE_PFX_PRINTF(" size * num = total\n"); + SCE_PFX_PRINTF("PfxRigidState %5d * %5d = %5d bytes\n",sizeof(PfxRigidState),numRigidBodies,sizeof(PfxRigidState)*numRigidBodies); + SCE_PFX_PRINTF("PfxRigidBody %5d * %5d = %5d bytes\n",sizeof(PfxRigidBody),numRigidBodies,sizeof(PfxRigidBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxCollidable %5d * %5d = %5d bytes\n",sizeof(PfxCollidable),numRigidBodies,sizeof(PfxCollidable)*numRigidBodies); + SCE_PFX_PRINTF("PfxJoint %5d * %5d = %5d bytes\n",sizeof(PfxJoint),numJoints,sizeof(PfxJoint)*numJoints); + SCE_PFX_PRINTF("PfxSolverBody %5d * %5d = %5d bytes\n",sizeof(PfxSolverBody),numRigidBodies,sizeof(PfxSolverBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxBroadphaseProxy %5d * %5d = %5d bytes\n",sizeof(PfxBroadphaseProxy),numRigidBodies,sizeof(PfxBroadphaseProxy)*numRigidBodies); + SCE_PFX_PRINTF("PfxContactManifold %5d * %5d = %5d bytes\n",sizeof(PfxContactManifold),NUM_CONTACTS,sizeof(PfxContactManifold)*NUM_CONTACTS); + SCE_PFX_PRINTF("PfxBroadphasePair %5d * %5d = %5d bytes\n",sizeof(PfxBroadphasePair),NUM_CONTACTS,sizeof(PfxBroadphasePair)*NUM_CONTACTS); + + int totalBytes = + (sizeof(PfxRigidState) + sizeof(PfxRigidBody) + sizeof(PfxCollidable) + sizeof(PfxSolverBody) + sizeof(PfxBroadphaseProxy)) * numRigidBodies + + (sizeof(PfxContactManifold) + sizeof(PfxBroadphasePair)) * NUM_CONTACTS; + SCE_PFX_PRINTF("----------------------------------------------------------\n"); + SCE_PFX_PRINTF("Total %5d bytes\n",totalBytes); +} + +/////////////////////////////////////////////////////////////////////////////// +// Initialize / Finalize Engine + +bool physics_init() +{ + return true; +} + +void physics_release() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Pick + +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2) +{ + return PfxVector3(0.0f); +} + +void physics_pick_update(const PfxVector3 &p) +{ +} + +void physics_pick_end() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Get Information + +int physics_get_num_rigidbodies() +{ + return numRigidBodies; +} + +const PfxRigidState& physics_get_state(int id) +{ + return states[id]; +} + +const PfxRigidBody& physics_get_body(int id) +{ + return bodies[id]; +} + +const PfxCollidable& physics_get_collidable(int id) +{ + return collidables[id]; +} + +int physics_get_num_contacts() +{ + return numPairs[pairSwap]; +} + +const PfxContactManifold &physics_get_contact(int id) +{ + return contacts[pfxGetConstraintId(pairsBuff[pairSwap][id])]; +} diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/physics_func.h b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/physics_func.h new file mode 100644 index 000000000..0aa7e07de --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/physics_func.h @@ -0,0 +1,49 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef __PHYSICS_FUNC_H__ +#define __PHYSICS_FUNC_H__ + +#define SCE_PFX_USE_PERFCOUNTER + +#include "physics_effects.h" + +using namespace sce::PhysicsEffects; + +//E Simulation +//J シミュレーション +bool physics_init(); +void physics_release(); +void physics_create_scene(int sceneId); +void physics_simulate(); + +//E Picking +//J ピッキング +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2); +void physics_pick_update(const PfxVector3 &p); +void physics_pick_end(); + +//E Change parameters +//J パラメータの取得 +int physics_get_num_rigidbodies(); +const PfxRigidState& physics_get_state(int id); +const PfxRigidBody& physics_get_body(int id); +const PfxCollidable& physics_get_collidable(int id); + +int physics_get_num_contacts(); +const PfxContactManifold &physics_get_contact(int id); + +#endif /* __PHYSICS_FUNC_H__ */ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/premake4.lua b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/premake4.lua new file mode 100644 index 000000000..ab367031b --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable/premake4.lua @@ -0,0 +1,22 @@ + project "2_stable" + + kind "WindowedApp" + targetdir "../../../bin" + includedirs {"../../../include"} + + links { + "physicseffects2_lowlevel", + "physicseffects2_baselevel", + "physicseffects2_util", + "opengl32" + } + + flags {"WinMain"} + + files { + "main.cpp", + "physics_func.cpp", + "../common/ctrl_func.win32.cpp", + "../common/perf_func.win32.cpp", + "../common/render_func.win32.cpp" + } \ No newline at end of file diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/barrel.h b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/barrel.h new file mode 100644 index 000000000..6574fa862 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/barrel.h @@ -0,0 +1,202 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define BarrelVtxCount 57 +#define BarrelIdxCount 180 + +static float BarrelVtx[] = { +0.0f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +-0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +0.0f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +-0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.957307f,-0.289072f,0.0f, +0.404509f,0.0f,-0.293893f, 0.809017f,0.0f,-0.587785f, +0.5f,0.0f,0.0f, 1.0f,0.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.774478f,-0.289072f,-0.562691f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +-0.154509f,0.0f,-0.475528f, -0.309017f,0.0f,-0.951057f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +-0.107853f,-0.5f,-0.331936f, -0.295824f,-0.289072f,-0.910453f, +-0.404509f,0.0f,-0.293893f, -0.809017f,0.0f,-0.587785f, +-0.282362f,-0.5f,-0.205148f, -0.774478f,-0.289072f,-0.562691f, +-0.5f,0.0f,0.0f, -1.0f,0.0f,0.0f, +-0.349018f,-0.5f,0.0f, -0.957307f,-0.289072f,0.0f, +-0.404508f,0.0f,0.293893f, -0.809017f,0.0f,0.587785f, +-0.282362f,-0.5f,0.205148f, -0.774478f,-0.289072f,0.562691f, +-0.154509f,0.0f,0.475528f, -0.309017f,0.0f,0.951056f, +-0.107853f,-0.5f,0.331936f, -0.295824f,-0.289072f,0.910453f, +0.154509f,0.0f,0.475528f, 0.309017f,0.0f,0.951056f, +0.107853f,-0.5f,0.331936f, 0.295824f,-0.289072f,0.910453f, +0.404509f,0.0f,0.293892f, 0.809017f,0.0f,0.587785f, +0.282362f,-0.5f,0.205148f, 0.774478f,-0.289072f,0.562691f, +0.282362f,0.5f,-0.205148f, 0.774478f,0.289072f,-0.562691f, +0.349018f,0.5f,0.0f, 0.957307f,0.289072f,0.0f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.107853f,0.5f,-0.331936f, -0.295824f,0.289072f,-0.910453f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.282362f,0.5f,-0.205148f, -0.774478f,0.289072f,-0.562691f, +-0.349018f,0.5f,0.0f, -0.957307f,0.289072f,0.0f, +-0.282362f,0.5f,0.205148f, -0.774478f,0.289072f,0.562691f, +-0.107853f,0.5f,0.331936f, -0.295824f,0.289072f,0.910453f, +0.107853f,0.5f,0.331936f, 0.295824f,0.289072f,0.910453f, +0.282362f,0.5f,0.205148f, 0.774478f,0.289072f,0.562691f, +}; + +static float BarrelTex[] = { +0.0f,0.5f, +0.0f,0.85f, +0.0f,0.75f, +0.0f,0.95f, +0.0f,0.05f, +0.0f,-0.05f, +0.0f,0.15f, +0.0f,0.25f, +0.0f,0.35f, +0.0f,0.45f, +0.0f,0.55f, +0.0f,0.65f, +1.0f,0.5f, +1.0f,0.75f, +1.0f,0.85f, +1.0f,0.95f, +1.0f,-0.05f, +1.0f,0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +0.0f,0.75f, +0.5f,0.85f, +0.5f,0.75f, +0.0f,0.85f, +0.5f,0.95f, +0.0f,0.95f, +0.0f,-0.05f, +0.5f,0.05f, +0.5f,-0.05f, +0.0f,0.05f, +0.5f,0.15f, +0.0f,0.15f, +0.5f,0.25f, +0.0f,0.25f, +0.5f,0.35f, +0.0f,0.35f, +0.5f,0.45f, +0.0f,0.45f, +0.5f,0.55f, +0.0f,0.55f, +0.5f,0.65f, +0.0f,0.65f, +1.0f,0.85f, +1.0f,0.75f, +1.0f,0.95f, +1.0f,0.05f, +1.0f,-0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +}; + +static unsigned short BarrelIdx[] = { +0,1,2, +0,3,1, +0,4,5, +0,6,4, +0,7,6, +0,8,7, +0,9,8, +0,10,9, +0,11,10, +0,2,11, +12,13,14, +12,14,15, +12,16,17, +12,17,18, +12,18,19, +12,19,20, +12,20,21, +12,21,22, +12,22,23, +12,23,13, +24,25,26, +24,27,25, +27,28,25, +27,29,28, +30,31,32, +30,33,31, +33,34,31, +33,35,34, +35,36,34, +35,37,36, +37,38,36, +37,39,38, +39,40,38, +39,41,40, +41,42,40, +41,43,42, +43,44,42, +43,45,44, +45,26,44, +45,24,26, +26,46,47, +26,25,46, +25,48,46, +25,28,48, +32,49,50, +32,31,49, +31,51,49, +31,34,51, +34,52,51, +34,36,52, +36,53,52, +36,38,53, +38,54,53, +38,40,54, +40,55,54, +40,42,55, +42,56,55, +42,44,56, +44,47,56, +44,26,47, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/landscape.h b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/landscape.h new file mode 100644 index 000000000..00f6cffd2 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/landscape.h @@ -0,0 +1,318 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define LargeMeshVtxCount 81 +#define LargeMeshIdxCount 384 + +static float LargeMeshVtx[] = { +-25.0f,-2.19407f,18.5625f, 0.232976f,0.967754f,0.0957829f, +-25.0f,0.0644502f,24.75f, 0.188094f,0.871343f,-0.45319f, +-18.75f,-4.50287f,18.5625f, -0.0716098f,0.995449f,0.0628767f, +-18.75f,-0.39999f,24.75f, -0.0602794f,0.895848f,-0.440253f, +-12.5f,-1.2166f,18.5625f, -0.269469f,0.961403f,0.0555879f, +-12.5f,-0.942431f,24.75f, -0.0997841f,0.993258f,0.0589987f, +-6.25f,1.93598f,18.5625f, -0.283933f,0.956351f,-0.0691025f, +-6.25f,-0.445954f,24.75f, -0.180725f,0.942766f,0.280233f, +0.0f,2.76983f,18.5625f, 0.171645f,0.984908f,0.0222501f, +0.0f,2.76642f,24.75f, 0.0784993f,0.995428f,-0.0544117f, +6.25f,-2.53736f,18.5625f, 0.248298f,0.965028f,0.0840741f, +6.25f,-0.915645f,24.75f, 0.164311f,0.945856f,-0.279926f, +12.5f,-1.60054f,18.5625f, -0.180435f,0.983586f,0.00115547f, +12.5f,0.831925f,24.75f, -0.0692495f,0.964821f,-0.253623f, +18.75f,-0.800282f,18.5625f, 0.10755f,0.951538f,0.288112f, +18.75f,-1.47284f,24.75f, 0.232178f,0.972664f,0.00429361f, +25.0f,-2.78379f,18.5625f, 0.1833f,0.937477f,0.295867f, +25.0f,-0.967508f,24.75f, -0.0773477f,0.956641f,-0.280812f, +-25.0f,-0.352038f,12.375f, -0.192222f,0.972435f,0.131987f, +-18.75f,0.681228f,12.375f, -0.107779f,0.962569f,0.248686f, +-12.5f,2.72065f,12.375f, 0.0520846f,0.993034f,0.105692f, +-6.25f,-1.78776f,12.375f, -0.0133223f,0.99674f,-0.0795754f, +0.0f,1.57707f,12.375f, -0.129025f,0.969662f,-0.207627f, +6.25f,0.424356f,12.375f, 0.180995f,0.97074f,0.157815f, +12.5f,0.283234f,12.375f, -0.16285f,0.973539f,0.160316f, +18.75f,2.57015f,12.375f, -0.165454f,0.978339f,0.124408f, +25.0f,3.07363f,12.375f, -0.00454559f,0.988151f,0.153417f, +-25.0f,-0.893751f,6.1875f, -0.0836251f,0.990084f,-0.112876f, +-18.75f,0.930932f,6.1875f, 0.00269413f,0.971838f,-0.235633f, +-12.5f,-0.684529f,6.1875f, -0.010319f,0.927048f,-0.3748f, +-6.25f,-0.661383f,6.1875f, 0.012265f,0.999875f,-0.00994222f, +0.0f,0.385718f,6.1875f, -0.15435f,0.984937f,-0.0779465f, +6.25f,0.589796f,6.1875f, 0.0241717f,0.999582f,-0.0158589f, +12.5f,0.47454f,6.1875f, -0.017184f,0.997953f,-0.0616073f, +18.75f,1.59939f,6.1875f, -0.0902706f,0.957309f,-0.274609f, +25.0f,1.13434f,6.1875f, 0.0346006f,0.957441f,-0.286547f, +-25.0f,0.74548f,0.0f, 0.329903f,0.930812f,0.157334f, +-18.75f,-2.47437f,0.0f, 0.247844f,0.968142f,0.0357041f, +-12.5f,-4.16309f,1.81975e-007f, -0.0623898f,0.997626f,-0.0291436f, +-6.25f,-0.700022f,0.0f, -0.217067f,0.974987f,-0.0477624f, +0.0f,-0.0957388f,0.0f, -0.117693f,0.990712f,-0.068098f, +6.25f,0.614077f,0.0f, -0.0713214f,0.997305f,0.01722f, +12.5f,0.299109f,0.0f, 0.218606f,0.968641f,0.118094f, +18.75f,-1.71753f,0.0f, 0.0339493f,0.985612f,-0.165579f, +25.0f,-1.12638f,0.0f, -0.0547573f,0.989177f,-0.136126f, +-25.0f,-0.403319f,-6.1875f, -0.1263f,0.989211f,-0.074223f, +-18.75f,-0.0730335f,-6.1875f, 0.0173428f,0.965382f,0.260261f, +-12.5f,-0.450125f,-6.1875f, 0.0658811f,0.875f,0.479619f, +-6.25f,-0.180204f,-6.1875f, 0.0116584f,0.981445f,0.19139f, +0.0f,-0.632679f,-6.1875f, -0.0557983f,0.993041f,-0.103716f, +6.25f,0.308409f,-6.1875f, -0.191898f,0.96766f,-0.163737f, +12.5f,2.5011f,-6.1875f, 0.0758397f,0.996403f,-0.0378189f, +18.75f,-1.69303f,-6.1875f, 0.16761f,0.974057f,0.15205f, +25.0f,-0.141349f,-6.1875f, -0.204846f,0.978471f,0.0251341f, +-25.0f,-1.10316f,-12.375f, -0.0350644f,0.993748f,-0.106001f, +-18.75f,1.06711f,-12.375f, -0.309806f,0.919244f,-0.242922f, +-12.5f,3.61544f,-12.375f, -0.0506281f,0.998702f,-0.00561657f, +-6.25f,1.6504f,-12.375f, 0.322294f,0.937465f,0.131477f, +0.0f,-1.60595f,-12.375f, 0.086016f,0.995916f,0.0274459f, +6.25f,-0.849859f,-12.375f, -0.0332811f,0.997087f,0.0686255f, +12.5f,-0.942201f,-12.375f, -0.153559f,0.982185f,-0.108312f, +18.75f,0.494873f,-12.375f, 0.0753195f,0.981472f,0.176181f, +25.0f,-0.333828f,-12.375f, 0.035057f,0.987194f,0.155624f, +-25.0f,2.1862f,-18.5625f, 0.612899f,0.782306f,0.111138f, +-18.75f,-3.38259f,-18.5625f, 0.0194078f,0.992789f,-0.118297f, +-12.5f,-0.880916f,-18.5625f, -0.282251f,0.949875f,-0.13443f, +-6.25f,0.818158f,-18.5625f, 0.1476f,0.981788f,-0.119612f, +0.0f,-1.48019f,-18.5625f, -0.044551f,0.996013f,-0.0772824f, +6.25f,1.47123f,-18.5625f, -0.117036f,0.97986f,0.161792f, +12.5f,0.164076f,-18.5625f, -0.0340355f,0.978993f,0.201034f, +18.75f,2.14568f,-18.5625f, -0.0439269f,0.994859f,0.0912435f, +25.0f,0.626506f,-18.5625f, 0.208015f,0.968592f,0.136229f, +-25.0f,0.296889f,-24.75f, 0.46973f,0.844327f,-0.257809f, +-18.75f,-3.18022f,-24.75f, -0.0226758f,0.998794f,-0.0435401f, +-12.5f,1.8927f,-24.75f, -0.202772f,0.919836f,0.335836f, +-6.25f,1.46387f,-24.75f, 0.224904f,0.955746f,0.189652f, +0.0f,-2.52726f,-24.75f, -0.0435882f,0.993572f,-0.10447f, +6.25f,1.30397f,-24.75f, -0.28646f,0.956525f,-0.0547707f, +12.5f,1.85812f,-24.75f, 0.0521949f,0.979796f,0.193067f, +18.75f,1.56331f,-24.75f, -0.0270784f,0.999629f,-0.00293115f, +25.0f,1.05366f,-24.75f, 0.161f,0.986887f,-0.0115473f, +}; + +static float LargeMeshTex[] = { +0.125f,0.0f, +0.0f,0.0f, +0.125f,0.125f, +0.0f,0.125f, +0.125f,0.25f, +0.0f,0.25f, +0.125f,0.375f, +0.0f,0.375f, +0.125f,0.5f, +0.0f,0.5f, +0.125f,0.625f, +0.0f,0.625f, +0.125f,0.75f, +0.0f,0.75f, +0.125f,0.875f, +0.0f,0.875f, +0.125f,1.0f, +0.0f,1.0f, +0.25f,0.0f, +0.25f,0.125f, +0.25f,0.25f, +0.25f,0.375f, +0.25f,0.5f, +0.25f,0.625f, +0.25f,0.75f, +0.25f,0.875f, +0.25f,1.0f, +0.375f,0.0f, +0.375f,0.125f, +0.375f,0.25f, +0.375f,0.375f, +0.375f,0.5f, +0.375f,0.625f, +0.375f,0.75f, +0.375f,0.875f, +0.375f,1.0f, +0.5f,0.0f, +0.5f,0.125f, +0.5f,0.25f, +0.5f,0.375f, +0.5f,0.5f, +0.5f,0.625f, +0.5f,0.75f, +0.5f,0.875f, +0.5f,1.0f, +0.625f,0.0f, +0.625f,0.125f, +0.625f,0.25f, +0.625f,0.375f, +0.625f,0.5f, +0.625f,0.625f, +0.625f,0.75f, +0.625f,0.875f, +0.625f,1.0f, +0.75f,0.0f, +0.75f,0.125f, +0.75f,0.25f, +0.75f,0.375f, +0.75f,0.5f, +0.75f,0.625f, +0.75f,0.75f, +0.75f,0.875f, +0.75f,1.0f, +0.875f,0.0f, +0.875f,0.125f, +0.875f,0.25f, +0.875f,0.375f, +0.875f,0.5f, +0.875f,0.625f, +0.875f,0.75f, +0.875f,0.875f, +0.875f,1.0f, +1.0f,0.0f, +1.0f,0.125f, +1.0f,0.25f, +1.0f,0.375f, +1.0f,0.5f, +1.0f,0.625f, +1.0f,0.75f, +1.0f,0.875f, +1.0f,1.0f, +}; + +static unsigned short LargeMeshIdx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +18,0,19, +2,19,0, +19,2,20, +4,20,2, +20,4,21, +6,21,4, +21,6,22, +8,22,6, +22,8,23, +10,23,8, +23,10,24, +12,24,10, +24,12,25, +14,25,12, +25,14,26, +16,26,14, +27,18,28, +19,28,18, +28,19,29, +20,29,19, +29,20,30, +21,30,20, +30,21,31, +22,31,21, +31,22,32, +23,32,22, +32,23,33, +24,33,23, +33,24,34, +25,34,24, +34,25,35, +26,35,25, +36,27,37, +28,37,27, +37,28,38, +29,38,28, +38,29,39, +30,39,29, +39,30,40, +31,40,30, +40,31,41, +32,41,31, +41,32,42, +33,42,32, +42,33,43, +34,43,33, +43,34,44, +35,44,34, +45,36,46, +37,46,36, +46,37,47, +38,47,37, +47,38,48, +39,48,38, +48,39,49, +40,49,39, +49,40,50, +41,50,40, +50,41,51, +42,51,41, +51,42,52, +43,52,42, +52,43,53, +44,53,43, +54,45,55, +46,55,45, +55,46,56, +47,56,46, +56,47,57, +48,57,47, +57,48,58, +49,58,48, +58,49,59, +50,59,49, +59,50,60, +51,60,50, +60,51,61, +52,61,51, +61,52,62, +53,62,52, +63,54,64, +55,64,54, +64,55,65, +56,65,55, +65,56,66, +57,66,56, +66,57,67, +58,67,57, +67,58,68, +59,68,58, +68,59,69, +60,69,59, +69,60,70, +61,70,60, +70,61,71, +62,71,61, +72,63,73, +64,73,63, +73,64,74, +65,74,64, +74,65,75, +66,75,65, +75,66,76, +67,76,66, +76,67,77, +68,77,67, +77,68,78, +69,78,68, +78,69,79, +70,79,69, +79,70,80, +71,80,70, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/main.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/main.cpp new file mode 100644 index 000000000..e005c870e --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/main.cpp @@ -0,0 +1,448 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../common/common.h" +#include "../common/ctrl_func.h" +#include "../common/render_func.h" +#include "../common/perf_func.h" +#include "physics_func.h" +#include "barrel.h" +#include "landscape.h" + +#ifdef _WIN32 + #include + #include +#endif + +// ARA begin insert new code +#ifdef __ANDROID__ + #include + #include +#endif +// ARA end + +#define SAMPLE_NAME "api_physics_effects/2_stable" + +static bool s_isRunning = true; + +int sceneId = 2; +bool simulating = false; + +int landscapeMeshId; +int convexMeshId; + +void render(void) +{ + render_begin(); + + for(int i=0;i -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_DOWN)) { + angX += 0.05f; + if(angX < -1.4f) angX = -1.4f; + if(angX > -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_LEFT)) { + angY -= 0.05f; + } + + if(ctrl_button_pressed(BTN_RIGHT)) { + angY += 0.05f; + } + + if(ctrl_button_pressed(BTN_ZOOM_OUT)) { + r *= 1.1f; + if(r > 500.0f) r = 500.0f; + } + + if(ctrl_button_pressed(BTN_ZOOM_IN)) { + r *= 0.9f; + if(r < 1.0f) r = 1.0f; + } + + if(ctrl_button_pressed(BTN_SCENE_RESET) == BTN_STAT_DOWN) { + physics_create_scene(sceneId); + } + + if(ctrl_button_pressed(BTN_SCENE_NEXT) == BTN_STAT_DOWN) { + physics_create_scene(++sceneId); + } + + if(ctrl_button_pressed(BTN_SIMULATION) == BTN_STAT_DOWN) { + simulating = !simulating; + } + + if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_DOWN) { + simulating = true; + } + else if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_UP || ctrl_button_pressed(BTN_STEP) == BTN_STAT_KEEP) { + simulating = false; + } + + render_set_view_angle(angX,angY,r); +} + +#ifndef _WIN32 + +// ARA begin insert new code +#ifdef __ANDROID__ + +/////////////////////////////////////////////////////////////////////////////// +// sceneChange +// +/// This function is used to change the physics scene on Android devices +/////////////////////////////////////////////////////////////////////////////// +void sceneChange() +{ + physics_create_scene(sceneId++); +} + +#else // __ANDROID__ +// ARA end + +/////////////////////////////////////////////////////////////////////////////// +// Main + +int main(void) +{ + init(); + + physics_create_scene(sceneId); + + printf("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + while (s_isRunning) { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + + shutdown(); + + printf("## %s: FINISHED ##\n", SAMPLE_NAME); + + return 0; +} + +// ARA begin insert new code +#endif // __ANDROID__ +// ARA end + +#else // _WIN32 + +/////////////////////////////////////////////////////////////////////////////// +// WinMain + +extern HDC hDC; +extern HGLRC hRC; +HWND hWnd; +HINSTANCE hInstance; + +void releaseWindow() +{ + if(hRC) { + wglMakeCurrent(0,0); + wglDeleteContext(hRC); + } + + if(hDC) ReleaseDC(hWnd,hDC); + if(hWnd) DestroyWindow(hWnd); + + UnregisterClass(SAMPLE_NAME,hInstance); +} + +LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) { + case WM_SYSCOMMAND: + { + switch (wParam) { + case SC_SCREENSAVE: + case SC_MONITORPOWER: + return 0; + } + break; + } + + case WM_CLOSE: + PostQuitMessage(0); + return 0; + + case WM_SIZE: + render_resize(LOWORD(lParam),HIWORD(lParam)); + return 0; + } + + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + +bool createWindow(char* title, int width, int height) +{ + WNDCLASS wc; + RECT rect; + rect.left=0; + rect.right=width; + rect.top=0; + rect.bottom=height; + + hInstance = GetModuleHandle(NULL); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = SAMPLE_NAME; + + if(!RegisterClass(&wc)) { + return false; + } + + AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE); + + if(!(hWnd=CreateWindowEx(WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,SAMPLE_NAME,title, + WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, + 0,0,rect.right-rect.left,rect.bottom-rect.top, + NULL,NULL,hInstance,NULL))) { + releaseWindow(); + return false; + } + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 32, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, + 0, 0, 0, 0, + 32, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + if(!(hDC=GetDC(hWnd))) + { + releaseWindow(); + OutputDebugString(""); + return FALSE; + } + + int pixelformat; + + if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){ + OutputDebugString("ChoosePixelFormat Failed...."); + return FALSE; + } + + if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE){ + OutputDebugString("SetPixelFormat Failed...."); + return FALSE; + } + + if (!(hRC=wglCreateContext(hDC))){ + OutputDebugString("Creating HGLRC Failed...."); + return FALSE; + } + + // Set Vsync + //BOOL (WINAPI *wglSwapIntervalEXT)(int) = NULL; + + //if(strstr((char*)glGetString( GL_EXTENSIONS ),"WGL_EXT_swap_control")== 0) { + //} + //else { + //wglSwapIntervalEXT = (BOOL (WINAPI*)(int))wglGetProcAddress("wglSwapIntervalEXT"); + //if(wglSwapIntervalEXT) wglSwapIntervalEXT(1); + //} + + wglMakeCurrent(hDC,hRC); + + ShowWindow(hWnd,SW_SHOW); + SetForegroundWindow(hWnd); + SetFocus(hWnd); + + render_resize(width, height); + + glClearColor(0.0f,0.0f,0.0f,0.0f); + glClearDepth(1.0f); + + return TRUE; +} + +int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) +{ + if(!createWindow(SAMPLE_NAME,DISPLAY_WIDTH,DISPLAY_HEIGHT)) { + MessageBox(NULL,"Can't create gl window.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return 0; + } + + init(); + + physics_create_scene(sceneId); + + SCE_PFX_PRINTF("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + MSG msg; + while(s_isRunning) { + if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if(msg.message==WM_QUIT) { + s_isRunning = false; + } + else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + else { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + } + + shutdown(); + + SCE_PFX_PRINTF("## %s: FINISHED ##\n", SAMPLE_NAME); + + releaseWindow(); + return (msg.wParam); +} + +#endif diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/physics_func.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/physics_func.cpp new file mode 100644 index 000000000..eaf49033f --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/physics_func.cpp @@ -0,0 +1,968 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "physics_func.h" +#include "../common/perf_func.h" + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Data + +#define NUM_RIGIDBODIES 5000 +#define NUM_JOINTS 5000 +#define NUM_CONTACTS 4000 + +const float timeStep = 0.016f; +const float separateBias = 0.1f; +int iteration = 5; + +//J ??????? +//E World size +PfxVector3 worldCenter(0.0f); +PfxVector3 worldExtent(500.0f); + +//J ?? +//E Rigid body +PfxRigidState states[NUM_RIGIDBODIES]; +PfxRigidBody bodies[NUM_RIGIDBODIES]; +PfxCollidable collidables[NUM_RIGIDBODIES]; +PfxSolverBody solverBodies[NUM_RIGIDBODIES]; +int numRigidBodies = 0; + +//J ????????????????? +//E Large mesh for representing a landscape +#include "landscape.h" +PfxLargeTriMesh gLargeMesh; + +//J ????? +//E Convex Mesh +#include "barrel.h" +PfxConvexMesh gConvex; + +//J ???? +//E Proxies +PfxBroadphaseProxy proxies[NUM_RIGIDBODIES]; + +//J ????? +//E Joint +PfxConstraintPair jointPairs[NUM_JOINTS]; +PfxJoint joints[NUM_JOINTS]; +int numJoints = 0; + +//J ?? +//E Pairs +unsigned int pairSwap; +unsigned int numPairs[2]; +PfxBroadphasePair pairsBuff[2][NUM_CONTACTS]; + +//J ????? +//E Contacts +PfxContactManifold contacts[NUM_CONTACTS]; +int numContacts; + +PfxUInt32 contactIdPool[NUM_CONTACTS]; +int numContactIdPool; + +//J ?????? +//E Temporary buffers +#define POOL_BYTES (5*1024*1024) +unsigned char SCE_PFX_ALIGNED(128) poolBuff[POOL_BYTES]; + +//J ???????????????? +//E Stack allocator for temporary buffers +PfxHeapManager pool(poolBuff,POOL_BYTES); + +// ARA begin insert new code +//E task manager for parallel demo +#define NUM_THREADS 1 +PfxTaskManager *taskManager = NULL; +//E need enough bytes for NUM_THREADS PfxTaskArg objects, with the space rounded up to fill a 16-bit aligned space +#define TASK_MANAGER_POOL_BYTES 1024 +unsigned char SCE_PFX_ALIGNED(16) taskPoolBuff[TASK_MANAGER_POOL_BYTES]; +// ARA end + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Function + +int frame = 0; + +void broadphase() +{ + pairSwap = 1-pairSwap; + + unsigned int &numPreviousPairs = numPairs[1-pairSwap]; + unsigned int &numCurrentPairs = numPairs[pairSwap]; + PfxBroadphasePair *previousPairs = pairsBuff[1-pairSwap]; + PfxBroadphasePair *currentPairs = pairsBuff[pairSwap]; + + //J ????????????????? + //E Find the axis along which all rigid bodies are most widely positioned + int axis = 0; + { + PfxVector3 s(0.0f),s2(0.0f); + for(int i=0;i v[0]) axis = 1; + if(v[2] > v[axis]) axis = 2; + } + + //J ??????????????? + //E Create broadpahse proxies + { + for(int i=0;i 0) { + cId = contactIdPool[--numContactIdPool]; + } + else { + cId = numContacts++; + } + if(cId >= NUM_CONTACTS) { + cId = 0; + } + SCE_PFX_ASSERT(cId < NUM_CONTACTS); + pfxSetContactId(outNewPairs[i],cId); + PfxContactManifold &contact = contacts[cId]; + contact.reset(pfxGetObjectIdA(outNewPairs[i]),pfxGetObjectIdB(outNewPairs[i])); + } + + //J ???????????? + //E Merge 'new' and 'keep' pairs + numCurrentPairs = 0; + for(PfxUInt32 i=0;i 0) { + pfxReleaseLargeTriMesh(gLargeMesh); + } + + PfxInt32 ret = pfxCreateLargeTriMesh(gLargeMesh,param); + if(ret != SCE_PFX_OK) { + SCE_PFX_PRINTF("Can't create large mesh.\n"); + } + + int id = numRigidBodies++; + PfxShape shape; + shape.reset(); + shape.setLargeTriMesh(&gLargeMesh); + collidables[id].reset(); + collidables[id].addShape(shape); + collidables[id].finish(); + bodies[id].reset(); + states[id].reset(); + states[id].setPosition(PfxVector3(0.0f,-5.0f,0.0f)); + states[id].setOrientation(PfxQuat::rotationX(0.5f)*PfxQuat::rotationY(0.7f)); + states[id].setMotionType(kPfxMotionTypeFixed); + states[id].setRigidBodyId(id); +} + +void physics_create_scene(int sceneId) +{ + const int numScenes = 4; + int sid = sceneId % numScenes; + + numRigidBodies= 0; + pairSwap = 0; + numPairs[0] = 0; + numPairs[1] = 0; + numContacts = 0; + numContactIdPool = 0; + numJoints = 0; + frame = 0; + + switch(sid) { + case 0: // simple primitives + createSceneBoxGround(); + createScenePrimitives(); + break; + + case 1: // joints + createSceneBoxGround(); + createSceneJoints(); + break; + + case 2: // stacking + createSceneBoxGround(); + createSceneStacking(); + break; + + case 3: // landscape + createSceneLandscape(); + createScenePrimitives(); + break; + } + + SCE_PFX_PRINTF("----- Size of rigid body buffer ------\n"); + SCE_PFX_PRINTF(" size * num = total\n"); + SCE_PFX_PRINTF("PfxRigidState %5d * %5d = %5d bytes\n",sizeof(PfxRigidState),numRigidBodies,sizeof(PfxRigidState)*numRigidBodies); + SCE_PFX_PRINTF("PfxRigidBody %5d * %5d = %5d bytes\n",sizeof(PfxRigidBody),numRigidBodies,sizeof(PfxRigidBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxCollidable %5d * %5d = %5d bytes\n",sizeof(PfxCollidable),numRigidBodies,sizeof(PfxCollidable)*numRigidBodies); + SCE_PFX_PRINTF("PfxJoint %5d * %5d = %5d bytes\n",sizeof(PfxJoint),numJoints,sizeof(PfxJoint)*numJoints); + SCE_PFX_PRINTF("PfxSolverBody %5d * %5d = %5d bytes\n",sizeof(PfxSolverBody),numRigidBodies,sizeof(PfxSolverBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxBroadphaseProxy %5d * %5d = %5d bytes\n",sizeof(PfxBroadphaseProxy),numRigidBodies,sizeof(PfxBroadphaseProxy)*numRigidBodies); + SCE_PFX_PRINTF("PfxContactManifold %5d * %5d = %5d bytes\n",sizeof(PfxContactManifold),NUM_CONTACTS,sizeof(PfxContactManifold)*NUM_CONTACTS); + SCE_PFX_PRINTF("PfxBroadphasePair %5d * %5d = %5d bytes\n",sizeof(PfxBroadphasePair),NUM_CONTACTS,sizeof(PfxBroadphasePair)*NUM_CONTACTS); + + int totalBytes = + (sizeof(PfxRigidState) + sizeof(PfxRigidBody) + sizeof(PfxCollidable) + sizeof(PfxSolverBody) + sizeof(PfxBroadphaseProxy)) * numRigidBodies + + (sizeof(PfxContactManifold) + sizeof(PfxBroadphasePair)) * NUM_CONTACTS; + SCE_PFX_PRINTF("----------------------------------------------------------\n"); + SCE_PFX_PRINTF("Total %5d bytes\n",totalBytes); + +// ARA begin insert new code +#ifdef USE_PTHREADS + if (!taskManager) + { + taskManager = PfxCreateTaskManagerPthreads(NUM_THREADS, NUM_THREADS, taskPoolBuff, TASK_MANAGER_POOL_BYTES); + taskManager->initialize(); + } +#endif +// ARA end +} + +/////////////////////////////////////////////////////////////////////////////// +// Initialize / Finalize Engine + +bool physics_init() +{ + return true; +} + +void physics_release() +{ +// ARA begin insert new code + if (taskManager) + taskManager->finalize(); +// ARA end +} + +/////////////////////////////////////////////////////////////////////////////// +// Pick + +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2) +{ + return PfxVector3(0.0f); +} + +void physics_pick_update(const PfxVector3 &p) +{ +} + +void physics_pick_end() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Get Information + +int physics_get_num_rigidbodies() +{ + return numRigidBodies; +} + +const PfxRigidState& physics_get_state(int id) +{ + return states[id]; +} + +const PfxRigidBody& physics_get_body(int id) +{ + return bodies[id]; +} + +const PfxCollidable& physics_get_collidable(int id) +{ + return collidables[id]; +} + +int physics_get_num_contacts() +{ + return numPairs[pairSwap]; +} + +const PfxContactManifold &physics_get_contact(int id) +{ + return contacts[pfxGetConstraintId(pairsBuff[pairSwap][id])]; +} diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/physics_func.h b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/physics_func.h new file mode 100644 index 000000000..0a6d2fe78 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/2_stable_parallel/physics_func.h @@ -0,0 +1,49 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef __PHYSICS_FUNC_H__ +#define __PHYSICS_FUNC_H__ + +#define SCE_PFX_USE_PERFCOUNTER + +#include "physics_effects.h" + +using namespace sce::PhysicsEffects; + +//E Simulation +//J ???????? +bool physics_init(); +void physics_release(); +void physics_create_scene(int sceneId); +void physics_simulate(); + +//E Picking +//J ????? +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2); +void physics_pick_update(const PfxVector3 &p); +void physics_pick_end(); + +//E Change parameters +//J ???????? +int physics_get_num_rigidbodies(); +const PfxRigidState& physics_get_state(int id); +const PfxRigidBody& physics_get_body(int id); +const PfxCollidable& physics_get_collidable(int id); + +int physics_get_num_contacts(); +const PfxContactManifold &physics_get_contact(int id); + +#endif /* __PHYSICS_FUNC_H__ */ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/3_sleep.windows.vcproj b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/3_sleep.windows.vcproj new file mode 100644 index 000000000..d3c7857a3 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/3_sleep.windows.vcproj @@ -0,0 +1,713 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/CMakeLists.txt b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/CMakeLists.txt new file mode 100644 index 000000000..d54bb9a3b --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/CMakeLists.txt @@ -0,0 +1,77 @@ +cmake_minimum_required(VERSION 2.4) + + +#this line has to appear before 'PROJECT' in order to be able to disable incremental linking +SET(MSVC_INCREMENTAL_DEFAULT ON) + +PROJECT(App_3_Sleep) + + +IF (NOT CMAKE_BUILD_TYPE) +# SET(CMAKE_BUILD_TYPE "Debug") + SET(CMAKE_BUILD_TYPE "Release") +ENDIF (NOT CMAKE_BUILD_TYPE) + + +OPTION(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC Runtime Library DLL (/MD or /MDd)" ON) +OPTION(USE_MSVC_INCREMENTAL_LINKING "Use MSVC Incremental Linking" OFF) + + +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + + +SET(App_3_Sleep_SRCS + main.cpp + physics_func.cpp + ../common/ctrl_func.win32.cpp + ../common/perf_func.win32.cpp + ../common/render_func.win32.cpp +) + + +SET(App_3_Sleep_HDRS + physics_func.h + landscape.h + barrel.h + ../common/render_func.h + ../common/common.h + ../common/ctrl_func.h + ../common/perf_func.h +) + + +INCLUDE_DIRECTORIES( + ${PHYSICS_EFFECTS_SOURCE_DIR}/include +# ${VECTOR_MATH_INCLUDE} +) + +#LINK_DIRECTORIES( +# +#) + +#ADD_DEFINITIONS(-DUNICODE) +#ADD_DEFINITIONS(-D_UNICODE) + +ADD_EXECUTABLE(App_3_Sleep WIN32 + ${App_3_Sleep_SRCS} + ${App_3_Sleep_HDRS} +) +TARGET_LINK_LIBRARIES(App_3_Sleep + PfxBaseLevel + PfxLowLevel + PfxUtil + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} +) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(App_3_Sleep PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(App_3_Sleep PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(App_3_Sleep PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF() + + + + \ No newline at end of file diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/barrel.h b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/barrel.h new file mode 100644 index 000000000..6574fa862 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/barrel.h @@ -0,0 +1,202 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define BarrelVtxCount 57 +#define BarrelIdxCount 180 + +static float BarrelVtx[] = { +0.0f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +-0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +0.0f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +-0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.957307f,-0.289072f,0.0f, +0.404509f,0.0f,-0.293893f, 0.809017f,0.0f,-0.587785f, +0.5f,0.0f,0.0f, 1.0f,0.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.774478f,-0.289072f,-0.562691f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +-0.154509f,0.0f,-0.475528f, -0.309017f,0.0f,-0.951057f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +-0.107853f,-0.5f,-0.331936f, -0.295824f,-0.289072f,-0.910453f, +-0.404509f,0.0f,-0.293893f, -0.809017f,0.0f,-0.587785f, +-0.282362f,-0.5f,-0.205148f, -0.774478f,-0.289072f,-0.562691f, +-0.5f,0.0f,0.0f, -1.0f,0.0f,0.0f, +-0.349018f,-0.5f,0.0f, -0.957307f,-0.289072f,0.0f, +-0.404508f,0.0f,0.293893f, -0.809017f,0.0f,0.587785f, +-0.282362f,-0.5f,0.205148f, -0.774478f,-0.289072f,0.562691f, +-0.154509f,0.0f,0.475528f, -0.309017f,0.0f,0.951056f, +-0.107853f,-0.5f,0.331936f, -0.295824f,-0.289072f,0.910453f, +0.154509f,0.0f,0.475528f, 0.309017f,0.0f,0.951056f, +0.107853f,-0.5f,0.331936f, 0.295824f,-0.289072f,0.910453f, +0.404509f,0.0f,0.293892f, 0.809017f,0.0f,0.587785f, +0.282362f,-0.5f,0.205148f, 0.774478f,-0.289072f,0.562691f, +0.282362f,0.5f,-0.205148f, 0.774478f,0.289072f,-0.562691f, +0.349018f,0.5f,0.0f, 0.957307f,0.289072f,0.0f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.107853f,0.5f,-0.331936f, -0.295824f,0.289072f,-0.910453f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.282362f,0.5f,-0.205148f, -0.774478f,0.289072f,-0.562691f, +-0.349018f,0.5f,0.0f, -0.957307f,0.289072f,0.0f, +-0.282362f,0.5f,0.205148f, -0.774478f,0.289072f,0.562691f, +-0.107853f,0.5f,0.331936f, -0.295824f,0.289072f,0.910453f, +0.107853f,0.5f,0.331936f, 0.295824f,0.289072f,0.910453f, +0.282362f,0.5f,0.205148f, 0.774478f,0.289072f,0.562691f, +}; + +static float BarrelTex[] = { +0.0f,0.5f, +0.0f,0.85f, +0.0f,0.75f, +0.0f,0.95f, +0.0f,0.05f, +0.0f,-0.05f, +0.0f,0.15f, +0.0f,0.25f, +0.0f,0.35f, +0.0f,0.45f, +0.0f,0.55f, +0.0f,0.65f, +1.0f,0.5f, +1.0f,0.75f, +1.0f,0.85f, +1.0f,0.95f, +1.0f,-0.05f, +1.0f,0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +0.0f,0.75f, +0.5f,0.85f, +0.5f,0.75f, +0.0f,0.85f, +0.5f,0.95f, +0.0f,0.95f, +0.0f,-0.05f, +0.5f,0.05f, +0.5f,-0.05f, +0.0f,0.05f, +0.5f,0.15f, +0.0f,0.15f, +0.5f,0.25f, +0.0f,0.25f, +0.5f,0.35f, +0.0f,0.35f, +0.5f,0.45f, +0.0f,0.45f, +0.5f,0.55f, +0.0f,0.55f, +0.5f,0.65f, +0.0f,0.65f, +1.0f,0.85f, +1.0f,0.75f, +1.0f,0.95f, +1.0f,0.05f, +1.0f,-0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +}; + +static unsigned short BarrelIdx[] = { +0,1,2, +0,3,1, +0,4,5, +0,6,4, +0,7,6, +0,8,7, +0,9,8, +0,10,9, +0,11,10, +0,2,11, +12,13,14, +12,14,15, +12,16,17, +12,17,18, +12,18,19, +12,19,20, +12,20,21, +12,21,22, +12,22,23, +12,23,13, +24,25,26, +24,27,25, +27,28,25, +27,29,28, +30,31,32, +30,33,31, +33,34,31, +33,35,34, +35,36,34, +35,37,36, +37,38,36, +37,39,38, +39,40,38, +39,41,40, +41,42,40, +41,43,42, +43,44,42, +43,45,44, +45,26,44, +45,24,26, +26,46,47, +26,25,46, +25,48,46, +25,28,48, +32,49,50, +32,31,49, +31,51,49, +31,34,51, +34,52,51, +34,36,52, +36,53,52, +36,38,53, +38,54,53, +38,40,54, +40,55,54, +40,42,55, +42,56,55, +42,44,56, +44,47,56, +44,26,47, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/landscape.h b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/landscape.h new file mode 100644 index 000000000..00f6cffd2 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/landscape.h @@ -0,0 +1,318 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define LargeMeshVtxCount 81 +#define LargeMeshIdxCount 384 + +static float LargeMeshVtx[] = { +-25.0f,-2.19407f,18.5625f, 0.232976f,0.967754f,0.0957829f, +-25.0f,0.0644502f,24.75f, 0.188094f,0.871343f,-0.45319f, +-18.75f,-4.50287f,18.5625f, -0.0716098f,0.995449f,0.0628767f, +-18.75f,-0.39999f,24.75f, -0.0602794f,0.895848f,-0.440253f, +-12.5f,-1.2166f,18.5625f, -0.269469f,0.961403f,0.0555879f, +-12.5f,-0.942431f,24.75f, -0.0997841f,0.993258f,0.0589987f, +-6.25f,1.93598f,18.5625f, -0.283933f,0.956351f,-0.0691025f, +-6.25f,-0.445954f,24.75f, -0.180725f,0.942766f,0.280233f, +0.0f,2.76983f,18.5625f, 0.171645f,0.984908f,0.0222501f, +0.0f,2.76642f,24.75f, 0.0784993f,0.995428f,-0.0544117f, +6.25f,-2.53736f,18.5625f, 0.248298f,0.965028f,0.0840741f, +6.25f,-0.915645f,24.75f, 0.164311f,0.945856f,-0.279926f, +12.5f,-1.60054f,18.5625f, -0.180435f,0.983586f,0.00115547f, +12.5f,0.831925f,24.75f, -0.0692495f,0.964821f,-0.253623f, +18.75f,-0.800282f,18.5625f, 0.10755f,0.951538f,0.288112f, +18.75f,-1.47284f,24.75f, 0.232178f,0.972664f,0.00429361f, +25.0f,-2.78379f,18.5625f, 0.1833f,0.937477f,0.295867f, +25.0f,-0.967508f,24.75f, -0.0773477f,0.956641f,-0.280812f, +-25.0f,-0.352038f,12.375f, -0.192222f,0.972435f,0.131987f, +-18.75f,0.681228f,12.375f, -0.107779f,0.962569f,0.248686f, +-12.5f,2.72065f,12.375f, 0.0520846f,0.993034f,0.105692f, +-6.25f,-1.78776f,12.375f, -0.0133223f,0.99674f,-0.0795754f, +0.0f,1.57707f,12.375f, -0.129025f,0.969662f,-0.207627f, +6.25f,0.424356f,12.375f, 0.180995f,0.97074f,0.157815f, +12.5f,0.283234f,12.375f, -0.16285f,0.973539f,0.160316f, +18.75f,2.57015f,12.375f, -0.165454f,0.978339f,0.124408f, +25.0f,3.07363f,12.375f, -0.00454559f,0.988151f,0.153417f, +-25.0f,-0.893751f,6.1875f, -0.0836251f,0.990084f,-0.112876f, +-18.75f,0.930932f,6.1875f, 0.00269413f,0.971838f,-0.235633f, +-12.5f,-0.684529f,6.1875f, -0.010319f,0.927048f,-0.3748f, +-6.25f,-0.661383f,6.1875f, 0.012265f,0.999875f,-0.00994222f, +0.0f,0.385718f,6.1875f, -0.15435f,0.984937f,-0.0779465f, +6.25f,0.589796f,6.1875f, 0.0241717f,0.999582f,-0.0158589f, +12.5f,0.47454f,6.1875f, -0.017184f,0.997953f,-0.0616073f, +18.75f,1.59939f,6.1875f, -0.0902706f,0.957309f,-0.274609f, +25.0f,1.13434f,6.1875f, 0.0346006f,0.957441f,-0.286547f, +-25.0f,0.74548f,0.0f, 0.329903f,0.930812f,0.157334f, +-18.75f,-2.47437f,0.0f, 0.247844f,0.968142f,0.0357041f, +-12.5f,-4.16309f,1.81975e-007f, -0.0623898f,0.997626f,-0.0291436f, +-6.25f,-0.700022f,0.0f, -0.217067f,0.974987f,-0.0477624f, +0.0f,-0.0957388f,0.0f, -0.117693f,0.990712f,-0.068098f, +6.25f,0.614077f,0.0f, -0.0713214f,0.997305f,0.01722f, +12.5f,0.299109f,0.0f, 0.218606f,0.968641f,0.118094f, +18.75f,-1.71753f,0.0f, 0.0339493f,0.985612f,-0.165579f, +25.0f,-1.12638f,0.0f, -0.0547573f,0.989177f,-0.136126f, +-25.0f,-0.403319f,-6.1875f, -0.1263f,0.989211f,-0.074223f, +-18.75f,-0.0730335f,-6.1875f, 0.0173428f,0.965382f,0.260261f, +-12.5f,-0.450125f,-6.1875f, 0.0658811f,0.875f,0.479619f, +-6.25f,-0.180204f,-6.1875f, 0.0116584f,0.981445f,0.19139f, +0.0f,-0.632679f,-6.1875f, -0.0557983f,0.993041f,-0.103716f, +6.25f,0.308409f,-6.1875f, -0.191898f,0.96766f,-0.163737f, +12.5f,2.5011f,-6.1875f, 0.0758397f,0.996403f,-0.0378189f, +18.75f,-1.69303f,-6.1875f, 0.16761f,0.974057f,0.15205f, +25.0f,-0.141349f,-6.1875f, -0.204846f,0.978471f,0.0251341f, +-25.0f,-1.10316f,-12.375f, -0.0350644f,0.993748f,-0.106001f, +-18.75f,1.06711f,-12.375f, -0.309806f,0.919244f,-0.242922f, +-12.5f,3.61544f,-12.375f, -0.0506281f,0.998702f,-0.00561657f, +-6.25f,1.6504f,-12.375f, 0.322294f,0.937465f,0.131477f, +0.0f,-1.60595f,-12.375f, 0.086016f,0.995916f,0.0274459f, +6.25f,-0.849859f,-12.375f, -0.0332811f,0.997087f,0.0686255f, +12.5f,-0.942201f,-12.375f, -0.153559f,0.982185f,-0.108312f, +18.75f,0.494873f,-12.375f, 0.0753195f,0.981472f,0.176181f, +25.0f,-0.333828f,-12.375f, 0.035057f,0.987194f,0.155624f, +-25.0f,2.1862f,-18.5625f, 0.612899f,0.782306f,0.111138f, +-18.75f,-3.38259f,-18.5625f, 0.0194078f,0.992789f,-0.118297f, +-12.5f,-0.880916f,-18.5625f, -0.282251f,0.949875f,-0.13443f, +-6.25f,0.818158f,-18.5625f, 0.1476f,0.981788f,-0.119612f, +0.0f,-1.48019f,-18.5625f, -0.044551f,0.996013f,-0.0772824f, +6.25f,1.47123f,-18.5625f, -0.117036f,0.97986f,0.161792f, +12.5f,0.164076f,-18.5625f, -0.0340355f,0.978993f,0.201034f, +18.75f,2.14568f,-18.5625f, -0.0439269f,0.994859f,0.0912435f, +25.0f,0.626506f,-18.5625f, 0.208015f,0.968592f,0.136229f, +-25.0f,0.296889f,-24.75f, 0.46973f,0.844327f,-0.257809f, +-18.75f,-3.18022f,-24.75f, -0.0226758f,0.998794f,-0.0435401f, +-12.5f,1.8927f,-24.75f, -0.202772f,0.919836f,0.335836f, +-6.25f,1.46387f,-24.75f, 0.224904f,0.955746f,0.189652f, +0.0f,-2.52726f,-24.75f, -0.0435882f,0.993572f,-0.10447f, +6.25f,1.30397f,-24.75f, -0.28646f,0.956525f,-0.0547707f, +12.5f,1.85812f,-24.75f, 0.0521949f,0.979796f,0.193067f, +18.75f,1.56331f,-24.75f, -0.0270784f,0.999629f,-0.00293115f, +25.0f,1.05366f,-24.75f, 0.161f,0.986887f,-0.0115473f, +}; + +static float LargeMeshTex[] = { +0.125f,0.0f, +0.0f,0.0f, +0.125f,0.125f, +0.0f,0.125f, +0.125f,0.25f, +0.0f,0.25f, +0.125f,0.375f, +0.0f,0.375f, +0.125f,0.5f, +0.0f,0.5f, +0.125f,0.625f, +0.0f,0.625f, +0.125f,0.75f, +0.0f,0.75f, +0.125f,0.875f, +0.0f,0.875f, +0.125f,1.0f, +0.0f,1.0f, +0.25f,0.0f, +0.25f,0.125f, +0.25f,0.25f, +0.25f,0.375f, +0.25f,0.5f, +0.25f,0.625f, +0.25f,0.75f, +0.25f,0.875f, +0.25f,1.0f, +0.375f,0.0f, +0.375f,0.125f, +0.375f,0.25f, +0.375f,0.375f, +0.375f,0.5f, +0.375f,0.625f, +0.375f,0.75f, +0.375f,0.875f, +0.375f,1.0f, +0.5f,0.0f, +0.5f,0.125f, +0.5f,0.25f, +0.5f,0.375f, +0.5f,0.5f, +0.5f,0.625f, +0.5f,0.75f, +0.5f,0.875f, +0.5f,1.0f, +0.625f,0.0f, +0.625f,0.125f, +0.625f,0.25f, +0.625f,0.375f, +0.625f,0.5f, +0.625f,0.625f, +0.625f,0.75f, +0.625f,0.875f, +0.625f,1.0f, +0.75f,0.0f, +0.75f,0.125f, +0.75f,0.25f, +0.75f,0.375f, +0.75f,0.5f, +0.75f,0.625f, +0.75f,0.75f, +0.75f,0.875f, +0.75f,1.0f, +0.875f,0.0f, +0.875f,0.125f, +0.875f,0.25f, +0.875f,0.375f, +0.875f,0.5f, +0.875f,0.625f, +0.875f,0.75f, +0.875f,0.875f, +0.875f,1.0f, +1.0f,0.0f, +1.0f,0.125f, +1.0f,0.25f, +1.0f,0.375f, +1.0f,0.5f, +1.0f,0.625f, +1.0f,0.75f, +1.0f,0.875f, +1.0f,1.0f, +}; + +static unsigned short LargeMeshIdx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +18,0,19, +2,19,0, +19,2,20, +4,20,2, +20,4,21, +6,21,4, +21,6,22, +8,22,6, +22,8,23, +10,23,8, +23,10,24, +12,24,10, +24,12,25, +14,25,12, +25,14,26, +16,26,14, +27,18,28, +19,28,18, +28,19,29, +20,29,19, +29,20,30, +21,30,20, +30,21,31, +22,31,21, +31,22,32, +23,32,22, +32,23,33, +24,33,23, +33,24,34, +25,34,24, +34,25,35, +26,35,25, +36,27,37, +28,37,27, +37,28,38, +29,38,28, +38,29,39, +30,39,29, +39,30,40, +31,40,30, +40,31,41, +32,41,31, +41,32,42, +33,42,32, +42,33,43, +34,43,33, +43,34,44, +35,44,34, +45,36,46, +37,46,36, +46,37,47, +38,47,37, +47,38,48, +39,48,38, +48,39,49, +40,49,39, +49,40,50, +41,50,40, +50,41,51, +42,51,41, +51,42,52, +43,52,42, +52,43,53, +44,53,43, +54,45,55, +46,55,45, +55,46,56, +47,56,46, +56,47,57, +48,57,47, +57,48,58, +49,58,48, +58,49,59, +50,59,49, +59,50,60, +51,60,50, +60,51,61, +52,61,51, +61,52,62, +53,62,52, +63,54,64, +55,64,54, +64,55,65, +56,65,55, +65,56,66, +57,66,56, +66,57,67, +58,67,57, +67,58,68, +59,68,58, +68,59,69, +60,69,59, +69,60,70, +61,70,60, +70,61,71, +62,71,61, +72,63,73, +64,73,63, +73,64,74, +65,74,64, +74,65,75, +66,75,65, +75,66,76, +67,76,66, +76,67,77, +68,77,67, +77,68,78, +69,78,68, +78,69,79, +70,79,69, +79,70,80, +71,80,70, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/main.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/main.cpp new file mode 100644 index 000000000..6c25d5c95 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/main.cpp @@ -0,0 +1,512 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../common/common.h" +#include "../common/ctrl_func.h" +#include "../common/render_func.h" +#include "../common/perf_func.h" +#include "physics_func.h" +#include "barrel.h" +#include "landscape.h" + +#ifdef _WIN32 + #include + #include +#endif + +// ARA begin insert new code +#ifdef __ANDROID__ + #include + #include +#endif +// ARA end + +#define SAMPLE_NAME "api_physics_effects/3_sleep" + +#define ENABLE_DEBUG_DRAW + +#ifdef ENABLE_DEBUG_DRAW + //#define ENABLE_DEBUG_DRAW_CONTACT + //#define ENABLE_DEBUG_DRAW_AABB + #define ENABLE_DEBUG_DRAW_ISLAND +#endif + +static bool s_isRunning = true; + +int sceneId = 0; +bool simulating = false; + +int landscapeMeshId; +int convexMeshId; + +void render(void) +{ + render_begin(); + + const PfxVector3 colorWhite(1.0f); + const PfxVector3 colorGray(0.7f); + + for(int i=0;i -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_DOWN)) { + angX += 0.05f; + if(angX < -1.4f) angX = -1.4f; + if(angX > -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_LEFT)) { + angY -= 0.05f; + } + + if(ctrl_button_pressed(BTN_RIGHT)) { + angY += 0.05f; + } + + if(ctrl_button_pressed(BTN_ZOOM_OUT)) { + r *= 1.1f; + if(r > 500.0f) r = 500.0f; + } + + if(ctrl_button_pressed(BTN_ZOOM_IN)) { + r *= 0.9f; + if(r < 1.0f) r = 1.0f; + } + + if(ctrl_button_pressed(BTN_SCENE_RESET) == BTN_STAT_DOWN) { + physics_create_scene(sceneId); + } + + if(ctrl_button_pressed(BTN_SCENE_NEXT) == BTN_STAT_DOWN) { + physics_create_scene(++sceneId); + } + + if(ctrl_button_pressed(BTN_SIMULATION) == BTN_STAT_DOWN) { + simulating = !simulating; + } + + if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_DOWN) { + simulating = true; + } + else if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_UP || ctrl_button_pressed(BTN_STEP) == BTN_STAT_KEEP) { + simulating = false; + } + + render_set_view_angle(angX,angY,r); +} + +#ifndef _WIN32 + +// ARA begin insert new code +#ifdef __ANDROID__ + +/////////////////////////////////////////////////////////////////////////////// +// sceneChange +// +/// This function is used to change the physics scene on Android devices +/////////////////////////////////////////////////////////////////////////////// +void sceneChange() +{ + physics_create_scene(sceneId++); +} + +#else // __ANDROID__ +// ARA end + +/////////////////////////////////////////////////////////////////////////////// +// Main + +int main(void) +{ + init(); + + physics_create_scene(sceneId); + + printf("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + while (s_isRunning) { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + + shutdown(); + + printf("## %s: FINISHED ##\n", SAMPLE_NAME); + + return 0; +} + +// ARA begin insert new code +#endif // __ANDROID__ +// ARA end + +#else // _WIN32 + +/////////////////////////////////////////////////////////////////////////////// +// WinMain + +extern HDC hDC; +extern HGLRC hRC; +HWND hWnd; +HINSTANCE hInstance; + +void releaseWindow() +{ + if(hRC) { + wglMakeCurrent(0,0); + wglDeleteContext(hRC); + } + + if(hDC) ReleaseDC(hWnd,hDC); + if(hWnd) DestroyWindow(hWnd); + + UnregisterClass(SAMPLE_NAME,hInstance); +} + +LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) { + case WM_SYSCOMMAND: + { + switch (wParam) { + case SC_SCREENSAVE: + case SC_MONITORPOWER: + return 0; + } + break; + } + + case WM_CLOSE: + PostQuitMessage(0); + return 0; + + case WM_SIZE: + render_resize(LOWORD(lParam),HIWORD(lParam)); + return 0; + } + + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + +bool createWindow(char* title, int width, int height) +{ + WNDCLASS wc; + RECT rect; + rect.left=0; + rect.right=width; + rect.top=0; + rect.bottom=height; + + hInstance = GetModuleHandle(NULL); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = SAMPLE_NAME; + + if(!RegisterClass(&wc)) { + return false; + } + + AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE); + + if(!(hWnd=CreateWindowEx(WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,SAMPLE_NAME,title, + WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, + 0,0,rect.right-rect.left,rect.bottom-rect.top, + NULL,NULL,hInstance,NULL))) { + releaseWindow(); + return false; + } + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 32, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, + 0, 0, 0, 0, + 32, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + if(!(hDC=GetDC(hWnd))) + { + releaseWindow(); + OutputDebugString(""); + return FALSE; + } + + int pixelformat; + + if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){ + OutputDebugString("ChoosePixelFormat Failed...."); + return FALSE; + } + + if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE){ + OutputDebugString("SetPixelFormat Failed...."); + return FALSE; + } + + if (!(hRC=wglCreateContext(hDC))){ + OutputDebugString("Creating HGLRC Failed...."); + return FALSE; + } + + // Set Vsync + //BOOL (WINAPI *wglSwapIntervalEXT)(int) = NULL; + + //if(strstr((char*)glGetString( GL_EXTENSIONS ),"WGL_EXT_swap_control")== 0) { + //} + //else { + //wglSwapIntervalEXT = (BOOL (WINAPI*)(int))wglGetProcAddress("wglSwapIntervalEXT"); + //if(wglSwapIntervalEXT) wglSwapIntervalEXT(1); + //} + + wglMakeCurrent(hDC,hRC); + + ShowWindow(hWnd,SW_SHOW); + SetForegroundWindow(hWnd); + SetFocus(hWnd); + + render_resize(width, height); + + glClearColor(0.0f,0.0f,0.0f,0.0f); + glClearDepth(1.0f); + + return TRUE; +} + +int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) +{ + if(!createWindow(SAMPLE_NAME,DISPLAY_WIDTH,DISPLAY_HEIGHT)) { + MessageBox(NULL,"Can't create gl window.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return 0; + } + + init(); + + physics_create_scene(sceneId); + + SCE_PFX_PRINTF("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + MSG msg; + while(s_isRunning) { + if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if(msg.message==WM_QUIT) { + s_isRunning = false; + } + else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + else { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + } + + shutdown(); + + SCE_PFX_PRINTF("## %s: FINISHED ##\n", SAMPLE_NAME); + + releaseWindow(); + return (msg.wParam); +} + +#endif diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/physics.png b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/physics.png new file mode 100644 index 000000000..7230a6617 Binary files /dev/null and b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/physics.png differ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/physics_func.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/physics_func.cpp new file mode 100644 index 000000000..f549d739c --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/physics_func.cpp @@ -0,0 +1,1016 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "physics_func.h" +#include "../common/perf_func.h" + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Data + +#define NUM_RIGIDBODIES 500 +#define NUM_JOINTS 500 +#define NUM_CONTACTS 4000 + +const float timeStep = 0.016f; +const float separateBias = 0.1f; +int iteration = 5; + +//J ワールドサイズ +//E World size +PfxVector3 worldCenter(0.0f); +PfxVector3 worldExtent(500.0f); + +//J 剛体 +//E Rigid body +PfxRigidState states[NUM_RIGIDBODIES]; +PfxRigidBody bodies[NUM_RIGIDBODIES]; +PfxCollidable collidables[NUM_RIGIDBODIES]; +PfxSolverBody solverBodies[NUM_RIGIDBODIES]; +int numRigidBodies = 0; + +//J 地形を表現するためのラージメッシュ +//E Large mesh for representing a landscape +#include "landscape.h" +PfxLargeTriMesh gLargeMesh; + +//J 凸メッシュ +//E Convex Mesh +#include "barrel.h" +PfxConvexMesh gConvex; + +//J プロキシ +//E Proxies +PfxBroadphaseProxy proxies[NUM_RIGIDBODIES]; + +//J ジョイント +//E Joint +PfxConstraintPair jointPairs[NUM_JOINTS]; +PfxJoint joints[NUM_JOINTS]; +int numJoints = 0; + +//J ペア +//E Pairs +unsigned int pairSwap; +unsigned int numPairs[2]; +PfxBroadphasePair pairsBuff[2][NUM_CONTACTS]; + +//J コンタクト +//E Contacts +PfxContactManifold contacts[NUM_CONTACTS]; +int numContacts; + +PfxUInt32 contactIdPool[NUM_CONTACTS]; +int numContactIdPool; + +//J シミュレーションアイランド +//E Island generation +PfxIsland *island=NULL; +PfxUInt8 SCE_PFX_ALIGNED(16) islandBuff[32*NUM_RIGIDBODIES]; // Island buffer should be 32 * the number of rigid bodies. + +//J スリープ制御 +//E Sleep control +/* + A sleeping object wakes up, when + * a new pair related to this rigid body is created + * a pair releated to this rigid body is removed + * a rigid body's velocity or position are updated + */ + +//J スリープに入るカウント +//E Count to enter sleeping +const PfxUInt32 sleepCount = 180; + +//J 速度が閾値以下ならばスリープカウントが増加 +//E If velocity is under the following value, sleep count is increased. +const PfxFloat sleepVelocity = 0.1f; + +//J 一時バッファ +//E Temporary buffers +#define POOL_BYTES (5*1024*1024) +unsigned char SCE_PFX_ALIGNED(128) poolBuff[POOL_BYTES]; + +//J 一時バッファ用スタックアロケータ +//E Stack allocator for temporary buffers +PfxHeapManager pool(poolBuff,POOL_BYTES); + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Function + +int frame = 0; + +void broadphase() +{ + pairSwap = 1-pairSwap; + + unsigned int &numPreviousPairs = numPairs[1-pairSwap]; + unsigned int &numCurrentPairs = numPairs[pairSwap]; + PfxBroadphasePair *previousPairs = pairsBuff[1-pairSwap]; + PfxBroadphasePair *currentPairs = pairsBuff[pairSwap]; + + //J 剛体が最も分散している軸を見つける + //E Find the axis along which all rigid bodies are most widely positioned + int axis = 0; + { + PfxVector3 s(0.0f),s2(0.0f); + for(int i=0;i v[0]) axis = 1; + if(v[2] > v[axis]) axis = 2; + } + + //J ブロードフェーズプロキシの更新 + //E Create broadpahse proxies + { + for(int i=0;i 0) { + cId = contactIdPool[--numContactIdPool]; + } + else { + cId = numContacts++; + } + if(cId >= NUM_CONTACTS) { + cId = 0; + } + SCE_PFX_ASSERT(cId < NUM_CONTACTS); + pfxSetContactId(outNewPairs[i],cId); + PfxContactManifold &contact = contacts[cId]; + contact.reset(pfxGetObjectIdA(outNewPairs[i]),pfxGetObjectIdB(outNewPairs[i])); + + //J 寝てる剛体を起こす + //E Wake up sleeping rigid bodies + PfxRigidState &stateA = states[pfxGetObjectIdA(outNewPairs[i])]; + PfxRigidState &stateB = states[pfxGetObjectIdB(outNewPairs[i])]; + if(stateA.isAsleep()) { + stateA.wakeup(); + SCE_PFX_PRINTF("wakeup %u\n",stateA.getRigidBodyId()); + } + if(stateB.isAsleep()) { + stateB.wakeup(); + SCE_PFX_PRINTF("wakeup %u\n",stateB.getRigidBodyId()); + } + } + + //J 新規ペアと維持ペアを合成 + //E Merge 'new' and 'keep' pairs + numCurrentPairs = 0; + for(PfxUInt32 i=0;i sleepCount) { + numCanSleep++; + } + } + } + } + + // Deactivate Island + if(numCanSleep > 0 && numCanSleep == numActive + numSleep) { + PfxIslandUnit *islandUnit = pfxGetFirstUnitInIsland(island,(PfxUInt32)i); + for(;islandUnit!=NULL;islandUnit=pfxGetNextUnitInIsland(islandUnit)) { + if(!(SCE_PFX_MOTION_MASK_CAN_SLEEP(states[pfxGetUnitId(islandUnit)].getMotionType()))) continue; + states[pfxGetUnitId(islandUnit)].sleep(); + } + } + + // Activate Island + else if(numSleep > 0 && numActive > 0) { + PfxIslandUnit *islandUnit = pfxGetFirstUnitInIsland(island,(PfxUInt32)i); + for(;islandUnit!=NULL;islandUnit=pfxGetNextUnitInIsland(islandUnit)) { + if(!(SCE_PFX_MOTION_MASK_CAN_SLEEP(states[pfxGetUnitId(islandUnit)].getMotionType()))) continue; + states[pfxGetUnitId(islandUnit)].wakeup(); + } + } + } + } +} + +void integrate() +{ + PfxUpdateRigidStatesParam param; + param.states = states; + param.bodies = bodies; + param.numRigidBodies = numRigidBodies; + param.timeStep = timeStep; + + pfxUpdateRigidStates(param); +} + +void physics_simulate() +{ + PfxPerfCounter pc; + + for(int i=1;i 0) { + pfxReleaseLargeTriMesh(gLargeMesh); + } + + PfxInt32 ret = pfxCreateLargeTriMesh(gLargeMesh,param); + if(ret != SCE_PFX_OK) { + SCE_PFX_PRINTF("Can't create large mesh.\n"); + } + + int id = numRigidBodies++; + PfxShape shape; + shape.reset(); + shape.setLargeTriMesh(&gLargeMesh); + collidables[id].reset(); + collidables[id].addShape(shape); + collidables[id].finish(); + bodies[id].reset(); + states[id].reset(); + states[id].setPosition(PfxVector3(0.0f,-5.0f,0.0f)); + states[id].setOrientation(PfxQuat::rotationX(0.5f)*PfxQuat::rotationY(0.7f)); + states[id].setMotionType(kPfxMotionTypeFixed); + states[id].setRigidBodyId(id); +} + +void physics_create_scene(int sceneId) +{ + const int numScenes = 4; + int sid = sceneId % numScenes; + + numRigidBodies= 0; + pairSwap = 0; + numPairs[0] = 0; + numPairs[1] = 0; + numContacts = 0; + numContactIdPool = 0; + numJoints = 0; + island = NULL; + frame = 0; + + switch(sid) { + case 0: // simple primitives + createSceneBoxGround(); + createScenePrimitives(); + break; + + case 1: // joints + createSceneBoxGround(); + createSceneJoints(); + break; + + case 2: // stacking + createSceneBoxGround(); + createSceneStacking(); + break; + + case 3: // landscape + createSceneLandscape(); + createScenePrimitives(); + break; + } + + SCE_PFX_PRINTF("----- Size of rigid body buffer ------\n"); + SCE_PFX_PRINTF(" size * num = total\n"); + SCE_PFX_PRINTF("PfxRigidState %5d * %5d = %5d bytes\n",sizeof(PfxRigidState),numRigidBodies,sizeof(PfxRigidState)*numRigidBodies); + SCE_PFX_PRINTF("PfxRigidBody %5d * %5d = %5d bytes\n",sizeof(PfxRigidBody),numRigidBodies,sizeof(PfxRigidBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxCollidable %5d * %5d = %5d bytes\n",sizeof(PfxCollidable),numRigidBodies,sizeof(PfxCollidable)*numRigidBodies); + SCE_PFX_PRINTF("PfxJoint %5d * %5d = %5d bytes\n",sizeof(PfxJoint),numJoints,sizeof(PfxJoint)*numJoints); + SCE_PFX_PRINTF("PfxSolverBody %5d * %5d = %5d bytes\n",sizeof(PfxSolverBody),numRigidBodies,sizeof(PfxSolverBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxBroadphaseProxy %5d * %5d = %5d bytes\n",sizeof(PfxBroadphaseProxy),numRigidBodies,sizeof(PfxBroadphaseProxy)*numRigidBodies); + SCE_PFX_PRINTF("PfxContactManifold %5d * %5d = %5d bytes\n",sizeof(PfxContactManifold),NUM_CONTACTS,sizeof(PfxContactManifold)*NUM_CONTACTS); + SCE_PFX_PRINTF("PfxBroadphasePair %5d * %5d = %5d bytes\n",sizeof(PfxBroadphasePair),NUM_CONTACTS,sizeof(PfxBroadphasePair)*NUM_CONTACTS); + + int totalBytes = + (sizeof(PfxRigidState) + sizeof(PfxRigidBody) + sizeof(PfxCollidable) + sizeof(PfxSolverBody) + sizeof(PfxBroadphaseProxy)) * numRigidBodies + + (sizeof(PfxContactManifold) + sizeof(PfxBroadphasePair)) * NUM_CONTACTS; + SCE_PFX_PRINTF("----------------------------------------------------------\n"); + SCE_PFX_PRINTF("Total %5d bytes\n",totalBytes); +} + +/////////////////////////////////////////////////////////////////////////////// +// Initialize / Finalize Engine + +bool physics_init() +{ + return true; +} + +void physics_release() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Pick + +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2) +{ + return PfxVector3(0.0f); +} + +void physics_pick_update(const PfxVector3 &p) +{ +} + +void physics_pick_end() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Get Information + +int physics_get_num_rigidbodies() +{ + return numRigidBodies; +} + +const PfxRigidState& physics_get_state(int id) +{ + return states[id]; +} + +const PfxRigidBody& physics_get_body(int id) +{ + return bodies[id]; +} + +const PfxCollidable& physics_get_collidable(int id) +{ + return collidables[id]; +} + +int physics_get_num_contacts() +{ + return numPairs[pairSwap]; +} + +const PfxContactManifold &physics_get_contact(int id) +{ + return contacts[pfxGetConstraintId(pairsBuff[pairSwap][id])]; +} + +const PfxIsland* physics_get_islands() +{ + return island; +} diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/physics_func.h b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/physics_func.h new file mode 100644 index 000000000..bde418949 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/3_sleep/physics_func.h @@ -0,0 +1,53 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef __PHYSICS_FUNC_H__ +#define __PHYSICS_FUNC_H__ + +#define SCE_PFX_USE_PERFCOUNTER + +#include "physics_effects.h" + +using namespace sce::PhysicsEffects; + +//E Simulation +//J シミュレーション +bool physics_init(); +void physics_release(); +void physics_create_scene(int sceneId); +void physics_simulate(); + +//E Picking +//J ピッキング +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2); +void physics_pick_update(const PfxVector3 &p); +void physics_pick_end(); + +//E Change parameters +//J パラメータの取得 +int physics_get_num_rigidbodies(); +const PfxRigidState& physics_get_state(int id); +const PfxRigidBody& physics_get_body(int id); +const PfxCollidable& physics_get_collidable(int id); + +// Get contact information +int physics_get_num_contacts(); +const PfxContactManifold &physics_get_contact(int id); + +// Get simulation island +const PfxIsland* physics_get_islands(); + +#endif /* __PHYSICS_FUNC_H__ */ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/4_motion_type.windows.vcproj b/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/4_motion_type.windows.vcproj new file mode 100644 index 000000000..f6d81a282 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/4_motion_type.windows.vcproj @@ -0,0 +1,721 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/CMakeLists.txt b/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/CMakeLists.txt new file mode 100644 index 000000000..bb31f7b58 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/CMakeLists.txt @@ -0,0 +1,75 @@ +cmake_minimum_required(VERSION 2.4) + + +#this line has to appear before 'PROJECT' in order to be able to disable incremental linking +SET(MSVC_INCREMENTAL_DEFAULT ON) + +PROJECT(App_4_MotionType) + + +IF (NOT CMAKE_BUILD_TYPE) +# SET(CMAKE_BUILD_TYPE "Debug") + SET(CMAKE_BUILD_TYPE "Release") +ENDIF (NOT CMAKE_BUILD_TYPE) + + +OPTION(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC Runtime Library DLL (/MD or /MDd)" ON) +OPTION(USE_MSVC_INCREMENTAL_LINKING "Use MSVC Incremental Linking" OFF) + + +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + + +SET(App_3_Sleep_SRCS + main.cpp + physics_func.cpp + ../common/ctrl_func.win32.cpp + ../common/perf_func.win32.cpp + ../common/render_func.win32.cpp +) + + +SET(App_3_Sleep_HDRS + physics_func.h + ../common/render_func.h + ../common/common.h + ../common/ctrl_func.h + ../common/perf_func.h +) + + +INCLUDE_DIRECTORIES( + ${PHYSICS_EFFECTS_SOURCE_DIR}/include +# ${VECTOR_MATH_INCLUDE} +) + +#LINK_DIRECTORIES( +# +#) + +#ADD_DEFINITIONS(-DUNICODE) +#ADD_DEFINITIONS(-D_UNICODE) + +ADD_EXECUTABLE(App_4_MotionType WIN32 + ${App_3_Sleep_SRCS} + ${App_3_Sleep_HDRS} +) +TARGET_LINK_LIBRARIES(App_4_MotionType + PfxBaseLevel + PfxLowLevel + PfxUtil + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} +) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(App_4_MotionType PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(App_4_MotionType PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(App_4_MotionType PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF() + + + + \ No newline at end of file diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/main.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/main.cpp new file mode 100644 index 000000000..62a53106a --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/main.cpp @@ -0,0 +1,481 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../common/common.h" +#include "../common/ctrl_func.h" +#include "../common/render_func.h" +#include "../common/perf_func.h" +#include "physics_func.h" + +#ifdef _WIN32 + #include + #include +#endif + +// ARA begin insert new code +#ifdef __ANDROID__ + #include + #include +#endif +// ARA end + +#define SAMPLE_NAME "api_physics_effects/4_motion_type" + +//#define ENABLE_DEBUG_DRAW + +#ifdef ENABLE_DEBUG_DRAW + #define ENABLE_DEBUG_DRAW_CONTACT + #define ENABLE_DEBUG_DRAW_AABB + #define ENABLE_DEBUG_DRAW_ISLAND +#endif + +static bool s_isRunning = true; + +int sceneId = 0; +bool simulating = false; + +void render(void) +{ + render_begin(); + + const PfxVector3 colorWhite(1.0f); + const PfxVector3 colorGray(0.7f); + + for(int i=0;i -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_DOWN)) { + angX += 0.05f; + if(angX < -1.4f) angX = -1.4f; + if(angX > -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_LEFT)) { + angY -= 0.05f; + } + + if(ctrl_button_pressed(BTN_RIGHT)) { + angY += 0.05f; + } + + if(ctrl_button_pressed(BTN_ZOOM_OUT)) { + r *= 1.1f; + if(r > 500.0f) r = 500.0f; + } + + if(ctrl_button_pressed(BTN_ZOOM_IN)) { + r *= 0.9f; + if(r < 1.0f) r = 1.0f; + } + + if(ctrl_button_pressed(BTN_SCENE_RESET) == BTN_STAT_DOWN) { + physics_create_scene(sceneId); + } + + if(ctrl_button_pressed(BTN_SCENE_NEXT) == BTN_STAT_DOWN) { + physics_create_scene(++sceneId); + } + + if(ctrl_button_pressed(BTN_SIMULATION) == BTN_STAT_DOWN) { + simulating = !simulating; + } + + if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_DOWN) { + simulating = true; + } + else if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_UP || ctrl_button_pressed(BTN_STEP) == BTN_STAT_KEEP) { + simulating = false; + } + + render_set_view_angle(angX,angY,r); +} + +#ifndef _WIN32 + +// ARA begin insert new code +#ifdef __ANDROID__ + +/////////////////////////////////////////////////////////////////////////////// +// sceneChange +// +/// This function is used to change the physics scene on Android devices +/////////////////////////////////////////////////////////////////////////////// +void sceneChange() +{ + physics_create_scene(sceneId++); +} + +#else // __ANDROID__ +// ARA end + +/////////////////////////////////////////////////////////////////////////////// +// Main + +int main(void) +{ + init(); + + physics_create_scene(sceneId); + + printf("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + while (s_isRunning) { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + + shutdown(); + + printf("## %s: FINISHED ##\n", SAMPLE_NAME); + + return 0; +} + +// ARA begin insert new code +#endif // __ANDROID__ +// ARA end + +#else // _WIN32 + +/////////////////////////////////////////////////////////////////////////////// +// WinMain + +extern HDC hDC; +extern HGLRC hRC; +HWND hWnd; +HINSTANCE hInstance; + +void releaseWindow() +{ + if(hRC) { + wglMakeCurrent(0,0); + wglDeleteContext(hRC); + } + + if(hDC) ReleaseDC(hWnd,hDC); + if(hWnd) DestroyWindow(hWnd); + + UnregisterClass(SAMPLE_NAME,hInstance); +} + +LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) { + case WM_SYSCOMMAND: + { + switch (wParam) { + case SC_SCREENSAVE: + case SC_MONITORPOWER: + return 0; + } + break; + } + + case WM_CLOSE: + PostQuitMessage(0); + return 0; + + case WM_SIZE: + render_resize(LOWORD(lParam),HIWORD(lParam)); + return 0; + } + + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + +bool createWindow(char* title, int width, int height) +{ + WNDCLASS wc; + RECT rect; + rect.left=0; + rect.right=width; + rect.top=0; + rect.bottom=height; + + hInstance = GetModuleHandle(NULL); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = SAMPLE_NAME; + + if(!RegisterClass(&wc)) { + return false; + } + + AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE); + + if(!(hWnd=CreateWindowEx(WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,SAMPLE_NAME,title, + WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, + 0,0,rect.right-rect.left,rect.bottom-rect.top, + NULL,NULL,hInstance,NULL))) { + releaseWindow(); + return false; + } + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 32, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, + 0, 0, 0, 0, + 32, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + if(!(hDC=GetDC(hWnd))) + { + releaseWindow(); + OutputDebugString(""); + return FALSE; + } + + int pixelformat; + + if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){ + OutputDebugString("ChoosePixelFormat Failed...."); + return FALSE; + } + + if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE){ + OutputDebugString("SetPixelFormat Failed...."); + return FALSE; + } + + if (!(hRC=wglCreateContext(hDC))){ + OutputDebugString("Creating HGLRC Failed...."); + return FALSE; + } + + // Set Vsync + //BOOL (WINAPI *wglSwapIntervalEXT)(int) = NULL; + + //if(strstr((char*)glGetString( GL_EXTENSIONS ),"WGL_EXT_swap_control")== 0) { + //} + //else { + //wglSwapIntervalEXT = (BOOL (WINAPI*)(int))wglGetProcAddress("wglSwapIntervalEXT"); + //if(wglSwapIntervalEXT) wglSwapIntervalEXT(1); + //} + + wglMakeCurrent(hDC,hRC); + + ShowWindow(hWnd,SW_SHOW); + SetForegroundWindow(hWnd); + SetFocus(hWnd); + + render_resize(width, height); + + glClearColor(0.0f,0.0f,0.0f,0.0f); + glClearDepth(1.0f); + + return TRUE; +} + +int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) +{ + if(!createWindow(SAMPLE_NAME,DISPLAY_WIDTH,DISPLAY_HEIGHT)) { + MessageBox(NULL,"Can't create gl window.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return 0; + } + + init(); + + physics_create_scene(sceneId); + + SCE_PFX_PRINTF("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + MSG msg; + while(s_isRunning) { + if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if(msg.message==WM_QUIT) { + s_isRunning = false; + } + else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + else { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + } + + shutdown(); + + SCE_PFX_PRINTF("## %s: FINISHED ##\n", SAMPLE_NAME); + + releaseWindow(); + return (msg.wParam); +} + +#endif diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/physics.png b/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/physics.png new file mode 100644 index 000000000..c1da418b4 Binary files /dev/null and b/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/physics.png differ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/physics_func.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/physics_func.cpp new file mode 100644 index 000000000..405c95f2a --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/physics_func.cpp @@ -0,0 +1,822 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "physics_func.h" +#include "../common/perf_func.h" + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Data + +#define NUM_RIGIDBODIES 500 +#define NUM_JOINTS 500 +#define NUM_CONTACTS 4000 + +const float timeStep = 0.016f; +const float separateBias = 0.1f; +int iteration = 5; + +//J ワールドサイズ +//E World size +PfxVector3 worldCenter(0.0f); +PfxVector3 worldExtent(500.0f); + +//J 剛体 +//E Rigid body +PfxRigidState states[NUM_RIGIDBODIES]; +PfxRigidBody bodies[NUM_RIGIDBODIES]; +PfxCollidable collidables[NUM_RIGIDBODIES]; +PfxSolverBody solverBodies[NUM_RIGIDBODIES]; +int numRigidBodies = 0; + +//J プロキシ +//E Proxies +PfxBroadphaseProxy proxies[NUM_RIGIDBODIES]; + +//J ジョイント +//E Joint +PfxConstraintPair jointPairs[NUM_JOINTS]; +PfxJoint joints[NUM_JOINTS]; +int numJoints = 0; + +//J ペア +//E Pairs +unsigned int pairSwap; +unsigned int numPairs[2]; +PfxBroadphasePair pairsBuff[2][NUM_CONTACTS]; + +//J コンタクト +//E Contacts +PfxContactManifold contacts[NUM_CONTACTS]; +int numContacts; + +PfxUInt32 contactIdPool[NUM_CONTACTS]; +int numContactIdPool; + +//J シミュレーションアイランド +//E Island generation +PfxIsland *island=NULL; +PfxUInt8 SCE_PFX_ALIGNED(16) islandBuff[32*NUM_RIGIDBODIES]; // Island buffer should be 32 * the number of rigid bodies. + +//J スリープ制御 +//E Sleep control +/* + A sleeping object wakes up, when + * a new pair related to this rigid body is created + * a pair releated to this rigid body is removed + * a rigid body's velocity or position are updated + */ + +//J スリープに入るカウント +//E Count to enter sleeping +const PfxUInt32 sleepCount = 180; + +//J 速度が閾値以下ならばスリープカウントが増加 +//E If velocity is under the following value, sleep count is increased. +const PfxFloat sleepVelocity = 0.1f; + +//J 一時バッファ +//E Temporary buffers +#define POOL_BYTES (5*1024*1024) +unsigned char SCE_PFX_ALIGNED(128) poolBuff[POOL_BYTES]; + +//J 一時バッファ用スタックアロケータ +//E Stack allocator for temporary buffers +PfxHeapManager pool(poolBuff,POOL_BYTES); + +// Keyframe +void updateKeyframe(); +int keyframeId; + +// Trigger +void updateTrigger(); +int triggerId; + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Function + +int frame = 0; + +void broadphase() +{ + pairSwap = 1-pairSwap; + + unsigned int &numPreviousPairs = numPairs[1-pairSwap]; + unsigned int &numCurrentPairs = numPairs[pairSwap]; + PfxBroadphasePair *previousPairs = pairsBuff[1-pairSwap]; + PfxBroadphasePair *currentPairs = pairsBuff[pairSwap]; + + //J 剛体が最も分散している軸を見つける + //E Find the axis along which all rigid bodies are most widely positioned + int axis = 0; + { + PfxVector3 s(0.0f),s2(0.0f); + for(int i=0;i v[0]) axis = 1; + if(v[2] > v[axis]) axis = 2; + } + + //J ブロードフェーズプロキシの更新 + //E Create broadpahse proxies + { + for(int i=0;i 0) { + cId = contactIdPool[--numContactIdPool]; + } + else { + cId = numContacts++; + } + if(cId >= NUM_CONTACTS) { + cId = 0; + } + SCE_PFX_ASSERT(cId < NUM_CONTACTS); + pfxSetContactId(outNewPairs[i],cId); + PfxContactManifold &contact = contacts[cId]; + contact.reset(pfxGetObjectIdA(outNewPairs[i]),pfxGetObjectIdB(outNewPairs[i])); + + //J 寝てる剛体を起こす + //E Wake up sleeping rigid bodies + PfxRigidState &stateA = states[pfxGetObjectIdA(outNewPairs[i])]; + PfxRigidState &stateB = states[pfxGetObjectIdB(outNewPairs[i])]; + if(stateA.isAsleep()) { + stateA.wakeup(); + } + if(stateB.isAsleep()) { + stateB.wakeup(); + } + } + + //J 新規ペアと維持ペアを合成 + //E Merge 'new' and 'keep' pairs + numCurrentPairs = 0; + for(PfxUInt32 i=0;i sleepCount) { + numCanSleep++; + } + } + } + } + + // Deactivate Island + if(numCanSleep > 0 && numCanSleep == numActive + numSleep) { + PfxIslandUnit *islandUnit = pfxGetFirstUnitInIsland(island,(PfxUInt32)i); + for(;islandUnit!=NULL;islandUnit=pfxGetNextUnitInIsland(islandUnit)) { + if(!(SCE_PFX_MOTION_MASK_CAN_SLEEP(states[pfxGetUnitId(islandUnit)].getMotionType()))) continue; + states[pfxGetUnitId(islandUnit)].sleep(); + } + } + + // Activate Island + else if(numSleep > 0 && numActive > 0) { + PfxIslandUnit *islandUnit = pfxGetFirstUnitInIsland(island,(PfxUInt32)i); + for(;islandUnit!=NULL;islandUnit=pfxGetNextUnitInIsland(islandUnit)) { + if(!(SCE_PFX_MOTION_MASK_CAN_SLEEP(states[pfxGetUnitId(islandUnit)].getMotionType()))) continue; + states[pfxGetUnitId(islandUnit)].wakeup(); + } + } + } + } +} + +void integrate() +{ + PfxUpdateRigidStatesParam param; + param.states = states; + param.bodies = bodies; + param.numRigidBodies = numRigidBodies; + param.timeStep = timeStep; + + pfxUpdateRigidStates(param); +} + +void physics_simulate() +{ + PfxPerfCounter pc; + + for(int i=1;i=0) updateKeyframe(); + if(triggerId>=0) updateTrigger(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Create Scene + +int createBrick(int id,const PfxVector3 &pos,const PfxQuat &rot,const PfxVector3 &boxSize,PfxFloat mass) +{ + PfxBox box(boxSize); + PfxShape shape; + shape.reset(); + shape.setBox(box); + collidables[id].reset(); + collidables[id].addShape(shape); + collidables[id].finish(); + bodies[id].reset(); + bodies[id].setRestitution(0.0f); + bodies[id].setMass(mass); + bodies[id].setInertia(pfxCalcInertiaBox(boxSize,mass)); + states[id].reset(); + states[id].setPosition(pos); + states[id].setOrientation(rot); + states[id].setMotionType(kPfxMotionTypeActive); + states[id].setUseSleep(1); // sleep mode ON + states[id].setRigidBodyId(id); + + return id; +} + +void createWall(const PfxVector3 &offsetPosition,int stackSize,const PfxVector3 &boxSize) +{ + PfxFloat bodyMass = 0.5f; + + PfxFloat diffX = boxSize[0] * 1.02f; + PfxFloat diffY = boxSize[1] * 1.02f; + PfxFloat diffZ = boxSize[2] * 1.02f; + + PfxFloat offset = -stackSize * (diffZ * 2.0f) * 0.5f; + PfxVector3 pos(0.0f, diffY, 0.0f); + + while(stackSize) { + for(int i=0;i 0) { + SCE_PFX_PRINTF("Find Contact %u\n",pfxGetObjectIdB(pair)); + } + } + if(pfxGetObjectIdB(pair) == triggerId) { + if(contact.getNumContacts() > 0) { + SCE_PFX_PRINTF("Find Contact %u\n",pfxGetObjectIdA(pair)); + } + } + } +} + +void createSceneBoxGround() +{ + int id = numRigidBodies++; + PfxBox box(150.0f,2.5f,150.0f); + PfxShape shape; + shape.reset(); + shape.setBox(box); + collidables[id].reset(); + collidables[id].addShape(shape); + collidables[id].finish(); + bodies[id].reset(); + states[id].reset(); + states[id].setPosition(PfxVector3(0.0f,-2.5f,0.0f)); + states[id].setMotionType(kPfxMotionTypeFixed); + states[id].setRigidBodyId(id); +} + +void physics_create_scene(int sceneId) +{ + const int numScenes = 3; + int sid = sceneId % numScenes; + + numRigidBodies= 0; + pairSwap = 0; + numPairs[0] = 0; + numPairs[1] = 0; + numContacts = 0; + numContactIdPool = 0; + numJoints = 0; + island = NULL; + frame = 0; + + keyframeId = -1; + triggerId = -1; + + switch(sid) { + case 0: + createSceneBoxGround(); + createSceneKeyframe(); + createWall(PfxVector3(0.0f,1.0f,0.0f),5,PfxVector3(0.5f)); + break; + + case 1: + createSceneBoxGround(); + createSceneOneWay(); + break; + + case 2: + createSceneBoxGround(); + createSceneTrigger(); + break; + } + + SCE_PFX_PRINTF("----- Size of rigid body buffer ------\n"); + SCE_PFX_PRINTF(" size * num = total\n"); + SCE_PFX_PRINTF("PfxRigidState %5d * %5d = %5d bytes\n",sizeof(PfxRigidState),numRigidBodies,sizeof(PfxRigidState)*numRigidBodies); + SCE_PFX_PRINTF("PfxRigidBody %5d * %5d = %5d bytes\n",sizeof(PfxRigidBody),numRigidBodies,sizeof(PfxRigidBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxCollidable %5d * %5d = %5d bytes\n",sizeof(PfxCollidable),numRigidBodies,sizeof(PfxCollidable)*numRigidBodies); + SCE_PFX_PRINTF("PfxJoint %5d * %5d = %5d bytes\n",sizeof(PfxJoint),numJoints,sizeof(PfxJoint)*numJoints); + SCE_PFX_PRINTF("PfxSolverBody %5d * %5d = %5d bytes\n",sizeof(PfxSolverBody),numRigidBodies,sizeof(PfxSolverBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxBroadphaseProxy %5d * %5d = %5d bytes\n",sizeof(PfxBroadphaseProxy),numRigidBodies,sizeof(PfxBroadphaseProxy)*numRigidBodies); + SCE_PFX_PRINTF("PfxContactManifold %5d * %5d = %5d bytes\n",sizeof(PfxContactManifold),NUM_CONTACTS,sizeof(PfxContactManifold)*NUM_CONTACTS); + SCE_PFX_PRINTF("PfxBroadphasePair %5d * %5d = %5d bytes\n",sizeof(PfxBroadphasePair),NUM_CONTACTS,sizeof(PfxBroadphasePair)*NUM_CONTACTS); + + int totalBytes = + (sizeof(PfxRigidState) + sizeof(PfxRigidBody) + sizeof(PfxCollidable) + sizeof(PfxSolverBody) + sizeof(PfxBroadphaseProxy)) * numRigidBodies + + (sizeof(PfxContactManifold) + sizeof(PfxBroadphasePair)) * NUM_CONTACTS; + SCE_PFX_PRINTF("----------------------------------------------------------\n"); + SCE_PFX_PRINTF("Total %5d bytes\n",totalBytes); +} + +/////////////////////////////////////////////////////////////////////////////// +// Initialize / Finalize Engine + +bool physics_init() +{ + return true; +} + +void physics_release() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Pick + +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2) +{ + return PfxVector3(0.0f); +} + +void physics_pick_update(const PfxVector3 &p) +{ +} + +void physics_pick_end() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Get Information + +int physics_get_num_rigidbodies() +{ + return numRigidBodies; +} + +const PfxRigidState& physics_get_state(int id) +{ + return states[id]; +} + +const PfxRigidBody& physics_get_body(int id) +{ + return bodies[id]; +} + +const PfxCollidable& physics_get_collidable(int id) +{ + return collidables[id]; +} + +int physics_get_num_contacts() +{ + return numPairs[pairSwap]; +} + +const PfxContactManifold &physics_get_contact(int id) +{ + return contacts[pfxGetConstraintId(pairsBuff[pairSwap][id])]; +} + +const PfxIsland* physics_get_islands() +{ + return island; +} diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/physics_func.h b/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/physics_func.h new file mode 100644 index 000000000..bde418949 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/4_motion_type/physics_func.h @@ -0,0 +1,53 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef __PHYSICS_FUNC_H__ +#define __PHYSICS_FUNC_H__ + +#define SCE_PFX_USE_PERFCOUNTER + +#include "physics_effects.h" + +using namespace sce::PhysicsEffects; + +//E Simulation +//J シミュレーション +bool physics_init(); +void physics_release(); +void physics_create_scene(int sceneId); +void physics_simulate(); + +//E Picking +//J ピッキング +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2); +void physics_pick_update(const PfxVector3 &p); +void physics_pick_end(); + +//E Change parameters +//J パラメータの取得 +int physics_get_num_rigidbodies(); +const PfxRigidState& physics_get_state(int id); +const PfxRigidBody& physics_get_body(int id); +const PfxCollidable& physics_get_collidable(int id); + +// Get contact information +int physics_get_num_contacts(); +const PfxContactManifold &physics_get_contact(int id); + +// Get simulation island +const PfxIsland* physics_get_islands(); + +#endif /* __PHYSICS_FUNC_H__ */ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/5_raycast.windows.vcproj b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/5_raycast.windows.vcproj new file mode 100644 index 000000000..c92d9152c --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/5_raycast.windows.vcproj @@ -0,0 +1,721 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/CMakeLists.txt b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/CMakeLists.txt new file mode 100644 index 000000000..f8687f7c0 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/CMakeLists.txt @@ -0,0 +1,77 @@ +cmake_minimum_required(VERSION 2.4) + + +#this line has to appear before 'PROJECT' in order to be able to disable incremental linking +SET(MSVC_INCREMENTAL_DEFAULT ON) + +PROJECT(App_5_Raycast) + + +IF (NOT CMAKE_BUILD_TYPE) +# SET(CMAKE_BUILD_TYPE "Debug") + SET(CMAKE_BUILD_TYPE "Release") +ENDIF (NOT CMAKE_BUILD_TYPE) + + +OPTION(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC Runtime Library DLL (/MD or /MDd)" ON) +OPTION(USE_MSVC_INCREMENTAL_LINKING "Use MSVC Incremental Linking" OFF) + + +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + + +SET(App_5_Raycast_SRCS + main.cpp + physics_func.cpp + ../common/ctrl_func.win32.cpp + ../common/perf_func.win32.cpp + ../common/render_func.win32.cpp +) + + +SET(App_5_Raycast_HDRS + physics_func.h + landscape.h + barrel.h + ../common/render_func.h + ../common/common.h + ../common/ctrl_func.h + ../common/perf_func.h +) + + +INCLUDE_DIRECTORIES( + ${PHYSICS_EFFECTS_SOURCE_DIR}/include +# ${VECTOR_MATH_INCLUDE} +) + +#LINK_DIRECTORIES( +# +#) + +#ADD_DEFINITIONS(-DUNICODE) +#ADD_DEFINITIONS(-D_UNICODE) + +ADD_EXECUTABLE(App_5_Raycast WIN32 + ${App_5_Raycast_SRCS} + ${App_5_Raycast_HDRS} +) +TARGET_LINK_LIBRARIES(App_5_Raycast + PfxBaseLevel + PfxLowLevel + PfxUtil + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} +) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(App_5_Raycast PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(App_5_Raycast PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(App_5_Raycast PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF() + + + + \ No newline at end of file diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/barrel.h b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/barrel.h new file mode 100644 index 000000000..6574fa862 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/barrel.h @@ -0,0 +1,202 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define BarrelVtxCount 57 +#define BarrelIdxCount 180 + +static float BarrelVtx[] = { +0.0f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +-0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +0.0f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +-0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.957307f,-0.289072f,0.0f, +0.404509f,0.0f,-0.293893f, 0.809017f,0.0f,-0.587785f, +0.5f,0.0f,0.0f, 1.0f,0.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.774478f,-0.289072f,-0.562691f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +-0.154509f,0.0f,-0.475528f, -0.309017f,0.0f,-0.951057f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +-0.107853f,-0.5f,-0.331936f, -0.295824f,-0.289072f,-0.910453f, +-0.404509f,0.0f,-0.293893f, -0.809017f,0.0f,-0.587785f, +-0.282362f,-0.5f,-0.205148f, -0.774478f,-0.289072f,-0.562691f, +-0.5f,0.0f,0.0f, -1.0f,0.0f,0.0f, +-0.349018f,-0.5f,0.0f, -0.957307f,-0.289072f,0.0f, +-0.404508f,0.0f,0.293893f, -0.809017f,0.0f,0.587785f, +-0.282362f,-0.5f,0.205148f, -0.774478f,-0.289072f,0.562691f, +-0.154509f,0.0f,0.475528f, -0.309017f,0.0f,0.951056f, +-0.107853f,-0.5f,0.331936f, -0.295824f,-0.289072f,0.910453f, +0.154509f,0.0f,0.475528f, 0.309017f,0.0f,0.951056f, +0.107853f,-0.5f,0.331936f, 0.295824f,-0.289072f,0.910453f, +0.404509f,0.0f,0.293892f, 0.809017f,0.0f,0.587785f, +0.282362f,-0.5f,0.205148f, 0.774478f,-0.289072f,0.562691f, +0.282362f,0.5f,-0.205148f, 0.774478f,0.289072f,-0.562691f, +0.349018f,0.5f,0.0f, 0.957307f,0.289072f,0.0f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.107853f,0.5f,-0.331936f, -0.295824f,0.289072f,-0.910453f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.282362f,0.5f,-0.205148f, -0.774478f,0.289072f,-0.562691f, +-0.349018f,0.5f,0.0f, -0.957307f,0.289072f,0.0f, +-0.282362f,0.5f,0.205148f, -0.774478f,0.289072f,0.562691f, +-0.107853f,0.5f,0.331936f, -0.295824f,0.289072f,0.910453f, +0.107853f,0.5f,0.331936f, 0.295824f,0.289072f,0.910453f, +0.282362f,0.5f,0.205148f, 0.774478f,0.289072f,0.562691f, +}; + +static float BarrelTex[] = { +0.0f,0.5f, +0.0f,0.85f, +0.0f,0.75f, +0.0f,0.95f, +0.0f,0.05f, +0.0f,-0.05f, +0.0f,0.15f, +0.0f,0.25f, +0.0f,0.35f, +0.0f,0.45f, +0.0f,0.55f, +0.0f,0.65f, +1.0f,0.5f, +1.0f,0.75f, +1.0f,0.85f, +1.0f,0.95f, +1.0f,-0.05f, +1.0f,0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +0.0f,0.75f, +0.5f,0.85f, +0.5f,0.75f, +0.0f,0.85f, +0.5f,0.95f, +0.0f,0.95f, +0.0f,-0.05f, +0.5f,0.05f, +0.5f,-0.05f, +0.0f,0.05f, +0.5f,0.15f, +0.0f,0.15f, +0.5f,0.25f, +0.0f,0.25f, +0.5f,0.35f, +0.0f,0.35f, +0.5f,0.45f, +0.0f,0.45f, +0.5f,0.55f, +0.0f,0.55f, +0.5f,0.65f, +0.0f,0.65f, +1.0f,0.85f, +1.0f,0.75f, +1.0f,0.95f, +1.0f,0.05f, +1.0f,-0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +}; + +static unsigned short BarrelIdx[] = { +0,1,2, +0,3,1, +0,4,5, +0,6,4, +0,7,6, +0,8,7, +0,9,8, +0,10,9, +0,11,10, +0,2,11, +12,13,14, +12,14,15, +12,16,17, +12,17,18, +12,18,19, +12,19,20, +12,20,21, +12,21,22, +12,22,23, +12,23,13, +24,25,26, +24,27,25, +27,28,25, +27,29,28, +30,31,32, +30,33,31, +33,34,31, +33,35,34, +35,36,34, +35,37,36, +37,38,36, +37,39,38, +39,40,38, +39,41,40, +41,42,40, +41,43,42, +43,44,42, +43,45,44, +45,26,44, +45,24,26, +26,46,47, +26,25,46, +25,48,46, +25,28,48, +32,49,50, +32,31,49, +31,51,49, +31,34,51, +34,52,51, +34,36,52, +36,53,52, +36,38,53, +38,54,53, +38,40,54, +40,55,54, +40,42,55, +42,56,55, +42,44,56, +44,47,56, +44,26,47, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/landscape.h b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/landscape.h new file mode 100644 index 000000000..00f6cffd2 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/landscape.h @@ -0,0 +1,318 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define LargeMeshVtxCount 81 +#define LargeMeshIdxCount 384 + +static float LargeMeshVtx[] = { +-25.0f,-2.19407f,18.5625f, 0.232976f,0.967754f,0.0957829f, +-25.0f,0.0644502f,24.75f, 0.188094f,0.871343f,-0.45319f, +-18.75f,-4.50287f,18.5625f, -0.0716098f,0.995449f,0.0628767f, +-18.75f,-0.39999f,24.75f, -0.0602794f,0.895848f,-0.440253f, +-12.5f,-1.2166f,18.5625f, -0.269469f,0.961403f,0.0555879f, +-12.5f,-0.942431f,24.75f, -0.0997841f,0.993258f,0.0589987f, +-6.25f,1.93598f,18.5625f, -0.283933f,0.956351f,-0.0691025f, +-6.25f,-0.445954f,24.75f, -0.180725f,0.942766f,0.280233f, +0.0f,2.76983f,18.5625f, 0.171645f,0.984908f,0.0222501f, +0.0f,2.76642f,24.75f, 0.0784993f,0.995428f,-0.0544117f, +6.25f,-2.53736f,18.5625f, 0.248298f,0.965028f,0.0840741f, +6.25f,-0.915645f,24.75f, 0.164311f,0.945856f,-0.279926f, +12.5f,-1.60054f,18.5625f, -0.180435f,0.983586f,0.00115547f, +12.5f,0.831925f,24.75f, -0.0692495f,0.964821f,-0.253623f, +18.75f,-0.800282f,18.5625f, 0.10755f,0.951538f,0.288112f, +18.75f,-1.47284f,24.75f, 0.232178f,0.972664f,0.00429361f, +25.0f,-2.78379f,18.5625f, 0.1833f,0.937477f,0.295867f, +25.0f,-0.967508f,24.75f, -0.0773477f,0.956641f,-0.280812f, +-25.0f,-0.352038f,12.375f, -0.192222f,0.972435f,0.131987f, +-18.75f,0.681228f,12.375f, -0.107779f,0.962569f,0.248686f, +-12.5f,2.72065f,12.375f, 0.0520846f,0.993034f,0.105692f, +-6.25f,-1.78776f,12.375f, -0.0133223f,0.99674f,-0.0795754f, +0.0f,1.57707f,12.375f, -0.129025f,0.969662f,-0.207627f, +6.25f,0.424356f,12.375f, 0.180995f,0.97074f,0.157815f, +12.5f,0.283234f,12.375f, -0.16285f,0.973539f,0.160316f, +18.75f,2.57015f,12.375f, -0.165454f,0.978339f,0.124408f, +25.0f,3.07363f,12.375f, -0.00454559f,0.988151f,0.153417f, +-25.0f,-0.893751f,6.1875f, -0.0836251f,0.990084f,-0.112876f, +-18.75f,0.930932f,6.1875f, 0.00269413f,0.971838f,-0.235633f, +-12.5f,-0.684529f,6.1875f, -0.010319f,0.927048f,-0.3748f, +-6.25f,-0.661383f,6.1875f, 0.012265f,0.999875f,-0.00994222f, +0.0f,0.385718f,6.1875f, -0.15435f,0.984937f,-0.0779465f, +6.25f,0.589796f,6.1875f, 0.0241717f,0.999582f,-0.0158589f, +12.5f,0.47454f,6.1875f, -0.017184f,0.997953f,-0.0616073f, +18.75f,1.59939f,6.1875f, -0.0902706f,0.957309f,-0.274609f, +25.0f,1.13434f,6.1875f, 0.0346006f,0.957441f,-0.286547f, +-25.0f,0.74548f,0.0f, 0.329903f,0.930812f,0.157334f, +-18.75f,-2.47437f,0.0f, 0.247844f,0.968142f,0.0357041f, +-12.5f,-4.16309f,1.81975e-007f, -0.0623898f,0.997626f,-0.0291436f, +-6.25f,-0.700022f,0.0f, -0.217067f,0.974987f,-0.0477624f, +0.0f,-0.0957388f,0.0f, -0.117693f,0.990712f,-0.068098f, +6.25f,0.614077f,0.0f, -0.0713214f,0.997305f,0.01722f, +12.5f,0.299109f,0.0f, 0.218606f,0.968641f,0.118094f, +18.75f,-1.71753f,0.0f, 0.0339493f,0.985612f,-0.165579f, +25.0f,-1.12638f,0.0f, -0.0547573f,0.989177f,-0.136126f, +-25.0f,-0.403319f,-6.1875f, -0.1263f,0.989211f,-0.074223f, +-18.75f,-0.0730335f,-6.1875f, 0.0173428f,0.965382f,0.260261f, +-12.5f,-0.450125f,-6.1875f, 0.0658811f,0.875f,0.479619f, +-6.25f,-0.180204f,-6.1875f, 0.0116584f,0.981445f,0.19139f, +0.0f,-0.632679f,-6.1875f, -0.0557983f,0.993041f,-0.103716f, +6.25f,0.308409f,-6.1875f, -0.191898f,0.96766f,-0.163737f, +12.5f,2.5011f,-6.1875f, 0.0758397f,0.996403f,-0.0378189f, +18.75f,-1.69303f,-6.1875f, 0.16761f,0.974057f,0.15205f, +25.0f,-0.141349f,-6.1875f, -0.204846f,0.978471f,0.0251341f, +-25.0f,-1.10316f,-12.375f, -0.0350644f,0.993748f,-0.106001f, +-18.75f,1.06711f,-12.375f, -0.309806f,0.919244f,-0.242922f, +-12.5f,3.61544f,-12.375f, -0.0506281f,0.998702f,-0.00561657f, +-6.25f,1.6504f,-12.375f, 0.322294f,0.937465f,0.131477f, +0.0f,-1.60595f,-12.375f, 0.086016f,0.995916f,0.0274459f, +6.25f,-0.849859f,-12.375f, -0.0332811f,0.997087f,0.0686255f, +12.5f,-0.942201f,-12.375f, -0.153559f,0.982185f,-0.108312f, +18.75f,0.494873f,-12.375f, 0.0753195f,0.981472f,0.176181f, +25.0f,-0.333828f,-12.375f, 0.035057f,0.987194f,0.155624f, +-25.0f,2.1862f,-18.5625f, 0.612899f,0.782306f,0.111138f, +-18.75f,-3.38259f,-18.5625f, 0.0194078f,0.992789f,-0.118297f, +-12.5f,-0.880916f,-18.5625f, -0.282251f,0.949875f,-0.13443f, +-6.25f,0.818158f,-18.5625f, 0.1476f,0.981788f,-0.119612f, +0.0f,-1.48019f,-18.5625f, -0.044551f,0.996013f,-0.0772824f, +6.25f,1.47123f,-18.5625f, -0.117036f,0.97986f,0.161792f, +12.5f,0.164076f,-18.5625f, -0.0340355f,0.978993f,0.201034f, +18.75f,2.14568f,-18.5625f, -0.0439269f,0.994859f,0.0912435f, +25.0f,0.626506f,-18.5625f, 0.208015f,0.968592f,0.136229f, +-25.0f,0.296889f,-24.75f, 0.46973f,0.844327f,-0.257809f, +-18.75f,-3.18022f,-24.75f, -0.0226758f,0.998794f,-0.0435401f, +-12.5f,1.8927f,-24.75f, -0.202772f,0.919836f,0.335836f, +-6.25f,1.46387f,-24.75f, 0.224904f,0.955746f,0.189652f, +0.0f,-2.52726f,-24.75f, -0.0435882f,0.993572f,-0.10447f, +6.25f,1.30397f,-24.75f, -0.28646f,0.956525f,-0.0547707f, +12.5f,1.85812f,-24.75f, 0.0521949f,0.979796f,0.193067f, +18.75f,1.56331f,-24.75f, -0.0270784f,0.999629f,-0.00293115f, +25.0f,1.05366f,-24.75f, 0.161f,0.986887f,-0.0115473f, +}; + +static float LargeMeshTex[] = { +0.125f,0.0f, +0.0f,0.0f, +0.125f,0.125f, +0.0f,0.125f, +0.125f,0.25f, +0.0f,0.25f, +0.125f,0.375f, +0.0f,0.375f, +0.125f,0.5f, +0.0f,0.5f, +0.125f,0.625f, +0.0f,0.625f, +0.125f,0.75f, +0.0f,0.75f, +0.125f,0.875f, +0.0f,0.875f, +0.125f,1.0f, +0.0f,1.0f, +0.25f,0.0f, +0.25f,0.125f, +0.25f,0.25f, +0.25f,0.375f, +0.25f,0.5f, +0.25f,0.625f, +0.25f,0.75f, +0.25f,0.875f, +0.25f,1.0f, +0.375f,0.0f, +0.375f,0.125f, +0.375f,0.25f, +0.375f,0.375f, +0.375f,0.5f, +0.375f,0.625f, +0.375f,0.75f, +0.375f,0.875f, +0.375f,1.0f, +0.5f,0.0f, +0.5f,0.125f, +0.5f,0.25f, +0.5f,0.375f, +0.5f,0.5f, +0.5f,0.625f, +0.5f,0.75f, +0.5f,0.875f, +0.5f,1.0f, +0.625f,0.0f, +0.625f,0.125f, +0.625f,0.25f, +0.625f,0.375f, +0.625f,0.5f, +0.625f,0.625f, +0.625f,0.75f, +0.625f,0.875f, +0.625f,1.0f, +0.75f,0.0f, +0.75f,0.125f, +0.75f,0.25f, +0.75f,0.375f, +0.75f,0.5f, +0.75f,0.625f, +0.75f,0.75f, +0.75f,0.875f, +0.75f,1.0f, +0.875f,0.0f, +0.875f,0.125f, +0.875f,0.25f, +0.875f,0.375f, +0.875f,0.5f, +0.875f,0.625f, +0.875f,0.75f, +0.875f,0.875f, +0.875f,1.0f, +1.0f,0.0f, +1.0f,0.125f, +1.0f,0.25f, +1.0f,0.375f, +1.0f,0.5f, +1.0f,0.625f, +1.0f,0.75f, +1.0f,0.875f, +1.0f,1.0f, +}; + +static unsigned short LargeMeshIdx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +18,0,19, +2,19,0, +19,2,20, +4,20,2, +20,4,21, +6,21,4, +21,6,22, +8,22,6, +22,8,23, +10,23,8, +23,10,24, +12,24,10, +24,12,25, +14,25,12, +25,14,26, +16,26,14, +27,18,28, +19,28,18, +28,19,29, +20,29,19, +29,20,30, +21,30,20, +30,21,31, +22,31,21, +31,22,32, +23,32,22, +32,23,33, +24,33,23, +33,24,34, +25,34,24, +34,25,35, +26,35,25, +36,27,37, +28,37,27, +37,28,38, +29,38,28, +38,29,39, +30,39,29, +39,30,40, +31,40,30, +40,31,41, +32,41,31, +41,32,42, +33,42,32, +42,33,43, +34,43,33, +43,34,44, +35,44,34, +45,36,46, +37,46,36, +46,37,47, +38,47,37, +47,38,48, +39,48,38, +48,39,49, +40,49,39, +49,40,50, +41,50,40, +50,41,51, +42,51,41, +51,42,52, +43,52,42, +52,43,53, +44,53,43, +54,45,55, +46,55,45, +55,46,56, +47,56,46, +56,47,57, +48,57,47, +57,48,58, +49,58,48, +58,49,59, +50,59,49, +59,50,60, +51,60,50, +60,51,61, +52,61,51, +61,52,62, +53,62,52, +63,54,64, +55,64,54, +64,55,65, +56,65,55, +65,56,66, +57,66,56, +66,57,67, +58,67,57, +67,58,68, +59,68,58, +68,59,69, +60,69,59, +69,60,70, +61,70,60, +70,61,71, +62,71,61, +72,63,73, +64,73,63, +73,64,74, +65,74,64, +74,65,75, +66,75,65, +75,66,76, +67,76,66, +76,67,77, +68,77,67, +77,68,78, +69,78,68, +78,69,79, +70,79,69, +79,70,80, +71,80,70, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/main.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/main.cpp new file mode 100644 index 000000000..9ec4e5ec6 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/main.cpp @@ -0,0 +1,544 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../common/common.h" +#include "../common/ctrl_func.h" +#include "../common/render_func.h" +#include "../common/perf_func.h" +#include "physics_func.h" +#include "barrel.h" +#include "landscape.h" + +#ifdef _WIN32 + #include + #include +#endif + +// ARA begin insert new code +#ifdef __ANDROID__ + #include + #include +#endif +// ARA end + +#define SAMPLE_NAME "api_physics_effects/5_raycast" + +//#define ENABLE_DEBUG_DRAW + +#ifdef ENABLE_DEBUG_DRAW + #define ENABLE_DEBUG_DRAW_CONTACT + #define ENABLE_DEBUG_DRAW_AABB + #define ENABLE_DEBUG_DRAW_ISLAND +#endif + +static bool s_isRunning = true; + +int sceneId = 0; +bool simulating = false; + +int landscapeMeshId; +int convexMeshId; + +void render(void) +{ + render_begin(); + + const PfxVector3 colorWhite(1.0f); + const PfxVector3 colorGray(0.7f); + + for(int i=0;i -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_DOWN)) { + angX += 0.05f; + if(angX < -1.4f) angX = -1.4f; + if(angX > -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_LEFT)) { + angY -= 0.05f; + } + + if(ctrl_button_pressed(BTN_RIGHT)) { + angY += 0.05f; + } + + if(ctrl_button_pressed(BTN_ZOOM_OUT)) { + r *= 1.1f; + if(r > 500.0f) r = 500.0f; + } + + if(ctrl_button_pressed(BTN_ZOOM_IN)) { + r *= 0.9f; + if(r < 1.0f) r = 1.0f; + } + + if(ctrl_button_pressed(BTN_SCENE_RESET) == BTN_STAT_DOWN) { + physics_create_scene(sceneId); + } + + if(ctrl_button_pressed(BTN_SCENE_NEXT) == BTN_STAT_DOWN) { + physics_create_scene(++sceneId); + } + + if(ctrl_button_pressed(BTN_SIMULATION) == BTN_STAT_DOWN) { + simulating = !simulating; + } + + if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_DOWN) { + simulating = true; + } + else if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_UP || ctrl_button_pressed(BTN_STEP) == BTN_STAT_KEEP) { + simulating = false; + } + + render_set_view_angle(angX,angY,r); +} + +#ifndef _WIN32 + +// ARA begin insert new code +#ifdef __ANDROID__ + +/////////////////////////////////////////////////////////////////////////////// +// sceneChange +// +/// This function is used to change the physics scene on Android devices +/////////////////////////////////////////////////////////////////////////////// +void sceneChange() +{ + physics_create_scene(sceneId++); +} + +#else // __ANDROID__ +// ARA end + +/////////////////////////////////////////////////////////////////////////////// +// Main + +int main(void) +{ + init(); + + physics_create_scene(sceneId); + + printf("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + while (s_isRunning) { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + + shutdown(); + + printf("## %s: FINISHED ##\n", SAMPLE_NAME); + + return 0; +} + +// ARA begin insert new code +#endif // __ANDROID__ +// ARA end + +#else // _WIN32 + +/////////////////////////////////////////////////////////////////////////////// +// WinMain + +extern HDC hDC; +extern HGLRC hRC; +HWND hWnd; +HINSTANCE hInstance; + +void releaseWindow() +{ + if(hRC) { + wglMakeCurrent(0,0); + wglDeleteContext(hRC); + } + + if(hDC) ReleaseDC(hWnd,hDC); + if(hWnd) DestroyWindow(hWnd); + + UnregisterClass(SAMPLE_NAME,hInstance); +} + +LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) { + case WM_SYSCOMMAND: + { + switch (wParam) { + case SC_SCREENSAVE: + case SC_MONITORPOWER: + return 0; + } + break; + } + + case WM_CLOSE: + PostQuitMessage(0); + return 0; + + case WM_SIZE: + render_resize(LOWORD(lParam),HIWORD(lParam)); + return 0; + } + + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + +bool createWindow(char* title, int width, int height) +{ + WNDCLASS wc; + RECT rect; + rect.left=0; + rect.right=width; + rect.top=0; + rect.bottom=height; + + hInstance = GetModuleHandle(NULL); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = SAMPLE_NAME; + + if(!RegisterClass(&wc)) { + return false; + } + + AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE); + + if(!(hWnd=CreateWindowEx(WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,SAMPLE_NAME,title, + WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, + 0,0,rect.right-rect.left,rect.bottom-rect.top, + NULL,NULL,hInstance,NULL))) { + releaseWindow(); + return false; + } + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 32, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, + 0, 0, 0, 0, + 32, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + if(!(hDC=GetDC(hWnd))) + { + releaseWindow(); + OutputDebugString(""); + return FALSE; + } + + int pixelformat; + + if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){ + OutputDebugString("ChoosePixelFormat Failed...."); + return FALSE; + } + + if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE){ + OutputDebugString("SetPixelFormat Failed...."); + return FALSE; + } + + if (!(hRC=wglCreateContext(hDC))){ + OutputDebugString("Creating HGLRC Failed...."); + return FALSE; + } + + // Set Vsync + //BOOL (WINAPI *wglSwapIntervalEXT)(int) = NULL; + + //if(strstr((char*)glGetString( GL_EXTENSIONS ),"WGL_EXT_swap_control")== 0) { + //} + //else { + //wglSwapIntervalEXT = (BOOL (WINAPI*)(int))wglGetProcAddress("wglSwapIntervalEXT"); + //if(wglSwapIntervalEXT) wglSwapIntervalEXT(1); + //} + + wglMakeCurrent(hDC,hRC); + + ShowWindow(hWnd,SW_SHOW); + SetForegroundWindow(hWnd); + SetFocus(hWnd); + + render_resize(width, height); + + glClearColor(0.0f,0.0f,0.0f,0.0f); + glClearDepth(1.0f); + + return TRUE; +} + +int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) +{ + if(!createWindow(SAMPLE_NAME,DISPLAY_WIDTH,DISPLAY_HEIGHT)) { + MessageBox(NULL,"Can't create gl window.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return 0; + } + + init(); + + physics_create_scene(sceneId); + + SCE_PFX_PRINTF("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + MSG msg; + while(s_isRunning) { + if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if(msg.message==WM_QUIT) { + s_isRunning = false; + } + else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + else { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + } + + shutdown(); + + SCE_PFX_PRINTF("## %s: FINISHED ##\n", SAMPLE_NAME); + + releaseWindow(); + return (msg.wParam); +} + +#endif diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/physics.png b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/physics.png new file mode 100644 index 000000000..ffe16ab6d Binary files /dev/null and b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/physics.png differ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/physics_func.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/physics_func.cpp new file mode 100644 index 000000000..e317df572 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/5_raycast/physics_func.cpp @@ -0,0 +1,1085 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "physics_func.h" +#include "../common/perf_func.h" + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Data + +#define NUM_RIGIDBODIES 500 +#define NUM_JOINTS 500 +#define NUM_CONTACTS 4000 +#define NUM_RAYS 100 + +const float timeStep = 0.016f; +const float separateBias = 0.1f; +int iteration = 5; + +//J ワールドサイズ +//E World size +PfxVector3 worldCenter(0.0f); +PfxVector3 worldExtent(500.0f); + +//J 剛体 +//E Rigid body +PfxRigidState states[NUM_RIGIDBODIES]; +PfxRigidBody bodies[NUM_RIGIDBODIES]; +PfxCollidable collidables[NUM_RIGIDBODIES]; +PfxSolverBody solverBodies[NUM_RIGIDBODIES]; +int numRigidBodies = 0; + +//J 地形を表現するためのラージメッシュ +//E Large mesh for representing a landscape +#include "landscape.h" +PfxLargeTriMesh gLargeMesh; + +//J 凸メッシュ +//E Convex Mesh +#include "barrel.h" +PfxConvexMesh gConvex; + +//J プロキシ +//E Proxies +PfxBroadphaseProxy proxies[6][NUM_RIGIDBODIES]; // shared by simulation and raycast + +//J ジョイント +//E Joint +PfxConstraintPair jointPairs[NUM_JOINTS]; +PfxJoint joints[NUM_JOINTS]; +int numJoints = 0; + +//J ペア +//E Pairs +unsigned int pairSwap; +unsigned int numPairs[2]; +PfxBroadphasePair pairsBuff[2][NUM_CONTACTS]; + +//J コンタクト +//E Contacts +PfxContactManifold contacts[NUM_CONTACTS]; +int numContacts; + +PfxUInt32 contactIdPool[NUM_CONTACTS]; +int numContactIdPool; + +//J シミュレーションアイランド +//E Island generation +PfxIsland *island=NULL; +PfxUInt8 SCE_PFX_ALIGNED(16) islandBuff[32*NUM_RIGIDBODIES]; // Island buffer should be 32 * the number of rigid bodies. + +//J スリープ制御 +//E Sleep control +/* + A sleeping object wakes up, when + * a new pair related to this rigid body is created + * a pair releated to this rigid body is removed + * a rigid body's velocity or position are updated + */ + +//J スリープに入るカウント +//E Count to enter sleeping +const PfxUInt32 sleepCount = 180; + +//J 速度が閾値以下ならばスリープカウントが増加 +//E If velocity is under the following value, sleep count is increased. +const PfxFloat sleepVelocity = 0.1f; + +//J 一時バッファ +//E Temporary buffers +#define POOL_BYTES (5*1024*1024) +unsigned char SCE_PFX_ALIGNED(128) poolBuff[POOL_BYTES]; + +//J 一時バッファ用スタックアロケータ +//E Stack allocator for temporary buffers +PfxHeapManager pool(poolBuff,POOL_BYTES); + +//J レイ +//E Ray +PfxRayInput SCE_PFX_ALIGNED(128) rayInputs[NUM_RAYS]; +PfxRayOutput SCE_PFX_ALIGNED(128) rayOutputs[NUM_RAYS]; +int numRays; + +/* + doAreaRaycastがtrueの場合、指定された領域内の剛体のみ判定対象とする +*/ +bool doAreaRaycast; +PfxVector3 areaCenter(0.0f); +PfxVector3 areaExtent(5.0f); + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Function + +int frame = 0; + +void broadphase() +{ + pairSwap = 1-pairSwap; + + unsigned int &numPreviousPairs = numPairs[1-pairSwap]; + unsigned int &numCurrentPairs = numPairs[pairSwap]; + PfxBroadphasePair *previousPairs = pairsBuff[1-pairSwap]; + PfxBroadphasePair *currentPairs = pairsBuff[pairSwap]; + + //J 剛体が最も分散している軸を見つける + //E Find the axis along which all rigid bodies are most widely positioned + int axis = 0; + { + PfxVector3 s(0.0f),s2(0.0f); + for(int i=0;i v[0]) axis = 1; + if(v[2] > v[axis]) axis = 2; + } + + //J ブロードフェーズプロキシの更新 + //E Create broadpahse proxies + { + //J レイキャストと共用するため、全ての軸に対するプロキシ配列を作成する + //E To share with ray casting, create proxy arrays for all axis + + PfxUpdateBroadphaseProxiesParam param; + param.workBytes = pfxGetWorkBytesOfUpdateBroadphaseProxies(numRigidBodies); + param.workBuff = pool.allocate(param.workBytes,128); + param.numRigidBodies = numRigidBodies; + param.offsetRigidStates = states; + param.offsetCollidables = collidables; + param.proxiesX = proxies[0]; + param.proxiesY = proxies[1]; + param.proxiesZ = proxies[2]; + param.proxiesXb = proxies[3]; + param.proxiesYb = proxies[4]; + param.proxiesZb = proxies[5]; + param.worldCenter = worldCenter; + param.worldExtent = worldExtent; + + PfxUpdateBroadphaseProxiesResult result; + + int ret = pfxUpdateBroadphaseProxies(param,result); + if(ret != SCE_PFX_OK) SCE_PFX_PRINTF("pfxUpdateBroadphaseProxies failed %d\n",ret); + + pool.deallocate(param.workBuff); + } + + //J 交差ペア探索 + //E Find overlapped pairs + { + PfxFindPairsParam findPairsParam; + findPairsParam.pairBytes = pfxGetPairBytesOfFindPairs(NUM_CONTACTS); + findPairsParam.pairBuff = pool.allocate(findPairsParam.pairBytes); + findPairsParam.workBytes = pfxGetWorkBytesOfFindPairs(NUM_CONTACTS); + findPairsParam.workBuff = pool.allocate(findPairsParam.workBytes); + findPairsParam.proxies = proxies[axis]; + findPairsParam.numProxies = numRigidBodies; + findPairsParam.maxPairs = NUM_CONTACTS; + findPairsParam.axis = axis; + + PfxFindPairsResult findPairsResult; + + int ret = pfxFindPairs(findPairsParam,findPairsResult); + if(ret != SCE_PFX_OK) SCE_PFX_PRINTF("pfxFindPairs failed %d\n",ret); + + pool.deallocate(findPairsParam.workBuff); + + //J 交差ペア合成 + //E Decompose overlapped pairs into 3 arrays + PfxDecomposePairsParam decomposePairsParam; + decomposePairsParam.pairBytes = pfxGetPairBytesOfDecomposePairs(numPreviousPairs,findPairsResult.numPairs); + decomposePairsParam.pairBuff = pool.allocate(decomposePairsParam.pairBytes); + decomposePairsParam.workBytes = pfxGetWorkBytesOfDecomposePairs(numPreviousPairs,findPairsResult.numPairs); + decomposePairsParam.workBuff = pool.allocate(decomposePairsParam.workBytes); + decomposePairsParam.previousPairs = previousPairs; + decomposePairsParam.numPreviousPairs = numPreviousPairs; + decomposePairsParam.currentPairs = findPairsResult.pairs; // Set pairs from pfxFindPairs() + decomposePairsParam.numCurrentPairs = findPairsResult.numPairs; // Set the number of pairs from pfxFindPairs() + + PfxDecomposePairsResult decomposePairsResult; + + ret = pfxDecomposePairs(decomposePairsParam,decomposePairsResult); + if(ret != SCE_PFX_OK) SCE_PFX_PRINTF("pfxDecomposePairs failed %d\n",ret); + + pool.deallocate(decomposePairsParam.workBuff); + + PfxBroadphasePair *outNewPairs = decomposePairsResult.outNewPairs; + PfxBroadphasePair *outKeepPairs = decomposePairsResult.outKeepPairs; + PfxBroadphasePair *outRemovePairs = decomposePairsResult.outRemovePairs; + PfxUInt32 numOutNewPairs = decomposePairsResult.numOutNewPairs; + PfxUInt32 numOutKeepPairs = decomposePairsResult.numOutKeepPairs; + PfxUInt32 numOutRemovePairs = decomposePairsResult.numOutRemovePairs; + + //J 廃棄ペアのコンタクトをプールに戻す + //E Put removed contacts into the contact pool + for(PfxUInt32 i=0;i 0) { + cId = contactIdPool[--numContactIdPool]; + } + else { + cId = numContacts++; + } + if(cId >= NUM_CONTACTS) { + cId = 0; + } + SCE_PFX_ASSERT(cId < NUM_CONTACTS); + pfxSetContactId(outNewPairs[i],cId); + PfxContactManifold &contact = contacts[cId]; + contact.reset(pfxGetObjectIdA(outNewPairs[i]),pfxGetObjectIdB(outNewPairs[i])); + + //J 寝てる剛体を起こす + //E Wake up sleeping rigid bodies + PfxRigidState &stateA = states[pfxGetObjectIdA(outNewPairs[i])]; + PfxRigidState &stateB = states[pfxGetObjectIdB(outNewPairs[i])]; + if(stateA.isAsleep()) { + stateA.wakeup(); + } + if(stateB.isAsleep()) { + stateB.wakeup(); + } + } + + //J 新規ペアと維持ペアを合成 + //E Merge 'new' and 'keep' pairs + numCurrentPairs = 0; + for(PfxUInt32 i=0;i sleepCount) { + numCanSleep++; + } + } + } + } + + // Deactivate Island + if(numCanSleep > 0 && numCanSleep == numActive + numSleep) { + PfxIslandUnit *islandUnit = pfxGetFirstUnitInIsland(island,(PfxUInt32)i); + for(;islandUnit!=NULL;islandUnit=pfxGetNextUnitInIsland(islandUnit)) { + if(!(SCE_PFX_MOTION_MASK_CAN_SLEEP(states[pfxGetUnitId(islandUnit)].getMotionType()))) continue; + states[pfxGetUnitId(islandUnit)].sleep(); + } + } + + // Activate Island + else if(numSleep > 0 && numActive > 0) { + PfxIslandUnit *islandUnit = pfxGetFirstUnitInIsland(island,(PfxUInt32)i); + for(;islandUnit!=NULL;islandUnit=pfxGetNextUnitInIsland(islandUnit)) { + if(!(SCE_PFX_MOTION_MASK_CAN_SLEEP(states[pfxGetUnitId(islandUnit)].getMotionType()))) continue; + states[pfxGetUnitId(islandUnit)].wakeup(); + } + } + } + } +} + +void integrate() +{ + PfxUpdateRigidStatesParam param; + param.states = states; + param.bodies = bodies; + param.numRigidBodies = numRigidBodies; + param.timeStep = timeStep; + + pfxUpdateRigidStates(param); +} + +int gatherBroadphaseProxiesInArea(const PfxVector3 ¢er,const PfxVector3 &extent) +{ + PfxUpdateBroadphaseProxiesParam param; + param.workBytes = pfxGetWorkBytesOfUpdateBroadphaseProxies(numRigidBodies); + param.workBuff = pool.allocate(param.workBytes,128); + param.numRigidBodies = numRigidBodies; + param.offsetRigidStates = states; + param.offsetCollidables = collidables; + param.proxiesX = proxies[0]; + param.proxiesY = proxies[1]; + param.proxiesZ = proxies[2]; + param.proxiesXb = proxies[3]; + param.proxiesYb = proxies[4]; + param.proxiesZb = proxies[5]; + param.worldCenter = center; + param.worldExtent = extent; + param.outOfWorldBehavior = SCE_PFX_OUT_OF_WORLD_BEHAVIOR_REMOVE_PROXY; + + PfxUpdateBroadphaseProxiesResult result; + + int ret = pfxUpdateBroadphaseProxies(param,result); + if(ret != SCE_PFX_OK) SCE_PFX_PRINTF("pfxUpdateBroadphaseProxies failed %d\n",ret); + + pool.deallocate(param.workBuff); + + return numRigidBodies - result.numOutOfWorldProxies; +} + +void castRays() +{ + PfxRayCastParam param; + + if(doAreaRaycast) { + static PfxFloat deltaRotY = 0.0f; + PfxQuat rotY = PfxQuat::rotationY(deltaRotY); + areaCenter = rotate(rotY,PfxVector3(15.0f,0.0f,0.0f)); + deltaRotY += 0.02f; + + int num = gatherBroadphaseProxiesInArea(areaCenter,areaExtent); + param.offsetRigidStates = states; + param.offsetCollidables = collidables; + param.proxiesX = proxies[0]; + param.proxiesY = proxies[1]; + param.proxiesZ = proxies[2]; + param.proxiesXb = proxies[3]; + param.proxiesYb = proxies[4]; + param.proxiesZb = proxies[5]; + param.numProxies = num; + param.rangeCenter = areaCenter; + param.rangeExtent = areaExtent; + } + else { + param.offsetRigidStates = states; + param.offsetCollidables = collidables; + param.proxiesX = proxies[0]; + param.proxiesY = proxies[1]; + param.proxiesZ = proxies[2]; + param.proxiesXb = proxies[3]; + param.proxiesYb = proxies[4]; + param.proxiesZb = proxies[5]; + param.numProxies = numRigidBodies; + param.rangeCenter = worldCenter; + param.rangeExtent = worldExtent; + } + + pfxCastRays(rayInputs,rayOutputs,numRays,param); +} + +void physics_simulate() +{ + PfxPerfCounter pc; + + for(int i=1;i 0) { + pfxReleaseLargeTriMesh(gLargeMesh); + } + + PfxInt32 ret = pfxCreateLargeTriMesh(gLargeMesh,param); + if(ret != SCE_PFX_OK) { + SCE_PFX_PRINTF("Can't create large mesh.\n"); + } + + int id = numRigidBodies++; + PfxShape shape; + shape.reset(); + shape.setLargeTriMesh(&gLargeMesh); + collidables[id].reset(); + collidables[id].addShape(shape); + collidables[id].finish(); + bodies[id].reset(); + states[id].reset(); + states[id].setPosition(PfxVector3(0.0f,0.0f,0.0f)); + states[id].setMotionType(kPfxMotionTypeFixed); + states[id].setRigidBodyId(id); +} + +void initRays(const PfxVector3 &p1,const PfxVector3 &p2) +{ + numRays = NUM_RAYS; + PfxQuat rot = PfxQuat::rotationY(2.0f*SCE_PFX_PI/(float)numRays); + PfxVector3 startPosition = p1; + PfxVector3 targetPosition = p2; + + for(int i=0;i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/CMakeLists.txt b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/CMakeLists.txt new file mode 100644 index 000000000..41459419b --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/CMakeLists.txt @@ -0,0 +1,77 @@ +cmake_minimum_required(VERSION 2.4) + + +#this line has to appear before 'PROJECT' in order to be able to disable incremental linking +SET(MSVC_INCREMENTAL_DEFAULT ON) + +PROJECT(App_6_Joint) + + +IF (NOT CMAKE_BUILD_TYPE) +# SET(CMAKE_BUILD_TYPE "Debug") + SET(CMAKE_BUILD_TYPE "Release") +ENDIF (NOT CMAKE_BUILD_TYPE) + + +OPTION(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC Runtime Library DLL (/MD or /MDd)" ON) +OPTION(USE_MSVC_INCREMENTAL_LINKING "Use MSVC Incremental Linking" OFF) + + +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + + +SET(App_6_Joint_SRCS + main.cpp + physics_func.cpp + ../common/ctrl_func.win32.cpp + ../common/perf_func.win32.cpp + ../common/render_func.win32.cpp +) + + +SET(App_6_Joint_HDRS + physics_func.h + landscape.h + barrel.h + ../common/render_func.h + ../common/common.h + ../common/ctrl_func.h + ../common/perf_func.h +) + + +INCLUDE_DIRECTORIES( + ${PHYSICS_EFFECTS_SOURCE_DIR}/include +# ${VECTOR_MATH_INCLUDE} +) + +#LINK_DIRECTORIES( +# +#) + +#ADD_DEFINITIONS(-DUNICODE) +#ADD_DEFINITIONS(-D_UNICODE) + +ADD_EXECUTABLE(App_6_Joint WIN32 + ${App_6_Joint_SRCS} + ${App_6_Joint_HDRS} +) +TARGET_LINK_LIBRARIES(App_6_Joint + PfxBaseLevel + PfxLowLevel + PfxUtil + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} +) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(App_6_Joint PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(App_6_Joint PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(App_6_Joint PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF() + + + + \ No newline at end of file diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/barrel.h b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/barrel.h new file mode 100644 index 000000000..6574fa862 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/barrel.h @@ -0,0 +1,202 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define BarrelVtxCount 57 +#define BarrelIdxCount 180 + +static float BarrelVtx[] = { +0.0f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +-0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +0.0f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +-0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.957307f,-0.289072f,0.0f, +0.404509f,0.0f,-0.293893f, 0.809017f,0.0f,-0.587785f, +0.5f,0.0f,0.0f, 1.0f,0.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.774478f,-0.289072f,-0.562691f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +-0.154509f,0.0f,-0.475528f, -0.309017f,0.0f,-0.951057f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +-0.107853f,-0.5f,-0.331936f, -0.295824f,-0.289072f,-0.910453f, +-0.404509f,0.0f,-0.293893f, -0.809017f,0.0f,-0.587785f, +-0.282362f,-0.5f,-0.205148f, -0.774478f,-0.289072f,-0.562691f, +-0.5f,0.0f,0.0f, -1.0f,0.0f,0.0f, +-0.349018f,-0.5f,0.0f, -0.957307f,-0.289072f,0.0f, +-0.404508f,0.0f,0.293893f, -0.809017f,0.0f,0.587785f, +-0.282362f,-0.5f,0.205148f, -0.774478f,-0.289072f,0.562691f, +-0.154509f,0.0f,0.475528f, -0.309017f,0.0f,0.951056f, +-0.107853f,-0.5f,0.331936f, -0.295824f,-0.289072f,0.910453f, +0.154509f,0.0f,0.475528f, 0.309017f,0.0f,0.951056f, +0.107853f,-0.5f,0.331936f, 0.295824f,-0.289072f,0.910453f, +0.404509f,0.0f,0.293892f, 0.809017f,0.0f,0.587785f, +0.282362f,-0.5f,0.205148f, 0.774478f,-0.289072f,0.562691f, +0.282362f,0.5f,-0.205148f, 0.774478f,0.289072f,-0.562691f, +0.349018f,0.5f,0.0f, 0.957307f,0.289072f,0.0f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.107853f,0.5f,-0.331936f, -0.295824f,0.289072f,-0.910453f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.282362f,0.5f,-0.205148f, -0.774478f,0.289072f,-0.562691f, +-0.349018f,0.5f,0.0f, -0.957307f,0.289072f,0.0f, +-0.282362f,0.5f,0.205148f, -0.774478f,0.289072f,0.562691f, +-0.107853f,0.5f,0.331936f, -0.295824f,0.289072f,0.910453f, +0.107853f,0.5f,0.331936f, 0.295824f,0.289072f,0.910453f, +0.282362f,0.5f,0.205148f, 0.774478f,0.289072f,0.562691f, +}; + +static float BarrelTex[] = { +0.0f,0.5f, +0.0f,0.85f, +0.0f,0.75f, +0.0f,0.95f, +0.0f,0.05f, +0.0f,-0.05f, +0.0f,0.15f, +0.0f,0.25f, +0.0f,0.35f, +0.0f,0.45f, +0.0f,0.55f, +0.0f,0.65f, +1.0f,0.5f, +1.0f,0.75f, +1.0f,0.85f, +1.0f,0.95f, +1.0f,-0.05f, +1.0f,0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +0.0f,0.75f, +0.5f,0.85f, +0.5f,0.75f, +0.0f,0.85f, +0.5f,0.95f, +0.0f,0.95f, +0.0f,-0.05f, +0.5f,0.05f, +0.5f,-0.05f, +0.0f,0.05f, +0.5f,0.15f, +0.0f,0.15f, +0.5f,0.25f, +0.0f,0.25f, +0.5f,0.35f, +0.0f,0.35f, +0.5f,0.45f, +0.0f,0.45f, +0.5f,0.55f, +0.0f,0.55f, +0.5f,0.65f, +0.0f,0.65f, +1.0f,0.85f, +1.0f,0.75f, +1.0f,0.95f, +1.0f,0.05f, +1.0f,-0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +}; + +static unsigned short BarrelIdx[] = { +0,1,2, +0,3,1, +0,4,5, +0,6,4, +0,7,6, +0,8,7, +0,9,8, +0,10,9, +0,11,10, +0,2,11, +12,13,14, +12,14,15, +12,16,17, +12,17,18, +12,18,19, +12,19,20, +12,20,21, +12,21,22, +12,22,23, +12,23,13, +24,25,26, +24,27,25, +27,28,25, +27,29,28, +30,31,32, +30,33,31, +33,34,31, +33,35,34, +35,36,34, +35,37,36, +37,38,36, +37,39,38, +39,40,38, +39,41,40, +41,42,40, +41,43,42, +43,44,42, +43,45,44, +45,26,44, +45,24,26, +26,46,47, +26,25,46, +25,48,46, +25,28,48, +32,49,50, +32,31,49, +31,51,49, +31,34,51, +34,52,51, +34,36,52, +36,53,52, +36,38,53, +38,54,53, +38,40,54, +40,55,54, +40,42,55, +42,56,55, +42,44,56, +44,47,56, +44,26,47, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/landscape.h b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/landscape.h new file mode 100644 index 000000000..00f6cffd2 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/landscape.h @@ -0,0 +1,318 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define LargeMeshVtxCount 81 +#define LargeMeshIdxCount 384 + +static float LargeMeshVtx[] = { +-25.0f,-2.19407f,18.5625f, 0.232976f,0.967754f,0.0957829f, +-25.0f,0.0644502f,24.75f, 0.188094f,0.871343f,-0.45319f, +-18.75f,-4.50287f,18.5625f, -0.0716098f,0.995449f,0.0628767f, +-18.75f,-0.39999f,24.75f, -0.0602794f,0.895848f,-0.440253f, +-12.5f,-1.2166f,18.5625f, -0.269469f,0.961403f,0.0555879f, +-12.5f,-0.942431f,24.75f, -0.0997841f,0.993258f,0.0589987f, +-6.25f,1.93598f,18.5625f, -0.283933f,0.956351f,-0.0691025f, +-6.25f,-0.445954f,24.75f, -0.180725f,0.942766f,0.280233f, +0.0f,2.76983f,18.5625f, 0.171645f,0.984908f,0.0222501f, +0.0f,2.76642f,24.75f, 0.0784993f,0.995428f,-0.0544117f, +6.25f,-2.53736f,18.5625f, 0.248298f,0.965028f,0.0840741f, +6.25f,-0.915645f,24.75f, 0.164311f,0.945856f,-0.279926f, +12.5f,-1.60054f,18.5625f, -0.180435f,0.983586f,0.00115547f, +12.5f,0.831925f,24.75f, -0.0692495f,0.964821f,-0.253623f, +18.75f,-0.800282f,18.5625f, 0.10755f,0.951538f,0.288112f, +18.75f,-1.47284f,24.75f, 0.232178f,0.972664f,0.00429361f, +25.0f,-2.78379f,18.5625f, 0.1833f,0.937477f,0.295867f, +25.0f,-0.967508f,24.75f, -0.0773477f,0.956641f,-0.280812f, +-25.0f,-0.352038f,12.375f, -0.192222f,0.972435f,0.131987f, +-18.75f,0.681228f,12.375f, -0.107779f,0.962569f,0.248686f, +-12.5f,2.72065f,12.375f, 0.0520846f,0.993034f,0.105692f, +-6.25f,-1.78776f,12.375f, -0.0133223f,0.99674f,-0.0795754f, +0.0f,1.57707f,12.375f, -0.129025f,0.969662f,-0.207627f, +6.25f,0.424356f,12.375f, 0.180995f,0.97074f,0.157815f, +12.5f,0.283234f,12.375f, -0.16285f,0.973539f,0.160316f, +18.75f,2.57015f,12.375f, -0.165454f,0.978339f,0.124408f, +25.0f,3.07363f,12.375f, -0.00454559f,0.988151f,0.153417f, +-25.0f,-0.893751f,6.1875f, -0.0836251f,0.990084f,-0.112876f, +-18.75f,0.930932f,6.1875f, 0.00269413f,0.971838f,-0.235633f, +-12.5f,-0.684529f,6.1875f, -0.010319f,0.927048f,-0.3748f, +-6.25f,-0.661383f,6.1875f, 0.012265f,0.999875f,-0.00994222f, +0.0f,0.385718f,6.1875f, -0.15435f,0.984937f,-0.0779465f, +6.25f,0.589796f,6.1875f, 0.0241717f,0.999582f,-0.0158589f, +12.5f,0.47454f,6.1875f, -0.017184f,0.997953f,-0.0616073f, +18.75f,1.59939f,6.1875f, -0.0902706f,0.957309f,-0.274609f, +25.0f,1.13434f,6.1875f, 0.0346006f,0.957441f,-0.286547f, +-25.0f,0.74548f,0.0f, 0.329903f,0.930812f,0.157334f, +-18.75f,-2.47437f,0.0f, 0.247844f,0.968142f,0.0357041f, +-12.5f,-4.16309f,1.81975e-007f, -0.0623898f,0.997626f,-0.0291436f, +-6.25f,-0.700022f,0.0f, -0.217067f,0.974987f,-0.0477624f, +0.0f,-0.0957388f,0.0f, -0.117693f,0.990712f,-0.068098f, +6.25f,0.614077f,0.0f, -0.0713214f,0.997305f,0.01722f, +12.5f,0.299109f,0.0f, 0.218606f,0.968641f,0.118094f, +18.75f,-1.71753f,0.0f, 0.0339493f,0.985612f,-0.165579f, +25.0f,-1.12638f,0.0f, -0.0547573f,0.989177f,-0.136126f, +-25.0f,-0.403319f,-6.1875f, -0.1263f,0.989211f,-0.074223f, +-18.75f,-0.0730335f,-6.1875f, 0.0173428f,0.965382f,0.260261f, +-12.5f,-0.450125f,-6.1875f, 0.0658811f,0.875f,0.479619f, +-6.25f,-0.180204f,-6.1875f, 0.0116584f,0.981445f,0.19139f, +0.0f,-0.632679f,-6.1875f, -0.0557983f,0.993041f,-0.103716f, +6.25f,0.308409f,-6.1875f, -0.191898f,0.96766f,-0.163737f, +12.5f,2.5011f,-6.1875f, 0.0758397f,0.996403f,-0.0378189f, +18.75f,-1.69303f,-6.1875f, 0.16761f,0.974057f,0.15205f, +25.0f,-0.141349f,-6.1875f, -0.204846f,0.978471f,0.0251341f, +-25.0f,-1.10316f,-12.375f, -0.0350644f,0.993748f,-0.106001f, +-18.75f,1.06711f,-12.375f, -0.309806f,0.919244f,-0.242922f, +-12.5f,3.61544f,-12.375f, -0.0506281f,0.998702f,-0.00561657f, +-6.25f,1.6504f,-12.375f, 0.322294f,0.937465f,0.131477f, +0.0f,-1.60595f,-12.375f, 0.086016f,0.995916f,0.0274459f, +6.25f,-0.849859f,-12.375f, -0.0332811f,0.997087f,0.0686255f, +12.5f,-0.942201f,-12.375f, -0.153559f,0.982185f,-0.108312f, +18.75f,0.494873f,-12.375f, 0.0753195f,0.981472f,0.176181f, +25.0f,-0.333828f,-12.375f, 0.035057f,0.987194f,0.155624f, +-25.0f,2.1862f,-18.5625f, 0.612899f,0.782306f,0.111138f, +-18.75f,-3.38259f,-18.5625f, 0.0194078f,0.992789f,-0.118297f, +-12.5f,-0.880916f,-18.5625f, -0.282251f,0.949875f,-0.13443f, +-6.25f,0.818158f,-18.5625f, 0.1476f,0.981788f,-0.119612f, +0.0f,-1.48019f,-18.5625f, -0.044551f,0.996013f,-0.0772824f, +6.25f,1.47123f,-18.5625f, -0.117036f,0.97986f,0.161792f, +12.5f,0.164076f,-18.5625f, -0.0340355f,0.978993f,0.201034f, +18.75f,2.14568f,-18.5625f, -0.0439269f,0.994859f,0.0912435f, +25.0f,0.626506f,-18.5625f, 0.208015f,0.968592f,0.136229f, +-25.0f,0.296889f,-24.75f, 0.46973f,0.844327f,-0.257809f, +-18.75f,-3.18022f,-24.75f, -0.0226758f,0.998794f,-0.0435401f, +-12.5f,1.8927f,-24.75f, -0.202772f,0.919836f,0.335836f, +-6.25f,1.46387f,-24.75f, 0.224904f,0.955746f,0.189652f, +0.0f,-2.52726f,-24.75f, -0.0435882f,0.993572f,-0.10447f, +6.25f,1.30397f,-24.75f, -0.28646f,0.956525f,-0.0547707f, +12.5f,1.85812f,-24.75f, 0.0521949f,0.979796f,0.193067f, +18.75f,1.56331f,-24.75f, -0.0270784f,0.999629f,-0.00293115f, +25.0f,1.05366f,-24.75f, 0.161f,0.986887f,-0.0115473f, +}; + +static float LargeMeshTex[] = { +0.125f,0.0f, +0.0f,0.0f, +0.125f,0.125f, +0.0f,0.125f, +0.125f,0.25f, +0.0f,0.25f, +0.125f,0.375f, +0.0f,0.375f, +0.125f,0.5f, +0.0f,0.5f, +0.125f,0.625f, +0.0f,0.625f, +0.125f,0.75f, +0.0f,0.75f, +0.125f,0.875f, +0.0f,0.875f, +0.125f,1.0f, +0.0f,1.0f, +0.25f,0.0f, +0.25f,0.125f, +0.25f,0.25f, +0.25f,0.375f, +0.25f,0.5f, +0.25f,0.625f, +0.25f,0.75f, +0.25f,0.875f, +0.25f,1.0f, +0.375f,0.0f, +0.375f,0.125f, +0.375f,0.25f, +0.375f,0.375f, +0.375f,0.5f, +0.375f,0.625f, +0.375f,0.75f, +0.375f,0.875f, +0.375f,1.0f, +0.5f,0.0f, +0.5f,0.125f, +0.5f,0.25f, +0.5f,0.375f, +0.5f,0.5f, +0.5f,0.625f, +0.5f,0.75f, +0.5f,0.875f, +0.5f,1.0f, +0.625f,0.0f, +0.625f,0.125f, +0.625f,0.25f, +0.625f,0.375f, +0.625f,0.5f, +0.625f,0.625f, +0.625f,0.75f, +0.625f,0.875f, +0.625f,1.0f, +0.75f,0.0f, +0.75f,0.125f, +0.75f,0.25f, +0.75f,0.375f, +0.75f,0.5f, +0.75f,0.625f, +0.75f,0.75f, +0.75f,0.875f, +0.75f,1.0f, +0.875f,0.0f, +0.875f,0.125f, +0.875f,0.25f, +0.875f,0.375f, +0.875f,0.5f, +0.875f,0.625f, +0.875f,0.75f, +0.875f,0.875f, +0.875f,1.0f, +1.0f,0.0f, +1.0f,0.125f, +1.0f,0.25f, +1.0f,0.375f, +1.0f,0.5f, +1.0f,0.625f, +1.0f,0.75f, +1.0f,0.875f, +1.0f,1.0f, +}; + +static unsigned short LargeMeshIdx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +18,0,19, +2,19,0, +19,2,20, +4,20,2, +20,4,21, +6,21,4, +21,6,22, +8,22,6, +22,8,23, +10,23,8, +23,10,24, +12,24,10, +24,12,25, +14,25,12, +25,14,26, +16,26,14, +27,18,28, +19,28,18, +28,19,29, +20,29,19, +29,20,30, +21,30,20, +30,21,31, +22,31,21, +31,22,32, +23,32,22, +32,23,33, +24,33,23, +33,24,34, +25,34,24, +34,25,35, +26,35,25, +36,27,37, +28,37,27, +37,28,38, +29,38,28, +38,29,39, +30,39,29, +39,30,40, +31,40,30, +40,31,41, +32,41,31, +41,32,42, +33,42,32, +42,33,43, +34,43,33, +43,34,44, +35,44,34, +45,36,46, +37,46,36, +46,37,47, +38,47,37, +47,38,48, +39,48,38, +48,39,49, +40,49,39, +49,40,50, +41,50,40, +50,41,51, +42,51,41, +51,42,52, +43,52,42, +52,43,53, +44,53,43, +54,45,55, +46,55,45, +55,46,56, +47,56,46, +56,47,57, +48,57,47, +57,48,58, +49,58,48, +58,49,59, +50,59,49, +59,50,60, +51,60,50, +60,51,61, +52,61,51, +61,52,62, +53,62,52, +63,54,64, +55,64,54, +64,55,65, +56,65,55, +65,56,66, +57,66,56, +66,57,67, +58,67,57, +67,58,68, +59,68,58, +68,59,69, +60,69,59, +69,60,70, +61,70,60, +70,61,71, +62,71,61, +72,63,73, +64,73,63, +73,64,74, +65,74,64, +74,65,75, +66,75,65, +75,66,76, +67,76,66, +76,67,77, +68,77,67, +77,68,78, +69,78,68, +78,69,79, +70,79,69, +79,70,80, +71,80,70, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/main.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/main.cpp new file mode 100644 index 000000000..e78f4fa25 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/main.cpp @@ -0,0 +1,513 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../common/common.h" +#include "../common/ctrl_func.h" +#include "../common/render_func.h" +#include "../common/perf_func.h" +#include "physics_func.h" + +#ifdef _WIN32 + #include + #include +#endif + +// ARA begin insert new code +#ifdef __ANDROID__ + #include + #include +#endif +// ARA end + +#define SAMPLE_NAME "api_physics_effects/6_joint" + +//#define ENABLE_DEBUG_DRAW + +#ifdef ENABLE_DEBUG_DRAW + #define ENABLE_DEBUG_DRAW_CONTACT + #define ENABLE_DEBUG_DRAW_AABB + #define ENABLE_DEBUG_DRAW_ISLAND +#endif + +static bool s_isRunning = true; + +int sceneId = 0; +bool simulating = false; + +void render(void) +{ + render_begin(); + + const PfxVector3 colorWhite(1.0f); + const PfxVector3 colorGray(0.7f); + + for(int i=0;i -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_DOWN)) { + angX += 0.05f; + if(angX < -1.4f) angX = -1.4f; + if(angX > -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_LEFT)) { + angY -= 0.05f; + } + + if(ctrl_button_pressed(BTN_RIGHT)) { + angY += 0.05f; + } + + if(ctrl_button_pressed(BTN_ZOOM_OUT)) { + r *= 1.1f; + if(r > 500.0f) r = 500.0f; + } + + if(ctrl_button_pressed(BTN_ZOOM_IN)) { + r *= 0.9f; + if(r < 1.0f) r = 1.0f; + } + + if(ctrl_button_pressed(BTN_SCENE_RESET) == BTN_STAT_DOWN) { + physics_create_scene(sceneId); + } + + if(ctrl_button_pressed(BTN_SCENE_NEXT) == BTN_STAT_DOWN) { + physics_create_scene(++sceneId); + } + + if(ctrl_button_pressed(BTN_SIMULATION) == BTN_STAT_DOWN) { + simulating = !simulating; + } + + if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_DOWN) { + simulating = true; + } + else if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_UP || ctrl_button_pressed(BTN_STEP) == BTN_STAT_KEEP) { + simulating = false; + } + + int w,h; + render_get_screent_size(w,h); + ctrl_set_screen_size(w,h); + + static PfxVector3 pickPos(0.0f); + + if(ctrl_button_pressed(BTN_PICK) == BTN_STAT_DOWN) { + int sx,sy; + ctrl_get_cursor_position(sx,sy); + PfxVector3 wp1((float)sx,(float)sy,0.0f); + PfxVector3 wp2((float)sx,(float)sy,1.0f); + wp1 = render_get_world_position(wp1); + wp2 = render_get_world_position(wp2); + pickPos = physics_pick_start(wp1,wp2); + } + else if(ctrl_button_pressed(BTN_PICK) == BTN_STAT_KEEP) { + int sx,sy; + ctrl_get_cursor_position(sx,sy); + PfxVector3 sp = render_get_screen_position(pickPos); + PfxVector3 wp((float)sx,(float)sy,sp[2]); + wp = render_get_world_position(wp); + physics_pick_update(wp); + } + else if(ctrl_button_pressed(BTN_PICK) == BTN_STAT_UP) { + physics_pick_end(); + } + + render_set_view_angle(angX,angY,r); +} + +#ifndef _WIN32 + +// ARA begin insert new code +#ifdef __ANDROID__ + +/////////////////////////////////////////////////////////////////////////////// +// sceneChange +// +/// This function is used to change the physics scene on Android devices +/////////////////////////////////////////////////////////////////////////////// +void sceneChange() +{ + physics_create_scene(sceneId++); +} + +#else // __ANDROID__ +// ARA end + +/////////////////////////////////////////////////////////////////////////////// +// Main + +int main(void) +{ + init(); + + physics_create_scene(sceneId); + + printf("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + while (s_isRunning) { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + + shutdown(); + + printf("## %s: FINISHED ##\n", SAMPLE_NAME); + + return 0; +} + +// ARA begin insert new code +#endif // __ANDROID__ +// ARA end + +#else // _WIN32 + +/////////////////////////////////////////////////////////////////////////////// +// WinMain + +extern HDC hDC; +extern HGLRC hRC; +HWND hWnd; +HINSTANCE hInstance; + +void releaseWindow() +{ + if(hRC) { + wglMakeCurrent(0,0); + wglDeleteContext(hRC); + } + + if(hDC) ReleaseDC(hWnd,hDC); + if(hWnd) DestroyWindow(hWnd); + + UnregisterClass(SAMPLE_NAME,hInstance); +} + +LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) { + case WM_SYSCOMMAND: + { + switch (wParam) { + case SC_SCREENSAVE: + case SC_MONITORPOWER: + return 0; + } + break; + } + + case WM_CLOSE: + PostQuitMessage(0); + return 0; + + case WM_SIZE: + render_resize(LOWORD(lParam),HIWORD(lParam)); + return 0; + } + + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + +bool createWindow(char* title, int width, int height) +{ + WNDCLASS wc; + RECT rect; + rect.left=0; + rect.right=width; + rect.top=0; + rect.bottom=height; + + hInstance = GetModuleHandle(NULL); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = SAMPLE_NAME; + + if(!RegisterClass(&wc)) { + return false; + } + + AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE); + + if(!(hWnd=CreateWindowEx(WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,SAMPLE_NAME,title, + WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, + 0,0,rect.right-rect.left,rect.bottom-rect.top, + NULL,NULL,hInstance,NULL))) { + releaseWindow(); + return false; + } + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 32, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, + 0, 0, 0, 0, + 32, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + if(!(hDC=GetDC(hWnd))) + { + releaseWindow(); + OutputDebugString(""); + return FALSE; + } + + int pixelformat; + + if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){ + OutputDebugString("ChoosePixelFormat Failed...."); + return FALSE; + } + + if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE){ + OutputDebugString("SetPixelFormat Failed...."); + return FALSE; + } + + if (!(hRC=wglCreateContext(hDC))){ + OutputDebugString("Creating HGLRC Failed...."); + return FALSE; + } + + // Set Vsync + //BOOL (WINAPI *wglSwapIntervalEXT)(int) = NULL; + + //if(strstr((char*)glGetString( GL_EXTENSIONS ),"WGL_EXT_swap_control")== 0) { + //} + //else { + //wglSwapIntervalEXT = (BOOL (WINAPI*)(int))wglGetProcAddress("wglSwapIntervalEXT"); + //if(wglSwapIntervalEXT) wglSwapIntervalEXT(1); + //} + + wglMakeCurrent(hDC,hRC); + + ShowWindow(hWnd,SW_SHOW); + SetForegroundWindow(hWnd); + SetFocus(hWnd); + + render_resize(width, height); + + glClearColor(0.0f,0.0f,0.0f,0.0f); + glClearDepth(1.0f); + + return TRUE; +} + +int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) +{ + if(!createWindow(SAMPLE_NAME,DISPLAY_WIDTH,DISPLAY_HEIGHT)) { + MessageBox(NULL,"Can't create gl window.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return 0; + } + + init(); + + physics_create_scene(sceneId); + + SCE_PFX_PRINTF("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + MSG msg; + while(s_isRunning) { + if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if(msg.message==WM_QUIT) { + s_isRunning = false; + } + else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + else { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + } + + shutdown(); + + SCE_PFX_PRINTF("## %s: FINISHED ##\n", SAMPLE_NAME); + + releaseWindow(); + return (msg.wParam); +} + +#endif diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/physics.png b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/physics.png new file mode 100644 index 000000000..d4813595d Binary files /dev/null and b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/physics.png differ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/physics_func.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/physics_func.cpp new file mode 100644 index 000000000..520571092 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/physics_func.cpp @@ -0,0 +1,1641 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "physics_func.h" +#include "../common/perf_func.h" + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Data + +#define NUM_RIGIDBODIES 500 +#define NUM_JOINTS 500 +#define NUM_CONTACTS 4000 + +const float timeStep = 0.016f; +const float separateBias = 0.1f; +int iteration = 8; + +//J ワールドサイズ +//E World size +PfxVector3 worldCenter(0.0f); +PfxVector3 worldExtent(500.0f); + +//J 剛体 +//E Rigid body +PfxRigidState states[NUM_RIGIDBODIES]; +PfxRigidBody bodies[NUM_RIGIDBODIES]; +PfxCollidable collidables[NUM_RIGIDBODIES]; +PfxSolverBody solverBodies[NUM_RIGIDBODIES]; +int numRigidBodies = 0; + +//J プロキシ +//E Proxies +PfxBroadphaseProxy proxies[6][NUM_RIGIDBODIES]; // shared by simulation and raycast + +//J ジョイント +//E Joint +PfxConstraintPair jointPairs[NUM_JOINTS]; +PfxJoint joints[NUM_JOINTS]; +int numJoints = 0; + +//J ペア +//E Pairs +unsigned int pairSwap; +unsigned int numPairs[2]; +PfxBroadphasePair pairsBuff[2][NUM_CONTACTS]; + +//J コンタクト +//E Contacts +PfxContactManifold contacts[NUM_CONTACTS]; +int numContacts; + +PfxUInt32 contactIdPool[NUM_CONTACTS]; +int numContactIdPool; + +//J シミュレーションアイランド +//E Island generation +PfxIsland *island=NULL; +PfxUInt8 SCE_PFX_ALIGNED(16) islandBuff[32*NUM_RIGIDBODIES]; // Island buffer should be 32 * the number of rigid bodies. + +//J スリープ制御 +//E Sleep control +/* + A sleeping object wakes up, when + * a new pair related to this rigid body is created + * a pair releated to this rigid body is removed + * a rigid body's velocity or position are updated + */ + +//J スリープに入るカウント +//E Count to enter sleeping +const PfxUInt32 sleepCount = 180; + +//J 速度が閾値以下ならばスリープカウントが増加 +//E If velocity is under the following value, sleep count is increased. +const PfxFloat sleepVelocity = 0.3f; + +//J 一時バッファ +//E Temporary buffers +#define POOL_BYTES (5*1024*1024) +unsigned char SCE_PFX_ALIGNED(128) poolBuff[POOL_BYTES]; + +//J 一時バッファ用スタックアロケータ +//E Stack allocator for temporary buffers +PfxHeapManager pool(poolBuff,POOL_BYTES); + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Function + +int frame = 0; + +void broadphase() +{ + pairSwap = 1-pairSwap; + + unsigned int &numPreviousPairs = numPairs[1-pairSwap]; + unsigned int &numCurrentPairs = numPairs[pairSwap]; + PfxBroadphasePair *previousPairs = pairsBuff[1-pairSwap]; + PfxBroadphasePair *currentPairs = pairsBuff[pairSwap]; + + //J 剛体が最も分散している軸を見つける + //E Find the axis along which all rigid bodies are most widely positioned + int axis = 0; + { + PfxVector3 s(0.0f),s2(0.0f); + for(int i=0;i v[0]) axis = 1; + if(v[2] > v[axis]) axis = 2; + } + + //J ブロードフェーズプロキシの更新 + //E Create broadpahse proxies + { + //J レイキャストと共用するため、全ての軸に対するプロキシ配列を作成する + //E To share with ray casting, create proxy arrays for all axis + + PfxUpdateBroadphaseProxiesParam param; + param.workBytes = pfxGetWorkBytesOfUpdateBroadphaseProxies(numRigidBodies); + param.workBuff = pool.allocate(param.workBytes,128); + param.numRigidBodies = numRigidBodies; + param.offsetRigidStates = states; + param.offsetCollidables = collidables; + param.proxiesX = proxies[0]; + param.proxiesY = proxies[1]; + param.proxiesZ = proxies[2]; + param.proxiesXb = proxies[3]; + param.proxiesYb = proxies[4]; + param.proxiesZb = proxies[5]; + param.worldCenter = worldCenter; + param.worldExtent = worldExtent; + + PfxUpdateBroadphaseProxiesResult result; + + int ret = pfxUpdateBroadphaseProxies(param,result); + if(ret != SCE_PFX_OK) SCE_PFX_PRINTF("pfxUpdateBroadphaseProxies failed %d\n",ret); + + pool.deallocate(param.workBuff); + } + + //J 交差ペア探索 + //E Find overlapped pairs + { + PfxFindPairsParam findPairsParam; + findPairsParam.pairBytes = pfxGetPairBytesOfFindPairs(NUM_CONTACTS); + findPairsParam.pairBuff = pool.allocate(findPairsParam.pairBytes); + findPairsParam.workBytes = pfxGetWorkBytesOfFindPairs(NUM_CONTACTS); + findPairsParam.workBuff = pool.allocate(findPairsParam.workBytes); + findPairsParam.proxies = proxies[axis]; + findPairsParam.numProxies = numRigidBodies; + findPairsParam.maxPairs = NUM_CONTACTS; + findPairsParam.axis = axis; + + PfxFindPairsResult findPairsResult; + + int ret = pfxFindPairs(findPairsParam,findPairsResult); + if(ret != SCE_PFX_OK) SCE_PFX_PRINTF("pfxFindPairs failed %d\n",ret); + + pool.deallocate(findPairsParam.workBuff); + + //J 交差ペア合成 + //E Decompose overlapped pairs into 3 arrays + PfxDecomposePairsParam decomposePairsParam; + decomposePairsParam.pairBytes = pfxGetPairBytesOfDecomposePairs(numPreviousPairs,findPairsResult.numPairs); + decomposePairsParam.pairBuff = pool.allocate(decomposePairsParam.pairBytes); + decomposePairsParam.workBytes = pfxGetWorkBytesOfDecomposePairs(numPreviousPairs,findPairsResult.numPairs); + decomposePairsParam.workBuff = pool.allocate(decomposePairsParam.workBytes); + decomposePairsParam.previousPairs = previousPairs; + decomposePairsParam.numPreviousPairs = numPreviousPairs; + decomposePairsParam.currentPairs = findPairsResult.pairs; // Set pairs from pfxFindPairs() + decomposePairsParam.numCurrentPairs = findPairsResult.numPairs; // Set the number of pairs from pfxFindPairs() + + PfxDecomposePairsResult decomposePairsResult; + + ret = pfxDecomposePairs(decomposePairsParam,decomposePairsResult); + if(ret != SCE_PFX_OK) SCE_PFX_PRINTF("pfxDecomposePairs failed %d\n",ret); + + pool.deallocate(decomposePairsParam.workBuff); + + PfxBroadphasePair *outNewPairs = decomposePairsResult.outNewPairs; + PfxBroadphasePair *outKeepPairs = decomposePairsResult.outKeepPairs; + PfxBroadphasePair *outRemovePairs = decomposePairsResult.outRemovePairs; + PfxUInt32 numOutNewPairs = decomposePairsResult.numOutNewPairs; + PfxUInt32 numOutKeepPairs = decomposePairsResult.numOutKeepPairs; + PfxUInt32 numOutRemovePairs = decomposePairsResult.numOutRemovePairs; + + //J 廃棄ペアのコンタクトをプールに戻す + //E Put removed contacts into the contact pool + for(PfxUInt32 i=0;i 0) { + cId = contactIdPool[--numContactIdPool]; + } + else { + cId = numContacts++; + } + if(cId >= NUM_CONTACTS) { + cId = 0; + } + SCE_PFX_ASSERT(cId < NUM_CONTACTS); + pfxSetContactId(outNewPairs[i],cId); + PfxContactManifold &contact = contacts[cId]; + contact.reset(pfxGetObjectIdA(outNewPairs[i]),pfxGetObjectIdB(outNewPairs[i])); + + //J 寝てる剛体を起こす + //E Wake up sleeping rigid bodies + PfxRigidState &stateA = states[pfxGetObjectIdA(outNewPairs[i])]; + PfxRigidState &stateB = states[pfxGetObjectIdB(outNewPairs[i])]; + if(stateA.isAsleep()) { + stateA.wakeup(); + SCE_PFX_PRINTF("wakeup %u\n",stateA.getRigidBodyId()); + } + if(stateB.isAsleep()) { + stateB.wakeup(); + SCE_PFX_PRINTF("wakeup %u\n",stateB.getRigidBodyId()); + } + } + + //J 新規ペアと維持ペアを合成 + //E Merge 'new' and 'keep' pairs + numCurrentPairs = 0; + for(PfxUInt32 i=0;i sleepCount) { + numCanSleep++; + } + } + } + } + + // Deactivate Island + if(numCanSleep > 0 && numCanSleep == numActive + numSleep) { + PfxIslandUnit *islandUnit = pfxGetFirstUnitInIsland(island,(PfxUInt32)i); + for(;islandUnit!=NULL;islandUnit=pfxGetNextUnitInIsland(islandUnit)) { + if(!(SCE_PFX_MOTION_MASK_CAN_SLEEP(states[pfxGetUnitId(islandUnit)].getMotionType()))) continue; + states[pfxGetUnitId(islandUnit)].sleep(); + } + } + + // Activate Island + else if(numSleep > 0 && numActive > 0) { + PfxIslandUnit *islandUnit = pfxGetFirstUnitInIsland(island,(PfxUInt32)i); + for(;islandUnit!=NULL;islandUnit=pfxGetNextUnitInIsland(islandUnit)) { + if(!(SCE_PFX_MOTION_MASK_CAN_SLEEP(states[pfxGetUnitId(islandUnit)].getMotionType()))) continue; + states[pfxGetUnitId(islandUnit)].wakeup(); + } + } + } + } +} + +void integrate() +{ + PfxUpdateRigidStatesParam param; + param.states = states; + param.bodies = bodies; + param.numRigidBodies = numRigidBodies; + param.timeStep = timeStep; + + pfxUpdateRigidStates(param); +} + +void physics_simulate() +{ + PfxPerfCounter pc; + + for(int i=1;i0) { + PfxRigidState &stateA = states[id-1]; + PfxRigidState &stateB = states[id]; + int jointId = numJoints++; + PfxSwingTwistJointInitParam jparam; + jparam.twistLowerAngle = -0.5f; + jparam.twistUpperAngle = 0.5f; + jparam.anchorPoint = (stateA.getPosition() + stateB.getPosition())*0.5f; + jparam.twistAxis = PfxVector3(1.0f,0.0f,0.0f); + pfxInitializeSwingTwistJoint(joints[jointId],stateA,stateB,jparam); + pfxUpdateJointPairs(jointPairs[jointId],jointId,joints[jointId],stateA,stateB); + + joints[jointId].m_constraints[3].m_damping = 0.1f; + } + + if(i==0) { + firstRope = id; + } + else if(i==numRopes-1) { + lastRope = id; + } + } + } + + const PfxFloat sphereRad = 2.0f; + + { + PfxShape shapeSphere; + shapeSphere.reset(); + shapeSphere.setSphere(PfxSphere(sphereRad)); + + { + PfxVector3 pos = states[firstRope].getPosition() - PfxVector3(ropeLen+sphereRad,0.0f,0.0f); + + int id2 = numRigidBodies++; + collidables[id2].reset(); + collidables[id2].addShape(shapeSphere); + collidables[id2].finish(); + bodies[id2].reset(); + bodies[id2].setMass(10.0f); + bodies[id2].setInertia(pfxCalcInertiaSphere(sphereRad,15.0f)); + states[id2].reset(); + states[id2].setPosition(pos); + states[id2].setMotionType(kPfxMotionTypeActive); + states[id2].setUseSleep(1); + states[id2].setRigidBodyId(id2); + states[id2].setContactFilterSelf(0x00000001); + states[id2].setContactFilterTarget(0xfffffffe); + + int jointId = numJoints++; + PfxBallJointInitParam jparam; + jparam.anchorPoint = states[firstRope].getPosition() - PfxVector3(ropeLen,0.0f,0.0f); + pfxInitializeBallJoint(joints[jointId],states[id2],states[firstRope],jparam); + pfxUpdateJointPairs(jointPairs[jointId],jointId,joints[jointId],states[id2],states[firstRope]); + } + + { + PfxVector3 pos = states[lastRope].getPosition() + PfxVector3(ropeLen+sphereRad,0.0f,0.0f); + + int id2 = numRigidBodies++; + collidables[id2].reset(); + collidables[id2].addShape(shapeSphere); + collidables[id2].finish(); + bodies[id2].reset(); + bodies[id2].setMass(2.0f); + bodies[id2].setInertia(pfxCalcInertiaSphere(sphereRad,5.0f)); + states[id2].reset(); + states[id2].setPosition(pos); + states[id2].setMotionType(kPfxMotionTypeActive); + states[id2].setUseSleep(1); + states[id2].setRigidBodyId(id2); + states[id2].setContactFilterSelf(0x00000001); + states[id2].setContactFilterTarget(0xfffffffe); + + int jointId = numJoints++; + PfxBallJointInitParam jparam; + jparam.anchorPoint = states[lastRope].getPosition() + PfxVector3(ropeLen,0.0f,0.0f); + pfxInitializeBallJoint(joints[jointId],states[id2],states[lastRope],jparam); + pfxUpdateJointPairs(jointPairs[jointId],jointId,joints[jointId],states[id2],states[lastRope]); + } + } +} + +void createSceneBoxGround() +{ + int id = numRigidBodies++; + PfxBox box(150.0f,2.5f,150.0f); + PfxShape shape; + shape.reset(); + shape.setBox(box); + collidables[id].reset(); + collidables[id].addShape(shape); + collidables[id].finish(); + bodies[id].reset(); + states[id].reset(); + states[id].setPosition(PfxVector3(0.0f,-2.5f,0.0f)); + states[id].setMotionType(kPfxMotionTypeFixed); + states[id].setRigidBodyId(id); +} + +void physics_create_scene(int sceneId) +{ + const int numScenes = 3; + int sid = sceneId % numScenes; + + numRigidBodies= 0; + pairSwap = 0; + numPairs[0] = 0; + numPairs[1] = 0; + numContacts = 0; + numContactIdPool = 0; + numJoints = 0; + island = NULL; + frame = 0; + + //E Keep a first joint as a pick joint + //J 最初のジョイントをピッキング用にキープ + numJoints = 1; + joints[0].m_active = 0; + pfxSetActive(jointPairs[0],false); + + switch(sid) { + case 0: // basic joints + createSceneBoxGround(); + createSceneBasicJoints(); + break; + + case 1: // ragdolls + createSceneBoxGround(); + createSceneRagdolls(); + break; + + case 2: // complex machine + createSceneBoxGround(); + createSceneComplexMachine(); + break; + } + + SCE_PFX_PRINTF("----- Size of rigid body buffer ------\n"); + SCE_PFX_PRINTF(" size * num = total\n"); + SCE_PFX_PRINTF("PfxRigidState %5d * %5d = %5d bytes\n",sizeof(PfxRigidState),numRigidBodies,sizeof(PfxRigidState)*numRigidBodies); + SCE_PFX_PRINTF("PfxRigidBody %5d * %5d = %5d bytes\n",sizeof(PfxRigidBody),numRigidBodies,sizeof(PfxRigidBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxCollidable %5d * %5d = %5d bytes\n",sizeof(PfxCollidable),numRigidBodies,sizeof(PfxCollidable)*numRigidBodies); + SCE_PFX_PRINTF("PfxJoint %5d * %5d = %5d bytes\n",sizeof(PfxJoint),numJoints,sizeof(PfxJoint)*numJoints); + SCE_PFX_PRINTF("PfxSolverBody %5d * %5d = %5d bytes\n",sizeof(PfxSolverBody),numRigidBodies,sizeof(PfxSolverBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxBroadphaseProxy %5d * %5d = %5d bytes\n",sizeof(PfxBroadphaseProxy),numRigidBodies,sizeof(PfxBroadphaseProxy)*numRigidBodies); + SCE_PFX_PRINTF("PfxContactManifold %5d * %5d = %5d bytes\n",sizeof(PfxContactManifold),NUM_CONTACTS,sizeof(PfxContactManifold)*NUM_CONTACTS); + SCE_PFX_PRINTF("PfxBroadphasePair %5d * %5d = %5d bytes\n",sizeof(PfxBroadphasePair),NUM_CONTACTS,sizeof(PfxBroadphasePair)*NUM_CONTACTS); + + int totalBytes = + (sizeof(PfxRigidState) + sizeof(PfxRigidBody) + sizeof(PfxCollidable) + sizeof(PfxSolverBody) + sizeof(PfxBroadphaseProxy)) * numRigidBodies + + (sizeof(PfxContactManifold) + sizeof(PfxBroadphasePair)) * NUM_CONTACTS; + SCE_PFX_PRINTF("----------------------------------------------------------\n"); + SCE_PFX_PRINTF("Total %5d bytes\n",totalBytes); +} + +/////////////////////////////////////////////////////////////////////////////// +// Initialize / Finalize Engine + +bool physics_init() +{ + return true; +} + +void physics_release() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Pick + +inline PfxVector3 calcLocalCoord(const PfxRigidState &state,const PfxVector3 &coord) +{ + return rotate(conj(state.getOrientation()),(coord - state.getPosition())); +} + +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2) +{ + PfxJoint &pickJoint = joints[0]; + + PfxRayCastParam param; + param.offsetRigidStates = states; + param.offsetCollidables = collidables; + param.proxiesX = proxies[0]; + param.proxiesY = proxies[1]; + param.proxiesZ = proxies[2]; + param.proxiesXb = proxies[3]; + param.proxiesYb = proxies[4]; + param.proxiesZb = proxies[5]; + param.numProxies = numRigidBodies; + param.rangeCenter = worldCenter; + param.rangeExtent = worldExtent; + + PfxRayInput pickRay; + PfxRayOutput pickOut; + + pickRay.m_contactFilterSelf = pickRay.m_contactFilterTarget = 0xffffffff; + pickRay.m_startPosition = p1; + pickRay.m_direction = p2-p1; + pickRay.m_facetMode = SCE_PFX_RAY_FACET_MODE_FRONT_ONLY; + pfxCastSingleRay(pickRay,pickOut,param); + + if(pickOut.m_contactFlag) { + PfxRigidState &stateA = states[0]; + PfxRigidState &stateB = states[pickOut.m_objectId]; + PfxRigidBody &bodyB = bodies[pickOut.m_objectId]; + + /* Connect a picked rigid body and the ground with a ball joint. + * Weaken pick power by adjusting a m_maxImpulse parameter so that impulse doesn't exceeds m_maxImpulse. + * It is needed, because constraint power is too strong. + */ + + PfxBallJointInitParam jparam; + jparam.anchorPoint = pickOut.m_contactPoint; + + pfxInitializeBallJoint(pickJoint,stateA,stateB,jparam); + pickJoint.m_constraints[0].m_maxImpulse = bodyB.getMass() * 2.0f; + pickJoint.m_constraints[1].m_maxImpulse = bodyB.getMass() * 2.0f; + pickJoint.m_constraints[2].m_maxImpulse = bodyB.getMass() * 2.0f; + + pfxUpdateJointPairs(jointPairs[0],0,pickJoint,stateA,stateB); + + SCE_PFX_PRINTF("pick objId %d ",pickOut.m_objectId); + if(pickOut.m_subData.m_type == PfxSubData::MESH_INFO) { + SCE_PFX_PRINTF("mesh islandId %d facetId %d",pickOut.m_subData.getIslandId(),pickOut.m_subData.getFacetId()); + } + SCE_PFX_PRINTF("\n"); + + return pickOut.m_contactPoint; + } + + return PfxVector3(0.0f); +} + +void physics_pick_update(const PfxVector3 &p) +{ + PfxJoint &pickJoint = joints[0]; + + if(pickJoint.m_active>0) { + pickJoint.m_anchorA = calcLocalCoord(states[pickJoint.m_rigidBodyIdA],p); + if(states[pickJoint.m_rigidBodyIdB].isAsleep()) { + states[pickJoint.m_rigidBodyIdB].wakeup(); + } + } +} + +void physics_pick_end() +{ + PfxJoint &pickJoint = joints[0]; + + if(pickJoint.m_active>0) { + pickJoint.m_active = 0; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Get Information + +int physics_get_num_rigidbodies() +{ + return numRigidBodies; +} + +const PfxRigidState& physics_get_state(int id) +{ + return states[id]; +} + +const PfxRigidBody& physics_get_body(int id) +{ + return bodies[id]; +} + +const PfxCollidable& physics_get_collidable(int id) +{ + return collidables[id]; +} + +int physics_get_num_contacts() +{ + return numPairs[pairSwap]; +} + +const PfxContactManifold &physics_get_contact(int id) +{ + return contacts[pfxGetConstraintId(pairsBuff[pairSwap][id])]; +} + +const PfxIsland* physics_get_islands() +{ + return island; +} diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/physics_func.h b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/physics_func.h new file mode 100644 index 000000000..bde418949 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/6_joint/physics_func.h @@ -0,0 +1,53 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef __PHYSICS_FUNC_H__ +#define __PHYSICS_FUNC_H__ + +#define SCE_PFX_USE_PERFCOUNTER + +#include "physics_effects.h" + +using namespace sce::PhysicsEffects; + +//E Simulation +//J シミュレーション +bool physics_init(); +void physics_release(); +void physics_create_scene(int sceneId); +void physics_simulate(); + +//E Picking +//J ピッキング +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2); +void physics_pick_update(const PfxVector3 &p); +void physics_pick_end(); + +//E Change parameters +//J パラメータの取得 +int physics_get_num_rigidbodies(); +const PfxRigidState& physics_get_state(int id); +const PfxRigidBody& physics_get_body(int id); +const PfxCollidable& physics_get_collidable(int id); + +// Get contact information +int physics_get_num_contacts(); +const PfxContactManifold &physics_get_contact(int id); + +// Get simulation island +const PfxIsland* physics_get_islands(); + +#endif /* __PHYSICS_FUNC_H__ */ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/99_BulletPhysicsEffects.vcproj b/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/99_BulletPhysicsEffects.vcproj new file mode 100644 index 000000000..c1903deb3 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/99_BulletPhysicsEffects.vcproj @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/CMakeLists.txt b/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/CMakeLists.txt new file mode 100644 index 000000000..4d210b93c --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/CMakeLists.txt @@ -0,0 +1,89 @@ +cmake_minimum_required(VERSION 2.4) + + +#this line has to appear before 'PROJECT' in order to be able to disable incremental linking +SET(MSVC_INCREMENTAL_DEFAULT ON) + +PROJECT(App_99_BulletPhysicsEffects) + + +IF (NOT CMAKE_BUILD_TYPE) +# SET(CMAKE_BUILD_TYPE "Debug") + SET(CMAKE_BUILD_TYPE "Release") +ENDIF (NOT CMAKE_BUILD_TYPE) + + +OPTION(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC Runtime Library DLL (/MD or /MDd)" ON) +OPTION(USE_MSVC_INCREMENTAL_LINKING "Use MSVC Incremental Linking" OFF) + + +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + + +SET(App_99_BulletPhysicsEffects_SRCS + main.cpp + bullet_physics_func.cpp + ../common/ctrl_func.win32.cpp + ../common/perf_func.win32.cpp + ../common/render_func.win32.cpp + ${PHYSICS_EFFECTS_SOURCE_DIR}/include/BulletPhysicsEffects/btBulletPhysicsEffectsWorld.cpp + ${PHYSICS_EFFECTS_SOURCE_DIR}/include/BulletPhysicsEffects/btLowLevelConstraintSolver2.cpp + ${PHYSICS_EFFECTS_SOURCE_DIR}/include/BulletPhysicsEffects/btLowLevelCollisionDispatcher.cpp + ${PHYSICS_EFFECTS_SOURCE_DIR}/include/BulletPhysicsEffects/btLowLevelBroadphase.cpp + +) + + +SET(App_99_BulletPhysicsEffects_HDRS + physics_func.h + landscape.h + barrel.h + ../common/render_func.h + ../common/common.h + ../common/ctrl_func.h + ../common/perf_func.h + ${PHYSICS_EFFECTS_SOURCE_DIR}/include/BulletPhysicsEffects/btBulletPhysicsEffectsWorld.h + ${PHYSICS_EFFECTS_SOURCE_DIR}/include/BulletPhysicsEffects/btLowLevelConstraintSolver2.h + ${PHYSICS_EFFECTS_SOURCE_DIR}/include/BulletPhysicsEffects/btLowLevelCollisionDispatcher.h + ${PHYSICS_EFFECTS_SOURCE_DIR}/include/BulletPhysicsEffects/btLowLevelBroadphase.h +) + + +INCLUDE_DIRECTORIES( + ../../../../../src +# ${VECTOR_MATH_INCLUDE} +) + +#LINK_DIRECTORIES( +# +#) + +#ADD_DEFINITIONS(-DUNICODE) +#ADD_DEFINITIONS(-D_UNICODE) + +ADD_EXECUTABLE(App_99_BulletPhysicsEffects WIN32 + ${App_99_BulletPhysicsEffects_SRCS} + ${App_99_BulletPhysicsEffects_HDRS} +) +TARGET_LINK_LIBRARIES(App_99_BulletPhysicsEffects + PfxBaseLevel + PfxLowLevel + PfxUtil + BulletDynamics + BulletCollision + LinearMath + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} +) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(App_99_BulletPhysicsEffects PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(App_99_BulletPhysicsEffects PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(App_99_BulletPhysicsEffects PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF() + + + + \ No newline at end of file diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/barrel.h b/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/barrel.h new file mode 100644 index 000000000..ade7bb5b1 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/barrel.h @@ -0,0 +1,202 @@ +/* +Physics Effects Copyright(C) 2011 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define BarrelVtxCount 57 +#define BarrelIdxCount 180 + +static float BarrelVtx[] = { +0.0f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,-0.331936f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,-0.205148f, 0.0f,-1.0f,0.0f, +-0.349018f,-0.5f,0.0f, 0.0f,-1.0f,0.0f, +-0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +-0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.107853f,-0.5f,0.331936f, 0.0f,-1.0f,0.0f, +0.282362f,-0.5f,0.205148f, 0.0f,-1.0f,0.0f, +0.0f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,-0.331936f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,-0.205148f, 0.0f,1.0f,0.0f, +-0.349018f,0.5f,0.0f, 0.0f,1.0f,0.0f, +-0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +-0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.107853f,0.5f,0.331936f, 0.0f,1.0f,0.0f, +0.282362f,0.5f,0.205148f, 0.0f,1.0f,0.0f, +0.349018f,-0.5f,0.0f, 0.957307f,-0.289072f,0.0f, +0.404509f,0.0f,-0.293893f, 0.809017f,0.0f,-0.587785f, +0.5f,0.0f,0.0f, 1.0f,0.0f,0.0f, +0.282362f,-0.5f,-0.205148f, 0.774478f,-0.289072f,-0.562691f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +0.107853f,-0.5f,-0.331936f, 0.295824f,-0.289072f,-0.910453f, +-0.154509f,0.0f,-0.475528f, -0.309017f,0.0f,-0.951057f, +0.154508f,0.0f,-0.475528f, 0.309017f,0.0f,-0.951057f, +-0.107853f,-0.5f,-0.331936f, -0.295824f,-0.289072f,-0.910453f, +-0.404509f,0.0f,-0.293893f, -0.809017f,0.0f,-0.587785f, +-0.282362f,-0.5f,-0.205148f, -0.774478f,-0.289072f,-0.562691f, +-0.5f,0.0f,0.0f, -1.0f,0.0f,0.0f, +-0.349018f,-0.5f,0.0f, -0.957307f,-0.289072f,0.0f, +-0.404508f,0.0f,0.293893f, -0.809017f,0.0f,0.587785f, +-0.282362f,-0.5f,0.205148f, -0.774478f,-0.289072f,0.562691f, +-0.154509f,0.0f,0.475528f, -0.309017f,0.0f,0.951056f, +-0.107853f,-0.5f,0.331936f, -0.295824f,-0.289072f,0.910453f, +0.154509f,0.0f,0.475528f, 0.309017f,0.0f,0.951056f, +0.107853f,-0.5f,0.331936f, 0.295824f,-0.289072f,0.910453f, +0.404509f,0.0f,0.293892f, 0.809017f,0.0f,0.587785f, +0.282362f,-0.5f,0.205148f, 0.774478f,-0.289072f,0.562691f, +0.282362f,0.5f,-0.205148f, 0.774478f,0.289072f,-0.562691f, +0.349018f,0.5f,0.0f, 0.957307f,0.289072f,0.0f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.107853f,0.5f,-0.331936f, -0.295824f,0.289072f,-0.910453f, +0.107853f,0.5f,-0.331936f, 0.295824f,0.289072f,-0.910453f, +-0.282362f,0.5f,-0.205148f, -0.774478f,0.289072f,-0.562691f, +-0.349018f,0.5f,0.0f, -0.957307f,0.289072f,0.0f, +-0.282362f,0.5f,0.205148f, -0.774478f,0.289072f,0.562691f, +-0.107853f,0.5f,0.331936f, -0.295824f,0.289072f,0.910453f, +0.107853f,0.5f,0.331936f, 0.295824f,0.289072f,0.910453f, +0.282362f,0.5f,0.205148f, 0.774478f,0.289072f,0.562691f, +}; + +static float BarrelTex[] = { +0.0f,0.5f, +0.0f,0.85f, +0.0f,0.75f, +0.0f,0.95f, +0.0f,0.05f, +0.0f,-0.05f, +0.0f,0.15f, +0.0f,0.25f, +0.0f,0.35f, +0.0f,0.45f, +0.0f,0.55f, +0.0f,0.65f, +1.0f,0.5f, +1.0f,0.75f, +1.0f,0.85f, +1.0f,0.95f, +1.0f,-0.05f, +1.0f,0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +0.0f,0.75f, +0.5f,0.85f, +0.5f,0.75f, +0.0f,0.85f, +0.5f,0.95f, +0.0f,0.95f, +0.0f,-0.05f, +0.5f,0.05f, +0.5f,-0.05f, +0.0f,0.05f, +0.5f,0.15f, +0.0f,0.15f, +0.5f,0.25f, +0.0f,0.25f, +0.5f,0.35f, +0.0f,0.35f, +0.5f,0.45f, +0.0f,0.45f, +0.5f,0.55f, +0.0f,0.55f, +0.5f,0.65f, +0.0f,0.65f, +1.0f,0.85f, +1.0f,0.75f, +1.0f,0.95f, +1.0f,0.05f, +1.0f,-0.05f, +1.0f,0.15f, +1.0f,0.25f, +1.0f,0.35f, +1.0f,0.45f, +1.0f,0.55f, +1.0f,0.65f, +}; + +static unsigned short BarrelIdx[] = { +0,1,2, +0,3,1, +0,4,5, +0,6,4, +0,7,6, +0,8,7, +0,9,8, +0,10,9, +0,11,10, +0,2,11, +12,13,14, +12,14,15, +12,16,17, +12,17,18, +12,18,19, +12,19,20, +12,20,21, +12,21,22, +12,22,23, +12,23,13, +24,25,26, +24,27,25, +27,28,25, +27,29,28, +30,31,32, +30,33,31, +33,34,31, +33,35,34, +35,36,34, +35,37,36, +37,38,36, +37,39,38, +39,40,38, +39,41,40, +41,42,40, +41,43,42, +43,44,42, +43,45,44, +45,26,44, +45,24,26, +26,46,47, +26,25,46, +25,48,46, +25,28,48, +32,49,50, +32,31,49, +31,51,49, +31,34,51, +34,52,51, +34,36,52, +36,53,52, +36,38,53, +38,54,53, +38,40,54, +40,55,54, +40,42,55, +42,56,55, +42,44,56, +44,47,56, +44,26,47, +}; + diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/bullet_physics_func.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/bullet_physics_func.cpp new file mode 100644 index 000000000..e342e2af0 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/bullet_physics_func.cpp @@ -0,0 +1,1241 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "physics_func.h" +#include "../common/perf_func.h" + +#include "BulletPhysicsEffects/btBulletPhysicsEffectsWorld.h" +#include "BulletPhysicsEffects/btLowLevelBroadphase.h" +#include "BulletPhysicsEffects/btLowLevelCollisionDispatcher.h" +#include "BulletPhysicsEffects/btLowLevelData.h" +#include "BulletPhysicsEffects/btLowLevelConstraintSolver.h" +#include "BulletPhysicsEffects/btLowLevelConstraintSolver2.h" + + +#include "LinearMath/btIDebugDraw.h" +#include "BulletMultiThreaded/vectormath2bullet.h" +#include "../common/render_func.h" +#if 0 +#ifdef _WIN32 +#include "BulletMultiThreaded/Win32ThreadSupport.h" +#endif + +btThreadSupportInterface* createSolverThreadSupport(int maxNumThreads) +{ +#define SEQUENTIAL +#ifdef SEQUENTIAL + SequentialThreadSupport::SequentialThreadConstructionInfo tci("solverThreads",SolverThreadFunc,SolverlsMemoryFunc); + SequentialThreadSupport* threadSupport = new SequentialThreadSupport(tci); + threadSupport->startSPU(); +#else + +#ifdef _WIN32 + Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("solverThreads",SolverThreadFunc,SolverlsMemoryFunc,maxNumThreads); + Win32ThreadSupport* threadSupport = new Win32ThreadSupport(threadConstructionInfo); + threadSupport->startSPU(); +#elif defined (USE_PTHREADS) + PosixThreadSupport::ThreadConstructionInfo solverConstructionInfo("solver", SolverThreadFunc, + SolverlsMemoryFunc, maxNumThreads); + + PosixThreadSupport* threadSupport = new PosixThreadSupport(solverConstructionInfo); + +#else + SequentialThreadSupport::SequentialThreadConstructionInfo tci("solverThreads",SolverThreadFunc,SolverlsMemoryFunc); + SequentialThreadSupport* threadSupport = new SequentialThreadSupport(tci); + threadSupport->startSPU(); +#endif + +#endif + + return threadSupport; +} +#endif + + +class PEDebugDrawer : public btIDebugDraw +{ + int m_debugMode; + +public: + + PEDebugDrawer() + :m_debugMode(0) + { + } + virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& clr) + { + PfxVector3 position1 = getVmVector3(from); + PfxVector3 position2 = getVmVector3(to); + PfxVector3 color = getVmVector3(clr); + render_debug_line(position1,position2,color); + } + virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color) + { + + } + + virtual void reportErrorWarning(const char* warningString) + { + SCE_PFX_PRINTF(warningString); + } + + virtual void draw3dText(const btVector3& location,const char* textString) + { + } + + virtual void setDebugMode(int debugMode) + { + m_debugMode = debugMode; + } + + virtual int getDebugMode() const + { + return m_debugMode; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Data + +#define NUM_RIGIDBODIES 5000 +#define NUM_JOINTS 500 +#define NUM_CONTACTS 20000 + +const float timeStep = 0.016f; +const float separateBias = 0.1f; +int iteration = 5; + + +//J ワールドサイズ +//E World size +PfxVector3 worldCenter(0.0f); +PfxVector3 worldExtent(500.0f); + +//J 剛体 +//E Rigid body +PfxRigidState states[NUM_RIGIDBODIES]; +PfxRigidBody bodies[NUM_RIGIDBODIES]; +PfxCollidable collidables[NUM_RIGIDBODIES]; +PfxSolverBody solverBodies[NUM_RIGIDBODIES]; +int numRigidBodies = 0; +//PfxConstraintPair jointPairs[NUM_JOINTS]; +PfxJoint joints[NUM_JOINTS]; +int numJoints = 0; + +//J 地形を表現するためのラージメッシュ +//E Large mesh for representing a landscape +#include "landscape.h" +PfxLargeTriMesh gLargeMesh; + +//J 凸メッシュ +//E Convex Mesh +#include "barrel.h" +PfxConvexMesh gConvex; + + + +int physics_get_num_rigidbodies() +{ + return numRigidBodies; +} + +const PfxRigidState& physics_get_state(int id) +{ + return states[id]; +} + +const PfxRigidBody& physics_get_body(int id) +{ + return bodies[id]; +} + +const PfxCollidable& physics_get_collidable(int id) +{ + return collidables[id]; +} + + + + + +/////////////////////////////////////////////////////////////////////////////// +// Create Scene + +void createBrick(int id,const PfxVector3 &pos,const PfxQuat &rot,const PfxVector3 &boxSize,PfxFloat mass) +{ + PfxBox box(boxSize); + PfxShape shape; + shape.reset(); + shape.setBox(box); + collidables[id].reset(); + collidables[id].addShape(shape); + collidables[id].finish(); + bodies[id].reset(); + bodies[id].setRestitution(0.0f); + bodies[id].setMass(mass); + bodies[id].setInertia(pfxCalcInertiaBox(boxSize,mass)); + states[id].reset(); + states[id].setPosition(pos); + states[id].setOrientation(rot); + states[id].setMotionType(kPfxMotionTypeActive); + states[id].setRigidBodyId(id); +} + +void createWall(const PfxVector3 &offsetPosition,int stackSize,const PfxVector3 &boxSize) +{ + PfxFloat bodyMass = 0.5f; + + PfxFloat diffX = boxSize[0] * 1.02f; + PfxFloat diffY = boxSize[1] * 1.02f; + PfxFloat diffZ = boxSize[2] * 1.02f; + + PfxFloat offset = -stackSize * (diffZ * 2.0f) * 0.5f; + PfxVector3 pos(0.0f, diffY, 0.0f); + + while(stackSize) { + for(int i=0;i 0) { + pfxReleaseLargeTriMesh(gLargeMesh); + } + + PfxInt32 ret = pfxCreateLargeTriMesh(gLargeMesh,param); + if(ret != SCE_PFX_OK) { + SCE_PFX_PRINTF("Can't create large mesh.\n"); + } + + int id = numRigidBodies++; + PfxShape shape; + shape.reset(); + shape.setLargeTriMesh(&gLargeMesh); + collidables[id].reset(); + collidables[id].addShape(shape); + collidables[id].finish(); + bodies[id].reset(); + states[id].reset(); + states[id].setPosition(PfxVector3(0.0f,-5.0f,0.0f)); + states[id].setOrientation(PfxQuat::rotationX(0.5f)*PfxQuat::rotationY(0.7f)); + states[id].setMotionType(kPfxMotionTypeFixed); + states[id].setRigidBodyId(id); +} + +#include +#include "BulletMultiThreaded/vectormath2bullet.h" + +btDefaultCollisionConfiguration* m_config=0; +btCollisionDispatcher* m_dispatcher=0; +btBroadphaseInterface* m_broadphase=0; +btConstraintSolver* m_solver=0; +btDiscreteDynamicsWorld* m_dynamicsWorld=0; +btThreadSupportInterface* sThreadSupport=0; + +void debugRenderPhysics() +{ + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); +} + +static void cleanupBullet(void) +{ + if (m_dynamicsWorld) + { + delete m_dynamicsWorld; + delete m_solver; +// delete sThreadSupport; + delete m_broadphase; + delete m_dispatcher; + delete m_config; + } +} + +void physics_simulate() +{ + //run the simulation + + static btClock clock; + static bool first = true; + if (first) + { + first=false; + clock.reset(); + } + btScalar dt = (btScalar)clock.getTimeMicroseconds(); + clock.reset(); + + + + m_dynamicsWorld->stepSimulation(dt/1000000.f); + + int i; + for (i=0;igetNumCollisionObjects();i++) + { + btRigidBody* body = btRigidBody::upcast(m_dynamicsWorld->getCollisionObjectArray()[i]); + if (body) + { + + PfxRigidState* state = (PfxRigidState*) body->getUserPointer(); + + PfxVector3 pe_pos = getVmVector3(body->getWorldTransform().getOrigin()); + PfxQuat pe_orn = getVmQuat(body->getWorldTransform().getRotation()); + PfxVector3 pe_lvel = getVmVector3(body->getLinearVelocity()); + PfxVector3 pe_avel = getVmVector3(body->getAngularVelocity()); + + state->setPosition(pe_pos); + state->setOrientation(pe_orn); + state->setLinearVelocity(pe_lvel); + state->setAngularVelocity(pe_avel); + } + } + + +} + +btRigidBody* addRigidBody(btCollisionShape* shape, btScalar mass, const btTransform& startTransform) +{ + btVector3 localInertia; + localInertia.setZero(); + + if (mass) + shape->calculateLocalInertia(mass,localInertia); + + btRigidBody* body = new btRigidBody(mass,0,shape,localInertia); + body->setWorldTransform(startTransform); + body->setActivationState(DISABLE_DEACTIVATION); + //body->setFriction(2); + m_dynamicsWorld->addRigidBody(body); + return body; +} + +static void convertToBullet(void) +{ + + cleanupBullet(); + + m_config = new btDefaultCollisionConfiguration(); + + btHashedOverlappingPairCache* pairCache = new btHashedOverlappingPairCache(); + //m_broadphase = new btDbvtBroadphase(); + btLowLevelData* lowLevelData = new btLowLevelData; + + lowLevelData->m_maxContacts = NUM_CONTACTS;//8024; + lowLevelData->m_contactIdPool = (int*) btAlignedAlloc(sizeof(int)*lowLevelData->m_maxContacts ,16); + lowLevelData->m_contacts = (PfxContactManifold*) btAlignedAlloc(sizeof(PfxContactManifold)*lowLevelData->m_maxContacts,16); + lowLevelData->m_maxPairs = lowLevelData->m_maxContacts;//?? + lowLevelData->m_pairsBuff[0] = (PfxBroadphasePair*) btAlignedAlloc(sizeof(PfxBroadphasePair)*lowLevelData->m_maxPairs,16); + lowLevelData->m_pairsBuff[1] = (PfxBroadphasePair*) btAlignedAlloc(sizeof(PfxBroadphasePair)*lowLevelData->m_maxPairs,16); + +#define USE_LL_BP +#ifdef USE_LL_BP + btLowLevelBroadphase* llbp = new btLowLevelBroadphase(lowLevelData,pairCache); + m_broadphase = llbp; +#else //USE_LL_BP + m_broadphase = new btDbvtBroadphase(); +#endif //USE_LL_BP + + //m_dispatcher = new btCollisionDispatcher(m_config); + m_dispatcher = new btLowLevelCollisionDispatcher(lowLevelData,m_config,NUM_CONTACTS); + +//#ifdef USE_PARALLEL_SOLVER +// m_solver = new btSequentialImpulseConstraintSolver(); +//#else + //sThreadSupport = createSolverThreadSupport(4); + //m_solver = new btLowLevelConstraintSolver(sThreadSupport); + m_solver = new btLowLevelConstraintSolver2(lowLevelData); +//#endif //USE_PARALLEL_SOLVER + + //m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_config); + m_dynamicsWorld = new btBulletPhysicsEffectsWorld(lowLevelData, m_dispatcher,llbp,m_solver,m_config,0); + PEDebugDrawer* drawer = new PEDebugDrawer(); + drawer->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawAabb); + + m_dynamicsWorld->setDebugDrawer(drawer); + + m_dynamicsWorld ->getSolverInfo().m_splitImpulse = true; + + for(int i=0;i shapes; + btAlignedObjectArray childTtransforms; + + PfxRigidState &state = states[i];//physics_get_state(i); + state.setUserData(0); + + + const PfxCollidable &coll = physics_get_collidable(i); + + PfxTransform3 rbT(state.getOrientation(), state.getPosition()); + + PfxShapeIterator itrShape(coll); + for(int j=0;jm_verts[0]; + btConvexHullShape* convexHull = new btConvexHullShape(vertices,convex->m_numVerts, sizeof(PfxVector3)); + shapes.push_back(convexHull); + } + break; + + case kPfxShapeLargeTriMesh: + { + const PfxLargeTriMesh* mesh = shape.getLargeTriMesh(); + btTriangleIndexVertexArray* meshInterface = new btTriangleIndexVertexArray(); + int i; + for (i= 0; i < mesh->m_numIslands;i++) + { + PfxTriMesh* island = &mesh->m_islands[i]; + + //mesh->m_islands + //mesh->m_numIslands + btIndexedMesh indexedMesh; + indexedMesh.m_indexType = PHY_UCHAR; + indexedMesh.m_numTriangles = island->m_numFacets; + indexedMesh.m_triangleIndexBase = &island->m_facets[0].m_vertIds[0]; + indexedMesh.m_triangleIndexStride = sizeof(PfxFacet); + indexedMesh.m_vertexBase = (const unsigned char*) &island->m_verts[0]; + indexedMesh.m_numVertices = island->m_numVerts;//unused + indexedMesh.m_vertexStride = sizeof(PfxVector3); + meshInterface->addIndexedMesh(indexedMesh,PHY_UCHAR); + } + + btBvhTriangleMeshShape* trimesh = new btBvhTriangleMeshShape(meshInterface,true); + shapes.push_back(trimesh); + } + + break; + + default: + { + printf("unknown\n"); + } + break; + } + } + + if(shapes.size()>0) + { + printf("shapes!\n"); + btCollisionShape* colShape = 0; + if (shapes.size()==1 && childTtransforms[0].getOrigin().fuzzyZero()) +//todo: also check orientation + { + colShape = shapes[0]; + } + else + { + btCompoundShape* compound = new btCompoundShape(); + for (int i=0;iaddChildShape(childTtransforms[i],shapes[i]); + } + colShape = compound; + + } + + btTransform worldTransform; + worldTransform.setIdentity(); + worldTransform.setOrigin(getBtVector3(rbT.getTranslation())); + PfxQuat quat(rbT.getUpper3x3()); + worldTransform.setBasis(btMatrix3x3(getBtQuat(quat))); + + btScalar mass = physics_get_body(i).getMass(); + btRigidBody* body = addRigidBody(colShape,mass,worldTransform); + void* ptr = (void*)&state; + body->setUserPointer(ptr); + state.setUserData(body); + } + + } + + //very basic joint conversion (only limits of PFX_JOINT_SWINGTWIST joint) + for (int i=0;isetLimit(i,0,0); + break; + } + case SCE_PFX_JOINT_LOCK_FREE: + { + dof6->setLimit(i,1,0); + break; + } + case SCE_PFX_JOINT_LOCK_LIMIT: + { + //deal with the case where angular limits of Y-axis are free and/or beyond -PI/2 and PI/2 + if ((i==4) && ((joint.m_constraints[i].m_movableLowerLimit<-SIMD_PI/2)||(joint.m_constraints[i].m_movableUpperLimit>SIMD_PI/2))) + { + printf("error with joint limits, forcing DOF to fixed\n"); + dof6->setLimit(i,0,0); + } else + { + dof6->setLimit(i,joint.m_constraints[i].m_movableLowerLimit,joint.m_constraints[i].m_movableUpperLimit); + } + + break; + } + default: + { + printf("unknown joint lock state\n"); + } + } + + } + + m_dynamicsWorld->addConstraint(dof6,true); + + } else + { + printf("error: missing bodies during joint conversion\n"); + } + break; + }; + case kPfxJointBall: + case kPfxJointHinge: + case kPfxJointSlider: + case kPfxJointFix: + case kPfxJointUniversal: + case kPfxJointAnimation: + default: + { + printf("unknown joint\n"); + } + } + } + + //create a large enough buffer. There is no method to pre-calculate the buffer size yet. + int maxSerializeBufferSize = 1024*1024*5; + + btDefaultSerializer* serializer = new btDefaultSerializer(maxSerializeBufferSize); + m_dynamicsWorld->serialize(serializer); + + FILE* file = fopen("testFile.bullet","wb"); + fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file); + fclose(file); + +} + +void physics_create_scene(int sceneId) +{ + const int numScenes = 4; + int sid = sceneId % numScenes; + + numRigidBodies= 0; +// numPairs = 0; +// numContacts = 0; + numJoints = 0; +// //frame = 0; + + switch(sid) { + case 0: // simple primitives + createSceneBoxGround(); + createScenePrimitives(); + break; + + case 1: // joints + createSceneBoxGround(); + createSceneJoints(); + break; + + case 2: // stacking + createSceneBoxGround(); + createSceneStacking(); + break; + + case 3: // landscape + createSceneLandscape(); + createScenePrimitives(); + break; + } + + SCE_PFX_PRINTF("----- Size of rigid body buffer ------\n"); + SCE_PFX_PRINTF(" size * num = total\n"); + SCE_PFX_PRINTF("PfxRigidState %5d * %5d = %5d bytes\n",sizeof(PfxRigidState),numRigidBodies,sizeof(PfxRigidState)*numRigidBodies); + SCE_PFX_PRINTF("PfxRigidBody %5d * %5d = %5d bytes\n",sizeof(PfxRigidBody),numRigidBodies,sizeof(PfxRigidBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxCollidable %5d * %5d = %5d bytes\n",sizeof(PfxCollidable),numRigidBodies,sizeof(PfxCollidable)*numRigidBodies); + //SCE_PFX_PRINTF("PfxJoint %5d * %5d = %5d bytes\n",sizeof(PfxJoint),numJoints,sizeof(PfxJoint)*numJoints); + SCE_PFX_PRINTF("PfxSolverBody %5d * %5d = %5d bytes\n",sizeof(PfxSolverBody),numRigidBodies,sizeof(PfxSolverBody)*numRigidBodies); + SCE_PFX_PRINTF("PfxBroadphaseProxy %5d * %5d = %5d bytes\n",sizeof(PfxBroadphaseProxy),numRigidBodies,sizeof(PfxBroadphaseProxy)*numRigidBodies); + SCE_PFX_PRINTF("PfxContactManifold %5d * %5d = %5d bytes\n",sizeof(PfxContactManifold),NUM_CONTACTS,sizeof(PfxContactManifold)*NUM_CONTACTS); + SCE_PFX_PRINTF("PfxBroadphasePair %5d * %5d = %5d bytes\n",sizeof(PfxBroadphasePair),NUM_CONTACTS,sizeof(PfxBroadphasePair)*NUM_CONTACTS); + + int totalBytes = + (sizeof(PfxRigidState) + sizeof(PfxRigidBody) + sizeof(PfxCollidable) + sizeof(PfxSolverBody) + sizeof(PfxBroadphaseProxy)) * numRigidBodies + + (sizeof(PfxContactManifold) + sizeof(PfxBroadphasePair)) * NUM_CONTACTS; + + //convert to Bullet + convertToBullet(); + + + SCE_PFX_PRINTF("----------------------------------------------------------\n"); + SCE_PFX_PRINTF("Total %5d bytes\n",totalBytes); +} + +bool physics_init() +{ + return true; +} + +void physics_release() +{ +} + + +#if 0 + +//J プロキシ +//E Proxies +PfxBroadphaseProxy proxies[NUM_RIGIDBODIES]; + +//J ジョイント +//E Joint +PfxConstraintPair jointPairs[NUM_JOINTS]; +PfxJoint joints[NUM_JOINTS]; +int numJoints = 0; + +//J ペア +//E Pairs +unsigned int numPairs; +PfxBroadphasePair pairs[NUM_CONTACTS]; + +//J コンタクト +//E Contacts +PfxContactManifold contacts[NUM_CONTACTS]; +int numContacts; + +//J 一時バッファ +//E Temporary buffers +#define POOL_BYTES (5*1024*1024) +unsigned char PFX_ALIGNED(128) poolBuff[POOL_BYTES]; + +//J 一時バッファ用スタックアロケータ +//E Stack allocator for temporary buffers +PfxHeapManager pool(poolBuff,POOL_BYTES); + +/////////////////////////////////////////////////////////////////////////////// +// Simulation Function + +int frame = 0; + +void broadphase() +{ + //J 剛体が最も分散している軸を見つける + //E Find the axis along which all rigid bodies are most widely positioned + int axis = 0; + { + PfxVector3 s(0.0f),s2(0.0f); + for(int i=0;i v[0]) axis = 1; + if(v[2] > v[axis]) axis = 2; + } + + //J ブロードフェーズプロキシの更新 + //E Create broadpahse proxies + { + for(int i=0;i + #include +#endif + +#define SAMPLE_NAME "api_physics_effects/1_simple" + +static bool s_isRunning = true; + +int sceneId = 2; +bool simulating = false; + +int landscapeMeshId; +int convexMeshId; + +/* + kPfxShapeSphere = 0, + kPfxShapeBox, + kPfxShapeCapsule, + kPfxShapeCylinder, + kPfxShapeConvexMesh, + kPfxShapeLargeTriMesh, + kPfxShapeReserved0, + kPfxShapeReserved1, + kPfxShapeReserved2, + kPfxShapeUser0, + kPfxShapeUser1, + kPfxShapeUser2, + kPfxShapeCount // =12 + */ + +extern void debugRenderPhysics(); + +static void render(void) +{ + + render_begin(); + + for(int i=0;i -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_DOWN)) { + angX += 0.05f*dt; + if(angX < -1.4f) angX = -1.4f; + if(angX > -0.01f) angX = -0.01f; + } + + if(ctrl_button_pressed(BTN_LEFT)) { + angY -= 0.05f*dt; + } + + if(ctrl_button_pressed(BTN_RIGHT)) { + angY += 0.05f*dt; + } + + if(ctrl_button_pressed(BTN_ZOOM_OUT)) { + r *= (1.f+0.2*dt); + if(r > 500.0f) r = 500.0f; + } + + if(ctrl_button_pressed(BTN_ZOOM_IN)) { + r *= (1.f-0.2*dt); + if(r < 1.0f) r = 1.0f; + } + + if(ctrl_button_pressed(BTN_SCENE_RESET) == BTN_STAT_DOWN) { + physics_create_scene(sceneId); + } + + if(ctrl_button_pressed(BTN_SCENE_NEXT) == BTN_STAT_DOWN) { + physics_create_scene(++sceneId); + } + + if(ctrl_button_pressed(BTN_SIMULATION) == BTN_STAT_DOWN) { + simulating = !simulating; + } + + if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_DOWN) { + simulating = true; + } + else if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_UP || ctrl_button_pressed(BTN_STEP) == BTN_STAT_KEEP) { + simulating = false; + } + + render_set_view_angle(angX,angY,r); +} + +#ifndef WIN32 + +/////////////////////////////////////////////////////////////////////////////// +// Main + +int main(void) +{ + init(); + + physics_create_scene(sceneId); + + printf("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + while (s_isRunning) { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + + shutdown(); + + printf("## %s: FINISHED ##\n", SAMPLE_NAME); + + return 0; +} + +#else + + +#include +#include + +static jmp_buf buf; + +void second(void) { + printf("second\n"); // prints + longjmp(buf,1); // jumps back to where setjmp was called - making setjmp now return 1 +} + +void first(void) { + second(); + printf("first\n"); // does not print +} + +int main2() { + if ( ! setjmp(buf) ) { + first(); // when executed, setjmp returns 0 + } else { // when longjmp jumps back, setjmp returns 1 + printf("main\n"); // prints + } + + return 0; +} + + +/////////////////////////////////////////////////////////////////////////////// +// WinMain + +extern HDC hDC; +extern HGLRC hRC; +HWND hWnd; +HINSTANCE hInstance; + +void releaseWindow() +{ + if(hRC) { + wglMakeCurrent(0,0); + wglDeleteContext(hRC); + } + + if(hDC) ReleaseDC(hWnd,hDC); + if(hWnd) DestroyWindow(hWnd); + + UnregisterClass(SAMPLE_NAME,hInstance); +} + +LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) { + case WM_SYSCOMMAND: + { + switch (wParam) { + case SC_SCREENSAVE: + case SC_MONITORPOWER: + return 0; + } + break; + } + + case WM_CLOSE: + PostQuitMessage(0); + return 0; + + case WM_SIZE: + render_resize(LOWORD(lParam),HIWORD(lParam)); + return 0; + } + + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + +bool createWindow(char* title, int width, int height) +{ + WNDCLASS wc; + RECT rect; + rect.left=0; + rect.right=width; + rect.top=0; + rect.bottom=height; + + hInstance = GetModuleHandle(NULL); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = SAMPLE_NAME; + + if(!RegisterClass(&wc)) { + return false; + } + + AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE); + + if(!(hWnd=CreateWindowEx(WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,SAMPLE_NAME,title, + WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, + 0,0,rect.right-rect.left,rect.bottom-rect.top, + NULL,NULL,hInstance,NULL))) { + releaseWindow(); + return false; + } + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 32, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, + 0, 0, 0, 0, + 32, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + if(!(hDC=GetDC(hWnd))) + { + releaseWindow(); + OutputDebugString(""); + return FALSE; + } + + int pixelformat; + + if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){ + OutputDebugString("ChoosePixelFormat Failed...."); + return FALSE; + } + + if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE){ + OutputDebugString("SetPixelFormat Failed...."); + return FALSE; + } + + if (!(hRC=wglCreateContext(hDC))){ + OutputDebugString("Creating HGLRC Failed...."); + return FALSE; + } + + // Set Vsync + //BOOL (WINAPI *wglSwapIntervalEXT)(int) = NULL; + + //if(strstr((char*)glGetString( GL_EXTENSIONS ),"WGL_EXT_swap_control")== 0) { + //} + //else { + //wglSwapIntervalEXT = (BOOL (WINAPI*)(int))wglGetProcAddress("wglSwapIntervalEXT"); + //if(wglSwapIntervalEXT) wglSwapIntervalEXT(1); + //} + + wglMakeCurrent(hDC,hRC); + + ShowWindow(hWnd,SW_SHOW); + SetForegroundWindow(hWnd); + SetFocus(hWnd); + + render_resize(width, height); + + glClearColor(0.0f,0.0f,0.0f,0.0f); + glClearDepth(1.0f); + + return TRUE; +} + +int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) +{ + main2(); + + if(!createWindow(SAMPLE_NAME,DISPLAY_WIDTH,DISPLAY_HEIGHT)) { + MessageBox(NULL,"Can't create gl window.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return 0; + } + + init(); + + physics_create_scene(sceneId); + + SCE_PFX_PRINTF("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME); + + MSG msg; + while(s_isRunning) { + if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if(msg.message==WM_QUIT) { + s_isRunning = false; + } + else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + else { + update(); + if(simulating) physics_simulate(); + render(); + + perf_sync(); + } + } + + shutdown(); + + SCE_PFX_PRINTF("## %s: FINISHED ##\n", SAMPLE_NAME); + + releaseWindow(); + return (msg.wParam); +} + +#endif diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/physics_func.h b/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/physics_func.h new file mode 100644 index 000000000..898ce2ce1 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/99_bullet_highlevel/physics_func.h @@ -0,0 +1,49 @@ +/* +Physics Effects Copyright(C) 2011 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef __PHYSICS_FUNC_H__ +#define __PHYSICS_FUNC_H__ + +#define SCE_PFX_USE_PERFCOUNTER + +#include "physics_effects.h" + +using namespace sce::PhysicsEffects; + +//E Simulation +//J シミュレーション +bool physics_init(); +void physics_release(); +void physics_create_scene(int sceneId); +void physics_simulate(); + +//E Picking +//J ピッキング +PfxVector3 physics_pick_start(const PfxVector3 &p1,const PfxVector3 &p2); +void physics_pick_update(const PfxVector3 &p); +void physics_pick_end(); + +//E Change parameters +//J パラメータの取得 +int physics_get_num_rigidbodies(); +const PfxRigidState& physics_get_state(int id); +const PfxRigidBody& physics_get_body(int id); +const PfxCollidable& physics_get_collidable(int id); + +int physics_get_num_contacts(); +const PfxContactManifold &physics_get_contact(int id); + +#endif /* __PHYSICS_FUNC_H__ */ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/CMakeLists.txt b/Extras/PhysicsEffects/sample/api_physics_effects/CMakeLists.txt new file mode 100644 index 000000000..543922336 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/CMakeLists.txt @@ -0,0 +1,16 @@ +SUBDIRS( + 0_console +) + +IF (WIN32) + SUBDIRS( + 1_simple + 2_stable + 3_sleep + 4_motion_type + 5_raycast + 6_joint + 99_bullet_highlevel +# common + ) +ENDIF() \ No newline at end of file diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/api_physics_effects.windows.sln b/Extras/PhysicsEffects/sample/api_physics_effects/api_physics_effects.windows.sln new file mode 100644 index 000000000..f337433cc --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/api_physics_effects.windows.sln @@ -0,0 +1,164 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "1_simple.windows", "1_simple\1_simple.windows.vcproj", "{C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}" + ProjectSection(ProjectDependencies) = postProject + {4908A1B7-06F4-4517-936A-D81D140004F7} = {4908A1B7-06F4-4517-936A-D81D140004F7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "2_stable.windows", "2_stable\2_stable.winsows.vcproj", "{4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}" + ProjectSection(ProjectDependencies) = postProject + {4908A1B7-06F4-4517-936A-D81D140004F7} = {4908A1B7-06F4-4517-936A-D81D140004F7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3_sleep.windows", "3_sleep\3_sleep.windows.vcproj", "{97E051D8-9233-410D-8123-E5ED749D6640}" + ProjectSection(ProjectDependencies) = postProject + {4908A1B7-06F4-4517-936A-D81D140004F7} = {4908A1B7-06F4-4517-936A-D81D140004F7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "4_motion_type.windows", "4_motion_type\4_motion_type.windows.vcproj", "{B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}" + ProjectSection(ProjectDependencies) = postProject + {4908A1B7-06F4-4517-936A-D81D140004F7} = {4908A1B7-06F4-4517-936A-D81D140004F7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "5_raycast.windows", "5_raycast\5_raycast.windows.vcproj", "{96B87A78-C8E3-43C5-B0E4-9A30999B2712}" + ProjectSection(ProjectDependencies) = postProject + {4908A1B7-06F4-4517-936A-D81D140004F7} = {4908A1B7-06F4-4517-936A-D81D140004F7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "6_joint.windows", "6_joint\6_joint.windows.vcproj", "{A296A166-9E6A-44DE-BF58-30131687A117}" + ProjectSection(ProjectDependencies) = postProject + {4908A1B7-06F4-4517-936A-D81D140004F7} = {4908A1B7-06F4-4517-936A-D81D140004F7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "physics_effects_lib.oss", "..\..\project\physics_effects_lib.oss.vcproj", "{4908A1B7-06F4-4517-936A-D81D140004F7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Win32 Debug|Win32 = Win32 Debug|Win32 + Win32 Debug|x64 = Win32 Debug|x64 + Win32 Release|Win32 = Win32 Release|Win32 + Win32 Release|x64 = Win32 Release|x64 + Win64 Debug|Win32 = Win64 Debug|Win32 + Win64 Debug|x64 = Win64 Debug|x64 + Win64 Release|Win32 = Win64 Release|Win32 + Win64 Release|x64 = Win64 Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win32 Debug|Win32.ActiveCfg = Win32 Debug|Win32 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win32 Debug|Win32.Build.0 = Win32 Debug|Win32 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win32 Debug|x64.ActiveCfg = Win32 Debug|x64 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win32 Debug|x64.Build.0 = Win32 Debug|x64 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win32 Release|Win32.ActiveCfg = Win32 Release|Win32 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win32 Release|Win32.Build.0 = Win32 Release|Win32 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win32 Release|x64.ActiveCfg = Win32 Release|x64 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win32 Release|x64.Build.0 = Win32 Release|x64 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win64 Debug|Win32.ActiveCfg = Win64 Debug|x64 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win64 Debug|Win32.Build.0 = Win64 Debug|x64 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win64 Debug|x64.ActiveCfg = Win64 Debug|x64 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win64 Debug|x64.Build.0 = Win64 Debug|x64 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win64 Release|Win32.ActiveCfg = Win64 Release|x64 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win64 Release|Win32.Build.0 = Win64 Release|x64 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win64 Release|x64.ActiveCfg = Win64 Release|x64 + {C74B57DB-C7EF-4718-8BD9-9F6AE6478FAC}.Win64 Release|x64.Build.0 = Win64 Release|x64 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win32 Debug|Win32.ActiveCfg = Win32 Debug|Win32 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win32 Debug|Win32.Build.0 = Win32 Debug|Win32 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win32 Debug|x64.ActiveCfg = Win32 Debug|x64 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win32 Debug|x64.Build.0 = Win32 Debug|x64 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win32 Release|Win32.ActiveCfg = Win32 Release|Win32 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win32 Release|Win32.Build.0 = Win32 Release|Win32 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win32 Release|x64.ActiveCfg = Win32 Release|x64 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win32 Release|x64.Build.0 = Win32 Release|x64 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win64 Debug|Win32.ActiveCfg = Win64 Debug|x64 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win64 Debug|Win32.Build.0 = Win64 Debug|x64 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win64 Debug|x64.ActiveCfg = Win64 Debug|x64 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win64 Debug|x64.Build.0 = Win64 Debug|x64 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win64 Release|Win32.ActiveCfg = Win64 Release|x64 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win64 Release|Win32.Build.0 = Win64 Release|x64 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win64 Release|x64.ActiveCfg = Win64 Release|x64 + {4CEE7D0E-6C26-4E94-9682-6ECB73091DF7}.Win64 Release|x64.Build.0 = Win64 Release|x64 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win32 Debug|Win32.ActiveCfg = Win32 Debug|Win32 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win32 Debug|Win32.Build.0 = Win32 Debug|Win32 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win32 Debug|x64.ActiveCfg = Win32 Debug|x64 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win32 Debug|x64.Build.0 = Win32 Debug|x64 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win32 Release|Win32.ActiveCfg = Win32 Release|Win32 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win32 Release|Win32.Build.0 = Win32 Release|Win32 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win32 Release|x64.ActiveCfg = Win32 Release|x64 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win32 Release|x64.Build.0 = Win32 Release|x64 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win64 Debug|Win32.ActiveCfg = Win64 Debug|x64 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win64 Debug|Win32.Build.0 = Win64 Debug|x64 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win64 Debug|x64.ActiveCfg = Win64 Debug|x64 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win64 Debug|x64.Build.0 = Win64 Debug|x64 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win64 Release|Win32.ActiveCfg = Win64 Release|x64 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win64 Release|Win32.Build.0 = Win64 Release|x64 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win64 Release|x64.ActiveCfg = Win64 Release|x64 + {97E051D8-9233-410D-8123-E5ED749D6640}.Win64 Release|x64.Build.0 = Win64 Release|x64 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win32 Debug|Win32.ActiveCfg = Win32 Debug|Win32 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win32 Debug|Win32.Build.0 = Win32 Debug|Win32 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win32 Debug|x64.ActiveCfg = Win32 Debug|x64 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win32 Debug|x64.Build.0 = Win32 Debug|x64 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win32 Release|Win32.ActiveCfg = Win32 Release|Win32 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win32 Release|Win32.Build.0 = Win32 Release|Win32 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win32 Release|x64.ActiveCfg = Win32 Release|x64 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win32 Release|x64.Build.0 = Win32 Release|x64 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win64 Debug|Win32.ActiveCfg = Win64 Debug|x64 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win64 Debug|Win32.Build.0 = Win64 Debug|x64 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win64 Debug|x64.ActiveCfg = Win64 Debug|x64 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win64 Debug|x64.Build.0 = Win64 Debug|x64 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win64 Release|Win32.ActiveCfg = Win64 Release|x64 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win64 Release|Win32.Build.0 = Win64 Release|x64 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win64 Release|x64.ActiveCfg = Win64 Release|x64 + {B4B4695B-055A-48F5-B9AC-A49F6BCAFCE2}.Win64 Release|x64.Build.0 = Win64 Release|x64 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win32 Debug|Win32.ActiveCfg = Win32 Debug|Win32 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win32 Debug|Win32.Build.0 = Win32 Debug|Win32 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win32 Debug|x64.ActiveCfg = Win32 Debug|x64 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win32 Debug|x64.Build.0 = Win32 Debug|x64 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win32 Release|Win32.ActiveCfg = Win32 Release|Win32 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win32 Release|Win32.Build.0 = Win32 Release|Win32 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win32 Release|x64.ActiveCfg = Win32 Release|x64 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win32 Release|x64.Build.0 = Win32 Release|x64 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win64 Debug|Win32.ActiveCfg = Win64 Debug|x64 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win64 Debug|Win32.Build.0 = Win64 Debug|x64 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win64 Debug|x64.ActiveCfg = Win64 Debug|x64 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win64 Debug|x64.Build.0 = Win64 Debug|x64 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win64 Release|Win32.ActiveCfg = Win64 Release|x64 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win64 Release|Win32.Build.0 = Win64 Release|x64 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win64 Release|x64.ActiveCfg = Win64 Release|x64 + {96B87A78-C8E3-43C5-B0E4-9A30999B2712}.Win64 Release|x64.Build.0 = Win64 Release|x64 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win32 Debug|Win32.ActiveCfg = Win32 Debug|Win32 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win32 Debug|Win32.Build.0 = Win32 Debug|Win32 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win32 Debug|x64.ActiveCfg = Win32 Debug|x64 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win32 Debug|x64.Build.0 = Win32 Debug|x64 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win32 Release|Win32.ActiveCfg = Win32 Release|Win32 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win32 Release|Win32.Build.0 = Win32 Release|Win32 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win32 Release|x64.ActiveCfg = Win32 Release|x64 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win32 Release|x64.Build.0 = Win32 Release|x64 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win64 Debug|Win32.ActiveCfg = Win64 Debug|x64 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win64 Debug|Win32.Build.0 = Win64 Debug|x64 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win64 Debug|x64.ActiveCfg = Win64 Debug|x64 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win64 Debug|x64.Build.0 = Win64 Debug|x64 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win64 Release|Win32.ActiveCfg = Win64 Release|x64 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win64 Release|Win32.Build.0 = Win64 Release|x64 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win64 Release|x64.ActiveCfg = Win64 Release|x64 + {A296A166-9E6A-44DE-BF58-30131687A117}.Win64 Release|x64.Build.0 = Win64 Release|x64 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win32 Debug|Win32.ActiveCfg = Win32 Debug|Win32 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win32 Debug|Win32.Build.0 = Win32 Debug|Win32 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win32 Debug|x64.ActiveCfg = Win32 Debug|x64 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win32 Debug|x64.Build.0 = Win32 Debug|x64 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win32 Release|Win32.ActiveCfg = Win32 Release|Win32 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win32 Release|Win32.Build.0 = Win32 Release|Win32 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win32 Release|x64.ActiveCfg = Win32 Release|x64 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win32 Release|x64.Build.0 = Win32 Release|x64 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win64 Debug|Win32.ActiveCfg = Win64 Debug|Win32 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win64 Debug|Win32.Build.0 = Win64 Debug|Win32 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win64 Debug|x64.ActiveCfg = Win64 Debug|x64 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win64 Debug|x64.Build.0 = Win64 Debug|x64 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win64 Release|Win32.ActiveCfg = Win64 Release|x64 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win64 Release|Win32.Build.0 = Win64 Release|x64 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win64 Release|x64.ActiveCfg = Win64 Release|x64 + {4908A1B7-06F4-4517-936A-D81D140004F7}.Win64 Release|x64.Build.0 = Win64 Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/common/box.h b/Extras/PhysicsEffects/sample/api_physics_effects/common/box.h new file mode 100644 index 000000000..716ee8e1b --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/common/box.h @@ -0,0 +1,70 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define NUM_BOX_VTX 36 +#define NUM_BOX_IDX 36 +const float box_vtx[] = { + -0.500000f,-0.500000f,-0.500000f,0.000000f,0.000000f,-1.000000f, + -0.500000f,0.500000f,-0.500000f,0.000000f,0.000000f,-1.000000f, + 0.500000f,0.500000f,-0.500000f,0.000000f,0.000000f,-1.000000f, + -0.500000f,-0.500000f,-0.500000f,0.000000f,0.000000f,-1.000000f, + 0.500000f,0.500000f,-0.500000f,0.000000f,0.000000f,-1.000000f, + 0.500000f,-0.500000f,-0.500000f,0.000000f,0.000000f,-1.000000f, + -0.500000f,-0.500000f,-0.500000f,0.000000f,-1.000000f,0.000000f, + 0.500000f,-0.500000f,-0.500000f,0.000000f,-1.000000f,0.000000f, + 0.500000f,-0.500000f,0.500000f,0.000000f,-1.000000f,0.000000f, + -0.500000f,-0.500000f,-0.500000f,0.000000f,-1.000000f,0.000000f, + 0.500000f,-0.500000f,0.500000f,0.000000f,-1.000000f,0.000000f, + -0.500000f,-0.500000f,0.500000f,0.000000f,-1.000000f,0.000000f, + -0.500000f,-0.500000f,-0.500000f,-1.000000f,0.000000f,0.000000f, + -0.500000f,-0.500000f,0.500000f,-1.000000f,0.000000f,0.000000f, + -0.500000f,0.500000f,0.500000f,-1.000000f,0.000000f,0.000000f, + -0.500000f,-0.500000f,-0.500000f,-1.000000f,0.000000f,0.000000f, + -0.500000f,0.500000f,0.500000f,-1.000000f,0.000000f,0.000000f, + -0.500000f,0.500000f,-0.500000f,-1.000000f,0.000000f,0.000000f, + -0.500000f,-0.500000f,0.500000f,0.000000f,0.000000f,1.000000f, + 0.500000f,-0.500000f,0.500000f,0.000000f,0.000000f,1.000000f, + 0.500000f,0.500000f,0.500000f,0.000000f,0.000000f,1.000000f, + -0.500000f,-0.500000f,0.500000f,0.000000f,0.000000f,1.000000f, + 0.500000f,0.500000f,0.500000f,0.000000f,0.000000f,1.000000f, + -0.500000f,0.500000f,0.500000f,0.000000f,0.000000f,1.000000f, + -0.500000f,0.500000f,-0.500000f,0.000000f,1.000000f,0.000000f, + -0.500000f,0.500000f,0.500000f,0.000000f,1.000000f,0.000000f, + 0.500000f,0.500000f,0.500000f,0.000000f,1.000000f,0.000000f, + -0.500000f,0.500000f,-0.500000f,0.000000f,1.000000f,0.000000f, + 0.500000f,0.500000f,0.500000f,0.000000f,1.000000f,0.000000f, + 0.500000f,0.500000f,-0.500000f,0.000000f,1.000000f,0.000000f, + 0.500000f,-0.500000f,-0.500000f,1.000000f,0.000000f,0.000000f, + 0.500000f,0.500000f,-0.500000f,1.000000f,0.000000f,0.000000f, + 0.500000f,0.500000f,0.500000f,1.000000f,0.000000f,0.000000f, + 0.500000f,-0.500000f,-0.500000f,1.000000f,0.000000f,0.000000f, + 0.500000f,0.500000f,0.500000f,1.000000f,0.000000f,0.000000f, + 0.500000f,-0.500000f,0.500000f,1.000000f,0.000000f,0.000000f, +}; +const unsigned short box_idx[] = { + 0,1,2, + 3,4,5, + 6,7,8, + 9,10,11, + 12,13,14, + 15,16,17, + 18,19,20, + 21,22,23, + 24,25,26, + 27,28,29, + 30,31,32, + 33,34,35, +}; diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/common/common.h b/Extras/PhysicsEffects/sample/api_physics_effects/common/common.h new file mode 100644 index 000000000..a1bdea2f4 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/common/common.h @@ -0,0 +1,31 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#include +#include +#include +#include +#include + +// Platform specific +#ifdef _WIN32 + #include +#endif + +#endif /* __COMMON_H__ */ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/common/ctrl_func.android.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/common/ctrl_func.android.cpp new file mode 100644 index 000000000..aa56a3ae4 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/common/ctrl_func.android.cpp @@ -0,0 +1,57 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "common.h" +#include "ctrl_func.h" + +int keyState[2][BTN_NUM] = {0}; +int keySw = 0; + +void ctrl_init() +{ + keySw = 0; +} + +void ctrl_release() +{ +} + +void ctrl_update() +{ +} + +ButtonStatus ctrl_button_pressed(ButtonID btnId) +{ + if(keyState[1-keySw][btnId] && !keyState[keySw][btnId]) { + return BTN_STAT_DOWN; + } + else if(keyState[1-keySw][btnId] && keyState[keySw][btnId]) { + return BTN_STAT_KEEP; + } + else if(!keyState[1-keySw][btnId] && keyState[keySw][btnId]) { + return BTN_STAT_UP; + } + + return BTN_STAT_NONE; +} + +void ctrl_set_screen_size(int w,int h) +{ +} + +void ctrl_get_cursor_position(int &cursorX,int &cursorY) +{ +} diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/common/ctrl_func.h b/Extras/PhysicsEffects/sample/api_physics_effects/common/ctrl_func.h new file mode 100644 index 000000000..2cf2fb772 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/common/ctrl_func.h @@ -0,0 +1,51 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef __CTRL_FUNC_H__ +#define __CTRL_FUNC_H__ + +enum ButtonID { + BTN_SCENE_RESET=0, + BTN_SCENE_NEXT, + BTN_SIMULATION, + BTN_STEP, + BTN_UP, + BTN_DOWN, + BTN_LEFT, + BTN_RIGHT, + BTN_ZOOM_IN, + BTN_ZOOM_OUT, + BTN_PICK, + BTN_NUM +}; + +enum ButtonStatus { + BTN_STAT_NONE = 0, + BTN_STAT_DOWN, + BTN_STAT_UP, + BTN_STAT_KEEP +}; + +void ctrl_init(); +void ctrl_release(); +void ctrl_update(); + +void ctrl_set_screen_size(int w,int h); +void ctrl_get_cursor_position(int &cursorX,int &cursorY); + +ButtonStatus ctrl_button_pressed(ButtonID btnId); + +#endif /* __CTRL_FUNC_H__ */ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/common/ctrl_func.win32.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/common/ctrl_func.win32.cpp new file mode 100644 index 000000000..ce3109888 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/common/ctrl_func.win32.cpp @@ -0,0 +1,78 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "common.h" +#include "ctrl_func.h" + +int keyState[2][BTN_NUM] = {0}; +int keySw = 0; + +void ctrl_init() +{ + keySw = 0; +} + +void ctrl_release() +{ +} + +void ctrl_update() +{ + keyState[keySw][BTN_SCENE_RESET] = GetAsyncKeyState(VK_F1); + keyState[keySw][BTN_SCENE_NEXT] = GetAsyncKeyState(VK_F2); + keyState[keySw][BTN_SIMULATION] = GetAsyncKeyState(VK_F3); + keyState[keySw][BTN_STEP] = GetAsyncKeyState(VK_F4); + keyState[keySw][BTN_UP] = GetAsyncKeyState(VK_UP); + keyState[keySw][BTN_DOWN] = GetAsyncKeyState(VK_DOWN); + keyState[keySw][BTN_LEFT] = GetAsyncKeyState(VK_LEFT); + keyState[keySw][BTN_RIGHT] = GetAsyncKeyState(VK_RIGHT); + keyState[keySw][BTN_ZOOM_IN] = GetAsyncKeyState(VK_INSERT); + keyState[keySw][BTN_ZOOM_OUT] = GetAsyncKeyState(VK_DELETE); + keyState[keySw][BTN_PICK] = GetAsyncKeyState(VK_LBUTTON); + keySw = 1-keySw; +} + +ButtonStatus ctrl_button_pressed(ButtonID btnId) +{ + if(keyState[1-keySw][btnId] && !keyState[keySw][btnId]) { + return BTN_STAT_DOWN; + } + else if(keyState[1-keySw][btnId] && keyState[keySw][btnId]) { + return BTN_STAT_KEEP; + } + else if(!keyState[1-keySw][btnId] && keyState[keySw][btnId]) { + return BTN_STAT_UP; + } + + return BTN_STAT_NONE; +} + +void ctrl_set_screen_size(int w,int h) +{ +} + +void ctrl_get_cursor_position(int &cursorX,int &cursorY) +{ + HWND hWnd = ::GetActiveWindow(); + + POINT pnt; + RECT rect; + ::GetCursorPos(&pnt); + ::ScreenToClient(hWnd,&pnt); + ::GetClientRect(hWnd,&rect); + cursorX = pnt.x - (rect.right - rect.left) / 2; + cursorY = (rect.bottom-rect.top) / 2 - pnt.y; +} diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/common/cylinder.h b/Extras/PhysicsEffects/sample/api_physics_effects/common/cylinder.h new file mode 100644 index 000000000..bba5d2a47 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/common/cylinder.h @@ -0,0 +1,154 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#define NUM_CYLINDER_VTX 68 +#define NUM_CYLINDER_IDX 192 +const float cylinder_vtx[] = { +-1.0f,0.0f,0.0f, -1.0f,0.0f,0.0f, +-1.0f,-0.923879f,-0.382683f, -1.0f,0.0f,0.0f, +-1.0f,-1.0f,1.62921e-007f, -1.0f,0.0f,0.0f, +-1.0f,-0.707107f,-0.707107f, -1.0f,0.0f,0.0f, +-1.0f,-0.382683f,-0.923879f, -1.0f,0.0f,0.0f, +-1.0f,0.0f,-1.0f, -1.0f,0.0f,0.0f, +-1.0f,0.382684f,-0.923879f, -1.0f,0.0f,0.0f, +-1.0f,0.707107f,-0.707107f, -1.0f,0.0f,0.0f, +-1.0f,0.92388f,-0.382683f, -1.0f,0.0f,0.0f, +-1.0f,1.0f,-1.62921e-007f, -1.0f,0.0f,0.0f, +-1.0f,0.92388f,0.382683f, -1.0f,0.0f,0.0f, +-1.0f,0.707107f,0.707107f, -1.0f,0.0f,0.0f, +-1.0f,0.382684f,0.92388f, -1.0f,0.0f,0.0f, +-1.0f,1.50996e-007f,1.0f, -1.0f,0.0f,0.0f, +-1.0f,-0.382683f,0.92388f, -1.0f,0.0f,0.0f, +-1.0f,-0.707107f,0.707107f, -1.0f,0.0f,0.0f, +-1.0f,-0.92388f,0.382683f, -1.0f,0.0f,0.0f, +1.0f,0.0f,0.0f, 1.0f,0.0f,0.0f, +1.0f,-1.0f,0.0f, 1.0f,0.0f,0.0f, +1.0f,-0.92388f,-0.382683f, 1.0f,0.0f,0.0f, +1.0f,-0.707107f,-0.707107f, 1.0f,0.0f,0.0f, +1.0f,-0.382684f,-0.92388f, 1.0f,0.0f,0.0f, +1.0f,-1.19209e-007f,-1.0f, 1.0f,0.0f,0.0f, +1.0f,0.382683f,-0.92388f, 1.0f,0.0f,0.0f, +1.0f,0.707107f,-0.707107f, 1.0f,0.0f,0.0f, +1.0f,0.923879f,-0.382684f, 1.0f,0.0f,0.0f, +1.0f,1.0f,-3.13917e-007f, 1.0f,0.0f,0.0f, +1.0f,0.92388f,0.382683f, 1.0f,0.0f,0.0f, +1.0f,0.707107f,0.707106f, 1.0f,0.0f,0.0f, +1.0f,0.382684f,0.923879f, 1.0f,0.0f,0.0f, +1.0f,0.0f,1.0f, 1.0f,0.0f,0.0f, +1.0f,-0.382684f,0.923879f, 1.0f,0.0f,0.0f, +1.0f,-0.707107f,0.707107f, 1.0f,0.0f,0.0f, +1.0f,-0.92388f,0.382683f, 1.0f,0.0f,0.0f, +-1.0f,-1.0f,1.62921e-007f, 0.0f,-1.0f,0.0f, +1.0f,-0.92388f,-0.382683f, 0.0f,-0.92388f,-0.382683f, +1.0f,-1.0f,0.0f, 0.0f,-1.0f,0.0f, +-1.0f,-0.923879f,-0.382683f, 0.0f,-0.92388f,-0.382683f, +1.0f,-0.707107f,-0.707107f, 0.0f,-0.707107f,-0.707107f, +-1.0f,-0.707107f,-0.707107f, 0.0f,-0.707107f,-0.707107f, +1.0f,-0.382684f,-0.92388f, 0.0f,-0.382684f,-0.92388f, +-1.0f,-0.382683f,-0.923879f, 0.0f,-0.382683f,-0.92388f, +1.0f,-1.19209e-007f,-1.0f, 0.0f,0.0f,-1.0f, +-1.0f,0.0f,-1.0f, 0.0f,0.0f,-1.0f, +-1.0f,0.0f,-1.0f, 0.0f,0.0f,-1.0f, +1.0f,0.382683f,-0.92388f, 0.0f,0.382683f,-0.92388f, +1.0f,-1.19209e-007f,-1.0f, 0.0f,0.0f,-1.0f, +-1.0f,0.382684f,-0.923879f, 0.0f,0.382683f,-0.92388f, +1.0f,0.707107f,-0.707107f, 0.0f,0.707107f,-0.707107f, +-1.0f,0.707107f,-0.707107f, 0.0f,0.707107f,-0.707107f, +1.0f,0.923879f,-0.382684f, 0.0f,0.923879f,-0.382684f, +-1.0f,0.92388f,-0.382683f, 0.0f,0.923879f,-0.382684f, +1.0f,1.0f,-3.13917e-007f, 0.0f,1.0f,-2.03489e-007f, +-1.0f,1.0f,-1.62921e-007f, 0.0f,1.0f,-2.13162e-007f, +1.0f,0.92388f,0.382683f, 0.0f,0.92388f,0.382683f, +-1.0f,0.92388f,0.382683f, 0.0f,0.92388f,0.382683f, +1.0f,0.707107f,0.707106f, 0.0f,0.707107f,0.707107f, +-1.0f,0.707107f,0.707107f, 0.0f,0.707107f,0.707107f, +1.0f,0.382684f,0.923879f, 0.0f,0.382684f,0.923879f, +-1.0f,0.382684f,0.92388f, 0.0f,0.382684f,0.923879f, +1.0f,0.0f,1.0f, 0.0f,0.0f,1.0f, +-1.0f,1.50996e-007f,1.0f, 0.0f,0.0f,1.0f, +1.0f,-0.382684f,0.923879f, 0.0f,-0.382684f,0.92388f, +-1.0f,-0.382683f,0.92388f, 0.0f,-0.382683f,0.92388f, +1.0f,-0.707107f,0.707107f, 0.0f,-0.707107f,0.707107f, +-1.0f,-0.707107f,0.707107f, 0.0f,-0.707107f,0.707107f, +1.0f,-0.92388f,0.382683f, 0.0f,-0.92388f,0.382683f, +-1.0f,-0.92388f,0.382683f, 0.0f,-0.92388f,0.382683f, +}; +const unsigned short cylinder_idx[] = { +0,1,2, +0,3,1, +0,4,3, +0,5,4, +0,6,5, +0,7,6, +0,8,7, +0,9,8, +0,10,9, +0,11,10, +0,12,11, +0,13,12, +0,14,13, +0,15,14, +0,16,15, +0,2,16, +17,18,19, +17,19,20, +17,20,21, +17,21,22, +17,22,23, +17,23,24, +17,24,25, +17,25,26, +17,26,27, +17,27,28, +17,28,29, +17,29,30, +17,30,31, +17,31,32, +17,32,33, +17,33,18, +34,35,36, +34,37,35, +37,38,35, +37,39,38, +39,40,38, +39,41,40, +41,42,40, +41,43,42, +44,45,46, +44,47,45, +47,48,45, +47,49,48, +49,50,48, +49,51,50, +51,52,50, +51,53,52, +53,54,52, +53,55,54, +55,56,54, +55,57,56, +57,58,56, +57,59,58, +59,60,58, +59,61,60, +61,62,60, +61,63,62, +63,64,62, +63,65,64, +65,66,64, +65,67,66, +67,36,66, +67,34,36, +}; diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/common/jni/physicseffects-android.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/common/jni/physicseffects-android.cpp new file mode 100644 index 000000000..9a42ad392 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/common/jni/physicseffects-android.cpp @@ -0,0 +1,241 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include "physicseffects-android.h" +#include "../render_func.h" +#include "../perf_func.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//---------------------------------------------------------------------------- +// Java_pfx_renderingsupport_PhysicsEffectsRenderer_nativePhysicsEffectsInit +// +/// Implementation of JNI function to initilize the simulation and start the +/// first scene. +/// +/// @param env Pointer to JNI environment +//---------------------------------------------------------------------------- +void +Java_pfx_renderingsupport_PhysicsEffectsRenderer_nativePhysicsEffectsInit( JNIEnv* env ) +{ + init(); + sceneChange(); +} + +//---------------------------------------------------------------------------- +// Java_pfx_renderingsupport_PhysicsEffectsRenderer_nativePhysicsEffectsSimulate +// +/// Implementation of JNI function to update the simulation and view parameters, +/// perform one simulation step, and redraw the scene. +/// +/// @param env Pointer to JNI environment +//---------------------------------------------------------------------------- +void +Java_pfx_renderingsupport_PhysicsEffectsRenderer_nativePhysicsEffectsSimulate( JNIEnv* env ) +{ + update(); + physics_simulate(); + render(); + perf_sync(); +} + +//---------------------------------------------------------------------------- +// Java_pfx_renderingsupport_PhysicsEffectsRenderer_nativePhysicsEffectsUpdate +// +/// Implementation of JNI function to update the camera view and simulation +/// parameters. +/// +/// @param env Pointer to JNI environment +//---------------------------------------------------------------------------- +void +Java_pfx_renderingsupport_PhysicsEffectsRenderer_nativePhysicsEffectsUpdate( JNIEnv* env ) +{ + update(); +} + +//---------------------------------------------------------------------------- +// Java_pfx_renderingsupport_PhysicsEffectsRenderer_nativePhysicsEffectsPhysStep +// +/// Implementation of JNI function to perform one simulation step. +/// +/// @param env Pointer to JNI environment +//---------------------------------------------------------------------------- +void +Java_pfx_renderingsupport_PhysicsEffectsRenderer_nativePhysicsEffectsPhysStep( JNIEnv* env ) +{ + physics_simulate(); +} + +//---------------------------------------------------------------------------- +// Java_pfx_renderingsupport_PhysicsEffectsRenderer_nativePhysicsEffectsRender +// +/// Implementation of JNI function to render the scene. +/// +/// @param env Pointer to JNI environment +//---------------------------------------------------------------------------- +void +Java_pfx_renderingsupport_PhysicsEffectsRenderer_nativePhysicsEffectsRender( JNIEnv* env ) +{ + render(); +} + +//---------------------------------------------------------------------------- +// Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeSceneChange +// +/// Implementation of JNI function to change to the next scene. +/// +/// @param env Pointer to JNI environment +//---------------------------------------------------------------------------- +void +Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeSceneChange( JNIEnv* env ) +{ + sceneChange(); +} + +//---------------------------------------------------------------------------- +// Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeCameraUp +// +/// Implementation of JNI function to tilt the camera up +/// +/// @param env Pointer to JNI environment +//---------------------------------------------------------------------------- +void +Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeCameraUp( JNIEnv* env ) +{ + float angX, angY, r; + render_get_view_angle(angX, angY, r); + + angX -= 0.05f; + if(angX < -1.4f) angX = -1.4f; + if(angX > -0.01f) angX = -0.01f; + + render_set_view_angle(angX, angY, r); +} + +//---------------------------------------------------------------------------- +// Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeCameraDown +// +/// Implementation of JNI function to tilt the camera down +/// +/// @param env Pointer to JNI environment +//---------------------------------------------------------------------------- +void +Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeCameraDown( JNIEnv* env ) +{ + float angX, angY, r; + render_get_view_angle(angX, angY, r); + + angX += 0.05f; + if(angX < -1.4f) angX = -1.4f; + if(angX > -0.01f) angX = -0.01f; + + render_set_view_angle(angX, angY, r); +} + +//---------------------------------------------------------------------------- +// Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeCameraLeft +// +/// Implementation of JNI function to tilt the camera left +/// +/// @param env Pointer to JNI environment +//---------------------------------------------------------------------------- +void +Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeCameraLeft( JNIEnv* env ) +{ + float angX, angY, r; + render_get_view_angle(angX, angY, r); + + angY -= 0.05f; + + render_set_view_angle(angX, angY, r); +} + +//---------------------------------------------------------------------------- +// Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeCameraRight +// +/// Implementation of JNI function to tilt the camera right +/// +/// @param env Pointer to JNI environment +//---------------------------------------------------------------------------- +void +Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeCameraRight( JNIEnv* env ) +{ + float angX, angY, r; + render_get_view_angle(angX, angY, r); + + angY += 0.05f; + + render_set_view_angle(angX, angY, r); +} + +//---------------------------------------------------------------------------- +// Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeCameraZoomOut +// +/// Implementation of JNI function to dolly the camera away from scene, +/// effectively zooming out. +/// +/// @param env Pointer to JNI environment +//---------------------------------------------------------------------------- +void +Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeCameraZoomOut( JNIEnv* env ) +{ + float angX, angY, r; + render_get_view_angle(angX, angY, r); + + r *= 1.1f; + if(r > 500.0f) r = 500.0f; + + render_set_view_angle(angX, angY, r); +} + +//---------------------------------------------------------------------------- +// Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeCameraZoomIn +// +/// Implementation of JNI function to dolly the camera towards scene, +/// effectively zooming in. +/// +/// @param env Pointer to JNI environment +//---------------------------------------------------------------------------- +void +Java_pfx_renderingsupport_PhysicsEffectsGLSurfaceView_nativeCameraZoomIn( JNIEnv* env ) +{ + float angX, angY, r; + render_get_view_angle(angX, angY, r); + + r *= 0.9f; + if(r < 1.0f) r = 1.0f; + + render_set_view_angle(angX, angY, r); +} + +#ifdef __cplusplus +} +#endif diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/common/jni/physicseffects-android.h b/Extras/PhysicsEffects/sample/api_physics_effects/common/jni/physicseffects-android.h new file mode 100644 index 000000000..1229cdf94 --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/common/jni/physicseffects-android.h @@ -0,0 +1,40 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef PHYSICSEFFECTS_ANDROID_H +#define PHYSICSEFFECTS_ANDROID_H + +// The following C++ functions must be provided by the +// sample application. +extern int init(); +extern void render(void); +extern void sceneChange(); +extern void update(void); +extern void physics_simulate(); + +#endif // !PHYSICSEFFECTS_ANDROID_H diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/common/perf_func.android.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/common/perf_func.android.cpp new file mode 100644 index 000000000..2b3d5656b --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/common/perf_func.android.cpp @@ -0,0 +1,38 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "common.h" +#include "perf_func.h" + +void perf_init() +{ +} + +void perf_release() +{ +} + +void perf_push_marker(char *str) +{ +} + +void perf_pop_marker() +{ +} + +void perf_sync() +{ +} diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/common/perf_func.h b/Extras/PhysicsEffects/sample/api_physics_effects/common/perf_func.h new file mode 100644 index 000000000..2868fe2dd --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/common/perf_func.h @@ -0,0 +1,26 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef __PERF_FUNC_H__ +#define __PERF_FUNC_H__ + +void perf_init(); +void perf_release(); +void perf_push_marker(char *str); +void perf_pop_marker(); +void perf_sync(); + +#endif /* __PERF_FUNC_H__ */ diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/common/perf_func.win32.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/common/perf_func.win32.cpp new file mode 100644 index 000000000..2b3d5656b --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/common/perf_func.win32.cpp @@ -0,0 +1,38 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "common.h" +#include "perf_func.h" + +void perf_init() +{ +} + +void perf_release() +{ +} + +void perf_push_marker(char *str) +{ +} + +void perf_pop_marker() +{ +} + +void perf_sync() +{ +} diff --git a/Extras/PhysicsEffects/sample/api_physics_effects/common/render_func.android.cpp b/Extras/PhysicsEffects/sample/api_physics_effects/common/render_func.android.cpp new file mode 100644 index 000000000..cadc8097f --- /dev/null +++ b/Extras/PhysicsEffects/sample/api_physics_effects/common/render_func.android.cpp @@ -0,0 +1,486 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "render_func.h" + +#include "box.h" +#include "sphere.h" +#include "cylinder.h" + +#include +#include + +// local variables +static int screen_width,screen_height; +static PfxMatrix4 g_pMat,g_vMat; +static PfxVector3 g_viewPos,g_lightPos,g_viewTgt; +static float lightRadius,lightRadX,lightRadY; +static float viewRadius,viewRadX,viewRadY,viewHeight; + +static unsigned short *box_wire_idx; +static unsigned short *sphere_wire_idx; +static unsigned short *cylinder_wire_idx; + +#define MAX_MESH 5 + +static struct MeshBuff { + float *vtx; + float *nml; + int numVtx; + unsigned short *idx; + unsigned short *wire_idx; + int numIdx; +} meshBuff[MAX_MESH]; +int numMesh; + +void render_init() +{ + screen_width = DISPLAY_WIDTH; + screen_height = DISPLAY_HEIGHT; + + // initalize matrix + g_pMat = PfxMatrix4::perspective(3.1415f/4.0f, (float)screen_width/(float)screen_height,0.1f, 1000.0f); + + // initalize parameters + lightRadius = 40.0f; + lightRadX = -0.6f; + lightRadY = 0.6f; + viewRadius = 40.0f; + viewRadX = -0.01f; + viewRadY = 0.0f; + viewHeight = 1.0f; + + g_viewTgt = PfxVector3(0.0f,viewHeight,0.0f); + + box_wire_idx = new unsigned short [NUM_BOX_IDX*2]; + sphere_wire_idx = new unsigned short [NUM_SPHERE_IDX*2]; + cylinder_wire_idx = new unsigned short [NUM_CYLINDER_IDX*2]; + + for(int i=0;i 0) { + for(int i=0;i=0&&meshId + +#include "box.h" +#include "sphere.h" +#include "cylinder.h" + +// context +HDC hDC; +HGLRC hRC; + +// local variables +static int screen_width,screen_height; +static PfxMatrix4 g_pMat,g_vMat; +static PfxVector3 g_viewPos,g_lightPos,g_viewTgt; +static float lightRadius,lightRadX,lightRadY; +static float viewRadius,viewRadX,viewRadY,viewHeight; + +static unsigned short *box_wire_idx; +static unsigned short *sphere_wire_idx; +static unsigned short *cylinder_wire_idx; + +#define MAX_MESH 5 + +static struct MeshBuff { + float *vtx; + float *nml; + int numVtx; + unsigned short *idx; + unsigned short *wire_idx; + int numIdx; +} meshBuff[MAX_MESH]; +int numMesh; + +void render_init() +{ + screen_width = DISPLAY_WIDTH; + screen_height = DISPLAY_HEIGHT; + + // initalize matrix + g_pMat = PfxMatrix4::perspective(3.1415f/4.0f, (float)screen_width/(float)screen_height,0.1f, 1000.0f); + + // initalize parameters + lightRadius = 40.0f; + lightRadX = -0.6f; + lightRadY = 0.6f; + viewRadius = 40.0f; + viewRadX = -0.01f; + viewRadY = 0.0f; + viewHeight = 1.0f; + + g_viewTgt = PfxVector3(0.0f,viewHeight,0.0f); + + box_wire_idx = new unsigned short [NUM_BOX_IDX*2]; + sphere_wire_idx = new unsigned short [NUM_SPHERE_IDX*2]; + cylinder_wire_idx = new unsigned short [NUM_CYLINDER_IDX*2]; + + for(int i=0;i 0) { + for(int i=0;i=0&&meshId = d18,d19 + vld1.32 {d16,d17}, [r0] @ input = d16,d17 +@ rearrange inputs into convenient order + vtrn.32 d18,d19 @ q9 = = d18,d19 + vrev64.32 d16,d16 @ q8 = = d16,d17 + vrev64.32 d18,d18 @ q9 = = d18,d19 + vtrn.32 d16,d17 @ q8 = = d16,d17 +@ perform first half of cross product using rearranged inputs + vmul.f32 q10, q8, q9 @ q10 = +@ rearrange inputs again + vtrn.32 d18,d19 @ q9 = = d18,d19 + vrev64.32 d16,d16 @ q8 = = d16,d17 + vrev64.32 d18,d18 @ q9 = = d18,d19 + vtrn.32 d16,d17 @ q8 = = d16,d17 +@ perform last half of cross product using rearranged inputs + vmls.f32 q10, q8, q9 @ q10 = +@ and store the result + vst1.32 {q10}, [r2] + bx lr + .fnend + +@ cross product, result stored directly to memory, version 2 + + .global CrossProductNeonResultInMemoryAssembly2 + .thumb_func +CrossProductNeonResultInMemoryAssembly2: + .fnstart + vld1.32 {d18[1]}, [r1]! + vld1.32 {d19[0]}, [r1]! + vld1.32 {d18[0]}, [r1]! + vld1.32 {d19[1]}, [r1] @ q9 = = d18,d19 + vld1.32 {d17[0]}, [r0]! + vld1.32 {d16}, [r0]! + vld1.32 {d17[1]}, [r0] @ q8 = = d16,d17 +@ perform first half of cross product using rearranged inputs + vmul.f32 q10, q8, q9 @ q10 = +@ rearrange inputs for second half + vtrn.32 d18,d19 @ q9 = = d18,d19 + vrev64.32 d16,d16 @ q8 = = d16,d17 + vrev64.32 d18,d18 @ q9 = = d18,d19 + vtrn.32 d16,d17 @ q8 = = d16,d17 +@ perform last half of cross product using rearranged inputs + vmls.f32 q10, q8, q9 @ q10 = +@ and store the result + vst1.32 {q10}, [r2] + bx lr + .fnend + + .global CrossProductNeonResultInMemoryAssembly3 + .thumb_func +CrossProductNeonResultInMemoryAssembly3: + .fnstart + vld1.32 {d18[1]}, [r1]! + vld1.32 {d19[0]}, [r1]! + vld1.32 {d18[0]}, [r1]! + vld1.32 {d19[1]}, [r1]! @ q9 = = d18,d19 + vld1.32 {d17[0]}, [r0]! + vld1.32 {d16}, [r0]! + vld1.32 {d17[1]}, [r0]! @ q8 = = d16,d17 +@ perform first half of cross product using rearranged inputs + vmul.f32 q10, q8, q9 @ q10 = + vld1.32 {d18[1]}, [r0]! + vld1.32 {d19[0]}, [r0]! + vld1.32 {d18[0]}, [r0]! + vld1.32 {d19[1]}, [r0]! @ q9 = = d18,d19 + vld1.32 {d17[0]}, [r1]! + vld1.32 {d16}, [r1]! + vld1.32 {d17[1]}, [r1]! @ q8 = = d16,d17 +@ perform last half of cross product using rearranged inputs + vmls.f32 q10, q8, q9 @ q10 = +@ and store the result + vst1.32 {q10}, [r2] + bx lr + .fnend + +@ cross product, result stored directly to memory, version 3 + +@ .global CrossProductNeonResultInMemoryAssembly3 +@ .thumb_func +@CrossProductNeonResultInMemoryAssembly3: +@ .fnstart +@ ldr r3, table +@ vld1.32 {d18,d19}, [r1] @ input = d18,d19 +@ vld1.32 {d16,d17}, [r0] @ input = d16,d17 +@ rearrange inputs into convenient order +@ vld1.32 {q10}, [r3]! +@ vld1.32 {q11}, [r3] +@ vtbl.8 q12, {d18,d19}, q10 +@ vtbl.8 q13, {d16,d17}, q11 +@ perform first half of cross product using rearranged inputs +@ vmul.f32 q14, q12, q13 +@ rearrange inputs again +@ vtbl.8 q12, {d18,d19}, q11 +@ vtbl.8 q13, {d16,d17}, q10 +@ perform last half of cross product using rearranged inputs +@ vmls.f32 q14, q12, q13 +@ and store the result +@ vst1.32 {q14}, [r2] +@ bx lr +@ .fnend + +@table: +@z2,x2,y2,w2 +@ dcb 08,09,10,11,00,01,02,03,04,05,06,07,00,00,00,00 +@y1,z1,x1,w1 +@ dcb 04,05,06,07,08,09,10,11,00,01,02,03,00,00,00,00 diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_dot_product.S b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_dot_product.S new file mode 100644 index 000000000..56aedfcaf --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_dot_product.S @@ -0,0 +1,98 @@ +@ +@ Applied Research Associates Inc. (c)2011 +@ +@ Redistribution and use in source and binary forms, +@ with or without modification, are permitted provided that the +@ following conditions are met: +@ * Redistributions of source code must retain the above copyright +@ notice, this list of conditions and the following disclaimer. +@ * Redistributions in binary form must reproduce the above copyright +@ notice, this list of conditions and the following disclaimer in the +@ documentation and/or other materials provided with the distribution. +@ * Neither the name of the Applied Research Associates Inc nor the names +@ of its contributors may be used to endorse or promote products derived +@ from this software without specific prior written permission. +@ +@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +@ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +@ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +@ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +@ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +@ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +@ POSSIBILITY OF SUCH DAMAGE. +@ + .syntax unified + .arch armv7-a + .fpu neon + .thumb + .text + .align 2 + +@ dot product, result returned in register + + .global DotProductNeonResultInRegisterAssembly + .thumb_func +DotProductNeonResultInRegisterAssembly: + .fnstart + vld1.32 {d16,d17}, [r0] @ input + vld1.32 {d18,d19}, [r1] @ input + vmul.f32 d14, d16, d18 @ d14= + vmla.f32 d14, d17, d19 @ d14=d14+= + vpadd.f32 d14, d14, d14 @ add the two halves of d14 together, result in each lane + vmov.f32 r0, s28 @ s28 aliases the first lane of d14 + bx lr + .fnend + +@ dot product, result stored directly to memory + + .global DotProductNeonResultInMemoryAssembly + .thumb_func +DotProductNeonResultInMemoryAssembly: + .fnstart + vld1.32 {d16,d17}, [r0] @ input + vld1.32 {d18,d19}, [r1] @ input + vmul.f32 d14, d16, d18 @ d14= +@ non-fused multiple accumulate + vmla.f32 d14, d17, d19 @ d14=d14+= +@ fused multiple accumulate - not recognized by GNU assembler +@@ vfma.f32 {d14}, d17, d19 @ d14=d14+= + vpadd.f32 d14, d14, d14 @ add the two halves of d14 together, same result in each lane + vst1.32 {d14}, [r2] + bx lr + .fnend + +@ dot product, result stored directly to memory, all inputs are contiguous in memory + + .global DotProductNeonResultInMemoryAssembly2 + .thumb_func +DotProductNeonResultInMemoryAssembly2: + .fnstart + vld1.32 {d16-d19}, [r0] @ input q8=, q9= + vmul.f32 d14, d16, d18 @ d14= +@ non-fused multiple accumulate + vmla.f32 d14, d17, d19 @ d14=d14+= +@ fused multiple accumulate - not recognized by GNU assembler +@@ vfma.f32 d14, d17, d19 @ d14=d14+= + vpadd.f32 d14, d14, d14 @ add the two halves of d14 together, same result in each lane + vst1.32 {d14}, [r1] + bx lr + .fnend + +@ same as DotProductNeonResultInMemoryAssembly2, but alternate methodology to compute result + + .global DotProductNeonResultInMemoryAssembly2b + .thumb_func +DotProductNeonResultInMemoryAssembly2b: + .fnstart + vld1.32 {d14-d17}, [r0] @ input q7=, q8= + vmul.f32 q7, q7, q8 @ q7 = = d14,d15 = s28,s29,s30,s31 + vpadd.f32 d14,d14,d14 @ add elements of d14 together= + vpadd.f32 d15,d15,d15 @ add elements of d14 together= + vadd.f32 d14,d14,d15 @ add d14 and d15 together, final result in both lanes + vst1.32 {d14}, [r1] + bx lr + .fnend diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_matrix3_operator_multiply.S b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_matrix3_operator_multiply.S new file mode 100644 index 000000000..2c4470e73 --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_matrix3_operator_multiply.S @@ -0,0 +1,62 @@ +@ +@ Applied Research Associates Inc. (c)2011 +@ +@ Redistribution and use in source and binary forms, +@ with or without modification, are permitted provided that the +@ following conditions are met: +@ * Redistributions of source code must retain the above copyright +@ notice, this list of conditions and the following disclaimer. +@ * Redistributions in binary form must reproduce the above copyright +@ notice, this list of conditions and the following disclaimer in the +@ documentation and/or other materials provided with the distribution. +@ * Neither the name of the Applied Research Associates Inc nor the names +@ of its contributors may be used to endorse or promote products derived +@ from this software without specific prior written permission. +@ +@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +@ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +@ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +@ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +@ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +@ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +@ POSSIBILITY OF SUCH DAMAGE. +@ + .syntax unified + .arch armv7-a + .fpu neon + .thumb + .text + .align 2 + +@ matrix3 operator *, result stored directly to memory + + .global Matrix3OperatorMultiplyNeon + .thumb_func +Matrix3OperatorMultiplyNeon: + .fnstart + vld1.32 {d16-d19}, [r0]! @ load first eight elements of matrix 0 + vld1.32 {d20-d21}, [r0] @ load second eight elements of matrix 0 + vld1.32 {d0-d3}, [r1]! @ load first eight elements of matrix 1 + vld1.32 {d4-d5}, [r1] @ load second eight elements of matrix 1 + + vmul.f32 q12, q8, d0[0] @ rslt col0 = (mat0 col0) * (mat1 col0 elt0) + vmul.f32 q13, q8, d2[0] @ rslt col1 = (mat0 col0) * (mat1 col1 elt0) + vmul.f32 q14, q8, d4[0] @ rslt col2 = (mat0 col0) * (mat1 col2 elt0) + + vmla.f32 q12, q9, d0[1] @ rslt col0 += (mat0 col1) * (mat1 col0 elt1) + vmla.f32 q13, q9, d2[1] @ rslt col1 += (mat0 col1) * (mat1 col1 elt1) + vmla.f32 q14, q9, d4[1] @ rslt col2 += (mat0 col1) * (mat1 col2 elt1) + + vmla.f32 q12, q10, d1[0] @ rslt col0 += (mat0 col2) * (mat1 col0 elt2) + vmla.f32 q13, q10, d3[0] @ rslt col1 += (mat0 col2) * (mat1 col1 elt2) + vmla.f32 q14, q10, d5[0] @ rslt col2 += (mat0 col2) * (mat1 col2 elt2) + + vst1.32 {d24-d27}, [r2]! @ store first eight elements of result + vst1.32 {d28-d29}, [r2] @ store second eight elements of result + + bx lr + .fnend diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_matrix4_operator_multiply.S b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_matrix4_operator_multiply.S new file mode 100644 index 000000000..848e998b7 --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_matrix4_operator_multiply.S @@ -0,0 +1,71 @@ +@ +@ Applied Research Associates Inc. (c)2011 +@ +@ Redistribution and use in source and binary forms, +@ with or without modification, are permitted provided that the +@ following conditions are met: +@ * Redistributions of source code must retain the above copyright +@ notice, this list of conditions and the following disclaimer. +@ * Redistributions in binary form must reproduce the above copyright +@ notice, this list of conditions and the following disclaimer in the +@ documentation and/or other materials provided with the distribution. +@ * Neither the name of the Applied Research Associates Inc nor the names +@ of its contributors may be used to endorse or promote products derived +@ from this software without specific prior written permission. +@ +@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +@ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +@ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +@ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +@ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +@ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +@ POSSIBILITY OF SUCH DAMAGE. +@ + .syntax unified + .arch armv7-a + .fpu neon + .thumb + .text + .align 2 + +@ matrix4 operator *, result stored directly to memory + + .global Matrix4OperatorMultiplyNeon + .thumb_func +Matrix4OperatorMultiplyNeon: + .fnstart + + vld1.32 {d16-d19}, [r0]! @ load first eight elements of matrix 0 + vld1.32 {d20-d23}, [r0] @ load second eight elements of matrix 0 + vld1.32 {d0-d3}, [r1]! @ load first eight elements of matrix 1 + vld1.32 {d4-d7}, [r1] @ load second eight elements of matrix 1 + + vmul.f32 q12, q8, d0[0] @ rslt col0 = (mat0 col0) * (mat1 col0 elt0) + vmul.f32 q13, q8, d2[0] @ rslt col1 = (mat0 col0) * (mat1 col1 elt0) + vmul.f32 q14, q8, d4[0] @ rslt col2 = (mat0 col0) * (mat1 col2 elt0) + vmul.f32 q15, q8, d6[0] @ rslt col3 = (mat0 col0) * (mat1 col3 elt0) + + vmla.f32 q12, q9, d0[1] @ rslt col0 += (mat0 col1) * (mat1 col0 elt1) + vmla.f32 q13, q9, d2[1] @ rslt col1 += (mat0 col1) * (mat1 col1 elt1) + vmla.f32 q14, q9, d4[1] @ rslt col2 += (mat0 col1) * (mat1 col2 elt1) + vmla.f32 q15, q9, d6[1] @ rslt col3 += (mat0 col1) * (mat1 col3 elt1) + + vmla.f32 q12, q10, d1[0] @ rslt col0 += (mat0 col2) * (mat1 col0 elt2) + vmla.f32 q13, q10, d3[0] @ rslt col1 += (mat0 col2) * (mat1 col1 elt2) + vmla.f32 q14, q10, d5[0] @ rslt col2 += (mat0 col2) * (mat1 col2 elt2) + vmla.f32 q15, q10, d7[0] @ rslt col3 += (mat0 col2) * (mat1 col2 elt2) + + vmla.f32 q12, q11, d1[1] @ rslt col0 += (mat0 col3) * (mat1 col0 elt3) + vmla.f32 q13, q11, d3[1] @ rslt col1 += (mat0 col3) * (mat1 col1 elt3) + vmla.f32 q14, q11, d5[1] @ rslt col2 += (mat0 col3) * (mat1 col2 elt3) + vmla.f32 q15, q11, d7[1] @ rslt col3 += (mat0 col3) * (mat1 col3 elt3) + + vst1.32 {d24-d27}, [r2]! @ store first eight elements of result + vst1.32 {d28-d31}, [r2] @ store second eight elements of result + + bx lr + .fnend diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_orthoInverse_transform3.S b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_orthoInverse_transform3.S new file mode 100644 index 000000000..161fde629 --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_orthoInverse_transform3.S @@ -0,0 +1,81 @@ +@ +@ Applied Research Associates Inc. (c)2011 +@ +@ Redistribution and use in source and binary forms, +@ with or without modification, are permitted provided that the +@ following conditions are met: +@ * Redistributions of source code must retain the above copyright +@ notice, this list of conditions and the following disclaimer. +@ * Redistributions in binary form must reproduce the above copyright +@ notice, this list of conditions and the following disclaimer in the +@ documentation and/or other materials provided with the distribution. +@ * Neither the name of the Applied Research Associates Inc nor the names +@ of its contributors may be used to endorse or promote products derived +@ from this software without specific prior written permission. +@ +@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +@ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +@ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +@ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +@ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +@ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +@ POSSIBILITY OF SUCH DAMAGE. +@ + .syntax unified + .arch armv7-a + .fpu neon + .thumb + .text + .align 2 + +@ orthoInverse of a transform3, result stored directly to memory + + .global OrthoInverseTransform3Neon + .thumb_func +OrthoInverseTransform3Neon: + .fnstart +@way 1 +@ vld1.f32 {d0-d3}, [r0]! @ load first eight elements of result +@ vld1.f32 {d4-d7}, [r0] @ load second eight elements of result + +@ vzip.f32 d0, d2 +@ vzip.f32 d1, d3 +@ vswp.f32 d1, d4 +@ vzip.f32 d1, d3 + +@way 2 (faster) +@ +@ +@ NOTE NOTE! This is broken! It does not use the last column of the input! Please see +@ implementation of pfxTransform3OrthoInverseNEON in vectormath_neon_assembly_implementations.S, in +@ include/vecmath/neon, for a correct implementation! +@ + vld1.f32 d0[0], [r0]! + vld1.f32 d2[0], [r0]! + vld1.f32 d4[0], [r0]! + vld1.f32 d1[1], [r0]! + + vld1.f32 d0[1], [r0]! + vld1.f32 d2[1], [r0]! + vld1.f32 d4[1], [r0]! + vld1.f32 d3[1], [r0]! + + vld1.f32 d1[0], [r0]! + vld1.f32 d3[0], [r0]! + vld1.f32 d5[0], [r0]! + vld1.f32 d5[1], [r0] + + vmul.f32 q3, q0, d1[0] + vmla.f32 q3, q1, d3[0] + vmla.f32 q3, q2, d5[0] + vneg.f32 q3, q3 + + vst1.f32 {d0-d3}, [r1]! @ store first eight elements of result + vst1.f32 {d4-d7}, [r1] @ store second eight elements of result + + bx lr + .fnend diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_transform3_operator_multiply.S b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_transform3_operator_multiply.S new file mode 100644 index 000000000..09c655e3b --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_transform3_operator_multiply.S @@ -0,0 +1,51 @@ +@ +@ Applied Research Associates Inc. (c)2011 +@ +@ Redistribution and use in source and binary forms, +@ with or without modification, are permitted provided that the +@ following conditions are met: +@ * Redistributions of source code must retain the above copyright +@ notice, this list of conditions and the following disclaimer. +@ * Redistributions in binary form must reproduce the above copyright +@ notice, this list of conditions and the following disclaimer in the +@ documentation and/or other materials provided with the distribution. +@ * Neither the name of the Applied Research Associates Inc nor the names +@ of its contributors may be used to endorse or promote products derived +@ from this software without specific prior written permission. +@ +@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +@ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +@ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +@ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +@ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +@ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +@ POSSIBILITY OF SUCH DAMAGE. +@ + .syntax unified + .arch armv7-a + .fpu neon + .thumb + .text + .align 2 + +@ transform3 operator *, result stored directly to memory + + .global Transform3OperatorMultiplyNeon + .thumb_func +Transform3OperatorMultiplyNeon: + .fnstart + + vld1.32 {d16-d19}, [r0]! @ load first eight elements of transform matrix + vld1.32 {d20-d21}, [r0] @ load second eight elements of transform matrix + vld1.32 {d0-d1}, [r1] @ load the four elements of vector3 + vmul.f32 q12, q8, d0[0] @ rslt col0 = (mat0 col0) * (mat1 col0 elt0) + vmla.f32 q12, q9, d0[1] @ rslt col0 += (mat0 col1) * (mat1 col0 elt1) + vmla.f32 q12, q10, d1[0] @ rslt col0 += (mat0 col2) * (mat1 col0 elt2) + vst1.32 {d24-d25}, [r2] @ store first eight elements of result + + bx lr + .fnend diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_transpose_matrix3.S b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_transpose_matrix3.S new file mode 100644 index 000000000..3d586bbd2 --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/neon_transpose_matrix3.S @@ -0,0 +1,81 @@ +@ +@ Applied Research Associates Inc. (c)2011 +@ +@ Redistribution and use in source and binary forms, +@ with or without modification, are permitted provided that the +@ following conditions are met: +@ * Redistributions of source code must retain the above copyright +@ notice, this list of conditions and the following disclaimer. +@ * Redistributions in binary form must reproduce the above copyright +@ notice, this list of conditions and the following disclaimer in the +@ documentation and/or other materials provided with the distribution. +@ * Neither the name of the Applied Research Associates Inc nor the names +@ of its contributors may be used to endorse or promote products derived +@ from this software without specific prior written permission. +@ +@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +@ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +@ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +@ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +@ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +@ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +@ POSSIBILITY OF SUCH DAMAGE. +@ + .syntax unified + .arch armv7-a + .fpu neon + .thumb + .text + .align 2 + +@ transpose a matrix3, result stored directly to memory + + .global TransposeMatrix3Neon + .thumb_func +TransposeMatrix3Neon: + .fnstart + +@way1 +@ vld1.f32 d0[0], [r0]! +@ vld1.f32 d2[0], [r0]! +@ vld1.f32 d4[0], [r0]! +@ vld1.f32 d1[1], [r0]! + +@ vld1.f32 d0[1], [r0]! +@ vld1.f32 d2[1], [r0]! +@ vld1.f32 d4[1], [r0]! +@ vld1.f32 d3[1], [r0]! + +@ vld1.f32 d1[0], [r0]! +@ vld1.f32 d3[0], [r0]! +@ vld1.f32 d5[0], [r0]! +@ vld1.f32 d5[1], [r0] + +@way2 +@ vld2.f32 {d0-d1}, [r0]! +@ vld2.f32 {d2-d3}, [r0]! +@ vld2.f32 {d4-d5}, [r0] + +@ vzip.f32 q0, q1 +@ vswp.f32 d1, d4 +@ vswp.f32 d3, d5 +@ vzip.f32 d1, d5 + +@way3 (Fastest) + vld1.f32 {d0-d3}, [r0]! @ store first eight elements of result + vld1.f32 {d4-d5}, [r0] @ store second eight elements of result + + vzip.f32 d0, d2 + vzip.f32 d1, d3 + vswp.f32 d1, d4 + vzip.f32 d1, d3 + + vst1.f32 {d0-d3}, [r1]! @ store first eight elements of result + vst1.f32 {d4-d5}, [r1] @ store second eight elements of result + + bx lr + .fnend diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon.h b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon.h new file mode 100644 index 000000000..04f059e9c --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon.h @@ -0,0 +1,43 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef TEST_NEON_H +#define TEST_NEON_H + +//Neon functions to test +void TestNeonDotProduct(); +void TestNeonCrossProduct(); +void TestNeonMatrix3OperatorMultiply(); +void TestNeonMatrix4OperatorMultiply(); +void TestNeonOrthoInverseTransform3(); +void TestNeonTransform3OperatorMultiply(); +void TestNeonTransposeMatrix3(); +void TestNeonSolveLinearConstraintRow(); + +#endif // TEST_NEON_H diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_cross_product.cpp b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_cross_product.cpp new file mode 100644 index 000000000..1350e2743 --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_cross_product.cpp @@ -0,0 +1,229 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "test_neon.h" +#define SCE_PFX_USE_PERFCOUNTER +#include "physics_effects.h" +#include +#include +#include +#include +#include + +// This works with gcc +#define SET_ALIGNMENT(alignment) __attribute__((__aligned__((alignment)))) + +//#define PRINT_COMPUTED_VECTOR_RESULTS + +// assembly implementations +extern "C" +{ + void CrossProductNeonResultInMemoryAssembly(float *a, float *b, float *pfResult); + void CrossProductNeonResultInMemoryAssembly2(float *a, float *b, float *pfResult); + void CrossProductNeonResultInMemoryAssembly3(float *a, float *b, float *pfResult); +} + +//---------------------------------------------------------------------------- +// CrossProductNeonResultInMemory +// +/// Performs a Vector3 style cross product using NEON intrinsics, storing the +/// result directly into system memory. +/// +/// @param a Input vector 1. Must point to 4 float values +/// @param b Input vector 2. Must point to 4 float values +/// @param pfResult [in] must point to an array of at least *4* +/// float values. [out] The result of the cross +/// product is contained in the first 3 lanes. +/// +/// NOTE: The parameter types here are floats, not float32_t's. gcc +/// sometimes doesn't interpret float32_t's correctly. In particular, +/// if the type of pfResult is set to float32_t*, gcc will throw an +/// internal compiler error (ICE) for this code. In memory, float32_t +/// and float are equivalent, so can cast between them explicitly. +//---------------------------------------------------------------------------- +void CrossProductNeonResultInMemory(float *a, float *b, float *pfResult) +{ + float32x4_t v1 = {a[1],a[2],a[0], 0.0f}; + float32x4_t v2 = {b[2],b[0],b[1], 0.0f}; + float32x4_t v3 = {a[2],a[0],a[1], 0.0f}; + float32x4_t v4 = {b[1],b[2],b[0], 0.0f}; + v1 = vmulq_f32(v1, v2); + v1 = vmlsq_f32(v1, v3, v4); + vst1q_f32((float32_t*)pfResult, v1); +} + +void CrossProductNeonResultInMemoryCPPAssembly(float *a, float *b, float *result) { + asm volatile( + "vld1.32 {d18[1]}, [r1]! \n\t" + "vld1.32 {d19[0]}, [r1]! \n\t" + "vld1.32 {d18[0]}, [r1]! \n\t" + "vld1.32 {d19[1]}, [r1] \n\t" + "vld1.32 {d17[0]}, [r0]! \n\t" + "vld1.32 {d16}, [r0]! \n\t" + "vld1.32 {d17[1]}, [r0] \n\t" + "vmul.f32 q10, q8, q9 \n\t" + "vtrn.32 d18,d19 \n\t" + "vrev64.32 d16,d16 \n\t" + "vrev64.32 d18,d18 \n\t" + "vtrn.32 d16,d17 \n\t" + "vmls.f32 q10, q8, q9 \n\t" + "vst1.32 {q10}, [r2] \n\t" + ); +} + +//---------------------------------------------------------------------------- +// CrossProductScalarResultInMemory +// +/// Performs a Vector3 style cross product using scalar math, storing the +/// result directly into system memory. +/// +/// @param a Input vector 1. Must point to 4 float values +/// @param b Input vector 2. Must point to 4 float values +/// @param pfResult [in] pointer to a float. [out] Contains the +/// result, dotproduct(a,b) +//---------------------------------------------------------------------------- +void CrossProductScalarResultInMemory(float *a, float *b, float *pfResult) +{ + pfResult[0] = a[1]*b[2] - a[2]*b[1]; + pfResult[1] = a[2]*b[0] - a[0]*b[2]; + pfResult[2] = a[0]*b[1] - a[1]*b[0]; +} + +//---------------------------------------------------------------------------- +// TestFastNeonCrossProduct +// +/// Run timing study of the cross product functions above, writing the +/// results to the Android verbose log. +//---------------------------------------------------------------------------- +void TestNeonCrossProduct() +{ + float SET_ALIGNMENT(64) data[] = {float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f, + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f}; + + float *a = &data[0]; + float *b = &data[4]; + + char szMsg[256]; + + sprintf(szMsg, ""); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"---------------------------------------"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "Cross product test inputs A=<%f,%f,%f>, B=<%f,%f,%f>", + a[0], a[1], a[2], b[0], b[1], b[2]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + float SET_ALIGNMENT(64) fResult[4]; + + double dTimeSpan, dRefTimeSpan;; + unsigned int uiNumTries = 10000000; + unsigned int i; + + sce::PhysicsEffects::PfxPerfCounter pc; + +// profile scalar cross product with direct memory return + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + CrossProductScalarResultInMemory(a, b, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + dRefTimeSpan = dTimeSpan; + sprintf(szMsg, "Time to do %i calls for CrossProductScalarResultInMemory: %f secs, speedup: %5.2f, result value=<%f,%f,%f>", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan, fResult[0], fResult[1], fResult[2]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + + +// profile NEON assembly volatile cross product with direct memory return + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + CrossProductNeonResultInMemoryCPPAssembly(a, b, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + sprintf(szMsg, "Time to do %i calls for CrossProductNeonResultInMemoryFast: %f secs, speedup: %5.2f, result value=<%f,%f,%f>", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan, fResult[0], fResult[1], fResult[2]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + + +// profile NEON cross product with direct memory return, assembly version + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + CrossProductNeonResultInMemoryAssembly(a, b, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + sprintf(szMsg, "Time to do %i calls for CrossProductNeonResultInMemoryAssembly: %f secs, speedup: %5.2f, result value=<%f,%f,%f>", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan, fResult[0], fResult[1], fResult[2]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + + +// profile NEON cross product with direct memory return, assembly version 2 + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + CrossProductNeonResultInMemoryAssembly2(a, b, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + + sprintf(szMsg, "Time to do %i calls for CrossProductNeonResultInMemoryAssembly2: %f secs, speedup: %5.2f, result value=<%f,%f,%f>", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan, fResult[0], fResult[1], fResult[2]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + + +// profile NEON cross product with direct memory return, assembly version 3 + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + CrossProductNeonResultInMemoryAssembly3(a, b, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + + sprintf(szMsg, "Time to do %i calls for CrossProductNeonResultInMemoryAssembly3: %f secs, speedup: %5.2f, result value=<%f,%f,%f>", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan, fResult[0], fResult[1], fResult[2]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); +} diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_dot_product.cpp b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_dot_product.cpp new file mode 100644 index 000000000..e1f5c1ff2 --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_dot_product.cpp @@ -0,0 +1,330 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "test_neon.h" +#define SCE_PFX_USE_PERFCOUNTER +#include "physics_effects.h" +#include +#include +#include +#include +#include + +// This works with gcc +#define SET_ALIGNMENT(alignment) __attribute__((__aligned__((alignment)))) + +//#define PRINT_COMPUTED_VECTOR_RESULTS + +// assembly implementations +extern "C" +{ + float32_t DotProductNeonResultInRegisterAssembly(float *a, float *b); + void DotProductNeonResultInMemoryAssembly(float *a, float *b, float *pfResult); + void DotProductNeonResultInMemoryAssembly2(float *data, float *pfResult); + void DotProductNeonResultInMemoryAssembly2b(float *data, float *pfResult); +} + +//---------------------------------------------------------------------------- +// DotProductNeonResultInRegister +// +/// Performs a Vector4 style dot product using NEON intrinsics, returning +/// the result in an ARM register. +/// +/// @param a Input vector 1. Must point to 4 float values +/// @param b Input vector 2. Must point to 4 float values +/// +/// @return dotproduct(a,b) +//---------------------------------------------------------------------------- +float32_t DotProductNeonResultInRegister(float *a, float *b) +{ + float32_t result[2]; + float32x2_t v1a = vld1_f32((float32_t*)a); + float32x2_t v1b = vld1_f32((float32_t*)(a + 2)); + float32x2_t v2a = vld1_f32((float32_t*)b); + float32x2_t v2b = vld1_f32((float32_t*)(b + 2)); + v1a = vmul_f32(v1a, v2a); + v1a = vmla_f32(v1a, v1b, v2b); + v1a = vpadd_f32(v1a, v1a); + vst1_f32(result, v1a); + return(result[0]); +} + +// pfResult must point to memory large enough to store *two* +// float32_t values +//---------------------------------------------------------------------------- +// DotProductNeonResultInMemory +// +/// Performs a Vector4 style dot product using NEON intrinsics, storing the +/// result directly into system memory. +/// +/// @param a Input vector 1. Must point to 4 float values +/// @param b Input vector 2. Must point to 4 float values +/// @param pfResult [in] must point to an array of at least *2* +/// float values. [out] The result of the dot +/// product is contained in both slots of the array. +/// Recommended to use the first one though they +/// have the same value +/// +/// NOTE: The parameter types here are floats, not float32_t's. gcc +/// sometimes doesn't interpret float32_t's correctly. In particular, +/// if the type of pfResult is set to float32_t*, gcc will throw an +/// internal compiler error (ICE) for this code. In memory, float32_t +/// and float are equivalent, so can cast between them explicitly. +//---------------------------------------------------------------------------- +void DotProductNeonResultInMemory(float *a, float *b, float *pfResult) +{ + float32x2_t v1a = vld1_f32((float32_t*)a); + float32x2_t v1b = vld1_f32((float32_t*)(a + 2)); + float32x2_t v2a = vld1_f32((float32_t*)b); + float32x2_t v2b = vld1_f32((float32_t*)(b + 2)); + v1a = vmul_f32(v1a, v2a); + v1a = vmla_f32(v1a, v1b, v2b); + v1a = vpadd_f32(v1a, v1a); + vst1_f32((float32_t*)pfResult, v1a); +} + +//---------------------------------------------------------------------------- +// DotProductScalarResultInRegister +// +/// Performs a Vector4 style dot product using scalar math, and returning +/// the result in an ARM register. +/// +/// @param a Input vector 1. Must point to 4 float values +/// @param b Input vector 2. Must point to 4 float values +/// +/// @return dotproduct(a,b) +//---------------------------------------------------------------------------- +float DotProductScalarResultInRegister(float *a, float *b) +{ + return(a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]); +} + +//---------------------------------------------------------------------------- +// DotProductScalarResultInMemory +// +/// Performs a Vector4 style dot product using scalar math, storing the +/// result directly into system memory. +/// +/// @param a Input vector 1. Must point to 4 float values +/// @param b Input vector 2. Must point to 4 float values +/// @param pfResult [in] pointer to a float. [out] Contains the +/// result, dotproduct(a,b) +//---------------------------------------------------------------------------- +void DotProductScalarResultInMemory(float *a, float *b, float *pfResult) +{ + *pfResult = a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]; +} + +//---------------------------------------------------------------------------- +// TestFastNeonDotProduct +// +/// Run timing study of the four dot product functions above, writing the +/// results to the Android verbose log. +//---------------------------------------------------------------------------- +void TestNeonDotProduct() +{ + float SET_ALIGNMENT(64) data[] = {float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX), + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX)}; + + float *a = &data[0]; + float *b = &data[4]; + + char szMsg[256]; + + sprintf(szMsg, ""); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"---------------------------------------"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + +#ifdef PRINT_COMPUTED_VECTOR_RESULTS + sprintf(szMsg, "Dot product test inputs A=<%f,%f,%f>, B=<%f,%f,%f>", + a[0], a[1], a[2], b[0], b[1], b[2]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); +#endif + + float SET_ALIGNMENT(64) fResult[2]; + + sce::PhysicsEffects::PfxPerfCounter pc; + double dTimeSpan, dRefTimeSpan; + unsigned int uiNumTries = 10000000; + unsigned int i; + + // profile scalar dot product with register return + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + fResult[0] = DotProductScalarResultInRegister(a, b); // C++ + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + dRefTimeSpan = dTimeSpan; +#ifdef PRINT_COMPUTED_VECTOR_RESULTS + sprintf(szMsg, "Time to do %i calls to scalar dot product return in register: %f, result value=%f", + uiNumTries, dTimeSpan, fResult[0]); +#else + sprintf(szMsg, "Sclr C++ Dot Product Register Return: %10.7f secs, REF TIME", dTimeSpan); +#endif + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + // profile NEON dot product with register return + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + fResult[0] = DotProductNeonResultInRegister(a, b); // C++ + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); +#ifdef PRINT_COMPUTED_VECTOR_RESULTS + sprintf(szMsg, "Time to do %i calls to NEON dot product return in register: %f, result value=%f", + uiNumTries, dTimeSpan, fResult[0]); +#else + sprintf(szMsg, "Neon C++ Dot Product Register Return: %10.7f secs, speedup: %5.2f", dTimeSpan, dRefTimeSpan/dTimeSpan); +#endif + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + // profile NEON dot product with register return, assembly version + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + fResult[0] = DotProductNeonResultInRegisterAssembly(a, b); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + +#ifdef PRINT_COMPUTED_VECTOR_RESULTS + sprintf(szMsg, "Time to do %i calls to NEON dot product return in register (assembly version): %f, result value=%f", + uiNumTries, dTimeSpan, fResult[0]); +#else + sprintf(szMsg, "Neon Asm Dot Product Register Return: %10.7f secs, speedup: %5.2f", dTimeSpan, dRefTimeSpan/dTimeSpan); +#endif + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + // profile scalar dot product with direct memory return + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + DotProductScalarResultInMemory(a, b, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + + dRefTimeSpan = dTimeSpan; +#ifdef PRINT_COMPUTED_VECTOR_RESULTS + sprintf(szMsg, "Time to do %i calls to scalar dot product return in memory: %f, result value=%f", + uiNumTries, dTimeSpan, fResult[0]); +#else + sprintf(szMsg, " Sclr C++ Dot Product Memory Return: %10.7f secs, REF TIME", dTimeSpan); +#endif + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + // profile NEON dot product with direct memory return + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + DotProductNeonResultInMemory(a, b, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + +#ifdef PRINT_COMPUTED_VECTOR_RESULTS + sprintf(szMsg, "Time to do %i calls to NEON dot product return in memory: %f, result value=%f", + uiNumTries, dTimeSpan, fResult[0]); +#else + sprintf(szMsg, " Neon C++ Dot Product Memory Return: %10.7f secs, speedup: %5.2f", dTimeSpan, dRefTimeSpan/dTimeSpan); +#endif + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + // profile NEON dot product with direct memory return, assembly version + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + DotProductNeonResultInMemoryAssembly(a, b, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + +#ifdef PRINT_COMPUTED_VECTOR_RESULTS + sprintf(szMsg, "Time to do %i calls to NEON dot product return in memory (assembly version): %f, result value=%f", + uiNumTries, dTimeSpan, fResult[0]); +#else + sprintf(szMsg, " Neon Asm Dot Product Memory Return: %10.7f secs, speedup: %5.2f", dTimeSpan, dRefTimeSpan/dTimeSpan); +#endif + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + // profile NEON dot product with direct memory return, assembly version with both + // inputs in contiguous memory block (array of structures) + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + DotProductNeonResultInMemoryAssembly2(data, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + +#ifdef PRINT_COMPUTED_VECTOR_RESULTS + sprintf(szMsg, "Time to do %i calls to NEON dot product return in memory (assembly version - array of structures): %f, result value=%f", + uiNumTries, dTimeSpan, fResult[0]); +#else + sprintf(szMsg, " Neon Asm2 Dot Product Memory Return: %10.7f secs, speedup: %5.2f", dTimeSpan, dRefTimeSpan/dTimeSpan); +#endif + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + // profile NEON dot product with direct memory return, assembly version with both + // inputs in contiguous memory block (array of structures), alternate methodology + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + DotProductNeonResultInMemoryAssembly2b(data, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + +#ifdef PRINT_COMPUTED_VECTOR_RESULTS + sprintf(szMsg, "Time to do %i calls to NEON dot product return in memory (assembly version - alternate methodology): %f, result value=%f", + uiNumTries, dTimeSpan, fResult[0]); +#else + sprintf(szMsg, " Neon Asm3 Dot Product Memory Return: %10.7f secs, speedup: %5.2f", dTimeSpan, dRefTimeSpan/dTimeSpan); +#endif + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); +} diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_matrix3_operator_multiply.cpp b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_matrix3_operator_multiply.cpp new file mode 100644 index 000000000..58d558993 --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_matrix3_operator_multiply.cpp @@ -0,0 +1,173 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "test_neon.h" +#define SCE_PFX_USE_PERFCOUNTER +#include "physics_effects.h" +#include +#include +#include +#include +#include + +// This works with gcc +#define SET_ALIGNMENT(alignment) __attribute__((__aligned__((alignment)))) + +// assembly implementations +extern "C" +{ + void Matrix3OperatorMultiplyNeon(float *mCol, float *mat, float *pfResult); +} + +//---------------------------------------------------------------------------- +// Matrix3OperatorMultiplyScalar +// +/// Performs a Matrix3 Vector3 multiply using scalar math, storing the +/// result directly into system memory. +/// +/// @param mCol Matrix3 Columns. Must point to 3x 4 float values +/// @param mat Matrix3 Columns. Must point to 3x 4 float values +/// @param pfResult [in] pointer to a float(matrix 3). [out] Contains the result +//---------------------------------------------------------------------------- +//inline const Vector3 Matrix3::operator *( const Vector3 & vec ) const +//{ +// return Vector3( +// ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), +// ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), +// ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) +// ); +//} +// +//inline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const +//{ +// return Matrix3( +// ( *this * mat.mCol0 ), +// ( *this * mat.mCol1 ), +// ( *this * mat.mCol2 ) +// ); +//} +void Matrix3OperatorMultiplyScalar(float *mCol, float *mat, float *pfResult) +{ + pfResult[0] = ( ( ( mCol[0] * mat[0] ) + ( mCol[4] * mat[1] ) ) + ( mCol[8] * mat[2] ) ); + pfResult[1] = ( ( ( mCol[1] * mat[0] ) + ( mCol[5] * mat[1] ) ) + ( mCol[9] * mat[2] ) ); + pfResult[2] = ( ( ( mCol[2] * mat[0] ) + ( mCol[6] * mat[1] ) ) + ( mCol[10] * mat[2] ) ); + pfResult[3] = 0.0f; + + pfResult[4] = ( ( ( mCol[0] * mat[4] ) + ( mCol[4] * mat[5] ) ) + ( mCol[8] * mat[6] ) ); + pfResult[5] = ( ( ( mCol[1] * mat[4] ) + ( mCol[5] * mat[5] ) ) + ( mCol[9] * mat[6] ) ); + pfResult[6] = ( ( ( mCol[2] * mat[4] ) + ( mCol[6] * mat[5] ) ) + ( mCol[10] * mat[6] ) ); + pfResult[7] = 0.0f; + + pfResult[8] = ( ( ( mCol[0] * mat[8] ) + ( mCol[4] * mat[9] ) ) + ( mCol[8] * mat[10] ) ); + pfResult[9] = ( ( ( mCol[1] * mat[8] ) + ( mCol[5] * mat[9] ) ) + ( mCol[9] * mat[10] ) ); + pfResult[10] = ( ( ( mCol[2] * mat[8] ) + ( mCol[6] * mat[9] ) ) + ( mCol[10] * mat[10] ) ); + pfResult[11] = 0.0f; +} + +//---------------------------------------------------------------------------- +// TestNeonMatrix3OperatorMultiply +// +/// Run timing study of the NeonMatrix3OperatorMultiply product functions above, writing the +/// results to the Android verbose log. +//---------------------------------------------------------------------------- +void TestNeonMatrix3OperatorMultiply() +{ + float SET_ALIGNMENT(64) data1[] = {float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f, + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f, + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f}; + float SET_ALIGNMENT(64) data2[] = {float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f, + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f, + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f}; + float *mCol = &data1[0]; + float *mat = &data2[0]; + float SET_ALIGNMENT(64) fResult[12]; + + sce::PhysicsEffects::PfxPerfCounter pc; + double dTimeSpan, dRefTimeSpan;; + unsigned int uiNumTries = 10000000; + unsigned int i; + + char szMsg[256]; + + sprintf(szMsg, ""); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"---------------------------------------"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"TestNeonMatrix3OperatorMultiply Start"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "Test input mCol: <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>", + mCol[0], mCol[1], mCol[2], mCol[3], + mCol[4], mCol[5], mCol[6], mCol[7], + mCol[8], mCol[9], mCol[10], mCol[11]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "Test input mat: <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>", + mat[0], mat[1], mat[2], mat[3], + mat[4], mat[5], mat[6], mat[7], + mat[8], mat[9], mat[10], mat[11]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + + +// profile scalar NeonMatrix3OperatorMultiplyScalar with direct memory return, c++ version + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + Matrix3OperatorMultiplyScalar(mCol, mat, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + dRefTimeSpan = dTimeSpan; + sprintf(szMsg, "Time to do %i calls for Matrix3OperatorMultiplyScalar: %f secs, speedup: %5.2f, result value=<%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan, fResult[0], fResult[1], fResult[2], fResult[3], + fResult[4], fResult[5], fResult[6], fResult[7], + fResult[8], fResult[9], fResult[10], fResult[11]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + +// profile NEON Matrix3OperatorMultiplyNeon with direct memory return, assembly version + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + Matrix3OperatorMultiplyNeon(mCol, mat, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + sprintf(szMsg, "Time to do %i calls for Matrix3OperatorMultiplyNeon: %f secs, speedup: %5.2f, result value=<%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan, fResult[0], fResult[1], fResult[2], fResult[3], + fResult[4], fResult[5], fResult[6], fResult[7], + fResult[8], fResult[9], fResult[10], fResult[11]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + + sprintf(szMsg,"TestNeonMatrix3OperatorMultiply End"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); +} diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_matrix4_operator_multiply.cpp b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_matrix4_operator_multiply.cpp new file mode 100644 index 000000000..9c88e805a --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_matrix4_operator_multiply.cpp @@ -0,0 +1,188 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "test_neon.h" +#define SCE_PFX_USE_PERFCOUNTER +#include "physics_effects.h" +#include +#include +#include +#include +#include + +// This works with gcc +#define SET_ALIGNMENT(alignment) __attribute__((__aligned__((alignment)))) + +// assembly implementations +extern "C" +{ + void Matrix4OperatorMultiplyNeon(float *mCol, float *mat, float *pfResult); +} + +//---------------------------------------------------------------------------- +// Matrix4OperatorMultiplyScalar +// +/// Performs a Matrix4 vector3 multiply using scalar math, storing the +/// result directly into system memory. +/// +/// @param mCol Input matrix 1. Must point to 4x 4 float values +/// @param mat Input matrix 2. Must point to 4x 4 float values +/// @param pfResult [in] pointer to a float(matrix). [out] Contains the result +//---------------------------------------------------------------------------- +//inline const Vector4 Matrix4::operator *( const Vector4 & vec ) const +//{ +// return Vector4( +// ( ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ) + ( mCol3.getX() * vec.getW() ) ), +// ( ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ) + ( mCol3.getY() * vec.getW() ) ), +// ( ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ( mCol3.getZ() * vec.getW() ) ), +// ( ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) + ( mCol3.getW() * vec.getW() ) ) +// ); +//} +//inline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const +//{ +// return Matrix4( +// ( *this * mat.mCol0 ), +// ( *this * mat.mCol1 ), +// ( *this * mat.mCol2 ), +// ( *this * mat.mCol3 ) +// ); +//} +void Matrix4OperatorMultiplyScalar(float *mCol, float *mat, float *pfResult) +{ + pfResult[0] = ( ( ( mCol[0] * mat[0] ) + ( mCol[4] * mat[1] ) ) + ( mCol[8] * mat[2] ) + ( mCol[12] * mat[3] ) ); + pfResult[1] = ( ( ( mCol[1] * mat[0] ) + ( mCol[5] * mat[1] ) ) + ( mCol[9] * mat[2] ) + ( mCol[13] * mat[3] ) ); + pfResult[2] = ( ( ( mCol[2] * mat[0] ) + ( mCol[6] * mat[1] ) ) + ( mCol[10] * mat[2] ) + ( mCol[14] * mat[3] ) ); + pfResult[3] = ( ( ( mCol[3] * mat[0] ) + ( mCol[7] * mat[1] ) ) + ( mCol[11] * mat[2] ) + ( mCol[15] * mat[3] ) ); + + pfResult[4] = ( ( ( mCol[0] * mat[4] ) + ( mCol[4] * mat[5] ) ) + ( mCol[8] * mat[6] ) + ( mCol[12] * mat[7] ) ); + pfResult[5] = ( ( ( mCol[1] * mat[4] ) + ( mCol[5] * mat[5] ) ) + ( mCol[9] * mat[6] ) + ( mCol[13] * mat[7] ) ); + pfResult[6] = ( ( ( mCol[2] * mat[4] ) + ( mCol[6] * mat[5] ) ) + ( mCol[10] * mat[6] ) + ( mCol[14] * mat[7] ) ); + pfResult[7] = ( ( ( mCol[3] * mat[4] ) + ( mCol[7] * mat[5] ) ) + ( mCol[11] * mat[6] ) + ( mCol[15] * mat[7] ) ); + + pfResult[8] = ( ( ( mCol[0] * mat[8] ) + ( mCol[4] * mat[9] ) ) + ( mCol[8] * mat[10] ) + ( mCol[12] * mat[11] ) ); + pfResult[9] = ( ( ( mCol[1] * mat[8] ) + ( mCol[5] * mat[9] ) ) + ( mCol[9] * mat[10] ) + ( mCol[13] * mat[11] ) ); + pfResult[10] = ( ( ( mCol[2] * mat[8] ) + ( mCol[6] * mat[9] ) ) + ( mCol[10] * mat[10] ) + ( mCol[14] * mat[11] ) ); + pfResult[11] = ( ( ( mCol[3] * mat[8] ) + ( mCol[7] * mat[9] ) ) + ( mCol[11] * mat[10] ) + ( mCol[15] * mat[11] ) ); + + pfResult[12] = ( ( ( mCol[0] * mat[12] ) + ( mCol[4] * mat[13] ) ) + ( mCol[8] * mat[14] ) + ( mCol[12] * mat[15] ) ); + pfResult[13] = ( ( ( mCol[1] * mat[12] ) + ( mCol[5] * mat[13] ) ) + ( mCol[9] * mat[14] ) + ( mCol[13] * mat[15] ) ); + pfResult[14] = ( ( ( mCol[2] * mat[12] ) + ( mCol[6] * mat[13] ) ) + ( mCol[10] * mat[14] ) + ( mCol[14] * mat[15] ) ); + pfResult[15] = ( ( ( mCol[3] * mat[12] ) + ( mCol[7] * mat[13] ) ) + ( mCol[11] * mat[14] ) + ( mCol[15] * mat[15] ) ); +} + +//---------------------------------------------------------------------------- +// TestNeonMatrix4OperatorMultiply +// +/// Run timing study of the matrix4 vector3 multiply operator from above, writing the +/// results to the Android verbose log. +//---------------------------------------------------------------------------- +void TestNeonMatrix4OperatorMultiply() +{ + float SET_ALIGNMENT(64) data1[] = {float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX), + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX), + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX), + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX)}; + float SET_ALIGNMENT(64) data2[] = {float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX), + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX), + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX), + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX)}; + float *mCol = &data1[0]; + float *mat = &data2[0]; + + char szMsg[256]; + + sprintf(szMsg, ""); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"---------------------------------------"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"TestNeonMatrix4OperatorMultiply Start"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "Test input mCol: <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>", + mCol[0], mCol[1], mCol[2], mCol[3], + mCol[4], mCol[5], mCol[6], mCol[7], + mCol[8], mCol[9], mCol[10], mCol[11], + mCol[12], mCol[13], mCol[14], mCol[15]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "Test input mat: <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>", + mat[0], mat[1], mat[2], mat[3], + mat[4], mat[5], mat[6], mat[7], + mat[8], mat[9], mat[10], mat[11], + mCol[12], mCol[13], mCol[14], mCol[15]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + float SET_ALIGNMENT(64) fResult[16]; + + + sce::PhysicsEffects::PfxPerfCounter pc; + double dTimeSpan, dRefTimeSpan;; + unsigned int uiNumTries = 10000000; + unsigned int i; + +// profile scalar Matrix4OperatorMultiplyScalar with direct memory return, c++ version + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + Matrix4OperatorMultiplyScalar(mCol, mat, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + dRefTimeSpan = dTimeSpan; + sprintf(szMsg, "Time to do %i calls for Matrix4OperatorMultiplyScalar: %f secs, speedup: %5.2f", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "result value: <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>", + fResult[0], fResult[1], fResult[2], fResult[3], + fResult[4], fResult[5], fResult[6], fResult[7], + fResult[8], fResult[9], fResult[10], fResult[11], + fResult[12], fResult[13], fResult[14], fResult[15]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + +// profile NEON Matrix4OperatorMultiplyNeon with direct memory return, assembly version + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + Matrix4OperatorMultiplyNeon(mCol, mat, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + sprintf(szMsg, "Time to do %i calls for Matrix4OperatorMultiplyNeon: %f secs, speedup: %5.2f, result value=<%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan, fResult[0], fResult[1], fResult[2], fResult[3], + fResult[4], fResult[5], fResult[6], fResult[7], + fResult[8], fResult[9], fResult[10], fResult[11], + fResult[12], fResult[13], fResult[14], fResult[15]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + + sprintf(szMsg,"TestNeonMatrix4OperatorMultiply End"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); +} diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_orthoInverse_transform3.cpp b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_orthoInverse_transform3.cpp new file mode 100644 index 000000000..216b350c2 --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_orthoInverse_transform3.cpp @@ -0,0 +1,173 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "test_neon.h" +#define SCE_PFX_USE_PERFCOUNTER +#include "physics_effects.h" +#include +#include +#include +#include +#include + +// This works with gcc +#define SET_ALIGNMENT(alignment) __attribute__((__aligned__((alignment)))) + +// assembly implementations +extern "C" +{ + void OrthoInverseTransform3Neon(float *trfm, float *pfResult); +} + +//---------------------------------------------------------------------------- +// OrthoInverseTransform3Scalar +// +/// Performs a ortho inverse of a transform3 using scalar math, storing the +/// result directly into system memory. +/// +/// @param trfm Input transform3. Must point to 4x 4 float values +/// @param pfResult [in] pointer to a float(tranform3). [out] Contains the result +//---------------------------------------------------------------------------- +//inline const Transform3 orthoInverse( const Transform3 & tfrm ) +//{ +// Vector3 inv0, inv1, inv2; +// inv0 = Vector3( tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX() ); +// inv1 = Vector3( tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY() ); +// inv2 = Vector3( tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ() ); +// return Transform3( +// inv0, +// inv1, +// inv2, +// Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) +// ); +//} +void OrthoInverseTransform3Scalar(float *trfm, float *pfResult) +{ + pfResult[0] = trfm[0]; + pfResult[1] = trfm[4]; + pfResult[2] = trfm[8]; + pfResult[3] = 0.0f; + + pfResult[4] = trfm[1]; + pfResult[5] = trfm[5]; + pfResult[6] = trfm[9]; + pfResult[7] = 0.0f; + + pfResult[8] = trfm[2]; + pfResult[9] = trfm[6]; + pfResult[10] = trfm[10]; + pfResult[11] = 0.0f; + + pfResult[12] = ( -( ( trfm[0] * trfm[8]) + ( ( trfm[1] * trfm[9]) + ( trfm[2] * trfm[10]) ) ) ); + pfResult[13] = ( -( ( trfm[4] * trfm[8]) + ( ( trfm[5] * trfm[9]) + ( trfm[6] * trfm[10]) ) ) ); + pfResult[14] = ( -( ( trfm[8] * trfm[8]) + ( ( trfm[9] * trfm[9]) + ( trfm[10] * trfm[10]) ) ) ); + pfResult[15] = 0.0f; +} + +//---------------------------------------------------------------------------- +// TestNeonOrthoInverseTransform3 +// +/// Run timing study of the orthoinverse on transform3 functions above, writing the +/// results to the Android verbose log. +//---------------------------------------------------------------------------- +void TestNeonOrthoInverseTransform3() +{ + float SET_ALIGNMENT(64) data1[] = {float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f, + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f, + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f, + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f}; + float *trfm = &data1[0]; + + char szMsg[256]; + + sprintf(szMsg, ""); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"---------------------------------------"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"TestNeonOrthoInverseTransform3 Start"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "Test input trfm: <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>>", + trfm[0], trfm[1], trfm[2], trfm[3], + trfm[4], trfm[5], trfm[6], trfm[7], + trfm[8], trfm[9], trfm[10], trfm[11], + trfm[12], trfm[13], trfm[14], trfm[15]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + float SET_ALIGNMENT(64) fResult[16]; + + + sce::PhysicsEffects::PfxPerfCounter pc; + double dTimeSpan, dRefTimeSpan;; + unsigned int uiNumTries = 10000000; + unsigned int i; + +// profile scalar OrthoInverseTransform3Scalar with direct memory return, c++ version + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + OrthoInverseTransform3Scalar(trfm, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + dRefTimeSpan = dTimeSpan; + sprintf(szMsg, "Time to do %i calls for OrthoInverseTransform3Scalar: %f secs, speedup: %5.2f", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "result value=<%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>", + fResult[0], fResult[1], fResult[2], fResult[3], + fResult[4], fResult[5], fResult[6], fResult[7], + fResult[8], fResult[9], fResult[10], fResult[11], + fResult[12], fResult[13], fResult[14], fResult[15]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + +// profile NEON OrthoInverseTransform3Neon with direct memory return, assembly version + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + OrthoInverseTransform3Neon(trfm, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + sprintf(szMsg, "Time to do %i calls for OrthoInverseTransform3Neon: %f secs, speedup: %5.2f", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "result value=<%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>", + fResult[0], fResult[1], fResult[2], fResult[3], + fResult[4], fResult[5], fResult[6], fResult[7], + fResult[8], fResult[9], fResult[10], fResult[11], + fResult[12], fResult[13], fResult[14], fResult[15]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + sprintf(szMsg,"TestNeonOrthoInverseTransform3 End"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); +} diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_solve_linear_constraint_row.cpp b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_solve_linear_constraint_row.cpp new file mode 100644 index 000000000..a98d8f993 --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_solve_linear_constraint_row.cpp @@ -0,0 +1,477 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "test_neon.h" +#define SCE_PFX_USE_PERFCOUNTER +#include "physics_effects.h" +#include +#include +#include +#include +#include + +// This works with gcc +#define SET_ALIGNMENT(alignment) __attribute__((__aligned__((alignment)))) + +//---------------------------------------------------------------------------- +// pfxSolveLinearConstraintRowScalar +// +/// Performs +/// +/// @param Input +//---------------------------------------------------------------------------- +void pfxSolveLinearConstraintRowScalar(float *constraint, // 8 floats + float *deltaLinearVelocityA, // 4 floats + float *deltaAngularVelocityA, // 4 floats + float massInvA, // 1 floats + float *inertiaInvA, // 12 floats + float *rA, // 4 floats + float *deltaLinearVelocityB, // 4 floats + float *deltaAngularVelocityB, // 4 floats + float massInvB, // 1 floats + float *inertiaInvB, // 12 floats + float *rB) // 4 floats +{ +//const PfxVector3 normal(pfxReadVector3(constraint.m_normal)); //fourth element is not zero and it need to be in assembly + float SET_ALIGNMENT(64) normalRead[] = {constraint[0],constraint[1],constraint[2],0.0f}; + float *normal = &normalRead[0]; +//PfxFloat deltaImpulse = constraint.m_rhs; + float deltaImpulse = constraint[4]; +//PfxVector3 dVA = deltaLinearVelocityA + cross(deltaAngularVelocityA,rA); + float SET_ALIGNMENT(64) dVARead[] = {deltaLinearVelocityA[0] + (deltaAngularVelocityA[1]*rA[2] - deltaAngularVelocityA[2]*rA[1]), + deltaLinearVelocityA[1] + (deltaAngularVelocityA[2]*rA[0] - deltaAngularVelocityA[0]*rA[2]), + deltaLinearVelocityA[2] + (deltaAngularVelocityA[0]*rA[1] - deltaAngularVelocityA[1]*rA[0]), + 0.0f}; + float *dVA = &dVARead[0]; +//PfxVector3 dVB = deltaLinearVelocityB + cross(deltaAngularVelocityB,rB); + float SET_ALIGNMENT(64) dVBRead[] = {deltaLinearVelocityB[0] + (deltaAngularVelocityB[1]*rB[2] - deltaAngularVelocityB[2]*rB[1]), + deltaLinearVelocityB[1] + (deltaAngularVelocityB[2]*rB[0] - deltaAngularVelocityB[0]*rB[2]), + deltaLinearVelocityB[2] + (deltaAngularVelocityB[0]*rB[1] - deltaAngularVelocityB[1]*rB[0]), + 0.0f}; + float *dVB = &dVBRead[0]; +//deltaImpulse -= constraint.m_jacDiagInv * dot(normal,dVA-dVB); + deltaImpulse -= constraint[4] * (normal[0]*(dVA[0]-dVB[0]) + normal[1]*(dVA[1]-dVB[1]) + normal[2]*(dVA[2]-dVB[2])); +//PfxFloat oldImpulse = constraint.m_accumImpulse; + float oldImpulse = constraint[7]; +//constraint.m_accumImpulse = SCE_PFX_CLAMP(oldImpulse + deltaImpulse,constraint.m_lowerLimit,constraint.m_upperLimit); + if((oldImpulse + deltaImpulse) > constraint[6]){ + if(constraint[6] > constraint[5]){ + constraint[7] = constraint[6]; + }else { + constraint[7] = constraint[5]; + } + } else { + if(oldImpulse + deltaImpulse > constraint[5]){ + constraint[7] = oldImpulse + deltaImpulse; + }else { + constraint[7] = constraint[5]; + } + } +//deltaImpulse = constraint.m_accumImpulse - oldImpulse; + deltaImpulse = constraint[7] - oldImpulse; +//deltaLinearVelocityA += deltaImpulse * massInvA * normal; + deltaLinearVelocityA[0] += deltaImpulse * massInvA * normal[0]; + deltaLinearVelocityA[1] += deltaImpulse * massInvA * normal[1]; + deltaLinearVelocityA[2] += deltaImpulse * massInvA * normal[2]; + deltaLinearVelocityA[3] += deltaImpulse * massInvA * normal[3]; + +//deltaAngularVelocityA += deltaImpulse * inertiaInvA * cross(rA,normal); + deltaAngularVelocityA[0] += deltaImpulse * ((inertiaInvA[0] * (rA[1]*normal[2] - rA[2]*normal[1])) + + (inertiaInvA[4] * (rA[2]*normal[0] - rA[0]*normal[2])) +// + (inertiaInvA[8] * (rA[0]*normal[1] - rA[1]*normal[0]))); + deltaAngularVelocityA[1] += deltaImpulse * ((inertiaInvA[1] * (rA[1]*normal[2] - rA[2]*normal[1])) + + (inertiaInvA[5] * (rA[2]*normal[0] - rA[0]*normal[2])) + + (inertiaInvA[9] * (rA[0]*normal[1] - rA[1]*normal[0]))); + deltaAngularVelocityA[2] += deltaImpulse * ((inertiaInvA[2] * (rA[1]*normal[2] - rA[2]*normal[1])) + + (inertiaInvA[6] * (rA[2]*normal[0] - rA[0]*normal[2])) + + (inertiaInvA[10] * (rA[0]*normal[1] - rA[1]*normal[0]))); + deltaAngularVelocityA[3] += deltaImpulse * ((inertiaInvA[3] * (rA[1]*normal[2] - rA[2]*normal[1])) + + (inertiaInvA[7] * (rA[2]*normal[0] - rA[0]*normal[2])) + + (inertiaInvA[11] * (rA[0]*normal[1] - rA[1]*normal[0]))); +//deltaLinearVelocityB -= deltaImpulse * massInvB * normal; + deltaLinearVelocityB[0] -= deltaImpulse * massInvB * normal[0]; + deltaLinearVelocityB[1] -= deltaImpulse * massInvB * normal[1]; + deltaLinearVelocityB[2] -= deltaImpulse * massInvB * normal[2]; + deltaLinearVelocityB[3] -= deltaImpulse * massInvB * normal[3]; + +//deltaAngularVelocityB -= deltaImpulse * inertiaInvB * cross(rB,normal); + deltaAngularVelocityB[0] -= deltaImpulse * ((inertiaInvB[0] * (rB[1]*normal[2] - rB[2]*normal[1])) + + (inertiaInvB[4] * (rB[2]*normal[0] - rB[0]*normal[2])) + + (inertiaInvB[8] * (rB[0]*normal[1] - rB[1]*normal[0]))); + deltaAngularVelocityB[1] -= deltaImpulse * ((inertiaInvB[1] * (rB[1]*normal[2] - rB[2]*normal[1])) + + (inertiaInvB[5] * (rB[2]*normal[0] - rB[0]*normal[2])) + + (inertiaInvB[9] * (rB[0]*normal[1] - rB[1]*normal[0]))); + deltaAngularVelocityB[2] -= deltaImpulse * ((inertiaInvB[2] * (rB[1]*normal[2] - rB[2]*normal[1])) + + (inertiaInvB[6] * (rB[2]*normal[0] - rB[0]*normal[2])) + + (inertiaInvB[10] * (rB[0]*normal[1] - rB[1]*normal[0]))); + deltaAngularVelocityB[3] -= deltaImpulse * ((inertiaInvB[3] * (rB[1]*normal[2] - rB[2]*normal[1])) + + (inertiaInvB[7] * (rB[2]*normal[0] - rB[0]*normal[2])) + + (inertiaInvB[11] * (rB[0]*normal[1] - rB[1]*normal[0]))); +} + +/*//////////////////////////////////////Source Code/////////////////////////////////////// +void pfxSolveLinearConstraintRow( + PfxConstraintRow &constraint, // 8 floats + PfxVector3 &deltaLinearVelocityA, // 4 floats + PfxVector3 &deltaAngularVelocityA, // 4 floats + PfxFloat massInvA, // 1 float +const PfxMatrix3 &inertiaInvA, // 12 floats +const PfxVector3 &rA, // 4 floats + PfxVector3 &deltaLinearVelocityB, // 4 floats + PfxVector3 &deltaAngularVelocityB, // 4 floats + PfxFloat massInvB, // 1 float +const PfxMatrix3 &inertiaInvB, // 12 floats +const PfxVector3 &rB) // 4 floats +{ + // PfxConstraintRow structure: + // PfxFloat m_normal[3]; + // PfxFloat m_rhs; + // PfxFloat m_jacDiagInv; + // PfxFloat m_lowerLimit; + // PfxFloat m_upperLimit; + // PfxFloat m_accumImpulse; +const PfxVector3 normal(pfxReadVector3(constraint.m_normal)); +PfxFloat deltaImpulse = constraint.m_rhs; +PfxVector3 dVA = deltaLinearVelocityA + cross(deltaAngularVelocityA,rA); +PfxVector3 dVB = deltaLinearVelocityB + cross(deltaAngularVelocityB,rB); +deltaImpulse -= constraint.m_jacDiagInv * dot(normal,dVA-dVB); +PfxFloat oldImpulse = constraint.m_accumImpulse; +constraint.m_accumImpulse = SCE_PFX_CLAMP(oldImpulse + deltaImpulse,constraint.m_lowerLimit,constraint.m_upperLimit); +deltaImpulse = constraint.m_accumImpulse - oldImpulse; +deltaLinearVelocityA += deltaImpulse * massInvA * normal; +deltaAngularVelocityA += deltaImpulse * inertiaInvA * cross(rA,normal); +deltaLinearVelocityB -= deltaImpulse * massInvB * normal; +deltaAngularVelocityB -= deltaImpulse * inertiaInvB * cross(rB,normal); +} +*/ + +void pfxSolveLinearConstraintRowNeonInline(float *constraint, // 8 floats + float *deltaLinearVelocityA, // 4 floats + float *deltaAngularVelocityA, // 4 floats + float *massInvA, // 1 floats + float *inertiaInvA, // 12 floats + float *rA, // 4 floats + float *deltaLinearVelocityB, // 4 floats + float *deltaAngularVelocityB, // 4 floats + float *massInvB, // 1 floats + float *inertiaInvB, // 12 floats + float *rB) // 4 floats +{ +// "r" (constraint), //%0 +// "r" (deltaLinearVelocityA), //%1 +// "r" (deltaAngularVelocityA), //%2 +// "r" (massInvA), //%3 +// "r" (inertiaInvA), //%4 +// "r" (rA), //%5 +// "r" (deltaLinearVelocityB), //%6 +// "r" (deltaAngularVelocityB), //%7 +// "r" (massInvB), //%8 +// "r" (inertiaInvB), //%9 +// "r" (rB) //%10 + asm volatile + ( + //Loads beforehand so the normal vector will be able to have zero in the 4th element + "vld1.32 {q0}, [%1] \n\t" //LOAD => deltaLinearVelocityA ----------------> q0 + "vld1.32 {q1}, [%2] \n\t" //LOAD => deltaAngularVelocityA ---------------> q1 + "vld1.32 {q2}, [%6] \n\t" //LOAD => deltaLinearVelocityB ----------------> q2 + "vld1.32 {q3}, [%7] \n\t" //LOAD => deltaAngularVelocityB ---------------> q3 + //const PfxVector3 normal(pfxReadVector3(constraint.m_normal)); + "vld1.32 {q4}, [%0]! \n\t" //LOAD => constraint normal--------------------> q4 + "vdup.32 d10, d1[1] \n\t" //set 4th element on normal vector to zero + "vtrn.32 d9, d10 \n\t" //LOAD => deltaImpulse ------------------------> q5 (d10[0] only) + //PfxFloat deltaImpulse = constraint.m_rhs; + "vld1.32 {d12}, [%0]! \n\t" //LOAD => constraint variables ----------------> q6 + "vld1.32 {d13[0]}, [%0]! \n\t" //constraint variables + "vld1.32 {d13[1]}, [%0] \n\t" //constraint load of remaining variables loaded this way keep pointer to m_accumilate in order to store back in later + //PfxVector3 dVA = deltaLinearVelocityA + cross(deltaAngularVelocityA,rA); + //PfxVector3 dVB = deltaLinearVelocityB + cross(deltaAngularVelocityB,rB); + "vld1.32 {d14[1]}, [%5] \n\t" //LOAD => rA for cross product use 1A ---------> q7 (save these for use later) + "vld1.32 {d18[1]}, [%10] \n\t" //LOAD => rB for cross product use 1B ---------> q9 + "vld1.32 {d17[0]}, [%5]! \n\t" //LOAD => rA for cross product use 2A ---------> q8 + "vld1.32 {d21[0]}, [%10]! \n\t" //LOAD => rB for cross product use 2B ---------> q10 + "vld1.32 {d16}, [%5] \n\t" //rA 2 + "vld1.32 {d20}, [%10] \n\t" //rB 2 + "vld1.32 {d15[0]}, [%5]! \n\t" //rA 1 + "vld1.32 {d19[0]}, [%10]! \n\t" //rB 1 + "vld1.32 {d14[0]}, [%5]! \n\t" //rA 1 + "vld1.32 {d18[0]}, [%10]! \n\t" //rB 1 + "vld1.32 {d15[1]}, [%5] \n\t" //rA 1 + "vld1.32 {d19[1]}, [%10] \n\t" //rB 1 + "vld1.32 {d17[1]}, [%5]! \n\t" //rA 2 + "vld1.32 {d21[1]}, [%10]! \n\t" //rB 2 + "vdup.32 q12, d1[1] \n\t" //set deltaAngularVelocityB 2 + "vdup.32 q13, d1[1] \n\t" //set deltaAngularVelocityB 1 + "vdup.32 q14, d1[1] \n\t" //set deltaAngularVelocityA 1 + "vdup.32 q15, d1[1] \n\t" //set deltaAngularVelocityA 2 + "vadd.f32 q14, q14, q1 \n\t" + "vadd.f32 q13, q13, q3 \n\t" + "vadd.f32 q15, q15, q1 \n\t" + "vadd.f32 q12, q12, q3 \n\t" + "vrev64.32 d28, d28 \n\t" //set deltaAngularVelocityA 1 + "vrev64.32 d26, d26 \n\t" //set deltaAngularVelocityB 1 + "vtrn.32 d30, d31 \n\t" //set deltaAngularVelocityA 2 + "vtrn.32 d24, d25 \n\t" //set deltaAngularVelocityB 2 + "vtrn.32 d28, d29 \n\t" //set deltaAngularVelocityA 1 + "vtrn.32 d26, d27 \n\t" //set deltaAngularVelocityB 1 + "vrev64.32 d30, d30 \n\t" //set deltaAngularVelocityA 2 + "vrev64.32 d24, d24 \n\t" //set deltaAngularVelocityB 2 + "vmul.f32 q14, q7, q14 \n\t" //operation for cross product 1A + "vmul.f32 q13, q9, q13 \n\t" //operation for cross product 1B + "vmls.f32 q14, q8, q15 \n\t" //operation for cross product 2A + "vmls.f32 q13, q10, q12 \n\t" //operation for cross product 2B + "vadd.f32 q14, q14, q0 \n\t" //operation for adding cross to linearVelocityA + "vadd.f32 q13, q13, q2 \n\t" //operation for adding cross to linearVelocityB + //LOAD => dVA --------------------------------> q14 + //LOAD => dVB --------------------------------> q13 + //FREE q11, q12, q15, d11 + //deltaImpulse -= constraint.m_jacDiagInv * dot(normal,dVA-dVB); + "vsub.f32 q11, q14, q13 \n\t" //TEMP q11 => dVA-dVB for dot product + /*find*/ "vmul.f32 q11, q11, q4 \n\t" //operation for dot product + /*fastest*/ "vpadd.f32 d22, d22, d22 \n\t" //operation for dot product + /*dot*/ "vpadd.f32 d23, d23, d23 \n\t" //operation for dot product + "vadd.f32 d22, d22, d23 \n\t" //operation for dot product + "vmul.f32 d22, d22, d12[0] \n\t" //m_jacDiagInv times dot product result + "vsub.f32 d10, d10, d22 \n\t" //subtract result from deltaImpule + //PfxFloat oldImpulse = constraint.m_accumImpulse; + "vdup.32 d11, d13[1] \n\t" //LOAD => oldImpulse -------------------------> q5 (d11 only) + //constraint.m_accumImpulse = SCE_PFX_CLAMP(oldImpulse + deltaImpulse,constraint.m_lowerLimit,constraint.m_upperLimit); + "vdup.32 d23, d13[0] \n\t" //TEMP q11 => m_upperLimit (d23 only) + "vdup.32 d24, d12[1] \n\t" //TEMP q12 => m_lowerLimit (d34 only) + "vadd.f32 d25, d10, d11 \n\t" //TEMP q12 => deltaImpulse + oldImplues (d25 only) + "vmin.f32 d25, d25, d23 \n\t" //operation MIN(v,b) + "vmax.f32 d22, d25, d24 \n\t" //operation MAX(a,MIN(v,b) + "vst1.32 {d22[0]}, [%0] \n\t" //store m_accumImpulse (incremented so that it can be reloaded for cross product later) + //deltaImpulse = constraint.m_accumImpulse - oldImpulse; + "vsub.f32 d10, d22, d11 \n\t" //operation to calculate new deltaImpule + //FREE q6, q11, q12, q13, q14, q15, d11 + //deltaLinearVelocityB -= deltaImpulse * massInvB * normal; + //deltaLinearVelocityA += deltaImpulse * massInvA * normal; + "vld1.32 {d11[0]}, [%3] \n\t" //LOAD => massInvA ---------------------------> q5 (d11[0] only) + "vld1.32 {d11[1]}, [%8] \n\t" //LOAD => massInvB ---------------------------> q5 (d11[1] only) + "vmul.f32 q11, q4, d11[0] \n\t" //TEMP q11 => operation normal times massInvA A + "vmul.f32 q12, q4, d11[1] \n\t" //TEMP q12 => operation normal times massInvB B + "vmul.f32 q11, q11, d10[0] \n\t" //TEMP q11 => operation result times DeltaImpulse A + "vmul.f32 q12, q12, d10[0] \n\t" //TEMP q12 => operation result times DeltaImpulse B + "vadd.f32 q0, q0, q11 \n\t" //operation create new deltaLinearVelocityA A + "vsub.f32 q2, q2, q12 \n\t" //operation create new deltaLinearVelocityB B + "vst1.32 {q0}, [%1] \n\t" //store the new deltaLinearVelocityA A + "vst1.32 {q2}, [%6] \n\t" //store the new deltaLinearVelocityB B + //FREE q0, q2, q6, q11, q12, q13, q14, q15, d11 + //deltaAngularVelocityA += deltaImpulse * inertiaInvA * cross(rA,normal); + //deltaAngularVelocityB -= deltaImpulse * inertiaInvB * cross(rB,normal); + "vdup.32 q14, d1[1] \n\t" //set normal cross load + "vdup.32 q15, d1[1] \n\t" // + "vadd.f32 q14, q14, q4 \n\t" // + "vadd.f32 q15, q15, q4 \n\t" // + "vrev64.32 d28, d28 \n\t" // + "vtrn.32 d30, d31 \n\t" // + "vtrn.32 d28, d29 \n\t" // + "vrev64.32 d30, d30 \n\t" // + "vmul.f32 q0, q8, q15 \n\t" //operation for cross product A + "vmul.f32 q2, q10, q15 \n\t" //operation for cross product B + "vmls.f32 q0, q14, q7 \n\t" //operation for cross product A + "vmls.f32 q2, q14, q9 \n\t" //operation for cross product B + //LOAD => cross product result A ------------> q0 + //LOAD => cross product result B ------------> q2 + //FREE q6, q7, q8, q9, q10, q11, q12, q13, q14, q15, d11 + + "vld1.32 {q13-q14}, [%4]! \n\t" //LOAD => inertiaInvA col0, col1 A ----------> q13, q14 + "vld1.32 {q9-q10}, [%9]! \n\t" //LOAD => inertiaInvB col0, col1 B -----------> q9, q10 + "vld1.32 {q15}, [%4] \n\t" //LOAD => inertiaInvA col2 A ----------------> q5 + "vld1.32 {q11}, [%9] \n\t" //LOAD => inertiaInvB col2 B -----------------> q11 + "vmul.f32 q13, q13, d0[0] \n\t" //operation inertiaInvA col0 = (col0) * (crossA elem0) A + "vmul.f32 q9, q9, d4[0] \n\t" //operation inertiaInvB col0 = (col0) * (crossB elem0) B + "vmla.f32 q13, q14, d0[1] \n\t" //operation inertiaInvA col1 = (col1) * (crossA elem1) A + "vmla.f32 q9, q10, d4[1] \n\t" //operation inertiaInvB col1 = (col1) * (crossB elem1) B + "vmla.f32 q13, q15, d1[0] \n\t" //operation inertiaInvA col2 = (col2) * (crossA elem2) A + "vmla.f32 q9, q11, d5[0] \n\t" //operation inertiaInvB col2 = (col2) * (crossB elem2) B + "vmul.f32 q13, q13, d10[0] \n\t" //operation inertiaInvA times deltaImpulse A + "vmul.f32 q9, q9, d10[0] \n\t" //operation inertiaInvB times deltaImpulse B + "vadd.f32 q1, q1, q13 \n\t" //operation accumulate the deltaAngularVelocityA A + "vsub.f32 q3, q3, q9 \n\t" //operation accumulate the deltaAngularVelocityB B + "vst1.32 {q1}, [%2] \n\t" //store deltaAngularVelocityA A + "vst1.32 {q3}, [%7] \n\t" //store deltaAngularVelocityB B + : // NO outputs! It is important to *not* put anything here. (Putting something here forces use of r0, which wreak havok + : "r" (constraint), "r" (deltaLinearVelocityA), "r" (deltaAngularVelocityA), "r" (massInvA), "r" (inertiaInvA), "r" (rA), "r" (deltaLinearVelocityB), "r" (deltaAngularVelocityB), "r" (massInvB), "r" (inertiaInvB), "r" (rB) //inputs + : "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" // clobbers + ); +} + +//---------------------------------------------------------------------------- +// TestNeonSolveLinearConstraintRow +// +/// Run timing study of the Linear Constraint Row Solver from above, writing the +/// results to the Android verbose log. +//---------------------------------------------------------------------------- +void TestNeonSolveLinearConstraintRow() +{ + //Scalar + float SET_ALIGNMENT(64) constraintDataScalar[] = {0.0f,1.0f,2.0f,3.0f,1.0f,2.0f,3.0f,4.0f}; + float SET_ALIGNMENT(64) deltaLinearVelocityADataScalar[] = {1.0f,2.0f,3.0f,0.0f}; + float SET_ALIGNMENT(64) deltaAngularVelocityADataScalar[] = {2.0f,3.0f,4.0f,0.0f}; + float SET_ALIGNMENT(64) inertiaInvADataScalar[] = {4.0f,5.0f,6.0f,0.0f,5.0f,6.0f,7.0f,0.0f,6.0f,7.0f,8.0f,0.0f}; + float SET_ALIGNMENT(64) rADataScalar[] = {5.0f,6.0f,7.0f,0.0f}; + float SET_ALIGNMENT(64) deltaLinearVelocityBDataScalar[] = {6.0f,7.0f,8.0f,0.0f}; + float SET_ALIGNMENT(64) deltaAngularVelocityBDataScalar[] = {9.0f,8.0f,7.0f,0.0f}; + float SET_ALIGNMENT(64) inertiaInvBDataScalar[] = {7.0f,6.0f,5.0f,0.0f,9.0f,8.0f,7.0f,0.0f,6.0f,7.0f,8.0f,0.0f}; + float SET_ALIGNMENT(64) rBDataScalar[] = {6.0f,5.0f,4.0f,0.0f}; + + float *constraintScalar = &constraintDataScalar[0]; + float *deltaLinearVelocityAScalar = &deltaLinearVelocityADataScalar[0]; + float *deltaAngularVelocityAScalar = &deltaAngularVelocityADataScalar[0]; + float massInvAScalar = 3.0f; + float *inertiaInvAScalar = &inertiaInvADataScalar[0]; + float *rAScalar = &rADataScalar[0]; + float *deltaLinearVelocityBScalar = &deltaLinearVelocityBDataScalar[0]; + float *deltaAngularVelocityBScalar = &deltaAngularVelocityBDataScalar[0]; + float massInvBScalar = 8.0f; + float *inertiaInvBScalar = &inertiaInvBDataScalar[0]; + float *rBScalar = &rBDataScalar[0]; + + //Neon + float SET_ALIGNMENT(64) constraintDataNeon[] = {0.0f,1.0f,2.0f,3.0f,1.0f,2.0f,3.0f,4.0f}; + float SET_ALIGNMENT(64) deltaLinearVelocityADataNeon[] = {1.0f,2.0f,3.0f,0.0f}; + float SET_ALIGNMENT(64) deltaAngularVelocityADataNeon[] = {2.0f,3.0f,4.0f,0.0f}; + float SET_ALIGNMENT(64) massInvADataNeon[] = {3.0f}; + float SET_ALIGNMENT(64) inertiaInvADataNeon[] = {4.0f,5.0f,6.0f,0.0f,5.0f,6.0f,7.0f,0.0f,6.0f,7.0f,8.0f,0.0f}; + float SET_ALIGNMENT(64) rADataNeon[] = {5.0f,6.0f,7.0f,0.0f}; + float SET_ALIGNMENT(64) deltaLinearVelocityBDataNeon[] = {6.0f,7.0f,8.0f,0.0f}; + float SET_ALIGNMENT(64) deltaAngularVelocityBDataNeon[] = {9.0f,8.0f,7.0f,0.0f}; + float SET_ALIGNMENT(64) massInvBDataNeon[] = {8.0f}; + float SET_ALIGNMENT(64) inertiaInvBDataNeon[] = {7.0f,6.0f,5.0f,0.0f,9.0f,8.0f,7.0f,0.0f,6.0f,7.0f,8.0f,0.0f}; + float SET_ALIGNMENT(64) rBDataNeon[] = {6.0f,5.0f,4.0f,0.0f}; + + float *constraintNeon = &constraintDataNeon[0]; + float *deltaLinearVelocityANeon = &deltaLinearVelocityADataNeon[0]; + float *deltaAngularVelocityANeon = &deltaAngularVelocityADataNeon[0]; + float *massInvANeon = &massInvADataNeon[0]; + float *inertiaInvANeon = &inertiaInvADataNeon[0]; + float *rANeon = &rADataNeon[0]; + float *deltaLinearVelocityBNeon = &deltaLinearVelocityBDataNeon[0]; + float *deltaAngularVelocityBNeon = &deltaAngularVelocityBDataNeon[0]; + float *massInvBNeon = &massInvBDataNeon[0]; + float *inertiaInvBNeon = &inertiaInvBDataNeon[0]; + float *rBNeon = &rBDataNeon[0]; + + char szMsg[256]; + + sprintf(szMsg, ""); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"---------------------------------------"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"TestNeonSolveLinearConstraintRow Start"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + + sce::PhysicsEffects::PfxPerfCounter pc; + double dTimeSpan, dRefTimeSpan;; + unsigned int uiNumTries = 10000000; + unsigned int i; + +// profile pfxSolveLinearConstraintRowScalar with direct memory return, c++ version + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + pfxSolveLinearConstraintRowScalar( + constraintScalar, + deltaLinearVelocityAScalar, + deltaAngularVelocityAScalar, + massInvAScalar, + inertiaInvAScalar, + rAScalar, + deltaLinearVelocityBScalar, + deltaAngularVelocityBScalar, + massInvBScalar, + inertiaInvBScalar, + rBScalar + ); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + dRefTimeSpan = dTimeSpan; + sprintf(szMsg, "Time to do %i calls for pfxSolveLinearConstraintRowScalar: %f secs, speedup: %5.2f", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "constraint.m_accumImpulse = <%f>", constraintScalar[7]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "deltaLinearVelocityA = <%f,%f,%f,%f>", + deltaLinearVelocityAScalar[0], deltaLinearVelocityAScalar[1], deltaLinearVelocityAScalar[2], deltaLinearVelocityAScalar[3]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "deltaAngularVelocityA = <%f,%f,%f,%f>", + deltaAngularVelocityAScalar[0], deltaAngularVelocityAScalar[1], deltaAngularVelocityAScalar[2], deltaAngularVelocityAScalar[3]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "deltaLinearVelocityB = <%f,%f,%f,%f>", + deltaLinearVelocityBScalar[0], deltaLinearVelocityBScalar[1], deltaLinearVelocityBScalar[2], deltaLinearVelocityBScalar[3]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "deltaAngularVelocityB = <%f,%f,%f,%f>", + deltaAngularVelocityBScalar[0], deltaAngularVelocityBScalar[1], deltaAngularVelocityBScalar[2], deltaAngularVelocityBScalar[3]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + +// profile NEON pfxSolveLinearConstraintRowNeonInline with direct memory return, inline assembly version + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + pfxSolveLinearConstraintRowNeonInline(constraintNeon, + deltaLinearVelocityANeon, + deltaAngularVelocityANeon, + massInvANeon, + inertiaInvANeon, + rANeon, + deltaLinearVelocityBNeon, + deltaAngularVelocityBNeon, + massInvBNeon, + inertiaInvBNeon, + rBNeon); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + sprintf(szMsg, "Time to do %i calls for pfxSolveLinearConstraintRowNeon: %f secs, speedup: %5.2f", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "constraint.m_accumImpulse = <%f>", constraintNeon[7]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "deltaLinearVelocityA = <%f,%f,%f,%f>", + deltaLinearVelocityANeon[0], deltaLinearVelocityANeon[1], deltaLinearVelocityANeon[2], deltaLinearVelocityANeon[3]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "deltaAngularVelocityA = <%f,%f,%f,%f>", + deltaAngularVelocityANeon[0], deltaAngularVelocityANeon[1], deltaAngularVelocityANeon[2], deltaAngularVelocityANeon[3]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "deltaLinearVelocityB = <%f,%f,%f,%f>", + deltaLinearVelocityBNeon[0], deltaLinearVelocityBNeon[1], deltaLinearVelocityBNeon[2], deltaLinearVelocityBNeon[3]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "deltaAngularVelocityB = <%f,%f,%f,%f>", + deltaAngularVelocityBNeon[0], deltaAngularVelocityBNeon[1], deltaAngularVelocityBNeon[2], deltaAngularVelocityBNeon[3]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + + sprintf(szMsg,"TestNeonSolveLinearConstraintRow End"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); +} diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_transform3_operator_multiply.cpp b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_transform3_operator_multiply.cpp new file mode 100644 index 000000000..fc3d1785d --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_transform3_operator_multiply.cpp @@ -0,0 +1,150 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "test_neon.h" +#define SCE_PFX_USE_PERFCOUNTER +#include "physics_effects.h" +#include +#include +#include +#include +#include + +// This works with gcc +#define SET_ALIGNMENT(alignment) __attribute__((__aligned__((alignment)))) + +// assembly implementations +extern "C" +{ + void Transform3OperatorMultiplyNeon(float *trfm, float *vec3, float *pfResult); +} + +//---------------------------------------------------------------------------- +// Transform3OperatorMultiplyScalar +// +/// Performs a multiply operation on a tranform3 using scalar math, storing the +/// result directly into system memory. +/// +/// @param trfm Input transform. Must point to 4x 4 float values +/// @param vec3 Input vector3. Must point to 4 float values +/// @param pfResult [in] pointer to a float(vector3). [out] Contains the result +//---------------------------------------------------------------------------- +//inline const Vector3 Transform3::operator *( const Vector3 & vec ) const +//{ +// return Vector3( +// ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), +// ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), +// ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) +// ); +//} +void Transform3OperatorMultiplyScalar(float *trfm, float *vec3, float *pfResult) +{ + pfResult[0] = ( ( ( trfm[0] * vec3[0] ) + ( trfm[4] * vec3[1] ) ) + ( trfm[8] * vec3[2] ) ); + pfResult[1] = ( ( ( trfm[1] * vec3[0] ) + ( trfm[5] * vec3[1] ) ) + ( trfm[9] * vec3[2] ) ); + pfResult[2] = ( ( ( trfm[2] * vec3[0] ) + ( trfm[6] * vec3[1] ) ) + ( trfm[10] * vec3[2] ) ); + pfResult[3] = 0.0f; +} + +//---------------------------------------------------------------------------- +// TestNeonTransform3OperatorMultiply +// +/// Run timing study of the Tranform3 multiply operator from above, writing the +/// results to the Android verbose log. +//---------------------------------------------------------------------------- +void TestNeonTransform3OperatorMultiply() +{ + float SET_ALIGNMENT(64) data1[] = {float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f, + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f, + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f, + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f}; + float SET_ALIGNMENT(64) data2[] = {float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f}; + + float *trfm = &data1[0]; + float *vec3 = &data2[0]; + + + char szMsg[256]; + + sprintf(szMsg, ""); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"---------------------------------------"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"TestNeonTransform3OperatorMultiply Start"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "Test input vec3: <%f,%f,%f,%f>", + vec3[0], vec3[1], vec3[2], vec3[3]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "Test input trfm: <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>>", + trfm[0], trfm[1], trfm[2], trfm[3], + trfm[4], trfm[5], trfm[6], trfm[7], + trfm[8], trfm[9], trfm[10], trfm[11], + trfm[12], trfm[13], trfm[14], trfm[15]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + float SET_ALIGNMENT(64) fResult[4]; + + + sce::PhysicsEffects::PfxPerfCounter pc; + double dTimeSpan, dRefTimeSpan;; + unsigned int uiNumTries = 10000000; + unsigned int i; + +// profile scalar Transform3OperatorMultiplyScalar with direct memory return, c++ version + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + Transform3OperatorMultiplyScalar(trfm, vec3, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + dRefTimeSpan = dTimeSpan; + sprintf(szMsg, "Time to do %i calls for Transform3OperatorMultiplyScalar: %f secs, speedup: %5.2f, result value=<%f,%f,%f,%f>", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan, fResult[0], fResult[1], fResult[2], fResult[3]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + +// profile NEON Transform3OperatorMultiplyNeon with direct memory return, assembly version + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + Transform3OperatorMultiplyNeon(trfm, vec3, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + sprintf(szMsg, "Time to do %i calls for Transform3OperatorMultiplyNeon: %f secs, speedup: %5.2f, result value=<%f,%f,%f,%f>", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan, fResult[0], fResult[1], fResult[2], fResult[3]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + + sprintf(szMsg,"TestNeonTransform3OperatorMultiply End"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); +} diff --git a/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_transpose_matrix3.cpp b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_transpose_matrix3.cpp new file mode 100644 index 000000000..bfadd8336 --- /dev/null +++ b/Extras/PhysicsEffects/sample/test_ARM_NEON_performance/test_neon_transpose_matrix3.cpp @@ -0,0 +1,154 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "test_neon.h" +#define SCE_PFX_USE_PERFCOUNTER +#include "physics_effects.h" +#include +#include +#include +#include +#include + +// This works with gcc +#define SET_ALIGNMENT(alignment) __attribute__((__aligned__((alignment)))) + +// assembly implementations +extern "C" +{ + void TransposeMatrix3Neon(float *mCol, float *pfResult); +} + +//---------------------------------------------------------------------------- +// TransposeMatrix3Scalar +// +/// Performs a transpose on a matrix3 using scalar math, storing the +/// result directly into system memory. +/// +/// @param mCol Input matrix. Must point to 3x 4 float values +/// @param pfResult [in] pointer to a float(matrix3). [out] Contains the result +//---------------------------------------------------------------------------- +//inline const Matrix3 transpose( const Matrix3 & mat ) +//{ +// return Matrix3( +// Vector3( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX() ), +// Vector3( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY() ), +// Vector3( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ() ) +// ); +//} +void TransposeMatrix3Scalar(float *mCol, float *pfResult) +{ + pfResult[0] = mCol[0]; + pfResult[1] = mCol[4]; + pfResult[2] = mCol[8]; + pfResult[3] = 0.0f; + + pfResult[4] = mCol[1]; + pfResult[5] = mCol[5]; + pfResult[6] = mCol[9]; + pfResult[7] = 0.0f; + + pfResult[8] = mCol[2]; + pfResult[9] = mCol[6]; + pfResult[10] = mCol[10]; + pfResult[11] = 0.0f; +} + +//---------------------------------------------------------------------------- +// TestNeonTransposeMatrix3 +// +/// Run timing study of the matrix3 transpose functions above, writing the +/// results to the Android verbose log. +//---------------------------------------------------------------------------- +void TestNeonTransposeMatrix3() +{ + float SET_ALIGNMENT(64) data[] = {float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f, + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f, + float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),float(rand())/float(RAND_MAX),0.0f}; + float *mCol = &data[0]; + + char szMsg[256]; + + sprintf(szMsg, ""); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"---------------------------------------"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg,"TestNeonTransposeMatrix3 Start"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + sprintf(szMsg, "Test input mCol: <%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>", + mCol[0], mCol[1], mCol[2], mCol[3], + mCol[4], mCol[5], mCol[6], mCol[7], + mCol[8], mCol[9], mCol[10], mCol[11]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + float SET_ALIGNMENT(64) fResult[12]; + + + sce::PhysicsEffects::PfxPerfCounter pc; + double dTimeSpan, dRefTimeSpan;; + unsigned int uiNumTries = 10000000; + unsigned int i; + +// profile scalar TransposeMatrix3Scalar with direct memory return, c++ version + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + TransposeMatrix3Scalar(mCol, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + dRefTimeSpan = dTimeSpan; + sprintf(szMsg, "Time to do %i calls for TransposeMatrix3Scalar: %f secs, speedup: %5.2f, result value=<%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan, fResult[0], fResult[1], fResult[2], fResult[3], + fResult[4], fResult[5], fResult[6], fResult[7], + fResult[8], fResult[9], fResult[10], fResult[11]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + +// profile NEON TransposeMatrix3Neon with direct memory return, assembly version + fResult[0] = 0.0f; + pc.countBegin(""); + for(i = 0; i < uiNumTries; i++) + { + TransposeMatrix3Neon(mCol, fResult); + } + pc.countEnd(); + dTimeSpan = pc.getCountTime(0); + pc.resetCount(); + sprintf(szMsg, "Time to do %i calls for TransposeMatrix3Neon: %f secs, speedup: %5.2f, result value=<%f,%f,%f,%f> <%f,%f,%f,%f> <%f,%f,%f,%f>", + uiNumTries, dTimeSpan, dRefTimeSpan/dTimeSpan, fResult[0], fResult[1], fResult[2], fResult[3], + fResult[4], fResult[5], fResult[6], fResult[7], + fResult[8], fResult[9], fResult[10], fResult[11]); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); + + + sprintf(szMsg,"TestNeonTransposeMatrix3 End"); + __android_log_write(ANDROID_LOG_VERBOSE,"PHYSICS TIMING STUDY", szMsg); +} diff --git a/Extras/PhysicsEffects/src/CMakeLists.txt b/Extras/PhysicsEffects/src/CMakeLists.txt new file mode 100644 index 000000000..4f73bd4d9 --- /dev/null +++ b/Extras/PhysicsEffects/src/CMakeLists.txt @@ -0,0 +1,11 @@ +SUBDIRS( + base_level + low_level + util +) + +SUBDIRS( + ../../../src/BulletDynamics + ../../../src/BulletCollision + ../../../src/LinearMath +) \ No newline at end of file diff --git a/Extras/PhysicsEffects/src/base_level/CMakeLists.txt b/Extras/PhysicsEffects/src/base_level/CMakeLists.txt new file mode 100644 index 000000000..433b3ad09 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/CMakeLists.txt @@ -0,0 +1,77 @@ +INCLUDE_DIRECTORIES( ${PHYSICS_EFFECTS_SOURCE_DIR}/include ) + +SET(PfxBaseLevel_SRCS + broadphase/pfx_update_broadphase_proxy.cpp + collision/pfx_collidable.cpp + collision/pfx_contact_box_box.cpp + collision/pfx_contact_box_capsule.cpp + collision/pfx_contact_box_sphere.cpp + collision/pfx_contact_cache.cpp + collision/pfx_contact_capsule_capsule.cpp + collision/pfx_contact_capsule_sphere.cpp + collision/pfx_contact_large_tri_mesh.cpp + collision/pfx_contact_manifold.cpp + collision/pfx_contact_sphere_sphere.cpp + collision/pfx_contact_tri_mesh_box.cpp + collision/pfx_contact_tri_mesh_capsule.cpp + collision/pfx_contact_tri_mesh_convex.cpp + collision/pfx_contact_tri_mesh_cylinder.cpp + collision/pfx_contact_tri_mesh_sphere.cpp + collision/pfx_gjk_solver.cpp + collision/pfx_gjk_support_func.cpp + collision/pfx_intersect_ray_box.cpp + collision/pfx_intersect_ray_capsule.cpp + collision/pfx_intersect_ray_convex.cpp + collision/pfx_intersect_ray_cylinder.cpp + collision/pfx_intersect_ray_large_tri_mesh.cpp + collision/pfx_intersect_ray_sphere.cpp + collision/pfx_shape.cpp + collision/pfx_simplex_solver.cpp + solver/pfx_contact_constraint.cpp + solver/pfx_joint_ball.cpp + solver/pfx_joint_fix.cpp + solver/pfx_joint_hinge.cpp + solver/pfx_joint_slider.cpp + solver/pfx_joint_swing_twist.cpp + solver/pfx_joint_universal.cpp + sort/pfx_sort.cpp + +) + +SET(PfxBaseLevel_HDRS + broadphase/pfx_check_collidable.h + collision/pfx_contact_box_box.h + collision/pfx_contact_box_capsule.h + collision/pfx_contact_box_sphere.h + collision/pfx_contact_cache.h + collision/pfx_contact_capsule_capsule.h + collision/pfx_contact_capsule_sphere.h + collision/pfx_contact_large_tri_mesh.h + collision/pfx_contact_sphere_sphere.h + collision/pfx_contact_tri_mesh_box.h + collision/pfx_contact_tri_mesh_capsule.h + collision/pfx_contact_tri_mesh_convex.h + collision/pfx_contact_tri_mesh_cylinder.h + collision/pfx_contact_tri_mesh_sphere.h + collision/pfx_gjk_solver.h + collision/pfx_gjk_support_func.h + collision/pfx_intersect_common.h + collision/pfx_intersect_ray_box.h + collision/pfx_intersect_ray_capsule.h + collision/pfx_intersect_ray_convex.h + collision/pfx_intersect_ray_cylinder.h + collision/pfx_intersect_ray_large_tri_mesh.h + collision/pfx_intersect_ray_sphere.h + collision/pfx_mesh_common.h + collision/pfx_simplex_solver.h + solver/pfx_check_solver.h + solver/pfx_constraint_row_solver.h +) + + + + +ADD_LIBRARY(PfxBaseLevel ${PfxBaseLevel_SRCS} ${PfxBaseLevel_HDRS}) + +SET_TARGET_PROPERTIES(PfxBaseLevel PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(PfxBaseLevel PROPERTIES SOVERSION ${BULLET_VERSION}) diff --git a/Extras/PhysicsEffects/src/base_level/broadphase/pfx_check_collidable.h b/Extras/PhysicsEffects/src/base_level/broadphase/pfx_check_collidable.h new file mode 100644 index 000000000..9a69bb211 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/broadphase/pfx_check_collidable.h @@ -0,0 +1,80 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CHECK_COLLIDABLE_H +#define _SCE_PFX_CHECK_COLLIDABLE_H + +#include "../../../include/physics_effects/base_level/rigidbody/pfx_rigid_state.h" +#include "../../../include/physics_effects/base_level/collision/pfx_aabb.h" +#include "../../../include/physics_effects/base_level/broadphase/pfx_broadphase_proxy.h" +#include "../../../include/physics_effects/base_level/broadphase/pfx_broadphase_pair.h" + +namespace sce { +namespace PhysicsEffects { + +// Collidable check table +/* + -----------------MotionTypeA + |0 1 0 1 1 + |1 1 1 1 1 + |0 1 0 1 1 + |1 1 1 0 1 + |1 1 1 1 0 +MotionTypeB + */ + +static SCE_PFX_FORCE_INLINE +PfxBool pfxCheckCollidableTable(ePfxMotionType i,ePfxMotionType j) +{ + const PfxUInt32 collidableTable = 0x00bfafbe; + + SCE_PFX_ASSERT(i < kPfxMotionTypeCount); + SCE_PFX_ASSERT(j < kPfxMotionTypeCount); + + PfxUInt32 idx = j * kPfxMotionTypeCount + i; + PfxUInt32 mask = 1 << (kPfxMotionTypeCount*kPfxMotionTypeCount-1-idx); + + return (collidableTable & mask) != 0; +} + +static SCE_PFX_FORCE_INLINE +PfxBool pfxCheckCollidableInBroadphase(const PfxBroadphaseProxy &proxyA, const PfxBroadphaseProxy &proxyB) +{ + ePfxMotionType motionA = (ePfxMotionType)(pfxGetMotionMask(proxyA)&SCE_PFX_MOTION_MASK_TYPE); + ePfxMotionType motionB = (ePfxMotionType)(pfxGetMotionMask(proxyB)&SCE_PFX_MOTION_MASK_TYPE); + + return + pfxCheckCollidableTable(motionA,motionB) && // モーションタイプ別衝突判定テーブル + ((pfxGetSelf(proxyA)&pfxGetTarget(proxyB)) && (pfxGetTarget(proxyA)&pfxGetSelf(proxyB))) && // 衝突フィルター + pfxTestAabb(proxyA,proxyB); // AABB交差判定 +} + +static SCE_PFX_FORCE_INLINE +PfxBool pfxCheckCollidableInCollision(const PfxBroadphasePair &pair) +{ + PfxUInt32 motionA = pfxGetMotionMaskA(pair)&SCE_PFX_MOTION_MASK_TYPE; + PfxUInt32 motionB = pfxGetMotionMaskB(pair)&SCE_PFX_MOTION_MASK_TYPE; + PfxUInt32 sleepA = pfxGetMotionMaskA(pair)&SCE_PFX_MOTION_MASK_SLEEPING; + PfxUInt32 sleepB = pfxGetMotionMaskB(pair)&SCE_PFX_MOTION_MASK_SLEEPING; + + return + pfxCheckCollidableTable((ePfxMotionType)motionA,(ePfxMotionType)motionB) && // モーションタイプ別衝突判定テーブル + !((sleepA != 0 && sleepB != 0) || (sleepA != 0 && motionB == kPfxMotionTypeFixed) || (sleepB != 0 && motionA == kPfxMotionTypeFixed)); // スリープ時のチェック +} +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_CHECK_COLLIDABLE_H diff --git a/Extras/PhysicsEffects/src/base_level/broadphase/pfx_update_broadphase_proxy.cpp b/Extras/PhysicsEffects/src/base_level/broadphase/pfx_update_broadphase_proxy.cpp new file mode 100644 index 000000000..9de1d91ad --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/broadphase/pfx_update_broadphase_proxy.cpp @@ -0,0 +1,234 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_perf_counter.h" +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "../../../include/physics_effects/base_level/collision/pfx_aabb.h" +#include "../../../include/physics_effects/base_level/broadphase/pfx_update_broadphase_proxy.h" + +namespace sce { +namespace PhysicsEffects { + +static SCE_PFX_FORCE_INLINE +PfxBool operator < (const PfxVector3 &v1,const PfxVector3 &v2) +{ + return maxElem(v2-v1) > 0.0f; +} + +PfxInt32 pfxUpdateBroadphaseProxy( + PfxBroadphaseProxy &proxy, + const PfxRigidState &state, + const PfxCollidable &coll, + const PfxVector3 &worldCenter, + const PfxVector3 &worldExtent, + PfxUInt32 axis) +{ + SCE_PFX_ALWAYS_ASSERT(axis<3); + + PfxInt32 ret = SCE_PFX_OK; + + PfxVector3 center = state.getPosition() + coll.getCenter(); + PfxVector3 half = absPerElem(PfxMatrix3(state.getOrientation())) * coll.getHalf(); + + PfxVector3 minRig = center - half; + PfxVector3 maxRig = center + half; + + PfxVector3 minWld = worldCenter - worldExtent; + PfxVector3 maxWld = worldCenter + worldExtent; + + if(maxWld < minRig || maxRig < minWld) { + ret = SCE_PFX_ERR_OUT_OF_WORLD; + } + + PfxVecInt3 aabbMin,aabbMax; + pfxConvertCoordWorldToLocal(worldCenter,worldExtent,minRig,maxRig,aabbMin,aabbMax); + + pfxSetXMin(proxy,aabbMin.getX()); + pfxSetXMax(proxy,aabbMax.getX()); + pfxSetYMin(proxy,aabbMin.getY()); + pfxSetYMax(proxy,aabbMax.getY()); + pfxSetZMin(proxy,aabbMin.getZ()); + pfxSetZMax(proxy,aabbMax.getZ()); + pfxSetKey(proxy,aabbMin.get(axis)); + pfxSetObjectId(proxy,state.getRigidBodyId()); + pfxSetMotionMask(proxy,state.getMotionMask()); + pfxSetSelf(proxy,state.getContactFilterSelf()); + pfxSetTarget(proxy,state.getContactFilterTarget()); + + return ret; +} + +PfxInt32 pfxUpdateBroadphaseProxy( + PfxBroadphaseProxy &proxy, + const PfxRigidState &state, + const PfxVector3 &objectCenter, + const PfxVector3 &objectHalf, + const PfxVector3 &worldCenter, + const PfxVector3 &worldExtent, + PfxUInt32 axis) +{ + SCE_PFX_ALWAYS_ASSERT(axis<3); + + PfxInt32 ret = SCE_PFX_OK; + + PfxVector3 minRig = objectCenter - objectHalf; + PfxVector3 maxRig = objectCenter + objectHalf; + + PfxVector3 minWld = worldCenter - worldExtent; + PfxVector3 maxWld = worldCenter + worldExtent; + + if(maxWld < minRig || maxRig < minWld) { + ret = SCE_PFX_ERR_OUT_OF_WORLD; + } + + PfxVecInt3 aabbMin,aabbMax; + pfxConvertCoordWorldToLocal(worldCenter,worldExtent,minRig,maxRig,aabbMin,aabbMax); + + pfxSetXMin(proxy,aabbMin.getX()); + pfxSetXMax(proxy,aabbMax.getX()); + pfxSetYMin(proxy,aabbMin.getY()); + pfxSetYMax(proxy,aabbMax.getY()); + pfxSetZMin(proxy,aabbMin.getZ()); + pfxSetZMax(proxy,aabbMax.getZ()); + pfxSetKey(proxy,aabbMin.get(axis)); + pfxSetObjectId(proxy,state.getRigidBodyId()); + pfxSetMotionMask(proxy,state.getMotionMask()); + pfxSetSelf(proxy,state.getContactFilterSelf()); + pfxSetTarget(proxy,state.getContactFilterTarget()); + + return ret; +} + +PfxInt32 pfxUpdateBroadphaseProxy( + PfxBroadphaseProxy &proxyX, + PfxBroadphaseProxy &proxyY, + PfxBroadphaseProxy &proxyZ, + PfxBroadphaseProxy &proxyXb, + PfxBroadphaseProxy &proxyYb, + PfxBroadphaseProxy &proxyZb, + const PfxRigidState &state, + const PfxCollidable &coll, + const PfxVector3 &worldCenter, + const PfxVector3 &worldExtent) +{ + PfxInt32 ret = SCE_PFX_OK; + + PfxVector3 center = state.getPosition() + coll.getCenter(); + PfxVector3 half = absPerElem(PfxMatrix3(state.getOrientation())) * coll.getHalf(); + + PfxVector3 minRig = center - half; + PfxVector3 maxRig = center + half; + + PfxVector3 minWld = worldCenter - worldExtent; + PfxVector3 maxWld = worldCenter + worldExtent; + + if(maxWld < minRig || maxRig < minWld) { + ret = SCE_PFX_ERR_OUT_OF_WORLD; + } + + PfxVecInt3 aabbMin,aabbMax; + pfxConvertCoordWorldToLocal(worldCenter,worldExtent,minRig,maxRig,aabbMin,aabbMax); + + PfxBroadphaseProxy proxy; + + pfxSetXMin(proxy,aabbMin.getX()); + pfxSetXMax(proxy,aabbMax.getX()); + pfxSetYMin(proxy,aabbMin.getY()); + pfxSetYMax(proxy,aabbMax.getY()); + pfxSetZMin(proxy,aabbMin.getZ()); + pfxSetZMax(proxy,aabbMax.getZ()); + pfxSetObjectId(proxy,state.getRigidBodyId()); + pfxSetMotionMask(proxy,state.getMotionMask()); + pfxSetSelf(proxy,state.getContactFilterSelf()); + pfxSetTarget(proxy,state.getContactFilterTarget()); + + proxyX = proxy; + proxyXb = proxy; + proxyY = proxy; + proxyYb = proxy; + proxyZ = proxy; + proxyZb = proxy; + + pfxSetKey(proxyX ,aabbMin.getX()); + pfxSetKey(proxyXb,aabbMax.getX()); + pfxSetKey(proxyY ,aabbMin.getY()); + pfxSetKey(proxyYb,aabbMax.getY()); + pfxSetKey(proxyZ ,aabbMin.getZ()); + pfxSetKey(proxyZb,aabbMax.getZ()); + + return ret; +} + +PfxInt32 pfxUpdateBroadphaseProxy( + PfxBroadphaseProxy &proxyX, + PfxBroadphaseProxy &proxyY, + PfxBroadphaseProxy &proxyZ, + PfxBroadphaseProxy &proxyXb, + PfxBroadphaseProxy &proxyYb, + PfxBroadphaseProxy &proxyZb, + const PfxRigidState &state, + const PfxVector3 &objectCenter, + const PfxVector3 &objectHalf, + const PfxVector3 &worldCenter, + const PfxVector3 &worldExtent) +{ + PfxInt32 ret = SCE_PFX_OK; + + PfxVector3 minRig = objectCenter - objectHalf; + PfxVector3 maxRig = objectCenter + objectHalf; + + PfxVector3 minWld = worldCenter - worldExtent; + PfxVector3 maxWld = worldCenter + worldExtent; + + if(maxWld < minRig || maxRig < minWld) { + ret = SCE_PFX_ERR_OUT_OF_WORLD; + } + + PfxVecInt3 aabbMin,aabbMax; + pfxConvertCoordWorldToLocal(worldCenter,worldExtent,minRig,maxRig,aabbMin,aabbMax); + + PfxBroadphaseProxy proxy; + + pfxSetXMin(proxy,aabbMin.getX()); + pfxSetXMax(proxy,aabbMax.getX()); + pfxSetYMin(proxy,aabbMin.getY()); + pfxSetYMax(proxy,aabbMax.getY()); + pfxSetZMin(proxy,aabbMin.getZ()); + pfxSetZMax(proxy,aabbMax.getZ()); + pfxSetObjectId(proxy,state.getRigidBodyId()); + pfxSetMotionMask(proxy,state.getMotionMask()); + pfxSetSelf(proxy,state.getContactFilterSelf()); + pfxSetTarget(proxy,state.getContactFilterTarget()); + + proxyX = proxy; + proxyXb = proxy; + proxyY = proxy; + proxyYb = proxy; + proxyZ = proxy; + proxyZb = proxy; + + pfxSetKey(proxyX ,aabbMin.getX()); + pfxSetKey(proxyXb,aabbMax.getX()); + pfxSetKey(proxyY ,aabbMin.getY()); + pfxSetKey(proxyYb,aabbMax.getY()); + pfxSetKey(proxyZ ,aabbMin.getZ()); + pfxSetKey(proxyZb,aabbMax.getZ()); + + return ret; +} + +} // namespace PhysicsEffects +} // namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_collidable.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_collidable.cpp new file mode 100644 index 000000000..9a8f596f5 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_collidable.cpp @@ -0,0 +1,56 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/collision/pfx_collidable.h" + +namespace sce { +namespace PhysicsEffects { + +void PfxCollidable::addShape(const PfxShape &shape) +{ + if(m_numShapes distanceThreshold ) return gap; \ + axisType = A_AXIS; \ + faceDimA = dim; \ + axisA = ident[dim]; \ + } \ + else \ + { \ + gap = gapsA.get##letter(); \ + if ( gap > distanceThreshold ) return gap; \ + else if ( gap > maxGap ) \ + { \ + maxGap = gap; \ + axisType = A_AXIS; \ + faceDimA = dim; \ + axisA = ident[dim]; \ + } \ + } \ +} + + +#define BaxisTest( dim, letter ) \ +{ \ + gap = gapsB.get##letter(); \ + if ( gap > distanceThreshold ) return gap; \ + else if ( gap > maxGap ) \ + { \ + maxGap = gap; \ + axisType = B_AXIS; \ + faceDimB = dim; \ + axisB = ident[dim]; \ + } \ +} + +#define CrossAxisTest( dima, dimb, letterb ) \ +{ \ + const PfxFloat lsqr_tolerance = 1.0e-30f; \ + PfxFloat lsqr; \ + \ + lsqr = lsqrs.getCol##dima().get##letterb(); \ + \ + if ( lsqr > lsqr_tolerance ) \ + { \ + PfxFloat l_recip = 1.0f / sqrtf( lsqr ); \ + gap = PfxFloat(gapsAxB.getCol##dima().get##letterb()) * l_recip; \ + \ + if ( gap > distanceThreshold ) \ + { \ + return gap; \ + } \ + \ + if ( gap > maxGap ) \ + { \ + maxGap = gap; \ + axisType = CROSS_AXIS; \ + edgeDimA = dima; \ + edgeDimB = dimb; \ + axisA = cross(ident[dima],matrixAB.getCol##dimb()) * l_recip; \ + } \ + } \ +} + +//------------------------------------------------------------------------------------------------- +// tests whether a vertex of box B and a face of box A are the closest features +//------------------------------------------------------------------------------------------------- + +inline +PfxFloat +VertexBFaceATest( + PfxBool & inVoronoi, + PfxFloat & t0, + PfxFloat & t1, + const PfxVector3 & hA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetBA, + const PfxMatrix3 & matrixAB, + const PfxMatrix3 & matrixBA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesB ) +{ + // compute a corner of box B in A's coordinate system + + PfxVector3 corner = + PfxVector3( faceOffsetAB + matrixAB.getCol0() * scalesB.getX() + matrixAB.getCol1() * scalesB.getY() ); + + // compute the parameters of the point on A, closest to this corner + + t0 = corner[0]; + t1 = corner[1]; + + if ( t0 > hA[0] ) + t0 = hA[0]; + else if ( t0 < -hA[0] ) + t0 = -hA[0]; + if ( t1 > hA[1] ) + t1 = hA[1]; + else if ( t1 < -hA[1] ) + t1 = -hA[1]; + + // do the Voronoi test: already know the point on B is in the Voronoi region of the + // point on A, check the reverse. + + PfxVector3 facePointB = + PfxVector3( mulPerElem( faceOffsetBA + matrixBA.getCol0() * t0 + matrixBA.getCol1() * t1 - scalesB, signsB ) ); + + inVoronoi = ( ( facePointB[0] >= voronoiTol * facePointB[2] ) && + ( facePointB[1] >= voronoiTol * facePointB[0] ) && + ( facePointB[2] >= voronoiTol * facePointB[1] ) ); + + return (SCE_PFX_SQR( corner[0] - t0 ) + SCE_PFX_SQR( corner[1] - t1 ) + SCE_PFX_SQR( corner[2] )); +} + +#define VertexBFaceA_SetNewMin() \ +{ \ + minDistSqr = distSqr; \ + localPointA.setX(t0); \ + localPointA.setY(t1); \ + localPointB.setX( scalesB.getX() ); \ + localPointB.setY( scalesB.getY() ); \ +} + +void +VertexBFaceATests( + PfxBool & done, + PfxFloat & minDistSqr, + PfxPoint3 & localPointA, + PfxPoint3 & localPointB, + const PfxVector3 & hA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetBA, + const PfxMatrix3 & matrixAB, + const PfxMatrix3 & matrixBA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesB, + PfxBool first ) +{ + PfxFloat t0, t1; + PfxFloat distSqr; + + distSqr = VertexBFaceATest( done, t0, t1, hA, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsB, scalesB ); + + if ( first ) { + VertexBFaceA_SetNewMin(); + } else { + if ( distSqr < minDistSqr ) { + VertexBFaceA_SetNewMin(); + } + } + + if ( done ) + return; + + signsB.setX( -signsB.getX() ); + scalesB.setX( -scalesB.getX() ); + + distSqr = VertexBFaceATest( done, t0, t1, hA, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsB, scalesB ); + + if ( distSqr < minDistSqr ) { + VertexBFaceA_SetNewMin(); + } + + if ( done ) + return; + + signsB.setY( -signsB.getY() ); + scalesB.setY( -scalesB.getY() ); + + distSqr = VertexBFaceATest( done, t0, t1, hA, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsB, scalesB ); + + if ( distSqr < minDistSqr ) { + VertexBFaceA_SetNewMin(); + } + + if ( done ) + return; + + signsB.setX( -signsB.getX() ); + scalesB.setX( -scalesB.getX() ); + + distSqr = VertexBFaceATest( done, t0, t1, hA, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsB, scalesB ); + + if ( distSqr < minDistSqr ) { + VertexBFaceA_SetNewMin(); + } +} + +//------------------------------------------------------------------------------------------------- +// VertexAFaceBTest: tests whether a vertex of box A and a face of box B are the closest features +//------------------------------------------------------------------------------------------------- + +inline +PfxFloat +VertexAFaceBTest( + PfxBool & inVoronoi, + PfxFloat & t0, + PfxFloat & t1, + const PfxVector3 & hB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetBA, + const PfxMatrix3 & matrixAB, + const PfxMatrix3 & matrixBA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesA ) +{ + PfxVector3 corner = + PfxVector3( faceOffsetBA + matrixBA.getCol0() * scalesA.getX() + matrixBA.getCol1() * scalesA.getY() ); + + t0 = corner[0]; + t1 = corner[1]; + + if ( t0 > hB[0] ) + t0 = hB[0]; + else if ( t0 < -hB[0] ) + t0 = -hB[0]; + if ( t1 > hB[1] ) + t1 = hB[1]; + else if ( t1 < -hB[1] ) + t1 = -hB[1]; + + PfxVector3 facePointA = + PfxVector3( mulPerElem( faceOffsetAB + matrixAB.getCol0() * t0 + matrixAB.getCol1() * t1 - scalesA, signsA ) ); + + inVoronoi = ( ( facePointA[0] >= voronoiTol * facePointA[2] ) && + ( facePointA[1] >= voronoiTol * facePointA[0] ) && + ( facePointA[2] >= voronoiTol * facePointA[1] ) ); + + return (SCE_PFX_SQR( corner[0] - t0 ) + SCE_PFX_SQR( corner[1] - t1 ) + SCE_PFX_SQR( corner[2] )); +} + +#define VertexAFaceB_SetNewMin() \ +{ \ + minDistSqr = distSqr; \ + localPointB.setX(t0); \ + localPointB.setY(t1); \ + localPointA.setX( scalesA.getX() ); \ + localPointA.setY( scalesA.getY() ); \ +} + +void +VertexAFaceBTests( + PfxBool & done, + PfxFloat & minDistSqr, + PfxPoint3 & localPointA, + PfxPoint3 & localPointB, + const PfxVector3 & hB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetBA, + const PfxMatrix3 & matrixAB, + const PfxMatrix3 & matrixBA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesA, + PfxBool first ) +{ + PfxFloat t0, t1; + PfxFloat distSqr; + + distSqr = VertexAFaceBTest( done, t0, t1, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, scalesA ); + + if ( first ) { + VertexAFaceB_SetNewMin(); + } else { + if ( distSqr < minDistSqr ) { + VertexAFaceB_SetNewMin(); + } + } + + if ( done ) + return; + + signsA.setX( -signsA.getX() ); + scalesA.setX( -scalesA.getX() ); + + distSqr = VertexAFaceBTest( done, t0, t1, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, scalesA ); + + if ( distSqr < minDistSqr ) { + VertexAFaceB_SetNewMin(); + } + + if ( done ) + return; + + signsA.setY( -signsA.getY() ); + scalesA.setY( -scalesA.getY() ); + + distSqr = VertexAFaceBTest( done, t0, t1, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, scalesA ); + + if ( distSqr < minDistSqr ) { + VertexAFaceB_SetNewMin(); + } + + if ( done ) + return; + + signsA.setX( -signsA.getX() ); + scalesA.setX( -scalesA.getX() ); + + distSqr = VertexAFaceBTest( done, t0, t1, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, scalesA ); + + if ( distSqr < minDistSqr ) { + VertexAFaceB_SetNewMin(); + } +} + +//------------------------------------------------------------------------------------------------- +// EdgeEdgeTest: +// +// tests whether a pair of edges are the closest features +// +// note on the shorthand: +// 'a' & 'b' refer to the edges. +// 'c' is the dimension of the axis that points from the face center to the edge Center +// 'd' is the dimension of the edge Direction +// the dimension of the face normal is 2 +//------------------------------------------------------------------------------------------------- + +#define EdgeEdgeTest( ac, ac_letter, ad, ad_letter, bc, bc_letter, bd, bd_letter ) \ +{ \ + PfxVector3 edgeOffsetAB; \ + PfxVector3 edgeOffsetBA; \ + \ + edgeOffsetAB = faceOffsetAB + matrixAB.getCol##bc() * scalesB.get##bc_letter(); \ + edgeOffsetAB.set##ac_letter( edgeOffsetAB.get##ac_letter() - scalesA.get##ac_letter() ); \ + \ + edgeOffsetBA = faceOffsetBA + matrixBA.getCol##ac() * scalesA.get##ac_letter(); \ + edgeOffsetBA.set##bc_letter( edgeOffsetBA.get##bc_letter() - scalesB.get##bc_letter() ); \ + \ + PfxFloat dirDot = matrixAB.getCol##bd().get##ad_letter(); \ + PfxFloat denom = 1.0f - dirDot*dirDot; \ + PfxFloat edgeOffsetAB_ad = edgeOffsetAB.get##ad_letter(); \ + PfxFloat edgeOffsetBA_bd = edgeOffsetBA.get##bd_letter(); \ + \ + if ( denom == 0.0f ) \ + { \ + tA = 0.0f; \ + } \ + else \ + { \ + tA = ( edgeOffsetAB_ad + edgeOffsetBA_bd * dirDot ) / denom; \ + } \ + \ + if ( tA < -hA[ad] ) tA = -hA[ad]; \ + else if ( tA > hA[ad] ) tA = hA[ad]; \ + \ + tB = tA * dirDot + edgeOffsetBA_bd; \ + \ + if ( tB < -hB[bd] ) \ + { \ + tB = -hB[bd]; \ + tA = tB * dirDot + edgeOffsetAB_ad; \ + \ + if ( tA < -hA[ad] ) tA = -hA[ad]; \ + else if ( tA > hA[ad] ) tA = hA[ad]; \ + } \ + else if ( tB > hB[bd] ) \ + { \ + tB = hB[bd]; \ + tA = tB * dirDot + edgeOffsetAB_ad; \ + \ + if ( tA < -hA[ad] ) tA = -hA[ad]; \ + else if ( tA > hA[ad] ) tA = hA[ad]; \ + } \ + \ + PfxVector3 edgeOffAB = PfxVector3( mulPerElem( edgeOffsetAB + matrixAB.getCol##bd() * tB, signsA ) );\ + PfxVector3 edgeOffBA = PfxVector3( mulPerElem( edgeOffsetBA + matrixBA.getCol##ad() * tA, signsB ) );\ + \ + inVoronoi = ( edgeOffAB[ac] >= voronoiTol * edgeOffAB[2] ) && \ + ( edgeOffAB[2] >= voronoiTol * edgeOffAB[ac] ) && \ + ( edgeOffBA[bc] >= voronoiTol * edgeOffBA[2] ) && \ + ( edgeOffBA[2] >= voronoiTol * edgeOffBA[bc] ); \ + \ + edgeOffAB[ad] -= tA; \ + edgeOffBA[bd] -= tB; \ + \ + return dot(edgeOffAB,edgeOffAB); \ +} + +PfxFloat +EdgeEdgeTest_0101( + PfxBool & inVoronoi, + PfxFloat & tA, + PfxFloat & tB, + const PfxVector3 & hA, + const PfxVector3 & hB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetBA, + const PfxMatrix3 & matrixAB, + const PfxMatrix3 & matrixBA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesB ) +{ + EdgeEdgeTest( 0, X, 1, Y, 0, X, 1, Y ); +} + +PfxFloat +EdgeEdgeTest_0110( + PfxBool & inVoronoi, + PfxFloat & tA, + PfxFloat & tB, + const PfxVector3 & hA, + const PfxVector3 & hB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetBA, + const PfxMatrix3 & matrixAB, + const PfxMatrix3 & matrixBA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesB ) +{ + EdgeEdgeTest( 0, X, 1, Y, 1, Y, 0, X ); +} + +PfxFloat +EdgeEdgeTest_1001( + PfxBool & inVoronoi, + PfxFloat & tA, + PfxFloat & tB, + const PfxVector3 & hA, + const PfxVector3 & hB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetBA, + const PfxMatrix3 & matrixAB, + const PfxMatrix3 & matrixBA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesB ) +{ + EdgeEdgeTest( 1, Y, 0, X, 0, X, 1, Y ); +} + +PfxFloat +EdgeEdgeTest_1010( + PfxBool & inVoronoi, + PfxFloat & tA, + PfxFloat & tB, + const PfxVector3 & hA, + const PfxVector3 & hB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetBA, + const PfxMatrix3 & matrixAB, + const PfxMatrix3 & matrixBA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesB ) +{ + EdgeEdgeTest( 1, Y, 0, X, 1, Y, 0, X ); +} + +#define EdgeEdge_SetNewMin( ac_letter, ad_letter, bc_letter, bd_letter ) \ +{ \ + minDistSqr = distSqr; \ + localPointA.set##ac_letter(scalesA.get##ac_letter()); \ + localPointA.set##ad_letter(tA); \ + localPointB.set##bc_letter(scalesB.get##bc_letter()); \ + localPointB.set##bd_letter(tB); \ + otherFaceDimA = testOtherFaceDimA; \ + otherFaceDimB = testOtherFaceDimB; \ +} + +void +EdgeEdgeTests( + PfxBool & done, + PfxFloat & minDistSqr, + PfxPoint3 & localPointA, + PfxPoint3 & localPointB, + int & otherFaceDimA, + int & otherFaceDimB, + const PfxVector3 & hA, + const PfxVector3 & hB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG faceOffsetBA, + const PfxMatrix3 & matrixAB, + const PfxMatrix3 & matrixBA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesB, + PfxBool first ) +{ + PfxFloat distSqr; + PfxFloat tA, tB; + + int testOtherFaceDimA, testOtherFaceDimB; + + testOtherFaceDimA = 0; + testOtherFaceDimB = 0; + + distSqr = EdgeEdgeTest_0101( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( first ) { + EdgeEdge_SetNewMin( X, Y, X, Y ); + } else { + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, X, Y ); + } + } + + if ( done ) + return; + + signsA.setX( -signsA.getX() ); + scalesA.setX( -scalesA.getX() ); + + distSqr = EdgeEdgeTest_0101( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, X, Y ); + } + + if ( done ) + return; + + signsB.setX( -signsB.getX() ); + scalesB.setX( -scalesB.getX() ); + + distSqr = EdgeEdgeTest_0101( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, X, Y ); + } + + if ( done ) + return; + + signsA.setX( -signsA.getX() ); + scalesA.setX( -scalesA.getX() ); + + distSqr = EdgeEdgeTest_0101( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, X, Y ); + } + + if ( done ) + return; + + testOtherFaceDimA = 1; + testOtherFaceDimB = 0; + signsB.setX( -signsB.getX() ); + scalesB.setX( -scalesB.getX() ); + + distSqr = EdgeEdgeTest_1001( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, X, Y ); + } + + if ( done ) + return; + + signsA.setY( -signsA.getY() ); + scalesA.setY( -scalesA.getY() ); + + distSqr = EdgeEdgeTest_1001( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, X, Y ); + } + + if ( done ) + return; + + signsB.setX( -signsB.getX() ); + scalesB.setX( -scalesB.getX() ); + + distSqr = EdgeEdgeTest_1001( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, X, Y ); + } + + if ( done ) + return; + + signsA.setY( -signsA.getY() ); + scalesA.setY( -scalesA.getY() ); + + distSqr = EdgeEdgeTest_1001( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, X, Y ); + } + + if ( done ) + return; + + testOtherFaceDimA = 0; + testOtherFaceDimB = 1; + signsB.setX( -signsB.getX() ); + scalesB.setX( -scalesB.getX() ); + + distSqr = EdgeEdgeTest_0110( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, Y, X ); + } + + if ( done ) + return; + + signsA.setX( -signsA.getX() ); + scalesA.setX( -scalesA.getX() ); + + distSqr = EdgeEdgeTest_0110( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, Y, X ); + } + + if ( done ) + return; + + signsB.setY( -signsB.getY() ); + scalesB.setY( -scalesB.getY() ); + + distSqr = EdgeEdgeTest_0110( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, Y, X ); + } + + if ( done ) + return; + + signsA.setX( -signsA.getX() ); + scalesA.setX( -scalesA.getX() ); + + distSqr = EdgeEdgeTest_0110( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, Y, X ); + } + + if ( done ) + return; + + testOtherFaceDimA = 1; + testOtherFaceDimB = 1; + signsB.setY( -signsB.getY() ); + scalesB.setY( -scalesB.getY() ); + + distSqr = EdgeEdgeTest_1010( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, Y, X ); + } + + if ( done ) + return; + + signsA.setY( -signsA.getY() ); + scalesA.setY( -scalesA.getY() ); + + distSqr = EdgeEdgeTest_1010( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, Y, X ); + } + + if ( done ) + return; + + signsB.setY( -signsB.getY() ); + scalesB.setY( -scalesB.getY() ); + + distSqr = EdgeEdgeTest_1010( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, Y, X ); + } + + if ( done ) + return; + + signsA.setY( -signsA.getY() ); + scalesA.setY( -scalesA.getY() ); + + distSqr = EdgeEdgeTest_1010( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, Y, X ); + } +} + +PfxFloat pfxContactBoxBox( + PfxVector3 &normal,PfxPoint3 &pointA,PfxPoint3 &pointB, + void *shapeA,const PfxTransform3 &transformA, + void *shapeB,const PfxTransform3 &transformB, + PfxFloat distanceThreshold) +{ + PfxBox &boxA = *((PfxBox*)shapeA); + PfxBox &boxB = *((PfxBox*)shapeB); + + PfxVector3 ident[3] = { + PfxVector3(1.0,0.0,0.0), + PfxVector3(0.0,1.0,0.0), + PfxVector3(0.0,0.0,1.0), + }; + + // get relative transformations + + PfxTransform3 transformAB, transformBA; + PfxMatrix3 matrixAB, matrixBA; + PfxVector3 offsetAB, offsetBA; + + transformAB = orthoInverse(transformA) * transformB; + transformBA = orthoInverse(transformAB); + + matrixAB = transformAB.getUpper3x3(); + offsetAB = transformAB.getTranslation(); + matrixBA = transformBA.getUpper3x3(); + offsetBA = transformBA.getTranslation(); + + PfxMatrix3 absMatrixAB = absPerElem(matrixAB); + PfxMatrix3 absMatrixBA = absPerElem(matrixBA); + + // find separating axis with largest gap between projections + + BoxSepAxisType axisType; + PfxVector3 axisA(0.0f), axisB(0.0f); + PfxFloat gap, maxGap; + int faceDimA = 0, faceDimB = 0, edgeDimA = 0, edgeDimB = 0; + + // face axes + + PfxVector3 gapsA = absPerElem(offsetAB) - boxA.m_half - absMatrixAB * boxB.m_half; + + AaxisTest(0,X,true); + AaxisTest(1,Y,false); + AaxisTest(2,Z,false); + + PfxVector3 gapsB = absPerElem(offsetBA) - boxB.m_half - absMatrixBA * boxA.m_half; + + BaxisTest(0,X); + BaxisTest(1,Y); + BaxisTest(2,Z); + + // cross product axes + + // 外積が0のときの対策 + absMatrixAB += PfxMatrix3(1.0e-5f); + absMatrixBA += PfxMatrix3(1.0e-5f); + + PfxMatrix3 lsqrs, projOffset, projAhalf, projBhalf; + + lsqrs.setCol0( mulPerElem( matrixBA.getCol2(), matrixBA.getCol2() ) + + mulPerElem( matrixBA.getCol1(), matrixBA.getCol1() ) ); + lsqrs.setCol1( mulPerElem( matrixBA.getCol2(), matrixBA.getCol2() ) + + mulPerElem( matrixBA.getCol0(), matrixBA.getCol0() ) ); + lsqrs.setCol2( mulPerElem( matrixBA.getCol1(), matrixBA.getCol1() ) + + mulPerElem( matrixBA.getCol0(), matrixBA.getCol0() ) ); + + projOffset.setCol0(matrixBA.getCol1() * offsetAB.getZ() - matrixBA.getCol2() * offsetAB.getY()); + projOffset.setCol1(matrixBA.getCol2() * offsetAB.getX() - matrixBA.getCol0() * offsetAB.getZ()); + projOffset.setCol2(matrixBA.getCol0() * offsetAB.getY() - matrixBA.getCol1() * offsetAB.getX()); + + projAhalf.setCol0(absMatrixBA.getCol1() * boxA.m_half.getZ() + absMatrixBA.getCol2() * boxA.m_half.getY()); + projAhalf.setCol1(absMatrixBA.getCol2() * boxA.m_half.getX() + absMatrixBA.getCol0() * boxA.m_half.getZ()); + projAhalf.setCol2(absMatrixBA.getCol0() * boxA.m_half.getY() + absMatrixBA.getCol1() * boxA.m_half.getX()); + + projBhalf.setCol0(absMatrixAB.getCol1() * boxB.m_half.getZ() + absMatrixAB.getCol2() * boxB.m_half.getY()); + projBhalf.setCol1(absMatrixAB.getCol2() * boxB.m_half.getX() + absMatrixAB.getCol0() * boxB.m_half.getZ()); + projBhalf.setCol2(absMatrixAB.getCol0() * boxB.m_half.getY() + absMatrixAB.getCol1() * boxB.m_half.getX()); + + PfxMatrix3 gapsAxB = absPerElem(projOffset) - projAhalf - transpose(projBhalf); + + CrossAxisTest(0,0,X); + CrossAxisTest(0,1,Y); + CrossAxisTest(0,2,Z); + CrossAxisTest(1,0,X); + CrossAxisTest(1,1,Y); + CrossAxisTest(1,2,Z); + CrossAxisTest(2,0,X); + CrossAxisTest(2,1,Y); + CrossAxisTest(2,2,Z); + + // need to pick the face on each box whose normal best matches the separating axis. + // will transform vectors to be in the coordinate system of this face to simplify things later. + // for this, a permutation matrix can be used, which the next section computes. + + int dimA[3], dimB[3]; + + if ( axisType == A_AXIS ) { + if ( dot(axisA,offsetAB) < 0.0f ) + axisA = -axisA; + axisB = matrixBA * -axisA; + + PfxVector3 absAxisB = PfxVector3(absPerElem(axisB)); + + if ( ( absAxisB[0] > absAxisB[1] ) && ( absAxisB[0] > absAxisB[2] ) ) + faceDimB = 0; + else if ( absAxisB[1] > absAxisB[2] ) + faceDimB = 1; + else + faceDimB = 2; + } else if ( axisType == B_AXIS ) { + if ( dot(axisB,offsetBA) < 0.0f ) + axisB = -axisB; + axisA = matrixAB * -axisB; + + PfxVector3 absAxisA = PfxVector3(absPerElem(axisA)); + + if ( ( absAxisA[0] > absAxisA[1] ) && ( absAxisA[0] > absAxisA[2] ) ) + faceDimA = 0; + else if ( absAxisA[1] > absAxisA[2] ) + faceDimA = 1; + else + faceDimA = 2; + } + + if ( axisType == CROSS_AXIS ) { + if ( dot(axisA,offsetAB) < 0.0f ) + axisA = -axisA; + axisB = matrixBA * -axisA; + + PfxVector3 absAxisA = PfxVector3(absPerElem(axisA)); + PfxVector3 absAxisB = PfxVector3(absPerElem(axisB)); + + dimA[1] = edgeDimA; + dimB[1] = edgeDimB; + + if ( edgeDimA == 0 ) { + if ( absAxisA[1] > absAxisA[2] ) { + dimA[0] = 2; + dimA[2] = 1; + } else { + dimA[0] = 1; + dimA[2] = 2; + } + } else if ( edgeDimA == 1 ) { + if ( absAxisA[2] > absAxisA[0] ) { + dimA[0] = 0; + dimA[2] = 2; + } else { + dimA[0] = 2; + dimA[2] = 0; + } + } else { + if ( absAxisA[0] > absAxisA[1] ) { + dimA[0] = 1; + dimA[2] = 0; + } else { + dimA[0] = 0; + dimA[2] = 1; + } + } + + if ( edgeDimB == 0 ) { + if ( absAxisB[1] > absAxisB[2] ) { + dimB[0] = 2; + dimB[2] = 1; + } else { + dimB[0] = 1; + dimB[2] = 2; + } + } else if ( edgeDimB == 1 ) { + if ( absAxisB[2] > absAxisB[0] ) { + dimB[0] = 0; + dimB[2] = 2; + } else { + dimB[0] = 2; + dimB[2] = 0; + } + } else { + if ( absAxisB[0] > absAxisB[1] ) { + dimB[0] = 1; + dimB[2] = 0; + } else { + dimB[0] = 0; + dimB[2] = 1; + } + } + } else { + dimA[2] = faceDimA; + dimA[0] = (faceDimA+1)%3; + dimA[1] = (faceDimA+2)%3; + dimB[2] = faceDimB; + dimB[0] = (faceDimB+1)%3; + dimB[1] = (faceDimB+2)%3; + } + + PfxMatrix3 aperm_col, bperm_col; + + aperm_col.setCol0(ident[dimA[0]]); + aperm_col.setCol1(ident[dimA[1]]); + aperm_col.setCol2(ident[dimA[2]]); + + bperm_col.setCol0(ident[dimB[0]]); + bperm_col.setCol1(ident[dimB[1]]); + bperm_col.setCol2(ident[dimB[2]]); + + PfxMatrix3 aperm_row, bperm_row; + + aperm_row = transpose(aperm_col); + bperm_row = transpose(bperm_col); + + // permute all box parameters to be in the face coordinate systems + + PfxMatrix3 matrixAB_perm = aperm_row * matrixAB * bperm_col; + PfxMatrix3 matrixBA_perm = transpose(matrixAB_perm); + + PfxVector3 offsetAB_perm, offsetBA_perm; + + offsetAB_perm = aperm_row * offsetAB; + offsetBA_perm = bperm_row * offsetBA; + + PfxVector3 halfA_perm, halfB_perm; + + halfA_perm = aperm_row * boxA.m_half; + halfB_perm = bperm_row * boxB.m_half; + + // compute the vector between the centers of each face, in each face's coordinate frame + + PfxVector3 signsA_perm, signsB_perm, scalesA_perm, scalesB_perm, faceOffsetAB_perm, faceOffsetBA_perm; + + signsA_perm = copySignPerElem(PfxVector3(1.0f),aperm_row * axisA); + signsB_perm = copySignPerElem(PfxVector3(1.0f),bperm_row * axisB); + scalesA_perm = mulPerElem( signsA_perm, halfA_perm ); + scalesB_perm = mulPerElem( signsB_perm, halfB_perm ); + + faceOffsetAB_perm = offsetAB_perm + matrixAB_perm.getCol2() * scalesB_perm.getZ(); + faceOffsetAB_perm.setZ( faceOffsetAB_perm.getZ() - scalesA_perm.getZ() ); + + faceOffsetBA_perm = offsetBA_perm + matrixBA_perm.getCol2() * scalesA_perm.getZ(); + faceOffsetBA_perm.setZ( faceOffsetBA_perm.getZ() - scalesB_perm.getZ() ); + + if ( maxGap < 0.0f ) { + // if boxes overlap, this will separate the faces for finding points of penetration. + + faceOffsetAB_perm -= aperm_row * axisA * maxGap * 1.01f; + faceOffsetBA_perm -= bperm_row * axisB * maxGap * 1.01f; + } + + // for each vertex/face or edge/edge pair of the two faces, find the closest points. + // + // these points each have an associated box feature (vertex, edge, or face). if each + // point is in the external Voronoi region of the other's feature, they are the + // closest points of the boxes, and the algorithm can exit. + // + // the feature pairs are arranged so that in the general case, the first test will + // succeed. degenerate cases (parallel faces) may require up to all tests in the + // worst case. + // + // if for some reason no case passes the Voronoi test, the features with the minimum + // distance are returned. + + PfxPoint3 localPointA_perm, localPointB_perm; + PfxFloat minDistSqr; + PfxBool done; + + PfxVector3 hA_perm( halfA_perm ), hB_perm( halfB_perm ); + + localPointA_perm.setZ( scalesA_perm.getZ() ); + localPointB_perm.setZ( scalesB_perm.getZ() ); + scalesA_perm.setZ(0.0f); + scalesB_perm.setZ(0.0f); + + int otherFaceDimA, otherFaceDimB; + + if ( axisType == CROSS_AXIS ) { + EdgeEdgeTests( done, minDistSqr, localPointA_perm, localPointB_perm, + otherFaceDimA, otherFaceDimB, + hA_perm, hB_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsA_perm, signsB_perm, + scalesA_perm, scalesB_perm, true ); + + if ( !done ) { + VertexBFaceATests( done, minDistSqr, localPointA_perm, localPointB_perm, + hA_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsB_perm, scalesB_perm, false ); + + if ( !done ) { + VertexAFaceBTests( done, minDistSqr, localPointA_perm, localPointB_perm, + hB_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsA_perm, scalesA_perm, false ); + } + } + } else if ( axisType == B_AXIS ) { + VertexAFaceBTests( done, minDistSqr, localPointA_perm, localPointB_perm, + hB_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsA_perm, scalesA_perm, true ); + + if ( !done ) { + VertexBFaceATests( done, minDistSqr, localPointA_perm, localPointB_perm, + hA_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsB_perm, scalesB_perm, false ); + + if ( !done ) { + EdgeEdgeTests( done, minDistSqr, localPointA_perm, localPointB_perm, + otherFaceDimA, otherFaceDimB, + hA_perm, hB_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsA_perm, signsB_perm, + scalesA_perm, scalesB_perm, false ); + } + } + } else { + VertexBFaceATests( done, minDistSqr, localPointA_perm, localPointB_perm, + hA_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsB_perm, scalesB_perm, true ); + + if ( !done ) { + VertexAFaceBTests( done, minDistSqr, localPointA_perm, localPointB_perm, + hB_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsA_perm, scalesA_perm, false ); + + if ( !done ) { + EdgeEdgeTests( done, minDistSqr, localPointA_perm, localPointB_perm, + otherFaceDimA, otherFaceDimB, + hA_perm, hB_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsA_perm, signsB_perm, + scalesA_perm, scalesB_perm, false ); + } + } + } + + // convert local points from face-local to box-local coordinate system + + pointA = PfxPoint3( aperm_col * PfxVector3( localPointA_perm ) ); + pointB = PfxPoint3( bperm_col * PfxVector3( localPointB_perm ) ); + + normal = transformA * axisA; + + //SCE_PFX_PRINTF("minDistSqr %f maxGap %f\n",minDistSqr,maxGap); + //SCE_PFX_PRINTF("normal %f %f %f\n",normal[0],normal[1],normal[2]); + //SCE_PFX_PRINTF("pointA %f %f %f\n",pointA[0],pointA[1],pointA[2]); + //SCE_PFX_PRINTF("pointB %f %f %f\n",pointB[0],pointB[1],pointB[2]); + + if ( maxGap < 0.0f ) { + return (maxGap); + } else { + return (sqrtf( minDistSqr )); + } +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_box.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_box.h new file mode 100644 index 000000000..69ff53018 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_box.h @@ -0,0 +1,33 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_BOX_BOX_H +#define _SCE_PFX_CONTACT_BOX_BOX_H + +#include "../../../include/physics_effects/base_level/base/pfx_common.h" +namespace sce { +namespace PhysicsEffects { + +PfxFloat pfxContactBoxBox( + PfxVector3 &normal,PfxPoint3 &pointA,PfxPoint3 &pointB, + void *shapeA,const PfxTransform3 &transformA, + void *shapeB,const PfxTransform3 &transformB, + PfxFloat distanceThreshold = SCE_PFX_FLT_MAX); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_CONTACT_BOX_BOX_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_capsule.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_capsule.cpp new file mode 100644 index 000000000..350953326 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_capsule.cpp @@ -0,0 +1,608 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/collision/pfx_box.h" +#include "../../../include/physics_effects/base_level/collision/pfx_capsule.h" +#include "pfx_contact_box_capsule.h" + +namespace sce { +namespace PhysicsEffects { + +enum BoxCapsSepAxisType +{ + BOX_AXIS, CROSS_AXIS +}; + +//------------------------------------------------------------------------------------------------- +// voronoiTol: bevels Voronoi planes slightly which helps when features are parallel. +//------------------------------------------------------------------------------------------------- + +static const PfxFloat voronoiTol = -1.0e-5f; + +//------------------------------------------------------------------------------------------------- +// lenSqrTol: minimum square of length for safe normalize. +//------------------------------------------------------------------------------------------------- + +static const PfxFloat lenSqrTol = 1.0e-30f; + +//------------------------------------------------------------------------------------------------- +// separating axis tests: gaps along each axis are computed, and the axis with the maximum +// gap is stored. cross product axes are normalized. +//------------------------------------------------------------------------------------------------- + +#define AaxisTest( dim, letter, first ) \ +{ \ + if ( first ) \ + { \ + maxGap = gapsA.get##letter(); \ + if ( maxGap - capsuleB.m_radius > distanceThreshold ) return maxGap - capsuleB.m_radius; \ + axisType = BOX_AXIS; \ + faceDimA = dim; \ + axisA = ident[dim]; \ + } \ + else \ + { \ + PfxFloat gap = gapsA.get##letter(); \ + if ( gap - capsuleB.m_radius > distanceThreshold ) return gap - capsuleB.m_radius; \ + else if ( gap > maxGap ) \ + { \ + maxGap = gap; \ + axisType = BOX_AXIS; \ + faceDimA = dim; \ + axisA = ident[dim]; \ + } \ + } \ +} + +#define CrossAxisTest( dima, lettera ) \ +{ \ + const PfxFloat lsqr_tolerance = 1.0e-30f; \ + PfxFloat lsqr; \ + \ + lsqr = lsqrs.get##lettera(); \ + \ + if ( lsqr > lsqr_tolerance ) \ + { \ + PfxFloat l_recip = 1.0f / sqrtf( lsqr ); \ + PfxFloat gap = PfxFloat(gapsAxB.get##lettera()) * l_recip; \ + \ + if ( gap - capsuleB.m_radius > distanceThreshold ) \ + { \ + return gap - capsuleB.m_radius; \ + } \ + \ + if ( gap > maxGap ) \ + { \ + maxGap = gap; \ + axisType = CROSS_AXIS; \ + edgeDimA = dima; \ + axisA = crossProdMat.getCol##dima() * l_recip; \ + } \ + } \ +} + +//------------------------------------------------------------------------------------------------- +// tests whether a vertex of box B and a face of box A are the closest features +//------------------------------------------------------------------------------------------------- + +inline +PfxFloat +VertexBFaceATest( + PfxBool& inVoronoi, + PfxFloat& t0, + PfxFloat& t1, + PfxVector3& ptsVec, + const PfxVector3& hA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG offsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG capsDirection, + PfxFloat signB, + PfxFloat scaleB ) +{ + // compute endpoint of capsule in box's coordinate system + + PfxVector3 endpoint = PfxVector3( offsetAB + capsDirection * scaleB ); + + // compute the parameters of the point on the box face closest to this corner. + + t0 = endpoint[0]; + t1 = endpoint[1]; + + if ( t0 > hA[0] ) + t0 = hA[0]; + else if ( t0 < -hA[0] ) + t0 = -hA[0]; + if ( t1 > hA[1] ) + t1 = hA[1]; + else if ( t1 < -hA[1] ) + t1 = -hA[1]; + + // get vector from face point to capsule endpoint + + endpoint[0] -= t0; + endpoint[1] -= t1; + ptsVec = PfxVector3(endpoint); + + // do the Voronoi test: already know the point on B is in the Voronoi region of the + // point on A, check the reverse. + + inVoronoi = ( -signB * dot(ptsVec,capsDirection) >= voronoiTol ); + + return (lengthSqr(ptsVec)); +} + +#define VertexBFaceA_SetNewMin() \ +{ \ + minDistSqr = distSqr; \ + closestPtsVec = ptsVec; \ + localPointA.setX(t0); \ + localPointA.setY(t1); \ + segmentParamB = scaleB; \ +} + +void +VertexBFaceATests( + PfxBool& done, + PfxFloat& minDistSqr, + PfxVector3& closestPtsVec, + PfxPoint3& localPointA, + PfxFloat& segmentParamB, + const PfxVector3& hA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG offsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG capsDirection, + PfxFloat signB, PfxFloat scaleB, + PfxBool first ) +{ + PfxVector3 ptsVec; + PfxFloat t0, t1; + PfxFloat distSqr; + + // test endpoint of capsule nearest to face + + distSqr = VertexBFaceATest( done, t0, t1, ptsVec, hA, offsetAB, capsDirection, signB, scaleB ); + + if ( first ) { + VertexBFaceA_SetNewMin(); + } else { + if ( distSqr < minDistSqr ) { + VertexBFaceA_SetNewMin(); + } + } + + if ( done ) + return; + + signB = -signB; + scaleB = -scaleB; + + // test other endpoint if necessary + + distSqr = VertexBFaceATest( done, t0, t1, ptsVec, hA, offsetAB, capsDirection, signB, scaleB ); + + if ( distSqr < minDistSqr ) { + VertexBFaceA_SetNewMin(); + } +} + +//------------------------------------------------------------------------------------------------- +// EdgeEdgeTest: +// +// tests whether a pair of edges are the closest features +// +// note on the shorthand: +// 'a' & 'b' refer to the edges. +// 'c' is the dimension of the axis that points from the face center to the edge Center +// 'd' is the dimension of the edge Direction +// the dimension of the face normal is 2 +//------------------------------------------------------------------------------------------------- + +#define EdgeEdgeTest( ac, ac_letter, ad, ad_letter ) \ +{ \ + /* get vector between edge centers */ \ + \ + ptsVec = offsetAB; \ + ptsVec.set##ac_letter( ptsVec.get##ac_letter() - scalesA.get##ac_letter() ); \ + \ + /* find parameters of closest points on line segments. */ \ + \ + PfxFloat capsDirection_ad = capsDirection.get##ad_letter(); \ + PfxFloat ptsVec_ad = ptsVec.get##ad_letter(); \ + PfxFloat capsDirDotPtsVec = dot(capsDirection,ptsVec); \ + PfxFloat denom = 1.0f - capsDirection_ad * capsDirection_ad; \ + \ + if ( denom == 0.0f ) \ + { \ + tA = 0.0f; \ + } \ + else \ + { \ + tA = ( ptsVec_ad - capsDirDotPtsVec * capsDirection_ad ) / denom; \ + if ( tA < -hA[ad] ) tA = -hA[ad]; \ + else if ( tA > hA[ad] ) tA = hA[ad]; \ + } \ + \ + tB = tA * capsDirection_ad - capsDirDotPtsVec; \ + \ + if ( tB < -hB ) \ + { \ + tB = -hB; \ + tA = tB * capsDirection_ad + ptsVec_ad; \ + \ + if ( tA < -hA[ad] ) tA = -hA[ad]; \ + else if ( tA > hA[ad] ) tA = hA[ad]; \ + } \ + else if ( tB > hB ) \ + { \ + tB = hB; \ + tA = tB * capsDirection_ad + ptsVec_ad; \ + \ + if ( tA < -hA[ad] ) tA = -hA[ad]; \ + else if ( tA > hA[ad] ) tA = hA[ad]; \ + } \ + \ + /* make vector to point at tB on edge B from the center of edge A. */ \ + /* test that it lies inside edge A's voronoi region. */ \ + \ + ptsVec += capsDirection * tB; \ + \ + PfxVector3 cptsVec( mulPerElem( ptsVec, signsA ) ); \ + \ + inVoronoi = ( cptsVec[ac] >= voronoiTol * cptsVec[2] ) && \ + ( cptsVec[2] >= voronoiTol * cptsVec[ac] ); \ + \ + ptsVec.set##ad_letter( ptsVec.get##ad_letter() - tA ); \ + \ + return lengthSqr(ptsVec); \ +} + +PfxFloat +EdgeEdgeTest_01( + PfxBool& inVoronoi, + PfxFloat& tA, + PfxFloat& tB, + PfxVector3& ptsVec, + const PfxVector3& hA, + PfxFloat hB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG offsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG capsDirection, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesA ) +{ + EdgeEdgeTest( 0, X, 1, Y ); +} + +PfxFloat +EdgeEdgeTest_10( + PfxBool& inVoronoi, + PfxFloat& tA, + PfxFloat& tB, + PfxVector3& ptsVec, + const PfxVector3& hA, + PfxFloat hB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG offsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG capsDirection, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesA ) +{ + EdgeEdgeTest( 1, Y, 0, X ); +} + +#define EdgeEdge_SetNewMin( ac_letter, ad_letter ) \ +{ \ + minDistSqr = distSqr; \ + closestPtsVec = ptsVec; \ + localPointA.set##ac_letter(scalesA.get##ac_letter()); \ + localPointA.set##ad_letter(tA); \ + segmentParamB = tB; \ + otherFaceDimA = testOtherFaceDimA; \ +} + +void +EdgeEdgeTests( + PfxBool& done, + PfxFloat& minDistSqr, + PfxVector3& closestPtsVec, + PfxPoint3& localPointA, + PfxFloat& segmentParamB, + int & otherFaceDimA, + const PfxVector3& hA, + PfxFloat hB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG offsetAB, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG capsDirection, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG signsA, + PfxVector3 SCE_VECTORMATH_AOS_VECTOR_ARG scalesA, + PfxBool first ) +{ + PfxVector3 ptsVec; + PfxFloat tA, tB; + int testOtherFaceDimA; + + testOtherFaceDimA = 0; + + PfxFloat distSqr = EdgeEdgeTest_01( done, tA, tB, ptsVec, hA, hB, + offsetAB, capsDirection, signsA, scalesA ); + + if ( first ) { + EdgeEdge_SetNewMin( X, Y ); + } else { + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y ); + } + } + + if ( done ) + return; + + signsA.setX( -signsA.getX() ); + scalesA.setX( -scalesA.getX() ); + + distSqr = EdgeEdgeTest_01( done, tA, tB, ptsVec, hA, hB, + offsetAB, capsDirection, signsA, scalesA ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y ); + } + + if ( done ) + return; + + testOtherFaceDimA = 1; + + distSqr = EdgeEdgeTest_10( done, tA, tB, ptsVec, hA, hB, + offsetAB, capsDirection, signsA, scalesA ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X ); + } + + if ( done ) + return; + + signsA.setY( -signsA.getY() ); + scalesA.setY( -scalesA.getY() ); + + distSqr = EdgeEdgeTest_10( done, tA, tB, ptsVec, hA, hB, + offsetAB, capsDirection, signsA, scalesA ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X ); + } +} + +PfxFloat pfxContactBoxCapsule( + PfxVector3 &normal,PfxPoint3 &pointA,PfxPoint3 &pointB, + void *shapeA,const PfxTransform3 &transformA, + void *shapeB,const PfxTransform3 &transformB, + PfxFloat distanceThreshold) +{ + PfxBox boxA = *((PfxBox*)shapeA); + PfxCapsule capsuleB = *((PfxCapsule*)shapeB); + + PfxVector3 ident[3] = { + PfxVector3(1.0,0.0,0.0), + PfxVector3(0.0,1.0,0.0), + PfxVector3(0.0,0.0,1.0), + }; + + // get capsule position and direction in box's coordinate system + + PfxMatrix3 matrixA = transformA.getUpper3x3(); + PfxMatrix3 matrixAinv = transpose(matrixA); + + PfxVector3 directionB = transformB.getUpper3x3().getCol0(); + PfxVector3 translationB = transformB.getTranslation(); + + PfxVector3 capsDirection = matrixAinv * directionB; + PfxVector3 absCapsDirection = absPerElem(capsDirection); + PfxVector3 offsetAB = matrixAinv * (translationB - transformA.getTranslation()); + + // find separating axis with largest gap between projections + + BoxCapsSepAxisType axisType; + PfxVector3 axisA; + PfxFloat maxGap; + int faceDimA = 0, edgeDimA = 0; + + // face axes + + // can compute all the gaps at once with VU0 + + PfxVector3 gapsA = absPerElem(offsetAB) - boxA.m_half - absCapsDirection * capsuleB.m_halfLen; + + AaxisTest( 0, X, true ); + AaxisTest( 1, Y, false ); + AaxisTest( 2, Z, false ); + + // cross product axes + + // compute gaps on all cross product axes using some VU0 math. suppose there's a tradeoff + // between doing this with SIMD all at once or without SIMD in each cross product test, since + // some test might exit early. + + PfxVector3 lsqrs, projOffset, projAhalf; + + PfxMatrix3 crossProdMat = crossMatrix(capsDirection) * PfxMatrix3::identity(); + PfxMatrix3 crossProdMatT = crossMatrix(-capsDirection) * PfxMatrix3::identity(); + + lsqrs = mulPerElem( crossProdMatT.getCol0(), crossProdMatT.getCol0() ) + + mulPerElem( crossProdMatT.getCol1(), crossProdMatT.getCol1() ) + + mulPerElem( crossProdMatT.getCol2(), crossProdMatT.getCol2() ); + + projOffset = crossProdMatT * offsetAB; + projAhalf = absPerElem(crossProdMatT) * boxA.m_half; + + PfxVector3 gapsAxB = absPerElem(projOffset) - projAhalf; + + CrossAxisTest( 0, X ); + CrossAxisTest( 1, Y ); + CrossAxisTest( 2, Z ); + + // make axis point from box center towards capsule center. + + if ( dot(axisA,offsetAB) < 0.0f ) + axisA = -axisA; + + // find the face on box whose normal best matches the separating axis. will use the entire + // face only in degenerate cases. + // + // to make things simpler later, change the coordinate system so that the face normal is the z + // direction. if an edge cross product axis was chosen above, also align the box edge to the y + // axis. this saves the later tests from having to know which face was chosen. changing the + // coordinate system involves permuting vector elements, so construct a permutation matrix. + // I believe this is a faster way to permute a bunch of vectors than using arrays. + + int dimA[3]; + + if ( axisType == CROSS_AXIS ) { + PfxVector3 absAxisA = PfxVector3(absPerElem(axisA)); + + dimA[1] = edgeDimA; + + if ( edgeDimA == 0 ) { + if ( absAxisA[1] > absAxisA[2] ) { + dimA[0] = 2; + dimA[2] = 1; + } else { + dimA[0] = 1; + dimA[2] = 2; + } + } else if ( edgeDimA == 1 ) { + if ( absAxisA[2] > absAxisA[0] ) { + dimA[0] = 0; + dimA[2] = 2; + } else { + dimA[0] = 2; + dimA[2] = 0; + } + } else { + if ( absAxisA[0] > absAxisA[1] ) { + dimA[0] = 1; + dimA[2] = 0; + } else { + dimA[0] = 0; + dimA[2] = 1; + } + } + } else { + dimA[2] = faceDimA; + dimA[0] = (faceDimA+1)%3; + dimA[1] = (faceDimA+2)%3; + } + + PfxMatrix3 aperm_col; + + aperm_col.setCol0(ident[dimA[0]]); + aperm_col.setCol1(ident[dimA[1]]); + aperm_col.setCol2(ident[dimA[2]]); + + PfxMatrix3 aperm_row = transpose(aperm_col); + + // permute vectors to be in face coordinate system. + + PfxVector3 offsetAB_perm = aperm_row * offsetAB; + PfxVector3 halfA_perm = aperm_row * boxA.m_half; + PfxVector3 signsA_perm = copySignPerElem(PfxVector3(1.0f), aperm_row * axisA); + PfxVector3 scalesA_perm = mulPerElem( signsA_perm, halfA_perm ); + PfxVector3 capsDirection_perm = aperm_row * capsDirection; + PfxFloat signB = (-dot(capsDirection,axisA) > 0.0f)? 1.0f : -1.0f; + PfxFloat scaleB = signB * capsuleB.m_halfLen; + + // compute the vector between the center of the box face and the capsule center + + offsetAB_perm.setZ( offsetAB_perm.getZ() - scalesA_perm.getZ() ); + + // if box and capsule overlap, this will separate them for finding points of penetration. + + if ( maxGap < 0.0f ) { + offsetAB_perm -= aperm_row * axisA * maxGap * 1.01f; + } + + // for each vertex/face or edge/edge pair of box face and line segment, find the closest + // points. + // + // these points each have an associated feature (vertex, edge, or face). if each + // point is in the external Voronoi region of the other's feature, they are the + // closest points of the objects, and the algorithm can exit. + // + // the feature pairs are arranged so that in the general case, the first test will + // succeed. degenerate cases (line segment parallel to face) may require up to all tests + // in the worst case. + // + // if for some reason no case passes the Voronoi test, the features with the minimum + // distance are returned. + + PfxVector3 closestPtsVec_perm; + PfxPoint3 localPointA_perm; + PfxFloat minDistSqr; + PfxFloat segmentParamB; + PfxBool done; + + localPointA_perm.setZ( scalesA_perm.getZ() ); + scalesA_perm.setZ(0.0f); + + PfxVector3 hA_perm( halfA_perm ); + + int otherFaceDimA; + + if ( axisType == CROSS_AXIS ) { + EdgeEdgeTests( done, minDistSqr, closestPtsVec_perm, localPointA_perm, segmentParamB, + otherFaceDimA, + hA_perm, capsuleB.m_halfLen, offsetAB_perm, capsDirection_perm, signsA_perm, + scalesA_perm, true ); + + if ( !done ) { + VertexBFaceATests( done, minDistSqr, closestPtsVec_perm, localPointA_perm, segmentParamB, + hA_perm, offsetAB_perm, capsDirection_perm, signB, scaleB, false ); + } + } else { + VertexBFaceATests( done, minDistSqr, closestPtsVec_perm, localPointA_perm, segmentParamB, + hA_perm, offsetAB_perm, capsDirection_perm, signB, scaleB, true ); + + if ( !done ) { + EdgeEdgeTests( done, minDistSqr, closestPtsVec_perm, localPointA_perm, segmentParamB, + otherFaceDimA, + hA_perm, capsuleB.m_halfLen, offsetAB_perm, capsDirection_perm, signsA_perm, + scalesA_perm, false ); + } + } + + // compute normal + + PfxBool centerInside = ( signsA_perm.getZ() * closestPtsVec_perm.getZ() < 0.0f ); + + if ( centerInside || ( minDistSqr < lenSqrTol ) ) { + normal = matrixA * axisA; + } else { + PfxVector3 closestPtsVec = aperm_col * closestPtsVec_perm; + normal = matrixA * ( closestPtsVec * (1.0f/sqrtf( minDistSqr )) ); + } + + // compute box point + + pointA = PfxPoint3( aperm_col * PfxVector3( localPointA_perm ) ); + + // compute capsule point + + pointB = PfxPoint3( transpose(transformB.getUpper3x3()) * ( directionB * segmentParamB - normal * capsuleB.m_radius ) ); + + if ( centerInside ) { + return (-sqrtf( minDistSqr ) - capsuleB.m_radius); + } else { + return (sqrtf( minDistSqr ) - capsuleB.m_radius); + } +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_capsule.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_capsule.h new file mode 100644 index 000000000..72e8aa7fd --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_capsule.h @@ -0,0 +1,34 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_BOX_CAPSULE_H +#define _SCE_PFX_CONTACT_BOX_CAPSULE_H + +#include "../../../include/physics_effects/base_level/base/pfx_common.h" + +namespace sce { +namespace PhysicsEffects { + +PfxFloat pfxContactBoxCapsule( + PfxVector3 &normal,PfxPoint3 &pointA,PfxPoint3 &pointB, + void *shapeA,const PfxTransform3 &transformA, + void *shapeB,const PfxTransform3 &transformB, + PfxFloat distanceThreshold = SCE_PFX_FLT_MAX); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_CONTACT_BOX_CAPSULE_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_sphere.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_sphere.cpp new file mode 100644 index 000000000..82a015e02 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_sphere.cpp @@ -0,0 +1,236 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/collision/pfx_box.h" +#include "../../../include/physics_effects/base_level/collision/pfx_sphere.h" +#include "pfx_contact_box_sphere.h" + +namespace sce { +namespace PhysicsEffects { + +static const PfxFloat lenSqrTol = 1.0e-30f; + +inline +PfxFloat +VertexBFaceATest( + PfxVector3& ptsVec, + PfxFloat& t0, + PfxFloat& t1, + const PfxVector3& hA, + const PfxVector3 &offsetAB ) +{ + // compute center of sphere in box's coordinate system + + PfxVector3 cptsVec = PfxVector3(offsetAB); + + // compute the parameters of the point on the face + + t0 = cptsVec[0]; + t1 = cptsVec[1]; + + if ( t0 > hA[0] ) + t0 = hA[0]; + else if ( t0 < -hA[0] ) + t0 = -hA[0]; + if ( t1 > hA[1] ) + t1 = hA[1]; + else if ( t1 < -hA[1] ) + t1 = -hA[1]; + + cptsVec[0] -= t0; + cptsVec[1] -= t1; + + ptsVec = PfxVector3( cptsVec ); + + return dot(ptsVec,ptsVec); +} + +PfxFloat pfxContactBoxSphere( + PfxVector3 &normal,PfxPoint3 &pointA,PfxPoint3 &pointB, + void *shapeA,const PfxTransform3 &transformA, + void *shapeB,const PfxTransform3 &transformB, + PfxFloat distanceThreshold) +{ + PfxBox &boxA = *((PfxBox*)shapeA); + PfxSphere &sphereB = *((PfxSphere*)shapeB); + + PfxVector3 ident[3] = { + PfxVector3(1.0,0.0,0.0), + PfxVector3(0.0,1.0,0.0), + PfxVector3(0.0,0.0,1.0), + }; + + //{ + // PfxMatrix3 identity = PfxMatrix3::identity(); + // ident[0] = identity.getCol0(); + // ident[1] = identity.getCol1(); + // ident[2] = identity.getCol2(); + //} + + // offsetAB is vector from A's center to B's center, in A's coordinate system + + PfxVector3 translationB = transformB.getTranslation(); + PfxVector3 offsetAB = transpose(transformA.getUpper3x3()) * ( translationB - + transformA.getTranslation() ); + + // find separating axis with largest gap between objects + + PfxVector3 axisA; + int faceDimA; + PfxFloat maxGap; + + PfxVector3 gapsA = absPerElem(offsetAB) - boxA.m_half - PfxVector3(sphereB.m_radius); + PfxVector3 signsA = copySignPerElem(PfxVector3(1.0f),offsetAB); + + { + PfxFloat gap = gapsA[0]; + + if( gap > distanceThreshold ) { + return gap; + } + + maxGap = gap; + faceDimA = 0; + axisA = mulPerElem( ident[0], signsA ); + + if( gap > maxGap ) { + maxGap = gap; + faceDimA = 0; + axisA = mulPerElem( ident[0], signsA ); + } + + gap = gapsA[1]; + + if( gap > distanceThreshold ) { + return gap; + } + + if( gap > maxGap ) { + maxGap = gap; + faceDimA = 1; + axisA = mulPerElem( ident[1], signsA ); + } + + gap = gapsA[2]; + + if( gap > distanceThreshold ) { + return gap; + } + + if( gap > maxGap ) { + maxGap = gap; + faceDimA = 2; + axisA = mulPerElem( ident[2], signsA ); + } + } + + // choose face in this direction, and make a new coordinate system which the z axis = face + // normal, x and y axes tangent to the face. to transform vectors into this coordinate + // system, will use a permutation matrix. + + int dimA[3]; + + dimA[2] = faceDimA; + dimA[0] = (faceDimA+1)%3; + dimA[1] = (faceDimA+2)%3; + + PfxMatrix3 apermCol; + + apermCol.setCol0(ident[dimA[0]]); + apermCol.setCol1(ident[dimA[1]]); + apermCol.setCol2(ident[dimA[2]]); + + PfxMatrix3 apermRow = transpose(apermCol); + + // permute vectors + + PfxVector3 halfA_perm = apermRow * boxA.m_half; + PfxVector3 offsetAB_perm = apermRow * offsetAB; + PfxVector3 signsA_perm = apermRow * signsA; + + // compute the vector between the center of the box face and the sphere center + + PfxFloat signA2 = signsA_perm.getZ(); + PfxFloat scaleA2 = halfA_perm.getZ() * signA2; + offsetAB_perm.setZ( offsetAB_perm.getZ() - scaleA2 ); + + // find point on face closest to sphere center + + PfxFloat t0, t1; + PfxFloat minDistSqr; + PfxVector3 closestPtsVec_perm; + PfxPoint3 localPointA_perm; + + minDistSqr = VertexBFaceATest( closestPtsVec_perm, t0, t1, PfxVector3( halfA_perm ), offsetAB_perm ); + + //SCE_PFX_PRINTF("faceDimA %d dimA %d %d %d\n",faceDimA,dimA[0],dimA[1],dimA[2]); + //SCE_PFX_PRINTF("boxA.m_half %f %f %f\n",boxA.m_half[0],boxA.m_half[1],boxA.m_half[2]); + //SCE_PFX_PRINTF("ident %f %f %f | %f %f %f | %f %f %f\n", + // ident[0][0],ident[0][1],ident[0][2], + // ident[1][0],ident[1][1],ident[1][2], + // ident[2][0],ident[2][1],ident[2][2]); + //SCE_PFX_PRINTF("apermCol %f %f %f | %f %f %f | %f %f %f\n", + // apermCol[0][0],apermCol[0][1],apermCol[0][2], + // apermCol[1][0],apermCol[1][1],apermCol[1][2], + // apermCol[2][0],apermCol[2][1],apermCol[2][2]); + //SCE_PFX_PRINTF("apermRow %f %f %f | %f %f %f | %f %f %f\n", + // apermRow[0][0],apermRow[0][1],apermRow[0][2], + // apermRow[1][0],apermRow[1][1],apermRow[1][2], + // apermRow[2][0],apermRow[2][1],apermRow[2][2]); + + //SCE_PFX_PRINTF("closestPtsVec_perm %f %f %f\n",closestPtsVec_perm[0],closestPtsVec_perm[1],closestPtsVec_perm[2]); + //SCE_PFX_PRINTF("halfA_perm %f %f %f\n",halfA_perm[0],halfA_perm[1],halfA_perm[2]); + //SCE_PFX_PRINTF("offsetAB_perm %f %f %f\n",offsetAB_perm[0],offsetAB_perm[1],offsetAB_perm[2]); + //SCE_PFX_PRINTF("t0 %f t1 %f scaleA2 %f\n",t0,t1,scaleA2); + + //SCE_PFX_PRINTF("minDistSqr %f sphereB.m_radius %f\n",minDistSqr,sphereB.m_radius); + + localPointA_perm = PfxPoint3( t0, t1, scaleA2 ); + + // compute normal + + bool centerInside = ( signA2 * closestPtsVec_perm.getZ() < 0.0f ); + + if ( centerInside || ( minDistSqr < lenSqrTol ) ) { + normal = transformA * axisA; + } else { + PfxVector3 closestPtsVec = apermCol * closestPtsVec_perm; + normal = transformA * ( closestPtsVec * ( 1.0f / sqrtf( minDistSqr ) ) ); + } + + // compute box point + + pointA = PfxPoint3( apermCol * PfxVector3( localPointA_perm ) ); + + // compute sphere point + + pointB = PfxPoint3( transpose(transformB.getUpper3x3()) * ( -normal * sphereB.m_radius ) ); + + // return distance + + //SCE_PFX_PRINTF("normal %f %f %f\n",(float)normal[0],(float)normal[1],(float)normal[2]); + //SCE_PFX_PRINTF("pointA %f %f %f\n",(float)pointA[0],(float)pointA[1],(float)pointA[2]); + //SCE_PFX_PRINTF("pointB %f %f %f\n",(float)pointB[0],(float)pointB[1],(float)pointB[2]); + + if ( centerInside ) { + return -sqrtf( minDistSqr ) - sphereB.m_radius; + } else { + return sqrtf( minDistSqr ) - sphereB.m_radius; + } +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_sphere.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_sphere.h new file mode 100644 index 000000000..24279d14a --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_box_sphere.h @@ -0,0 +1,34 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_BOX_SPHERE_H +#define _SCE_PFX_CONTACT_BOX_SPHERE_H + +#include "../../../include/physics_effects/base_level/base/pfx_common.h" + +namespace sce { +namespace PhysicsEffects { + +PfxFloat pfxContactBoxSphere( + PfxVector3 &normal,PfxPoint3 &pointA,PfxPoint3 &pointB, + void *shapeA,const PfxTransform3 &transformA, + void *shapeB,const PfxTransform3 &transformB, + PfxFloat distanceThreshold = SCE_PFX_FLT_MAX); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_CONTACT_BOXSPHERE_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_cache.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_cache.cpp new file mode 100644 index 000000000..24e945e73 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_cache.cpp @@ -0,0 +1,164 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "pfx_contact_cache.h" + +namespace sce { +namespace PhysicsEffects { + +#define SCE_PFX_CONTACT_SAME_POINT 0.01f + +int PfxContactCache::findNearestContactPoint(const PfxPoint3 &newPoint,const PfxVector3 &newNormal) +{ + int nearestIdx = -1; + PfxFloat minDiff = SCE_PFX_CONTACT_SAME_POINT; + for(PfxUInt32 i=0;i 0.99f) { + minDiff = diff; + nearestIdx = i; + } + } + return nearestIdx; +} + +int PfxContactCache::sort4ContactPoints(const PfxPoint3 &newCP,PfxFloat newDistance) +{ + int maxPenetrationIndex = -1; + PfxFloat maxPenetration = newDistance; + + // 最も深い衝突点は排除対象からはずす + for(int i=0;i maxVal) { + maxIndex = 1; + maxVal = res[1]; + } + + if (res[2] > maxVal) { + maxIndex = 2; + maxVal = res[2]; + } + + if (res[3] > maxVal) { + maxIndex = 3; + maxVal = res[3]; + } + + return maxIndex; +} + +void PfxContactCache::addContactPoint( + PfxFloat newDistance, + const PfxVector3 &newNormal, // world coords + const PfxPoint3 &newPointA, // local to the objectA + const PfxPoint3 &newPointB, // local to the objectB + PfxSubData subData) +{ + int id = findNearestContactPoint(newPointA,newNormal); + + if(id < 0 && m_numContacts < SCE_PFX_MAX_CACHED_CONTACT_POINTS) { + // 衝突点を新規追加 + id = m_numContacts++; + m_cachedContactPoints[id].reset(); + } + else if(id < 0){ + // ソート + id = sort4ContactPoints(newPointA,newDistance); + m_cachedContactPoints[id].reset(); + } + + m_cachedContactPoints[id].m_distance = newDistance; + m_cachedContactPoints[id].m_subData = subData; + m_cachedContactPoints[id].m_normal = newNormal; + m_cachedContactPoints[id].m_localPointA = newPointA; + m_cachedContactPoints[id].m_localPointB = newPointB; +} + +void PfxContactCache::addContactPoint(const PfxCachedContactPoint &cp) +{ + PfxPoint3 pA = cp.m_localPointA; + + int id = findNearestContactPoint(pA,cp.m_normal); + + if(id >= 0) { + if(m_cachedContactPoints[id].m_distance > cp.m_distance) { + // 同一点を発見、衝突点情報を更新 + m_cachedContactPoints[id].m_distance = cp.m_distance; + m_cachedContactPoints[id].m_normal = cp.m_normal; + m_cachedContactPoints[id].m_localPointA = cp.m_localPointA; + m_cachedContactPoints[id].m_localPointB = cp.m_localPointB; + } + } + else if(m_numContacts < SCE_PFX_MAX_CACHED_CONTACT_POINTS) { + // 衝突点を新規追加 + m_cachedContactPoints[m_numContacts++] = cp; + } + else { + // ソート + id = sort4ContactPoints(pA,cp.m_distance); + + // コンタクトポイント入れ替え + m_cachedContactPoints[id] = cp; + } +} + +} //namespace PhysicsEffects +} //namespace sce + diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_cache.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_cache.h new file mode 100644 index 000000000..5093b7974 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_cache.h @@ -0,0 +1,100 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_CACHE_H +#define _SCE_PFX_CONTACT_CACHE_H + +#include "../../../include/physics_effects/base_level/base/pfx_common.h" +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "../../../include/physics_effects/base_level/collision/pfx_sub_data.h" + +namespace sce { +namespace PhysicsEffects { + +#define SCE_PFX_MAX_CACHED_CONTACT_POINTS 4 + +/* + 内部の衝突判定に使う軽量なコンタクトキャッシュ +*/ + +/////////////////////////////////////////////////////////////////////////////// +// Contact Point + +struct PfxCachedContactPoint +{ + PfxSubData m_subData; + PfxUInt8 m_shapeIdA; + PfxUInt8 m_shapeIdB; + SCE_PFX_PADDING(1,2) + PfxFloat m_distance; + PfxVector3 m_normal; + PfxPoint3 m_localPointA; + PfxPoint3 m_localPointB; + + void reset() + { + m_shapeIdA = m_shapeIdB = 0; + m_subData = PfxSubData(); + m_distance = SCE_PFX_FLT_MAX; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// Contact Point + +class PfxContactCache +{ +private: + PfxUInt32 m_numContacts; + SCE_PFX_PADDING(1,12) + PfxCachedContactPoint m_cachedContactPoints[SCE_PFX_MAX_CACHED_CONTACT_POINTS]; + + int findNearestContactPoint(const PfxPoint3 &newPoint,const PfxVector3 &newNormal); + int sort4ContactPoints(const PfxPoint3 &newPoint,PfxFloat newDistance); + +public: + PfxContactCache() : m_numContacts(0) {} + + void addContactPoint( + PfxFloat newDistance, + const PfxVector3 &newNormal, // world normal vector + const PfxPoint3 &newPointA, // local contact point to the objectA + const PfxPoint3 &newPointB, // local contact point to the objectB + PfxSubData m_subData); + + void addContactPoint(const PfxCachedContactPoint &cp); + + int getNumContacts() const {return (int)m_numContacts;} + + PfxCachedContactPoint &getContactPoint(int i) {return m_cachedContactPoints[i];} + + const PfxCachedContactPoint &getContactPoint(int i) const {return m_cachedContactPoints[i];} + + PfxFloat getDistance(int i) {return m_cachedContactPoints[i].m_distance;} + + const PfxVector3 &getNormal(int i) const {return m_cachedContactPoints[i].m_normal;} + + const PfxPoint3 &getLocalPointA(int i) const {return m_cachedContactPoints[i].m_localPointA;} + + const PfxPoint3 &getLocalPointB(int i) const {return m_cachedContactPoints[i].m_localPointB;} + + const PfxSubData &getSubData(int i) const {return m_cachedContactPoints[i].m_subData;} +}; + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_CONTACT_CACHE_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_capsule_capsule.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_capsule_capsule.cpp new file mode 100644 index 000000000..e4e07eedb --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_capsule_capsule.cpp @@ -0,0 +1,144 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "../../../include/physics_effects/base_level/collision/pfx_capsule.h" +#include "pfx_contact_capsule_capsule.h" + +namespace sce { +namespace PhysicsEffects { + +inline +void +segmentsClosestPoints( + PfxVector3& ptsVector, + PfxVector3& offsetA, + PfxVector3& offsetB, + PfxFloat& tA, PfxFloat& tB, + const PfxVector3 &translation, + const PfxVector3 &dirA, PfxFloat hlenA, + const PfxVector3 &dirB, PfxFloat hlenB ) +{ + // compute the parameters of the closest points on each line segment + + PfxFloat dirA_dot_dirB = dot(dirA,dirB); + PfxFloat dirA_dot_trans = dot(dirA,translation); + PfxFloat dirB_dot_trans = dot(dirB,translation); + + PfxFloat denom = 1.0f - dirA_dot_dirB * dirA_dot_dirB; + + if ( denom == 0.0f ) { + tA = 0.0f; + } else { + tA = ( dirA_dot_trans - dirB_dot_trans * dirA_dot_dirB ) / denom; + if ( tA < -hlenA ) + tA = -hlenA; + else if ( tA > hlenA ) + tA = hlenA; + } + + tB = tA * dirA_dot_dirB - dirB_dot_trans; + + if ( tB < -hlenB ) { + tB = -hlenB; + tA = tB * dirA_dot_dirB + dirA_dot_trans; + + if ( tA < -hlenA ) + tA = -hlenA; + else if ( tA > hlenA ) + tA = hlenA; + } else if ( tB > hlenB ) { + tB = hlenB; + tA = tB * dirA_dot_dirB + dirA_dot_trans; + + if ( tA < -hlenA ) + tA = -hlenA; + else if ( tA > hlenA ) + tA = hlenA; + } + + // compute the closest points relative to segment centers. + + offsetA = dirA * tA; + offsetB = dirB * tB; + + ptsVector = translation - offsetA + offsetB; +} + +inline +void +segmentsNormal( PfxVector3& normal, const PfxVector3 &ptsVector ) +{ + // compute the unit direction vector between the closest points. + // with convex objects, you want the unit direction providing the largest gap between the + // objects when they're projected onto it. So, if you have a few candidates covering different + // configurations of the objects, you can compute them all, test the gaps and pick best axis + // based on this. Some directions might be degenerate, and the normalized() function tests for + // degeneracy and returns an arbitrary unit vector in that case. + + PfxVector3 testDir; + + // closest points vector + + normal = pfxSafeNormalize(ptsVector); +} + +PfxFloat pfxContactCapsuleCapsule( + PfxVector3 &normal,PfxPoint3 &pointA,PfxPoint3 &pointB, + void *shapeA,const PfxTransform3 &transformA, + void *shapeB,const PfxTransform3 &transformB, + PfxFloat distanceThreshold) +{ + PfxCapsule &capsuleA = *((PfxCapsule*)shapeA); + PfxCapsule &capsuleB = *((PfxCapsule*)shapeB); + + PfxVector3 directionA = transformA.getUpper3x3().getCol0(); + PfxVector3 translationA = transformA.getTranslation(); + PfxVector3 directionB = transformB.getUpper3x3().getCol0(); + PfxVector3 translationB = transformB.getTranslation(); + + // translation between centers + + PfxVector3 translation = translationB - translationA; + + // compute the closest points of the capsule line segments + + PfxVector3 ptsVector; // the vector between the closest points + PfxVector3 offsetA, offsetB; // offsets from segment centers to their closest points + PfxFloat tA, tB; // parameters on line segment + + segmentsClosestPoints( ptsVector, offsetA, offsetB, tA, tB, translation, + directionA, capsuleA.m_halfLen, directionB, capsuleB.m_halfLen ); + + PfxFloat distance = length(ptsVector) - capsuleA.m_radius - capsuleB.m_radius; + + if ( distance > distanceThreshold ) + return distance; + + // compute the contact normal + + segmentsNormal( normal, ptsVector ); + + // compute points on capsules + + pointA = PfxPoint3( transpose(transformA.getUpper3x3()) * ( offsetA + normal * capsuleA.m_radius ) ); + pointB = PfxPoint3( transpose(transformB.getUpper3x3()) * ( offsetB - normal * capsuleB.m_radius ) ); + + return distance; +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_capsule_capsule.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_capsule_capsule.h new file mode 100644 index 000000000..744e7a014 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_capsule_capsule.h @@ -0,0 +1,34 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_CAPSULE_CAPSULE_H +#define _SCE_PFX_CONTACT_CAPSULE_CAPSULE_H + +#include "../../../include/physics_effects/base_level/base/pfx_common.h" + +namespace sce { +namespace PhysicsEffects { + +PfxFloat pfxContactCapsuleCapsule( + PfxVector3 &normal,PfxPoint3 &pointA,PfxPoint3 &pointB, + void *shapeA,const PfxTransform3 &transformA, + void *shapeB,const PfxTransform3 &transformB, + PfxFloat distanceThreshold = SCE_PFX_FLT_MAX); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_CONTACT_CAPSULE_CAPSULE_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_capsule_sphere.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_capsule_sphere.cpp new file mode 100644 index 000000000..7102ac0dd --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_capsule_sphere.cpp @@ -0,0 +1,108 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "../../../include/physics_effects/base_level/collision/pfx_capsule.h" +#include "../../../include/physics_effects/base_level/collision/pfx_sphere.h" +#include "pfx_contact_capsule_sphere.h" + +namespace sce { +namespace PhysicsEffects { + +inline +void +segmentPointClosestPoints( + PfxVector3& ptsVector, + PfxVector3& offsetA, + PfxFloat& tA, + const PfxVector3 &translation, + const PfxVector3 &dirA, PfxFloat hLenA ) +{ + // compute the parameters of the closest points on each line segment + + tA = dot(dirA,translation); + + if ( tA < -hLenA ) + tA = -hLenA; + else if ( tA > hLenA ) + tA = hLenA; + + // compute the closest point on segment relative to its center. + + offsetA = dirA * tA; + ptsVector = translation - offsetA; +} + +inline +void +segmentPointNormal( PfxVector3& normal, const PfxVector3 &ptsVector ) +{ + // compute the unit direction vector between the closest points. + // with convex objects, you want the unit direction providing the largest gap between the + // objects when they're projected onto it. So, if you have a few candidates covering different + // configurations of the objects, you can compute them all, test the gaps and pick best axis + // based on this. Some directions might be degenerate, and the normalized() function tests for + // degeneracy and returns an arbitrary unit vector in that case. + + // closest points vector + + normal = pfxSafeNormalize(ptsVector); +} + +PfxFloat pfxContactCapsuleSphere( + PfxVector3 &normal,PfxPoint3 &pointA,PfxPoint3 &pointB, + void *shapeA,const PfxTransform3 &transformA, + void *shapeB,const PfxTransform3 &transformB, + PfxFloat distanceThreshold) +{ + PfxCapsule &capsuleA = *((PfxCapsule*)shapeA); + PfxSphere &sphereB = *((PfxSphere*)shapeB); + + PfxVector3 directionA = transformA.getUpper3x3().getCol0(); + PfxVector3 translationA = transformA.getTranslation(); + PfxVector3 translationB = transformB.getTranslation(); + + // translation between centers of capsule and sphere + + PfxVector3 translation = translationB - translationA; + + // compute the closest point on the capsule line segment to the sphere center + + PfxVector3 ptsVector; + PfxVector3 offsetA; + PfxFloat tA; + + segmentPointClosestPoints( ptsVector, offsetA, tA, translation, directionA, capsuleA.m_halfLen ); + + PfxFloat distance = length(ptsVector) - capsuleA.m_radius - sphereB.m_radius; + + if ( distance > distanceThreshold ) + return distance; + + // compute the contact normal + + segmentPointNormal( normal, ptsVector ); + + // compute points on capsule and sphere + + pointA = PfxPoint3( transpose(transformA.getUpper3x3()) * ( offsetA + normal * capsuleA.m_radius ) ); + pointB = PfxPoint3( transpose(transformB.getUpper3x3()) * ( -normal * sphereB.m_radius ) ); + + return distance; +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_capsule_sphere.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_capsule_sphere.h new file mode 100644 index 000000000..653a8e4fa --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_capsule_sphere.h @@ -0,0 +1,34 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_CAPSULE_SPHERE_H +#define _SCE_PFX_CONTACT_CAPSULE_SPHERE_H + +#include "../../../include/physics_effects/base_level/base/pfx_common.h" + +namespace sce { +namespace PhysicsEffects { + +PfxFloat pfxContactCapsuleSphere( + PfxVector3 &normal,PfxPoint3 &pointA,PfxPoint3 &pointB, + void *shapeA,const PfxTransform3 &transformA, + void *shapeB,const PfxTransform3 &transformB, + PfxFloat distanceThreshold = SCE_PFX_FLT_MAX); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_CONTACT_CAPSULE_SPHERE_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_large_tri_mesh.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_large_tri_mesh.cpp new file mode 100644 index 000000000..764a738d3 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_large_tri_mesh.cpp @@ -0,0 +1,152 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "pfx_contact_tri_mesh_sphere.h" +#include "pfx_contact_tri_mesh_box.h" +#include "pfx_contact_tri_mesh_capsule.h" +#include "pfx_contact_tri_mesh_cylinder.h" +#include "pfx_contact_tri_mesh_convex.h" +#include "pfx_contact_large_tri_mesh.h" +#include "pfx_intersect_common.h" +#include "pfx_mesh_common.h" + + +namespace sce { +namespace PhysicsEffects { + + +PfxInt32 pfxContactLargeTriMesh( + PfxContactCache &contacts, + const PfxLargeTriMesh *lmeshA, + const PfxTransform3 &transformA, + const PfxShape &shapeB, + const PfxTransform3 &transformB, + PfxFloat distanceThreshold) +{ + PfxTransform3 transformAB; + PfxMatrix3 matrixAB; + PfxVector3 offsetAB; + + // Bローカル→Aローカルへの変換 + transformAB = orthoInverse(transformA) * transformB; + matrixAB = transformAB.getUpper3x3(); + offsetAB = transformAB.getTranslation(); + + // ----------------------------------------------------- + // LargeTriMeshに含まれるTriMeshのAABBと凸体のAABBを判定し、 + // 交差するものを個別に衝突判定する。※LargeMesh座標系 + + PfxVector3 shapeHalf(0.0f); + PfxVector3 shapeCenter = offsetAB; + + + switch(shapeB.getType()) { + case kPfxShapeSphere: + shapeHalf = PfxVector3(shapeB.getSphere().m_radius); + break; + + case kPfxShapeCapsule: + { + PfxCapsule capsule = shapeB.getCapsule(); + shapeHalf = absPerElem(matrixAB) * PfxVector3(capsule.m_halfLen+capsule.m_radius,capsule.m_radius,capsule.m_radius); + } + break; + + case kPfxShapeCylinder: + { + PfxCylinder cylinder = shapeB.getCylinder(); + shapeHalf = absPerElem(matrixAB) * PfxVector3(cylinder.m_halfLen,cylinder.m_radius,cylinder.m_radius); + } + break; + + case kPfxShapeBox: + shapeHalf = absPerElem(matrixAB) * shapeB.getBox().m_half; + break; + + case kPfxShapeConvexMesh: + shapeHalf = absPerElem(matrixAB) * shapeB.getConvexMesh()->m_half; + break; + + default: + break; + } + + // ----------------------------------------------------- + // アイランドとの衝突判定 + + PfxVecInt3 aabbMinL,aabbMaxL; + lmeshA->getLocalPosition((shapeCenter-shapeHalf),(shapeCenter+shapeHalf),aabbMinL,aabbMaxL); + + PfxUInt32 numIslands = lmeshA->m_numIslands; + + { + for(PfxUInt32 i=0;im_aabbList[i]; + if(aabbMaxL.getX() < pfxGetXMin(aabbB) || aabbMinL.getX() > pfxGetXMax(aabbB)) continue; + if(aabbMaxL.getY() < pfxGetYMin(aabbB) || aabbMinL.getY() > pfxGetYMax(aabbB)) continue; + if(aabbMaxL.getZ() < pfxGetZMin(aabbB) || aabbMinL.getZ() > pfxGetZMax(aabbB)) continue; + + PfxTriMesh *island = &lmeshA->m_islands[i]; + + // 衝突判定 + PfxContactCache localContacts; + switch(shapeB.getType()) { + case kPfxShapeSphere: + pfxContactTriMeshSphere(localContacts,island,transformA,shapeB.getSphere(),transformB,distanceThreshold); + break; + + case kPfxShapeCapsule: + pfxContactTriMeshCapsule(localContacts,island,transformA,shapeB.getCapsule(),transformB,distanceThreshold); + break; + + case kPfxShapeBox: + pfxContactTriMeshBox(localContacts,island,transformA,shapeB.getBox(),transformB,distanceThreshold); + break; + + case kPfxShapeCylinder: + pfxContactTriMeshCylinder(localContacts,island,transformA,shapeB.getCylinder(),transformB,distanceThreshold); + break; + + case kPfxShapeConvexMesh: + pfxContactTriMeshConvex(localContacts,island,transformA,*shapeB.getConvexMesh(),transformB,distanceThreshold); + break; + + default: + break; + } + + + // 衝突点を追加 + for(int j=0;j 0.99f) { + minDiff = diff; + nearestIdx = i; + } + } + return nearestIdx; +} + +int PfxContactManifold::sort4ContactPoints(const PfxPoint3 &newCP,PfxFloat newDistance) +{ + int maxPenetrationIndex = -1; + PfxFloat maxPenetration = newDistance; + + // 最も深い衝突点は排除対象からはずす + for(int i=0;i maxVal) { + maxIndex = 1; + maxVal = res[1]; + } + + if (res[2] > maxVal) { + maxIndex = 2; + maxVal = res[2]; + } + + if (res[3] > maxVal) { + maxIndex = 3; + maxVal = res[3]; + } + + return maxIndex; +} + +void PfxContactManifold::addContactPoint( + PfxFloat newDistance, + const PfxVector3 &newNormal, // world coords + const PfxPoint3 &newPointA, // local to the objectA + const PfxPoint3 &newPointB, // local to the objectB + PfxSubData subData) +{ + int id = findNearestContactPoint(newPointA,newNormal); + + if(id < 0 && m_numContacts < SCE_PFX_NUMCONTACTS_PER_BODIES) { + // 衝突点を新規追加 + id = m_numContacts++; + m_contactPoints[id].reset(); + } + else if(id < 0){ + // ソート + id = sort4ContactPoints(newPointA,newDistance); + m_contactPoints[id].reset(); + } + + m_contactPoints[id].m_distance = newDistance; + m_contactPoints[id].m_subData = subData; + pfxStorePoint3(newPointA,m_contactPoints[id].m_localPointA); + pfxStorePoint3(newPointB,m_contactPoints[id].m_localPointB); + pfxStoreVector3(newNormal,m_contactPoints[id].m_constraintRow[0].m_normal); +} + +void PfxContactManifold::addContactPoint(const PfxContactPoint &cp) +{ + PfxPoint3 pA = pfxReadPoint3(cp.m_localPointA); + + int id = findNearestContactPoint(pA,pfxReadVector3(cp.m_constraintRow[0].m_normal)); + + if(id >= 0) { +#if 1 + PfxVector3 nml1(pfxReadVector3(m_contactPoints[id].m_constraintRow[0].m_normal)); + PfxVector3 nml2(pfxReadVector3(cp.m_constraintRow[0].m_normal)); + if(fabsf(dot(nml1,nml2)) > 0.99f ) { + // 同一点を発見、蓄積された情報を継続 + m_contactPoints[id].m_distance = cp.m_distance; + m_contactPoints[id].m_localPointA[0] = cp.m_localPointA[0]; + m_contactPoints[id].m_localPointA[1] = cp.m_localPointA[1]; + m_contactPoints[id].m_localPointA[2] = cp.m_localPointA[2]; + m_contactPoints[id].m_localPointB[0] = cp.m_localPointB[0]; + m_contactPoints[id].m_localPointB[1] = cp.m_localPointB[1]; + m_contactPoints[id].m_localPointB[2] = cp.m_localPointB[2]; + m_contactPoints[id].m_constraintRow[0].m_normal[0] = cp.m_constraintRow[0].m_normal[0]; + m_contactPoints[id].m_constraintRow[0].m_normal[1] = cp.m_constraintRow[0].m_normal[1]; + m_contactPoints[id].m_constraintRow[0].m_normal[2] = cp.m_constraintRow[0].m_normal[2]; + } + else { + // 同一点ではあるが法線が違うため更新 + m_contactPoints[id] = cp; + } +#else + if(m_contactPoints[id].m_distance > cp.m_distance) { + // 同一点を発見、衝突点情報を更新 + m_contactPoints[id].m_distance = cp.m_distance; + m_contactPoints[id].m_localPointA[0] = cp.m_localPointA[0]; + m_contactPoints[id].m_localPointA[1] = cp.m_localPointA[1]; + m_contactPoints[id].m_localPointA[2] = cp.m_localPointA[2]; + m_contactPoints[id].m_localPointB[0] = cp.m_localPointB[0]; + m_contactPoints[id].m_localPointB[1] = cp.m_localPointB[1]; + m_contactPoints[id].m_localPointB[2] = cp.m_localPointB[2]; + m_contactPoints[id].m_constraintRow[0].m_normal[0] = cp.m_constraintRow[0].m_normal[0]; + m_contactPoints[id].m_constraintRow[0].m_normal[1] = cp.m_constraintRow[0].m_normal[1]; + m_contactPoints[id].m_constraintRow[0].m_normal[2] = cp.m_constraintRow[0].m_normal[2]; + } +#endif + } + else if(m_numContacts < SCE_PFX_NUMCONTACTS_PER_BODIES) { + // 衝突点を新規追加 + m_contactPoints[m_numContacts++] = cp; + } + else { + // ソート + id = sort4ContactPoints(pA,cp.m_distance); + + // コンタクトポイント入れ替え + m_contactPoints[id] = cp; + } +} + +void PfxContactManifold::merge(const PfxContactManifold &contact) +{ + SCE_PFX_ALWAYS_ASSERT(m_rigidBodyIdA == contact.getRigidBodyIdA()); + SCE_PFX_ALWAYS_ASSERT(m_rigidBodyIdB == contact.getRigidBodyIdB()); + + for(int i=0;i 0) { + PfxVector3 normal = pfxReadVector3(m_contactPoints[i].m_constraintRow[0].m_normal); + PfxVector3 cpA = pA + rotate(qA,pfxReadVector3(m_contactPoints[i].m_localPointA)); + PfxVector3 cpB = pB + rotate(qB,pfxReadVector3(m_contactPoints[i].m_localPointB)); + + // 貫通深度がプラスに転じたかどうかをチェック + PfxFloat distance = dot(normal,(cpA - cpB)); + if(distance > SCE_PFX_CONTACT_THRESHOLD_NORMAL) { + removeContactPoint(i); + i--; + continue; + } + m_contactPoints[i].m_distance = distance; + + // 深度方向を除去して両点の距離をチェック + cpA = cpA - m_contactPoints[i].m_distance * normal; + PfxFloat distanceAB = lengthSqr(cpA - cpB); + if(distanceAB > SCE_PFX_CONTACT_THRESHOLD_TANGENT) { + removeContactPoint(i); + i--; + continue; + } + } + if(m_contactPoints[i].m_duration < 255) m_contactPoints[i].m_duration++; + } + if(m_numContacts > 0 && m_duration < 65535) m_duration++; +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_sphere_sphere.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_sphere_sphere.cpp new file mode 100644 index 000000000..f55f09660 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_sphere_sphere.cpp @@ -0,0 +1,76 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/collision/pfx_sphere.h" +#include "pfx_contact_sphere_sphere.h" + +namespace sce { +namespace PhysicsEffects { + +const PfxFloat lenSqrTol = 1.0e-30f; + +PfxFloat pfxContactSphereSphere( + PfxVector3 &normal,PfxPoint3 &pointA,PfxPoint3 &pointB, + void *shapeA,const PfxTransform3 &transformA, + void *shapeB,const PfxTransform3 &transformB, + PfxFloat distanceThreshold) +{ + PfxSphere &sphereA = *((PfxSphere*)shapeA); + PfxSphere &sphereB = *((PfxSphere*)shapeB); + + PfxVector3 direction(0.0f); + + PfxVector3 translationA = transformA.getTranslation(); + PfxVector3 translationB = transformB.getTranslation(); + + // get the offset vector between sphere centers + + PfxVector3 offsetAB; + + offsetAB = translationB - translationA; + + // normalize the offset to compute the direction vector + + PfxFloat distSqr = dot(offsetAB,offsetAB); + PfxFloat dist = sqrtf(distSqr); + PfxFloat sphereDist = dist - sphereA.m_radius - sphereB.m_radius; + + if ( sphereDist > distanceThreshold ) { + return sphereDist; + } + + if ( distSqr > lenSqrTol ) { + PfxFloat distInv = 1.0f / dist; + + direction = offsetAB * distInv; + } else { + direction = PfxVector3(0.0f, 0.0f, 1.0f); + } + + normal = direction; + + // compute the points on the spheres, in world space + + pointA = PfxPoint3( transpose(transformA.getUpper3x3()) * ( direction * sphereA.m_radius ) ); + pointB = PfxPoint3( transpose(transformB.getUpper3x3()) * ( -direction * sphereB.m_radius ) ); + + // return the distance between the spheres + + return sphereDist; +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_sphere_sphere.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_sphere_sphere.h new file mode 100644 index 000000000..03def3598 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_sphere_sphere.h @@ -0,0 +1,33 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_SPHERE_SPHERE_H +#define _SCE_PFX_CONTACT_SPHERE_SPHERE_H + +#include "../../../include/physics_effects/base_level/base/pfx_common.h" +namespace sce { +namespace PhysicsEffects { + +PfxFloat pfxContactSphereSphere( + PfxVector3 &normal,PfxPoint3 &pointA,PfxPoint3 &pointB, + void *shapeA,const PfxTransform3 &transformA, + void *shapeB,const PfxTransform3 &transformB, + PfxFloat distanceThreshold = SCE_PFX_FLT_MAX); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_CONTACT_SPHERE_SPHERE_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_box.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_box.cpp new file mode 100644 index 000000000..199d762ea --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_box.cpp @@ -0,0 +1,456 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "pfx_contact_tri_mesh_box.h" +#include "pfx_intersect_common.h" +#include "pfx_mesh_common.h" + +namespace sce { +namespace PhysicsEffects { + +static SCE_PFX_FORCE_INLINE +bool checkSAT(const PfxVector3 &axis,PfxFloat AMin,PfxFloat AMax,PfxFloat BMin,PfxFloat BMax,PfxFloat &distMin,PfxVector3 &axisMin) +{ + // ■ 非接触. + + // A: +----+ + // B:+----+ + if(BMax <= AMin) { + return true; + } + + // A:+----+ + // B: +----+ + else if(AMax <= BMin) { + return true; + } + + // ■ 内包 + + //A: +--+ + //B: +------+ + if(BMin < AMin && AMax < BMax) { + PfxFloat d = AMin-BMax; + if(distMin < d) { + distMin = d; + axisMin = axis; + } + } + + //A: +------+ + //B: +--+ + else if(AMin < BMin && BMax < AMax) { + PfxFloat d = AMin-BMax; + if(distMin < d) { + distMin = d; + axisMin = axis; + } + } + + // ■ 接触 + + // A: +----+ + // B:+----+ + else if(BMin < AMin && AMin < BMax) { + PfxFloat d = AMin-BMax; + if(distMin < d) { + distMin = d; + axisMin = axis; + } + } + + // A: +----+ + // B: +----+ + else if(AMin < BMin && BMin < AMax) { + PfxFloat d = BMin-AMax; + if(distMin < d) { + distMin = d; + axisMin = -axis; + } + } + + return false; +} + +static SCE_PFX_FORCE_INLINE +bool pfxContactTriangleBox(PfxContactCache &contacts,PfxUInt32 facetId, + const PfxVector3 &normal,const PfxVector3 &p0,const PfxVector3 &p1,const PfxVector3 &p2, + const PfxFloat thickness,const PfxFloat angle0,const PfxFloat angle1,const PfxFloat angle2, + PfxUInt32 edgeChk, + const PfxVector3 &boxHalf) +{ + const PfxFloat epsilon = 0.00001f; + + // 最も浅い貫通深度とそのときの分離軸 + PfxFloat distMin = -SCE_PFX_FLT_MAX; + PfxVector3 axisMin(0.0f); + + //------------------------------------------- + // 1.分離軸判定 + { + PfxVector3 facetPnts[6] = { + p0,p1,p2,p0-thickness*normal,p1-thickness*normal,p2-thickness*normal + }; + + PfxVector3 sideNml[3] = { + normalize(cross((facetPnts[1] - facetPnts[0]),normal)), + normalize(cross((facetPnts[2] - facetPnts[1]),normal)), + normalize(cross((facetPnts[0] - facetPnts[2]),normal)), + }; + + + // Trianglesの面 -> Box + { + // 分離軸 + const PfxVector3 sepAxis = normal; + + // 分離平面 + PfxPlane planeA(sepAxis,p0); + + // Boxを分離軸に投影して範囲を取得 + PfxFloat r = dot(boxHalf,absPerElem(sepAxis)); + PfxFloat boxOffset = planeA.onPlane(PfxVector3(0.0f)); + PfxFloat boxMax = boxOffset + r; + PfxFloat boxMin = boxOffset - r; + + // 判定 + if(boxMin > 0.0f || boxMax < -thickness) { + return false; + } + + if(distMin < boxMin) { + distMin = boxMin; + axisMin = -sepAxis; + } + } + + // Box -> Triangles + for(int bf=0;bf<3;bf++) { + // 分離軸 + PfxVector3 sepAxis(0.0f); + sepAxis[bf] = 1.0f; + + // 分離軸の方向をチェック + if(dot(normal,sepAxis) > 0.0f) + sepAxis = -sepAxis; + + // Trianglesを分離軸に投影して範囲を取得 + PfxFloat triMin,triMax; + pfxGetProjAxisPnts6(facetPnts,sepAxis,triMin,triMax); + + // Boxを分離軸に投影して範囲を取得 + PfxFloat boxMin = -boxHalf[bf]; + PfxFloat boxMax = boxHalf[bf]; + + if(checkSAT(sepAxis,triMin,triMax,boxMin,boxMax,distMin,axisMin)) { + return false; + } + } + + // エッジ Triangles面のエッジ(x3)×Boxのエッジ(x3) + for(int e=0;e<3;e++) { + PfxVector3 dir = normalize(facetPnts[(e+1)%3] - facetPnts[e]); + + for(int i=0;i<3;i++) { + PfxVector3 boxEdge(0.0f); + boxEdge[i] = 1.0f; + + // エッジが平行であれば判定しない + if(pfxIsSameDirection(dir,boxEdge)) continue; + + PfxVector3 sepAxis = normalize(cross(dir,boxEdge)); + + // 分離軸の方向をチェック + if(dot(normal,sepAxis) > 0.0f) + sepAxis = -sepAxis; + + // Trianglesを分離軸に投影して範囲を取得 + PfxFloat triMin,triMax; + pfxGetProjAxisPnts6(facetPnts,sepAxis,triMin,triMax); + + // Boxを分離軸に投影して範囲を取得 + PfxFloat r = dot(boxHalf,absPerElem(sepAxis)); + PfxFloat boxMin = -r; + PfxFloat boxMax = r; + + if(checkSAT(sepAxis,triMin,triMax,boxMin,boxMax,distMin,axisMin)) { + return false; + } + } + } + + // 面に厚みがある場合の補助的な判定(交差するかしないかだけを判定) + if(thickness > 0.0f) { + // 厚み側面の法線 + for(int i=0;i<3;i++) { + // 分離平面 + PfxPlane planeA(sideNml[i],facetPnts[i]); + + // Boxを分離軸に投影して範囲を取得 + PfxFloat r = dot(boxHalf,absPerElem(sideNml[i])); + PfxFloat boxOffset = planeA.onPlane(PfxVector3(0.0f)); + PfxFloat boxMin = boxOffset - r; + + if(boxMin > 0.0f) { + return false; + } + } + + // 2つの厚み側面のなすエッジ3×ボックスのエッジ3 + for(int e=0;e<3;e++) { + PfxVector3 edgeVec = normalize(cross(sideNml[(e+1)%3],sideNml[e])); + + for(int i=0;i<3;i++) { + PfxVector3 boxEdge(0.0f); + boxEdge[i] = 1.0f; + + // エッジが平行であれば判定しない + if(pfxIsSameDirection(edgeVec,boxEdge)) continue; + + PfxVector3 sepAxis = normalize(cross(edgeVec,boxEdge)); + + // Trianglesを分離軸に投影して範囲を取得 + PfxFloat triMin,triMax; + pfxGetProjAxisPnts3(facetPnts,sepAxis,triMin,triMax); + + // Boxを分離軸に投影して範囲を取得 + PfxFloat r = dot(boxHalf,absPerElem(sepAxis)); + PfxFloat boxMin = -r; + PfxFloat boxMax = r; + + if(triMax < boxMin || boxMax < triMin) { + return false; + } + } + } + } + } + + //------------------------------------------- + // 2.衝突点の探索 + { + // 分離軸方向に引き離す(最近接を判定するため、交差回避させる) + PfxVector3 sepAxis = 1.1f * fabsf(distMin) * axisMin; + + const PfxVector3 facetPnts[3] = { + p0 + sepAxis, + p1 + sepAxis, + p2 + sepAxis, + }; + + const PfxVector3 boxPnts[8] = { + mulPerElem(PfxVector3(-1.0f,-1.0f,-1.0f),boxHalf), + mulPerElem(PfxVector3(-1.0f,-1.0f, 1.0f),boxHalf), + mulPerElem(PfxVector3( 1.0f,-1.0f, 1.0f),boxHalf), + mulPerElem(PfxVector3( 1.0f,-1.0f,-1.0f),boxHalf), + mulPerElem(PfxVector3(-1.0f, 1.0f,-1.0f),boxHalf), + mulPerElem(PfxVector3(-1.0f, 1.0f, 1.0f),boxHalf), + mulPerElem(PfxVector3( 1.0f, 1.0f, 1.0f),boxHalf), + mulPerElem(PfxVector3( 1.0f, 1.0f,-1.0f),boxHalf), + }; + + //-------------------------------------------------------------------- + // 衝突点の探索 + + PfxClosestPoints cp; + PfxVector3 sA,sB; + + // エッジ間の最短距離と座標値を算出 + { + const int boxIds[] = { + 0,1, + 1,2, + 2,3, + 3,0, + 4,5, + 5,6, + 6,7, + 7,4, + 0,4, + 3,7, + 2,6, + 1,5, + }; + + for(int i=0;i<3;i++) { + for(int j=0;j<12;j++) { + pfxClosestTwoLines(facetPnts[i],facetPnts[(i+1)%3],boxPnts[boxIds[j*2]],boxPnts[boxIds[j*2+1]],sA,sB); + cp.add(PfxPoint3(sA),PfxPoint3(sB),lengthSqr(sA-sB)); + } + } + } + + // Triangleの頂点 -> Boxの面 + { +#ifdef SCE_PFX_USE_GEOMETRY + PfxFloatInVec sqrDist; + PfxGeomAabb aabb(PfxPoint3(0.0f),boxHalf); + { + PfxPoint3 closestPoint = sce::Geometry::Aos::closestPoint(PfxPoint3(facetPnts[0]),aabb,&sqrDist); + cp.add(PfxPoint3(facetPnts[0]),closestPoint,sqrDist); + } + { + PfxPoint3 closestPoint = sce::Geometry::Aos::closestPoint(PfxPoint3(facetPnts[1]),aabb,&sqrDist); + cp.add(PfxPoint3(facetPnts[1]),closestPoint,sqrDist); + } + { + PfxPoint3 closestPoint = sce::Geometry::Aos::closestPoint(PfxPoint3(facetPnts[2]),aabb,&sqrDist); + cp.add(PfxPoint3(facetPnts[2]),closestPoint,sqrDist); + } +#else + pfxClosestPointAABB(facetPnts[0],boxHalf,sB); + cp.add(PfxPoint3(facetPnts[0]),PfxPoint3(sB),lengthSqr(sB-facetPnts[0])); + + pfxClosestPointAABB(facetPnts[1],boxHalf,sB); + cp.add(PfxPoint3(facetPnts[1]),PfxPoint3(sB),lengthSqr(sB-facetPnts[1])); + + pfxClosestPointAABB(facetPnts[2],boxHalf,sB); + cp.add(PfxPoint3(facetPnts[2]),PfxPoint3(sB),lengthSqr(sB-facetPnts[2])); +#endif + } + + // Boxの頂点 -> Trianglesの面 + PfxTriangle triangleA(facetPnts[0],facetPnts[1],facetPnts[2]); + for(int i=0;i<8;i++) { + pfxClosestPointTriangle(boxPnts[i],triangleA,sA); + cp.add(PfxPoint3(sA),PfxPoint3(boxPnts[i]),lengthSqr(sA-boxPnts[i])); + } + + for(int i=0;im_facets[selFacets[f]]; + + PfxVector3 facetNormal = matrixBA * pfxReadVector3(facet.m_normal); + + PfxVector3 facetPntsA[3] = { + offsetBA + matrixBA * meshA->m_verts[facet.m_vertIds[0]], + offsetBA + matrixBA * meshA->m_verts[facet.m_vertIds[1]], + offsetBA + matrixBA * meshA->m_verts[facet.m_vertIds[2]], + }; + + const PfxEdge *edge[3] = { + &meshA->m_edges[facet.m_edgeIds[0]], + &meshA->m_edges[facet.m_edgeIds[1]], + &meshA->m_edges[facet.m_edgeIds[2]], + }; + + PfxUInt32 edgeChk = + ((edge[0]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x01) | + ((edge[1]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x02) | + ((edge[2]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x04); + + pfxContactTriangleBox(localContacts,selFacets[f], + facetNormal,facetPntsA[0],facetPntsA[1],facetPntsA[2], + facet.m_thickness, + 0.5f*SCE_PFX_PI*(edge[0]->m_tilt/255.0f), + 0.5f*SCE_PFX_PI*(edge[1]->m_tilt/255.0f), + 0.5f*SCE_PFX_PI*(edge[2]->m_tilt/255.0f), + edgeChk,boxB.m_half); + } + + for(int i=0;im_facets[subData.getFacetId()]; + + PfxTriangle triangleA( + meshA->m_verts[facet.m_vertIds[0]], + meshA->m_verts[facet.m_vertIds[1]], + meshA->m_verts[facet.m_vertIds[2]]); + + PfxFloat s=0.0f,t=0.0f; + pfxGetLocalCoords(PfxVector3(localContacts.getLocalPointA(i)),triangleA,s,t); + subData.m_type = PfxSubData::MESH_INFO; + subData.setFacetLocalS(s); + subData.setFacetLocalT(t); + + contacts.addContactPoint( + localContacts.getDistance(i), + transformB.getUpper3x3() * localContacts.getNormal(i), + transformAB * localContacts.getLocalPointA(i), + localContacts.getLocalPointB(i), + subData); + } + + return contacts.getNumContacts(); +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_box.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_box.h new file mode 100644 index 000000000..60584b4ef --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_box.h @@ -0,0 +1,38 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_TRI_MESH_BOX_H +#define _SCE_PFX_CONTACT_TRI_MESH_BOX_H + +#include "../../../include/physics_effects/base_level/collision/pfx_tri_mesh.h" +#include "../../../include/physics_effects/base_level/collision/pfx_box.h" +#include "pfx_contact_cache.h" + +namespace sce { +namespace PhysicsEffects { + +PfxInt32 pfxContactTriMeshBox( + PfxContactCache &contacts, + const PfxTriMesh *meshA, + const PfxTransform3 &transformA, + const PfxBox &boxB, + const PfxTransform3 &transformB, + PfxFloat distanceThreshold = SCE_PFX_FLT_MAX ); + +} // namespace PhysicsEffects +} // namespace sce + +#endif // _SCE_PFX_CONTACT_TRI_MESH_BOX_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_capsule.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_capsule.cpp new file mode 100644 index 000000000..e5fcb5049 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_capsule.cpp @@ -0,0 +1,570 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "pfx_contact_tri_mesh_capsule.h" +#include "pfx_intersect_common.h" +#include "pfx_mesh_common.h" + +namespace sce { +namespace PhysicsEffects { + +// 分離軸が見つかった場合はすぐに処理を抜けるため最短距離が返されるわけではないことに注意 + +/* + ○ カプセル分離軸(x19) + 面法線 + カプセル軸 x エッジ0 + カプセル軸 x エッジ1 + カプセル軸 x エッジ2 + ((カプセル点0-面点0) x エッジ0) x エッジ0 + ((カプセル点0-面点1) x エッジ1) x エッジ1 + ((カプセル点0-面点2) x エッジ2) x エッジ2 + ((カプセル点1-面点0) x エッジ0) x エッジ0 + ((カプセル点1-面点1) x エッジ1) x エッジ1 + ((カプセル点1-面点2) x エッジ2) x エッジ2 + ((面点0-カプセル点0) x カプセル軸) x カプセル軸 + ((面点1-カプセル点0) x カプセル軸) x カプセル軸 + ((面点2-カプセル点0) x カプセル軸) x カプセル軸 + 面点0-カプセル点0 + 面点1-カプセル点0 + 面点2-カプセル点0 + 面点0-カプセル点1 + 面点1-カプセル点1 + 面点2-カプセル点1 + */ + +static SCE_PFX_FORCE_INLINE +bool checkSAT(const PfxVector3 &axis,PfxFloat AMin,PfxFloat AMax,PfxFloat BMin,PfxFloat BMax,PfxFloat &distMin,PfxVector3 &axisMin) +{ + // ■ 非接触. + + // A: +----+ + // B:+----+ + if(BMax <= AMin) { + return true; + } + + // A:+----+ + // B: +----+ + else if(AMax <= BMin) { + return true; + } + + // ■ 内包 + + //A: +--+ + //B: +------+ + if(BMin < AMin && AMax < BMax) { + PfxFloat d = AMin-BMax; + if(distMin < d) { + distMin = d; + axisMin = axis; + } + } + + //A: +------+ + //B: +--+ + else if(AMin < BMin && BMax < AMax) { + PfxFloat d = AMin-BMax; + if(distMin < d) { + distMin = d; + axisMin = axis; + } + } + + // ■ 接触 + + // A: +----+ + // B:+----+ + else if(BMin < AMin && AMin < BMax) { + PfxFloat d = AMin-BMax; + if(distMin < d) { + distMin = d; + axisMin = axis; + } + } + + // A: +----+ + // B: +----+ + else if(AMin < BMin && BMin < AMax) { + PfxFloat d = BMin-AMax; + if(distMin < d) { + distMin = d; + axisMin = -axis; + } + } + + return false; +} + +static SCE_PFX_FORCE_INLINE +bool pfxContactTriangleCapsule(PfxContactCache &contacts,PfxUInt32 facetId, + const PfxVector3 &normal,const PfxVector3 &p0,const PfxVector3 &p1,const PfxVector3 &p2, + const PfxFloat thickness,const PfxFloat angle0,const PfxFloat angle1,const PfxFloat angle2, + PfxUInt32 edgeChk, + PfxFloat capsuleRadius,const PfxVector3 &capP0,const PfxVector3 &capP1) +{ + const PfxFloat epsilon = 0.00001f; + + // 最も浅い貫通深度とそのときの分離軸 + PfxFloat distMin = -SCE_PFX_FLT_MAX; + PfxVector3 axisMin(0.0f); + + //------------------------------------------- + // 1.分離軸判定 + { + PfxVector3 facetPnts[6] = { + p0,p1,p2,p0-thickness*normal,p1-thickness*normal,p2-thickness*normal + }; + + PfxVector3 sideNml[3] = { + normalize(cross((facetPnts[1] - facetPnts[0]),normal)), + normalize(cross((facetPnts[2] - facetPnts[1]),normal)), + normalize(cross((facetPnts[0] - facetPnts[2]),normal)), + }; + + + const PfxVector3 capPnts[2] = { + capP0,capP1 + }; + + { + const PfxVector3 &sepAxis = normal; + + // 分離平面 + PfxPlane plane(sepAxis,facetPnts[0]); + + // Capsule(B)を分離軸に投影して範囲を取得 + PfxFloat test1,test2,BMin,BMax; + test1 = plane.onPlane(capP0); + test2 = plane.onPlane(capP1); + BMax = SCE_PFX_MAX(test1,test2) + capsuleRadius; + BMin = SCE_PFX_MIN(test1,test2) - capsuleRadius; + + // 判定 + if(BMin > 0.0f || BMax < -thickness) { + return false; + } + + if(distMin < BMin) { + distMin = BMin; + axisMin = -sepAxis; + } + } + + //------------------------------------------- + // カプセル軸 x 面エッジ0,1,2 + // ※Triangles座標系 (Aローカル) + + { + for(int e=0;e<3;e++) { + PfxVector3 sepAxis = cross(capP1-capP0,facetPnts[(e+1)%3]-facetPnts[e]); + PfxFloat l=length(sepAxis); + if(l < 0.00001f) continue; + sepAxis /= l; + + if(dot(normal,sepAxis) > 0.0f) + sepAxis = -sepAxis; + + // Triangleを分離軸に投影 + PfxFloat AMin=SCE_PFX_FLT_MAX,AMax=-SCE_PFX_FLT_MAX; + pfxGetProjAxisPnts6(facetPnts,sepAxis,AMin,AMax); + + // カプセルを分離軸に投影 + PfxFloat BMin=SCE_PFX_FLT_MAX,BMax=-SCE_PFX_FLT_MAX; + pfxGetProjAxisPnts2(capPnts,sepAxis,BMin,BMax); + BMin -= capsuleRadius; + BMax += capsuleRadius; + + if(checkSAT(sepAxis,AMin,AMax,BMin,BMax,distMin,axisMin)) { + return false; + } + } + } + + //------------------------------------------- + // ((カプセル点0-面点0,1,2) x エッジ0,1,2) x エッジ0,1,2 + // ※Triangles座標系 (Aローカル) + + { + for(int e=0;e<3;e++) { + PfxVector3 edge = facetPnts[(e+1)%3]-facetPnts[e]; + PfxVector3 sepAxis = normalize(cross(cross(capP0-facetPnts[e],edge),edge)); + + if(dot(normal,sepAxis) > 0.0f) + sepAxis = -sepAxis; + + // Triangleを分離軸に投影 + PfxFloat AMin=SCE_PFX_FLT_MAX,AMax=-SCE_PFX_FLT_MAX; + pfxGetProjAxisPnts6(facetPnts,sepAxis,AMin,AMax); + + // カプセルを分離軸に投影 + PfxFloat BMin=SCE_PFX_FLT_MAX,BMax=-SCE_PFX_FLT_MAX; + pfxGetProjAxisPnts2(capPnts,sepAxis,BMin,BMax); + BMin -= capsuleRadius; + BMax += capsuleRadius; + + if(checkSAT(sepAxis,AMin,AMax,BMin,BMax,distMin,axisMin)) { + return false; + } + } + } + + //------------------------------------------- + // ((カプセル点1-面点0,1,2) x エッジ0,1,2) x エッジ0,1,2 + // ※Triangles座標系 (Aローカル) + + { + for(int e=0;e<3;e++) { + PfxVector3 edge = facetPnts[(e+1)%3]-facetPnts[e]; + PfxVector3 sepAxis = normalize(cross(cross(capP1-facetPnts[e],edge),edge)); + + if(dot(normal,sepAxis) > 0.0f) + sepAxis = -sepAxis; + + // Triangleを分離軸に投影 + PfxFloat AMin=SCE_PFX_FLT_MAX,AMax=-SCE_PFX_FLT_MAX; + pfxGetProjAxisPnts6(facetPnts,sepAxis,AMin,AMax); + + // カプセルを分離軸に投影 + PfxFloat BMin=SCE_PFX_FLT_MAX,BMax=-SCE_PFX_FLT_MAX; + pfxGetProjAxisPnts2(capPnts,sepAxis,BMin,BMax); + BMin -= capsuleRadius; + BMax += capsuleRadius; + + if(checkSAT(sepAxis,AMin,AMax,BMin,BMax,distMin,axisMin)) { + return false; + } + } + } + + //------------------------------------------- + // ((面点0,1,2-カプセル点0) x カプセル軸) x カプセル軸 + // ※Triangles座標系 (Aローカル) + + { + for(int e=0;e<3;e++) { + PfxVector3 capdir = capP1-capP0; + PfxVector3 sepAxis = cross(cross(facetPnts[e]-capP0,capdir),capdir); + PfxFloat l=length(sepAxis); + if(l < 0.00001f) continue; + sepAxis /= l; + + if(dot(normal,sepAxis) > 0.0f) + sepAxis = -sepAxis; + + // Triangleを分離軸に投影 + PfxFloat AMin=SCE_PFX_FLT_MAX,AMax=-SCE_PFX_FLT_MAX; + pfxGetProjAxisPnts6(facetPnts,sepAxis,AMin,AMax); + + // カプセルを分離軸に投影 + PfxFloat BMin=SCE_PFX_FLT_MAX,BMax=-SCE_PFX_FLT_MAX; + pfxGetProjAxisPnts2(capPnts,sepAxis,BMin,BMax); + BMin -= capsuleRadius; + BMax += capsuleRadius; + + if(checkSAT(sepAxis,AMin,AMax,BMin,BMax,distMin,axisMin)) { + return false; + } + } + } + + //------------------------------------------- + // 面点0,1,2-カプセル点0 + // ※Triangles座標系 (Aローカル) + + { + for(int e=0;e<3;e++) { + PfxVector3 sepAxis = normalize(facetPnts[e]-capP0); + + // Triangleを分離軸に投影 + PfxFloat AMin=SCE_PFX_FLT_MAX,AMax=-SCE_PFX_FLT_MAX; + pfxGetProjAxisPnts6(facetPnts,sepAxis,AMin,AMax); + + // カプセルを分離軸に投影 + PfxFloat BMin=SCE_PFX_FLT_MAX,BMax=-SCE_PFX_FLT_MAX; + pfxGetProjAxisPnts2(capPnts,sepAxis,BMin,BMax); + BMin -= capsuleRadius; + BMax += capsuleRadius; + + if(checkSAT(sepAxis,AMin,AMax,BMin,BMax,distMin,axisMin)) { + return false; + } + } + } + + //------------------------------------------- + // 面点0,1,2-カプセル点1 + // ※Triangles座標系 (Aローカル) + + { + for(int e=0;e<3;e++) { + PfxVector3 sepAxis = normalize(facetPnts[e]-capP1); + + // Triangleを分離軸に投影 + PfxFloat AMin=SCE_PFX_FLT_MAX,AMax=-SCE_PFX_FLT_MAX; + pfxGetProjAxisPnts6(facetPnts,sepAxis,AMin,AMax); + + // カプセルを分離軸に投影 + PfxFloat BMin=SCE_PFX_FLT_MAX,BMax=-SCE_PFX_FLT_MAX; + pfxGetProjAxisPnts2(capPnts,sepAxis,BMin,BMax); + BMin -= capsuleRadius; + BMax += capsuleRadius; + + if(checkSAT(sepAxis,AMin,AMax,BMin,BMax,distMin,axisMin)) { + return false; + } + } + } + + // 面に厚みがある場合の補助的な判定(面法線 x カプセル軸) + // 交差するかしないかだけを判定 + if(thickness > 0.0f) { + // 厚み側面の法線 + for(int i=0;i<3;i++) { + // 分離平面 + PfxPlane plane(sideNml[i],facetPnts[i]); + + // カプセルを分離軸に投影して範囲を取得 + PfxFloat test1,test2,BMin; + test1 = plane.onPlane(capP0); + test2 = plane.onPlane(capP1); + BMin = SCE_PFX_MIN(test1,test2) - capsuleRadius; + + if(BMin > 0.0f) { + return false; + } + } + + // 2つの厚み側面のなすエッジ3×カプセル軸 + for(int e=0;e<3;e++) { + PfxVector3 edgeVec = normalize(cross(sideNml[(e+1)%3],sideNml[e])); + PfxVector3 capVec = capP1-capP0; + + // エッジが平行であれば判定しない + if(pfxIsSameDirection(edgeVec,capVec)) continue; + + PfxVector3 sepAxis = normalize(cross(edgeVec,capVec)); + + // Trianglesを分離軸に投影して範囲を取得 + PfxFloat triMin,triMax; + pfxGetProjAxisPnts3(facetPnts,sepAxis,triMin,triMax); + + // カプセルを分離軸に投影して範囲を取得 + PfxFloat BMin=SCE_PFX_FLT_MAX,BMax=-SCE_PFX_FLT_MAX; + pfxGetProjAxisPnts2(capPnts,sepAxis,BMin,BMax); + BMin -= capsuleRadius; + BMax += capsuleRadius; + + if(triMax < BMin || BMax < triMin) { + return false; + } + } + } + } + + //------------------------------------------- + // 2.衝突点の探索 + + { + // 分離軸方向に引き離す(最近接を判定するため、交差回避させる) + PfxVector3 sepAxis = 1.1f * fabsf(distMin) * axisMin; + + const PfxVector3 facetPnts[3] = { + p0 + sepAxis, + p1 + sepAxis, + p2 + sepAxis, + }; + + //-------------------------------------------------------------------- + // 衝突点の探索 + + PfxClosestPoints cp; + PfxVector3 sA,sB; + + //-------------------------------------------------------------------- + //Triangleの頂点 -> Capsule + + // カプセルの線分と面のエッジx3の最近接点の算出 +#ifdef SCE_PFX_USE_GEOMETRY + PfxGeomSegment segmentC((PfxPoint3)capP0,(PfxPoint3)capP1); + + { + PfxGeomSegment segmentF((PfxPoint3)facetPnts[0],(PfxPoint3)facetPnts[1]); + PfxPoint3 closestPointA,closestPointB; + PfxFloatInVec sqrDist = closestPoints(segmentC,segmentF,closestPointB,closestPointA); + cp.add(closestPointA,closestPointB + normalize(closestPointA-closestPointB)*capsuleRadius,sqrDist); + } + { + PfxGeomSegment segmentF((PfxPoint3)facetPnts[1],(PfxPoint3)facetPnts[2]); + PfxPoint3 closestPointA,closestPointB; + PfxFloatInVec sqrDist = closestPoints(segmentC,segmentF,closestPointB,closestPointA); + cp.add(closestPointA,closestPointB + normalize(closestPointA-closestPointB)*capsuleRadius,sqrDist); + } + { + PfxGeomSegment segmentF((PfxPoint3)facetPnts[2],(PfxPoint3)facetPnts[0]); + PfxPoint3 closestPointA,closestPointB; + PfxFloatInVec sqrDist = closestPoints(segmentC,segmentF,closestPointB,closestPointA); + cp.add(closestPointA,closestPointB + normalize(closestPointA-closestPointB)*capsuleRadius,sqrDist); + } +#else + pfxClosestTwoLines(capP0,capP1,facetPnts[0],facetPnts[1],sB,sA); + cp.add(PfxPoint3(sA),PfxPoint3(sB + normalize(sA-sB)*capsuleRadius),lengthSqr(sA-sB)); + + pfxClosestTwoLines(capP0,capP1,facetPnts[1],facetPnts[2],sB,sA); + cp.add(PfxPoint3(sA),PfxPoint3(sB + normalize(sA-sB)*capsuleRadius),lengthSqr(sA-sB)); + + pfxClosestTwoLines(capP0,capP1,facetPnts[2],facetPnts[0],sB,sA); + cp.add(PfxPoint3(sA),PfxPoint3(sB + normalize(sA-sB)*capsuleRadius),lengthSqr(sA-sB)); +#endif + + // カプセルの端点と面の最近接点の算出 + PfxTriangle triangleA(facetPnts[0],facetPnts[1],facetPnts[2]); + pfxClosestPointTriangle(capP0,triangleA,sA); + cp.add(PfxPoint3(sA),PfxPoint3(capP0+normalize(sA-capP0)*capsuleRadius),lengthSqr(sA-capP0)); + + pfxClosestPointTriangle(capP1,triangleA,sA); + cp.add(PfxPoint3(sA),PfxPoint3(capP1+normalize(sA-capP1)*capsuleRadius),lengthSqr(sA-capP1)); + + for(int i=0;im_facets[selFacets[f]]; + + PfxVector3 facetNormal = matrixBA * pfxReadVector3(facet.m_normal); + + PfxVector3 facetPntsA[3] = { + offsetBA + matrixBA * meshA->m_verts[facet.m_vertIds[0]], + offsetBA + matrixBA * meshA->m_verts[facet.m_vertIds[1]], + offsetBA + matrixBA * meshA->m_verts[facet.m_vertIds[2]], + }; + + const PfxEdge *edge[3] = { + &meshA->m_edges[facet.m_edgeIds[0]], + &meshA->m_edges[facet.m_edgeIds[1]], + &meshA->m_edges[facet.m_edgeIds[2]], + }; + + PfxUInt32 edgeChk = + ((edge[0]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x01) | + ((edge[1]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x02) | + ((edge[2]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x04); + + pfxContactTriangleCapsule(localContacts,selFacets[f], + facetNormal,facetPntsA[0],facetPntsA[1],facetPntsA[2], + facet.m_thickness, + 0.5f*SCE_PFX_PI*(edge[0]->m_tilt/255.0f), + 0.5f*SCE_PFX_PI*(edge[1]->m_tilt/255.0f), + 0.5f*SCE_PFX_PI*(edge[2]->m_tilt/255.0f), + edgeChk,capsuleB.m_radius,vCapAB[0],vCapAB[1]); + } + + for(int i=0;im_facets[subData.getFacetId()]; + + PfxTriangle triangleA( + meshA->m_verts[facet.m_vertIds[0]], + meshA->m_verts[facet.m_vertIds[1]], + meshA->m_verts[facet.m_vertIds[2]]); + + PfxFloat s=0.0f,t=0.0f; + pfxGetLocalCoords(PfxVector3(localContacts.getLocalPointA(i)),triangleA,s,t); + subData.m_type = PfxSubData::MESH_INFO; + subData.setFacetLocalS(s); + subData.setFacetLocalT(t); + + contacts.addContactPoint( + localContacts.getDistance(i), + transformB.getUpper3x3() * localContacts.getNormal(i), + transformAB * localContacts.getLocalPointA(i), + localContacts.getLocalPointB(i), + subData); + } + + return contacts.getNumContacts(); +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_capsule.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_capsule.h new file mode 100644 index 000000000..9e392ffee --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_capsule.h @@ -0,0 +1,39 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_TRI_MESH_CAPSULE_H +#define _SCE_PFX_CONTACT_TRI_MESH_CAPSULE_H + +#include "../../../include/physics_effects/base_level/collision/pfx_tri_mesh.h" +#include "../../../include/physics_effects/base_level/collision/pfx_capsule.h" +#include "pfx_contact_cache.h" + +namespace sce { +namespace PhysicsEffects { + +PfxInt32 pfxContactTriMeshCapsule( + PfxContactCache &contacts, + const PfxTriMesh *meshA, + const PfxTransform3 &transformA, + const PfxCapsule &capsuleB, + const PfxTransform3 &transformB, + PfxFloat distanceThreshold = SCE_PFX_FLT_MAX ); + + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_CONTACT_TRI_MESH_CAPSULE_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_convex.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_convex.cpp new file mode 100644 index 000000000..545186ffe --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_convex.cpp @@ -0,0 +1,167 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "pfx_contact_tri_mesh_convex.h" +#include "pfx_intersect_common.h" +#include "pfx_mesh_common.h" +#include "pfx_gjk_solver.h" +#include "pfx_gjk_support_func.h" + +namespace sce { +namespace PhysicsEffects { + + +static SCE_PFX_FORCE_INLINE +bool pfxContactTriangleConvex(PfxContactCache &contacts,PfxUInt32 facetId, + const PfxVector3 &normal,const PfxVector3 &p0,const PfxVector3 &p1,const PfxVector3 &p2, + const PfxFloat thickness,const PfxFloat angle0,const PfxFloat angle1,const PfxFloat angle2, + PfxUInt32 edgeChk, + const PfxConvexMesh &convex) +{ + PfxVector3 facetPnts[6] = { + p0,p1,p2,p0-thickness*normal,p1-thickness*normal,p2-thickness*normal + }; + + + PfxPoint3 pA(0.0f),pB(0.0f); + PfxVector3 nml(0.0f); + PfxGjkSolver gjk; + + gjk.setup((void*)facetPnts,(void*)&convex,pfxGetSupportVertexTriangleWithThickness,pfxGetSupportVertexConvex); + PfxFloat d = gjk.collide(nml,pA,pB,PfxTransform3::identity(),PfxTransform3::identity(),SCE_PFX_FLT_MAX); + if(d >= 0.0f) return false; + + PfxVector3 pointsOnTriangle = PfxVector3(pA); + PfxVector3 pointsOnConvex = PfxVector3(pB); + PfxVector3 axis = nml; + + // 面上の最近接点が凸エッジ上でない場合は法線を変える + if( ((edgeChk&0x01)&&pfxPointOnLine(pointsOnTriangle,p0,p1)) || + ((edgeChk&0x02)&&pfxPointOnLine(pointsOnTriangle,p1,p2)) || + ((edgeChk&0x04)&&pfxPointOnLine(pointsOnTriangle,p2,p0)) ) { + axis=-normal; + } + + PfxSubData subData; + subData.setFacetId(facetId); + contacts.addContactPoint(-length(pointsOnTriangle-pointsOnConvex),axis,pA,pB,subData); + + return true; +} + +PfxInt32 pfxContactTriMeshConvex( + PfxContactCache &contacts, + const PfxTriMesh *meshA, + const PfxTransform3 &transformA, + const PfxConvexMesh &convexB, + const PfxTransform3 &transformB, + PfxFloat distanceThreshold) +{ + (void) distanceThreshold; + + PfxTransform3 transformAB, transformBA; + PfxMatrix3 matrixBA; + PfxVector3 offsetBA; + + // Bローカル→Aローカルへの変換. + transformAB = orthoInverse(transformA) * transformB; + + // Aローカル→Bローカルへの変換. + transformBA = orthoInverse(transformAB); + + matrixBA = transformBA.getUpper3x3(); + offsetBA = transformBA.getTranslation(); + + //------------------------------------------- + // 判定する面を絞り込む. + + PfxUInt8 SCE_PFX_ALIGNED(16) selFacets[SCE_PFX_NUMMESHFACETS] = { 0 }; + PfxUInt32 numSelFacets = 0; + + // ※convexB座標系 + PfxVector3 aabbB(convexB.m_half); + numSelFacets = pfxGatherFacets(meshA,(PfxFloat*)&aabbB,offsetBA,matrixBA,selFacets); + + if(numSelFacets == 0) { + return 0; + } + + //------------------------------------------- + // 面ごとに衝突を検出 + + PfxContactCache localContacts; + + for(PfxUInt32 f = 0; f < numSelFacets; f++) { + const PfxFacet &facet = meshA->m_facets[selFacets[f]]; + + PfxVector3 facetNormal = matrixBA * pfxReadVector3(facet.m_normal); + + PfxVector3 facetPntsA[3] = { + offsetBA + matrixBA * meshA->m_verts[facet.m_vertIds[0]], + offsetBA + matrixBA * meshA->m_verts[facet.m_vertIds[1]], + offsetBA + matrixBA * meshA->m_verts[facet.m_vertIds[2]], + }; + + const PfxEdge *edge[3] = { + &meshA->m_edges[facet.m_edgeIds[0]], + &meshA->m_edges[facet.m_edgeIds[1]], + &meshA->m_edges[facet.m_edgeIds[2]], + }; + + PfxUInt32 edgeChk = + ((edge[0]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x01) | + ((edge[1]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x02) | + ((edge[2]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x04); + + pfxContactTriangleConvex(localContacts,selFacets[f], + facetNormal,facetPntsA[0],facetPntsA[1],facetPntsA[2], + facet.m_thickness, + 0.5f*SCE_PFX_PI*(edge[0]->m_tilt/255.0f), + 0.5f*SCE_PFX_PI*(edge[1]->m_tilt/255.0f), + 0.5f*SCE_PFX_PI*(edge[2]->m_tilt/255.0f), + edgeChk,convexB); + } + + for(int i=0;im_facets[subData.getFacetId()]; + + PfxTriangle triangleA( + meshA->m_verts[facet.m_vertIds[0]], + meshA->m_verts[facet.m_vertIds[1]], + meshA->m_verts[facet.m_vertIds[2]]); + + PfxFloat s=0.0f,t=0.0f; + pfxGetLocalCoords(PfxVector3(localContacts.getLocalPointA(i)),triangleA,s,t); + subData.m_type = PfxSubData::MESH_INFO; + subData.setFacetLocalS(s); + subData.setFacetLocalT(t); + + contacts.addContactPoint( + localContacts.getDistance(i), + transformB.getUpper3x3() * localContacts.getNormal(i), + transformAB * localContacts.getLocalPointA(i), + localContacts.getLocalPointB(i), + subData); + } + + return contacts.getNumContacts(); +} +} //namespace PhysicsEffects +} //namespace sce + diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_convex.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_convex.h new file mode 100644 index 000000000..e653670df --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_convex.h @@ -0,0 +1,37 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_TRI_MESH_CONVEX_H +#define _SCE_PFX_CONTACT_TRI_MESH_CONVEX_H + +#include "../../../include/physics_effects/base_level/collision/pfx_tri_mesh.h" +#include "pfx_contact_cache.h" + +namespace sce { +namespace PhysicsEffects { + +PfxInt32 pfxContactTriMeshConvex( + PfxContactCache &contacts, + const PfxTriMesh *meshA, + const PfxTransform3 &transformA, + const PfxConvexMesh &convexB, + const PfxTransform3 &transformB, + PfxFloat distanceThreshold = SCE_PFX_FLT_MAX ); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_CONTACT_TRI_MESH_CONVEX_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_cylinder.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_cylinder.cpp new file mode 100644 index 000000000..608e99c17 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_cylinder.cpp @@ -0,0 +1,165 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "pfx_contact_tri_mesh_cylinder.h" +#include "pfx_intersect_common.h" +#include "pfx_mesh_common.h" +#include "pfx_gjk_solver.h" +#include "pfx_gjk_support_func.h" + +namespace sce { +namespace PhysicsEffects { + +static SCE_PFX_FORCE_INLINE +bool pfxContactTriangleCylinder(PfxContactCache &contacts,PfxUInt32 facetId, + const PfxVector3 &normal,const PfxVector3 &p0,const PfxVector3 &p1,const PfxVector3 &p2, + const PfxFloat thickness,const PfxFloat angle0,const PfxFloat angle1,const PfxFloat angle2, + PfxUInt32 edgeChk, + const PfxCylinder &cylinder) +{ + PfxVector3 facetPnts[6] = { + p0,p1,p2,p0-thickness*normal,p1-thickness*normal,p2-thickness*normal + }; + + + PfxPoint3 pA(0.0f),pB(0.0f); + PfxVector3 nml(0.0f); + PfxGjkSolver gjk; + + gjk.setup((void*)facetPnts,(void*)&cylinder,pfxGetSupportVertexTriangleWithThickness,pfxGetSupportVertexCylinder); + PfxFloat d = gjk.collide(nml,pA,pB,PfxTransform3::identity(),PfxTransform3::identity(),SCE_PFX_FLT_MAX); + if(d >= 0.0f) return false; + + PfxVector3 pointsOnTriangle = PfxVector3(pA); + PfxVector3 pointsOnConvex = PfxVector3(pB); + PfxVector3 axis = nml; + + // 面上の最近接点が凸エッジ上でない場合は法線を変える + if( ((edgeChk&0x01)&&pfxPointOnLine(pointsOnTriangle,p0,p1)) || + ((edgeChk&0x02)&&pfxPointOnLine(pointsOnTriangle,p1,p2)) || + ((edgeChk&0x04)&&pfxPointOnLine(pointsOnTriangle,p2,p0)) ) { + axis=-normal; + } + + PfxSubData subData; + subData.setFacetId(facetId); + contacts.addContactPoint(-length(pointsOnTriangle-pointsOnConvex),axis,pA,pB,subData); + + return true; +} + +PfxInt32 pfxContactTriMeshCylinder( + PfxContactCache &contacts, + const PfxTriMesh *meshA, + const PfxTransform3 &transformA, + const PfxCylinder &cylinderB, + const PfxTransform3 &transformB, + PfxFloat distanceThreshold) +{ + (void) distanceThreshold; + + PfxTransform3 transformAB, transformBA; + PfxMatrix3 matrixBA; + PfxVector3 offsetBA; + + // Bローカル→Aローカルへの変換. + transformAB = orthoInverse(transformA) * transformB; + + // Aローカル→Bローカルへの変換. + transformBA = orthoInverse(transformAB); + + matrixBA = transformBA.getUpper3x3(); + offsetBA = transformBA.getTranslation(); + + //------------------------------------------- + // 判定する面を絞り込む. + + PfxUInt8 SCE_PFX_ALIGNED(16) selFacets[SCE_PFX_NUMMESHFACETS] = { 0 }; + PfxUInt32 numSelFacets = 0; + + // ※cylinderB座標系 + PfxVector3 aabbB(cylinderB.m_halfLen,cylinderB.m_radius,cylinderB.m_radius); + numSelFacets = pfxGatherFacets(meshA,(PfxFloat*)&aabbB,offsetBA,matrixBA,selFacets); + + if(numSelFacets == 0) { + return 0; + } + + //------------------------------------------- + // 面ごとに衝突を検出 + + PfxContactCache localContacts; + + for(PfxUInt32 f = 0; f < numSelFacets; f++) { + const PfxFacet &facet = meshA->m_facets[selFacets[f]]; + + PfxVector3 facetNormal = matrixBA * pfxReadVector3(facet.m_normal); + + PfxVector3 facetPntsA[3] = { + offsetBA + matrixBA * meshA->m_verts[facet.m_vertIds[0]], + offsetBA + matrixBA * meshA->m_verts[facet.m_vertIds[1]], + offsetBA + matrixBA * meshA->m_verts[facet.m_vertIds[2]], + }; + + const PfxEdge *edge[3] = { + &meshA->m_edges[facet.m_edgeIds[0]], + &meshA->m_edges[facet.m_edgeIds[1]], + &meshA->m_edges[facet.m_edgeIds[2]], + }; + + PfxUInt32 edgeChk = + ((edge[0]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x01) | + ((edge[1]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x02) | + ((edge[2]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x04); + + pfxContactTriangleCylinder(localContacts,selFacets[f], + facetNormal,facetPntsA[0],facetPntsA[1],facetPntsA[2], + facet.m_thickness, + 0.5f*SCE_PFX_PI*(edge[0]->m_tilt/255.0f), + 0.5f*SCE_PFX_PI*(edge[1]->m_tilt/255.0f), + 0.5f*SCE_PFX_PI*(edge[2]->m_tilt/255.0f), + edgeChk,cylinderB); + } + + for(int i=0;im_facets[subData.getFacetId()]; + + PfxTriangle triangleA( + meshA->m_verts[facet.m_vertIds[0]], + meshA->m_verts[facet.m_vertIds[1]], + meshA->m_verts[facet.m_vertIds[2]]); + + PfxFloat s=0.0f,t=0.0f; + pfxGetLocalCoords(PfxVector3(localContacts.getLocalPointA(i)),triangleA,s,t); + subData.m_type = PfxSubData::MESH_INFO; + subData.setFacetLocalS(s); + subData.setFacetLocalT(t); + + contacts.addContactPoint( + localContacts.getDistance(i), + transformB.getUpper3x3() * localContacts.getNormal(i), + transformAB * localContacts.getLocalPointA(i), + localContacts.getLocalPointB(i), + subData); + } + + return contacts.getNumContacts(); +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_cylinder.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_cylinder.h new file mode 100644 index 000000000..5d9c9dbd3 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_cylinder.h @@ -0,0 +1,38 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_TRI_MESH_CYLINDER_H +#define _SCE_PFX_CONTACT_TRI_MESH_CYLINDER_H + +#include "../../../include/physics_effects/base_level/collision/pfx_tri_mesh.h" +#include "../../../include/physics_effects/base_level/collision/pfx_cylinder.h" +#include "pfx_contact_cache.h" + +namespace sce { +namespace PhysicsEffects { + +PfxInt32 pfxContactTriMeshCylinder( + PfxContactCache &contacts, + const PfxTriMesh *meshA, + const PfxTransform3 &transformA, + const PfxCylinder &cylinderB, + const PfxTransform3 &transformB, + PfxFloat distanceThreshold = SCE_PFX_FLT_MAX ); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_CONTACT_TRI_MESH_CYLINDER_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_sphere.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_sphere.cpp new file mode 100644 index 000000000..39d248b27 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_sphere.cpp @@ -0,0 +1,239 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "pfx_contact_tri_mesh_sphere.h" +#include "pfx_intersect_common.h" +#include "pfx_mesh_common.h" + +namespace sce { +namespace PhysicsEffects { + +static SCE_PFX_FORCE_INLINE +bool pfxContactTriangleSphere(PfxContactCache &contacts,PfxUInt32 facetId, + const PfxVector3 &normal,const PfxVector3 &p0,const PfxVector3 &p1,const PfxVector3 &p2, + const PfxFloat thickness,const PfxFloat angle0,const PfxFloat angle1,const PfxFloat angle2, + PfxUInt32 edgeChk, + PfxFloat sphereRadius,const PfxVector3 &spherePos) +{ + PfxVector3 facetPnts[3] = { + p0,p1,p2, + }; + + // 早期判定 + { + PfxPlane planeA(normal,p0); + PfxFloat len1 = planeA.onPlane(spherePos); + + if(len1 >= sphereRadius || len1 < -thickness-sphereRadius) return false; + + } + + // 球と面の最近接点を計算 + { + PfxTriangle triangleA(p0,p1,p2); + PfxVector3 pntA; + // pfxClosestPointTriangle(spherePos,triangleA,pntA); + bool insideTriangle = false; + while(1) { + PfxVector3 ab = p1 - p0; + PfxVector3 ac = p2 - p0; + PfxVector3 ap = spherePos - p0; + PfxFloat d1 = dot(ab, ap); + PfxFloat d2 = dot(ac, ap); + if(d1 <= 0.0f && d2 <= 0.0f) { + pntA = p0; + break; + } + + PfxVector3 bp = spherePos - p1; + PfxFloat d3 = dot(ab, bp); + PfxFloat d4 = dot(ac, bp); + if (d3 >= 0.0f && d4 <= d3) { + pntA = p1; + break; + } + + PfxFloat vc = d1*d4 - d3*d2; + if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) { + PfxFloat v = d1 / (d1 - d3); + pntA = p0 + v * ab; + break; + } + + PfxVector3 cp = spherePos - p2; + PfxFloat d5 = dot(ab, cp); + PfxFloat d6 = dot(ac, cp); + if (d6 >= 0.0f && d5 <= d6) { + pntA = p2; + break; + } + + PfxFloat vb = d5*d2 - d1*d6; + if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) { + PfxFloat w = d2 / (d2 - d6); + pntA = p0 + w * ac; + break; + } + + PfxFloat va = d3*d6 - d5*d4; + if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) { + PfxFloat w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); + pntA = p1 + w * (p2 - p1); + break; + } + + PfxFloat den = 1.0f / (va + vb + vc); + PfxFloat v = vb * den; + PfxFloat w = vc * den; + pntA = p0 + ab * v + ac * w; + insideTriangle = true; + break; + } + PfxVector3 distVec = pntA - spherePos; + PfxFloat l = length(distVec); + + if(!insideTriangle && l >= sphereRadius) return false; + + // 分離軸 + PfxVector3 sepAxis = (l < 0.00001f || insideTriangle) ? -normal : distVec / l; + + // 球上の衝突点 + PfxVector3 pointsOnSphere = spherePos + sphereRadius * sepAxis; + PfxVector3 pointsOnTriangle = pntA; + + // 面上の最近接点が凸エッジ上でない場合は法線を変える + if( ((edgeChk&0x01)&&pfxPointOnLine(pointsOnTriangle,p0,p1)) || + ((edgeChk&0x02)&&pfxPointOnLine(pointsOnTriangle,p1,p2)) || + ((edgeChk&0x04)&&pfxPointOnLine(pointsOnTriangle,p2,p0)) ) { + sepAxis=-normal; + } + + PfxSubData subData; + subData.setFacetId(facetId); + contacts.addContactPoint(-length(pointsOnSphere-pointsOnTriangle),sepAxis,PfxPoint3(pointsOnTriangle),PfxPoint3(pointsOnSphere),subData); + } + + return true; +} + +PfxInt32 pfxContactTriMeshSphere( + PfxContactCache &contacts, + const PfxTriMesh *meshA, + const PfxTransform3 &transformA, + const PfxSphere &sphereB, + const PfxTransform3 &transformB, + PfxFloat distanceThreshold) +{ + (void) distanceThreshold; + + PfxTransform3 transformAB,transformBA; + PfxMatrix3 matrixBA; + PfxVector3 offsetBA; + + // Bローカル→Aローカルへの変換 + transformAB = orthoInverse(transformA) * transformB; + + // Aローカル→Bローカルへの変換 + transformBA = orthoInverse(transformAB); + + matrixBA = transformBA.getUpper3x3(); + offsetBA = transformBA.getTranslation(); + + //------------------------------------------- + // 判定する面を絞り込む + + PfxUInt8 SCE_PFX_ALIGNED(16) selFacets[SCE_PFX_NUMMESHFACETS] = {0}; + PfxUInt32 numSelFacets = 0; + + PfxVector3 aabbB(sphereB.m_radius); + numSelFacets = pfxGatherFacets(meshA,(PfxFloat*)&aabbB,offsetBA,matrixBA,selFacets); + + if(numSelFacets == 0) { + return 0; + } + + //----------------------------------------------- + // 判定 + + PfxContactCache localContacts; + + // TriangleMeshの面->sphereの判定 + // ※TriangleMesh座標系 + { + for(PfxUInt32 f = 0; f < numSelFacets; f++ ) { + const PfxFacet &facet = meshA->m_facets[selFacets[f]]; + + const PfxVector3 facetNormal = pfxReadVector3(facet.m_normal); + + const PfxVector3 facetPnts[3] = { + meshA->m_verts[facet.m_vertIds[0]], + meshA->m_verts[facet.m_vertIds[1]], + meshA->m_verts[facet.m_vertIds[2]], + }; + + const PfxEdge *edge[3] = { + &meshA->m_edges[facet.m_edgeIds[0]], + &meshA->m_edges[facet.m_edgeIds[1]], + &meshA->m_edges[facet.m_edgeIds[2]], + }; + + PfxVector3 sepAxis,pntA,pntB; + + PfxUInt32 edgeChk = + ((edge[0]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x01) | + ((edge[1]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x02) | + ((edge[2]->m_angleType==SCE_PFX_EDGE_CONVEX)?0x00:0x04); + + pfxContactTriangleSphere(localContacts,selFacets[f], + facetNormal,facetPnts[0],facetPnts[1],facetPnts[2], + facet.m_thickness, + 0.5f*SCE_PFX_PI*(edge[0]->m_tilt/255.0f), + 0.5f*SCE_PFX_PI*(edge[1]->m_tilt/255.0f), + 0.5f*SCE_PFX_PI*(edge[2]->m_tilt/255.0f), + edgeChk, + sphereB.m_radius,transformAB.getTranslation()); + } + } + + for(int i=0;im_facets[subData.getFacetId()]; + + PfxTriangle triangleA( + meshA->m_verts[facet.m_vertIds[0]], + meshA->m_verts[facet.m_vertIds[1]], + meshA->m_verts[facet.m_vertIds[2]]); + + PfxFloat s=0.0f,t=0.0f; + pfxGetLocalCoords(PfxVector3(localContacts.getLocalPointA(i)),triangleA,s,t); + subData.m_type = PfxSubData::MESH_INFO; + subData.setFacetLocalS(s); + subData.setFacetLocalT(t); + + contacts.addContactPoint( + localContacts.getDistance(i), + transformA.getUpper3x3() * localContacts.getNormal(i), + localContacts.getLocalPointA(i), + transformBA * localContacts.getLocalPointB(i), + subData); + } + + return contacts.getNumContacts(); +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_sphere.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_sphere.h new file mode 100644 index 000000000..5dc3bba50 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_contact_tri_mesh_sphere.h @@ -0,0 +1,38 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONTACT_TRI_MESH_SPHERE_H +#define _SCE_PFX_CONTACT_TRI_MESH_SPHERE_H + +#include "../../../include/physics_effects/base_level/collision/pfx_tri_mesh.h" +#include "../../../include/physics_effects/base_level/collision/pfx_sphere.h" +#include "pfx_contact_cache.h" + +namespace sce { +namespace PhysicsEffects { + +PfxInt32 pfxContactTriMeshSphere( + PfxContactCache &contacts, + const PfxTriMesh *meshA, + const PfxTransform3 &transformA, + const PfxSphere &sphereB, + const PfxTransform3 &transformB, + PfxFloat distanceThreshold = SCE_PFX_FLT_MAX ); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_CONTACT_TRI_MESH_SPHERE_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_gjk_solver.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_gjk_solver.cpp new file mode 100644 index 000000000..e7c4c2403 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_gjk_solver.cpp @@ -0,0 +1,485 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "pfx_gjk_solver.h" +#include "pfx_intersect_common.h" + + +namespace sce { +namespace PhysicsEffects { + + +template +struct PfxGjkStack { + int cur; + T data[maxData]; + + PfxGjkStack() : cur(0) {} + + void push(const T &d) + { + SCE_PFX_ASSERT(cur gs; + + gs.push(PfxGjkEdge(facet,i)); + + do { + PfxGjkEdge stk = gs.pop(); + PfxGjkFacet *ft = stk.f; + + if(ft->obsolete==0) { + // wから見えるかどうかを判定 + if(dot(ft->normal,w-ft->closest) < 0.0f) { + // 見えないのでエッジを登録 + SCE_PFX_ASSERT(numEdges<=(int)MAX_FACETS); + edges[numEdges] = stk; + numEdges++; + } + else { + ft->obsolete = 1; + gs.push(PfxGjkEdge(ft->adj[(stk.i+2)%3],ft->j[(stk.i+2)%3])); + gs.push(PfxGjkEdge(ft->adj[(stk.i+1)%3],ft->j[(stk.i+1)%3])); + } + } + } while(SCE_PFX_UNLIKELY(!gs.isEmpty())); +} + +/////////////////////////////////////////////////////////////////////////////// +// Detect Penetration Depth (EPA) + +PfxFloat PfxGjkSolver::detectPenetrationDepth( + const PfxTransform3 &transformA,const PfxTransform3 &transformB, + PfxVector3 &pA,PfxVector3 &pB,PfxVector3 &normal) +{ + PfxMatrix3 invRotA = transpose(transformA.getUpper3x3()); + PfxMatrix3 invRotB = transpose(transformB.getUpper3x3()); + + int epaIterationCount = 0; + PfxFloat distance = SCE_PFX_FLT_MAX; + + numFacets = 0; + numFacetsHead = 0; + + // 初期状態の判定 + if(m_simplex.numVertices <= 1) { + return distance; + } + else if(m_simplex.numVertices == 2) { + PfxVector3 v0 = m_simplex.W[0]; + PfxVector3 v1 = m_simplex.W[1]; + PfxVector3 dir = normalize(v1-v0); + PfxMatrix3 rot = PfxMatrix3::rotation(2.0943951023932f,dir);//120 deg + int axis; + if(dir[0] < dir[1]) { + if(dir[0] < dir[2]) { + axis = 0; + } + else { + axis = 2; + } + } + else { + if(dir[1] < dir[2]) { + axis = 1; + } + else { + axis = 2; + } + } + PfxVector3 vec(0.0f); + vec[axis] = 1.0f; + + PfxVector3 aux[3]; + aux[0] = cross(dir,vec); + aux[1] = rot * aux[0]; + aux[2] = rot * aux[1]; + + PfxVector3 p[3],q[3],w[3]; + + for(int i=0;i<3;i++) { + PfxVector3 pInA,qInB; + getSupportVertexShapeA(shapeA,invRotA * aux[i],pInA); + getSupportVertexShapeB(shapeB,invRotB * (-aux[i]),qInB); + p[i] = transformA.getTranslation() + transformA.getUpper3x3() * pInA; + q[i] = transformB.getTranslation() + transformB.getUpper3x3() * qInB; + w[i] = p[i] - q[i]; + vertsP[i] = p[i]; + vertsQ[i] = q[i]; + vertsW[i] = w[i]; + } + + if(originInTetrahedron(w[0],w[1],w[2],v0)) { + vertsP[3] = m_simplex.P[0]; + vertsQ[3] = m_simplex.Q[0]; + vertsW[3] = m_simplex.W[0]; + numVerts = 4; + } + else if(originInTetrahedron(w[0],w[1],w[2],v1)){ + vertsP[3] = m_simplex.P[1]; + vertsQ[3] = m_simplex.Q[1]; + vertsW[3] = m_simplex.W[1]; + numVerts = 4; + } + else { + return distance; + } + } + else if(m_simplex.numVertices == 3) { + numVerts = 3; + for(int i=0;i 0.0f) { + PfxVector3 vertsP1,vertsQ1,vertsW1; + PfxVector3 vertsP3,vertsQ3,vertsW3; + vertsQ1=vertsQ[1];vertsW1=vertsW[1];vertsP1=vertsP[1]; + vertsQ3=vertsQ[3];vertsW3=vertsW[3];vertsP3=vertsP[3]; + vertsQ[1]=vertsQ3;vertsW[1]=vertsW3;vertsP[1]=vertsP3; + vertsQ[3]=vertsQ1;vertsW[3]=vertsW1;vertsP[3]=vertsP1; + } + + { + PfxGjkFacet *f0 = addFacet(0,1,2); + PfxGjkFacet *f1 = addFacet(0,3,1); + PfxGjkFacet *f2 = addFacet(0,2,3); + PfxGjkFacet *f3 = addFacet(1,3,2); + + if(SCE_PFX_UNLIKELY(!f0 || !f1 || !f2 || !f3)) return distance; + + linkFacets(f0,0,f1,2); + linkFacets(f0,1,f3,2); + linkFacets(f0,2,f2,0); + linkFacets(f1,0,f2,2); + linkFacets(f1,1,f3,0); + linkFacets(f2,1,f3,1); + } + + // 探索 + PfxGjkFacet *facetMin = NULL; + + do { + // 原点から一番近い点を算出し、そのベクトルと支点を返す + int minFacetIdx = 0; + { + PfxFloat minDistSqr = SCE_PFX_FLT_MAX; + for(int i=0;iobsolete==0 && facetsHead[i]->distSqr < minDistSqr) { + minDistSqr = facetsHead[i]->distSqr; + facetMin = facetsHead[i]; + minFacetIdx = i; + } + } + } + + // リストからはずす + facetsHead[minFacetIdx] = facetsHead[--numFacetsHead]; + + PfxVector3 pInA(0.0f),qInB(0.0f); + getSupportVertexShapeA(shapeA,invRotA * facetMin->normal,pInA); + getSupportVertexShapeB(shapeB,invRotB * (-facetMin->normal),qInB); + PfxVector3 p = transformA.getTranslation() + transformA.getUpper3x3() * pInA; + PfxVector3 q = transformB.getTranslation() + transformB.getUpper3x3() * qInB; + PfxVector3 w = p - q; + PfxVector3 v = facetMin->closest; + + // 最近接点チェック + PfxFloat l0 = length(v); + PfxFloat l1 = dot(facetMin->normal,w); + + if((l1 - l0) < SCE_PFX_GJK_EPSILON) { + break; + } + + // 求めた点を追加して面を分割 + { + SCE_PFX_ASSERT(numVerts<(int)MAX_VERTS); + int vId = numVerts++; + vertsP[vId] = p; + vertsQ[vId] = q; + vertsW[vId] = w; + + facetMin->obsolete = 1; + + numEdges = 0; + + silhouette(facetMin->adj[0],facetMin->j[0],w); + silhouette(facetMin->adj[1],facetMin->j[1],w); + silhouette(facetMin->adj[2],facetMin->j[2],w); + + if(SCE_PFX_UNLIKELY(numEdges == 0)) break; + + bool edgeCheck = true; + PfxGjkFacet *firstFacet,*lastFacet; + { + PfxGjkEdge &edge = edges[0]; + int v0 = edge.f->v[(edge.i+1)%3]; + int v1 = edge.f->v[edge.i]; + firstFacet = addFacet(v0,v1,vId); + if(SCE_PFX_UNLIKELY(!firstFacet)) { + edgeCheck = false; + break; + } + linkFacets(edge.f,edge.i,firstFacet,0); + lastFacet = firstFacet; + } + + if(SCE_PFX_UNLIKELY(!edgeCheck)) break; + + for(int e=1;ev[(edge.i+1)%3]; + int v1 = edge.f->v[edge.i]; + PfxGjkFacet *f = addFacet(v0,v1,vId); + if(SCE_PFX_UNLIKELY(!f)) {edgeCheck=false;break;} + linkFacets(edge.f,edge.i,f,0); + linkFacets(f,2,lastFacet,1); + lastFacet = f; + } + if(SCE_PFX_UNLIKELY(!edgeCheck)) break; + + linkFacets(lastFacet,1,firstFacet,2); + } + + epaIterationCount++; + if(SCE_PFX_UNLIKELY(epaIterationCount > SCE_PFX_EPA_ITERATION_MAX || numFacetsHead == 0)) { + break; + } + } while(1); + + // 衝突点計算 + int v1 = facetMin->v[0]; + int v2 = facetMin->v[1]; + int v3 = facetMin->v[2]; + + PfxVector3 p0 = vertsW[v2]-vertsW[v1]; + PfxVector3 p1 = vertsW[v3]-vertsW[v1]; + PfxVector3 p2 = facetMin->closest-vertsW[v1]; + + PfxVector3 v = cross( p0, p1 ); + PfxVector3 crS = cross( v, p0 ); + PfxVector3 crT = cross( v, p1 ); + PfxFloat d0 = dot( crT, p0 ); + PfxFloat d1 = dot( crS, p1 ); + + if(fabsf(d0) < SCE_PFX_GJK_EPSILON || fabsf(d1) < SCE_PFX_GJK_EPSILON) return distance; + + PfxFloat lamda1 = dot( crT, p2 ) / d0; + PfxFloat lamda2 = dot( crS, p2 ) / d1; + + pA = vertsP[v1] + lamda1*(vertsP[v2]-vertsP[v1]) + lamda2*(vertsP[v3]-vertsP[v1]); + pB = vertsQ[v1] + lamda1*(vertsQ[v2]-vertsQ[v1]) + lamda2*(vertsQ[v3]-vertsQ[v1]); + + PfxFloat lenSqr = lengthSqr(pB-pA); + normal = normalize(pB-pA); + + return -sqrtf(lenSqr); +} + +/////////////////////////////////////////////////////////////////////////////// +// Gjk + +PfxFloat PfxGjkSolver::collide( PfxVector3& normal, PfxPoint3 &pointA, PfxPoint3 &pointB, + const PfxTransform3 & transformA, + const PfxTransform3 & transformB, + PfxFloat distanceThreshold) +{ + (void) distanceThreshold; + + int gjkIterationCount = 0; + + m_simplex.reset(); + + PfxTransform3 cTransformA = transformA; + PfxTransform3 cTransformB = transformB; + PfxMatrix3 invRotA = transpose(cTransformA.getUpper3x3()); + PfxMatrix3 invRotB = transpose(cTransformB.getUpper3x3()); + + PfxVector3 offset = (cTransformA.getTranslation() + cTransformB.getTranslation())*0.5f; + cTransformA.setTranslation(cTransformA.getTranslation()-offset); + cTransformB.setTranslation(cTransformB.getTranslation()-offset); + + PfxVector3 separatingAxis(-cTransformA.getTranslation()); + if(lengthSqr(separatingAxis) < 0.000001f) separatingAxis = PfxVector3(1.0,0.0,0.0); + PfxFloat squaredDistance = SCE_PFX_FLT_MAX; + PfxFloat delta = 0.0f; + PfxFloat distance = SCE_PFX_FLT_MAX; + + for(;;) { + // サポート頂点の取得 + PfxVector3 pInA,qInB; + + getSupportVertexShapeA(shapeA,invRotA * (-separatingAxis),pInA); + getSupportVertexShapeB(shapeB,invRotB * separatingAxis,qInB); + + PfxVector3 p = cTransformA.getTranslation() + cTransformA.getUpper3x3() * pInA; + PfxVector3 q = cTransformB.getTranslation() + cTransformB.getUpper3x3() * qInB; + PfxVector3 w = p - q; + + delta = dot(separatingAxis,w); + + // 早期終了チェック + if(SCE_PFX_UNLIKELY(delta > 0.0f)) { + normal = separatingAxis; + return distance; + } + + if(SCE_PFX_UNLIKELY(m_simplex.inSimplex(w))) { + break; + } + + PfxFloat f0 = squaredDistance - delta; + PfxFloat f1 = squaredDistance * SCE_PFX_GJK_EPSILON; + + if (SCE_PFX_UNLIKELY(f0 <= f1)) { + break; + } + + // 頂点を単体に追加 + m_simplex.addVertex(w,p,q); + + // 原点と単体の最近接点を求め、分離軸を返す + if(SCE_PFX_UNLIKELY(!m_simplex.closest(separatingAxis))) { + normal = separatingAxis; + return distance; + } + + squaredDistance = lengthSqr(separatingAxis); + + if(SCE_PFX_UNLIKELY(gjkIterationCount >= SCE_PFX_GJK_ITERATION_MAX || m_simplex.fullSimplex())) { + break; + } + + gjkIterationCount++; + } + + PfxVector3 pA(0.0f),pB(0.0f); + + // 2つのConvexは交差しているので、接触点を探索する + PfxFloat dist = detectPenetrationDepth(cTransformA,cTransformB,pA,pB,normal); + + //マージン考慮 + if(dist < 0.0f) { + pA += normal * SCE_PFX_GJK_MARGIN; + pB -= normal * SCE_PFX_GJK_MARGIN; + dist = dot(normal,pA-pB); + pointA = orthoInverse(transformA)*PfxPoint3(pA+offset); + pointB = orthoInverse(transformB)*PfxPoint3(pB+offset); + } + + return dist; +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_gjk_solver.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_gjk_solver.h new file mode 100644 index 000000000..9d980a3a7 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_gjk_solver.h @@ -0,0 +1,190 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_GJK_SOLVER_H +#define _SCE_PFX_GJK_SOLVER_H + +#include "../../../include/physics_effects/base_level/base/pfx_common.h" +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "pfx_simplex_solver.h" + +namespace sce { +namespace PhysicsEffects { + +#define SCE_PFX_GJK_EPSILON 1e-04f +#define SCE_PFX_GJK_MARGIN 0.025f +#define SCE_PFX_GJK_ITERATION_MAX 10 +#define SCE_PFX_EPA_ITERATION_MAX 10 + +/////////////////////////////////////////////////////////////////////////////// +// Support Function + +typedef void (*PfxGetSupportVertexFunc)(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex); + +/////////////////////////////////////////////////////////////////////////////// +// Gjk +class PfxSimplexSolver; + +class PfxGjkSolver +{ +private: + static const PfxUInt32 MAX_VERTS = 128; + static const PfxUInt32 MAX_EDGES = 128; + static const PfxUInt32 MAX_FACETS = 64; + + PfxSimplexSolver m_simplex; + + // 面 + struct PfxGjkFacet { + PfxVector3 normal; // 面の法線 + PfxVector3 closest; // 原点からの最短ベクトル + PfxUInt32 obsolete; // 廃棄面判定 + PfxFloat distSqr; // 原点からの距離 + PfxInt32 v[3]; // 頂点 + PfxInt32 j[3]; // 隣接面から見たIndex + PfxGjkFacet *adj[3]; // 隣接面 + SCE_PFX_PADDING(1,4) + }; + + // エッジ + struct PfxGjkEdge { + PfxGjkFacet *f; + PfxInt32 i; + PfxGjkEdge() {} + PfxGjkEdge(PfxGjkFacet *f_,PfxInt32 i_) + { + f = f_; + i= i_; + } + }; + + PfxVector3 g_vertsP[MAX_VERTS]; + PfxVector3 g_vertsQ[MAX_VERTS]; + PfxVector3 g_vertsW[MAX_VERTS]; + PfxGjkFacet g_facets[MAX_FACETS]; + PfxGjkFacet *g_facetsHead[MAX_FACETS]; + PfxGjkEdge g_edges[MAX_EDGES]; + + PfxVector3 SCE_PFX_ALIGNED(16) *vertsP; + SCE_PFX_PADDING(1,12) + PfxVector3 SCE_PFX_ALIGNED(16) *vertsQ; + SCE_PFX_PADDING(2,12) + PfxVector3 SCE_PFX_ALIGNED(16) *vertsW; + SCE_PFX_PADDING(3,12) + PfxGjkFacet SCE_PFX_ALIGNED(16) *facets; + SCE_PFX_PADDING(4,12) + PfxGjkFacet SCE_PFX_ALIGNED(16) **facetsHead; + SCE_PFX_PADDING(5,12) + PfxGjkEdge SCE_PFX_ALIGNED(16) *edges; + + int numVerts; + int numEdges; + int numFacets; + int numFacetsHead; + SCE_PFX_PADDING(6,12) + + inline PfxGjkFacet *addFacet(int v1,int v2,int v3); + + inline void linkFacets(PfxGjkFacet *f1,int e1,PfxGjkFacet *f2,int e2); + void silhouette(PfxGjkFacet *facet,int i,PfxVector3 &w); + + inline bool originInTetrahedron(const PfxVector3& p0,const PfxVector3& p1,const PfxVector3& p2,const PfxVector3& p3); + + PfxFloat detectPenetrationDepth( + const PfxTransform3 &transformA,const PfxTransform3 &transformB, + PfxVector3 &pA,PfxVector3 &pB,PfxVector3 &normal); + + void *shapeA; + void *shapeB; + PfxGetSupportVertexFunc getSupportVertexShapeA; + PfxGetSupportVertexFunc getSupportVertexShapeB; + +public: + PfxGjkSolver(); + ~PfxGjkSolver(); + + void setup(void *sA,void *sB,PfxGetSupportVertexFunc fA,PfxGetSupportVertexFunc fB); + + PfxFloat collide( PfxVector3& normal, PfxPoint3 &pointA, PfxPoint3 &pointB, + const PfxTransform3 & transformA, + const PfxTransform3 & transformB, + PfxFloat distanceThreshold = SCE_PFX_FLT_MAX); +}; + +inline +PfxGjkSolver::PfxGjkFacet *PfxGjkSolver::addFacet(int v1,int v2,int v3) +{ + if(SCE_PFX_UNLIKELY(numFacets == (int)MAX_FACETS)) + return NULL; + + PfxGjkFacet &facet = facets[numFacets]; + + PfxVector3 V1 = vertsW[v1]; + PfxVector3 V2 = vertsW[v2]; + PfxVector3 V3 = vertsW[v3]; + facet.obsolete = 0; + facet.v[0] = v1; + facet.v[1] = v2; + facet.v[2] = v3; + + PfxVector3 normal = cross(V3-V1,V2-V1); + + PfxFloat l = lengthSqr(normal); + + if(l < SCE_PFX_GJK_EPSILON * SCE_PFX_GJK_EPSILON) { + return NULL; + } + + normal /= sqrtf(l); + facet.closest = dot(V1,normal)*normal; + facet.normal =normal; + + facet.distSqr = lengthSqr(facet.closest); + + facetsHead[numFacetsHead++] = &facet; + numFacets++; + + return &facet; +} + +inline +void PfxGjkSolver::linkFacets(PfxGjkFacet *f1,int e1,PfxGjkFacet *f2,int e2) +{ + f1->adj[e1] = f2; + f2->adj[e2] = f1; + f1->j[e1] = e2; + f2->j[e2] = e1; +} + +inline +bool PfxGjkSolver::originInTetrahedron(const PfxVector3& p0,const PfxVector3& p1,const PfxVector3& p2,const PfxVector3& p3) +{ + PfxVector3 n0 = cross((p1-p0),(p2-p0)); + PfxVector3 n1 = cross((p2-p1),(p3-p1)); + PfxVector3 n2 = cross((p3-p2),(p0-p2)); + PfxVector3 n3 = cross((p0-p3),(p1-p3)); + + return + dot(n0,p0) * dot(n0,p3-p0) <= 0.0f && + dot(n1,p1) * dot(n1,p0-p1) <= 0.0f && + dot(n2,p2) * dot(n2,p1-p2) <= 0.0f && + dot(n3,p3) * dot(n3,p2-p3) <= 0.0f; +} + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_GJK_SOLVER_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_gjk_support_func.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_gjk_support_func.cpp new file mode 100644 index 000000000..b252b3f87 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_gjk_support_func.cpp @@ -0,0 +1,134 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "pfx_gjk_support_func.h" +#include "../../../include/physics_effects/base_level/collision/pfx_tri_mesh.h" +#include "../../../include/physics_effects/base_level/collision/pfx_box.h" +#include "../../../include/physics_effects/base_level/collision/pfx_capsule.h" +#include "../../../include/physics_effects/base_level/collision/pfx_cylinder.h" +#include "../../../include/physics_effects/base_level/collision/pfx_sphere.h" + +namespace sce { +namespace PhysicsEffects { + +#define SCE_PFX_GJK_MARGIN 0.025f + +/////////////////////////////////////////////////////////////////////////////// +// Support Function + +void pfxGetSupportVertexTriangle(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex) +{ + PfxVector3 *vtx = (PfxVector3*)shape; + +PfxFloat d0 = dot(vtx[0],seperatingAxis); +PfxFloat d1 = dot(vtx[1],seperatingAxis); +PfxFloat d2 = dot(vtx[2],seperatingAxis); + +int reti = 2; + +if(d0 > d1 && d0 > d2) { + reti = 0; +} +else if(d1 > d2) { + reti = 1; +} + + supportVertex = vtx[reti] + SCE_PFX_GJK_MARGIN * normalize(seperatingAxis); +} + +void pfxGetSupportVertexTriangleWithThickness(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex) +{ + PfxVector3 *vtx = (PfxVector3*)shape; + +PfxFloat d[6]; +d[0] = dot(vtx[0],seperatingAxis); +d[1] = dot(vtx[1],seperatingAxis); +d[2] = dot(vtx[2],seperatingAxis); +d[3] = dot(vtx[3],seperatingAxis); +d[4] = dot(vtx[4],seperatingAxis); +d[5] = dot(vtx[5],seperatingAxis); + +int reti = 0; +for(int i=1;i<6;i++) { + if(d[reti] < d[i]) { + reti = i; + } +} + + supportVertex = vtx[reti] + SCE_PFX_GJK_MARGIN * normalize(seperatingAxis); +} + +void pfxGetSupportVertexConvex(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex) +{ + PfxConvexMesh *mesh = (PfxConvexMesh*)shape; + int reti = 0; +PfxFloat dmax = dot(mesh->m_verts[0],seperatingAxis); +for(int i=1;im_numVerts;i++) { + PfxFloat d = dot(mesh->m_verts[i],seperatingAxis); + if(d > dmax) { + dmax =d; + reti = i; + } +} + supportVertex = mesh->m_verts[reti] + SCE_PFX_GJK_MARGIN * normalize(seperatingAxis); +} + +void pfxGetSupportVertexBox(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex) +{ + PfxBox *box = (PfxBox*)shape; + PfxVector3 boxHalf = box->m_half + PfxVector3(SCE_PFX_GJK_MARGIN); + supportVertex[0] = seperatingAxis[0]>0.0f?boxHalf[0]:-boxHalf[0]; + supportVertex[1] = seperatingAxis[1]>0.0f?boxHalf[1]:-boxHalf[1]; + supportVertex[2] = seperatingAxis[2]>0.0f?boxHalf[2]:-boxHalf[2]; +} + +void pfxGetSupportVertexCapsule(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex) +{ + PfxCapsule *capsule = (PfxCapsule*)shape; + PfxVector3 u(1.0f,0.0f,0.0f); + + PfxFloat udotv = dot(seperatingAxis,u); + PfxVector3 dir = u * (udotv > 0.0f ? capsule->m_halfLen : -capsule->m_halfLen); + supportVertex = dir + normalize(seperatingAxis) * (capsule->m_radius + SCE_PFX_GJK_MARGIN); +} + +void pfxGetSupportVertexSphere(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex) +{ + PfxSphere *sphere = (PfxSphere*)shape; + supportVertex = normalize(seperatingAxis) * (sphere->m_radius + SCE_PFX_GJK_MARGIN); +} + +void pfxGetSupportVertexCylinder(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex) +{ + PfxCylinder *cylinder = (PfxCylinder*)shape; + PfxVector3 u(1.0f,0.0f,0.0f); + + PfxFloat udotv = dot(seperatingAxis,u); + PfxFloat s = seperatingAxis[1]*seperatingAxis[1]+seperatingAxis[2]*seperatingAxis[2]; + if(s < 0.000001f) { + supportVertex = u * (udotv > 0.0f ? cylinder->m_halfLen + SCE_PFX_GJK_MARGIN : -cylinder->m_halfLen-SCE_PFX_GJK_MARGIN); + } + else { + PfxVector3 dir = u * (udotv > 0.0f ? cylinder->m_halfLen : -cylinder->m_halfLen); + PfxVector3 vYZ = seperatingAxis; + vYZ[0] = 0.0f; + vYZ /= sqrtf(s); + supportVertex = dir + vYZ * (cylinder->m_radius) + normalize(seperatingAxis) * SCE_PFX_GJK_MARGIN; + } +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_gjk_support_func.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_gjk_support_func.h new file mode 100644 index 000000000..b7ede87bf --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_gjk_support_func.h @@ -0,0 +1,36 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_GJK_SUPPORT_FUNC_H +#define _SCE_PFX_GJK_SUPPORT_FUNC_H + +namespace sce { +namespace PhysicsEffects { + +#include "../../../include/physics_effects/base_level/base/pfx_common.h" + +void pfxGetSupportVertexTriangle(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex); +void pfxGetSupportVertexTriangleWithThickness(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex); +void pfxGetSupportVertexConvex(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex); +void pfxGetSupportVertexBox(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex); +void pfxGetSupportVertexCapsule(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex); +void pfxGetSupportVertexSphere(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex); +void pfxGetSupportVertexCylinder(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_GJK_SUPPORT_FUNC_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_common.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_common.h new file mode 100644 index 000000000..b7cfd752b --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_common.h @@ -0,0 +1,427 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_INTERSECT_COMMON_H +#define _SCE_PFX_INTERSECT_COMMON_H + +#include "../../../include/physics_effects/base_level/collision/pfx_ray.h" + +namespace sce { +namespace PhysicsEffects { + +#define SCE_PFX_INTERSECT_COMMON_EPSILON 0.00001f +#define SCE_PFX_RAY_TRIANGLE_EPSILON 0.00001f + +// Internally used intersect functions + +struct PfxTriangle +{ + PfxVector3 points[3]; + + PfxTriangle(const PfxVector3 &p0,const PfxVector3 &p1,const PfxVector3 &p2) + { + points[0] = p0; + points[1] = p1; + points[2] = p2; + } +}; + +struct PfxPlane +{ + PfxVector3 normal; // normal + PfxVector3 point; // point on the plane + + PfxPlane(const PfxVector3 &n,const PfxVector3 &q) + { + normal = n; + point = q; + } + + PfxPlane(const PfxTriangle &triangle) + { + normal = normalize(cross(triangle.points[1]-triangle.points[0],triangle.points[2]-triangle.points[0])); + point = triangle.points[0]; + } + + PfxFloat onPlane(const PfxVector3 &p) const + { + return dot((p-point),normal); + } +}; + +static SCE_PFX_FORCE_INLINE +PfxBool pfxIntersectRayAABBFast( + const PfxVector3 &rayStartPosition, + const PfxVector3 &rayDirection, + const PfxVector3 &AABBcenter, + const PfxVector3 &AABBhalf, + PfxFloat &variable) +{ + PfxVector3 AABBmin = AABBcenter - AABBhalf; + PfxVector3 AABBmax = AABBcenter + AABBhalf; + + PfxVector3 dir = rayDirection; + PfxVector3 absDir = absPerElem(dir); + PfxVector3 sign = copySignPerElem(PfxVector3(1.0),dir); + +if(absDir[0] < SCE_PFX_INTERSECT_COMMON_EPSILON) { + if(rayStartPosition[0] < AABBmin[0] || rayStartPosition[0] > AABBmax[0]) { + return false; + } + dir[0] = sign[0] * SCE_PFX_INTERSECT_COMMON_EPSILON; +} + +if(absDir[1] < SCE_PFX_INTERSECT_COMMON_EPSILON) { + if(rayStartPosition[1] < AABBmin[1] || rayStartPosition[1] > AABBmax[1]) { + return false; + } + dir[1] = sign[1] * SCE_PFX_INTERSECT_COMMON_EPSILON; +} + +if(absDir[2] < SCE_PFX_INTERSECT_COMMON_EPSILON) { + if(rayStartPosition[2] < AABBmin[2] || rayStartPosition[2] > AABBmax[2]) { + return false; + } + dir[2] = sign[2] * SCE_PFX_INTERSECT_COMMON_EPSILON; +} + + PfxVector3 t1 = divPerElem(AABBmin - rayStartPosition, dir); + PfxVector3 t2 = divPerElem(AABBmax - rayStartPosition, dir); + + PfxVector3 tmin = minPerElem(t1,t2); + PfxVector3 tmax = maxPerElem(t1,t2); + +if(maxElem(tmin) > minElem(tmax)) return false; + +if(tmin[0] > tmin[1]) { + if(tmin[0] > tmin[2]) { + variable = tmin[0]; + } + else { + variable = tmin[2]; + } +} +else { + if(tmin[1] > tmin[2]) { + variable = tmin[1]; + } + else { + variable = tmin[2]; + } +} + + return true; +} + +static SCE_PFX_FORCE_INLINE +PfxBool pfxIntersectRayAABB( + const PfxVector3 &rayStartPosition, + const PfxVector3 &rayDirection, + const PfxVector3 &AABBcenter, + const PfxVector3 &AABBhalf, + PfxFloat &variable, + PfxVector3 &normal) +{ + PfxVector3 AABBmin = AABBcenter - AABBhalf; + PfxVector3 AABBmax = AABBcenter + AABBhalf; + + PfxVector3 dir = rayDirection; + PfxVector3 absDir = absPerElem(dir); + PfxVector3 sign = copySignPerElem(PfxVector3(1.0),dir); + + // 始点がBoxの内側にあるか判定 + if( AABBmin[0] < rayStartPosition[0] && rayStartPosition[0] < AABBmax[0] && + AABBmin[1] < rayStartPosition[1] && rayStartPosition[1] < AABBmax[1] && + AABBmin[2] < rayStartPosition[2] && rayStartPosition[2] < AABBmax[2]) { + return false; + } + +if(absDir[0] < SCE_PFX_INTERSECT_COMMON_EPSILON) { + if(rayStartPosition[0] < AABBmin[0] || rayStartPosition[0] > AABBmax[0]) { + return false; + } + dir[0] = sign[0] * SCE_PFX_INTERSECT_COMMON_EPSILON; +} + +if(absDir[1] < SCE_PFX_INTERSECT_COMMON_EPSILON) { + if(rayStartPosition[1] < AABBmin[1] || rayStartPosition[1] > AABBmax[1]) { + return false; + } + dir[1] = sign[1] * SCE_PFX_INTERSECT_COMMON_EPSILON; +} + +if(absDir[2] < SCE_PFX_INTERSECT_COMMON_EPSILON) { + if(rayStartPosition[2] < AABBmin[2] || rayStartPosition[2] > AABBmax[2]) { + return false; + } + dir[2] = sign[2] * SCE_PFX_INTERSECT_COMMON_EPSILON; +} + + PfxVector3 t1 = divPerElem(AABBmin - rayStartPosition, dir); + PfxVector3 t2 = divPerElem(AABBmax - rayStartPosition, dir); + + PfxVector3 tmin = minPerElem(t1,t2); + PfxVector3 tmax = maxPerElem(t1,t2); + + normal = PfxVector3(0); + +if(maxElem(tmin) > minElem(tmax)) return false; + +if(tmin[0] > tmin[1]) { + if(tmin[0] > tmin[2]) { + variable = tmin[0]; + normal[0] = -sign[0]; + } + else { + variable = tmin[2]; + normal[2] = -sign[2]; + } +} +else { + if(tmin[1] > tmin[2]) { + variable = tmin[1]; + normal[1] = -sign[1]; + } + else { + variable = tmin[2]; + normal[2] = -sign[2]; + } +} + + return true; +} + +static SCE_PFX_FORCE_INLINE +void pfxClosestTwoLines( + const PfxVector3 &p1,const PfxVector3 &q1, // line1 + const PfxVector3 &p2,const PfxVector3 &q2, // line2 + PfxVector3 &s1,PfxVector3 &s2) +{ + PfxVector3 v1 = q1-p1; + PfxVector3 v2 = q2-p2; + PfxVector3 r = p1 - p2; + + PfxFloat a = dot(v1,v1); + PfxFloat e = dot(v2,v2); + PfxFloat f = dot(v2,r); + PfxFloat b = dot(v1,v2); + PfxFloat c = dot(v1,r); + PfxFloat den = a*e-b*b; + + PfxFloat s,t; + + if(den != 0.0f) { + s = SCE_PFX_CLAMP((b*f-c*e)/den,0.0f,1.0f); + } + else { + s = 0.0f; + } + + t = (b*s+f)/e; + + if(t < 0.0f) { + t = 0.0f; + s = SCE_PFX_CLAMP(-c/a,0.0f,1.0f); + } + else if(t > 1.0f) { + t = 1.0f; + s = SCE_PFX_CLAMP((b-c)/a,0.0f,1.0f); + } + + s1 = p1 + s * v1; + s2 = p2 + t * v2; +} + +static SCE_PFX_FORCE_INLINE +void pfxClosestPointAABB( + const PfxVector3 &point, + const PfxVector3 &AABBhalf, + PfxVector3 &s) +{ + s = point; + s = maxPerElem(s,-AABBhalf); + s = minPerElem(s,AABBhalf); +} + +static SCE_PFX_FORCE_INLINE +void pfxClosestPointTriangle( + const PfxVector3 &point, + const PfxTriangle &triangle, + PfxVector3 &s) +{ + PfxVector3 a = triangle.points[0]; + PfxVector3 b = triangle.points[1]; + PfxVector3 c = triangle.points[2]; + PfxVector3 ab = b - a; + PfxVector3 ac = c - a; + PfxVector3 ap = point - a; + PfxFloat d1 = dot(ab, ap); + PfxFloat d2 = dot(ac, ap); + if(d1 <= 0.0f && d2 <= 0.0f) { + s = a; + return; + } + + PfxVector3 bp = point - b; + PfxFloat d3 = dot(ab, bp); + PfxFloat d4 = dot(ac, bp); + if (d3 >= 0.0f && d4 <= d3) { + s = b; + return; + } + + PfxFloat vc = d1*d4 - d3*d2; + if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) { + PfxFloat v = d1 / (d1 - d3); + s = a + v * ab; + return; + } + + PfxVector3 cp = point - c; + PfxFloat d5 = dot(ab, cp); + PfxFloat d6 = dot(ac, cp); + if (d6 >= 0.0f && d5 <= d6) { + s = c; + return; + } + + PfxFloat vb = d5*d2 - d1*d6; + if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) { + PfxFloat w = d2 / (d2 - d6); + s = a + w * ac; + return; + } + + PfxFloat va = d3*d6 - d5*d4; + if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) { + PfxFloat w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); + s = b + w * (c - b); + return; + } + + PfxFloat den = 1.0f / (va + vb + vc); + PfxFloat v = vb * den; + PfxFloat w = vc * den; + s = a + ab * v + ac * w; +} + +static SCE_PFX_FORCE_INLINE +PfxBool pfxIntersectRayTriangle( + const PfxVector3 &rayStartPosition, + const PfxVector3 &rayDirection, + const PfxTriangle &triangle, + PfxFloat &variable) +{ + PfxFloat v,w; + PfxVector3 ab = triangle.points[1] - triangle.points[0]; + PfxVector3 ac = triangle.points[2] - triangle.points[0]; + + PfxVector3 n = cross(ab,ac); + + PfxFloat d = dot(-rayDirection,n); + + if(fabsf(d) < 0.00001f) return false; + + PfxVector3 ap = rayStartPosition - triangle.points[0]; + PfxFloat t = dot(ap,n) / d; + + if(t <= 0.0f || t >= 1.0f) return false; + + variable = t; + + PfxVector3 e = cross(-rayDirection,ap); + v = dot(ac,e) / d; + if(v < -SCE_PFX_RAY_TRIANGLE_EPSILON || v > 1.0f+SCE_PFX_RAY_TRIANGLE_EPSILON) return false; + + w = -dot(ab,e) / d; + if(w < -SCE_PFX_RAY_TRIANGLE_EPSILON || v+w > 1.0f+SCE_PFX_RAY_TRIANGLE_EPSILON) return false; + + return true; +} + +static SCE_PFX_FORCE_INLINE +PfxBool pfxIntersectRayTriangleWithoutFrontFace( + const PfxVector3 &rayStartPosition, + const PfxVector3 &rayDirection, + const PfxTriangle &triangle, + PfxFloat &variable) +{ + PfxFloat v,w; + PfxVector3 ab = triangle.points[1] - triangle.points[0]; + PfxVector3 ac = triangle.points[2] - triangle.points[0]; + + PfxVector3 n = cross(ab,ac); + + PfxFloat d = dot(-rayDirection,n); + + if(d >= 0.0f) return false; + + PfxVector3 ap = rayStartPosition - triangle.points[0]; + PfxFloat t = dot(ap,n) / d; + + if(t <= 0.0f || t >= 1.0f) return false; + + variable = t; + + PfxVector3 e = cross(-rayDirection,ap); + v = dot(ac,e) / d; + if(v < -SCE_PFX_RAY_TRIANGLE_EPSILON || v > 1.0f+SCE_PFX_RAY_TRIANGLE_EPSILON) return false; + + w = -dot(ab,e) / d; + if(w < -SCE_PFX_RAY_TRIANGLE_EPSILON || v+w > 1.0f+SCE_PFX_RAY_TRIANGLE_EPSILON) return false; + + return true; +} + +static SCE_PFX_FORCE_INLINE +PfxBool pfxIntersectRayTriangleWithoutBackFace( + const PfxVector3 &rayStartPosition, + const PfxVector3 &rayDirection, + const PfxTriangle &triangle, + PfxFloat &variable) +{ + PfxFloat v,w; + PfxVector3 ab = triangle.points[1] - triangle.points[0]; + PfxVector3 ac = triangle.points[2] - triangle.points[0]; + + PfxVector3 n = cross(ab,ac); + + PfxFloat d = dot(-rayDirection,n); + + if(d <= 0.0f) return false; + + PfxVector3 ap = rayStartPosition - triangle.points[0]; + PfxFloat t = dot(ap,n) / d; + + if(t <= 0.0f || t >= 1.0f) return false; + + variable = t; + + PfxVector3 e = cross(-rayDirection,ap); + v = dot(ac,e) / d; + if(v < -SCE_PFX_RAY_TRIANGLE_EPSILON || v > 1.0f+SCE_PFX_RAY_TRIANGLE_EPSILON) return false; + + w = -dot(ab,e) / d; + if(w < -SCE_PFX_RAY_TRIANGLE_EPSILON || v+w > 1.0f+SCE_PFX_RAY_TRIANGLE_EPSILON) return false; + + return true; +} + +} //namespace PhysicsEffects +} //namespace sce + + +#endif // _SCE_PFX_INTERSECT_COMMON_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_box.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_box.cpp new file mode 100644 index 000000000..9d109f208 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_box.cpp @@ -0,0 +1,47 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "pfx_intersect_common.h" +#include "pfx_intersect_ray_box.h" + +namespace sce { +namespace PhysicsEffects { + +PfxBool pfxIntersectRayBox(const PfxRayInput &ray,PfxRayOutput &out,const PfxBox &box,const PfxTransform3 &transform) +{ + // レイをBoxのローカル座標へ変換 + PfxTransform3 transformBox = orthoInverse(transform); + PfxVector3 rayStartPosition = transformBox.getUpper3x3() * ray.m_startPosition + transformBox.getTranslation(); + PfxVector3 rayDirection = transformBox.getUpper3x3() * ray.m_direction; + + // 交差判定 + PfxFloat tmpVariable=0.0f; + PfxVector3 tmpNormal(0.0f); + if(pfxIntersectRayAABB(rayStartPosition,rayDirection,PfxVector3(0.0f),box.m_half,tmpVariable,tmpNormal)) { + if(tmpVariable > 0.0f && tmpVariable < out.m_variable) { + out.m_contactFlag = true; + out.m_variable = tmpVariable; + out.m_contactPoint = ray.m_startPosition + tmpVariable * ray.m_direction; + out.m_contactNormal = transform.getUpper3x3() * tmpNormal; + out.m_subData.m_type = PfxSubData::NONE; + return true; + } + } + + return false; +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_box.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_box.h new file mode 100644 index 000000000..dfd71417b --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_box.h @@ -0,0 +1,31 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_INTERSECT_RAYBOX_H +#define _SCE_PFX_INTERSECT_RAYBOX_H + +#include "../../../include/physics_effects/base_level/collision/pfx_ray.h" +#include "../../../include/physics_effects/base_level/collision/pfx_box.h" + +namespace sce { +namespace PhysicsEffects { + +PfxBool pfxIntersectRayBox(const PfxRayInput &ray,PfxRayOutput &out,const PfxBox &box,const PfxTransform3 &transform); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_INTERSECT_RAYBOX_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_capsule.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_capsule.cpp new file mode 100644 index 000000000..78b8fc407 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_capsule.cpp @@ -0,0 +1,136 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "pfx_intersect_common.h" +#include "pfx_intersect_ray_capsule.h" + +namespace sce { +namespace PhysicsEffects { +PfxBool pfxIntersectRayCapsule(const PfxRayInput &ray,PfxRayOutput &out,const PfxCapsule &capsule,const PfxTransform3 &transform) +{ + // レイをCapsuleのローカル座標へ変換 + PfxTransform3 transformCapsule = orthoInverse(transform); + PfxVector3 startPosL = transformCapsule.getUpper3x3() * ray.m_startPosition + transformCapsule.getTranslation(); + PfxVector3 rayDirL = transformCapsule.getUpper3x3() * ray.m_direction; + + PfxFloat radSqr = capsule.m_radius * capsule.m_radius; + + // 始点がカプセルの内側にあるか判定 + { + PfxFloat h = fabsf(startPosL[0]); + if(h > capsule.m_halfLen) h = capsule.m_halfLen; + PfxVector3 Px(out.m_variable,0,0); + PfxFloat sqrLen = lengthSqr(startPosL-Px); + if(sqrLen <= radSqr) return false; + } + + // カプセルの胴体との交差判定 + do { + PfxVector3 P(startPosL); + PfxVector3 D(rayDirL); + + P[0] = 0.0f; + D[0] = 0.0f; + + PfxFloat a = dot(D,D); + PfxFloat b = dot(P,D); + PfxFloat c = dot(P,P) - radSqr; + + PfxFloat d = b * b - a * c; + + if(d < 0.0f || fabs(a) < 0.00001f) return false; + + PfxFloat tt = ( -b - sqrtf(d) ) / a; + + if(tt < 0.0f) + break; + else if(tt > 1.0f) + return false; + + if(tt < out.m_variable) { + PfxVector3 cp = startPosL + tt * rayDirL; + + if(fabsf(cp[0]) <= capsule.m_halfLen) { + out.m_contactFlag = true; + out.m_variable = tt; + out.m_contactPoint = PfxVector3(transform * PfxPoint3(cp)); + out.m_contactNormal = transform.getUpper3x3() * normalize(cp); + out.m_subData.m_type = PfxSubData::NONE; + return true; + } + } + } while(0); + + // カプセルの両端にある球体との交差判定 + PfxFloat a = dot(rayDirL,rayDirL); + if(fabs(a) < 0.00001f) return false; + + do { + PfxVector3 center(capsule.m_halfLen,0.0f,0.0f); + PfxVector3 v = startPosL - center; + + PfxFloat b = dot(v,rayDirL); + PfxFloat c = dot(v,v) - radSqr; + + PfxFloat d = b * b - a * c; + + if(d < 0.0f) break; + + PfxFloat tt = ( -b - sqrtf(d) ) / a; + + if(tt < 0.0f || tt > 1.0f) break; + + if(tt < out.m_variable) { + PfxVector3 cp = startPosL + tt * rayDirL; + out.m_contactFlag = true; + out.m_variable = tt; + out.m_contactPoint = ray.m_startPosition + tt * ray.m_direction; + out.m_contactNormal = transform.getUpper3x3() * normalize(cp-center); + out.m_subData.m_type = PfxSubData::NONE; + return true; + } + } while(0); + + { + PfxVector3 center(-capsule.m_halfLen,0.0f,0.0f); + PfxVector3 v = startPosL - center; + + PfxFloat b = dot(v,rayDirL); + PfxFloat c = dot(v,v) - radSqr; + + PfxFloat d = b * b - a * c; + + if(d < 0.0f) return false; + + PfxFloat tt = ( -b - sqrtf(d) ) / a; + + if(tt < 0.0f || tt > 1.0f) return false; + + if(tt < out.m_variable) { + PfxVector3 cp = startPosL + out.m_variable * rayDirL; + out.m_contactFlag = true; + out.m_variable = tt; + out.m_contactPoint = ray.m_startPosition + tt * ray.m_direction; + out.m_contactNormal = transform.getUpper3x3() * normalize(cp-center); + out.m_subData.m_type = PfxSubData::NONE; + return true; + } + } + + return false; +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_capsule.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_capsule.h new file mode 100644 index 000000000..559ebf5c1 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_capsule.h @@ -0,0 +1,31 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_INTERSECT_RAYCAPSULE_H +#define _SCE_PFX_INTERSECT_RAYCAPSULE_H + +#include "../../../include/physics_effects/base_level/collision/pfx_ray.h" +#include "../../../include/physics_effects/base_level/collision/pfx_capsule.h" + +namespace sce { +namespace PhysicsEffects { + +PfxBool pfxIntersectRayCapsule(const PfxRayInput &ray,PfxRayOutput &out,const PfxCapsule &capsule,const PfxTransform3 &transform); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_INTERSECT_RAYCAPSULE_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_convex.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_convex.cpp new file mode 100644 index 000000000..303ae7395 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_convex.cpp @@ -0,0 +1,56 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/collision/pfx_tri_mesh.h" +#include "pfx_intersect_common.h" +#include "pfx_intersect_ray_convex.h" + +namespace sce { +namespace PhysicsEffects { + +PfxBool pfxIntersectRayConvex(const PfxRayInput &ray,PfxRayOutput &out,const void *shape,const PfxTransform3 &transform) +{ + const PfxConvexMesh *convex = (const PfxConvexMesh*)shape; + + // レイをConvexのローカル座標へ変換 + PfxTransform3 transformConvex = orthoInverse(transform); + PfxVector3 startPosL = transformConvex.getUpper3x3() * ray.m_startPosition + transformConvex.getTranslation(); + PfxVector3 rayDirL = transformConvex.getUpper3x3() * ray.m_direction; + + // レイとConvexの交差判定 + PfxFloat tmpVariable(0.0f); + PfxVector3 tmpNormal; + bool ret = false; + for(PfxUInt32 f=0;f<(PfxUInt32)convex->m_numIndices/3;f++) { + PfxTriangle triangle( + convex->m_verts[convex->m_indices[f*3 ]], + convex->m_verts[convex->m_indices[f*3+1]], + convex->m_verts[convex->m_indices[f*3+2]]); + + if(pfxIntersectRayTriangleWithoutBackFace(startPosL,rayDirL,triangle,tmpVariable) && tmpVariable < out.m_variable) { + out.m_contactFlag = true; + out.m_variable = tmpVariable; + out.m_contactPoint = ray.m_startPosition + tmpVariable * ray.m_direction; + out.m_contactNormal = transform.getUpper3x3() * normalize(cross(triangle.points[2]-triangle.points[1],triangle.points[0]-triangle.points[1])); + out.m_subData.m_type = PfxSubData::NONE; + ret = true; + } + } + + return ret; +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_convex.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_convex.h new file mode 100644 index 000000000..548290015 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_convex.h @@ -0,0 +1,30 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_INTERSECT_RAYCONVEX_H +#define _SCE_PFX_INTERSECT_RAYCONVEX_H + +#include "../../../include/physics_effects/base_level/collision/pfx_ray.h" + +namespace sce { +namespace PhysicsEffects { + +PfxBool pfxIntersectRayConvex(const PfxRayInput &ray,PfxRayOutput &out,const void *shape,const PfxTransform3 &transform); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_INTERSECT_RAYCONVEX_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_cylinder.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_cylinder.cpp new file mode 100644 index 000000000..8b28dfcfb --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_cylinder.cpp @@ -0,0 +1,106 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "pfx_intersect_common.h" +#include "pfx_intersect_ray_cylinder.h" + +namespace sce { +namespace PhysicsEffects { + +PfxBool pfxIntersectRayCylinder(const PfxRayInput &ray,PfxRayOutput &out,const PfxCylinder &cylinder,const PfxTransform3 &transform) +{ + // レイを円柱のローカル座標へ変換 + PfxTransform3 transformCapsule = orthoInverse(transform); + PfxVector3 startPosL = transformCapsule.getUpper3x3() * ray.m_startPosition + transformCapsule.getTranslation(); + PfxVector3 rayDirL = transformCapsule.getUpper3x3() * ray.m_direction; + + PfxFloat radSqr = cylinder.m_radius * cylinder.m_radius; + + // 始点が円柱の内側にあるか判定 + { + PfxFloat h = fabsf(startPosL[0]); + if(h > cylinder.m_halfLen) h = cylinder.m_halfLen; + PfxVector3 Px(out.m_variable,0,0); + PfxFloat sqrLen = lengthSqr(startPosL-Px); + if(sqrLen <= radSqr) return false; + } + + // 円柱の胴体との交差判定 + do { + PfxVector3 P(startPosL); + PfxVector3 D(rayDirL); + + P[0] = 0.0f; + D[0] = 0.0f; + + PfxFloat a = dot(D,D); + PfxFloat b = dot(P,D); + PfxFloat c = dot(P,P) - radSqr; + + PfxFloat d = b * b - a * c; + + if(d < 0.0f || fabs(a) < 0.00001f) return false; + + PfxFloat tt = ( -b - sqrtf(d) ) / a; + + if(tt < 0.0f) + break; + else if(tt > 1.0f) + return false; + + if(tt < out.m_variable) { + PfxVector3 cp = startPosL + tt * rayDirL; + + if(fabsf(cp[0]) <= cylinder.m_halfLen) { + out.m_contactFlag = true; + out.m_variable = tt; + out.m_contactPoint = PfxVector3(transform * PfxPoint3(cp)); + out.m_contactNormal = transform.getUpper3x3() * normalize(cp); + out.m_subData.m_type = PfxSubData::NONE; + return true; + } + } + } while(0); + + // 円柱の両端にある平面との交差判定 + { + if(fabsf(rayDirL[0]) < 0.00001f) return false; + + PfxFloat t1 = ( cylinder.m_halfLen - startPosL[0] ) / rayDirL[0]; + PfxFloat t2 = ( - cylinder.m_halfLen - startPosL[0] ) / rayDirL[0]; + + PfxFloat tt = SCE_PFX_MIN(t1,t2); + + if(tt < 0.0f || tt > 1.0f) return false; + + PfxVector3 p = startPosL + tt * rayDirL; + p[0] = 0.0f; + + if(lengthSqr(p) < radSqr && tt < out.m_variable) { + PfxVector3 cp = startPosL + tt * rayDirL; + out.m_contactFlag = true; + out.m_variable = tt; + out.m_contactPoint = ray.m_startPosition + tt * ray.m_direction; + out.m_contactNormal = transform.getUpper3x3() * ((cp[0]>0.0f)?PfxVector3(1.0,0.0,0.0):PfxVector3(-1.0,0.0,0.0)); + out.m_subData.m_type = PfxSubData::NONE; + return true; + } + } + + return false; +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_cylinder.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_cylinder.h new file mode 100644 index 000000000..ccee5ff0a --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_cylinder.h @@ -0,0 +1,31 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_INTERSECT_RAYCYLINDER_H +#define _SCE_PFX_INTERSECT_RAYCYLINDER_H + +#include "../../../include/physics_effects/base_level/collision/pfx_ray.h" +#include "../../../include/physics_effects/base_level/collision/pfx_cylinder.h" + +namespace sce { +namespace PhysicsEffects { + +PfxBool pfxIntersectRayCylinder(const PfxRayInput &ray,PfxRayOutput &out,const PfxCylinder &cylinder,const PfxTransform3 &transform); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_INTERSECT_RAYCYLINDER_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_large_tri_mesh.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_large_tri_mesh.cpp new file mode 100644 index 000000000..a1e1c9fea --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_large_tri_mesh.cpp @@ -0,0 +1,169 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/collision/pfx_large_tri_mesh.h" +#include "pfx_intersect_common.h" +#include "pfx_mesh_common.h" +#include "pfx_intersect_ray_large_tri_mesh.h" + + +namespace sce { +namespace PhysicsEffects { + + +static SCE_PFX_FORCE_INLINE +PfxBool pfxIntersectRayTriMesh(const PfxTriMesh &mesh,const PfxVector3 &rayStart,const PfxVector3 &rayDir, + PfxUInt32 facetMode,PfxFloat &variable,PfxVector3 &normal,PfxSubData &subData) +{ + bool ret = false; + PfxFloat nearest_t = variable; + PfxVector3 nearest_nml(0.0f); + PfxUInt32 nearest_f = 0; + + for(PfxUInt32 f=0;f pfxGetXMax(aabbB)) continue; + if(aabbMaxL.getY() < pfxGetYMin(aabbB) || aabbMinL.getY() > pfxGetYMax(aabbB)) continue; + if(aabbMaxL.getZ() < pfxGetZMin(aabbB) || aabbMinL.getZ() > pfxGetZMax(aabbB)) continue; + // Todo:早期終了チェック + + PfxVector3 aabbMin,aabbMax; + aabbMin = largeMesh.getWorldPosition(PfxVecInt3((PfxFloat)pfxGetXMin(aabbB),(PfxFloat)pfxGetYMin(aabbB),(PfxFloat)pfxGetZMin(aabbB))); + aabbMax = largeMesh.getWorldPosition(PfxVecInt3((PfxFloat)pfxGetXMax(aabbB),(PfxFloat)pfxGetYMax(aabbB),(PfxFloat)pfxGetZMax(aabbB))); + + PfxFloat tmpVariable = 1.0f; + PfxVector3 tmpNormal; + + if( !pfxIntersectRayAABBFast( + rayStartPosition,rayDirection, + (aabbMax+aabbMin)*0.5f, + (aabbMax-aabbMin)*0.5f, + tmpVariable) ) + continue; + + if( out.m_variable <= tmpVariable ) continue; + + // アイランドとの交差チェック + const PfxTriMesh *island = &largeMesh.m_islands[i]; + + PfxSubData subData; + tmpVariable = out.m_variable; + + if( pfxIntersectRayTriMesh(*island,rayStartPosition,rayDirection,ray.m_facetMode,tmpVariable,tmpNormal,subData) && + tmpVariable < out.m_variable ) { + out.m_contactFlag = true; + out.m_variable = tmpVariable; + out.m_contactPoint = ray.m_startPosition + tmpVariable * ray.m_direction; + out.m_contactNormal = transform.getUpper3x3() * tmpNormal; + subData.setIslandId(i); + out.m_subData = subData; + ret = true; + } + + } + } + + return ret; +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_large_tri_mesh.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_large_tri_mesh.h new file mode 100644 index 000000000..5bb49703f --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_large_tri_mesh.h @@ -0,0 +1,30 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_INTERSECT_RAYLARGETRIMESH_H +#define _SCE_PFX_INTERSECT_RAYLARGETRIMESH_H + +#include "../../../include/physics_effects/base_level/collision/pfx_ray.h" + +namespace sce { +namespace PhysicsEffects { + +PfxBool pfxIntersectRayLargeTriMesh(const PfxRayInput &ray,PfxRayOutput &out,const void *shape,const PfxTransform3 &transform); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_INTERSECT_RAYLARGETRIMESH_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_sphere.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_sphere.cpp new file mode 100644 index 000000000..6de422b00 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_sphere.cpp @@ -0,0 +1,55 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/collision/pfx_sphere.h" +#include "pfx_intersect_common.h" +#include "pfx_intersect_ray_sphere.h" + +namespace sce { +namespace PhysicsEffects { + +PfxBool pfxIntersectRaySphere(const PfxRayInput &ray,PfxRayOutput &out,const PfxSphere &sphere,const PfxTransform3 &transform) +{ + PfxVector3 v = ray.m_startPosition - transform.getTranslation(); + + PfxFloat a = dot(ray.m_direction,ray.m_direction); + PfxFloat b = dot(v,ray.m_direction); + PfxFloat c = dot(v,v) - sphere.m_radius * sphere.m_radius; + + if(c < 0.0f) return false; + + PfxFloat d = b * b - a * c; + + if(d < 0.0f || fabsf(a) < 0.00001f) return false; + + PfxFloat tt = ( -b - sqrtf(d) ) / a; + + if(tt < 0.0f || tt > 1.0f) return false; + + if(tt < out.m_variable) { + out.m_contactFlag = true; + out.m_variable = tt; + out.m_contactPoint = ray.m_startPosition + tt * ray.m_direction; + out.m_contactNormal = normalize(out.m_contactPoint - transform.getTranslation()); + out.m_subData.m_type = PfxSubData::NONE; + return true; + } + + return false; +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_sphere.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_sphere.h new file mode 100644 index 000000000..5df29718e --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_intersect_ray_sphere.h @@ -0,0 +1,31 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_INTERSECT_RAYSPHERE_H +#define _SCE_PFX_INTERSECT_RAYSPHERE_H + +#include "../../../include/physics_effects/base_level/collision/pfx_ray.h" +#include "../../../include/physics_effects/base_level/collision/pfx_sphere.h" + +namespace sce { +namespace PhysicsEffects { + +PfxBool pfxIntersectRaySphere(const PfxRayInput &ray,PfxRayOutput &out,const PfxSphere &sphere,const PfxTransform3 &transform); + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_INTERSECT_RAYSPHERE_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_mesh_common.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_mesh_common.h new file mode 100644 index 000000000..bd2d8ffa1 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_mesh_common.h @@ -0,0 +1,194 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_MESH_COMMON_H +#define _SCE_PFX_MESH_COMMON_H + +#include "../../../include/physics_effects/base_level/base/pfx_common.h" +#include "../../../include/physics_effects/base_level/collision/pfx_tri_mesh.h" + +namespace sce { +namespace PhysicsEffects { + + +struct PfxClosestPoints { + PfxPoint3 pA[4],pB[4]; + PfxFloat distSqr[4]; + PfxFloat closestDistSqr; + int numPoints; + SCE_PFX_PADDING(1,8) + + PfxClosestPoints() + { + numPoints = 0; + closestDistSqr = SCE_PFX_FLT_MAX; + } + + void set(int i,const PfxPoint3 &pointA,const PfxPoint3 &pointB,PfxFloat d) + { + pA[i] = pointA; + pB[i] = pointB; + distSqr[i] = d; + } + + void add(const PfxPoint3 &pointA,const PfxPoint3 &pointB,PfxFloat d) + { + const PfxFloat epsilon = 0.00001f; + if(closestDistSqr < d) return; + + closestDistSqr = d + epsilon; + + int replaceId = -1; + PfxFloat distMax = -SCE_PFX_FLT_MAX; + for(int i=0;im_numFacets;f++) { + const PfxFacet &facet = mesh->m_facets[f]; + + PfxVector3 facetCenter = absPerElem(offsetPos + offsetRot * pfxReadVector3(facet.m_center)); + PfxVector3 halfBA = absOffsetRot * pfxReadVector3(facet.m_half); + + // ConvexBのAABBとチェック + if(facetCenter[0] > (halfBA[0]+aabbHalf[0])) continue; + if(facetCenter[1] > (halfBA[1]+aabbHalf[1])) continue; + if(facetCenter[2] > (halfBA[2]+aabbHalf[2])) continue; + + // この面は判定 + selFacets[numSelFacets++] = (PfxUInt8)f; +} + + return numSelFacets; +} + +static SCE_PFX_FORCE_INLINE +void pfxGetProjAxisPnts6( + const PfxVector3 *verts,const PfxVector3 &axis, + PfxFloat &distMin,PfxFloat &distMax) +{ +PfxFloat p0 = dot(axis, verts[0]); +PfxFloat p1 = dot(axis, verts[1]); +PfxFloat p2 = dot(axis, verts[2]); +PfxFloat p3 = dot(axis, verts[3]); +PfxFloat p4 = dot(axis, verts[4]); +PfxFloat p5 = dot(axis, verts[5]); +distMin = SCE_PFX_MIN(p5,SCE_PFX_MIN(p4,SCE_PFX_MIN(p3,SCE_PFX_MIN(p2,SCE_PFX_MIN(p0,p1))))); +distMax = SCE_PFX_MAX(p5,SCE_PFX_MAX(p4,SCE_PFX_MAX(p3,SCE_PFX_MAX(p2,SCE_PFX_MAX(p0,p1))))); +} + +static SCE_PFX_FORCE_INLINE +void pfxGetProjAxisPnts3( + const PfxVector3 *verts,const PfxVector3 &axis, + PfxFloat &distMin,PfxFloat &distMax) +{ +PfxFloat p0 = dot(axis, verts[0]); +PfxFloat p1 = dot(axis, verts[1]); +PfxFloat p2 = dot(axis, verts[2]); +distMin = SCE_PFX_MIN(p2,SCE_PFX_MIN(p0,p1)); +distMax = SCE_PFX_MAX(p2,SCE_PFX_MAX(p0,p1)); +} + +static SCE_PFX_FORCE_INLINE +void pfxGetProjAxisPnts2( + const PfxVector3 *verts,const PfxVector3 &axis, + PfxFloat &distMin,PfxFloat &distMax) +{ +PfxFloat p0 = dot(axis, verts[0]); +PfxFloat p1 = dot(axis, verts[1]); +distMin = SCE_PFX_MIN(p0,p1); +distMax = SCE_PFX_MAX(p0,p1); +} + +/////////////////////////////////////////////////////////////////////////////// +// 2つのベクトルの向きをチェック + +static SCE_PFX_FORCE_INLINE +bool pfxIsSameDirection(const PfxVector3 &vecA,const PfxVector3 &vecB) +{ +return fabsf(dot(vecA,vecB)) > 0.9999f; +} + +/////////////////////////////////////////////////////////////////////////////// +// 面ローカルの座標を算出 + +static SCE_PFX_FORCE_INLINE +void pfxGetLocalCoords( + const PfxVector3 &pointOnTriangle, + const PfxTriangle &triangle, + PfxFloat &s,PfxFloat &t) +{ + PfxVector3 v0 = triangle.points[1] - triangle.points[0]; + PfxVector3 v1 = triangle.points[2] - triangle.points[0]; + PfxVector3 dir = pointOnTriangle - triangle.points[0]; + PfxVector3 v = cross( v0, v1 ); + PfxVector3 crS = cross( v, v0 ); + PfxVector3 crT = cross( v, v1 ); + s = dot( crT, dir ) / dot( crT, v0 ); + t = dot( crS, dir ) / dot( crS, v1 ); +} + +// a,bからなる直線上に点pがあるかどうかを判定 +static SCE_PFX_FORCE_INLINE +bool pfxPointOnLine(const PfxVector3 &p,const PfxVector3 &a,const PfxVector3 &b) +{ + PfxVector3 ab = normalize(b-a); + PfxVector3 q = a + ab * dot(p-a,ab); + return lengthSqr(p-q) < 0.00001f; +} + +// 線分a,b上に点pがあるかどうかを判定 +static SCE_PFX_FORCE_INLINE +bool pfxPointOnSegment(const PfxVector3 &p,const PfxVector3 &a,const PfxVector3 &b) +{ + PfxVector3 ab = b-a; + PfxVector3 ap = p-a; + PfxFloat denom = dot(ab,ab); + PfxFloat num = dot(ap,ab); + PfxFloat t = num/denom; + if(t < 0.0f || t > 1.0f) return false; + return (dot(ap,ap)-num*t) < 0.00001f; +} + + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_MESH_COMMON_H diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_shape.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_shape.cpp new file mode 100644 index 000000000..0f9ef88e5 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_shape.cpp @@ -0,0 +1,95 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/collision/pfx_shape.h" + +namespace sce { +namespace PhysicsEffects { +void pfxGetShapeAabbDummy(const PfxShape &shape,PfxVector3 &aabbMin,PfxVector3 &aabbMax) +{ + (void)shape,(void)aabbMin,(void)aabbMax; +} + +void pfxGetShapeAabbSphere(const PfxShape &shape,PfxVector3 &aabbMin,PfxVector3 &aabbMax) +{ + aabbMin = shape.getOffsetPosition() - PfxVector3(shape.getSphere().m_radius); + aabbMax = shape.getOffsetPosition() + PfxVector3(shape.getSphere().m_radius); +} + +void pfxGetShapeAabbBox(const PfxShape &shape,PfxVector3 &aabbMin,PfxVector3 &aabbMax) +{ + PfxVector3 boxSize = absPerElem(PfxMatrix3(shape.getOffsetOrientation())) * shape.getBox().m_half; + aabbMin = shape.getOffsetPosition() - boxSize; + aabbMax = shape.getOffsetPosition() + boxSize; +} + +void pfxGetShapeAabbCapsule(const PfxShape &shape,PfxVector3 &aabbMin,PfxVector3 &aabbMax) +{ + PfxVector3 dir = rotate(shape.getOffsetOrientation(),PfxVector3(1.0f,0.0f,0.0f)); + PfxVector3 capSize = absPerElem(dir) * shape.getCapsule().m_halfLen + + PfxVector3(shape.getCapsule().m_radius); + aabbMin = shape.getOffsetPosition() - capSize; + aabbMax = shape.getOffsetPosition() + capSize; +} + +void pfxGetShapeAabbCylinder(const PfxShape &shape,PfxVector3 &aabbMin,PfxVector3 &aabbMax) +{ + PfxVector3 capSize = absPerElem(PfxMatrix3(shape.getOffsetOrientation())) * + PfxVector3(shape.getCylinder().m_halfLen,shape.getCylinder().m_radius,shape.getCylinder().m_radius); + aabbMin = shape.getOffsetPosition() - capSize; + aabbMax = shape.getOffsetPosition() + capSize; +} + +void pfxGetShapeAabbConvexMesh(const PfxShape &shape,PfxVector3 &aabbMin,PfxVector3 &aabbMax) +{ + const PfxConvexMesh *convex = shape.getConvexMesh(); + PfxVector3 half = absPerElem(PfxMatrix3(shape.getOffsetOrientation())) * convex->m_half; + aabbMin = shape.getOffsetPosition() - half; + aabbMax = shape.getOffsetPosition() + half; +} + +void pfxGetShapeAabbLargeTriMesh(const PfxShape &shape,PfxVector3 &aabbMin,PfxVector3 &aabbMax) +{ + const PfxLargeTriMesh *largemesh = shape.getLargeTriMesh(); + PfxVector3 half = absPerElem(PfxMatrix3(shape.getOffsetOrientation())) * largemesh->m_half; + aabbMin = shape.getOffsetPosition() - half; + aabbMax = shape.getOffsetPosition() + half; +} + +typedef void (*PfxFuncGetShapeAabb)(const PfxShape &shape,PfxVector3 &aabbMin,PfxVector3 &aabbMax); + +PfxFuncGetShapeAabb pfxFuncGetShapeAabb[kPfxShapeCount] = { + pfxGetShapeAabbSphere, + pfxGetShapeAabbBox, + pfxGetShapeAabbCapsule, + pfxGetShapeAabbCylinder, + pfxGetShapeAabbConvexMesh, + pfxGetShapeAabbLargeTriMesh, + pfxGetShapeAabbDummy, + pfxGetShapeAabbDummy, + pfxGetShapeAabbDummy, + pfxGetShapeAabbDummy, + pfxGetShapeAabbDummy, + pfxGetShapeAabbDummy, +}; + +void PfxShape::getAabb(PfxVector3 &aabbMin,PfxVector3 &aabbMax) const +{ + return pfxFuncGetShapeAabb[m_type](*this,aabbMin,aabbMax); +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_simplex_solver.cpp b/Extras/PhysicsEffects/src/base_level/collision/pfx_simplex_solver.cpp new file mode 100644 index 000000000..197555d70 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_simplex_solver.cpp @@ -0,0 +1,284 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "pfx_simplex_solver.h" +#include "pfx_gjk_solver.h" + +namespace sce { +namespace PhysicsEffects { +inline static +bool operator ==(const PfxVector3 &a,const PfxVector3 &b) +{ + return lengthSqr(a-b) < (SCE_PFX_GJK_EPSILON * SCE_PFX_GJK_EPSILON); +} + +bool PfxSimplexSolver::closest(PfxVector3& v) +{ + bool ret = false; + + bc.reset(); + + switch(numVertices) { + case 0: + ret = false; + break; + + case 1: + { + PfxVector3 tmpP = P[0]; + PfxVector3 tmpQ = Q[0]; + v = tmpP-tmpQ; + bc.reset(); + bc.setBarycentricCoordinates(1.0f,0.0f,0.0f,0.0f); + ret = bc.isValid(); + } + break; + + case 2: + { + PfxVector3 dir = W[1] - W[0]; + PfxFloat t = dot(-W[0],dir) / dot(dir,dir); + + if(t < 0.0f) t = 0.0f; + if(t > 1.0f) t = 1.0f; + + bc.setBarycentricCoordinates(1-t,t,0.0f,0.0f); + + PfxVector3 tmpP = P[0] + t * (P[1] - P[0]); + PfxVector3 tmpQ = Q[0] + t * (Q[1] - Q[0]); + v = tmpP - tmpQ; + + reduceVertices(); + + ret = bc.isValid(); + break; + } + + case 3: + { + const PfxVector3& a = W[0]; + const PfxVector3& b = W[1]; + const PfxVector3& c = W[2]; + + closestPointTriangleFromOrigin(a,b,c,bc); + + PfxVector3 tmpP = P[0] * bc.barycentricCoords[0] + + P[1] * bc.barycentricCoords[1] + + P[2] * bc.barycentricCoords[2]; + + PfxVector3 tmpQ = Q[0] * bc.barycentricCoords[0] + + Q[1] * bc.barycentricCoords[1] + + Q[2] * bc.barycentricCoords[2]; + + v = tmpP-tmpQ; + + reduceVertices(); + ret = bc.isValid(); + break; + } + + case 4: + { + const PfxVector3& a = W[0]; + const PfxVector3& b = W[1]; + const PfxVector3& c = W[2]; + const PfxVector3& d = W[3]; + + if(closestPointTetrahedronFromOrigin(a,b,c,d,bc)) { + PfxVector3 tmpP = P[0] * bc.barycentricCoords[0] + + P[1] * bc.barycentricCoords[1] + + P[2] * bc.barycentricCoords[2] + + P[3] * bc.barycentricCoords[3]; + + PfxVector3 tmpQ = Q[0] * bc.barycentricCoords[0] + + Q[1] * bc.barycentricCoords[1] + + Q[2] * bc.barycentricCoords[2] + + Q[3] * bc.barycentricCoords[3]; + v = tmpP-tmpQ; + + reduceVertices(); + ret = bc.isValid(); + } else { + // 原点が内部に存在→交差している + ret = true; + v = PfxVector3(0.0f); + } + break; + } + }; + + return ret; +} + +bool PfxSimplexSolver::inSimplex(const PfxVector3& w) +{ + for(int i=0;i= 0.0f && d4 <= d3) { + result.closest = b; + result.setBarycentricCoordinates(0.0f,1.0f,0.0f,0.0f); + return true; + } + + PfxFloat vc = d1*d4 - d3*d2; + if(vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) { + PfxFloat v = d1 / (d1 - d3); + result.closest = a + v * ab; + result.setBarycentricCoordinates(1.0f-v,v,0.0f,0.0f); + return true; + } + + PfxVector3 cp = p - c; + PfxFloat d5 = dot(ab,cp); + PfxFloat d6 = dot(ac,cp); + if(d6 >= 0.0f && d5 <= d6) { + result.closest = c; + result.setBarycentricCoordinates(0.0f,0.0f,1.0f,0.0f); + return true; + } + + PfxFloat vb = d5*d2 - d1*d6; + if(vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) { + PfxFloat w = d2 / (d2 - d6); + result.closest = a + w * ac; + result.setBarycentricCoordinates(1.0f-w,0.0f,w,0.0f); + return true; + } + + PfxFloat va = d3*d6 - d5*d4; + if(va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) { + PfxFloat w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); + result.closest = b + w * (c - b); + result.setBarycentricCoordinates(0.0f,1.0f-w,w,0.0f); + return true; + } + + PfxFloat denom = PfxFloat(1.0) / (va + vb + vc); + PfxFloat v = vb * denom; + PfxFloat w = vc * denom; + + result.closest = a + ab * v + ac * w; + result.setBarycentricCoordinates(1.0f-v-w,v,w,0.0f); + + return true; +} + +bool PfxSimplexSolver::closestPointTetrahedronFromOrigin(const PfxVector3 &a,const PfxVector3 &b,const PfxVector3 &c,const PfxVector3 &d,PfxBarycentricCoords& finalResult) +{ + PfxBarycentricCoords tempResult; + PfxVector3 p(0.0f); + + finalResult.closest = p; + finalResult.usedVertices = 0; + + bool pointOutsideABC = originOutsideOfPlane(a, b, c, d); + bool pointOutsideACD = originOutsideOfPlane(a, c, d, b); + bool pointOutsideADB = originOutsideOfPlane(a, d, b, c); + bool pointOutsideBDC = originOutsideOfPlane(b, d, c, a); + + if(!pointOutsideABC && !pointOutsideACD && !pointOutsideADB && !pointOutsideBDC) + return false; + + PfxFloat bestSqDist = SCE_PFX_FLT_MAX; + + if(pointOutsideABC) { + closestPointTriangleFromOrigin(a, b, c,tempResult); + PfxVector3 q = tempResult.closest; + PfxFloat sqDist = dot((q - p),(q - p)); + if(sqDist < bestSqDist) { + bestSqDist = sqDist; + finalResult.closest = q; + finalResult.setBarycentricCoordinates( + tempResult.barycentricCoords[0], + tempResult.barycentricCoords[1], + tempResult.barycentricCoords[2], + 0); + } + } + + if(pointOutsideACD) { + closestPointTriangleFromOrigin(a, c, d,tempResult); + PfxVector3 q = tempResult.closest; + PfxFloat sqDist = dot((q - p),(q - p)); + if(sqDist < bestSqDist) { + bestSqDist = sqDist; + finalResult.closest = q; + finalResult.setBarycentricCoordinates( + tempResult.barycentricCoords[0], + 0, + tempResult.barycentricCoords[1], + tempResult.barycentricCoords[2]); + } + } + + if(pointOutsideADB) { + closestPointTriangleFromOrigin(a, d, b,tempResult); + PfxVector3 q = tempResult.closest; + PfxFloat sqDist = dot((q - p),(q - p)); + if(sqDist < bestSqDist) { + bestSqDist = sqDist; + finalResult.closest = q; + finalResult.setBarycentricCoordinates( + tempResult.barycentricCoords[0], + tempResult.barycentricCoords[2], + 0, + tempResult.barycentricCoords[1]); + } + } + + if(pointOutsideBDC) { + closestPointTriangleFromOrigin(b, d, c,tempResult); + PfxVector3 q = tempResult.closest; + PfxFloat sqDist = dot((q - p),(q - p)); + if(sqDist < bestSqDist) { + bestSqDist = sqDist; + finalResult.closest = q; + finalResult.setBarycentricCoordinates( + 0, + tempResult.barycentricCoords[0], + tempResult.barycentricCoords[2], + tempResult.barycentricCoords[1]); + } + } + + return true; +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/collision/pfx_simplex_solver.h b/Extras/PhysicsEffects/src/base_level/collision/pfx_simplex_solver.h new file mode 100644 index 000000000..a8aa1a5c2 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/collision/pfx_simplex_solver.h @@ -0,0 +1,153 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_SIMPLEX_SOLVER_H +#define _SCE_PFX_SIMPLEX_SOLVER_H + +#include "../../../include/physics_effects/base_level/base/pfx_common.h" + +namespace sce { +namespace PhysicsEffects { + + +/////////////////////////////////////////////////////////////////////////////// +// Voronoi Simplex Solver + +struct SCE_PFX_ALIGNED(16) PfxBarycentricCoords { + PfxVector3 closest; +PfxFloat barycentricCoords[4]; + unsigned int usedVertices; + SCE_PFX_PADDING(1,12) + + void reset() + { + barycentricCoords[0] = 0.0f; + barycentricCoords[1] = 0.0f; + barycentricCoords[2] = 0.0f; + barycentricCoords[3] = 0.0f; + usedVertices = 0; + } + + bool isValid() + { + return (barycentricCoords[0] >= 0.0f) && + (barycentricCoords[1] >= 0.0f) && + (barycentricCoords[2] >= 0.0f) && + (barycentricCoords[3] >= 0.0f); + } + +void setBarycentricCoordinates(PfxFloat a,PfxFloat b,PfxFloat c,PfxFloat d) +{ + barycentricCoords[0] = a; + barycentricCoords[1] = b; + barycentricCoords[2] = c; + barycentricCoords[3] = d; + if(a != 0.0f) usedVertices |= 1<<3; + if(b != 0.0f) usedVertices |= 1<<2; + if(c != 0.0f) usedVertices |= 1<<1; + if(d != 0.0f) usedVertices |= 1; +} +}; + +class PfxSimplexSolver { +private: + static const int MAX_VERTS = 4; + +public: + int numVertices; + SCE_PFX_PADDING(1,12) + PfxVector3 W[MAX_VERTS]; + PfxVector3 P[MAX_VERTS]; + PfxVector3 Q[MAX_VERTS]; + + PfxBarycentricCoords bc; + + inline void removeVertex(int index); + inline void reduceVertices (); + + inline bool originOutsideOfPlane(const PfxVector3& a, const PfxVector3& b, const PfxVector3& c, const PfxVector3& d); + bool closestPointTetrahedronFromOrigin(const PfxVector3 &a,const PfxVector3 &b,const PfxVector3 &c,const PfxVector3 &d, PfxBarycentricCoords& result); + bool closestPointTriangleFromOrigin(const PfxVector3 &a,const PfxVector3 &b,const PfxVector3 &c,PfxBarycentricCoords& result); + +public: + void reset() + { + numVertices = 0; + bc.reset(); + } + + inline void addVertex(const PfxVector3& w_, const PfxVector3& p_, const PfxVector3& q_); + + bool closest(PfxVector3& v); + + bool fullSimplex() const + { + return (numVertices == 4); + } + + bool inSimplex(const PfxVector3& w); +}; + +inline +void PfxSimplexSolver::removeVertex(int index) +{ + SCE_PFX_ASSERT(numVertices>0); + numVertices--; + W[index] = W[numVertices]; + P[index] = P[numVertices]; + Q[index] = Q[numVertices]; +} + +inline +void PfxSimplexSolver::reduceVertices () +{ + if ((numVertices >= 4) && (!(bc.usedVertices&0x01))) + removeVertex(3); + + if ((numVertices >= 3) && (!(bc.usedVertices&0x02))) + removeVertex(2); + + if ((numVertices >= 2) && (!(bc.usedVertices&0x04))) + removeVertex(1); + + if ((numVertices >= 1) && (!(bc.usedVertices&0x08))) + removeVertex(0); +} + +inline +void PfxSimplexSolver::addVertex(const PfxVector3& w, const PfxVector3& p, const PfxVector3& q) +{ + W[numVertices] = w; + P[numVertices] = p; + Q[numVertices] = q; + numVertices++; +} + +inline +bool PfxSimplexSolver::originOutsideOfPlane(const PfxVector3& a, const PfxVector3& b, const PfxVector3& c, const PfxVector3& d) +{ + PfxVector3 normal = cross((b-a),(c-a)); + + PfxFloat signp = dot(-a,normal); + PfxFloat signd = dot((d - a),normal); + + return signp * signd < 0.0f; +} + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_SIMPLEX_SOLVER_H diff --git a/Extras/PhysicsEffects/src/base_level/premake4.lua b/Extras/PhysicsEffects/src/base_level/premake4.lua new file mode 100644 index 000000000..112a875ce --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/premake4.lua @@ -0,0 +1,12 @@ + project "physicseffects2_baselevel" + + kind "StaticLib" + targetdir "../../build/lib" + includedirs { + ".", + } + files { + "**.cpp", + "../../include/physics_effects/base_level/**.h" + + } \ No newline at end of file diff --git a/Extras/PhysicsEffects/src/base_level/solver/pfx_check_solver.h b/Extras/PhysicsEffects/src/base_level/solver/pfx_check_solver.h new file mode 100644 index 000000000..417998b3f --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/solver/pfx_check_solver.h @@ -0,0 +1,67 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CHECK_SOLVER_H_ +#define _SCE_PFX_CHECK_SOLVER_H_ + +#include "../../../include/physics_effects/base_level/rigidbody/pfx_rigid_state.h" +#include "../../../include/physics_effects/base_level/solver/pfx_constraint_pair.h" + +namespace sce { +namespace PhysicsEffects { + +// Solver check table +/* + -----------------MotionTypeA + |0 1 0 1 0 + |1 1 1 1 0 + |0 1 0 1 0 + |1 1 1 0 0 + |0 0 0 0 0 +MotionTypeB + */ + +static SCE_PFX_FORCE_INLINE +PfxBool pfxCheckSolverTable(ePfxMotionType i,ePfxMotionType j) +{ + const PfxUInt32 solverTable = 0x00af2b80; + + SCE_PFX_ASSERT(i < kPfxMotionTypeCount); + SCE_PFX_ASSERT(j < kPfxMotionTypeCount); + + PfxUInt32 idx = j * kPfxMotionTypeCount + i; + PfxUInt32 mask = 1 << (kPfxMotionTypeCount*kPfxMotionTypeCount-1-idx); + return (solverTable & mask) != 0; +} + +static SCE_PFX_FORCE_INLINE +PfxBool pfxCheckSolver(const PfxConstraintPair &pair) +{ + PfxUInt32 motionA = pfxGetMotionMaskA(pair)&SCE_PFX_MOTION_MASK_TYPE; + PfxUInt32 motionB = pfxGetMotionMaskB(pair)&SCE_PFX_MOTION_MASK_TYPE; + PfxUInt32 sleepA = pfxGetMotionMaskA(pair)&SCE_PFX_MOTION_MASK_SLEEPING; + PfxUInt32 sleepB = pfxGetMotionMaskB(pair)&SCE_PFX_MOTION_MASK_SLEEPING; + + return + pfxGetActive(pair) && + pfxCheckSolverTable((ePfxMotionType)motionA,(ePfxMotionType)motionB) && // モーションタイプ別衝突判定テーブル + !((sleepA != 0 && sleepB != 0) || (sleepA != 0 && motionB == kPfxMotionTypeFixed) || (sleepB != 0 && motionA == kPfxMotionTypeFixed));// スリープ時のチェック +} + +} //namespace PhysicsEffects +} //namespace sce + +#endif /* _SCE_PFX_CHECK_SOLVER_H_ */ diff --git a/Extras/PhysicsEffects/src/base_level/solver/pfx_constraint_row_solver.h b/Extras/PhysicsEffects/src/base_level/solver/pfx_constraint_row_solver.h new file mode 100644 index 000000000..146fc411e --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/solver/pfx_constraint_row_solver.h @@ -0,0 +1,296 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_CONSTRAINT_ROW_SOLVER_H +#define _SCE_PFX_CONSTRAINT_ROW_SOLVER_H + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "../../../include/physics_effects/base_level/solver/pfx_constraint_row.h" +#include "../../../include/physics_effects/base_level/solver/pfx_joint_constraint.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// Constraint Row Solver + +// ARA begin insert new code +#ifdef __ARM_NEON__ +// prototype for inline NEON assembly version +void pfxSolveLinearConstraintRowNEON(PfxConstraintRow &constraint, + PfxVector3 &deltaLinearVelocityA,PfxVector3 &deltaAngularVelocityA, + PfxFloat &massInvA,const PfxMatrix3 &inertiaInvA,const PfxVector3 &rA, + PfxVector3 &deltaLinearVelocityB,PfxVector3 &deltaAngularVelocityB, + PfxFloat &massInvB,const PfxMatrix3 &inertiaInvB,const PfxVector3 &rB); +#endif // __ARM_NEON__ +// ARA end + +static SCE_PFX_FORCE_INLINE +void pfxSolveLinearConstraintRow(PfxConstraintRow &constraint, + PfxVector3 &deltaLinearVelocityA,PfxVector3 &deltaAngularVelocityA, + PfxFloat massInvA,const PfxMatrix3 &inertiaInvA,const PfxVector3 &rA, + PfxVector3 &deltaLinearVelocityB,PfxVector3 &deltaAngularVelocityB, + PfxFloat massInvB,const PfxMatrix3 &inertiaInvB,const PfxVector3 &rB) +{ +const PfxVector3 normal(pfxReadVector3(constraint.m_normal)); +PfxFloat deltaImpulse = constraint.m_rhs; +PfxVector3 dVA = deltaLinearVelocityA + cross(deltaAngularVelocityA,rA); +PfxVector3 dVB = deltaLinearVelocityB + cross(deltaAngularVelocityB,rB); +deltaImpulse -= constraint.m_jacDiagInv * dot(normal,dVA-dVB); +PfxFloat oldImpulse = constraint.m_accumImpulse; +constraint.m_accumImpulse = SCE_PFX_CLAMP(oldImpulse + deltaImpulse,constraint.m_lowerLimit,constraint.m_upperLimit); +deltaImpulse = constraint.m_accumImpulse - oldImpulse; +deltaLinearVelocityA += deltaImpulse * massInvA * normal; +deltaAngularVelocityA += deltaImpulse * inertiaInvA * cross(rA,normal); +deltaLinearVelocityB -= deltaImpulse * massInvB * normal; +deltaAngularVelocityB -= deltaImpulse * inertiaInvB * cross(rB,normal); +} + +static SCE_PFX_FORCE_INLINE +void pfxSolveAngularConstraintRow(PfxConstraintRow &constraint, + PfxVector3 &deltaAngularVelocityA, + const PfxMatrix3 &inertiaInvA,const PfxVector3 &rA, + PfxVector3 &deltaAngularVelocityB, + const PfxMatrix3 &inertiaInvB,const PfxVector3 &rB) +{ + (void)rA,(void)rB; +const PfxVector3 normal(pfxReadVector3(constraint.m_normal)); +PfxFloat deltaImpulse = constraint.m_rhs; +deltaImpulse -= constraint.m_jacDiagInv * dot(normal,deltaAngularVelocityA-deltaAngularVelocityB); +PfxFloat oldImpulse = constraint.m_accumImpulse; +constraint.m_accumImpulse = SCE_PFX_CLAMP(oldImpulse + deltaImpulse,constraint.m_lowerLimit,constraint.m_upperLimit); +deltaImpulse = constraint.m_accumImpulse - oldImpulse; +deltaAngularVelocityA += deltaImpulse * inertiaInvA * normal; +deltaAngularVelocityB -= deltaImpulse * inertiaInvB * normal; +} + + +/////////////////////////////////////////////////////////////////////////////// +// Calc Joint Angle + +static SCE_PFX_FORCE_INLINE +void pfxCalcJointAngleSwingTwist(PfxMatrix3 &worldFrameA,PfxMatrix3 &worldFrameB,PfxFloat *angle,PfxVector3 *axis) +{ + // フレームA座標系への変換マトリクス + PfxMatrix3 frameBA = transpose(worldFrameA) * worldFrameB; + + // クォータニオン回転をtwistとswingに分離 + PfxQuat swing,twist,qBA(frameBA); + swing = PfxQuat::rotation(PfxVector3(1.0f,0.0f,0.0f),frameBA.getCol0()); + twist = qBA * conj(swing); + + if(dot(twist,PfxQuat::rotationX(0.0f)) < 0.0f) { + twist = -twist; + } + + // それぞれの回転軸と回転角度を算出 + pfxGetRotationAngleAndAxis(normalize(twist),angle[0],axis[0]); + pfxGetRotationAngleAndAxis(normalize(swing),angle[1],axis[1]); + + if(angle[1] < 0.00001f) { + axis[1] = PfxVector3(0.0f,1.0f,0.0f); + } + + // twistの軸方向のチェック + if(dot(axis[0],frameBA.getCol0()) < 0.0f) { + angle[0] = -angle[0]; + } + + axis[0] = worldFrameB.getCol0(); + axis[1] = worldFrameA * axis[1]; + axis[2] = cross(axis[0],axis[1]); + angle[2] = 0.0f; +} + +static SCE_PFX_FORCE_INLINE +void pfxCalcJointAngleSwing1Swing2Twist(PfxMatrix3 &worldFrameA,PfxMatrix3 &worldFrameB,PfxFloat *angle,PfxVector3 *axis) +{ + // フレームA座標系への変換マトリクス + PfxMatrix3 frameBA = transpose(worldFrameA) * worldFrameB; + + // クォータニオン回転をtwistとswingに分離 + PfxQuat swing,twist,qBA(frameBA); + swing = PfxQuat::rotation(PfxVector3(1.0f,0.0f,0.0f),frameBA.getCol0()); + twist = qBA * conj(swing); + + if(dot(twist,PfxQuat::rotationX(0.0f)) < 0.0f) { + twist = -twist; + } + + PfxQuat swing1,swing2; + + PfxVector3 pXY = frameBA.getCol0();pXY[2] = 0.0f; + PfxVector3 pXZ = frameBA.getCol0();pXZ[1] = 0.0f; + + if(fabsf(frameBA.getCol0()[1]) < fabsf(frameBA.getCol0()[2])) { + swing1 = PfxQuat::rotation(PfxVector3(1.0f,0.0f,0.0f),pXZ); + swing2 = swing * conj(swing1); + } + else { + swing2 = PfxQuat::rotation(PfxVector3(1.0f,0.0f,0.0f),pXY); + swing1 = conj(swing2) * swing; + } + + // それぞれの回転軸と回転角度を算出 + pfxGetRotationAngleAndAxis(normalize(twist),angle[0],axis[0]); + pfxGetRotationAngleAndAxis(normalize(swing2),angle[1],axis[1]); + pfxGetRotationAngleAndAxis(normalize(swing1),angle[2],axis[2]); + + if(angle[1] < 0.00001f) { + angle[1] = 0.0f; + axis[1] = PfxVector3(0.0f,1.0f,0.0f); + } + + if(angle[2] < 0.00001f) { + angle[2] = 0.0f; + axis[2] = PfxVector3(0.0f,0.0f,1.0f); + } + + // twistの軸方向のチェック + if(dot(axis[0],frameBA.getCol0()) < 0.0f) { + angle[0] = -angle[0]; + } + + axis[0] = worldFrameB.getCol0(); + axis[1] = worldFrameA * axis[1]; + axis[2] = worldFrameA * axis[2]; +} + +static SCE_PFX_FORCE_INLINE +void pfxCalcJointAngleUniversal(PfxMatrix3 &worldFrameA,PfxMatrix3 &worldFrameB,PfxFloat *angle,PfxVector3 *axis) +{ + // フレームA座標系への変換マトリクス + PfxMatrix3 frameBA = transpose(worldFrameA) * worldFrameB; + + // クォータニオン回転をtwistとswingに分離 + PfxQuat swing,swing1,swing2,twist,qBA(frameBA); + PfxVector3 Pxy(frameBA.getCol0()); + Pxy[2] = 0.0f; + swing1 = PfxQuat::rotation(PfxVector3(1.0f,0.0f,0.0f),normalize(Pxy)); + swing = PfxQuat::rotation(PfxVector3(1.0f,0.0f,0.0f),frameBA.getCol0()); + swing2 = swing * conj(swing1); + twist = conj(swing) * qBA; + + if(dot(twist,PfxQuat::rotationX(0.0f)) < 0.0f) { + twist = -twist; + } + + pfxGetRotationAngleAndAxis(normalize(twist),angle[0],axis[0]); + pfxGetRotationAngleAndAxis(normalize(swing1),angle[1],axis[1]); + pfxGetRotationAngleAndAxis(normalize(swing2),angle[2],axis[2]); + + if(axis[1].getZ() < 0.0f) { + axis[1] = -axis[1]; + angle[1] = -angle[1]; + } + + PfxVector3 chkY = cross(PfxVector3(0.0f,0.0f,1.0f),frameBA.getCol0()); + if(dot(chkY,axis[2]) < 0.0f) { + axis[2] = -axis[2]; + angle[2] = -angle[2]; + } + + // twistの軸方向のチェック + if(dot(axis[0],frameBA.getCol0()) < 0.0f) { + angle[0] = -angle[0]; + } + + axis[0] = worldFrameB.getCol0(); + axis[1] = worldFrameA * axis[1]; + axis[2] = worldFrameA * axis[2]; +} + +/////////////////////////////////////////////////////////////////////////////// +// Calc Joint Limit + +static SCE_PFX_FORCE_INLINE +void pfxCalcLinearLimit( + const PfxJointConstraint &jointConstraint, + PfxFloat &posErr,PfxFloat &velocityAmp,PfxFloat &lowerLimit,PfxFloat &upperLimit) +{ + switch(jointConstraint.m_lock) { + case SCE_PFX_JOINT_LOCK_FREE: + posErr = 0.0f; + velocityAmp *= jointConstraint.m_damping; + break; + + case SCE_PFX_JOINT_LOCK_LIMIT: + if(posErr >= jointConstraint.m_movableLowerLimit && posErr <= jointConstraint.m_movableUpperLimit) { + posErr = 0.0f; + velocityAmp *= jointConstraint.m_damping; + } + else { + if(posErr < jointConstraint.m_movableLowerLimit) { + posErr = posErr - jointConstraint.m_movableLowerLimit; + posErr = SCE_PFX_MIN(0.0f,posErr+SCE_PFX_JOINT_LINEAR_SLOP); + upperLimit = SCE_PFX_MIN(0.0f,upperLimit); + velocityAmp = 1.0f; + } + else { // posErr > movableUpperLimit + posErr = posErr - jointConstraint.m_movableUpperLimit; + posErr = SCE_PFX_MAX(0.0f,posErr-SCE_PFX_JOINT_LINEAR_SLOP); + lowerLimit = SCE_PFX_MAX(0.0f,lowerLimit); + velocityAmp = 1.0f; + } + } + break; + + default: // SCE_PFX_JOINT_LOCK_FIX + break; + } +} + +static SCE_PFX_FORCE_INLINE +void pfxCalcAngularLimit( + const PfxJointConstraint &jointConstraint, + PfxFloat &posErr,PfxFloat &velocityAmp,PfxFloat &lowerLimit,PfxFloat &upperLimit) +{ + switch(jointConstraint.m_lock) { + case SCE_PFX_JOINT_LOCK_FREE: + posErr = 0.0f; + velocityAmp *= jointConstraint.m_damping; + break; + + case SCE_PFX_JOINT_LOCK_LIMIT: + if(posErr >= jointConstraint.m_movableLowerLimit && posErr <= jointConstraint.m_movableUpperLimit) { + posErr = 0.0f; + velocityAmp *= jointConstraint.m_damping; + } + else { + if(posErr < jointConstraint.m_movableLowerLimit) { + posErr = posErr - jointConstraint.m_movableLowerLimit; + posErr = SCE_PFX_MIN(0.0f,posErr+SCE_PFX_JOINT_ANGULAR_SLOP); + upperLimit = SCE_PFX_MIN(0.0f,upperLimit); + velocityAmp = 1.0f; + } + else { // posErr > movableUpperLimit + posErr = posErr - jointConstraint.m_movableUpperLimit; + posErr = SCE_PFX_MAX(0.0f,posErr-SCE_PFX_JOINT_ANGULAR_SLOP); + lowerLimit = SCE_PFX_MAX(0.0f,lowerLimit); + velocityAmp = 1.0f; + } + } + break; + + default: // SCE_PFX_JOINT_LOCK_FIX + break; + } +} + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_CONSTRAINT_ROW_SOLVER_H diff --git a/Extras/PhysicsEffects/src/base_level/solver/pfx_constraint_row_solver_neon.cpp b/Extras/PhysicsEffects/src/base_level/solver/pfx_constraint_row_solver_neon.cpp new file mode 100644 index 000000000..c07a144da --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/solver/pfx_constraint_row_solver_neon.cpp @@ -0,0 +1,186 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +#ifdef __ANDROID__ + +#include "../../../include/physics_effects.h" +#include + +namespace sce { +namespace PhysicsEffects { + +//---------------------------------------------------------------------------- +// pfxSolveLinearConstraintRowNEON +// +/// NEON inline assembly implementation of the pfxSolveLinearConstraintRow +/// function. +/// +/// @param constraint Constraint row to be solved +/// @param deltaLinearVelocityA Change in linear velocity for object A +/// @param deltaAngularVelocityA Change in angular velocity for object A +/// @param massInvA Mass inverse for object A +/// @param inertiaInvA Inertia tensor inverse for object A +/// @param rA Position of contact point for object A +/// @param deltaLinearVelocityB Change in linear velocity for object B +/// @param deltaAngularVelocityB Change in angular velocity for object B +/// @param massInvB Mass inverse for object B +/// @param inertiaInvB Inertia tensor inverse for object B +/// @param rB Position of contact point for object B +//---------------------------------------------------------------------------- +//GSR version +void pfxSolveLinearConstraintRowNEON(PfxConstraintRow &constraint, + PfxVector3 &deltaLinearVelocityA,PfxVector3 &deltaAngularVelocityA, + PfxFloat &massInvA,const PfxMatrix3 &inertiaInvA,const PfxVector3 &rA, + PfxVector3 &deltaLinearVelocityB,PfxVector3 &deltaAngularVelocityB, + PfxFloat &massInvB,const PfxMatrix3 &inertiaInvB,const PfxVector3 &rB) +{ + asm volatile + ( + //Loads beforehand so the normal vector will be able to have zero in the 4th element + "vld1.32 {q0}, [%1] \n\t" //LOAD => deltaLinearVelocityA ----------------> q0 + "vld1.32 {q1}, [%2] \n\t" //LOAD => deltaAngularVelocityA ---------------> q1 + "vld1.32 {q2}, [%6] \n\t" //LOAD => deltaLinearVelocityB ----------------> q2 + "vld1.32 {q3}, [%7] \n\t" //LOAD => deltaAngularVelocityB ---------------> q3 + //const PfxVector3 normal(pfxReadVector3(constraint.m_normal)); + "vld1.32 {q4}, [%0]! \n\t" //LOAD => constraint normal--------------------> q4 + "vdup.32 d10, d1[1] \n\t" //set 4th element on normal vector to zero. It is zero since q0 holds a vec3...d1[1] is 4th element and on C++ side we set this to zero + "vtrn.32 d9, d10 \n\t" //LOAD => deltaImpulse ------------------------> q5 (d10[0] only) + //PfxFloat deltaImpulse = constraint.m_rhs; + "vld1.32 {d12}, [%0]! \n\t" //LOAD => constraint variables ----------------> q6 + "vld1.32 {d13[0]}, [%0]! \n\t" //constraint variables + "vld1.32 {d13[1]}, [%0] \n\t" //constraint load of remaining variables loaded this way keep pointer to m_accumulate in order to store back in later + //PfxVector3 dVA = deltaLinearVelocityA + cross(deltaAngularVelocityA,rA); + //PfxVector3 dVB = deltaLinearVelocityB + cross(deltaAngularVelocityB,rB); + "vld1.32 {d14[1]}, [%5] \n\t" //LOAD => rA for cross product use 1A ---------> q7 (save these for use later) + "vld1.32 {d18[1]}, [%10] \n\t" //LOAD => rB for cross product use 1B ---------> q9 + "vld1.32 {d17[0]}, [%5]! \n\t" //LOAD => rA for cross product use 2A ---------> q8 + "vld1.32 {d21[0]}, [%10]! \n\t" //LOAD => rB for cross product use 2B ---------> q10 + "vld1.32 {d16}, [%5] \n\t" //rA 2 + "vld1.32 {d20}, [%10] \n\t" //rB 2 + "vld1.32 {d15[0]}, [%5]! \n\t" //rA 1 + "vld1.32 {d19[0]}, [%10]! \n\t" //rB 1 + "vld1.32 {d14[0]}, [%5]! \n\t" //rA 1 + "vld1.32 {d18[0]}, [%10]! \n\t" //rB 1 + "vld1.32 {d15[1]}, [%5] \n\t" //rA 1 + "vld1.32 {d19[1]}, [%10] \n\t" //rB 1 + "vld1.32 {d17[1]}, [%5]! \n\t" //rA 2 + "vld1.32 {d21[1]}, [%10]! \n\t" //rB 2 + "vmov.f32 q14, q1 \n\t" + "vmov.f32 q13, q3 \n\t" + "vmov.f32 q15, q1 \n\t" + "vmov.f32 q12, q3 \n\t" + "vrev64.32 d28, d28 \n\t" //set deltaAngularVelocityA 1 + "vtrn.32 d28, d29 \n\t" //set deltaAngularVelocityA 1 + "vrev64.32 d26, d26 \n\t" //set deltaAngularVelocityB 1 + "vmul.f32 q14, q7, q14 \n\t" //operation for cross product 1A + "vtrn.32 d26, d27 \n\t" //set deltaAngularVelocityB 1 + "vtrn.32 d30, d31 \n\t" //set deltaAngularVelocityA 2 + "vmul.f32 q13, q9, q13 \n\t" //operation for cross product 1B + "vtrn.32 d24, d25 \n\t" //set deltaAngularVelocityB 2 + "vrev64.32 d30, d30 \n\t" //set deltaAngularVelocityA 2 + "vrev64.32 d24, d24 \n\t" //set deltaAngularVelocityB 2 + "vmls.f32 q14, q8, q15 \n\t" //operation for cross product 2A + "vmls.f32 q13, q10, q12 \n\t" //operation for cross product 2B + "vadd.f32 q14, q14, q0 \n\t" //operation for adding cross to linearVelocityA + "vadd.f32 q13, q13, q2 \n\t" //operation for adding cross to linearVelocityB + //LOAD => dVA --------------------------------> q14 + //LOAD => dVB --------------------------------> q13 + //FREE q11, q12, q15, d11 + //deltaImpulse -= constraint.m_jacDiagInv * dot(normal,dVA-dVB); + "vsub.f32 q11, q14, q13 \n\t" //TEMP q11 => dVA-dVB for dot product + "vmul.f32 q11, q11, q4 \n\t" //operation for dot product + "vpadd.f32 d22, d22, d22 \n\t" //operation for dot product + "vpadd.f32 d23, d23, d23 \n\t" //operation for dot product + "vadd.f32 d22, d22, d23 \n\t" //operation for dot product + "vmul.f32 d22, d22, d12[0] \n\t" //m_jacDiagInv times dot product result + "vsub.f32 d10, d10, d22 \n\t" //subtract result from deltaImpule + //PfxFloat oldImpulse = constraint.m_accumImpulse; + "vdup.32 d11, d13[1] \n\t" //LOAD => oldImpulse -------------------------> q5 (d11 only) + //constraint.m_accumImpulse = SCE_PFX_CLAMP(oldImpulse + deltaImpulse,constraint.m_lowerLimit,constraint.m_upperLimit); + "vdup.32 d23, d13[0] \n\t" //TEMP q11 => m_upperLimit (d23 only) + "vdup.32 d24, d12[1] \n\t" //TEMP q12 => m_lowerLimit (d34 only) + "vadd.f32 d25, d10, d11 \n\t" //TEMP q12 => deltaImpulse + oldImplues (d25 only) + "vmin.f32 d25, d25, d23 \n\t" //operation MIN(v,b) + "vmax.f32 d22, d25, d24 \n\t" //operation MAX(a,MIN(v,b) + "vst1.32 {d22[0]}, [%0] \n\t" //store m_accumImpulse (incremented so that it can be reloaded for cross product later) + //deltaImpulse = constraint.m_accumImpulse - oldImpulse; + "vsub.f32 d10, d22, d11 \n\t" //operation to calculate new deltaImpule + //FREE q6, q11, q12, q13, q14, q15, d11 + //deltaLinearVelocityB -= deltaImpulse * massInvB * normal; + //deltaLinearVelocityA += deltaImpulse * massInvA * normal; + "vld1.32 {d11[0]}, [%3] \n\t" //LOAD => massInvA ---------------------------> q5 (d11[0] only) + "vld1.32 {d11[1]}, [%8] \n\t" //LOAD => massInvB ---------------------------> q5 (d11[1] only) + "vmul.f32 q11, q4, d11[0] \n\t" //TEMP q11 => operation normal times massInvA A + "vmul.f32 q12, q4, d11[1] \n\t" //TEMP q12 => operation normal times massInvB B + "vmul.f32 q11, q11, d10[0] \n\t" //TEMP q11 => operation result times DeltaImpulse A + "vmul.f32 q12, q12, d10[0] \n\t" //TEMP q12 => operation result times DeltaImpulse B + "vadd.f32 q0, q0, q11 \n\t" //operation create new deltaLinearVelocityA A + "vst1.32 {q0}, [%1] \n\t" //store the new deltaLinearVelocityA A + "vsub.f32 q2, q2, q12 \n\t" //operation create new deltaLinearVelocityB B + "vst1.32 {q2}, [%6] \n\t" //store the new deltaLinearVelocityB B + //FREE q0, q2, q6, q11, q12, q13, q14, q15, d11 + //deltaAngularVelocityA += deltaImpulse * inertiaInvA * cross(rA,normal); + //deltaAngularVelocityB -= deltaImpulse * inertiaInvB * cross(rB,normal); + "vmov.f32 q14, q4 \n\t" // + "vmov.f32 q15, q4 \n\t" // + "vtrn.32 d30, d31 \n\t" // + "vrev64.32 d30, d30 \n\t" // + "vmul.f32 q0, q8, q15 \n\t" //operation for cross product A + "vrev64.32 d28, d28 \n\t" // + "vmul.f32 q2, q10, q15 \n\t" //operation for cross product B + "vtrn.32 d28, d29 \n\t" // + "vmls.f32 q0, q14, q7 \n\t" //operation for cross product A + "vmls.f32 q2, q14, q9 \n\t" //operation for cross product B + //LOAD => cross product result A ------------> q0 + //LOAD => cross product result B ------------> q2 + //FREE q6, q7, q8, q9, q10, q11, q12, q13, q14, q15, d11 + + "vld1.32 {q13-q14}, [%4]! \n\t" //LOAD => inertiaInvA col0, col1 A ----------> q13, q14 + "vld1.32 {q9-q10}, [%9]! \n\t" //LOAD => inertiaInvB col0, col1 B -----------> q9, q10 + "vld1.32 {q15}, [%4] \n\t" //LOAD => inertiaInvA col2 A ----------------> q5 + "vld1.32 {q11}, [%9] \n\t" //LOAD => inertiaInvB col2 B -----------------> q11 + "vmul.f32 q13, q13, d0[0] \n\t" //operation inertiaInvA col0 = (col0) * (crossA elem0) A + "vmul.f32 q9, q9, d4[0] \n\t" //operation inertiaInvB col0 = (col0) * (crossB elem0) B + "vmla.f32 q13, q14, d0[1] \n\t" //operation inertiaInvA col1 = (col1) * (crossA elem1) A + "vmla.f32 q9, q10, d4[1] \n\t" //operation inertiaInvB col1 = (col1) * (crossB elem1) B + "vmla.f32 q13, q15, d1[0] \n\t" //operation inertiaInvA col2 = (col2) * (crossA elem2) A + "vmla.f32 q9, q11, d5[0] \n\t" //operation inertiaInvB col2 = (col2) * (crossB elem2) B + "vmul.f32 q13, q13, d10[0] \n\t" //operation inertiaInvA times deltaImpulse A + "vmul.f32 q9, q9, d10[0] \n\t" //operation inertiaInvB times deltaImpulse B + "vadd.f32 q1, q1, q13 \n\t" //operation accumulate the deltaAngularVelocityA A + "vst1.32 {q1}, [%2] \n\t" //store deltaAngularVelocityA A + "vsub.f32 q3, q3, q9 \n\t" //operation accumulate the deltaAngularVelocityB B + "vst1.32 {q3}, [%7] \n\t" //store deltaAngularVelocityB B + : // NO direct outputs! It is important to *not* put anything here. Real output is written directly to memory pointed to by inputs + : "r" (&constraint), "r" (&deltaLinearVelocityA), "r" (&deltaAngularVelocityA), "r" (&massInvA), "r" (&inertiaInvA), "r" (&rA), "r" (&deltaLinearVelocityB), "r" (&deltaAngularVelocityB), "r" (&massInvB), "r" (&inertiaInvB), "r" (&rB) //inputs + : "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" // clobbers + ); +} + +} //namespace PhysicsEffects +} //namespace sce +#endif //__ANDROID__ diff --git a/Extras/PhysicsEffects/src/base_level/solver/pfx_contact_constraint.cpp b/Extras/PhysicsEffects/src/base_level/solver/pfx_contact_constraint.cpp new file mode 100644 index 000000000..494d97d32 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/solver/pfx_contact_constraint.cpp @@ -0,0 +1,194 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "../../../include/physics_effects/base_level/solver/pfx_contact_constraint.h" +#include "pfx_constraint_row_solver.h" + +namespace sce { +namespace PhysicsEffects { + +#define SCE_PFX_CONTACT_SLOP 0.001f + +void pfxSetupContactConstraint( + PfxConstraintRow &constraintResponse, + PfxConstraintRow &constraintFriction1, + PfxConstraintRow &constraintFriction2, + PfxFloat penetrationDepth, + PfxFloat restitution, + PfxFloat friction, + const PfxVector3 &contactNormal, + const PfxVector3 &contactPointA, + const PfxVector3 &contactPointB, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + PfxFloat separateBias, + PfxFloat timeStep + ) +{ + (void)friction; + + PfxVector3 rA = rotate(solverBodyA.m_orientation,contactPointA); + PfxVector3 rB = rotate(solverBodyB.m_orientation,contactPointB); + + PfxFloat massInvA = solverBodyA.m_massInv; + PfxFloat massInvB = solverBodyB.m_massInv; + PfxMatrix3 inertiaInvA = solverBodyA.m_inertiaInv; + PfxMatrix3 inertiaInvB = solverBodyB.m_inertiaInv; + + if(solverBodyA.m_motionType == kPfxMotionTypeOneWay) { + massInvB = 0.0f; + inertiaInvB = PfxMatrix3(0.0f); + } + if(solverBodyB.m_motionType == kPfxMotionTypeOneWay) { + massInvA = 0.0f; + inertiaInvA = PfxMatrix3(0.0f); + } + + PfxMatrix3 K = PfxMatrix3::scale(PfxVector3(massInvA + massInvB)) - + crossMatrix(rA) * inertiaInvA * crossMatrix(rA) - + crossMatrix(rB) * inertiaInvB * crossMatrix(rB); + + PfxVector3 vA = stateA.getLinearVelocity() + cross(stateA.getAngularVelocity(),rA); + PfxVector3 vB = stateB.getLinearVelocity() + cross(stateB.getAngularVelocity(),rB); + PfxVector3 vAB = vA-vB; + + PfxVector3 tangent1,tangent2; + pfxGetPlaneSpace(contactNormal,tangent1,tangent2); + + // Contact Constraint + { + PfxVector3 normal = contactNormal; + + PfxFloat denom = dot(K*normal,normal); + + constraintResponse.m_rhs = -(1.0f+restitution)*dot(vAB,normal); // velocity error + constraintResponse.m_rhs -= (separateBias * SCE_PFX_MIN(0.0f,penetrationDepth+SCE_PFX_CONTACT_SLOP)) / timeStep; // position error + constraintResponse.m_rhs /= denom; + constraintResponse.m_jacDiagInv = 1.0f/denom; + constraintResponse.m_lowerLimit = 0.0f; + constraintResponse.m_upperLimit = SCE_PFX_FLT_MAX; + pfxStoreVector3(normal,constraintResponse.m_normal); + } + + // Friction Constraint 1 + { + PfxVector3 normal = tangent1; + + PfxFloat denom = dot(K*normal,normal); + + constraintFriction1.m_jacDiagInv = 1.0f/denom; + constraintFriction1.m_rhs = -dot(vAB,normal); + constraintFriction1.m_rhs *= constraintFriction1.m_jacDiagInv; + constraintFriction1.m_lowerLimit = 0.0f; + constraintFriction1.m_upperLimit = SCE_PFX_FLT_MAX; + pfxStoreVector3(normal,constraintFriction1.m_normal); + } + + // Friction Constraint 2 + { + PfxVector3 normal = tangent2; + + PfxFloat denom = dot(K*normal,normal); + + constraintFriction2.m_jacDiagInv = 1.0f/denom; + constraintFriction2.m_rhs = -dot(vAB,normal); + constraintFriction2.m_rhs *= constraintFriction2.m_jacDiagInv; + constraintFriction2.m_lowerLimit = 0.0f; + constraintFriction2.m_upperLimit = SCE_PFX_FLT_MAX; + pfxStoreVector3(normal,constraintFriction2.m_normal); + } +} + +void pfxSolveContactConstraint( + PfxConstraintRow &constraintResponse, + PfxConstraintRow &constraintFriction1, + PfxConstraintRow &constraintFriction2, + const PfxVector3 &contactPointA, + const PfxVector3 &contactPointB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + PfxFloat friction + ) +{ + PfxVector3 rA = rotate(solverBodyA.m_orientation,contactPointA); + PfxVector3 rB = rotate(solverBodyB.m_orientation,contactPointB); + + PfxFloat massInvA = solverBodyA.m_massInv; + PfxFloat massInvB = solverBodyB.m_massInv; + PfxMatrix3 inertiaInvA = solverBodyA.m_inertiaInv; + PfxMatrix3 inertiaInvB = solverBodyB.m_inertiaInv; + + if(solverBodyA.m_motionType == kPfxMotionTypeOneWay) { + massInvB = 0.0f; + inertiaInvB = PfxMatrix3(0.0f); + } + if(solverBodyB.m_motionType == kPfxMotionTypeOneWay) { + massInvA = 0.0f; + inertiaInvA = PfxMatrix3(0.0f); + } + +// ARA begin insert new code +#ifdef __ARM_NEON__ + pfxSolveLinearConstraintRowNEON(constraintResponse, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,massInvA,inertiaInvA,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,massInvB,inertiaInvB,rB); +#else // __ARM_NEON__ +// ARA end + + pfxSolveLinearConstraintRow(constraintResponse, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,massInvA,inertiaInvA,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,massInvB,inertiaInvB,rB); + +// ARA begin insert new code +#endif // __ARM_NEON__ +// ARA end + + PfxFloat mf = friction*fabsf(constraintResponse.m_accumImpulse); + constraintFriction1.m_lowerLimit = -mf; + constraintFriction1.m_upperLimit = mf; + constraintFriction2.m_lowerLimit = -mf; + constraintFriction2.m_upperLimit = mf; + +// ARA begin insert new code +#ifdef __ARM_NEON__ + pfxSolveLinearConstraintRowNEON(constraintFriction1, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,massInvA,inertiaInvA,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,massInvB,inertiaInvB,rB); + + pfxSolveLinearConstraintRowNEON(constraintFriction2, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,massInvA,inertiaInvA,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,massInvB,inertiaInvB,rB); +#else // __ARM_NEON__ +// ARA end + + pfxSolveLinearConstraintRow(constraintFriction1, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,massInvA,inertiaInvA,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,massInvB,inertiaInvB,rB); + + pfxSolveLinearConstraintRow(constraintFriction2, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,massInvA,inertiaInvA,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,massInvB,inertiaInvB,rB); + +// ARA begin insert new code +#endif // __ARM_NEON__ +// ARA end +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_ball.cpp b/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_ball.cpp new file mode 100644 index 000000000..37ca8678a --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_ball.cpp @@ -0,0 +1,179 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "../../../include/physics_effects/base_level/solver/pfx_joint_ball.h" +#include "pfx_constraint_row_solver.h" + +namespace sce { +namespace PhysicsEffects { + +PfxInt32 pfxInitializeBallJoint(PfxJoint &joint, + const PfxRigidState &stateA,const PfxRigidState &stateB, + const PfxBallJointInitParam ¶m) +{ + joint.m_active = 1; + joint.m_numConstraints = 3; + joint.m_userData = NULL; + joint.m_type = kPfxJointBall; + joint.m_rigidBodyIdA = stateA.getRigidBodyId(); + joint.m_rigidBodyIdB = stateB.getRigidBodyId(); + + for(int i=0;i<3;i++) { + joint.m_constraints[i].reset(); + } + + joint.m_constraints[0].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[1].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[2].m_lock = SCE_PFX_JOINT_LOCK_FIX; + + PfxMatrix3 rotA = transpose(PfxMatrix3(stateA.getOrientation())); + PfxMatrix3 rotB = transpose(PfxMatrix3(stateB.getOrientation())); + + joint.m_anchorA = rotA * (param.anchorPoint - stateA.getPosition()); + joint.m_anchorB = rotB * (param.anchorPoint - stateB.getPosition()); + + joint.m_frameA = PfxMatrix3::identity(); + joint.m_frameB = rotB * PfxMatrix3(stateA.getOrientation()) * joint.m_frameA; + + return SCE_PFX_OK; +} + +void pfxSetupBallJoint( + PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + PfxFloat timeStep + ) +{ + PfxVector3 rA = rotate(solverBodyA.m_orientation,joint.m_anchorA); + PfxVector3 rB = rotate(solverBodyB.m_orientation,joint.m_anchorB); + + PfxVector3 vA = stateA.getLinearVelocity() + cross(stateA.getAngularVelocity(),rA); + PfxVector3 vB = stateB.getLinearVelocity() + cross(stateB.getAngularVelocity(),rB); + PfxVector3 vAB = vA-vB; + + PfxVector3 distance = (stateA.getPosition() + rA) - (stateB.getPosition() + rB); + + PfxMatrix3 worldFrameA,worldFrameB; + worldFrameA = PfxMatrix3(solverBodyA.m_orientation) * joint.m_frameA; + worldFrameB = PfxMatrix3(solverBodyB.m_orientation) * joint.m_frameB; + + // Linear Constraint + PfxMatrix3 K = PfxMatrix3::scale(PfxVector3(solverBodyA.m_massInv + solverBodyB.m_massInv)) - + crossMatrix(rA) * solverBodyA.m_inertiaInv * crossMatrix(rA) - + crossMatrix(rB) * solverBodyB.m_inertiaInv * crossMatrix(rB); + + for(int c=0;c<3;c++) { + PfxJointConstraint &jointConstraint = joint.m_constraints[c]; + PfxConstraintRow &constraint = jointConstraint.m_constraintRow; + + PfxVector3 normal = worldFrameA[c]; + + PfxFloat posErr = dot(distance,-normal); + PfxFloat lowerLimit = -jointConstraint.m_maxImpulse; + PfxFloat upperLimit = jointConstraint.m_maxImpulse; + PfxFloat velocityAmp = 1.0f; + + pfxCalcLinearLimit(jointConstraint,posErr,velocityAmp,lowerLimit,upperLimit); + + PfxFloat denom = dot(K*normal,normal); + + constraint.m_rhs = -velocityAmp*dot(vAB,normal); + constraint.m_rhs -= (jointConstraint.m_bias * (-posErr)) / timeStep; + constraint.m_rhs *= jointConstraint.m_weight/denom; + constraint.m_jacDiagInv = jointConstraint.m_weight*velocityAmp/denom; + constraint.m_lowerLimit = lowerLimit; + constraint.m_upperLimit = upperLimit; + pfxStoreVector3(normal,constraint.m_normal); + } +} + +void pfxWarmStartBallJoint( + PfxJoint &joint, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB + ) +{ + PfxVector3 rA = rotate(solverBodyA.m_orientation,joint.m_anchorA); + PfxVector3 rB = rotate(solverBodyB.m_orientation,joint.m_anchorB); + + // Linear Constraint + for(int c=0;c<3;c++) { + PfxJointConstraint &jointConstraint = joint.m_constraints[c]; + PfxConstraintRow &constraint = jointConstraint.m_constraintRow; + + if(jointConstraint.m_warmStarting == 0) { + constraint.m_accumImpulse = 0.0f; + } + else { + PfxVector3 normal = pfxReadVector3(constraint.m_normal); + PfxFloat deltaImpulse = constraint.m_accumImpulse; + solverBodyA.m_deltaLinearVelocity += deltaImpulse * solverBodyA.m_massInv * normal; + solverBodyA.m_deltaAngularVelocity += deltaImpulse * solverBodyA.m_inertiaInv * cross(rA,normal); + solverBodyB.m_deltaLinearVelocity -= deltaImpulse * solverBodyB.m_massInv * normal; + solverBodyB.m_deltaAngularVelocity -= deltaImpulse * solverBodyB.m_inertiaInv * cross(rB,normal); + } + } +} + +void pfxSolveBallJoint( + PfxJoint &joint, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB + ) +{ + PfxVector3 rA = rotate(solverBodyA.m_orientation,joint.m_anchorA); + PfxVector3 rB = rotate(solverBodyB.m_orientation,joint.m_anchorB); + + // Linear Constraint +// ARA begin insert new code +#ifdef __ARM_NEON__ + pfxSolveLinearConstraintRowNEON(joint.m_constraints[0].m_constraintRow, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); + + pfxSolveLinearConstraintRowNEON(joint.m_constraints[1].m_constraintRow, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); + + pfxSolveLinearConstraintRowNEON(joint.m_constraints[2].m_constraintRow, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); +#else // __ARM_NEON__ +// ARA end + + pfxSolveLinearConstraintRow(joint.m_constraints[0].m_constraintRow, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); + + pfxSolveLinearConstraintRow(joint.m_constraints[1].m_constraintRow, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); + + pfxSolveLinearConstraintRow(joint.m_constraints[2].m_constraintRow, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); + +// ARA begin insert new code +#endif // __ARM_NEON__ +// ARA end +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_fix.cpp b/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_fix.cpp new file mode 100644 index 000000000..bb5509f65 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_fix.cpp @@ -0,0 +1,54 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "../../../include/physics_effects/base_level/solver/pfx_joint_fix.h" +#include "pfx_constraint_row_solver.h" + +namespace sce { +namespace PhysicsEffects { + +PfxInt32 pfxInitializeFixJoint(PfxJoint &joint, + const PfxRigidState &stateA,const PfxRigidState &stateB, + const PfxFixJointInitParam ¶m) +{ + joint.m_active = 1; + joint.m_numConstraints = 6; + joint.m_userData = NULL; + joint.m_type = kPfxJointFix; + joint.m_rigidBodyIdA = stateA.getRigidBodyId(); + joint.m_rigidBodyIdB = stateB.getRigidBodyId(); + + for(int i=0;i<6;i++) { + joint.m_constraints[i].reset(); + joint.m_constraints[i].m_lock = SCE_PFX_JOINT_LOCK_FIX; + } + + // Calc joint frame + PfxMatrix3 rotA = transpose(PfxMatrix3(stateA.getOrientation())); + PfxMatrix3 rotB = transpose(PfxMatrix3(stateB.getOrientation())); + + joint.m_anchorA = rotA * (param.anchorPoint - stateA.getPosition()); + joint.m_anchorB = rotB * (param.anchorPoint - stateB.getPosition()); + + joint.m_frameA = PfxMatrix3::identity(); + joint.m_frameB = rotB * PfxMatrix3(stateA.getOrientation()) * joint.m_frameA; + + return SCE_PFX_OK; +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_hinge.cpp b/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_hinge.cpp new file mode 100644 index 000000000..c913a36a3 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_hinge.cpp @@ -0,0 +1,80 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "../../../include/physics_effects/base_level/solver/pfx_joint_hinge.h" +#include "pfx_constraint_row_solver.h" + +namespace sce { +namespace PhysicsEffects { + +PfxInt32 pfxInitializeHingeJoint(PfxJoint &joint, + const PfxRigidState &stateA,const PfxRigidState &stateB, + const PfxHingeJointInitParam ¶m) +{ + joint.m_active = 1; + joint.m_numConstraints = 6; + joint.m_userData = NULL; + joint.m_type = kPfxJointHinge; + joint.m_rigidBodyIdA = stateA.getRigidBodyId(); + joint.m_rigidBodyIdB = stateB.getRigidBodyId(); + + for(int i=0;i<6;i++) { + joint.m_constraints[i].reset(); + } + + joint.m_constraints[0].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[1].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[2].m_lock = SCE_PFX_JOINT_LOCK_FIX; + if(param.lowerAngle == 0.0f && param.upperAngle == 0.0f) { + joint.m_constraints[3].m_lock = SCE_PFX_JOINT_LOCK_FREE; + } + else { + joint.m_constraints[3].m_lock = SCE_PFX_JOINT_LOCK_LIMIT; + } + joint.m_constraints[4].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[5].m_lock = SCE_PFX_JOINT_LOCK_FIX; + + // Set twist angle limit + if(param.lowerAngle > param.upperAngle || + !SCE_PFX_RANGE_CHECK(param.lowerAngle,-SCE_PFX_PI,SCE_PFX_PI) || + !SCE_PFX_RANGE_CHECK(param.upperAngle,-SCE_PFX_PI,SCE_PFX_PI)) { + return SCE_PFX_ERR_OUT_OF_RANGE; + } + joint.m_constraints[3].m_movableLowerLimit = param.lowerAngle; + joint.m_constraints[3].m_movableUpperLimit = param.upperAngle; + + // Calc joint frame + PfxMatrix3 rotA = transpose(PfxMatrix3(stateA.getOrientation())); + PfxMatrix3 rotB = transpose(PfxMatrix3(stateB.getOrientation())); + + PfxVector3 axisInA = rotA * normalize(param.axis); + + joint.m_anchorA = rotA * (param.anchorPoint - stateA.getPosition()); + joint.m_anchorB = rotB * (param.anchorPoint - stateB.getPosition()); + + PfxVector3 axis1, axis2; + + pfxGetPlaneSpace(axisInA, axis1, axis2 ); + + joint.m_frameA = PfxMatrix3(axisInA, axis1, axis2); + joint.m_frameB = rotB * PfxMatrix3(stateA.getOrientation()) * joint.m_frameA; + + return SCE_PFX_OK; +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_slider.cpp b/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_slider.cpp new file mode 100644 index 000000000..8b843cc57 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_slider.cpp @@ -0,0 +1,78 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "../../../include/physics_effects/base_level/solver/pfx_joint_slider.h" +#include "pfx_constraint_row_solver.h" + +namespace sce { +namespace PhysicsEffects { + +PfxInt32 pfxInitializeSliderJoint(PfxJoint &joint, + const PfxRigidState &stateA,const PfxRigidState &stateB, + const PfxSliderJointInitParam ¶m) +{ + joint.m_active = 1; + joint.m_numConstraints = 6; + joint.m_userData = NULL; + joint.m_type = kPfxJointSlider; + joint.m_rigidBodyIdA = stateA.getRigidBodyId(); + joint.m_rigidBodyIdB = stateB.getRigidBodyId(); + + for(int i=0;i<6;i++) { + joint.m_constraints[i].reset(); + } + + if(param.lowerDistance == 0.0f && param.upperDistance == 0.0f) { + joint.m_constraints[0].m_lock = SCE_PFX_JOINT_LOCK_FREE; + } + else { + joint.m_constraints[0].m_lock = SCE_PFX_JOINT_LOCK_LIMIT; + } + joint.m_constraints[1].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[2].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[3].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[4].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[5].m_lock = SCE_PFX_JOINT_LOCK_FIX; + + if(param.lowerDistance > param.upperDistance ) { + return SCE_PFX_ERR_OUT_OF_RANGE; + } + + joint.m_constraints[0].m_movableLowerLimit = param.lowerDistance; + joint.m_constraints[0].m_movableUpperLimit = param.upperDistance; + + // Calc joint frame + PfxMatrix3 rotA = transpose(PfxMatrix3(stateA.getOrientation())); + PfxMatrix3 rotB = transpose(PfxMatrix3(stateB.getOrientation())); + + PfxVector3 axisInA = rotA * normalize(param.direction); + + joint.m_anchorA = rotA * (param.anchorPoint - stateA.getPosition()); + joint.m_anchorB = rotB * (param.anchorPoint - stateB.getPosition()); + + PfxVector3 axis1, axis2; + + pfxGetPlaneSpace(axisInA, axis1, axis2 ); + + joint.m_frameA = PfxMatrix3(axisInA, axis1, axis2); + joint.m_frameB = rotB * PfxMatrix3(stateA.getOrientation()) * joint.m_frameA; + + return SCE_PFX_OK; +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_swing_twist.cpp b/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_swing_twist.cpp new file mode 100644 index 000000000..f19b5c317 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_swing_twist.cpp @@ -0,0 +1,268 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "../../../include/physics_effects/base_level/solver/pfx_joint_swing_twist.h" +#include "pfx_constraint_row_solver.h" + + +namespace sce { +namespace PhysicsEffects { + +PfxInt32 pfxInitializeSwingTwistJoint(PfxJoint &joint, + const PfxRigidState &stateA,const PfxRigidState &stateB, + const PfxSwingTwistJointInitParam ¶m) +{ + joint.m_active = 1; + joint.m_numConstraints = 6; + joint.m_userData = NULL; + joint.m_type = kPfxJointSwingtwist; + joint.m_rigidBodyIdA = stateA.getRigidBodyId(); + joint.m_rigidBodyIdB = stateB.getRigidBodyId(); + + for(int i=0;i<6;i++) { + joint.m_constraints[i].reset(); + } + + joint.m_constraints[0].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[1].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[2].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[3].m_lock = SCE_PFX_JOINT_LOCK_LIMIT; + joint.m_constraints[4].m_lock = SCE_PFX_JOINT_LOCK_LIMIT; + joint.m_constraints[5].m_lock = SCE_PFX_JOINT_LOCK_FREE; + + // Set twist angle limit + if(param.twistLowerAngle > param.twistUpperAngle || + !SCE_PFX_RANGE_CHECK(param.twistLowerAngle,-SCE_PFX_PI,SCE_PFX_PI) || + !SCE_PFX_RANGE_CHECK(param.twistUpperAngle,-SCE_PFX_PI,SCE_PFX_PI)) { + return SCE_PFX_ERR_OUT_OF_RANGE; + } + joint.m_constraints[3].m_movableLowerLimit = param.twistLowerAngle; + joint.m_constraints[3].m_movableUpperLimit = param.twistUpperAngle; + + // Set swing angle limit + if(param.swingLowerAngle > param.swingUpperAngle || + !SCE_PFX_RANGE_CHECK(param.swingLowerAngle,0.0f,SCE_PFX_PI) || + !SCE_PFX_RANGE_CHECK(param.swingUpperAngle,0.0f,SCE_PFX_PI)) { + return SCE_PFX_ERR_OUT_OF_RANGE; + } + joint.m_constraints[4].m_movableLowerLimit = param.swingLowerAngle; + joint.m_constraints[4].m_movableUpperLimit = param.swingUpperAngle; + + // Calc joint frame + PfxMatrix3 rotA = transpose(PfxMatrix3(stateA.getOrientation())); + PfxMatrix3 rotB = transpose(PfxMatrix3(stateB.getOrientation())); + + PfxVector3 axisInA = rotA * normalize(param.twistAxis); + + joint.m_anchorA = rotA * (param.anchorPoint - stateA.getPosition()); + joint.m_anchorB = rotB * (param.anchorPoint - stateB.getPosition()); + + PfxVector3 axis1, axis2; + + pfxGetPlaneSpace(axisInA, axis1, axis2 ); + + joint.m_frameA = PfxMatrix3(axisInA, axis1, axis2); + joint.m_frameB = rotB * PfxMatrix3(stateA.getOrientation()) * joint.m_frameA; + + return SCE_PFX_OK; +} + +void pfxSetupSwingTwistJoint( + PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + PfxFloat timeStep + ) +{ + PfxVector3 rA = rotate(solverBodyA.m_orientation,joint.m_anchorA); + PfxVector3 rB = rotate(solverBodyB.m_orientation,joint.m_anchorB); + + PfxVector3 vA = stateA.getLinearVelocity() + cross(stateA.getAngularVelocity(),rA); + PfxVector3 vB = stateB.getLinearVelocity() + cross(stateB.getAngularVelocity(),rB); + PfxVector3 vAB = vA-vB; + + PfxVector3 angAB = stateA.getAngularVelocity() - stateB.getAngularVelocity(); + + PfxVector3 distance = (stateA.getPosition() + rA) - (stateB.getPosition() + rB); + + PfxMatrix3 worldFrameA,worldFrameB; + worldFrameA = PfxMatrix3(solverBodyA.m_orientation) * joint.m_frameA; + worldFrameB = PfxMatrix3(solverBodyB.m_orientation) * joint.m_frameB; + + // Linear Constraint + PfxMatrix3 K = PfxMatrix3::scale(PfxVector3(solverBodyA.m_massInv + solverBodyB.m_massInv)) - + crossMatrix(rA) * solverBodyA.m_inertiaInv * crossMatrix(rA) - + crossMatrix(rB) * solverBodyB.m_inertiaInv * crossMatrix(rB); + + for(int c=0;c<3;c++) { + PfxJointConstraint &jointConstraint = joint.m_constraints[c]; + PfxConstraintRow &constraint = jointConstraint.m_constraintRow; + + PfxVector3 normal = worldFrameA[c]; + + PfxFloat posErr = dot(distance,-normal); + PfxFloat lowerLimit = -jointConstraint.m_maxImpulse; + PfxFloat upperLimit = jointConstraint.m_maxImpulse; + PfxFloat velocityAmp = 1.0f; + + pfxCalcLinearLimit(jointConstraint,posErr,velocityAmp,lowerLimit,upperLimit); + + PfxFloat denom = dot(K*normal,normal); + + constraint.m_rhs = -velocityAmp*dot(vAB,normal); + constraint.m_rhs -= (jointConstraint.m_bias * (-posErr)) / timeStep; + constraint.m_rhs *= jointConstraint.m_weight/denom; + constraint.m_jacDiagInv = jointConstraint.m_weight*velocityAmp/denom; + constraint.m_lowerLimit = lowerLimit; + constraint.m_upperLimit = upperLimit; + pfxStoreVector3(normal,constraint.m_normal); + } + + PfxVector3 axis[3]; + PfxFloat angle[3]; + pfxCalcJointAngleSwingTwist(worldFrameA,worldFrameB,angle,axis); + + // Angular Constraint + for(int c=3;c<6;c++) { + PfxJointConstraint &jointConstraint = joint.m_constraints[c]; + PfxConstraintRow &constraint = jointConstraint.m_constraintRow; + + PfxVector3 normal = axis[c-3]; + + PfxFloat posErr = angle[c-3]; + PfxFloat lowerLimit = -jointConstraint.m_maxImpulse; + PfxFloat upperLimit = jointConstraint.m_maxImpulse; + PfxFloat velocityAmp = 1.0f; + + pfxCalcAngularLimit(jointConstraint,posErr,velocityAmp,lowerLimit,upperLimit); + + PfxFloat denom = dot((solverBodyA.m_inertiaInv+solverBodyB.m_inertiaInv)*normal,normal); + + constraint.m_rhs = -velocityAmp*dot(angAB,normal); // velocity error + constraint.m_rhs -= (jointConstraint.m_bias * (-posErr)) / timeStep; // position error + constraint.m_rhs *= jointConstraint.m_weight/denom; + constraint.m_jacDiagInv = jointConstraint.m_weight*velocityAmp/denom; + constraint.m_lowerLimit = lowerLimit; + constraint.m_upperLimit = upperLimit; + pfxStoreVector3(normal,constraint.m_normal); + } +} + +void pfxWarmStartSwingTwistJoint( + PfxJoint &joint, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB + ) +{ + PfxVector3 rA = rotate(solverBodyA.m_orientation,joint.m_anchorA); + PfxVector3 rB = rotate(solverBodyB.m_orientation,joint.m_anchorB); + + // Linear Constraint + for(int c=0;c<3;c++) { + PfxJointConstraint &jointConstraint = joint.m_constraints[c]; + PfxConstraintRow &constraint = jointConstraint.m_constraintRow; + + if(jointConstraint.m_warmStarting == 0) { + constraint.m_accumImpulse = 0.0f; + } + else { + PfxVector3 normal = pfxReadVector3(constraint.m_normal); + PfxFloat deltaImpulse = constraint.m_accumImpulse; + solverBodyA.m_deltaLinearVelocity += deltaImpulse * solverBodyA.m_massInv * normal; + solverBodyA.m_deltaAngularVelocity += deltaImpulse * solverBodyA.m_inertiaInv * cross(rA,normal); + solverBodyB.m_deltaLinearVelocity -= deltaImpulse * solverBodyB.m_massInv * normal; + solverBodyB.m_deltaAngularVelocity -= deltaImpulse * solverBodyB.m_inertiaInv * cross(rB,normal); + } + } + + // Angular Constraint + for(int c=3;c<6;c++) { + PfxJointConstraint &jointConstraint = joint.m_constraints[c]; + PfxConstraintRow &constraint = jointConstraint.m_constraintRow; + + if(jointConstraint.m_warmStarting == 0) { + constraint.m_accumImpulse = 0.0f; + } + else { + PfxVector3 normal = pfxReadVector3(constraint.m_normal); + PfxFloat deltaImpulse = constraint.m_accumImpulse; + solverBodyA.m_deltaAngularVelocity += deltaImpulse * solverBodyA.m_inertiaInv * normal; + solverBodyB.m_deltaAngularVelocity -= deltaImpulse * solverBodyB.m_inertiaInv * normal; + } + } +} + +void pfxSolveSwingTwistJoint( + PfxJoint &joint, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB + ) +{ + PfxVector3 rA = rotate(solverBodyA.m_orientation,joint.m_anchorA); + PfxVector3 rB = rotate(solverBodyB.m_orientation,joint.m_anchorB); + + // Linear Constraint +// ARA begin insert new code +#ifdef __ARM_NEON__ + pfxSolveLinearConstraintRowNEON(joint.m_constraints[0].m_constraintRow, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); + + pfxSolveLinearConstraintRowNEON(joint.m_constraints[1].m_constraintRow, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); + + pfxSolveLinearConstraintRowNEON(joint.m_constraints[2].m_constraintRow, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); +#else // __ARM_NEON__ +// ARA end + + pfxSolveLinearConstraintRow(joint.m_constraints[0].m_constraintRow, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); + + pfxSolveLinearConstraintRow(joint.m_constraints[1].m_constraintRow, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); + + pfxSolveLinearConstraintRow(joint.m_constraints[2].m_constraintRow, + solverBodyA.m_deltaLinearVelocity,solverBodyA.m_deltaAngularVelocity,solverBodyA.m_massInv,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaLinearVelocity,solverBodyB.m_deltaAngularVelocity,solverBodyB.m_massInv,solverBodyB.m_inertiaInv,rB); + +// ARA begin insert new code +#endif // __ARM_NEON__ +// ARA end + + // Angular Constraint + pfxSolveAngularConstraintRow(joint.m_constraints[3].m_constraintRow, + solverBodyA.m_deltaAngularVelocity,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaAngularVelocity,solverBodyB.m_inertiaInv,rB); + + pfxSolveAngularConstraintRow(joint.m_constraints[4].m_constraintRow, + solverBodyA.m_deltaAngularVelocity,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaAngularVelocity,solverBodyB.m_inertiaInv,rB); + + pfxSolveAngularConstraintRow(joint.m_constraints[5].m_constraintRow, + solverBodyA.m_deltaAngularVelocity,solverBodyA.m_inertiaInv,rA, + solverBodyB.m_deltaAngularVelocity,solverBodyB.m_inertiaInv,rB); +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_universal.cpp b/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_universal.cpp new file mode 100644 index 000000000..0e8a39ca5 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/solver/pfx_joint_universal.cpp @@ -0,0 +1,163 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "../../../include/physics_effects/base_level/solver/pfx_joint_universal.h" +#include "pfx_constraint_row_solver.h" + +namespace sce { +namespace PhysicsEffects { + +PfxInt32 pfxInitializeUniversalJoint(PfxJoint &joint, + const PfxRigidState &stateA,const PfxRigidState &stateB, + const PfxUniversalJointInitParam ¶m) +{ + joint.m_active = 1; + joint.m_numConstraints = 6; + joint.m_userData = NULL; + joint.m_type = kPfxJointUniversal; + joint.m_rigidBodyIdA = stateA.getRigidBodyId(); + joint.m_rigidBodyIdB = stateB.getRigidBodyId(); + + for(int i=0;i<6;i++) { + joint.m_constraints[i].reset(); + } + + joint.m_constraints[0].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[1].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[2].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[3].m_lock = SCE_PFX_JOINT_LOCK_FIX; + joint.m_constraints[4].m_lock = SCE_PFX_JOINT_LOCK_LIMIT; + joint.m_constraints[5].m_lock = SCE_PFX_JOINT_LOCK_LIMIT; + + // Set swing angle limit + if(param.swing1LowerAngle > param.swing1UpperAngle || + !SCE_PFX_RANGE_CHECK(param.swing1LowerAngle,-SCE_PFX_PI,SCE_PFX_PI) || + !SCE_PFX_RANGE_CHECK(param.swing1UpperAngle,-SCE_PFX_PI,SCE_PFX_PI) || + param.swing2LowerAngle > param.swing2UpperAngle || + !SCE_PFX_RANGE_CHECK(param.swing2LowerAngle,-SCE_PFX_PI,SCE_PFX_PI) || + !SCE_PFX_RANGE_CHECK(param.swing2UpperAngle,-SCE_PFX_PI,SCE_PFX_PI)) { + return SCE_PFX_ERR_OUT_OF_RANGE; + } + + joint.m_constraints[4].m_movableLowerLimit = param.swing1LowerAngle; + joint.m_constraints[4].m_movableUpperLimit = param.swing1UpperAngle; + joint.m_constraints[5].m_movableLowerLimit = param.swing2LowerAngle; + joint.m_constraints[5].m_movableUpperLimit = param.swing2UpperAngle; + + // Calc joint frame + PfxMatrix3 rotA = transpose(PfxMatrix3(stateA.getOrientation())); + PfxMatrix3 rotB = transpose(PfxMatrix3(stateB.getOrientation())); + + PfxVector3 axisInA = rotA * normalize(param.axis); + + joint.m_anchorA = rotA * (param.anchorPoint - stateA.getPosition()); + joint.m_anchorB = rotB * (param.anchorPoint - stateB.getPosition()); + + PfxVector3 axis1, axis2; + + pfxGetPlaneSpace(axisInA, axis1, axis2 ); + + joint.m_frameA = PfxMatrix3(axisInA, axis1, axis2); + joint.m_frameB = rotB * PfxMatrix3(stateA.getOrientation()) * joint.m_frameA; + + return SCE_PFX_OK; +} + +void pfxSetupUniversalJoint( + PfxJoint &joint, + const PfxRigidState &stateA, + const PfxRigidState &stateB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + PfxFloat timeStep + ) +{ + PfxVector3 rA = rotate(solverBodyA.m_orientation,joint.m_anchorA); + PfxVector3 rB = rotate(solverBodyB.m_orientation,joint.m_anchorB); + + PfxVector3 vA = stateA.getLinearVelocity() + cross(stateA.getAngularVelocity(),rA); + PfxVector3 vB = stateB.getLinearVelocity() + cross(stateB.getAngularVelocity(),rB); + PfxVector3 vAB = vA-vB; + + PfxVector3 angAB = stateA.getAngularVelocity() - stateB.getAngularVelocity(); + + PfxVector3 distance = (stateA.getPosition() + rA) - (stateB.getPosition() + rB); + + PfxMatrix3 worldFrameA,worldFrameB; + worldFrameA = PfxMatrix3(solverBodyA.m_orientation) * joint.m_frameA; + worldFrameB = PfxMatrix3(solverBodyB.m_orientation) * joint.m_frameB; + + // Linear Constraint + PfxMatrix3 K = PfxMatrix3::scale(PfxVector3(solverBodyA.m_massInv + solverBodyB.m_massInv)) - + crossMatrix(rA) * solverBodyA.m_inertiaInv * crossMatrix(rA) - + crossMatrix(rB) * solverBodyB.m_inertiaInv * crossMatrix(rB); + + for(int c=0;c<3;c++) { + PfxJointConstraint &jointConstraint = joint.m_constraints[c]; + PfxConstraintRow &constraint = jointConstraint.m_constraintRow; + + PfxVector3 normal = worldFrameA[c]; + + PfxFloat posErr = dot(distance,-normal); + PfxFloat lowerLimit = -jointConstraint.m_maxImpulse; + PfxFloat upperLimit = jointConstraint.m_maxImpulse; + PfxFloat velocityAmp = 1.0f; + + pfxCalcLinearLimit(jointConstraint,posErr,velocityAmp,lowerLimit,upperLimit); + + PfxFloat denom = dot(K*normal,normal); + + constraint.m_rhs = -velocityAmp*dot(vAB,normal); + constraint.m_rhs -= (jointConstraint.m_bias * (-posErr)) / timeStep; + constraint.m_rhs *= jointConstraint.m_weight/denom; + constraint.m_jacDiagInv = jointConstraint.m_weight*velocityAmp/denom; + constraint.m_lowerLimit = lowerLimit; + constraint.m_upperLimit = upperLimit; + pfxStoreVector3(normal,constraint.m_normal); + } + + PfxVector3 axis[3]; + PfxFloat angle[3]; + pfxCalcJointAngleUniversal(worldFrameA,worldFrameB,angle,axis); + + // Angular Constraint + for(int c=3;c<6;c++) { + PfxJointConstraint &jointConstraint = joint.m_constraints[c]; + PfxConstraintRow &constraint = jointConstraint.m_constraintRow; + + PfxVector3 normal = axis[c-3]; + + PfxFloat posErr = angle[c-3]; + PfxFloat lowerLimit = -jointConstraint.m_maxImpulse; + PfxFloat upperLimit = jointConstraint.m_maxImpulse; + PfxFloat velocityAmp = 1.0f; + + pfxCalcAngularLimit(jointConstraint,posErr,velocityAmp,lowerLimit,upperLimit); + + PfxFloat denom = dot((solverBodyA.m_inertiaInv+solverBodyB.m_inertiaInv)*normal,normal); + + constraint.m_rhs = -velocityAmp*dot(angAB,normal); // velocity error + constraint.m_rhs -= (jointConstraint.m_bias * (-posErr)) / timeStep; // position error + constraint.m_rhs *= jointConstraint.m_weight/denom; + constraint.m_jacDiagInv = jointConstraint.m_weight*velocityAmp/denom; + constraint.m_lowerLimit = lowerLimit; + constraint.m_upperLimit = upperLimit; + pfxStoreVector3(normal,constraint.m_normal); + } +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/base_level/sort/pfx_sort.cpp b/Extras/PhysicsEffects/src/base_level/sort/pfx_sort.cpp new file mode 100644 index 000000000..7ce6509a1 --- /dev/null +++ b/Extras/PhysicsEffects/src/base_level/sort/pfx_sort.cpp @@ -0,0 +1,267 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/sort/pfx_sort.h" + +namespace sce { +namespace PhysicsEffects { + + +#define Key(a) pfxGetKey(a) + +/////////////////////////////////////////////////////////////////////////////// +// Merge Sort + + + +template +SCE_PFX_FORCE_INLINE +void pfxCompareAndSwap(SortData &d1,SortData &d2) +{ +if(Key(d1) > Key(d2)) { + SortData tmp = d1; + d1 = d2; + d2 = tmp; +} +} + +template +SCE_PFX_FORCE_INLINE +void pfxMergeTwoBuffers11(SortData* d1,int n1,SortData* d2,int n2) +{ +(void)n1,(void)n2,(void)d2; +pfxCompareAndSwap(d1[0],d1[1]); +} + +template +SCE_PFX_FORCE_INLINE +void pfxMergeTwoBuffers12(SortData* d1,int n1,SortData* d2,int n2) +{ +(void)n1,(void)d2,(void)n2; +pfxCompareAndSwap(d1[0],d1[1]); +pfxCompareAndSwap(d1[1],d1[2]); +} + +template +SCE_PFX_FORCE_INLINE +void pfxMergeTwoBuffers22(SortData* d1,int n1,SortData* d2,int n2) +{ +(void)n1,(void)d2,(void)n2; +pfxCompareAndSwap(d1[0],d1[2]); +pfxCompareAndSwap(d1[1],d1[3]); +pfxCompareAndSwap(d1[1],d1[2]); +} + +template +SCE_PFX_FORCE_INLINE +void pfxMergeTwoBuffers23(SortData* d1,int n1,SortData* d2,int n2) +{ +(void)n1,(void)d2,(void)n2; +pfxCompareAndSwap(d1[0],d1[2]); +pfxCompareAndSwap(d1[1],d1[4]); +pfxCompareAndSwap(d1[2],d1[3]); +pfxCompareAndSwap(d1[1],d1[2]); +pfxCompareAndSwap(d1[2],d1[3]); +} + +template +SCE_PFX_FORCE_INLINE +void pfxMergeTwoBuffers33(SortData* d1,int n1,SortData* d2,int n2) +{ +(void)n1,(void)d2,(void)n2; +pfxCompareAndSwap(d1[0],d1[3]); +pfxCompareAndSwap(d1[2],d1[5]); +pfxCompareAndSwap(d1[1],d1[2]); +pfxCompareAndSwap(d1[3],d1[4]); +pfxCompareAndSwap(d1[1],d1[3]); +pfxCompareAndSwap(d1[2],d1[4]); +pfxCompareAndSwap(d1[2],d1[3]); +} + +template +void pfxMergeTwoBuffers(SortData* d1,unsigned int n1,SortData* d2,unsigned int n2,SortData *buff) +{ +unsigned int i=0,j=0; + +while(i +void pfxMergeSort(SortData *d,SortData *buff,int n) +{ +int n1 = n>>1; +int n2 = n-n1; +if(n1>1) pfxMergeSort(d,buff,n1); +if(n2>1) pfxMergeSort(d+n1,buff,n2); + +int nadd = n1+n2; + +if(nadd==2) { + pfxMergeTwoBuffers11(d,n1,d+n1,n2); +} +else if(nadd==3) { + pfxMergeTwoBuffers12(d,n1,d+n1,n2); +} +else if(nadd==4) { + pfxMergeTwoBuffers22(d,n1,d+n1,n2); +} +else if(nadd==5) { + pfxMergeTwoBuffers23(d,n1,d+n1,n2); +} +else if(nadd==6) { + pfxMergeTwoBuffers33(d,n1,d+n1,n2); +} +else { + pfxMergeTwoBuffers(d,n1,d+n1,n2,buff); +} +} + + +/////////////////////////////////////////////////////////////////////////////// +// Bitonic Sort + + +template +void pfxBitonicMerge(SortData *d,unsigned int n,int dir) +{ +if(n > 1) { + unsigned int k = n>>1; + for(unsigned int i=0;i Key(d[i+k])) { + SortData t = d[i+k]; + d[i+k] = d[i]; + d[i] = t; + } + if(dir==1 && Key(d[i]) < Key(d[i+k])) { + SortData t = d[i+k]; + d[i+k] = d[i]; + d[i] = t; + } + } + pfxBitonicMerge(d,k,dir); + pfxBitonicMerge(d+k,k,dir); +} +} + +template +void pfxBitonicSortInternal(SortData *d,unsigned int n,unsigned int dir=0) +{ +if(n > 1) { + unsigned int k = n>>1; + pfxBitonicSortInternal(d,k,0); + pfxBitonicSortInternal(d+k,k,1); + pfxBitonicMerge(d,n,dir); +} +} + +template +void pfxBitonicSort(SortData *d,SortData *buff,unsigned int n) +{ +pfxBitonicSortInternal(d,n,0); +memcpy(buff,d,sizeof(SortData)*n); +} + + +/////////////////////////////////////////////////////////////////////////////// +// Hybrid Sort (Bitonic + Merge) + +struct PfxDiv2n { + unsigned int id; + unsigned int num; + + PfxDiv2n() {} + + PfxDiv2n(unsigned int i,unsigned int n) + { + id = i; + num = n; + } +}; + +template +void pfxHybridSort(SortData *data,SortData *buff,unsigned int n) +{ + unsigned int numDiv = 0; + PfxDiv2n divData[32]; + + unsigned int id = 0; + unsigned int rest = n; + unsigned int mask = 0x01; + + while(rest>0) { + if((mask&n)>0) { + divData[numDiv++] = PfxDiv2n(id,mask); + pfxBitonicSort(data+id,buff+id,mask); + rest ^= mask; + id += mask; + } + mask <<= 1; + } + + if(numDiv==1) { + for(unsigned int i=0;i 2 || param.axis < 0) return SCE_PFX_ERR_INVALID_VALUE; + if(!SCE_PFX_PTR_IS_ALIGNED16(param.proxies) || !SCE_PFX_PTR_IS_ALIGNED16(param.pairBuff)) return SCE_PFX_ERR_INVALID_ALIGN; + if(SCE_PFX_AVAILABLE_BYTES_ALIGN16(param.workBuff,param.workBytes) < pfxGetWorkBytesOfFindPairs(param.maxPairs,maxTasks) ) return SCE_PFX_ERR_OUT_OF_BUFFER; + if(SCE_PFX_AVAILABLE_BYTES_ALIGN16(param.pairBuff,param.pairBytes) < pfxGetPairBytesOfFindPairs(param.maxPairs) ) return SCE_PFX_ERR_OUT_OF_BUFFER; + return SCE_PFX_OK; +} + +PfxUInt32 pfxGetPairBytesOfDecomposePairs(PfxUInt32 numPreviousPairs,PfxUInt32 numCurrentPairs) +{ + return sizeof(PfxBroadphasePair)*(numPreviousPairs*2+numCurrentPairs); +} + +PfxInt32 pfxCheckParamOfDecomposePairs(const PfxDecomposePairsParam ¶m,int maxTasks) +{ + if(!param.workBuff || !param.pairBuff || !param.previousPairs || !param.currentPairs) return SCE_PFX_ERR_INVALID_VALUE; + if(!SCE_PFX_PTR_IS_ALIGNED16(param.previousPairs) || !SCE_PFX_PTR_IS_ALIGNED16(param.currentPairs) || !SCE_PFX_PTR_IS_ALIGNED16(param.pairBuff) ) return SCE_PFX_ERR_INVALID_ALIGN; + if(SCE_PFX_AVAILABLE_BYTES_ALIGN16(param.workBuff,param.workBytes) < pfxGetWorkBytesOfDecomposePairs(param.numPreviousPairs,param.numCurrentPairs,maxTasks)) return SCE_PFX_ERR_OUT_OF_BUFFER; + if(SCE_PFX_AVAILABLE_BYTES_ALIGN16(param.pairBuff,param.pairBytes) < pfxGetPairBytesOfDecomposePairs(param.numPreviousPairs,param.numCurrentPairs)) return SCE_PFX_ERR_OUT_OF_BUFFER; + return SCE_PFX_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// SINGLE THREAD + +PfxInt32 pfxUpdateBroadphaseProxies(PfxUpdateBroadphaseProxiesParam ¶m,PfxUpdateBroadphaseProxiesResult &result) +{ + PfxInt32 ret = pfxCheckParamOfUpdateBroadphaseProxies(param); + if(ret != SCE_PFX_OK) return ret; + + SCE_PFX_PUSH_MARKER("pfxUpdateBroadphaseProxies") + + result.numOutOfWorldProxies = 0; + + for(int i=0;i<(int)param.numRigidBodies;i++) { + PfxInt32 chk = pfxUpdateBroadphaseProxy( + param.proxiesX[i], + param.proxiesY[i], + param.proxiesZ[i], + param.proxiesXb[i], + param.proxiesYb[i], + param.proxiesZb[i], + param.offsetRigidStates[i], + param.offsetCollidables[i], + param.worldCenter, + param.worldExtent); + + if(chk == SCE_PFX_ERR_OUT_OF_WORLD) { + result.numOutOfWorldProxies++; + + if(param.outOfWorldBehavior & SCE_PFX_OUT_OF_WORLD_BEHAVIOR_FIX_MOTION) { + PfxRigidState &state = param.offsetRigidStates[i]; + state.setMotionType(kPfxMotionTypeFixed); + pfxSetMotionMask(param.proxiesX[i],state.getMotionMask()); + pfxSetMotionMask(param.proxiesY[i],state.getMotionMask()); + pfxSetMotionMask(param.proxiesZ[i],state.getMotionMask()); + pfxSetMotionMask(param.proxiesXb[i],state.getMotionMask()); + pfxSetMotionMask(param.proxiesYb[i],state.getMotionMask()); + pfxSetMotionMask(param.proxiesZb[i],state.getMotionMask()); + } + + if(param.outOfWorldBehavior & SCE_PFX_OUT_OF_WORLD_BEHAVIOR_REMOVE_PROXY) { + pfxSetKey(param.proxiesX[i],SCE_PFX_SENTINEL_KEY); + pfxSetKey(param.proxiesY[i],SCE_PFX_SENTINEL_KEY); + pfxSetKey(param.proxiesZ[i],SCE_PFX_SENTINEL_KEY); + pfxSetKey(param.proxiesXb[i],SCE_PFX_SENTINEL_KEY); + pfxSetKey(param.proxiesYb[i],SCE_PFX_SENTINEL_KEY); + pfxSetKey(param.proxiesZb[i],SCE_PFX_SENTINEL_KEY); + } + } + } + + PfxHeapManager pool((unsigned char*)param.workBuff,param.workBytes); + PfxBroadphaseProxy *workProxies = (PfxBroadphaseProxy*)pool.allocate(sizeof(PfxBroadphaseProxy)*param.numRigidBodies,PfxHeapManager::ALIGN128); + + pfxSort(param.proxiesX,workProxies,param.numRigidBodies); + pfxSort(param.proxiesY,workProxies,param.numRigidBodies); + pfxSort(param.proxiesZ,workProxies,param.numRigidBodies); + pfxSort(param.proxiesXb,workProxies,param.numRigidBodies); + pfxSort(param.proxiesYb,workProxies,param.numRigidBodies); + pfxSort(param.proxiesZb,workProxies,param.numRigidBodies); + + pool.deallocate(workProxies); + + SCE_PFX_POP_MARKER(); + + return SCE_PFX_OK; +} + +PfxInt32 pfxFindPairs(PfxFindPairsParam ¶m,PfxFindPairsResult &result) +{ + PfxInt32 ret = pfxCheckParamOfFindPairs(param,0); + if(ret != SCE_PFX_OK) return ret; + + SCE_PFX_PUSH_MARKER("pfxFindPairs") + + void *workBuff = param.workBuff; + PfxUInt32 workBytes = param.workBytes; + PfxBroadphaseProxy *proxies = param.proxies; + PfxUInt32 numProxies = param.numProxies; + PfxUInt32 maxPairs = param.maxPairs; + int axis = param.axis; + + (void) workBytes; + + PfxBroadphasePair *pairs = (PfxBroadphasePair*)SCE_PFX_PTR_ALIGN16(param.pairBuff); + PfxUInt32 numPairs = 0; + + for(PfxUInt32 i=0;i= maxPairs) + return SCE_PFX_ERR_OUT_OF_MAX_PAIRS; + + PfxBroadphasePair &pair = pairs[numPairs++]; + pfxSetActive(pair,true); + pfxSetObjectIdA(pair,pfxGetObjectId(proxyA)); + pfxSetObjectIdB(pair,pfxGetObjectId(proxyB)); + pfxSetMotionMaskA(pair,pfxGetMotionMask(proxyA)); + pfxSetMotionMaskB(pair,pfxGetMotionMask(proxyB)); + + pfxSetKey(pair,pfxCreateUniqueKey(pfxGetObjectId(proxyA),pfxGetObjectId(proxyB))); + } + } + } + + pfxSort(pairs,(PfxBroadphasePair*)workBuff,numPairs); + + result.pairs = pairs; + result.numPairs = numPairs; + + SCE_PFX_POP_MARKER(); + + return SCE_PFX_OK; +} + +PfxInt32 pfxDecomposePairs(PfxDecomposePairsParam ¶m,PfxDecomposePairsResult &result) +{ + PfxInt32 ret = pfxCheckParamOfDecomposePairs(param,0); + if(ret != SCE_PFX_OK) return ret; + + SCE_PFX_PUSH_MARKER("pfxDecomposePairs") + + PfxBroadphasePair *previousPairs = param.previousPairs; + PfxUInt32 numPreviousPairs = param.numPreviousPairs; + PfxBroadphasePair *currentPairs = param.currentPairs; + PfxUInt32 numCurrentPairs = param.numCurrentPairs; + + PfxBroadphasePair *outNewPairs = (PfxBroadphasePair*)SCE_PFX_PTR_ALIGN16(param.pairBuff); + PfxBroadphasePair *outKeepPairs = outNewPairs + numCurrentPairs; + PfxBroadphasePair *outRemovePairs = outKeepPairs + numPreviousPairs; + + PfxUInt32 nNew = 0; + PfxUInt32 nKeep = 0; + PfxUInt32 nRemove = 0; + + PfxUInt32 oldId = 0,newId = 0; + + while(oldId pfxGetKey(previousPairs[oldId])) { + // remove + SCE_PFX_ASSERT(nRemove<=numPreviousPairs); + outRemovePairs[nRemove] = previousPairs[oldId]; + nRemove++; + oldId++; + } + else if(pfxGetKey(currentPairs[newId]) == pfxGetKey(previousPairs[oldId])) { + // keep + SCE_PFX_ASSERT(nKeep<=numPreviousPairs); + outKeepPairs[nKeep] = currentPairs[newId]; + pfxSetContactId(outKeepPairs[nKeep],pfxGetContactId(previousPairs[oldId])); + nKeep++; + oldId++; + newId++; + } + else { + // new + SCE_PFX_ASSERT(nNew<=numCurrentPairs); + outNewPairs[nNew] = currentPairs[newId]; + nNew++; + newId++; + } + }; + + if(newIdio); + + PfxRayInput *rayInputs = (PfxRayInput*)arg->data[0]; + PfxRayOutput *rayOutputs = (PfxRayOutput*)arg->data[1]; + PfxUInt32 iFirstRay = arg->data[2]; + PfxUInt32 iEndRay = arg->data[3]; + + for(PfxUInt32 i = iFirstRay; i < iEndRay; i++) + { + pfxCastSingleRay(rayInputs[i], rayOutputs[i], param); + } +} + +//---------------------------------------------------------------------------- +// pfxCastRays +// +/// Perform cast rays in parallel using a task manager. +/// +/// @param rayInputs [in] Array of rays to cast +/// @param rayOutputs [out] On return contains output of ray casts +/// @param param Information about ray cast +/// @param taskManager Pointer to the thread task manager to use +//---------------------------------------------------------------------------- +void pfxCastRays(PfxRayInput *rayInputs,PfxRayOutput *rayOutputs,int numRays, + PfxRayCastParam ¶m,PfxTaskManager *taskManager) +{ + SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesX)); + SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesY)); + SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesZ)); + SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesXb)); + SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesYb)); + SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesZb)); + SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidStates)); + SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.offsetCollidables)); + + SCE_PFX_PUSH_MARKER("pfxCastRays"); + + PfxUInt32 maxBatchSize = numRays / (PfxUInt32)(taskManager->getNumTasks()); + PfxUInt32 iEnd = maxBatchSize, iStart = 0; + int task = 0; + taskManager->setTaskEntry((void*)pfxCastRaysStartTaskEntry); + + for (task = 0; task < taskManager->getNumTasks() - 1; task++, iStart += maxBatchSize, iEnd += maxBatchSize) + { + taskManager->startTask(task, static_cast(¶m), (PfxUInt32)rayInputs, (PfxUInt32)rayOutputs, iStart, iEnd); + } + + // send final task + iEnd = numRays; + taskManager->startTask(taskManager->getNumTasks() - 1, static_cast(¶m), iStart, iEnd, 0, 0); + + // wait for tasks to complete + PfxUInt32 data1, data2, data3, data4; + for (PfxUInt32 i = 0; i < taskManager->getNumTasks(); i++) + taskManager->waitTask(task, data1, data2, data3, data4); + + SCE_PFX_POP_MARKER(); +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/low_level/collision/pfx_batched_ray_cast_single.cpp b/Extras/PhysicsEffects/src/low_level/collision/pfx_batched_ray_cast_single.cpp new file mode 100644 index 000000000..49a4c43d3 --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/collision/pfx_batched_ray_cast_single.cpp @@ -0,0 +1,47 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/low_level/collision/pfx_batched_ray_cast.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// SINGLE THREAD + +void pfxCastRaysStart(PfxRayInput *rayInputs,PfxRayOutput *rayOutputs,int numRays,PfxRayCastParam ¶m) +{ + for(int i=0;iio); + + PfxUInt32 iFirstContactPair = arg->data[0]; + PfxUInt32 iEndContactPair = arg->data[1]; + + PfxConstraintPair *contactPairs = param.contactPairs; + PfxContactManifold *offsetContactManifolds = param.offsetContactManifolds; + PfxRigidState *offsetRigidStates = param.offsetRigidStates; + PfxCollidable *offsetCollidables = param.offsetCollidables; + PfxUInt32 numRigidBodies = param.numRigidBodies; + + for(PfxUInt32 i = iFirstContactPair; i < iEndContactPair; i++) + { + const PfxBroadphasePair &pair = contactPairs[i]; + if(!pfxCheckCollidableInCollision(pair)) + continue; + + PfxUInt32 iContact = pfxGetContactId(pair); + PfxUInt32 iA = pfxGetObjectIdA(pair); + PfxUInt32 iB = pfxGetObjectIdB(pair); + + PfxContactManifold &contact = offsetContactManifolds[iContact]; + + SCE_PFX_ALWAYS_ASSERT(iA==contact.getRigidBodyIdA()); + SCE_PFX_ALWAYS_ASSERT(iB==contact.getRigidBodyIdB()); + + PfxRigidState &stateA = offsetRigidStates[iA]; + PfxRigidState &stateB = offsetRigidStates[iB]; + PfxCollidable &collA = offsetCollidables[iA]; + PfxCollidable &collB = offsetCollidables[iB]; + PfxTransform3 tA0(stateA.getOrientation(), stateA.getPosition()); + PfxTransform3 tB0(stateB.getOrientation(), stateB.getPosition()); + + PfxContactCache contactCache; + + PfxShapeIterator itrShapeA(collA); + for(PfxUInt32 j=0;jgetNumTasks()); + PfxUInt32 iEnd = maxBatchSize, iStart = 0; + int task = 0; + taskManager->setTaskEntry((void*)pfxDetectCollisionTaskEntry); + + for (task = 0; task < taskManager->getNumTasks() - 1; task++, iStart += maxBatchSize, iEnd += maxBatchSize) + { + taskManager->startTask(task, static_cast(¶m), iStart, iEnd, 0, 0); + } + + // send final task + iEnd = param.numContactPairs; + taskManager->startTask(taskManager->getNumTasks() - 1, static_cast(¶m), iStart, iEnd, 0, 0); + + // wait for tasks to complete + PfxUInt32 data1, data2, data3, data4; + for (PfxUInt32 i = 0; i < taskManager->getNumTasks(); i++) + taskManager->waitTask(task, data1, data2, data3, data4); + + SCE_PFX_POP_MARKER(); + + return SCE_PFX_OK; +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/low_level/collision/pfx_collision_detection_single.cpp b/Extras/PhysicsEffects/src/low_level/collision/pfx_collision_detection_single.cpp new file mode 100644 index 000000000..424230f9b --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/collision/pfx_collision_detection_single.cpp @@ -0,0 +1,125 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_perf_counter.h" +#include "../../../include/physics_effects/base_level/collision/pfx_shape_iterator.h" +#include "../../../include/physics_effects/low_level/collision/pfx_collision_detection.h" +#include "../../base_level/broadphase/pfx_check_collidable.h" +#include "../../base_level/collision/pfx_contact_cache.h" +#include "pfx_detect_collision_func.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// + +int pfxCheckParamOfDetectCollision(PfxDetectCollisionParam ¶m) +{ + if(!param.contactPairs || !param.offsetContactManifolds || !param.offsetRigidStates|| !param.offsetCollidables ) return SCE_PFX_ERR_INVALID_VALUE; + if(!SCE_PFX_PTR_IS_ALIGNED16(param.contactPairs) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetContactManifolds) || + !SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidStates) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetCollidables)) return SCE_PFX_ERR_INVALID_ALIGN; + return SCE_PFX_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// SINGLE THREAD + +#define SCE_PFX_CONTACT_THRESHOLD 0.0f + +PfxInt32 pfxDetectCollision(PfxDetectCollisionParam ¶m) +{ + PfxInt32 ret = pfxCheckParamOfDetectCollision(param); + if(ret != SCE_PFX_OK) + return ret; + + SCE_PFX_PUSH_MARKER("pfxDetectCollision"); + + PfxConstraintPair *contactPairs = param.contactPairs; + PfxUInt32 numContactPairs = param.numContactPairs; + PfxContactManifold *offsetContactManifolds = param.offsetContactManifolds; + PfxRigidState *offsetRigidStates = param.offsetRigidStates; + PfxCollidable *offsetCollidables = param.offsetCollidables; + PfxUInt32 numRigidBodies = param.numRigidBodies; + + for(PfxUInt32 i=0;i= kPfxShapeCount || shapeTypeB >= kPfxShapeCount) { + return SCE_PFX_ERR_OUT_OF_RANGE; + } + + funcTbl_detectCollision[shapeTypeA][shapeTypeB] = func; + + return SCE_PFX_OK; +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/low_level/collision/pfx_detect_collision_func.h b/Extras/PhysicsEffects/src/low_level/collision/pfx_detect_collision_func.h new file mode 100644 index 000000000..77a5a46de --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/collision/pfx_detect_collision_func.h @@ -0,0 +1,37 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_DETECT_COLLISION_FUNC_H +#define _SCE_PFX_DETECT_COLLISION_FUNC_H + +#include "../../base_level/collision/pfx_contact_cache.h" + +namespace sce { +namespace PhysicsEffects { + +typedef void (*pfx_detect_collision_func)( + PfxContactCache &contacts, + const PfxShape & shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA, + const PfxShape & shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB, + float contactThreshold); + +pfx_detect_collision_func pfxGetDetectCollisionFunc(PfxUInt8 shapeTypeA,PfxUInt8 shapeTypeB); + +int pfxSetDetectCollisionFunc(PfxUInt8 shapeTypeA,PfxUInt8 shapeTypeB,pfx_detect_collision_func func); + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_DETECT_COLLISION_FUNC_H diff --git a/Extras/PhysicsEffects/src/low_level/collision/pfx_intersect_ray_func.cpp b/Extras/PhysicsEffects/src/low_level/collision/pfx_intersect_ray_func.cpp new file mode 100644 index 000000000..78467cd97 --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/collision/pfx_intersect_ray_func.cpp @@ -0,0 +1,129 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/collision/pfx_shape.h" +#include "../../base_level/collision/pfx_intersect_ray_box.h" +#include "../../base_level/collision/pfx_intersect_ray_sphere.h" +#include "../../base_level/collision/pfx_intersect_ray_capsule.h" +#include "../../base_level/collision/pfx_intersect_ray_cylinder.h" +#include "../../base_level/collision/pfx_intersect_ray_convex.h" +#include "../../base_level/collision/pfx_intersect_ray_large_tri_mesh.h" +#include "pfx_intersect_ray_func.h" + + +namespace sce { +namespace PhysicsEffects { + + +/////////////////////////////////////////////////////////////////////////////// +// Ray Intersection Function Table + +PfxBool intersectRayFuncDummy( + const PfxRayInput &ray,PfxRayOutput &out, + const PfxShape &shape,const PfxTransform3 &transform) +{ + (void)ray,(void)out,(void)shape,(void)transform; + return false; +} + +PfxBool intersectRayFuncBox( + const PfxRayInput &ray,PfxRayOutput &out, + const PfxShape &shape,const PfxTransform3 &transform) +{ + return pfxIntersectRayBox(ray,out,shape.getBox(),transform); +} + +PfxBool intersectRayFuncSphere( + const PfxRayInput &ray,PfxRayOutput &out, + const PfxShape &shape,const PfxTransform3 &transform) +{ + return pfxIntersectRaySphere(ray,out,shape.getSphere(),transform); +} + +PfxBool intersectRayFuncCapsule( + const PfxRayInput &ray,PfxRayOutput &out, + const PfxShape &shape,const PfxTransform3 &transform) +{ + return pfxIntersectRayCapsule(ray,out,shape.getCapsule(),transform); +} + +PfxBool intersectRayFuncCylinder( + const PfxRayInput &ray,PfxRayOutput &out, + const PfxShape &shape,const PfxTransform3 &transform) +{ + return pfxIntersectRayCylinder(ray,out,shape.getCylinder(),transform); +} + +PfxBool intersectRayFuncConvex( + const PfxRayInput &ray,PfxRayOutput &out, + const PfxShape &shape,const PfxTransform3 &transform) +{ +const PfxConvexMesh *convex = shape.getConvexMesh(); + + PfxBool ret = pfxIntersectRayConvex(ray,out,(const void*)convex,transform); + + + return ret; +} + +PfxBool intersectRayFuncLargeTriMesh( + const PfxRayInput &ray,PfxRayOutput &out, + const PfxShape &shape,const PfxTransform3 &transform) +{ +const PfxLargeTriMesh *lmesh = shape.getLargeTriMesh(); + + PfxBool ret = pfxIntersectRayLargeTriMesh(ray,out,(const void*)lmesh,transform); + + + return ret; +} + +PfxIntersectRayFunc funcTbl_intersectRay[kPfxShapeCount] = { + intersectRayFuncSphere, + intersectRayFuncBox, + intersectRayFuncCapsule, + intersectRayFuncCylinder, + intersectRayFuncConvex, + intersectRayFuncLargeTriMesh, + intersectRayFuncDummy, + intersectRayFuncDummy, + intersectRayFuncDummy, + intersectRayFuncDummy, + intersectRayFuncDummy, + intersectRayFuncDummy, +}; + +/////////////////////////////////////////////////////////////////////////////// +// Ray Intersection Function Table Interface + +PfxIntersectRayFunc pfxGetIntersectRayFunc(PfxUInt8 shapeType) +{ + return funcTbl_intersectRay[shapeType]; +} + +PfxInt32 pfxSetIntersectRayFunc(PfxUInt8 shapeType,PfxIntersectRayFunc func) +{ + if(shapeType >= kPfxShapeCount) { + return SCE_PFX_ERR_OUT_OF_RANGE; + } + + funcTbl_intersectRay[shapeType] = func; + + return SCE_PFX_OK; +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/low_level/collision/pfx_intersect_ray_func.h b/Extras/PhysicsEffects/src/low_level/collision/pfx_intersect_ray_func.h new file mode 100644 index 000000000..e0e53f9ac --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/collision/pfx_intersect_ray_func.h @@ -0,0 +1,36 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_INTERSECT_RAY_FUNC_H +#define _SCE_PFX_INTERSECT_RAY_FUNC_H + +#include "../../../include/physics_effects/base_level/collision/pfx_ray.h" + +namespace sce { +namespace PhysicsEffects { + +typedef PfxBool (*PfxIntersectRayFunc)( + const PfxRayInput &ray,PfxRayOutput &out, + const PfxShape &shape,const PfxTransform3 &transform); + +PfxIntersectRayFunc pfxGetIntersectRayFunc(PfxUInt8 shapeType); + +PfxInt32 pfxSetIntersectRayFunc(PfxUInt8 shapeType,PfxIntersectRayFunc func); + +} //namespace PhysicsEffects +} //namespace sce + +#endif /* _SCE_PFX_INTERSECT_RAY_FUNC_H */ diff --git a/Extras/PhysicsEffects/src/low_level/collision/pfx_island_generation.cpp b/Extras/PhysicsEffects/src/low_level/collision/pfx_island_generation.cpp new file mode 100644 index 000000000..bb65583bf --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/collision/pfx_island_generation.cpp @@ -0,0 +1,231 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/rigidbody/pfx_rigid_state.h" +#include "../../../include/physics_effects/low_level/collision/pfx_island_generation.h" + +namespace sce { +namespace PhysicsEffects { + +struct PfxIslandNode { + PfxUInt32 rootId; + PfxUInt32 rank; + PfxUInt32 islandId; + PfxUInt32 isRoot; +}; + +struct PfxIslandUnit +{ + PfxUInt32 id; + PfxIslandUnit *next; +}; + +struct PfxIsland +{ + PfxUInt32 numNodes; + PfxUInt32 numIslands; + PfxIslandNode *nodes; + PfxIslandUnit *islandsUnits; + PfxIslandUnit **islandsHeads; +}; + +PfxUInt32 pfxIslandNodeFind(PfxUInt32 i,PfxIsland *island) +{ + if( i != island->nodes[i].rootId ) { + island->nodes[i].rootId = pfxIslandNodeFind(island->nodes[i].rootId,island); + } + return island->nodes[i].rootId; +} + +void pfxIslandNodeLink(PfxUInt32 iA,PfxUInt32 iB,PfxIsland *island) +{ + if(island->nodes[iA].rank > island->nodes[iB].rank) { + island->nodes[iB].rootId = iA; + } + else if(island->nodes[iA].rank == island->nodes[iB].rank) { + island->nodes[iA].rootId = iB; + island->nodes[iB].rank++; + } + else { + island->nodes[iA].rootId = iB; + } +} + +void pfxIslandNodeUnion(PfxUInt32 iA,PfxUInt32 iB,PfxIsland *island) +{ + SCE_PFX_ALWAYS_ASSERT(iAnumNodes); + SCE_PFX_ALWAYS_ASSERT(iBnumNodes); + + pfxIslandNodeLink(pfxIslandNodeFind(iA,island),pfxIslandNodeFind(iB,island),island); +} + +PfxUInt32 pfxGetIslandBytesOfGenerateIsland(PfxUInt32 numObjects) +{ + return 16 + + SCE_PFX_ALLOC_BYTES_ALIGN16(sizeof(PfxIsland)) + + SCE_PFX_ALLOC_BYTES_ALIGN16(sizeof(PfxIslandNode)*numObjects) + + SCE_PFX_ALLOC_BYTES_ALIGN16(sizeof(PfxIslandUnit*)*numObjects) + + SCE_PFX_ALLOC_BYTES_ALIGN16(sizeof(PfxIslandUnit)*numObjects); +} + +SCE_PFX_FORCE_INLINE int pfxCheckParamOfGenerateIsland(const PfxGenerateIslandParam ¶m) +{ + if(!param.islandBuff || !param.pairs) return SCE_PFX_ERR_INVALID_VALUE; + if(!SCE_PFX_PTR_IS_ALIGNED16(param.pairs)) return SCE_PFX_ERR_INVALID_ALIGN; + if(SCE_PFX_AVAILABLE_BYTES_ALIGN16(param.islandBuff,param.islandBytes) < pfxGetIslandBytesOfGenerateIsland(param.numObjects) ) return SCE_PFX_ERR_OUT_OF_BUFFER; + return SCE_PFX_OK; +} + +PfxInt32 pfxGenerateIsland(PfxGenerateIslandParam ¶m,PfxGenerateIslandResult &result) +{ + int ret = pfxCheckParamOfGenerateIsland(param); + if(ret != SCE_PFX_OK) return ret; + + PfxConstraintPair *pairs = param.pairs; + PfxUInt32 numPairs = param.numPairs; + PfxUInt32 numUnits = param.numObjects; + + memset(param.islandBuff,0,param.islandBytes); + + PfxHeapManager pool((unsigned char*)param.islandBuff,param.islandBytes); + + PfxIsland *island = (PfxIsland*)pool.allocate(sizeof(PfxIsland)); + island->numIslands = 0; + island->numNodes = numUnits; + island->nodes = (PfxIslandNode*)pool.allocate(sizeof(PfxIslandNode)*numUnits); + island->islandsHeads = (PfxIslandUnit**)pool.allocate(sizeof(PfxIslandUnit*)*numUnits); + island->islandsUnits = (PfxIslandUnit*)pool.allocate(sizeof(PfxIslandUnit)*numUnits); + + result.island = island; + + // 初期化 + for(PfxUInt32 i=0;inumNodes;i++) { + island->nodes[i].rootId = i; + island->nodes[i].rank = 0; + } + + return pfxAppendPairs(island,pairs,numPairs); +} + +PfxUInt32 pfxGetNumIslands(const PfxIsland *islands) +{ + SCE_PFX_ALWAYS_ASSERT(islands); + return islands->numIslands; +} + +PfxIslandUnit *pfxGetFirstUnitInIsland(const PfxIsland *islands,PfxUInt32 islandId) +{ + SCE_PFX_ALWAYS_ASSERT(islands); + SCE_PFX_ALWAYS_ASSERT(islandId < islands->numIslands); + return islands->islandsHeads[islandId]; +} + +PfxIslandUnit *pfxGetNextUnitInIsland(const PfxIslandUnit *islandUnit) +{ + SCE_PFX_ALWAYS_ASSERT(islandUnit); + return islandUnit->next; +} + +PfxUInt32 pfxGetUnitId(const PfxIslandUnit *islandUnit) +{ + SCE_PFX_ALWAYS_ASSERT(islandUnit); + return islandUnit->id; +} + +PfxUInt32 pfxGetIslandId(const PfxIsland *islands,PfxUInt32 unitId) +{ + SCE_PFX_ALWAYS_ASSERT(islands&&unitIdnumNodes); + return islands->nodes[unitId].islandId; +} + +PfxInt32 pfxAppendPairs(PfxIsland *island,PfxConstraintPair *pairs,PfxUInt32 numPairs) +{ + if(numPairs == 0) { + return SCE_PFX_OK; + } + + if(!island || !pairs) return SCE_PFX_ERR_INVALID_VALUE; + if(!SCE_PFX_PTR_IS_ALIGNED16(island) || !SCE_PFX_PTR_IS_ALIGNED16(pairs)) return SCE_PFX_ERR_INVALID_ALIGN; + + // 統合 + for(PfxUInt32 i=0;inumNodes); + SCE_PFX_ALWAYS_ASSERT(iBnumNodes); + + if( (SCE_PFX_MOTION_MASK_DYNAMIC(pfxGetMotionMaskA(pair)&SCE_PFX_MOTION_MASK_TYPE)) && + (SCE_PFX_MOTION_MASK_DYNAMIC(pfxGetMotionMaskB(pair)&SCE_PFX_MOTION_MASK_TYPE)) ) { + pfxIslandNodeUnion(iA,iB,island); + } + } + } + + // アイランド生成のための初期化 + for(PfxUInt32 i=0;inumNodes;i++) { + island->nodes[i].islandId = 0; + island->nodes[i].isRoot = 0; + island->islandsHeads[i] = NULL; + } + + // 親へ直結 + PfxUInt32 id = 0; + for(PfxUInt32 i=0;inumNodes;i++) { + PfxUInt32 rootId = pfxIslandNodeFind(i,island); + if( island->nodes[rootId].isRoot == 0 ) { + island->nodes[rootId].islandId = id++; + island->nodes[rootId].isRoot = 1; + } + island->nodes[i].islandId = island->nodes[rootId].islandId; + } + + // アイランド作成 + PfxUInt32 n = 0; + for(PfxUInt32 i=0;inumNodes;i++) { + PfxUInt32 islandId = island->nodes[i].islandId; + PfxIslandUnit *newUnit = &island->islandsUnits[n++]; + newUnit->id = i; + + if(!island->islandsHeads[islandId]) { + island->islandsHeads[islandId] = newUnit; + continue; + } + + PfxIslandUnit *unit=island->islandsHeads[islandId]; + island->islandsHeads[islandId] = newUnit; + newUnit->next = unit; + } + + island->numIslands = id; + + return SCE_PFX_OK; +} + +void pfxResetIsland(PfxIsland *island) +{ + SCE_PFX_ALWAYS_ASSERT(island); + island->numIslands = 0; + for(PfxUInt32 i=0;inumNodes;i++) { + island->nodes[i].rootId = i; + island->nodes[i].rank = 0; + } +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/low_level/collision/pfx_ray_cast.cpp b/Extras/PhysicsEffects/src/low_level/collision/pfx_ray_cast.cpp new file mode 100644 index 000000000..20b8446c0 --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/collision/pfx_ray_cast.cpp @@ -0,0 +1,228 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h" +#include "../../../include/physics_effects/low_level/collision/pfx_ray_cast.h" +#include "../../../include/physics_effects/base_level/collision/pfx_shape_iterator.h" +#include "pfx_intersect_ray_func.h" +#include "../../base_level/collision/pfx_intersect_common.h" + + +namespace sce { +namespace PhysicsEffects { + + +void pfxRayTraverseForward( + const PfxRayInput &ray,PfxRayOutput &out,const PfxAabb16 &rayAABB, + PfxBroadphaseProxy *proxies,int numProxies, + PfxRigidState *offsetRigidStates, + PfxCollidable *offsetCollidables, + int axis,const PfxVector3 ¢er,const PfxVector3 &half) +{ +#ifdef SCE_PFX_USE_GEOMETRY + PfxGeomSegment segment((PfxPoint3)ray.m_startPosition,ray.m_direction); +#endif + + for(int i=0;i=0;i--) { + PfxBroadphaseProxy &proxy = proxies[i]; + + // 終了条件のチェック + if(pfxGetXYZMax(proxy,axis) < pfxGetXYZMin(rayAABB,axis)) { + return; + } + + PfxVector3 boundOnRay = ray.m_startPosition + out.m_variable * ray.m_direction; + PfxVector3 AABBmin = pfxConvertCoordLocalToWorld(PfxVecInt3((PfxInt32)pfxGetXMin(proxy),(PfxInt32)pfxGetYMin(proxy),(PfxInt32)pfxGetZMin(proxy)),center,half); + PfxVector3 AABBmax = pfxConvertCoordLocalToWorld(PfxVecInt3((PfxInt32)pfxGetXMax(proxy),(PfxInt32)pfxGetYMax(proxy),(PfxInt32)pfxGetZMax(proxy)),center,half); + + if(AABBmax[axis] < boundOnRay[axis]) { + return; + } + + // スキップ + if(pfxGetXYZMax(rayAABB,axis) < pfxGetXYZMin(proxy,axis)) { + continue; + } + + PfxUInt16 rigidbodyId = pfxGetObjectId(proxy); + PfxUInt32 contactFilterSelf = pfxGetSelf(proxy); + PfxUInt32 contactFilterTarget = pfxGetTarget(proxy); + +#ifdef SCE_PFX_USE_GEOMETRY + PfxFloatInVec t_(1.0f); + PfxGeomAabb aabb((PfxPoint3)AABBmin,(PfxPoint3)AABBmax); + if( (ray.m_contactFilterSelf&contactFilterTarget) && (ray.m_contactFilterTarget&contactFilterSelf) && pfxTestAabb(rayAABB,proxy) && + intersectionPoint(segment,aabb,&t_) && t_ < out.m_variable ) { +#else + float t_=1.0f; + if( (ray.m_contactFilterSelf&contactFilterTarget) && (ray.m_contactFilterTarget&contactFilterSelf) && pfxTestAabb(rayAABB,proxy) && + pfxIntersectRayAABBFast(ray.m_startPosition,ray.m_direction,(AABBmax+AABBmin)*0.5f,(AABBmax-AABBmin)*0.5f,t_) && t_ < out.m_variable ) { +#endif + + PfxRigidState &state = offsetRigidStates[rigidbodyId]; + PfxCollidable &coll = offsetCollidables[rigidbodyId]; + PfxTransform3 transform(state.getOrientation(), state.getPosition()); + + PfxRayOutput tout = out; + + PfxShapeIterator itrShape(coll); + for(PfxUInt32 j=0;j 0) { + pfxRayTraverseForward( + ray,out,rayAABB, + proxies[axis],param.numProxies, + param.offsetRigidStates,param.offsetCollidables, + axis,param.rangeCenter,param.rangeExtent); + } + else { + pfxRayTraverseBackward( + ray,out,rayAABB, + proxies[axis+3],param.numProxies, + param.offsetRigidStates,param.offsetCollidables, + axis,param.rangeCenter,param.rangeExtent); + } +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/low_level/collision/pfx_refresh_contacts_parallel.cpp b/Extras/PhysicsEffects/src/low_level/collision/pfx_refresh_contacts_parallel.cpp new file mode 100644 index 000000000..4c167ab4a --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/collision/pfx_refresh_contacts_parallel.cpp @@ -0,0 +1,115 @@ +/* +Applied Research Associates Inc. (c)2011 + +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_perf_counter.h" +#include "../../../include/physics_effects/base_level/sort/pfx_sort.h" +#include "../../../include/physics_effects/low_level/collision/pfx_refresh_contacts.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// This function is implemented in pfx_refresh_contacts_single.cpp +extern int pfxCheckParamOfRefreshContacts(PfxRefreshContactsParam ¶m); + +/////////////////////////////////////////////////////////////////////////////// +// MULTIPLE THREADS + +//---------------------------------------------------------------------------- +// pfxRefreshContactsTaskEntry +// +/// The thread PfxTaskEntry function used to perform refresh contacts in +/// parallel +//---------------------------------------------------------------------------- +void pfxRefreshContactsTaskEntry(PfxTaskArg *arg) +{ + PfxRefreshContactsParam ¶m = *((PfxRefreshContactsParam*)arg->io); + + PfxUInt32 iFirstContactPair = arg->data[0]; + PfxUInt32 iEndContactPair = arg->data[1]; + + PfxConstraintPair *contactPairs = param.contactPairs; + PfxContactManifold *offsetContactManifolds = param.offsetContactManifolds; + PfxRigidState *offsetRigidStates = param.offsetRigidStates; + PfxUInt32 numRigidBodies = param.numRigidBodies; + + for(PfxUInt32 i = iFirstContactPair; i < iEndContactPair; i++) + { + PfxBroadphasePair &pair = contactPairs[i]; + + PfxUInt32 iContact = pfxGetContactId(pair); + PfxUInt32 iA = pfxGetObjectIdA(pair); + PfxUInt32 iB = pfxGetObjectIdB(pair); + + PfxContactManifold &contact = offsetContactManifolds[iContact]; + + SCE_PFX_ALWAYS_ASSERT(iA==contact.getRigidBodyIdA()); + SCE_PFX_ALWAYS_ASSERT(iB==contact.getRigidBodyIdB()); + + PfxRigidState &instA = offsetRigidStates[iA]; + PfxRigidState &instB = offsetRigidStates[iB]; + + contact.refresh( + instA.getPosition(),instA.getOrientation(), + instB.getPosition(),instB.getOrientation() ); + } +} + +//---------------------------------------------------------------------------- +// pfxRefreshContacts +// +/// Perform refresh contacts in parallel using a task manager. +/// +/// @param param Information about contact pairs +/// @param taskManager Pointer to the thread task manager to use +/// +/// @return SCE_PFX_OK if successful, otherwise, returns an error code. +//---------------------------------------------------------------------------- +PfxInt32 pfxRefreshContacts(PfxRefreshContactsParam ¶m, PfxTaskManager *taskManager) +{ + PfxInt32 ret = pfxCheckParamOfRefreshContacts(param); + if(ret != SCE_PFX_OK) return ret; + + SCE_PFX_PUSH_MARKER("pfxRefreshContacts"); + + PfxUInt32 maxBatchSize = param.numContactPairs / (PfxUInt32)(taskManager->getNumTasks()); + PfxUInt32 iEnd = maxBatchSize, iStart = 0; + int task = 0; + taskManager->setTaskEntry((void*)pfxRefreshContactsTaskEntry); + + for (task = 0; task < taskManager->getNumTasks() - 1; task++, iStart += maxBatchSize, iEnd += maxBatchSize) + { + taskManager->startTask(task, static_cast(¶m), iStart, iEnd, 0, 0); + } + + // send final task + iEnd = param.numContactPairs; + taskManager->startTask(taskManager->getNumTasks() - 1, static_cast(¶m), iStart, iEnd, 0, 0); + + // wait for tasks to complete + PfxUInt32 data1, data2, data3, data4; + for (PfxUInt32 i = 0; i < taskManager->getNumTasks(); i++) + taskManager->waitTask(task, data1, data2, data3, data4); + + SCE_PFX_POP_MARKER(); + + return SCE_PFX_OK; +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/low_level/collision/pfx_refresh_contacts_single.cpp b/Extras/PhysicsEffects/src/low_level/collision/pfx_refresh_contacts_single.cpp new file mode 100644 index 000000000..8bce7d5cf --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/collision/pfx_refresh_contacts_single.cpp @@ -0,0 +1,76 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_perf_counter.h" +#include "../../../include/physics_effects/base_level/sort/pfx_sort.h" +#include "../../../include/physics_effects/low_level/collision/pfx_refresh_contacts.h" + +namespace sce { +namespace PhysicsEffects { + +int pfxCheckParamOfRefreshContacts(PfxRefreshContactsParam ¶m) +{ + if(!param.contactPairs || !param.offsetContactManifolds || !param.offsetRigidStates ) return SCE_PFX_ERR_INVALID_VALUE; + if(!SCE_PFX_PTR_IS_ALIGNED16(param.contactPairs) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetContactManifolds) || + !SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidStates)) return SCE_PFX_ERR_INVALID_ALIGN; + return SCE_PFX_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// SINGLE THREAD + +PfxInt32 pfxRefreshContacts(PfxRefreshContactsParam ¶m) +{ + PfxInt32 ret = pfxCheckParamOfRefreshContacts(param); + if(ret != SCE_PFX_OK) return ret; + + SCE_PFX_PUSH_MARKER("pfxRefreshContacts"); + + PfxConstraintPair *contactPairs = param.contactPairs; + PfxUInt32 numContactPairs = param.numContactPairs; + PfxContactManifold *offsetContactManifolds = param.offsetContactManifolds; + PfxRigidState *offsetRigidStates = param.offsetRigidStates; + PfxUInt32 numRigidBodies = param.numRigidBodies; + + for(PfxUInt32 i=0;i0&&(!param.contactPairs||!param.offsetContactManifolds)) || + (param.numJointPairs>0&&(!param.jointPairs||!param.offsetJoints)) || !param.offsetRigidStates || !param.offsetSolverBodies) return SCE_PFX_ERR_INVALID_VALUE; + if(!SCE_PFX_PTR_IS_ALIGNED16(param.contactPairs) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetContactManifolds) || + !SCE_PFX_PTR_IS_ALIGNED16(param.jointPairs) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetJoints) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidStates) || + !SCE_PFX_PTR_IS_ALIGNED16(param.offsetSolverBodies)) return SCE_PFX_ERR_INVALID_ALIGN; + if(SCE_PFX_AVAILABLE_BYTES_ALIGN16(param.workBuff,param.workBytes) < pfxGetWorkBytesOfSolveConstraints(param.numRigidBodies,param.numContactPairs,param.numJointPairs, taskManager->getNumTasks()) ) return SCE_PFX_ERR_OUT_OF_BUFFER; + return SCE_PFX_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// MULTIPLE THREADS + +//---------------------------------------------------------------------------- +// pfxSetupSolverBodiesTaskEntry +// +/// The thread PfxTaskEntry function used to setup solver bodies in parallel. +//---------------------------------------------------------------------------- +void pfxSetupSolverBodiesTaskEntry(PfxTaskArg *arg) +{ + PfxSetupSolverBodiesParam ¶m = *((PfxSetupSolverBodiesParam*)arg->io); + + PfxUInt32 iFirstBody = arg->data[0]; + PfxUInt32 iEndBody = arg->data[1]; + + PfxRigidState *states = param.states; + PfxRigidBody *bodies = param.bodies; + PfxSolverBody *solverBodies = param.solverBodies; + + for(PfxUInt32 i = iFirstBody; i < iEndBody; i++) + { + PfxRigidState &state = states[i]; + PfxRigidBody &body = bodies[i]; + PfxSolverBody &solverBody = solverBodies[i]; + + solverBody.m_orientation = state.getOrientation(); + solverBody.m_deltaLinearVelocity = PfxVector3(0.0f); + solverBody.m_deltaAngularVelocity = PfxVector3(0.0f); + solverBody.m_motionType = state.getMotionMask(); + + if(SCE_PFX_MOTION_MASK_DYNAMIC(state.getMotionType())) { + PfxMatrix3 ori(solverBody.m_orientation); + solverBody.m_massInv = body.getMassInv(); + solverBody.m_inertiaInv = ori * body.getInertiaInv() * transpose(ori); + } + else { + solverBody.m_massInv = 0.0f; + solverBody.m_inertiaInv = PfxMatrix3(0.0f); + } + } + + SCE_PFX_POP_MARKER(); +} + +//---------------------------------------------------------------------------- +// pfxSetupSolverBodies +// +/// Perform setup solver bodies in parallel using a task manager. +/// +/// @param param Information about rigid bodies +/// @param taskManager Pointer to the thread task manager to use +/// +/// @return SCE_PFX_OK if successful, otherwise, returns an error code. +//---------------------------------------------------------------------------- +PfxInt32 pfxSetupSolverBodies(PfxSetupSolverBodiesParam ¶m, + PfxTaskManager *taskManager) +{ + PfxInt32 ret = pfxCheckParamOfSetupSolverBodies(param); + if(ret != SCE_PFX_OK) return ret; + + SCE_PFX_PUSH_MARKER("pfxSetupSolverBodies"); + + PfxUInt32 maxBatchSize = param.numRigidBodies / (PfxUInt32)(taskManager->getNumTasks()); + PfxUInt32 iEnd = maxBatchSize, iStart = 0; + int task = 0; + taskManager->setTaskEntry((void*)pfxSetupSolverBodiesTaskEntry); + + for (task = 0; task < taskManager->getNumTasks() - 1; task++, iStart += maxBatchSize, iEnd += maxBatchSize) + { + taskManager->startTask(task, static_cast(¶m), iStart, iEnd, 0, 0); + } + + // send final task + iEnd = param.numRigidBodies; + taskManager->startTask(taskManager->getNumTasks() - 1, static_cast(¶m), iStart, iEnd, 0, 0); + + // wait for tasks to complete + PfxUInt32 data1, data2, data3, data4; + for (PfxUInt32 i = 0; i < taskManager->getNumTasks(); i++) + taskManager->waitTask(task, data1, data2, data3, data4); + + SCE_PFX_POP_MARKER(); + + return SCE_PFX_OK; +} + +//---------------------------------------------------------------------------- +// pfxSetupContactConstraintsTaskEntry +// +/// The thread PfxTaskEntry function used to setup contact constraints in +/// parallel. +//---------------------------------------------------------------------------- +void pfxSetupContactConstraintsTaskEntry(PfxTaskArg *arg) +{ + PfxSetupContactConstraintsParam ¶m = *((PfxSetupContactConstraintsParam*)arg->io); + + PfxUInt32 iFirstContactPair = arg->data[0]; + PfxUInt32 iEndContactPair = arg->data[1]; + + PfxConstraintPair *contactPairs = param.contactPairs; + PfxUInt32 numContactPairs = param.numContactPairs; + PfxContactManifold *offsetContactManifolds = param.offsetContactManifolds; + PfxRigidState *offsetRigidStates = param.offsetRigidStates; + PfxRigidBody *offsetRigidBodies = param.offsetRigidBodies; + PfxSolverBody *offsetSolverBodies = param.offsetSolverBodies; + + for(PfxUInt32 i = iFirstContactPair; i < iEndContactPair; i++) + { + PfxConstraintPair &pair = contactPairs[i]; + if(!pfxCheckSolver(pair)) + { + continue; + } + + PfxUInt16 iA = pfxGetObjectIdA(pair); + PfxUInt16 iB = pfxGetObjectIdB(pair); + PfxUInt32 iConstraint = pfxGetConstraintId(pair); + + PfxContactManifold &contact = offsetContactManifolds[iConstraint]; + + SCE_PFX_ALWAYS_ASSERT(iA==contact.getRigidBodyIdA()); + SCE_PFX_ALWAYS_ASSERT(iB==contact.getRigidBodyIdB()); + + PfxRigidState &stateA = offsetRigidStates[iA]; + PfxRigidBody &bodyA = offsetRigidBodies[iA]; + PfxSolverBody &solverBodyA = offsetSolverBodies[iA]; + + PfxRigidState &stateB = offsetRigidStates[iB]; + PfxRigidBody &bodyB = offsetRigidBodies[iB]; + PfxSolverBody &solverBodyB = offsetSolverBodies[iB]; + + contact.setInternalFlag(0); + + PfxFloat restitution = 0.5f * (bodyA.getRestitution() + bodyB.getRestitution()); + if(contact.getDuration() > 1) restitution = 0.0f; + + PfxFloat friction = sqrtf(bodyA.getFriction() * bodyB.getFriction()); + + for(int j=0;jgetNumTasks()); + PfxUInt32 iEnd = maxBatchSize, iStart = 0; + int task = 0; + taskManager->setTaskEntry((void*)pfxSetupContactConstraintsTaskEntry); + + for (task = 0; task < taskManager->getNumTasks() - 1; task++, iStart += maxBatchSize, iEnd += maxBatchSize) + { + taskManager->startTask(task, static_cast(¶m), iStart, iEnd, 0, 0); + } + + // send final task + iEnd = param.numContactPairs; + taskManager->startTask(taskManager->getNumTasks() - 1, static_cast(¶m), iStart, iEnd, 0, 0); + + // wait for tasks to complete + PfxUInt32 data1, data2, data3, data4; + for (PfxUInt32 i = 0; i < taskManager->getNumTasks(); i++) + taskManager->waitTask(task, data1, data2, data3, data4); + + SCE_PFX_POP_MARKER(); + + return SCE_PFX_OK; +} + +//---------------------------------------------------------------------------- +// pfxSetupJointConstraintsTaskEntry +// +/// The thread PfxTaskEntry function used to setup joint constraints in +/// parallel. +//---------------------------------------------------------------------------- +void pfxSetupJointConstraintsTaskEntry(PfxTaskArg *arg) +{ + PfxSetupJointConstraintsParam ¶m = *((PfxSetupJointConstraintsParam*)arg->io); + + PfxUInt32 iFirstJointPair = arg->data[0]; + PfxUInt32 iEndJointPair = arg->data[1]; + + PfxConstraintPair *jointPairs = param.jointPairs; + PfxUInt32 numJointPairs = param.numJointPairs; + PfxJoint *offsetJoints = param.offsetJoints; + PfxRigidState *offsetRigidStates = param.offsetRigidStates; + PfxSolverBody *offsetSolverBodies = param.offsetSolverBodies; + + for(PfxUInt32 i = iFirstJointPair; i < iEndJointPair; i++) + { + PfxConstraintPair &pair = jointPairs[i]; + if(!pfxCheckSolver(pair)) + { + continue; + } + + PfxUInt16 iA = pfxGetObjectIdA(pair); + PfxUInt16 iB = pfxGetObjectIdB(pair); + PfxUInt32 iConstraint = pfxGetConstraintId(pair); + + PfxJoint &joint = offsetJoints[iConstraint]; + + SCE_PFX_ALWAYS_ASSERT(iA==joint.m_rigidBodyIdA); + SCE_PFX_ALWAYS_ASSERT(iB==joint.m_rigidBodyIdB); + + PfxRigidState &stateA = offsetRigidStates[iA]; + PfxSolverBody &solverBodyA = offsetSolverBodies[iA]; + + PfxRigidState &stateB = offsetRigidStates[iB]; + PfxSolverBody &solverBodyB = offsetSolverBodies[iB]; + + pfxGetSetupJointConstraintFunc(joint.m_type)( + joint, + stateA, + stateB, + solverBodyA, + solverBodyB, + param.timeStep); + } +} + +//---------------------------------------------------------------------------- +// pfxSetupJointConstraints +// +/// Perform setup joint constraints in parallel using a task manager. +/// +/// @param param Information about joint constraints +/// @param taskManager Pointer to the thread task manager to use +/// +/// @return SCE_PFX_OK if successful, otherwise, returns an error code. +//---------------------------------------------------------------------------- +PfxInt32 pfxSetupJointConstraints(PfxSetupJointConstraintsParam ¶m, + PfxTaskManager *taskManager) +{ + PfxInt32 ret = pfxCheckParamOfSetupJointConstraints(param); + if(ret != SCE_PFX_OK) return ret; + + SCE_PFX_PUSH_MARKER("pfxSetupJointConstraints"); + + PfxUInt32 maxBatchSize = param.numJointPairs / (PfxUInt32)(taskManager->getNumTasks()); + PfxUInt32 iEnd = maxBatchSize, iStart = 0; + int task = 0; + taskManager->setTaskEntry((void*)pfxSetupJointConstraintsTaskEntry); + + for (task = 0; task < taskManager->getNumTasks() - 1; task++, iStart += maxBatchSize, iEnd += maxBatchSize) + { + taskManager->startTask(task, static_cast(¶m), iStart, iEnd, 0, 0); + } + + // send final task + iEnd = param.numJointPairs; + taskManager->startTask(taskManager->getNumTasks() - 1, static_cast(¶m), iStart, iEnd, 0, 0); + + // wait for tasks to complete + PfxUInt32 data1, data2, data3, data4; + for (PfxUInt32 i = 0; i < taskManager->getNumTasks(); i++) + taskManager->waitTask(task, data1, data2, data3, data4); + + SCE_PFX_POP_MARKER(); + + return SCE_PFX_OK; +} + +//---------------------------------------------------------------------------- +// pfxSplitConstraints +// +/// Given a set of constraints to be solved, split the constraints into +/// a collection of phases, with each phase having one or more independent +/// batches that can be solved in parallel. The phases must be solved +/// sequentially. +/// +/// @param numRigidBodies [in] Total number of rigid bodies referenced +/// in the given set of constraints +/// @param constraintpairs [in] Pointer to array of constraints to split. +/// For clarity, note that the pairs always stay +/// together. Some pairs are split to be solved +/// in parallel with other pairs. +/// @param numConstraints [in] Number of constraints to split +/// @param taskManager [in] Pointer to the thread task manager that will +/// eventually be used to solve the constraints. +/// @param group [out] On return, contains information about +/// the phases and batches that define the splitting +/// @param batches [out] Caller should pass a pointer to a pre- +/// allocated array of SCE_PFX_MAX_SOLVER_BATCHES +/// PfxParallelBatch objects. On output, these will +/// be populated with the correct number of pairs +/// for each batch. + +/// +/// @return SCE_PFX_OK if successful, otherwise, returns an error code. +//---------------------------------------------------------------------------- +void pfxSplitConstraints(PfxUInt32 numRigidBodies, PfxConstraintPair *constraintPairs, + PfxUInt32 numConstraints, PfxTaskManager *taskManager, PfxParallelGroup *group, + PfxParallelBatch *batches) +{ + SCE_PFX_PUSH_MARKER("pfxSplitConstraints"); + + // allocate a table that will be used to indicate, for a given phase being + // populated, which batch a given body belongs to. + PfxInt32 bufSize = sizeof(PfxUInt8) * numRigidBodies; + bufSize = ((bufSize + 127) >> 7) << 7; // 128 bytes alignment + PfxUInt8 *bodyTable = (PfxUInt8*)taskManager->allocate(bufSize); + + // allocate a table that will be used to indicate, for a given phase being + // populated, which batch a given pair of bodies belongs to. + PfxUInt32 *pairTable; + size_t allocSize = sizeof(PfxUInt32)*((numConstraints + 31) / 32); + pairTable = (PfxUInt32*)taskManager->allocate(allocSize); + memset(pairTable, 0, allocSize); + + // + PfxUInt32 numTasks = taskManager->getNumTasks(); + PfxUInt32 targetCount = SCE_PFX_MAX(PfxUInt32(SCE_PFX_MIN_SOLVER_PAIRS), + SCE_PFX_MIN(numConstraints / (numTasks * 2), PfxUInt32(SCE_PFX_MAX_SOLVER_PAIRS))); + PfxUInt32 startIndex = 0; + + PfxUInt32 phaseId; + PfxUInt32 batchId; + PfxUInt32 totalCount = 0; + + PfxUInt32 maxBatches = SCE_PFX_MIN(numTasks, PfxUInt32(SCE_PFX_MAX_SOLVER_BATCHES)); + + // accumulate phases and batches until group resources are exhausted or all incoming + // pairs are accounted for. + for (phaseId = 0; phaseId < SCE_PFX_MAX_SOLVER_PHASES && totalCount < numConstraints; phaseId++) + { + bool startIndexCheck = true; + + group->numBatches[phaseId] = 0; + + PfxUInt32 i = startIndex; + // Initialize body table such that no body is assigned to any batch. (0xff is explicitly assumed to + // mean no batch assigned) + memset(bodyTable, 0xff, bufSize); + + // accumulate batches within the current phase. This code creates batches that are + // independent, e.g., no batch on this phase will touch the same bodies as any other + // batch on the phase. Batches within a phase can be solved in parallel on shared memory + // multiprocessor hardware. + for (batchId = 0; i < numConstraints && totalCount < numConstraints && batchId < maxBatches; batchId++) + { + PfxUInt32 pairCount=0; + PfxParallelBatch &batch = batches[(phaseId * SCE_PFX_MAX_SOLVER_BATCHES) + batchId]; + PfxUInt32 pairId = 0; + + // iterate through pairs, and assigns the pairs to batches + for (; i < numConstraints && pairCount < targetCount; i++) + { + PfxUInt32 idxP = i >> 5; + PfxUInt32 maskP = 1L << (i & 31); + + if(pairTable[idxP] & maskP) // pair is already assigned to a phase/batch + continue; + + PfxUInt16 idxA = pfxGetObjectIdA(constraintPairs[i]); + PfxUInt16 idxB = pfxGetObjectIdB(constraintPairs[i]); + + // It is possible an incoming constraint pair can be skipped. For example, if the pair is inactive, + // or if both its objects are static, unmoving objects and therefore would be unaffected by constraints. + // This conditional statement addresses constraints to be skipped. + if (!pfxGetActive(constraintPairs[i]) || + (SCE_PFX_MOTION_MASK_STATIC(pfxGetMotionMaskA(constraintPairs[i])&SCE_PFX_MOTION_MASK_TYPE) && + SCE_PFX_MOTION_MASK_STATIC(pfxGetMotionMaskB(constraintPairs[i])&SCE_PFX_MOTION_MASK_TYPE)) ) + { + if (startIndexCheck) + startIndex++; + + //assign pair -> skip it because it has no constraints + pairTable[idxP] |= maskP; + totalCount++; + continue; + } + + // If either body of the current pair belongs to another batch already, we cannot add the current + // pair to the current batch. Must defer to another phase + if( (bodyTable[idxA] != batchId && bodyTable[idxA] != 0xff) || + (bodyTable[idxB] != batchId && bodyTable[idxB] != 0xff) ) + { + startIndexCheck = false; // so we will revisit this during allocation of next phase + continue; + } + + // Dynamic bodies for current pair are assigned to the current batch in this phase. + // Static bodies are not assigned. Since they never move, and their corresponding solver + // bodies are therefore never touched, they can actually be used by any batch. + if (SCE_PFX_MOTION_MASK_DYNAMIC(pfxGetMotionMaskA(constraintPairs[i])&SCE_PFX_MOTION_MASK_TYPE)) + bodyTable[idxA] = batchId; + + if (SCE_PFX_MOTION_MASK_DYNAMIC(pfxGetMotionMaskB(constraintPairs[i])&SCE_PFX_MOTION_MASK_TYPE)) + bodyTable[idxB] = batchId; + + if(startIndexCheck) + startIndex++; + + pairTable[idxP] |= maskP; // pair has been handled + + //add the pair 'i' to the current batch + batch.pairIndices[pairId++] = i; + pairCount++; + } + + group->numPairs[(phaseId * SCE_PFX_MAX_SOLVER_BATCHES) + batchId] = (PfxUInt16)pairId; + totalCount += pairCount; + } + group->numBatches[phaseId] = batchId; + } + + group->numPhases = phaseId; + + taskManager->deallocate(bodyTable); + taskManager->deallocate(pairTable); + + SCE_PFX_POP_MARKER(); +} + +//---------------------------------------------------------------------------- +// pfxSolveConstraintsTaskEntry +// +/// The thread PfxTaskEntry function used to solve constraints in parallel. +//---------------------------------------------------------------------------- +void pfxSolveConstraintsTaskEntry(PfxTaskArg *arg) +{ + PfxSolveConstraintsParam ¶m = *((PfxSolveConstraintsParam*)arg->io); + + PfxConstraintPair *contactPairs = param.contactPairs; + PfxContactManifold *offsetContactManifolds = param.offsetContactManifolds; + PfxConstraintPair *jointPairs = param.jointPairs; + PfxJoint *offsetJoints = param.offsetJoints; + PfxRigidState *offsetRigidStates = param.offsetRigidStates; + PfxSolverBody *offsetSolverBodies = param.offsetSolverBodies; + + PfxParallelGroup *jointgroup = (PfxParallelGroup*)arg->data[0]; + PfxParallelBatch *jointbatches = (PfxParallelBatch*)arg->data[1]; + PfxParallelGroup *contactgroup = (PfxParallelGroup*)arg->data[2]; + PfxParallelBatch *contactbatches = (PfxParallelBatch*)arg->data[3]; + + // Warm Starting + { + // Joints + for (PfxUInt16 phase = 0; phase < jointgroup->numPhases; phase++) + { + for (PfxUInt16 batchId = 0; batchId < jointgroup->numBatches[phase]; batchId++) + { + PfxUInt16 numJointPairs = jointgroup->numPairs[(phase * SCE_PFX_MAX_SOLVER_BATCHES) + batchId]; + if ((arg->taskId == (batchId % arg->maxTasks)) && numJointPairs > 0) // only spend time on batches meant for this task + { + const PfxParallelBatch &batch = jointbatches[(phase * SCE_PFX_MAX_SOLVER_BATCHES) + batchId]; + for (PfxUInt16 i = 0; i < numJointPairs; i++) + { + PfxConstraintPair &pair = jointPairs[batch.pairIndices[i]]; + if(!pfxCheckSolver(pair)) + continue; + + PfxUInt16 iA = pfxGetObjectIdA(pair); + PfxUInt16 iB = pfxGetObjectIdB(pair); + + PfxJoint &joint = offsetJoints[pfxGetConstraintId(pair)]; + + SCE_PFX_ASSERT(iA==joint.m_rigidBodyIdA); + SCE_PFX_ASSERT(iB==joint.m_rigidBodyIdB); + + PfxSolverBody &solverBodyA = offsetSolverBodies[iA]; + PfxSolverBody &solverBodyB = offsetSolverBodies[iB]; + + pfxGetWarmStartJointConstraintFunc(joint.m_type)( + joint, + solverBodyA, + solverBodyB); + } + } + + arg->barrier->sync(); // block until all threads are ready to go to next phase + } + } + + // Contacts + for (PfxUInt16 phase = 0; phase < contactgroup->numPhases; phase++) + { + for (PfxUInt16 batchId = 0; batchId < contactgroup->numBatches[phase]; batchId++) + { + PfxUInt16 numContactPairs = contactgroup->numPairs[(phase * SCE_PFX_MAX_SOLVER_BATCHES) + batchId]; + if ((arg->taskId == (batchId % arg->maxTasks)) && numContactPairs > 0) // only spend time on batches meant for this task + { + const PfxParallelBatch &batch = contactbatches[(phase * SCE_PFX_MAX_SOLVER_BATCHES) + batchId]; + for (PfxUInt16 i = 0; i < numContactPairs; i++) + { + PfxConstraintPair &pair = contactPairs[batch.pairIndices[i]]; + if(!pfxCheckSolver(pair)) + { + continue; + } + + PfxUInt16 iA = pfxGetObjectIdA(pair); + PfxUInt16 iB = pfxGetObjectIdB(pair); + + PfxContactManifold &contact = offsetContactManifolds[pfxGetConstraintId(pair)]; + + SCE_PFX_ASSERT(iA==contact.getRigidBodyIdA()); + SCE_PFX_ASSERT(iB==contact.getRigidBodyIdB()); + + PfxSolverBody &solverBodyA = offsetSolverBodies[iA]; + PfxSolverBody &solverBodyB = offsetSolverBodies[iB]; + + PfxFloat massInvA = solverBodyA.m_massInv; + PfxFloat massInvB = solverBodyB.m_massInv; + PfxMatrix3 inertiaInvA = solverBodyA.m_inertiaInv; + PfxMatrix3 inertiaInvB = solverBodyB.m_inertiaInv; + + if(solverBodyA.m_motionType == kPfxMotionTypeOneWay) + { + massInvB = 0.0f; + inertiaInvB = PfxMatrix3(0.0f); + } + + if(solverBodyB.m_motionType == kPfxMotionTypeOneWay) + { + massInvA = 0.0f; + inertiaInvA = PfxMatrix3(0.0f); + } + + for(int j = 0; j < contact.getNumContacts(); j++) + { + PfxContactPoint &cp = contact.getContactPoint(j); + + PfxVector3 rA = rotate(solverBodyA.m_orientation,pfxReadVector3(cp.m_localPointA)); + PfxVector3 rB = rotate(solverBodyB.m_orientation,pfxReadVector3(cp.m_localPointB)); + + for(int k = 0; k < 3; k++) + { + PfxVector3 normal = pfxReadVector3(cp.m_constraintRow[k].m_normal); + PfxFloat deltaImpulse = cp.m_constraintRow[k].m_accumImpulse; + solverBodyA.m_deltaLinearVelocity += deltaImpulse * massInvA * normal; + solverBodyA.m_deltaAngularVelocity += deltaImpulse * inertiaInvA * cross(rA,normal); + solverBodyB.m_deltaLinearVelocity -= deltaImpulse * massInvB * normal; + solverBodyB.m_deltaAngularVelocity -= deltaImpulse * inertiaInvB * cross(rB,normal); + } + } + } + } + } + + arg->barrier->sync(); // block until all threads are ready to go to next phase + } + } + + // Solver + for(PfxUInt32 iteration = 0; iteration < param.iteration; iteration++) + { + // Joints + for (PfxUInt16 phase = 0; phase < jointgroup->numPhases; phase++) + { + for (PfxUInt16 batchId = 0; batchId < jointgroup->numBatches[phase]; batchId++) + { + PfxUInt16 numJointPairs = jointgroup->numPairs[(phase * SCE_PFX_MAX_SOLVER_BATCHES) + batchId]; + if ((arg->taskId == (batchId % arg->maxTasks)) && numJointPairs > 0) // only spend time on batches meant for this task + { + const PfxParallelBatch &batch = jointbatches[(phase * SCE_PFX_MAX_SOLVER_BATCHES) + batchId]; + for(PfxUInt16 i = 0; i < numJointPairs; i++) + { + PfxConstraintPair &pair = jointPairs[batch.pairIndices[i]]; + if(!pfxCheckSolver(pair)) + continue; + + PfxUInt16 iA = pfxGetObjectIdA(pair); + PfxUInt16 iB = pfxGetObjectIdB(pair); + + PfxJoint &joint = offsetJoints[pfxGetConstraintId(pair)]; + + SCE_PFX_ASSERT(iA==joint.m_rigidBodyIdA); + SCE_PFX_ASSERT(iB==joint.m_rigidBodyIdB); + + PfxSolverBody &solverBodyA = offsetSolverBodies[iA]; + PfxSolverBody &solverBodyB = offsetSolverBodies[iB]; + + pfxGetSolveJointConstraintFunc(joint.m_type)( + joint, + solverBodyA, + solverBodyB); + } + } + } + + arg->barrier->sync(); // block until all threads are ready to go to next phase + } + + // Contacts + for (PfxUInt32 phase = 0; phase < contactgroup->numPhases; phase++) + { + for (PfxUInt32 batchId = 0; batchId < contactgroup->numBatches[phase]; batchId++) + { + PfxUInt32 numContactPairs = contactgroup->numPairs[(phase * SCE_PFX_MAX_SOLVER_BATCHES) + batchId]; + if ((arg->taskId == (batchId % arg->maxTasks)) && numContactPairs > 0) // only spend time on batches meant for this task + { + const PfxParallelBatch &batch = contactbatches[(phase * SCE_PFX_MAX_SOLVER_BATCHES) + batchId]; + for(PfxUInt32 i = 0; i < numContactPairs; i++) + { + PfxConstraintPair &pair = contactPairs[batch.pairIndices[i]]; + if(!pfxCheckSolver(pair)) + continue; + + PfxUInt16 iA = pfxGetObjectIdA(pair); + PfxUInt16 iB = pfxGetObjectIdB(pair); + + PfxContactManifold &contact = offsetContactManifolds[pfxGetConstraintId(pair)]; + + SCE_PFX_ASSERT(iA==contact.getRigidBodyIdA()); + SCE_PFX_ASSERT(iB==contact.getRigidBodyIdB()); + + PfxSolverBody &solverBodyA = offsetSolverBodies[iA]; + PfxSolverBody &solverBodyB = offsetSolverBodies[iB]; + + for(int j = 0; j < contact.getNumContacts(); j++) + { + PfxContactPoint &cp = contact.getContactPoint(j); + + pfxSolveContactConstraint( + cp.m_constraintRow[0], + cp.m_constraintRow[1], + cp.m_constraintRow[2], + pfxReadVector3(cp.m_localPointA), + pfxReadVector3(cp.m_localPointB), + solverBodyA, + solverBodyB, + contact.getCompositeFriction() + ); + } + } + } + } + + arg->barrier->sync(); // block until all threads are ready to go to next phase + } + } +} + +//---------------------------------------------------------------------------- +// pfxSolveConstraints +// +/// Perform setup joint constraints in parallel using a task manager. +/// +/// @param param Information about constraints +/// @param taskManager Pointer to the thread task manager to use +/// +/// @return SCE_PFX_OK if successful, otherwise, returns an error code. +//---------------------------------------------------------------------------- +PfxInt32 pfxSolveConstraints(PfxSolveConstraintsParam ¶m, + PfxTaskManager *taskManager) +{ + PfxInt32 ret = pfxCheckParamOfSolveConstraints(param); + if(ret != SCE_PFX_OK) return ret; + + SCE_PFX_PUSH_MARKER("pfxSolveConstraints"); + + PfxParallelGroup *contactgroup = (PfxParallelGroup*)taskManager->allocate(sizeof(PfxParallelGroup)); + PfxParallelBatch *contactbatches = (PfxParallelBatch*)taskManager->allocate(sizeof(PfxParallelBatch) * (SCE_PFX_MAX_SOLVER_PHASES * SCE_PFX_MAX_SOLVER_BATCHES)); + PfxParallelGroup *jointgroup = (PfxParallelGroup*)taskManager->allocate(sizeof(PfxParallelGroup)); + PfxParallelBatch *jointbatches = (PfxParallelBatch*)taskManager->allocate(sizeof(PfxParallelBatch) * (SCE_PFX_MAX_SOLVER_PHASES * SCE_PFX_MAX_SOLVER_BATCHES)); + + // split constraints into independent phases and batches. Phases allow + // a set of non-independent constraints to be solved in parallel. One + // phase may have dependencies within another phase, but the phases are + // solved sequentially. Within a phases, there are multiple batches, and + // the batches are independent. Since they are independent, they can be + // distributed to different processors and solved in parallel. + pfxSplitConstraints(param.numRigidBodies, param.contactPairs, param.numContactPairs, + taskManager, contactgroup, contactbatches); + pfxSplitConstraints(param.numRigidBodies, param.jointPairs, param.numJointPairs, + taskManager, jointgroup, jointbatches); + + // parallel solve + taskManager->setTaskEntry((void*)pfxSolveConstraintsTaskEntry); + int task = 0; + for (; task < taskManager->getNumTasks(); task++) + { + taskManager->startTask(task, static_cast(¶m), (PfxUInt32)jointgroup, (PfxUInt32)jointbatches, + (PfxUInt32)contactgroup, (PfxUInt32)contactbatches); + } + + // wait for tasks to complete + PfxUInt32 data1, data2, data3, data4; + for (PfxUInt32 i = 0; i < taskManager->getNumTasks(); i++) + taskManager->waitTask(task, data1, data2, data3, data4); + + // post solve + PfxRigidState *offsetRigidStates = param.offsetRigidStates; + PfxSolverBody *offsetSolverBodies = param.offsetSolverBodies; + for (PfxUInt32 i = 0; i < param.numRigidBodies; i++) + { + param.offsetRigidStates[i].setLinearVelocity(param.offsetRigidStates[i].getLinearVelocity() + + param.offsetSolverBodies[i].m_deltaLinearVelocity); + param.offsetRigidStates[i].setAngularVelocity(param.offsetRigidStates[i].getAngularVelocity() + + param.offsetSolverBodies[i].m_deltaAngularVelocity); + } + + taskManager->clearPool(); + + SCE_PFX_POP_MARKER(); + + return SCE_PFX_OK; +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/low_level/solver/pfx_constraint_solver_single.cpp b/Extras/PhysicsEffects/src/low_level/solver/pfx_constraint_solver_single.cpp new file mode 100644 index 000000000..49bd6fa6a --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/solver/pfx_constraint_solver_single.cpp @@ -0,0 +1,399 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_perf_counter.h" +#include "../../../include/physics_effects/base_level/solver/pfx_contact_constraint.h" +#include "../../../include/physics_effects/low_level/solver/pfx_joint_constraint_func.h" +#include "../../../include/physics_effects/low_level/solver/pfx_constraint_solver.h" +#include "../../base_level/solver/pfx_check_solver.h" +#include "pfx_parallel_group.h" + +namespace sce { +namespace PhysicsEffects { + +PfxUInt32 pfxGetWorkBytesOfSolveConstraints(PfxUInt32 numRigidBodies,PfxUInt32 numContactPairs,PfxUInt32 numJointPairs,PfxUInt32 maxTasks) +{ + (void)maxTasks; + PfxUInt32 workBytes = SCE_PFX_ALLOC_BYTES_ALIGN16(sizeof(PfxUInt8) * numRigidBodies) + + SCE_PFX_ALLOC_BYTES_ALIGN16(sizeof(PfxUInt32)*((SCE_PFX_MAX(numContactPairs,numJointPairs)+31)/32)); + + workBytes += 128 + (SCE_PFX_ALLOC_BYTES_ALIGN16(sizeof(PfxParallelGroup)) + + SCE_PFX_ALLOC_BYTES_ALIGN128(sizeof(PfxParallelBatch)*(SCE_PFX_MAX_SOLVER_PHASES*SCE_PFX_MAX_SOLVER_BATCHES))) * 2; + + return workBytes; +} + +PfxInt32 pfxCheckParamOfSetupSolverBodies(const PfxSetupSolverBodiesParam ¶m) +{ + if(!param.states || !param.bodies || !param.solverBodies ) return SCE_PFX_ERR_INVALID_VALUE; + if(!SCE_PFX_PTR_IS_ALIGNED16(param.states) || !SCE_PFX_PTR_IS_ALIGNED16(param.bodies) || !SCE_PFX_PTR_IS_ALIGNED16(param.solverBodies)) return SCE_PFX_ERR_INVALID_ALIGN; + return SCE_PFX_OK; +} + +PfxInt32 pfxCheckParamOfSetupContactConstraints(const PfxSetupContactConstraintsParam ¶m) +{ + if((param.numContactPairs>0&&(!param.contactPairs||!param.offsetContactManifolds)) || !param.offsetRigidStates || + !param.offsetRigidBodies || !param.offsetSolverBodies || param.timeStep <= 0.0f) return SCE_PFX_ERR_INVALID_VALUE; + if(!SCE_PFX_PTR_IS_ALIGNED16(param.contactPairs) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetContactManifolds) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidStates) || + !SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidBodies) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetSolverBodies)) return SCE_PFX_ERR_INVALID_ALIGN; + return SCE_PFX_OK; +} + +PfxInt32 pfxCheckParamOfSetupJointConstraints(const PfxSetupJointConstraintsParam ¶m) +{ + if((param.numJointPairs>0&&(!param.jointPairs||!param.offsetJoints)) || !param.offsetRigidStates || + !param.offsetRigidBodies || !param.offsetSolverBodies || param.timeStep <= 0.0f) return SCE_PFX_ERR_INVALID_VALUE; + if(!SCE_PFX_PTR_IS_ALIGNED16(param.jointPairs) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetJoints) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidStates) || + !SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidBodies) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetSolverBodies)) return SCE_PFX_ERR_INVALID_ALIGN; + return SCE_PFX_OK; +} + +PfxInt32 pfxCheckParamOfSolveConstraints(const PfxSolveConstraintsParam ¶m) +{ + if((param.numContactPairs>0&&(!param.contactPairs||!param.offsetContactManifolds)) || + (param.numJointPairs>0&&(!param.jointPairs||!param.offsetJoints)) || !param.offsetRigidStates || !param.offsetSolverBodies) return SCE_PFX_ERR_INVALID_VALUE; + if(!SCE_PFX_PTR_IS_ALIGNED16(param.contactPairs) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetContactManifolds) || + !SCE_PFX_PTR_IS_ALIGNED16(param.jointPairs) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetJoints) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidStates) || + !SCE_PFX_PTR_IS_ALIGNED16(param.offsetSolverBodies)) return SCE_PFX_ERR_INVALID_ALIGN; + if(SCE_PFX_AVAILABLE_BYTES_ALIGN16(param.workBuff,param.workBytes) < pfxGetWorkBytesOfSolveConstraints(param.numRigidBodies,param.numContactPairs,param.numJointPairs) ) return SCE_PFX_ERR_OUT_OF_BUFFER; + return SCE_PFX_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// SINGLE THREAD + +PfxInt32 pfxSetupSolverBodies(PfxSetupSolverBodiesParam ¶m) +{ + PfxInt32 ret = pfxCheckParamOfSetupSolverBodies(param); + if(ret != SCE_PFX_OK) return ret; + + SCE_PFX_PUSH_MARKER("pfxSetupSolverBodies"); + + PfxRigidState *states = param.states; + PfxRigidBody *bodies = param.bodies; + PfxSolverBody *solverBodies = param.solverBodies; + PfxUInt32 numRigidBodies = param.numRigidBodies; + + for(PfxUInt32 i=0;i 1) restitution = 0.0f; + + PfxFloat friction = sqrtf(bodyA.getFriction() * bodyB.getFriction()); + + for(int j=0;j= kPfxJointCount) { + return SCE_PFX_ERR_OUT_OF_RANGE; + } + + funcTbl_setupJointConstraint[jointType] = func; + + return SCE_PFX_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// Warm Start Joint Constraint Function Table + +void warmStartJointConstraintDummy( + PfxJoint &joint, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB) +{ + (void)joint,(void)solverBodyA,(void)solverBodyB; +} + +PfxWarmStartJointConstraintFunc funcTbl_warmStartJointConstraint[kPfxJointCount] = { + pfxWarmStartBallJoint, + pfxWarmStartSwingTwistJoint, + pfxWarmStartSwingTwistJoint, + pfxWarmStartSwingTwistJoint, + pfxWarmStartSwingTwistJoint, + pfxWarmStartSwingTwistJoint, + warmStartJointConstraintDummy, + warmStartJointConstraintDummy, + warmStartJointConstraintDummy, + warmStartJointConstraintDummy, + warmStartJointConstraintDummy, + warmStartJointConstraintDummy, + warmStartJointConstraintDummy, + warmStartJointConstraintDummy, + warmStartJointConstraintDummy, +}; + +/////////////////////////////////////////////////////////////////////////////// +// Warm Start Joint Constraint Function Table Interface + +PfxWarmStartJointConstraintFunc pfxGetWarmStartJointConstraintFunc(PfxUInt8 jointType) +{ + SCE_PFX_ASSERT(jointType= kPfxJointCount) { + return SCE_PFX_ERR_OUT_OF_RANGE; + } + + funcTbl_warmStartJointConstraint[jointType] = func; + + return SCE_PFX_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// Solve Joint Constraint Function Table + +void solveJointConstraintDummy( + PfxJoint &joint, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB) +{ + (void)joint,(void)solverBodyA,(void)solverBodyB; +} + +PfxSolveJointConstraintFunc funcTbl_solveJointConstraint[kPfxJointCount] = { + pfxSolveBallJoint, + pfxSolveSwingTwistJoint, + pfxSolveSwingTwistJoint, + pfxSolveSwingTwistJoint, + pfxSolveSwingTwistJoint, + pfxSolveSwingTwistJoint, + solveJointConstraintDummy, + solveJointConstraintDummy, + solveJointConstraintDummy, + solveJointConstraintDummy, + solveJointConstraintDummy, + solveJointConstraintDummy, + solveJointConstraintDummy, + solveJointConstraintDummy, + solveJointConstraintDummy, +}; + +/////////////////////////////////////////////////////////////////////////////// +// Solve Joint Constraint Function Table Interface + +PfxSolveJointConstraintFunc pfxGetSolveJointConstraintFunc(PfxUInt8 jointType) +{ + SCE_PFX_ASSERT(jointType= kPfxJointCount) { + return SCE_PFX_ERR_OUT_OF_RANGE; + } + + funcTbl_solveJointConstraint[jointType] = func; + + return SCE_PFX_OK; +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/low_level/solver/pfx_parallel_group.h b/Extras/PhysicsEffects/src/low_level/solver/pfx_parallel_group.h new file mode 100644 index 000000000..6b4664cfe --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/solver/pfx_parallel_group.h @@ -0,0 +1,44 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_PARALLEL_GROUP_H +#define _SCE_PFX_PARALLEL_GROUP_H + +/////////////////////////////////////////////////////////////////////////////// +// Parallel Group + +#define SCE_PFX_MAX_SOLVER_PHASES 64 // 最大フェーズ数 +#define SCE_PFX_MAX_SOLVER_BATCHES 32 // 1フェーズに含まれる最大並列処理バッチ +#define SCE_PFX_MAX_SOLVER_PAIRS 64 // 1バッチに含まれる最大ペア数 +#define SCE_PFX_MIN_SOLVER_PAIRS 16 // 1バッチに含まれる最小ペア数 + +namespace sce { +namespace PhysicsEffects { + +struct SCE_PFX_ALIGNED(128) PfxParallelBatch { + PfxUInt16 pairIndices[SCE_PFX_MAX_SOLVER_PAIRS]; +}; + +struct SCE_PFX_ALIGNED(128) PfxParallelGroup { + PfxUInt16 numPhases; + PfxUInt16 numBatches[SCE_PFX_MAX_SOLVER_PHASES]; // 各フェーズの保持する並列実行可能なバッチの数 + PfxUInt16 numPairs[SCE_PFX_MAX_SOLVER_PHASES*SCE_PFX_MAX_SOLVER_BATCHES]; // 各バッチの保持するペアの数 +SCE_PFX_PADDING(1,126) +}; + +} //namespace PhysicsEffects +} //namespace sce +#endif // _SCE_PFX_PARALLEL_GROUP_H diff --git a/Extras/PhysicsEffects/src/low_level/solver/pfx_update_rigid_states_parallel.cpp b/Extras/PhysicsEffects/src/low_level/solver/pfx_update_rigid_states_parallel.cpp new file mode 100644 index 000000000..1c90e210e --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/solver/pfx_update_rigid_states_parallel.cpp @@ -0,0 +1,94 @@ +/* +Applied Research Associates Inc. (c)2011 + +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_perf_counter.h" +#include "../../../include/physics_effects/base_level/solver/pfx_integrate.h" +#include "../../../include/physics_effects/low_level/solver/pfx_update_rigid_states.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// This function is implemented in pfx_update_rigid_states_single.cpp +extern PfxInt32 pfxCheckParamOfUpdateRigidStates(const PfxUpdateRigidStatesParam ¶m); + +/////////////////////////////////////////////////////////////////////////////// +// MULTIPLE THREADS + +//---------------------------------------------------------------------------- +// pfxUpdateRigidStatesTaskEntry +// +/// The thread PfxTaskEntry function used to update rigid body states in +/// parallel. +//---------------------------------------------------------------------------- +void pfxUpdateRigidStatesTaskEntry(PfxTaskArg *arg) +{ + PfxUpdateRigidStatesParam ¶m = *((PfxUpdateRigidStatesParam*)arg->io); + + PfxUInt32 iFirstBody = arg->data[0]; + PfxUInt32 iEndBody = arg->data[1]; + + for(PfxUInt32 i = iFirstBody; i < iEndBody; i++) + { + pfxIntegrate(param.states[i],param.bodies[i],param.timeStep); + } +} + +//---------------------------------------------------------------------------- +// pfxUpdateRigidStates +// +/// Perform update rigid states in parallel using a task manager. +/// +/// @param param Information about rigid bodies +/// @param taskManager Pointer to the thread task manager to use +/// +/// @return SCE_PFX_OK if successful, otherwise, returns an error code. +//---------------------------------------------------------------------------- +PfxInt32 pfxUpdateRigidStates(PfxUpdateRigidStatesParam ¶m, PfxTaskManager *taskManager) +{ + PfxInt32 ret = pfxCheckParamOfUpdateRigidStates(param); + if(ret != SCE_PFX_OK) return ret; + + SCE_PFX_PUSH_MARKER("pfxUpdateRigidStates"); + + PfxUInt32 maxBatchSize = param.numRigidBodies / (PfxUInt32)(taskManager->getNumTasks()); + PfxUInt32 iEnd = maxBatchSize, iStart = 0; + int task = 0; + taskManager->setTaskEntry((void*)pfxUpdateRigidStatesTaskEntry); + + for (task = 0; task < taskManager->getNumTasks() - 1; task++, iStart += maxBatchSize, iEnd += maxBatchSize) + { + taskManager->startTask(task, static_cast(¶m), iStart, iEnd, 0, 0); + } + + // send final task + iEnd = param.numRigidBodies; + taskManager->startTask(taskManager->getNumTasks() - 1, static_cast(¶m), iStart, iEnd, 0, 0); + + // wait for tasks to complete + PfxUInt32 data1, data2, data3, data4; + for (PfxUInt32 i = 0; i < taskManager->getNumTasks(); i++) + taskManager->waitTask(task, data1, data2, data3, data4); + + SCE_PFX_POP_MARKER(); + + return SCE_PFX_OK; +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/low_level/solver/pfx_update_rigid_states_single.cpp b/Extras/PhysicsEffects/src/low_level/solver/pfx_update_rigid_states_single.cpp new file mode 100644 index 000000000..827daff3d --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/solver/pfx_update_rigid_states_single.cpp @@ -0,0 +1,51 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../../include/physics_effects/base_level/base/pfx_perf_counter.h" +#include "../../../include/physics_effects/base_level/solver/pfx_integrate.h" +#include "../../../include/physics_effects/low_level/solver/pfx_update_rigid_states.h" + +namespace sce { +namespace PhysicsEffects { + +PfxInt32 pfxCheckParamOfUpdateRigidStates(const PfxUpdateRigidStatesParam ¶m) +{ + if(!param.states || !param.bodies || param.timeStep <= 0.0f) return SCE_PFX_ERR_INVALID_VALUE; + if(!SCE_PFX_PTR_IS_ALIGNED16(param.states) || !SCE_PFX_PTR_IS_ALIGNED16(param.bodies)) return SCE_PFX_ERR_INVALID_ALIGN; + return SCE_PFX_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// SINGLE THREAD + +PfxInt32 pfxUpdateRigidStates(PfxUpdateRigidStatesParam ¶m) +{ + PfxInt32 ret = pfxCheckParamOfUpdateRigidStates(param); + if(ret != SCE_PFX_OK) return ret; + + SCE_PFX_PUSH_MARKER("pfxUpdateRigidStates"); + + for(PfxUInt32 i=0;i 0) + { + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_mutex_destroy(&m_mutex)); + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_cond_destroy(&m_cond)); + } +} + +//---------------------------------------------------------------------------- +// PfxPthreadsBarrier::sync +// +/// This function is used to sync m_numThreads worker threads. Each worker +/// should call sync() when it finishes a task. All workers will block until +/// the last worker also calls sync(). +//---------------------------------------------------------------------------- +void PfxPthreadsBarrier::sync() +{ + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_mutex_lock(&m_mutex)); + + m_called++; + + if (m_called == m_maxThreads) + { + // last thread to join broadcasts a condition that will release + // all the threads waiting at the barrier. The barrier is reset + // to be ready for the next sync point. + m_called = 0; + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_cond_broadcast(&m_cond)); + } + else + { + // First m_numThreads - 1 worker threads block on the condition. + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_cond_wait(&m_cond, &m_mutex)); + } + + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_mutex_unlock(&m_mutex)); +} + +//---------------------------------------------------------------------------- +// PfxPthreadsBarrier::setMaxCount +// +/// Set the number of threads that the barrier should wait for. This also +/// initializes a mutex and condition variable that are used to implement +/// the barrier. +/// +/// @param n Number of threads that should wait at the barrier. +//---------------------------------------------------------------------------- +void PfxPthreadsBarrier::setMaxCount(int n) +{ + if (m_maxThreads > 0) + { + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_mutex_destroy(&m_mutex)); + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_cond_destroy(&m_cond)); + } + + m_called = 0; + + if (0 < n) + { + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_mutex_init(&m_mutex,NULL)); + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_cond_init(&m_cond,NULL)); + } + + m_maxThreads = n; +} + +//---------------------------------------------------------------------------- +// PfxPthreadsBarrier::getMaxCount +// +/// Get the number of threads that the barrier will wait for. +/// +/// @return The number of threads the barrier waits for +//---------------------------------------------------------------------------- +int PfxPthreadsBarrier::getMaxCount() +{ + return m_maxThreads; +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// PfxPthreadsCriticalSection::PfxPthreadsCriticalSection +// +/// Default constructor +//---------------------------------------------------------------------------- +PfxPthreadsCriticalSection::PfxPthreadsCriticalSection() +{ + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_mutex_init(&m_mutex,NULL)); +} + +//---------------------------------------------------------------------------- +// PfxPthreadsCriticalSection::~PfxPthreadsCriticalSection +// +/// Destructor +//---------------------------------------------------------------------------- +PfxPthreadsCriticalSection::~PfxPthreadsCriticalSection() +{ + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_mutex_destroy(&m_mutex)); +} + +//---------------------------------------------------------------------------- +// PfxPthreadsCriticalSection::getSharedParam +// +/// Get the value of a shared parameter. Note that user must lock the +/// critical section before performing this action. +/// +/// @param i index of shared parameter to retrieve. Must have value +/// between 0 and 31 +/// +/// @return Shared parameter value +//---------------------------------------------------------------------------- +PfxUInt32 PfxPthreadsCriticalSection::getSharedParam(int i) +{ + return(m_commonBuff[i]); +} + +//---------------------------------------------------------------------------- +// PfxPthreadsCriticalSection::setSharedParam +// +/// Set the value of a shared parameter. Note that user must lock the +/// critical section before performing this action. +/// +/// @param i index of shared parameter to set. Must have value +/// between 0 and 31 +/// @param p Value to assign to shared parameter +//---------------------------------------------------------------------------- +void PfxPthreadsCriticalSection::setSharedParam(int i,PfxUInt32 p) +{ + m_commonBuff[i] = p; +} + +//---------------------------------------------------------------------------- +// PfxPthreadsCriticalSection::lock +// +/// Lock the critical section +//---------------------------------------------------------------------------- +void PfxPthreadsCriticalSection::lock() +{ + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_mutex_lock(&m_mutex)); +} + +//---------------------------------------------------------------------------- +// PfxPthreadsCriticalSection::lock +// +/// Unlock the critical section +//---------------------------------------------------------------------------- +void PfxPthreadsCriticalSection::unlock() +{ + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_mutex_unlock(&m_mutex)); +} + +//---------------------------------------------------------------------------- +// Factory functions +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// PfxCreateBarrierPthreads +// +/// Factory function to create a pthreads-based barrier +/// +/// @param n Max number of tasks +//---------------------------------------------------------------------------- +PfxBarrier *PfxCreateBarrierPthreads(int n) +{ + PfxPthreadsBarrier *barrier = new PfxPthreadsBarrier; + barrier->setMaxCount(n); + return(barrier); +} + +//---------------------------------------------------------------------------- +// PfxCreateCriticalSectionPthreads +// +/// Factory function to create a pthreads-based critical section +//---------------------------------------------------------------------------- +PfxCriticalSection *PfxCreateCriticalSectionPthreads() +{ + PfxPthreadsCriticalSection *cs = new PfxPthreadsCriticalSection; + return(cs); +} + +} //namespace PhysicsEffects +} //namespace sce + +#endif //__ANDROID__ diff --git a/Extras/PhysicsEffects/src/low_level/task/pfx_sync_components_pthreads.h b/Extras/PhysicsEffects/src/low_level/task/pfx_sync_components_pthreads.h new file mode 100644 index 000000000..1bc405201 --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/task/pfx_sync_components_pthreads.h @@ -0,0 +1,93 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _SCE_PFX_SYNC_COMPONENTS_PTHREADS_H +#define _SCE_PFX_SYNC_COMPONENTS_PTHREADS_H + +#include "../../../include/physics_effects/base_level/base/pfx_common.h" +#include "../../../include/physics_effects/low_level/task/pfx_pthreads.h" +#include "../../../include/physics_effects/low_level/task/pfx_sync_components.h" +#include +#include + +namespace sce { +namespace PhysicsEffects { + +//---------------------------------------------------------------------------- +// PfxPthreadsBarrier +// +/// Implementation of a barrier using pthreads. This version uses a mutex +/// and condition variable rather than using native pthreads barrier, which +/// enables it to be used on platforms that don't support pthreads barriers +/// (such as Android 2.3x) +//---------------------------------------------------------------------------- +class PfxPthreadsBarrier : public PfxBarrier +{ + public: + PfxPthreadsBarrier(); + virtual ~PfxPthreadsBarrier(); + + // from PfxBarrier + virtual void sync(); + virtual void setMaxCount(int n); + virtual int getMaxCount(); + + private: + pthread_mutex_t m_mutex; ///< Mutex used to block worker threads + pthread_cond_t m_cond; ///< Condition variable + + int m_maxThreads; ///< Maximum number of worker threads + int m_called; ///< Number of worker threads waiting at barrier +}; + +//---------------------------------------------------------------------------- +// PfxPthreadsBarrier +// +/// Implementation of a critical section using pthreads. +//---------------------------------------------------------------------------- +class PfxPthreadsCriticalSection : public PfxCriticalSection +{ + public: + PfxPthreadsCriticalSection(); + virtual ~PfxPthreadsCriticalSection(); + + // from PfxCriticalSection + virtual PfxUInt32 getSharedParam(int i); + virtual void setSharedParam(int i,PfxUInt32 p); + + virtual void lock(); + virtual void unlock(); + + private: + pthread_mutex_t m_mutex; ///< Mutex used to implement lock +}; + +} //namespace PhysicsEffects +} //namespace sce + +#endif // _SCE_PFX_SYNC_COMPONENTS_PTHREADS_H diff --git a/Extras/PhysicsEffects/src/low_level/task/pfx_task_manager_pthreads.cpp b/Extras/PhysicsEffects/src/low_level/task/pfx_task_manager_pthreads.cpp new file mode 100644 index 000000000..cecc5aa8c --- /dev/null +++ b/Extras/PhysicsEffects/src/low_level/task/pfx_task_manager_pthreads.cpp @@ -0,0 +1,311 @@ +/* + Applied Research Associates Inc. (c)2011 + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Applied Research Associates Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __ANDROID__ + +#include "../../../include/physics_effects/base_level/base/pfx_common.h" +#include "../../../include/physics_effects/low_level/task/pfx_pthreads.h" +#include "../../../include/physics_effects/low_level/task/pfx_task_manager.h" +#include "../../../include/physics_effects/low_level/task/pfx_sync_components.h" +#include "pfx_sync_components_pthreads.h" + +namespace sce { +namespace PhysicsEffects { + +//---------------------------------------------------------------------------- +// Standalone functions and structs +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// PfxPthreadsThreadData +// +/// Struct to store information needed by worker threads +//---------------------------------------------------------------------------- +struct PfxPthreadsThreadData +{ + // task runner information + PfxTaskArg *taskargument; ///< Pointer to argument for the task entry function + PfxTaskEntry taskEntry; ///< Pointer to current task entry function + + // pthreads synchronization and thread info + pthread_t thread; ///< Current thread + sem_t semaphore; ///< Semaphore used to wake the thread + sem_t *taskmanagersemaphore; ///< Semaphore used to notify parent thread +}; + +//---------------------------------------------------------------------------- +// PfxPthreadsThreadFunction +// +/// The thread function used for threads created and managed using a +/// PfxPthreadsThreadPool +//---------------------------------------------------------------------------- +void *PfxPthreadsThreadFunction(void *argument) +{ + PfxPthreadsThreadData *threaddata = (PfxPthreadsThreadData*)argument; + + while (1) + { + // wait until a task is available + SCE_PFX_CHECK_PTHREADS_OUTCOME(sem_wait(&threaddata->semaphore)); + + // do work + if (threaddata->taskEntry) + threaddata->taskEntry(threaddata->taskargument); + + // notify threadpool that task is done + SCE_PFX_CHECK_PTHREADS_OUTCOME(sem_post(threaddata->taskmanagersemaphore)); + + // If no task, then exit + if (!threaddata->taskEntry) + pthread_exit(0); + } + + return 0; +} + +//---------------------------------------------------------------------------- +// Class definitions +//---------------------------------------------------------------------------- +class PfxPthreadsTaskManager : public PfxTaskManager +{ + public: + PfxPthreadsTaskManager(PfxUInt32 numTasks, PfxUInt32 maxTasks, void *workBuff, PfxUInt32 workBytes) : + PfxTaskManager(numTasks, maxTasks, workBuff, workBytes), + m_threads(NULL) {} + + // from PfxTaskManager + virtual PfxUInt32 getSharedParam(int i); + virtual void setSharedParam(int i, PfxUInt32 p); + virtual void startTask(int taskId, void *io, PfxUInt32 data1, PfxUInt32 data2, + PfxUInt32 data3, PfxUInt32 data4); + virtual void waitTask(int &taskId, PfxUInt32 &data1, PfxUInt32 &data2, + PfxUInt32 &data3, PfxUInt32 &data4); + + virtual void initialize(); + virtual void finalize(); + + protected: + PfxPthreadsTaskManager() : PfxTaskManager(), m_threads(NULL) {} + + private: + PfxPthreadsThreadData *m_threads; ///< Pointer to array of running threads (count is m_numThreads); + PfxPthreadsBarrier m_barrier; ///< Barrier used to sync task groups + PfxPthreadsCriticalSection m_cs; ///< Critical section used to manage shared parameters + sem_t m_taskmanagersemaphore; ///< Synchronization semaphore for task manager +}; + +//---------------------------------------------------------------------------- +// PfxPthreadsTaskManager +// +/// Implementation of a task manager using pthreads. +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// PfxPthreadsTaskManager::initialize +// +/// Initialize the task manager +//---------------------------------------------------------------------------- +void PfxPthreadsTaskManager::initialize() +{ + if (0 == m_maxTasks) + return; + + if (m_threads) // already started + { + SCE_PFX_PRINTF("PfxPthreadsThreadPool attempt to start threads when they are already started, line %i, file %s\n", __LINE__, __FILE__); + return; + } + + m_threads = (PfxPthreadsThreadData*)m_pool.allocate(sizeof(PfxPthreadsThreadData)*m_maxTasks); + if (!m_threads) + { + SCE_PFX_PRINTF("PfxPthreadsThreadPool unable to allocate threads at line %i in file %s\n", __LINE__, __FILE__); + return; + } + + m_barrier.setMaxCount(m_maxTasks); + + // Initialize sync semaphore + SCE_PFX_CHECK_PTHREADS_OUTCOME(sem_init(&m_taskmanagersemaphore, 0, 0)); + + // Allocate and start the threads + for (unsigned int i = 0; i < m_maxTasks; i++) + { + // Prepare argument data structure for task entry functions. Mostly, this is + // setting parameters that are fixed until the simulation ends + m_taskArg[i].taskId = i; + m_taskArg[i].maxTasks = m_maxTasks; + m_taskArg[i].barrier = &m_barrier; + m_taskArg[i].criticalSection = &m_cs; + m_taskArg[i].io = NULL; + + // Prepare other per-thread data + m_threads[i].taskEntry = NULL; + m_threads[i].taskargument = &m_taskArg[i]; + m_threads[i].taskmanagersemaphore = &m_taskmanagersemaphore; + + // Now create the thread's semaphore, then start the thread + SCE_PFX_CHECK_PTHREADS_OUTCOME(sem_init(&m_threads[i].semaphore, 0, 0)); + SCE_PFX_CHECK_PTHREADS_OUTCOME(pthread_create(&m_threads[i].thread, NULL, PfxPthreadsThreadFunction, (void*)&m_threads[i])); + } +} + +//---------------------------------------------------------------------------- +// PfxPthreadsTaskManager::finalize +// +/// Finalize the task manager +//---------------------------------------------------------------------------- +void PfxPthreadsTaskManager::finalize() +{ + // stop the threads + for (unsigned int i = 0; i < m_maxTasks; i++) + { + m_threads[i].taskEntry = NULL; // NULL task tells thread to exit + SCE_PFX_CHECK_PTHREADS_OUTCOME(sem_post(&m_threads[i].semaphore)); + } + + // wait for them all to exit + for (unsigned int i = 0; i < m_maxTasks; i++) + SCE_PFX_CHECK_PTHREADS_OUTCOME(sem_wait(&m_taskmanagersemaphore)); + + // destroy per-thread semaphores + for (unsigned int i = 0; i < m_maxTasks; i++) + SCE_PFX_CHECK_PTHREADS_OUTCOME(sem_destroy(&m_threads[i].semaphore)); + + // delete thread pool + delete [] m_threads; + m_threads = NULL; + + // destroy task manager semaphore and reset barrier + SCE_PFX_CHECK_PTHREADS_OUTCOME(sem_destroy(&m_taskmanagersemaphore)); + + m_barrier.setMaxCount(0); +} + +//---------------------------------------------------------------------------- +// PfxPthreadsTaskManager::startTask +// +/// Start a task +/// +/// @param taskId [in] task thread identifier/index +/// @param io [in, out] task input and output buffer +/// @param data1 [in] first of four user parameter data values for the task +/// @param data2 [in] second of four user parameter data values for the task +/// @param data3 [in] third of four user parameter data values for the task +/// @param data4 [in] fourth of four user parameter data values for the task +//---------------------------------------------------------------------------- +void PfxPthreadsTaskManager::startTask(int taskId,void *io,PfxUInt32 data1, + PfxUInt32 data2,PfxUInt32 data3,PfxUInt32 data4) +{ + m_threads[taskId].taskEntry = m_taskEntry; + m_taskArg[taskId].io = io; + m_taskArg[taskId].data[0] = data1; + m_taskArg[taskId].data[1] = data2; + m_taskArg[taskId].data[2] = data3; + m_taskArg[taskId].data[3] = data4; + SCE_PFX_CHECK_PTHREADS_OUTCOME(sem_post(&m_threads[taskId].semaphore)); +} + +//---------------------------------------------------------------------------- +// PfxPthreadsTaskManager::waitTask +// +/// Wait for a task to finish +/// +/// @param taskId [out] task thread identifier/index +/// @param data1 [out] first of four data values from the task +/// @param data2 [out] second of four data values from the task +/// @param data3 [out] third of four data values from the task +/// @param data4 [out] fourth of four data values from the task +//---------------------------------------------------------------------------- +void PfxPthreadsTaskManager::waitTask(int &taskId,PfxUInt32 &data1,PfxUInt32 &data2, + PfxUInt32 &data3,PfxUInt32 &data4) +{ + SCE_PFX_CHECK_PTHREADS_OUTCOME(sem_wait(&m_taskmanagersemaphore)); +} + +//---------------------------------------------------------------------------- +// PfxPthreadsTaskManager::getSharedParam +// +/// Get the value of a shared parameter +/// +/// @param i index of shared parameter to retrieve. Must have value +/// between 0 and 31 +/// +/// @return Shared parameter value +//---------------------------------------------------------------------------- +PfxUInt32 PfxPthreadsTaskManager::getSharedParam(int i) +{ + m_cs.lock(); + PfxUInt32 paramval = m_cs.getSharedParam(i); + m_cs.unlock(); + return(paramval); +} + +//---------------------------------------------------------------------------- +// PfxPthreadsTaskManager::setSharedParam +// +/// Set the value of a shared parameter +/// +/// @param i index of shared parameter to set. Must have value +/// between 0 and 31 +/// @param p Value to assign to shared parameter +//---------------------------------------------------------------------------- +void PfxPthreadsTaskManager::setSharedParam(int i, PfxUInt32 p) +{ + m_cs.lock(); + PfxUInt32 paramval = m_cs.getSharedParam(i); + m_cs.setSharedParam(i, p); + m_cs.unlock(); +} + +//---------------------------------------------------------------------------- +// Factory functions +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// PfxCreateTaskManagerPthreads +// +/// Factory function to create a pthreads-based task manager +/// +/// @param numTasks number of tasks +/// @param maxTasks max number of tasks +/// @param workBuff work buffer +/// @param workBytes size of work buffer, in bytes +//---------------------------------------------------------------------------- +PfxTaskManager *PfxCreateTaskManagerPthreads(PfxUInt32 numTasks,PfxUInt32 maxTasks, + void *workBuff,PfxUInt32 workBytes) +{ + PfxTaskManager *taskmanager = new PfxPthreadsTaskManager(numTasks, maxTasks, + workBuff, workBytes); + return(taskmanager); +} + +} //namespace PhysicsEffects +} //namespace sce + +#endif //__ANDROID__ diff --git a/Extras/PhysicsEffects/src/util/CMakeLists.txt b/Extras/PhysicsEffects/src/util/CMakeLists.txt new file mode 100644 index 000000000..223cfa467 --- /dev/null +++ b/Extras/PhysicsEffects/src/util/CMakeLists.txt @@ -0,0 +1,20 @@ +INCLUDE_DIRECTORIES( ${PHYSICS_EFFECTS_SOURCE_DIR}/include ) + +SET(PfxUtil_SRCS + pfx_mass.cpp + pfx_mesh_creator.cpp +) + +SET(PfxUtil_HDRS + pfx_array.h + pfx_array_implementation.h + pfx_util_common.h +) + + + + +ADD_LIBRARY(PfxUtil ${PfxUtil_SRCS} ${PfxUtil_HDRS}) + +SET_TARGET_PROPERTIES(PfxUtil PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(PfxUtil PROPERTIES SOVERSION ${BULLET_VERSION}) diff --git a/Extras/PhysicsEffects/src/util/pfx_array.h b/Extras/PhysicsEffects/src/util/pfx_array.h new file mode 100644 index 000000000..b25834680 --- /dev/null +++ b/Extras/PhysicsEffects/src/util/pfx_array.h @@ -0,0 +1,187 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#ifndef _SCE_PFX_ARRAY_H +#define _SCE_PFX_ARRAY_H + +#include "../../include/physics_effects/base_level/base/pfx_common.h" +#include "pfx_util_common.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// 基本的なコンテナクラス + +/////////////////////////////////////////////////////////////////////////////// +// PfxArray + +/* + 可変配列 +*/ + +template +class PfxArray +{ +private: + PfxUInt32 m_numData; + PfxUInt32 m_maxData; + SCE_PFX_PADDING(1,8) + T SCE_PFX_ALIGNED(16) *m_data; + SCE_PFX_PADDING(2,12) + +public: + PfxArray() : m_numData(0),m_maxData(100) + { + m_data = (T*)SCE_PFX_UTIL_ALLOC(16,sizeof(T)*m_maxData); + } + + PfxArray(PfxUInt32 maxData) : m_numData(0),m_maxData(maxData) + { + m_data = (T*)SCE_PFX_UTIL_ALLOC(16,sizeof(T)*m_maxData); + } + + ~PfxArray() + { + SCE_PFX_UTIL_FREE(m_data); + } + + PfxUInt32 size() const {return m_numData;} + + inline T& operator[](PfxUInt32 i); + + inline const T& operator[](PfxUInt32 i) const; + + inline const PfxArray& operator=(const PfxArray &array); + + // 指定数分のデータを準備する + inline void assign(PfxUInt32 num,const T &initData); + + // データを追加 + inline PfxUInt32 push(const T& data); + + // i番目のデータを消去 + inline bool remove(PfxUInt32 i); + + inline bool empty() const {return m_numData==0;} + + inline void clear() {m_numData = 0;} +}; + +/////////////////////////////////////////////////////////////////////////////// +// PfxQueue + +/* + キュー(最大数固定) +*/ + +template +class PfxQueue +{ +private: + PfxUInt32 m_numData; + PfxUInt32 m_maxData; + PfxUInt32 m_head; + PfxUInt32 m_tail; + T SCE_PFX_ALIGNED(16) *m_data; + SCE_PFX_PADDING(1,12) + + PfxQueue() {} + +public: + + PfxQueue(PfxUInt32 maxData) : m_numData(0),m_maxData(maxData),m_head(0),m_tail(0) + { + m_data = (T*)SCE_PFX_UTIL_ALLOC(16,sizeof(T)*m_maxData); + } + + ~PfxQueue() + { + SCE_PFX_UTIL_FREE(m_data); + } + + PfxUInt32 size() const {return m_numData;} + + // データをキューに入れる + inline PfxUInt32 push(const T& data); + + // 最後尾のデータを消去 + inline void pop(); + + // 先頭のデータを参照 + inline T& front(); + + // 先頭のデータを参照 + inline const T& front() const; + + inline bool empty() const {return m_numData==0;} + + inline void clear() {m_numData = 0;} +}; + +/////////////////////////////////////////////////////////////////////////////// +// PfxStack + +/* + スタック(最大数固定) +*/ + +template +class PfxStack +{ +private: + PfxUInt32 m_numData; + PfxUInt32 m_maxData; + T SCE_PFX_ALIGNED(16) *m_data; + + PfxStack() {} + +public: + + PfxStack(PfxUInt32 maxData) : m_numData(0),m_maxData(maxData) + { + m_data = (T*)SCE_PFX_UTIL_ALLOC(16,sizeof(T)*m_maxData); + } + + ~PfxStack() + { + SCE_PFX_UTIL_FREE(m_data); + } + + PfxUInt32 size() const {return m_numData;} + + // データをスタックに入れる + inline PfxUInt32 push(const T& data); + + // 末尾のデータを消去 + inline void pop(); + + // 末尾のデータを参照 + inline T& top(); + + // 末尾のデータを参照 + inline const T& top() const; + + inline bool empty() const {return m_numData==0;} + + inline void clear() {m_numData = 0;} +}; + +} //namespace PhysicsEffects +} //namespace sce +#include "pfx_array_implementation.h" + +#endif // _SCE_PFX_ARRAY_H diff --git a/Extras/PhysicsEffects/src/util/pfx_array_implementation.h b/Extras/PhysicsEffects/src/util/pfx_array_implementation.h new file mode 100644 index 000000000..21374088a --- /dev/null +++ b/Extras/PhysicsEffects/src/util/pfx_array_implementation.h @@ -0,0 +1,159 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +/////////////////////////////////////////////////////////////////////////////// +// PfxArray + +namespace sce { +namespace PhysicsEffects { +template +inline T& PfxArray::operator[](PfxUInt32 i) +{ + return m_data[i]; +} + +template +inline const T& PfxArray::operator[](PfxUInt32 i) const +{ + return m_data[i]; +} + +template +inline const PfxArray& PfxArray::operator=(const PfxArray &array) +{ + clear(); + if(array.size() > m_maxData) { + m_maxData = array.size(); + m_data = (T*)SCE_PFX_UTIL_REALLOC(m_data,16,sizeof(T)*m_maxData); + SCE_PFX_ASSERT(m_data); + } + for(PfxUInt32 i=0;i +inline void PfxArray::assign(PfxUInt32 num,const T &initData) +{ + clear(); + if(num > m_maxData) { + m_maxData = num; + m_data = (T*)SCE_PFX_UTIL_REALLOC(m_data,16,sizeof(T)*m_maxData); + SCE_PFX_ASSERT(m_data); + } + for(PfxUInt32 i=0;i +inline PfxUInt32 PfxArray::push(const T& data) +{ + if(m_numData == m_maxData) { + m_maxData<<=1; + m_data = (T*)SCE_PFX_UTIL_REALLOC(m_data,16,sizeof(T)*m_maxData); + SCE_PFX_ASSERT(m_data); + } + + PfxUInt32 id = m_numData++; + m_data[id] = data; + return id; +} + +template +inline bool PfxArray::remove(PfxUInt32 i) +{ + if(i>=m_numData) { + return false; + } + + m_numData--; + m_data[i] = m_data[m_numData]; + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// PfxQueue + +template +inline PfxUInt32 PfxQueue::push(const T& data) +{ + SCE_PFX_ASSERT(m_numData +inline void PfxQueue::pop() +{ + SCE_PFX_ASSERT(m_numData>0); + m_head = (m_head+1)%m_maxData; + m_numData--; +} + +template +inline T& PfxQueue::front() +{ + SCE_PFX_ASSERT(m_numData>0); + return m_data[m_head]; +} + +template +inline const T& PfxQueue::front() const +{ + SCE_PFX_ASSERT(m_numData>0); + return m_data[m_head]; +} + +/////////////////////////////////////////////////////////////////////////////// +// PfxStack + +template +inline PfxUInt32 PfxStack::push(const T& data) +{ + SCE_PFX_ASSERT(m_numData +inline void PfxStack::pop() +{ + SCE_PFX_ASSERT(m_numData>0); + m_numData--; +} + +template +inline T& PfxStack::top() +{ + SCE_PFX_ASSERT(m_numData>0); + return m_data[m_numData-1]; +} + +template +inline const T& PfxStack::top() const +{ + SCE_PFX_ASSERT(m_numData>0); + return m_data[m_numData-1]; +} +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/util/pfx_mass.cpp b/Extras/PhysicsEffects/src/util/pfx_mass.cpp new file mode 100644 index 000000000..ef274bc17 --- /dev/null +++ b/Extras/PhysicsEffects/src/util/pfx_mass.cpp @@ -0,0 +1,102 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../include/physics_effects/util/pfx_mass.h" + +namespace sce { +namespace PhysicsEffects { + +/////////////////////////////////////////////////////////////////////////////// +// Box + +PfxFloat pfxCalcMassBox(PfxFloat density,const PfxVector3 &halfExtent) +{ + return density * halfExtent[0] * halfExtent[1] * halfExtent[2] * 8; +} + +PfxMatrix3 pfxCalcInertiaBox(const PfxVector3 &halfExtent,PfxFloat mass) +{ + PfxVector3 sqrSz = halfExtent * 2.0f; + sqrSz = mulPerElem(sqrSz,sqrSz); + PfxMatrix3 inertia = PfxMatrix3::identity(); + inertia[0][0] = (mass*(sqrSz[1]+sqrSz[2]))/12.0f; + inertia[1][1] = (mass*(sqrSz[0]+sqrSz[2]))/12.0f; + inertia[2][2] = (mass*(sqrSz[0]+sqrSz[1]))/12.0f; + return inertia; +} + +/////////////////////////////////////////////////////////////////////////////// +// Sphere + +PfxFloat pfxCalcMassSphere(PfxFloat density,PfxFloat radius) +{ + return (4.0f/3.0f) * SCE_PFX_PI * radius * radius * radius * density; +} + +PfxMatrix3 pfxCalcInertiaSphere(PfxFloat radius,PfxFloat mass) +{ + PfxMatrix3 inertia = PfxMatrix3::identity(); + inertia[0][0] = inertia[1][1] = inertia[2][2] = 0.4f * mass * radius * radius; + return inertia; +} + +/////////////////////////////////////////////////////////////////////////////// +// Cylinder + +PfxFloat pfxCalcMassCylinder(PfxFloat density,PfxFloat halfLength,PfxFloat radius) +{ + return SCE_PFX_PI * radius * radius * 2.0f * halfLength * density; +} + +static inline +PfxMatrix3 pfxCalcInertiaCylinder(PfxFloat halfLength,PfxFloat radius,PfxFloat mass,int axis) +{ + PfxMatrix3 inertia = PfxMatrix3::identity(); + inertia[0][0] = inertia[1][1] = inertia[2][2] = 0.25f * mass * radius * radius + 0.33f * mass * halfLength * halfLength; + inertia[axis][axis] = 0.5f * mass * radius * radius; + return inertia; +} + +PfxMatrix3 pfxCalcInertiaCylinderX(PfxFloat halfLength,PfxFloat radius,PfxFloat mass) +{ + return pfxCalcInertiaCylinder(radius,halfLength,mass,0); +} + +PfxMatrix3 pfxCalcInertiaCylinderY(PfxFloat halfLength,PfxFloat radius,PfxFloat mass) +{ + return pfxCalcInertiaCylinder(radius,halfLength,mass,1); +} + +PfxMatrix3 pfxCalcInertiaCylinderZ(PfxFloat halfLength,PfxFloat radius,PfxFloat mass) +{ + return pfxCalcInertiaCylinder(radius,halfLength,mass,2); +} + +/////////////////////////////////////////////////////////////////////////////// + +PfxMatrix3 pfxMassTranslate(PfxFloat mass,const PfxMatrix3 &inertia,const PfxVector3 &translation) +{ + PfxMatrix3 m = crossMatrix(translation); + return inertia + mass * (-m*m); +} + +PfxMatrix3 pfxMassRotate(const PfxMatrix3 &inertia,const PfxMatrix3 &rotate) +{ + return rotate * inertia * transpose(rotate); +} + +} //namespace PhysicsEffects +} //namespace sce diff --git a/Extras/PhysicsEffects/src/util/pfx_mesh_creator.cpp b/Extras/PhysicsEffects/src/util/pfx_mesh_creator.cpp new file mode 100644 index 000000000..6613cb19c --- /dev/null +++ b/Extras/PhysicsEffects/src/util/pfx_mesh_creator.cpp @@ -0,0 +1,944 @@ +/* +Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc. +All rights reserved. + +Physics Effects is open software; you can redistribute it and/or +modify it under the terms of the BSD License. + +Physics Effects is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the BSD License for more details. + +A copy of the BSD License is distributed with +Physics Effects under the filename: physics_effects_license.txt +*/ + +#include "../../include/physics_effects/util/pfx_mesh_creator.h" +#include "pfx_array.h" +#include "../base_level/collision/pfx_intersect_common.h" + +namespace sce { +namespace PhysicsEffects { + +#define SCE_PFX_LARGETRIMESH_MAX_ISLANDS 256 + +/////////////////////////////////////////////////////////////////////////////// +// 凸メッシュ作成時に使用する関数 + +PfxInt32 pfxCreateConvexMesh(PfxConvexMesh &convex,const PfxCreateConvexMeshParam ¶m) +{ + // Check input + if(param.numVerts == 0 || param.numTriangles == 0 || !param.verts || !param.triangles) + return SCE_PFX_ERR_INVALID_VALUE; + + if(param.numVerts >= SCE_PFX_NUMMESHVERTICES || param.numTriangles >= SCE_PFX_NUMMESHFACETS) + return SCE_PFX_ERR_OUT_OF_RANGE; + + PfxArray vertList; + for(PfxUInt32 i=0;i facetList; + for(PfxUInt32 i=0;i facetsInIsland[SCE_PFX_MAX_LARGETRIMESH_ISLANDS]; + PfxUInt32 numIslands; + SCE_PFX_PADDING(1,12) + + PfxMcIslands() + { + numIslands = 0; + } + + void add(PfxArray &facets) + { + facetsInIsland[numIslands++] = facets; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// ラージメッシュ作成時に使用する補助関数 + +static +bool intersect(const PfxMcFacet &facetA,const PfxMcFacet &facetB,PfxFloat &closestDistance) +{ + const PfxFloat epsilon = 0.00001f; + + PfxVector3 pA[3] = { + facetA.v[0]->coord, + facetA.v[1]->coord, + facetA.v[2]->coord + }; + + PfxVector3 pB[3] = { + facetB.v[0]->coord, + facetB.v[1]->coord, + facetB.v[2]->coord + }; + + // 面Bが面Aの厚みを考慮した範囲内に有るかどうかチェック + + // 上下面 + { + PfxPlane planeA(facetA.n,pA[0]); + PfxFloat dmin = SCE_PFX_FLT_MAX; + PfxFloat dmax = -SCE_PFX_FLT_MAX; + for(int i=0;i<3;i++) { + PfxFloat d = planeA.onPlane(pB[i]); + dmin = SCE_PFX_MIN(dmin,d); + dmax = SCE_PFX_MAX(dmax,d); + } + + if(dmin > -epsilon || dmax < -facetA.thickness) return false; + + // 面Aと面Bの最近接距離 + if(dmax > 0.0f) { + // 面A,Bは交差 + return false; + } + else if(dmax > -epsilon) { + // 隣接面 + return false; + } + else { + closestDistance = -dmax; + } + } + + // 側面 + for(int p=0;p<3;p++) { + PfxVector3 sideVec = normalize(cross((pA[(p+1)%3]-pA[p]),facetA.n)); + PfxPlane planeA(sideVec,pA[p]); + + PfxFloat dmin = SCE_PFX_FLT_MAX; + for(int i=0;i<3;i++) { + PfxFloat d = planeA.onPlane(pB[i]); + dmin = SCE_PFX_MIN(dmin,d); + } + + if(dmin > -epsilon) return false; + } + + return true; +} + +static +void divideMeshes( + PfxUInt32 numFacetsLimit,PfxFloat islandsRatio, + PfxMcIslands &islands, + PfxArray &facets, + const PfxVector3 ¢er,const PfxVector3 &half) +{ + PfxFloat halfLimit = length(half) * islandsRatio; + + // 含まれる面数が規定値以下であれば、アイランドに登録 + if((facets.size() <= SCE_PFX_NUMMESHFACETS && length(half) < halfLimit) || + (facets.size() <= numFacetsLimit ) ) { + islands.add(facets); + return; + } + + // さらに分割 + PfxVector3 newCenter0,newCenter1; + PfxVector3 newHalf0,newHalf1; + PfxArray newFacets0; + PfxArray newFacets1; + + // 最も適切と思われる分離軸を探す + int divAxis; + { + if(half[0] > half[1]) { + if(half[0] > half[2]) { + divAxis = 0; + } + else if(half[1] > half[2]) { + divAxis = 1; + } + else { + divAxis = 2; + } + } + else { + if(half[1] > half[2]) { + divAxis = 1; + } + else if(half[0] > half[2]) { + divAxis = 0; + } + else { + divAxis = 2; + } + } + } + + // 中心で分割して、さらに再帰的に処理を続ける + { + PfxVector3 movCenter(0.0f); + movCenter[divAxis] = 0.5f*half[divAxis]; + + newCenter0 = center + movCenter; + newCenter1 = center - movCenter; + newHalf0 = half; + newHalf0[divAxis] *= 0.5f; + newHalf1 = newHalf0; + } + + // 新しいAABBに含まれる面をそれぞれの領域に分配 + for(PfxUInt32 f=0;faabbMin + facets[f]->aabbMax) * 0.5f; + PfxVector3 facetHalf = (facets[f]->aabbMax - facets[f]->aabbMin) * 0.5f; + + // AABB判定 + if(!(fabsf(newCenter0[divAxis]-facetCenter[divAxis]) > (newHalf0[divAxis]+facetHalf[divAxis]))) { + // この面はAABB0に登録 + newFacets0.push(facets[f]); + } + else { + // この面はAABB1に登録 + newFacets1.push(facets[f]); + } + } + + if(newFacets0.size() < newFacets1.size()) { + if(newFacets0.size() > 0) + divideMeshes(numFacetsLimit,islandsRatio,islands,newFacets0,newCenter0,newHalf0); + if(newFacets1.size() > 0) + divideMeshes(numFacetsLimit,islandsRatio,islands,newFacets1,newCenter1,newHalf1); + } + else { + if(newFacets1.size() > 0) + divideMeshes(numFacetsLimit,islandsRatio,islands,newFacets1,newCenter1,newHalf1); + if(newFacets0.size() > 0) + divideMeshes(numFacetsLimit,islandsRatio,islands,newFacets0,newCenter0,newHalf0); + } +} + +static +int addIslandToLargeTriMesh(PfxLargeTriMesh &lmesh,PfxTriMesh &island) +{ + SCE_PFX_ASSERT(island.m_numFacets <= SCE_PFX_NUMMESHFACETS); + + int newIsland = lmesh.m_numIslands++; + lmesh.m_islands[newIsland] = island; + + // アイランドローカルのAABBを計算 + if(island.m_numFacets > 0) { + PfxVector3 aabbMin(SCE_PFX_FLT_MAX),aabbMax(-SCE_PFX_FLT_MAX); + + for(PfxUInt32 i=0;i &facets) +{ + if(facets.empty()) return; + + island.m_numFacets = facets.size(); + + PfxUInt32 vertsFlag[(0xff*SCE_PFX_NUMMESHFACETS*3+31)/32]; + memset(vertsFlag,0,sizeof(PfxUInt32)*((0xff*SCE_PFX_NUMMESHFACETS*3+31)/32)); + + PfxArray edgeHead(facets.size()*3); + PfxArray edgeList(facets.size()*3); + + PfxMcEdgeEntry* nl = NULL; + edgeHead.assign(facets.size()*3,nl); + edgeList.assign(facets.size()*3,PfxMcEdgeEntry()); + + int vcnt = 0; + int ecnt = 0; + for(PfxUInt32 f=0;fv[v]; + PfxUInt32 idx = vert->i; + PfxUInt32 mask = 1 << (idx & 31); + if((vertsFlag[idx>>5] & mask) == 0) { + SCE_PFX_ASSERT(vcnt>5] |= mask; + island.m_verts[vcnt] = vert->coord; + vert->flag = vcnt;// 新しいインデックス + vcnt++; + } + oFacet.m_vertIds[v] = (PfxUInt8)vert->flag; + } + + // Edge + for(int v=0;v<3;v++) { + PfxUInt8 viMin = SCE_PFX_MIN(oFacet.m_vertIds[v],oFacet.m_vertIds[(v+1)%3]); + PfxUInt8 viMax = SCE_PFX_MAX(oFacet.m_vertIds[v],oFacet.m_vertIds[(v+1)%3]); + int key = ((0x8da6b343*viMin+0xd8163841*viMax)%(island.m_numFacets*3)); + for(PfxMcEdgeEntry *e=edgeHead[key];;e=e->next) { + if(!e) { + edgeList[ecnt].vertId[0] = viMin; + edgeList[ecnt].vertId[1] = viMax; + edgeList[ecnt].facetId[0] = f; + edgeList[ecnt].numFacets = 1; + edgeList[ecnt].edgeNum[0] = v; + edgeList[ecnt].edgeId = ecnt; + edgeList[ecnt].dir = normalize(island.m_verts[viMax]-island.m_verts[viMin]); + edgeList[ecnt].next = edgeHead[key]; + edgeHead[key] = &edgeList[ecnt]; + + PfxEdge edge; + edge.m_angleType = iEdge[v]->angleType; + // 厚み角の設定 0~πを0~255の整数値に変換して格納 + edge.m_tilt = (PfxUInt8)((iEdge[v]->angle/(0.5f*SCE_PFX_PI))*255.0f); + edge.m_vertId[0] = viMin; + edge.m_vertId[1] = viMax; + + oFacet.m_edgeIds[v] = ecnt; + island.m_edges[ecnt] = edge; + SCE_PFX_ASSERT(ecnt <= SCE_PFX_NUMMESHEDGES); + ecnt++; + break; + } + + if(e->vertId[0] == viMin && e->vertId[1] == viMax) { + SCE_PFX_ASSERT(e->numFacets==1); + e->facetId[1] = f; + e->edgeNum[1] = v; + e->numFacets = 2; + oFacet.m_edgeIds[v] = e->edgeId; + break; + } + } + } + } + + island.m_numEdges = ecnt; + island.m_numVerts = vcnt; + + island.updateAABB(); +} + +/////////////////////////////////////////////////////////////////////////////// +// ラージメッシュ + +PfxInt32 pfxCreateLargeTriMesh(PfxLargeTriMesh &lmesh,const PfxCreateLargeTriMeshParam ¶m) +{ + // Check input + if(param.numVerts == 0 || param.numTriangles == 0 || !param.verts || !param.triangles) + return SCE_PFX_ERR_INVALID_VALUE; + + if(param.islandsRatio < 0.0f || param.islandsRatio > 1.0f) + return SCE_PFX_ERR_OUT_OF_RANGE; + + if(param.numFacetsLimit == 0 || param.numFacetsLimit > SCE_PFX_NUMMESHFACETS) + return SCE_PFX_ERR_OUT_OF_RANGE; + + const PfxFloat epsilon = 0.00001f; + + PfxArray vertList(param.numVerts); // 頂点配列 + PfxArray facetList(param.numTriangles); // 面配列 + PfxArray edgeList(param.numTriangles*3); // エッジ配列 + PfxArray edgeHead(param.numTriangles*3); + + //J 頂点配列作成 + for(PfxUInt32 i=0;i triEntry(numTriangles*3); + PfxArray triHead(numTriangles*3); // 頂点から面への参照リスト + PfxInt32 cnt = 0; + + PfxMcTriList* nl = NULL; + triEntry.assign(numTriangles*3,PfxMcTriList()); + triHead.assign(numTriangles*3,nl); + + // 頂点から面への参照リストを作成 + for(PfxUInt32 i=0;ii; + triEntry[cnt].facet = &facetList[i]; + triEntry[cnt].next = triHead[vertId]; + triHead[vertId] = &triEntry[cnt++]; + } + } + + // 同一頂点をまとめる + if(param.flag & SCE_PFX_MESH_FLAG_AUTO_ELIMINATION) { + for(PfxUInt32 i=0;inext) { + for(PfxInt32 k=0;k<3;k++) { + if(f->facet->v[k] == &vertList[j]) { + f->facet->v[k] = &vertList[i]; // 頂点を付け替える + break; + } + } + } + } + } + } + } + } + + // 接続面間の角度を算出して面にセット + PfxMcEdge *nl = NULL; + edgeHead.assign(numTriangles*3,nl); + edgeList.assign(numTriangles*3,PfxMcEdge()); + + // エッジ配列の作成 + PfxUInt32 ecnt = 0; + for(PfxUInt32 i=0;inext) { + if(!e) { + edgeList[ecnt].vertId[0] = viMin; + edgeList[ecnt].vertId[1] = viMax; + edgeList[ecnt].facetId[0] = i; + edgeList[ecnt].edgeId[0] = v; + edgeList[ecnt].numFacets = 1; + edgeList[ecnt].next = edgeHead[key]; + edgeList[ecnt].angleType = SCE_PFX_EDGE_CONVEX; + edgeList[ecnt].angle = 0.0f; + edgeHead[key] = &edgeList[ecnt]; + f.e[v] = &edgeList[ecnt]; + ecnt++; + break; + } + + if(e->vertId[0] == viMin && e->vertId[1] == viMax) { + SCE_PFX_ALWAYS_ASSERT_MSG(e->numFacets == 1,"An edge connected with over 2 triangles is invalid"); + e->facetId[1] = i; + e->edgeId[1] = v; + e->numFacets = 2; + f.e[v] = e; + f.neighbor[v] = e->facetId[0]; + f.neighborEdgeId[v] = e->edgeId[0]; + facetList[e->facetId[0]].neighbor[e->edgeId[0]] = i; + facetList[e->facetId[0]].neighborEdgeId[e->edgeId[0]] = e->edgeId[1]; + break; + } + } + } + } + + // 角度を計算 + for(PfxUInt32 i=0;i cqueue(ecnt); + + for(PfxUInt32 j=0;j<3;j++) { + if(facetA.neighbor[j] >= 0) { + cqueue.push(PfxMcFacetLink( + j, + facetA.e[j]->vertId[0],facetA.e[j]->vertId[1], + i,j, + facetA.neighbor[j],facetA.neighborEdgeId[j])); + } + } + + while(!cqueue.empty()) { + PfxMcFacetLink link = cqueue.front(); + cqueue.pop(); + + PfxMcFacet &ofacet = facetList[link.ofacetId]; + PfxMcEdge *edge = ofacet.e[link.oedgeId]; + + // facetAとのなす角を計算 + { + // 面に含まれるが、このエッジに含まれない点 + PfxUInt32 ids[3] = {2,0,1}; + PfxVector3 v1 = facetA.v[ids[link.baseEdgeId]]->coord; + PfxVector3 v2 = ofacet.v[ids[link.oedgeId]]->coord; + + // エッジの凹凸判定 + PfxVector3 midPnt = (v1 + v2) * 0.5f; + PfxVector3 pntOnEdge = facetA.v[link.baseEdgeId]->coord; + + PfxFloat chk1 = dot(facetA.n,midPnt-pntOnEdge); + PfxFloat chk2 = dot(ofacet.n,midPnt-pntOnEdge); + + if(chk1 < -epsilon && chk2 < -epsilon) { + if(link.ifacetId == i) edge->angleType = SCE_PFX_EDGE_CONVEX; + + // 厚み角の判定に使う角度をセット + if(param.flag & SCE_PFX_MESH_FLAG_AUTO_THICKNESS) { + edge->angle = 0.5f*acosf(dot(facetA.n,ofacet.n)); + } + } + else if(chk1 > epsilon && chk2 > epsilon) { + if(link.ifacetId == i) edge->angleType = SCE_PFX_EDGE_CONCAVE; + } + else { + if(link.ifacetId == i) edge->angleType = SCE_PFX_EDGE_FLAT; + } + } + + // 次の接続面を登録(コメントアウトすると頂点で接続された面を考慮しない) + if(param.flag & SCE_PFX_MESH_FLAG_AUTO_THICKNESS) { + PfxInt32 nextEdgeId = (link.oedgeId+1)%3; + PfxMcEdge *nextEdge = ofacet.e[nextEdgeId]; + if(ofacet.neighbor[nextEdgeId] >= 0 && ofacet.neighbor[nextEdgeId] != i && + ((PfxInt32)nextEdge->vertId[0] == link.vid1 || (PfxInt32)nextEdge->vertId[0] == link.vid2 || + (PfxInt32)nextEdge->vertId[1] == link.vid1 || (PfxInt32)nextEdge->vertId[1] == link.vid2) ) { + cqueue.push(PfxMcFacetLink( + link.baseEdgeId, + link.vid1,link.vid2, + link.ofacetId,link.iedgeId, + ofacet.neighbor[nextEdgeId],ofacet.neighborEdgeId[nextEdgeId])); + } + nextEdgeId = (link.oedgeId+2)%3; + nextEdge = ofacet.e[nextEdgeId]; + if(ofacet.neighbor[nextEdgeId] >= 0 && ofacet.neighbor[nextEdgeId] != i && + ((PfxInt32)nextEdge->vertId[0] == link.vid1 || (PfxInt32)nextEdge->vertId[0] == link.vid2 || + (PfxInt32)nextEdge->vertId[1] == link.vid1 || (PfxInt32)nextEdge->vertId[1] == link.vid2) ) { + cqueue.push(PfxMcFacetLink( + link.baseEdgeId, + link.vid1,link.vid2, + link.ofacetId,link.iedgeId, + ofacet.neighbor[nextEdgeId],ofacet.neighborEdgeId[nextEdgeId])); + } + } + } + } + + // 面に厚みを付ける + if(param.flag & SCE_PFX_MESH_FLAG_AUTO_THICKNESS) { + for(PfxUInt32 i=0;ifacetId[0] || + j == (PfxInt32)facetA.e[0]->facetId[1] || + j == (PfxInt32)facetA.e[1]->facetId[0] || + j == (PfxInt32)facetA.e[1]->facetId[1] || + j == (PfxInt32)facetA.e[2]->facetId[0] || + j == (PfxInt32)facetA.e[2]->facetId[1]) { + continue; + } + + PfxMcFacet &facetB = facetList[j]; + + // 交差判定 + PfxFloat closestDistance=0; + if(intersect(facetA,facetB,closestDistance)) { + // 最近接距離/2を厚みとして採用 + facetA.thickness = SCE_PFX_MAX(param.defaultThickness,SCE_PFX_MIN(facetA.thickness,closestDistance * 0.5f)); + } + } + + } + } + + // 面の面積によって3種類に分類する + PfxFloat areaMin=SCE_PFX_FLT_MAX,areaMax=-SCE_PFX_FLT_MAX; + for(PfxUInt32 f=0;f<(PfxUInt32)numTriangles;f++) { + PfxVector3 pnts[3] = { + facetList[f].v[0]->coord, + facetList[f].v[1]->coord, + facetList[f].v[2]->coord, + }; + areaMin = SCE_PFX_MIN(areaMin,facetList[f].area); + areaMax = SCE_PFX_MAX(areaMax,facetList[f].area); + + // 面のAABBを算出 + facetList[f].aabbMin = minPerElem(pnts[2],minPerElem(pnts[1],pnts[0])); + facetList[f].aabbMax = maxPerElem(pnts[2],maxPerElem(pnts[1],pnts[0])); + } + + PfxFloat areaDiff = (areaMax-areaMin)/3.0f; + PfxFloat areaLevel0,areaLevel1; + areaLevel0 = areaMin + areaDiff; + areaLevel1 = areaMin + areaDiff * 2.0f; + + PfxArray facetsLv0(numTriangles); + PfxArray facetsLv1(numTriangles); + PfxArray facetsLv2(numTriangles); + + for(PfxUInt32 f=0;f areaLevel1) { + facetsLv2.push(fct); + } + else { + facetsLv1.push(fct); + } + } + + // アイランドの配列 + PfxMcIslands islands; + PfxVector3 lmeshSize; + + // レベル毎にPfxTriMeshを作成 + if(!facetsLv0.empty()) { + // 全体のAABBを求める + PfxVector3 aabbMin,aabbMax,center,half; + aabbMin =facetsLv0[0]->aabbMin; + aabbMax = facetsLv0[0]->aabbMax; + for(PfxUInt32 f=1;faabbMin,aabbMin); + aabbMax = maxPerElem(facetsLv0[f]->aabbMax,aabbMax); + } + center = ( aabbMin + aabbMax ) * 0.5f; + half = ( aabbMax - aabbMin ) * 0.5f; + + // 再帰的に処理 + divideMeshes( + param.numFacetsLimit,param.islandsRatio, + islands, + facetsLv0, + center,half); + + lmeshSize = maxPerElem(lmeshSize,maxPerElem(absPerElem(aabbMin),absPerElem(aabbMax))); + } + + if(!facetsLv1.empty()) { + // 全体のAABBを求める + PfxVector3 aabbMin,aabbMax,center,half; + aabbMin =facetsLv1[0]->aabbMin; + aabbMax = facetsLv1[0]->aabbMax; + for(PfxUInt32 f=1;faabbMin,aabbMin); + aabbMax = maxPerElem(facetsLv1[f]->aabbMax,aabbMax); + } + center = ( aabbMin + aabbMax ) * 0.5f; + half = ( aabbMax - aabbMin ) * 0.5f; + + // 再帰的に処理 + divideMeshes( + param.numFacetsLimit,param.islandsRatio, + islands, + facetsLv1, + center,half); + + lmeshSize = maxPerElem(lmeshSize,maxPerElem(absPerElem(aabbMin),absPerElem(aabbMax))); + } + + if(!facetsLv2.empty()) { + // 全体のAABBを求める + PfxVector3 aabbMin,aabbMax,center,half; + aabbMin =facetsLv2[0]->aabbMin; + aabbMax = facetsLv2[0]->aabbMax; + for(PfxUInt32 f=1;faabbMin,aabbMin); + aabbMax = maxPerElem(facetsLv2[f]->aabbMax,aabbMax); + } + center = ( aabbMin + aabbMax ) * 0.5f; + half = ( aabbMax - aabbMin ) * 0.5f; + + // 再帰的に処理 + divideMeshes( + param.numFacetsLimit,param.islandsRatio, + islands, + facetsLv2, + center,half); + + lmeshSize = maxPerElem(lmeshSize,maxPerElem(absPerElem(aabbMin),absPerElem(aabbMax))); + } + + lmesh.m_half = lmeshSize; + + // Check Islands + //for(PfxInt32 i=0;iv[0]->i,facet->v[1]->i,facet->v[2]->i); + // } + //} + + // PfxLargeTriMeshの生成 + if(islands.numIslands > 0) { + lmesh.m_numIslands = 0; + lmesh.m_aabbList = (PfxAabb16*)SCE_PFX_UTIL_ALLOC(128,sizeof(PfxAabb16)*islands.numIslands); + lmesh.m_islands = (PfxTriMesh*)SCE_PFX_UTIL_ALLOC(128,sizeof(PfxTriMesh)*islands.numIslands); + + PfxInt32 maxFacets=0,maxVerts=0,maxEdges=0; + for(PfxUInt32 i=0;i + +#ifdef _WIN32 + #define SCE_PFX_UTIL_ALLOC(align,size) _aligned_malloc(size,align) + #define SCE_PFX_UTIL_REALLOC(ptr,align,size) _aligned_realloc(ptr,size,align) + #define SCE_PFX_UTIL_FREE(ptr) if(ptr) {_aligned_free(ptr);ptr=NULL;} +#else + #define SCE_PFX_UTIL_ALLOC(align,size) malloc(size) + #define SCE_PFX_UTIL_REALLOC(ptr,align,size) realloc(ptr,size) + #define SCE_PFX_UTIL_FREE(ptr) if(ptr) {free(ptr);ptr=NULL;} +#endif + +#endif // _SCE_PFX_UTIL_COMMON_H diff --git a/Extras/PhysicsEffects/src/util/premake4.lua b/Extras/PhysicsEffects/src/util/premake4.lua new file mode 100644 index 000000000..483f81775 --- /dev/null +++ b/Extras/PhysicsEffects/src/util/premake4.lua @@ -0,0 +1,12 @@ + project "physicseffects2_util" + + kind "StaticLib" + targetdir "../../build/lib" + includedirs { + ".", + } + files { + "**.cpp", + "../../include/physics_effects/util/**.h" + + } \ No newline at end of file