fix: some file didn't have the svn:eol-style native yet
This commit is contained in:
@@ -1,65 +1,65 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwCopyDLL", "TwCopyDLL.vcproj", "{AB180E0E-0EFA-4AD4-8F08-4492D144D963}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwSimpleGLFW", "TwSimpleGLFW.vcproj", "{29C096AF-172E-4A36-A1FE-E15B259D6834}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963} = {AB180E0E-0EFA-4AD4-8F08-4492D144D963}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwSimpleGLUT", "TwSimpleGLUT.vcproj", "{CC6C3AFD-5DD9-498F-9184-C53E663C2ABF}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963} = {AB180E0E-0EFA-4AD4-8F08-4492D144D963}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwSimpleSDL", "TwSimpleSDL.vcproj", "{3B516919-D0DA-43CE-820E-8306368F605B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963} = {AB180E0E-0EFA-4AD4-8F08-4492D144D963}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwSimpleDX9", "TwSimpleDX9.vcproj", "{6B414E54-701C-4ED3-9034-F5CD7BFC3451}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwAdvanced1", "TwAdvanced1.vcproj", "{008D1CEC-1586-4C89-B524-DF15D9605163}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963} = {AB180E0E-0EFA-4AD4-8F08-4492D144D963}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963}.Debug.ActiveCfg = Debug|Win32
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963}.Debug.Build.0 = Debug|Win32
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963}.Release.ActiveCfg = Release|Win32
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963}.Release.Build.0 = Release|Win32
|
||||
{29C096AF-172E-4A36-A1FE-E15B259D6834}.Debug.ActiveCfg = Debug|Win32
|
||||
{29C096AF-172E-4A36-A1FE-E15B259D6834}.Debug.Build.0 = Debug|Win32
|
||||
{29C096AF-172E-4A36-A1FE-E15B259D6834}.Release.ActiveCfg = Release|Win32
|
||||
{29C096AF-172E-4A36-A1FE-E15B259D6834}.Release.Build.0 = Release|Win32
|
||||
{CC6C3AFD-5DD9-498F-9184-C53E663C2ABF}.Debug.ActiveCfg = Debug|Win32
|
||||
{CC6C3AFD-5DD9-498F-9184-C53E663C2ABF}.Debug.Build.0 = Debug|Win32
|
||||
{CC6C3AFD-5DD9-498F-9184-C53E663C2ABF}.Release.ActiveCfg = Release|Win32
|
||||
{CC6C3AFD-5DD9-498F-9184-C53E663C2ABF}.Release.Build.0 = Release|Win32
|
||||
{3B516919-D0DA-43CE-820E-8306368F605B}.Debug.ActiveCfg = Debug|Win32
|
||||
{3B516919-D0DA-43CE-820E-8306368F605B}.Debug.Build.0 = Debug|Win32
|
||||
{3B516919-D0DA-43CE-820E-8306368F605B}.Release.ActiveCfg = Release|Win32
|
||||
{3B516919-D0DA-43CE-820E-8306368F605B}.Release.Build.0 = Release|Win32
|
||||
{6B414E54-701C-4ED3-9034-F5CD7BFC3451}.Debug.ActiveCfg = Debug|Win32
|
||||
{6B414E54-701C-4ED3-9034-F5CD7BFC3451}.Debug.Build.0 = Debug|Win32
|
||||
{6B414E54-701C-4ED3-9034-F5CD7BFC3451}.Release.ActiveCfg = Release|Win32
|
||||
{6B414E54-701C-4ED3-9034-F5CD7BFC3451}.Release.Build.0 = Release|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Debug.ActiveCfg = Debug|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Debug.Build.0 = Debug|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Release.ActiveCfg = Release|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwCopyDLL", "TwCopyDLL.vcproj", "{AB180E0E-0EFA-4AD4-8F08-4492D144D963}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwSimpleGLFW", "TwSimpleGLFW.vcproj", "{29C096AF-172E-4A36-A1FE-E15B259D6834}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963} = {AB180E0E-0EFA-4AD4-8F08-4492D144D963}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwSimpleGLUT", "TwSimpleGLUT.vcproj", "{CC6C3AFD-5DD9-498F-9184-C53E663C2ABF}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963} = {AB180E0E-0EFA-4AD4-8F08-4492D144D963}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwSimpleSDL", "TwSimpleSDL.vcproj", "{3B516919-D0DA-43CE-820E-8306368F605B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963} = {AB180E0E-0EFA-4AD4-8F08-4492D144D963}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwSimpleDX9", "TwSimpleDX9.vcproj", "{6B414E54-701C-4ED3-9034-F5CD7BFC3451}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwAdvanced1", "TwAdvanced1.vcproj", "{008D1CEC-1586-4C89-B524-DF15D9605163}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963} = {AB180E0E-0EFA-4AD4-8F08-4492D144D963}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963}.Debug.ActiveCfg = Debug|Win32
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963}.Debug.Build.0 = Debug|Win32
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963}.Release.ActiveCfg = Release|Win32
|
||||
{AB180E0E-0EFA-4AD4-8F08-4492D144D963}.Release.Build.0 = Release|Win32
|
||||
{29C096AF-172E-4A36-A1FE-E15B259D6834}.Debug.ActiveCfg = Debug|Win32
|
||||
{29C096AF-172E-4A36-A1FE-E15B259D6834}.Debug.Build.0 = Debug|Win32
|
||||
{29C096AF-172E-4A36-A1FE-E15B259D6834}.Release.ActiveCfg = Release|Win32
|
||||
{29C096AF-172E-4A36-A1FE-E15B259D6834}.Release.Build.0 = Release|Win32
|
||||
{CC6C3AFD-5DD9-498F-9184-C53E663C2ABF}.Debug.ActiveCfg = Debug|Win32
|
||||
{CC6C3AFD-5DD9-498F-9184-C53E663C2ABF}.Debug.Build.0 = Debug|Win32
|
||||
{CC6C3AFD-5DD9-498F-9184-C53E663C2ABF}.Release.ActiveCfg = Release|Win32
|
||||
{CC6C3AFD-5DD9-498F-9184-C53E663C2ABF}.Release.Build.0 = Release|Win32
|
||||
{3B516919-D0DA-43CE-820E-8306368F605B}.Debug.ActiveCfg = Debug|Win32
|
||||
{3B516919-D0DA-43CE-820E-8306368F605B}.Debug.Build.0 = Debug|Win32
|
||||
{3B516919-D0DA-43CE-820E-8306368F605B}.Release.ActiveCfg = Release|Win32
|
||||
{3B516919-D0DA-43CE-820E-8306368F605B}.Release.Build.0 = Release|Win32
|
||||
{6B414E54-701C-4ED3-9034-F5CD7BFC3451}.Debug.ActiveCfg = Debug|Win32
|
||||
{6B414E54-701C-4ED3-9034-F5CD7BFC3451}.Debug.Build.0 = Debug|Win32
|
||||
{6B414E54-701C-4ED3-9034-F5CD7BFC3451}.Release.ActiveCfg = Release|Win32
|
||||
{6B414E54-701C-4ED3-9034-F5CD7BFC3451}.Release.Build.0 = Release|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Debug.ActiveCfg = Debug|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Debug.Build.0 = Debug|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Release.ActiveCfg = Release|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -1,142 +1,142 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TwAdvanced1"
|
||||
ProjectGUID="{008D1CEC-1586-4C89-B524-DF15D9605163}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="glfwdll.lib opengl32.lib glu32.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../lib/debug,../lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\glfw\lib\win32\glfw.dll xcopy /y /f c:\sdk\glfw\lib\win32\glfw.dll debug
|
||||
if exist ..\lib\AntTweakBar.dll xcopy /y /f ..\lib\AntTweakBar.dll debug
|
||||
if exist ..\lib\debug\AntTweakBar.dll xcopy /y /f ..\lib\debug\AntTweakBar.dll debug
|
||||
"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="bin"
|
||||
IntermediateDirectory="bin"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="glfwdll.lib opengl32.lib glu32.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../lib"
|
||||
GenerateDebugInformation="FALSE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\glfw\lib\win32\glfw.dll xcopy /y /f c:\sdk\glfw\lib\win32\glfw.dll bin
|
||||
if exist ..\lib\AntTweakBar.dll xcopy /y /f ..\lib\AntTweakBar.dll bin
|
||||
"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="TwAdvanced1.cpp">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TwAdvanced1"
|
||||
ProjectGUID="{008D1CEC-1586-4C89-B524-DF15D9605163}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="glfwdll.lib opengl32.lib glu32.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../lib/debug,../lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\glfw\lib\win32\glfw.dll xcopy /y /f c:\sdk\glfw\lib\win32\glfw.dll debug
|
||||
if exist ..\lib\AntTweakBar.dll xcopy /y /f ..\lib\AntTweakBar.dll debug
|
||||
if exist ..\lib\debug\AntTweakBar.dll xcopy /y /f ..\lib\debug\AntTweakBar.dll debug
|
||||
"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="bin"
|
||||
IntermediateDirectory="bin"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="glfwdll.lib opengl32.lib glu32.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../lib"
|
||||
GenerateDebugInformation="FALSE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\glfw\lib\win32\glfw.dll xcopy /y /f c:\sdk\glfw\lib\win32\glfw.dll bin
|
||||
if exist ..\lib\AntTweakBar.dll xcopy /y /f ..\lib\AntTweakBar.dll bin
|
||||
"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="TwAdvanced1.cpp">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TwCopyDLL"
|
||||
ProjectGUID="{AB180E0E-0EFA-4AD4-8F08-4492D144D963}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="10"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="if exist ..\lib\debug\AntTweakBar.dll ( xcopy /y /f ..\lib\debug\AntTweakBar.dll debug ) else ( xcopy /y /f ..\lib\AntTweakBar.dll debug )
|
||||
"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="bin"
|
||||
IntermediateDirectory="bin"
|
||||
ConfigurationType="10"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="xcopy /y /f ..\lib\AntTweakBar.dll bin"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TwCopyDLL"
|
||||
ProjectGUID="{AB180E0E-0EFA-4AD4-8F08-4492D144D963}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="10"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="if exist ..\lib\debug\AntTweakBar.dll ( xcopy /y /f ..\lib\debug\AntTweakBar.dll debug ) else ( xcopy /y /f ..\lib\AntTweakBar.dll debug )
|
||||
"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="bin"
|
||||
IntermediateDirectory="bin"
|
||||
ConfigurationType="10"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="xcopy /y /f ..\lib\AntTweakBar.dll bin"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
||||
@@ -1,138 +1,138 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TwSimpleDX9"
|
||||
ProjectGUID="{6B414E54-701C-4ED3-9034-F5CD7BFC3451}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="d3d9.lib dxerr9.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../lib/debug,../lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="bin"
|
||||
IntermediateDirectory="bin"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
||||
StringPooling="TRUE"
|
||||
ExceptionHandling="FALSE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="2"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="d3d9.lib dxerr9.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="../lib"
|
||||
GenerateDebugInformation="FALSE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="TwSimpleDX9.cpp">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TwSimpleDX9"
|
||||
ProjectGUID="{6B414E54-701C-4ED3-9034-F5CD7BFC3451}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="d3d9.lib dxerr9.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../lib/debug,../lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="bin"
|
||||
IntermediateDirectory="bin"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
||||
StringPooling="TRUE"
|
||||
ExceptionHandling="FALSE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="2"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="d3d9.lib dxerr9.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="../lib"
|
||||
GenerateDebugInformation="FALSE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="TwSimpleDX9.cpp">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
||||
@@ -1,137 +1,137 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TwSimpleGLFW"
|
||||
ProjectGUID="{29C096AF-172E-4A36-A1FE-E15B259D6834}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="glfwdll.lib opengl32.lib glu32.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../lib/debug,../lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\glfw\lib\win32\glfw.dll xcopy /y /f c:\sdk\glfw\lib\win32\glfw.dll debug"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="bin"
|
||||
IntermediateDirectory="bin"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="glfwdll.lib opengl32.lib glu32.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../lib"
|
||||
GenerateDebugInformation="FALSE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\glfw\lib\win32\glfw.dll xcopy /y /f c:\sdk\glfw\lib\win32\glfw.dll bin"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="TwSimpleGLFW.c">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TwSimpleGLFW"
|
||||
ProjectGUID="{29C096AF-172E-4A36-A1FE-E15B259D6834}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="glfwdll.lib opengl32.lib glu32.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../lib/debug,../lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\glfw\lib\win32\glfw.dll xcopy /y /f c:\sdk\glfw\lib\win32\glfw.dll debug"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="bin"
|
||||
IntermediateDirectory="bin"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="glfwdll.lib opengl32.lib glu32.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../lib"
|
||||
GenerateDebugInformation="FALSE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\glfw\lib\win32\glfw.dll xcopy /y /f c:\sdk\glfw\lib\win32\glfw.dll bin"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="TwSimpleGLFW.c">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
||||
@@ -1,141 +1,141 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TwSimpleGLUT"
|
||||
ProjectGUID="{CC6C3AFD-5DD9-498F-9184-C53E663C2ABF}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include;C:\SDK\glut"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="../lib/debug;../lib;C:\SDK\glut\lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\glut\lib\glut32.dll xcopy /y /f c:\sdk\glut\lib\glut32.dll debug"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="bin"
|
||||
IntermediateDirectory="bin"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="../include;C:\SDK\glut"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="TRUE"
|
||||
ExceptionHandling="FALSE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
DisableLanguageExtensions="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="../lib;C:\SDK\glut\lib"
|
||||
GenerateDebugInformation="FALSE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\glut\lib\glut32.dll xcopy /y /f c:\sdk\glut\lib\glut32.dll bin"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="TwSimpleGLUT.c">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TwSimpleGLUT"
|
||||
ProjectGUID="{CC6C3AFD-5DD9-498F-9184-C53E663C2ABF}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include;C:\SDK\glut"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="../lib/debug;../lib;C:\SDK\glut\lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\glut\lib\glut32.dll xcopy /y /f c:\sdk\glut\lib\glut32.dll debug"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="bin"
|
||||
IntermediateDirectory="bin"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="../include;C:\SDK\glut"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="TRUE"
|
||||
ExceptionHandling="FALSE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
DisableLanguageExtensions="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="../lib;C:\SDK\glut\lib"
|
||||
GenerateDebugInformation="FALSE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\glut\lib\glut32.dll xcopy /y /f c:\sdk\glut\lib\glut32.dll bin"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="TwSimpleGLUT.c">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
||||
@@ -1,178 +1,178 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TwSimpleSDL"
|
||||
ProjectGUID="{3B516919-D0DA-43CE-820E-8306368F605B}"
|
||||
SccProjectName=""
|
||||
SccLocalPath="">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="bin"
|
||||
IntermediateDirectory="bin"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="../include;c:/sdk/sdl/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile=""
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/vc70.pdb"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="TRUE"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
CompileAs="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
IgnoreImportLibrary="FALSE"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="SDL.lib opengl32.lib glu32.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="../lib;c:/sdk/sdl/lib"
|
||||
IgnoreAllDefaultLibraries="FALSE"
|
||||
IgnoreDefaultLibraryNames=""
|
||||
ProgramDatabaseFile=""
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName="$(OutDir)/TwTestSDL.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\sdl\lib\sdl.dll xcopy /y /f c:\sdk\sdl\lib\sdl.dll bin"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include,c:/sdk/sdl/include"
|
||||
PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile=""
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/vc70.pdb"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="TRUE"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="SDL.lib opengl32.lib glu32.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="../lib/debug;../lib;c:/sdk/sdl/lib"
|
||||
IgnoreAllDefaultLibraries="FALSE"
|
||||
IgnoreDefaultLibraryNames=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
SubSystem="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName="$(OutDir)/TwTestSDL.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\sdl\lib\sdl.dll xcopy /y /f c:\sdk\sdl\lib\sdl.dll .\debug"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="TwSimpleSDL.c">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TwSimpleSDL"
|
||||
ProjectGUID="{3B516919-D0DA-43CE-820E-8306368F605B}"
|
||||
SccProjectName=""
|
||||
SccLocalPath="">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="bin"
|
||||
IntermediateDirectory="bin"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="../include;c:/sdk/sdl/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile=""
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/vc70.pdb"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="TRUE"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
CompileAs="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
IgnoreImportLibrary="FALSE"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="SDL.lib opengl32.lib glu32.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="../lib;c:/sdk/sdl/lib"
|
||||
IgnoreAllDefaultLibraries="FALSE"
|
||||
IgnoreDefaultLibraryNames=""
|
||||
ProgramDatabaseFile=""
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName="$(OutDir)/TwTestSDL.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\sdl\lib\sdl.dll xcopy /y /f c:\sdk\sdl\lib\sdl.dll bin"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include,c:/sdk/sdl/include"
|
||||
PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile=""
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/vc70.pdb"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="TRUE"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="SDL.lib opengl32.lib glu32.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="../lib/debug;../lib;c:/sdk/sdl/lib"
|
||||
IgnoreAllDefaultLibraries="FALSE"
|
||||
IgnoreDefaultLibraryNames=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
SubSystem="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName="$(OutDir)/TwTestSDL.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist c:\sdk\sdl\lib\sdl.dll xcopy /y /f c:\sdk\sdl\lib\sdl.dll .\debug"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="TwSimpleSDL.c">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
||||
@@ -1,83 +1,83 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
//#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Fran<61>ais (France) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
|
||||
#ifdef _WIN32
|
||||
//LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Cursor
|
||||
//
|
||||
|
||||
IDC_CURSOR1 CURSOR "res\\cur00013.cur"
|
||||
IDC_CURSOR2 CURSOR "res\\cur00000.cur"
|
||||
IDC_CURSOR3 CURSOR "res\\cur00001.cur"
|
||||
IDC_CURSOR4 CURSOR "res\\cur00002.cur"
|
||||
IDC_CURSOR5 CURSOR "res\\cur00003.cur"
|
||||
IDC_CURSOR6 CURSOR "res\\cur00004.cur"
|
||||
IDC_CURSOR7 CURSOR "res\\cur00005.cur"
|
||||
IDC_CURSOR8 CURSOR "res\\cur00006.cur"
|
||||
IDC_CURSOR9 CURSOR "res\\cur00007.cur"
|
||||
IDC_CURSOR10 CURSOR "res\\cur00008.cur"
|
||||
IDC_CURSOR11 CURSOR "res\\cur00009.cur"
|
||||
IDC_CURSOR12 CURSOR "res\\cur00010.cur"
|
||||
IDC_CURSOR13 CURSOR "res\\cur00011.cur"
|
||||
IDC_CURSOR14 CURSOR "res\\cur00012.cur"
|
||||
#endif // Fran<61>ais (France) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
//#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Fran<61>ais (France) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
|
||||
#ifdef _WIN32
|
||||
//LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Cursor
|
||||
//
|
||||
|
||||
IDC_CURSOR1 CURSOR "res\\cur00013.cur"
|
||||
IDC_CURSOR2 CURSOR "res\\cur00000.cur"
|
||||
IDC_CURSOR3 CURSOR "res\\cur00001.cur"
|
||||
IDC_CURSOR4 CURSOR "res\\cur00002.cur"
|
||||
IDC_CURSOR5 CURSOR "res\\cur00003.cur"
|
||||
IDC_CURSOR6 CURSOR "res\\cur00004.cur"
|
||||
IDC_CURSOR7 CURSOR "res\\cur00005.cur"
|
||||
IDC_CURSOR8 CURSOR "res\\cur00006.cur"
|
||||
IDC_CURSOR9 CURSOR "res\\cur00007.cur"
|
||||
IDC_CURSOR10 CURSOR "res\\cur00008.cur"
|
||||
IDC_CURSOR11 CURSOR "res\\cur00009.cur"
|
||||
IDC_CURSOR12 CURSOR "res\\cur00010.cur"
|
||||
IDC_CURSOR13 CURSOR "res\\cur00011.cur"
|
||||
IDC_CURSOR14 CURSOR "res\\cur00012.cur"
|
||||
#endif // Fran<61>ais (France) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AntTweakBar", "AntTweakBar.vcproj", "{B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwAdvanced1", "..\examples\TwAdvanced1.vcproj", "{008D1CEC-1586-4C89-B524-DF15D9605163}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Debug.ActiveCfg = Debug|Win32
|
||||
{B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Debug.Build.0 = Debug|Win32
|
||||
{B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Release.ActiveCfg = Release|Win32
|
||||
{B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Release.Build.0 = Release|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Debug.ActiveCfg = Debug|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Debug.Build.0 = Debug|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Release.ActiveCfg = Release|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AntTweakBar", "AntTweakBar.vcproj", "{B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwAdvanced1", "..\examples\TwAdvanced1.vcproj", "{008D1CEC-1586-4C89-B524-DF15D9605163}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Debug.ActiveCfg = Debug|Win32
|
||||
{B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Debug.Build.0 = Debug|Win32
|
||||
{B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Release.ActiveCfg = Release|Win32
|
||||
{B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Release.Build.0 = Release|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Debug.ActiveCfg = Debug|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Debug.Build.0 = Debug|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Release.ActiveCfg = Release|Win32
|
||||
{008D1CEC-1586-4C89-B524-DF15D9605163}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -1,380 +1,380 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="AntTweakBar"
|
||||
ProjectGUID="{B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}"
|
||||
SccProjectName=""
|
||||
SccLocalPath="">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../lib"
|
||||
IntermediateDirectory=".\release"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
ImproveFloatingPointConsistency="FALSE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="../include;C:\SDK\SDL\include;C:\SDK\GLFW\include;C:\SDK\glut"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TW_EXPORTS"
|
||||
StringPooling="TRUE"
|
||||
ExceptionHandling="FALSE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
UsePrecompiledHeader="3"
|
||||
PrecompiledHeaderThrough="TwPrecomp.h"
|
||||
PrecompiledHeaderFile="$(IntDir)/AntTweakBar.pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="TRUE"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
RegisterOutput="FALSE"
|
||||
IgnoreImportLibrary="FALSE"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib"
|
||||
OutputFile="$(OutDir)/AntTweakBar.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
GenerateDebugInformation="FALSE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
MapExports="FALSE"
|
||||
SetChecksum="TRUE"
|
||||
ImportLibrary="$(OutDir)/$(TargetName).lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName="$(OutDir)/AntTweakBar.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="xcopy /y /f ..\lib\AntTweakBar.dll ..\examples\bin"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
AdditionalIncludeDirectories="res"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../lib/debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include;C:\SDK\SDL\include;C:\SDK\GLFW\include;C:\SDK\glut"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TW_EXPORTS"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="3"
|
||||
PrecompiledHeaderThrough="TwPrecomp.h"
|
||||
PrecompiledHeaderFile="$(IntDir)/AntTweakBar.pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="TRUE"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib"
|
||||
OutputFile="$(OutDir)/AntTweakBar.dll"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="TRUE"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(TargetName).lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName="$(OutDir)/AntTweakBar.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist ..\examples\debug xcopy /y /f ..\lib\debug\AntTweakBar.dll ..\examples\debug\."/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
AdditionalIncludeDirectories="res"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
|
||||
<File
|
||||
RelativePath="AntTweakBar.rc">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="LoadOGL.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwBar.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwColors.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwDirect3D9.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwEventGLFW.c">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwEventGLUT.c">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwEventSDL.c">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwEventWin32.c">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwFonts.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwMgr.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwOpenGL.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwPrecomp.cpp">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Public Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl">
|
||||
<File
|
||||
RelativePath="..\include\AntTweakBar.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Private Header Files"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="AntPerfTimer.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="LoadOGL.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="resource.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwBar.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwColors.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwDirect3D9.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwFonts.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwGraph.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwMgr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwOpenGL.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwPrecomp.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="AntTweakBar.rc">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00000.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00001.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00002.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00003.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00004.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00005.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00006.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00007.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00008.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00009.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00010.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00011.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00012.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00013.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\FontChars.txt">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\FontLargeAA.pgm">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\FontNormal.pgm">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="FontSmall.pgm">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="AntTweakBar"
|
||||
ProjectGUID="{B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}"
|
||||
SccProjectName=""
|
||||
SccLocalPath="">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../lib"
|
||||
IntermediateDirectory=".\release"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
ImproveFloatingPointConsistency="FALSE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="../include;C:\SDK\SDL\include;C:\SDK\GLFW\include;C:\SDK\glut"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TW_EXPORTS"
|
||||
StringPooling="TRUE"
|
||||
ExceptionHandling="FALSE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
UsePrecompiledHeader="3"
|
||||
PrecompiledHeaderThrough="TwPrecomp.h"
|
||||
PrecompiledHeaderFile="$(IntDir)/AntTweakBar.pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="TRUE"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
RegisterOutput="FALSE"
|
||||
IgnoreImportLibrary="FALSE"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib"
|
||||
OutputFile="$(OutDir)/AntTweakBar.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
GenerateDebugInformation="FALSE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
MapExports="FALSE"
|
||||
SetChecksum="TRUE"
|
||||
ImportLibrary="$(OutDir)/$(TargetName).lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName="$(OutDir)/AntTweakBar.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="xcopy /y /f ..\lib\AntTweakBar.dll ..\examples\bin"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
AdditionalIncludeDirectories="res"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../lib/debug"
|
||||
IntermediateDirectory="debug"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include;C:\SDK\SDL\include;C:\SDK\GLFW\include;C:\SDK\glut"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TW_EXPORTS"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="3"
|
||||
PrecompiledHeaderThrough="TwPrecomp.h"
|
||||
PrecompiledHeaderFile="$(IntDir)/AntTweakBar.pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="TRUE"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib"
|
||||
OutputFile="$(OutDir)/AntTweakBar.dll"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="TRUE"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(TargetName).lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName="$(OutDir)/AntTweakBar.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="if exist ..\examples\debug xcopy /y /f ..\lib\debug\AntTweakBar.dll ..\examples\debug\."/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
AdditionalIncludeDirectories="res"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
|
||||
<File
|
||||
RelativePath="AntTweakBar.rc">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="LoadOGL.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwBar.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwColors.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwDirect3D9.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwEventGLFW.c">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwEventGLUT.c">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwEventSDL.c">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwEventWin32.c">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwFonts.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwMgr.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwOpenGL.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwPrecomp.cpp">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Public Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl">
|
||||
<File
|
||||
RelativePath="..\include\AntTweakBar.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Private Header Files"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="AntPerfTimer.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="LoadOGL.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="resource.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwBar.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwColors.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwDirect3D9.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwFonts.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwGraph.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwMgr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwOpenGL.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="TwPrecomp.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="AntTweakBar.rc">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00000.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00001.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00002.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00003.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00004.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00005.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00006.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00007.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00008.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00009.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00010.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00011.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00012.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\cur00013.cur">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\FontChars.txt">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\FontLargeAA.pgm">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="res\FontNormal.pgm">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="FontSmall.pgm">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
||||
@@ -1,232 +1,232 @@
|
||||
!"#$%&'()*+,-./0123456789:;<=>?
|
||||
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
||||
`abcdefghijklmnopqrstuvwxyz{|}~
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
032
|
||||
033 !
|
||||
034 "
|
||||
035 #
|
||||
036 $
|
||||
037 %
|
||||
038 &
|
||||
039 '
|
||||
040 (
|
||||
041 )
|
||||
042 *
|
||||
043 +
|
||||
044 ,
|
||||
045 -
|
||||
046 .
|
||||
047 /
|
||||
048 0
|
||||
049 1
|
||||
050 2
|
||||
051 3
|
||||
052 4
|
||||
053 5
|
||||
054 6
|
||||
055 7
|
||||
056 8
|
||||
057 9
|
||||
058 :
|
||||
059 ;
|
||||
060 <
|
||||
061 =
|
||||
062 >
|
||||
063 ?
|
||||
064 @
|
||||
065 A
|
||||
066 B
|
||||
067 C
|
||||
068 D
|
||||
069 E
|
||||
070 F
|
||||
071 G
|
||||
072 H
|
||||
073 I
|
||||
074 J
|
||||
075 K
|
||||
076 L
|
||||
077 M
|
||||
078 N
|
||||
079 O
|
||||
080 P
|
||||
081 Q
|
||||
082 R
|
||||
083 S
|
||||
084 T
|
||||
085 U
|
||||
086 V
|
||||
087 W
|
||||
088 X
|
||||
089 Y
|
||||
090 Z
|
||||
091 [
|
||||
092 \
|
||||
093 ]
|
||||
094 ^
|
||||
095 _
|
||||
096 `
|
||||
097 a
|
||||
098 b
|
||||
099 c
|
||||
100 d
|
||||
101 e
|
||||
102 f
|
||||
103 g
|
||||
104 h
|
||||
105 i
|
||||
106 j
|
||||
107 k
|
||||
108 l
|
||||
109 m
|
||||
110 n
|
||||
111 o
|
||||
112 p
|
||||
113 q
|
||||
114 r
|
||||
115 s
|
||||
116 t
|
||||
117 u
|
||||
118 v
|
||||
119 w
|
||||
120 x
|
||||
121 y
|
||||
122 z
|
||||
123 {
|
||||
124 |
|
||||
125 }
|
||||
126 ~
|
||||
127
|
||||
128 <20>
|
||||
129 <20>
|
||||
130 <20>
|
||||
131 <20>
|
||||
132 <20>
|
||||
133 <20>
|
||||
134 <20>
|
||||
135 <20>
|
||||
136 <20>
|
||||
137 <20>
|
||||
138 <20>
|
||||
139 <20>
|
||||
140 <20>
|
||||
141 <20>
|
||||
142 <20>
|
||||
143 <20>
|
||||
144 <20>
|
||||
145 <20>
|
||||
146 <20>
|
||||
147 <20>
|
||||
148 <20>
|
||||
149 <20>
|
||||
150 <20>
|
||||
151 <20>
|
||||
152 <20>
|
||||
153 <20>
|
||||
154 <20>
|
||||
155 <20>
|
||||
156 <20>
|
||||
157 <20>
|
||||
158 <20>
|
||||
159 <20>
|
||||
160 <20>
|
||||
161 <20>
|
||||
162 <20>
|
||||
163 <20>
|
||||
164 <20>
|
||||
165 <20>
|
||||
166 <20>
|
||||
167 <20>
|
||||
168 <20>
|
||||
169 <20>
|
||||
170 <20>
|
||||
171 <20>
|
||||
172 <20>
|
||||
173 <20>
|
||||
174 <20>
|
||||
175 <20>
|
||||
176 <20>
|
||||
177 <20>
|
||||
178 <20>
|
||||
179 <20>
|
||||
180 <20>
|
||||
181 <20>
|
||||
182 <20>
|
||||
183 <20>
|
||||
184 <20>
|
||||
185 <20>
|
||||
186 <20>
|
||||
187 <20>
|
||||
188 <20>
|
||||
189 <20>
|
||||
190 <20>
|
||||
191 <20>
|
||||
192 <20>
|
||||
193 <20>
|
||||
194 <20>
|
||||
195 <20>
|
||||
196 <20>
|
||||
197 <20>
|
||||
198 <20>
|
||||
199 <20>
|
||||
200 <20>
|
||||
201 <20>
|
||||
202 <20>
|
||||
203 <20>
|
||||
204 <20>
|
||||
205 <20>
|
||||
206 <20>
|
||||
207 <20>
|
||||
208 <20>
|
||||
209 <20>
|
||||
210 <20>
|
||||
211 <20>
|
||||
212 <20>
|
||||
213 <20>
|
||||
214 <20>
|
||||
215 <20>
|
||||
216 <20>
|
||||
217 <20>
|
||||
218 <20>
|
||||
219 <20>
|
||||
220 <20>
|
||||
221 <20>
|
||||
222 <20>
|
||||
223 <20>
|
||||
224 <20>
|
||||
225 <20>
|
||||
226 <20>
|
||||
227 <20>
|
||||
228 <20>
|
||||
229 <20>
|
||||
230 <20>
|
||||
231 <20>
|
||||
232 <20>
|
||||
233 <20>
|
||||
234 <20>
|
||||
235 <20>
|
||||
236 <20>
|
||||
237 <20>
|
||||
238 <20>
|
||||
239 <20>
|
||||
240 <20>
|
||||
241 <20>
|
||||
242 <20>
|
||||
243 <20>
|
||||
244 <20>
|
||||
245 <20>
|
||||
246 <20>
|
||||
247 <20>
|
||||
248 <20>
|
||||
249 <20>
|
||||
250 <20>
|
||||
251 <20>
|
||||
252 <20>
|
||||
253 <20>
|
||||
254 <20>
|
||||
!"#$%&'()*+,-./0123456789:;<=>?
|
||||
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
||||
`abcdefghijklmnopqrstuvwxyz{|}~
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
032
|
||||
033 !
|
||||
034 "
|
||||
035 #
|
||||
036 $
|
||||
037 %
|
||||
038 &
|
||||
039 '
|
||||
040 (
|
||||
041 )
|
||||
042 *
|
||||
043 +
|
||||
044 ,
|
||||
045 -
|
||||
046 .
|
||||
047 /
|
||||
048 0
|
||||
049 1
|
||||
050 2
|
||||
051 3
|
||||
052 4
|
||||
053 5
|
||||
054 6
|
||||
055 7
|
||||
056 8
|
||||
057 9
|
||||
058 :
|
||||
059 ;
|
||||
060 <
|
||||
061 =
|
||||
062 >
|
||||
063 ?
|
||||
064 @
|
||||
065 A
|
||||
066 B
|
||||
067 C
|
||||
068 D
|
||||
069 E
|
||||
070 F
|
||||
071 G
|
||||
072 H
|
||||
073 I
|
||||
074 J
|
||||
075 K
|
||||
076 L
|
||||
077 M
|
||||
078 N
|
||||
079 O
|
||||
080 P
|
||||
081 Q
|
||||
082 R
|
||||
083 S
|
||||
084 T
|
||||
085 U
|
||||
086 V
|
||||
087 W
|
||||
088 X
|
||||
089 Y
|
||||
090 Z
|
||||
091 [
|
||||
092 \
|
||||
093 ]
|
||||
094 ^
|
||||
095 _
|
||||
096 `
|
||||
097 a
|
||||
098 b
|
||||
099 c
|
||||
100 d
|
||||
101 e
|
||||
102 f
|
||||
103 g
|
||||
104 h
|
||||
105 i
|
||||
106 j
|
||||
107 k
|
||||
108 l
|
||||
109 m
|
||||
110 n
|
||||
111 o
|
||||
112 p
|
||||
113 q
|
||||
114 r
|
||||
115 s
|
||||
116 t
|
||||
117 u
|
||||
118 v
|
||||
119 w
|
||||
120 x
|
||||
121 y
|
||||
122 z
|
||||
123 {
|
||||
124 |
|
||||
125 }
|
||||
126 ~
|
||||
127
|
||||
128 <20>
|
||||
129 <20>
|
||||
130 <20>
|
||||
131 <20>
|
||||
132 <20>
|
||||
133 <20>
|
||||
134 <20>
|
||||
135 <20>
|
||||
136 <20>
|
||||
137 <20>
|
||||
138 <20>
|
||||
139 <20>
|
||||
140 <20>
|
||||
141 <20>
|
||||
142 <20>
|
||||
143 <20>
|
||||
144 <20>
|
||||
145 <20>
|
||||
146 <20>
|
||||
147 <20>
|
||||
148 <20>
|
||||
149 <20>
|
||||
150 <20>
|
||||
151 <20>
|
||||
152 <20>
|
||||
153 <20>
|
||||
154 <20>
|
||||
155 <20>
|
||||
156 <20>
|
||||
157 <20>
|
||||
158 <20>
|
||||
159 <20>
|
||||
160 <20>
|
||||
161 <20>
|
||||
162 <20>
|
||||
163 <20>
|
||||
164 <20>
|
||||
165 <20>
|
||||
166 <20>
|
||||
167 <20>
|
||||
168 <20>
|
||||
169 <20>
|
||||
170 <20>
|
||||
171 <20>
|
||||
172 <20>
|
||||
173 <20>
|
||||
174 <20>
|
||||
175 <20>
|
||||
176 <20>
|
||||
177 <20>
|
||||
178 <20>
|
||||
179 <20>
|
||||
180 <20>
|
||||
181 <20>
|
||||
182 <20>
|
||||
183 <20>
|
||||
184 <20>
|
||||
185 <20>
|
||||
186 <20>
|
||||
187 <20>
|
||||
188 <20>
|
||||
189 <20>
|
||||
190 <20>
|
||||
191 <20>
|
||||
192 <20>
|
||||
193 <20>
|
||||
194 <20>
|
||||
195 <20>
|
||||
196 <20>
|
||||
197 <20>
|
||||
198 <20>
|
||||
199 <20>
|
||||
200 <20>
|
||||
201 <20>
|
||||
202 <20>
|
||||
203 <20>
|
||||
204 <20>
|
||||
205 <20>
|
||||
206 <20>
|
||||
207 <20>
|
||||
208 <20>
|
||||
209 <20>
|
||||
210 <20>
|
||||
211 <20>
|
||||
212 <20>
|
||||
213 <20>
|
||||
214 <20>
|
||||
215 <20>
|
||||
216 <20>
|
||||
217 <20>
|
||||
218 <20>
|
||||
219 <20>
|
||||
220 <20>
|
||||
221 <20>
|
||||
222 <20>
|
||||
223 <20>
|
||||
224 <20>
|
||||
225 <20>
|
||||
226 <20>
|
||||
227 <20>
|
||||
228 <20>
|
||||
229 <20>
|
||||
230 <20>
|
||||
231 <20>
|
||||
232 <20>
|
||||
233 <20>
|
||||
234 <20>
|
||||
235 <20>
|
||||
236 <20>
|
||||
237 <20>
|
||||
238 <20>
|
||||
239 <20>
|
||||
240 <20>
|
||||
241 <20>
|
||||
242 <20>
|
||||
243 <20>
|
||||
244 <20>
|
||||
245 <20>
|
||||
246 <20>
|
||||
247 <20>
|
||||
248 <20>
|
||||
249 <20>
|
||||
250 <20>
|
||||
251 <20>
|
||||
252 <20>
|
||||
253 <20>
|
||||
254 <20>
|
||||
255 <20>
|
||||
@@ -1,165 +1,165 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "BipartiteBoxPruning.h"
|
||||
#include "RenderingHelpers.h"
|
||||
#include "GLFontRenderer.h"
|
||||
|
||||
BipartiteBoxPruningTest::BipartiteBoxPruningTest() :
|
||||
mBar (null),
|
||||
mNbBoxes (0),
|
||||
mBoxes (null),
|
||||
mBoxPtrs (null),
|
||||
mBoxTime (null),
|
||||
mSpeed (0.0f),
|
||||
mAmplitude (100.0f)
|
||||
{
|
||||
}
|
||||
|
||||
BipartiteBoxPruningTest::~BipartiteBoxPruningTest()
|
||||
{
|
||||
DELETEARRAY(mBoxTime);
|
||||
DELETEARRAY(mBoxPtrs);
|
||||
DELETEARRAY(mBoxes);
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::Init()
|
||||
{
|
||||
mNbBoxes = 1024;
|
||||
mBoxes = new AABB[mNbBoxes];
|
||||
mBoxPtrs = new const AABB*[mNbBoxes];
|
||||
mBoxTime = new float[mNbBoxes];
|
||||
for(udword i=0;i<mNbBoxes;i++)
|
||||
{
|
||||
Point Center, Extents;
|
||||
|
||||
Center.x = (UnitRandomFloat()-0.5f) * 100.0f;
|
||||
Center.y = (UnitRandomFloat()-0.5f) * 10.0f;
|
||||
Center.z = (UnitRandomFloat()-0.5f) * 100.0f;
|
||||
Extents.x = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
Extents.y = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
Extents.z = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
|
||||
mBoxes[i].SetCenterExtents(Center, Extents);
|
||||
mBoxPtrs[i] = &mBoxes[i];
|
||||
|
||||
mBoxTime[i] = 2000.0f*UnitRandomFloat();
|
||||
}
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::Release()
|
||||
{
|
||||
DELETEARRAY(mBoxTime);
|
||||
DELETEARRAY(mBoxes);
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::Select()
|
||||
{
|
||||
// Create a tweak bar
|
||||
{
|
||||
mBar = TwNewBar("BipartiteBoxPruning");
|
||||
TwAddVarRW(mBar, "Speed", TW_TYPE_FLOAT, &mSpeed, " min=0.0 max=0.01 step=0.00001");
|
||||
TwAddVarRW(mBar, "Amplitude", TW_TYPE_FLOAT, &mAmplitude, " min=10.0 max=200.0 step=0.1");
|
||||
}
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::Deselect()
|
||||
{
|
||||
if(mBar)
|
||||
{
|
||||
TwDeleteBar(mBar);
|
||||
mBar = null;
|
||||
}
|
||||
}
|
||||
|
||||
bool BipartiteBoxPruningTest::UpdateBoxes()
|
||||
{
|
||||
for(udword i=0;i<mNbBoxes;i++)
|
||||
{
|
||||
mBoxTime[i] += mSpeed;
|
||||
|
||||
Point Center,Extents;
|
||||
mBoxes[i].GetExtents(Extents);
|
||||
|
||||
Center.x = cosf(mBoxTime[i]*2.17f)*mAmplitude + sinf(mBoxTime[i])*mAmplitude*0.5f;
|
||||
Center.y = cosf(mBoxTime[i]*1.38f)*mAmplitude + sinf(mBoxTime[i]*mAmplitude);
|
||||
Center.z = sinf(mBoxTime[i]*0.777f)*mAmplitude;
|
||||
|
||||
mBoxes[i].SetCenterExtents(Center, Extents);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::PerformTest()
|
||||
{
|
||||
UpdateBoxes();
|
||||
|
||||
// We pretend that half the boxes belong to first group, and the other half to the second group.
|
||||
udword Nb0 = mNbBoxes/2;
|
||||
udword Nb1 = mNbBoxes - Nb0;
|
||||
|
||||
mPairs.ResetPairs();
|
||||
mProfiler.Start();
|
||||
BipartiteBoxPruning(Nb0, mBoxPtrs, Nb1, mBoxPtrs+Nb0, mPairs, Axes(AXES_XZY));
|
||||
mProfiler.End();
|
||||
mProfiler.Accum();
|
||||
|
||||
// printf("%d pairs colliding\r ", mPairs.GetNbPairs());
|
||||
|
||||
bool* Flags = (bool*)_alloca(sizeof(bool)*mNbBoxes);
|
||||
ZeroMemory(Flags, sizeof(bool)*mNbBoxes);
|
||||
const Pair* P = mPairs.GetPairs();
|
||||
for(udword i=0;i<mPairs.GetNbPairs();i++)
|
||||
{
|
||||
// A colliding pair is (i,j) where 0 <= i < Nb0 and 0 <= j < Nb1
|
||||
Flags[P[i].id0] = true;
|
||||
Flags[P[i].id1+Nb0] = true;
|
||||
}
|
||||
|
||||
// Render boxes
|
||||
OBB CurrentBox;
|
||||
CurrentBox.mRot.Identity();
|
||||
for(udword i=0;i<mNbBoxes;i++)
|
||||
{
|
||||
if(Flags[i]) glColor3f(1.0f, 0.0f, 0.0f);
|
||||
else
|
||||
{
|
||||
if(i<Nb0)
|
||||
glColor3f(0.0f, 1.0f, 0.0f);
|
||||
else
|
||||
glColor3f(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
mBoxes[i].GetCenter(CurrentBox.mCenter);
|
||||
mBoxes[i].GetExtents(CurrentBox.mExtents);
|
||||
DrawOBB(CurrentBox);
|
||||
}
|
||||
|
||||
char Buffer[4096];
|
||||
sprintf(Buffer, "BipartiteBoxPruning - %5.1f us (%d cycles) - %d pairs\n", mProfiler.mMsTime, mProfiler.mCycles, mPairs.GetNbPairs());
|
||||
GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer);
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::KeyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::MouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::MotionCallback(int x, int y)
|
||||
{
|
||||
}
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "BipartiteBoxPruning.h"
|
||||
#include "RenderingHelpers.h"
|
||||
#include "GLFontRenderer.h"
|
||||
|
||||
BipartiteBoxPruningTest::BipartiteBoxPruningTest() :
|
||||
mBar (null),
|
||||
mNbBoxes (0),
|
||||
mBoxes (null),
|
||||
mBoxPtrs (null),
|
||||
mBoxTime (null),
|
||||
mSpeed (0.0f),
|
||||
mAmplitude (100.0f)
|
||||
{
|
||||
}
|
||||
|
||||
BipartiteBoxPruningTest::~BipartiteBoxPruningTest()
|
||||
{
|
||||
DELETEARRAY(mBoxTime);
|
||||
DELETEARRAY(mBoxPtrs);
|
||||
DELETEARRAY(mBoxes);
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::Init()
|
||||
{
|
||||
mNbBoxes = 1024;
|
||||
mBoxes = new AABB[mNbBoxes];
|
||||
mBoxPtrs = new const AABB*[mNbBoxes];
|
||||
mBoxTime = new float[mNbBoxes];
|
||||
for(udword i=0;i<mNbBoxes;i++)
|
||||
{
|
||||
Point Center, Extents;
|
||||
|
||||
Center.x = (UnitRandomFloat()-0.5f) * 100.0f;
|
||||
Center.y = (UnitRandomFloat()-0.5f) * 10.0f;
|
||||
Center.z = (UnitRandomFloat()-0.5f) * 100.0f;
|
||||
Extents.x = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
Extents.y = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
Extents.z = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
|
||||
mBoxes[i].SetCenterExtents(Center, Extents);
|
||||
mBoxPtrs[i] = &mBoxes[i];
|
||||
|
||||
mBoxTime[i] = 2000.0f*UnitRandomFloat();
|
||||
}
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::Release()
|
||||
{
|
||||
DELETEARRAY(mBoxTime);
|
||||
DELETEARRAY(mBoxes);
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::Select()
|
||||
{
|
||||
// Create a tweak bar
|
||||
{
|
||||
mBar = TwNewBar("BipartiteBoxPruning");
|
||||
TwAddVarRW(mBar, "Speed", TW_TYPE_FLOAT, &mSpeed, " min=0.0 max=0.01 step=0.00001");
|
||||
TwAddVarRW(mBar, "Amplitude", TW_TYPE_FLOAT, &mAmplitude, " min=10.0 max=200.0 step=0.1");
|
||||
}
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::Deselect()
|
||||
{
|
||||
if(mBar)
|
||||
{
|
||||
TwDeleteBar(mBar);
|
||||
mBar = null;
|
||||
}
|
||||
}
|
||||
|
||||
bool BipartiteBoxPruningTest::UpdateBoxes()
|
||||
{
|
||||
for(udword i=0;i<mNbBoxes;i++)
|
||||
{
|
||||
mBoxTime[i] += mSpeed;
|
||||
|
||||
Point Center,Extents;
|
||||
mBoxes[i].GetExtents(Extents);
|
||||
|
||||
Center.x = cosf(mBoxTime[i]*2.17f)*mAmplitude + sinf(mBoxTime[i])*mAmplitude*0.5f;
|
||||
Center.y = cosf(mBoxTime[i]*1.38f)*mAmplitude + sinf(mBoxTime[i]*mAmplitude);
|
||||
Center.z = sinf(mBoxTime[i]*0.777f)*mAmplitude;
|
||||
|
||||
mBoxes[i].SetCenterExtents(Center, Extents);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::PerformTest()
|
||||
{
|
||||
UpdateBoxes();
|
||||
|
||||
// We pretend that half the boxes belong to first group, and the other half to the second group.
|
||||
udword Nb0 = mNbBoxes/2;
|
||||
udword Nb1 = mNbBoxes - Nb0;
|
||||
|
||||
mPairs.ResetPairs();
|
||||
mProfiler.Start();
|
||||
BipartiteBoxPruning(Nb0, mBoxPtrs, Nb1, mBoxPtrs+Nb0, mPairs, Axes(AXES_XZY));
|
||||
mProfiler.End();
|
||||
mProfiler.Accum();
|
||||
|
||||
// printf("%d pairs colliding\r ", mPairs.GetNbPairs());
|
||||
|
||||
bool* Flags = (bool*)_alloca(sizeof(bool)*mNbBoxes);
|
||||
ZeroMemory(Flags, sizeof(bool)*mNbBoxes);
|
||||
const Pair* P = mPairs.GetPairs();
|
||||
for(udword i=0;i<mPairs.GetNbPairs();i++)
|
||||
{
|
||||
// A colliding pair is (i,j) where 0 <= i < Nb0 and 0 <= j < Nb1
|
||||
Flags[P[i].id0] = true;
|
||||
Flags[P[i].id1+Nb0] = true;
|
||||
}
|
||||
|
||||
// Render boxes
|
||||
OBB CurrentBox;
|
||||
CurrentBox.mRot.Identity();
|
||||
for(udword i=0;i<mNbBoxes;i++)
|
||||
{
|
||||
if(Flags[i]) glColor3f(1.0f, 0.0f, 0.0f);
|
||||
else
|
||||
{
|
||||
if(i<Nb0)
|
||||
glColor3f(0.0f, 1.0f, 0.0f);
|
||||
else
|
||||
glColor3f(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
mBoxes[i].GetCenter(CurrentBox.mCenter);
|
||||
mBoxes[i].GetExtents(CurrentBox.mExtents);
|
||||
DrawOBB(CurrentBox);
|
||||
}
|
||||
|
||||
char Buffer[4096];
|
||||
sprintf(Buffer, "BipartiteBoxPruning - %5.1f us (%d cycles) - %d pairs\n", mProfiler.mMsTime, mProfiler.mCycles, mPairs.GetNbPairs());
|
||||
GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer);
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::KeyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::MouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void BipartiteBoxPruningTest::MotionCallback(int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 BIPARTITEBOXPRUNING_H
|
||||
#define BIPARTITEBOXPRUNING_H
|
||||
|
||||
#include "CollisionTest.h"
|
||||
#include "Profiling.h"
|
||||
|
||||
class BipartiteBoxPruningTest : public CollisionTest
|
||||
{
|
||||
public:
|
||||
BipartiteBoxPruningTest();
|
||||
virtual ~BipartiteBoxPruningTest();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Release();
|
||||
virtual void PerformTest();
|
||||
virtual void Select();
|
||||
virtual void Deselect();
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y);
|
||||
virtual void MouseCallback(int button, int state, int x, int y);
|
||||
virtual void MotionCallback(int x, int y);
|
||||
|
||||
TwBar* mBar; //!< AntTweakBar
|
||||
Profiler mProfiler;
|
||||
|
||||
udword mNbBoxes;
|
||||
AABB* mBoxes;
|
||||
const AABB** mBoxPtrs;
|
||||
Pairs mPairs;
|
||||
float* mBoxTime;
|
||||
float mSpeed;
|
||||
float mAmplitude;
|
||||
private:
|
||||
bool UpdateBoxes();
|
||||
};
|
||||
|
||||
#endif // BIPARTITEBOXPRUNING_H
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 BIPARTITEBOXPRUNING_H
|
||||
#define BIPARTITEBOXPRUNING_H
|
||||
|
||||
#include "CollisionTest.h"
|
||||
#include "Profiling.h"
|
||||
|
||||
class BipartiteBoxPruningTest : public CollisionTest
|
||||
{
|
||||
public:
|
||||
BipartiteBoxPruningTest();
|
||||
virtual ~BipartiteBoxPruningTest();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Release();
|
||||
virtual void PerformTest();
|
||||
virtual void Select();
|
||||
virtual void Deselect();
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y);
|
||||
virtual void MouseCallback(int button, int state, int x, int y);
|
||||
virtual void MotionCallback(int x, int y);
|
||||
|
||||
TwBar* mBar; //!< AntTweakBar
|
||||
Profiler mProfiler;
|
||||
|
||||
udword mNbBoxes;
|
||||
AABB* mBoxes;
|
||||
const AABB** mBoxPtrs;
|
||||
Pairs mPairs;
|
||||
float* mBoxTime;
|
||||
float mSpeed;
|
||||
float mAmplitude;
|
||||
private:
|
||||
bool UpdateBoxes();
|
||||
};
|
||||
|
||||
#endif // BIPARTITEBOXPRUNING_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,65 +1,65 @@
|
||||
/*
|
||||
BulletSAPCompleteBoxPruningTest, Copyright (c) 2008 Erwin Coumans
|
||||
Part of:
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 BULLET_SAP_COMPLETEBOXPRUNING_H
|
||||
#define BULLET_SAP_COMPLETEBOXPRUNING_H
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
#include "CollisionTest.h"
|
||||
#include "Profiling.h"
|
||||
|
||||
class BulletSAPCompleteBoxPruningTest : public CollisionTest
|
||||
{
|
||||
public:
|
||||
BulletSAPCompleteBoxPruningTest(int numBoxes,int method);
|
||||
virtual ~BulletSAPCompleteBoxPruningTest();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Release();
|
||||
virtual void PerformTest();
|
||||
void RenderAll();
|
||||
void Render();
|
||||
virtual void Select();
|
||||
virtual void Deselect();
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y);
|
||||
virtual void MouseCallback(int button, int state, int x, int y);
|
||||
virtual void MotionCallback(int x, int y);
|
||||
|
||||
TwBar* mBar; //!< AntTweakBar
|
||||
Profiler mProfiler;
|
||||
|
||||
class btBroadphaseInterface* m_broadphase;
|
||||
bool m_isdbvt;
|
||||
btAlignedObjectArray<struct btBroadphaseProxy*> m_proxies;
|
||||
|
||||
udword mNbBoxes;
|
||||
AABB* mBoxes;
|
||||
bool* mFlags;
|
||||
const char* methodname;
|
||||
const AABB** mBoxPtrs;
|
||||
Pairs mPairs;
|
||||
float* mBoxTime;
|
||||
float mAmplitude;
|
||||
bool m_firstTime;
|
||||
int m_method;
|
||||
|
||||
private:
|
||||
bool UpdateBoxes(int numBoxes);
|
||||
};
|
||||
|
||||
#endif // BULLET_SAP_COMPLETEBOXPRUNING_H
|
||||
/*
|
||||
BulletSAPCompleteBoxPruningTest, Copyright (c) 2008 Erwin Coumans
|
||||
Part of:
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 BULLET_SAP_COMPLETEBOXPRUNING_H
|
||||
#define BULLET_SAP_COMPLETEBOXPRUNING_H
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
#include "CollisionTest.h"
|
||||
#include "Profiling.h"
|
||||
|
||||
class BulletSAPCompleteBoxPruningTest : public CollisionTest
|
||||
{
|
||||
public:
|
||||
BulletSAPCompleteBoxPruningTest(int numBoxes,int method);
|
||||
virtual ~BulletSAPCompleteBoxPruningTest();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Release();
|
||||
virtual void PerformTest();
|
||||
void RenderAll();
|
||||
void Render();
|
||||
virtual void Select();
|
||||
virtual void Deselect();
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y);
|
||||
virtual void MouseCallback(int button, int state, int x, int y);
|
||||
virtual void MotionCallback(int x, int y);
|
||||
|
||||
TwBar* mBar; //!< AntTweakBar
|
||||
Profiler mProfiler;
|
||||
|
||||
class btBroadphaseInterface* m_broadphase;
|
||||
bool m_isdbvt;
|
||||
btAlignedObjectArray<struct btBroadphaseProxy*> m_proxies;
|
||||
|
||||
udword mNbBoxes;
|
||||
AABB* mBoxes;
|
||||
bool* mFlags;
|
||||
const char* methodname;
|
||||
const AABB** mBoxPtrs;
|
||||
Pairs mPairs;
|
||||
float* mBoxTime;
|
||||
float mAmplitude;
|
||||
bool m_firstTime;
|
||||
int m_method;
|
||||
|
||||
private:
|
||||
bool UpdateBoxes(int numBoxes);
|
||||
};
|
||||
|
||||
#endif // BULLET_SAP_COMPLETEBOXPRUNING_H
|
||||
|
||||
@@ -1,444 +1,444 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "CollisionTest.h"
|
||||
#include "SphereMeshQuery.h"
|
||||
#include "OBBMeshQuery.h"
|
||||
#include "CapsuleMeshQuery.h"
|
||||
#include "CompleteBoxPruning.h"
|
||||
#include "BulletSAPCompleteBoxPruningTest.h"
|
||||
#include "BulletSAPCompleteBoxPruningTest.h"
|
||||
#include "BipartiteBoxPruning.h"
|
||||
#include "OpcodeArraySAPTest.h"
|
||||
#include "RenderingHelpers.h"
|
||||
#include "Terrain.h"
|
||||
#include "Camera.h"
|
||||
#include "GLFontRenderer.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.h"
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
|
||||
#define NUM_SAP_BOXES 8192
|
||||
//#define NUM_SAP_BOXES 16384
|
||||
//#define NUM_SAP_BOXES 1024
|
||||
|
||||
int percentUpdate = 100;
|
||||
//float objectSpeed = 0.005f;
|
||||
float objectSpeed = 0.01f;
|
||||
bool enableDraw = true;
|
||||
|
||||
//Broadphase comparison
|
||||
//Static case (updating 10% of objects to same position ( -> no swaps)
|
||||
//number of objects //OPCODE BoxPruning / Bullet SAP / Bullet MultiSAP
|
||||
//1024 0.35ms, 0.03ms, 0.15ms
|
||||
//8192 21ms, 0.2ms, 5ms
|
||||
//16384 92ms , 0.5ms, 28ms
|
||||
|
||||
//Dynamic case, 10% objects are moving as fast as this testbed allows (0.01?)
|
||||
//number of objects //OPCODE BoxPruning / Bullet SAP / Bullet MultiSAP
|
||||
//1024 0.35ms, 0.2ms, 0.25ms
|
||||
//8192 21ms , 15ms , 13ms
|
||||
//16384 92ms, 80ms, 49ms
|
||||
|
||||
|
||||
#define WINDOW_WIDTH 1024
|
||||
#define WINDOW_HEIGHT 768
|
||||
|
||||
static int gMouseX = 0;
|
||||
static int gMouseY = 0;
|
||||
static int gButton = 0;
|
||||
|
||||
static TwBar* gMainBar = null;
|
||||
enum TestIndex
|
||||
{
|
||||
// TEST_SPHERE_MESH_QUERY,
|
||||
// TEST_OBB_MESH_QUERY,
|
||||
// TEST_CAPSULE_MESH_QUERY,
|
||||
// TEST_COMPLETE_BOX_PRUNING=0,
|
||||
TEST_COMPLETE_BOX_PRUNING_8192,
|
||||
// TEST_BULLET_SAP_1024,
|
||||
// TEST_BULLET_SAP_8192,
|
||||
// TEST_BULLET_SAP_SORTEDPAIRS_8192,
|
||||
// TEST_BULLET_MULTISAP_8192,
|
||||
// TEST_BIPARTITE_BOX_PRUNING,
|
||||
TEST_DBVT_8192,
|
||||
TEST_BULLET_CUDA_8192,
|
||||
TEST_BULLET_3DGRID_8192,
|
||||
TEST_OPCODE_ARRAY_SAP,
|
||||
MAX_NB_TESTS
|
||||
};
|
||||
|
||||
//static int gTest = TEST_DBVT_8192;//TEST_BULLET_MULTISAP_8192;
|
||||
//static int gSelectedTest = TEST_DBVT_8192;//TEST_BULLET_MULTISAP_8192;
|
||||
static int gTest = TEST_BULLET_CUDA_8192;
|
||||
static int gSelectedTest = TEST_BULLET_CUDA_8192;
|
||||
static CollisionTest* gCollisionTests[MAX_NB_TESTS];
|
||||
|
||||
static GLFontRenderer gFnt;
|
||||
|
||||
/////////////////
|
||||
|
||||
static void KeyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 27: exit(0); break;
|
||||
|
||||
case '+':
|
||||
{
|
||||
if(gTest!=MAX_NB_TESTS-1)
|
||||
{
|
||||
gCollisionTests[gTest]->Deselect();
|
||||
gTest++;
|
||||
gSelectedTest++;
|
||||
gCollisionTests[gTest]->Select();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '-':
|
||||
{
|
||||
if(gTest)
|
||||
{
|
||||
gCollisionTests[gTest]->Deselect();
|
||||
gTest--;
|
||||
gSelectedTest--;
|
||||
gCollisionTests[gTest]->Select();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 101: MoveCameraForward(); break;
|
||||
case 103: MoveCameraBackward(); break;
|
||||
case 100: MoveCameraRight(); break;
|
||||
case 102: MoveCameraLeft(); break;
|
||||
default: gCollisionTests[gTest]->KeyboardCallback(key, x, y); break;
|
||||
}
|
||||
|
||||
TwEventKeyboardGLUT(key, x, y);
|
||||
}
|
||||
|
||||
static void ArrowKeyCallback(int key, int x, int y)
|
||||
{
|
||||
KeyboardCallback(key, x, y);
|
||||
|
||||
TwEventSpecialGLUT(key, x, y);
|
||||
}
|
||||
|
||||
static void MouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
gButton = button;
|
||||
gMouseX = x;
|
||||
gMouseY = y;
|
||||
|
||||
if(!TwEventMouseButtonGLUT(button, state, x, y))
|
||||
{
|
||||
gCollisionTests[gTest]->MouseCallback(button, state, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static void MotionCallback(int x, int y)
|
||||
{
|
||||
if(!TwEventMouseMotionGLUT(x, y))
|
||||
{
|
||||
if(gButton==2)
|
||||
{
|
||||
int dx = gMouseX - x;
|
||||
int dy = gMouseY - y;
|
||||
|
||||
RotateCamera(dx, dy);
|
||||
|
||||
gMouseX = x;
|
||||
gMouseY = y;
|
||||
}
|
||||
else
|
||||
gCollisionTests[gTest]->MotionCallback(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static void RenderCallback()
|
||||
{
|
||||
// Clear buffers
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Setup camera
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
SetupCameraMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
if(0 /*gRenderWireframe*/)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
else
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
gCollisionTests[gTest]->PerformTest();
|
||||
|
||||
// Draw tweak bars
|
||||
TwDraw();
|
||||
|
||||
glutSwapBuffers();
|
||||
glutPostRedisplay();
|
||||
|
||||
if(gSelectedTest!=gTest)
|
||||
{
|
||||
gCollisionTests[gTest]->Deselect();
|
||||
gTest = gSelectedTest;
|
||||
gCollisionTests[gTest]->Select();
|
||||
}
|
||||
}
|
||||
|
||||
static void ReshapeCallback(int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
// Send the new window size to AntTweakBar
|
||||
TwWindowSize(width, height);
|
||||
}
|
||||
|
||||
static void IdleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
static void Terminate()
|
||||
{
|
||||
ReleaseTerrain();
|
||||
|
||||
for(int i=0;i<MAX_NB_TESTS;i++)
|
||||
{
|
||||
gCollisionTests[i]->Release();
|
||||
DELETESINGLE(gCollisionTests[i]);
|
||||
}
|
||||
|
||||
if(gMainBar)
|
||||
{
|
||||
TwDeleteBar(gMainBar);
|
||||
gMainBar = null;
|
||||
}
|
||||
|
||||
TwTerminate();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
{
|
||||
::SetPriorityClass(::GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
|
||||
/*btDbvt::benchmark();
|
||||
exit(0);*/
|
||||
}
|
||||
// Initialize AntTweakBar
|
||||
// (note that AntTweakBar could also be intialize after GLUT, no matter)
|
||||
if(!TwInit(TW_OPENGL, NULL))
|
||||
{
|
||||
// A fatal error occured
|
||||
fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError());
|
||||
}
|
||||
|
||||
// Initialize Glut
|
||||
glutInit(&argc, argv);
|
||||
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
|
||||
int mainHandle = glutCreateWindow("CD Test Framework");
|
||||
|
||||
/* HWND hWnd;
|
||||
hWnd = FindWindow("GLUT", "CD Test Framework");
|
||||
RECT Rect;
|
||||
GetWindowRect(hWnd, &Rect);
|
||||
*/
|
||||
glutCreateMenu(NULL);
|
||||
glutSetWindow(mainHandle);
|
||||
glutDisplayFunc(RenderCallback);
|
||||
glutReshapeFunc(ReshapeCallback);
|
||||
glutIdleFunc(IdleCallback);
|
||||
glutKeyboardFunc(KeyboardCallback);
|
||||
glutSpecialFunc(ArrowKeyCallback);
|
||||
glutMouseFunc(MouseCallback);
|
||||
glutMotionFunc(MotionCallback);
|
||||
atexit(Terminate); // Called after glutMainLoop ends
|
||||
|
||||
glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
|
||||
TwGLUTModifiersFunc(glutGetModifiers);
|
||||
|
||||
// Setup default render states
|
||||
glClearColor(0.3f, 0.4f, 0.5f, 1.0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
// Setup lighting
|
||||
glEnable(GL_LIGHTING);
|
||||
float AmbientColor[] = { 0.0f, 0.1f, 0.2f, 0.0f }; glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientColor);
|
||||
float DiffuseColor[] = { 1.0f, 1.0f, 1.0f, 0.0f }; glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseColor);
|
||||
float SpecularColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularColor);
|
||||
float Position[] = { -10.0f, 1000.0f, -4.0f, 1.0f }; glLightfv(GL_LIGHT0, GL_POSITION, Position);
|
||||
glEnable(GL_LIGHT0);
|
||||
|
||||
gFnt.init();
|
||||
gFnt.setScreenResolution(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
gFnt.setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
CreateTerrain();
|
||||
|
||||
// Create main tweak bar
|
||||
{
|
||||
gMainBar = TwNewBar("CollisionTests");
|
||||
TwEnumVal testEV[MAX_NB_TESTS] = {
|
||||
// {TEST_SPHERE_MESH_QUERY, "Sphere-mesh query"},
|
||||
// {TEST_OBB_MESH_QUERY, "OBB-mesh query"},
|
||||
// {TEST_CAPSULE_MESH_QUERY, "Capsule-mesh query"},
|
||||
// {TEST_COMPLETE_BOX_PRUNING, "OPCODE SAP 1024"},
|
||||
{TEST_COMPLETE_BOX_PRUNING_8192, "OPCODE BOX PRUNING 8192"},
|
||||
// {TEST_BULLET_SAP_1024, "Bullet SAP HASHPAIR 1024"},
|
||||
// {TEST_BULLET_SAP_8192, "Bullet SAP HASHPAIR 8192"},
|
||||
// {TEST_BULLET_SAP_SORTEDPAIRS_8192, "Bullet SAP SORTEDPAIR 8192"},
|
||||
// {TEST_BULLET_MULTISAP_8192, "Bullet MultiSAP 8192"},
|
||||
// {TEST_BIPARTITE_BOX_PRUNING, "Bipartite box pruning"},
|
||||
{TEST_DBVT_8192, "Bullet DBVT 8192"},
|
||||
{TEST_BULLET_CUDA_8192, "Bullet CUDA 8192"},
|
||||
{TEST_BULLET_3DGRID_8192, "Bullet 3D Grid 8192"},
|
||||
{TEST_OPCODE_ARRAY_SAP, "OPCODE ARRAY SAP"},
|
||||
};
|
||||
TwType testType = TwDefineEnum("CollisionTest", testEV, MAX_NB_TESTS);
|
||||
TwAddVarRW(gMainBar, "CollisionTests", testType, &gSelectedTest, "");
|
||||
TwAddVarRW(gMainBar, "% of updates",TW_TYPE_INT32,&percentUpdate,"min=0 max=100");
|
||||
TwAddVarRW(gMainBar, "Draw",TW_TYPE_BOOLCPP,&enableDraw,"");
|
||||
}
|
||||
|
||||
// Create tests
|
||||
gTest = 0;
|
||||
// gCollisionTests[TEST_SPHERE_MESH_QUERY] = new SphereMeshQuery;
|
||||
// gCollisionTests[TEST_OBB_MESH_QUERY] = new OBBMeshQuery;
|
||||
// gCollisionTests[TEST_CAPSULE_MESH_QUERY] = new CapsuleMeshQuery;
|
||||
// gCollisionTests[TEST_COMPLETE_BOX_PRUNING] = new CompleteBoxPruningTest(NUM_SAP_BOXES);
|
||||
// gCollisionTests[TEST_COMPLETE_BOX_PRUNING_8192] = new CompleteBoxPruningTest(NUM_SAP_BOXES);
|
||||
gCollisionTests[TEST_COMPLETE_BOX_PRUNING_8192] = new CompleteBoxPruningTest(NUM_SAP_BOXES);
|
||||
// gCollisionTests[TEST_BULLET_SAP_1024] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,1);
|
||||
// gCollisionTests[TEST_BULLET_SAP_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,1);
|
||||
// gCollisionTests[TEST_BULLET_SAP_SORTEDPAIRS_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,3);
|
||||
// gCollisionTests[TEST_BULLET_MULTISAP_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,6);
|
||||
// gCollisionTests[TEST_BIPARTITE_BOX_PRUNING] = new BipartiteBoxPruningTest;
|
||||
gCollisionTests[TEST_DBVT_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,7);
|
||||
gCollisionTests[TEST_BULLET_CUDA_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,8);
|
||||
gCollisionTests[TEST_BULLET_3DGRID_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,9);
|
||||
gCollisionTests[TEST_OPCODE_ARRAY_SAP] = new OpcodeArraySAPTest(NUM_SAP_BOXES);
|
||||
|
||||
for(int i=0;i<MAX_NB_TESTS;i++)
|
||||
gCollisionTests[i]->Init();
|
||||
gCollisionTests[gTest]->Select();
|
||||
|
||||
//
|
||||
MotionCallback(0,0);
|
||||
|
||||
// Run
|
||||
glutMainLoop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef OLDIES
|
||||
|
||||
#include "btBulletCollisionCommon.h"
|
||||
|
||||
class BulletMeshInterface : public btStridingMeshInterface
|
||||
{
|
||||
public:
|
||||
/// get read and write access to a subpart of a triangle mesh
|
||||
/// this subpart has a continuous array of vertices and indices
|
||||
/// in this way the mesh can be handled as chunks of memory with striding
|
||||
/// very similar to OpenGL vertexarray support
|
||||
/// make a call to unLockVertexBase when the read and write access is finished
|
||||
virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0)
|
||||
{
|
||||
numverts = gTerrainData->nbVerts;
|
||||
(*vertexbase) = (unsigned char *)gTerrainData->verts;
|
||||
type = PHY_FLOAT;
|
||||
stride = sizeof(Point);
|
||||
|
||||
numfaces = gTerrainData->nbFaces;
|
||||
(*indexbase) = (unsigned char *)gTerrainData->faces;
|
||||
indicestype = PHY_INTEGER;
|
||||
indexstride = 3*sizeof(udword); // ??
|
||||
}
|
||||
|
||||
virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const
|
||||
{
|
||||
numverts = gTerrainData->nbVerts;
|
||||
(*vertexbase) = (unsigned char *)gTerrainData->verts;
|
||||
type = PHY_FLOAT;
|
||||
stride = sizeof(Point);
|
||||
|
||||
numfaces = gTerrainData->nbFaces;
|
||||
(*indexbase) = (unsigned char *)gTerrainData->faces;
|
||||
indicestype = PHY_INTEGER;
|
||||
indexstride = 3*sizeof(udword); // ??
|
||||
}
|
||||
|
||||
/// unLockVertexBase finishes the access to a subpart of the triangle mesh
|
||||
/// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished
|
||||
virtual void unLockVertexBase(int subpart)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void unLockReadOnlyVertexBase(int subpart) const
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// getNumSubParts returns the number of seperate subparts
|
||||
/// each subpart has a continuous array of vertices and indices
|
||||
virtual int getNumSubParts() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void preallocateVertices(int numverts)
|
||||
{
|
||||
}
|
||||
virtual void preallocateIndices(int numindices)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
void BuildBulletTree()
|
||||
{
|
||||
/* BulletMeshInterface btMeshInterface;
|
||||
|
||||
btOptimizedBvh* btTree = new btOptimizedBvh;
|
||||
btTree->build(&btMeshInterface, true);
|
||||
|
||||
|
||||
struct MyNodeOverlapCallback : public btNodeOverlapCallback
|
||||
{
|
||||
virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface);
|
||||
|
||||
m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "CollisionTest.h"
|
||||
#include "SphereMeshQuery.h"
|
||||
#include "OBBMeshQuery.h"
|
||||
#include "CapsuleMeshQuery.h"
|
||||
#include "CompleteBoxPruning.h"
|
||||
#include "BulletSAPCompleteBoxPruningTest.h"
|
||||
#include "BulletSAPCompleteBoxPruningTest.h"
|
||||
#include "BipartiteBoxPruning.h"
|
||||
#include "OpcodeArraySAPTest.h"
|
||||
#include "RenderingHelpers.h"
|
||||
#include "Terrain.h"
|
||||
#include "Camera.h"
|
||||
#include "GLFontRenderer.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.h"
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
|
||||
#define NUM_SAP_BOXES 8192
|
||||
//#define NUM_SAP_BOXES 16384
|
||||
//#define NUM_SAP_BOXES 1024
|
||||
|
||||
int percentUpdate = 100;
|
||||
//float objectSpeed = 0.005f;
|
||||
float objectSpeed = 0.01f;
|
||||
bool enableDraw = true;
|
||||
|
||||
//Broadphase comparison
|
||||
//Static case (updating 10% of objects to same position ( -> no swaps)
|
||||
//number of objects //OPCODE BoxPruning / Bullet SAP / Bullet MultiSAP
|
||||
//1024 0.35ms, 0.03ms, 0.15ms
|
||||
//8192 21ms, 0.2ms, 5ms
|
||||
//16384 92ms , 0.5ms, 28ms
|
||||
|
||||
//Dynamic case, 10% objects are moving as fast as this testbed allows (0.01?)
|
||||
//number of objects //OPCODE BoxPruning / Bullet SAP / Bullet MultiSAP
|
||||
//1024 0.35ms, 0.2ms, 0.25ms
|
||||
//8192 21ms , 15ms , 13ms
|
||||
//16384 92ms, 80ms, 49ms
|
||||
|
||||
|
||||
#define WINDOW_WIDTH 1024
|
||||
#define WINDOW_HEIGHT 768
|
||||
|
||||
static int gMouseX = 0;
|
||||
static int gMouseY = 0;
|
||||
static int gButton = 0;
|
||||
|
||||
static TwBar* gMainBar = null;
|
||||
enum TestIndex
|
||||
{
|
||||
// TEST_SPHERE_MESH_QUERY,
|
||||
// TEST_OBB_MESH_QUERY,
|
||||
// TEST_CAPSULE_MESH_QUERY,
|
||||
// TEST_COMPLETE_BOX_PRUNING=0,
|
||||
TEST_COMPLETE_BOX_PRUNING_8192,
|
||||
// TEST_BULLET_SAP_1024,
|
||||
// TEST_BULLET_SAP_8192,
|
||||
// TEST_BULLET_SAP_SORTEDPAIRS_8192,
|
||||
// TEST_BULLET_MULTISAP_8192,
|
||||
// TEST_BIPARTITE_BOX_PRUNING,
|
||||
TEST_DBVT_8192,
|
||||
TEST_BULLET_CUDA_8192,
|
||||
TEST_BULLET_3DGRID_8192,
|
||||
TEST_OPCODE_ARRAY_SAP,
|
||||
MAX_NB_TESTS
|
||||
};
|
||||
|
||||
//static int gTest = TEST_DBVT_8192;//TEST_BULLET_MULTISAP_8192;
|
||||
//static int gSelectedTest = TEST_DBVT_8192;//TEST_BULLET_MULTISAP_8192;
|
||||
static int gTest = TEST_BULLET_CUDA_8192;
|
||||
static int gSelectedTest = TEST_BULLET_CUDA_8192;
|
||||
static CollisionTest* gCollisionTests[MAX_NB_TESTS];
|
||||
|
||||
static GLFontRenderer gFnt;
|
||||
|
||||
/////////////////
|
||||
|
||||
static void KeyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 27: exit(0); break;
|
||||
|
||||
case '+':
|
||||
{
|
||||
if(gTest!=MAX_NB_TESTS-1)
|
||||
{
|
||||
gCollisionTests[gTest]->Deselect();
|
||||
gTest++;
|
||||
gSelectedTest++;
|
||||
gCollisionTests[gTest]->Select();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '-':
|
||||
{
|
||||
if(gTest)
|
||||
{
|
||||
gCollisionTests[gTest]->Deselect();
|
||||
gTest--;
|
||||
gSelectedTest--;
|
||||
gCollisionTests[gTest]->Select();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 101: MoveCameraForward(); break;
|
||||
case 103: MoveCameraBackward(); break;
|
||||
case 100: MoveCameraRight(); break;
|
||||
case 102: MoveCameraLeft(); break;
|
||||
default: gCollisionTests[gTest]->KeyboardCallback(key, x, y); break;
|
||||
}
|
||||
|
||||
TwEventKeyboardGLUT(key, x, y);
|
||||
}
|
||||
|
||||
static void ArrowKeyCallback(int key, int x, int y)
|
||||
{
|
||||
KeyboardCallback(key, x, y);
|
||||
|
||||
TwEventSpecialGLUT(key, x, y);
|
||||
}
|
||||
|
||||
static void MouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
gButton = button;
|
||||
gMouseX = x;
|
||||
gMouseY = y;
|
||||
|
||||
if(!TwEventMouseButtonGLUT(button, state, x, y))
|
||||
{
|
||||
gCollisionTests[gTest]->MouseCallback(button, state, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static void MotionCallback(int x, int y)
|
||||
{
|
||||
if(!TwEventMouseMotionGLUT(x, y))
|
||||
{
|
||||
if(gButton==2)
|
||||
{
|
||||
int dx = gMouseX - x;
|
||||
int dy = gMouseY - y;
|
||||
|
||||
RotateCamera(dx, dy);
|
||||
|
||||
gMouseX = x;
|
||||
gMouseY = y;
|
||||
}
|
||||
else
|
||||
gCollisionTests[gTest]->MotionCallback(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static void RenderCallback()
|
||||
{
|
||||
// Clear buffers
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Setup camera
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
SetupCameraMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
if(0 /*gRenderWireframe*/)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
else
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
gCollisionTests[gTest]->PerformTest();
|
||||
|
||||
// Draw tweak bars
|
||||
TwDraw();
|
||||
|
||||
glutSwapBuffers();
|
||||
glutPostRedisplay();
|
||||
|
||||
if(gSelectedTest!=gTest)
|
||||
{
|
||||
gCollisionTests[gTest]->Deselect();
|
||||
gTest = gSelectedTest;
|
||||
gCollisionTests[gTest]->Select();
|
||||
}
|
||||
}
|
||||
|
||||
static void ReshapeCallback(int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
// Send the new window size to AntTweakBar
|
||||
TwWindowSize(width, height);
|
||||
}
|
||||
|
||||
static void IdleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
static void Terminate()
|
||||
{
|
||||
ReleaseTerrain();
|
||||
|
||||
for(int i=0;i<MAX_NB_TESTS;i++)
|
||||
{
|
||||
gCollisionTests[i]->Release();
|
||||
DELETESINGLE(gCollisionTests[i]);
|
||||
}
|
||||
|
||||
if(gMainBar)
|
||||
{
|
||||
TwDeleteBar(gMainBar);
|
||||
gMainBar = null;
|
||||
}
|
||||
|
||||
TwTerminate();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
{
|
||||
::SetPriorityClass(::GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
|
||||
/*btDbvt::benchmark();
|
||||
exit(0);*/
|
||||
}
|
||||
// Initialize AntTweakBar
|
||||
// (note that AntTweakBar could also be intialize after GLUT, no matter)
|
||||
if(!TwInit(TW_OPENGL, NULL))
|
||||
{
|
||||
// A fatal error occured
|
||||
fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError());
|
||||
}
|
||||
|
||||
// Initialize Glut
|
||||
glutInit(&argc, argv);
|
||||
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
|
||||
int mainHandle = glutCreateWindow("CD Test Framework");
|
||||
|
||||
/* HWND hWnd;
|
||||
hWnd = FindWindow("GLUT", "CD Test Framework");
|
||||
RECT Rect;
|
||||
GetWindowRect(hWnd, &Rect);
|
||||
*/
|
||||
glutCreateMenu(NULL);
|
||||
glutSetWindow(mainHandle);
|
||||
glutDisplayFunc(RenderCallback);
|
||||
glutReshapeFunc(ReshapeCallback);
|
||||
glutIdleFunc(IdleCallback);
|
||||
glutKeyboardFunc(KeyboardCallback);
|
||||
glutSpecialFunc(ArrowKeyCallback);
|
||||
glutMouseFunc(MouseCallback);
|
||||
glutMotionFunc(MotionCallback);
|
||||
atexit(Terminate); // Called after glutMainLoop ends
|
||||
|
||||
glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
|
||||
TwGLUTModifiersFunc(glutGetModifiers);
|
||||
|
||||
// Setup default render states
|
||||
glClearColor(0.3f, 0.4f, 0.5f, 1.0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
// Setup lighting
|
||||
glEnable(GL_LIGHTING);
|
||||
float AmbientColor[] = { 0.0f, 0.1f, 0.2f, 0.0f }; glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientColor);
|
||||
float DiffuseColor[] = { 1.0f, 1.0f, 1.0f, 0.0f }; glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseColor);
|
||||
float SpecularColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularColor);
|
||||
float Position[] = { -10.0f, 1000.0f, -4.0f, 1.0f }; glLightfv(GL_LIGHT0, GL_POSITION, Position);
|
||||
glEnable(GL_LIGHT0);
|
||||
|
||||
gFnt.init();
|
||||
gFnt.setScreenResolution(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
gFnt.setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
CreateTerrain();
|
||||
|
||||
// Create main tweak bar
|
||||
{
|
||||
gMainBar = TwNewBar("CollisionTests");
|
||||
TwEnumVal testEV[MAX_NB_TESTS] = {
|
||||
// {TEST_SPHERE_MESH_QUERY, "Sphere-mesh query"},
|
||||
// {TEST_OBB_MESH_QUERY, "OBB-mesh query"},
|
||||
// {TEST_CAPSULE_MESH_QUERY, "Capsule-mesh query"},
|
||||
// {TEST_COMPLETE_BOX_PRUNING, "OPCODE SAP 1024"},
|
||||
{TEST_COMPLETE_BOX_PRUNING_8192, "OPCODE BOX PRUNING 8192"},
|
||||
// {TEST_BULLET_SAP_1024, "Bullet SAP HASHPAIR 1024"},
|
||||
// {TEST_BULLET_SAP_8192, "Bullet SAP HASHPAIR 8192"},
|
||||
// {TEST_BULLET_SAP_SORTEDPAIRS_8192, "Bullet SAP SORTEDPAIR 8192"},
|
||||
// {TEST_BULLET_MULTISAP_8192, "Bullet MultiSAP 8192"},
|
||||
// {TEST_BIPARTITE_BOX_PRUNING, "Bipartite box pruning"},
|
||||
{TEST_DBVT_8192, "Bullet DBVT 8192"},
|
||||
{TEST_BULLET_CUDA_8192, "Bullet CUDA 8192"},
|
||||
{TEST_BULLET_3DGRID_8192, "Bullet 3D Grid 8192"},
|
||||
{TEST_OPCODE_ARRAY_SAP, "OPCODE ARRAY SAP"},
|
||||
};
|
||||
TwType testType = TwDefineEnum("CollisionTest", testEV, MAX_NB_TESTS);
|
||||
TwAddVarRW(gMainBar, "CollisionTests", testType, &gSelectedTest, "");
|
||||
TwAddVarRW(gMainBar, "% of updates",TW_TYPE_INT32,&percentUpdate,"min=0 max=100");
|
||||
TwAddVarRW(gMainBar, "Draw",TW_TYPE_BOOLCPP,&enableDraw,"");
|
||||
}
|
||||
|
||||
// Create tests
|
||||
gTest = 0;
|
||||
// gCollisionTests[TEST_SPHERE_MESH_QUERY] = new SphereMeshQuery;
|
||||
// gCollisionTests[TEST_OBB_MESH_QUERY] = new OBBMeshQuery;
|
||||
// gCollisionTests[TEST_CAPSULE_MESH_QUERY] = new CapsuleMeshQuery;
|
||||
// gCollisionTests[TEST_COMPLETE_BOX_PRUNING] = new CompleteBoxPruningTest(NUM_SAP_BOXES);
|
||||
// gCollisionTests[TEST_COMPLETE_BOX_PRUNING_8192] = new CompleteBoxPruningTest(NUM_SAP_BOXES);
|
||||
gCollisionTests[TEST_COMPLETE_BOX_PRUNING_8192] = new CompleteBoxPruningTest(NUM_SAP_BOXES);
|
||||
// gCollisionTests[TEST_BULLET_SAP_1024] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,1);
|
||||
// gCollisionTests[TEST_BULLET_SAP_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,1);
|
||||
// gCollisionTests[TEST_BULLET_SAP_SORTEDPAIRS_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,3);
|
||||
// gCollisionTests[TEST_BULLET_MULTISAP_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,6);
|
||||
// gCollisionTests[TEST_BIPARTITE_BOX_PRUNING] = new BipartiteBoxPruningTest;
|
||||
gCollisionTests[TEST_DBVT_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,7);
|
||||
gCollisionTests[TEST_BULLET_CUDA_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,8);
|
||||
gCollisionTests[TEST_BULLET_3DGRID_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,9);
|
||||
gCollisionTests[TEST_OPCODE_ARRAY_SAP] = new OpcodeArraySAPTest(NUM_SAP_BOXES);
|
||||
|
||||
for(int i=0;i<MAX_NB_TESTS;i++)
|
||||
gCollisionTests[i]->Init();
|
||||
gCollisionTests[gTest]->Select();
|
||||
|
||||
//
|
||||
MotionCallback(0,0);
|
||||
|
||||
// Run
|
||||
glutMainLoop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef OLDIES
|
||||
|
||||
#include "btBulletCollisionCommon.h"
|
||||
|
||||
class BulletMeshInterface : public btStridingMeshInterface
|
||||
{
|
||||
public:
|
||||
/// get read and write access to a subpart of a triangle mesh
|
||||
/// this subpart has a continuous array of vertices and indices
|
||||
/// in this way the mesh can be handled as chunks of memory with striding
|
||||
/// very similar to OpenGL vertexarray support
|
||||
/// make a call to unLockVertexBase when the read and write access is finished
|
||||
virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0)
|
||||
{
|
||||
numverts = gTerrainData->nbVerts;
|
||||
(*vertexbase) = (unsigned char *)gTerrainData->verts;
|
||||
type = PHY_FLOAT;
|
||||
stride = sizeof(Point);
|
||||
|
||||
numfaces = gTerrainData->nbFaces;
|
||||
(*indexbase) = (unsigned char *)gTerrainData->faces;
|
||||
indicestype = PHY_INTEGER;
|
||||
indexstride = 3*sizeof(udword); // ??
|
||||
}
|
||||
|
||||
virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const
|
||||
{
|
||||
numverts = gTerrainData->nbVerts;
|
||||
(*vertexbase) = (unsigned char *)gTerrainData->verts;
|
||||
type = PHY_FLOAT;
|
||||
stride = sizeof(Point);
|
||||
|
||||
numfaces = gTerrainData->nbFaces;
|
||||
(*indexbase) = (unsigned char *)gTerrainData->faces;
|
||||
indicestype = PHY_INTEGER;
|
||||
indexstride = 3*sizeof(udword); // ??
|
||||
}
|
||||
|
||||
/// unLockVertexBase finishes the access to a subpart of the triangle mesh
|
||||
/// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished
|
||||
virtual void unLockVertexBase(int subpart)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void unLockReadOnlyVertexBase(int subpart) const
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// getNumSubParts returns the number of seperate subparts
|
||||
/// each subpart has a continuous array of vertices and indices
|
||||
virtual int getNumSubParts() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void preallocateVertices(int numverts)
|
||||
{
|
||||
}
|
||||
virtual void preallocateIndices(int numindices)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
void BuildBulletTree()
|
||||
{
|
||||
/* BulletMeshInterface btMeshInterface;
|
||||
|
||||
btOptimizedBvh* btTree = new btOptimizedBvh;
|
||||
btTree->build(&btMeshInterface, true);
|
||||
|
||||
|
||||
struct MyNodeOverlapCallback : public btNodeOverlapCallback
|
||||
{
|
||||
virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface);
|
||||
|
||||
m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 CDTESTFRAMEWORK_H
|
||||
#define CDTESTFRAMEWORK_H
|
||||
|
||||
#endif // CDTESTFRAMEWORK_H
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 CDTESTFRAMEWORK_H
|
||||
#define CDTESTFRAMEWORK_H
|
||||
|
||||
#endif // CDTESTFRAMEWORK_H
|
||||
|
||||
@@ -1,78 +1,78 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CDTestFramework", "CDTestFramework.vcproj", "{0565DB39-45CC-416E-B549-BFC24F2666D1}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE} = {6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A} = {7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2} = {DBE44CA3-2912-4441-8D99-AA2242688AD2}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Opcode", "Opcode\Opcode.vcproj", "{DBE44CA3-2912-4441-8D99-AA2242688AD2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbulletmath", "..\..\msvc\8\libbulletmath.vcproj", "{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbulletcollision", "..\..\msvc\8\libbulletcollision.vcproj", "{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
DebugDll|Win32 = DebugDll|Win32
|
||||
DebugDoublePrecision|Win32 = DebugDoublePrecision|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
ReleaseDll|Win32 = ReleaseDll|Win32
|
||||
ReleaseDoublePrecision|Win32 = ReleaseDoublePrecision|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.DebugDll|Win32.ActiveCfg = Debug|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.DebugDll|Win32.Build.0 = Debug|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.DebugDoublePrecision|Win32.ActiveCfg = Debug|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.DebugDoublePrecision|Win32.Build.0 = Debug|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.Release|Win32.Build.0 = Release|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.ReleaseDll|Win32.ActiveCfg = Release|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.ReleaseDll|Win32.Build.0 = Release|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.ReleaseDoublePrecision|Win32.ActiveCfg = Release|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.ReleaseDoublePrecision|Win32.Build.0 = Release|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.DebugDll|Win32.ActiveCfg = Debug|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.DebugDll|Win32.Build.0 = Debug|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.DebugDoublePrecision|Win32.ActiveCfg = Debug|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.DebugDoublePrecision|Win32.Build.0 = Debug|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.Release|Win32.Build.0 = Release|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.ReleaseDll|Win32.ActiveCfg = Release|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.ReleaseDll|Win32.Build.0 = Release|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.ReleaseDoublePrecision|Win32.ActiveCfg = Release|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.ReleaseDoublePrecision|Win32.Build.0 = Release|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDll|Win32.ActiveCfg = DebugDll|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDll|Win32.Build.0 = DebugDll|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDoublePrecision|Win32.ActiveCfg = DebugDoublePrecision|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDoublePrecision|Win32.Build.0 = DebugDoublePrecision|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Release|Win32.Build.0 = Release|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDll|Win32.ActiveCfg = ReleaseDll|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDll|Win32.Build.0 = ReleaseDll|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDoublePrecision|Win32.ActiveCfg = ReleaseDoublePrecision|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDoublePrecision|Win32.Build.0 = ReleaseDoublePrecision|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDll|Win32.ActiveCfg = DebugDll|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDll|Win32.Build.0 = DebugDll|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDoublePrecision|Win32.ActiveCfg = DebugDoublePrecision|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDoublePrecision|Win32.Build.0 = DebugDoublePrecision|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Release|Win32.Build.0 = Release|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDll|Win32.ActiveCfg = ReleaseDll|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDll|Win32.Build.0 = ReleaseDll|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDoublePrecision|Win32.ActiveCfg = ReleaseDoublePrecision|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDoublePrecision|Win32.Build.0 = ReleaseDoublePrecision|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CDTestFramework", "CDTestFramework.vcproj", "{0565DB39-45CC-416E-B549-BFC24F2666D1}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE} = {6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A} = {7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2} = {DBE44CA3-2912-4441-8D99-AA2242688AD2}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Opcode", "Opcode\Opcode.vcproj", "{DBE44CA3-2912-4441-8D99-AA2242688AD2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbulletmath", "..\..\msvc\8\libbulletmath.vcproj", "{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbulletcollision", "..\..\msvc\8\libbulletcollision.vcproj", "{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
DebugDll|Win32 = DebugDll|Win32
|
||||
DebugDoublePrecision|Win32 = DebugDoublePrecision|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
ReleaseDll|Win32 = ReleaseDll|Win32
|
||||
ReleaseDoublePrecision|Win32 = ReleaseDoublePrecision|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.DebugDll|Win32.ActiveCfg = Debug|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.DebugDll|Win32.Build.0 = Debug|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.DebugDoublePrecision|Win32.ActiveCfg = Debug|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.DebugDoublePrecision|Win32.Build.0 = Debug|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.Release|Win32.Build.0 = Release|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.ReleaseDll|Win32.ActiveCfg = Release|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.ReleaseDll|Win32.Build.0 = Release|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.ReleaseDoublePrecision|Win32.ActiveCfg = Release|Win32
|
||||
{0565DB39-45CC-416E-B549-BFC24F2666D1}.ReleaseDoublePrecision|Win32.Build.0 = Release|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.DebugDll|Win32.ActiveCfg = Debug|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.DebugDll|Win32.Build.0 = Debug|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.DebugDoublePrecision|Win32.ActiveCfg = Debug|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.DebugDoublePrecision|Win32.Build.0 = Debug|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.Release|Win32.Build.0 = Release|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.ReleaseDll|Win32.ActiveCfg = Release|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.ReleaseDll|Win32.Build.0 = Release|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.ReleaseDoublePrecision|Win32.ActiveCfg = Release|Win32
|
||||
{DBE44CA3-2912-4441-8D99-AA2242688AD2}.ReleaseDoublePrecision|Win32.Build.0 = Release|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDll|Win32.ActiveCfg = DebugDll|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDll|Win32.Build.0 = DebugDll|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDoublePrecision|Win32.ActiveCfg = DebugDoublePrecision|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDoublePrecision|Win32.Build.0 = DebugDoublePrecision|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Release|Win32.Build.0 = Release|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDll|Win32.ActiveCfg = ReleaseDll|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDll|Win32.Build.0 = ReleaseDll|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDoublePrecision|Win32.ActiveCfg = ReleaseDoublePrecision|Win32
|
||||
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDoublePrecision|Win32.Build.0 = ReleaseDoublePrecision|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDll|Win32.ActiveCfg = DebugDll|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDll|Win32.Build.0 = DebugDll|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDoublePrecision|Win32.ActiveCfg = DebugDoublePrecision|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDoublePrecision|Win32.Build.0 = DebugDoublePrecision|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Release|Win32.Build.0 = Release|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDll|Win32.ActiveCfg = ReleaseDll|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDll|Win32.Build.0 = ReleaseDll|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDoublePrecision|Win32.ActiveCfg = ReleaseDoublePrecision|Win32
|
||||
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDoublePrecision|Win32.Build.0 = ReleaseDoublePrecision|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
|
||||
CD Test Framework
|
||||
=================
|
||||
|
||||
This is a very small app used to test various collision detection (CD) algorithms.
|
||||
It will be first used as a demo/sample for Opcode 1.3 (a lot of people requested this),
|
||||
and then I will also include benchmarks against competing libraries (Bullet, GIMPACT, etc).
|
||||
|
||||
Update April 2, 2008
|
||||
Erwin Coumans added Bullet support for broadphase test (SAP, MultiSAP, other tests follow)
|
||||
This CDTestFramework is now included in Bullet/Extras under the ZLib license.
|
||||
|
||||
Current version includes tests for:
|
||||
- sphere vs mesh queries
|
||||
- OBB vs mesh queries
|
||||
- capsule vs mesh queries
|
||||
- complete box pruning
|
||||
- bipartite box pruning
|
||||
|
||||
|
||||
Pierre Terdiman
|
||||
March 16, 2007
|
||||
|
||||
External libs used:
|
||||
|
||||
Opcode 1.3 (http://www.codercorner.com/Opcode.htm)
|
||||
AntTweakBar (http://www.antisphere.com/Wiki/tools:anttweakbar)
|
||||
Bullet Physics Library (http://bulletphysics.com)
|
||||
|
||||
Contact email:
|
||||
|
||||
CD Test Framework
|
||||
=================
|
||||
|
||||
This is a very small app used to test various collision detection (CD) algorithms.
|
||||
It will be first used as a demo/sample for Opcode 1.3 (a lot of people requested this),
|
||||
and then I will also include benchmarks against competing libraries (Bullet, GIMPACT, etc).
|
||||
|
||||
Update April 2, 2008
|
||||
Erwin Coumans added Bullet support for broadphase test (SAP, MultiSAP, other tests follow)
|
||||
This CDTestFramework is now included in Bullet/Extras under the ZLib license.
|
||||
|
||||
Current version includes tests for:
|
||||
- sphere vs mesh queries
|
||||
- OBB vs mesh queries
|
||||
- capsule vs mesh queries
|
||||
- complete box pruning
|
||||
- bipartite box pruning
|
||||
|
||||
|
||||
Pierre Terdiman
|
||||
March 16, 2007
|
||||
|
||||
External libs used:
|
||||
|
||||
Opcode 1.3 (http://www.codercorner.com/Opcode.htm)
|
||||
AntTweakBar (http://www.antisphere.com/Wiki/tools:anttweakbar)
|
||||
Bullet Physics Library (http://bulletphysics.com)
|
||||
|
||||
Contact email:
|
||||
pierre@codercorner.com
|
||||
@@ -1,365 +1,365 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="CDTestFramework"
|
||||
ProjectGUID="{0565DB39-45CC-416E-B549-BFC24F2666D1}"
|
||||
RootNamespace="CDTestFramework"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=".\Opcode;.\AntTweakBar\include;.\GIMPACT\Include;../../src;../../Glut"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
ExceptionHandling="0"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="./Bin/CDTestFrameworkDEBUG.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=".\AntTweakBar\lib;../../Glut"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/CDTestFramework.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories=".\Opcode;.\AntTweakBar\include;.\GIMPACT\Include;../../src;../../Glut"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
ExceptionHandling="0"
|
||||
RuntimeLibrary="0"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
FloatingPointModel="2"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cudart.lib"
|
||||
OutputFile="./Bin/CDTestFramework.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=".\AntTweakBar\lib,../../Glut;"$(CUDA_LIB_PATH)""
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\BipartiteBoxPruning.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BipartiteBoxPruning.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BulletSAPCompleteBoxPruningTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BulletSAPCompleteBoxPruningTest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Camera.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Camera.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CapsuleMeshQuery.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CapsuleMeshQuery.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CDTestFramework.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CDTestFramework.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CollisionTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CollisionTest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CompleteBoxPruning.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CompleteBoxPruning.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GLFontData.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GLFontRenderer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GLFontRenderer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\IceHelpers.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\IceHelpers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\OBBMeshQuery.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\OBBMeshQuery.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\OpcodeArraySAPTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\OpcodeArraySAPTest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Profiling.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\RenderingHelpers.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\RenderingHelpers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SphereMeshQuery.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SphereMeshQuery.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Terrain.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Terrain.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\CDTestFramework.txt"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\VTune\CDTestFramework.vpj"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ReadMe.txt"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="CDTestFramework"
|
||||
ProjectGUID="{0565DB39-45CC-416E-B549-BFC24F2666D1}"
|
||||
RootNamespace="CDTestFramework"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=".\Opcode;.\AntTweakBar\include;.\GIMPACT\Include;../../src;../../Glut"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
ExceptionHandling="0"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="./Bin/CDTestFrameworkDEBUG.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=".\AntTweakBar\lib;../../Glut"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/CDTestFramework.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories=".\Opcode;.\AntTweakBar\include;.\GIMPACT\Include;../../src;../../Glut"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
ExceptionHandling="0"
|
||||
RuntimeLibrary="0"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
FloatingPointModel="2"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cudart.lib"
|
||||
OutputFile="./Bin/CDTestFramework.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=".\AntTweakBar\lib,../../Glut;"$(CUDA_LIB_PATH)""
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\BipartiteBoxPruning.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BipartiteBoxPruning.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BulletSAPCompleteBoxPruningTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BulletSAPCompleteBoxPruningTest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Camera.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Camera.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CapsuleMeshQuery.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CapsuleMeshQuery.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CDTestFramework.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CDTestFramework.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CollisionTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CollisionTest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CompleteBoxPruning.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CompleteBoxPruning.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GLFontData.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GLFontRenderer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GLFontRenderer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\IceHelpers.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\IceHelpers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\OBBMeshQuery.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\OBBMeshQuery.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\OpcodeArraySAPTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\OpcodeArraySAPTest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Profiling.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\RenderingHelpers.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\RenderingHelpers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SphereMeshQuery.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SphereMeshQuery.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Terrain.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Terrain.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\CDTestFramework.txt"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\VTune\CDTestFramework.vpj"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ReadMe.txt"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
||||
@@ -1,156 +1,156 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Camera.h"
|
||||
|
||||
static const float gCamSpeed = 1.0f;
|
||||
//static Point gEye(3.0616338f, 1.1985892f, 2.5769043f);
|
||||
//static Point gDir(-0.66853905,-0.14004262,-0.73037237);
|
||||
static Point gEye(240, 205, 205);
|
||||
static Point gDir(-1,-1,-1);
|
||||
static Point gN;
|
||||
static float gFOV = 60.0f;
|
||||
|
||||
const Point& GetCameraPos()
|
||||
{
|
||||
return gEye;
|
||||
}
|
||||
|
||||
const Point& GetCameraDir()
|
||||
{
|
||||
return gDir;
|
||||
}
|
||||
|
||||
void MoveCameraForward()
|
||||
{
|
||||
gEye += gDir * gCamSpeed;
|
||||
}
|
||||
|
||||
void MoveCameraBackward()
|
||||
{
|
||||
gEye -= gDir * gCamSpeed;
|
||||
}
|
||||
|
||||
void MoveCameraRight()
|
||||
{
|
||||
gEye -= gN * gCamSpeed;
|
||||
}
|
||||
|
||||
void MoveCameraLeft()
|
||||
{
|
||||
gEye += gN * gCamSpeed;
|
||||
}
|
||||
|
||||
static const float NxPiF32 = 3.141592653589793f;
|
||||
|
||||
float degToRad(float a)
|
||||
{
|
||||
return (float)0.01745329251994329547 * a;
|
||||
}
|
||||
|
||||
class NxQuat
|
||||
{
|
||||
public:
|
||||
NxQuat(){}
|
||||
|
||||
NxQuat(const float angle, const Point & axis)
|
||||
{
|
||||
x = axis.x;
|
||||
y = axis.y;
|
||||
z = axis.z;
|
||||
|
||||
const float i_length = 1.0f / sqrtf( x*x + y*y + z*z );
|
||||
x = x * i_length;
|
||||
y = y * i_length;
|
||||
z = z * i_length;
|
||||
|
||||
float Half = degToRad(angle * 0.5f);
|
||||
|
||||
w = cosf(Half);
|
||||
const float sin_theta_over_two = sinf(Half );
|
||||
x = x * sin_theta_over_two;
|
||||
y = y * sin_theta_over_two;
|
||||
z = z * sin_theta_over_two;
|
||||
}
|
||||
|
||||
void NxQuat::multiply(const NxQuat& left, const Point& right)
|
||||
{
|
||||
float a,b,c,d;
|
||||
|
||||
a = - left.x*right.x - left.y*right.y - left.z *right.z;
|
||||
b = left.w*right.x + left.y*right.z - right.y*left.z;
|
||||
c = left.w*right.y + left.z*right.x - right.z*left.x;
|
||||
d = left.w*right.z + left.x*right.y - right.x*left.y;
|
||||
|
||||
w = a;
|
||||
x = b;
|
||||
y = c;
|
||||
z = d;
|
||||
}
|
||||
|
||||
void NxQuat::rotate(Point & v) const
|
||||
{
|
||||
NxQuat myInverse;
|
||||
myInverse.x = -x;
|
||||
myInverse.y = -y;
|
||||
myInverse.z = -z;
|
||||
myInverse.w = w;
|
||||
|
||||
NxQuat left;
|
||||
left.multiply(*this,v);
|
||||
v.x = left.w*myInverse.x + myInverse.w*left.x + left.y*myInverse.z - myInverse.y*left.z;
|
||||
v.y = left.w*myInverse.y + myInverse.w*left.y + left.z*myInverse.x - myInverse.z*left.x;
|
||||
v.z = left.w*myInverse.z + myInverse.w*left.z + left.x*myInverse.y - myInverse.x*left.y;
|
||||
}
|
||||
|
||||
float x,y,z,w;
|
||||
};
|
||||
|
||||
void RotateCamera(int dx, int dy)
|
||||
{
|
||||
gDir = gDir.Normalize();
|
||||
gN = gDir ^ Point(0,1,0);
|
||||
|
||||
NxQuat qx(NxPiF32 * dx * 20/ 180.0f, Point(0,1,0));
|
||||
qx.rotate(gDir);
|
||||
NxQuat qy(NxPiF32 * dy * 20/ 180.0f, gN);
|
||||
qy.rotate(gDir);
|
||||
}
|
||||
|
||||
void SetupCameraMatrix()
|
||||
{
|
||||
glLoadIdentity();
|
||||
gluPerspective(gFOV, ((float)glutGet(GLUT_WINDOW_WIDTH))/((float)glutGet(GLUT_WINDOW_HEIGHT)), 1.0f, 10000.0f);
|
||||
gluLookAt(gEye.x, gEye.y, gEye.z, gEye.x + gDir.x, gEye.y + gDir.y, gEye.z + gDir.z, 0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
|
||||
Point ComputeWorldRay(int xs, int ys)
|
||||
{
|
||||
GLint viewPort[4];
|
||||
GLdouble modelMatrix[16];
|
||||
GLdouble projMatrix[16];
|
||||
glGetIntegerv(GL_VIEWPORT, viewPort);
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
|
||||
ys = viewPort[3] - ys - 1;
|
||||
GLdouble wx0, wy0, wz0;
|
||||
gluUnProject((GLdouble) xs, (GLdouble) ys, 0.0, modelMatrix, projMatrix, viewPort, &wx0, &wy0, &wz0);
|
||||
GLdouble wx1, wy1, wz1;
|
||||
gluUnProject((GLdouble) xs, (GLdouble) ys, 1.0, modelMatrix, projMatrix, viewPort, &wx1, &wy1, &wz1);
|
||||
Point tmp(float(wx1-wx0), float(wy1-wy0), float(wz1-wz0));
|
||||
tmp.Normalize();
|
||||
return tmp;
|
||||
}
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Camera.h"
|
||||
|
||||
static const float gCamSpeed = 1.0f;
|
||||
//static Point gEye(3.0616338f, 1.1985892f, 2.5769043f);
|
||||
//static Point gDir(-0.66853905,-0.14004262,-0.73037237);
|
||||
static Point gEye(240, 205, 205);
|
||||
static Point gDir(-1,-1,-1);
|
||||
static Point gN;
|
||||
static float gFOV = 60.0f;
|
||||
|
||||
const Point& GetCameraPos()
|
||||
{
|
||||
return gEye;
|
||||
}
|
||||
|
||||
const Point& GetCameraDir()
|
||||
{
|
||||
return gDir;
|
||||
}
|
||||
|
||||
void MoveCameraForward()
|
||||
{
|
||||
gEye += gDir * gCamSpeed;
|
||||
}
|
||||
|
||||
void MoveCameraBackward()
|
||||
{
|
||||
gEye -= gDir * gCamSpeed;
|
||||
}
|
||||
|
||||
void MoveCameraRight()
|
||||
{
|
||||
gEye -= gN * gCamSpeed;
|
||||
}
|
||||
|
||||
void MoveCameraLeft()
|
||||
{
|
||||
gEye += gN * gCamSpeed;
|
||||
}
|
||||
|
||||
static const float NxPiF32 = 3.141592653589793f;
|
||||
|
||||
float degToRad(float a)
|
||||
{
|
||||
return (float)0.01745329251994329547 * a;
|
||||
}
|
||||
|
||||
class NxQuat
|
||||
{
|
||||
public:
|
||||
NxQuat(){}
|
||||
|
||||
NxQuat(const float angle, const Point & axis)
|
||||
{
|
||||
x = axis.x;
|
||||
y = axis.y;
|
||||
z = axis.z;
|
||||
|
||||
const float i_length = 1.0f / sqrtf( x*x + y*y + z*z );
|
||||
x = x * i_length;
|
||||
y = y * i_length;
|
||||
z = z * i_length;
|
||||
|
||||
float Half = degToRad(angle * 0.5f);
|
||||
|
||||
w = cosf(Half);
|
||||
const float sin_theta_over_two = sinf(Half );
|
||||
x = x * sin_theta_over_two;
|
||||
y = y * sin_theta_over_two;
|
||||
z = z * sin_theta_over_two;
|
||||
}
|
||||
|
||||
void NxQuat::multiply(const NxQuat& left, const Point& right)
|
||||
{
|
||||
float a,b,c,d;
|
||||
|
||||
a = - left.x*right.x - left.y*right.y - left.z *right.z;
|
||||
b = left.w*right.x + left.y*right.z - right.y*left.z;
|
||||
c = left.w*right.y + left.z*right.x - right.z*left.x;
|
||||
d = left.w*right.z + left.x*right.y - right.x*left.y;
|
||||
|
||||
w = a;
|
||||
x = b;
|
||||
y = c;
|
||||
z = d;
|
||||
}
|
||||
|
||||
void NxQuat::rotate(Point & v) const
|
||||
{
|
||||
NxQuat myInverse;
|
||||
myInverse.x = -x;
|
||||
myInverse.y = -y;
|
||||
myInverse.z = -z;
|
||||
myInverse.w = w;
|
||||
|
||||
NxQuat left;
|
||||
left.multiply(*this,v);
|
||||
v.x = left.w*myInverse.x + myInverse.w*left.x + left.y*myInverse.z - myInverse.y*left.z;
|
||||
v.y = left.w*myInverse.y + myInverse.w*left.y + left.z*myInverse.x - myInverse.z*left.x;
|
||||
v.z = left.w*myInverse.z + myInverse.w*left.z + left.x*myInverse.y - myInverse.x*left.y;
|
||||
}
|
||||
|
||||
float x,y,z,w;
|
||||
};
|
||||
|
||||
void RotateCamera(int dx, int dy)
|
||||
{
|
||||
gDir = gDir.Normalize();
|
||||
gN = gDir ^ Point(0,1,0);
|
||||
|
||||
NxQuat qx(NxPiF32 * dx * 20/ 180.0f, Point(0,1,0));
|
||||
qx.rotate(gDir);
|
||||
NxQuat qy(NxPiF32 * dy * 20/ 180.0f, gN);
|
||||
qy.rotate(gDir);
|
||||
}
|
||||
|
||||
void SetupCameraMatrix()
|
||||
{
|
||||
glLoadIdentity();
|
||||
gluPerspective(gFOV, ((float)glutGet(GLUT_WINDOW_WIDTH))/((float)glutGet(GLUT_WINDOW_HEIGHT)), 1.0f, 10000.0f);
|
||||
gluLookAt(gEye.x, gEye.y, gEye.z, gEye.x + gDir.x, gEye.y + gDir.y, gEye.z + gDir.z, 0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
|
||||
Point ComputeWorldRay(int xs, int ys)
|
||||
{
|
||||
GLint viewPort[4];
|
||||
GLdouble modelMatrix[16];
|
||||
GLdouble projMatrix[16];
|
||||
glGetIntegerv(GL_VIEWPORT, viewPort);
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
|
||||
ys = viewPort[3] - ys - 1;
|
||||
GLdouble wx0, wy0, wz0;
|
||||
gluUnProject((GLdouble) xs, (GLdouble) ys, 0.0, modelMatrix, projMatrix, viewPort, &wx0, &wy0, &wz0);
|
||||
GLdouble wx1, wy1, wz1;
|
||||
gluUnProject((GLdouble) xs, (GLdouble) ys, 1.0, modelMatrix, projMatrix, viewPort, &wx1, &wy1, &wz1);
|
||||
Point tmp(float(wx1-wx0), float(wy1-wy0), float(wz1-wz0));
|
||||
tmp.Normalize();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
const Point& GetCameraPos();
|
||||
const Point& GetCameraDir();
|
||||
void RotateCamera(int dx, int dy);
|
||||
|
||||
void MoveCameraForward();
|
||||
void MoveCameraBackward();
|
||||
void MoveCameraRight();
|
||||
void MoveCameraLeft();
|
||||
|
||||
void SetupCameraMatrix();
|
||||
Point ComputeWorldRay(int xs, int ys);
|
||||
|
||||
#endif // CAMERA_H
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
const Point& GetCameraPos();
|
||||
const Point& GetCameraDir();
|
||||
void RotateCamera(int dx, int dy);
|
||||
|
||||
void MoveCameraForward();
|
||||
void MoveCameraBackward();
|
||||
void MoveCameraRight();
|
||||
void MoveCameraLeft();
|
||||
|
||||
void SetupCameraMatrix();
|
||||
Point ComputeWorldRay(int xs, int ys);
|
||||
|
||||
#endif // CAMERA_H
|
||||
|
||||
@@ -1,127 +1,127 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "IceHelpers.h"
|
||||
#include "RenderingHelpers.h"
|
||||
#include "Terrain.h"
|
||||
#include "CapsuleMeshQuery.h"
|
||||
#include "Camera.h"
|
||||
#include "GLFontRenderer.h"
|
||||
|
||||
CapsuleMeshQuery::CapsuleMeshQuery() :
|
||||
mBar (null),
|
||||
mDist (0.0f),
|
||||
mValidHit (false)
|
||||
{
|
||||
}
|
||||
|
||||
CapsuleMeshQuery::~CapsuleMeshQuery()
|
||||
{
|
||||
}
|
||||
|
||||
void CapsuleMeshQuery::Init()
|
||||
{
|
||||
mP0 = Point(0.0f, -4.0f, 0.0f);
|
||||
mP1 = Point(0.0f, 4.0f, 0.0f);
|
||||
|
||||
Matrix3x3 MX,MY;
|
||||
RotX(MX, 45.0f);
|
||||
RotY(MY, 45.0f);
|
||||
|
||||
mWorld = MX * MY;
|
||||
mWorld.SetTrans(0.0f, 4.0f, 0.0f);
|
||||
}
|
||||
|
||||
void CapsuleMeshQuery::Release()
|
||||
{
|
||||
}
|
||||
|
||||
void CapsuleMeshQuery::PerformTest()
|
||||
{
|
||||
RenderTerrain();
|
||||
|
||||
mCapsule.mP0 = mP0 * mWorld;
|
||||
mCapsule.mP1 = mP1 * mWorld;
|
||||
mCapsule.mRadius = 1.0f;
|
||||
DrawCapsule(mWorld, mP0, mP1, 1.0f);
|
||||
|
||||
const Model* TM = GetTerrainModel();
|
||||
if(TM)
|
||||
{
|
||||
LSSCollider Collider;
|
||||
|
||||
mProfiler.Start();
|
||||
bool Status = Collider.Collide(mCache, mCapsule, *TM, null, null);
|
||||
mProfiler.End();
|
||||
mProfiler.Accum();
|
||||
|
||||
if(Status)
|
||||
{
|
||||
if(Collider.GetContactStatus())
|
||||
{
|
||||
udword NbTris = Collider.GetNbTouchedPrimitives();
|
||||
const udword* Indices = Collider.GetTouchedPrimitives();
|
||||
|
||||
RenderTerrainTriangles(NbTris, Indices);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Raycast hit
|
||||
if(mValidHit)
|
||||
{
|
||||
Point wp = mLocalHit + (Point)mWorld.GetTrans();
|
||||
DrawLine(wp, wp + Point(1.0f, 0.0f, 0.0f), Point(1,0,0), 1.0f);
|
||||
DrawLine(wp, wp + Point(0.0f, 1.0f, 0.0f), Point(0,1,0), 1.0f);
|
||||
DrawLine(wp, wp + Point(0.0f, 0.0f, 1.0f), Point(0,0,1), 1.0f);
|
||||
}
|
||||
|
||||
char Buffer[4096];
|
||||
sprintf(Buffer, "Capsule-mesh query = %5.1f us (%d cycles)\n", mProfiler.mMsTime, mProfiler.mCycles);
|
||||
GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer);
|
||||
}
|
||||
|
||||
void CapsuleMeshQuery::KeyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void CapsuleMeshQuery::MouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
mValidHit = false;
|
||||
if(!button && !state)
|
||||
{
|
||||
Point Dir = ComputeWorldRay(x, y);
|
||||
|
||||
float s[2];
|
||||
if(RayCapsuleOverlap(GetCameraPos(), Dir, mCapsule, s))
|
||||
{
|
||||
mValidHit = true;
|
||||
mDist = s[0];
|
||||
Point hit = GetCameraPos() + Dir * mDist;
|
||||
mLocalHit = hit - (Point)mWorld.GetTrans();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CapsuleMeshQuery::MotionCallback(int x, int y)
|
||||
{
|
||||
if(mValidHit)
|
||||
{
|
||||
Point Dir = ComputeWorldRay(x, y);
|
||||
mWorld.SetTrans(GetCameraPos() + Dir*mDist - mLocalHit);
|
||||
}
|
||||
}
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "IceHelpers.h"
|
||||
#include "RenderingHelpers.h"
|
||||
#include "Terrain.h"
|
||||
#include "CapsuleMeshQuery.h"
|
||||
#include "Camera.h"
|
||||
#include "GLFontRenderer.h"
|
||||
|
||||
CapsuleMeshQuery::CapsuleMeshQuery() :
|
||||
mBar (null),
|
||||
mDist (0.0f),
|
||||
mValidHit (false)
|
||||
{
|
||||
}
|
||||
|
||||
CapsuleMeshQuery::~CapsuleMeshQuery()
|
||||
{
|
||||
}
|
||||
|
||||
void CapsuleMeshQuery::Init()
|
||||
{
|
||||
mP0 = Point(0.0f, -4.0f, 0.0f);
|
||||
mP1 = Point(0.0f, 4.0f, 0.0f);
|
||||
|
||||
Matrix3x3 MX,MY;
|
||||
RotX(MX, 45.0f);
|
||||
RotY(MY, 45.0f);
|
||||
|
||||
mWorld = MX * MY;
|
||||
mWorld.SetTrans(0.0f, 4.0f, 0.0f);
|
||||
}
|
||||
|
||||
void CapsuleMeshQuery::Release()
|
||||
{
|
||||
}
|
||||
|
||||
void CapsuleMeshQuery::PerformTest()
|
||||
{
|
||||
RenderTerrain();
|
||||
|
||||
mCapsule.mP0 = mP0 * mWorld;
|
||||
mCapsule.mP1 = mP1 * mWorld;
|
||||
mCapsule.mRadius = 1.0f;
|
||||
DrawCapsule(mWorld, mP0, mP1, 1.0f);
|
||||
|
||||
const Model* TM = GetTerrainModel();
|
||||
if(TM)
|
||||
{
|
||||
LSSCollider Collider;
|
||||
|
||||
mProfiler.Start();
|
||||
bool Status = Collider.Collide(mCache, mCapsule, *TM, null, null);
|
||||
mProfiler.End();
|
||||
mProfiler.Accum();
|
||||
|
||||
if(Status)
|
||||
{
|
||||
if(Collider.GetContactStatus())
|
||||
{
|
||||
udword NbTris = Collider.GetNbTouchedPrimitives();
|
||||
const udword* Indices = Collider.GetTouchedPrimitives();
|
||||
|
||||
RenderTerrainTriangles(NbTris, Indices);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Raycast hit
|
||||
if(mValidHit)
|
||||
{
|
||||
Point wp = mLocalHit + (Point)mWorld.GetTrans();
|
||||
DrawLine(wp, wp + Point(1.0f, 0.0f, 0.0f), Point(1,0,0), 1.0f);
|
||||
DrawLine(wp, wp + Point(0.0f, 1.0f, 0.0f), Point(0,1,0), 1.0f);
|
||||
DrawLine(wp, wp + Point(0.0f, 0.0f, 1.0f), Point(0,0,1), 1.0f);
|
||||
}
|
||||
|
||||
char Buffer[4096];
|
||||
sprintf(Buffer, "Capsule-mesh query = %5.1f us (%d cycles)\n", mProfiler.mMsTime, mProfiler.mCycles);
|
||||
GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer);
|
||||
}
|
||||
|
||||
void CapsuleMeshQuery::KeyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void CapsuleMeshQuery::MouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
mValidHit = false;
|
||||
if(!button && !state)
|
||||
{
|
||||
Point Dir = ComputeWorldRay(x, y);
|
||||
|
||||
float s[2];
|
||||
if(RayCapsuleOverlap(GetCameraPos(), Dir, mCapsule, s))
|
||||
{
|
||||
mValidHit = true;
|
||||
mDist = s[0];
|
||||
Point hit = GetCameraPos() + Dir * mDist;
|
||||
mLocalHit = hit - (Point)mWorld.GetTrans();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CapsuleMeshQuery::MotionCallback(int x, int y)
|
||||
{
|
||||
if(mValidHit)
|
||||
{
|
||||
Point Dir = ComputeWorldRay(x, y);
|
||||
mWorld.SetTrans(GetCameraPos() + Dir*mDist - mLocalHit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 CAPSULEMESHQUERY_H
|
||||
#define CAPSULEMESHQUERY_H
|
||||
|
||||
#include "CollisionTest.h"
|
||||
#include "Profiling.h"
|
||||
|
||||
class CapsuleMeshQuery : public CollisionTest
|
||||
{
|
||||
public:
|
||||
CapsuleMeshQuery();
|
||||
virtual ~CapsuleMeshQuery();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Release();
|
||||
virtual void PerformTest();
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y);
|
||||
virtual void MouseCallback(int button, int state, int x, int y);
|
||||
virtual void MotionCallback(int x, int y);
|
||||
|
||||
TwBar* mBar; //!< AntTweakBar
|
||||
Profiler mProfiler;
|
||||
|
||||
Point mP0;
|
||||
Point mP1;
|
||||
Matrix4x4 mWorld;
|
||||
LSS mCapsule;
|
||||
LSSCache mCache;
|
||||
|
||||
float mDist;
|
||||
Point mLocalHit;
|
||||
bool mValidHit;
|
||||
};
|
||||
|
||||
#endif // CAPSULEMESHQUERY_H
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 CAPSULEMESHQUERY_H
|
||||
#define CAPSULEMESHQUERY_H
|
||||
|
||||
#include "CollisionTest.h"
|
||||
#include "Profiling.h"
|
||||
|
||||
class CapsuleMeshQuery : public CollisionTest
|
||||
{
|
||||
public:
|
||||
CapsuleMeshQuery();
|
||||
virtual ~CapsuleMeshQuery();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Release();
|
||||
virtual void PerformTest();
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y);
|
||||
virtual void MouseCallback(int button, int state, int x, int y);
|
||||
virtual void MotionCallback(int x, int y);
|
||||
|
||||
TwBar* mBar; //!< AntTweakBar
|
||||
Profiler mProfiler;
|
||||
|
||||
Point mP0;
|
||||
Point mP1;
|
||||
Matrix4x4 mWorld;
|
||||
LSS mCapsule;
|
||||
LSSCache mCache;
|
||||
|
||||
float mDist;
|
||||
Point mLocalHit;
|
||||
bool mValidHit;
|
||||
};
|
||||
|
||||
#endif // CAPSULEMESHQUERY_H
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "CollisionTest.h"
|
||||
|
||||
OpcodeSettings::OpcodeSettings() :
|
||||
mPrimitiveTests (true),
|
||||
mFirstContact (false),
|
||||
mUseCache (false)
|
||||
{
|
||||
}
|
||||
|
||||
void OpcodeSettings::AddToTweakBar(TwBar* tbar)
|
||||
{
|
||||
TwAddVarRW(tbar, "Primitive tests", TW_TYPE_BOOLCPP, &mPrimitiveTests, " group='Opcode' ");
|
||||
TwAddVarRW(tbar, "First contact", TW_TYPE_BOOLCPP, &mFirstContact, " group='Opcode' ");
|
||||
TwAddVarRW(tbar, "Temporal coherence", TW_TYPE_BOOLCPP, &mUseCache, " group='Opcode' ");
|
||||
}
|
||||
|
||||
void OpcodeSettings::SetupCollider(Collider& collider) const
|
||||
{
|
||||
collider.SetFirstContact(mFirstContact);
|
||||
collider.SetPrimitiveTests(mPrimitiveTests);
|
||||
collider.SetTemporalCoherence(mUseCache);
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "CollisionTest.h"
|
||||
|
||||
OpcodeSettings::OpcodeSettings() :
|
||||
mPrimitiveTests (true),
|
||||
mFirstContact (false),
|
||||
mUseCache (false)
|
||||
{
|
||||
}
|
||||
|
||||
void OpcodeSettings::AddToTweakBar(TwBar* tbar)
|
||||
{
|
||||
TwAddVarRW(tbar, "Primitive tests", TW_TYPE_BOOLCPP, &mPrimitiveTests, " group='Opcode' ");
|
||||
TwAddVarRW(tbar, "First contact", TW_TYPE_BOOLCPP, &mFirstContact, " group='Opcode' ");
|
||||
TwAddVarRW(tbar, "Temporal coherence", TW_TYPE_BOOLCPP, &mUseCache, " group='Opcode' ");
|
||||
}
|
||||
|
||||
void OpcodeSettings::SetupCollider(Collider& collider) const
|
||||
{
|
||||
collider.SetFirstContact(mFirstContact);
|
||||
collider.SetPrimitiveTests(mPrimitiveTests);
|
||||
collider.SetTemporalCoherence(mUseCache);
|
||||
}
|
||||
@@ -1,50 +1,50 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 COLLISIONTEST_H
|
||||
#define COLLISIONTEST_H
|
||||
|
||||
class CollisionTest
|
||||
{
|
||||
public:
|
||||
|
||||
CollisionTest() {}
|
||||
virtual ~CollisionTest() {}
|
||||
|
||||
virtual void Init() = 0;
|
||||
virtual void Release() = 0;
|
||||
virtual void PerformTest() = 0;
|
||||
virtual void Select() {}
|
||||
virtual void Deselect() {}
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y) {}
|
||||
virtual void MouseCallback(int button, int state, int x, int y) {}
|
||||
virtual void MotionCallback(int x, int y) {}
|
||||
};
|
||||
|
||||
class OpcodeSettings
|
||||
{
|
||||
public:
|
||||
OpcodeSettings();
|
||||
|
||||
void AddToTweakBar(TwBar* tbar);
|
||||
void SetupCollider(Collider& collider) const;
|
||||
|
||||
bool mPrimitiveTests;
|
||||
bool mFirstContact;
|
||||
bool mUseCache;
|
||||
};
|
||||
|
||||
#endif // COLLISIONTEST_H
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 COLLISIONTEST_H
|
||||
#define COLLISIONTEST_H
|
||||
|
||||
class CollisionTest
|
||||
{
|
||||
public:
|
||||
|
||||
CollisionTest() {}
|
||||
virtual ~CollisionTest() {}
|
||||
|
||||
virtual void Init() = 0;
|
||||
virtual void Release() = 0;
|
||||
virtual void PerformTest() = 0;
|
||||
virtual void Select() {}
|
||||
virtual void Deselect() {}
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y) {}
|
||||
virtual void MouseCallback(int button, int state, int x, int y) {}
|
||||
virtual void MotionCallback(int x, int y) {}
|
||||
};
|
||||
|
||||
class OpcodeSettings
|
||||
{
|
||||
public:
|
||||
OpcodeSettings();
|
||||
|
||||
void AddToTweakBar(TwBar* tbar);
|
||||
void SetupCollider(Collider& collider) const;
|
||||
|
||||
bool mPrimitiveTests;
|
||||
bool mFirstContact;
|
||||
bool mUseCache;
|
||||
};
|
||||
|
||||
#endif // COLLISIONTEST_H
|
||||
|
||||
@@ -1,168 +1,168 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "CompleteBoxPruning.h"
|
||||
#include "RenderingHelpers.h"
|
||||
#include "GLFontRenderer.h"
|
||||
|
||||
CompleteBoxPruningTest::CompleteBoxPruningTest(int numBoxes) :
|
||||
mBar (null),
|
||||
mNbBoxes (numBoxes),
|
||||
mBoxes (null),
|
||||
mBoxPtrs (null),
|
||||
mBoxTime (null),
|
||||
mSpeed (0.005f),
|
||||
mAmplitude (100.0f)
|
||||
{
|
||||
}
|
||||
|
||||
CompleteBoxPruningTest::~CompleteBoxPruningTest()
|
||||
{
|
||||
DELETEARRAY(mBoxTime);
|
||||
DELETEARRAY(mBoxPtrs);
|
||||
DELETEARRAY(mBoxes);
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::Init()
|
||||
{
|
||||
m_firstTime = true;
|
||||
|
||||
SRand(0);
|
||||
mBoxes = new AABB[mNbBoxes];
|
||||
mBoxPtrs = new const AABB*[mNbBoxes];
|
||||
mBoxTime = new float[mNbBoxes];
|
||||
for(udword i=0;i<mNbBoxes;i++)
|
||||
{
|
||||
Point Center, Extents;
|
||||
|
||||
Center.x = (UnitRandomFloat()-0.5f) * 100.0f;
|
||||
Center.y = (UnitRandomFloat()-0.5f) * 10.0f;
|
||||
Center.z = (UnitRandomFloat()-0.5f) * 100.0f;
|
||||
Extents.x = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
Extents.y = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
Extents.z = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
|
||||
mBoxes[i].SetCenterExtents(Center, Extents);
|
||||
mBoxPtrs[i] = &mBoxes[i];
|
||||
|
||||
mBoxTime[i] = 2000.0f*UnitRandomFloat();
|
||||
}
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::Release()
|
||||
{
|
||||
DELETEARRAY(mBoxTime);
|
||||
DELETEARRAY(mBoxes);
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::Select()
|
||||
{
|
||||
// Create a tweak bar
|
||||
{
|
||||
mBar = TwNewBar("OPC_CompleteBoxPruning");
|
||||
TwAddVarRW(mBar, "Speed", TW_TYPE_FLOAT, &mSpeed, " min=0.0 max=0.01 step=0.00001");
|
||||
TwAddVarRW(mBar, "Amplitude", TW_TYPE_FLOAT, &mAmplitude, " min=10.0 max=200.0 step=0.1");
|
||||
}
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::Deselect()
|
||||
{
|
||||
if(mBar)
|
||||
{
|
||||
TwDeleteBar(mBar);
|
||||
mBar = null;
|
||||
}
|
||||
}
|
||||
|
||||
bool CompleteBoxPruningTest::UpdateBoxes(int numBoxes)
|
||||
{
|
||||
for(udword i=0;i<numBoxes;i++)
|
||||
{
|
||||
mBoxTime[i] += mSpeed;
|
||||
|
||||
Point Center,Extents;
|
||||
mBoxes[i].GetExtents(Extents);
|
||||
|
||||
Center.x = cosf(mBoxTime[i]*2.17f)*mAmplitude + sinf(mBoxTime[i])*mAmplitude*0.5f;
|
||||
Center.y = cosf(mBoxTime[i]*1.38f)*mAmplitude + sinf(mBoxTime[i]*mAmplitude);
|
||||
Center.z = sinf(mBoxTime[i]*0.777f)*mAmplitude;
|
||||
|
||||
mBoxes[i].SetCenterExtents(Center, Extents);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
extern int percentUpdate;
|
||||
|
||||
void CompleteBoxPruningTest::PerformTest()
|
||||
{
|
||||
int numBoxes = (mNbBoxes*percentUpdate)/100;
|
||||
if (m_firstTime)
|
||||
{
|
||||
numBoxes = mNbBoxes;
|
||||
m_firstTime = false;
|
||||
}
|
||||
|
||||
mProfiler.Start();
|
||||
UpdateBoxes(numBoxes);
|
||||
|
||||
mPairs.ResetPairs();
|
||||
|
||||
|
||||
|
||||
CompleteBoxPruning(mNbBoxes, mBoxPtrs, mPairs, Axes(AXES_XZY));
|
||||
mProfiler.End();
|
||||
mProfiler.Accum();
|
||||
|
||||
// printf("%d pairs colliding\r ", mPairs.GetNbPairs());
|
||||
|
||||
bool* Flags = (bool*)_alloca(sizeof(bool)*mNbBoxes);
|
||||
ZeroMemory(Flags, sizeof(bool)*mNbBoxes);
|
||||
const Pair* P = mPairs.GetPairs();
|
||||
for(udword i=0;i<mPairs.GetNbPairs();i++)
|
||||
{
|
||||
Flags[P[i].id0] = true;
|
||||
Flags[P[i].id1] = true;
|
||||
}
|
||||
|
||||
// Render boxes
|
||||
OBB CurrentBox;
|
||||
CurrentBox.mRot.Identity();
|
||||
for(udword i=0;i<mNbBoxes;i++)
|
||||
{
|
||||
if(Flags[i]) glColor3f(1.0f, 0.0f, 0.0f);
|
||||
else glColor3f(0.0f, 1.0f, 0.0f);
|
||||
mBoxes[i].GetCenter(CurrentBox.mCenter);
|
||||
mBoxes[i].GetExtents(CurrentBox.mExtents);
|
||||
DrawOBB(CurrentBox);
|
||||
}
|
||||
|
||||
char Buffer[4096];
|
||||
sprintf(Buffer, "CompleteBoxPruning: %5.1f us (%d cycles) : %d pairs\n", mProfiler.mMsTime, mProfiler.mCycles, mPairs.GetNbPairs());
|
||||
GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer);
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::KeyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::MouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::MotionCallback(int x, int y)
|
||||
{
|
||||
}
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "CompleteBoxPruning.h"
|
||||
#include "RenderingHelpers.h"
|
||||
#include "GLFontRenderer.h"
|
||||
|
||||
CompleteBoxPruningTest::CompleteBoxPruningTest(int numBoxes) :
|
||||
mBar (null),
|
||||
mNbBoxes (numBoxes),
|
||||
mBoxes (null),
|
||||
mBoxPtrs (null),
|
||||
mBoxTime (null),
|
||||
mSpeed (0.005f),
|
||||
mAmplitude (100.0f)
|
||||
{
|
||||
}
|
||||
|
||||
CompleteBoxPruningTest::~CompleteBoxPruningTest()
|
||||
{
|
||||
DELETEARRAY(mBoxTime);
|
||||
DELETEARRAY(mBoxPtrs);
|
||||
DELETEARRAY(mBoxes);
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::Init()
|
||||
{
|
||||
m_firstTime = true;
|
||||
|
||||
SRand(0);
|
||||
mBoxes = new AABB[mNbBoxes];
|
||||
mBoxPtrs = new const AABB*[mNbBoxes];
|
||||
mBoxTime = new float[mNbBoxes];
|
||||
for(udword i=0;i<mNbBoxes;i++)
|
||||
{
|
||||
Point Center, Extents;
|
||||
|
||||
Center.x = (UnitRandomFloat()-0.5f) * 100.0f;
|
||||
Center.y = (UnitRandomFloat()-0.5f) * 10.0f;
|
||||
Center.z = (UnitRandomFloat()-0.5f) * 100.0f;
|
||||
Extents.x = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
Extents.y = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
Extents.z = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
|
||||
mBoxes[i].SetCenterExtents(Center, Extents);
|
||||
mBoxPtrs[i] = &mBoxes[i];
|
||||
|
||||
mBoxTime[i] = 2000.0f*UnitRandomFloat();
|
||||
}
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::Release()
|
||||
{
|
||||
DELETEARRAY(mBoxTime);
|
||||
DELETEARRAY(mBoxes);
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::Select()
|
||||
{
|
||||
// Create a tweak bar
|
||||
{
|
||||
mBar = TwNewBar("OPC_CompleteBoxPruning");
|
||||
TwAddVarRW(mBar, "Speed", TW_TYPE_FLOAT, &mSpeed, " min=0.0 max=0.01 step=0.00001");
|
||||
TwAddVarRW(mBar, "Amplitude", TW_TYPE_FLOAT, &mAmplitude, " min=10.0 max=200.0 step=0.1");
|
||||
}
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::Deselect()
|
||||
{
|
||||
if(mBar)
|
||||
{
|
||||
TwDeleteBar(mBar);
|
||||
mBar = null;
|
||||
}
|
||||
}
|
||||
|
||||
bool CompleteBoxPruningTest::UpdateBoxes(int numBoxes)
|
||||
{
|
||||
for(udword i=0;i<numBoxes;i++)
|
||||
{
|
||||
mBoxTime[i] += mSpeed;
|
||||
|
||||
Point Center,Extents;
|
||||
mBoxes[i].GetExtents(Extents);
|
||||
|
||||
Center.x = cosf(mBoxTime[i]*2.17f)*mAmplitude + sinf(mBoxTime[i])*mAmplitude*0.5f;
|
||||
Center.y = cosf(mBoxTime[i]*1.38f)*mAmplitude + sinf(mBoxTime[i]*mAmplitude);
|
||||
Center.z = sinf(mBoxTime[i]*0.777f)*mAmplitude;
|
||||
|
||||
mBoxes[i].SetCenterExtents(Center, Extents);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
extern int percentUpdate;
|
||||
|
||||
void CompleteBoxPruningTest::PerformTest()
|
||||
{
|
||||
int numBoxes = (mNbBoxes*percentUpdate)/100;
|
||||
if (m_firstTime)
|
||||
{
|
||||
numBoxes = mNbBoxes;
|
||||
m_firstTime = false;
|
||||
}
|
||||
|
||||
mProfiler.Start();
|
||||
UpdateBoxes(numBoxes);
|
||||
|
||||
mPairs.ResetPairs();
|
||||
|
||||
|
||||
|
||||
CompleteBoxPruning(mNbBoxes, mBoxPtrs, mPairs, Axes(AXES_XZY));
|
||||
mProfiler.End();
|
||||
mProfiler.Accum();
|
||||
|
||||
// printf("%d pairs colliding\r ", mPairs.GetNbPairs());
|
||||
|
||||
bool* Flags = (bool*)_alloca(sizeof(bool)*mNbBoxes);
|
||||
ZeroMemory(Flags, sizeof(bool)*mNbBoxes);
|
||||
const Pair* P = mPairs.GetPairs();
|
||||
for(udword i=0;i<mPairs.GetNbPairs();i++)
|
||||
{
|
||||
Flags[P[i].id0] = true;
|
||||
Flags[P[i].id1] = true;
|
||||
}
|
||||
|
||||
// Render boxes
|
||||
OBB CurrentBox;
|
||||
CurrentBox.mRot.Identity();
|
||||
for(udword i=0;i<mNbBoxes;i++)
|
||||
{
|
||||
if(Flags[i]) glColor3f(1.0f, 0.0f, 0.0f);
|
||||
else glColor3f(0.0f, 1.0f, 0.0f);
|
||||
mBoxes[i].GetCenter(CurrentBox.mCenter);
|
||||
mBoxes[i].GetExtents(CurrentBox.mExtents);
|
||||
DrawOBB(CurrentBox);
|
||||
}
|
||||
|
||||
char Buffer[4096];
|
||||
sprintf(Buffer, "CompleteBoxPruning: %5.1f us (%d cycles) : %d pairs\n", mProfiler.mMsTime, mProfiler.mCycles, mPairs.GetNbPairs());
|
||||
GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer);
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::KeyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::MouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void CompleteBoxPruningTest::MotionCallback(int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 COMPLETEBOXPRUNING_H
|
||||
#define COMPLETEBOXPRUNING_H
|
||||
|
||||
#include "CollisionTest.h"
|
||||
#include "Profiling.h"
|
||||
|
||||
class CompleteBoxPruningTest : public CollisionTest
|
||||
{
|
||||
public:
|
||||
CompleteBoxPruningTest(int numBoxes);
|
||||
virtual ~CompleteBoxPruningTest();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Release();
|
||||
virtual void PerformTest();
|
||||
virtual void Select();
|
||||
virtual void Deselect();
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y);
|
||||
virtual void MouseCallback(int button, int state, int x, int y);
|
||||
virtual void MotionCallback(int x, int y);
|
||||
|
||||
TwBar* mBar; //!< AntTweakBar
|
||||
Profiler mProfiler;
|
||||
|
||||
udword mNbBoxes;
|
||||
AABB* mBoxes;
|
||||
const AABB** mBoxPtrs;
|
||||
Pairs mPairs;
|
||||
float* mBoxTime;
|
||||
float mSpeed;
|
||||
float mAmplitude;
|
||||
bool m_firstTime;
|
||||
|
||||
private:
|
||||
bool UpdateBoxes(int numBoxes);
|
||||
};
|
||||
|
||||
#endif // COMPLETEBOXPRUNING_H
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 COMPLETEBOXPRUNING_H
|
||||
#define COMPLETEBOXPRUNING_H
|
||||
|
||||
#include "CollisionTest.h"
|
||||
#include "Profiling.h"
|
||||
|
||||
class CompleteBoxPruningTest : public CollisionTest
|
||||
{
|
||||
public:
|
||||
CompleteBoxPruningTest(int numBoxes);
|
||||
virtual ~CompleteBoxPruningTest();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Release();
|
||||
virtual void PerformTest();
|
||||
virtual void Select();
|
||||
virtual void Deselect();
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y);
|
||||
virtual void MouseCallback(int button, int state, int x, int y);
|
||||
virtual void MotionCallback(int x, int y);
|
||||
|
||||
TwBar* mBar; //!< AntTweakBar
|
||||
Profiler mProfiler;
|
||||
|
||||
udword mNbBoxes;
|
||||
AABB* mBoxes;
|
||||
const AABB** mBoxPtrs;
|
||||
Pairs mPairs;
|
||||
float* mBoxTime;
|
||||
float mSpeed;
|
||||
float mAmplitude;
|
||||
bool m_firstTime;
|
||||
|
||||
private:
|
||||
bool UpdateBoxes(int numBoxes);
|
||||
};
|
||||
|
||||
#endif // COMPLETEBOXPRUNING_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,207 +1,207 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "GLFontData.h"
|
||||
#include "GLFontRenderer.h"
|
||||
|
||||
bool GLFontRenderer::m_isInit=false;
|
||||
unsigned int GLFontRenderer::m_textureObject=0;
|
||||
int GLFontRenderer::m_screenWidth=640;
|
||||
int GLFontRenderer::m_screenHeight=480;
|
||||
float GLFontRenderer::m_color[4]={1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
bool GLFontRenderer::init()
|
||||
{
|
||||
glGenTextures(1, &m_textureObject);
|
||||
if(m_textureObject == 0) return false;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureObject);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
// expand to rgba
|
||||
unsigned char* pNewSource = new unsigned char[OGL_FONT_TEXTURE_WIDTH*OGL_FONT_TEXTURE_HEIGHT*4];
|
||||
for(int i=0;i<OGL_FONT_TEXTURE_WIDTH*OGL_FONT_TEXTURE_HEIGHT;i++)
|
||||
{
|
||||
pNewSource[i*4+0]=255;
|
||||
pNewSource[i*4+1]=255;
|
||||
pNewSource[i*4+2]=255;
|
||||
pNewSource[i*4+3]=OGLFontData[i];
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, OGL_FONT_TEXTURE_WIDTH, OGL_FONT_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, pNewSource);
|
||||
delete[] pNewSource;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLFontRenderer::print(float x, float y, float fontSize, const char* pString, bool forceMonoSpace, int monoSpaceWidth, bool doOrthoProj)
|
||||
{
|
||||
// x = x*m_screenWidth;
|
||||
// y = y*m_screenHeight;
|
||||
fontSize = fontSize*m_screenHeight;
|
||||
|
||||
if(!m_isInit)
|
||||
{
|
||||
m_isInit = init();
|
||||
}
|
||||
|
||||
unsigned int num = (unsigned int)strlen(pString);
|
||||
if(m_isInit && num > 0)
|
||||
{
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureObject);
|
||||
|
||||
|
||||
if(doOrthoProj)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0, m_screenWidth, 0, m_screenHeight, -1, 1);
|
||||
}
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glColor4f(m_color[0], m_color[1], m_color[2], m_color[3]);
|
||||
|
||||
const float glyphHeightUV = ((float)OGL_FONT_CHARS_PER_COL)/OGL_FONT_TEXTURE_HEIGHT*2-0.01f;
|
||||
|
||||
float translate = 0.0f;
|
||||
|
||||
float* pVertList = new float[num*3*6];
|
||||
float* pTextureCoordList = new float[num*2*6];
|
||||
int vertIndex = 0;
|
||||
int textureCoordIndex = 0;
|
||||
|
||||
float translateDown = 0.0f;
|
||||
unsigned int count = 0;
|
||||
|
||||
for(unsigned int i=0;i<num; i++)
|
||||
{
|
||||
const float glyphWidthUV = ((float)OGL_FONT_CHARS_PER_ROW)/OGL_FONT_TEXTURE_WIDTH;
|
||||
|
||||
if (pString[i] == '\n') {
|
||||
translateDown-=0.005f*m_screenHeight+fontSize;
|
||||
translate = 0.0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
int c = pString[i]-OGL_FONT_CHAR_BASE;
|
||||
if (c < OGL_FONT_CHARS_PER_ROW*OGL_FONT_CHARS_PER_COL) {
|
||||
|
||||
count++;
|
||||
|
||||
float glyphWidth = (float)GLFontGlyphWidth[c];
|
||||
if(forceMonoSpace){
|
||||
glyphWidth = (float)monoSpaceWidth;
|
||||
}
|
||||
|
||||
glyphWidth = glyphWidth*(fontSize/(((float)OGL_FONT_TEXTURE_WIDTH)/OGL_FONT_CHARS_PER_ROW))-0.01f;
|
||||
|
||||
float cxUV = float((c)%OGL_FONT_CHARS_PER_ROW)/OGL_FONT_CHARS_PER_ROW+0.008f;
|
||||
float cyUV = float((c)/OGL_FONT_CHARS_PER_ROW)/OGL_FONT_CHARS_PER_COL+0.008f;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV+glyphHeightUV;
|
||||
pVertList[vertIndex++] = x+0+translate;
|
||||
pVertList[vertIndex++] = y+0+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV+glyphWidthUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV;
|
||||
pVertList[vertIndex++] = x+fontSize+translate;
|
||||
pVertList[vertIndex++] = y+fontSize+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV;
|
||||
pVertList[vertIndex++] = x+0+translate;
|
||||
pVertList[vertIndex++] = y+fontSize+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV+glyphHeightUV;
|
||||
pVertList[vertIndex++] = x+0+translate;
|
||||
pVertList[vertIndex++] = y+0+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV+glyphWidthUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV+glyphHeightUV;
|
||||
pVertList[vertIndex++] = x+fontSize+translate;
|
||||
pVertList[vertIndex++] = y+0+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV+glyphWidthUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV;
|
||||
pVertList[vertIndex++] = x+fontSize+translate;
|
||||
pVertList[vertIndex++] = y+fontSize+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
translate+=glyphWidth;
|
||||
}
|
||||
}
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, pVertList);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, pTextureCoordList);
|
||||
glDrawArrays(GL_TRIANGLES, 0, count*6);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
delete[] pVertList;
|
||||
delete[] pTextureCoordList;
|
||||
|
||||
if(doOrthoProj)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
}
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
void GLFontRenderer::setScreenResolution(int screenWidth, int screenHeight)
|
||||
{
|
||||
m_screenWidth = screenWidth;
|
||||
m_screenHeight = screenHeight;
|
||||
}
|
||||
|
||||
void GLFontRenderer::setColor(float r, float g, float b, float a)
|
||||
{
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
m_color[2] = b;
|
||||
m_color[3] = a;
|
||||
}
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "GLFontData.h"
|
||||
#include "GLFontRenderer.h"
|
||||
|
||||
bool GLFontRenderer::m_isInit=false;
|
||||
unsigned int GLFontRenderer::m_textureObject=0;
|
||||
int GLFontRenderer::m_screenWidth=640;
|
||||
int GLFontRenderer::m_screenHeight=480;
|
||||
float GLFontRenderer::m_color[4]={1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
bool GLFontRenderer::init()
|
||||
{
|
||||
glGenTextures(1, &m_textureObject);
|
||||
if(m_textureObject == 0) return false;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureObject);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
// expand to rgba
|
||||
unsigned char* pNewSource = new unsigned char[OGL_FONT_TEXTURE_WIDTH*OGL_FONT_TEXTURE_HEIGHT*4];
|
||||
for(int i=0;i<OGL_FONT_TEXTURE_WIDTH*OGL_FONT_TEXTURE_HEIGHT;i++)
|
||||
{
|
||||
pNewSource[i*4+0]=255;
|
||||
pNewSource[i*4+1]=255;
|
||||
pNewSource[i*4+2]=255;
|
||||
pNewSource[i*4+3]=OGLFontData[i];
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, OGL_FONT_TEXTURE_WIDTH, OGL_FONT_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, pNewSource);
|
||||
delete[] pNewSource;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLFontRenderer::print(float x, float y, float fontSize, const char* pString, bool forceMonoSpace, int monoSpaceWidth, bool doOrthoProj)
|
||||
{
|
||||
// x = x*m_screenWidth;
|
||||
// y = y*m_screenHeight;
|
||||
fontSize = fontSize*m_screenHeight;
|
||||
|
||||
if(!m_isInit)
|
||||
{
|
||||
m_isInit = init();
|
||||
}
|
||||
|
||||
unsigned int num = (unsigned int)strlen(pString);
|
||||
if(m_isInit && num > 0)
|
||||
{
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureObject);
|
||||
|
||||
|
||||
if(doOrthoProj)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0, m_screenWidth, 0, m_screenHeight, -1, 1);
|
||||
}
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glColor4f(m_color[0], m_color[1], m_color[2], m_color[3]);
|
||||
|
||||
const float glyphHeightUV = ((float)OGL_FONT_CHARS_PER_COL)/OGL_FONT_TEXTURE_HEIGHT*2-0.01f;
|
||||
|
||||
float translate = 0.0f;
|
||||
|
||||
float* pVertList = new float[num*3*6];
|
||||
float* pTextureCoordList = new float[num*2*6];
|
||||
int vertIndex = 0;
|
||||
int textureCoordIndex = 0;
|
||||
|
||||
float translateDown = 0.0f;
|
||||
unsigned int count = 0;
|
||||
|
||||
for(unsigned int i=0;i<num; i++)
|
||||
{
|
||||
const float glyphWidthUV = ((float)OGL_FONT_CHARS_PER_ROW)/OGL_FONT_TEXTURE_WIDTH;
|
||||
|
||||
if (pString[i] == '\n') {
|
||||
translateDown-=0.005f*m_screenHeight+fontSize;
|
||||
translate = 0.0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
int c = pString[i]-OGL_FONT_CHAR_BASE;
|
||||
if (c < OGL_FONT_CHARS_PER_ROW*OGL_FONT_CHARS_PER_COL) {
|
||||
|
||||
count++;
|
||||
|
||||
float glyphWidth = (float)GLFontGlyphWidth[c];
|
||||
if(forceMonoSpace){
|
||||
glyphWidth = (float)monoSpaceWidth;
|
||||
}
|
||||
|
||||
glyphWidth = glyphWidth*(fontSize/(((float)OGL_FONT_TEXTURE_WIDTH)/OGL_FONT_CHARS_PER_ROW))-0.01f;
|
||||
|
||||
float cxUV = float((c)%OGL_FONT_CHARS_PER_ROW)/OGL_FONT_CHARS_PER_ROW+0.008f;
|
||||
float cyUV = float((c)/OGL_FONT_CHARS_PER_ROW)/OGL_FONT_CHARS_PER_COL+0.008f;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV+glyphHeightUV;
|
||||
pVertList[vertIndex++] = x+0+translate;
|
||||
pVertList[vertIndex++] = y+0+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV+glyphWidthUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV;
|
||||
pVertList[vertIndex++] = x+fontSize+translate;
|
||||
pVertList[vertIndex++] = y+fontSize+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV;
|
||||
pVertList[vertIndex++] = x+0+translate;
|
||||
pVertList[vertIndex++] = y+fontSize+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV+glyphHeightUV;
|
||||
pVertList[vertIndex++] = x+0+translate;
|
||||
pVertList[vertIndex++] = y+0+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV+glyphWidthUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV+glyphHeightUV;
|
||||
pVertList[vertIndex++] = x+fontSize+translate;
|
||||
pVertList[vertIndex++] = y+0+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV+glyphWidthUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV;
|
||||
pVertList[vertIndex++] = x+fontSize+translate;
|
||||
pVertList[vertIndex++] = y+fontSize+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
translate+=glyphWidth;
|
||||
}
|
||||
}
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, pVertList);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, pTextureCoordList);
|
||||
glDrawArrays(GL_TRIANGLES, 0, count*6);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
delete[] pVertList;
|
||||
delete[] pTextureCoordList;
|
||||
|
||||
if(doOrthoProj)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
}
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
void GLFontRenderer::setScreenResolution(int screenWidth, int screenHeight)
|
||||
{
|
||||
m_screenWidth = screenWidth;
|
||||
m_screenHeight = screenHeight;
|
||||
}
|
||||
|
||||
void GLFontRenderer::setColor(float r, float g, float b, float a)
|
||||
{
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
m_color[2] = b;
|
||||
m_color[3] = a;
|
||||
}
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 GLFONTRENDERER_H
|
||||
#define GLFONTRENDERER_H
|
||||
|
||||
class GLFontRenderer{
|
||||
|
||||
private:
|
||||
|
||||
static bool m_isInit;
|
||||
static unsigned int m_textureObject;
|
||||
static int m_screenWidth;
|
||||
static int m_screenHeight;
|
||||
static float m_color[4];
|
||||
|
||||
public:
|
||||
|
||||
static bool init();
|
||||
static void print(float x, float y, float fontSize, const char* pString, bool forceMonoSpace=false, int monoSpaceWidth=11, bool doOrthoProj=true);
|
||||
static void setScreenResolution(int screenWidth, int screenHeight);
|
||||
static void setColor(float r, float g, float b, float a);
|
||||
|
||||
};
|
||||
|
||||
#endif // GLFONTRENDERER_H
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 GLFONTRENDERER_H
|
||||
#define GLFONTRENDERER_H
|
||||
|
||||
class GLFontRenderer{
|
||||
|
||||
private:
|
||||
|
||||
static bool m_isInit;
|
||||
static unsigned int m_textureObject;
|
||||
static int m_screenWidth;
|
||||
static int m_screenHeight;
|
||||
static float m_color[4];
|
||||
|
||||
public:
|
||||
|
||||
static bool init();
|
||||
static void print(float x, float y, float fontSize, const char* pString, bool forceMonoSpace=false, int monoSpaceWidth=11, bool doOrthoProj=true);
|
||||
static void setScreenResolution(int screenWidth, int screenHeight);
|
||||
static void setColor(float r, float g, float b, float a);
|
||||
|
||||
};
|
||||
|
||||
#endif // GLFONTRENDERER_H
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||
=========================
|
||||
|
||||
V 1.0 - March 16, 2007
|
||||
|
||||
- sphere vs mesh queries
|
||||
- OBB vs mesh queries
|
||||
- capsule vs mesh queries
|
||||
- complete box pruning
|
||||
- bipartite box pruning
|
||||
|
||||
|
||||
=========================
|
||||
|
||||
V 1.0 - March 16, 2007
|
||||
|
||||
- sphere vs mesh queries
|
||||
- OBB vs mesh queries
|
||||
- capsule vs mesh queries
|
||||
- complete box pruning
|
||||
- bipartite box pruning
|
||||
|
||||
|
||||
@@ -1,358 +1,358 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "IceHelpers.h"
|
||||
|
||||
// Misc functions borrowed & adapted from ICE
|
||||
|
||||
void RotX(Matrix3x3& m, float angle)
|
||||
{
|
||||
float Cos = cosf(angle);
|
||||
float Sin = sinf(angle);
|
||||
m.Identity();
|
||||
m.m[1][1] = m.m[2][2] = Cos;
|
||||
m.m[2][1] = -Sin;
|
||||
m.m[1][2] = Sin;
|
||||
}
|
||||
|
||||
void RotY(Matrix3x3& m, float angle)
|
||||
{
|
||||
float Cos = cosf(angle);
|
||||
float Sin = sinf(angle);
|
||||
m.Identity();
|
||||
m.m[0][0] = m.m[2][2] = Cos;
|
||||
m.m[2][0] = Sin;
|
||||
m.m[0][2] = -Sin;
|
||||
}
|
||||
|
||||
void RotZ(Matrix3x3& m, float angle)
|
||||
{
|
||||
float Cos = cosf(angle);
|
||||
float Sin = sinf(angle);
|
||||
m.Identity();
|
||||
m.m[0][0] = m.m[1][1] = Cos;
|
||||
m.m[1][0] = -Sin;
|
||||
m.m[0][1] = Sin;
|
||||
}
|
||||
|
||||
bool SegmentSphere(const Point& origin, const Point& dir, float length, const Point& center, float radius, float& dist, Point& hit_pos)
|
||||
{
|
||||
// get the offset vector
|
||||
Point offset = center - origin;
|
||||
|
||||
// get the distance along the ray to the center point of the sphere
|
||||
float ray_dist = dir | offset;
|
||||
|
||||
// get the squared distances
|
||||
float off2 = offset | offset;
|
||||
float rd2 = radius * radius;
|
||||
if(off2 <= rd2)
|
||||
{
|
||||
// we're in the sphere
|
||||
hit_pos = origin;
|
||||
dist = 0.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(ray_dist <= 0 || (ray_dist - length) > radius)
|
||||
{
|
||||
// moving away from object or too far away
|
||||
return false;
|
||||
}
|
||||
|
||||
// find hit distance squared
|
||||
float d = rd2 - (off2 - ray_dist * ray_dist);
|
||||
if(d<0.0f)
|
||||
{
|
||||
// ray passes by sphere without hitting
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the distance along the ray
|
||||
dist = ray_dist - sqrtf(d);
|
||||
if(dist > length)
|
||||
{
|
||||
// hit point beyond length
|
||||
return false;
|
||||
}
|
||||
|
||||
// sort out the details
|
||||
hit_pos = origin + dir * dist;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool /*Ctc::*/RayAABB2(const Point& min, const Point& max, const Point& origin, const Point& dir, Point& coord)
|
||||
{
|
||||
BOOL Inside = TRUE;
|
||||
Point MaxT;
|
||||
MaxT.x=MaxT.y=MaxT.z=-1.0f;
|
||||
|
||||
// Find candidate planes.
|
||||
for(udword i=0;i<3;i++)
|
||||
{
|
||||
if(origin[i] < min[i])
|
||||
{
|
||||
coord[i] = min[i];
|
||||
Inside = FALSE;
|
||||
|
||||
// Calculate T distances to candidate planes
|
||||
if(IR(dir[i])) MaxT[i] = (min[i] - origin[i]) / dir[i];
|
||||
}
|
||||
else if(origin[i] > max[i])
|
||||
{
|
||||
coord[i] = max[i];
|
||||
Inside = FALSE;
|
||||
|
||||
// Calculate T distances to candidate planes
|
||||
if(IR(dir[i])) MaxT[i] = (max[i] - origin[i]) / dir[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Ray origin inside bounding box
|
||||
if(Inside)
|
||||
{
|
||||
coord = origin;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get largest of the maxT's for final choice of intersection
|
||||
udword WhichPlane = 0;
|
||||
if(MaxT[1] > MaxT[WhichPlane]) WhichPlane = 1;
|
||||
if(MaxT[2] > MaxT[WhichPlane]) WhichPlane = 2;
|
||||
|
||||
// Check final candidate actually inside box
|
||||
if(IR(MaxT[WhichPlane])&0x80000000) return false;
|
||||
|
||||
for(udword i=0;i<3;i++)
|
||||
{
|
||||
if(i!=WhichPlane)
|
||||
{
|
||||
coord[i] = origin[i] + MaxT[WhichPlane] * dir[i];
|
||||
#ifdef RAYAABB_EPSILON
|
||||
if(coord[i] < min[i] - RAYAABB_EPSILON || coord[i] > max[i] + RAYAABB_EPSILON) return false;
|
||||
#else
|
||||
if(coord[i] < min[i] || coord[i] > max[i]) return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return true; // ray hits box
|
||||
}
|
||||
|
||||
static const bool gNormalize = true;
|
||||
|
||||
udword /*Ctc::*/RayCapsuleOverlap(const Point& origin, const Point& dir, const LSS& capsule, float s[2])
|
||||
{
|
||||
// set up quadratic Q(t) = a*t^2 + 2*b*t + c
|
||||
Point kU, kV, kW, capsDir;
|
||||
capsule.ComputeDirection(capsDir);
|
||||
kW = capsDir;
|
||||
|
||||
float fWLength = kW.Magnitude();
|
||||
kW.Normalize();
|
||||
|
||||
// generate orthonormal basis
|
||||
|
||||
float fInvLength;
|
||||
if ( fabsf(kW.x) >= fabsf(kW.y) )
|
||||
{
|
||||
// W.x or W.z is the largest magnitude component, swap them
|
||||
fInvLength = 1.0f/sqrtf(kW.x*kW.x + kW.z*kW.z);
|
||||
kU.x = -kW.z*fInvLength;
|
||||
kU.y = 0.0f;
|
||||
kU.z = +kW.x*fInvLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
// W.y or W.z is the largest magnitude component, swap them
|
||||
fInvLength = 1.0f/sqrtf(kW.y*kW.y + kW.z*kW.z);
|
||||
kU.x = 0.0f;
|
||||
kU.y = +kW.z*fInvLength;
|
||||
kU.z = -kW.y*fInvLength;
|
||||
}
|
||||
kV = kW^kU;
|
||||
kU.Normalize();
|
||||
if(gNormalize)
|
||||
kV.Normalize();
|
||||
|
||||
// compute intersection
|
||||
|
||||
Point kD(kU|dir, kV|dir, kW|dir);
|
||||
float fDLength = kD.Magnitude();
|
||||
kD.Normalize();
|
||||
|
||||
float fInvDLength = 1.0f/fDLength;
|
||||
Point kDiff = origin - capsule.mP0;
|
||||
Point kP(kU|kDiff, kV|kDiff, kW|kDiff);
|
||||
float fRadiusSqr = capsule.mRadius*capsule.mRadius;
|
||||
|
||||
float fInv, fA, fB, fC, fDiscr, fRoot, fT, fTmp;
|
||||
|
||||
// Is the velocity parallel to the capsule direction? (or zero)
|
||||
if ( fabsf(kD.z) >= 1.0f - FLT_EPSILON || fDLength < FLT_EPSILON )
|
||||
{
|
||||
|
||||
float fAxisDir = dir|capsDir;
|
||||
|
||||
fDiscr = fRadiusSqr - kP.x*kP.x - kP.y*kP.y;
|
||||
if ( fAxisDir < 0 && fDiscr >= 0.0f )
|
||||
{
|
||||
// Velocity anti-parallel to the capsule direction
|
||||
fRoot = sqrtf(fDiscr);
|
||||
s[0] = (kP.z + fRoot)*fInvDLength;
|
||||
s[1] = -(fWLength - kP.z + fRoot)*fInvDLength;
|
||||
return 2;
|
||||
}
|
||||
else if ( fAxisDir > 0 && fDiscr >= 0.0f )
|
||||
{
|
||||
// Velocity parallel to the capsule direction
|
||||
fRoot = sqrtf(fDiscr);
|
||||
s[0] = -(kP.z + fRoot)*fInvDLength;
|
||||
s[1] = (fWLength - kP.z + fRoot)*fInvDLength;
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// sphere heading wrong direction, or no velocity at all
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// test intersection with infinite cylinder
|
||||
fA = kD.x*kD.x + kD.y*kD.y;
|
||||
fB = kP.x*kD.x + kP.y*kD.y;
|
||||
fC = kP.x*kP.x + kP.y*kP.y - fRadiusSqr;
|
||||
fDiscr = fB*fB - fA*fC;
|
||||
if ( fDiscr < 0.0f )
|
||||
{
|
||||
// line does not intersect infinite cylinder
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iQuantity = 0;
|
||||
|
||||
if ( fDiscr > 0.0f )
|
||||
{
|
||||
// line intersects infinite cylinder in two places
|
||||
fRoot = sqrtf(fDiscr);
|
||||
fInv = 1.0f/fA;
|
||||
fT = (-fB - fRoot)*fInv;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( 0.0f <= fTmp && fTmp <= fWLength )
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
|
||||
fT = (-fB + fRoot)*fInv;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( 0.0f <= fTmp && fTmp <= fWLength )
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
|
||||
if ( iQuantity == 2 )
|
||||
{
|
||||
// line intersects capsule wall in two places
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// line is tangent to infinite cylinder
|
||||
fT = -fB/fA;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( 0.0f <= fTmp && fTmp <= fWLength )
|
||||
{
|
||||
s[0] = fT*fInvDLength;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// test intersection with bottom hemisphere
|
||||
// fA = 1
|
||||
fB += kP.z*kD.z;
|
||||
fC += kP.z*kP.z;
|
||||
fDiscr = fB*fB - fC;
|
||||
if ( fDiscr > 0.0f )
|
||||
{
|
||||
fRoot = sqrtf(fDiscr);
|
||||
fT = -fB - fRoot;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( fTmp <= 0.0f )
|
||||
{
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
if ( iQuantity == 2 )
|
||||
return 2;
|
||||
}
|
||||
|
||||
fT = -fB + fRoot;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( fTmp <= 0.0f )
|
||||
{
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
if ( iQuantity == 2 )
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else if ( fDiscr == 0.0f )
|
||||
{
|
||||
fT = -fB;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( fTmp <= 0.0f )
|
||||
{
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
if ( iQuantity == 2 )
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
// test intersection with top hemisphere
|
||||
// fA = 1
|
||||
fB -= kD.z*fWLength;
|
||||
fC += fWLength*(fWLength - 2.0f*kP.z);
|
||||
|
||||
fDiscr = fB*fB - fC;
|
||||
if ( fDiscr > 0.0f )
|
||||
{
|
||||
fRoot = sqrtf(fDiscr);
|
||||
fT = -fB - fRoot;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( fTmp >= fWLength )
|
||||
{
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
if ( iQuantity == 2 )
|
||||
return 2;
|
||||
}
|
||||
|
||||
fT = -fB + fRoot;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( fTmp >= fWLength )
|
||||
{
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
if ( iQuantity == 2 )
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else if ( fDiscr == 0.0f )
|
||||
{
|
||||
fT = -fB;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( fTmp >= fWLength )
|
||||
{
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
if ( iQuantity == 2 )
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
return iQuantity;
|
||||
}
|
||||
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "IceHelpers.h"
|
||||
|
||||
// Misc functions borrowed & adapted from ICE
|
||||
|
||||
void RotX(Matrix3x3& m, float angle)
|
||||
{
|
||||
float Cos = cosf(angle);
|
||||
float Sin = sinf(angle);
|
||||
m.Identity();
|
||||
m.m[1][1] = m.m[2][2] = Cos;
|
||||
m.m[2][1] = -Sin;
|
||||
m.m[1][2] = Sin;
|
||||
}
|
||||
|
||||
void RotY(Matrix3x3& m, float angle)
|
||||
{
|
||||
float Cos = cosf(angle);
|
||||
float Sin = sinf(angle);
|
||||
m.Identity();
|
||||
m.m[0][0] = m.m[2][2] = Cos;
|
||||
m.m[2][0] = Sin;
|
||||
m.m[0][2] = -Sin;
|
||||
}
|
||||
|
||||
void RotZ(Matrix3x3& m, float angle)
|
||||
{
|
||||
float Cos = cosf(angle);
|
||||
float Sin = sinf(angle);
|
||||
m.Identity();
|
||||
m.m[0][0] = m.m[1][1] = Cos;
|
||||
m.m[1][0] = -Sin;
|
||||
m.m[0][1] = Sin;
|
||||
}
|
||||
|
||||
bool SegmentSphere(const Point& origin, const Point& dir, float length, const Point& center, float radius, float& dist, Point& hit_pos)
|
||||
{
|
||||
// get the offset vector
|
||||
Point offset = center - origin;
|
||||
|
||||
// get the distance along the ray to the center point of the sphere
|
||||
float ray_dist = dir | offset;
|
||||
|
||||
// get the squared distances
|
||||
float off2 = offset | offset;
|
||||
float rd2 = radius * radius;
|
||||
if(off2 <= rd2)
|
||||
{
|
||||
// we're in the sphere
|
||||
hit_pos = origin;
|
||||
dist = 0.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(ray_dist <= 0 || (ray_dist - length) > radius)
|
||||
{
|
||||
// moving away from object or too far away
|
||||
return false;
|
||||
}
|
||||
|
||||
// find hit distance squared
|
||||
float d = rd2 - (off2 - ray_dist * ray_dist);
|
||||
if(d<0.0f)
|
||||
{
|
||||
// ray passes by sphere without hitting
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the distance along the ray
|
||||
dist = ray_dist - sqrtf(d);
|
||||
if(dist > length)
|
||||
{
|
||||
// hit point beyond length
|
||||
return false;
|
||||
}
|
||||
|
||||
// sort out the details
|
||||
hit_pos = origin + dir * dist;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool /*Ctc::*/RayAABB2(const Point& min, const Point& max, const Point& origin, const Point& dir, Point& coord)
|
||||
{
|
||||
BOOL Inside = TRUE;
|
||||
Point MaxT;
|
||||
MaxT.x=MaxT.y=MaxT.z=-1.0f;
|
||||
|
||||
// Find candidate planes.
|
||||
for(udword i=0;i<3;i++)
|
||||
{
|
||||
if(origin[i] < min[i])
|
||||
{
|
||||
coord[i] = min[i];
|
||||
Inside = FALSE;
|
||||
|
||||
// Calculate T distances to candidate planes
|
||||
if(IR(dir[i])) MaxT[i] = (min[i] - origin[i]) / dir[i];
|
||||
}
|
||||
else if(origin[i] > max[i])
|
||||
{
|
||||
coord[i] = max[i];
|
||||
Inside = FALSE;
|
||||
|
||||
// Calculate T distances to candidate planes
|
||||
if(IR(dir[i])) MaxT[i] = (max[i] - origin[i]) / dir[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Ray origin inside bounding box
|
||||
if(Inside)
|
||||
{
|
||||
coord = origin;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get largest of the maxT's for final choice of intersection
|
||||
udword WhichPlane = 0;
|
||||
if(MaxT[1] > MaxT[WhichPlane]) WhichPlane = 1;
|
||||
if(MaxT[2] > MaxT[WhichPlane]) WhichPlane = 2;
|
||||
|
||||
// Check final candidate actually inside box
|
||||
if(IR(MaxT[WhichPlane])&0x80000000) return false;
|
||||
|
||||
for(udword i=0;i<3;i++)
|
||||
{
|
||||
if(i!=WhichPlane)
|
||||
{
|
||||
coord[i] = origin[i] + MaxT[WhichPlane] * dir[i];
|
||||
#ifdef RAYAABB_EPSILON
|
||||
if(coord[i] < min[i] - RAYAABB_EPSILON || coord[i] > max[i] + RAYAABB_EPSILON) return false;
|
||||
#else
|
||||
if(coord[i] < min[i] || coord[i] > max[i]) return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return true; // ray hits box
|
||||
}
|
||||
|
||||
static const bool gNormalize = true;
|
||||
|
||||
udword /*Ctc::*/RayCapsuleOverlap(const Point& origin, const Point& dir, const LSS& capsule, float s[2])
|
||||
{
|
||||
// set up quadratic Q(t) = a*t^2 + 2*b*t + c
|
||||
Point kU, kV, kW, capsDir;
|
||||
capsule.ComputeDirection(capsDir);
|
||||
kW = capsDir;
|
||||
|
||||
float fWLength = kW.Magnitude();
|
||||
kW.Normalize();
|
||||
|
||||
// generate orthonormal basis
|
||||
|
||||
float fInvLength;
|
||||
if ( fabsf(kW.x) >= fabsf(kW.y) )
|
||||
{
|
||||
// W.x or W.z is the largest magnitude component, swap them
|
||||
fInvLength = 1.0f/sqrtf(kW.x*kW.x + kW.z*kW.z);
|
||||
kU.x = -kW.z*fInvLength;
|
||||
kU.y = 0.0f;
|
||||
kU.z = +kW.x*fInvLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
// W.y or W.z is the largest magnitude component, swap them
|
||||
fInvLength = 1.0f/sqrtf(kW.y*kW.y + kW.z*kW.z);
|
||||
kU.x = 0.0f;
|
||||
kU.y = +kW.z*fInvLength;
|
||||
kU.z = -kW.y*fInvLength;
|
||||
}
|
||||
kV = kW^kU;
|
||||
kU.Normalize();
|
||||
if(gNormalize)
|
||||
kV.Normalize();
|
||||
|
||||
// compute intersection
|
||||
|
||||
Point kD(kU|dir, kV|dir, kW|dir);
|
||||
float fDLength = kD.Magnitude();
|
||||
kD.Normalize();
|
||||
|
||||
float fInvDLength = 1.0f/fDLength;
|
||||
Point kDiff = origin - capsule.mP0;
|
||||
Point kP(kU|kDiff, kV|kDiff, kW|kDiff);
|
||||
float fRadiusSqr = capsule.mRadius*capsule.mRadius;
|
||||
|
||||
float fInv, fA, fB, fC, fDiscr, fRoot, fT, fTmp;
|
||||
|
||||
// Is the velocity parallel to the capsule direction? (or zero)
|
||||
if ( fabsf(kD.z) >= 1.0f - FLT_EPSILON || fDLength < FLT_EPSILON )
|
||||
{
|
||||
|
||||
float fAxisDir = dir|capsDir;
|
||||
|
||||
fDiscr = fRadiusSqr - kP.x*kP.x - kP.y*kP.y;
|
||||
if ( fAxisDir < 0 && fDiscr >= 0.0f )
|
||||
{
|
||||
// Velocity anti-parallel to the capsule direction
|
||||
fRoot = sqrtf(fDiscr);
|
||||
s[0] = (kP.z + fRoot)*fInvDLength;
|
||||
s[1] = -(fWLength - kP.z + fRoot)*fInvDLength;
|
||||
return 2;
|
||||
}
|
||||
else if ( fAxisDir > 0 && fDiscr >= 0.0f )
|
||||
{
|
||||
// Velocity parallel to the capsule direction
|
||||
fRoot = sqrtf(fDiscr);
|
||||
s[0] = -(kP.z + fRoot)*fInvDLength;
|
||||
s[1] = (fWLength - kP.z + fRoot)*fInvDLength;
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// sphere heading wrong direction, or no velocity at all
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// test intersection with infinite cylinder
|
||||
fA = kD.x*kD.x + kD.y*kD.y;
|
||||
fB = kP.x*kD.x + kP.y*kD.y;
|
||||
fC = kP.x*kP.x + kP.y*kP.y - fRadiusSqr;
|
||||
fDiscr = fB*fB - fA*fC;
|
||||
if ( fDiscr < 0.0f )
|
||||
{
|
||||
// line does not intersect infinite cylinder
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iQuantity = 0;
|
||||
|
||||
if ( fDiscr > 0.0f )
|
||||
{
|
||||
// line intersects infinite cylinder in two places
|
||||
fRoot = sqrtf(fDiscr);
|
||||
fInv = 1.0f/fA;
|
||||
fT = (-fB - fRoot)*fInv;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( 0.0f <= fTmp && fTmp <= fWLength )
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
|
||||
fT = (-fB + fRoot)*fInv;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( 0.0f <= fTmp && fTmp <= fWLength )
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
|
||||
if ( iQuantity == 2 )
|
||||
{
|
||||
// line intersects capsule wall in two places
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// line is tangent to infinite cylinder
|
||||
fT = -fB/fA;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( 0.0f <= fTmp && fTmp <= fWLength )
|
||||
{
|
||||
s[0] = fT*fInvDLength;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// test intersection with bottom hemisphere
|
||||
// fA = 1
|
||||
fB += kP.z*kD.z;
|
||||
fC += kP.z*kP.z;
|
||||
fDiscr = fB*fB - fC;
|
||||
if ( fDiscr > 0.0f )
|
||||
{
|
||||
fRoot = sqrtf(fDiscr);
|
||||
fT = -fB - fRoot;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( fTmp <= 0.0f )
|
||||
{
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
if ( iQuantity == 2 )
|
||||
return 2;
|
||||
}
|
||||
|
||||
fT = -fB + fRoot;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( fTmp <= 0.0f )
|
||||
{
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
if ( iQuantity == 2 )
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else if ( fDiscr == 0.0f )
|
||||
{
|
||||
fT = -fB;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( fTmp <= 0.0f )
|
||||
{
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
if ( iQuantity == 2 )
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
// test intersection with top hemisphere
|
||||
// fA = 1
|
||||
fB -= kD.z*fWLength;
|
||||
fC += fWLength*(fWLength - 2.0f*kP.z);
|
||||
|
||||
fDiscr = fB*fB - fC;
|
||||
if ( fDiscr > 0.0f )
|
||||
{
|
||||
fRoot = sqrtf(fDiscr);
|
||||
fT = -fB - fRoot;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( fTmp >= fWLength )
|
||||
{
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
if ( iQuantity == 2 )
|
||||
return 2;
|
||||
}
|
||||
|
||||
fT = -fB + fRoot;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( fTmp >= fWLength )
|
||||
{
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
if ( iQuantity == 2 )
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else if ( fDiscr == 0.0f )
|
||||
{
|
||||
fT = -fB;
|
||||
fTmp = kP.z + fT*kD.z;
|
||||
if ( fTmp >= fWLength )
|
||||
{
|
||||
s[iQuantity++] = fT*fInvDLength;
|
||||
if ( iQuantity == 2 )
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
return iQuantity;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 ICEHELPERS_H
|
||||
#define ICEHELPERS_H
|
||||
|
||||
void RotX(Matrix3x3& m, float angle);
|
||||
void RotY(Matrix3x3& m, float angle);
|
||||
void RotZ(Matrix3x3& m, float angle);
|
||||
|
||||
udword RayCapsuleOverlap(const Point& origin, const Point& dir, const LSS& capsule, float s[2]);
|
||||
bool SegmentSphere(const Point& origin, const Point& dir, float length, const Point& center, float radius, float& dist, Point& hit_pos);
|
||||
bool RayAABB2(const Point& min, const Point& max, const Point& origin, const Point& dir, Point& coord);
|
||||
|
||||
inline_ bool RayOBB(const Point& origin, const Point& dir, const OBB& box, float& dist, Point& hit_pos)
|
||||
{
|
||||
Point LocalOrigin = box.mRot * (origin - box.mCenter);
|
||||
Point LocalDir = box.mRot * dir;
|
||||
|
||||
Point LocalImpact;
|
||||
if(RayAABB2(-box.mExtents, box.mExtents, LocalOrigin, LocalDir, LocalImpact))
|
||||
{
|
||||
dist = LocalImpact.Distance(LocalOrigin);
|
||||
hit_pos = LocalImpact * box.mRot + box.mCenter;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // ICEHELPERS_H
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 ICEHELPERS_H
|
||||
#define ICEHELPERS_H
|
||||
|
||||
void RotX(Matrix3x3& m, float angle);
|
||||
void RotY(Matrix3x3& m, float angle);
|
||||
void RotZ(Matrix3x3& m, float angle);
|
||||
|
||||
udword RayCapsuleOverlap(const Point& origin, const Point& dir, const LSS& capsule, float s[2]);
|
||||
bool SegmentSphere(const Point& origin, const Point& dir, float length, const Point& center, float radius, float& dist, Point& hit_pos);
|
||||
bool RayAABB2(const Point& min, const Point& max, const Point& origin, const Point& dir, Point& coord);
|
||||
|
||||
inline_ bool RayOBB(const Point& origin, const Point& dir, const OBB& box, float& dist, Point& hit_pos)
|
||||
{
|
||||
Point LocalOrigin = box.mRot * (origin - box.mCenter);
|
||||
Point LocalDir = box.mRot * dir;
|
||||
|
||||
Point LocalImpact;
|
||||
if(RayAABB2(-box.mExtents, box.mExtents, LocalOrigin, LocalDir, LocalImpact))
|
||||
{
|
||||
dist = LocalImpact.Distance(LocalOrigin);
|
||||
hit_pos = LocalImpact * box.mRot + box.mCenter;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // ICEHELPERS_H
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//CDTestFramework re-distributed under the ZLib license with permission of Pierre Terdiman
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
DbvtTest.* and btDbvt.* are distributed under the ZLIb license, Copyright Nathanael Presson
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BulletSAPCompleteBoxPruningTest.* distributed under the ZLib license, Copyright Erwin Coumans
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//ICE and OPCODE 1.3 re-distributed under the ZLib license with permission of Pierre Terdiman
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//CDTestFramework re-distributed under the ZLib license with permission of Pierre Terdiman
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
DbvtTest.* and btDbvt.* are distributed under the ZLIb license, Copyright Nathanael Presson
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BulletSAPCompleteBoxPruningTest.* distributed under the ZLib license, Copyright Erwin Coumans
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//ICE and OPCODE 1.3 re-distributed under the ZLib license with permission of Pierre Terdiman
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
@@ -1,157 +1,157 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "OBBMeshQuery.h"
|
||||
#include "Terrain.h"
|
||||
#include "IceHelpers.h"
|
||||
#include "RenderingHelpers.h"
|
||||
#include "Camera.h"
|
||||
#include "GLFontRenderer.h"
|
||||
|
||||
OBBMeshQuery::OBBMeshQuery() :
|
||||
mBar (null),
|
||||
mAngleX (0.0f),
|
||||
mAngleY (0.0f),
|
||||
mAngleZ (0.0f),
|
||||
mDist (0.0f),
|
||||
mValidHit (false)
|
||||
{
|
||||
}
|
||||
|
||||
OBBMeshQuery::~OBBMeshQuery()
|
||||
{
|
||||
}
|
||||
|
||||
void OBBMeshQuery::Init()
|
||||
{
|
||||
mBox.mCenter = Point(0.0f, 0.0f, 0.0f);
|
||||
mBox.mExtents = Point(1.0f, 1.0f, 1.0f);
|
||||
mBox.mRot.Identity();
|
||||
}
|
||||
|
||||
void OBBMeshQuery::Release()
|
||||
{
|
||||
Deselect();
|
||||
}
|
||||
|
||||
void OBBMeshQuery::Select()
|
||||
{
|
||||
// Create a tweak bar
|
||||
{
|
||||
mBar = TwNewBar("OBBMeshQuery");
|
||||
TwAddVarRW(mBar, "Extents.x", TW_TYPE_FLOAT, &mBox.mExtents.x, " min=0.01 max=200.0 step=0.05 group='Extents' ");
|
||||
TwAddVarRW(mBar, "Extents.y", TW_TYPE_FLOAT, &mBox.mExtents.y, " min=0.01 max=200.0 step=0.05 group='Extents' ");
|
||||
TwAddVarRW(mBar, "Extents.z", TW_TYPE_FLOAT, &mBox.mExtents.z, " min=0.01 max=200.0 step=0.05 group='Extents' ");
|
||||
TwAddVarRW(mBar, "Rot.x", TW_TYPE_FLOAT, &mAngleX, " min=0.0 max=6.28 step=0.01 group='Rotation' ");
|
||||
TwAddVarRW(mBar, "Rot.y", TW_TYPE_FLOAT, &mAngleY, " min=0.0 max=6.28 step=0.01 group='Rotation' ");
|
||||
TwAddVarRW(mBar, "Rot.z", TW_TYPE_FLOAT, &mAngleZ, " min=0.0 max=6.28 step=0.01 group='Rotation' ");
|
||||
|
||||
mSettings.AddToTweakBar(mBar);
|
||||
|
||||
// mProfiler.AddToTweakBar(mBar);
|
||||
}
|
||||
}
|
||||
|
||||
void OBBMeshQuery::Deselect()
|
||||
{
|
||||
if(mBar)
|
||||
{
|
||||
TwDeleteBar(mBar);
|
||||
mBar = null;
|
||||
}
|
||||
}
|
||||
|
||||
void OBBMeshQuery::PerformTest()
|
||||
{
|
||||
RenderTerrain();
|
||||
|
||||
Matrix3x3 MX,MY,MZ;
|
||||
RotX(MX, mAngleX);
|
||||
RotY(MY, mAngleY);
|
||||
RotY(MZ, mAngleZ);
|
||||
mBox.mRot = MX * MY * MZ;
|
||||
|
||||
DrawOBB(mBox);
|
||||
|
||||
const Model* TM = GetTerrainModel();
|
||||
if(TM)
|
||||
{
|
||||
OBBCollider Collider;
|
||||
mSettings.SetupCollider(Collider);
|
||||
|
||||
mProfiler.Start();
|
||||
bool Status = Collider.Collide(mCache, mBox, *TM, null, null);
|
||||
mProfiler.End();
|
||||
mProfiler.Accum();
|
||||
|
||||
if(Status)
|
||||
{
|
||||
if(Collider.GetContactStatus())
|
||||
{
|
||||
udword NbTris = Collider.GetNbTouchedPrimitives();
|
||||
const udword* Indices = Collider.GetTouchedPrimitives();
|
||||
|
||||
RenderTerrainTriangles(NbTris, Indices);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Raycast hit
|
||||
if(mValidHit)
|
||||
{
|
||||
Point wp = mLocalHit + mBox.mCenter;
|
||||
DrawLine(wp, wp + Point(1.0f, 0.0f, 0.0f), Point(1,0,0), 1.0f);
|
||||
DrawLine(wp, wp + Point(0.0f, 1.0f, 0.0f), Point(0,1,0), 1.0f);
|
||||
DrawLine(wp, wp + Point(0.0f, 0.0f, 1.0f), Point(0,0,1), 1.0f);
|
||||
}
|
||||
|
||||
char Buffer[4096];
|
||||
sprintf(Buffer, "OBB-mesh query = %5.1f us (%d cycles)\n", mProfiler.mMsTime, mProfiler.mCycles);
|
||||
GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer);
|
||||
}
|
||||
|
||||
void OBBMeshQuery::KeyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void OBBMeshQuery::MouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
mValidHit = false;
|
||||
if(!button && !state)
|
||||
{
|
||||
Point Dir = ComputeWorldRay(x, y);
|
||||
|
||||
float d;
|
||||
Point hit;
|
||||
if(RayOBB(GetCameraPos(), Dir, mBox, d, hit))
|
||||
{
|
||||
mValidHit = true;
|
||||
mDist = d;
|
||||
mLocalHit = hit - mBox.mCenter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OBBMeshQuery::MotionCallback(int x, int y)
|
||||
{
|
||||
if(mValidHit)
|
||||
{
|
||||
Point Dir = ComputeWorldRay(x, y);
|
||||
mBox.mCenter = GetCameraPos() + Dir*mDist - mLocalHit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "OBBMeshQuery.h"
|
||||
#include "Terrain.h"
|
||||
#include "IceHelpers.h"
|
||||
#include "RenderingHelpers.h"
|
||||
#include "Camera.h"
|
||||
#include "GLFontRenderer.h"
|
||||
|
||||
OBBMeshQuery::OBBMeshQuery() :
|
||||
mBar (null),
|
||||
mAngleX (0.0f),
|
||||
mAngleY (0.0f),
|
||||
mAngleZ (0.0f),
|
||||
mDist (0.0f),
|
||||
mValidHit (false)
|
||||
{
|
||||
}
|
||||
|
||||
OBBMeshQuery::~OBBMeshQuery()
|
||||
{
|
||||
}
|
||||
|
||||
void OBBMeshQuery::Init()
|
||||
{
|
||||
mBox.mCenter = Point(0.0f, 0.0f, 0.0f);
|
||||
mBox.mExtents = Point(1.0f, 1.0f, 1.0f);
|
||||
mBox.mRot.Identity();
|
||||
}
|
||||
|
||||
void OBBMeshQuery::Release()
|
||||
{
|
||||
Deselect();
|
||||
}
|
||||
|
||||
void OBBMeshQuery::Select()
|
||||
{
|
||||
// Create a tweak bar
|
||||
{
|
||||
mBar = TwNewBar("OBBMeshQuery");
|
||||
TwAddVarRW(mBar, "Extents.x", TW_TYPE_FLOAT, &mBox.mExtents.x, " min=0.01 max=200.0 step=0.05 group='Extents' ");
|
||||
TwAddVarRW(mBar, "Extents.y", TW_TYPE_FLOAT, &mBox.mExtents.y, " min=0.01 max=200.0 step=0.05 group='Extents' ");
|
||||
TwAddVarRW(mBar, "Extents.z", TW_TYPE_FLOAT, &mBox.mExtents.z, " min=0.01 max=200.0 step=0.05 group='Extents' ");
|
||||
TwAddVarRW(mBar, "Rot.x", TW_TYPE_FLOAT, &mAngleX, " min=0.0 max=6.28 step=0.01 group='Rotation' ");
|
||||
TwAddVarRW(mBar, "Rot.y", TW_TYPE_FLOAT, &mAngleY, " min=0.0 max=6.28 step=0.01 group='Rotation' ");
|
||||
TwAddVarRW(mBar, "Rot.z", TW_TYPE_FLOAT, &mAngleZ, " min=0.0 max=6.28 step=0.01 group='Rotation' ");
|
||||
|
||||
mSettings.AddToTweakBar(mBar);
|
||||
|
||||
// mProfiler.AddToTweakBar(mBar);
|
||||
}
|
||||
}
|
||||
|
||||
void OBBMeshQuery::Deselect()
|
||||
{
|
||||
if(mBar)
|
||||
{
|
||||
TwDeleteBar(mBar);
|
||||
mBar = null;
|
||||
}
|
||||
}
|
||||
|
||||
void OBBMeshQuery::PerformTest()
|
||||
{
|
||||
RenderTerrain();
|
||||
|
||||
Matrix3x3 MX,MY,MZ;
|
||||
RotX(MX, mAngleX);
|
||||
RotY(MY, mAngleY);
|
||||
RotY(MZ, mAngleZ);
|
||||
mBox.mRot = MX * MY * MZ;
|
||||
|
||||
DrawOBB(mBox);
|
||||
|
||||
const Model* TM = GetTerrainModel();
|
||||
if(TM)
|
||||
{
|
||||
OBBCollider Collider;
|
||||
mSettings.SetupCollider(Collider);
|
||||
|
||||
mProfiler.Start();
|
||||
bool Status = Collider.Collide(mCache, mBox, *TM, null, null);
|
||||
mProfiler.End();
|
||||
mProfiler.Accum();
|
||||
|
||||
if(Status)
|
||||
{
|
||||
if(Collider.GetContactStatus())
|
||||
{
|
||||
udword NbTris = Collider.GetNbTouchedPrimitives();
|
||||
const udword* Indices = Collider.GetTouchedPrimitives();
|
||||
|
||||
RenderTerrainTriangles(NbTris, Indices);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Raycast hit
|
||||
if(mValidHit)
|
||||
{
|
||||
Point wp = mLocalHit + mBox.mCenter;
|
||||
DrawLine(wp, wp + Point(1.0f, 0.0f, 0.0f), Point(1,0,0), 1.0f);
|
||||
DrawLine(wp, wp + Point(0.0f, 1.0f, 0.0f), Point(0,1,0), 1.0f);
|
||||
DrawLine(wp, wp + Point(0.0f, 0.0f, 1.0f), Point(0,0,1), 1.0f);
|
||||
}
|
||||
|
||||
char Buffer[4096];
|
||||
sprintf(Buffer, "OBB-mesh query = %5.1f us (%d cycles)\n", mProfiler.mMsTime, mProfiler.mCycles);
|
||||
GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer);
|
||||
}
|
||||
|
||||
void OBBMeshQuery::KeyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void OBBMeshQuery::MouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
mValidHit = false;
|
||||
if(!button && !state)
|
||||
{
|
||||
Point Dir = ComputeWorldRay(x, y);
|
||||
|
||||
float d;
|
||||
Point hit;
|
||||
if(RayOBB(GetCameraPos(), Dir, mBox, d, hit))
|
||||
{
|
||||
mValidHit = true;
|
||||
mDist = d;
|
||||
mLocalHit = hit - mBox.mCenter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OBBMeshQuery::MotionCallback(int x, int y)
|
||||
{
|
||||
if(mValidHit)
|
||||
{
|
||||
Point Dir = ComputeWorldRay(x, y);
|
||||
mBox.mCenter = GetCameraPos() + Dir*mDist - mLocalHit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 OBBMESHQUERY_H
|
||||
#define OBBMESHQUERY_H
|
||||
|
||||
#include "CollisionTest.h"
|
||||
#include "Profiling.h"
|
||||
|
||||
class OBBMeshQuery : public CollisionTest
|
||||
{
|
||||
public:
|
||||
OBBMeshQuery();
|
||||
virtual ~OBBMeshQuery();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Release();
|
||||
virtual void PerformTest();
|
||||
virtual void Select();
|
||||
virtual void Deselect();
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y);
|
||||
virtual void MouseCallback(int button, int state, int x, int y);
|
||||
virtual void MotionCallback(int x, int y);
|
||||
|
||||
TwBar* mBar; //!< AntTweakBar
|
||||
OBB mBox;
|
||||
|
||||
float mAngleX;
|
||||
float mAngleY;
|
||||
float mAngleZ;
|
||||
|
||||
OBBCache mCache;
|
||||
OpcodeSettings mSettings;
|
||||
Profiler mProfiler;
|
||||
|
||||
float mDist;
|
||||
Point mLocalHit;
|
||||
bool mValidHit;
|
||||
};
|
||||
|
||||
#endif // OBBMESHQUERY_H
|
||||
/*
|
||||
CDTestFramework http://codercorner.com
|
||||
Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.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 OBBMESHQUERY_H
|
||||
#define OBBMESHQUERY_H
|
||||
|
||||
#include "CollisionTest.h"
|
||||
#include "Profiling.h"
|
||||
|
||||
class OBBMeshQuery : public CollisionTest
|
||||
{
|
||||
public:
|
||||
OBBMeshQuery();
|
||||
virtual ~OBBMeshQuery();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Release();
|
||||
virtual void PerformTest();
|
||||
virtual void Select();
|
||||
virtual void Deselect();
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y);
|
||||
virtual void MouseCallback(int button, int state, int x, int y);
|
||||
virtual void MotionCallback(int x, int y);
|
||||
|
||||
TwBar* mBar; //!< AntTweakBar
|
||||
OBB mBox;
|
||||
|
||||
float mAngleX;
|
||||
float mAngleY;
|
||||
float mAngleZ;
|
||||
|
||||
OBBCache mCache;
|
||||
OpcodeSettings mSettings;
|
||||
Profiler mProfiler;
|
||||
|
||||
float mDist;
|
||||
Point mLocalHit;
|
||||
bool mValidHit;
|
||||
};
|
||||
|
||||
#endif // OBBMESHQUERY_H
|
||||
|
||||
@@ -1,422 +1,422 @@
|
||||
/*
|
||||
* ICE OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains AABB-related code.
|
||||
* \file IceAABB.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 29, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* AABB class.
|
||||
* \class AABB
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the sum of two AABBs.
|
||||
* \param aabb [in] the other AABB
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
AABB& AABB::Add(const AABB& aabb)
|
||||
{
|
||||
// Compute new min & max values
|
||||
Point Min; GetMin(Min);
|
||||
Point Tmp; aabb.GetMin(Tmp);
|
||||
Min.Min(Tmp);
|
||||
|
||||
Point Max; GetMax(Max);
|
||||
aabb.GetMax(Tmp);
|
||||
Max.Max(Tmp);
|
||||
|
||||
// Update this
|
||||
SetMinMax(Min, Max);
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Makes a cube from the AABB.
|
||||
* \param cube [out] the cube AABB
|
||||
* \return cube edge length
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float AABB::MakeCube(AABB& cube) const
|
||||
{
|
||||
Point Ext; GetExtents(Ext);
|
||||
float Max = Ext.Max();
|
||||
|
||||
Point Cnt; GetCenter(Cnt);
|
||||
cube.SetCenterExtents(Cnt, Point(Max, Max, Max));
|
||||
return Max;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Makes a sphere from the AABB.
|
||||
* \param sphere [out] sphere containing the AABB
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void AABB::MakeSphere(Sphere& sphere) const
|
||||
{
|
||||
GetExtents(sphere.mCenter);
|
||||
sphere.mRadius = sphere.mCenter.Magnitude() * 1.00001f; // To make sure sphere::Contains(*this) succeeds
|
||||
GetCenter(sphere.mCenter);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks a box is inside another box.
|
||||
* \param box [in] the other AABB
|
||||
* \return true if current box is inside input box
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool AABB::IsInside(const AABB& box) const
|
||||
{
|
||||
if(box.GetMin(0)>GetMin(0)) return false;
|
||||
if(box.GetMin(1)>GetMin(1)) return false;
|
||||
if(box.GetMin(2)>GetMin(2)) return false;
|
||||
if(box.GetMax(0)<GetMax(0)) return false;
|
||||
if(box.GetMax(1)<GetMax(1)) return false;
|
||||
if(box.GetMax(2)<GetMax(2)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the AABB planes.
|
||||
* \param planes [out] 6 planes surrounding the box
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool AABB::ComputePlanes(Plane* planes) const
|
||||
{
|
||||
// Checkings
|
||||
if(!planes) return false;
|
||||
|
||||
Point Center, Extents;
|
||||
GetCenter(Center);
|
||||
GetExtents(Extents);
|
||||
|
||||
// Writes normals
|
||||
planes[0].n = Point(1.0f, 0.0f, 0.0f);
|
||||
planes[1].n = Point(-1.0f, 0.0f, 0.0f);
|
||||
planes[2].n = Point(0.0f, 1.0f, 0.0f);
|
||||
planes[3].n = Point(0.0f, -1.0f, 0.0f);
|
||||
planes[4].n = Point(0.0f, 0.0f, 1.0f);
|
||||
planes[5].n = Point(0.0f, 0.0f, -1.0f);
|
||||
|
||||
// Compute a point on each plane
|
||||
Point p0 = Point(Center.x+Extents.x, Center.y, Center.z);
|
||||
Point p1 = Point(Center.x-Extents.x, Center.y, Center.z);
|
||||
Point p2 = Point(Center.x, Center.y+Extents.y, Center.z);
|
||||
Point p3 = Point(Center.x, Center.y-Extents.y, Center.z);
|
||||
Point p4 = Point(Center.x, Center.y, Center.z+Extents.z);
|
||||
Point p5 = Point(Center.x, Center.y, Center.z-Extents.z);
|
||||
|
||||
// Compute d
|
||||
planes[0].d = -(planes[0].n|p0);
|
||||
planes[1].d = -(planes[1].n|p1);
|
||||
planes[2].d = -(planes[2].n|p2);
|
||||
planes[3].d = -(planes[3].n|p3);
|
||||
planes[4].d = -(planes[4].n|p4);
|
||||
planes[5].d = -(planes[5].n|p5);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the aabb points.
|
||||
* \param pts [out] 8 box points
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool AABB::ComputePoints(Point* pts) const
|
||||
{
|
||||
// Checkings
|
||||
if(!pts) return false;
|
||||
|
||||
// Get box corners
|
||||
Point min; GetMin(min);
|
||||
Point max; GetMax(max);
|
||||
|
||||
// 7+------+6 0 = ---
|
||||
// /| /| 1 = +--
|
||||
// / | / | 2 = ++-
|
||||
// / 4+---/--+5 3 = -+-
|
||||
// 3+------+2 / y z 4 = --+
|
||||
// | / | / | / 5 = +-+
|
||||
// |/ |/ |/ 6 = +++
|
||||
// 0+------+1 *---x 7 = -++
|
||||
|
||||
// Generate 8 corners of the bbox
|
||||
pts[0] = Point(min.x, min.y, min.z);
|
||||
pts[1] = Point(max.x, min.y, min.z);
|
||||
pts[2] = Point(max.x, max.y, min.z);
|
||||
pts[3] = Point(min.x, max.y, min.z);
|
||||
pts[4] = Point(min.x, min.y, max.z);
|
||||
pts[5] = Point(max.x, min.y, max.z);
|
||||
pts[6] = Point(max.x, max.y, max.z);
|
||||
pts[7] = Point(min.x, max.y, max.z);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets vertex normals.
|
||||
* \param pts [out] 8 box points
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const Point* AABB::GetVertexNormals() const
|
||||
{
|
||||
static float VertexNormals[] =
|
||||
{
|
||||
-INVSQRT3, -INVSQRT3, -INVSQRT3,
|
||||
INVSQRT3, -INVSQRT3, -INVSQRT3,
|
||||
INVSQRT3, INVSQRT3, -INVSQRT3,
|
||||
-INVSQRT3, INVSQRT3, -INVSQRT3,
|
||||
-INVSQRT3, -INVSQRT3, INVSQRT3,
|
||||
INVSQRT3, -INVSQRT3, INVSQRT3,
|
||||
INVSQRT3, INVSQRT3, INVSQRT3,
|
||||
-INVSQRT3, INVSQRT3, INVSQRT3
|
||||
};
|
||||
return (const Point*)VertexNormals;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns edges.
|
||||
* \return 24 indices (12 edges) indexing the list returned by ComputePoints()
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const udword* AABB::GetEdges() const
|
||||
{
|
||||
static udword Indices[] = {
|
||||
0, 1, 1, 2, 2, 3, 3, 0,
|
||||
7, 6, 6, 5, 5, 4, 4, 7,
|
||||
1, 5, 6, 2,
|
||||
3, 7, 4, 0
|
||||
};
|
||||
return Indices;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns edge normals.
|
||||
* \return edge normals in local space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const Point* AABB::GetEdgeNormals() const
|
||||
{
|
||||
static float EdgeNormals[] =
|
||||
{
|
||||
0, -INVSQRT2, -INVSQRT2, // 0-1
|
||||
INVSQRT2, 0, -INVSQRT2, // 1-2
|
||||
0, INVSQRT2, -INVSQRT2, // 2-3
|
||||
-INVSQRT2, 0, -INVSQRT2, // 3-0
|
||||
|
||||
0, INVSQRT2, INVSQRT2, // 7-6
|
||||
INVSQRT2, 0, INVSQRT2, // 6-5
|
||||
0, -INVSQRT2, INVSQRT2, // 5-4
|
||||
-INVSQRT2, 0, INVSQRT2, // 4-7
|
||||
|
||||
INVSQRT2, -INVSQRT2, 0, // 1-5
|
||||
INVSQRT2, INVSQRT2, 0, // 6-2
|
||||
-INVSQRT2, INVSQRT2, 0, // 3-7
|
||||
-INVSQRT2, -INVSQRT2, 0 // 4-0
|
||||
};
|
||||
return (const Point*)EdgeNormals;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// (C) 1996-98 Vienna University of Technology
|
||||
// ===========================================================================
|
||||
// NAME: bboxarea
|
||||
// TYPE: c++ code
|
||||
// PROJECT: Bounding Box Area
|
||||
// CONTENT: Computes area of 2D projection of 3D oriented bounding box
|
||||
// VERSION: 1.0
|
||||
// ===========================================================================
|
||||
// AUTHORS: ds Dieter Schmalstieg
|
||||
// ep Erik Pojar
|
||||
// ===========================================================================
|
||||
// HISTORY:
|
||||
//
|
||||
// 19-sep-99 15:23:03 ds last modification
|
||||
// 01-dec-98 15:23:03 ep created
|
||||
// ===========================================================================
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SAMPLE CODE STARTS HERE
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// NOTE: This sample program requires OPEN INVENTOR!
|
||||
|
||||
//indexlist: this table stores the 64 possible cases of classification of
|
||||
//the eyepoint with respect to the 6 defining planes of the bbox (2^6=64)
|
||||
//only 26 (3^3-1, where 1 is "inside" cube) of these cases are valid.
|
||||
//the first 6 numbers in each row are the indices of the bbox vertices that
|
||||
//form the outline of which we want to compute the area (counterclockwise
|
||||
//ordering), the 7th entry means the number of vertices in the outline.
|
||||
//there are 6 cases with a single face and and a 4-vertex outline, and
|
||||
//20 cases with 2 or 3 faces and a 6-vertex outline. a value of 0 indicates
|
||||
//an invalid case.
|
||||
|
||||
|
||||
// Original list was made of 7 items, I added an 8th element:
|
||||
// - to padd on a cache line
|
||||
// - to repeat the first entry to avoid modulos
|
||||
//
|
||||
// I also replaced original ints with sbytes.
|
||||
|
||||
static const sbyte gIndexList[64][8] =
|
||||
{
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, // 0 inside
|
||||
{ 0, 4, 7, 3, 0,-1,-1, 4}, // 1 left
|
||||
{ 1, 2, 6, 5, 1,-1,-1, 4}, // 2 right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, // 3 -
|
||||
{ 0, 1, 5, 4, 0,-1,-1, 4}, // 4 bottom
|
||||
{ 0, 1, 5, 4, 7, 3, 0, 6}, // 5 bottom, left
|
||||
{ 0, 1, 2, 6, 5, 4, 0, 6}, // 6 bottom, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, // 7 -
|
||||
{ 2, 3, 7, 6, 2,-1,-1, 4}, // 8 top
|
||||
{ 0, 4, 7, 6, 2, 3, 0, 6}, // 9 top, left
|
||||
{ 1, 2, 3, 7, 6, 5, 1, 6}, //10 top, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //11 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //12 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //13 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //14 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //15 -
|
||||
{ 0, 3, 2, 1, 0,-1,-1, 4}, //16 front
|
||||
{ 0, 4, 7, 3, 2, 1, 0, 6}, //17 front, left
|
||||
{ 0, 3, 2, 6, 5, 1, 0, 6}, //18 front, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //19 -
|
||||
{ 0, 3, 2, 1, 5, 4, 0, 6}, //20 front, bottom
|
||||
{ 1, 5, 4, 7, 3, 2, 1, 6}, //21 front, bottom, left
|
||||
{ 0, 3, 2, 6, 5, 4, 0, 6}, //22 front, bottom, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //23 -
|
||||
{ 0, 3, 7, 6, 2, 1, 0, 6}, //24 front, top
|
||||
{ 0, 4, 7, 6, 2, 1, 0, 6}, //25 front, top, left
|
||||
{ 0, 3, 7, 6, 5, 1, 0, 6}, //26 front, top, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //27 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //28 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //29 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //30 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //31 -
|
||||
{ 4, 5, 6, 7, 4,-1,-1, 4}, //32 back
|
||||
{ 0, 4, 5, 6, 7, 3, 0, 6}, //33 back, left
|
||||
{ 1, 2, 6, 7, 4, 5, 1, 6}, //34 back, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //35 -
|
||||
{ 0, 1, 5, 6, 7, 4, 0, 6}, //36 back, bottom
|
||||
{ 0, 1, 5, 6, 7, 3, 0, 6}, //37 back, bottom, left
|
||||
{ 0, 1, 2, 6, 7, 4, 0, 6}, //38 back, bottom, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //39 -
|
||||
{ 2, 3, 7, 4, 5, 6, 2, 6}, //40 back, top
|
||||
{ 0, 4, 5, 6, 2, 3, 0, 6}, //41 back, top, left
|
||||
{ 1, 2, 3, 7, 4, 5, 1, 6}, //42 back, top, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //43 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //44 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //45 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //46 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //47 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //48 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //49 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //50 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //51 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //52 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //53 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //54 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //55 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //56 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //57 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //58 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //59 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //60 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //61 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //62 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0} //63 invalid
|
||||
};
|
||||
|
||||
const sbyte* AABB::ComputeOutline(const Point& local_eye, sdword& num) const
|
||||
{
|
||||
// Get box corners
|
||||
Point min; GetMin(min);
|
||||
Point max; GetMax(max);
|
||||
|
||||
// Compute 6-bit code to classify eye with respect to the 6 defining planes of the bbox
|
||||
int pos = ((local_eye.x < min.x) ? 1 : 0) // 1 = left
|
||||
+ ((local_eye.x > max.x) ? 2 : 0) // 2 = right
|
||||
+ ((local_eye.y < min.y) ? 4 : 0) // 4 = bottom
|
||||
+ ((local_eye.y > max.y) ? 8 : 0) // 8 = top
|
||||
+ ((local_eye.z < min.z) ? 16 : 0) // 16 = front
|
||||
+ ((local_eye.z > max.z) ? 32 : 0); // 32 = back
|
||||
|
||||
// Look up number of vertices in outline
|
||||
num = (sdword)gIndexList[pos][7];
|
||||
// Zero indicates invalid case
|
||||
if(!num) return null;
|
||||
|
||||
return &gIndexList[pos][0];
|
||||
}
|
||||
|
||||
// calculateBoxArea: computes the screen-projected 2D area of an oriented 3D bounding box
|
||||
|
||||
//const Point& eye, //eye point (in bbox object coordinates)
|
||||
//const AABB& box, //3d bbox
|
||||
//const Matrix4x4& mat, //free transformation for bbox
|
||||
//float width, float height, int& num)
|
||||
float AABB::ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num) const
|
||||
{
|
||||
const sbyte* Outline = ComputeOutline(eye, num);
|
||||
if(!Outline) return -1.0f;
|
||||
|
||||
// Compute box vertices
|
||||
Point vertexBox[8], dst[8];
|
||||
ComputePoints(vertexBox);
|
||||
|
||||
// Transform all outline corners into 2D screen space
|
||||
for(sdword i=0;i<num;i++)
|
||||
{
|
||||
HPoint Projected;
|
||||
vertexBox[Outline[i]].ProjectToScreen(width, height, mat, Projected);
|
||||
dst[i] = Projected;
|
||||
}
|
||||
|
||||
float Sum = (dst[num-1][0] - dst[0][0]) * (dst[num-1][1] + dst[0][1]);
|
||||
|
||||
for(int i=0; i<num-1; i++)
|
||||
Sum += (dst[i][0] - dst[i+1][0]) * (dst[i][1] + dst[i+1][1]);
|
||||
|
||||
return Sum * 0.5f; //return computed value corrected by 0.5
|
||||
}
|
||||
/*
|
||||
* ICE OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains AABB-related code.
|
||||
* \file IceAABB.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 29, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* AABB class.
|
||||
* \class AABB
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the sum of two AABBs.
|
||||
* \param aabb [in] the other AABB
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
AABB& AABB::Add(const AABB& aabb)
|
||||
{
|
||||
// Compute new min & max values
|
||||
Point Min; GetMin(Min);
|
||||
Point Tmp; aabb.GetMin(Tmp);
|
||||
Min.Min(Tmp);
|
||||
|
||||
Point Max; GetMax(Max);
|
||||
aabb.GetMax(Tmp);
|
||||
Max.Max(Tmp);
|
||||
|
||||
// Update this
|
||||
SetMinMax(Min, Max);
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Makes a cube from the AABB.
|
||||
* \param cube [out] the cube AABB
|
||||
* \return cube edge length
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float AABB::MakeCube(AABB& cube) const
|
||||
{
|
||||
Point Ext; GetExtents(Ext);
|
||||
float Max = Ext.Max();
|
||||
|
||||
Point Cnt; GetCenter(Cnt);
|
||||
cube.SetCenterExtents(Cnt, Point(Max, Max, Max));
|
||||
return Max;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Makes a sphere from the AABB.
|
||||
* \param sphere [out] sphere containing the AABB
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void AABB::MakeSphere(Sphere& sphere) const
|
||||
{
|
||||
GetExtents(sphere.mCenter);
|
||||
sphere.mRadius = sphere.mCenter.Magnitude() * 1.00001f; // To make sure sphere::Contains(*this) succeeds
|
||||
GetCenter(sphere.mCenter);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks a box is inside another box.
|
||||
* \param box [in] the other AABB
|
||||
* \return true if current box is inside input box
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool AABB::IsInside(const AABB& box) const
|
||||
{
|
||||
if(box.GetMin(0)>GetMin(0)) return false;
|
||||
if(box.GetMin(1)>GetMin(1)) return false;
|
||||
if(box.GetMin(2)>GetMin(2)) return false;
|
||||
if(box.GetMax(0)<GetMax(0)) return false;
|
||||
if(box.GetMax(1)<GetMax(1)) return false;
|
||||
if(box.GetMax(2)<GetMax(2)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the AABB planes.
|
||||
* \param planes [out] 6 planes surrounding the box
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool AABB::ComputePlanes(Plane* planes) const
|
||||
{
|
||||
// Checkings
|
||||
if(!planes) return false;
|
||||
|
||||
Point Center, Extents;
|
||||
GetCenter(Center);
|
||||
GetExtents(Extents);
|
||||
|
||||
// Writes normals
|
||||
planes[0].n = Point(1.0f, 0.0f, 0.0f);
|
||||
planes[1].n = Point(-1.0f, 0.0f, 0.0f);
|
||||
planes[2].n = Point(0.0f, 1.0f, 0.0f);
|
||||
planes[3].n = Point(0.0f, -1.0f, 0.0f);
|
||||
planes[4].n = Point(0.0f, 0.0f, 1.0f);
|
||||
planes[5].n = Point(0.0f, 0.0f, -1.0f);
|
||||
|
||||
// Compute a point on each plane
|
||||
Point p0 = Point(Center.x+Extents.x, Center.y, Center.z);
|
||||
Point p1 = Point(Center.x-Extents.x, Center.y, Center.z);
|
||||
Point p2 = Point(Center.x, Center.y+Extents.y, Center.z);
|
||||
Point p3 = Point(Center.x, Center.y-Extents.y, Center.z);
|
||||
Point p4 = Point(Center.x, Center.y, Center.z+Extents.z);
|
||||
Point p5 = Point(Center.x, Center.y, Center.z-Extents.z);
|
||||
|
||||
// Compute d
|
||||
planes[0].d = -(planes[0].n|p0);
|
||||
planes[1].d = -(planes[1].n|p1);
|
||||
planes[2].d = -(planes[2].n|p2);
|
||||
planes[3].d = -(planes[3].n|p3);
|
||||
planes[4].d = -(planes[4].n|p4);
|
||||
planes[5].d = -(planes[5].n|p5);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the aabb points.
|
||||
* \param pts [out] 8 box points
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool AABB::ComputePoints(Point* pts) const
|
||||
{
|
||||
// Checkings
|
||||
if(!pts) return false;
|
||||
|
||||
// Get box corners
|
||||
Point min; GetMin(min);
|
||||
Point max; GetMax(max);
|
||||
|
||||
// 7+------+6 0 = ---
|
||||
// /| /| 1 = +--
|
||||
// / | / | 2 = ++-
|
||||
// / 4+---/--+5 3 = -+-
|
||||
// 3+------+2 / y z 4 = --+
|
||||
// | / | / | / 5 = +-+
|
||||
// |/ |/ |/ 6 = +++
|
||||
// 0+------+1 *---x 7 = -++
|
||||
|
||||
// Generate 8 corners of the bbox
|
||||
pts[0] = Point(min.x, min.y, min.z);
|
||||
pts[1] = Point(max.x, min.y, min.z);
|
||||
pts[2] = Point(max.x, max.y, min.z);
|
||||
pts[3] = Point(min.x, max.y, min.z);
|
||||
pts[4] = Point(min.x, min.y, max.z);
|
||||
pts[5] = Point(max.x, min.y, max.z);
|
||||
pts[6] = Point(max.x, max.y, max.z);
|
||||
pts[7] = Point(min.x, max.y, max.z);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets vertex normals.
|
||||
* \param pts [out] 8 box points
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const Point* AABB::GetVertexNormals() const
|
||||
{
|
||||
static float VertexNormals[] =
|
||||
{
|
||||
-INVSQRT3, -INVSQRT3, -INVSQRT3,
|
||||
INVSQRT3, -INVSQRT3, -INVSQRT3,
|
||||
INVSQRT3, INVSQRT3, -INVSQRT3,
|
||||
-INVSQRT3, INVSQRT3, -INVSQRT3,
|
||||
-INVSQRT3, -INVSQRT3, INVSQRT3,
|
||||
INVSQRT3, -INVSQRT3, INVSQRT3,
|
||||
INVSQRT3, INVSQRT3, INVSQRT3,
|
||||
-INVSQRT3, INVSQRT3, INVSQRT3
|
||||
};
|
||||
return (const Point*)VertexNormals;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns edges.
|
||||
* \return 24 indices (12 edges) indexing the list returned by ComputePoints()
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const udword* AABB::GetEdges() const
|
||||
{
|
||||
static udword Indices[] = {
|
||||
0, 1, 1, 2, 2, 3, 3, 0,
|
||||
7, 6, 6, 5, 5, 4, 4, 7,
|
||||
1, 5, 6, 2,
|
||||
3, 7, 4, 0
|
||||
};
|
||||
return Indices;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns edge normals.
|
||||
* \return edge normals in local space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const Point* AABB::GetEdgeNormals() const
|
||||
{
|
||||
static float EdgeNormals[] =
|
||||
{
|
||||
0, -INVSQRT2, -INVSQRT2, // 0-1
|
||||
INVSQRT2, 0, -INVSQRT2, // 1-2
|
||||
0, INVSQRT2, -INVSQRT2, // 2-3
|
||||
-INVSQRT2, 0, -INVSQRT2, // 3-0
|
||||
|
||||
0, INVSQRT2, INVSQRT2, // 7-6
|
||||
INVSQRT2, 0, INVSQRT2, // 6-5
|
||||
0, -INVSQRT2, INVSQRT2, // 5-4
|
||||
-INVSQRT2, 0, INVSQRT2, // 4-7
|
||||
|
||||
INVSQRT2, -INVSQRT2, 0, // 1-5
|
||||
INVSQRT2, INVSQRT2, 0, // 6-2
|
||||
-INVSQRT2, INVSQRT2, 0, // 3-7
|
||||
-INVSQRT2, -INVSQRT2, 0 // 4-0
|
||||
};
|
||||
return (const Point*)EdgeNormals;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// (C) 1996-98 Vienna University of Technology
|
||||
// ===========================================================================
|
||||
// NAME: bboxarea
|
||||
// TYPE: c++ code
|
||||
// PROJECT: Bounding Box Area
|
||||
// CONTENT: Computes area of 2D projection of 3D oriented bounding box
|
||||
// VERSION: 1.0
|
||||
// ===========================================================================
|
||||
// AUTHORS: ds Dieter Schmalstieg
|
||||
// ep Erik Pojar
|
||||
// ===========================================================================
|
||||
// HISTORY:
|
||||
//
|
||||
// 19-sep-99 15:23:03 ds last modification
|
||||
// 01-dec-98 15:23:03 ep created
|
||||
// ===========================================================================
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SAMPLE CODE STARTS HERE
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// NOTE: This sample program requires OPEN INVENTOR!
|
||||
|
||||
//indexlist: this table stores the 64 possible cases of classification of
|
||||
//the eyepoint with respect to the 6 defining planes of the bbox (2^6=64)
|
||||
//only 26 (3^3-1, where 1 is "inside" cube) of these cases are valid.
|
||||
//the first 6 numbers in each row are the indices of the bbox vertices that
|
||||
//form the outline of which we want to compute the area (counterclockwise
|
||||
//ordering), the 7th entry means the number of vertices in the outline.
|
||||
//there are 6 cases with a single face and and a 4-vertex outline, and
|
||||
//20 cases with 2 or 3 faces and a 6-vertex outline. a value of 0 indicates
|
||||
//an invalid case.
|
||||
|
||||
|
||||
// Original list was made of 7 items, I added an 8th element:
|
||||
// - to padd on a cache line
|
||||
// - to repeat the first entry to avoid modulos
|
||||
//
|
||||
// I also replaced original ints with sbytes.
|
||||
|
||||
static const sbyte gIndexList[64][8] =
|
||||
{
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, // 0 inside
|
||||
{ 0, 4, 7, 3, 0,-1,-1, 4}, // 1 left
|
||||
{ 1, 2, 6, 5, 1,-1,-1, 4}, // 2 right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, // 3 -
|
||||
{ 0, 1, 5, 4, 0,-1,-1, 4}, // 4 bottom
|
||||
{ 0, 1, 5, 4, 7, 3, 0, 6}, // 5 bottom, left
|
||||
{ 0, 1, 2, 6, 5, 4, 0, 6}, // 6 bottom, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, // 7 -
|
||||
{ 2, 3, 7, 6, 2,-1,-1, 4}, // 8 top
|
||||
{ 0, 4, 7, 6, 2, 3, 0, 6}, // 9 top, left
|
||||
{ 1, 2, 3, 7, 6, 5, 1, 6}, //10 top, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //11 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //12 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //13 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //14 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //15 -
|
||||
{ 0, 3, 2, 1, 0,-1,-1, 4}, //16 front
|
||||
{ 0, 4, 7, 3, 2, 1, 0, 6}, //17 front, left
|
||||
{ 0, 3, 2, 6, 5, 1, 0, 6}, //18 front, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //19 -
|
||||
{ 0, 3, 2, 1, 5, 4, 0, 6}, //20 front, bottom
|
||||
{ 1, 5, 4, 7, 3, 2, 1, 6}, //21 front, bottom, left
|
||||
{ 0, 3, 2, 6, 5, 4, 0, 6}, //22 front, bottom, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //23 -
|
||||
{ 0, 3, 7, 6, 2, 1, 0, 6}, //24 front, top
|
||||
{ 0, 4, 7, 6, 2, 1, 0, 6}, //25 front, top, left
|
||||
{ 0, 3, 7, 6, 5, 1, 0, 6}, //26 front, top, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //27 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //28 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //29 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //30 -
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //31 -
|
||||
{ 4, 5, 6, 7, 4,-1,-1, 4}, //32 back
|
||||
{ 0, 4, 5, 6, 7, 3, 0, 6}, //33 back, left
|
||||
{ 1, 2, 6, 7, 4, 5, 1, 6}, //34 back, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //35 -
|
||||
{ 0, 1, 5, 6, 7, 4, 0, 6}, //36 back, bottom
|
||||
{ 0, 1, 5, 6, 7, 3, 0, 6}, //37 back, bottom, left
|
||||
{ 0, 1, 2, 6, 7, 4, 0, 6}, //38 back, bottom, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //39 -
|
||||
{ 2, 3, 7, 4, 5, 6, 2, 6}, //40 back, top
|
||||
{ 0, 4, 5, 6, 2, 3, 0, 6}, //41 back, top, left
|
||||
{ 1, 2, 3, 7, 4, 5, 1, 6}, //42 back, top, right
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //43 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //44 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //45 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //46 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //47 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //48 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //49 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //50 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //51 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //52 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //53 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //54 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //55 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //56 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //57 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //58 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //59 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //60 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //61 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0}, //62 invalid
|
||||
{-1,-1,-1,-1,-1,-1,-1, 0} //63 invalid
|
||||
};
|
||||
|
||||
const sbyte* AABB::ComputeOutline(const Point& local_eye, sdword& num) const
|
||||
{
|
||||
// Get box corners
|
||||
Point min; GetMin(min);
|
||||
Point max; GetMax(max);
|
||||
|
||||
// Compute 6-bit code to classify eye with respect to the 6 defining planes of the bbox
|
||||
int pos = ((local_eye.x < min.x) ? 1 : 0) // 1 = left
|
||||
+ ((local_eye.x > max.x) ? 2 : 0) // 2 = right
|
||||
+ ((local_eye.y < min.y) ? 4 : 0) // 4 = bottom
|
||||
+ ((local_eye.y > max.y) ? 8 : 0) // 8 = top
|
||||
+ ((local_eye.z < min.z) ? 16 : 0) // 16 = front
|
||||
+ ((local_eye.z > max.z) ? 32 : 0); // 32 = back
|
||||
|
||||
// Look up number of vertices in outline
|
||||
num = (sdword)gIndexList[pos][7];
|
||||
// Zero indicates invalid case
|
||||
if(!num) return null;
|
||||
|
||||
return &gIndexList[pos][0];
|
||||
}
|
||||
|
||||
// calculateBoxArea: computes the screen-projected 2D area of an oriented 3D bounding box
|
||||
|
||||
//const Point& eye, //eye point (in bbox object coordinates)
|
||||
//const AABB& box, //3d bbox
|
||||
//const Matrix4x4& mat, //free transformation for bbox
|
||||
//float width, float height, int& num)
|
||||
float AABB::ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num) const
|
||||
{
|
||||
const sbyte* Outline = ComputeOutline(eye, num);
|
||||
if(!Outline) return -1.0f;
|
||||
|
||||
// Compute box vertices
|
||||
Point vertexBox[8], dst[8];
|
||||
ComputePoints(vertexBox);
|
||||
|
||||
// Transform all outline corners into 2D screen space
|
||||
for(sdword i=0;i<num;i++)
|
||||
{
|
||||
HPoint Projected;
|
||||
vertexBox[Outline[i]].ProjectToScreen(width, height, mat, Projected);
|
||||
dst[i] = Projected;
|
||||
}
|
||||
|
||||
float Sum = (dst[num-1][0] - dst[0][0]) * (dst[num-1][1] + dst[0][1]);
|
||||
|
||||
for(int i=0; i<num-1; i++)
|
||||
Sum += (dst[i][0] - dst[i+1][0]) * (dst[i][1] + dst[i+1][1]);
|
||||
|
||||
return Sum * 0.5f; //return computed value corrected by 0.5
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,52 +1,52 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains an allocator base class.
|
||||
* \file IceAllocator.h
|
||||
* \author Pierre Terdiman
|
||||
* \date December, 19, 2003
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEALLOCATOR_H
|
||||
#define ICEALLOCATOR_H
|
||||
|
||||
enum MemoryType
|
||||
{
|
||||
MEMORY_PERSISTENT,
|
||||
MEMORY_TEMP,
|
||||
};
|
||||
|
||||
class ICECORE_API Allocator
|
||||
{
|
||||
public:
|
||||
virtual void* malloc(size_t size, MemoryType type) = 0;
|
||||
virtual void* mallocDebug(size_t size, const char* filename, udword line, const char* class_name, MemoryType type) = 0;
|
||||
virtual void* realloc(void* memory, size_t size) = 0;
|
||||
virtual void* shrink(void* memory, size_t size) = 0;
|
||||
virtual void free(void* memory) = 0;
|
||||
};
|
||||
|
||||
FUNCTION ICECORE_API Allocator* GetAllocator();
|
||||
FUNCTION ICECORE_API bool SetAllocator(Allocator& allocator);
|
||||
FUNCTION ICECORE_API void DumpMemory();
|
||||
|
||||
class ICECORE_API Allocateable
|
||||
{
|
||||
public:
|
||||
#ifdef DONT_TRACK_MEMORY_LEAKS
|
||||
inline_ void* operator new (size_t size, MemoryType type) { return GetAllocator()->malloc(size, type); }
|
||||
inline_ void* operator new (size_t size, const char * filename, int line, const char* class_name, MemoryType type) { return GetAllocator()->mallocDebug(size, filename, line, class_name, type); }
|
||||
inline_ void* operator new[] (size_t size, MemoryType type) { return GetAllocator()->malloc(size, type); }
|
||||
inline_ void* operator new[] (size_t size, const char * filename, int line, const char* class_name, MemoryType type) { return GetAllocator()->mallocDebug(size, filename, line, class_name, type); }
|
||||
inline_ void operator delete (void* p) { GetAllocator()->free(p); }
|
||||
inline_ void operator delete (void* p, MemoryType) { GetAllocator()->free(p); }
|
||||
inline_ void operator delete (void* p, const char*, int, const char*, MemoryType) { GetAllocator()->free(p); }
|
||||
inline_ void operator delete[] (void* p) { GetAllocator()->free(p); }
|
||||
inline_ void operator delete[] (void* p, MemoryType) { GetAllocator()->free(p); }
|
||||
inline_ void operator delete[] (void* p, const char*, int, const char*, MemoryType) { GetAllocator()->free(p); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // ICEALLOCATOR_H
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains an allocator base class.
|
||||
* \file IceAllocator.h
|
||||
* \author Pierre Terdiman
|
||||
* \date December, 19, 2003
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEALLOCATOR_H
|
||||
#define ICEALLOCATOR_H
|
||||
|
||||
enum MemoryType
|
||||
{
|
||||
MEMORY_PERSISTENT,
|
||||
MEMORY_TEMP,
|
||||
};
|
||||
|
||||
class ICECORE_API Allocator
|
||||
{
|
||||
public:
|
||||
virtual void* malloc(size_t size, MemoryType type) = 0;
|
||||
virtual void* mallocDebug(size_t size, const char* filename, udword line, const char* class_name, MemoryType type) = 0;
|
||||
virtual void* realloc(void* memory, size_t size) = 0;
|
||||
virtual void* shrink(void* memory, size_t size) = 0;
|
||||
virtual void free(void* memory) = 0;
|
||||
};
|
||||
|
||||
FUNCTION ICECORE_API Allocator* GetAllocator();
|
||||
FUNCTION ICECORE_API bool SetAllocator(Allocator& allocator);
|
||||
FUNCTION ICECORE_API void DumpMemory();
|
||||
|
||||
class ICECORE_API Allocateable
|
||||
{
|
||||
public:
|
||||
#ifdef DONT_TRACK_MEMORY_LEAKS
|
||||
inline_ void* operator new (size_t size, MemoryType type) { return GetAllocator()->malloc(size, type); }
|
||||
inline_ void* operator new (size_t size, const char * filename, int line, const char* class_name, MemoryType type) { return GetAllocator()->mallocDebug(size, filename, line, class_name, type); }
|
||||
inline_ void* operator new[] (size_t size, MemoryType type) { return GetAllocator()->malloc(size, type); }
|
||||
inline_ void* operator new[] (size_t size, const char * filename, int line, const char* class_name, MemoryType type) { return GetAllocator()->mallocDebug(size, filename, line, class_name, type); }
|
||||
inline_ void operator delete (void* p) { GetAllocator()->free(p); }
|
||||
inline_ void operator delete (void* p, MemoryType) { GetAllocator()->free(p); }
|
||||
inline_ void operator delete (void* p, const char*, int, const char*, MemoryType) { GetAllocator()->free(p); }
|
||||
inline_ void operator delete[] (void* p) { GetAllocator()->free(p); }
|
||||
inline_ void operator delete[] (void* p, MemoryType) { GetAllocator()->free(p); }
|
||||
inline_ void operator delete[] (void* p, const char*, int, const char*, MemoryType) { GetAllocator()->free(p); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // ICEALLOCATOR_H
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains custom assertion code.
|
||||
* \file IceAssert.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 14, 2001
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEASSERT_H
|
||||
#define ICEASSERT_H
|
||||
|
||||
// Leave the {} so that you can write this kind of things safely in release mode:
|
||||
// if(condition) ASSERT()
|
||||
|
||||
#ifndef ASSERT
|
||||
#if defined( _DEBUG )
|
||||
FUNCTION ICECORE_API bool CustomAssertFunction(int, char*, int, char*, bool&);
|
||||
|
||||
//! Custom ASSERT function. Various usages:
|
||||
//! ASSERT(condition)
|
||||
//! ASSERT(!"Not implemented")
|
||||
//! ASSERT(condition && "error text")
|
||||
#define ASSERT(exp) \
|
||||
{ \
|
||||
static bool IgnoreAlways = false; \
|
||||
if(!IgnoreAlways) \
|
||||
{ \
|
||||
if(CustomAssertFunction((int)(exp), #exp, __LINE__, __FILE__, IgnoreAlways)) \
|
||||
{ \
|
||||
_asm { int 3 } \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define ASSERT(exp) {}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef assert
|
||||
#define assert ASSERT
|
||||
#endif
|
||||
|
||||
#define ICE_COMPILE_TIME_ASSERT(exp) extern char ICE_Dummy[ (exp) ? 1 : -1 ]
|
||||
|
||||
#endif // ICEASSERT_H
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains custom assertion code.
|
||||
* \file IceAssert.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 14, 2001
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEASSERT_H
|
||||
#define ICEASSERT_H
|
||||
|
||||
// Leave the {} so that you can write this kind of things safely in release mode:
|
||||
// if(condition) ASSERT()
|
||||
|
||||
#ifndef ASSERT
|
||||
#if defined( _DEBUG )
|
||||
FUNCTION ICECORE_API bool CustomAssertFunction(int, char*, int, char*, bool&);
|
||||
|
||||
//! Custom ASSERT function. Various usages:
|
||||
//! ASSERT(condition)
|
||||
//! ASSERT(!"Not implemented")
|
||||
//! ASSERT(condition && "error text")
|
||||
#define ASSERT(exp) \
|
||||
{ \
|
||||
static bool IgnoreAlways = false; \
|
||||
if(!IgnoreAlways) \
|
||||
{ \
|
||||
if(CustomAssertFunction((int)(exp), #exp, __LINE__, __FILE__, IgnoreAlways)) \
|
||||
{ \
|
||||
_asm { int 3 } \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define ASSERT(exp) {}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef assert
|
||||
#define assert ASSERT
|
||||
#endif
|
||||
|
||||
#define ICE_COMPILE_TIME_ASSERT(exp) extern char ICE_Dummy[ (exp) ? 1 : -1 ]
|
||||
|
||||
#endif // ICEASSERT_H
|
||||
|
||||
@@ -1,70 +1,70 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains axes definition.
|
||||
* \file IceAxes.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 29, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEAXES_H__
|
||||
#define __ICEAXES_H__
|
||||
|
||||
enum PointComponent
|
||||
{
|
||||
_X = 0,
|
||||
_Y = 1,
|
||||
_Z = 2,
|
||||
_W = 3,
|
||||
|
||||
_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
enum AxisOrder
|
||||
{
|
||||
AXES_XYZ = (_X)|(_Y<<2)|(_Z<<4),
|
||||
AXES_XZY = (_X)|(_Z<<2)|(_Y<<4),
|
||||
AXES_YXZ = (_Y)|(_X<<2)|(_Z<<4),
|
||||
AXES_YZX = (_Y)|(_Z<<2)|(_X<<4),
|
||||
AXES_ZXY = (_Z)|(_X<<2)|(_Y<<4),
|
||||
AXES_ZYX = (_Z)|(_Y<<2)|(_X<<4),
|
||||
|
||||
AXES_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
class ICEMATHS_API Axes
|
||||
{
|
||||
public:
|
||||
|
||||
inline_ Axes(AxisOrder order)
|
||||
{
|
||||
mAxis0 = (order ) & 3;
|
||||
mAxis1 = (order>>2) & 3;
|
||||
mAxis2 = (order>>4) & 3;
|
||||
}
|
||||
inline_ ~Axes() {}
|
||||
|
||||
udword mAxis0;
|
||||
udword mAxis1;
|
||||
udword mAxis2;
|
||||
};
|
||||
|
||||
#endif // __ICEAXES_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains axes definition.
|
||||
* \file IceAxes.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 29, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEAXES_H__
|
||||
#define __ICEAXES_H__
|
||||
|
||||
enum PointComponent
|
||||
{
|
||||
_X = 0,
|
||||
_Y = 1,
|
||||
_Z = 2,
|
||||
_W = 3,
|
||||
|
||||
_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
enum AxisOrder
|
||||
{
|
||||
AXES_XYZ = (_X)|(_Y<<2)|(_Z<<4),
|
||||
AXES_XZY = (_X)|(_Z<<2)|(_Y<<4),
|
||||
AXES_YXZ = (_Y)|(_X<<2)|(_Z<<4),
|
||||
AXES_YZX = (_Y)|(_Z<<2)|(_X<<4),
|
||||
AXES_ZXY = (_Z)|(_X<<2)|(_Y<<4),
|
||||
AXES_ZYX = (_Z)|(_Y<<2)|(_X<<4),
|
||||
|
||||
AXES_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
class ICEMATHS_API Axes
|
||||
{
|
||||
public:
|
||||
|
||||
inline_ Axes(AxisOrder order)
|
||||
{
|
||||
mAxis0 = (order ) & 3;
|
||||
mAxis1 = (order>>2) & 3;
|
||||
mAxis2 = (order>>4) & 3;
|
||||
}
|
||||
inline_ ~Axes() {}
|
||||
|
||||
udword mAxis0;
|
||||
udword mAxis1;
|
||||
udword mAxis2;
|
||||
};
|
||||
|
||||
#endif // __ICEAXES_H__
|
||||
|
||||
@@ -1,73 +1,73 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for bit arrays.
|
||||
* \file IceBitArray.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A simple array of bits stored as bytes.
|
||||
*
|
||||
* \class Container
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "StdAfx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BitArray::BitArray() : mSize(0), mBits(null)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BitArray::BitArray(udword nb_bits) : mSize(0), mBits(null)
|
||||
{
|
||||
Init(nb_bits);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BitArray::~BitArray()
|
||||
{
|
||||
ICE_FREE(mBits);
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Initializes the bit array for a given number of entries
|
||||
* \param nb_bits [in] max number of entries in the array
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool BitArray::Init(udword nb_bits)
|
||||
{
|
||||
mSize = BitsToDwords(nb_bits);
|
||||
// Get ram for n bits
|
||||
ICE_FREE(mBits);
|
||||
mBits = (udword*)ICE_ALLOC(sizeof(udword)*mSize);
|
||||
// Set all bits to 0
|
||||
ClearAll();
|
||||
return true;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for bit arrays.
|
||||
* \file IceBitArray.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A simple array of bits stored as bytes.
|
||||
*
|
||||
* \class Container
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "StdAfx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BitArray::BitArray() : mSize(0), mBits(null)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BitArray::BitArray(udword nb_bits) : mSize(0), mBits(null)
|
||||
{
|
||||
Init(nb_bits);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BitArray::~BitArray()
|
||||
{
|
||||
ICE_FREE(mBits);
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Initializes the bit array for a given number of entries
|
||||
* \param nb_bits [in] max number of entries in the array
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool BitArray::Init(udword nb_bits)
|
||||
{
|
||||
mSize = BitsToDwords(nb_bits);
|
||||
// Get ram for n bits
|
||||
ICE_FREE(mBits);
|
||||
mBits = (udword*)ICE_ALLOC(sizeof(udword)*mSize);
|
||||
// Set all bits to 0
|
||||
ClearAll();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,82 +1,82 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for bit arrays.
|
||||
* \file IceBitArray.h
|
||||
* \author Pierre Terdiman
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEBITARRAY_H
|
||||
#define ICEBITARRAY_H
|
||||
|
||||
inline_ udword BitsToBytes(udword nb_bits)
|
||||
{
|
||||
return (nb_bits>>3) + ((nb_bits&7) ? 1 : 0);
|
||||
}
|
||||
|
||||
inline_ udword BitsToDwords(udword nb_bits)
|
||||
{
|
||||
return (nb_bits>>5) + ((nb_bits&31) ? 1 : 0);
|
||||
}
|
||||
|
||||
// Use that one instead of an array of bools. Takes less ram, nearly as fast [no bounds checkings and so on].
|
||||
class ICECORE_API BitArray
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
BitArray();
|
||||
BitArray(udword nb_bits);
|
||||
//! Destructor
|
||||
~BitArray();
|
||||
|
||||
bool Init(udword nb_bits);
|
||||
|
||||
// Data management
|
||||
inline_ void SetBit(udword bit_number) { mBits[bit_number>>5] |= 1<<(bit_number&31); }
|
||||
inline_ void ClearBit(udword bit_number) { mBits[bit_number>>5] &= ~(1<<(bit_number&31)); }
|
||||
inline_ void ToggleBit(udword bit_number) { mBits[bit_number>>5] ^= 1<<(bit_number&31); }
|
||||
|
||||
inline_ void ClearAll() { ZeroMemory(mBits, mSize*4); }
|
||||
inline_ void SetAll() { FillMemory(mBits, mSize*4, 0xff); }
|
||||
|
||||
// Data access
|
||||
inline_ BOOL IsSet(udword bit_number) const { return mBits[bit_number>>5] & (1<<(bit_number&31)); }
|
||||
|
||||
inline_ const udword* GetBits() const { return mBits; }
|
||||
inline_ udword GetSize() const { return mSize; }
|
||||
|
||||
protected:
|
||||
udword* mBits; //!< Array of bits
|
||||
udword mSize; //!< Size of the array in dwords
|
||||
};
|
||||
|
||||
// - We consider square symmetric N*N matrices
|
||||
// - A N*N symmetric matrix has N(N+1)/2 elements
|
||||
// - A boolean version needs N(N+1)/16 bytes
|
||||
// N NbBits NbBytes
|
||||
// 4 10 -
|
||||
// 8 36 4.5
|
||||
// 16 136 17 <= the one we select
|
||||
// 32 528 66
|
||||
static ubyte BitMasks[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
|
||||
static ubyte NegBitMasks[] = { 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F };
|
||||
class ICECORE_API BoolSquareSymmetricMatrix16
|
||||
{
|
||||
public:
|
||||
inline_ udword Index(udword x, udword y) const { if(x>y) Swap(x,y); return x + (y ? ((y-1)*y)>>1 : 0); }
|
||||
|
||||
inline_ void Set(udword x, udword y) { udword i = Index(x, y); mBits[i>>3] |= BitMasks[i&7]; }
|
||||
inline_ void Clear(udword x, udword y) { udword i = Index(x, y); mBits[i>>3] &= NegBitMasks[i&7]; }
|
||||
inline_ void Toggle(udword x, udword y) { udword i = Index(x, y); mBits[i>>3] ^= BitMasks[i&7]; }
|
||||
inline_ bool IsSet(udword x, udword y) const { udword i = Index(x, y); return (mBits[i>>3] & BitMasks[i&7])!=0; }
|
||||
|
||||
inline_ void ClearAll() { ZeroMemory(mBits, 17); }
|
||||
inline_ void SetAll() { FillMemory(mBits, 17, 0xff); }
|
||||
|
||||
ubyte mBits[17];
|
||||
};
|
||||
|
||||
#endif // ICEBITARRAY_H
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for bit arrays.
|
||||
* \file IceBitArray.h
|
||||
* \author Pierre Terdiman
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEBITARRAY_H
|
||||
#define ICEBITARRAY_H
|
||||
|
||||
inline_ udword BitsToBytes(udword nb_bits)
|
||||
{
|
||||
return (nb_bits>>3) + ((nb_bits&7) ? 1 : 0);
|
||||
}
|
||||
|
||||
inline_ udword BitsToDwords(udword nb_bits)
|
||||
{
|
||||
return (nb_bits>>5) + ((nb_bits&31) ? 1 : 0);
|
||||
}
|
||||
|
||||
// Use that one instead of an array of bools. Takes less ram, nearly as fast [no bounds checkings and so on].
|
||||
class ICECORE_API BitArray
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
BitArray();
|
||||
BitArray(udword nb_bits);
|
||||
//! Destructor
|
||||
~BitArray();
|
||||
|
||||
bool Init(udword nb_bits);
|
||||
|
||||
// Data management
|
||||
inline_ void SetBit(udword bit_number) { mBits[bit_number>>5] |= 1<<(bit_number&31); }
|
||||
inline_ void ClearBit(udword bit_number) { mBits[bit_number>>5] &= ~(1<<(bit_number&31)); }
|
||||
inline_ void ToggleBit(udword bit_number) { mBits[bit_number>>5] ^= 1<<(bit_number&31); }
|
||||
|
||||
inline_ void ClearAll() { ZeroMemory(mBits, mSize*4); }
|
||||
inline_ void SetAll() { FillMemory(mBits, mSize*4, 0xff); }
|
||||
|
||||
// Data access
|
||||
inline_ BOOL IsSet(udword bit_number) const { return mBits[bit_number>>5] & (1<<(bit_number&31)); }
|
||||
|
||||
inline_ const udword* GetBits() const { return mBits; }
|
||||
inline_ udword GetSize() const { return mSize; }
|
||||
|
||||
protected:
|
||||
udword* mBits; //!< Array of bits
|
||||
udword mSize; //!< Size of the array in dwords
|
||||
};
|
||||
|
||||
// - We consider square symmetric N*N matrices
|
||||
// - A N*N symmetric matrix has N(N+1)/2 elements
|
||||
// - A boolean version needs N(N+1)/16 bytes
|
||||
// N NbBits NbBytes
|
||||
// 4 10 -
|
||||
// 8 36 4.5
|
||||
// 16 136 17 <= the one we select
|
||||
// 32 528 66
|
||||
static ubyte BitMasks[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
|
||||
static ubyte NegBitMasks[] = { 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F };
|
||||
class ICECORE_API BoolSquareSymmetricMatrix16
|
||||
{
|
||||
public:
|
||||
inline_ udword Index(udword x, udword y) const { if(x>y) Swap(x,y); return x + (y ? ((y-1)*y)>>1 : 0); }
|
||||
|
||||
inline_ void Set(udword x, udword y) { udword i = Index(x, y); mBits[i>>3] |= BitMasks[i&7]; }
|
||||
inline_ void Clear(udword x, udword y) { udword i = Index(x, y); mBits[i>>3] &= NegBitMasks[i&7]; }
|
||||
inline_ void Toggle(udword x, udword y) { udword i = Index(x, y); mBits[i>>3] ^= BitMasks[i&7]; }
|
||||
inline_ bool IsSet(udword x, udword y) const { udword i = Index(x, y); return (mBits[i>>3] & BitMasks[i&7])!=0; }
|
||||
|
||||
inline_ void ClearAll() { ZeroMemory(mBits, 17); }
|
||||
inline_ void SetAll() { FillMemory(mBits, 17, 0xff); }
|
||||
|
||||
ubyte mBits[17];
|
||||
};
|
||||
|
||||
#endif // ICEBITARRAY_H
|
||||
|
||||
@@ -1,158 +1,158 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code to compute the minimal bounding sphere.
|
||||
* \file IceBoundingSphere.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 29, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEBOUNDINGSPHERE_H__
|
||||
#define __ICEBOUNDINGSPHERE_H__
|
||||
|
||||
enum BSphereMethod
|
||||
{
|
||||
BS_NONE,
|
||||
BS_GEMS,
|
||||
BS_MINIBALL,
|
||||
|
||||
BS_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
class ICEMATHS_API Sphere
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ Sphere() {}
|
||||
//! Constructor
|
||||
inline_ Sphere(const Point& center, float radius) : mCenter(center), mRadius(radius) {}
|
||||
//! Constructor
|
||||
Sphere(udword nb_verts, const Point* verts);
|
||||
//! Copy constructor
|
||||
inline_ Sphere(const Sphere& sphere) : mCenter(sphere.mCenter), mRadius(sphere.mRadius) {}
|
||||
//! Destructor
|
||||
inline_ ~Sphere() {}
|
||||
|
||||
BSphereMethod Compute(udword nb_verts, const Point* verts);
|
||||
bool FastCompute(udword nb_verts, const Point* verts);
|
||||
|
||||
// Access methods
|
||||
inline_ const Point& GetCenter() const { return mCenter; }
|
||||
inline_ float GetRadius() const { return mRadius; }
|
||||
|
||||
inline_ const Point& Center() const { return mCenter; }
|
||||
inline_ float Radius() const { return mRadius; }
|
||||
|
||||
inline_ Sphere& Set(const Point& center, float radius) { mCenter = center; mRadius = radius; return *this; }
|
||||
inline_ Sphere& SetCenter(const Point& center) { mCenter = center; return *this; }
|
||||
inline_ Sphere& SetRadius(float radius) { mRadius = radius; return *this; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a point is contained within the sphere.
|
||||
* \param p [in] the point to test
|
||||
* \return true if inside the sphere
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ bool Contains(const Point& p) const
|
||||
{
|
||||
return mCenter.SquareDistance(p) <= mRadius*mRadius;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a sphere is contained within the sphere.
|
||||
* \param sphere [in] the sphere to test
|
||||
* \return true if inside the sphere
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ bool Contains(const Sphere& sphere) const
|
||||
{
|
||||
// If our radius is the smallest, we can't possibly contain the other sphere
|
||||
if(mRadius < sphere.mRadius) return false;
|
||||
// So r is always positive or null now
|
||||
float r = mRadius - sphere.mRadius;
|
||||
return mCenter.SquareDistance(sphere.mCenter) <= r*r;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a box is contained within the sphere.
|
||||
* \param aabb [in] the box to test
|
||||
* \return true if inside the sphere
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL Contains(const AABB& aabb) const
|
||||
{
|
||||
// I assume if all 8 box vertices are inside the sphere, so does the whole box.
|
||||
// Sounds ok but maybe there's a better way?
|
||||
float R2 = mRadius * mRadius;
|
||||
#ifdef USE_MIN_MAX
|
||||
const Point& Max = ((ShadowAABB&)&aabb).mMax;
|
||||
const Point& Min = ((ShadowAABB&)&aabb).mMin;
|
||||
#else
|
||||
Point Max; aabb.GetMax(Max);
|
||||
Point Min; aabb.GetMin(Min);
|
||||
#endif
|
||||
Point p;
|
||||
p.x=Max.x; p.y=Max.y; p.z=Max.z; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Max.x; p.y=Max.y; p.z=Min.z; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if the sphere intersects another sphere
|
||||
* \param sphere [in] the other sphere
|
||||
* \return true if spheres overlap
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ bool Intersect(const Sphere& sphere) const
|
||||
{
|
||||
float r = mRadius + sphere.mRadius;
|
||||
return mCenter.SquareDistance(sphere.mCenter) <= r*r;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks the sphere is valid.
|
||||
* \return true if the box is valid
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL IsValid() const
|
||||
{
|
||||
// Consistency condition for spheres: Radius >= 0.0f
|
||||
if(mRadius < 0.0f) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
public:
|
||||
Point mCenter; //!< Sphere center
|
||||
float mRadius; //!< Sphere radius
|
||||
};
|
||||
|
||||
#endif // __ICEBOUNDINGSPHERE_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code to compute the minimal bounding sphere.
|
||||
* \file IceBoundingSphere.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 29, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEBOUNDINGSPHERE_H__
|
||||
#define __ICEBOUNDINGSPHERE_H__
|
||||
|
||||
enum BSphereMethod
|
||||
{
|
||||
BS_NONE,
|
||||
BS_GEMS,
|
||||
BS_MINIBALL,
|
||||
|
||||
BS_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
class ICEMATHS_API Sphere
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ Sphere() {}
|
||||
//! Constructor
|
||||
inline_ Sphere(const Point& center, float radius) : mCenter(center), mRadius(radius) {}
|
||||
//! Constructor
|
||||
Sphere(udword nb_verts, const Point* verts);
|
||||
//! Copy constructor
|
||||
inline_ Sphere(const Sphere& sphere) : mCenter(sphere.mCenter), mRadius(sphere.mRadius) {}
|
||||
//! Destructor
|
||||
inline_ ~Sphere() {}
|
||||
|
||||
BSphereMethod Compute(udword nb_verts, const Point* verts);
|
||||
bool FastCompute(udword nb_verts, const Point* verts);
|
||||
|
||||
// Access methods
|
||||
inline_ const Point& GetCenter() const { return mCenter; }
|
||||
inline_ float GetRadius() const { return mRadius; }
|
||||
|
||||
inline_ const Point& Center() const { return mCenter; }
|
||||
inline_ float Radius() const { return mRadius; }
|
||||
|
||||
inline_ Sphere& Set(const Point& center, float radius) { mCenter = center; mRadius = radius; return *this; }
|
||||
inline_ Sphere& SetCenter(const Point& center) { mCenter = center; return *this; }
|
||||
inline_ Sphere& SetRadius(float radius) { mRadius = radius; return *this; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a point is contained within the sphere.
|
||||
* \param p [in] the point to test
|
||||
* \return true if inside the sphere
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ bool Contains(const Point& p) const
|
||||
{
|
||||
return mCenter.SquareDistance(p) <= mRadius*mRadius;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a sphere is contained within the sphere.
|
||||
* \param sphere [in] the sphere to test
|
||||
* \return true if inside the sphere
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ bool Contains(const Sphere& sphere) const
|
||||
{
|
||||
// If our radius is the smallest, we can't possibly contain the other sphere
|
||||
if(mRadius < sphere.mRadius) return false;
|
||||
// So r is always positive or null now
|
||||
float r = mRadius - sphere.mRadius;
|
||||
return mCenter.SquareDistance(sphere.mCenter) <= r*r;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a box is contained within the sphere.
|
||||
* \param aabb [in] the box to test
|
||||
* \return true if inside the sphere
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL Contains(const AABB& aabb) const
|
||||
{
|
||||
// I assume if all 8 box vertices are inside the sphere, so does the whole box.
|
||||
// Sounds ok but maybe there's a better way?
|
||||
float R2 = mRadius * mRadius;
|
||||
#ifdef USE_MIN_MAX
|
||||
const Point& Max = ((ShadowAABB&)&aabb).mMax;
|
||||
const Point& Min = ((ShadowAABB&)&aabb).mMin;
|
||||
#else
|
||||
Point Max; aabb.GetMax(Max);
|
||||
Point Min; aabb.GetMin(Min);
|
||||
#endif
|
||||
Point p;
|
||||
p.x=Max.x; p.y=Max.y; p.z=Max.z; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Max.x; p.y=Max.y; p.z=Min.z; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if the sphere intersects another sphere
|
||||
* \param sphere [in] the other sphere
|
||||
* \return true if spheres overlap
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ bool Intersect(const Sphere& sphere) const
|
||||
{
|
||||
float r = mRadius + sphere.mRadius;
|
||||
return mCenter.SquareDistance(sphere.mCenter) <= r*r;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks the sphere is valid.
|
||||
* \return true if the box is valid
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL IsValid() const
|
||||
{
|
||||
// Consistency condition for spheres: Radius >= 0.0f
|
||||
if(mRadius < 0.0f) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
public:
|
||||
Point mCenter; //!< Sphere center
|
||||
float mRadius; //!< Sphere radius
|
||||
};
|
||||
|
||||
#endif // __ICEBOUNDINGSPHERE_H__
|
||||
|
||||
@@ -1,423 +1,423 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a simple container class.
|
||||
* \file IceContainer.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a list of 32-bits values.
|
||||
* Use this class when you need to store an unknown number of values. The list is automatically
|
||||
* resized and can contains 32-bits entities (dwords or floats)
|
||||
*
|
||||
* \class Container
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
* \date 08.15.98
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "StdAfx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
// Static members
|
||||
#ifdef CONTAINER_STATS
|
||||
udword Container::mNbContainers = 0;
|
||||
udword Container::mUsedRam = 0;
|
||||
LinkedList Container::mContainers;
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor. No entries allocated there.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::Container() : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f)
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers++;
|
||||
mUsedRam+=sizeof(Container);
|
||||
mContainers.AddElem(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor. Also allocates a given number of entries.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::Container(udword size, float growth_factor) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null)
|
||||
{
|
||||
SetGrowthFactor(growth_factor);
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers++;
|
||||
mUsedRam+=sizeof(Container);
|
||||
mContainers.AddElem(this);
|
||||
#endif
|
||||
SetSize(size);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::Container(const Container& object) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f)
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers++;
|
||||
mUsedRam+=sizeof(Container);
|
||||
mContainers.AddElem(this);
|
||||
#endif
|
||||
*this = object;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Destructor. Frees everything and leaves.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::~Container()
|
||||
{
|
||||
Empty();
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers--;
|
||||
mUsedRam-=GetUsedRam();
|
||||
mContainers.RemElem(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Initializes the container so that it uses an external memory buffer. The container doesn't own the memory, resizing is disabled.
|
||||
* \param max_entries [in] max number of entries in the container
|
||||
* \param entries [in] external memory buffer
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Container::InitSharedBuffers(udword max_entries, udword* entries)
|
||||
{
|
||||
Empty(); // Make sure everything has been released
|
||||
mMaxNbEntries = max_entries;
|
||||
mEntries = entries;
|
||||
mGrowthFactor = -1.0f; // Negative growth ==> resize is disabled
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Clears the container. All stored values are deleted, and it frees used ram.
|
||||
* \see Reset()
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Container::Empty()
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
if(mGrowthFactor>=0.0f) ICE_FREE(mEntries); // Release memory if we own it
|
||||
mCurNbEntries = mMaxNbEntries = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Resizes the container.
|
||||
* \param needed [in] assume the container can be added at least "needed" values
|
||||
* \return true if success.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Resize(udword needed)
|
||||
{
|
||||
// Check growth is allowed
|
||||
if(mGrowthFactor<=0.0f)
|
||||
{
|
||||
ASSERT(!"Invalid operation - trying to resize a static buffer!");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Subtract previous amount of bytes
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Get more entries
|
||||
mMaxNbEntries = mMaxNbEntries ? udword(float(mMaxNbEntries)*mGrowthFactor) : 2; // Default nb Entries = 2
|
||||
if(mMaxNbEntries<mCurNbEntries + needed) mMaxNbEntries = mCurNbEntries + needed;
|
||||
|
||||
// Get some bytes for new entries
|
||||
udword* NewEntries = (udword*)ICE_ALLOC(sizeof(udword)*mMaxNbEntries);
|
||||
CHECKALLOC(NewEntries);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Copy old data if needed
|
||||
if(mCurNbEntries) CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword));
|
||||
|
||||
// Delete old data
|
||||
ICE_FREE(mEntries);
|
||||
|
||||
// Assign new pointer
|
||||
mEntries = NewEntries;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Sets the initial size of the container. If it already contains something, it's discarded.
|
||||
* \param nb [in] Number of entries
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::SetSize(udword nb)
|
||||
{
|
||||
// Make sure it's empty
|
||||
Empty();
|
||||
|
||||
// Checkings
|
||||
if(!nb) return false;
|
||||
|
||||
// Initialize for nb entries
|
||||
mMaxNbEntries = nb;
|
||||
|
||||
// Get some bytes for new entries
|
||||
mEntries = (udword*)ICE_ALLOC(sizeof(udword)*mMaxNbEntries);
|
||||
CHECKALLOC(mEntries);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the container and get rid of unused bytes.
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Refit()
|
||||
{
|
||||
// Check refit is allowed
|
||||
if(mGrowthFactor<=0.0f)
|
||||
{
|
||||
ASSERT(!"Invalid operation - trying to refit a static buffer!");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Subtract previous amount of bytes
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Get just enough entries
|
||||
mMaxNbEntries = mCurNbEntries;
|
||||
if(!mMaxNbEntries) return false;
|
||||
|
||||
// Get just enough bytes
|
||||
udword* NewEntries = (udword*)ICE_ALLOC(sizeof(udword)*mMaxNbEntries);
|
||||
CHECKALLOC(NewEntries);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Copy old data
|
||||
CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword));
|
||||
|
||||
// Delete old data
|
||||
ICE_FREE(mEntries);
|
||||
|
||||
// Assign new pointer
|
||||
mEntries = NewEntries;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Same as Refit but more efficient
|
||||
bool Container::Shrink()
|
||||
{
|
||||
if(!mEntries) return false;
|
||||
if(!mCurNbEntries)
|
||||
{
|
||||
Empty();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to shrink the pointer
|
||||
if(!GetAllocator()->shrink(mEntries, sizeof(udword)*mCurNbEntries))
|
||||
return false;
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Subtract previous amount of bytes
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Get just enough entries
|
||||
mMaxNbEntries = mCurNbEntries;
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks whether the container already contains a given value.
|
||||
* \param entry [in] the value to look for in the container
|
||||
* \param location [out] a possible pointer to store the entry location
|
||||
* \see Add(udword entry)
|
||||
* \see Add(float entry)
|
||||
* \see Empty()
|
||||
* \return true if the value has been found in the container, else false.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Contains(udword entry, udword* location) const
|
||||
{
|
||||
// Look for the entry
|
||||
for(udword i=0;i<mCurNbEntries;i++)
|
||||
{
|
||||
if(mEntries[i]==entry)
|
||||
{
|
||||
if(location) *location = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Deletes an entry. If the container contains such an entry, it's removed.
|
||||
* \param entry [in] the value to delete.
|
||||
* \return true if the value has been found in the container, else false.
|
||||
* \warning This method is arbitrary slow (O(n)) and should be used carefully. Insertion order is not preserved.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Delete(udword entry)
|
||||
{
|
||||
// Look for the entry
|
||||
for(udword i=0;i<mCurNbEntries;i++)
|
||||
{
|
||||
if(mEntries[i]==entry)
|
||||
{
|
||||
// Entry has been found at index i. The strategy is to copy the last current entry at index i, and decrement the current number of entries.
|
||||
DeleteIndex(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Deletes an entry, preserving the insertion order. If the container contains such an entry, it's removed.
|
||||
* \param entry [in] the value to delete.
|
||||
* \return true if the value has been found in the container, else false.
|
||||
* \warning This method is arbitrary slow (O(n)) and should be used carefully.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::DeleteKeepingOrder(udword entry)
|
||||
{
|
||||
// Look for the entry
|
||||
for(udword i=0;i<mCurNbEntries;i++)
|
||||
{
|
||||
if(mEntries[i]==entry)
|
||||
{
|
||||
// Entry has been found at index i.
|
||||
// Shift entries to preserve order. You really should use a linked list instead.
|
||||
mCurNbEntries--;
|
||||
for(udword j=i;j<mCurNbEntries;j++)
|
||||
{
|
||||
mEntries[j] = mEntries[j+1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the next entry, starting from input one.
|
||||
* \param entry [in/out] On input, the entry to look for. On output, the next entry
|
||||
* \param find_mode [in] wrap/clamp
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Container::FindNext(udword& entry, FindMode find_mode)
|
||||
{
|
||||
udword Location;
|
||||
if(Contains(entry, &Location))
|
||||
{
|
||||
Location++;
|
||||
if(Location==mCurNbEntries) Location = find_mode==FIND_WRAP ? 0 : mCurNbEntries-1;
|
||||
entry = mEntries[Location];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the previous entry, starting from input one.
|
||||
* \param entry [in/out] On input, the entry to look for. On output, the previous entry
|
||||
* \param find_mode [in] wrap/clamp
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Container::FindPrev(udword& entry, FindMode find_mode)
|
||||
{
|
||||
udword Location;
|
||||
if(Contains(entry, &Location))
|
||||
{
|
||||
Location--;
|
||||
if(Location==0xffffffff) Location = find_mode==FIND_WRAP ? mCurNbEntries-1 : 0;
|
||||
entry = mEntries[Location];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the ram used by the container.
|
||||
* \return the ram used in bytes.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
udword Container::GetUsedRam() const
|
||||
{
|
||||
return sizeof(Container) + mMaxNbEntries * sizeof(udword);
|
||||
}
|
||||
|
||||
float Container::GetGrowthFactor() const
|
||||
{
|
||||
return mGrowthFactor;
|
||||
}
|
||||
|
||||
void Container::SetGrowthFactor(float growth)
|
||||
{
|
||||
// Negative growths are reserved for internal usages
|
||||
if(growth<0.0f) growth = 0.0f;
|
||||
mGrowthFactor = growth;
|
||||
}
|
||||
|
||||
//! Operator for "Container A = Container B"
|
||||
void Container::operator=(const Container& object)
|
||||
{
|
||||
SetSize(object.GetNbEntries());
|
||||
CopyMemory(mEntries, object.GetEntries(), mMaxNbEntries*sizeof(udword));
|
||||
mCurNbEntries = mMaxNbEntries;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a simple container class.
|
||||
* \file IceContainer.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a list of 32-bits values.
|
||||
* Use this class when you need to store an unknown number of values. The list is automatically
|
||||
* resized and can contains 32-bits entities (dwords or floats)
|
||||
*
|
||||
* \class Container
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
* \date 08.15.98
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "StdAfx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
// Static members
|
||||
#ifdef CONTAINER_STATS
|
||||
udword Container::mNbContainers = 0;
|
||||
udword Container::mUsedRam = 0;
|
||||
LinkedList Container::mContainers;
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor. No entries allocated there.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::Container() : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f)
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers++;
|
||||
mUsedRam+=sizeof(Container);
|
||||
mContainers.AddElem(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor. Also allocates a given number of entries.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::Container(udword size, float growth_factor) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null)
|
||||
{
|
||||
SetGrowthFactor(growth_factor);
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers++;
|
||||
mUsedRam+=sizeof(Container);
|
||||
mContainers.AddElem(this);
|
||||
#endif
|
||||
SetSize(size);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::Container(const Container& object) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f)
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers++;
|
||||
mUsedRam+=sizeof(Container);
|
||||
mContainers.AddElem(this);
|
||||
#endif
|
||||
*this = object;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Destructor. Frees everything and leaves.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::~Container()
|
||||
{
|
||||
Empty();
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers--;
|
||||
mUsedRam-=GetUsedRam();
|
||||
mContainers.RemElem(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Initializes the container so that it uses an external memory buffer. The container doesn't own the memory, resizing is disabled.
|
||||
* \param max_entries [in] max number of entries in the container
|
||||
* \param entries [in] external memory buffer
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Container::InitSharedBuffers(udword max_entries, udword* entries)
|
||||
{
|
||||
Empty(); // Make sure everything has been released
|
||||
mMaxNbEntries = max_entries;
|
||||
mEntries = entries;
|
||||
mGrowthFactor = -1.0f; // Negative growth ==> resize is disabled
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Clears the container. All stored values are deleted, and it frees used ram.
|
||||
* \see Reset()
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Container::Empty()
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
if(mGrowthFactor>=0.0f) ICE_FREE(mEntries); // Release memory if we own it
|
||||
mCurNbEntries = mMaxNbEntries = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Resizes the container.
|
||||
* \param needed [in] assume the container can be added at least "needed" values
|
||||
* \return true if success.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Resize(udword needed)
|
||||
{
|
||||
// Check growth is allowed
|
||||
if(mGrowthFactor<=0.0f)
|
||||
{
|
||||
ASSERT(!"Invalid operation - trying to resize a static buffer!");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Subtract previous amount of bytes
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Get more entries
|
||||
mMaxNbEntries = mMaxNbEntries ? udword(float(mMaxNbEntries)*mGrowthFactor) : 2; // Default nb Entries = 2
|
||||
if(mMaxNbEntries<mCurNbEntries + needed) mMaxNbEntries = mCurNbEntries + needed;
|
||||
|
||||
// Get some bytes for new entries
|
||||
udword* NewEntries = (udword*)ICE_ALLOC(sizeof(udword)*mMaxNbEntries);
|
||||
CHECKALLOC(NewEntries);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Copy old data if needed
|
||||
if(mCurNbEntries) CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword));
|
||||
|
||||
// Delete old data
|
||||
ICE_FREE(mEntries);
|
||||
|
||||
// Assign new pointer
|
||||
mEntries = NewEntries;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Sets the initial size of the container. If it already contains something, it's discarded.
|
||||
* \param nb [in] Number of entries
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::SetSize(udword nb)
|
||||
{
|
||||
// Make sure it's empty
|
||||
Empty();
|
||||
|
||||
// Checkings
|
||||
if(!nb) return false;
|
||||
|
||||
// Initialize for nb entries
|
||||
mMaxNbEntries = nb;
|
||||
|
||||
// Get some bytes for new entries
|
||||
mEntries = (udword*)ICE_ALLOC(sizeof(udword)*mMaxNbEntries);
|
||||
CHECKALLOC(mEntries);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the container and get rid of unused bytes.
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Refit()
|
||||
{
|
||||
// Check refit is allowed
|
||||
if(mGrowthFactor<=0.0f)
|
||||
{
|
||||
ASSERT(!"Invalid operation - trying to refit a static buffer!");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Subtract previous amount of bytes
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Get just enough entries
|
||||
mMaxNbEntries = mCurNbEntries;
|
||||
if(!mMaxNbEntries) return false;
|
||||
|
||||
// Get just enough bytes
|
||||
udword* NewEntries = (udword*)ICE_ALLOC(sizeof(udword)*mMaxNbEntries);
|
||||
CHECKALLOC(NewEntries);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Copy old data
|
||||
CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword));
|
||||
|
||||
// Delete old data
|
||||
ICE_FREE(mEntries);
|
||||
|
||||
// Assign new pointer
|
||||
mEntries = NewEntries;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Same as Refit but more efficient
|
||||
bool Container::Shrink()
|
||||
{
|
||||
if(!mEntries) return false;
|
||||
if(!mCurNbEntries)
|
||||
{
|
||||
Empty();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to shrink the pointer
|
||||
if(!GetAllocator()->shrink(mEntries, sizeof(udword)*mCurNbEntries))
|
||||
return false;
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Subtract previous amount of bytes
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Get just enough entries
|
||||
mMaxNbEntries = mCurNbEntries;
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks whether the container already contains a given value.
|
||||
* \param entry [in] the value to look for in the container
|
||||
* \param location [out] a possible pointer to store the entry location
|
||||
* \see Add(udword entry)
|
||||
* \see Add(float entry)
|
||||
* \see Empty()
|
||||
* \return true if the value has been found in the container, else false.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Contains(udword entry, udword* location) const
|
||||
{
|
||||
// Look for the entry
|
||||
for(udword i=0;i<mCurNbEntries;i++)
|
||||
{
|
||||
if(mEntries[i]==entry)
|
||||
{
|
||||
if(location) *location = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Deletes an entry. If the container contains such an entry, it's removed.
|
||||
* \param entry [in] the value to delete.
|
||||
* \return true if the value has been found in the container, else false.
|
||||
* \warning This method is arbitrary slow (O(n)) and should be used carefully. Insertion order is not preserved.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Delete(udword entry)
|
||||
{
|
||||
// Look for the entry
|
||||
for(udword i=0;i<mCurNbEntries;i++)
|
||||
{
|
||||
if(mEntries[i]==entry)
|
||||
{
|
||||
// Entry has been found at index i. The strategy is to copy the last current entry at index i, and decrement the current number of entries.
|
||||
DeleteIndex(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Deletes an entry, preserving the insertion order. If the container contains such an entry, it's removed.
|
||||
* \param entry [in] the value to delete.
|
||||
* \return true if the value has been found in the container, else false.
|
||||
* \warning This method is arbitrary slow (O(n)) and should be used carefully.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::DeleteKeepingOrder(udword entry)
|
||||
{
|
||||
// Look for the entry
|
||||
for(udword i=0;i<mCurNbEntries;i++)
|
||||
{
|
||||
if(mEntries[i]==entry)
|
||||
{
|
||||
// Entry has been found at index i.
|
||||
// Shift entries to preserve order. You really should use a linked list instead.
|
||||
mCurNbEntries--;
|
||||
for(udword j=i;j<mCurNbEntries;j++)
|
||||
{
|
||||
mEntries[j] = mEntries[j+1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the next entry, starting from input one.
|
||||
* \param entry [in/out] On input, the entry to look for. On output, the next entry
|
||||
* \param find_mode [in] wrap/clamp
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Container::FindNext(udword& entry, FindMode find_mode)
|
||||
{
|
||||
udword Location;
|
||||
if(Contains(entry, &Location))
|
||||
{
|
||||
Location++;
|
||||
if(Location==mCurNbEntries) Location = find_mode==FIND_WRAP ? 0 : mCurNbEntries-1;
|
||||
entry = mEntries[Location];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the previous entry, starting from input one.
|
||||
* \param entry [in/out] On input, the entry to look for. On output, the previous entry
|
||||
* \param find_mode [in] wrap/clamp
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Container::FindPrev(udword& entry, FindMode find_mode)
|
||||
{
|
||||
udword Location;
|
||||
if(Contains(entry, &Location))
|
||||
{
|
||||
Location--;
|
||||
if(Location==0xffffffff) Location = find_mode==FIND_WRAP ? mCurNbEntries-1 : 0;
|
||||
entry = mEntries[Location];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the ram used by the container.
|
||||
* \return the ram used in bytes.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
udword Container::GetUsedRam() const
|
||||
{
|
||||
return sizeof(Container) + mMaxNbEntries * sizeof(udword);
|
||||
}
|
||||
|
||||
float Container::GetGrowthFactor() const
|
||||
{
|
||||
return mGrowthFactor;
|
||||
}
|
||||
|
||||
void Container::SetGrowthFactor(float growth)
|
||||
{
|
||||
// Negative growths are reserved for internal usages
|
||||
if(growth<0.0f) growth = 0.0f;
|
||||
mGrowthFactor = growth;
|
||||
}
|
||||
|
||||
//! Operator for "Container A = Container B"
|
||||
void Container::operator=(const Container& object)
|
||||
{
|
||||
SetSize(object.GetNbEntries());
|
||||
CopyMemory(mEntries, object.GetEntries(), mMaxNbEntries*sizeof(udword));
|
||||
mCurNbEntries = mMaxNbEntries;
|
||||
}
|
||||
|
||||
@@ -1,254 +1,254 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a simple container class.
|
||||
* \file IceContainer.h
|
||||
* \author Pierre Terdiman
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICECONTAINER_H
|
||||
#define ICECONTAINER_H
|
||||
|
||||
// #define CONTAINER_STATS // #### doesn't work with micro-threads!
|
||||
|
||||
class LinkedList;
|
||||
|
||||
enum FindMode
|
||||
{
|
||||
FIND_CLAMP,
|
||||
FIND_WRAP,
|
||||
|
||||
FIND_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
class ICECORE_API Container : public Allocateable
|
||||
#ifdef CONTAINER_STATS
|
||||
, public ListElem
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
Container();
|
||||
Container(const Container& object);
|
||||
Container(udword size, float growth_factor);
|
||||
~Container();
|
||||
// Management
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Initializes the container so that it uses an external memory buffer. The container doesn't own the memory, resizing is disabled.
|
||||
* \param max_entries [in] max number of entries in the container
|
||||
* \param entries [in] external memory buffer
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void InitSharedBuffers(udword max_entries, udword* entries);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A O(1) method to add a value in the container. The container is automatically resized if needed.
|
||||
* The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
|
||||
* costs a lot more than the call overhead...
|
||||
*
|
||||
* \param entry [in] a udword to store in the container
|
||||
* \see Add(float entry)
|
||||
* \see Empty()
|
||||
* \see Contains(udword entry)
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ Container& Add(udword entry)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries==mMaxNbEntries) Resize();
|
||||
|
||||
// Add new entry
|
||||
mEntries[mCurNbEntries++] = entry;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline_ Container& Add(const udword* entries, udword nb)
|
||||
{
|
||||
if(entries && nb)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
|
||||
|
||||
// Add new entry
|
||||
CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(udword));
|
||||
mCurNbEntries += nb;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline_ Container& Add(const Container& container)
|
||||
{
|
||||
return Add(container.GetEntries(), container.GetNbEntries());
|
||||
}
|
||||
|
||||
inline_ udword* Reserve(udword nb)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
|
||||
|
||||
// We expect the user to fill reserved memory with 'nb' udwords
|
||||
udword* Reserved = &mEntries[mCurNbEntries];
|
||||
|
||||
// Meanwhile, we do as if it had been filled
|
||||
mCurNbEntries += nb;
|
||||
|
||||
// This is mainly used to avoid the copy when possible
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A O(1) method to add a value in the container. The container is automatically resized if needed.
|
||||
* The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
|
||||
* costs a lot more than the call overhead...
|
||||
*
|
||||
* \param entry [in] a float to store in the container
|
||||
* \see Add(udword entry)
|
||||
* \see Empty()
|
||||
* \see Contains(udword entry)
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ Container& Add(float entry)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries==mMaxNbEntries) Resize();
|
||||
|
||||
// Add new entry
|
||||
mEntries[mCurNbEntries++] = IR(entry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline_ Container& Add(const float* entries, udword nb)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
|
||||
|
||||
// Add new entry
|
||||
CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(float));
|
||||
mCurNbEntries+=nb;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Add unique [slow]
|
||||
inline_ Container& AddUnique(udword entry)
|
||||
{
|
||||
if(!Contains(entry)) Add(entry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Clears the container. All stored values are deleted, and it frees used ram.
|
||||
* \see Reset()
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Empty();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Resets the container. Stored values are discarded but the buffer is kept so that further calls don't need resizing again.
|
||||
* That's a kind of temporal coherence.
|
||||
* \see Empty()
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void Reset()
|
||||
{
|
||||
// Avoid the write if possible
|
||||
// ### CMOV
|
||||
if(mCurNbEntries) mCurNbEntries = 0;
|
||||
}
|
||||
|
||||
// HANDLE WITH CARE - I hope you know what you're doing
|
||||
inline_ void ForceSize(udword size)
|
||||
{
|
||||
mCurNbEntries = size;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Sets the initial size of the container. If it already contains something, it's discarded.
|
||||
* \param nb [in] Number of entries
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool SetSize(udword nb);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the container and get rid of unused bytes.
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Refit();
|
||||
|
||||
bool Shrink();
|
||||
|
||||
// Checks whether the container already contains a given value.
|
||||
bool Contains(udword entry, udword* location=null) const;
|
||||
// Deletes an entry - doesn't preserve insertion order.
|
||||
bool Delete(udword entry);
|
||||
// Deletes an entry - does preserve insertion order.
|
||||
bool DeleteKeepingOrder(udword entry);
|
||||
//! Deletes the very last entry.
|
||||
inline_ void DeleteLastEntry() { if(mCurNbEntries) mCurNbEntries--; }
|
||||
//! Deletes the entry whose index is given
|
||||
inline_ void DeleteIndex(udword index) { mEntries[index] = mEntries[--mCurNbEntries]; }
|
||||
|
||||
// Helpers
|
||||
Container& FindNext(udword& entry, FindMode find_mode=FIND_CLAMP);
|
||||
Container& FindPrev(udword& entry, FindMode find_mode=FIND_CLAMP);
|
||||
// Data access.
|
||||
inline_ udword GetNbEntries() const { return mCurNbEntries; } //!< Returns the current number of entries.
|
||||
inline_ udword GetMaxNbEntries() const { return mMaxNbEntries; } //!< Returns max number of entries before resizing.
|
||||
inline_ udword GetEntry(udword i) const { return mEntries[i]; } //!< Returns ith entry.
|
||||
inline_ udword* GetEntries() const { return mEntries; } //!< Returns the list of entries.
|
||||
|
||||
inline_ udword GetFirst() const { return mEntries[0]; }
|
||||
inline_ udword GetLast() const { return mEntries[mCurNbEntries-1]; }
|
||||
|
||||
// Growth control
|
||||
float GetGrowthFactor() const; //!< Returns the growth factor
|
||||
void SetGrowthFactor(float growth); //!< Sets the growth factor
|
||||
inline_ bool IsFull() const { return mCurNbEntries==mMaxNbEntries; } //!< Checks the container is full
|
||||
inline_ BOOL IsNotEmpty() const { return mCurNbEntries; } //!< Checks the container is empty
|
||||
|
||||
//! Read-access as an array
|
||||
inline_ udword operator[](udword i) const { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; }
|
||||
//! Write-access as an array
|
||||
inline_ udword& operator[](udword i) { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; }
|
||||
|
||||
// Stats
|
||||
udword GetUsedRam() const;
|
||||
|
||||
//! Operator for "Container A = Container B"
|
||||
void operator = (const Container& object);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
static udword GetNbContainers() { return mNbContainers; }
|
||||
static udword GetTotalBytes() { return mUsedRam; }
|
||||
static LinkedList& GetContainers() { return mContainers; }
|
||||
private:
|
||||
|
||||
static udword mNbContainers; //!< Number of containers around
|
||||
static udword mUsedRam; //!< Amount of bytes used by containers in the system
|
||||
static LinkedList mContainers;
|
||||
#endif
|
||||
private:
|
||||
// Resizing
|
||||
bool Resize(udword needed=1);
|
||||
// Data
|
||||
udword mMaxNbEntries; //!< Maximum possible number of entries
|
||||
udword mCurNbEntries; //!< Current number of entries
|
||||
udword* mEntries; //!< List of entries
|
||||
float mGrowthFactor; //!< Resize: new number of entries = old number * mGrowthFactor
|
||||
};
|
||||
|
||||
#endif // ICECONTAINER_H
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a simple container class.
|
||||
* \file IceContainer.h
|
||||
* \author Pierre Terdiman
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICECONTAINER_H
|
||||
#define ICECONTAINER_H
|
||||
|
||||
// #define CONTAINER_STATS // #### doesn't work with micro-threads!
|
||||
|
||||
class LinkedList;
|
||||
|
||||
enum FindMode
|
||||
{
|
||||
FIND_CLAMP,
|
||||
FIND_WRAP,
|
||||
|
||||
FIND_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
class ICECORE_API Container : public Allocateable
|
||||
#ifdef CONTAINER_STATS
|
||||
, public ListElem
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
Container();
|
||||
Container(const Container& object);
|
||||
Container(udword size, float growth_factor);
|
||||
~Container();
|
||||
// Management
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Initializes the container so that it uses an external memory buffer. The container doesn't own the memory, resizing is disabled.
|
||||
* \param max_entries [in] max number of entries in the container
|
||||
* \param entries [in] external memory buffer
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void InitSharedBuffers(udword max_entries, udword* entries);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A O(1) method to add a value in the container. The container is automatically resized if needed.
|
||||
* The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
|
||||
* costs a lot more than the call overhead...
|
||||
*
|
||||
* \param entry [in] a udword to store in the container
|
||||
* \see Add(float entry)
|
||||
* \see Empty()
|
||||
* \see Contains(udword entry)
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ Container& Add(udword entry)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries==mMaxNbEntries) Resize();
|
||||
|
||||
// Add new entry
|
||||
mEntries[mCurNbEntries++] = entry;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline_ Container& Add(const udword* entries, udword nb)
|
||||
{
|
||||
if(entries && nb)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
|
||||
|
||||
// Add new entry
|
||||
CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(udword));
|
||||
mCurNbEntries += nb;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline_ Container& Add(const Container& container)
|
||||
{
|
||||
return Add(container.GetEntries(), container.GetNbEntries());
|
||||
}
|
||||
|
||||
inline_ udword* Reserve(udword nb)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
|
||||
|
||||
// We expect the user to fill reserved memory with 'nb' udwords
|
||||
udword* Reserved = &mEntries[mCurNbEntries];
|
||||
|
||||
// Meanwhile, we do as if it had been filled
|
||||
mCurNbEntries += nb;
|
||||
|
||||
// This is mainly used to avoid the copy when possible
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A O(1) method to add a value in the container. The container is automatically resized if needed.
|
||||
* The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
|
||||
* costs a lot more than the call overhead...
|
||||
*
|
||||
* \param entry [in] a float to store in the container
|
||||
* \see Add(udword entry)
|
||||
* \see Empty()
|
||||
* \see Contains(udword entry)
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ Container& Add(float entry)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries==mMaxNbEntries) Resize();
|
||||
|
||||
// Add new entry
|
||||
mEntries[mCurNbEntries++] = IR(entry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline_ Container& Add(const float* entries, udword nb)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
|
||||
|
||||
// Add new entry
|
||||
CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(float));
|
||||
mCurNbEntries+=nb;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Add unique [slow]
|
||||
inline_ Container& AddUnique(udword entry)
|
||||
{
|
||||
if(!Contains(entry)) Add(entry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Clears the container. All stored values are deleted, and it frees used ram.
|
||||
* \see Reset()
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Empty();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Resets the container. Stored values are discarded but the buffer is kept so that further calls don't need resizing again.
|
||||
* That's a kind of temporal coherence.
|
||||
* \see Empty()
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void Reset()
|
||||
{
|
||||
// Avoid the write if possible
|
||||
// ### CMOV
|
||||
if(mCurNbEntries) mCurNbEntries = 0;
|
||||
}
|
||||
|
||||
// HANDLE WITH CARE - I hope you know what you're doing
|
||||
inline_ void ForceSize(udword size)
|
||||
{
|
||||
mCurNbEntries = size;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Sets the initial size of the container. If it already contains something, it's discarded.
|
||||
* \param nb [in] Number of entries
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool SetSize(udword nb);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the container and get rid of unused bytes.
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Refit();
|
||||
|
||||
bool Shrink();
|
||||
|
||||
// Checks whether the container already contains a given value.
|
||||
bool Contains(udword entry, udword* location=null) const;
|
||||
// Deletes an entry - doesn't preserve insertion order.
|
||||
bool Delete(udword entry);
|
||||
// Deletes an entry - does preserve insertion order.
|
||||
bool DeleteKeepingOrder(udword entry);
|
||||
//! Deletes the very last entry.
|
||||
inline_ void DeleteLastEntry() { if(mCurNbEntries) mCurNbEntries--; }
|
||||
//! Deletes the entry whose index is given
|
||||
inline_ void DeleteIndex(udword index) { mEntries[index] = mEntries[--mCurNbEntries]; }
|
||||
|
||||
// Helpers
|
||||
Container& FindNext(udword& entry, FindMode find_mode=FIND_CLAMP);
|
||||
Container& FindPrev(udword& entry, FindMode find_mode=FIND_CLAMP);
|
||||
// Data access.
|
||||
inline_ udword GetNbEntries() const { return mCurNbEntries; } //!< Returns the current number of entries.
|
||||
inline_ udword GetMaxNbEntries() const { return mMaxNbEntries; } //!< Returns max number of entries before resizing.
|
||||
inline_ udword GetEntry(udword i) const { return mEntries[i]; } //!< Returns ith entry.
|
||||
inline_ udword* GetEntries() const { return mEntries; } //!< Returns the list of entries.
|
||||
|
||||
inline_ udword GetFirst() const { return mEntries[0]; }
|
||||
inline_ udword GetLast() const { return mEntries[mCurNbEntries-1]; }
|
||||
|
||||
// Growth control
|
||||
float GetGrowthFactor() const; //!< Returns the growth factor
|
||||
void SetGrowthFactor(float growth); //!< Sets the growth factor
|
||||
inline_ bool IsFull() const { return mCurNbEntries==mMaxNbEntries; } //!< Checks the container is full
|
||||
inline_ BOOL IsNotEmpty() const { return mCurNbEntries; } //!< Checks the container is empty
|
||||
|
||||
//! Read-access as an array
|
||||
inline_ udword operator[](udword i) const { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; }
|
||||
//! Write-access as an array
|
||||
inline_ udword& operator[](udword i) { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; }
|
||||
|
||||
// Stats
|
||||
udword GetUsedRam() const;
|
||||
|
||||
//! Operator for "Container A = Container B"
|
||||
void operator = (const Container& object);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
static udword GetNbContainers() { return mNbContainers; }
|
||||
static udword GetTotalBytes() { return mUsedRam; }
|
||||
static LinkedList& GetContainers() { return mContainers; }
|
||||
private:
|
||||
|
||||
static udword mNbContainers; //!< Number of containers around
|
||||
static udword mUsedRam; //!< Amount of bytes used by containers in the system
|
||||
static LinkedList mContainers;
|
||||
#endif
|
||||
private:
|
||||
// Resizing
|
||||
bool Resize(udword needed=1);
|
||||
// Data
|
||||
udword mMaxNbEntries; //!< Maximum possible number of entries
|
||||
udword mCurNbEntries; //!< Current number of entries
|
||||
udword* mEntries; //!< List of entries
|
||||
float mGrowthFactor; //!< Resize: new number of entries = old number * mGrowthFactor
|
||||
};
|
||||
|
||||
#endif // ICECONTAINER_H
|
||||
|
||||
@@ -1,403 +1,403 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains FPU related code.
|
||||
* \file IceFPU.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEFPU_H
|
||||
#define ICEFPU_H
|
||||
|
||||
#define SIGN_BITMASK 0x80000000
|
||||
|
||||
//! Integer representation of a floating-point value.
|
||||
#define IR(x) ((udword&)(x))
|
||||
|
||||
//! Signed integer representation of a floating-point value.
|
||||
#define SIR(x) ((sdword&)(x))
|
||||
|
||||
//! Absolute integer representation of a floating-point value
|
||||
#define AIR(x) (IR(x)&0x7fffffff)
|
||||
|
||||
//! Floating-point representation of an integer value.
|
||||
#define FR(x) ((float&)(x))
|
||||
|
||||
//! Integer-based comparison of a floating point value.
|
||||
//! Don't use it blindly, it can be faster or slower than the FPU comparison, depends on the context.
|
||||
#define IS_NEGATIVE_FLOAT(x) (IR(x)&0x80000000)
|
||||
|
||||
//! Checks 2 values have different signs
|
||||
inline_ BOOL DifferentSign(float f0, float f1)
|
||||
{
|
||||
return (IR(f0)^IR(f1))&SIGN_BITMASK;
|
||||
}
|
||||
|
||||
//! Fast fabs for floating-point values. It just clears the sign bit.
|
||||
//! Don't use it blindy, it can be faster or slower than the FPU comparison, depends on the context.
|
||||
inline_ float FastFabs(float x)
|
||||
{
|
||||
udword FloatBits = IR(x)&0x7fffffff;
|
||||
return FR(FloatBits);
|
||||
}
|
||||
|
||||
//! Fast square root for floating-point values.
|
||||
inline_ float FastSqrt(float square)
|
||||
{
|
||||
float retval;
|
||||
|
||||
__asm {
|
||||
mov eax, square
|
||||
sub eax, 0x3F800000
|
||||
sar eax, 1
|
||||
add eax, 0x3F800000
|
||||
mov [retval], eax
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
//! Saturates positive to zero.
|
||||
inline_ float fsat(float f)
|
||||
{
|
||||
udword y = (udword&)f & ~((sdword&)f >>31);
|
||||
return (float&)y;
|
||||
}
|
||||
|
||||
//! Computes 1.0f / sqrtf(x).
|
||||
inline_ float frsqrt(float f)
|
||||
{
|
||||
float x = f * 0.5f;
|
||||
udword y = 0x5f3759df - ((udword&)f >> 1);
|
||||
// Iteration...
|
||||
(float&)y = (float&)y * ( 1.5f - ( x * (float&)y * (float&)y ) );
|
||||
// Result
|
||||
return (float&)y;
|
||||
}
|
||||
|
||||
//! Computes 1.0f / sqrtf(x). Comes from NVIDIA.
|
||||
inline_ float InvSqrt(const float& x)
|
||||
{
|
||||
udword tmp = (udword(IEEE_1_0 << 1) + IEEE_1_0 - *(udword*)&x) >> 1;
|
||||
float y = *(float*)&tmp;
|
||||
return y * (1.47f - 0.47f * x * y * y);
|
||||
}
|
||||
|
||||
//! Computes 1.0f / sqrtf(x). Comes from Quake3. Looks like the first one I had above.
|
||||
//! See http://www.magic-software.com/3DGEDInvSqrt.html
|
||||
inline_ float RSqrt(float number)
|
||||
{
|
||||
long i;
|
||||
float x2, y;
|
||||
const float threehalfs = 1.5f;
|
||||
|
||||
x2 = number * 0.5f;
|
||||
y = number;
|
||||
i = * (long *) &y;
|
||||
i = 0x5f3759df - (i >> 1);
|
||||
y = * (float *) &i;
|
||||
y = y * (threehalfs - (x2 * y * y));
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
inline_ float fsqrt(float f)
|
||||
{
|
||||
udword y = ( ( (sdword&)f - 0x3f800000 ) >> 1 ) + 0x3f800000;
|
||||
// Iteration...?
|
||||
// (float&)y = (3.0f - ((float&)y * (float&)y) / f) * (float&)y * 0.5f;
|
||||
// Result
|
||||
return (float&)y;
|
||||
}
|
||||
|
||||
//! Returns the float ranged espilon value.
|
||||
inline_ float fepsilon(float f)
|
||||
{
|
||||
udword b = (udword&)f & 0xff800000;
|
||||
udword a = b | 0x00000001;
|
||||
(float&)a -= (float&)b;
|
||||
// Result
|
||||
return (float&)a;
|
||||
}
|
||||
|
||||
//! Is the float valid ?
|
||||
inline_ bool IsNAN(float value) { return (IR(value)&0x7f800000) == 0x7f800000; }
|
||||
inline_ bool IsIndeterminate(float value) { return IR(value) == 0xffc00000; }
|
||||
inline_ bool IsPlusInf(float value) { return IR(value) == 0x7f800000; }
|
||||
inline_ bool IsMinusInf(float value) { return IR(value) == 0xff800000; }
|
||||
|
||||
inline_ bool IsValidFloat(float value)
|
||||
{
|
||||
if(IsNAN(value)) return false;
|
||||
if(IsIndeterminate(value)) return false;
|
||||
if(IsPlusInf(value)) return false;
|
||||
if(IsMinusInf(value)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define CHECK_VALID_FLOAT(x) ASSERT(IsValidFloat(x));
|
||||
|
||||
/*
|
||||
//! FPU precision setting function.
|
||||
inline_ void SetFPU()
|
||||
{
|
||||
// This function evaluates whether the floating-point
|
||||
// control word is set to single precision/round to nearest/
|
||||
// exceptions disabled. If these conditions don't hold, the
|
||||
// function changes the control word to set them and returns
|
||||
// TRUE, putting the old control word value in the passback
|
||||
// location pointed to by pwOldCW.
|
||||
{
|
||||
uword wTemp, wSave;
|
||||
|
||||
__asm fstcw wSave
|
||||
if (wSave & 0x300 || // Not single mode
|
||||
0x3f != (wSave & 0x3f) || // Exceptions enabled
|
||||
wSave & 0xC00) // Not round to nearest mode
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov ax, wSave
|
||||
and ax, not 300h ;; single mode
|
||||
or ax, 3fh ;; disable all exceptions
|
||||
and ax, not 0xC00 ;; round to nearest mode
|
||||
mov wTemp, ax
|
||||
fldcw wTemp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
//! This function computes the slowest possible floating-point value (you can also directly use FLT_EPSILON)
|
||||
inline_ float ComputeFloatEpsilon()
|
||||
{
|
||||
float f = 1.0f;
|
||||
((udword&)f)^=1;
|
||||
return f - 1.0f; // You can check it's the same as FLT_EPSILON
|
||||
}
|
||||
|
||||
inline_ bool IsFloatZero(float x, float epsilon=1e-6f)
|
||||
{
|
||||
return x*x < epsilon;
|
||||
}
|
||||
|
||||
#define FCOMI_ST0 _asm _emit 0xdb _asm _emit 0xf0
|
||||
#define FCOMIP_ST0 _asm _emit 0xdf _asm _emit 0xf0
|
||||
#define FCMOVB_ST0 _asm _emit 0xda _asm _emit 0xc0
|
||||
#define FCMOVNB_ST0 _asm _emit 0xdb _asm _emit 0xc0
|
||||
|
||||
#define FCOMI_ST1 _asm _emit 0xdb _asm _emit 0xf1
|
||||
#define FCOMIP_ST1 _asm _emit 0xdf _asm _emit 0xf1
|
||||
#define FCMOVB_ST1 _asm _emit 0xda _asm _emit 0xc1
|
||||
#define FCMOVNB_ST1 _asm _emit 0xdb _asm _emit 0xc1
|
||||
|
||||
#define FCOMI_ST2 _asm _emit 0xdb _asm _emit 0xf2
|
||||
#define FCOMIP_ST2 _asm _emit 0xdf _asm _emit 0xf2
|
||||
#define FCMOVB_ST2 _asm _emit 0xda _asm _emit 0xc2
|
||||
#define FCMOVNB_ST2 _asm _emit 0xdb _asm _emit 0xc2
|
||||
|
||||
#define FCOMI_ST3 _asm _emit 0xdb _asm _emit 0xf3
|
||||
#define FCOMIP_ST3 _asm _emit 0xdf _asm _emit 0xf3
|
||||
#define FCMOVB_ST3 _asm _emit 0xda _asm _emit 0xc3
|
||||
#define FCMOVNB_ST3 _asm _emit 0xdb _asm _emit 0xc3
|
||||
|
||||
#define FCOMI_ST4 _asm _emit 0xdb _asm _emit 0xf4
|
||||
#define FCOMIP_ST4 _asm _emit 0xdf _asm _emit 0xf4
|
||||
#define FCMOVB_ST4 _asm _emit 0xda _asm _emit 0xc4
|
||||
#define FCMOVNB_ST4 _asm _emit 0xdb _asm _emit 0xc4
|
||||
|
||||
#define FCOMI_ST5 _asm _emit 0xdb _asm _emit 0xf5
|
||||
#define FCOMIP_ST5 _asm _emit 0xdf _asm _emit 0xf5
|
||||
#define FCMOVB_ST5 _asm _emit 0xda _asm _emit 0xc5
|
||||
#define FCMOVNB_ST5 _asm _emit 0xdb _asm _emit 0xc5
|
||||
|
||||
#define FCOMI_ST6 _asm _emit 0xdb _asm _emit 0xf6
|
||||
#define FCOMIP_ST6 _asm _emit 0xdf _asm _emit 0xf6
|
||||
#define FCMOVB_ST6 _asm _emit 0xda _asm _emit 0xc6
|
||||
#define FCMOVNB_ST6 _asm _emit 0xdb _asm _emit 0xc6
|
||||
|
||||
#define FCOMI_ST7 _asm _emit 0xdb _asm _emit 0xf7
|
||||
#define FCOMIP_ST7 _asm _emit 0xdf _asm _emit 0xf7
|
||||
#define FCMOVB_ST7 _asm _emit 0xda _asm _emit 0xc7
|
||||
#define FCMOVNB_ST7 _asm _emit 0xdb _asm _emit 0xc7
|
||||
|
||||
//! A global function to find MAX(a,b) using FCOMI/FCMOV
|
||||
inline_ float FCMax2(float a, float b)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
FCOMI_ST1
|
||||
FCMOVB_ST1
|
||||
_asm fstp [Res]
|
||||
_asm fcomp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MIN(a,b) using FCOMI/FCMOV
|
||||
inline_ float FCMin2(float a, float b)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
FCOMI_ST1
|
||||
FCMOVNB_ST1
|
||||
_asm fstp [Res]
|
||||
_asm fcomp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MAX(a,b,c) using FCOMI/FCMOV
|
||||
inline_ float FCMax3(float a, float b, float c)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
_asm fld [c]
|
||||
FCOMI_ST1
|
||||
FCMOVB_ST1
|
||||
FCOMI_ST2
|
||||
FCMOVB_ST2
|
||||
_asm fstp [Res]
|
||||
_asm fcompp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MIN(a,b,c) using FCOMI/FCMOV
|
||||
inline_ float FCMin3(float a, float b, float c)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
_asm fld [c]
|
||||
FCOMI_ST1
|
||||
FCMOVNB_ST1
|
||||
FCOMI_ST2
|
||||
FCMOVNB_ST2
|
||||
_asm fstp [Res]
|
||||
_asm fcompp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MAX(a,b,c,d) using FCOMI/FCMOV
|
||||
inline_ float FCMax4(float a, float b, float c, float d)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
_asm fld [c]
|
||||
_asm fld [d]
|
||||
FCOMI_ST1
|
||||
FCMOVB_ST1
|
||||
FCOMI_ST2
|
||||
FCMOVB_ST2
|
||||
FCOMI_ST3
|
||||
FCMOVB_ST3
|
||||
_asm fstp [Res]
|
||||
_asm fcompp
|
||||
_asm fcomp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MIN(a,b,c,d) using FCOMI/FCMOV
|
||||
inline_ float FCMin4(float a, float b, float c, float d)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
_asm fld [c]
|
||||
_asm fld [d]
|
||||
FCOMI_ST1
|
||||
FCMOVNB_ST1
|
||||
FCOMI_ST2
|
||||
FCMOVNB_ST2
|
||||
FCOMI_ST3
|
||||
FCMOVNB_ST3
|
||||
_asm fstp [Res]
|
||||
_asm fcompp
|
||||
_asm fcomp
|
||||
return Res;
|
||||
}
|
||||
|
||||
inline_ int ConvertToSortable(float f)
|
||||
{
|
||||
int& Fi = (int&)f;
|
||||
int Fmask = (Fi>>31);
|
||||
Fi ^= Fmask;
|
||||
Fmask &= ~(1<<31);
|
||||
Fi -= Fmask;
|
||||
return Fi;
|
||||
}
|
||||
|
||||
inline_ udword EncodeFloat(const float val)
|
||||
{
|
||||
// We may need to check on -0 and 0
|
||||
// But it should make no practical difference.
|
||||
udword ir = IR(val);
|
||||
|
||||
if(ir & 0x80000000) //negative?
|
||||
ir = ~ir;//reverse sequence of negative numbers
|
||||
else
|
||||
ir |= 0x80000000; // flip sign
|
||||
|
||||
return ir;
|
||||
}
|
||||
|
||||
inline_ float DecodeFloat(udword ir)
|
||||
{
|
||||
udword rv;
|
||||
|
||||
if(ir & 0x80000000) //positive?
|
||||
rv = ir & ~0x80000000; //flip sign
|
||||
else
|
||||
rv = ~ir; //undo reversal
|
||||
|
||||
return FR(rv);
|
||||
}
|
||||
|
||||
enum FPUMode
|
||||
{
|
||||
FPU_FLOOR = 0,
|
||||
FPU_CEIL = 1,
|
||||
FPU_BEST = 2,
|
||||
|
||||
FPU_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
FUNCTION ICECORE_API FPUMode GetFPUMode();
|
||||
FUNCTION ICECORE_API void SaveFPU();
|
||||
FUNCTION ICECORE_API void RestoreFPU();
|
||||
FUNCTION ICECORE_API void SetFPUFloorMode();
|
||||
FUNCTION ICECORE_API void SetFPUCeilMode();
|
||||
FUNCTION ICECORE_API void SetFPUBestMode();
|
||||
|
||||
FUNCTION ICECORE_API void SetFPUPrecision24();
|
||||
FUNCTION ICECORE_API void SetFPUPrecision53();
|
||||
FUNCTION ICECORE_API void SetFPUPrecision64();
|
||||
FUNCTION ICECORE_API void SetFPURoundingChop();
|
||||
FUNCTION ICECORE_API void SetFPURoundingUp();
|
||||
FUNCTION ICECORE_API void SetFPURoundingDown();
|
||||
FUNCTION ICECORE_API void SetFPURoundingNear();
|
||||
|
||||
FUNCTION ICECORE_API int intChop(const float& f);
|
||||
FUNCTION ICECORE_API int intFloor(const float& f);
|
||||
FUNCTION ICECORE_API int intCeil(const float& f);
|
||||
|
||||
inline_ sdword MyFloor(float f)
|
||||
{
|
||||
return (sdword)f - (IR(f)>>31);
|
||||
}
|
||||
|
||||
class ICECORE_API FPUGuard
|
||||
{
|
||||
public:
|
||||
FPUGuard();
|
||||
~FPUGuard();
|
||||
private:
|
||||
uword mControlWord;
|
||||
};
|
||||
|
||||
#endif // ICEFPU_H
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains FPU related code.
|
||||
* \file IceFPU.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEFPU_H
|
||||
#define ICEFPU_H
|
||||
|
||||
#define SIGN_BITMASK 0x80000000
|
||||
|
||||
//! Integer representation of a floating-point value.
|
||||
#define IR(x) ((udword&)(x))
|
||||
|
||||
//! Signed integer representation of a floating-point value.
|
||||
#define SIR(x) ((sdword&)(x))
|
||||
|
||||
//! Absolute integer representation of a floating-point value
|
||||
#define AIR(x) (IR(x)&0x7fffffff)
|
||||
|
||||
//! Floating-point representation of an integer value.
|
||||
#define FR(x) ((float&)(x))
|
||||
|
||||
//! Integer-based comparison of a floating point value.
|
||||
//! Don't use it blindly, it can be faster or slower than the FPU comparison, depends on the context.
|
||||
#define IS_NEGATIVE_FLOAT(x) (IR(x)&0x80000000)
|
||||
|
||||
//! Checks 2 values have different signs
|
||||
inline_ BOOL DifferentSign(float f0, float f1)
|
||||
{
|
||||
return (IR(f0)^IR(f1))&SIGN_BITMASK;
|
||||
}
|
||||
|
||||
//! Fast fabs for floating-point values. It just clears the sign bit.
|
||||
//! Don't use it blindy, it can be faster or slower than the FPU comparison, depends on the context.
|
||||
inline_ float FastFabs(float x)
|
||||
{
|
||||
udword FloatBits = IR(x)&0x7fffffff;
|
||||
return FR(FloatBits);
|
||||
}
|
||||
|
||||
//! Fast square root for floating-point values.
|
||||
inline_ float FastSqrt(float square)
|
||||
{
|
||||
float retval;
|
||||
|
||||
__asm {
|
||||
mov eax, square
|
||||
sub eax, 0x3F800000
|
||||
sar eax, 1
|
||||
add eax, 0x3F800000
|
||||
mov [retval], eax
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
//! Saturates positive to zero.
|
||||
inline_ float fsat(float f)
|
||||
{
|
||||
udword y = (udword&)f & ~((sdword&)f >>31);
|
||||
return (float&)y;
|
||||
}
|
||||
|
||||
//! Computes 1.0f / sqrtf(x).
|
||||
inline_ float frsqrt(float f)
|
||||
{
|
||||
float x = f * 0.5f;
|
||||
udword y = 0x5f3759df - ((udword&)f >> 1);
|
||||
// Iteration...
|
||||
(float&)y = (float&)y * ( 1.5f - ( x * (float&)y * (float&)y ) );
|
||||
// Result
|
||||
return (float&)y;
|
||||
}
|
||||
|
||||
//! Computes 1.0f / sqrtf(x). Comes from NVIDIA.
|
||||
inline_ float InvSqrt(const float& x)
|
||||
{
|
||||
udword tmp = (udword(IEEE_1_0 << 1) + IEEE_1_0 - *(udword*)&x) >> 1;
|
||||
float y = *(float*)&tmp;
|
||||
return y * (1.47f - 0.47f * x * y * y);
|
||||
}
|
||||
|
||||
//! Computes 1.0f / sqrtf(x). Comes from Quake3. Looks like the first one I had above.
|
||||
//! See http://www.magic-software.com/3DGEDInvSqrt.html
|
||||
inline_ float RSqrt(float number)
|
||||
{
|
||||
long i;
|
||||
float x2, y;
|
||||
const float threehalfs = 1.5f;
|
||||
|
||||
x2 = number * 0.5f;
|
||||
y = number;
|
||||
i = * (long *) &y;
|
||||
i = 0x5f3759df - (i >> 1);
|
||||
y = * (float *) &i;
|
||||
y = y * (threehalfs - (x2 * y * y));
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
inline_ float fsqrt(float f)
|
||||
{
|
||||
udword y = ( ( (sdword&)f - 0x3f800000 ) >> 1 ) + 0x3f800000;
|
||||
// Iteration...?
|
||||
// (float&)y = (3.0f - ((float&)y * (float&)y) / f) * (float&)y * 0.5f;
|
||||
// Result
|
||||
return (float&)y;
|
||||
}
|
||||
|
||||
//! Returns the float ranged espilon value.
|
||||
inline_ float fepsilon(float f)
|
||||
{
|
||||
udword b = (udword&)f & 0xff800000;
|
||||
udword a = b | 0x00000001;
|
||||
(float&)a -= (float&)b;
|
||||
// Result
|
||||
return (float&)a;
|
||||
}
|
||||
|
||||
//! Is the float valid ?
|
||||
inline_ bool IsNAN(float value) { return (IR(value)&0x7f800000) == 0x7f800000; }
|
||||
inline_ bool IsIndeterminate(float value) { return IR(value) == 0xffc00000; }
|
||||
inline_ bool IsPlusInf(float value) { return IR(value) == 0x7f800000; }
|
||||
inline_ bool IsMinusInf(float value) { return IR(value) == 0xff800000; }
|
||||
|
||||
inline_ bool IsValidFloat(float value)
|
||||
{
|
||||
if(IsNAN(value)) return false;
|
||||
if(IsIndeterminate(value)) return false;
|
||||
if(IsPlusInf(value)) return false;
|
||||
if(IsMinusInf(value)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define CHECK_VALID_FLOAT(x) ASSERT(IsValidFloat(x));
|
||||
|
||||
/*
|
||||
//! FPU precision setting function.
|
||||
inline_ void SetFPU()
|
||||
{
|
||||
// This function evaluates whether the floating-point
|
||||
// control word is set to single precision/round to nearest/
|
||||
// exceptions disabled. If these conditions don't hold, the
|
||||
// function changes the control word to set them and returns
|
||||
// TRUE, putting the old control word value in the passback
|
||||
// location pointed to by pwOldCW.
|
||||
{
|
||||
uword wTemp, wSave;
|
||||
|
||||
__asm fstcw wSave
|
||||
if (wSave & 0x300 || // Not single mode
|
||||
0x3f != (wSave & 0x3f) || // Exceptions enabled
|
||||
wSave & 0xC00) // Not round to nearest mode
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov ax, wSave
|
||||
and ax, not 300h ;; single mode
|
||||
or ax, 3fh ;; disable all exceptions
|
||||
and ax, not 0xC00 ;; round to nearest mode
|
||||
mov wTemp, ax
|
||||
fldcw wTemp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
//! This function computes the slowest possible floating-point value (you can also directly use FLT_EPSILON)
|
||||
inline_ float ComputeFloatEpsilon()
|
||||
{
|
||||
float f = 1.0f;
|
||||
((udword&)f)^=1;
|
||||
return f - 1.0f; // You can check it's the same as FLT_EPSILON
|
||||
}
|
||||
|
||||
inline_ bool IsFloatZero(float x, float epsilon=1e-6f)
|
||||
{
|
||||
return x*x < epsilon;
|
||||
}
|
||||
|
||||
#define FCOMI_ST0 _asm _emit 0xdb _asm _emit 0xf0
|
||||
#define FCOMIP_ST0 _asm _emit 0xdf _asm _emit 0xf0
|
||||
#define FCMOVB_ST0 _asm _emit 0xda _asm _emit 0xc0
|
||||
#define FCMOVNB_ST0 _asm _emit 0xdb _asm _emit 0xc0
|
||||
|
||||
#define FCOMI_ST1 _asm _emit 0xdb _asm _emit 0xf1
|
||||
#define FCOMIP_ST1 _asm _emit 0xdf _asm _emit 0xf1
|
||||
#define FCMOVB_ST1 _asm _emit 0xda _asm _emit 0xc1
|
||||
#define FCMOVNB_ST1 _asm _emit 0xdb _asm _emit 0xc1
|
||||
|
||||
#define FCOMI_ST2 _asm _emit 0xdb _asm _emit 0xf2
|
||||
#define FCOMIP_ST2 _asm _emit 0xdf _asm _emit 0xf2
|
||||
#define FCMOVB_ST2 _asm _emit 0xda _asm _emit 0xc2
|
||||
#define FCMOVNB_ST2 _asm _emit 0xdb _asm _emit 0xc2
|
||||
|
||||
#define FCOMI_ST3 _asm _emit 0xdb _asm _emit 0xf3
|
||||
#define FCOMIP_ST3 _asm _emit 0xdf _asm _emit 0xf3
|
||||
#define FCMOVB_ST3 _asm _emit 0xda _asm _emit 0xc3
|
||||
#define FCMOVNB_ST3 _asm _emit 0xdb _asm _emit 0xc3
|
||||
|
||||
#define FCOMI_ST4 _asm _emit 0xdb _asm _emit 0xf4
|
||||
#define FCOMIP_ST4 _asm _emit 0xdf _asm _emit 0xf4
|
||||
#define FCMOVB_ST4 _asm _emit 0xda _asm _emit 0xc4
|
||||
#define FCMOVNB_ST4 _asm _emit 0xdb _asm _emit 0xc4
|
||||
|
||||
#define FCOMI_ST5 _asm _emit 0xdb _asm _emit 0xf5
|
||||
#define FCOMIP_ST5 _asm _emit 0xdf _asm _emit 0xf5
|
||||
#define FCMOVB_ST5 _asm _emit 0xda _asm _emit 0xc5
|
||||
#define FCMOVNB_ST5 _asm _emit 0xdb _asm _emit 0xc5
|
||||
|
||||
#define FCOMI_ST6 _asm _emit 0xdb _asm _emit 0xf6
|
||||
#define FCOMIP_ST6 _asm _emit 0xdf _asm _emit 0xf6
|
||||
#define FCMOVB_ST6 _asm _emit 0xda _asm _emit 0xc6
|
||||
#define FCMOVNB_ST6 _asm _emit 0xdb _asm _emit 0xc6
|
||||
|
||||
#define FCOMI_ST7 _asm _emit 0xdb _asm _emit 0xf7
|
||||
#define FCOMIP_ST7 _asm _emit 0xdf _asm _emit 0xf7
|
||||
#define FCMOVB_ST7 _asm _emit 0xda _asm _emit 0xc7
|
||||
#define FCMOVNB_ST7 _asm _emit 0xdb _asm _emit 0xc7
|
||||
|
||||
//! A global function to find MAX(a,b) using FCOMI/FCMOV
|
||||
inline_ float FCMax2(float a, float b)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
FCOMI_ST1
|
||||
FCMOVB_ST1
|
||||
_asm fstp [Res]
|
||||
_asm fcomp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MIN(a,b) using FCOMI/FCMOV
|
||||
inline_ float FCMin2(float a, float b)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
FCOMI_ST1
|
||||
FCMOVNB_ST1
|
||||
_asm fstp [Res]
|
||||
_asm fcomp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MAX(a,b,c) using FCOMI/FCMOV
|
||||
inline_ float FCMax3(float a, float b, float c)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
_asm fld [c]
|
||||
FCOMI_ST1
|
||||
FCMOVB_ST1
|
||||
FCOMI_ST2
|
||||
FCMOVB_ST2
|
||||
_asm fstp [Res]
|
||||
_asm fcompp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MIN(a,b,c) using FCOMI/FCMOV
|
||||
inline_ float FCMin3(float a, float b, float c)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
_asm fld [c]
|
||||
FCOMI_ST1
|
||||
FCMOVNB_ST1
|
||||
FCOMI_ST2
|
||||
FCMOVNB_ST2
|
||||
_asm fstp [Res]
|
||||
_asm fcompp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MAX(a,b,c,d) using FCOMI/FCMOV
|
||||
inline_ float FCMax4(float a, float b, float c, float d)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
_asm fld [c]
|
||||
_asm fld [d]
|
||||
FCOMI_ST1
|
||||
FCMOVB_ST1
|
||||
FCOMI_ST2
|
||||
FCMOVB_ST2
|
||||
FCOMI_ST3
|
||||
FCMOVB_ST3
|
||||
_asm fstp [Res]
|
||||
_asm fcompp
|
||||
_asm fcomp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MIN(a,b,c,d) using FCOMI/FCMOV
|
||||
inline_ float FCMin4(float a, float b, float c, float d)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
_asm fld [c]
|
||||
_asm fld [d]
|
||||
FCOMI_ST1
|
||||
FCMOVNB_ST1
|
||||
FCOMI_ST2
|
||||
FCMOVNB_ST2
|
||||
FCOMI_ST3
|
||||
FCMOVNB_ST3
|
||||
_asm fstp [Res]
|
||||
_asm fcompp
|
||||
_asm fcomp
|
||||
return Res;
|
||||
}
|
||||
|
||||
inline_ int ConvertToSortable(float f)
|
||||
{
|
||||
int& Fi = (int&)f;
|
||||
int Fmask = (Fi>>31);
|
||||
Fi ^= Fmask;
|
||||
Fmask &= ~(1<<31);
|
||||
Fi -= Fmask;
|
||||
return Fi;
|
||||
}
|
||||
|
||||
inline_ udword EncodeFloat(const float val)
|
||||
{
|
||||
// We may need to check on -0 and 0
|
||||
// But it should make no practical difference.
|
||||
udword ir = IR(val);
|
||||
|
||||
if(ir & 0x80000000) //negative?
|
||||
ir = ~ir;//reverse sequence of negative numbers
|
||||
else
|
||||
ir |= 0x80000000; // flip sign
|
||||
|
||||
return ir;
|
||||
}
|
||||
|
||||
inline_ float DecodeFloat(udword ir)
|
||||
{
|
||||
udword rv;
|
||||
|
||||
if(ir & 0x80000000) //positive?
|
||||
rv = ir & ~0x80000000; //flip sign
|
||||
else
|
||||
rv = ~ir; //undo reversal
|
||||
|
||||
return FR(rv);
|
||||
}
|
||||
|
||||
enum FPUMode
|
||||
{
|
||||
FPU_FLOOR = 0,
|
||||
FPU_CEIL = 1,
|
||||
FPU_BEST = 2,
|
||||
|
||||
FPU_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
FUNCTION ICECORE_API FPUMode GetFPUMode();
|
||||
FUNCTION ICECORE_API void SaveFPU();
|
||||
FUNCTION ICECORE_API void RestoreFPU();
|
||||
FUNCTION ICECORE_API void SetFPUFloorMode();
|
||||
FUNCTION ICECORE_API void SetFPUCeilMode();
|
||||
FUNCTION ICECORE_API void SetFPUBestMode();
|
||||
|
||||
FUNCTION ICECORE_API void SetFPUPrecision24();
|
||||
FUNCTION ICECORE_API void SetFPUPrecision53();
|
||||
FUNCTION ICECORE_API void SetFPUPrecision64();
|
||||
FUNCTION ICECORE_API void SetFPURoundingChop();
|
||||
FUNCTION ICECORE_API void SetFPURoundingUp();
|
||||
FUNCTION ICECORE_API void SetFPURoundingDown();
|
||||
FUNCTION ICECORE_API void SetFPURoundingNear();
|
||||
|
||||
FUNCTION ICECORE_API int intChop(const float& f);
|
||||
FUNCTION ICECORE_API int intFloor(const float& f);
|
||||
FUNCTION ICECORE_API int intCeil(const float& f);
|
||||
|
||||
inline_ sdword MyFloor(float f)
|
||||
{
|
||||
return (sdword)f - (IR(f)>>31);
|
||||
}
|
||||
|
||||
class ICECORE_API FPUGuard
|
||||
{
|
||||
public:
|
||||
FPUGuard();
|
||||
~FPUGuard();
|
||||
private:
|
||||
uword mControlWord;
|
||||
};
|
||||
|
||||
#endif // ICEFPU_H
|
||||
|
||||
@@ -1,87 +1,87 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for homogeneous points.
|
||||
* \file IceHPoint.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Homogeneous point.
|
||||
*
|
||||
* Use it:
|
||||
* - for clipping in homogeneous space (standard way)
|
||||
* - to differentiate between points (w=1) and vectors (w=0).
|
||||
* - in some cases you can also use it instead of Point for padding reasons.
|
||||
*
|
||||
* \class HPoint
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
* \warning No cross-product in 4D.
|
||||
* \warning HPoint *= Matrix3x3 doesn't exist, the matrix is first casted to a 4x4
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Point Mul = HPoint * Matrix3x3;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Point HPoint::operator*(const Matrix3x3& mat) const
|
||||
{
|
||||
return Point(
|
||||
x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0],
|
||||
x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1],
|
||||
x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// HPoint Mul = HPoint * Matrix4x4;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HPoint HPoint::operator*(const Matrix4x4& mat) const
|
||||
{
|
||||
return HPoint(
|
||||
x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + w * mat.m[3][0],
|
||||
x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + w * mat.m[3][1],
|
||||
x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + w * mat.m[3][2],
|
||||
x * mat.m[0][3] + y * mat.m[1][3] + z * mat.m[2][3] + w * mat.m[3][3]);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// HPoint *= Matrix4x4
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HPoint& HPoint::operator*=(const Matrix4x4& mat)
|
||||
{
|
||||
float xp = x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + w * mat.m[3][0];
|
||||
float yp = x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + w * mat.m[3][1];
|
||||
float zp = x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + w * mat.m[3][2];
|
||||
float wp = x * mat.m[0][3] + y * mat.m[1][3] + z * mat.m[2][3] + w * mat.m[3][3];
|
||||
|
||||
x = xp; y = yp; z = zp; w = wp;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for homogeneous points.
|
||||
* \file IceHPoint.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Homogeneous point.
|
||||
*
|
||||
* Use it:
|
||||
* - for clipping in homogeneous space (standard way)
|
||||
* - to differentiate between points (w=1) and vectors (w=0).
|
||||
* - in some cases you can also use it instead of Point for padding reasons.
|
||||
*
|
||||
* \class HPoint
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
* \warning No cross-product in 4D.
|
||||
* \warning HPoint *= Matrix3x3 doesn't exist, the matrix is first casted to a 4x4
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Point Mul = HPoint * Matrix3x3;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Point HPoint::operator*(const Matrix3x3& mat) const
|
||||
{
|
||||
return Point(
|
||||
x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0],
|
||||
x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1],
|
||||
x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// HPoint Mul = HPoint * Matrix4x4;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HPoint HPoint::operator*(const Matrix4x4& mat) const
|
||||
{
|
||||
return HPoint(
|
||||
x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + w * mat.m[3][0],
|
||||
x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + w * mat.m[3][1],
|
||||
x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + w * mat.m[3][2],
|
||||
x * mat.m[0][3] + y * mat.m[1][3] + z * mat.m[2][3] + w * mat.m[3][3]);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// HPoint *= Matrix4x4
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HPoint& HPoint::operator*=(const Matrix4x4& mat)
|
||||
{
|
||||
float xp = x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + w * mat.m[3][0];
|
||||
float yp = x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + w * mat.m[3][1];
|
||||
float zp = x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + w * mat.m[3][2];
|
||||
float wp = x * mat.m[0][3] + y * mat.m[1][3] + z * mat.m[2][3] + w * mat.m[3][3];
|
||||
|
||||
x = xp; y = yp; z = zp; w = wp;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,173 +1,173 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for homogeneous points.
|
||||
* \file IceHPoint.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEHPOINT_H__
|
||||
#define __ICEHPOINT_H__
|
||||
|
||||
class ICEMATHS_API HPoint : public Point
|
||||
{
|
||||
public:
|
||||
|
||||
//! Empty constructor
|
||||
inline_ HPoint() {}
|
||||
//! Constructor from floats
|
||||
inline_ HPoint(float _x, float _y, float _z, float _w=0.0f) : Point(_x, _y, _z), w(_w) {}
|
||||
//! Constructor from array
|
||||
inline_ HPoint(const float f[4]) : Point(f), w(f[3]) {}
|
||||
//! Constructor from a Point
|
||||
inline_ HPoint(const Point& p, float _w=0.0f) : Point(p), w(_w) {}
|
||||
//! Destructor
|
||||
inline_ ~HPoint() {}
|
||||
|
||||
//! Clear the point
|
||||
inline_ HPoint& Zero() { x = y = z = w = 0.0f; return *this; }
|
||||
|
||||
//! Assignment from values
|
||||
inline_ HPoint& Set(float _x, float _y, float _z, float _w ) { x = _x; y = _y; z = _z; w = _w; return *this; }
|
||||
//! Assignment from array
|
||||
inline_ HPoint& Set(const float f[4]) { x = f[_X]; y = f[_Y]; z = f[_Z]; w = f[_W]; return *this; }
|
||||
//! Assignment from another h-point
|
||||
inline_ HPoint& Set(const HPoint& src) { x = src.x; y = src.y; z = src.z; w = src.w; return *this; }
|
||||
|
||||
//! Add a vector
|
||||
inline_ HPoint& Add(float _x, float _y, float _z, float _w ) { x += _x; y += _y; z += _z; w += _w; return *this; }
|
||||
//! Add a vector
|
||||
inline_ HPoint& Add(const float f[4]) { x += f[_X]; y += f[_Y]; z += f[_Z]; w += f[_W]; return *this; }
|
||||
|
||||
//! Subtract a vector
|
||||
inline_ HPoint& Sub(float _x, float _y, float _z, float _w ) { x -= _x; y -= _y; z -= _z; w -= _w; return *this; }
|
||||
//! Subtract a vector
|
||||
inline_ HPoint& Sub(const float f[4]) { x -= f[_X]; y -= f[_Y]; z -= f[_Z]; w -= f[_W]; return *this; }
|
||||
|
||||
//! Multiplies by a scalar
|
||||
inline_ HPoint& Mul(float s) { x *= s; y *= s; z *= s; w *= s; return *this; }
|
||||
|
||||
//! Returns MIN(x, y, z, w);
|
||||
float Min() const { return MIN(x, MIN(y, MIN(z, w))); }
|
||||
//! Returns MAX(x, y, z, w);
|
||||
float Max() const { return MAX(x, MAX(y, MAX(z, w))); }
|
||||
//! Sets each element to be componentwise minimum
|
||||
HPoint& Min(const HPoint& p) { x = MIN(x, p.x); y = MIN(y, p.y); z = MIN(z, p.z); w = MIN(w, p.w); return *this; }
|
||||
//! Sets each element to be componentwise maximum
|
||||
HPoint& Max(const HPoint& p) { x = MAX(x, p.x); y = MAX(y, p.y); z = MAX(z, p.z); w = MAX(w, p.w); return *this; }
|
||||
|
||||
//! Computes square magnitude
|
||||
inline_ float SquareMagnitude() const { return x*x + y*y + z*z + w*w; }
|
||||
//! Computes magnitude
|
||||
inline_ float Magnitude() const { return sqrtf(x*x + y*y + z*z + w*w); }
|
||||
|
||||
//! Normalize the vector
|
||||
inline_ HPoint& Normalize()
|
||||
{
|
||||
float M = Magnitude();
|
||||
if(M)
|
||||
{
|
||||
M = 1.0f / M;
|
||||
x *= M;
|
||||
y *= M;
|
||||
z *= M;
|
||||
w *= M;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Arithmetic operators
|
||||
//! Operator for HPoint Negate = - HPoint;
|
||||
inline_ HPoint operator-() const { return HPoint(-x, -y, -z, -w); }
|
||||
|
||||
//! Operator for HPoint Plus = HPoint + HPoint;
|
||||
inline_ HPoint operator+(const HPoint& p) const { return HPoint(x + p.x, y + p.y, z + p.z, w + p.w); }
|
||||
//! Operator for HPoint Minus = HPoint - HPoint;
|
||||
inline_ HPoint operator-(const HPoint& p) const { return HPoint(x - p.x, y - p.y, z - p.z, w - p.w); }
|
||||
|
||||
//! Operator for HPoint Mul = HPoint * HPoint;
|
||||
inline_ HPoint operator*(const HPoint& p) const { return HPoint(x * p.x, y * p.y, z * p.z, w * p.w); }
|
||||
//! Operator for HPoint Scale = HPoint * float;
|
||||
inline_ HPoint operator*(float s) const { return HPoint(x * s, y * s, z * s, w * s); }
|
||||
//! Operator for HPoint Scale = float * HPoint;
|
||||
inline_ friend HPoint operator*(float s, const HPoint& p) { return HPoint(s * p.x, s * p.y, s * p.z, s * p.w); }
|
||||
|
||||
//! Operator for HPoint Div = HPoint / HPoint;
|
||||
inline_ HPoint operator/(const HPoint& p) const { return HPoint(x / p.x, y / p.y, z / p.z, w / p.w); }
|
||||
//! Operator for HPoint Scale = HPoint / float;
|
||||
inline_ HPoint operator/(float s) const { s = 1.0f / s; return HPoint(x * s, y * s, z * s, w * s); }
|
||||
//! Operator for HPoint Scale = float / HPoint;
|
||||
inline_ friend HPoint operator/(float s, const HPoint& p) { return HPoint(s / p.x, s / p.y, s / p.z, s / p.w); }
|
||||
|
||||
//! Operator for float DotProd = HPoint | HPoint;
|
||||
inline_ float operator|(const HPoint& p) const { return x*p.x + y*p.y + z*p.z + w*p.w; }
|
||||
// No cross-product in 4D
|
||||
|
||||
//! Operator for HPoint += HPoint;
|
||||
inline_ HPoint& operator+=(const HPoint& p) { x += p.x; y += p.y; z += p.z; w += p.w; return *this; }
|
||||
//! Operator for HPoint += float;
|
||||
inline_ HPoint& operator+=(float s) { x += s; y += s; z += s; w += s; return *this; }
|
||||
|
||||
//! Operator for HPoint -= HPoint;
|
||||
inline_ HPoint& operator-=(const HPoint& p) { x -= p.x; y -= p.y; z -= p.z; w -= p.w; return *this; }
|
||||
//! Operator for HPoint -= float;
|
||||
inline_ HPoint& operator-=(float s) { x -= s; y -= s; z -= s; w -= s; return *this; }
|
||||
|
||||
//! Operator for HPoint *= HPoint;
|
||||
inline_ HPoint& operator*=(const HPoint& p) { x *= p.x; y *= p.y; z *= p.z; w *= p.w; return *this; }
|
||||
//! Operator for HPoint *= float;
|
||||
inline_ HPoint& operator*=(float s) { x*=s; y*=s; z*=s; w*=s; return *this; }
|
||||
|
||||
//! Operator for HPoint /= HPoint;
|
||||
inline_ HPoint& operator/=(const HPoint& p) { x /= p.x; y /= p.y; z /= p.z; w /= p.w; return *this; }
|
||||
//! Operator for HPoint /= float;
|
||||
inline_ HPoint& operator/=(float s) { s = 1.0f / s; x*=s; y*=s; z*=s; w*=s; return *this; }
|
||||
|
||||
// Arithmetic operators
|
||||
|
||||
//! Operator for Point Mul = HPoint * Matrix3x3;
|
||||
Point operator*(const Matrix3x3& mat) const;
|
||||
//! Operator for HPoint Mul = HPoint * Matrix4x4;
|
||||
HPoint operator*(const Matrix4x4& mat) const;
|
||||
|
||||
// HPoint *= Matrix3x3 doesn't exist, the matrix is first casted to a 4x4
|
||||
//! Operator for HPoint *= Matrix4x4
|
||||
HPoint& operator*=(const Matrix4x4& mat);
|
||||
|
||||
// Logical operators
|
||||
|
||||
//! Operator for "if(HPoint==HPoint)"
|
||||
inline_ bool operator==(const HPoint& p) const { return ( (x==p.x)&&(y==p.y)&&(z==p.z)&&(w==p.w)); }
|
||||
//! Operator for "if(HPoint!=HPoint)"
|
||||
inline_ bool operator!=(const HPoint& p) const { return ( (x!=p.x)||(y!=p.y)||(z!=p.z)||(w!=p.w)); }
|
||||
|
||||
// Cast operators
|
||||
|
||||
//! Cast a HPoint to a Point. w is discarded.
|
||||
inline_ operator Point() const { return Point(x, y, z); }
|
||||
|
||||
public:
|
||||
float w;
|
||||
};
|
||||
|
||||
#endif // __ICEHPOINT_H__
|
||||
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for homogeneous points.
|
||||
* \file IceHPoint.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEHPOINT_H__
|
||||
#define __ICEHPOINT_H__
|
||||
|
||||
class ICEMATHS_API HPoint : public Point
|
||||
{
|
||||
public:
|
||||
|
||||
//! Empty constructor
|
||||
inline_ HPoint() {}
|
||||
//! Constructor from floats
|
||||
inline_ HPoint(float _x, float _y, float _z, float _w=0.0f) : Point(_x, _y, _z), w(_w) {}
|
||||
//! Constructor from array
|
||||
inline_ HPoint(const float f[4]) : Point(f), w(f[3]) {}
|
||||
//! Constructor from a Point
|
||||
inline_ HPoint(const Point& p, float _w=0.0f) : Point(p), w(_w) {}
|
||||
//! Destructor
|
||||
inline_ ~HPoint() {}
|
||||
|
||||
//! Clear the point
|
||||
inline_ HPoint& Zero() { x = y = z = w = 0.0f; return *this; }
|
||||
|
||||
//! Assignment from values
|
||||
inline_ HPoint& Set(float _x, float _y, float _z, float _w ) { x = _x; y = _y; z = _z; w = _w; return *this; }
|
||||
//! Assignment from array
|
||||
inline_ HPoint& Set(const float f[4]) { x = f[_X]; y = f[_Y]; z = f[_Z]; w = f[_W]; return *this; }
|
||||
//! Assignment from another h-point
|
||||
inline_ HPoint& Set(const HPoint& src) { x = src.x; y = src.y; z = src.z; w = src.w; return *this; }
|
||||
|
||||
//! Add a vector
|
||||
inline_ HPoint& Add(float _x, float _y, float _z, float _w ) { x += _x; y += _y; z += _z; w += _w; return *this; }
|
||||
//! Add a vector
|
||||
inline_ HPoint& Add(const float f[4]) { x += f[_X]; y += f[_Y]; z += f[_Z]; w += f[_W]; return *this; }
|
||||
|
||||
//! Subtract a vector
|
||||
inline_ HPoint& Sub(float _x, float _y, float _z, float _w ) { x -= _x; y -= _y; z -= _z; w -= _w; return *this; }
|
||||
//! Subtract a vector
|
||||
inline_ HPoint& Sub(const float f[4]) { x -= f[_X]; y -= f[_Y]; z -= f[_Z]; w -= f[_W]; return *this; }
|
||||
|
||||
//! Multiplies by a scalar
|
||||
inline_ HPoint& Mul(float s) { x *= s; y *= s; z *= s; w *= s; return *this; }
|
||||
|
||||
//! Returns MIN(x, y, z, w);
|
||||
float Min() const { return MIN(x, MIN(y, MIN(z, w))); }
|
||||
//! Returns MAX(x, y, z, w);
|
||||
float Max() const { return MAX(x, MAX(y, MAX(z, w))); }
|
||||
//! Sets each element to be componentwise minimum
|
||||
HPoint& Min(const HPoint& p) { x = MIN(x, p.x); y = MIN(y, p.y); z = MIN(z, p.z); w = MIN(w, p.w); return *this; }
|
||||
//! Sets each element to be componentwise maximum
|
||||
HPoint& Max(const HPoint& p) { x = MAX(x, p.x); y = MAX(y, p.y); z = MAX(z, p.z); w = MAX(w, p.w); return *this; }
|
||||
|
||||
//! Computes square magnitude
|
||||
inline_ float SquareMagnitude() const { return x*x + y*y + z*z + w*w; }
|
||||
//! Computes magnitude
|
||||
inline_ float Magnitude() const { return sqrtf(x*x + y*y + z*z + w*w); }
|
||||
|
||||
//! Normalize the vector
|
||||
inline_ HPoint& Normalize()
|
||||
{
|
||||
float M = Magnitude();
|
||||
if(M)
|
||||
{
|
||||
M = 1.0f / M;
|
||||
x *= M;
|
||||
y *= M;
|
||||
z *= M;
|
||||
w *= M;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Arithmetic operators
|
||||
//! Operator for HPoint Negate = - HPoint;
|
||||
inline_ HPoint operator-() const { return HPoint(-x, -y, -z, -w); }
|
||||
|
||||
//! Operator for HPoint Plus = HPoint + HPoint;
|
||||
inline_ HPoint operator+(const HPoint& p) const { return HPoint(x + p.x, y + p.y, z + p.z, w + p.w); }
|
||||
//! Operator for HPoint Minus = HPoint - HPoint;
|
||||
inline_ HPoint operator-(const HPoint& p) const { return HPoint(x - p.x, y - p.y, z - p.z, w - p.w); }
|
||||
|
||||
//! Operator for HPoint Mul = HPoint * HPoint;
|
||||
inline_ HPoint operator*(const HPoint& p) const { return HPoint(x * p.x, y * p.y, z * p.z, w * p.w); }
|
||||
//! Operator for HPoint Scale = HPoint * float;
|
||||
inline_ HPoint operator*(float s) const { return HPoint(x * s, y * s, z * s, w * s); }
|
||||
//! Operator for HPoint Scale = float * HPoint;
|
||||
inline_ friend HPoint operator*(float s, const HPoint& p) { return HPoint(s * p.x, s * p.y, s * p.z, s * p.w); }
|
||||
|
||||
//! Operator for HPoint Div = HPoint / HPoint;
|
||||
inline_ HPoint operator/(const HPoint& p) const { return HPoint(x / p.x, y / p.y, z / p.z, w / p.w); }
|
||||
//! Operator for HPoint Scale = HPoint / float;
|
||||
inline_ HPoint operator/(float s) const { s = 1.0f / s; return HPoint(x * s, y * s, z * s, w * s); }
|
||||
//! Operator for HPoint Scale = float / HPoint;
|
||||
inline_ friend HPoint operator/(float s, const HPoint& p) { return HPoint(s / p.x, s / p.y, s / p.z, s / p.w); }
|
||||
|
||||
//! Operator for float DotProd = HPoint | HPoint;
|
||||
inline_ float operator|(const HPoint& p) const { return x*p.x + y*p.y + z*p.z + w*p.w; }
|
||||
// No cross-product in 4D
|
||||
|
||||
//! Operator for HPoint += HPoint;
|
||||
inline_ HPoint& operator+=(const HPoint& p) { x += p.x; y += p.y; z += p.z; w += p.w; return *this; }
|
||||
//! Operator for HPoint += float;
|
||||
inline_ HPoint& operator+=(float s) { x += s; y += s; z += s; w += s; return *this; }
|
||||
|
||||
//! Operator for HPoint -= HPoint;
|
||||
inline_ HPoint& operator-=(const HPoint& p) { x -= p.x; y -= p.y; z -= p.z; w -= p.w; return *this; }
|
||||
//! Operator for HPoint -= float;
|
||||
inline_ HPoint& operator-=(float s) { x -= s; y -= s; z -= s; w -= s; return *this; }
|
||||
|
||||
//! Operator for HPoint *= HPoint;
|
||||
inline_ HPoint& operator*=(const HPoint& p) { x *= p.x; y *= p.y; z *= p.z; w *= p.w; return *this; }
|
||||
//! Operator for HPoint *= float;
|
||||
inline_ HPoint& operator*=(float s) { x*=s; y*=s; z*=s; w*=s; return *this; }
|
||||
|
||||
//! Operator for HPoint /= HPoint;
|
||||
inline_ HPoint& operator/=(const HPoint& p) { x /= p.x; y /= p.y; z /= p.z; w /= p.w; return *this; }
|
||||
//! Operator for HPoint /= float;
|
||||
inline_ HPoint& operator/=(float s) { s = 1.0f / s; x*=s; y*=s; z*=s; w*=s; return *this; }
|
||||
|
||||
// Arithmetic operators
|
||||
|
||||
//! Operator for Point Mul = HPoint * Matrix3x3;
|
||||
Point operator*(const Matrix3x3& mat) const;
|
||||
//! Operator for HPoint Mul = HPoint * Matrix4x4;
|
||||
HPoint operator*(const Matrix4x4& mat) const;
|
||||
|
||||
// HPoint *= Matrix3x3 doesn't exist, the matrix is first casted to a 4x4
|
||||
//! Operator for HPoint *= Matrix4x4
|
||||
HPoint& operator*=(const Matrix4x4& mat);
|
||||
|
||||
// Logical operators
|
||||
|
||||
//! Operator for "if(HPoint==HPoint)"
|
||||
inline_ bool operator==(const HPoint& p) const { return ( (x==p.x)&&(y==p.y)&&(z==p.z)&&(w==p.w)); }
|
||||
//! Operator for "if(HPoint!=HPoint)"
|
||||
inline_ bool operator!=(const HPoint& p) const { return ( (x!=p.x)||(y!=p.y)||(z!=p.z)||(w!=p.w)); }
|
||||
|
||||
// Cast operators
|
||||
|
||||
//! Cast a HPoint to a Point. w is discarded.
|
||||
inline_ operator Point() const { return Point(x, y, z); }
|
||||
|
||||
public:
|
||||
float w;
|
||||
};
|
||||
|
||||
#endif // __ICEHPOINT_H__
|
||||
|
||||
|
||||
@@ -1,78 +1,78 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains hashing code.
|
||||
* \file IceHashing.h
|
||||
* \author Pierre Terdiman
|
||||
* \date May, 08, 1999
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEHASHING_H
|
||||
#define ICEHASHING_H
|
||||
|
||||
#define HashSize(n) ((udword)1<<(n))
|
||||
#define HashMask(n) (HashSize(n)-1)
|
||||
|
||||
ICECORE_API udword Hash(const char* str);
|
||||
ICECORE_API udword Hash(ubyte* k, udword length, udword initval);
|
||||
|
||||
// Bob Jenkin's hash
|
||||
inline_ unsigned int Hash32Bits_0(unsigned int key)
|
||||
{
|
||||
key += (key << 12);
|
||||
key ^= (key >> 22);
|
||||
key += (key << 4);
|
||||
key ^= (key >> 9);
|
||||
key += (key << 10);
|
||||
key ^= (key >> 2);
|
||||
key += (key << 7);
|
||||
key ^= (key >> 12);
|
||||
return key;
|
||||
}
|
||||
|
||||
// Thomas Wang's hash
|
||||
inline_ int Hash32Bits_1(int key)
|
||||
{
|
||||
key += ~(key << 15);
|
||||
key ^= (key >> 10);
|
||||
key += (key << 3);
|
||||
key ^= (key >> 6);
|
||||
key += ~(key << 11);
|
||||
key ^= (key >> 16);
|
||||
return key;
|
||||
}
|
||||
|
||||
// Thomas Wang's hash
|
||||
inline_ __int64 Hash64Bits_0(__int64 key)
|
||||
{
|
||||
key += ~(key << 32);
|
||||
key ^= (key >> 22);
|
||||
key += ~(key << 13);
|
||||
key ^= (key >> 8);
|
||||
key += (key << 3);
|
||||
key ^= (key >> 15);
|
||||
key += ~(key << 27);
|
||||
key ^= (key >> 31);
|
||||
return key;
|
||||
}
|
||||
|
||||
inline_ __int64 Hash64Bits_1(__int64 key)
|
||||
{
|
||||
__int64 c1 = 0x6e5ea73858134343L;
|
||||
__int64 c2 = 0xb34e8f99a2ec9ef5L;
|
||||
key ^= ((c1 ^ key) >> 32);
|
||||
key *= c1;
|
||||
key ^= ((c2 ^ key) >> 31);
|
||||
key *= c2;
|
||||
key ^= ((c1 ^ key) >> 32);
|
||||
return key;
|
||||
}
|
||||
|
||||
inline_ udword Hash(udword id0, udword id1)
|
||||
{
|
||||
return Hash32Bits_1( (id0&0xffff)|(id1<<16) );
|
||||
}
|
||||
|
||||
#endif // ICEHASHING_H
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains hashing code.
|
||||
* \file IceHashing.h
|
||||
* \author Pierre Terdiman
|
||||
* \date May, 08, 1999
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEHASHING_H
|
||||
#define ICEHASHING_H
|
||||
|
||||
#define HashSize(n) ((udword)1<<(n))
|
||||
#define HashMask(n) (HashSize(n)-1)
|
||||
|
||||
ICECORE_API udword Hash(const char* str);
|
||||
ICECORE_API udword Hash(ubyte* k, udword length, udword initval);
|
||||
|
||||
// Bob Jenkin's hash
|
||||
inline_ unsigned int Hash32Bits_0(unsigned int key)
|
||||
{
|
||||
key += (key << 12);
|
||||
key ^= (key >> 22);
|
||||
key += (key << 4);
|
||||
key ^= (key >> 9);
|
||||
key += (key << 10);
|
||||
key ^= (key >> 2);
|
||||
key += (key << 7);
|
||||
key ^= (key >> 12);
|
||||
return key;
|
||||
}
|
||||
|
||||
// Thomas Wang's hash
|
||||
inline_ int Hash32Bits_1(int key)
|
||||
{
|
||||
key += ~(key << 15);
|
||||
key ^= (key >> 10);
|
||||
key += (key << 3);
|
||||
key ^= (key >> 6);
|
||||
key += ~(key << 11);
|
||||
key ^= (key >> 16);
|
||||
return key;
|
||||
}
|
||||
|
||||
// Thomas Wang's hash
|
||||
inline_ __int64 Hash64Bits_0(__int64 key)
|
||||
{
|
||||
key += ~(key << 32);
|
||||
key ^= (key >> 22);
|
||||
key += ~(key << 13);
|
||||
key ^= (key >> 8);
|
||||
key += (key << 3);
|
||||
key ^= (key >> 15);
|
||||
key += ~(key << 27);
|
||||
key ^= (key >> 31);
|
||||
return key;
|
||||
}
|
||||
|
||||
inline_ __int64 Hash64Bits_1(__int64 key)
|
||||
{
|
||||
__int64 c1 = 0x6e5ea73858134343L;
|
||||
__int64 c2 = 0xb34e8f99a2ec9ef5L;
|
||||
key ^= ((c1 ^ key) >> 32);
|
||||
key *= c1;
|
||||
key ^= ((c2 ^ key) >> 31);
|
||||
key *= c2;
|
||||
key ^= ((c1 ^ key) >> 32);
|
||||
return key;
|
||||
}
|
||||
|
||||
inline_ udword Hash(udword id0, udword id1)
|
||||
{
|
||||
return Hash32Bits_1( (id0&0xffff)|(id1<<16) );
|
||||
}
|
||||
|
||||
#endif // ICEHASHING_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,84 +1,84 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a handy indexed triangle class.
|
||||
* \file IceIndexedTriangle.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 17, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEINDEXEDTRIANGLE_H__
|
||||
#define __ICEINDEXEDTRIANGLE_H__
|
||||
|
||||
// Forward declarations
|
||||
enum CubeIndex;
|
||||
|
||||
// An indexed triangle class.
|
||||
class ICEMATHS_API IndexedTriangle
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ IndexedTriangle() {}
|
||||
//! Constructor
|
||||
inline_ IndexedTriangle(udword r0, udword r1, udword r2) { mVRef[0]=r0; mVRef[1]=r1; mVRef[2]=r2; }
|
||||
//! Copy constructor
|
||||
inline_ IndexedTriangle(const IndexedTriangle& triangle)
|
||||
{
|
||||
mVRef[0] = triangle.mVRef[0];
|
||||
mVRef[1] = triangle.mVRef[1];
|
||||
mVRef[2] = triangle.mVRef[2];
|
||||
}
|
||||
//! Destructor
|
||||
inline_ ~IndexedTriangle() {}
|
||||
//! Vertex-references
|
||||
udword mVRef[3];
|
||||
|
||||
// Methods
|
||||
void Flip();
|
||||
float Area(const Point* verts) const;
|
||||
float Perimeter(const Point* verts) const;
|
||||
float Compacity(const Point* verts) const;
|
||||
void Normal(const Point* verts, Point& normal) const;
|
||||
void DenormalizedNormal(const Point* verts, Point& normal) const;
|
||||
void Center(const Point* verts, Point& center) const;
|
||||
void CenteredNormal(const Point* verts, Point& normal) const;
|
||||
void RandomPoint(const Point* verts, Point& random) const;
|
||||
bool IsVisible(const Point* verts, const Point& source) const;
|
||||
bool BackfaceCulling(const Point* verts, const Point& source) const;
|
||||
float ComputeOcclusionPotential(const Point* verts, const Point& view) const;
|
||||
bool ReplaceVertex(udword oldref, udword newref);
|
||||
bool IsDegenerate() const;
|
||||
bool HasVertex(udword ref) const;
|
||||
bool HasVertex(udword ref, udword* index) const;
|
||||
ubyte FindEdge(udword vref0, udword vref1) const;
|
||||
udword OppositeVertex(udword vref0, udword vref1) const;
|
||||
inline_ udword OppositeVertex(ubyte edgenb) const { return mVRef[2-edgenb]; }
|
||||
void GetVRefs(ubyte edgenb, udword& vref0, udword& vref1, udword& vref2) const;
|
||||
float MinEdgeLength(const Point* verts) const;
|
||||
float MaxEdgeLength(const Point* verts) const;
|
||||
void ComputePoint(const Point* verts, float u, float v, Point& pt, udword* nearvtx=null) const;
|
||||
float Angle(const IndexedTriangle& tri, const Point* verts) const;
|
||||
inline_ Plane PlaneEquation(const Point* verts) const { return Plane(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); }
|
||||
bool Equal(const IndexedTriangle& tri) const;
|
||||
CubeIndex ComputeCubeIndex(const Point* verts) const;
|
||||
};
|
||||
|
||||
#endif // __ICEINDEXEDTRIANGLE_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a handy indexed triangle class.
|
||||
* \file IceIndexedTriangle.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 17, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEINDEXEDTRIANGLE_H__
|
||||
#define __ICEINDEXEDTRIANGLE_H__
|
||||
|
||||
// Forward declarations
|
||||
enum CubeIndex;
|
||||
|
||||
// An indexed triangle class.
|
||||
class ICEMATHS_API IndexedTriangle
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ IndexedTriangle() {}
|
||||
//! Constructor
|
||||
inline_ IndexedTriangle(udword r0, udword r1, udword r2) { mVRef[0]=r0; mVRef[1]=r1; mVRef[2]=r2; }
|
||||
//! Copy constructor
|
||||
inline_ IndexedTriangle(const IndexedTriangle& triangle)
|
||||
{
|
||||
mVRef[0] = triangle.mVRef[0];
|
||||
mVRef[1] = triangle.mVRef[1];
|
||||
mVRef[2] = triangle.mVRef[2];
|
||||
}
|
||||
//! Destructor
|
||||
inline_ ~IndexedTriangle() {}
|
||||
//! Vertex-references
|
||||
udword mVRef[3];
|
||||
|
||||
// Methods
|
||||
void Flip();
|
||||
float Area(const Point* verts) const;
|
||||
float Perimeter(const Point* verts) const;
|
||||
float Compacity(const Point* verts) const;
|
||||
void Normal(const Point* verts, Point& normal) const;
|
||||
void DenormalizedNormal(const Point* verts, Point& normal) const;
|
||||
void Center(const Point* verts, Point& center) const;
|
||||
void CenteredNormal(const Point* verts, Point& normal) const;
|
||||
void RandomPoint(const Point* verts, Point& random) const;
|
||||
bool IsVisible(const Point* verts, const Point& source) const;
|
||||
bool BackfaceCulling(const Point* verts, const Point& source) const;
|
||||
float ComputeOcclusionPotential(const Point* verts, const Point& view) const;
|
||||
bool ReplaceVertex(udword oldref, udword newref);
|
||||
bool IsDegenerate() const;
|
||||
bool HasVertex(udword ref) const;
|
||||
bool HasVertex(udword ref, udword* index) const;
|
||||
ubyte FindEdge(udword vref0, udword vref1) const;
|
||||
udword OppositeVertex(udword vref0, udword vref1) const;
|
||||
inline_ udword OppositeVertex(ubyte edgenb) const { return mVRef[2-edgenb]; }
|
||||
void GetVRefs(ubyte edgenb, udword& vref0, udword& vref1, udword& vref2) const;
|
||||
float MinEdgeLength(const Point* verts) const;
|
||||
float MaxEdgeLength(const Point* verts) const;
|
||||
void ComputePoint(const Point* verts, float u, float v, Point& pt, udword* nearvtx=null) const;
|
||||
float Angle(const IndexedTriangle& tri, const Point* verts) const;
|
||||
inline_ Plane PlaneEquation(const Point* verts) const { return Plane(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); }
|
||||
bool Equal(const IndexedTriangle& tri) const;
|
||||
CubeIndex ComputeCubeIndex(const Point* verts) const;
|
||||
};
|
||||
|
||||
#endif // __ICEINDEXEDTRIANGLE_H__
|
||||
|
||||
@@ -1,91 +1,91 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for line-swept spheres.
|
||||
* \file IceLSS.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICELSS_H__
|
||||
#define __ICELSS_H__
|
||||
|
||||
class ICEMATHS_API LSS : public Segment
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ LSS() {}
|
||||
//! Constructor
|
||||
inline_ LSS(const Segment& seg, float radius) : Segment(seg), mRadius(radius) {}
|
||||
//! Destructor
|
||||
inline_ ~LSS() {}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes an OBB surrounding the LSS.
|
||||
* \param box [out] the OBB
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void ComputeOBB(OBB& box);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a point is contained within the LSS.
|
||||
* \param pt [in] the point to test
|
||||
* \return true if inside the LSS
|
||||
* \warning point and LSS must be in same space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ bool Contains(const Point& pt) const { return SquareDistance(pt) <= mRadius*mRadius; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a sphere is contained within the LSS.
|
||||
* \param sphere [in] the sphere to test
|
||||
* \return true if inside the LSS
|
||||
* \warning sphere and LSS must be in same space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ bool Contains(const Sphere& sphere)
|
||||
{
|
||||
float d = mRadius - sphere.mRadius;
|
||||
if(d>=0.0f) return SquareDistance(sphere.mCenter) <= d*d;
|
||||
else return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if an LSS is contained within the LSS.
|
||||
* \param lss [in] the LSS to test
|
||||
* \return true if inside the LSS
|
||||
* \warning both LSS must be in same space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ bool Contains(const LSS& lss)
|
||||
{
|
||||
// We check the LSS contains the two spheres at the start and end of the sweep
|
||||
return Contains(Sphere(lss.mP0, lss.mRadius)) && Contains(Sphere(lss.mP0, lss.mRadius));
|
||||
}
|
||||
|
||||
float mRadius; //!< Sphere radius
|
||||
};
|
||||
|
||||
#endif // __ICELSS_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for line-swept spheres.
|
||||
* \file IceLSS.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICELSS_H__
|
||||
#define __ICELSS_H__
|
||||
|
||||
class ICEMATHS_API LSS : public Segment
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ LSS() {}
|
||||
//! Constructor
|
||||
inline_ LSS(const Segment& seg, float radius) : Segment(seg), mRadius(radius) {}
|
||||
//! Destructor
|
||||
inline_ ~LSS() {}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes an OBB surrounding the LSS.
|
||||
* \param box [out] the OBB
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void ComputeOBB(OBB& box);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a point is contained within the LSS.
|
||||
* \param pt [in] the point to test
|
||||
* \return true if inside the LSS
|
||||
* \warning point and LSS must be in same space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ bool Contains(const Point& pt) const { return SquareDistance(pt) <= mRadius*mRadius; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a sphere is contained within the LSS.
|
||||
* \param sphere [in] the sphere to test
|
||||
* \return true if inside the LSS
|
||||
* \warning sphere and LSS must be in same space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ bool Contains(const Sphere& sphere)
|
||||
{
|
||||
float d = mRadius - sphere.mRadius;
|
||||
if(d>=0.0f) return SquareDistance(sphere.mCenter) <= d*d;
|
||||
else return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if an LSS is contained within the LSS.
|
||||
* \param lss [in] the LSS to test
|
||||
* \return true if inside the LSS
|
||||
* \warning both LSS must be in same space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ bool Contains(const LSS& lss)
|
||||
{
|
||||
// We check the LSS contains the two spheres at the start and end of the sweep
|
||||
return Contains(Sphere(lss.mP0, lss.mRadius)) && Contains(Sphere(lss.mP0, lss.mRadius));
|
||||
}
|
||||
|
||||
float mRadius; //!< Sphere radius
|
||||
};
|
||||
|
||||
#endif // __ICELSS_H__
|
||||
|
||||
@@ -1,64 +1,64 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for 3x3 matrices.
|
||||
* \file IceMatrix3x3.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 3x3 matrix.
|
||||
* DirectX-compliant, ie row-column order, ie m[Row][Col].
|
||||
* Same as:
|
||||
* m11 m12 m13 first row.
|
||||
* m21 m22 m23 second row.
|
||||
* m31 m32 m33 third row.
|
||||
* Stored in memory as m11 m12 m13 m21...
|
||||
*
|
||||
* Multiplication rules:
|
||||
*
|
||||
* [x'y'z'] = [xyz][M]
|
||||
*
|
||||
* x' = x*m11 + y*m21 + z*m31
|
||||
* y' = x*m12 + y*m22 + z*m32
|
||||
* z' = x*m13 + y*m23 + z*m33
|
||||
*
|
||||
* \class Matrix3x3
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
// Cast operator
|
||||
Matrix3x3::operator Matrix4x4() const
|
||||
{
|
||||
return Matrix4x4(
|
||||
m[0][0], m[0][1], m[0][2], 0.0f,
|
||||
m[1][0], m[1][1], m[1][2], 0.0f,
|
||||
m[2][0], m[2][1], m[2][2], 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for 3x3 matrices.
|
||||
* \file IceMatrix3x3.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 3x3 matrix.
|
||||
* DirectX-compliant, ie row-column order, ie m[Row][Col].
|
||||
* Same as:
|
||||
* m11 m12 m13 first row.
|
||||
* m21 m22 m23 second row.
|
||||
* m31 m32 m33 third row.
|
||||
* Stored in memory as m11 m12 m13 m21...
|
||||
*
|
||||
* Multiplication rules:
|
||||
*
|
||||
* [x'y'z'] = [xyz][M]
|
||||
*
|
||||
* x' = x*m11 + y*m21 + z*m31
|
||||
* y' = x*m12 + y*m22 + z*m32
|
||||
* z' = x*m13 + y*m23 + z*m33
|
||||
*
|
||||
* \class Matrix3x3
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
// Cast operator
|
||||
Matrix3x3::operator Matrix4x4() const
|
||||
{
|
||||
return Matrix4x4(
|
||||
m[0][0], m[0][1], m[0][2], 0.0f,
|
||||
m[1][0], m[1][1], m[1][2], 0.0f,
|
||||
m[2][0], m[2][1], m[2][2], 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,152 +1,152 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for 4x4 matrices.
|
||||
* \file IceMatrix4x4.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 4x4 matrix.
|
||||
* DirectX-compliant, ie row-column order, ie m[Row][Col].
|
||||
* Same as:
|
||||
* m11 m12 m13 m14 first row.
|
||||
* m21 m22 m23 m24 second row.
|
||||
* m31 m32 m33 m34 third row.
|
||||
* m41 m42 m43 m44 fourth row.
|
||||
* Translation is (m41, m42, m43), (m14, m24, m34, m44) = (0, 0, 0, 1).
|
||||
* Stored in memory as m11 m12 m13 m14 m21...
|
||||
*
|
||||
* Multiplication rules:
|
||||
*
|
||||
* [x'y'z'1] = [xyz1][M]
|
||||
*
|
||||
* x' = x*m11 + y*m21 + z*m31 + m41
|
||||
* y' = x*m12 + y*m22 + z*m32 + m42
|
||||
* z' = x*m13 + y*m23 + z*m33 + m43
|
||||
* 1' = 0 + 0 + 0 + m44
|
||||
*
|
||||
* \class Matrix4x4
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Inverts a PR matrix. (which only contains a rotation and a translation)
|
||||
* This is faster and less subject to FPU errors than the generic inversion code.
|
||||
*
|
||||
* \relates Matrix4x4
|
||||
* \fn InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src)
|
||||
* \param dest [out] destination matrix
|
||||
* \param src [in] source matrix
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
ICEMATHS_API void IceMaths::InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src)
|
||||
{
|
||||
dest.m[0][0] = src.m[0][0];
|
||||
dest.m[1][0] = src.m[0][1];
|
||||
dest.m[2][0] = src.m[0][2];
|
||||
dest.m[3][0] = -(src.m[3][0]*src.m[0][0] + src.m[3][1]*src.m[0][1] + src.m[3][2]*src.m[0][2]);
|
||||
|
||||
dest.m[0][1] = src.m[1][0];
|
||||
dest.m[1][1] = src.m[1][1];
|
||||
dest.m[2][1] = src.m[1][2];
|
||||
dest.m[3][1] = -(src.m[3][0]*src.m[1][0] + src.m[3][1]*src.m[1][1] + src.m[3][2]*src.m[1][2]);
|
||||
|
||||
dest.m[0][2] = src.m[2][0];
|
||||
dest.m[1][2] = src.m[2][1];
|
||||
dest.m[2][2] = src.m[2][2];
|
||||
dest.m[3][2] = -(src.m[3][0]*src.m[2][0] + src.m[3][1]*src.m[2][1] + src.m[3][2]*src.m[2][2]);
|
||||
|
||||
dest.m[0][3] = 0.0f;
|
||||
dest.m[1][3] = 0.0f;
|
||||
dest.m[2][3] = 0.0f;
|
||||
dest.m[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compute the cofactor of the Matrix at a specified location
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Matrix4x4::CoFactor(udword row, udword col) const
|
||||
{
|
||||
return (( m[(row+1)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+3)&3][(col+3)&3] +
|
||||
m[(row+1)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+3)&3][(col+1)&3] +
|
||||
m[(row+1)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+3)&3][(col+2)&3])
|
||||
- (m[(row+3)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+1)&3][(col+3)&3] +
|
||||
m[(row+3)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+1)&3][(col+1)&3] +
|
||||
m[(row+3)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+1)&3][(col+2)&3])) * ((row + col) & 1 ? -1.0f : +1.0f);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compute the determinant of the Matrix
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Matrix4x4::Determinant() const
|
||||
{
|
||||
return m[0][0] * CoFactor(0, 0) +
|
||||
m[0][1] * CoFactor(0, 1) +
|
||||
m[0][2] * CoFactor(0, 2) +
|
||||
m[0][3] * CoFactor(0, 3);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compute the inverse of the matrix
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Matrix4x4& Matrix4x4::Invert()
|
||||
{
|
||||
float Det = Determinant();
|
||||
Matrix4x4 Temp;
|
||||
|
||||
if(fabsf(Det) < MATRIX4X4_EPSILON)
|
||||
return *this; // The matrix is not invertible! Singular case!
|
||||
|
||||
float IDet = 1.0f / Det;
|
||||
|
||||
Temp.m[0][0] = CoFactor(0,0) * IDet;
|
||||
Temp.m[1][0] = CoFactor(0,1) * IDet;
|
||||
Temp.m[2][0] = CoFactor(0,2) * IDet;
|
||||
Temp.m[3][0] = CoFactor(0,3) * IDet;
|
||||
Temp.m[0][1] = CoFactor(1,0) * IDet;
|
||||
Temp.m[1][1] = CoFactor(1,1) * IDet;
|
||||
Temp.m[2][1] = CoFactor(1,2) * IDet;
|
||||
Temp.m[3][1] = CoFactor(1,3) * IDet;
|
||||
Temp.m[0][2] = CoFactor(2,0) * IDet;
|
||||
Temp.m[1][2] = CoFactor(2,1) * IDet;
|
||||
Temp.m[2][2] = CoFactor(2,2) * IDet;
|
||||
Temp.m[3][2] = CoFactor(2,3) * IDet;
|
||||
Temp.m[0][3] = CoFactor(3,0) * IDet;
|
||||
Temp.m[1][3] = CoFactor(3,1) * IDet;
|
||||
Temp.m[2][3] = CoFactor(3,2) * IDet;
|
||||
Temp.m[3][3] = CoFactor(3,3) * IDet;
|
||||
|
||||
*this = Temp;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for 4x4 matrices.
|
||||
* \file IceMatrix4x4.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 4x4 matrix.
|
||||
* DirectX-compliant, ie row-column order, ie m[Row][Col].
|
||||
* Same as:
|
||||
* m11 m12 m13 m14 first row.
|
||||
* m21 m22 m23 m24 second row.
|
||||
* m31 m32 m33 m34 third row.
|
||||
* m41 m42 m43 m44 fourth row.
|
||||
* Translation is (m41, m42, m43), (m14, m24, m34, m44) = (0, 0, 0, 1).
|
||||
* Stored in memory as m11 m12 m13 m14 m21...
|
||||
*
|
||||
* Multiplication rules:
|
||||
*
|
||||
* [x'y'z'1] = [xyz1][M]
|
||||
*
|
||||
* x' = x*m11 + y*m21 + z*m31 + m41
|
||||
* y' = x*m12 + y*m22 + z*m32 + m42
|
||||
* z' = x*m13 + y*m23 + z*m33 + m43
|
||||
* 1' = 0 + 0 + 0 + m44
|
||||
*
|
||||
* \class Matrix4x4
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Inverts a PR matrix. (which only contains a rotation and a translation)
|
||||
* This is faster and less subject to FPU errors than the generic inversion code.
|
||||
*
|
||||
* \relates Matrix4x4
|
||||
* \fn InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src)
|
||||
* \param dest [out] destination matrix
|
||||
* \param src [in] source matrix
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
ICEMATHS_API void IceMaths::InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src)
|
||||
{
|
||||
dest.m[0][0] = src.m[0][0];
|
||||
dest.m[1][0] = src.m[0][1];
|
||||
dest.m[2][0] = src.m[0][2];
|
||||
dest.m[3][0] = -(src.m[3][0]*src.m[0][0] + src.m[3][1]*src.m[0][1] + src.m[3][2]*src.m[0][2]);
|
||||
|
||||
dest.m[0][1] = src.m[1][0];
|
||||
dest.m[1][1] = src.m[1][1];
|
||||
dest.m[2][1] = src.m[1][2];
|
||||
dest.m[3][1] = -(src.m[3][0]*src.m[1][0] + src.m[3][1]*src.m[1][1] + src.m[3][2]*src.m[1][2]);
|
||||
|
||||
dest.m[0][2] = src.m[2][0];
|
||||
dest.m[1][2] = src.m[2][1];
|
||||
dest.m[2][2] = src.m[2][2];
|
||||
dest.m[3][2] = -(src.m[3][0]*src.m[2][0] + src.m[3][1]*src.m[2][1] + src.m[3][2]*src.m[2][2]);
|
||||
|
||||
dest.m[0][3] = 0.0f;
|
||||
dest.m[1][3] = 0.0f;
|
||||
dest.m[2][3] = 0.0f;
|
||||
dest.m[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compute the cofactor of the Matrix at a specified location
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Matrix4x4::CoFactor(udword row, udword col) const
|
||||
{
|
||||
return (( m[(row+1)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+3)&3][(col+3)&3] +
|
||||
m[(row+1)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+3)&3][(col+1)&3] +
|
||||
m[(row+1)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+3)&3][(col+2)&3])
|
||||
- (m[(row+3)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+1)&3][(col+3)&3] +
|
||||
m[(row+3)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+1)&3][(col+1)&3] +
|
||||
m[(row+3)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+1)&3][(col+2)&3])) * ((row + col) & 1 ? -1.0f : +1.0f);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compute the determinant of the Matrix
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Matrix4x4::Determinant() const
|
||||
{
|
||||
return m[0][0] * CoFactor(0, 0) +
|
||||
m[0][1] * CoFactor(0, 1) +
|
||||
m[0][2] * CoFactor(0, 2) +
|
||||
m[0][3] * CoFactor(0, 3);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compute the inverse of the matrix
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Matrix4x4& Matrix4x4::Invert()
|
||||
{
|
||||
float Det = Determinant();
|
||||
Matrix4x4 Temp;
|
||||
|
||||
if(fabsf(Det) < MATRIX4X4_EPSILON)
|
||||
return *this; // The matrix is not invertible! Singular case!
|
||||
|
||||
float IDet = 1.0f / Det;
|
||||
|
||||
Temp.m[0][0] = CoFactor(0,0) * IDet;
|
||||
Temp.m[1][0] = CoFactor(0,1) * IDet;
|
||||
Temp.m[2][0] = CoFactor(0,2) * IDet;
|
||||
Temp.m[3][0] = CoFactor(0,3) * IDet;
|
||||
Temp.m[0][1] = CoFactor(1,0) * IDet;
|
||||
Temp.m[1][1] = CoFactor(1,1) * IDet;
|
||||
Temp.m[2][1] = CoFactor(1,2) * IDet;
|
||||
Temp.m[3][1] = CoFactor(1,3) * IDet;
|
||||
Temp.m[0][2] = CoFactor(2,0) * IDet;
|
||||
Temp.m[1][2] = CoFactor(2,1) * IDet;
|
||||
Temp.m[2][2] = CoFactor(2,2) * IDet;
|
||||
Temp.m[3][2] = CoFactor(2,3) * IDet;
|
||||
Temp.m[0][3] = CoFactor(3,0) * IDet;
|
||||
Temp.m[1][3] = CoFactor(3,1) * IDet;
|
||||
Temp.m[2][3] = CoFactor(3,2) * IDet;
|
||||
Temp.m[3][3] = CoFactor(3,3) * IDet;
|
||||
|
||||
*this = Temp;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,471 +1,471 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for 4x4 matrices.
|
||||
* \file IceMatrix4x4.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEMATRIX4X4_H__
|
||||
#define __ICEMATRIX4X4_H__
|
||||
|
||||
// Forward declarations
|
||||
class PRS;
|
||||
class PR;
|
||||
|
||||
#define MATRIX4X4_EPSILON (1.0e-7f)
|
||||
|
||||
class ICEMATHS_API Matrix4x4
|
||||
{
|
||||
// void LUBackwardSubstitution( sdword *indx, float* b );
|
||||
// void LUDecomposition( sdword* indx, float* d );
|
||||
|
||||
public:
|
||||
//! Empty constructor.
|
||||
inline_ Matrix4x4() {}
|
||||
//! Constructor from 16 values
|
||||
inline_ Matrix4x4( float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33)
|
||||
{
|
||||
m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03;
|
||||
m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13;
|
||||
m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23;
|
||||
m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33;
|
||||
}
|
||||
//! Copy constructor
|
||||
inline_ Matrix4x4(const Matrix4x4& mat) { CopyMemory(m, &mat.m, 16*sizeof(float)); }
|
||||
//! Destructor.
|
||||
inline_ ~Matrix4x4() {}
|
||||
|
||||
//! Assign values (rotation only)
|
||||
inline_ Matrix4x4& Set( float m00, float m01, float m02,
|
||||
float m10, float m11, float m12,
|
||||
float m20, float m21, float m22)
|
||||
{
|
||||
m[0][0] = m00; m[0][1] = m01; m[0][2] = m02;
|
||||
m[1][0] = m10; m[1][1] = m11; m[1][2] = m12;
|
||||
m[2][0] = m20; m[2][1] = m21; m[2][2] = m22;
|
||||
return *this;
|
||||
}
|
||||
//! Assign values
|
||||
inline_ Matrix4x4& Set( float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33)
|
||||
{
|
||||
m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03;
|
||||
m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13;
|
||||
m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23;
|
||||
m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Copy from a Matrix4x4
|
||||
inline_ void Copy(const Matrix4x4& source) { CopyMemory(m, source.m, 16*sizeof(float)); }
|
||||
|
||||
// Row-column access
|
||||
//! Returns a row.
|
||||
inline_ void GetRow(const udword r, HPoint& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; p.w=m[r][3]; }
|
||||
//! Returns a row.
|
||||
inline_ void GetRow(const udword r, Point& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; }
|
||||
//! Returns a row.
|
||||
inline_ const HPoint& GetRow(const udword r) const { return *(const HPoint*)&m[r][0]; }
|
||||
//! Returns a row.
|
||||
inline_ HPoint& GetRow(const udword r) { return *(HPoint*)&m[r][0]; }
|
||||
//! Sets a row.
|
||||
inline_ void SetRow(const udword r, const HPoint& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]=p.w; }
|
||||
//! Sets a row.
|
||||
inline_ void SetRow(const udword r, const Point& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]= (r!=3) ? 0.0f : 1.0f; }
|
||||
//! Returns a column.
|
||||
inline_ void GetCol(const udword c, HPoint& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; p.w=m[3][c]; }
|
||||
//! Returns a column.
|
||||
inline_ void GetCol(const udword c, Point& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; }
|
||||
//! Sets a column.
|
||||
inline_ void SetCol(const udword c, const HPoint& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]=p.w; }
|
||||
//! Sets a column.
|
||||
inline_ void SetCol(const udword c, const Point& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]= (c!=3) ? 0.0f : 1.0f; }
|
||||
|
||||
// Translation
|
||||
//! Returns the translation part of the matrix.
|
||||
inline_ const HPoint& GetTrans() const { return GetRow(3); }
|
||||
//! Gets the translation part of the matrix
|
||||
inline_ void GetTrans(Point& p) const { p.x=m[3][0]; p.y=m[3][1]; p.z=m[3][2]; }
|
||||
//! Sets the translation part of the matrix, from a Point.
|
||||
inline_ void SetTrans(const Point& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; }
|
||||
//! Sets the translation part of the matrix, from a HPoint.
|
||||
inline_ void SetTrans(const HPoint& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; m[3][3]=p.w; }
|
||||
//! Sets the translation part of the matrix, from floats.
|
||||
inline_ void SetTrans(float tx, float ty, float tz) { m[3][0]=tx; m[3][1]=ty; m[3][2]=tz; }
|
||||
|
||||
// Scale
|
||||
//! Sets the scale from a Point. The point is put on the diagonal.
|
||||
inline_ void SetScale(const Point& p) { m[0][0]=p.x; m[1][1]=p.y; m[2][2]=p.z; }
|
||||
//! Sets the scale from floats. Values are put on the diagonal.
|
||||
inline_ void SetScale(float sx, float sy, float sz) { m[0][0]=sx; m[1][1]=sy; m[2][2]=sz; }
|
||||
//! Scales from a Point. Each row is multiplied by a component.
|
||||
void Scale(const Point& p)
|
||||
{
|
||||
m[0][0] *= p.x; m[1][0] *= p.y; m[2][0] *= p.z;
|
||||
m[0][1] *= p.x; m[1][1] *= p.y; m[2][1] *= p.z;
|
||||
m[0][2] *= p.x; m[1][2] *= p.y; m[2][2] *= p.z;
|
||||
}
|
||||
//! Scales from floats. Each row is multiplied by a value.
|
||||
void Scale(float sx, float sy, float sz)
|
||||
{
|
||||
m[0][0] *= sx; m[1][0] *= sy; m[2][0] *= sz;
|
||||
m[0][1] *= sx; m[1][1] *= sy; m[2][1] *= sz;
|
||||
m[0][2] *= sx; m[1][2] *= sy; m[2][2] *= sz;
|
||||
}
|
||||
/*
|
||||
//! Returns a row.
|
||||
inline_ HPoint GetRow(const udword row) const { return mRow[row]; }
|
||||
//! Sets a row.
|
||||
inline_ Matrix4x4& SetRow(const udword row, const HPoint& p) { mRow[row] = p; return *this; }
|
||||
//! Sets a row.
|
||||
Matrix4x4& SetRow(const udword row, const Point& p)
|
||||
{
|
||||
m[row][0] = p.x;
|
||||
m[row][1] = p.y;
|
||||
m[row][2] = p.z;
|
||||
m[row][3] = (row != 3) ? 0.0f : 1.0f;
|
||||
return *this;
|
||||
}
|
||||
//! Returns a column.
|
||||
HPoint GetCol(const udword col) const
|
||||
{
|
||||
HPoint Res;
|
||||
Res.x = m[0][col];
|
||||
Res.y = m[1][col];
|
||||
Res.z = m[2][col];
|
||||
Res.w = m[3][col];
|
||||
return Res;
|
||||
}
|
||||
//! Sets a column.
|
||||
Matrix4x4& SetCol(const udword col, const HPoint& p)
|
||||
{
|
||||
m[0][col] = p.x;
|
||||
m[1][col] = p.y;
|
||||
m[2][col] = p.z;
|
||||
m[3][col] = p.w;
|
||||
return *this;
|
||||
}
|
||||
//! Sets a column.
|
||||
Matrix4x4& SetCol(const udword col, const Point& p)
|
||||
{
|
||||
m[0][col] = p.x;
|
||||
m[1][col] = p.y;
|
||||
m[2][col] = p.z;
|
||||
m[3][col] = (col != 3) ? 0.0f : 1.0f;
|
||||
return *this;
|
||||
}
|
||||
*/
|
||||
//! Computes the trace. The trace is the sum of the 4 diagonal components.
|
||||
inline_ float Trace() const { return m[0][0] + m[1][1] + m[2][2] + m[3][3]; }
|
||||
//! Computes the trace of the upper 3x3 matrix.
|
||||
inline_ float Trace3x3() const { return m[0][0] + m[1][1] + m[2][2]; }
|
||||
//! Clears the matrix.
|
||||
inline_ void Zero() { ZeroMemory(&m, sizeof(m)); }
|
||||
//! Sets the identity matrix.
|
||||
inline_ void Identity() { Zero(); m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f; }
|
||||
//! Checks for identity
|
||||
inline_ bool IsIdentity() const
|
||||
{
|
||||
if(IR(m[0][0])!=IEEE_1_0) return false;
|
||||
if(IR(m[0][1])!=0) return false;
|
||||
if(IR(m[0][2])!=0) return false;
|
||||
if(IR(m[0][3])!=0) return false;
|
||||
|
||||
if(IR(m[1][0])!=0) return false;
|
||||
if(IR(m[1][1])!=IEEE_1_0) return false;
|
||||
if(IR(m[1][2])!=0) return false;
|
||||
if(IR(m[1][3])!=0) return false;
|
||||
|
||||
if(IR(m[2][0])!=0) return false;
|
||||
if(IR(m[2][1])!=0) return false;
|
||||
if(IR(m[2][2])!=IEEE_1_0) return false;
|
||||
if(IR(m[2][3])!=0) return false;
|
||||
|
||||
if(IR(m[3][0])!=0) return false;
|
||||
if(IR(m[3][1])!=0) return false;
|
||||
if(IR(m[3][2])!=0) return false;
|
||||
if(IR(m[3][3])!=IEEE_1_0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Checks matrix validity
|
||||
inline_ BOOL IsValid() const
|
||||
{
|
||||
for(udword j=0;j<4;j++)
|
||||
{
|
||||
for(udword i=0;i<4;i++)
|
||||
{
|
||||
if(!IsValidFloat(m[j][i])) return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//! Sets a rotation matrix around the X axis.
|
||||
void RotX(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[1][1] = m[2][2] = Cos; m[2][1] = -Sin; m[1][2] = Sin; }
|
||||
//! Sets a rotation matrix around the Y axis.
|
||||
void RotY(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[2][2] = Cos; m[2][0] = Sin; m[0][2] = -Sin; }
|
||||
//! Sets a rotation matrix around the Z axis.
|
||||
void RotZ(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[1][1] = Cos; m[1][0] = -Sin; m[0][1] = Sin; }
|
||||
|
||||
//! Makes a rotation matrix about an arbitrary axis
|
||||
Matrix4x4& Rot(float angle, Point& p1, Point& p2);
|
||||
|
||||
//! Transposes the matrix.
|
||||
void Transpose()
|
||||
{
|
||||
IR(m[1][0]) ^= IR(m[0][1]); IR(m[0][1]) ^= IR(m[1][0]); IR(m[1][0]) ^= IR(m[0][1]);
|
||||
IR(m[2][0]) ^= IR(m[0][2]); IR(m[0][2]) ^= IR(m[2][0]); IR(m[2][0]) ^= IR(m[0][2]);
|
||||
IR(m[3][0]) ^= IR(m[0][3]); IR(m[0][3]) ^= IR(m[3][0]); IR(m[3][0]) ^= IR(m[0][3]);
|
||||
IR(m[1][2]) ^= IR(m[2][1]); IR(m[2][1]) ^= IR(m[1][2]); IR(m[1][2]) ^= IR(m[2][1]);
|
||||
IR(m[1][3]) ^= IR(m[3][1]); IR(m[3][1]) ^= IR(m[1][3]); IR(m[1][3]) ^= IR(m[3][1]);
|
||||
IR(m[2][3]) ^= IR(m[3][2]); IR(m[3][2]) ^= IR(m[2][3]); IR(m[2][3]) ^= IR(m[3][2]);
|
||||
}
|
||||
|
||||
//! Computes a cofactor. Used for matrix inversion.
|
||||
float CoFactor(udword row, udword col) const;
|
||||
//! Computes the determinant of the matrix.
|
||||
float Determinant() const;
|
||||
//! Inverts the matrix. Determinant must be different from zero, else matrix can't be inverted.
|
||||
Matrix4x4& Invert();
|
||||
// Matrix& ComputeAxisMatrix(Point& axis, float angle);
|
||||
|
||||
// Cast operators
|
||||
//! Casts a Matrix4x4 to a Matrix3x3.
|
||||
inline_ operator Matrix3x3() const
|
||||
{
|
||||
return Matrix3x3(
|
||||
m[0][0], m[0][1], m[0][2],
|
||||
m[1][0], m[1][1], m[1][2],
|
||||
m[2][0], m[2][1], m[2][2]);
|
||||
}
|
||||
//! Casts a Matrix4x4 to a Quat.
|
||||
operator Quat() const;
|
||||
//! Casts a Matrix4x4 to a PR.
|
||||
operator PR() const;
|
||||
|
||||
// Arithmetic operators
|
||||
//! Operator for Matrix4x4 Plus = Matrix4x4 + Matrix4x4;
|
||||
inline_ Matrix4x4 operator+(const Matrix4x4& mat) const
|
||||
{
|
||||
return Matrix4x4(
|
||||
m[0][0]+mat.m[0][0], m[0][1]+mat.m[0][1], m[0][2]+mat.m[0][2], m[0][3]+mat.m[0][3],
|
||||
m[1][0]+mat.m[1][0], m[1][1]+mat.m[1][1], m[1][2]+mat.m[1][2], m[1][3]+mat.m[1][3],
|
||||
m[2][0]+mat.m[2][0], m[2][1]+mat.m[2][1], m[2][2]+mat.m[2][2], m[2][3]+mat.m[2][3],
|
||||
m[3][0]+mat.m[3][0], m[3][1]+mat.m[3][1], m[3][2]+mat.m[3][2], m[3][3]+mat.m[3][3]);
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 Minus = Matrix4x4 - Matrix4x4;
|
||||
inline_ Matrix4x4 operator-(const Matrix4x4& mat) const
|
||||
{
|
||||
return Matrix4x4(
|
||||
m[0][0]-mat.m[0][0], m[0][1]-mat.m[0][1], m[0][2]-mat.m[0][2], m[0][3]-mat.m[0][3],
|
||||
m[1][0]-mat.m[1][0], m[1][1]-mat.m[1][1], m[1][2]-mat.m[1][2], m[1][3]-mat.m[1][3],
|
||||
m[2][0]-mat.m[2][0], m[2][1]-mat.m[2][1], m[2][2]-mat.m[2][2], m[2][3]-mat.m[2][3],
|
||||
m[3][0]-mat.m[3][0], m[3][1]-mat.m[3][1], m[3][2]-mat.m[3][2], m[3][3]-mat.m[3][3]);
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 Mul = Matrix4x4 * Matrix4x4;
|
||||
inline_ Matrix4x4 operator*(const Matrix4x4& mat) const
|
||||
{
|
||||
return Matrix4x4(
|
||||
m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0] + m[0][3]*mat.m[3][0],
|
||||
m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1] + m[0][3]*mat.m[3][1],
|
||||
m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2] + m[0][3]*mat.m[3][2],
|
||||
m[0][0]*mat.m[0][3] + m[0][1]*mat.m[1][3] + m[0][2]*mat.m[2][3] + m[0][3]*mat.m[3][3],
|
||||
|
||||
m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0] + m[1][3]*mat.m[3][0],
|
||||
m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1] + m[1][3]*mat.m[3][1],
|
||||
m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2] + m[1][3]*mat.m[3][2],
|
||||
m[1][0]*mat.m[0][3] + m[1][1]*mat.m[1][3] + m[1][2]*mat.m[2][3] + m[1][3]*mat.m[3][3],
|
||||
|
||||
m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0] + m[2][3]*mat.m[3][0],
|
||||
m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1] + m[2][3]*mat.m[3][1],
|
||||
m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2] + m[2][3]*mat.m[3][2],
|
||||
m[2][0]*mat.m[0][3] + m[2][1]*mat.m[1][3] + m[2][2]*mat.m[2][3] + m[2][3]*mat.m[3][3],
|
||||
|
||||
m[3][0]*mat.m[0][0] + m[3][1]*mat.m[1][0] + m[3][2]*mat.m[2][0] + m[3][3]*mat.m[3][0],
|
||||
m[3][0]*mat.m[0][1] + m[3][1]*mat.m[1][1] + m[3][2]*mat.m[2][1] + m[3][3]*mat.m[3][1],
|
||||
m[3][0]*mat.m[0][2] + m[3][1]*mat.m[1][2] + m[3][2]*mat.m[2][2] + m[3][3]*mat.m[3][2],
|
||||
m[3][0]*mat.m[0][3] + m[3][1]*mat.m[1][3] + m[3][2]*mat.m[2][3] + m[3][3]*mat.m[3][3]);
|
||||
}
|
||||
|
||||
//! Operator for HPoint Mul = Matrix4x4 * HPoint;
|
||||
inline_ HPoint operator*(const HPoint& v) const { return HPoint(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v, GetRow(3)|v); }
|
||||
|
||||
//! Operator for Point Mul = Matrix4x4 * Point;
|
||||
inline_ Point operator*(const Point& v) const
|
||||
{
|
||||
return Point( m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3],
|
||||
m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3],
|
||||
m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3] );
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 Scale = Matrix4x4 * float;
|
||||
inline_ Matrix4x4 operator*(float s) const
|
||||
{
|
||||
return Matrix4x4(
|
||||
m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s,
|
||||
m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s,
|
||||
m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s,
|
||||
m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s);
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 Scale = float * Matrix4x4;
|
||||
inline_ friend Matrix4x4 operator*(float s, const Matrix4x4& mat)
|
||||
{
|
||||
return Matrix4x4(
|
||||
s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2], s*mat.m[0][3],
|
||||
s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2], s*mat.m[1][3],
|
||||
s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2], s*mat.m[2][3],
|
||||
s*mat.m[3][0], s*mat.m[3][1], s*mat.m[3][2], s*mat.m[3][3]);
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 Div = Matrix4x4 / float;
|
||||
inline_ Matrix4x4 operator/(float s) const
|
||||
{
|
||||
if(s) s = 1.0f / s;
|
||||
|
||||
return Matrix4x4(
|
||||
m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s,
|
||||
m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s,
|
||||
m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s,
|
||||
m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s);
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 Div = float / Matrix4x4;
|
||||
inline_ friend Matrix4x4 operator/(float s, const Matrix4x4& mat)
|
||||
{
|
||||
return Matrix4x4(
|
||||
s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2], s/mat.m[0][3],
|
||||
s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2], s/mat.m[1][3],
|
||||
s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2], s/mat.m[2][3],
|
||||
s/mat.m[3][0], s/mat.m[3][1], s/mat.m[3][2], s/mat.m[3][3]);
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 += Matrix4x4;
|
||||
inline_ Matrix4x4& operator+=(const Matrix4x4& mat)
|
||||
{
|
||||
m[0][0]+=mat.m[0][0]; m[0][1]+=mat.m[0][1]; m[0][2]+=mat.m[0][2]; m[0][3]+=mat.m[0][3];
|
||||
m[1][0]+=mat.m[1][0]; m[1][1]+=mat.m[1][1]; m[1][2]+=mat.m[1][2]; m[1][3]+=mat.m[1][3];
|
||||
m[2][0]+=mat.m[2][0]; m[2][1]+=mat.m[2][1]; m[2][2]+=mat.m[2][2]; m[2][3]+=mat.m[2][3];
|
||||
m[3][0]+=mat.m[3][0]; m[3][1]+=mat.m[3][1]; m[3][2]+=mat.m[3][2]; m[3][3]+=mat.m[3][3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 -= Matrix4x4;
|
||||
inline_ Matrix4x4& operator-=(const Matrix4x4& mat)
|
||||
{
|
||||
m[0][0]-=mat.m[0][0]; m[0][1]-=mat.m[0][1]; m[0][2]-=mat.m[0][2]; m[0][3]-=mat.m[0][3];
|
||||
m[1][0]-=mat.m[1][0]; m[1][1]-=mat.m[1][1]; m[1][2]-=mat.m[1][2]; m[1][3]-=mat.m[1][3];
|
||||
m[2][0]-=mat.m[2][0]; m[2][1]-=mat.m[2][1]; m[2][2]-=mat.m[2][2]; m[2][3]-=mat.m[2][3];
|
||||
m[3][0]-=mat.m[3][0]; m[3][1]-=mat.m[3][1]; m[3][2]-=mat.m[3][2]; m[3][3]-=mat.m[3][3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 *= Matrix4x4;
|
||||
Matrix4x4& operator*=(const Matrix4x4& mat)
|
||||
{
|
||||
HPoint TempRow;
|
||||
|
||||
GetRow(0, TempRow);
|
||||
m[0][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0];
|
||||
m[0][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1];
|
||||
m[0][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2];
|
||||
m[0][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3];
|
||||
|
||||
GetRow(1, TempRow);
|
||||
m[1][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0];
|
||||
m[1][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1];
|
||||
m[1][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2];
|
||||
m[1][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3];
|
||||
|
||||
GetRow(2, TempRow);
|
||||
m[2][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0];
|
||||
m[2][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1];
|
||||
m[2][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2];
|
||||
m[2][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3];
|
||||
|
||||
GetRow(3, TempRow);
|
||||
m[3][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0];
|
||||
m[3][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1];
|
||||
m[3][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2];
|
||||
m[3][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 *= float;
|
||||
inline_ Matrix4x4& operator*=(float s)
|
||||
{
|
||||
m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s;
|
||||
m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s;
|
||||
m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s;
|
||||
m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 /= float;
|
||||
inline_ Matrix4x4& operator/=(float s)
|
||||
{
|
||||
if(s) s = 1.0f / s;
|
||||
m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s;
|
||||
m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s;
|
||||
m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s;
|
||||
m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline_ const HPoint& operator[](int row) const { return *(const HPoint*)&m[row][0]; }
|
||||
inline_ HPoint& operator[](int row) { return *(HPoint*)&m[row][0]; }
|
||||
|
||||
public:
|
||||
|
||||
float m[4][4];
|
||||
};
|
||||
|
||||
//! Quickly rotates & translates a vector, using the 4x3 part of a 4x4 matrix
|
||||
inline_ void TransformPoint4x3(Point& dest, const Point& source, const Matrix4x4& rot)
|
||||
{
|
||||
dest.x = rot.m[3][0] + source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0];
|
||||
dest.y = rot.m[3][1] + source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1];
|
||||
dest.z = rot.m[3][2] + source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2];
|
||||
}
|
||||
|
||||
//! Quickly rotates a vector, using the 3x3 part of a 4x4 matrix
|
||||
inline_ void TransformPoint3x3(Point& dest, const Point& source, const Matrix4x4& rot)
|
||||
{
|
||||
dest.x = source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0];
|
||||
dest.y = source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1];
|
||||
dest.z = source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2];
|
||||
}
|
||||
|
||||
ICEMATHS_API void InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src);
|
||||
|
||||
#endif // __ICEMATRIX4X4_H__
|
||||
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for 4x4 matrices.
|
||||
* \file IceMatrix4x4.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEMATRIX4X4_H__
|
||||
#define __ICEMATRIX4X4_H__
|
||||
|
||||
// Forward declarations
|
||||
class PRS;
|
||||
class PR;
|
||||
|
||||
#define MATRIX4X4_EPSILON (1.0e-7f)
|
||||
|
||||
class ICEMATHS_API Matrix4x4
|
||||
{
|
||||
// void LUBackwardSubstitution( sdword *indx, float* b );
|
||||
// void LUDecomposition( sdword* indx, float* d );
|
||||
|
||||
public:
|
||||
//! Empty constructor.
|
||||
inline_ Matrix4x4() {}
|
||||
//! Constructor from 16 values
|
||||
inline_ Matrix4x4( float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33)
|
||||
{
|
||||
m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03;
|
||||
m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13;
|
||||
m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23;
|
||||
m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33;
|
||||
}
|
||||
//! Copy constructor
|
||||
inline_ Matrix4x4(const Matrix4x4& mat) { CopyMemory(m, &mat.m, 16*sizeof(float)); }
|
||||
//! Destructor.
|
||||
inline_ ~Matrix4x4() {}
|
||||
|
||||
//! Assign values (rotation only)
|
||||
inline_ Matrix4x4& Set( float m00, float m01, float m02,
|
||||
float m10, float m11, float m12,
|
||||
float m20, float m21, float m22)
|
||||
{
|
||||
m[0][0] = m00; m[0][1] = m01; m[0][2] = m02;
|
||||
m[1][0] = m10; m[1][1] = m11; m[1][2] = m12;
|
||||
m[2][0] = m20; m[2][1] = m21; m[2][2] = m22;
|
||||
return *this;
|
||||
}
|
||||
//! Assign values
|
||||
inline_ Matrix4x4& Set( float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33)
|
||||
{
|
||||
m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03;
|
||||
m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13;
|
||||
m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23;
|
||||
m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Copy from a Matrix4x4
|
||||
inline_ void Copy(const Matrix4x4& source) { CopyMemory(m, source.m, 16*sizeof(float)); }
|
||||
|
||||
// Row-column access
|
||||
//! Returns a row.
|
||||
inline_ void GetRow(const udword r, HPoint& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; p.w=m[r][3]; }
|
||||
//! Returns a row.
|
||||
inline_ void GetRow(const udword r, Point& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; }
|
||||
//! Returns a row.
|
||||
inline_ const HPoint& GetRow(const udword r) const { return *(const HPoint*)&m[r][0]; }
|
||||
//! Returns a row.
|
||||
inline_ HPoint& GetRow(const udword r) { return *(HPoint*)&m[r][0]; }
|
||||
//! Sets a row.
|
||||
inline_ void SetRow(const udword r, const HPoint& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]=p.w; }
|
||||
//! Sets a row.
|
||||
inline_ void SetRow(const udword r, const Point& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]= (r!=3) ? 0.0f : 1.0f; }
|
||||
//! Returns a column.
|
||||
inline_ void GetCol(const udword c, HPoint& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; p.w=m[3][c]; }
|
||||
//! Returns a column.
|
||||
inline_ void GetCol(const udword c, Point& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; }
|
||||
//! Sets a column.
|
||||
inline_ void SetCol(const udword c, const HPoint& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]=p.w; }
|
||||
//! Sets a column.
|
||||
inline_ void SetCol(const udword c, const Point& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]= (c!=3) ? 0.0f : 1.0f; }
|
||||
|
||||
// Translation
|
||||
//! Returns the translation part of the matrix.
|
||||
inline_ const HPoint& GetTrans() const { return GetRow(3); }
|
||||
//! Gets the translation part of the matrix
|
||||
inline_ void GetTrans(Point& p) const { p.x=m[3][0]; p.y=m[3][1]; p.z=m[3][2]; }
|
||||
//! Sets the translation part of the matrix, from a Point.
|
||||
inline_ void SetTrans(const Point& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; }
|
||||
//! Sets the translation part of the matrix, from a HPoint.
|
||||
inline_ void SetTrans(const HPoint& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; m[3][3]=p.w; }
|
||||
//! Sets the translation part of the matrix, from floats.
|
||||
inline_ void SetTrans(float tx, float ty, float tz) { m[3][0]=tx; m[3][1]=ty; m[3][2]=tz; }
|
||||
|
||||
// Scale
|
||||
//! Sets the scale from a Point. The point is put on the diagonal.
|
||||
inline_ void SetScale(const Point& p) { m[0][0]=p.x; m[1][1]=p.y; m[2][2]=p.z; }
|
||||
//! Sets the scale from floats. Values are put on the diagonal.
|
||||
inline_ void SetScale(float sx, float sy, float sz) { m[0][0]=sx; m[1][1]=sy; m[2][2]=sz; }
|
||||
//! Scales from a Point. Each row is multiplied by a component.
|
||||
void Scale(const Point& p)
|
||||
{
|
||||
m[0][0] *= p.x; m[1][0] *= p.y; m[2][0] *= p.z;
|
||||
m[0][1] *= p.x; m[1][1] *= p.y; m[2][1] *= p.z;
|
||||
m[0][2] *= p.x; m[1][2] *= p.y; m[2][2] *= p.z;
|
||||
}
|
||||
//! Scales from floats. Each row is multiplied by a value.
|
||||
void Scale(float sx, float sy, float sz)
|
||||
{
|
||||
m[0][0] *= sx; m[1][0] *= sy; m[2][0] *= sz;
|
||||
m[0][1] *= sx; m[1][1] *= sy; m[2][1] *= sz;
|
||||
m[0][2] *= sx; m[1][2] *= sy; m[2][2] *= sz;
|
||||
}
|
||||
/*
|
||||
//! Returns a row.
|
||||
inline_ HPoint GetRow(const udword row) const { return mRow[row]; }
|
||||
//! Sets a row.
|
||||
inline_ Matrix4x4& SetRow(const udword row, const HPoint& p) { mRow[row] = p; return *this; }
|
||||
//! Sets a row.
|
||||
Matrix4x4& SetRow(const udword row, const Point& p)
|
||||
{
|
||||
m[row][0] = p.x;
|
||||
m[row][1] = p.y;
|
||||
m[row][2] = p.z;
|
||||
m[row][3] = (row != 3) ? 0.0f : 1.0f;
|
||||
return *this;
|
||||
}
|
||||
//! Returns a column.
|
||||
HPoint GetCol(const udword col) const
|
||||
{
|
||||
HPoint Res;
|
||||
Res.x = m[0][col];
|
||||
Res.y = m[1][col];
|
||||
Res.z = m[2][col];
|
||||
Res.w = m[3][col];
|
||||
return Res;
|
||||
}
|
||||
//! Sets a column.
|
||||
Matrix4x4& SetCol(const udword col, const HPoint& p)
|
||||
{
|
||||
m[0][col] = p.x;
|
||||
m[1][col] = p.y;
|
||||
m[2][col] = p.z;
|
||||
m[3][col] = p.w;
|
||||
return *this;
|
||||
}
|
||||
//! Sets a column.
|
||||
Matrix4x4& SetCol(const udword col, const Point& p)
|
||||
{
|
||||
m[0][col] = p.x;
|
||||
m[1][col] = p.y;
|
||||
m[2][col] = p.z;
|
||||
m[3][col] = (col != 3) ? 0.0f : 1.0f;
|
||||
return *this;
|
||||
}
|
||||
*/
|
||||
//! Computes the trace. The trace is the sum of the 4 diagonal components.
|
||||
inline_ float Trace() const { return m[0][0] + m[1][1] + m[2][2] + m[3][3]; }
|
||||
//! Computes the trace of the upper 3x3 matrix.
|
||||
inline_ float Trace3x3() const { return m[0][0] + m[1][1] + m[2][2]; }
|
||||
//! Clears the matrix.
|
||||
inline_ void Zero() { ZeroMemory(&m, sizeof(m)); }
|
||||
//! Sets the identity matrix.
|
||||
inline_ void Identity() { Zero(); m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f; }
|
||||
//! Checks for identity
|
||||
inline_ bool IsIdentity() const
|
||||
{
|
||||
if(IR(m[0][0])!=IEEE_1_0) return false;
|
||||
if(IR(m[0][1])!=0) return false;
|
||||
if(IR(m[0][2])!=0) return false;
|
||||
if(IR(m[0][3])!=0) return false;
|
||||
|
||||
if(IR(m[1][0])!=0) return false;
|
||||
if(IR(m[1][1])!=IEEE_1_0) return false;
|
||||
if(IR(m[1][2])!=0) return false;
|
||||
if(IR(m[1][3])!=0) return false;
|
||||
|
||||
if(IR(m[2][0])!=0) return false;
|
||||
if(IR(m[2][1])!=0) return false;
|
||||
if(IR(m[2][2])!=IEEE_1_0) return false;
|
||||
if(IR(m[2][3])!=0) return false;
|
||||
|
||||
if(IR(m[3][0])!=0) return false;
|
||||
if(IR(m[3][1])!=0) return false;
|
||||
if(IR(m[3][2])!=0) return false;
|
||||
if(IR(m[3][3])!=IEEE_1_0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Checks matrix validity
|
||||
inline_ BOOL IsValid() const
|
||||
{
|
||||
for(udword j=0;j<4;j++)
|
||||
{
|
||||
for(udword i=0;i<4;i++)
|
||||
{
|
||||
if(!IsValidFloat(m[j][i])) return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//! Sets a rotation matrix around the X axis.
|
||||
void RotX(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[1][1] = m[2][2] = Cos; m[2][1] = -Sin; m[1][2] = Sin; }
|
||||
//! Sets a rotation matrix around the Y axis.
|
||||
void RotY(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[2][2] = Cos; m[2][0] = Sin; m[0][2] = -Sin; }
|
||||
//! Sets a rotation matrix around the Z axis.
|
||||
void RotZ(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[1][1] = Cos; m[1][0] = -Sin; m[0][1] = Sin; }
|
||||
|
||||
//! Makes a rotation matrix about an arbitrary axis
|
||||
Matrix4x4& Rot(float angle, Point& p1, Point& p2);
|
||||
|
||||
//! Transposes the matrix.
|
||||
void Transpose()
|
||||
{
|
||||
IR(m[1][0]) ^= IR(m[0][1]); IR(m[0][1]) ^= IR(m[1][0]); IR(m[1][0]) ^= IR(m[0][1]);
|
||||
IR(m[2][0]) ^= IR(m[0][2]); IR(m[0][2]) ^= IR(m[2][0]); IR(m[2][0]) ^= IR(m[0][2]);
|
||||
IR(m[3][0]) ^= IR(m[0][3]); IR(m[0][3]) ^= IR(m[3][0]); IR(m[3][0]) ^= IR(m[0][3]);
|
||||
IR(m[1][2]) ^= IR(m[2][1]); IR(m[2][1]) ^= IR(m[1][2]); IR(m[1][2]) ^= IR(m[2][1]);
|
||||
IR(m[1][3]) ^= IR(m[3][1]); IR(m[3][1]) ^= IR(m[1][3]); IR(m[1][3]) ^= IR(m[3][1]);
|
||||
IR(m[2][3]) ^= IR(m[3][2]); IR(m[3][2]) ^= IR(m[2][3]); IR(m[2][3]) ^= IR(m[3][2]);
|
||||
}
|
||||
|
||||
//! Computes a cofactor. Used for matrix inversion.
|
||||
float CoFactor(udword row, udword col) const;
|
||||
//! Computes the determinant of the matrix.
|
||||
float Determinant() const;
|
||||
//! Inverts the matrix. Determinant must be different from zero, else matrix can't be inverted.
|
||||
Matrix4x4& Invert();
|
||||
// Matrix& ComputeAxisMatrix(Point& axis, float angle);
|
||||
|
||||
// Cast operators
|
||||
//! Casts a Matrix4x4 to a Matrix3x3.
|
||||
inline_ operator Matrix3x3() const
|
||||
{
|
||||
return Matrix3x3(
|
||||
m[0][0], m[0][1], m[0][2],
|
||||
m[1][0], m[1][1], m[1][2],
|
||||
m[2][0], m[2][1], m[2][2]);
|
||||
}
|
||||
//! Casts a Matrix4x4 to a Quat.
|
||||
operator Quat() const;
|
||||
//! Casts a Matrix4x4 to a PR.
|
||||
operator PR() const;
|
||||
|
||||
// Arithmetic operators
|
||||
//! Operator for Matrix4x4 Plus = Matrix4x4 + Matrix4x4;
|
||||
inline_ Matrix4x4 operator+(const Matrix4x4& mat) const
|
||||
{
|
||||
return Matrix4x4(
|
||||
m[0][0]+mat.m[0][0], m[0][1]+mat.m[0][1], m[0][2]+mat.m[0][2], m[0][3]+mat.m[0][3],
|
||||
m[1][0]+mat.m[1][0], m[1][1]+mat.m[1][1], m[1][2]+mat.m[1][2], m[1][3]+mat.m[1][3],
|
||||
m[2][0]+mat.m[2][0], m[2][1]+mat.m[2][1], m[2][2]+mat.m[2][2], m[2][3]+mat.m[2][3],
|
||||
m[3][0]+mat.m[3][0], m[3][1]+mat.m[3][1], m[3][2]+mat.m[3][2], m[3][3]+mat.m[3][3]);
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 Minus = Matrix4x4 - Matrix4x4;
|
||||
inline_ Matrix4x4 operator-(const Matrix4x4& mat) const
|
||||
{
|
||||
return Matrix4x4(
|
||||
m[0][0]-mat.m[0][0], m[0][1]-mat.m[0][1], m[0][2]-mat.m[0][2], m[0][3]-mat.m[0][3],
|
||||
m[1][0]-mat.m[1][0], m[1][1]-mat.m[1][1], m[1][2]-mat.m[1][2], m[1][3]-mat.m[1][3],
|
||||
m[2][0]-mat.m[2][0], m[2][1]-mat.m[2][1], m[2][2]-mat.m[2][2], m[2][3]-mat.m[2][3],
|
||||
m[3][0]-mat.m[3][0], m[3][1]-mat.m[3][1], m[3][2]-mat.m[3][2], m[3][3]-mat.m[3][3]);
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 Mul = Matrix4x4 * Matrix4x4;
|
||||
inline_ Matrix4x4 operator*(const Matrix4x4& mat) const
|
||||
{
|
||||
return Matrix4x4(
|
||||
m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0] + m[0][3]*mat.m[3][0],
|
||||
m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1] + m[0][3]*mat.m[3][1],
|
||||
m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2] + m[0][3]*mat.m[3][2],
|
||||
m[0][0]*mat.m[0][3] + m[0][1]*mat.m[1][3] + m[0][2]*mat.m[2][3] + m[0][3]*mat.m[3][3],
|
||||
|
||||
m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0] + m[1][3]*mat.m[3][0],
|
||||
m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1] + m[1][3]*mat.m[3][1],
|
||||
m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2] + m[1][3]*mat.m[3][2],
|
||||
m[1][0]*mat.m[0][3] + m[1][1]*mat.m[1][3] + m[1][2]*mat.m[2][3] + m[1][3]*mat.m[3][3],
|
||||
|
||||
m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0] + m[2][3]*mat.m[3][0],
|
||||
m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1] + m[2][3]*mat.m[3][1],
|
||||
m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2] + m[2][3]*mat.m[3][2],
|
||||
m[2][0]*mat.m[0][3] + m[2][1]*mat.m[1][3] + m[2][2]*mat.m[2][3] + m[2][3]*mat.m[3][3],
|
||||
|
||||
m[3][0]*mat.m[0][0] + m[3][1]*mat.m[1][0] + m[3][2]*mat.m[2][0] + m[3][3]*mat.m[3][0],
|
||||
m[3][0]*mat.m[0][1] + m[3][1]*mat.m[1][1] + m[3][2]*mat.m[2][1] + m[3][3]*mat.m[3][1],
|
||||
m[3][0]*mat.m[0][2] + m[3][1]*mat.m[1][2] + m[3][2]*mat.m[2][2] + m[3][3]*mat.m[3][2],
|
||||
m[3][0]*mat.m[0][3] + m[3][1]*mat.m[1][3] + m[3][2]*mat.m[2][3] + m[3][3]*mat.m[3][3]);
|
||||
}
|
||||
|
||||
//! Operator for HPoint Mul = Matrix4x4 * HPoint;
|
||||
inline_ HPoint operator*(const HPoint& v) const { return HPoint(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v, GetRow(3)|v); }
|
||||
|
||||
//! Operator for Point Mul = Matrix4x4 * Point;
|
||||
inline_ Point operator*(const Point& v) const
|
||||
{
|
||||
return Point( m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3],
|
||||
m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3],
|
||||
m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3] );
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 Scale = Matrix4x4 * float;
|
||||
inline_ Matrix4x4 operator*(float s) const
|
||||
{
|
||||
return Matrix4x4(
|
||||
m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s,
|
||||
m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s,
|
||||
m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s,
|
||||
m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s);
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 Scale = float * Matrix4x4;
|
||||
inline_ friend Matrix4x4 operator*(float s, const Matrix4x4& mat)
|
||||
{
|
||||
return Matrix4x4(
|
||||
s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2], s*mat.m[0][3],
|
||||
s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2], s*mat.m[1][3],
|
||||
s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2], s*mat.m[2][3],
|
||||
s*mat.m[3][0], s*mat.m[3][1], s*mat.m[3][2], s*mat.m[3][3]);
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 Div = Matrix4x4 / float;
|
||||
inline_ Matrix4x4 operator/(float s) const
|
||||
{
|
||||
if(s) s = 1.0f / s;
|
||||
|
||||
return Matrix4x4(
|
||||
m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s,
|
||||
m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s,
|
||||
m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s,
|
||||
m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s);
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 Div = float / Matrix4x4;
|
||||
inline_ friend Matrix4x4 operator/(float s, const Matrix4x4& mat)
|
||||
{
|
||||
return Matrix4x4(
|
||||
s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2], s/mat.m[0][3],
|
||||
s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2], s/mat.m[1][3],
|
||||
s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2], s/mat.m[2][3],
|
||||
s/mat.m[3][0], s/mat.m[3][1], s/mat.m[3][2], s/mat.m[3][3]);
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 += Matrix4x4;
|
||||
inline_ Matrix4x4& operator+=(const Matrix4x4& mat)
|
||||
{
|
||||
m[0][0]+=mat.m[0][0]; m[0][1]+=mat.m[0][1]; m[0][2]+=mat.m[0][2]; m[0][3]+=mat.m[0][3];
|
||||
m[1][0]+=mat.m[1][0]; m[1][1]+=mat.m[1][1]; m[1][2]+=mat.m[1][2]; m[1][3]+=mat.m[1][3];
|
||||
m[2][0]+=mat.m[2][0]; m[2][1]+=mat.m[2][1]; m[2][2]+=mat.m[2][2]; m[2][3]+=mat.m[2][3];
|
||||
m[3][0]+=mat.m[3][0]; m[3][1]+=mat.m[3][1]; m[3][2]+=mat.m[3][2]; m[3][3]+=mat.m[3][3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 -= Matrix4x4;
|
||||
inline_ Matrix4x4& operator-=(const Matrix4x4& mat)
|
||||
{
|
||||
m[0][0]-=mat.m[0][0]; m[0][1]-=mat.m[0][1]; m[0][2]-=mat.m[0][2]; m[0][3]-=mat.m[0][3];
|
||||
m[1][0]-=mat.m[1][0]; m[1][1]-=mat.m[1][1]; m[1][2]-=mat.m[1][2]; m[1][3]-=mat.m[1][3];
|
||||
m[2][0]-=mat.m[2][0]; m[2][1]-=mat.m[2][1]; m[2][2]-=mat.m[2][2]; m[2][3]-=mat.m[2][3];
|
||||
m[3][0]-=mat.m[3][0]; m[3][1]-=mat.m[3][1]; m[3][2]-=mat.m[3][2]; m[3][3]-=mat.m[3][3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 *= Matrix4x4;
|
||||
Matrix4x4& operator*=(const Matrix4x4& mat)
|
||||
{
|
||||
HPoint TempRow;
|
||||
|
||||
GetRow(0, TempRow);
|
||||
m[0][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0];
|
||||
m[0][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1];
|
||||
m[0][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2];
|
||||
m[0][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3];
|
||||
|
||||
GetRow(1, TempRow);
|
||||
m[1][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0];
|
||||
m[1][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1];
|
||||
m[1][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2];
|
||||
m[1][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3];
|
||||
|
||||
GetRow(2, TempRow);
|
||||
m[2][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0];
|
||||
m[2][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1];
|
||||
m[2][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2];
|
||||
m[2][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3];
|
||||
|
||||
GetRow(3, TempRow);
|
||||
m[3][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0];
|
||||
m[3][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1];
|
||||
m[3][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2];
|
||||
m[3][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 *= float;
|
||||
inline_ Matrix4x4& operator*=(float s)
|
||||
{
|
||||
m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s;
|
||||
m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s;
|
||||
m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s;
|
||||
m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Operator for Matrix4x4 /= float;
|
||||
inline_ Matrix4x4& operator/=(float s)
|
||||
{
|
||||
if(s) s = 1.0f / s;
|
||||
m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s;
|
||||
m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s;
|
||||
m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s;
|
||||
m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline_ const HPoint& operator[](int row) const { return *(const HPoint*)&m[row][0]; }
|
||||
inline_ HPoint& operator[](int row) { return *(HPoint*)&m[row][0]; }
|
||||
|
||||
public:
|
||||
|
||||
float m[4][4];
|
||||
};
|
||||
|
||||
//! Quickly rotates & translates a vector, using the 4x3 part of a 4x4 matrix
|
||||
inline_ void TransformPoint4x3(Point& dest, const Point& source, const Matrix4x4& rot)
|
||||
{
|
||||
dest.x = rot.m[3][0] + source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0];
|
||||
dest.y = rot.m[3][1] + source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1];
|
||||
dest.z = rot.m[3][2] + source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2];
|
||||
}
|
||||
|
||||
//! Quickly rotates a vector, using the 3x3 part of a 4x4 matrix
|
||||
inline_ void TransformPoint3x3(Point& dest, const Point& source, const Matrix4x4& rot)
|
||||
{
|
||||
dest.x = source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0];
|
||||
dest.y = source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1];
|
||||
dest.z = source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2];
|
||||
}
|
||||
|
||||
ICEMATHS_API void InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src);
|
||||
|
||||
#endif // __ICEMATRIX4X4_H__
|
||||
|
||||
|
||||
@@ -1,180 +1,180 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains all memory macros.
|
||||
* \file IceMemoryMacros.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEMEMORYMACROS_H
|
||||
#define ICEMEMORYMACROS_H
|
||||
|
||||
#undef ZeroMemory
|
||||
#undef CopyMemory
|
||||
#undef MoveMemory
|
||||
#undef FillMemory
|
||||
|
||||
//! Clears a buffer.
|
||||
//! \param addr [in] buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \see FillMemory
|
||||
//! \see StoreDwords
|
||||
//! \see CopyMemory
|
||||
//! \see MoveMemory
|
||||
inline_ void ZeroMemory(void* addr, regsize size) { memset(addr, 0, size); }
|
||||
|
||||
//! Fills a buffer with a given byte.
|
||||
//! \param addr [in] buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \param val [in] the byte value
|
||||
//! \see StoreDwords
|
||||
//! \see ZeroMemory
|
||||
//! \see CopyMemory
|
||||
//! \see MoveMemory
|
||||
inline_ void FillMemory(void* dest, regsize size, ubyte val) { memset(dest, val, size); }
|
||||
|
||||
//! Fills a buffer with a given dword.
|
||||
//! \param addr [in] buffer address
|
||||
//! \param nb [in] number of dwords to write
|
||||
//! \param value [in] the dword value
|
||||
//! \see FillMemory
|
||||
//! \see ZeroMemory
|
||||
//! \see CopyMemory
|
||||
//! \see MoveMemory
|
||||
//! \warning writes nb*4 bytes !
|
||||
inline_ void StoreDwords(udword* dest, udword nb, udword value)
|
||||
{
|
||||
// The asm code below **SHOULD** be equivalent to one of those C versions
|
||||
// or the other if your compiled is good: (checked on VC++ 6.0)
|
||||
//
|
||||
// 1) while(nb--) *dest++ = value;
|
||||
//
|
||||
// 2) for(udword i=0;i<nb;i++) dest[i] = value;
|
||||
//
|
||||
_asm push eax
|
||||
_asm push ecx
|
||||
_asm push edi
|
||||
_asm mov edi, dest
|
||||
_asm mov ecx, nb
|
||||
_asm mov eax, value
|
||||
_asm rep stosd
|
||||
_asm pop edi
|
||||
_asm pop ecx
|
||||
_asm pop eax
|
||||
}
|
||||
|
||||
//! Copies a buffer.
|
||||
//! \param addr [in] destination buffer address
|
||||
//! \param addr [in] source buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \see ZeroMemory
|
||||
//! \see FillMemory
|
||||
//! \see StoreDwords
|
||||
//! \see MoveMemory
|
||||
inline_ void CopyMemory(void* dest, const void* src, regsize size) { memcpy(dest, src, size); }
|
||||
|
||||
//! Moves a buffer.
|
||||
//! \param addr [in] destination buffer address
|
||||
//! \param addr [in] source buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \see ZeroMemory
|
||||
//! \see FillMemory
|
||||
//! \see StoreDwords
|
||||
//! \see CopyMemory
|
||||
inline_ void MoveMemory(void* dest, const void* src, regsize size) { memmove(dest, src, size); }
|
||||
|
||||
//! Flexible buffer copy
|
||||
//! \param src [in] source buffer address
|
||||
//! \param dst [in] destination buffer address
|
||||
//! \param nb_elem [in] number of elements to copy
|
||||
//! \param elem_size [in] size of an element
|
||||
//! \param stride [in] stride in bytes, including size of element
|
||||
inline_ void FlexiCopy(const void* src, void* dst, udword nb_elem, regsize elem_size, udword stride)
|
||||
{
|
||||
ubyte* d = (ubyte*)dst;
|
||||
const ubyte* s = (const ubyte*)src;
|
||||
const ubyte* Last = s + stride*nb_elem;
|
||||
while(s!=Last)
|
||||
{
|
||||
CopyMemory(d, s, elem_size);
|
||||
d += elem_size;
|
||||
s += stride;
|
||||
}
|
||||
}
|
||||
|
||||
//! Gives the size of current object. This avoids some mistakes (e.g. "sizeof(this)").
|
||||
#define SIZEOFOBJECT sizeof(*this)
|
||||
|
||||
//! Clears current object. Laziness is my business! HANDLE WITH CARE. ### Removed, too dangerous, cleared too many v-tables
|
||||
//#define CLEAROBJECT { memset(this, 0, SIZEOFOBJECT); }
|
||||
|
||||
// The two macros below are here for several reasons:
|
||||
// - sometimes we write "delete x" instead of "delete []x" just because we don't pay attention. Using the macro forces you
|
||||
// to think about what you're deleting, just because you have to write the macro's name (SINGLE or ARRAY).
|
||||
// - always clearing the pointer afterwards prevents some double-deletion in various situations.
|
||||
// - deleting null is a valid operation according to the standard, yet some lame memory managers don't like it. In sake of
|
||||
// robustness, we avoid trying.
|
||||
|
||||
//! Deletes an instance of a class.
|
||||
#define DELETESINGLE(x) if (x) { delete x; x = null; }
|
||||
//! Deletes an array.
|
||||
#define DELETEARRAY(x) if (x) { delete []x; x = null; }
|
||||
|
||||
//! Safe D3D-style release
|
||||
#define SAFE_RELEASE(x) if (x) { (x)->Release(); (x) = null; }
|
||||
|
||||
//! Safe ICE-style release
|
||||
#define SAFE_DESTRUCT(x) if (x) { (x)->SelfDestruct(); (x) = null; }
|
||||
|
||||
#ifdef ICEERROR_H
|
||||
//! Standard alloc checking. HANDLE WITH CARE. Relies on strict coding rules. Probably shouldn't be used outside of ICE.
|
||||
#define CHECKALLOC(x) if(!x) return SetIceError("Out of memory.", EC_OUT_OF_MEMORY);
|
||||
#else
|
||||
#define CHECKALLOC(x) if(!x) return false;
|
||||
#endif
|
||||
|
||||
//! Standard allocation cycle
|
||||
#define SAFE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = new type[count]; CHECKALLOC(ptr);
|
||||
#define SAFE_ICE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = ICE_NEW(type)[count]; CHECKALLOC(ptr);
|
||||
|
||||
//! Don't use inline for alloca !!!
|
||||
#ifdef WIN32
|
||||
#define StackAlloc(x) _alloca(x)
|
||||
#elif LINUX
|
||||
#define StackAlloc(x) alloca(x)
|
||||
#elif defined(__APPLE__)
|
||||
#define StackAlloc(x) alloca(x)
|
||||
#elif defined(_XBOX)
|
||||
#define StackAlloc(x) _alloca(x)
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
// #define ICE_ALLOC_TMP(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #x, MEMORY_TEMP)
|
||||
// #define ICE_ALLOC(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #x, MEMORY_PERSISTENT)
|
||||
#define ICE_ALLOC_TMP(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, "(undefined)", MEMORY_TEMP)
|
||||
#define ICE_ALLOC(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, "(undefined)", MEMORY_PERSISTENT)
|
||||
#define ICE_ALLOC_TMP2(x, y) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #y, MEMORY_TEMP)
|
||||
#define ICE_ALLOC2(x, y) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #y, MEMORY_PERSISTENT)
|
||||
#else
|
||||
#define ICE_ALLOC_TMP(x) GetAllocator()->malloc(x, MEMORY_TEMP)
|
||||
#define ICE_ALLOC(x) GetAllocator()->malloc(x, MEMORY_PERSISTENT)
|
||||
#endif
|
||||
#define ICE_FREE(x) if(x) { GetAllocator()->free(x); x = null; }
|
||||
|
||||
#ifdef DONT_TRACK_MEMORY_LEAKS
|
||||
#ifdef _DEBUG
|
||||
#define ICE_NEW_TMP(x) new(__FILE__, __LINE__, #x, MEMORY_TEMP) x
|
||||
#define ICE_NEW(x) new(__FILE__, __LINE__, #x, MEMORY_PERSISTENT) x
|
||||
#else
|
||||
#define ICE_NEW_TMP(x) new(MEMORY_TEMP) x
|
||||
#define ICE_NEW(x) new(MEMORY_PERSISTENT) x
|
||||
#endif
|
||||
#else
|
||||
#define ICE_NEW_TMP(x) new x
|
||||
#define ICE_NEW(x) new x
|
||||
#endif
|
||||
|
||||
#endif // ICEMEMORYMACROS_H
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains all memory macros.
|
||||
* \file IceMemoryMacros.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEMEMORYMACROS_H
|
||||
#define ICEMEMORYMACROS_H
|
||||
|
||||
#undef ZeroMemory
|
||||
#undef CopyMemory
|
||||
#undef MoveMemory
|
||||
#undef FillMemory
|
||||
|
||||
//! Clears a buffer.
|
||||
//! \param addr [in] buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \see FillMemory
|
||||
//! \see StoreDwords
|
||||
//! \see CopyMemory
|
||||
//! \see MoveMemory
|
||||
inline_ void ZeroMemory(void* addr, regsize size) { memset(addr, 0, size); }
|
||||
|
||||
//! Fills a buffer with a given byte.
|
||||
//! \param addr [in] buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \param val [in] the byte value
|
||||
//! \see StoreDwords
|
||||
//! \see ZeroMemory
|
||||
//! \see CopyMemory
|
||||
//! \see MoveMemory
|
||||
inline_ void FillMemory(void* dest, regsize size, ubyte val) { memset(dest, val, size); }
|
||||
|
||||
//! Fills a buffer with a given dword.
|
||||
//! \param addr [in] buffer address
|
||||
//! \param nb [in] number of dwords to write
|
||||
//! \param value [in] the dword value
|
||||
//! \see FillMemory
|
||||
//! \see ZeroMemory
|
||||
//! \see CopyMemory
|
||||
//! \see MoveMemory
|
||||
//! \warning writes nb*4 bytes !
|
||||
inline_ void StoreDwords(udword* dest, udword nb, udword value)
|
||||
{
|
||||
// The asm code below **SHOULD** be equivalent to one of those C versions
|
||||
// or the other if your compiled is good: (checked on VC++ 6.0)
|
||||
//
|
||||
// 1) while(nb--) *dest++ = value;
|
||||
//
|
||||
// 2) for(udword i=0;i<nb;i++) dest[i] = value;
|
||||
//
|
||||
_asm push eax
|
||||
_asm push ecx
|
||||
_asm push edi
|
||||
_asm mov edi, dest
|
||||
_asm mov ecx, nb
|
||||
_asm mov eax, value
|
||||
_asm rep stosd
|
||||
_asm pop edi
|
||||
_asm pop ecx
|
||||
_asm pop eax
|
||||
}
|
||||
|
||||
//! Copies a buffer.
|
||||
//! \param addr [in] destination buffer address
|
||||
//! \param addr [in] source buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \see ZeroMemory
|
||||
//! \see FillMemory
|
||||
//! \see StoreDwords
|
||||
//! \see MoveMemory
|
||||
inline_ void CopyMemory(void* dest, const void* src, regsize size) { memcpy(dest, src, size); }
|
||||
|
||||
//! Moves a buffer.
|
||||
//! \param addr [in] destination buffer address
|
||||
//! \param addr [in] source buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \see ZeroMemory
|
||||
//! \see FillMemory
|
||||
//! \see StoreDwords
|
||||
//! \see CopyMemory
|
||||
inline_ void MoveMemory(void* dest, const void* src, regsize size) { memmove(dest, src, size); }
|
||||
|
||||
//! Flexible buffer copy
|
||||
//! \param src [in] source buffer address
|
||||
//! \param dst [in] destination buffer address
|
||||
//! \param nb_elem [in] number of elements to copy
|
||||
//! \param elem_size [in] size of an element
|
||||
//! \param stride [in] stride in bytes, including size of element
|
||||
inline_ void FlexiCopy(const void* src, void* dst, udword nb_elem, regsize elem_size, udword stride)
|
||||
{
|
||||
ubyte* d = (ubyte*)dst;
|
||||
const ubyte* s = (const ubyte*)src;
|
||||
const ubyte* Last = s + stride*nb_elem;
|
||||
while(s!=Last)
|
||||
{
|
||||
CopyMemory(d, s, elem_size);
|
||||
d += elem_size;
|
||||
s += stride;
|
||||
}
|
||||
}
|
||||
|
||||
//! Gives the size of current object. This avoids some mistakes (e.g. "sizeof(this)").
|
||||
#define SIZEOFOBJECT sizeof(*this)
|
||||
|
||||
//! Clears current object. Laziness is my business! HANDLE WITH CARE. ### Removed, too dangerous, cleared too many v-tables
|
||||
//#define CLEAROBJECT { memset(this, 0, SIZEOFOBJECT); }
|
||||
|
||||
// The two macros below are here for several reasons:
|
||||
// - sometimes we write "delete x" instead of "delete []x" just because we don't pay attention. Using the macro forces you
|
||||
// to think about what you're deleting, just because you have to write the macro's name (SINGLE or ARRAY).
|
||||
// - always clearing the pointer afterwards prevents some double-deletion in various situations.
|
||||
// - deleting null is a valid operation according to the standard, yet some lame memory managers don't like it. In sake of
|
||||
// robustness, we avoid trying.
|
||||
|
||||
//! Deletes an instance of a class.
|
||||
#define DELETESINGLE(x) if (x) { delete x; x = null; }
|
||||
//! Deletes an array.
|
||||
#define DELETEARRAY(x) if (x) { delete []x; x = null; }
|
||||
|
||||
//! Safe D3D-style release
|
||||
#define SAFE_RELEASE(x) if (x) { (x)->Release(); (x) = null; }
|
||||
|
||||
//! Safe ICE-style release
|
||||
#define SAFE_DESTRUCT(x) if (x) { (x)->SelfDestruct(); (x) = null; }
|
||||
|
||||
#ifdef ICEERROR_H
|
||||
//! Standard alloc checking. HANDLE WITH CARE. Relies on strict coding rules. Probably shouldn't be used outside of ICE.
|
||||
#define CHECKALLOC(x) if(!x) return SetIceError("Out of memory.", EC_OUT_OF_MEMORY);
|
||||
#else
|
||||
#define CHECKALLOC(x) if(!x) return false;
|
||||
#endif
|
||||
|
||||
//! Standard allocation cycle
|
||||
#define SAFE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = new type[count]; CHECKALLOC(ptr);
|
||||
#define SAFE_ICE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = ICE_NEW(type)[count]; CHECKALLOC(ptr);
|
||||
|
||||
//! Don't use inline for alloca !!!
|
||||
#ifdef WIN32
|
||||
#define StackAlloc(x) _alloca(x)
|
||||
#elif LINUX
|
||||
#define StackAlloc(x) alloca(x)
|
||||
#elif defined(__APPLE__)
|
||||
#define StackAlloc(x) alloca(x)
|
||||
#elif defined(_XBOX)
|
||||
#define StackAlloc(x) _alloca(x)
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
// #define ICE_ALLOC_TMP(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #x, MEMORY_TEMP)
|
||||
// #define ICE_ALLOC(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #x, MEMORY_PERSISTENT)
|
||||
#define ICE_ALLOC_TMP(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, "(undefined)", MEMORY_TEMP)
|
||||
#define ICE_ALLOC(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, "(undefined)", MEMORY_PERSISTENT)
|
||||
#define ICE_ALLOC_TMP2(x, y) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #y, MEMORY_TEMP)
|
||||
#define ICE_ALLOC2(x, y) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #y, MEMORY_PERSISTENT)
|
||||
#else
|
||||
#define ICE_ALLOC_TMP(x) GetAllocator()->malloc(x, MEMORY_TEMP)
|
||||
#define ICE_ALLOC(x) GetAllocator()->malloc(x, MEMORY_PERSISTENT)
|
||||
#endif
|
||||
#define ICE_FREE(x) if(x) { GetAllocator()->free(x); x = null; }
|
||||
|
||||
#ifdef DONT_TRACK_MEMORY_LEAKS
|
||||
#ifdef _DEBUG
|
||||
#define ICE_NEW_TMP(x) new(__FILE__, __LINE__, #x, MEMORY_TEMP) x
|
||||
#define ICE_NEW(x) new(__FILE__, __LINE__, #x, MEMORY_PERSISTENT) x
|
||||
#else
|
||||
#define ICE_NEW_TMP(x) new(MEMORY_TEMP) x
|
||||
#define ICE_NEW(x) new(MEMORY_PERSISTENT) x
|
||||
#endif
|
||||
#else
|
||||
#define ICE_NEW_TMP(x) new x
|
||||
#define ICE_NEW(x) new x
|
||||
#endif
|
||||
|
||||
#endif // ICEMEMORYMACROS_H
|
||||
|
||||
@@ -1,339 +1,339 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains OBB-related code.
|
||||
* \file IceOBB.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 29, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* An Oriented Bounding Box (OBB).
|
||||
* \class OBB
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a point is contained within the OBB.
|
||||
* \param p [in] the world point to test
|
||||
* \return true if inside the OBB
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool OBB::ContainsPoint(const Point& p) const
|
||||
{
|
||||
// Point in OBB test using lazy evaluation and early exits
|
||||
|
||||
// Translate to box space
|
||||
Point RelPoint = p - mCenter;
|
||||
|
||||
// Point * mRot maps from box space to world space
|
||||
// mRot * Point maps from world space to box space (what we need here)
|
||||
|
||||
float f = mRot.m[0][0] * RelPoint.x + mRot.m[0][1] * RelPoint.y + mRot.m[0][2] * RelPoint.z;
|
||||
if(f >= mExtents.x || f <= -mExtents.x) return false;
|
||||
|
||||
f = mRot.m[1][0] * RelPoint.x + mRot.m[1][1] * RelPoint.y + mRot.m[1][2] * RelPoint.z;
|
||||
if(f >= mExtents.y || f <= -mExtents.y) return false;
|
||||
|
||||
f = mRot.m[2][0] * RelPoint.x + mRot.m[2][1] * RelPoint.y + mRot.m[2][2] * RelPoint.z;
|
||||
if(f >= mExtents.z || f <= -mExtents.z) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Builds an OBB from an AABB and a world transform.
|
||||
* \param aabb [in] the aabb
|
||||
* \param mat [in] the world transform
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void OBB::Create(const AABB& aabb, const Matrix4x4& mat)
|
||||
{
|
||||
// Note: must be coherent with Rotate()
|
||||
|
||||
aabb.GetCenter(mCenter);
|
||||
aabb.GetExtents(mExtents);
|
||||
// Here we have the same as OBB::Rotate(mat) where the obb is (mCenter, mExtents, Identity).
|
||||
|
||||
// So following what's done in Rotate:
|
||||
// - x-form the center
|
||||
mCenter *= mat;
|
||||
// - combine rotation with identity, i.e. just use given matrix
|
||||
mRot = mat;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the obb planes.
|
||||
* \param planes [out] 6 box planes
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool OBB::ComputePlanes(Plane* planes) const
|
||||
{
|
||||
// Checkings
|
||||
if(!planes) return false;
|
||||
|
||||
Point Axis0 = mRot[0];
|
||||
Point Axis1 = mRot[1];
|
||||
Point Axis2 = mRot[2];
|
||||
|
||||
// Writes normals
|
||||
planes[0].n = Axis0;
|
||||
planes[1].n = -Axis0;
|
||||
planes[2].n = Axis1;
|
||||
planes[3].n = -Axis1;
|
||||
planes[4].n = Axis2;
|
||||
planes[5].n = -Axis2;
|
||||
|
||||
// Compute a point on each plane
|
||||
Point p0 = mCenter + Axis0 * mExtents.x;
|
||||
Point p1 = mCenter - Axis0 * mExtents.x;
|
||||
Point p2 = mCenter + Axis1 * mExtents.y;
|
||||
Point p3 = mCenter - Axis1 * mExtents.y;
|
||||
Point p4 = mCenter + Axis2 * mExtents.z;
|
||||
Point p5 = mCenter - Axis2 * mExtents.z;
|
||||
|
||||
// Compute d
|
||||
planes[0].d = -(planes[0].n|p0);
|
||||
planes[1].d = -(planes[1].n|p1);
|
||||
planes[2].d = -(planes[2].n|p2);
|
||||
planes[3].d = -(planes[3].n|p3);
|
||||
planes[4].d = -(planes[4].n|p4);
|
||||
planes[5].d = -(planes[5].n|p5);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the obb points.
|
||||
* \param pts [out] 8 box points
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool OBB::ComputePoints(Point* pts) const
|
||||
{
|
||||
// Checkings
|
||||
if(!pts) return false;
|
||||
|
||||
Point Axis0 = mRot[0];
|
||||
Point Axis1 = mRot[1];
|
||||
Point Axis2 = mRot[2];
|
||||
|
||||
Axis0 *= mExtents.x;
|
||||
Axis1 *= mExtents.y;
|
||||
Axis2 *= mExtents.z;
|
||||
|
||||
// 7+------+6 0 = ---
|
||||
// /| /| 1 = +--
|
||||
// / | / | 2 = ++-
|
||||
// / 4+---/--+5 3 = -+-
|
||||
// 3+------+2 / y z 4 = --+
|
||||
// | / | / | / 5 = +-+
|
||||
// |/ |/ |/ 6 = +++
|
||||
// 0+------+1 *---x 7 = -++
|
||||
|
||||
pts[0] = mCenter - Axis0 - Axis1 - Axis2;
|
||||
pts[1] = mCenter + Axis0 - Axis1 - Axis2;
|
||||
pts[2] = mCenter + Axis0 + Axis1 - Axis2;
|
||||
pts[3] = mCenter - Axis0 + Axis1 - Axis2;
|
||||
pts[4] = mCenter - Axis0 - Axis1 + Axis2;
|
||||
pts[5] = mCenter + Axis0 - Axis1 + Axis2;
|
||||
pts[6] = mCenter + Axis0 + Axis1 + Axis2;
|
||||
pts[7] = mCenter - Axis0 + Axis1 + Axis2;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes vertex normals.
|
||||
* \param pts [out] 8 box points
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool OBB::ComputeVertexNormals(Point* pts) const
|
||||
{
|
||||
static float VertexNormals[] =
|
||||
{
|
||||
-INVSQRT3, -INVSQRT3, -INVSQRT3,
|
||||
INVSQRT3, -INVSQRT3, -INVSQRT3,
|
||||
INVSQRT3, INVSQRT3, -INVSQRT3,
|
||||
-INVSQRT3, INVSQRT3, -INVSQRT3,
|
||||
-INVSQRT3, -INVSQRT3, INVSQRT3,
|
||||
INVSQRT3, -INVSQRT3, INVSQRT3,
|
||||
INVSQRT3, INVSQRT3, INVSQRT3,
|
||||
-INVSQRT3, INVSQRT3, INVSQRT3
|
||||
};
|
||||
|
||||
if(!pts) return false;
|
||||
|
||||
const Point* VN = (const Point*)VertexNormals;
|
||||
for(udword i=0;i<8;i++)
|
||||
{
|
||||
pts[i] = VN[i] * mRot;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns edges.
|
||||
* \return 24 indices (12 edges) indexing the list returned by ComputePoints()
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const udword* OBB::GetEdges() const
|
||||
{
|
||||
static udword Indices[] = {
|
||||
0, 1, 1, 2, 2, 3, 3, 0,
|
||||
7, 6, 6, 5, 5, 4, 4, 7,
|
||||
1, 5, 6, 2,
|
||||
3, 7, 4, 0
|
||||
};
|
||||
return Indices;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns local edge normals.
|
||||
* \return edge normals in local space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const Point* OBB::GetLocalEdgeNormals() const
|
||||
{
|
||||
static float EdgeNormals[] =
|
||||
{
|
||||
0, -INVSQRT2, -INVSQRT2, // 0-1
|
||||
INVSQRT2, 0, -INVSQRT2, // 1-2
|
||||
0, INVSQRT2, -INVSQRT2, // 2-3
|
||||
-INVSQRT2, 0, -INVSQRT2, // 3-0
|
||||
|
||||
0, INVSQRT2, INVSQRT2, // 7-6
|
||||
INVSQRT2, 0, INVSQRT2, // 6-5
|
||||
0, -INVSQRT2, INVSQRT2, // 5-4
|
||||
-INVSQRT2, 0, INVSQRT2, // 4-7
|
||||
|
||||
INVSQRT2, -INVSQRT2, 0, // 1-5
|
||||
INVSQRT2, INVSQRT2, 0, // 6-2
|
||||
-INVSQRT2, INVSQRT2, 0, // 3-7
|
||||
-INVSQRT2, -INVSQRT2, 0 // 4-0
|
||||
};
|
||||
return (const Point*)EdgeNormals;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns world edge normal
|
||||
* \param edge_index [in] 0 <= edge index < 12
|
||||
* \param world_normal [out] edge normal in world space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void OBB::ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const
|
||||
{
|
||||
ASSERT(edge_index<12);
|
||||
world_normal = GetLocalEdgeNormals()[edge_index] * mRot;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes an LSS surrounding the OBB.
|
||||
* \param lss [out] the LSS
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void OBB::ComputeLSS(LSS& lss) const
|
||||
{
|
||||
Point Axis0 = mRot[0];
|
||||
Point Axis1 = mRot[1];
|
||||
Point Axis2 = mRot[2];
|
||||
|
||||
switch(mExtents.LargestAxis())
|
||||
{
|
||||
case 0:
|
||||
lss.mRadius = (mExtents.y + mExtents.z)*0.5f;
|
||||
lss.mP0 = mCenter + Axis0 * (mExtents.x - lss.mRadius);
|
||||
lss.mP1 = mCenter - Axis0 * (mExtents.x - lss.mRadius);
|
||||
break;
|
||||
case 1:
|
||||
lss.mRadius = (mExtents.x + mExtents.z)*0.5f;
|
||||
lss.mP0 = mCenter + Axis1 * (mExtents.y - lss.mRadius);
|
||||
lss.mP1 = mCenter - Axis1 * (mExtents.y - lss.mRadius);
|
||||
break;
|
||||
case 2:
|
||||
lss.mRadius = (mExtents.x + mExtents.y)*0.5f;
|
||||
lss.mP0 = mCenter + Axis2 * (mExtents.z - lss.mRadius);
|
||||
lss.mP1 = mCenter - Axis2 * (mExtents.z - lss.mRadius);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks the OBB is inside another OBB.
|
||||
* \param box [in] the other OBB
|
||||
* \return TRUE if we're inside the other box
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOL OBB::IsInside(const OBB& box) const
|
||||
{
|
||||
// Make a 4x4 from the box & inverse it
|
||||
Matrix4x4 M0Inv;
|
||||
{
|
||||
Matrix4x4 M0 = box.mRot;
|
||||
M0.SetTrans(box.mCenter);
|
||||
InvertPRMatrix(M0Inv, M0);
|
||||
}
|
||||
|
||||
// With our inversed 4x4, create box1 in space of box0
|
||||
OBB _1in0;
|
||||
Rotate(M0Inv, _1in0);
|
||||
|
||||
// This should cancel out box0's rotation, i.e. it's now an AABB.
|
||||
// => Center(0,0,0), Rot(identity)
|
||||
|
||||
// The two boxes are in the same space so now we can compare them.
|
||||
|
||||
// Create the AABB of (box1 in space of box0)
|
||||
const Matrix3x3& mtx = _1in0.mRot;
|
||||
|
||||
float f = fabsf(mtx.m[0][0] * mExtents.x) + fabsf(mtx.m[1][0] * mExtents.y) + fabsf(mtx.m[2][0] * mExtents.z) - box.mExtents.x;
|
||||
if(f > _1in0.mCenter.x) return FALSE;
|
||||
if(-f < _1in0.mCenter.x) return FALSE;
|
||||
|
||||
f = fabsf(mtx.m[0][1] * mExtents.x) + fabsf(mtx.m[1][1] * mExtents.y) + fabsf(mtx.m[2][1] * mExtents.z) - box.mExtents.y;
|
||||
if(f > _1in0.mCenter.y) return FALSE;
|
||||
if(-f < _1in0.mCenter.y) return FALSE;
|
||||
|
||||
f = fabsf(mtx.m[0][2] * mExtents.x) + fabsf(mtx.m[1][2] * mExtents.y) + fabsf(mtx.m[2][2] * mExtents.z) - box.mExtents.z;
|
||||
if(f > _1in0.mCenter.z) return FALSE;
|
||||
if(-f < _1in0.mCenter.z) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains OBB-related code.
|
||||
* \file IceOBB.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 29, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* An Oriented Bounding Box (OBB).
|
||||
* \class OBB
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a point is contained within the OBB.
|
||||
* \param p [in] the world point to test
|
||||
* \return true if inside the OBB
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool OBB::ContainsPoint(const Point& p) const
|
||||
{
|
||||
// Point in OBB test using lazy evaluation and early exits
|
||||
|
||||
// Translate to box space
|
||||
Point RelPoint = p - mCenter;
|
||||
|
||||
// Point * mRot maps from box space to world space
|
||||
// mRot * Point maps from world space to box space (what we need here)
|
||||
|
||||
float f = mRot.m[0][0] * RelPoint.x + mRot.m[0][1] * RelPoint.y + mRot.m[0][2] * RelPoint.z;
|
||||
if(f >= mExtents.x || f <= -mExtents.x) return false;
|
||||
|
||||
f = mRot.m[1][0] * RelPoint.x + mRot.m[1][1] * RelPoint.y + mRot.m[1][2] * RelPoint.z;
|
||||
if(f >= mExtents.y || f <= -mExtents.y) return false;
|
||||
|
||||
f = mRot.m[2][0] * RelPoint.x + mRot.m[2][1] * RelPoint.y + mRot.m[2][2] * RelPoint.z;
|
||||
if(f >= mExtents.z || f <= -mExtents.z) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Builds an OBB from an AABB and a world transform.
|
||||
* \param aabb [in] the aabb
|
||||
* \param mat [in] the world transform
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void OBB::Create(const AABB& aabb, const Matrix4x4& mat)
|
||||
{
|
||||
// Note: must be coherent with Rotate()
|
||||
|
||||
aabb.GetCenter(mCenter);
|
||||
aabb.GetExtents(mExtents);
|
||||
// Here we have the same as OBB::Rotate(mat) where the obb is (mCenter, mExtents, Identity).
|
||||
|
||||
// So following what's done in Rotate:
|
||||
// - x-form the center
|
||||
mCenter *= mat;
|
||||
// - combine rotation with identity, i.e. just use given matrix
|
||||
mRot = mat;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the obb planes.
|
||||
* \param planes [out] 6 box planes
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool OBB::ComputePlanes(Plane* planes) const
|
||||
{
|
||||
// Checkings
|
||||
if(!planes) return false;
|
||||
|
||||
Point Axis0 = mRot[0];
|
||||
Point Axis1 = mRot[1];
|
||||
Point Axis2 = mRot[2];
|
||||
|
||||
// Writes normals
|
||||
planes[0].n = Axis0;
|
||||
planes[1].n = -Axis0;
|
||||
planes[2].n = Axis1;
|
||||
planes[3].n = -Axis1;
|
||||
planes[4].n = Axis2;
|
||||
planes[5].n = -Axis2;
|
||||
|
||||
// Compute a point on each plane
|
||||
Point p0 = mCenter + Axis0 * mExtents.x;
|
||||
Point p1 = mCenter - Axis0 * mExtents.x;
|
||||
Point p2 = mCenter + Axis1 * mExtents.y;
|
||||
Point p3 = mCenter - Axis1 * mExtents.y;
|
||||
Point p4 = mCenter + Axis2 * mExtents.z;
|
||||
Point p5 = mCenter - Axis2 * mExtents.z;
|
||||
|
||||
// Compute d
|
||||
planes[0].d = -(planes[0].n|p0);
|
||||
planes[1].d = -(planes[1].n|p1);
|
||||
planes[2].d = -(planes[2].n|p2);
|
||||
planes[3].d = -(planes[3].n|p3);
|
||||
planes[4].d = -(planes[4].n|p4);
|
||||
planes[5].d = -(planes[5].n|p5);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the obb points.
|
||||
* \param pts [out] 8 box points
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool OBB::ComputePoints(Point* pts) const
|
||||
{
|
||||
// Checkings
|
||||
if(!pts) return false;
|
||||
|
||||
Point Axis0 = mRot[0];
|
||||
Point Axis1 = mRot[1];
|
||||
Point Axis2 = mRot[2];
|
||||
|
||||
Axis0 *= mExtents.x;
|
||||
Axis1 *= mExtents.y;
|
||||
Axis2 *= mExtents.z;
|
||||
|
||||
// 7+------+6 0 = ---
|
||||
// /| /| 1 = +--
|
||||
// / | / | 2 = ++-
|
||||
// / 4+---/--+5 3 = -+-
|
||||
// 3+------+2 / y z 4 = --+
|
||||
// | / | / | / 5 = +-+
|
||||
// |/ |/ |/ 6 = +++
|
||||
// 0+------+1 *---x 7 = -++
|
||||
|
||||
pts[0] = mCenter - Axis0 - Axis1 - Axis2;
|
||||
pts[1] = mCenter + Axis0 - Axis1 - Axis2;
|
||||
pts[2] = mCenter + Axis0 + Axis1 - Axis2;
|
||||
pts[3] = mCenter - Axis0 + Axis1 - Axis2;
|
||||
pts[4] = mCenter - Axis0 - Axis1 + Axis2;
|
||||
pts[5] = mCenter + Axis0 - Axis1 + Axis2;
|
||||
pts[6] = mCenter + Axis0 + Axis1 + Axis2;
|
||||
pts[7] = mCenter - Axis0 + Axis1 + Axis2;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes vertex normals.
|
||||
* \param pts [out] 8 box points
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool OBB::ComputeVertexNormals(Point* pts) const
|
||||
{
|
||||
static float VertexNormals[] =
|
||||
{
|
||||
-INVSQRT3, -INVSQRT3, -INVSQRT3,
|
||||
INVSQRT3, -INVSQRT3, -INVSQRT3,
|
||||
INVSQRT3, INVSQRT3, -INVSQRT3,
|
||||
-INVSQRT3, INVSQRT3, -INVSQRT3,
|
||||
-INVSQRT3, -INVSQRT3, INVSQRT3,
|
||||
INVSQRT3, -INVSQRT3, INVSQRT3,
|
||||
INVSQRT3, INVSQRT3, INVSQRT3,
|
||||
-INVSQRT3, INVSQRT3, INVSQRT3
|
||||
};
|
||||
|
||||
if(!pts) return false;
|
||||
|
||||
const Point* VN = (const Point*)VertexNormals;
|
||||
for(udword i=0;i<8;i++)
|
||||
{
|
||||
pts[i] = VN[i] * mRot;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns edges.
|
||||
* \return 24 indices (12 edges) indexing the list returned by ComputePoints()
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const udword* OBB::GetEdges() const
|
||||
{
|
||||
static udword Indices[] = {
|
||||
0, 1, 1, 2, 2, 3, 3, 0,
|
||||
7, 6, 6, 5, 5, 4, 4, 7,
|
||||
1, 5, 6, 2,
|
||||
3, 7, 4, 0
|
||||
};
|
||||
return Indices;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns local edge normals.
|
||||
* \return edge normals in local space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const Point* OBB::GetLocalEdgeNormals() const
|
||||
{
|
||||
static float EdgeNormals[] =
|
||||
{
|
||||
0, -INVSQRT2, -INVSQRT2, // 0-1
|
||||
INVSQRT2, 0, -INVSQRT2, // 1-2
|
||||
0, INVSQRT2, -INVSQRT2, // 2-3
|
||||
-INVSQRT2, 0, -INVSQRT2, // 3-0
|
||||
|
||||
0, INVSQRT2, INVSQRT2, // 7-6
|
||||
INVSQRT2, 0, INVSQRT2, // 6-5
|
||||
0, -INVSQRT2, INVSQRT2, // 5-4
|
||||
-INVSQRT2, 0, INVSQRT2, // 4-7
|
||||
|
||||
INVSQRT2, -INVSQRT2, 0, // 1-5
|
||||
INVSQRT2, INVSQRT2, 0, // 6-2
|
||||
-INVSQRT2, INVSQRT2, 0, // 3-7
|
||||
-INVSQRT2, -INVSQRT2, 0 // 4-0
|
||||
};
|
||||
return (const Point*)EdgeNormals;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns world edge normal
|
||||
* \param edge_index [in] 0 <= edge index < 12
|
||||
* \param world_normal [out] edge normal in world space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void OBB::ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const
|
||||
{
|
||||
ASSERT(edge_index<12);
|
||||
world_normal = GetLocalEdgeNormals()[edge_index] * mRot;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes an LSS surrounding the OBB.
|
||||
* \param lss [out] the LSS
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void OBB::ComputeLSS(LSS& lss) const
|
||||
{
|
||||
Point Axis0 = mRot[0];
|
||||
Point Axis1 = mRot[1];
|
||||
Point Axis2 = mRot[2];
|
||||
|
||||
switch(mExtents.LargestAxis())
|
||||
{
|
||||
case 0:
|
||||
lss.mRadius = (mExtents.y + mExtents.z)*0.5f;
|
||||
lss.mP0 = mCenter + Axis0 * (mExtents.x - lss.mRadius);
|
||||
lss.mP1 = mCenter - Axis0 * (mExtents.x - lss.mRadius);
|
||||
break;
|
||||
case 1:
|
||||
lss.mRadius = (mExtents.x + mExtents.z)*0.5f;
|
||||
lss.mP0 = mCenter + Axis1 * (mExtents.y - lss.mRadius);
|
||||
lss.mP1 = mCenter - Axis1 * (mExtents.y - lss.mRadius);
|
||||
break;
|
||||
case 2:
|
||||
lss.mRadius = (mExtents.x + mExtents.y)*0.5f;
|
||||
lss.mP0 = mCenter + Axis2 * (mExtents.z - lss.mRadius);
|
||||
lss.mP1 = mCenter - Axis2 * (mExtents.z - lss.mRadius);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks the OBB is inside another OBB.
|
||||
* \param box [in] the other OBB
|
||||
* \return TRUE if we're inside the other box
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOL OBB::IsInside(const OBB& box) const
|
||||
{
|
||||
// Make a 4x4 from the box & inverse it
|
||||
Matrix4x4 M0Inv;
|
||||
{
|
||||
Matrix4x4 M0 = box.mRot;
|
||||
M0.SetTrans(box.mCenter);
|
||||
InvertPRMatrix(M0Inv, M0);
|
||||
}
|
||||
|
||||
// With our inversed 4x4, create box1 in space of box0
|
||||
OBB _1in0;
|
||||
Rotate(M0Inv, _1in0);
|
||||
|
||||
// This should cancel out box0's rotation, i.e. it's now an AABB.
|
||||
// => Center(0,0,0), Rot(identity)
|
||||
|
||||
// The two boxes are in the same space so now we can compare them.
|
||||
|
||||
// Create the AABB of (box1 in space of box0)
|
||||
const Matrix3x3& mtx = _1in0.mRot;
|
||||
|
||||
float f = fabsf(mtx.m[0][0] * mExtents.x) + fabsf(mtx.m[1][0] * mExtents.y) + fabsf(mtx.m[2][0] * mExtents.z) - box.mExtents.x;
|
||||
if(f > _1in0.mCenter.x) return FALSE;
|
||||
if(-f < _1in0.mCenter.x) return FALSE;
|
||||
|
||||
f = fabsf(mtx.m[0][1] * mExtents.x) + fabsf(mtx.m[1][1] * mExtents.y) + fabsf(mtx.m[2][1] * mExtents.z) - box.mExtents.y;
|
||||
if(f > _1in0.mCenter.y) return FALSE;
|
||||
if(-f < _1in0.mCenter.y) return FALSE;
|
||||
|
||||
f = fabsf(mtx.m[0][2] * mExtents.x) + fabsf(mtx.m[1][2] * mExtents.y) + fabsf(mtx.m[2][2] * mExtents.z) - box.mExtents.z;
|
||||
if(f > _1in0.mCenter.z) return FALSE;
|
||||
if(-f < _1in0.mCenter.z) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1,193 +1,193 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains OBB-related code. (oriented bounding box)
|
||||
* \file IceOBB.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 13, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEOBB_H__
|
||||
#define __ICEOBB_H__
|
||||
|
||||
// Forward declarations
|
||||
class LSS;
|
||||
|
||||
class ICEMATHS_API OBB
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ OBB() {}
|
||||
//! Constructor
|
||||
inline_ OBB(const Point& center, const Point& extents, const Matrix3x3& rot) : mCenter(center), mExtents(extents), mRot(rot) {}
|
||||
//! Destructor
|
||||
inline_ ~OBB() {}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Setups an empty OBB.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void SetEmpty()
|
||||
{
|
||||
mCenter.Zero();
|
||||
mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);
|
||||
mRot.Identity();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a point is contained within the OBB.
|
||||
* \param p [in] the world point to test
|
||||
* \return true if inside the OBB
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool ContainsPoint(const Point& p) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Builds an OBB from an AABB and a world transform.
|
||||
* \param aabb [in] the aabb
|
||||
* \param mat [in] the world transform
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Create(const AABB& aabb, const Matrix4x4& mat);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Recomputes the OBB after an arbitrary transform by a 4x4 matrix.
|
||||
* \param mtx [in] the transform matrix
|
||||
* \param obb [out] the transformed OBB
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void Rotate(const Matrix4x4& mtx, OBB& obb) const
|
||||
{
|
||||
// The extents remain constant
|
||||
obb.mExtents = mExtents;
|
||||
// The center gets x-formed
|
||||
obb.mCenter = mCenter * mtx;
|
||||
// Combine rotations
|
||||
obb.mRot = mRot * Matrix3x3(mtx);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks the OBB is valid.
|
||||
* \return true if the box is valid
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL IsValid() const
|
||||
{
|
||||
// Consistency condition for (Center, Extents) boxes: Extents >= 0.0f
|
||||
if(mExtents.x < 0.0f) return FALSE;
|
||||
if(mExtents.y < 0.0f) return FALSE;
|
||||
if(mExtents.z < 0.0f) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the obb planes.
|
||||
* \param planes [out] 6 box planes
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool ComputePlanes(Plane* planes) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the obb points.
|
||||
* \param pts [out] 8 box points
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool ComputePoints(Point* pts) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes vertex normals.
|
||||
* \param pts [out] 8 box points
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool ComputeVertexNormals(Point* pts) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns edges.
|
||||
* \return 24 indices (12 edges) indexing the list returned by ComputePoints()
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const udword* GetEdges() const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns local edge normals.
|
||||
* \return edge normals in local space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const Point* GetLocalEdgeNormals() const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns world edge normal
|
||||
* \param edge_index [in] 0 <= edge index < 12
|
||||
* \param world_normal [out] edge normal in world space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes an LSS surrounding the OBB.
|
||||
* \param lss [out] the LSS
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void ComputeLSS(LSS& lss) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks the OBB is inside another OBB.
|
||||
* \param box [in] the other OBB
|
||||
* \return TRUE if we're inside the other box
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOL IsInside(const OBB& box) const;
|
||||
|
||||
inline_ const Point& GetCenter() const { return mCenter; }
|
||||
inline_ const Point& GetExtents() const { return mExtents; }
|
||||
inline_ const Matrix3x3& GetRot() const { return mRot; }
|
||||
|
||||
inline_ void GetRotatedExtents(Matrix3x3& extents) const
|
||||
{
|
||||
extents = mRot;
|
||||
extents.Scale(mExtents);
|
||||
}
|
||||
|
||||
Point mCenter; //!< B for Box
|
||||
Point mExtents; //!< B for Bounding
|
||||
Matrix3x3 mRot; //!< O for Oriented
|
||||
|
||||
// Orientation is stored in row-major format,
|
||||
// i.e. rows = eigen vectors of the covariance matrix
|
||||
};
|
||||
|
||||
#endif // __ICEOBB_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains OBB-related code. (oriented bounding box)
|
||||
* \file IceOBB.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 13, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEOBB_H__
|
||||
#define __ICEOBB_H__
|
||||
|
||||
// Forward declarations
|
||||
class LSS;
|
||||
|
||||
class ICEMATHS_API OBB
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ OBB() {}
|
||||
//! Constructor
|
||||
inline_ OBB(const Point& center, const Point& extents, const Matrix3x3& rot) : mCenter(center), mExtents(extents), mRot(rot) {}
|
||||
//! Destructor
|
||||
inline_ ~OBB() {}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Setups an empty OBB.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void SetEmpty()
|
||||
{
|
||||
mCenter.Zero();
|
||||
mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);
|
||||
mRot.Identity();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tests if a point is contained within the OBB.
|
||||
* \param p [in] the world point to test
|
||||
* \return true if inside the OBB
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool ContainsPoint(const Point& p) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Builds an OBB from an AABB and a world transform.
|
||||
* \param aabb [in] the aabb
|
||||
* \param mat [in] the world transform
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Create(const AABB& aabb, const Matrix4x4& mat);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Recomputes the OBB after an arbitrary transform by a 4x4 matrix.
|
||||
* \param mtx [in] the transform matrix
|
||||
* \param obb [out] the transformed OBB
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void Rotate(const Matrix4x4& mtx, OBB& obb) const
|
||||
{
|
||||
// The extents remain constant
|
||||
obb.mExtents = mExtents;
|
||||
// The center gets x-formed
|
||||
obb.mCenter = mCenter * mtx;
|
||||
// Combine rotations
|
||||
obb.mRot = mRot * Matrix3x3(mtx);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks the OBB is valid.
|
||||
* \return true if the box is valid
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL IsValid() const
|
||||
{
|
||||
// Consistency condition for (Center, Extents) boxes: Extents >= 0.0f
|
||||
if(mExtents.x < 0.0f) return FALSE;
|
||||
if(mExtents.y < 0.0f) return FALSE;
|
||||
if(mExtents.z < 0.0f) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the obb planes.
|
||||
* \param planes [out] 6 box planes
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool ComputePlanes(Plane* planes) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the obb points.
|
||||
* \param pts [out] 8 box points
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool ComputePoints(Point* pts) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes vertex normals.
|
||||
* \param pts [out] 8 box points
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool ComputeVertexNormals(Point* pts) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns edges.
|
||||
* \return 24 indices (12 edges) indexing the list returned by ComputePoints()
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const udword* GetEdges() const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns local edge normals.
|
||||
* \return edge normals in local space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const Point* GetLocalEdgeNormals() const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns world edge normal
|
||||
* \param edge_index [in] 0 <= edge index < 12
|
||||
* \param world_normal [out] edge normal in world space
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes an LSS surrounding the OBB.
|
||||
* \param lss [out] the LSS
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void ComputeLSS(LSS& lss) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks the OBB is inside another OBB.
|
||||
* \param box [in] the other OBB
|
||||
* \return TRUE if we're inside the other box
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOL IsInside(const OBB& box) const;
|
||||
|
||||
inline_ const Point& GetCenter() const { return mCenter; }
|
||||
inline_ const Point& GetExtents() const { return mExtents; }
|
||||
inline_ const Matrix3x3& GetRot() const { return mRot; }
|
||||
|
||||
inline_ void GetRotatedExtents(Matrix3x3& extents) const
|
||||
{
|
||||
extents = mRot;
|
||||
extents.Scale(mExtents);
|
||||
}
|
||||
|
||||
Point mCenter; //!< B for Box
|
||||
Point mExtents; //!< B for Bounding
|
||||
Matrix3x3 mRot; //!< O for Oriented
|
||||
|
||||
// Orientation is stored in row-major format,
|
||||
// i.e. rows = eigen vectors of the covariance matrix
|
||||
};
|
||||
|
||||
#endif // __ICEOBB_H__
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a simple pair class.
|
||||
* \file IcePairs.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 13, 2003
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEPAIRS_H__
|
||||
#define __ICEPAIRS_H__
|
||||
|
||||
//! A generic couple structure
|
||||
struct ICECORE_API Pair
|
||||
{
|
||||
inline_ Pair() {}
|
||||
inline_ Pair(udword i0, udword i1) : id0(i0), id1(i1) {}
|
||||
|
||||
udword id0; //!< First index of the pair
|
||||
udword id1; //!< Second index of the pair
|
||||
};
|
||||
|
||||
class ICECORE_API Pairs : private Container
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
Pairs() {}
|
||||
~Pairs() {}
|
||||
|
||||
inline_ udword GetNbPairs() const { return GetNbEntries()>>1; }
|
||||
inline_ const Pair* GetPairs() const { return (const Pair*)GetEntries(); }
|
||||
inline_ const Pair* GetPair(udword i) const { return (const Pair*)&GetEntries()[i+i]; }
|
||||
|
||||
inline_ BOOL HasPairs() const { return IsNotEmpty(); }
|
||||
|
||||
inline_ void ResetPairs() { Reset(); }
|
||||
inline_ void DeleteLastPair() { DeleteLastEntry(); DeleteLastEntry(); }
|
||||
|
||||
inline_ void AddPair(const Pair& p) { Add(p.id0).Add(p.id1); }
|
||||
inline_ void AddPair(udword id0, udword id1) { Add(id0).Add(id1); }
|
||||
};
|
||||
|
||||
#endif // __ICEPAIRS_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a simple pair class.
|
||||
* \file IcePairs.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 13, 2003
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEPAIRS_H__
|
||||
#define __ICEPAIRS_H__
|
||||
|
||||
//! A generic couple structure
|
||||
struct ICECORE_API Pair
|
||||
{
|
||||
inline_ Pair() {}
|
||||
inline_ Pair(udword i0, udword i1) : id0(i0), id1(i1) {}
|
||||
|
||||
udword id0; //!< First index of the pair
|
||||
udword id1; //!< Second index of the pair
|
||||
};
|
||||
|
||||
class ICECORE_API Pairs : private Container
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
Pairs() {}
|
||||
~Pairs() {}
|
||||
|
||||
inline_ udword GetNbPairs() const { return GetNbEntries()>>1; }
|
||||
inline_ const Pair* GetPairs() const { return (const Pair*)GetEntries(); }
|
||||
inline_ const Pair* GetPair(udword i) const { return (const Pair*)&GetEntries()[i+i]; }
|
||||
|
||||
inline_ BOOL HasPairs() const { return IsNotEmpty(); }
|
||||
|
||||
inline_ void ResetPairs() { Reset(); }
|
||||
inline_ void DeleteLastPair() { DeleteLastEntry(); DeleteLastEntry(); }
|
||||
|
||||
inline_ void AddPair(const Pair& p) { Add(p.id0).Add(p.id1); }
|
||||
inline_ void AddPair(udword id0, udword id1) { Add(id0).Add(id1); }
|
||||
};
|
||||
|
||||
#endif // __ICEPAIRS_H__
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for planes.
|
||||
* \file IcePlane.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Plane class.
|
||||
* \class Plane
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the plane equation from 3 points.
|
||||
* \param p0 [in] first point
|
||||
* \param p1 [in] second point
|
||||
* \param p2 [in] third point
|
||||
* \return Self-reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Plane& Plane::Set(const Point& p0, const Point& p1, const Point& p2)
|
||||
{
|
||||
Point Edge0 = p1 - p0;
|
||||
Point Edge1 = p2 - p0;
|
||||
|
||||
n = Edge0 ^ Edge1;
|
||||
n.Normalize();
|
||||
|
||||
d = -(p0 | n);
|
||||
|
||||
return *this;
|
||||
}
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for planes.
|
||||
* \file IcePlane.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Plane class.
|
||||
* \class Plane
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the plane equation from 3 points.
|
||||
* \param p0 [in] first point
|
||||
* \param p1 [in] second point
|
||||
* \param p2 [in] third point
|
||||
* \return Self-reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Plane& Plane::Set(const Point& p0, const Point& p1, const Point& p2)
|
||||
{
|
||||
Point Edge0 = p1 - p0;
|
||||
Point Edge1 = p2 - p0;
|
||||
|
||||
n = Edge0 ^ Edge1;
|
||||
n.Normalize();
|
||||
|
||||
d = -(p0 | n);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1,129 +1,129 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for planes.
|
||||
* \file IcePlane.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEPLANE_H__
|
||||
#define __ICEPLANE_H__
|
||||
|
||||
#define PLANE_EPSILON (1.0e-7f)
|
||||
|
||||
class ICEMATHS_API Plane
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ Plane() { }
|
||||
//! Constructor from a normal and a distance
|
||||
inline_ Plane(float nx, float ny, float nz, float d) { Set(nx, ny, nz, d); }
|
||||
//! Constructor from a point on the plane and a normal
|
||||
inline_ Plane(const Point& p, const Point& n) { Set(p, n); }
|
||||
//! Constructor from three points
|
||||
inline_ Plane(const Point& p0, const Point& p1, const Point& p2) { Set(p0, p1, p2); }
|
||||
//! Constructor from a normal and a distance
|
||||
inline_ Plane(const Point& _n, float _d) { n = _n; d = _d; }
|
||||
//! Copy constructor
|
||||
inline_ Plane(const Plane& plane) : n(plane.n), d(plane.d) { }
|
||||
//! Destructor
|
||||
inline_ ~Plane() { }
|
||||
|
||||
inline_ Plane& Zero() { n.Zero(); d = 0.0f; return *this; }
|
||||
inline_ Plane& Set(float nx, float ny, float nz, float _d) { n.Set(nx, ny, nz); d = _d; return *this; }
|
||||
inline_ Plane& Set(const Point& p, const Point& _n) { n = _n; d = - p | _n; return *this; }
|
||||
Plane& Set(const Point& p0, const Point& p1, const Point& p2);
|
||||
|
||||
inline_ float Distance(const Point& p) const { return (p | n) + d; }
|
||||
inline_ bool Belongs(const Point& p) const { return fabsf(Distance(p)) < PLANE_EPSILON; }
|
||||
|
||||
inline_ void Normalize()
|
||||
{
|
||||
float Denom = 1.0f / n.Magnitude();
|
||||
n.x *= Denom;
|
||||
n.y *= Denom;
|
||||
n.z *= Denom;
|
||||
d *= Denom;
|
||||
}
|
||||
public:
|
||||
// Members
|
||||
Point n; //!< The normal to the plane
|
||||
float d; //!< The distance from the origin
|
||||
|
||||
// Cast operators
|
||||
inline_ operator Point() const { return n; }
|
||||
inline_ operator HPoint() const { return HPoint(n, d); }
|
||||
|
||||
// Arithmetic operators
|
||||
inline_ Plane operator*(const Matrix4x4& m) const
|
||||
{
|
||||
// Old code from Irion. Kept for reference.
|
||||
Plane Ret(*this);
|
||||
return Ret *= m;
|
||||
}
|
||||
|
||||
inline_ Plane& operator*=(const Matrix4x4& m)
|
||||
{
|
||||
// Old code from Irion. Kept for reference.
|
||||
Point n2 = HPoint(n, 0.0f) * m;
|
||||
d = -((Point) (HPoint( -d*n, 1.0f ) * m) | n2);
|
||||
n = n2;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster.
|
||||
* \param transformed [out] transformed plane
|
||||
* \param plane [in] source plane
|
||||
* \param transform [in] transform matrix
|
||||
* \warning the plane normal must be unit-length
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void TransformPlane(Plane& transformed, const Plane& plane, const Matrix4x4& transform)
|
||||
{
|
||||
// Rotate the normal using the rotation part of the 4x4 matrix
|
||||
transformed.n = plane.n * Matrix3x3(transform);
|
||||
|
||||
// Compute new d
|
||||
transformed.d = plane.d - (Point(transform.GetTrans())|transformed.n);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster.
|
||||
* \param plane [in/out] source plane (transformed on return)
|
||||
* \param transform [in] transform matrix
|
||||
* \warning the plane normal must be unit-length
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void TransformPlane(Plane& plane, const Matrix4x4& transform)
|
||||
{
|
||||
// Rotate the normal using the rotation part of the 4x4 matrix
|
||||
plane.n *= Matrix3x3(transform);
|
||||
|
||||
// Compute new d
|
||||
plane.d -= Point(transform.GetTrans())|plane.n;
|
||||
}
|
||||
|
||||
#endif // __ICEPLANE_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for planes.
|
||||
* \file IcePlane.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEPLANE_H__
|
||||
#define __ICEPLANE_H__
|
||||
|
||||
#define PLANE_EPSILON (1.0e-7f)
|
||||
|
||||
class ICEMATHS_API Plane
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ Plane() { }
|
||||
//! Constructor from a normal and a distance
|
||||
inline_ Plane(float nx, float ny, float nz, float d) { Set(nx, ny, nz, d); }
|
||||
//! Constructor from a point on the plane and a normal
|
||||
inline_ Plane(const Point& p, const Point& n) { Set(p, n); }
|
||||
//! Constructor from three points
|
||||
inline_ Plane(const Point& p0, const Point& p1, const Point& p2) { Set(p0, p1, p2); }
|
||||
//! Constructor from a normal and a distance
|
||||
inline_ Plane(const Point& _n, float _d) { n = _n; d = _d; }
|
||||
//! Copy constructor
|
||||
inline_ Plane(const Plane& plane) : n(plane.n), d(plane.d) { }
|
||||
//! Destructor
|
||||
inline_ ~Plane() { }
|
||||
|
||||
inline_ Plane& Zero() { n.Zero(); d = 0.0f; return *this; }
|
||||
inline_ Plane& Set(float nx, float ny, float nz, float _d) { n.Set(nx, ny, nz); d = _d; return *this; }
|
||||
inline_ Plane& Set(const Point& p, const Point& _n) { n = _n; d = - p | _n; return *this; }
|
||||
Plane& Set(const Point& p0, const Point& p1, const Point& p2);
|
||||
|
||||
inline_ float Distance(const Point& p) const { return (p | n) + d; }
|
||||
inline_ bool Belongs(const Point& p) const { return fabsf(Distance(p)) < PLANE_EPSILON; }
|
||||
|
||||
inline_ void Normalize()
|
||||
{
|
||||
float Denom = 1.0f / n.Magnitude();
|
||||
n.x *= Denom;
|
||||
n.y *= Denom;
|
||||
n.z *= Denom;
|
||||
d *= Denom;
|
||||
}
|
||||
public:
|
||||
// Members
|
||||
Point n; //!< The normal to the plane
|
||||
float d; //!< The distance from the origin
|
||||
|
||||
// Cast operators
|
||||
inline_ operator Point() const { return n; }
|
||||
inline_ operator HPoint() const { return HPoint(n, d); }
|
||||
|
||||
// Arithmetic operators
|
||||
inline_ Plane operator*(const Matrix4x4& m) const
|
||||
{
|
||||
// Old code from Irion. Kept for reference.
|
||||
Plane Ret(*this);
|
||||
return Ret *= m;
|
||||
}
|
||||
|
||||
inline_ Plane& operator*=(const Matrix4x4& m)
|
||||
{
|
||||
// Old code from Irion. Kept for reference.
|
||||
Point n2 = HPoint(n, 0.0f) * m;
|
||||
d = -((Point) (HPoint( -d*n, 1.0f ) * m) | n2);
|
||||
n = n2;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster.
|
||||
* \param transformed [out] transformed plane
|
||||
* \param plane [in] source plane
|
||||
* \param transform [in] transform matrix
|
||||
* \warning the plane normal must be unit-length
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void TransformPlane(Plane& transformed, const Plane& plane, const Matrix4x4& transform)
|
||||
{
|
||||
// Rotate the normal using the rotation part of the 4x4 matrix
|
||||
transformed.n = plane.n * Matrix3x3(transform);
|
||||
|
||||
// Compute new d
|
||||
transformed.d = plane.d - (Point(transform.GetTrans())|transformed.n);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster.
|
||||
* \param plane [in/out] source plane (transformed on return)
|
||||
* \param transform [in] transform matrix
|
||||
* \warning the plane normal must be unit-length
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void TransformPlane(Plane& plane, const Matrix4x4& transform)
|
||||
{
|
||||
// Rotate the normal using the rotation part of the 4x4 matrix
|
||||
plane.n *= Matrix3x3(transform);
|
||||
|
||||
// Compute new d
|
||||
plane.d -= Point(transform.GetTrans())|plane.n;
|
||||
}
|
||||
|
||||
#endif // __ICEPLANE_H__
|
||||
|
||||
@@ -1,209 +1,209 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for 3D vectors.
|
||||
* \file IcePoint.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 3D point.
|
||||
*
|
||||
* The name is "Point" instead of "Vector" since a vector is N-dimensional, whereas a point is an implicit "vector of dimension 3".
|
||||
* So the choice was between "Point" and "Vector3", the first one looked better (IMHO).
|
||||
*
|
||||
* Some people, then, use a typedef to handle both points & vectors using the same class: typedef Point Vector3;
|
||||
* This is bad since it opens the door to a lot of confusion while reading the code. I know it may sounds weird but check this out:
|
||||
*
|
||||
* \code
|
||||
* Point P0,P1 = some 3D points;
|
||||
* Point Delta = P1 - P0;
|
||||
* \endcode
|
||||
*
|
||||
* This compiles fine, although you should have written:
|
||||
*
|
||||
* \code
|
||||
* Point P0,P1 = some 3D points;
|
||||
* Vector3 Delta = P1 - P0;
|
||||
* \endcode
|
||||
*
|
||||
* Subtle things like this are not caught at compile-time, and when you find one in the code, you never know whether it's a mistake
|
||||
* from the author or something you don't get.
|
||||
*
|
||||
* One way to handle it at compile-time would be to use different classes for Point & Vector3, only overloading operator "-" for vectors.
|
||||
* But then, you get a lot of redundant code in thoses classes, and basically it's really a lot of useless work.
|
||||
*
|
||||
* Another way would be to use homogeneous points: w=1 for points, w=0 for vectors. That's why the HPoint class exists. Now, to store
|
||||
* your model's vertices and in most cases, you really want to use Points to save ram.
|
||||
*
|
||||
* \class Point
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Creates a positive unit random vector.
|
||||
* \return Self-reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Point& Point::PositiveUnitRandomVector()
|
||||
{
|
||||
x = UnitRandomFloat();
|
||||
y = UnitRandomFloat();
|
||||
z = UnitRandomFloat();
|
||||
Normalize();
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Creates a unit random vector.
|
||||
* \return Self-reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Point& Point::UnitRandomVector()
|
||||
{
|
||||
x = UnitRandomFloat() - 0.5f;
|
||||
y = UnitRandomFloat() - 0.5f;
|
||||
z = UnitRandomFloat() - 0.5f;
|
||||
Normalize();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Cast operator
|
||||
// WARNING: not inlined
|
||||
Point::operator HPoint() const { return HPoint(x, y, z, 0.0f); }
|
||||
|
||||
Point& Point::Refract(const Point& eye, const Point& n, float refractindex, Point& refracted)
|
||||
{
|
||||
// Point EyePt = eye position
|
||||
// Point p = current vertex
|
||||
// Point n = vertex normal
|
||||
// Point rv = refracted vector
|
||||
// Eye vector - doesn't need to be normalized
|
||||
Point Env;
|
||||
Env.x = eye.x - x;
|
||||
Env.y = eye.y - y;
|
||||
Env.z = eye.z - z;
|
||||
|
||||
float NDotE = n|Env;
|
||||
float NDotN = n|n;
|
||||
NDotE /= refractindex;
|
||||
|
||||
// Refracted vector
|
||||
refracted = n*NDotE - Env*NDotN;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point& Point::ProjectToPlane(const Plane& p)
|
||||
{
|
||||
*this-= (p.d + (*this|p.n))*p.n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Point::ProjectToScreen(float halfrenderwidth, float halfrenderheight, const Matrix4x4& mat, HPoint& projected) const
|
||||
{
|
||||
projected = HPoint(x, y, z, 1.0f) * mat;
|
||||
projected.w = 1.0f / projected.w;
|
||||
|
||||
projected.x*=projected.w;
|
||||
projected.y*=projected.w;
|
||||
projected.z*=projected.w;
|
||||
|
||||
projected.x *= halfrenderwidth; projected.x += halfrenderwidth;
|
||||
projected.y *= -halfrenderheight; projected.y += halfrenderheight;
|
||||
}
|
||||
|
||||
void Point::SetNotUsed()
|
||||
{
|
||||
// We use a particular integer pattern : 0xffffffff everywhere. This is a NAN.
|
||||
IR(x) = 0xffffffff;
|
||||
IR(y) = 0xffffffff;
|
||||
IR(z) = 0xffffffff;
|
||||
}
|
||||
|
||||
BOOL Point::IsNotUsed() const
|
||||
{
|
||||
if(IR(x)!=0xffffffff) return FALSE;
|
||||
if(IR(y)!=0xffffffff) return FALSE;
|
||||
if(IR(z)!=0xffffffff) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Point& Point::Mult(const Matrix3x3& mat, const Point& a)
|
||||
{
|
||||
x = a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2];
|
||||
y = a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2];
|
||||
z = a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point& Point::Mult2(const Matrix3x3& mat1, const Point& a1, const Matrix3x3& mat2, const Point& a2)
|
||||
{
|
||||
x = a1.x * mat1.m[0][0] + a1.y * mat1.m[0][1] + a1.z * mat1.m[0][2] + a2.x * mat2.m[0][0] + a2.y * mat2.m[0][1] + a2.z * mat2.m[0][2];
|
||||
y = a1.x * mat1.m[1][0] + a1.y * mat1.m[1][1] + a1.z * mat1.m[1][2] + a2.x * mat2.m[1][0] + a2.y * mat2.m[1][1] + a2.z * mat2.m[1][2];
|
||||
z = a1.x * mat1.m[2][0] + a1.y * mat1.m[2][1] + a1.z * mat1.m[2][2] + a2.x * mat2.m[2][0] + a2.y * mat2.m[2][1] + a2.z * mat2.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point& Point::Mac(const Matrix3x3& mat, const Point& a)
|
||||
{
|
||||
x += a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2];
|
||||
y += a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2];
|
||||
z += a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point& Point::TransMult(const Matrix3x3& mat, const Point& a)
|
||||
{
|
||||
x = a.x * mat.m[0][0] + a.y * mat.m[1][0] + a.z * mat.m[2][0];
|
||||
y = a.x * mat.m[0][1] + a.y * mat.m[1][1] + a.z * mat.m[2][1];
|
||||
z = a.x * mat.m[0][2] + a.y * mat.m[1][2] + a.z * mat.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point& Point::Transform(const Point& r, const Matrix3x3& rotpos, const Point& linpos)
|
||||
{
|
||||
x = r.x * rotpos.m[0][0] + r.y * rotpos.m[0][1] + r.z * rotpos.m[0][2] + linpos.x;
|
||||
y = r.x * rotpos.m[1][0] + r.y * rotpos.m[1][1] + r.z * rotpos.m[1][2] + linpos.y;
|
||||
z = r.x * rotpos.m[2][0] + r.y * rotpos.m[2][1] + r.z * rotpos.m[2][2] + linpos.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point& Point::InvTransform(const Point& r, const Matrix3x3& rotpos, const Point& linpos)
|
||||
{
|
||||
float sx = r.x - linpos.x;
|
||||
float sy = r.y - linpos.y;
|
||||
float sz = r.z - linpos.z;
|
||||
x = sx * rotpos.m[0][0] + sy * rotpos.m[1][0] + sz * rotpos.m[2][0];
|
||||
y = sx * rotpos.m[0][1] + sy * rotpos.m[1][1] + sz * rotpos.m[2][1];
|
||||
z = sx * rotpos.m[0][2] + sy * rotpos.m[1][2] + sz * rotpos.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for 3D vectors.
|
||||
* \file IcePoint.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 3D point.
|
||||
*
|
||||
* The name is "Point" instead of "Vector" since a vector is N-dimensional, whereas a point is an implicit "vector of dimension 3".
|
||||
* So the choice was between "Point" and "Vector3", the first one looked better (IMHO).
|
||||
*
|
||||
* Some people, then, use a typedef to handle both points & vectors using the same class: typedef Point Vector3;
|
||||
* This is bad since it opens the door to a lot of confusion while reading the code. I know it may sounds weird but check this out:
|
||||
*
|
||||
* \code
|
||||
* Point P0,P1 = some 3D points;
|
||||
* Point Delta = P1 - P0;
|
||||
* \endcode
|
||||
*
|
||||
* This compiles fine, although you should have written:
|
||||
*
|
||||
* \code
|
||||
* Point P0,P1 = some 3D points;
|
||||
* Vector3 Delta = P1 - P0;
|
||||
* \endcode
|
||||
*
|
||||
* Subtle things like this are not caught at compile-time, and when you find one in the code, you never know whether it's a mistake
|
||||
* from the author or something you don't get.
|
||||
*
|
||||
* One way to handle it at compile-time would be to use different classes for Point & Vector3, only overloading operator "-" for vectors.
|
||||
* But then, you get a lot of redundant code in thoses classes, and basically it's really a lot of useless work.
|
||||
*
|
||||
* Another way would be to use homogeneous points: w=1 for points, w=0 for vectors. That's why the HPoint class exists. Now, to store
|
||||
* your model's vertices and in most cases, you really want to use Points to save ram.
|
||||
*
|
||||
* \class Point
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Creates a positive unit random vector.
|
||||
* \return Self-reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Point& Point::PositiveUnitRandomVector()
|
||||
{
|
||||
x = UnitRandomFloat();
|
||||
y = UnitRandomFloat();
|
||||
z = UnitRandomFloat();
|
||||
Normalize();
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Creates a unit random vector.
|
||||
* \return Self-reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Point& Point::UnitRandomVector()
|
||||
{
|
||||
x = UnitRandomFloat() - 0.5f;
|
||||
y = UnitRandomFloat() - 0.5f;
|
||||
z = UnitRandomFloat() - 0.5f;
|
||||
Normalize();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Cast operator
|
||||
// WARNING: not inlined
|
||||
Point::operator HPoint() const { return HPoint(x, y, z, 0.0f); }
|
||||
|
||||
Point& Point::Refract(const Point& eye, const Point& n, float refractindex, Point& refracted)
|
||||
{
|
||||
// Point EyePt = eye position
|
||||
// Point p = current vertex
|
||||
// Point n = vertex normal
|
||||
// Point rv = refracted vector
|
||||
// Eye vector - doesn't need to be normalized
|
||||
Point Env;
|
||||
Env.x = eye.x - x;
|
||||
Env.y = eye.y - y;
|
||||
Env.z = eye.z - z;
|
||||
|
||||
float NDotE = n|Env;
|
||||
float NDotN = n|n;
|
||||
NDotE /= refractindex;
|
||||
|
||||
// Refracted vector
|
||||
refracted = n*NDotE - Env*NDotN;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point& Point::ProjectToPlane(const Plane& p)
|
||||
{
|
||||
*this-= (p.d + (*this|p.n))*p.n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Point::ProjectToScreen(float halfrenderwidth, float halfrenderheight, const Matrix4x4& mat, HPoint& projected) const
|
||||
{
|
||||
projected = HPoint(x, y, z, 1.0f) * mat;
|
||||
projected.w = 1.0f / projected.w;
|
||||
|
||||
projected.x*=projected.w;
|
||||
projected.y*=projected.w;
|
||||
projected.z*=projected.w;
|
||||
|
||||
projected.x *= halfrenderwidth; projected.x += halfrenderwidth;
|
||||
projected.y *= -halfrenderheight; projected.y += halfrenderheight;
|
||||
}
|
||||
|
||||
void Point::SetNotUsed()
|
||||
{
|
||||
// We use a particular integer pattern : 0xffffffff everywhere. This is a NAN.
|
||||
IR(x) = 0xffffffff;
|
||||
IR(y) = 0xffffffff;
|
||||
IR(z) = 0xffffffff;
|
||||
}
|
||||
|
||||
BOOL Point::IsNotUsed() const
|
||||
{
|
||||
if(IR(x)!=0xffffffff) return FALSE;
|
||||
if(IR(y)!=0xffffffff) return FALSE;
|
||||
if(IR(z)!=0xffffffff) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Point& Point::Mult(const Matrix3x3& mat, const Point& a)
|
||||
{
|
||||
x = a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2];
|
||||
y = a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2];
|
||||
z = a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point& Point::Mult2(const Matrix3x3& mat1, const Point& a1, const Matrix3x3& mat2, const Point& a2)
|
||||
{
|
||||
x = a1.x * mat1.m[0][0] + a1.y * mat1.m[0][1] + a1.z * mat1.m[0][2] + a2.x * mat2.m[0][0] + a2.y * mat2.m[0][1] + a2.z * mat2.m[0][2];
|
||||
y = a1.x * mat1.m[1][0] + a1.y * mat1.m[1][1] + a1.z * mat1.m[1][2] + a2.x * mat2.m[1][0] + a2.y * mat2.m[1][1] + a2.z * mat2.m[1][2];
|
||||
z = a1.x * mat1.m[2][0] + a1.y * mat1.m[2][1] + a1.z * mat1.m[2][2] + a2.x * mat2.m[2][0] + a2.y * mat2.m[2][1] + a2.z * mat2.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point& Point::Mac(const Matrix3x3& mat, const Point& a)
|
||||
{
|
||||
x += a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2];
|
||||
y += a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2];
|
||||
z += a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point& Point::TransMult(const Matrix3x3& mat, const Point& a)
|
||||
{
|
||||
x = a.x * mat.m[0][0] + a.y * mat.m[1][0] + a.z * mat.m[2][0];
|
||||
y = a.x * mat.m[0][1] + a.y * mat.m[1][1] + a.z * mat.m[2][1];
|
||||
z = a.x * mat.m[0][2] + a.y * mat.m[1][2] + a.z * mat.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point& Point::Transform(const Point& r, const Matrix3x3& rotpos, const Point& linpos)
|
||||
{
|
||||
x = r.x * rotpos.m[0][0] + r.y * rotpos.m[0][1] + r.z * rotpos.m[0][2] + linpos.x;
|
||||
y = r.x * rotpos.m[1][0] + r.y * rotpos.m[1][1] + r.z * rotpos.m[1][2] + linpos.y;
|
||||
z = r.x * rotpos.m[2][0] + r.y * rotpos.m[2][1] + r.z * rotpos.m[2][2] + linpos.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point& Point::InvTransform(const Point& r, const Matrix3x3& rotpos, const Point& linpos)
|
||||
{
|
||||
float sx = r.x - linpos.x;
|
||||
float sy = r.y - linpos.y;
|
||||
float sz = r.z - linpos.z;
|
||||
x = sx * rotpos.m[0][0] + sy * rotpos.m[1][0] + sz * rotpos.m[2][0];
|
||||
y = sx * rotpos.m[0][1] + sy * rotpos.m[1][1] + sz * rotpos.m[2][1];
|
||||
z = sx * rotpos.m[0][2] + sy * rotpos.m[1][2] + sz * rotpos.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,158 +1,158 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains preprocessor stuff. This should be the first included header.
|
||||
* \file IcePreprocessor.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEPREPROCESSOR_H
|
||||
#define ICEPREPROCESSOR_H
|
||||
|
||||
// Check platform
|
||||
#if defined( _WIN32 ) || defined( WIN32 )
|
||||
#pragma message("Compiling on Windows...")
|
||||
#define PLATFORM_WINDOWS
|
||||
#else
|
||||
#pragma message("Compiling on unknown platform...")
|
||||
#endif
|
||||
|
||||
// Check compiler
|
||||
#if defined(_MSC_VER)
|
||||
#pragma message("Compiling with VC++...")
|
||||
#define COMPILER_VISUAL_CPP
|
||||
|
||||
#if _MSC_VER > 1300
|
||||
#pragma message("Compiling with VC7")
|
||||
#define COMPILER_VC7
|
||||
#else
|
||||
#pragma message("Compiling with VC6")
|
||||
#define COMPILER_VC6
|
||||
#endif
|
||||
#else
|
||||
#pragma message("Compiling with unknown compiler...")
|
||||
#endif
|
||||
|
||||
// Check compiler options. If this file is included in user-apps, this
|
||||
// shouldn't be needed, so that they can use what they like best.
|
||||
#ifndef ICE_DONT_CHECK_COMPILER_OPTIONS
|
||||
#ifdef COMPILER_VISUAL_CPP
|
||||
#if defined(_CHAR_UNSIGNED)
|
||||
#endif
|
||||
|
||||
#if defined(_CPPRTTI)
|
||||
#error Please disable RTTI...
|
||||
#endif
|
||||
|
||||
#if defined(_CPPUNWIND)
|
||||
#error Please disable exceptions...
|
||||
#endif
|
||||
|
||||
#if defined(_MT)
|
||||
// Multithreading
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Check debug mode
|
||||
#ifdef DEBUG // May be defined instead of _DEBUG. Let's fix it.
|
||||
#ifndef _DEBUG
|
||||
#define _DEBUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Here you may define items for debug builds
|
||||
#endif
|
||||
|
||||
#ifndef THIS_FILE
|
||||
#define THIS_FILE __FILE__
|
||||
#endif
|
||||
|
||||
#ifndef ICE_NO_DLL
|
||||
#ifdef ICECORE_EXPORTS
|
||||
#define ICECORE_API __declspec(dllexport)
|
||||
#else
|
||||
#define ICECORE_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define ICECORE_API
|
||||
#endif
|
||||
|
||||
#define FUNCTION extern "C"
|
||||
|
||||
// Cosmetic stuff [mainly useful with multiple inheritance]
|
||||
#define override(base_class) virtual
|
||||
|
||||
// Our own inline keyword, so that:
|
||||
// - we can switch to __forceinline to check it's really better or not
|
||||
// - we can remove __forceinline if the compiler doesn't support it
|
||||
// #define inline_ __forceinline
|
||||
// #define inline_ inline
|
||||
|
||||
// Contributed by Bruce Mitchener
|
||||
#if defined(COMPILER_VISUAL_CPP)
|
||||
#define inline_ __forceinline
|
||||
// #define inline_ inline
|
||||
#elif defined(__GNUC__) && __GNUC__ < 3
|
||||
#define inline_ inline
|
||||
#elif defined(__GNUC__)
|
||||
#define inline_ inline __attribute__ ((always_inline))
|
||||
#else
|
||||
#define inline_ inline
|
||||
#endif
|
||||
|
||||
// Down the hatch
|
||||
#pragma inline_depth( 255 )
|
||||
|
||||
#ifdef COMPILER_VISUAL_CPP
|
||||
#pragma intrinsic(memcmp)
|
||||
#pragma intrinsic(memcpy)
|
||||
#pragma intrinsic(memset)
|
||||
#pragma intrinsic(strcat)
|
||||
#pragma intrinsic(strcmp)
|
||||
#pragma intrinsic(strcpy)
|
||||
#pragma intrinsic(strlen)
|
||||
#pragma intrinsic(abs)
|
||||
#pragma intrinsic(labs)
|
||||
#endif
|
||||
|
||||
// ANSI compliance
|
||||
#ifdef _DEBUG
|
||||
// Remove painful warning in debug
|
||||
inline_ bool ReturnsFalse(){ return false; }
|
||||
#define for if(ReturnsFalse()){} else for
|
||||
#else
|
||||
#define for if(0){} else for
|
||||
#endif
|
||||
|
||||
// Don't override new/delete
|
||||
#define DEFAULT_NEWDELETE
|
||||
#define DONT_TRACK_MEMORY_LEAKS
|
||||
|
||||
//! Macro used to give me a clue when it crashes in release and only the assembly is available
|
||||
#define INCLUDE_GUARDIANS
|
||||
#ifdef INCLUDE_GUARDIANS
|
||||
#define GUARD(x) \
|
||||
{ \
|
||||
static const char guard_text[] = x; \
|
||||
_asm push eax \
|
||||
_asm nop \
|
||||
_asm nop \
|
||||
_asm nop \
|
||||
_asm nop \
|
||||
_asm lea eax, guard_text \
|
||||
_asm nop \
|
||||
_asm nop \
|
||||
_asm nop \
|
||||
_asm nop \
|
||||
_asm pop eax \
|
||||
}
|
||||
#else
|
||||
#define GUARD(x)
|
||||
#endif
|
||||
|
||||
#endif // ICEPREPROCESSOR_H
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains preprocessor stuff. This should be the first included header.
|
||||
* \file IcePreprocessor.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEPREPROCESSOR_H
|
||||
#define ICEPREPROCESSOR_H
|
||||
|
||||
// Check platform
|
||||
#if defined( _WIN32 ) || defined( WIN32 )
|
||||
#pragma message("Compiling on Windows...")
|
||||
#define PLATFORM_WINDOWS
|
||||
#else
|
||||
#pragma message("Compiling on unknown platform...")
|
||||
#endif
|
||||
|
||||
// Check compiler
|
||||
#if defined(_MSC_VER)
|
||||
#pragma message("Compiling with VC++...")
|
||||
#define COMPILER_VISUAL_CPP
|
||||
|
||||
#if _MSC_VER > 1300
|
||||
#pragma message("Compiling with VC7")
|
||||
#define COMPILER_VC7
|
||||
#else
|
||||
#pragma message("Compiling with VC6")
|
||||
#define COMPILER_VC6
|
||||
#endif
|
||||
#else
|
||||
#pragma message("Compiling with unknown compiler...")
|
||||
#endif
|
||||
|
||||
// Check compiler options. If this file is included in user-apps, this
|
||||
// shouldn't be needed, so that they can use what they like best.
|
||||
#ifndef ICE_DONT_CHECK_COMPILER_OPTIONS
|
||||
#ifdef COMPILER_VISUAL_CPP
|
||||
#if defined(_CHAR_UNSIGNED)
|
||||
#endif
|
||||
|
||||
#if defined(_CPPRTTI)
|
||||
#error Please disable RTTI...
|
||||
#endif
|
||||
|
||||
#if defined(_CPPUNWIND)
|
||||
#error Please disable exceptions...
|
||||
#endif
|
||||
|
||||
#if defined(_MT)
|
||||
// Multithreading
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Check debug mode
|
||||
#ifdef DEBUG // May be defined instead of _DEBUG. Let's fix it.
|
||||
#ifndef _DEBUG
|
||||
#define _DEBUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Here you may define items for debug builds
|
||||
#endif
|
||||
|
||||
#ifndef THIS_FILE
|
||||
#define THIS_FILE __FILE__
|
||||
#endif
|
||||
|
||||
#ifndef ICE_NO_DLL
|
||||
#ifdef ICECORE_EXPORTS
|
||||
#define ICECORE_API __declspec(dllexport)
|
||||
#else
|
||||
#define ICECORE_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define ICECORE_API
|
||||
#endif
|
||||
|
||||
#define FUNCTION extern "C"
|
||||
|
||||
// Cosmetic stuff [mainly useful with multiple inheritance]
|
||||
#define override(base_class) virtual
|
||||
|
||||
// Our own inline keyword, so that:
|
||||
// - we can switch to __forceinline to check it's really better or not
|
||||
// - we can remove __forceinline if the compiler doesn't support it
|
||||
// #define inline_ __forceinline
|
||||
// #define inline_ inline
|
||||
|
||||
// Contributed by Bruce Mitchener
|
||||
#if defined(COMPILER_VISUAL_CPP)
|
||||
#define inline_ __forceinline
|
||||
// #define inline_ inline
|
||||
#elif defined(__GNUC__) && __GNUC__ < 3
|
||||
#define inline_ inline
|
||||
#elif defined(__GNUC__)
|
||||
#define inline_ inline __attribute__ ((always_inline))
|
||||
#else
|
||||
#define inline_ inline
|
||||
#endif
|
||||
|
||||
// Down the hatch
|
||||
#pragma inline_depth( 255 )
|
||||
|
||||
#ifdef COMPILER_VISUAL_CPP
|
||||
#pragma intrinsic(memcmp)
|
||||
#pragma intrinsic(memcpy)
|
||||
#pragma intrinsic(memset)
|
||||
#pragma intrinsic(strcat)
|
||||
#pragma intrinsic(strcmp)
|
||||
#pragma intrinsic(strcpy)
|
||||
#pragma intrinsic(strlen)
|
||||
#pragma intrinsic(abs)
|
||||
#pragma intrinsic(labs)
|
||||
#endif
|
||||
|
||||
// ANSI compliance
|
||||
#ifdef _DEBUG
|
||||
// Remove painful warning in debug
|
||||
inline_ bool ReturnsFalse(){ return false; }
|
||||
#define for if(ReturnsFalse()){} else for
|
||||
#else
|
||||
#define for if(0){} else for
|
||||
#endif
|
||||
|
||||
// Don't override new/delete
|
||||
#define DEFAULT_NEWDELETE
|
||||
#define DONT_TRACK_MEMORY_LEAKS
|
||||
|
||||
//! Macro used to give me a clue when it crashes in release and only the assembly is available
|
||||
#define INCLUDE_GUARDIANS
|
||||
#ifdef INCLUDE_GUARDIANS
|
||||
#define GUARD(x) \
|
||||
{ \
|
||||
static const char guard_text[] = x; \
|
||||
_asm push eax \
|
||||
_asm nop \
|
||||
_asm nop \
|
||||
_asm nop \
|
||||
_asm nop \
|
||||
_asm lea eax, guard_text \
|
||||
_asm nop \
|
||||
_asm nop \
|
||||
_asm nop \
|
||||
_asm nop \
|
||||
_asm pop eax \
|
||||
}
|
||||
#else
|
||||
#define GUARD(x)
|
||||
#endif
|
||||
|
||||
#endif // ICEPREPROCESSOR_H
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for random generators.
|
||||
* \file IceRandom.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date August, 9, 2001
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
void IceCore:: SRand(udword seed)
|
||||
{
|
||||
srand(seed);
|
||||
}
|
||||
|
||||
udword IceCore::Rand()
|
||||
{
|
||||
return rand();
|
||||
}
|
||||
|
||||
|
||||
static BasicRandom gRandomGenerator(42);
|
||||
|
||||
udword IceCore::GetRandomIndex(udword max_index)
|
||||
{
|
||||
// We don't use rand() since it's limited to RAND_MAX
|
||||
udword Index = gRandomGenerator.Randomize();
|
||||
return Index % max_index;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for random generators.
|
||||
* \file IceRandom.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date August, 9, 2001
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
void IceCore:: SRand(udword seed)
|
||||
{
|
||||
srand(seed);
|
||||
}
|
||||
|
||||
udword IceCore::Rand()
|
||||
{
|
||||
return rand();
|
||||
}
|
||||
|
||||
|
||||
static BasicRandom gRandomGenerator(42);
|
||||
|
||||
udword IceCore::GetRandomIndex(udword max_index)
|
||||
{
|
||||
// We don't use rand() since it's limited to RAND_MAX
|
||||
udword Index = gRandomGenerator.Randomize();
|
||||
return Index % max_index;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,58 +1,58 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for random generators.
|
||||
* \file IceRandom.h
|
||||
* \author Pierre Terdiman
|
||||
* \date August, 9, 2001
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICERANDOM_H__
|
||||
#define __ICERANDOM_H__
|
||||
|
||||
FUNCTION ICECORE_API void SRand(udword seed);
|
||||
FUNCTION ICECORE_API udword Rand();
|
||||
|
||||
//! Returns a unit random floating-point value
|
||||
inline_ float UnitRandomFloat() { return float(Rand()) * ONE_OVER_RAND_MAX; }
|
||||
|
||||
//! Returns a random index so that 0<= index < max_index
|
||||
ICECORE_API udword GetRandomIndex(udword max_index);
|
||||
|
||||
class ICECORE_API BasicRandom
|
||||
{
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
inline_ BasicRandom(udword seed=0) : mRnd(seed) {}
|
||||
//! Destructor
|
||||
inline_ ~BasicRandom() {}
|
||||
|
||||
inline_ void SetSeed(udword seed) { mRnd = seed; }
|
||||
inline_ udword GetCurrentValue() const { return mRnd; }
|
||||
inline_ udword Randomize() { mRnd = mRnd * 2147001325 + 715136305; return mRnd; }
|
||||
|
||||
private:
|
||||
udword mRnd;
|
||||
};
|
||||
|
||||
#endif // __ICERANDOM_H__
|
||||
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for random generators.
|
||||
* \file IceRandom.h
|
||||
* \author Pierre Terdiman
|
||||
* \date August, 9, 2001
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICERANDOM_H__
|
||||
#define __ICERANDOM_H__
|
||||
|
||||
FUNCTION ICECORE_API void SRand(udword seed);
|
||||
FUNCTION ICECORE_API udword Rand();
|
||||
|
||||
//! Returns a unit random floating-point value
|
||||
inline_ float UnitRandomFloat() { return float(Rand()) * ONE_OVER_RAND_MAX; }
|
||||
|
||||
//! Returns a random index so that 0<= index < max_index
|
||||
ICECORE_API udword GetRandomIndex(udword max_index);
|
||||
|
||||
class ICECORE_API BasicRandom
|
||||
{
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
inline_ BasicRandom(udword seed=0) : mRnd(seed) {}
|
||||
//! Destructor
|
||||
inline_ ~BasicRandom() {}
|
||||
|
||||
inline_ void SetSeed(udword seed) { mRnd = seed; }
|
||||
inline_ udword GetCurrentValue() const { return mRnd; }
|
||||
inline_ udword Randomize() { mRnd = mRnd * 2147001325 + 715136305; return mRnd; }
|
||||
|
||||
private:
|
||||
udword mRnd;
|
||||
};
|
||||
|
||||
#endif // __ICERANDOM_H__
|
||||
|
||||
|
||||
@@ -1,100 +1,100 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for rays.
|
||||
* \file IceRay.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Ray class.
|
||||
* A ray is a half-line P(t) = mOrig + mDir * t, with 0 <= t <= +infinity
|
||||
* \class Ray
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
O = Origin = impact point
|
||||
i = normalized vector along the x axis
|
||||
j = normalized vector along the y axis = actually the normal vector in O
|
||||
D = Direction vector, norm |D| = 1
|
||||
N = Projection of D on y axis, norm |N| = normal reaction
|
||||
T = Projection of D on x axis, norm |T| = tangential reaction
|
||||
R = Reflexion vector
|
||||
|
||||
^y
|
||||
|
|
||||
|
|
||||
|
|
||||
_ _ _| _ _ _
|
||||
* * *|
|
||||
\ | /
|
||||
\ |N / |
|
||||
R\ | /D
|
||||
\ | / |
|
||||
\ | /
|
||||
_________\|/______*_______>x
|
||||
O T
|
||||
|
||||
Let define theta = angle between D and N. Then cos(theta) = |N| / |D| = |N| since D is normalized.
|
||||
|
||||
j|D = |j|*|D|*cos(theta) => |N| = j|D
|
||||
|
||||
Then we simply have:
|
||||
|
||||
D = N + T
|
||||
|
||||
To compute tangential reaction :
|
||||
|
||||
T = D - N
|
||||
|
||||
To compute reflexion vector :
|
||||
|
||||
R = N - T = N - (D-N) = 2*N - D
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
float Ray::SquareDistance(const Point& point, float* t) const
|
||||
{
|
||||
Point Diff = point - mOrig;
|
||||
float fT = Diff | mDir;
|
||||
|
||||
if(fT<=0.0f)
|
||||
{
|
||||
fT = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
fT /= mDir.SquareMagnitude();
|
||||
Diff -= fT*mDir;
|
||||
}
|
||||
|
||||
if(t) *t = fT;
|
||||
|
||||
return Diff.SquareMagnitude();
|
||||
}
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for rays.
|
||||
* \file IceRay.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Ray class.
|
||||
* A ray is a half-line P(t) = mOrig + mDir * t, with 0 <= t <= +infinity
|
||||
* \class Ray
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
O = Origin = impact point
|
||||
i = normalized vector along the x axis
|
||||
j = normalized vector along the y axis = actually the normal vector in O
|
||||
D = Direction vector, norm |D| = 1
|
||||
N = Projection of D on y axis, norm |N| = normal reaction
|
||||
T = Projection of D on x axis, norm |T| = tangential reaction
|
||||
R = Reflexion vector
|
||||
|
||||
^y
|
||||
|
|
||||
|
|
||||
|
|
||||
_ _ _| _ _ _
|
||||
* * *|
|
||||
\ | /
|
||||
\ |N / |
|
||||
R\ | /D
|
||||
\ | / |
|
||||
\ | /
|
||||
_________\|/______*_______>x
|
||||
O T
|
||||
|
||||
Let define theta = angle between D and N. Then cos(theta) = |N| / |D| = |N| since D is normalized.
|
||||
|
||||
j|D = |j|*|D|*cos(theta) => |N| = j|D
|
||||
|
||||
Then we simply have:
|
||||
|
||||
D = N + T
|
||||
|
||||
To compute tangential reaction :
|
||||
|
||||
T = D - N
|
||||
|
||||
To compute reflexion vector :
|
||||
|
||||
R = N - T = N - (D-N) = 2*N - D
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
float Ray::SquareDistance(const Point& point, float* t) const
|
||||
{
|
||||
Point Diff = point - mOrig;
|
||||
float fT = Diff | mDir;
|
||||
|
||||
if(fT<=0.0f)
|
||||
{
|
||||
fT = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
fT /= mDir.SquareMagnitude();
|
||||
Diff -= fT*mDir;
|
||||
}
|
||||
|
||||
if(t) *t = fT;
|
||||
|
||||
return Diff.SquareMagnitude();
|
||||
}
|
||||
|
||||
@@ -1,114 +1,114 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for rays.
|
||||
* \file IceRay.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICERAY_H__
|
||||
#define __ICERAY_H__
|
||||
|
||||
class ICEMATHS_API Ray
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ Ray() {}
|
||||
//! Constructor
|
||||
inline_ Ray(const Point& orig, const Point& dir) : mOrig(orig), mDir(dir) {}
|
||||
//! Copy constructor
|
||||
inline_ Ray(const Ray& ray) : mOrig(ray.mOrig), mDir(ray.mDir) {}
|
||||
//! Destructor
|
||||
inline_ ~Ray() {}
|
||||
|
||||
float SquareDistance(const Point& point, float* t=null) const;
|
||||
inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); }
|
||||
|
||||
Point mOrig; //!< Ray origin
|
||||
Point mDir; //!< Normalized direction
|
||||
};
|
||||
|
||||
inline_ void ComputeReflexionVector(Point& reflected, const Point& incoming_dir, const Point& outward_normal)
|
||||
{
|
||||
reflected = incoming_dir - outward_normal * 2.0f * (incoming_dir|outward_normal);
|
||||
}
|
||||
|
||||
inline_ void ComputeReflexionVector(Point& reflected, const Point& source, const Point& impact, const Point& normal)
|
||||
{
|
||||
Point V = impact - source;
|
||||
reflected = V - normal * 2.0f * (V|normal);
|
||||
}
|
||||
|
||||
inline_ void DecomposeVector(Point& normal_compo, Point& tangent_compo, const Point& outward_dir, const Point& outward_normal)
|
||||
{
|
||||
normal_compo = outward_normal * (outward_dir|outward_normal);
|
||||
tangent_compo = outward_dir - normal_compo;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Transforms a direction vector from world space to local space
|
||||
* \param local_dir [out] direction vector in local space
|
||||
* \param world_dir [in] direction vector in world space
|
||||
* \param world [in] world transform
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void ComputeLocalDirection(Point& local_dir, const Point& world_dir, const Matrix4x4& world)
|
||||
{
|
||||
// Get world direction back in local space
|
||||
// Matrix3x3 InvWorld = world;
|
||||
// local_dir = InvWorld * world_dir;
|
||||
local_dir = Matrix3x3(world) * world_dir;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Transforms a position vector from world space to local space
|
||||
* \param local_pt [out] position vector in local space
|
||||
* \param world_pt [in] position vector in world space
|
||||
* \param world [in] world transform
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void ComputeLocalPoint(Point& local_pt, const Point& world_pt, const Matrix4x4& world)
|
||||
{
|
||||
// Get world vertex back in local space
|
||||
Matrix4x4 InvWorld = world;
|
||||
InvWorld.Invert();
|
||||
local_pt = world_pt * InvWorld;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Transforms a ray from world space to local space
|
||||
* \param local_ray [out] ray in local space
|
||||
* \param world_ray [in] ray in world space
|
||||
* \param world [in] world transform
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void ComputeLocalRay(Ray& local_ray, const Ray& world_ray, const Matrix4x4& world)
|
||||
{
|
||||
// Get world ray back in local space
|
||||
ComputeLocalDirection(local_ray.mDir, world_ray.mDir, world);
|
||||
ComputeLocalPoint(local_ray.mOrig, world_ray.mOrig, world);
|
||||
}
|
||||
|
||||
#endif // __ICERAY_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for rays.
|
||||
* \file IceRay.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICERAY_H__
|
||||
#define __ICERAY_H__
|
||||
|
||||
class ICEMATHS_API Ray
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ Ray() {}
|
||||
//! Constructor
|
||||
inline_ Ray(const Point& orig, const Point& dir) : mOrig(orig), mDir(dir) {}
|
||||
//! Copy constructor
|
||||
inline_ Ray(const Ray& ray) : mOrig(ray.mOrig), mDir(ray.mDir) {}
|
||||
//! Destructor
|
||||
inline_ ~Ray() {}
|
||||
|
||||
float SquareDistance(const Point& point, float* t=null) const;
|
||||
inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); }
|
||||
|
||||
Point mOrig; //!< Ray origin
|
||||
Point mDir; //!< Normalized direction
|
||||
};
|
||||
|
||||
inline_ void ComputeReflexionVector(Point& reflected, const Point& incoming_dir, const Point& outward_normal)
|
||||
{
|
||||
reflected = incoming_dir - outward_normal * 2.0f * (incoming_dir|outward_normal);
|
||||
}
|
||||
|
||||
inline_ void ComputeReflexionVector(Point& reflected, const Point& source, const Point& impact, const Point& normal)
|
||||
{
|
||||
Point V = impact - source;
|
||||
reflected = V - normal * 2.0f * (V|normal);
|
||||
}
|
||||
|
||||
inline_ void DecomposeVector(Point& normal_compo, Point& tangent_compo, const Point& outward_dir, const Point& outward_normal)
|
||||
{
|
||||
normal_compo = outward_normal * (outward_dir|outward_normal);
|
||||
tangent_compo = outward_dir - normal_compo;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Transforms a direction vector from world space to local space
|
||||
* \param local_dir [out] direction vector in local space
|
||||
* \param world_dir [in] direction vector in world space
|
||||
* \param world [in] world transform
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void ComputeLocalDirection(Point& local_dir, const Point& world_dir, const Matrix4x4& world)
|
||||
{
|
||||
// Get world direction back in local space
|
||||
// Matrix3x3 InvWorld = world;
|
||||
// local_dir = InvWorld * world_dir;
|
||||
local_dir = Matrix3x3(world) * world_dir;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Transforms a position vector from world space to local space
|
||||
* \param local_pt [out] position vector in local space
|
||||
* \param world_pt [in] position vector in world space
|
||||
* \param world [in] world transform
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void ComputeLocalPoint(Point& local_pt, const Point& world_pt, const Matrix4x4& world)
|
||||
{
|
||||
// Get world vertex back in local space
|
||||
Matrix4x4 InvWorld = world;
|
||||
InvWorld.Invert();
|
||||
local_pt = world_pt * InvWorld;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Transforms a ray from world space to local space
|
||||
* \param local_ray [out] ray in local space
|
||||
* \param world_ray [in] ray in world space
|
||||
* \param world [in] world transform
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void ComputeLocalRay(Ray& local_ray, const Ray& world_ray, const Matrix4x4& world)
|
||||
{
|
||||
// Get world ray back in local space
|
||||
ComputeLocalDirection(local_ray.mDir, world_ray.mDir, world);
|
||||
ComputeLocalPoint(local_ray.mOrig, world_ray.mOrig, world);
|
||||
}
|
||||
|
||||
#endif // __ICERAY_H__
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,74 +1,74 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains source code from the article "Radix Sort Revisited".
|
||||
* \file IceRevisitedRadix.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICERADIXSORT_H
|
||||
#define ICERADIXSORT_H
|
||||
|
||||
//! Allocate histograms & offsets locally
|
||||
#define RADIX_LOCAL_RAM
|
||||
|
||||
enum RadixHint
|
||||
{
|
||||
RADIX_SIGNED, //!< Input values are signed
|
||||
RADIX_UNSIGNED, //!< Input values are unsigned
|
||||
|
||||
RADIX_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
class ICECORE_API RadixSort : public Allocateable
|
||||
{
|
||||
public:
|
||||
// Constructor/Destructor
|
||||
RadixSort();
|
||||
~RadixSort();
|
||||
// Sorting methods
|
||||
RadixSort& Sort(const udword* input, udword nb, RadixHint hint=RADIX_SIGNED);
|
||||
RadixSort& Sort(const float* input, udword nb);
|
||||
|
||||
//! Access to results. mRanks is a list of indices in sorted order, i.e. in the order you may further process your data
|
||||
inline_ const udword* GetRanks() const { return mRanks; }
|
||||
|
||||
//! mIndices2 gets trashed on calling the sort routine, but otherwise you can recycle it the way you want.
|
||||
inline_ udword* GetRecyclable() const { return mRanks2; }
|
||||
|
||||
// Stats
|
||||
udword GetUsedRam() const;
|
||||
//! Returns the total number of calls to the radix sorter.
|
||||
inline_ udword GetNbTotalCalls() const { return mTotalCalls; }
|
||||
//! Returns the number of eraly exits due to temporal coherence.
|
||||
inline_ udword GetNbHits() const { return mNbHits; }
|
||||
|
||||
bool SetRankBuffers(udword* ranks0, udword* ranks1);
|
||||
|
||||
PREVENT_COPY(RadixSort)
|
||||
private:
|
||||
#ifndef RADIX_LOCAL_RAM
|
||||
udword* mHistogram; //!< Counters for each byte
|
||||
udword* mOffset; //!< Offsets (nearly a cumulative distribution function)
|
||||
#endif
|
||||
udword mCurrentSize; //!< Current size of the indices list
|
||||
udword* mRanks; //!< Two lists, swapped each pass
|
||||
udword* mRanks2;
|
||||
// Stats
|
||||
udword mTotalCalls; //!< Total number of calls to the sort routine
|
||||
udword mNbHits; //!< Number of early exits due to coherence
|
||||
// Stack-radix
|
||||
bool mDeleteRanks; //!<
|
||||
// Internal methods
|
||||
void CheckResize(udword nb);
|
||||
bool Resize(udword nb);
|
||||
};
|
||||
|
||||
#define StackRadixSort(name, ranks0, ranks1) \
|
||||
RadixSort name; \
|
||||
name.SetRankBuffers(ranks0, ranks1);
|
||||
|
||||
#endif // ICERADIXSORT_H
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains source code from the article "Radix Sort Revisited".
|
||||
* \file IceRevisitedRadix.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICERADIXSORT_H
|
||||
#define ICERADIXSORT_H
|
||||
|
||||
//! Allocate histograms & offsets locally
|
||||
#define RADIX_LOCAL_RAM
|
||||
|
||||
enum RadixHint
|
||||
{
|
||||
RADIX_SIGNED, //!< Input values are signed
|
||||
RADIX_UNSIGNED, //!< Input values are unsigned
|
||||
|
||||
RADIX_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
class ICECORE_API RadixSort : public Allocateable
|
||||
{
|
||||
public:
|
||||
// Constructor/Destructor
|
||||
RadixSort();
|
||||
~RadixSort();
|
||||
// Sorting methods
|
||||
RadixSort& Sort(const udword* input, udword nb, RadixHint hint=RADIX_SIGNED);
|
||||
RadixSort& Sort(const float* input, udword nb);
|
||||
|
||||
//! Access to results. mRanks is a list of indices in sorted order, i.e. in the order you may further process your data
|
||||
inline_ const udword* GetRanks() const { return mRanks; }
|
||||
|
||||
//! mIndices2 gets trashed on calling the sort routine, but otherwise you can recycle it the way you want.
|
||||
inline_ udword* GetRecyclable() const { return mRanks2; }
|
||||
|
||||
// Stats
|
||||
udword GetUsedRam() const;
|
||||
//! Returns the total number of calls to the radix sorter.
|
||||
inline_ udword GetNbTotalCalls() const { return mTotalCalls; }
|
||||
//! Returns the number of eraly exits due to temporal coherence.
|
||||
inline_ udword GetNbHits() const { return mNbHits; }
|
||||
|
||||
bool SetRankBuffers(udword* ranks0, udword* ranks1);
|
||||
|
||||
PREVENT_COPY(RadixSort)
|
||||
private:
|
||||
#ifndef RADIX_LOCAL_RAM
|
||||
udword* mHistogram; //!< Counters for each byte
|
||||
udword* mOffset; //!< Offsets (nearly a cumulative distribution function)
|
||||
#endif
|
||||
udword mCurrentSize; //!< Current size of the indices list
|
||||
udword* mRanks; //!< Two lists, swapped each pass
|
||||
udword* mRanks2;
|
||||
// Stats
|
||||
udword mTotalCalls; //!< Total number of calls to the sort routine
|
||||
udword mNbHits; //!< Number of early exits due to coherence
|
||||
// Stack-radix
|
||||
bool mDeleteRanks; //!<
|
||||
// Internal methods
|
||||
void CheckResize(udword nb);
|
||||
bool Resize(udword nb);
|
||||
};
|
||||
|
||||
#define StackRadixSort(name, ranks0, ranks1) \
|
||||
RadixSort name; \
|
||||
name.SetRankBuffers(ranks0, ranks1);
|
||||
|
||||
#endif // ICERADIXSORT_H
|
||||
|
||||
@@ -1,73 +1,73 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for segments.
|
||||
* \file IceSegment.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Segment class.
|
||||
* A segment is defined by S(t) = mP0 * (1 - t) + mP1 * t, with 0 <= t <= 1
|
||||
* Alternatively, a segment is S(t) = Origin + t * Direction for 0 <= t <= 1.
|
||||
* Direction is not necessarily unit length. The end points are Origin = mP0 and Origin + Direction = mP1.
|
||||
*
|
||||
* \class Segment
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
float Segment::SquareDistance(const Point& point, float* t) const
|
||||
{
|
||||
Point Diff = point - mP0;
|
||||
Point Dir = mP1 - mP0;
|
||||
float fT = Diff | Dir;
|
||||
|
||||
if(fT<=0.0f)
|
||||
{
|
||||
fT = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
float SqrLen= Dir.SquareMagnitude();
|
||||
if(fT>=SqrLen)
|
||||
{
|
||||
fT = 1.0f;
|
||||
Diff -= Dir;
|
||||
}
|
||||
else
|
||||
{
|
||||
fT /= SqrLen;
|
||||
Diff -= fT*Dir;
|
||||
}
|
||||
}
|
||||
|
||||
if(t) *t = fT;
|
||||
|
||||
return Diff.SquareMagnitude();
|
||||
}
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for segments.
|
||||
* \file IceSegment.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Segment class.
|
||||
* A segment is defined by S(t) = mP0 * (1 - t) + mP1 * t, with 0 <= t <= 1
|
||||
* Alternatively, a segment is S(t) = Origin + t * Direction for 0 <= t <= 1.
|
||||
* Direction is not necessarily unit length. The end points are Origin = mP0 and Origin + Direction = mP1.
|
||||
*
|
||||
* \class Segment
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
float Segment::SquareDistance(const Point& point, float* t) const
|
||||
{
|
||||
Point Diff = point - mP0;
|
||||
Point Dir = mP1 - mP0;
|
||||
float fT = Diff | Dir;
|
||||
|
||||
if(fT<=0.0f)
|
||||
{
|
||||
fT = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
float SqrLen= Dir.SquareMagnitude();
|
||||
if(fT>=SqrLen)
|
||||
{
|
||||
fT = 1.0f;
|
||||
Diff -= Dir;
|
||||
}
|
||||
else
|
||||
{
|
||||
fT /= SqrLen;
|
||||
Diff -= fT*Dir;
|
||||
}
|
||||
}
|
||||
|
||||
if(t) *t = fT;
|
||||
|
||||
return Diff.SquareMagnitude();
|
||||
}
|
||||
|
||||
@@ -1,71 +1,71 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for segments.
|
||||
* \file IceSegment.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICESEGMENT_H__
|
||||
#define __ICESEGMENT_H__
|
||||
|
||||
class ICEMATHS_API Segment
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ Segment() {}
|
||||
//! Constructor
|
||||
inline_ Segment(const Point& p0, const Point& p1) : mP0(p0), mP1(p1) {}
|
||||
//! Copy constructor
|
||||
inline_ Segment(const Segment& seg) : mP0(seg.mP0), mP1(seg.mP1) {}
|
||||
//! Destructor
|
||||
inline_ ~Segment() {}
|
||||
|
||||
inline_ const Point& GetOrigin() const { return mP0; }
|
||||
inline_ Point ComputeDirection() const { return mP1 - mP0; }
|
||||
inline_ void ComputeDirection(Point& dir) const { dir = mP1 - mP0; }
|
||||
inline_ float ComputeLength() const { return mP1.Distance(mP0); }
|
||||
inline_ float ComputeSquareLength() const { return mP1.SquareDistance(mP0); }
|
||||
|
||||
inline_ void SetOriginDirection(const Point& origin, const Point& direction)
|
||||
{
|
||||
mP0 = mP1 = origin;
|
||||
mP1 += direction;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes a point on the segment
|
||||
* \param pt [out] point on segment
|
||||
* \param t [in] point's parameter [t=0 => pt = mP0, t=1 => pt = mP1]
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void ComputePoint(Point& pt, float t) const { pt = mP0 + t * (mP1 - mP0); }
|
||||
|
||||
float SquareDistance(const Point& point, float* t=null) const;
|
||||
inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); }
|
||||
|
||||
Point mP0; //!< Start of segment
|
||||
Point mP1; //!< End of segment
|
||||
};
|
||||
|
||||
#endif // __ICESEGMENT_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for segments.
|
||||
* \file IceSegment.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICESEGMENT_H__
|
||||
#define __ICESEGMENT_H__
|
||||
|
||||
class ICEMATHS_API Segment
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ Segment() {}
|
||||
//! Constructor
|
||||
inline_ Segment(const Point& p0, const Point& p1) : mP0(p0), mP1(p1) {}
|
||||
//! Copy constructor
|
||||
inline_ Segment(const Segment& seg) : mP0(seg.mP0), mP1(seg.mP1) {}
|
||||
//! Destructor
|
||||
inline_ ~Segment() {}
|
||||
|
||||
inline_ const Point& GetOrigin() const { return mP0; }
|
||||
inline_ Point ComputeDirection() const { return mP1 - mP0; }
|
||||
inline_ void ComputeDirection(Point& dir) const { dir = mP1 - mP0; }
|
||||
inline_ float ComputeLength() const { return mP1.Distance(mP0); }
|
||||
inline_ float ComputeSquareLength() const { return mP1.SquareDistance(mP0); }
|
||||
|
||||
inline_ void SetOriginDirection(const Point& origin, const Point& direction)
|
||||
{
|
||||
mP0 = mP1 = origin;
|
||||
mP1 += direction;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes a point on the segment
|
||||
* \param pt [out] point on segment
|
||||
* \param t [in] point's parameter [t=0 => pt = mP0, t=1 => pt = mP1]
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void ComputePoint(Point& pt, float t) const { pt = mP0 + t * (mP1 - mP0); }
|
||||
|
||||
float SquareDistance(const Point& point, float* t=null) const;
|
||||
inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); }
|
||||
|
||||
Point mP0; //!< Start of segment
|
||||
Point mP1; //!< End of segment
|
||||
};
|
||||
|
||||
#endif // __ICESEGMENT_H__
|
||||
|
||||
@@ -1,302 +1,302 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a handy triangle class.
|
||||
* \file IceTriangle.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 17, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a triangle class.
|
||||
*
|
||||
* \class Tri
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
* \date 08.15.98
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static sdword VPlaneSideEps(const Point& v, const Plane& plane, float epsilon)
|
||||
{
|
||||
// Compute distance from current vertex to the plane
|
||||
float Dist = plane.Distance(v);
|
||||
// Compute side:
|
||||
// 1 = the vertex is on the positive side of the plane
|
||||
// -1 = the vertex is on the negative side of the plane
|
||||
// 0 = the vertex is on the plane (within epsilon)
|
||||
return Dist > epsilon ? 1 : Dist < -epsilon ? -1 : 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Flips the winding order.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Triangle::Flip()
|
||||
{
|
||||
Point Tmp = mVerts[1];
|
||||
mVerts[1] = mVerts[2];
|
||||
mVerts[2] = Tmp;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle area.
|
||||
* \return the area
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Triangle::Area() const
|
||||
{
|
||||
const Point& p0 = mVerts[0];
|
||||
const Point& p1 = mVerts[1];
|
||||
const Point& p2 = mVerts[2];
|
||||
return ((p0 - p1)^(p0 - p2)).Magnitude() * 0.5f;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle perimeter.
|
||||
* \return the perimeter
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Triangle::Perimeter() const
|
||||
{
|
||||
const Point& p0 = mVerts[0];
|
||||
const Point& p1 = mVerts[1];
|
||||
const Point& p2 = mVerts[2];
|
||||
return p0.Distance(p1)
|
||||
+ p0.Distance(p2)
|
||||
+ p1.Distance(p2);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle compacity.
|
||||
* \return the compacity
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Triangle::Compacity() const
|
||||
{
|
||||
float P = Perimeter();
|
||||
if(P==0.0f) return 0.0f;
|
||||
return (4.0f*PI*Area()/(P*P));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle normal.
|
||||
* \param normal [out] the computed normal
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Triangle::Normal(Point& normal) const
|
||||
{
|
||||
const Point& p0 = mVerts[0];
|
||||
const Point& p1 = mVerts[1];
|
||||
const Point& p2 = mVerts[2];
|
||||
normal = ((p0 - p1)^(p0 - p2)).Normalize();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle denormalized normal.
|
||||
* \param normal [out] the computed normal
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Triangle::DenormalizedNormal(Point& normal) const
|
||||
{
|
||||
const Point& p0 = mVerts[0];
|
||||
const Point& p1 = mVerts[1];
|
||||
const Point& p2 = mVerts[2];
|
||||
normal = ((p0 - p1)^(p0 - p2));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle center.
|
||||
* \param center [out] the computed center
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Triangle::Center(Point& center) const
|
||||
{
|
||||
const Point& p0 = mVerts[0];
|
||||
const Point& p1 = mVerts[1];
|
||||
const Point& p2 = mVerts[2];
|
||||
center = (p0 + p1 + p2)*INV3;
|
||||
}
|
||||
|
||||
PartVal Triangle::TestAgainstPlane(const Plane& plane, float epsilon) const
|
||||
{
|
||||
bool Pos = false, Neg = false;
|
||||
|
||||
// Loop through all vertices
|
||||
for(udword i=0;i<3;i++)
|
||||
{
|
||||
// Compute side:
|
||||
sdword Side = VPlaneSideEps(mVerts[i], plane, epsilon);
|
||||
|
||||
if (Side < 0) Neg = true;
|
||||
else if (Side > 0) Pos = true;
|
||||
}
|
||||
|
||||
if (!Pos && !Neg) return TRI_ON_PLANE;
|
||||
else if (Pos && Neg) return TRI_INTERSECT;
|
||||
else if (Pos && !Neg) return TRI_PLUS_SPACE;
|
||||
else if (!Pos && Neg) return TRI_MINUS_SPACE;
|
||||
|
||||
// What?!
|
||||
return TRI_FORCEDWORD;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle moment.
|
||||
* \param m [out] the moment
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
void Triangle::ComputeMoment(Moment& m)
|
||||
{
|
||||
// Compute the area of the triangle
|
||||
m.mArea = Area();
|
||||
|
||||
// Compute the centroid
|
||||
Center(m.mCentroid);
|
||||
|
||||
// Second-order components. Handle zero-area faces.
|
||||
Point& p = mVerts[0];
|
||||
Point& q = mVerts[1];
|
||||
Point& r = mVerts[2];
|
||||
if(m.mArea==0.0f)
|
||||
{
|
||||
// This triangle has zero area. The second order components would be eliminated with the usual formula, so, for the
|
||||
// sake of robustness we use an alternative form. These are the centroid and second-order components of the triangle's vertices.
|
||||
m.mCovariance.m[0][0] = (p.x*p.x + q.x*q.x + r.x*r.x);
|
||||
m.mCovariance.m[0][1] = (p.x*p.y + q.x*q.y + r.x*r.y);
|
||||
m.mCovariance.m[0][2] = (p.x*p.z + q.x*q.z + r.x*r.z);
|
||||
m.mCovariance.m[1][1] = (p.y*p.y + q.y*q.y + r.y*r.y);
|
||||
m.mCovariance.m[1][2] = (p.y*p.z + q.y*q.z + r.y*r.z);
|
||||
m.mCovariance.m[2][2] = (p.z*p.z + q.z*q.z + r.z*r.z);
|
||||
m.mCovariance.m[2][1] = m.mCovariance.m[1][2];
|
||||
m.mCovariance.m[1][0] = m.mCovariance.m[0][1];
|
||||
m.mCovariance.m[2][0] = m.mCovariance.m[0][2];
|
||||
}
|
||||
else
|
||||
{
|
||||
const float OneOverTwelve = 1.0f / 12.0f;
|
||||
m.mCovariance.m[0][0] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.x + p.x*p.x + q.x*q.x + r.x*r.x) * OneOverTwelve;
|
||||
m.mCovariance.m[0][1] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.y + p.x*p.y + q.x*q.y + r.x*r.y) * OneOverTwelve;
|
||||
m.mCovariance.m[1][1] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.y + p.y*p.y + q.y*q.y + r.y*r.y) * OneOverTwelve;
|
||||
m.mCovariance.m[0][2] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.z + p.x*p.z + q.x*q.z + r.x*r.z) * OneOverTwelve;
|
||||
m.mCovariance.m[1][2] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.z + p.y*p.z + q.y*q.z + r.y*r.z) * OneOverTwelve;
|
||||
m.mCovariance.m[2][2] = m.mArea * (9.0f * m.mCentroid.z*m.mCentroid.z + p.z*p.z + q.z*q.z + r.z*r.z) * OneOverTwelve;
|
||||
m.mCovariance.m[2][1] = m.mCovariance.m[1][2];
|
||||
m.mCovariance.m[1][0] = m.mCovariance.m[0][1];
|
||||
m.mCovariance.m[2][0] = m.mCovariance.m[0][2];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle's smallest edge length.
|
||||
* \return the smallest edge length
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Triangle::MinEdgeLength() const
|
||||
{
|
||||
float Min = MAX_FLOAT;
|
||||
float Length01 = mVerts[0].Distance(mVerts[1]);
|
||||
float Length02 = mVerts[0].Distance(mVerts[2]);
|
||||
float Length12 = mVerts[1].Distance(mVerts[2]);
|
||||
if(Length01 < Min) Min = Length01;
|
||||
if(Length02 < Min) Min = Length02;
|
||||
if(Length12 < Min) Min = Length12;
|
||||
return Min;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle's largest edge length.
|
||||
* \return the largest edge length
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Triangle::MaxEdgeLength() const
|
||||
{
|
||||
float Max = MIN_FLOAT;
|
||||
float Length01 = mVerts[0].Distance(mVerts[1]);
|
||||
float Length02 = mVerts[0].Distance(mVerts[2]);
|
||||
float Length12 = mVerts[1].Distance(mVerts[2]);
|
||||
if(Length01 > Max) Max = Length01;
|
||||
if(Length02 > Max) Max = Length02;
|
||||
if(Length12 > Max) Max = Length12;
|
||||
return Max;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes a point on the triangle according to the stabbing information.
|
||||
* \param u,v [in] point's barycentric coordinates
|
||||
* \param pt [out] point on triangle
|
||||
* \param nearvtx [out] index of nearest vertex
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Triangle::ComputePoint(float u, float v, Point& pt, udword* nearvtx) const
|
||||
{
|
||||
// Compute point coordinates
|
||||
pt = (1.0f - u - v)*mVerts[0] + u*mVerts[1] + v*mVerts[2];
|
||||
|
||||
// Compute nearest vertex if needed
|
||||
if(nearvtx)
|
||||
{
|
||||
// Compute distance vector
|
||||
Point d(mVerts[0].SquareDistance(pt), // Distance^2 from vertex 0 to point on the face
|
||||
mVerts[1].SquareDistance(pt), // Distance^2 from vertex 1 to point on the face
|
||||
mVerts[2].SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face
|
||||
|
||||
// Get smallest distance
|
||||
*nearvtx = d.SmallestAxis();
|
||||
}
|
||||
}
|
||||
|
||||
void Triangle::Inflate(float fat_coeff, bool constant_border)
|
||||
{
|
||||
// Compute triangle center
|
||||
Point TriangleCenter;
|
||||
Center(TriangleCenter);
|
||||
|
||||
// Don't normalize?
|
||||
// Normalize => add a constant border, regardless of triangle size
|
||||
// Don't => add more to big triangles
|
||||
for(udword i=0;i<3;i++)
|
||||
{
|
||||
Point v = mVerts[i] - TriangleCenter;
|
||||
|
||||
if(constant_border) v.Normalize();
|
||||
|
||||
mVerts[i] += v * fat_coeff;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a handy triangle class.
|
||||
* \file IceTriangle.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 17, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a triangle class.
|
||||
*
|
||||
* \class Tri
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
* \date 08.15.98
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static sdword VPlaneSideEps(const Point& v, const Plane& plane, float epsilon)
|
||||
{
|
||||
// Compute distance from current vertex to the plane
|
||||
float Dist = plane.Distance(v);
|
||||
// Compute side:
|
||||
// 1 = the vertex is on the positive side of the plane
|
||||
// -1 = the vertex is on the negative side of the plane
|
||||
// 0 = the vertex is on the plane (within epsilon)
|
||||
return Dist > epsilon ? 1 : Dist < -epsilon ? -1 : 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Flips the winding order.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Triangle::Flip()
|
||||
{
|
||||
Point Tmp = mVerts[1];
|
||||
mVerts[1] = mVerts[2];
|
||||
mVerts[2] = Tmp;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle area.
|
||||
* \return the area
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Triangle::Area() const
|
||||
{
|
||||
const Point& p0 = mVerts[0];
|
||||
const Point& p1 = mVerts[1];
|
||||
const Point& p2 = mVerts[2];
|
||||
return ((p0 - p1)^(p0 - p2)).Magnitude() * 0.5f;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle perimeter.
|
||||
* \return the perimeter
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Triangle::Perimeter() const
|
||||
{
|
||||
const Point& p0 = mVerts[0];
|
||||
const Point& p1 = mVerts[1];
|
||||
const Point& p2 = mVerts[2];
|
||||
return p0.Distance(p1)
|
||||
+ p0.Distance(p2)
|
||||
+ p1.Distance(p2);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle compacity.
|
||||
* \return the compacity
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Triangle::Compacity() const
|
||||
{
|
||||
float P = Perimeter();
|
||||
if(P==0.0f) return 0.0f;
|
||||
return (4.0f*PI*Area()/(P*P));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle normal.
|
||||
* \param normal [out] the computed normal
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Triangle::Normal(Point& normal) const
|
||||
{
|
||||
const Point& p0 = mVerts[0];
|
||||
const Point& p1 = mVerts[1];
|
||||
const Point& p2 = mVerts[2];
|
||||
normal = ((p0 - p1)^(p0 - p2)).Normalize();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle denormalized normal.
|
||||
* \param normal [out] the computed normal
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Triangle::DenormalizedNormal(Point& normal) const
|
||||
{
|
||||
const Point& p0 = mVerts[0];
|
||||
const Point& p1 = mVerts[1];
|
||||
const Point& p2 = mVerts[2];
|
||||
normal = ((p0 - p1)^(p0 - p2));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle center.
|
||||
* \param center [out] the computed center
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Triangle::Center(Point& center) const
|
||||
{
|
||||
const Point& p0 = mVerts[0];
|
||||
const Point& p1 = mVerts[1];
|
||||
const Point& p2 = mVerts[2];
|
||||
center = (p0 + p1 + p2)*INV3;
|
||||
}
|
||||
|
||||
PartVal Triangle::TestAgainstPlane(const Plane& plane, float epsilon) const
|
||||
{
|
||||
bool Pos = false, Neg = false;
|
||||
|
||||
// Loop through all vertices
|
||||
for(udword i=0;i<3;i++)
|
||||
{
|
||||
// Compute side:
|
||||
sdword Side = VPlaneSideEps(mVerts[i], plane, epsilon);
|
||||
|
||||
if (Side < 0) Neg = true;
|
||||
else if (Side > 0) Pos = true;
|
||||
}
|
||||
|
||||
if (!Pos && !Neg) return TRI_ON_PLANE;
|
||||
else if (Pos && Neg) return TRI_INTERSECT;
|
||||
else if (Pos && !Neg) return TRI_PLUS_SPACE;
|
||||
else if (!Pos && Neg) return TRI_MINUS_SPACE;
|
||||
|
||||
// What?!
|
||||
return TRI_FORCEDWORD;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle moment.
|
||||
* \param m [out] the moment
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
void Triangle::ComputeMoment(Moment& m)
|
||||
{
|
||||
// Compute the area of the triangle
|
||||
m.mArea = Area();
|
||||
|
||||
// Compute the centroid
|
||||
Center(m.mCentroid);
|
||||
|
||||
// Second-order components. Handle zero-area faces.
|
||||
Point& p = mVerts[0];
|
||||
Point& q = mVerts[1];
|
||||
Point& r = mVerts[2];
|
||||
if(m.mArea==0.0f)
|
||||
{
|
||||
// This triangle has zero area. The second order components would be eliminated with the usual formula, so, for the
|
||||
// sake of robustness we use an alternative form. These are the centroid and second-order components of the triangle's vertices.
|
||||
m.mCovariance.m[0][0] = (p.x*p.x + q.x*q.x + r.x*r.x);
|
||||
m.mCovariance.m[0][1] = (p.x*p.y + q.x*q.y + r.x*r.y);
|
||||
m.mCovariance.m[0][2] = (p.x*p.z + q.x*q.z + r.x*r.z);
|
||||
m.mCovariance.m[1][1] = (p.y*p.y + q.y*q.y + r.y*r.y);
|
||||
m.mCovariance.m[1][2] = (p.y*p.z + q.y*q.z + r.y*r.z);
|
||||
m.mCovariance.m[2][2] = (p.z*p.z + q.z*q.z + r.z*r.z);
|
||||
m.mCovariance.m[2][1] = m.mCovariance.m[1][2];
|
||||
m.mCovariance.m[1][0] = m.mCovariance.m[0][1];
|
||||
m.mCovariance.m[2][0] = m.mCovariance.m[0][2];
|
||||
}
|
||||
else
|
||||
{
|
||||
const float OneOverTwelve = 1.0f / 12.0f;
|
||||
m.mCovariance.m[0][0] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.x + p.x*p.x + q.x*q.x + r.x*r.x) * OneOverTwelve;
|
||||
m.mCovariance.m[0][1] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.y + p.x*p.y + q.x*q.y + r.x*r.y) * OneOverTwelve;
|
||||
m.mCovariance.m[1][1] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.y + p.y*p.y + q.y*q.y + r.y*r.y) * OneOverTwelve;
|
||||
m.mCovariance.m[0][2] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.z + p.x*p.z + q.x*q.z + r.x*r.z) * OneOverTwelve;
|
||||
m.mCovariance.m[1][2] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.z + p.y*p.z + q.y*q.z + r.y*r.z) * OneOverTwelve;
|
||||
m.mCovariance.m[2][2] = m.mArea * (9.0f * m.mCentroid.z*m.mCentroid.z + p.z*p.z + q.z*q.z + r.z*r.z) * OneOverTwelve;
|
||||
m.mCovariance.m[2][1] = m.mCovariance.m[1][2];
|
||||
m.mCovariance.m[1][0] = m.mCovariance.m[0][1];
|
||||
m.mCovariance.m[2][0] = m.mCovariance.m[0][2];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle's smallest edge length.
|
||||
* \return the smallest edge length
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Triangle::MinEdgeLength() const
|
||||
{
|
||||
float Min = MAX_FLOAT;
|
||||
float Length01 = mVerts[0].Distance(mVerts[1]);
|
||||
float Length02 = mVerts[0].Distance(mVerts[2]);
|
||||
float Length12 = mVerts[1].Distance(mVerts[2]);
|
||||
if(Length01 < Min) Min = Length01;
|
||||
if(Length02 < Min) Min = Length02;
|
||||
if(Length12 < Min) Min = Length12;
|
||||
return Min;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes the triangle's largest edge length.
|
||||
* \return the largest edge length
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
float Triangle::MaxEdgeLength() const
|
||||
{
|
||||
float Max = MIN_FLOAT;
|
||||
float Length01 = mVerts[0].Distance(mVerts[1]);
|
||||
float Length02 = mVerts[0].Distance(mVerts[2]);
|
||||
float Length12 = mVerts[1].Distance(mVerts[2]);
|
||||
if(Length01 > Max) Max = Length01;
|
||||
if(Length02 > Max) Max = Length02;
|
||||
if(Length12 > Max) Max = Length12;
|
||||
return Max;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Computes a point on the triangle according to the stabbing information.
|
||||
* \param u,v [in] point's barycentric coordinates
|
||||
* \param pt [out] point on triangle
|
||||
* \param nearvtx [out] index of nearest vertex
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Triangle::ComputePoint(float u, float v, Point& pt, udword* nearvtx) const
|
||||
{
|
||||
// Compute point coordinates
|
||||
pt = (1.0f - u - v)*mVerts[0] + u*mVerts[1] + v*mVerts[2];
|
||||
|
||||
// Compute nearest vertex if needed
|
||||
if(nearvtx)
|
||||
{
|
||||
// Compute distance vector
|
||||
Point d(mVerts[0].SquareDistance(pt), // Distance^2 from vertex 0 to point on the face
|
||||
mVerts[1].SquareDistance(pt), // Distance^2 from vertex 1 to point on the face
|
||||
mVerts[2].SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face
|
||||
|
||||
// Get smallest distance
|
||||
*nearvtx = d.SmallestAxis();
|
||||
}
|
||||
}
|
||||
|
||||
void Triangle::Inflate(float fat_coeff, bool constant_border)
|
||||
{
|
||||
// Compute triangle center
|
||||
Point TriangleCenter;
|
||||
Center(TriangleCenter);
|
||||
|
||||
// Don't normalize?
|
||||
// Normalize => add a constant border, regardless of triangle size
|
||||
// Don't => add more to big triangles
|
||||
for(udword i=0;i<3;i++)
|
||||
{
|
||||
Point v = mVerts[i] - TriangleCenter;
|
||||
|
||||
if(constant_border) v.Normalize();
|
||||
|
||||
mVerts[i] += v * fat_coeff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,84 +1,84 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a handy triangle class.
|
||||
* \file IceTriangle.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 17, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICETRIANGLE_H__
|
||||
#define __ICETRIANGLE_H__
|
||||
|
||||
// Forward declarations
|
||||
class Moment;
|
||||
|
||||
// Partitioning values
|
||||
enum PartVal
|
||||
{
|
||||
TRI_MINUS_SPACE = 0, //!< Triangle is in the negative space
|
||||
TRI_PLUS_SPACE = 1, //!< Triangle is in the positive space
|
||||
TRI_INTERSECT = 2, //!< Triangle intersects plane
|
||||
TRI_ON_PLANE = 3, //!< Triangle and plane are coplanar
|
||||
|
||||
TRI_FORCEDWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
// A triangle class.
|
||||
class ICEMATHS_API Triangle
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ Triangle() {}
|
||||
//! Constructor
|
||||
inline_ Triangle(const Point& p0, const Point& p1, const Point& p2) { mVerts[0]=p0; mVerts[1]=p1; mVerts[2]=p2; }
|
||||
//! Copy constructor
|
||||
inline_ Triangle(const Triangle& triangle)
|
||||
{
|
||||
mVerts[0] = triangle.mVerts[0];
|
||||
mVerts[1] = triangle.mVerts[1];
|
||||
mVerts[2] = triangle.mVerts[2];
|
||||
}
|
||||
//! Destructor
|
||||
inline_ ~Triangle() {}
|
||||
//! Vertices
|
||||
Point mVerts[3];
|
||||
|
||||
// Methods
|
||||
void Flip();
|
||||
float Area() const;
|
||||
float Perimeter() const;
|
||||
float Compacity() const;
|
||||
void Normal(Point& normal) const;
|
||||
void DenormalizedNormal(Point& normal) const;
|
||||
void Center(Point& center) const;
|
||||
inline_ Plane PlaneEquation() const { return Plane(mVerts[0], mVerts[1], mVerts[2]); }
|
||||
|
||||
PartVal TestAgainstPlane(const Plane& plane, float epsilon) const;
|
||||
// float Distance(Point& cp, Point& cq, Tri& tri);
|
||||
void ComputeMoment(Moment& m);
|
||||
float MinEdgeLength() const;
|
||||
float MaxEdgeLength() const;
|
||||
void ComputePoint(float u, float v, Point& pt, udword* nearvtx=null) const;
|
||||
void Inflate(float fat_coeff, bool constant_border);
|
||||
};
|
||||
|
||||
#endif // __ICETRIANGLE_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a handy triangle class.
|
||||
* \file IceTriangle.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 17, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICETRIANGLE_H__
|
||||
#define __ICETRIANGLE_H__
|
||||
|
||||
// Forward declarations
|
||||
class Moment;
|
||||
|
||||
// Partitioning values
|
||||
enum PartVal
|
||||
{
|
||||
TRI_MINUS_SPACE = 0, //!< Triangle is in the negative space
|
||||
TRI_PLUS_SPACE = 1, //!< Triangle is in the positive space
|
||||
TRI_INTERSECT = 2, //!< Triangle intersects plane
|
||||
TRI_ON_PLANE = 3, //!< Triangle and plane are coplanar
|
||||
|
||||
TRI_FORCEDWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
// A triangle class.
|
||||
class ICEMATHS_API Triangle
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ Triangle() {}
|
||||
//! Constructor
|
||||
inline_ Triangle(const Point& p0, const Point& p1, const Point& p2) { mVerts[0]=p0; mVerts[1]=p1; mVerts[2]=p2; }
|
||||
//! Copy constructor
|
||||
inline_ Triangle(const Triangle& triangle)
|
||||
{
|
||||
mVerts[0] = triangle.mVerts[0];
|
||||
mVerts[1] = triangle.mVerts[1];
|
||||
mVerts[2] = triangle.mVerts[2];
|
||||
}
|
||||
//! Destructor
|
||||
inline_ ~Triangle() {}
|
||||
//! Vertices
|
||||
Point mVerts[3];
|
||||
|
||||
// Methods
|
||||
void Flip();
|
||||
float Area() const;
|
||||
float Perimeter() const;
|
||||
float Compacity() const;
|
||||
void Normal(Point& normal) const;
|
||||
void DenormalizedNormal(Point& normal) const;
|
||||
void Center(Point& center) const;
|
||||
inline_ Plane PlaneEquation() const { return Plane(mVerts[0], mVerts[1], mVerts[2]); }
|
||||
|
||||
PartVal TestAgainstPlane(const Plane& plane, float epsilon) const;
|
||||
// float Distance(Point& cp, Point& cq, Tri& tri);
|
||||
void ComputeMoment(Moment& m);
|
||||
float MinEdgeLength() const;
|
||||
float MaxEdgeLength() const;
|
||||
void ComputePoint(float u, float v, Point& pt, udword* nearvtx=null) const;
|
||||
void Inflate(float fat_coeff, bool constant_border);
|
||||
};
|
||||
|
||||
#endif // __ICETRIANGLE_H__
|
||||
|
||||
@@ -1,77 +1,77 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for a triangle container.
|
||||
* \file IceTrilist.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICETRILIST_H__
|
||||
#define __ICETRILIST_H__
|
||||
|
||||
class ICEMATHS_API TriList : public Container
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
TriList() {}
|
||||
~TriList() {}
|
||||
|
||||
inline_ udword GetNbTriangles() const { return GetNbEntries()/9; }
|
||||
inline_ Triangle* GetTriangles() const { return (Triangle*)GetEntries(); }
|
||||
|
||||
void AddTri(const Triangle& tri)
|
||||
{
|
||||
Add(tri.mVerts[0].x).Add(tri.mVerts[0].y).Add(tri.mVerts[0].z);
|
||||
Add(tri.mVerts[1].x).Add(tri.mVerts[1].y).Add(tri.mVerts[1].z);
|
||||
Add(tri.mVerts[2].x).Add(tri.mVerts[2].y).Add(tri.mVerts[2].z);
|
||||
}
|
||||
|
||||
void AddTri(const Point& p0, const Point& p1, const Point& p2)
|
||||
{
|
||||
Add(p0.x).Add(p0.y).Add(p0.z);
|
||||
Add(p1.x).Add(p1.y).Add(p1.z);
|
||||
Add(p2.x).Add(p2.y).Add(p2.z);
|
||||
}
|
||||
};
|
||||
|
||||
class ICEMATHS_API TriangleList : public Container
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
TriangleList() {}
|
||||
~TriangleList() {}
|
||||
|
||||
inline_ udword GetNbTriangles() const { return GetNbEntries()/3; }
|
||||
inline_ IndexedTriangle* GetTriangles() const { return (IndexedTriangle*)GetEntries();}
|
||||
|
||||
void AddTriangle(const IndexedTriangle& tri)
|
||||
{
|
||||
Add(tri.mVRef[0]).Add(tri.mVRef[1]).Add(tri.mVRef[2]);
|
||||
}
|
||||
|
||||
void AddTriangle(udword vref0, udword vref1, udword vref2)
|
||||
{
|
||||
Add(vref0).Add(vref1).Add(vref2);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //__ICETRILIST_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for a triangle container.
|
||||
* \file IceTrilist.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICETRILIST_H__
|
||||
#define __ICETRILIST_H__
|
||||
|
||||
class ICEMATHS_API TriList : public Container
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
TriList() {}
|
||||
~TriList() {}
|
||||
|
||||
inline_ udword GetNbTriangles() const { return GetNbEntries()/9; }
|
||||
inline_ Triangle* GetTriangles() const { return (Triangle*)GetEntries(); }
|
||||
|
||||
void AddTri(const Triangle& tri)
|
||||
{
|
||||
Add(tri.mVerts[0].x).Add(tri.mVerts[0].y).Add(tri.mVerts[0].z);
|
||||
Add(tri.mVerts[1].x).Add(tri.mVerts[1].y).Add(tri.mVerts[1].z);
|
||||
Add(tri.mVerts[2].x).Add(tri.mVerts[2].y).Add(tri.mVerts[2].z);
|
||||
}
|
||||
|
||||
void AddTri(const Point& p0, const Point& p1, const Point& p2)
|
||||
{
|
||||
Add(p0.x).Add(p0.y).Add(p0.z);
|
||||
Add(p1.x).Add(p1.y).Add(p1.z);
|
||||
Add(p2.x).Add(p2.y).Add(p2.z);
|
||||
}
|
||||
};
|
||||
|
||||
class ICEMATHS_API TriangleList : public Container
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
TriangleList() {}
|
||||
~TriangleList() {}
|
||||
|
||||
inline_ udword GetNbTriangles() const { return GetNbEntries()/3; }
|
||||
inline_ IndexedTriangle* GetTriangles() const { return (IndexedTriangle*)GetEntries();}
|
||||
|
||||
void AddTriangle(const IndexedTriangle& tri)
|
||||
{
|
||||
Add(tri.mVRef[0]).Add(tri.mVRef[1]).Add(tri.mVRef[2]);
|
||||
}
|
||||
|
||||
void AddTriangle(udword vref0, udword vref1, udword vref2)
|
||||
{
|
||||
Add(vref0).Add(vref1).Add(vref2);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //__ICETRILIST_H__
|
||||
|
||||
@@ -1,181 +1,181 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains custom types.
|
||||
* \file IceTypes.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICETYPES_H
|
||||
#define ICETYPES_H
|
||||
|
||||
#define USE_HANDLE_MANAGER
|
||||
|
||||
// Constants
|
||||
#ifndef PI
|
||||
#define PI 3.1415926535897932384626433832795028841971693993751f //!< PI
|
||||
#endif
|
||||
#define HALFPI 1.57079632679489661923f //!< 0.5 * PI
|
||||
#define TWOPI 6.28318530717958647692f //!< 2.0 * PI
|
||||
#define INVPI 0.31830988618379067154f //!< 1.0 / PI
|
||||
|
||||
#define RADTODEG 57.2957795130823208768f //!< 180.0 / PI, convert radians to degrees
|
||||
#define DEGTORAD 0.01745329251994329577f //!< PI / 180.0, convert degrees to radians
|
||||
|
||||
#define EXP 2.71828182845904523536f //!< e
|
||||
#define INVLOG2 3.32192809488736234787f //!< 1.0 / log10(2)
|
||||
#define LN2 0.693147180559945f //!< ln(2)
|
||||
#define INVLN2 1.44269504089f //!< 1.0f / ln(2)
|
||||
|
||||
#define INV3 0.33333333333333333333f //!< 1/3
|
||||
#define INV6 0.16666666666666666666f //!< 1/6
|
||||
#define INV7 0.14285714285714285714f //!< 1/7
|
||||
#define INV9 0.11111111111111111111f //!< 1/9
|
||||
#define INV255 0.00392156862745098039f //!< 1/255
|
||||
|
||||
#define SQRT2 1.41421356237f //!< sqrt(2)
|
||||
#define INVSQRT2 0.707106781188f //!< 1 / sqrt(2)
|
||||
|
||||
#define SQRT3 1.73205080757f //!< sqrt(3)
|
||||
#define INVSQRT3 0.577350269189f //!< 1 / sqrt(3)
|
||||
|
||||
#define null 0 //!< our own NULL pointer
|
||||
|
||||
// Custom types used in ICE
|
||||
typedef signed char sbyte; //!< sizeof(sbyte) must be 1
|
||||
typedef unsigned char ubyte; //!< sizeof(ubyte) must be 1
|
||||
typedef signed short sword; //!< sizeof(sword) must be 2
|
||||
typedef unsigned short uword; //!< sizeof(uword) must be 2
|
||||
typedef signed int sdword; //!< sizeof(sdword) must be 4
|
||||
typedef unsigned int udword; //!< sizeof(udword) must be 4
|
||||
#ifdef WIN32
|
||||
typedef signed __int64 sqword; //!< sizeof(sqword) must be 8
|
||||
typedef unsigned __int64 uqword; //!< sizeof(uqword) must be 8
|
||||
#elif LINUX
|
||||
typedef signed long long sqword; //!< sizeof(sqword) must be 8
|
||||
typedef unsigned long long uqword; //!< sizeof(uqword) must be 8
|
||||
#elif defined(__APPLE__)
|
||||
typedef signed long long sqword; //!< sizeof(sqword) must be 8
|
||||
typedef unsigned long long uqword; //!< sizeof(uqword) must be 8
|
||||
#elif defined(_XBOX)
|
||||
typedef signed __int64 sqword; //!< sizeof(sqword) must be 8
|
||||
typedef unsigned __int64 uqword; //!< sizeof(uqword) must be 8
|
||||
#endif
|
||||
typedef float float32; //!< sizeof(float32) must be 4
|
||||
typedef double float64; //!< sizeof(float64) must be 8
|
||||
typedef size_t regsize; //!< sizeof(regsize) must be sizeof(void*)
|
||||
|
||||
// For test purpose you can force one of those:
|
||||
// typedef udword regsize;
|
||||
// typedef uqword regsize;
|
||||
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(bool)==1); // ...otherwise things might fail with VC++ 4.2 !
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(ubyte)==1);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sbyte)==1);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sword)==2);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(uword)==2);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(udword)==4);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sdword)==4);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(uqword)==8);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sqword)==8);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(float32)==4);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(float64)==8);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(regsize)==sizeof(void*));
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
#define DECLARE_ICE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
|
||||
|
||||
typedef udword DynID; //!< Dynamic identifier
|
||||
#ifdef USE_HANDLE_MANAGER
|
||||
typedef udword KID; //!< Kernel ID
|
||||
// DECLARE_ICE_HANDLE(KID);
|
||||
#else
|
||||
typedef uword KID; //!< Kernel ID
|
||||
#endif
|
||||
#define INVALID_ID 0xffffffff //!< Invalid dword ID (counterpart of null pointers)
|
||||
#ifdef USE_HANDLE_MANAGER
|
||||
#define INVALID_KID 0xffffffff //!< Invalid Kernel ID
|
||||
#else
|
||||
#define INVALID_KID 0xffff //!< Invalid Kernel ID
|
||||
#endif
|
||||
#define INVALID_NUMBER 0xDEADBEEF //!< Standard junk value
|
||||
|
||||
// Define BOOL if needed
|
||||
#ifndef BOOL
|
||||
typedef int BOOL; //!< Another boolean type.
|
||||
#endif
|
||||
|
||||
//! Union of a float and a sdword
|
||||
typedef union {
|
||||
float f; //!< The float
|
||||
sdword d; //!< The integer
|
||||
}scell;
|
||||
|
||||
//! Union of a float and a udword
|
||||
typedef union {
|
||||
float f; //!< The float
|
||||
udword d; //!< The integer
|
||||
}ucell;
|
||||
|
||||
// Type ranges
|
||||
#define MAX_SBYTE 0x7f //!< max possible sbyte value
|
||||
#define MIN_SBYTE 0x80 //!< min possible sbyte value
|
||||
#define MAX_UBYTE 0xff //!< max possible ubyte value
|
||||
#define MIN_UBYTE 0x00 //!< min possible ubyte value
|
||||
#define MAX_SWORD 0x7fff //!< max possible sword value
|
||||
#define MIN_SWORD 0x8000 //!< min possible sword value
|
||||
#define MAX_UWORD 0xffff //!< max possible uword value
|
||||
#define MIN_UWORD 0x0000 //!< min possible uword value
|
||||
#define MAX_SDWORD 0x7fffffff //!< max possible sdword value
|
||||
#define MIN_SDWORD 0x80000000 //!< min possible sdword value
|
||||
#define MAX_UDWORD 0xffffffff //!< max possible udword value
|
||||
#define MIN_UDWORD 0x00000000 //!< min possible udword value
|
||||
#define MAX_FLOAT FLT_MAX //!< max possible float value
|
||||
#define MIN_FLOAT (-FLT_MAX) //!< min possible loat value
|
||||
#define IEEE_1_0 0x3f800000 //!< integer representation of 1.0
|
||||
#define IEEE_255_0 0x437f0000 //!< integer representation of 255.0
|
||||
#define IEEE_MAX_FLOAT 0x7f7fffff //!< integer representation of MAX_FLOAT
|
||||
#define IEEE_MIN_FLOAT 0xff7fffff //!< integer representation of MIN_FLOAT
|
||||
#define IEEE_UNDERFLOW_LIMIT 0x1a000000
|
||||
|
||||
#define ONE_OVER_RAND_MAX (1.0f / float(RAND_MAX)) //!< Inverse of the max possible value returned by rand()
|
||||
|
||||
typedef void** VTABLE; //!< A V-Table.
|
||||
|
||||
#undef MIN
|
||||
#undef MAX
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b)) //!< Returns the min value between a and b
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b)) //!< Returns the max value between a and b
|
||||
#define MAXMAX(a,b,c) ((a) > (b) ? MAX (a,c) : MAX (b,c)) //!< Returns the max value between a, b and c
|
||||
|
||||
template<class T> inline_ const T& TMin (const T& a, const T& b) { return b < a ? b : a; }
|
||||
template<class T> inline_ const T& TMax (const T& a, const T& b) { return a < b ? b : a; }
|
||||
template<class T> inline_ void TSetMin (T& a, const T& b) { if(a>b) a = b; }
|
||||
template<class T> inline_ void TSetMax (T& a, const T& b) { if(a<b) a = b; }
|
||||
|
||||
/* Obsolete stuff - if needed, move to dedicated header and include in few files using this.
|
||||
#define SQR(x) ((x)*(x)) //!< Returns x square
|
||||
#define CUBE(x) ((x)*(x)*(x)) //!< Returns x cube
|
||||
|
||||
#define AND & //!< ...
|
||||
#define OR | //!< ...
|
||||
#define XOR ^ //!< ...
|
||||
|
||||
#define QUADRAT(x) ((x)*(x)) //!< Returns x square
|
||||
|
||||
typedef int (__stdcall* PROC)(); //!< A standard procedure call.
|
||||
typedef bool (*ENUMERATION)(udword value, udword param, udword context); //!< ICE standard enumeration call
|
||||
|
||||
#ifdef _WIN32
|
||||
// Used to compile legacy code
|
||||
__forceinline void srand48(udword x) { srand(x); }
|
||||
__forceinline void srandom(udword x) { srand(x); }
|
||||
__forceinline double random() { return (double)rand(); }
|
||||
__forceinline double drand48() { return (double) ( ((double)rand()) / ((double)RAND_MAX) ); }
|
||||
#endif
|
||||
*/
|
||||
|
||||
#endif // ICETYPES_H
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains custom types.
|
||||
* \file IceTypes.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICETYPES_H
|
||||
#define ICETYPES_H
|
||||
|
||||
#define USE_HANDLE_MANAGER
|
||||
|
||||
// Constants
|
||||
#ifndef PI
|
||||
#define PI 3.1415926535897932384626433832795028841971693993751f //!< PI
|
||||
#endif
|
||||
#define HALFPI 1.57079632679489661923f //!< 0.5 * PI
|
||||
#define TWOPI 6.28318530717958647692f //!< 2.0 * PI
|
||||
#define INVPI 0.31830988618379067154f //!< 1.0 / PI
|
||||
|
||||
#define RADTODEG 57.2957795130823208768f //!< 180.0 / PI, convert radians to degrees
|
||||
#define DEGTORAD 0.01745329251994329577f //!< PI / 180.0, convert degrees to radians
|
||||
|
||||
#define EXP 2.71828182845904523536f //!< e
|
||||
#define INVLOG2 3.32192809488736234787f //!< 1.0 / log10(2)
|
||||
#define LN2 0.693147180559945f //!< ln(2)
|
||||
#define INVLN2 1.44269504089f //!< 1.0f / ln(2)
|
||||
|
||||
#define INV3 0.33333333333333333333f //!< 1/3
|
||||
#define INV6 0.16666666666666666666f //!< 1/6
|
||||
#define INV7 0.14285714285714285714f //!< 1/7
|
||||
#define INV9 0.11111111111111111111f //!< 1/9
|
||||
#define INV255 0.00392156862745098039f //!< 1/255
|
||||
|
||||
#define SQRT2 1.41421356237f //!< sqrt(2)
|
||||
#define INVSQRT2 0.707106781188f //!< 1 / sqrt(2)
|
||||
|
||||
#define SQRT3 1.73205080757f //!< sqrt(3)
|
||||
#define INVSQRT3 0.577350269189f //!< 1 / sqrt(3)
|
||||
|
||||
#define null 0 //!< our own NULL pointer
|
||||
|
||||
// Custom types used in ICE
|
||||
typedef signed char sbyte; //!< sizeof(sbyte) must be 1
|
||||
typedef unsigned char ubyte; //!< sizeof(ubyte) must be 1
|
||||
typedef signed short sword; //!< sizeof(sword) must be 2
|
||||
typedef unsigned short uword; //!< sizeof(uword) must be 2
|
||||
typedef signed int sdword; //!< sizeof(sdword) must be 4
|
||||
typedef unsigned int udword; //!< sizeof(udword) must be 4
|
||||
#ifdef WIN32
|
||||
typedef signed __int64 sqword; //!< sizeof(sqword) must be 8
|
||||
typedef unsigned __int64 uqword; //!< sizeof(uqword) must be 8
|
||||
#elif LINUX
|
||||
typedef signed long long sqword; //!< sizeof(sqword) must be 8
|
||||
typedef unsigned long long uqword; //!< sizeof(uqword) must be 8
|
||||
#elif defined(__APPLE__)
|
||||
typedef signed long long sqword; //!< sizeof(sqword) must be 8
|
||||
typedef unsigned long long uqword; //!< sizeof(uqword) must be 8
|
||||
#elif defined(_XBOX)
|
||||
typedef signed __int64 sqword; //!< sizeof(sqword) must be 8
|
||||
typedef unsigned __int64 uqword; //!< sizeof(uqword) must be 8
|
||||
#endif
|
||||
typedef float float32; //!< sizeof(float32) must be 4
|
||||
typedef double float64; //!< sizeof(float64) must be 8
|
||||
typedef size_t regsize; //!< sizeof(regsize) must be sizeof(void*)
|
||||
|
||||
// For test purpose you can force one of those:
|
||||
// typedef udword regsize;
|
||||
// typedef uqword regsize;
|
||||
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(bool)==1); // ...otherwise things might fail with VC++ 4.2 !
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(ubyte)==1);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sbyte)==1);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sword)==2);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(uword)==2);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(udword)==4);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sdword)==4);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(uqword)==8);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sqword)==8);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(float32)==4);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(float64)==8);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(regsize)==sizeof(void*));
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
#define DECLARE_ICE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
|
||||
|
||||
typedef udword DynID; //!< Dynamic identifier
|
||||
#ifdef USE_HANDLE_MANAGER
|
||||
typedef udword KID; //!< Kernel ID
|
||||
// DECLARE_ICE_HANDLE(KID);
|
||||
#else
|
||||
typedef uword KID; //!< Kernel ID
|
||||
#endif
|
||||
#define INVALID_ID 0xffffffff //!< Invalid dword ID (counterpart of null pointers)
|
||||
#ifdef USE_HANDLE_MANAGER
|
||||
#define INVALID_KID 0xffffffff //!< Invalid Kernel ID
|
||||
#else
|
||||
#define INVALID_KID 0xffff //!< Invalid Kernel ID
|
||||
#endif
|
||||
#define INVALID_NUMBER 0xDEADBEEF //!< Standard junk value
|
||||
|
||||
// Define BOOL if needed
|
||||
#ifndef BOOL
|
||||
typedef int BOOL; //!< Another boolean type.
|
||||
#endif
|
||||
|
||||
//! Union of a float and a sdword
|
||||
typedef union {
|
||||
float f; //!< The float
|
||||
sdword d; //!< The integer
|
||||
}scell;
|
||||
|
||||
//! Union of a float and a udword
|
||||
typedef union {
|
||||
float f; //!< The float
|
||||
udword d; //!< The integer
|
||||
}ucell;
|
||||
|
||||
// Type ranges
|
||||
#define MAX_SBYTE 0x7f //!< max possible sbyte value
|
||||
#define MIN_SBYTE 0x80 //!< min possible sbyte value
|
||||
#define MAX_UBYTE 0xff //!< max possible ubyte value
|
||||
#define MIN_UBYTE 0x00 //!< min possible ubyte value
|
||||
#define MAX_SWORD 0x7fff //!< max possible sword value
|
||||
#define MIN_SWORD 0x8000 //!< min possible sword value
|
||||
#define MAX_UWORD 0xffff //!< max possible uword value
|
||||
#define MIN_UWORD 0x0000 //!< min possible uword value
|
||||
#define MAX_SDWORD 0x7fffffff //!< max possible sdword value
|
||||
#define MIN_SDWORD 0x80000000 //!< min possible sdword value
|
||||
#define MAX_UDWORD 0xffffffff //!< max possible udword value
|
||||
#define MIN_UDWORD 0x00000000 //!< min possible udword value
|
||||
#define MAX_FLOAT FLT_MAX //!< max possible float value
|
||||
#define MIN_FLOAT (-FLT_MAX) //!< min possible loat value
|
||||
#define IEEE_1_0 0x3f800000 //!< integer representation of 1.0
|
||||
#define IEEE_255_0 0x437f0000 //!< integer representation of 255.0
|
||||
#define IEEE_MAX_FLOAT 0x7f7fffff //!< integer representation of MAX_FLOAT
|
||||
#define IEEE_MIN_FLOAT 0xff7fffff //!< integer representation of MIN_FLOAT
|
||||
#define IEEE_UNDERFLOW_LIMIT 0x1a000000
|
||||
|
||||
#define ONE_OVER_RAND_MAX (1.0f / float(RAND_MAX)) //!< Inverse of the max possible value returned by rand()
|
||||
|
||||
typedef void** VTABLE; //!< A V-Table.
|
||||
|
||||
#undef MIN
|
||||
#undef MAX
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b)) //!< Returns the min value between a and b
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b)) //!< Returns the max value between a and b
|
||||
#define MAXMAX(a,b,c) ((a) > (b) ? MAX (a,c) : MAX (b,c)) //!< Returns the max value between a, b and c
|
||||
|
||||
template<class T> inline_ const T& TMin (const T& a, const T& b) { return b < a ? b : a; }
|
||||
template<class T> inline_ const T& TMax (const T& a, const T& b) { return a < b ? b : a; }
|
||||
template<class T> inline_ void TSetMin (T& a, const T& b) { if(a>b) a = b; }
|
||||
template<class T> inline_ void TSetMax (T& a, const T& b) { if(a<b) a = b; }
|
||||
|
||||
/* Obsolete stuff - if needed, move to dedicated header and include in few files using this.
|
||||
#define SQR(x) ((x)*(x)) //!< Returns x square
|
||||
#define CUBE(x) ((x)*(x)*(x)) //!< Returns x cube
|
||||
|
||||
#define AND & //!< ...
|
||||
#define OR | //!< ...
|
||||
#define XOR ^ //!< ...
|
||||
|
||||
#define QUADRAT(x) ((x)*(x)) //!< Returns x square
|
||||
|
||||
typedef int (__stdcall* PROC)(); //!< A standard procedure call.
|
||||
typedef bool (*ENUMERATION)(udword value, udword param, udword context); //!< ICE standard enumeration call
|
||||
|
||||
#ifdef _WIN32
|
||||
// Used to compile legacy code
|
||||
__forceinline void srand48(udword x) { srand(x); }
|
||||
__forceinline void srandom(udword x) { srand(x); }
|
||||
__forceinline double random() { return (double)rand(); }
|
||||
__forceinline double drand48() { return (double) ( ((double)rand()) / ((double)RAND_MAX) ); }
|
||||
#endif
|
||||
*/
|
||||
|
||||
#endif // ICETYPES_H
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains misc. useful macros & defines.
|
||||
* \file IceUtils.cpp
|
||||
* \author Pierre Terdiman (collected from various sources)
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns the alignment of the input address.
|
||||
* \fn Alignment()
|
||||
* \param address [in] address to check
|
||||
* \return the best alignment (e.g. 1 for odd addresses, etc)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
udword IceCore::Alignment(udword address)
|
||||
{
|
||||
// Returns 0 for null addresses
|
||||
if(!address) return 0;
|
||||
|
||||
// Test all bits
|
||||
udword Align = 1;
|
||||
for(udword i=1;i<32;i++)
|
||||
{
|
||||
// Returns as soon as the alignment is broken
|
||||
if(address&Align) return Align;
|
||||
Align<<=1;
|
||||
}
|
||||
// Here all bits are null, except the highest one (else the address would be null)
|
||||
return Align;
|
||||
}
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains misc. useful macros & defines.
|
||||
* \file IceUtils.cpp
|
||||
* \author Pierre Terdiman (collected from various sources)
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns the alignment of the input address.
|
||||
* \fn Alignment()
|
||||
* \param address [in] address to check
|
||||
* \return the best alignment (e.g. 1 for odd addresses, etc)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
udword IceCore::Alignment(udword address)
|
||||
{
|
||||
// Returns 0 for null addresses
|
||||
if(!address) return 0;
|
||||
|
||||
// Test all bits
|
||||
udword Align = 1;
|
||||
for(udword i=1;i<32;i++)
|
||||
{
|
||||
// Returns as soon as the alignment is broken
|
||||
if(address&Align) return Align;
|
||||
Align<<=1;
|
||||
}
|
||||
// Here all bits are null, except the highest one (else the address would be null)
|
||||
return Align;
|
||||
}
|
||||
|
||||
@@ -1,377 +1,377 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains misc. useful macros & defines.
|
||||
* \file IceUtils.h
|
||||
* \author Pierre Terdiman (personal code + collected from various sources)
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEUTILS_H
|
||||
#define ICEUTILS_H
|
||||
|
||||
#define START_RUNONCE { static bool __RunOnce__ = false; if(!__RunOnce__){
|
||||
#define END_RUNONCE __RunOnce__ = true;}}
|
||||
|
||||
//! Reverse all the bits in a 32 bit word (from Steve Baker's Cute Code Collection)
|
||||
//! (each line can be done in any order.
|
||||
inline_ void ReverseBits(udword& n)
|
||||
{
|
||||
n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
|
||||
n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
|
||||
n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
|
||||
n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
|
||||
n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
|
||||
// Etc for larger integers (64 bits in Java)
|
||||
// NOTE: the >> operation must be unsigned! (>>> in java)
|
||||
}
|
||||
|
||||
//! Count the number of '1' bits in a 32 bit word (from Steve Baker's Cute Code Collection)
|
||||
inline_ udword CountBits(udword n)
|
||||
{
|
||||
// This relies of the fact that the count of n bits can NOT overflow
|
||||
// an n bit integer. EG: 1 bit count takes a 1 bit integer, 2 bit counts
|
||||
// 2 bit integer, 3 bit count requires only a 2 bit integer.
|
||||
// So we add all bit pairs, then each nible, then each byte etc...
|
||||
n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1);
|
||||
n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2);
|
||||
n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4);
|
||||
n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8);
|
||||
n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16);
|
||||
// Etc for larger integers (64 bits in Java)
|
||||
// NOTE: the >> operation must be unsigned! (>>> in java)
|
||||
return n;
|
||||
}
|
||||
|
||||
//! Even faster?
|
||||
inline_ udword CountBits2(udword bits)
|
||||
{
|
||||
bits = bits - ((bits >> 1) & 0x55555555);
|
||||
bits = ((bits >> 2) & 0x33333333) + (bits & 0x33333333);
|
||||
bits = ((bits >> 4) + bits) & 0x0F0F0F0F;
|
||||
return (bits * 0x01010101) >> 24;
|
||||
}
|
||||
|
||||
// "Population Count (Ones Count)
|
||||
// The population count of a binary integer value x is the number of one bits in the value. Although many machines have
|
||||
// single instructions for this, the single instructions are usually microcoded loops that test a bit per cycle; a log-time
|
||||
// algorithm coded in C is often faster. The following code uses a variable-precision SWAR algorithm to perform a tree
|
||||
// reduction adding the bits in a 32-bit value:"
|
||||
inline_ udword ones32(udword x)
|
||||
{
|
||||
/* 32-bit recursive reduction using SWAR...
|
||||
but first step is mapping 2-bit values
|
||||
into sum of 2 1-bit values in sneaky way
|
||||
*/
|
||||
x -= ((x >> 1) & 0x55555555);
|
||||
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
|
||||
x = (((x >> 4) + x) & 0x0f0f0f0f);
|
||||
x += (x >> 8);
|
||||
x += (x >> 16);
|
||||
return (x & 0x0000003f);
|
||||
// "It is worthwhile noting that the SWAR population count algorithm given above can be improved upon for the case of
|
||||
// counting the population of multi-word bit sets. How? The last few steps in the reduction are using only a portion
|
||||
// of the SWAR width to produce their results; thus, it would be possible to combine these steps across multiple words
|
||||
// being reduced. One additional note: the AMD Athlon optimization guidelines suggest a very similar algorithm that
|
||||
// replaces the last three lines with return((x * 0x01010101) >> 24);. For the Athlon (which has a very fast integer
|
||||
// multiply), I would have expected AMD's code to be faster... but it is actually 6% slower according to my benchmarks
|
||||
// using a 1.2GHz Athlon (a Thunderbird). Why? Well, it so happens that GCC doesn't use a multiply instruction - it
|
||||
// writes out the equivalent shift and add sequence!"
|
||||
}
|
||||
|
||||
// "Trailing Zero Count
|
||||
// Given the Least Significant 1 Bit and Population Count (Ones Count) algorithms, it is trivial to combine them to
|
||||
// construct a trailing zero count (as pointed-out by Joe Bowbeer):"
|
||||
inline_ udword tzc(sdword x)
|
||||
{
|
||||
return(ones32((x & -x) - 1));
|
||||
}
|
||||
|
||||
//! Spread out bits. EG 00001111 -> 0101010101
|
||||
//! 00001010 -> 0100010000
|
||||
//! This is used to interleave two integers to produce a `Morton Key'
|
||||
//! used in Space Filling Curves (See DrDobbs Journal, July 1999)
|
||||
//! Order is important.
|
||||
inline_ void SpreadBits(udword& n)
|
||||
{
|
||||
n = ( n & 0x0000ffff) | (( n & 0xffff0000) << 16);
|
||||
n = ( n & 0x000000ff) | (( n & 0x0000ff00) << 8);
|
||||
n = ( n & 0x000f000f) | (( n & 0x00f000f0) << 4);
|
||||
n = ( n & 0x03030303) | (( n & 0x0c0c0c0c) << 2);
|
||||
n = ( n & 0x11111111) | (( n & 0x22222222) << 1);
|
||||
}
|
||||
|
||||
// "Next Largest Power of 2
|
||||
// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
|
||||
// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
|
||||
// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
|
||||
// largest power of 2. For a 32-bit value:"
|
||||
inline_ udword NextPowerOfTwo(udword x)
|
||||
{
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
return x+1;
|
||||
}
|
||||
|
||||
//! Test to see if a number is an exact power of two (from Steve Baker's Cute Code Collection)
|
||||
inline_ bool IsPowerOfTwo(udword n) { return ((n&(n-1))==0); }
|
||||
|
||||
//! Zero the least significant '1' bit in a word. (from Steve Baker's Cute Code Collection)
|
||||
inline_ void ZeroLeastSetBit(udword& n) { n&=(n-1); }
|
||||
|
||||
//! Set the least significant N bits in a word. (from Steve Baker's Cute Code Collection)
|
||||
inline_ void SetLeastNBits(udword& x, udword n) { x|=~(~0<<n); }
|
||||
|
||||
//! Classic XOR swap (from Steve Baker's Cute Code Collection)
|
||||
//! x ^= y; /* x' = (x^y) */
|
||||
//! y ^= x; /* y' = (y^(x^y)) = x */
|
||||
//! x ^= y; /* x' = (x^y)^x = y */
|
||||
inline_ void Swap(udword& x, udword& y) { x ^= y; y ^= x; x ^= y; }
|
||||
|
||||
//! Little/Big endian (from Steve Baker's Cute Code Collection)
|
||||
//!
|
||||
//! Extra comments by Kenny Hoff:
|
||||
//! Determines the byte-ordering of the current machine (little or big endian)
|
||||
//! by setting an integer value to 1 (so least significant bit is now 1); take
|
||||
//! the address of the int and cast to a byte pointer (treat integer as an
|
||||
//! array of four bytes); check the value of the first byte (must be 0 or 1).
|
||||
//! If the value is 1, then the first byte least significant byte and this
|
||||
//! implies LITTLE endian. If the value is 0, the first byte is the most
|
||||
//! significant byte, BIG endian. Examples:
|
||||
//! integer 1 on BIG endian: 00000000 00000000 00000000 00000001
|
||||
//! integer 1 on LITTLE endian: 00000001 00000000 00000000 00000000
|
||||
//!---------------------------------------------------------------------------
|
||||
//! int IsLittleEndian() { int x=1; return ( ((char*)(&x))[0] ); }
|
||||
inline_ char LittleEndian() { int i = 1; return *((char*)&i); }
|
||||
|
||||
//!< Alternative abs function
|
||||
inline_ udword abs_(sdword x) { sdword y= x >> 31; return (x^y)-y; }
|
||||
|
||||
// "Integer Minimum or Maximum
|
||||
// Given 2's complement integer values x and y, the minimum can be computed without any branches as
|
||||
// x+(((y-x)>>(WORDBITS-1))&(y-x)).
|
||||
// Logically, this works because the shift by (WORDBITS-1) replicates the sign bit to create a mask
|
||||
// -- be aware, however, that the C language does not require that shifts are signed even if their
|
||||
// operands are signed, so there is a potential portability problem. Additionally, one might think
|
||||
// that a shift by any number greater than or equal to WORDBITS would have the same effect, but many
|
||||
// instruction sets have shifts that behave strangely when such shift distances are specified.
|
||||
// Of course, maximum can be computed using the same trick:
|
||||
// x-(((x-y)>>(WORDBITS-1))&(x-y))."
|
||||
|
||||
//!< Alternative min function
|
||||
inline_ sdword min_(sdword a, sdword b) { sdword delta = b-a; return a + (delta&(delta>>31)); }
|
||||
//!< Alternative max function
|
||||
inline_ sdword max_(sdword a, sdword b) { sdword delta = a-b; return a - (delta&(delta>>31)); }
|
||||
|
||||
// "Integer Selection
|
||||
// A branchless, lookup-free, alternative to code like if (a<b) x=c; else x=d; is ((((a-b) >> (WORDBITS-1)) & (c^d)) ^ d).
|
||||
// This code assumes that the shift is signed, which, of course, C does not promise."
|
||||
inline_ sdword IntegerSelection(sdword a, sdword b, sdword c, sdword d)
|
||||
{
|
||||
return ((((a-b)>>31) & (c^d)) ^ d);
|
||||
}
|
||||
|
||||
// Determine if one of the bytes in a 4 byte word is zero
|
||||
inline_ BOOL HasNullByte(udword x) { return ((x + 0xfefefeff) & (~x) & 0x80808080); }
|
||||
|
||||
// To find the smallest 1 bit in a word EG: ~~~~~~10---0 => 0----010---0
|
||||
inline_ udword LowestOneBit(udword w) { return ((w) & (~(w)+1)); }
|
||||
// inline_ udword LowestOneBit_(udword w) { return ((w) & (-(w))); }
|
||||
|
||||
// "Most Significant 1 Bit
|
||||
// Given a binary integer value x, the most significant 1 bit (highest numbered element of a bit set)
|
||||
// can be computed using a SWAR algorithm that recursively "folds" the upper bits into the lower bits.
|
||||
// This process yields a bit vector with the same most significant 1 as x, but all 1's below it.
|
||||
// Bitwise AND of the original value with the complement of the "folded" value shifted down by one
|
||||
// yields the most significant bit. For a 32-bit value:"
|
||||
inline_ udword msb32(udword x)
|
||||
{
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
return (x & ~(x >> 1));
|
||||
}
|
||||
|
||||
// "Gray Code Conversion
|
||||
// A Gray code is any binary coding sequence in which only a single bit position changes as we move from one value to the next.
|
||||
// There are many such codes, but the traditional one is computed such that the Kth Gray code is K^(K>>1).
|
||||
//
|
||||
// The well-known algorithm for conversion from Gray to binary is a linear sequence of XORs that makes it seem each bit must be
|
||||
// dealt with separately. Fortunately, that is equivalent to a parallel prefix XOR that can be computed using SWAR techniques
|
||||
// in log time. For 32-bit Gray code values produced as described above, the conversion from Gray code back to unsigned binary is:"
|
||||
inline_ udword g2b(udword gray)
|
||||
{
|
||||
gray ^= (gray >> 16);
|
||||
gray ^= (gray >> 8);
|
||||
gray ^= (gray >> 4);
|
||||
gray ^= (gray >> 2);
|
||||
gray ^= (gray >> 1);
|
||||
return gray;
|
||||
}
|
||||
|
||||
/*
|
||||
"Just call it repeatedly with various input values and always with the same variable as "memory".
|
||||
The sharpness determines the degree of filtering, where 0 completely filters out the input, and 1
|
||||
does no filtering at all.
|
||||
|
||||
I seem to recall from college that this is called an IIR (Infinite Impulse Response) filter. As opposed
|
||||
to the more typical FIR (Finite Impulse Response).
|
||||
|
||||
Also, I'd say that you can make more intelligent and interesting filters than this, for example filters
|
||||
that remove wrong responses from the mouse because it's being moved too fast. You'd want such a filter
|
||||
to be applied before this one, of course."
|
||||
|
||||
(JCAB on Flipcode)
|
||||
*/
|
||||
inline_ float FeedbackFilter(float val, float& memory, float sharpness)
|
||||
{
|
||||
ASSERT(sharpness>=0.0f && sharpness<=1.0f && "Invalid sharpness value in feedback filter");
|
||||
if(sharpness<0.0f) sharpness = 0.0f;
|
||||
else if(sharpness>1.0f) sharpness = 1.0f;
|
||||
return memory = val * sharpness + memory * (1.0f - sharpness);
|
||||
}
|
||||
|
||||
//! "If you can guarantee that your input domain (i.e. value of x) is slightly
|
||||
//! limited (abs(x) must be < ((1<<31u)-32767)), then you can use the
|
||||
//! following code to clamp the resulting value into [-32768,+32767] range:"
|
||||
inline_ int ClampToInt16(int x)
|
||||
{
|
||||
// ASSERT(abs(x) < (int)((1<<31u)-32767));
|
||||
|
||||
int delta = 32767 - x;
|
||||
x += (delta>>31) & delta;
|
||||
delta = x + 32768;
|
||||
x -= (delta>>31) & delta;
|
||||
return x;
|
||||
}
|
||||
|
||||
// Generic functions
|
||||
template<class Type> inline_ void TSwap(Type& a, Type& b) { const Type c = a; a = b; b = c; }
|
||||
template<class Type> inline_ Type TClamp(const Type& x, const Type& lo, const Type& hi) { return ((x<lo) ? lo : (x>hi) ? hi : x); }
|
||||
|
||||
template<class Type> inline_ void TSort(Type& a, Type& b)
|
||||
{
|
||||
if(a>b) TSwap(a, b);
|
||||
}
|
||||
|
||||
template<class Type> inline_ void TSort(Type& a, Type& b, Type& c)
|
||||
{
|
||||
if(a>b) TSwap(a, b);
|
||||
if(b>c) TSwap(b, c);
|
||||
if(a>b) TSwap(a, b);
|
||||
if(b>c) TSwap(b, c);
|
||||
}
|
||||
|
||||
// Prevent nasty user-manipulations (strategy borrowed from Charles Bloom)
|
||||
// #define PREVENT_COPY(curclass) void operator = (const curclass& object) { ASSERT(!"Bad use of operator ="); }
|
||||
// ... actually this is better !
|
||||
#define PREVENT_COPY(cur_class) private: cur_class(const cur_class& object); cur_class& operator=(const cur_class& object);
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
#define OFFSET_OF(Class, Member) (size_t)&(((Class*)0)->Member)
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
#if !defined(_XBOX)
|
||||
// Already defined on Xbox.
|
||||
#define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0]))
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns the alignment of the input address.
|
||||
* \fn Alignment()
|
||||
* \param address [in] address to check
|
||||
* \return the best alignment (e.g. 1 for odd addresses, etc)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
FUNCTION ICECORE_API udword Alignment(udword address);
|
||||
|
||||
#define IS_ALIGNED_2(x) ((x&1)==0)
|
||||
#define IS_ALIGNED_4(x) ((x&3)==0)
|
||||
#define IS_ALIGNED_8(x) ((x&7)==0)
|
||||
|
||||
// Updates a pointer with "stride" bytes
|
||||
inline_ void UpdatePtr(void*& ptr, udword stride) { ptr = ((ubyte*)ptr) + stride; }
|
||||
|
||||
// From Jon Watte IIRC
|
||||
inline_ void _prefetch(void const* ptr) { (void)*(char const volatile *)ptr; }
|
||||
|
||||
// Compute implicit coords from an index:
|
||||
// The idea is to get back 2D coords from a 1D index.
|
||||
// For example:
|
||||
//
|
||||
// 0 1 2 ... nbu-1
|
||||
// nbu nbu+1 i ...
|
||||
//
|
||||
// We have i, we're looking for the equivalent (u=2, v=1) location.
|
||||
// i = u + v*nbu
|
||||
// <=> i/nbu = u/nbu + v
|
||||
// Since 0 <= u < nbu, u/nbu = 0 (integer)
|
||||
// Hence: v = i/nbu
|
||||
// Then we simply put it back in the original equation to compute u = i - v*nbu
|
||||
inline_ void Compute2DCoords(udword& u, udword& v, udword i, udword nbu)
|
||||
{
|
||||
v = i / nbu;
|
||||
u = i - (v * nbu);
|
||||
}
|
||||
|
||||
// In 3D: i = u + v*nbu + w*nbu*nbv
|
||||
// <=> i/(nbu*nbv) = u/(nbu*nbv) + v/nbv + w
|
||||
// u/(nbu*nbv) is null since u/nbu was null already.
|
||||
// v/nbv is null as well for the same reason.
|
||||
// Hence w = i/(nbu*nbv)
|
||||
// Then we're left with a 2D problem: i' = i - w*nbu*nbv = u + v*nbu
|
||||
inline_ void Compute3DCoords(udword& u, udword& v, udword& w, udword i, udword nbu, udword nbu_nbv)
|
||||
{
|
||||
w = i / (nbu_nbv);
|
||||
Compute2DCoords(u, v, i - (w * nbu_nbv), nbu);
|
||||
}
|
||||
|
||||
// Calling fsincos instead of fsin+fcos. Twice faster.
|
||||
inline_ void FSinCos(float& c, float& s, float f)
|
||||
{
|
||||
float LocalCos, LocalSin;
|
||||
float Local = f;
|
||||
#ifdef WIN32
|
||||
_asm fld Local
|
||||
_asm fsincos
|
||||
_asm fstp LocalCos
|
||||
_asm fstp LocalSin
|
||||
#elif LINUX
|
||||
asm("fld Local\n\t"
|
||||
"fsincos\n\t"
|
||||
"fstp LocalCos\n\t"
|
||||
"fstp LocalSin\n\t"
|
||||
);
|
||||
#endif
|
||||
c = LocalCos;
|
||||
s = LocalSin;
|
||||
}
|
||||
|
||||
// Modulo3 macros. See http://www.codercorner.com/Modulo3.htm
|
||||
#define GET_NEXT_INDICES(i, j, k) \
|
||||
k = 0x01000201; \
|
||||
k>>=(i<<3); \
|
||||
j = k & 0xff; \
|
||||
k>>=8; \
|
||||
k&=0xff;
|
||||
|
||||
#define GET_NEXT_INDICES2(i, j, k) \
|
||||
j = ( 9 >> (i<<1)) & 3; \
|
||||
k = (18 >> (i<<1)) & 3;
|
||||
|
||||
// 0=>1, 1=>2, 2=>0
|
||||
inline_ udword Modulo3(udword i)
|
||||
{
|
||||
ASSERT(i==0 || i==1 || i==2);
|
||||
return (9 >> (i << 1)) & 3;
|
||||
}
|
||||
|
||||
#endif // ICEUTILS_H
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains misc. useful macros & defines.
|
||||
* \file IceUtils.h
|
||||
* \author Pierre Terdiman (personal code + collected from various sources)
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef ICEUTILS_H
|
||||
#define ICEUTILS_H
|
||||
|
||||
#define START_RUNONCE { static bool __RunOnce__ = false; if(!__RunOnce__){
|
||||
#define END_RUNONCE __RunOnce__ = true;}}
|
||||
|
||||
//! Reverse all the bits in a 32 bit word (from Steve Baker's Cute Code Collection)
|
||||
//! (each line can be done in any order.
|
||||
inline_ void ReverseBits(udword& n)
|
||||
{
|
||||
n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
|
||||
n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
|
||||
n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
|
||||
n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
|
||||
n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
|
||||
// Etc for larger integers (64 bits in Java)
|
||||
// NOTE: the >> operation must be unsigned! (>>> in java)
|
||||
}
|
||||
|
||||
//! Count the number of '1' bits in a 32 bit word (from Steve Baker's Cute Code Collection)
|
||||
inline_ udword CountBits(udword n)
|
||||
{
|
||||
// This relies of the fact that the count of n bits can NOT overflow
|
||||
// an n bit integer. EG: 1 bit count takes a 1 bit integer, 2 bit counts
|
||||
// 2 bit integer, 3 bit count requires only a 2 bit integer.
|
||||
// So we add all bit pairs, then each nible, then each byte etc...
|
||||
n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1);
|
||||
n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2);
|
||||
n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4);
|
||||
n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8);
|
||||
n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16);
|
||||
// Etc for larger integers (64 bits in Java)
|
||||
// NOTE: the >> operation must be unsigned! (>>> in java)
|
||||
return n;
|
||||
}
|
||||
|
||||
//! Even faster?
|
||||
inline_ udword CountBits2(udword bits)
|
||||
{
|
||||
bits = bits - ((bits >> 1) & 0x55555555);
|
||||
bits = ((bits >> 2) & 0x33333333) + (bits & 0x33333333);
|
||||
bits = ((bits >> 4) + bits) & 0x0F0F0F0F;
|
||||
return (bits * 0x01010101) >> 24;
|
||||
}
|
||||
|
||||
// "Population Count (Ones Count)
|
||||
// The population count of a binary integer value x is the number of one bits in the value. Although many machines have
|
||||
// single instructions for this, the single instructions are usually microcoded loops that test a bit per cycle; a log-time
|
||||
// algorithm coded in C is often faster. The following code uses a variable-precision SWAR algorithm to perform a tree
|
||||
// reduction adding the bits in a 32-bit value:"
|
||||
inline_ udword ones32(udword x)
|
||||
{
|
||||
/* 32-bit recursive reduction using SWAR...
|
||||
but first step is mapping 2-bit values
|
||||
into sum of 2 1-bit values in sneaky way
|
||||
*/
|
||||
x -= ((x >> 1) & 0x55555555);
|
||||
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
|
||||
x = (((x >> 4) + x) & 0x0f0f0f0f);
|
||||
x += (x >> 8);
|
||||
x += (x >> 16);
|
||||
return (x & 0x0000003f);
|
||||
// "It is worthwhile noting that the SWAR population count algorithm given above can be improved upon for the case of
|
||||
// counting the population of multi-word bit sets. How? The last few steps in the reduction are using only a portion
|
||||
// of the SWAR width to produce their results; thus, it would be possible to combine these steps across multiple words
|
||||
// being reduced. One additional note: the AMD Athlon optimization guidelines suggest a very similar algorithm that
|
||||
// replaces the last three lines with return((x * 0x01010101) >> 24);. For the Athlon (which has a very fast integer
|
||||
// multiply), I would have expected AMD's code to be faster... but it is actually 6% slower according to my benchmarks
|
||||
// using a 1.2GHz Athlon (a Thunderbird). Why? Well, it so happens that GCC doesn't use a multiply instruction - it
|
||||
// writes out the equivalent shift and add sequence!"
|
||||
}
|
||||
|
||||
// "Trailing Zero Count
|
||||
// Given the Least Significant 1 Bit and Population Count (Ones Count) algorithms, it is trivial to combine them to
|
||||
// construct a trailing zero count (as pointed-out by Joe Bowbeer):"
|
||||
inline_ udword tzc(sdword x)
|
||||
{
|
||||
return(ones32((x & -x) - 1));
|
||||
}
|
||||
|
||||
//! Spread out bits. EG 00001111 -> 0101010101
|
||||
//! 00001010 -> 0100010000
|
||||
//! This is used to interleave two integers to produce a `Morton Key'
|
||||
//! used in Space Filling Curves (See DrDobbs Journal, July 1999)
|
||||
//! Order is important.
|
||||
inline_ void SpreadBits(udword& n)
|
||||
{
|
||||
n = ( n & 0x0000ffff) | (( n & 0xffff0000) << 16);
|
||||
n = ( n & 0x000000ff) | (( n & 0x0000ff00) << 8);
|
||||
n = ( n & 0x000f000f) | (( n & 0x00f000f0) << 4);
|
||||
n = ( n & 0x03030303) | (( n & 0x0c0c0c0c) << 2);
|
||||
n = ( n & 0x11111111) | (( n & 0x22222222) << 1);
|
||||
}
|
||||
|
||||
// "Next Largest Power of 2
|
||||
// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
|
||||
// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
|
||||
// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
|
||||
// largest power of 2. For a 32-bit value:"
|
||||
inline_ udword NextPowerOfTwo(udword x)
|
||||
{
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
return x+1;
|
||||
}
|
||||
|
||||
//! Test to see if a number is an exact power of two (from Steve Baker's Cute Code Collection)
|
||||
inline_ bool IsPowerOfTwo(udword n) { return ((n&(n-1))==0); }
|
||||
|
||||
//! Zero the least significant '1' bit in a word. (from Steve Baker's Cute Code Collection)
|
||||
inline_ void ZeroLeastSetBit(udword& n) { n&=(n-1); }
|
||||
|
||||
//! Set the least significant N bits in a word. (from Steve Baker's Cute Code Collection)
|
||||
inline_ void SetLeastNBits(udword& x, udword n) { x|=~(~0<<n); }
|
||||
|
||||
//! Classic XOR swap (from Steve Baker's Cute Code Collection)
|
||||
//! x ^= y; /* x' = (x^y) */
|
||||
//! y ^= x; /* y' = (y^(x^y)) = x */
|
||||
//! x ^= y; /* x' = (x^y)^x = y */
|
||||
inline_ void Swap(udword& x, udword& y) { x ^= y; y ^= x; x ^= y; }
|
||||
|
||||
//! Little/Big endian (from Steve Baker's Cute Code Collection)
|
||||
//!
|
||||
//! Extra comments by Kenny Hoff:
|
||||
//! Determines the byte-ordering of the current machine (little or big endian)
|
||||
//! by setting an integer value to 1 (so least significant bit is now 1); take
|
||||
//! the address of the int and cast to a byte pointer (treat integer as an
|
||||
//! array of four bytes); check the value of the first byte (must be 0 or 1).
|
||||
//! If the value is 1, then the first byte least significant byte and this
|
||||
//! implies LITTLE endian. If the value is 0, the first byte is the most
|
||||
//! significant byte, BIG endian. Examples:
|
||||
//! integer 1 on BIG endian: 00000000 00000000 00000000 00000001
|
||||
//! integer 1 on LITTLE endian: 00000001 00000000 00000000 00000000
|
||||
//!---------------------------------------------------------------------------
|
||||
//! int IsLittleEndian() { int x=1; return ( ((char*)(&x))[0] ); }
|
||||
inline_ char LittleEndian() { int i = 1; return *((char*)&i); }
|
||||
|
||||
//!< Alternative abs function
|
||||
inline_ udword abs_(sdword x) { sdword y= x >> 31; return (x^y)-y; }
|
||||
|
||||
// "Integer Minimum or Maximum
|
||||
// Given 2's complement integer values x and y, the minimum can be computed without any branches as
|
||||
// x+(((y-x)>>(WORDBITS-1))&(y-x)).
|
||||
// Logically, this works because the shift by (WORDBITS-1) replicates the sign bit to create a mask
|
||||
// -- be aware, however, that the C language does not require that shifts are signed even if their
|
||||
// operands are signed, so there is a potential portability problem. Additionally, one might think
|
||||
// that a shift by any number greater than or equal to WORDBITS would have the same effect, but many
|
||||
// instruction sets have shifts that behave strangely when such shift distances are specified.
|
||||
// Of course, maximum can be computed using the same trick:
|
||||
// x-(((x-y)>>(WORDBITS-1))&(x-y))."
|
||||
|
||||
//!< Alternative min function
|
||||
inline_ sdword min_(sdword a, sdword b) { sdword delta = b-a; return a + (delta&(delta>>31)); }
|
||||
//!< Alternative max function
|
||||
inline_ sdword max_(sdword a, sdword b) { sdword delta = a-b; return a - (delta&(delta>>31)); }
|
||||
|
||||
// "Integer Selection
|
||||
// A branchless, lookup-free, alternative to code like if (a<b) x=c; else x=d; is ((((a-b) >> (WORDBITS-1)) & (c^d)) ^ d).
|
||||
// This code assumes that the shift is signed, which, of course, C does not promise."
|
||||
inline_ sdword IntegerSelection(sdword a, sdword b, sdword c, sdword d)
|
||||
{
|
||||
return ((((a-b)>>31) & (c^d)) ^ d);
|
||||
}
|
||||
|
||||
// Determine if one of the bytes in a 4 byte word is zero
|
||||
inline_ BOOL HasNullByte(udword x) { return ((x + 0xfefefeff) & (~x) & 0x80808080); }
|
||||
|
||||
// To find the smallest 1 bit in a word EG: ~~~~~~10---0 => 0----010---0
|
||||
inline_ udword LowestOneBit(udword w) { return ((w) & (~(w)+1)); }
|
||||
// inline_ udword LowestOneBit_(udword w) { return ((w) & (-(w))); }
|
||||
|
||||
// "Most Significant 1 Bit
|
||||
// Given a binary integer value x, the most significant 1 bit (highest numbered element of a bit set)
|
||||
// can be computed using a SWAR algorithm that recursively "folds" the upper bits into the lower bits.
|
||||
// This process yields a bit vector with the same most significant 1 as x, but all 1's below it.
|
||||
// Bitwise AND of the original value with the complement of the "folded" value shifted down by one
|
||||
// yields the most significant bit. For a 32-bit value:"
|
||||
inline_ udword msb32(udword x)
|
||||
{
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
return (x & ~(x >> 1));
|
||||
}
|
||||
|
||||
// "Gray Code Conversion
|
||||
// A Gray code is any binary coding sequence in which only a single bit position changes as we move from one value to the next.
|
||||
// There are many such codes, but the traditional one is computed such that the Kth Gray code is K^(K>>1).
|
||||
//
|
||||
// The well-known algorithm for conversion from Gray to binary is a linear sequence of XORs that makes it seem each bit must be
|
||||
// dealt with separately. Fortunately, that is equivalent to a parallel prefix XOR that can be computed using SWAR techniques
|
||||
// in log time. For 32-bit Gray code values produced as described above, the conversion from Gray code back to unsigned binary is:"
|
||||
inline_ udword g2b(udword gray)
|
||||
{
|
||||
gray ^= (gray >> 16);
|
||||
gray ^= (gray >> 8);
|
||||
gray ^= (gray >> 4);
|
||||
gray ^= (gray >> 2);
|
||||
gray ^= (gray >> 1);
|
||||
return gray;
|
||||
}
|
||||
|
||||
/*
|
||||
"Just call it repeatedly with various input values and always with the same variable as "memory".
|
||||
The sharpness determines the degree of filtering, where 0 completely filters out the input, and 1
|
||||
does no filtering at all.
|
||||
|
||||
I seem to recall from college that this is called an IIR (Infinite Impulse Response) filter. As opposed
|
||||
to the more typical FIR (Finite Impulse Response).
|
||||
|
||||
Also, I'd say that you can make more intelligent and interesting filters than this, for example filters
|
||||
that remove wrong responses from the mouse because it's being moved too fast. You'd want such a filter
|
||||
to be applied before this one, of course."
|
||||
|
||||
(JCAB on Flipcode)
|
||||
*/
|
||||
inline_ float FeedbackFilter(float val, float& memory, float sharpness)
|
||||
{
|
||||
ASSERT(sharpness>=0.0f && sharpness<=1.0f && "Invalid sharpness value in feedback filter");
|
||||
if(sharpness<0.0f) sharpness = 0.0f;
|
||||
else if(sharpness>1.0f) sharpness = 1.0f;
|
||||
return memory = val * sharpness + memory * (1.0f - sharpness);
|
||||
}
|
||||
|
||||
//! "If you can guarantee that your input domain (i.e. value of x) is slightly
|
||||
//! limited (abs(x) must be < ((1<<31u)-32767)), then you can use the
|
||||
//! following code to clamp the resulting value into [-32768,+32767] range:"
|
||||
inline_ int ClampToInt16(int x)
|
||||
{
|
||||
// ASSERT(abs(x) < (int)((1<<31u)-32767));
|
||||
|
||||
int delta = 32767 - x;
|
||||
x += (delta>>31) & delta;
|
||||
delta = x + 32768;
|
||||
x -= (delta>>31) & delta;
|
||||
return x;
|
||||
}
|
||||
|
||||
// Generic functions
|
||||
template<class Type> inline_ void TSwap(Type& a, Type& b) { const Type c = a; a = b; b = c; }
|
||||
template<class Type> inline_ Type TClamp(const Type& x, const Type& lo, const Type& hi) { return ((x<lo) ? lo : (x>hi) ? hi : x); }
|
||||
|
||||
template<class Type> inline_ void TSort(Type& a, Type& b)
|
||||
{
|
||||
if(a>b) TSwap(a, b);
|
||||
}
|
||||
|
||||
template<class Type> inline_ void TSort(Type& a, Type& b, Type& c)
|
||||
{
|
||||
if(a>b) TSwap(a, b);
|
||||
if(b>c) TSwap(b, c);
|
||||
if(a>b) TSwap(a, b);
|
||||
if(b>c) TSwap(b, c);
|
||||
}
|
||||
|
||||
// Prevent nasty user-manipulations (strategy borrowed from Charles Bloom)
|
||||
// #define PREVENT_COPY(curclass) void operator = (const curclass& object) { ASSERT(!"Bad use of operator ="); }
|
||||
// ... actually this is better !
|
||||
#define PREVENT_COPY(cur_class) private: cur_class(const cur_class& object); cur_class& operator=(const cur_class& object);
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
#define OFFSET_OF(Class, Member) (size_t)&(((Class*)0)->Member)
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
#if !defined(_XBOX)
|
||||
// Already defined on Xbox.
|
||||
#define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0]))
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns the alignment of the input address.
|
||||
* \fn Alignment()
|
||||
* \param address [in] address to check
|
||||
* \return the best alignment (e.g. 1 for odd addresses, etc)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
FUNCTION ICECORE_API udword Alignment(udword address);
|
||||
|
||||
#define IS_ALIGNED_2(x) ((x&1)==0)
|
||||
#define IS_ALIGNED_4(x) ((x&3)==0)
|
||||
#define IS_ALIGNED_8(x) ((x&7)==0)
|
||||
|
||||
// Updates a pointer with "stride" bytes
|
||||
inline_ void UpdatePtr(void*& ptr, udword stride) { ptr = ((ubyte*)ptr) + stride; }
|
||||
|
||||
// From Jon Watte IIRC
|
||||
inline_ void _prefetch(void const* ptr) { (void)*(char const volatile *)ptr; }
|
||||
|
||||
// Compute implicit coords from an index:
|
||||
// The idea is to get back 2D coords from a 1D index.
|
||||
// For example:
|
||||
//
|
||||
// 0 1 2 ... nbu-1
|
||||
// nbu nbu+1 i ...
|
||||
//
|
||||
// We have i, we're looking for the equivalent (u=2, v=1) location.
|
||||
// i = u + v*nbu
|
||||
// <=> i/nbu = u/nbu + v
|
||||
// Since 0 <= u < nbu, u/nbu = 0 (integer)
|
||||
// Hence: v = i/nbu
|
||||
// Then we simply put it back in the original equation to compute u = i - v*nbu
|
||||
inline_ void Compute2DCoords(udword& u, udword& v, udword i, udword nbu)
|
||||
{
|
||||
v = i / nbu;
|
||||
u = i - (v * nbu);
|
||||
}
|
||||
|
||||
// In 3D: i = u + v*nbu + w*nbu*nbv
|
||||
// <=> i/(nbu*nbv) = u/(nbu*nbv) + v/nbv + w
|
||||
// u/(nbu*nbv) is null since u/nbu was null already.
|
||||
// v/nbv is null as well for the same reason.
|
||||
// Hence w = i/(nbu*nbv)
|
||||
// Then we're left with a 2D problem: i' = i - w*nbu*nbv = u + v*nbu
|
||||
inline_ void Compute3DCoords(udword& u, udword& v, udword& w, udword i, udword nbu, udword nbu_nbv)
|
||||
{
|
||||
w = i / (nbu_nbv);
|
||||
Compute2DCoords(u, v, i - (w * nbu_nbv), nbu);
|
||||
}
|
||||
|
||||
// Calling fsincos instead of fsin+fcos. Twice faster.
|
||||
inline_ void FSinCos(float& c, float& s, float f)
|
||||
{
|
||||
float LocalCos, LocalSin;
|
||||
float Local = f;
|
||||
#ifdef WIN32
|
||||
_asm fld Local
|
||||
_asm fsincos
|
||||
_asm fstp LocalCos
|
||||
_asm fstp LocalSin
|
||||
#elif LINUX
|
||||
asm("fld Local\n\t"
|
||||
"fsincos\n\t"
|
||||
"fstp LocalCos\n\t"
|
||||
"fstp LocalSin\n\t"
|
||||
);
|
||||
#endif
|
||||
c = LocalCos;
|
||||
s = LocalSin;
|
||||
}
|
||||
|
||||
// Modulo3 macros. See http://www.codercorner.com/Modulo3.htm
|
||||
#define GET_NEXT_INDICES(i, j, k) \
|
||||
k = 0x01000201; \
|
||||
k>>=(i<<3); \
|
||||
j = k & 0xff; \
|
||||
k>>=8; \
|
||||
k&=0xff;
|
||||
|
||||
#define GET_NEXT_INDICES2(i, j, k) \
|
||||
j = ( 9 >> (i<<1)) & 3; \
|
||||
k = (18 >> (i<<1)) & 3;
|
||||
|
||||
// 0=>1, 1=>2, 2=>0
|
||||
inline_ udword Modulo3(udword i)
|
||||
{
|
||||
ASSERT(i==0 || i==1 || i==2);
|
||||
return (9 >> (i << 1)) & 3;
|
||||
}
|
||||
|
||||
#endif // ICEUTILS_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,361 +1,361 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a simple container class.
|
||||
* \file IceContainer.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a list of 32-bits values.
|
||||
* Use this class when you need to store an unknown number of values. The list is automatically
|
||||
* resized and can contains 32-bits entities (dwords or floats)
|
||||
*
|
||||
* \class Container
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
* \date 08.15.98
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace IceCore;
|
||||
|
||||
// Static members
|
||||
#ifdef CONTAINER_STATS
|
||||
udword Container::mNbContainers = 0;
|
||||
udword Container::mUsedRam = 0;
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor. No entries allocated there.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::Container() : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f)
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers++;
|
||||
mUsedRam+=sizeof(Container);
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor. Also allocates a given number of entries.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::Container(udword size, float growth_factor) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(growth_factor)
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers++;
|
||||
mUsedRam+=sizeof(Container);
|
||||
#endif
|
||||
SetSize(size);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::Container(const Container& object) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f)
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers++;
|
||||
mUsedRam+=sizeof(Container);
|
||||
#endif
|
||||
*this = object;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Destructor. Frees everything and leaves.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::~Container()
|
||||
{
|
||||
Empty();
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers--;
|
||||
mUsedRam-=GetUsedRam();
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Clears the container. All stored values are deleted, and it frees used ram.
|
||||
* \see Reset()
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Container::Empty()
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
DELETEARRAY(mEntries);
|
||||
mCurNbEntries = mMaxNbEntries = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Resizes the container.
|
||||
* \param needed [in] assume the container can be added at least "needed" values
|
||||
* \return true if success.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Resize(udword needed)
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
// Subtract previous amount of bytes
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Get more entries
|
||||
mMaxNbEntries = mMaxNbEntries ? udword(float(mMaxNbEntries)*mGrowthFactor) : 2; // Default nb Entries = 2
|
||||
if(mMaxNbEntries<mCurNbEntries + needed) mMaxNbEntries = mCurNbEntries + needed;
|
||||
|
||||
// Get some bytes for new entries
|
||||
udword* NewEntries = new udword[mMaxNbEntries];
|
||||
CHECKALLOC(NewEntries);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Copy old data if needed
|
||||
if(mCurNbEntries) CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword));
|
||||
|
||||
// Delete old data
|
||||
DELETEARRAY(mEntries);
|
||||
|
||||
// Assign new pointer
|
||||
mEntries = NewEntries;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Sets the initial size of the container. If it already contains something, it's discarded.
|
||||
* \param nb [in] Number of entries
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::SetSize(udword nb)
|
||||
{
|
||||
// Make sure it's empty
|
||||
Empty();
|
||||
|
||||
// Checkings
|
||||
if(!nb) return false;
|
||||
|
||||
// Initialize for nb entries
|
||||
mMaxNbEntries = nb;
|
||||
|
||||
// Get some bytes for new entries
|
||||
mEntries = new udword[mMaxNbEntries];
|
||||
CHECKALLOC(mEntries);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the container and get rid of unused bytes.
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Refit()
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
// Subtract previous amount of bytes
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Get just enough entries
|
||||
mMaxNbEntries = mCurNbEntries;
|
||||
if(!mMaxNbEntries) return false;
|
||||
|
||||
// Get just enough bytes
|
||||
udword* NewEntries = new udword[mMaxNbEntries];
|
||||
CHECKALLOC(NewEntries);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Copy old data
|
||||
CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword));
|
||||
|
||||
// Delete old data
|
||||
DELETEARRAY(mEntries);
|
||||
|
||||
// Assign new pointer
|
||||
mEntries = NewEntries;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks whether the container already contains a given value.
|
||||
* \param entry [in] the value to look for in the container
|
||||
* \param location [out] a possible pointer to store the entry location
|
||||
* \see Add(udword entry)
|
||||
* \see Add(float entry)
|
||||
* \see Empty()
|
||||
* \return true if the value has been found in the container, else false.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Contains(udword entry, udword* location) const
|
||||
{
|
||||
// Look for the entry
|
||||
for(udword i=0;i<mCurNbEntries;i++)
|
||||
{
|
||||
if(mEntries[i]==entry)
|
||||
{
|
||||
if(location) *location = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Deletes an entry. If the container contains such an entry, it's removed.
|
||||
* \param entry [in] the value to delete.
|
||||
* \return true if the value has been found in the container, else false.
|
||||
* \warning This method is arbitrary slow (O(n)) and should be used carefully. Insertion order is not preserved.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Delete(udword entry)
|
||||
{
|
||||
// Look for the entry
|
||||
for(udword i=0;i<mCurNbEntries;i++)
|
||||
{
|
||||
if(mEntries[i]==entry)
|
||||
{
|
||||
// Entry has been found at index i. The strategy is to copy the last current entry at index i, and decrement the current number of entries.
|
||||
DeleteIndex(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Deletes an entry, preserving the insertion order. If the container contains such an entry, it's removed.
|
||||
* \param entry [in] the value to delete.
|
||||
* \return true if the value has been found in the container, else false.
|
||||
* \warning This method is arbitrary slow (O(n)) and should be used carefully.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::DeleteKeepingOrder(udword entry)
|
||||
{
|
||||
// Look for the entry
|
||||
for(udword i=0;i<mCurNbEntries;i++)
|
||||
{
|
||||
if(mEntries[i]==entry)
|
||||
{
|
||||
// Entry has been found at index i.
|
||||
// Shift entries to preserve order. You really should use a linked list instead.
|
||||
mCurNbEntries--;
|
||||
for(udword j=i;j<mCurNbEntries;j++)
|
||||
{
|
||||
mEntries[j] = mEntries[j+1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the next entry, starting from input one.
|
||||
* \param entry [in/out] On input, the entry to look for. On output, the next entry
|
||||
* \param find_mode [in] wrap/clamp
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Container::FindNext(udword& entry, FindMode find_mode)
|
||||
{
|
||||
udword Location;
|
||||
if(Contains(entry, &Location))
|
||||
{
|
||||
Location++;
|
||||
if(Location==mCurNbEntries) Location = find_mode==FIND_WRAP ? 0 : mCurNbEntries-1;
|
||||
entry = mEntries[Location];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the previous entry, starting from input one.
|
||||
* \param entry [in/out] On input, the entry to look for. On output, the previous entry
|
||||
* \param find_mode [in] wrap/clamp
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Container::FindPrev(udword& entry, FindMode find_mode)
|
||||
{
|
||||
udword Location;
|
||||
if(Contains(entry, &Location))
|
||||
{
|
||||
Location--;
|
||||
if(Location==0xffffffff) Location = find_mode==FIND_WRAP ? mCurNbEntries-1 : 0;
|
||||
entry = mEntries[Location];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the ram used by the container.
|
||||
* \return the ram used in bytes.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
udword Container::GetUsedRam() const
|
||||
{
|
||||
return sizeof(Container) + mMaxNbEntries * sizeof(udword);
|
||||
}
|
||||
|
||||
void Container::operator=(const Container& object)
|
||||
{
|
||||
SetSize(object.GetNbEntries());
|
||||
CopyMemory(mEntries, object.GetEntries(), mMaxNbEntries*sizeof(udword));
|
||||
mCurNbEntries = mMaxNbEntries;
|
||||
}
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a simple container class.
|
||||
* \file IceContainer.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a list of 32-bits values.
|
||||
* Use this class when you need to store an unknown number of values. The list is automatically
|
||||
* resized and can contains 32-bits entities (dwords or floats)
|
||||
*
|
||||
* \class Container
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.0
|
||||
* \date 08.15.98
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace IceCore;
|
||||
|
||||
// Static members
|
||||
#ifdef CONTAINER_STATS
|
||||
udword Container::mNbContainers = 0;
|
||||
udword Container::mUsedRam = 0;
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor. No entries allocated there.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::Container() : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f)
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers++;
|
||||
mUsedRam+=sizeof(Container);
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor. Also allocates a given number of entries.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::Container(udword size, float growth_factor) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(growth_factor)
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers++;
|
||||
mUsedRam+=sizeof(Container);
|
||||
#endif
|
||||
SetSize(size);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::Container(const Container& object) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f)
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers++;
|
||||
mUsedRam+=sizeof(Container);
|
||||
#endif
|
||||
*this = object;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Destructor. Frees everything and leaves.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container::~Container()
|
||||
{
|
||||
Empty();
|
||||
#ifdef CONTAINER_STATS
|
||||
mNbContainers--;
|
||||
mUsedRam-=GetUsedRam();
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Clears the container. All stored values are deleted, and it frees used ram.
|
||||
* \see Reset()
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Container::Empty()
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
DELETEARRAY(mEntries);
|
||||
mCurNbEntries = mMaxNbEntries = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Resizes the container.
|
||||
* \param needed [in] assume the container can be added at least "needed" values
|
||||
* \return true if success.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Resize(udword needed)
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
// Subtract previous amount of bytes
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Get more entries
|
||||
mMaxNbEntries = mMaxNbEntries ? udword(float(mMaxNbEntries)*mGrowthFactor) : 2; // Default nb Entries = 2
|
||||
if(mMaxNbEntries<mCurNbEntries + needed) mMaxNbEntries = mCurNbEntries + needed;
|
||||
|
||||
// Get some bytes for new entries
|
||||
udword* NewEntries = new udword[mMaxNbEntries];
|
||||
CHECKALLOC(NewEntries);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Copy old data if needed
|
||||
if(mCurNbEntries) CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword));
|
||||
|
||||
// Delete old data
|
||||
DELETEARRAY(mEntries);
|
||||
|
||||
// Assign new pointer
|
||||
mEntries = NewEntries;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Sets the initial size of the container. If it already contains something, it's discarded.
|
||||
* \param nb [in] Number of entries
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::SetSize(udword nb)
|
||||
{
|
||||
// Make sure it's empty
|
||||
Empty();
|
||||
|
||||
// Checkings
|
||||
if(!nb) return false;
|
||||
|
||||
// Initialize for nb entries
|
||||
mMaxNbEntries = nb;
|
||||
|
||||
// Get some bytes for new entries
|
||||
mEntries = new udword[mMaxNbEntries];
|
||||
CHECKALLOC(mEntries);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the container and get rid of unused bytes.
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Refit()
|
||||
{
|
||||
#ifdef CONTAINER_STATS
|
||||
// Subtract previous amount of bytes
|
||||
mUsedRam-=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Get just enough entries
|
||||
mMaxNbEntries = mCurNbEntries;
|
||||
if(!mMaxNbEntries) return false;
|
||||
|
||||
// Get just enough bytes
|
||||
udword* NewEntries = new udword[mMaxNbEntries];
|
||||
CHECKALLOC(NewEntries);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
// Add current amount of bytes
|
||||
mUsedRam+=mMaxNbEntries*sizeof(udword);
|
||||
#endif
|
||||
|
||||
// Copy old data
|
||||
CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword));
|
||||
|
||||
// Delete old data
|
||||
DELETEARRAY(mEntries);
|
||||
|
||||
// Assign new pointer
|
||||
mEntries = NewEntries;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks whether the container already contains a given value.
|
||||
* \param entry [in] the value to look for in the container
|
||||
* \param location [out] a possible pointer to store the entry location
|
||||
* \see Add(udword entry)
|
||||
* \see Add(float entry)
|
||||
* \see Empty()
|
||||
* \return true if the value has been found in the container, else false.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Contains(udword entry, udword* location) const
|
||||
{
|
||||
// Look for the entry
|
||||
for(udword i=0;i<mCurNbEntries;i++)
|
||||
{
|
||||
if(mEntries[i]==entry)
|
||||
{
|
||||
if(location) *location = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Deletes an entry. If the container contains such an entry, it's removed.
|
||||
* \param entry [in] the value to delete.
|
||||
* \return true if the value has been found in the container, else false.
|
||||
* \warning This method is arbitrary slow (O(n)) and should be used carefully. Insertion order is not preserved.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::Delete(udword entry)
|
||||
{
|
||||
// Look for the entry
|
||||
for(udword i=0;i<mCurNbEntries;i++)
|
||||
{
|
||||
if(mEntries[i]==entry)
|
||||
{
|
||||
// Entry has been found at index i. The strategy is to copy the last current entry at index i, and decrement the current number of entries.
|
||||
DeleteIndex(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Deletes an entry, preserving the insertion order. If the container contains such an entry, it's removed.
|
||||
* \param entry [in] the value to delete.
|
||||
* \return true if the value has been found in the container, else false.
|
||||
* \warning This method is arbitrary slow (O(n)) and should be used carefully.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Container::DeleteKeepingOrder(udword entry)
|
||||
{
|
||||
// Look for the entry
|
||||
for(udword i=0;i<mCurNbEntries;i++)
|
||||
{
|
||||
if(mEntries[i]==entry)
|
||||
{
|
||||
// Entry has been found at index i.
|
||||
// Shift entries to preserve order. You really should use a linked list instead.
|
||||
mCurNbEntries--;
|
||||
for(udword j=i;j<mCurNbEntries;j++)
|
||||
{
|
||||
mEntries[j] = mEntries[j+1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the next entry, starting from input one.
|
||||
* \param entry [in/out] On input, the entry to look for. On output, the next entry
|
||||
* \param find_mode [in] wrap/clamp
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Container::FindNext(udword& entry, FindMode find_mode)
|
||||
{
|
||||
udword Location;
|
||||
if(Contains(entry, &Location))
|
||||
{
|
||||
Location++;
|
||||
if(Location==mCurNbEntries) Location = find_mode==FIND_WRAP ? 0 : mCurNbEntries-1;
|
||||
entry = mEntries[Location];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the previous entry, starting from input one.
|
||||
* \param entry [in/out] On input, the entry to look for. On output, the previous entry
|
||||
* \param find_mode [in] wrap/clamp
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Container::FindPrev(udword& entry, FindMode find_mode)
|
||||
{
|
||||
udword Location;
|
||||
if(Contains(entry, &Location))
|
||||
{
|
||||
Location--;
|
||||
if(Location==0xffffffff) Location = find_mode==FIND_WRAP ? mCurNbEntries-1 : 0;
|
||||
entry = mEntries[Location];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the ram used by the container.
|
||||
* \return the ram used in bytes.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
udword Container::GetUsedRam() const
|
||||
{
|
||||
return sizeof(Container) + mMaxNbEntries * sizeof(udword);
|
||||
}
|
||||
|
||||
void Container::operator=(const Container& object)
|
||||
{
|
||||
SetSize(object.GetNbEntries());
|
||||
CopyMemory(mEntries, object.GetEntries(), mMaxNbEntries*sizeof(udword));
|
||||
mCurNbEntries = mMaxNbEntries;
|
||||
}
|
||||
|
||||
@@ -1,228 +1,228 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a simple container class.
|
||||
* \file IceContainer.h
|
||||
* \author Pierre Terdiman
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICECONTAINER_H__
|
||||
#define __ICECONTAINER_H__
|
||||
|
||||
#define CONTAINER_STATS
|
||||
|
||||
enum FindMode
|
||||
{
|
||||
FIND_CLAMP,
|
||||
FIND_WRAP,
|
||||
|
||||
FIND_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
class ICECORE_API Container
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
Container();
|
||||
Container(const Container& object);
|
||||
Container(udword size, float growth_factor);
|
||||
~Container();
|
||||
// Management
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A O(1) method to add a value in the container. The container is automatically resized if needed.
|
||||
* The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
|
||||
* costs a lot more than the call overhead...
|
||||
*
|
||||
* \param entry [in] a udword to store in the container
|
||||
* \see Add(float entry)
|
||||
* \see Empty()
|
||||
* \see Contains(udword entry)
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ Container& Add(udword entry)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries==mMaxNbEntries) Resize();
|
||||
|
||||
// Add new entry
|
||||
mEntries[mCurNbEntries++] = entry;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline_ Container& Add(const udword* entries, udword nb)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
|
||||
|
||||
// Add new entry
|
||||
CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(udword));
|
||||
mCurNbEntries+=nb;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A O(1) method to add a value in the container. The container is automatically resized if needed.
|
||||
* The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
|
||||
* costs a lot more than the call overhead...
|
||||
*
|
||||
* \param entry [in] a float to store in the container
|
||||
* \see Add(udword entry)
|
||||
* \see Empty()
|
||||
* \see Contains(udword entry)
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ Container& Add(float entry)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries==mMaxNbEntries) Resize();
|
||||
|
||||
// Add new entry
|
||||
mEntries[mCurNbEntries++] = IR(entry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline_ Container& Add(const float* entries, udword nb)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
|
||||
|
||||
// Add new entry
|
||||
CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(float));
|
||||
mCurNbEntries+=nb;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Add unique [slow]
|
||||
inline_ Container& AddUnique(udword entry)
|
||||
{
|
||||
if(!Contains(entry)) Add(entry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Clears the container. All stored values are deleted, and it frees used ram.
|
||||
* \see Reset()
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Empty();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Resets the container. Stored values are discarded but the buffer is kept so that further calls don't need resizing again.
|
||||
* That's a kind of temporal coherence.
|
||||
* \see Empty()
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void Reset()
|
||||
{
|
||||
// Avoid the write if possible
|
||||
// ### CMOV
|
||||
if(mCurNbEntries) mCurNbEntries = 0;
|
||||
}
|
||||
|
||||
// HANDLE WITH CARE
|
||||
inline_ void ForceSize(udword size)
|
||||
{
|
||||
mCurNbEntries = size;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Sets the initial size of the container. If it already contains something, it's discarded.
|
||||
* \param nb [in] Number of entries
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool SetSize(udword nb);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the container and get rid of unused bytes.
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Refit();
|
||||
|
||||
// Checks whether the container already contains a given value.
|
||||
bool Contains(udword entry, udword* location=null) const;
|
||||
// Deletes an entry - doesn't preserve insertion order.
|
||||
bool Delete(udword entry);
|
||||
// Deletes an entry - does preserve insertion order.
|
||||
bool DeleteKeepingOrder(udword entry);
|
||||
//! Deletes the very last entry.
|
||||
inline_ void DeleteLastEntry() { if(mCurNbEntries) mCurNbEntries--; }
|
||||
//! Deletes the entry whose index is given
|
||||
inline_ void DeleteIndex(udword index) { mEntries[index] = mEntries[--mCurNbEntries]; }
|
||||
|
||||
// Helpers
|
||||
Container& FindNext(udword& entry, FindMode find_mode=FIND_CLAMP);
|
||||
Container& FindPrev(udword& entry, FindMode find_mode=FIND_CLAMP);
|
||||
// Data access.
|
||||
inline_ udword GetNbEntries() const { return mCurNbEntries; } //!< Returns the current number of entries.
|
||||
inline_ udword GetEntry(udword i) const { return mEntries[i]; } //!< Returns ith entry
|
||||
inline_ udword* GetEntries() const { return mEntries; } //!< Returns the list of entries.
|
||||
|
||||
inline_ udword GetFirst() const { return mEntries[0]; }
|
||||
inline_ udword GetLast() const { return mEntries[mCurNbEntries-1]; }
|
||||
|
||||
// Growth control
|
||||
inline_ float GetGrowthFactor() const { return mGrowthFactor; } //!< Returns the growth factor
|
||||
inline_ void SetGrowthFactor(float growth) { mGrowthFactor = growth; } //!< Sets the growth factor
|
||||
inline_ bool IsFull() const { return mCurNbEntries==mMaxNbEntries; } //!< Checks the container is full
|
||||
inline_ BOOL IsNotEmpty() const { return mCurNbEntries; } //!< Checks the container is empty
|
||||
|
||||
//! Read-access as an array
|
||||
inline_ udword operator[](udword i) const { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; }
|
||||
//! Write-access as an array
|
||||
inline_ udword& operator[](udword i) { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; }
|
||||
|
||||
// Stats
|
||||
udword GetUsedRam() const;
|
||||
|
||||
//! Operator for "Container A = Container B"
|
||||
void operator = (const Container& object);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
inline_ udword GetNbContainers() const { return mNbContainers; }
|
||||
inline_ udword GetTotalBytes() const { return mUsedRam; }
|
||||
private:
|
||||
|
||||
static udword mNbContainers; //!< Number of containers around
|
||||
static udword mUsedRam; //!< Amount of bytes used by containers in the system
|
||||
#endif
|
||||
private:
|
||||
// Resizing
|
||||
bool Resize(udword needed=1);
|
||||
// Data
|
||||
udword mMaxNbEntries; //!< Maximum possible number of entries
|
||||
udword mCurNbEntries; //!< Current number of entries
|
||||
udword* mEntries; //!< List of entries
|
||||
float mGrowthFactor; //!< Resize: new number of entries = old number * mGrowthFactor
|
||||
};
|
||||
|
||||
#endif // __ICECONTAINER_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains a simple container class.
|
||||
* \file IceContainer.h
|
||||
* \author Pierre Terdiman
|
||||
* \date February, 5, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICECONTAINER_H__
|
||||
#define __ICECONTAINER_H__
|
||||
|
||||
#define CONTAINER_STATS
|
||||
|
||||
enum FindMode
|
||||
{
|
||||
FIND_CLAMP,
|
||||
FIND_WRAP,
|
||||
|
||||
FIND_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
class ICECORE_API Container
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
Container();
|
||||
Container(const Container& object);
|
||||
Container(udword size, float growth_factor);
|
||||
~Container();
|
||||
// Management
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A O(1) method to add a value in the container. The container is automatically resized if needed.
|
||||
* The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
|
||||
* costs a lot more than the call overhead...
|
||||
*
|
||||
* \param entry [in] a udword to store in the container
|
||||
* \see Add(float entry)
|
||||
* \see Empty()
|
||||
* \see Contains(udword entry)
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ Container& Add(udword entry)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries==mMaxNbEntries) Resize();
|
||||
|
||||
// Add new entry
|
||||
mEntries[mCurNbEntries++] = entry;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline_ Container& Add(const udword* entries, udword nb)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
|
||||
|
||||
// Add new entry
|
||||
CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(udword));
|
||||
mCurNbEntries+=nb;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A O(1) method to add a value in the container. The container is automatically resized if needed.
|
||||
* The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
|
||||
* costs a lot more than the call overhead...
|
||||
*
|
||||
* \param entry [in] a float to store in the container
|
||||
* \see Add(udword entry)
|
||||
* \see Empty()
|
||||
* \see Contains(udword entry)
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ Container& Add(float entry)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries==mMaxNbEntries) Resize();
|
||||
|
||||
// Add new entry
|
||||
mEntries[mCurNbEntries++] = IR(entry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline_ Container& Add(const float* entries, udword nb)
|
||||
{
|
||||
// Resize if needed
|
||||
if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
|
||||
|
||||
// Add new entry
|
||||
CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(float));
|
||||
mCurNbEntries+=nb;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Add unique [slow]
|
||||
inline_ Container& AddUnique(udword entry)
|
||||
{
|
||||
if(!Contains(entry)) Add(entry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Clears the container. All stored values are deleted, and it frees used ram.
|
||||
* \see Reset()
|
||||
* \return Self-Reference
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Container& Empty();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Resets the container. Stored values are discarded but the buffer is kept so that further calls don't need resizing again.
|
||||
* That's a kind of temporal coherence.
|
||||
* \see Empty()
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void Reset()
|
||||
{
|
||||
// Avoid the write if possible
|
||||
// ### CMOV
|
||||
if(mCurNbEntries) mCurNbEntries = 0;
|
||||
}
|
||||
|
||||
// HANDLE WITH CARE
|
||||
inline_ void ForceSize(udword size)
|
||||
{
|
||||
mCurNbEntries = size;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Sets the initial size of the container. If it already contains something, it's discarded.
|
||||
* \param nb [in] Number of entries
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool SetSize(udword nb);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the container and get rid of unused bytes.
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Refit();
|
||||
|
||||
// Checks whether the container already contains a given value.
|
||||
bool Contains(udword entry, udword* location=null) const;
|
||||
// Deletes an entry - doesn't preserve insertion order.
|
||||
bool Delete(udword entry);
|
||||
// Deletes an entry - does preserve insertion order.
|
||||
bool DeleteKeepingOrder(udword entry);
|
||||
//! Deletes the very last entry.
|
||||
inline_ void DeleteLastEntry() { if(mCurNbEntries) mCurNbEntries--; }
|
||||
//! Deletes the entry whose index is given
|
||||
inline_ void DeleteIndex(udword index) { mEntries[index] = mEntries[--mCurNbEntries]; }
|
||||
|
||||
// Helpers
|
||||
Container& FindNext(udword& entry, FindMode find_mode=FIND_CLAMP);
|
||||
Container& FindPrev(udword& entry, FindMode find_mode=FIND_CLAMP);
|
||||
// Data access.
|
||||
inline_ udword GetNbEntries() const { return mCurNbEntries; } //!< Returns the current number of entries.
|
||||
inline_ udword GetEntry(udword i) const { return mEntries[i]; } //!< Returns ith entry
|
||||
inline_ udword* GetEntries() const { return mEntries; } //!< Returns the list of entries.
|
||||
|
||||
inline_ udword GetFirst() const { return mEntries[0]; }
|
||||
inline_ udword GetLast() const { return mEntries[mCurNbEntries-1]; }
|
||||
|
||||
// Growth control
|
||||
inline_ float GetGrowthFactor() const { return mGrowthFactor; } //!< Returns the growth factor
|
||||
inline_ void SetGrowthFactor(float growth) { mGrowthFactor = growth; } //!< Sets the growth factor
|
||||
inline_ bool IsFull() const { return mCurNbEntries==mMaxNbEntries; } //!< Checks the container is full
|
||||
inline_ BOOL IsNotEmpty() const { return mCurNbEntries; } //!< Checks the container is empty
|
||||
|
||||
//! Read-access as an array
|
||||
inline_ udword operator[](udword i) const { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; }
|
||||
//! Write-access as an array
|
||||
inline_ udword& operator[](udword i) { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; }
|
||||
|
||||
// Stats
|
||||
udword GetUsedRam() const;
|
||||
|
||||
//! Operator for "Container A = Container B"
|
||||
void operator = (const Container& object);
|
||||
|
||||
#ifdef CONTAINER_STATS
|
||||
inline_ udword GetNbContainers() const { return mNbContainers; }
|
||||
inline_ udword GetTotalBytes() const { return mUsedRam; }
|
||||
private:
|
||||
|
||||
static udword mNbContainers; //!< Number of containers around
|
||||
static udword mUsedRam; //!< Amount of bytes used by containers in the system
|
||||
#endif
|
||||
private:
|
||||
// Resizing
|
||||
bool Resize(udword needed=1);
|
||||
// Data
|
||||
udword mMaxNbEntries; //!< Maximum possible number of entries
|
||||
udword mCurNbEntries; //!< Current number of entries
|
||||
udword* mEntries; //!< List of entries
|
||||
float mGrowthFactor; //!< Resize: new number of entries = old number * mGrowthFactor
|
||||
};
|
||||
|
||||
#endif // __ICECONTAINER_H__
|
||||
|
||||
@@ -1,333 +1,333 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains FPU related code.
|
||||
* \file IceFPU.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEFPU_H__
|
||||
#define __ICEFPU_H__
|
||||
|
||||
#define SIGN_BITMASK 0x80000000
|
||||
|
||||
//! Integer representation of a floating-point value.
|
||||
#define IR(x) ((udword&)(x))
|
||||
|
||||
//! Signed integer representation of a floating-point value.
|
||||
#define SIR(x) ((sdword&)(x))
|
||||
|
||||
//! Absolute integer representation of a floating-point value
|
||||
#define AIR(x) (IR(x)&0x7fffffff)
|
||||
|
||||
//! Floating-point representation of an integer value.
|
||||
#define FR(x) ((float&)(x))
|
||||
|
||||
//! Integer-based comparison of a floating point value.
|
||||
//! Don't use it blindly, it can be faster or slower than the FPU comparison, depends on the context.
|
||||
#define IS_NEGATIVE_FLOAT(x) (IR(x)&0x80000000)
|
||||
|
||||
//! Fast fabs for floating-point values. It just clears the sign bit.
|
||||
//! Don't use it blindy, it can be faster or slower than the FPU comparison, depends on the context.
|
||||
inline_ float FastFabs(float x)
|
||||
{
|
||||
udword FloatBits = IR(x)&0x7fffffff;
|
||||
return FR(FloatBits);
|
||||
}
|
||||
|
||||
//! Fast square root for floating-point values.
|
||||
inline_ float FastSqrt(float square)
|
||||
{
|
||||
float retval;
|
||||
|
||||
__asm {
|
||||
mov eax, square
|
||||
sub eax, 0x3F800000
|
||||
sar eax, 1
|
||||
add eax, 0x3F800000
|
||||
mov [retval], eax
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
//! Saturates positive to zero.
|
||||
inline_ float fsat(float f)
|
||||
{
|
||||
udword y = (udword&)f & ~((sdword&)f >>31);
|
||||
return (float&)y;
|
||||
}
|
||||
|
||||
//! Computes 1.0f / sqrtf(x).
|
||||
inline_ float frsqrt(float f)
|
||||
{
|
||||
float x = f * 0.5f;
|
||||
udword y = 0x5f3759df - ((udword&)f >> 1);
|
||||
// Iteration...
|
||||
(float&)y = (float&)y * ( 1.5f - ( x * (float&)y * (float&)y ) );
|
||||
// Result
|
||||
return (float&)y;
|
||||
}
|
||||
|
||||
//! Computes 1.0f / sqrtf(x). Comes from NVIDIA.
|
||||
inline_ float InvSqrt(const float& x)
|
||||
{
|
||||
udword tmp = (udword(IEEE_1_0 << 1) + IEEE_1_0 - *(udword*)&x) >> 1;
|
||||
float y = *(float*)&tmp;
|
||||
return y * (1.47f - 0.47f * x * y * y);
|
||||
}
|
||||
|
||||
//! Computes 1.0f / sqrtf(x). Comes from Quake3. Looks like the first one I had above.
|
||||
//! See http://www.magic-software.com/3DGEDInvSqrt.html
|
||||
inline_ float RSqrt(float number)
|
||||
{
|
||||
long i;
|
||||
float x2, y;
|
||||
const float threehalfs = 1.5f;
|
||||
|
||||
x2 = number * 0.5f;
|
||||
y = number;
|
||||
i = * (long *) &y;
|
||||
i = 0x5f3759df - (i >> 1);
|
||||
y = * (float *) &i;
|
||||
y = y * (threehalfs - (x2 * y * y));
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
inline_ float fsqrt(float f)
|
||||
{
|
||||
udword y = ( ( (sdword&)f - 0x3f800000 ) >> 1 ) + 0x3f800000;
|
||||
// Iteration...?
|
||||
// (float&)y = (3.0f - ((float&)y * (float&)y) / f) * (float&)y * 0.5f;
|
||||
// Result
|
||||
return (float&)y;
|
||||
}
|
||||
|
||||
//! Returns the float ranged espilon value.
|
||||
inline_ float fepsilon(float f)
|
||||
{
|
||||
udword b = (udword&)f & 0xff800000;
|
||||
udword a = b | 0x00000001;
|
||||
(float&)a -= (float&)b;
|
||||
// Result
|
||||
return (float&)a;
|
||||
}
|
||||
|
||||
//! Is the float valid ?
|
||||
inline_ bool IsNAN(float value) { return (IR(value)&0x7f800000) == 0x7f800000; }
|
||||
inline_ bool IsIndeterminate(float value) { return IR(value) == 0xffc00000; }
|
||||
inline_ bool IsPlusInf(float value) { return IR(value) == 0x7f800000; }
|
||||
inline_ bool IsMinusInf(float value) { return IR(value) == 0xff800000; }
|
||||
|
||||
inline_ bool IsValidFloat(float value)
|
||||
{
|
||||
if(IsNAN(value)) return false;
|
||||
if(IsIndeterminate(value)) return false;
|
||||
if(IsPlusInf(value)) return false;
|
||||
if(IsMinusInf(value)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define CHECK_VALID_FLOAT(x) ASSERT(IsValidFloat(x));
|
||||
|
||||
/*
|
||||
//! FPU precision setting function.
|
||||
inline_ void SetFPU()
|
||||
{
|
||||
// This function evaluates whether the floating-point
|
||||
// control word is set to single precision/round to nearest/
|
||||
// exceptions disabled. If these conditions don't hold, the
|
||||
// function changes the control word to set them and returns
|
||||
// TRUE, putting the old control word value in the passback
|
||||
// location pointed to by pwOldCW.
|
||||
{
|
||||
uword wTemp, wSave;
|
||||
|
||||
__asm fstcw wSave
|
||||
if (wSave & 0x300 || // Not single mode
|
||||
0x3f != (wSave & 0x3f) || // Exceptions enabled
|
||||
wSave & 0xC00) // Not round to nearest mode
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov ax, wSave
|
||||
and ax, not 300h ;; single mode
|
||||
or ax, 3fh ;; disable all exceptions
|
||||
and ax, not 0xC00 ;; round to nearest mode
|
||||
mov wTemp, ax
|
||||
fldcw wTemp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
//! This function computes the slowest possible floating-point value (you can also directly use FLT_EPSILON)
|
||||
inline_ float ComputeFloatEpsilon()
|
||||
{
|
||||
float f = 1.0f;
|
||||
((udword&)f)^=1;
|
||||
return f - 1.0f; // You can check it's the same as FLT_EPSILON
|
||||
}
|
||||
|
||||
inline_ bool IsFloatZero(float x, float epsilon=1e-6f)
|
||||
{
|
||||
return x*x < epsilon;
|
||||
}
|
||||
|
||||
#define FCOMI_ST0 _asm _emit 0xdb _asm _emit 0xf0
|
||||
#define FCOMIP_ST0 _asm _emit 0xdf _asm _emit 0xf0
|
||||
#define FCMOVB_ST0 _asm _emit 0xda _asm _emit 0xc0
|
||||
#define FCMOVNB_ST0 _asm _emit 0xdb _asm _emit 0xc0
|
||||
|
||||
#define FCOMI_ST1 _asm _emit 0xdb _asm _emit 0xf1
|
||||
#define FCOMIP_ST1 _asm _emit 0xdf _asm _emit 0xf1
|
||||
#define FCMOVB_ST1 _asm _emit 0xda _asm _emit 0xc1
|
||||
#define FCMOVNB_ST1 _asm _emit 0xdb _asm _emit 0xc1
|
||||
|
||||
#define FCOMI_ST2 _asm _emit 0xdb _asm _emit 0xf2
|
||||
#define FCOMIP_ST2 _asm _emit 0xdf _asm _emit 0xf2
|
||||
#define FCMOVB_ST2 _asm _emit 0xda _asm _emit 0xc2
|
||||
#define FCMOVNB_ST2 _asm _emit 0xdb _asm _emit 0xc2
|
||||
|
||||
#define FCOMI_ST3 _asm _emit 0xdb _asm _emit 0xf3
|
||||
#define FCOMIP_ST3 _asm _emit 0xdf _asm _emit 0xf3
|
||||
#define FCMOVB_ST3 _asm _emit 0xda _asm _emit 0xc3
|
||||
#define FCMOVNB_ST3 _asm _emit 0xdb _asm _emit 0xc3
|
||||
|
||||
#define FCOMI_ST4 _asm _emit 0xdb _asm _emit 0xf4
|
||||
#define FCOMIP_ST4 _asm _emit 0xdf _asm _emit 0xf4
|
||||
#define FCMOVB_ST4 _asm _emit 0xda _asm _emit 0xc4
|
||||
#define FCMOVNB_ST4 _asm _emit 0xdb _asm _emit 0xc4
|
||||
|
||||
#define FCOMI_ST5 _asm _emit 0xdb _asm _emit 0xf5
|
||||
#define FCOMIP_ST5 _asm _emit 0xdf _asm _emit 0xf5
|
||||
#define FCMOVB_ST5 _asm _emit 0xda _asm _emit 0xc5
|
||||
#define FCMOVNB_ST5 _asm _emit 0xdb _asm _emit 0xc5
|
||||
|
||||
#define FCOMI_ST6 _asm _emit 0xdb _asm _emit 0xf6
|
||||
#define FCOMIP_ST6 _asm _emit 0xdf _asm _emit 0xf6
|
||||
#define FCMOVB_ST6 _asm _emit 0xda _asm _emit 0xc6
|
||||
#define FCMOVNB_ST6 _asm _emit 0xdb _asm _emit 0xc6
|
||||
|
||||
#define FCOMI_ST7 _asm _emit 0xdb _asm _emit 0xf7
|
||||
#define FCOMIP_ST7 _asm _emit 0xdf _asm _emit 0xf7
|
||||
#define FCMOVB_ST7 _asm _emit 0xda _asm _emit 0xc7
|
||||
#define FCMOVNB_ST7 _asm _emit 0xdb _asm _emit 0xc7
|
||||
|
||||
//! A global function to find MAX(a,b) using FCOMI/FCMOV
|
||||
inline_ float FCMax2(float a, float b)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
FCOMI_ST1
|
||||
FCMOVB_ST1
|
||||
_asm fstp [Res]
|
||||
_asm fcomp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MIN(a,b) using FCOMI/FCMOV
|
||||
inline_ float FCMin2(float a, float b)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
FCOMI_ST1
|
||||
FCMOVNB_ST1
|
||||
_asm fstp [Res]
|
||||
_asm fcomp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MAX(a,b,c) using FCOMI/FCMOV
|
||||
inline_ float FCMax3(float a, float b, float c)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
_asm fld [c]
|
||||
FCOMI_ST1
|
||||
FCMOVB_ST1
|
||||
FCOMI_ST2
|
||||
FCMOVB_ST2
|
||||
_asm fstp [Res]
|
||||
_asm fcompp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MIN(a,b,c) using FCOMI/FCMOV
|
||||
inline_ float FCMin3(float a, float b, float c)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
_asm fld [c]
|
||||
FCOMI_ST1
|
||||
FCMOVNB_ST1
|
||||
FCOMI_ST2
|
||||
FCMOVNB_ST2
|
||||
_asm fstp [Res]
|
||||
_asm fcompp
|
||||
return Res;
|
||||
}
|
||||
|
||||
inline_ int ConvertToSortable(float f)
|
||||
{
|
||||
int& Fi = (int&)f;
|
||||
int Fmask = (Fi>>31);
|
||||
Fi ^= Fmask;
|
||||
Fmask &= ~(1<<31);
|
||||
Fi -= Fmask;
|
||||
return Fi;
|
||||
}
|
||||
|
||||
enum FPUMode
|
||||
{
|
||||
FPU_FLOOR = 0,
|
||||
FPU_CEIL = 1,
|
||||
FPU_BEST = 2,
|
||||
|
||||
FPU_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
FUNCTION ICECORE_API FPUMode GetFPUMode();
|
||||
FUNCTION ICECORE_API void SaveFPU();
|
||||
FUNCTION ICECORE_API void RestoreFPU();
|
||||
FUNCTION ICECORE_API void SetFPUFloorMode();
|
||||
FUNCTION ICECORE_API void SetFPUCeilMode();
|
||||
FUNCTION ICECORE_API void SetFPUBestMode();
|
||||
|
||||
FUNCTION ICECORE_API void SetFPUPrecision24();
|
||||
FUNCTION ICECORE_API void SetFPUPrecision53();
|
||||
FUNCTION ICECORE_API void SetFPUPrecision64();
|
||||
FUNCTION ICECORE_API void SetFPURoundingChop();
|
||||
FUNCTION ICECORE_API void SetFPURoundingUp();
|
||||
FUNCTION ICECORE_API void SetFPURoundingDown();
|
||||
FUNCTION ICECORE_API void SetFPURoundingNear();
|
||||
|
||||
FUNCTION ICECORE_API int intChop(const float& f);
|
||||
FUNCTION ICECORE_API int intFloor(const float& f);
|
||||
FUNCTION ICECORE_API int intCeil(const float& f);
|
||||
|
||||
#endif // __ICEFPU_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains FPU related code.
|
||||
* \file IceFPU.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEFPU_H__
|
||||
#define __ICEFPU_H__
|
||||
|
||||
#define SIGN_BITMASK 0x80000000
|
||||
|
||||
//! Integer representation of a floating-point value.
|
||||
#define IR(x) ((udword&)(x))
|
||||
|
||||
//! Signed integer representation of a floating-point value.
|
||||
#define SIR(x) ((sdword&)(x))
|
||||
|
||||
//! Absolute integer representation of a floating-point value
|
||||
#define AIR(x) (IR(x)&0x7fffffff)
|
||||
|
||||
//! Floating-point representation of an integer value.
|
||||
#define FR(x) ((float&)(x))
|
||||
|
||||
//! Integer-based comparison of a floating point value.
|
||||
//! Don't use it blindly, it can be faster or slower than the FPU comparison, depends on the context.
|
||||
#define IS_NEGATIVE_FLOAT(x) (IR(x)&0x80000000)
|
||||
|
||||
//! Fast fabs for floating-point values. It just clears the sign bit.
|
||||
//! Don't use it blindy, it can be faster or slower than the FPU comparison, depends on the context.
|
||||
inline_ float FastFabs(float x)
|
||||
{
|
||||
udword FloatBits = IR(x)&0x7fffffff;
|
||||
return FR(FloatBits);
|
||||
}
|
||||
|
||||
//! Fast square root for floating-point values.
|
||||
inline_ float FastSqrt(float square)
|
||||
{
|
||||
float retval;
|
||||
|
||||
__asm {
|
||||
mov eax, square
|
||||
sub eax, 0x3F800000
|
||||
sar eax, 1
|
||||
add eax, 0x3F800000
|
||||
mov [retval], eax
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
//! Saturates positive to zero.
|
||||
inline_ float fsat(float f)
|
||||
{
|
||||
udword y = (udword&)f & ~((sdword&)f >>31);
|
||||
return (float&)y;
|
||||
}
|
||||
|
||||
//! Computes 1.0f / sqrtf(x).
|
||||
inline_ float frsqrt(float f)
|
||||
{
|
||||
float x = f * 0.5f;
|
||||
udword y = 0x5f3759df - ((udword&)f >> 1);
|
||||
// Iteration...
|
||||
(float&)y = (float&)y * ( 1.5f - ( x * (float&)y * (float&)y ) );
|
||||
// Result
|
||||
return (float&)y;
|
||||
}
|
||||
|
||||
//! Computes 1.0f / sqrtf(x). Comes from NVIDIA.
|
||||
inline_ float InvSqrt(const float& x)
|
||||
{
|
||||
udword tmp = (udword(IEEE_1_0 << 1) + IEEE_1_0 - *(udword*)&x) >> 1;
|
||||
float y = *(float*)&tmp;
|
||||
return y * (1.47f - 0.47f * x * y * y);
|
||||
}
|
||||
|
||||
//! Computes 1.0f / sqrtf(x). Comes from Quake3. Looks like the first one I had above.
|
||||
//! See http://www.magic-software.com/3DGEDInvSqrt.html
|
||||
inline_ float RSqrt(float number)
|
||||
{
|
||||
long i;
|
||||
float x2, y;
|
||||
const float threehalfs = 1.5f;
|
||||
|
||||
x2 = number * 0.5f;
|
||||
y = number;
|
||||
i = * (long *) &y;
|
||||
i = 0x5f3759df - (i >> 1);
|
||||
y = * (float *) &i;
|
||||
y = y * (threehalfs - (x2 * y * y));
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
inline_ float fsqrt(float f)
|
||||
{
|
||||
udword y = ( ( (sdword&)f - 0x3f800000 ) >> 1 ) + 0x3f800000;
|
||||
// Iteration...?
|
||||
// (float&)y = (3.0f - ((float&)y * (float&)y) / f) * (float&)y * 0.5f;
|
||||
// Result
|
||||
return (float&)y;
|
||||
}
|
||||
|
||||
//! Returns the float ranged espilon value.
|
||||
inline_ float fepsilon(float f)
|
||||
{
|
||||
udword b = (udword&)f & 0xff800000;
|
||||
udword a = b | 0x00000001;
|
||||
(float&)a -= (float&)b;
|
||||
// Result
|
||||
return (float&)a;
|
||||
}
|
||||
|
||||
//! Is the float valid ?
|
||||
inline_ bool IsNAN(float value) { return (IR(value)&0x7f800000) == 0x7f800000; }
|
||||
inline_ bool IsIndeterminate(float value) { return IR(value) == 0xffc00000; }
|
||||
inline_ bool IsPlusInf(float value) { return IR(value) == 0x7f800000; }
|
||||
inline_ bool IsMinusInf(float value) { return IR(value) == 0xff800000; }
|
||||
|
||||
inline_ bool IsValidFloat(float value)
|
||||
{
|
||||
if(IsNAN(value)) return false;
|
||||
if(IsIndeterminate(value)) return false;
|
||||
if(IsPlusInf(value)) return false;
|
||||
if(IsMinusInf(value)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define CHECK_VALID_FLOAT(x) ASSERT(IsValidFloat(x));
|
||||
|
||||
/*
|
||||
//! FPU precision setting function.
|
||||
inline_ void SetFPU()
|
||||
{
|
||||
// This function evaluates whether the floating-point
|
||||
// control word is set to single precision/round to nearest/
|
||||
// exceptions disabled. If these conditions don't hold, the
|
||||
// function changes the control word to set them and returns
|
||||
// TRUE, putting the old control word value in the passback
|
||||
// location pointed to by pwOldCW.
|
||||
{
|
||||
uword wTemp, wSave;
|
||||
|
||||
__asm fstcw wSave
|
||||
if (wSave & 0x300 || // Not single mode
|
||||
0x3f != (wSave & 0x3f) || // Exceptions enabled
|
||||
wSave & 0xC00) // Not round to nearest mode
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov ax, wSave
|
||||
and ax, not 300h ;; single mode
|
||||
or ax, 3fh ;; disable all exceptions
|
||||
and ax, not 0xC00 ;; round to nearest mode
|
||||
mov wTemp, ax
|
||||
fldcw wTemp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
//! This function computes the slowest possible floating-point value (you can also directly use FLT_EPSILON)
|
||||
inline_ float ComputeFloatEpsilon()
|
||||
{
|
||||
float f = 1.0f;
|
||||
((udword&)f)^=1;
|
||||
return f - 1.0f; // You can check it's the same as FLT_EPSILON
|
||||
}
|
||||
|
||||
inline_ bool IsFloatZero(float x, float epsilon=1e-6f)
|
||||
{
|
||||
return x*x < epsilon;
|
||||
}
|
||||
|
||||
#define FCOMI_ST0 _asm _emit 0xdb _asm _emit 0xf0
|
||||
#define FCOMIP_ST0 _asm _emit 0xdf _asm _emit 0xf0
|
||||
#define FCMOVB_ST0 _asm _emit 0xda _asm _emit 0xc0
|
||||
#define FCMOVNB_ST0 _asm _emit 0xdb _asm _emit 0xc0
|
||||
|
||||
#define FCOMI_ST1 _asm _emit 0xdb _asm _emit 0xf1
|
||||
#define FCOMIP_ST1 _asm _emit 0xdf _asm _emit 0xf1
|
||||
#define FCMOVB_ST1 _asm _emit 0xda _asm _emit 0xc1
|
||||
#define FCMOVNB_ST1 _asm _emit 0xdb _asm _emit 0xc1
|
||||
|
||||
#define FCOMI_ST2 _asm _emit 0xdb _asm _emit 0xf2
|
||||
#define FCOMIP_ST2 _asm _emit 0xdf _asm _emit 0xf2
|
||||
#define FCMOVB_ST2 _asm _emit 0xda _asm _emit 0xc2
|
||||
#define FCMOVNB_ST2 _asm _emit 0xdb _asm _emit 0xc2
|
||||
|
||||
#define FCOMI_ST3 _asm _emit 0xdb _asm _emit 0xf3
|
||||
#define FCOMIP_ST3 _asm _emit 0xdf _asm _emit 0xf3
|
||||
#define FCMOVB_ST3 _asm _emit 0xda _asm _emit 0xc3
|
||||
#define FCMOVNB_ST3 _asm _emit 0xdb _asm _emit 0xc3
|
||||
|
||||
#define FCOMI_ST4 _asm _emit 0xdb _asm _emit 0xf4
|
||||
#define FCOMIP_ST4 _asm _emit 0xdf _asm _emit 0xf4
|
||||
#define FCMOVB_ST4 _asm _emit 0xda _asm _emit 0xc4
|
||||
#define FCMOVNB_ST4 _asm _emit 0xdb _asm _emit 0xc4
|
||||
|
||||
#define FCOMI_ST5 _asm _emit 0xdb _asm _emit 0xf5
|
||||
#define FCOMIP_ST5 _asm _emit 0xdf _asm _emit 0xf5
|
||||
#define FCMOVB_ST5 _asm _emit 0xda _asm _emit 0xc5
|
||||
#define FCMOVNB_ST5 _asm _emit 0xdb _asm _emit 0xc5
|
||||
|
||||
#define FCOMI_ST6 _asm _emit 0xdb _asm _emit 0xf6
|
||||
#define FCOMIP_ST6 _asm _emit 0xdf _asm _emit 0xf6
|
||||
#define FCMOVB_ST6 _asm _emit 0xda _asm _emit 0xc6
|
||||
#define FCMOVNB_ST6 _asm _emit 0xdb _asm _emit 0xc6
|
||||
|
||||
#define FCOMI_ST7 _asm _emit 0xdb _asm _emit 0xf7
|
||||
#define FCOMIP_ST7 _asm _emit 0xdf _asm _emit 0xf7
|
||||
#define FCMOVB_ST7 _asm _emit 0xda _asm _emit 0xc7
|
||||
#define FCMOVNB_ST7 _asm _emit 0xdb _asm _emit 0xc7
|
||||
|
||||
//! A global function to find MAX(a,b) using FCOMI/FCMOV
|
||||
inline_ float FCMax2(float a, float b)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
FCOMI_ST1
|
||||
FCMOVB_ST1
|
||||
_asm fstp [Res]
|
||||
_asm fcomp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MIN(a,b) using FCOMI/FCMOV
|
||||
inline_ float FCMin2(float a, float b)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
FCOMI_ST1
|
||||
FCMOVNB_ST1
|
||||
_asm fstp [Res]
|
||||
_asm fcomp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MAX(a,b,c) using FCOMI/FCMOV
|
||||
inline_ float FCMax3(float a, float b, float c)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
_asm fld [c]
|
||||
FCOMI_ST1
|
||||
FCMOVB_ST1
|
||||
FCOMI_ST2
|
||||
FCMOVB_ST2
|
||||
_asm fstp [Res]
|
||||
_asm fcompp
|
||||
return Res;
|
||||
}
|
||||
|
||||
//! A global function to find MIN(a,b,c) using FCOMI/FCMOV
|
||||
inline_ float FCMin3(float a, float b, float c)
|
||||
{
|
||||
float Res;
|
||||
_asm fld [a]
|
||||
_asm fld [b]
|
||||
_asm fld [c]
|
||||
FCOMI_ST1
|
||||
FCMOVNB_ST1
|
||||
FCOMI_ST2
|
||||
FCMOVNB_ST2
|
||||
_asm fstp [Res]
|
||||
_asm fcompp
|
||||
return Res;
|
||||
}
|
||||
|
||||
inline_ int ConvertToSortable(float f)
|
||||
{
|
||||
int& Fi = (int&)f;
|
||||
int Fmask = (Fi>>31);
|
||||
Fi ^= Fmask;
|
||||
Fmask &= ~(1<<31);
|
||||
Fi -= Fmask;
|
||||
return Fi;
|
||||
}
|
||||
|
||||
enum FPUMode
|
||||
{
|
||||
FPU_FLOOR = 0,
|
||||
FPU_CEIL = 1,
|
||||
FPU_BEST = 2,
|
||||
|
||||
FPU_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
FUNCTION ICECORE_API FPUMode GetFPUMode();
|
||||
FUNCTION ICECORE_API void SaveFPU();
|
||||
FUNCTION ICECORE_API void RestoreFPU();
|
||||
FUNCTION ICECORE_API void SetFPUFloorMode();
|
||||
FUNCTION ICECORE_API void SetFPUCeilMode();
|
||||
FUNCTION ICECORE_API void SetFPUBestMode();
|
||||
|
||||
FUNCTION ICECORE_API void SetFPUPrecision24();
|
||||
FUNCTION ICECORE_API void SetFPUPrecision53();
|
||||
FUNCTION ICECORE_API void SetFPUPrecision64();
|
||||
FUNCTION ICECORE_API void SetFPURoundingChop();
|
||||
FUNCTION ICECORE_API void SetFPURoundingUp();
|
||||
FUNCTION ICECORE_API void SetFPURoundingDown();
|
||||
FUNCTION ICECORE_API void SetFPURoundingNear();
|
||||
|
||||
FUNCTION ICECORE_API int intChop(const float& f);
|
||||
FUNCTION ICECORE_API int intFloor(const float& f);
|
||||
FUNCTION ICECORE_API int intCeil(const float& f);
|
||||
|
||||
#endif // __ICEFPU_H__
|
||||
|
||||
@@ -1,121 +1,121 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains all memory macros.
|
||||
* \file IceMemoryMacros.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEMEMORYMACROS_H__
|
||||
#define __ICEMEMORYMACROS_H__
|
||||
|
||||
#undef ZeroMemory
|
||||
#undef CopyMemory
|
||||
#undef MoveMemory
|
||||
#undef FillMemory
|
||||
|
||||
//! Clears a buffer.
|
||||
//! \param addr [in] buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \see FillMemory
|
||||
//! \see StoreDwords
|
||||
//! \see CopyMemory
|
||||
//! \see MoveMemory
|
||||
inline_ void ZeroMemory(void* addr, udword size) { memset(addr, 0, size); }
|
||||
|
||||
//! Fills a buffer with a given byte.
|
||||
//! \param addr [in] buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \param val [in] the byte value
|
||||
//! \see StoreDwords
|
||||
//! \see ZeroMemory
|
||||
//! \see CopyMemory
|
||||
//! \see MoveMemory
|
||||
inline_ void FillMemory(void* dest, udword size, ubyte val) { memset(dest, val, size); }
|
||||
|
||||
//! Fills a buffer with a given dword.
|
||||
//! \param addr [in] buffer address
|
||||
//! \param nb [in] number of dwords to write
|
||||
//! \param value [in] the dword value
|
||||
//! \see FillMemory
|
||||
//! \see ZeroMemory
|
||||
//! \see CopyMemory
|
||||
//! \see MoveMemory
|
||||
//! \warning writes nb*4 bytes !
|
||||
inline_ void StoreDwords(udword* dest, udword nb, udword value)
|
||||
{
|
||||
// The asm code below **SHOULD** be equivalent to one of those C versions
|
||||
// or the other if your compiled is good: (checked on VC++ 6.0)
|
||||
//
|
||||
// 1) while(nb--) *dest++ = value;
|
||||
//
|
||||
// 2) for(udword i=0;i<nb;i++) dest[i] = value;
|
||||
//
|
||||
_asm push eax
|
||||
_asm push ecx
|
||||
_asm push edi
|
||||
_asm mov edi, dest
|
||||
_asm mov ecx, nb
|
||||
_asm mov eax, value
|
||||
_asm rep stosd
|
||||
_asm pop edi
|
||||
_asm pop ecx
|
||||
_asm pop eax
|
||||
}
|
||||
|
||||
//! Copies a buffer.
|
||||
//! \param addr [in] destination buffer address
|
||||
//! \param addr [in] source buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \see ZeroMemory
|
||||
//! \see FillMemory
|
||||
//! \see StoreDwords
|
||||
//! \see MoveMemory
|
||||
inline_ void CopyMemory(void* dest, const void* src, udword size) { memcpy(dest, src, size); }
|
||||
|
||||
//! Moves a buffer.
|
||||
//! \param addr [in] destination buffer address
|
||||
//! \param addr [in] source buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \see ZeroMemory
|
||||
//! \see FillMemory
|
||||
//! \see StoreDwords
|
||||
//! \see CopyMemory
|
||||
inline_ void MoveMemory(void* dest, const void* src, udword size) { memmove(dest, src, size); }
|
||||
|
||||
#define SIZEOFOBJECT sizeof(*this) //!< Gives the size of current object. Avoid some mistakes (e.g. "sizeof(this)").
|
||||
//#define CLEAROBJECT { memset(this, 0, SIZEOFOBJECT); } //!< Clears current object. Laziness is my business. HANDLE WITH CARE.
|
||||
#define DELETESINGLE(x) if (x) { delete x; x = null; } //!< Deletes an instance of a class.
|
||||
#define DELETEARRAY(x) if (x) { delete []x; x = null; } //!< Deletes an array.
|
||||
#define SAFE_RELEASE(x) if (x) { (x)->Release(); (x) = null; } //!< Safe D3D-style release
|
||||
#define SAFE_DESTRUCT(x) if (x) { (x)->SelfDestruct(); (x) = null; } //!< Safe ICE-style release
|
||||
|
||||
#ifdef __ICEERROR_H__
|
||||
#define CHECKALLOC(x) if(!x) return SetIceError("Out of memory.", EC_OUT_OF_MEMORY); //!< Standard alloc checking. HANDLE WITH CARE.
|
||||
#else
|
||||
#define CHECKALLOC(x) if(!x) return false;
|
||||
#endif
|
||||
|
||||
//! Standard allocation cycle
|
||||
#define SAFE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = new type[count]; CHECKALLOC(ptr);
|
||||
|
||||
#endif // __ICEMEMORYMACROS_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains all memory macros.
|
||||
* \file IceMemoryMacros.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEMEMORYMACROS_H__
|
||||
#define __ICEMEMORYMACROS_H__
|
||||
|
||||
#undef ZeroMemory
|
||||
#undef CopyMemory
|
||||
#undef MoveMemory
|
||||
#undef FillMemory
|
||||
|
||||
//! Clears a buffer.
|
||||
//! \param addr [in] buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \see FillMemory
|
||||
//! \see StoreDwords
|
||||
//! \see CopyMemory
|
||||
//! \see MoveMemory
|
||||
inline_ void ZeroMemory(void* addr, udword size) { memset(addr, 0, size); }
|
||||
|
||||
//! Fills a buffer with a given byte.
|
||||
//! \param addr [in] buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \param val [in] the byte value
|
||||
//! \see StoreDwords
|
||||
//! \see ZeroMemory
|
||||
//! \see CopyMemory
|
||||
//! \see MoveMemory
|
||||
inline_ void FillMemory(void* dest, udword size, ubyte val) { memset(dest, val, size); }
|
||||
|
||||
//! Fills a buffer with a given dword.
|
||||
//! \param addr [in] buffer address
|
||||
//! \param nb [in] number of dwords to write
|
||||
//! \param value [in] the dword value
|
||||
//! \see FillMemory
|
||||
//! \see ZeroMemory
|
||||
//! \see CopyMemory
|
||||
//! \see MoveMemory
|
||||
//! \warning writes nb*4 bytes !
|
||||
inline_ void StoreDwords(udword* dest, udword nb, udword value)
|
||||
{
|
||||
// The asm code below **SHOULD** be equivalent to one of those C versions
|
||||
// or the other if your compiled is good: (checked on VC++ 6.0)
|
||||
//
|
||||
// 1) while(nb--) *dest++ = value;
|
||||
//
|
||||
// 2) for(udword i=0;i<nb;i++) dest[i] = value;
|
||||
//
|
||||
_asm push eax
|
||||
_asm push ecx
|
||||
_asm push edi
|
||||
_asm mov edi, dest
|
||||
_asm mov ecx, nb
|
||||
_asm mov eax, value
|
||||
_asm rep stosd
|
||||
_asm pop edi
|
||||
_asm pop ecx
|
||||
_asm pop eax
|
||||
}
|
||||
|
||||
//! Copies a buffer.
|
||||
//! \param addr [in] destination buffer address
|
||||
//! \param addr [in] source buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \see ZeroMemory
|
||||
//! \see FillMemory
|
||||
//! \see StoreDwords
|
||||
//! \see MoveMemory
|
||||
inline_ void CopyMemory(void* dest, const void* src, udword size) { memcpy(dest, src, size); }
|
||||
|
||||
//! Moves a buffer.
|
||||
//! \param addr [in] destination buffer address
|
||||
//! \param addr [in] source buffer address
|
||||
//! \param size [in] buffer length
|
||||
//! \see ZeroMemory
|
||||
//! \see FillMemory
|
||||
//! \see StoreDwords
|
||||
//! \see CopyMemory
|
||||
inline_ void MoveMemory(void* dest, const void* src, udword size) { memmove(dest, src, size); }
|
||||
|
||||
#define SIZEOFOBJECT sizeof(*this) //!< Gives the size of current object. Avoid some mistakes (e.g. "sizeof(this)").
|
||||
//#define CLEAROBJECT { memset(this, 0, SIZEOFOBJECT); } //!< Clears current object. Laziness is my business. HANDLE WITH CARE.
|
||||
#define DELETESINGLE(x) if (x) { delete x; x = null; } //!< Deletes an instance of a class.
|
||||
#define DELETEARRAY(x) if (x) { delete []x; x = null; } //!< Deletes an array.
|
||||
#define SAFE_RELEASE(x) if (x) { (x)->Release(); (x) = null; } //!< Safe D3D-style release
|
||||
#define SAFE_DESTRUCT(x) if (x) { (x)->SelfDestruct(); (x) = null; } //!< Safe ICE-style release
|
||||
|
||||
#ifdef __ICEERROR_H__
|
||||
#define CHECKALLOC(x) if(!x) return SetIceError("Out of memory.", EC_OUT_OF_MEMORY); //!< Standard alloc checking. HANDLE WITH CARE.
|
||||
#else
|
||||
#define CHECKALLOC(x) if(!x) return false;
|
||||
#endif
|
||||
|
||||
//! Standard allocation cycle
|
||||
#define SAFE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = new type[count]; CHECKALLOC(ptr);
|
||||
|
||||
#endif // __ICEMEMORYMACROS_H__
|
||||
|
||||
@@ -1,144 +1,144 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains preprocessor stuff. This should be the first included header.
|
||||
* \file IcePreprocessor.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEPREPROCESSOR_H__
|
||||
#define __ICEPREPROCESSOR_H__
|
||||
|
||||
// Check platform
|
||||
#if defined( _WIN32 ) || defined( WIN32 )
|
||||
#pragma message("Compiling on Windows...")
|
||||
#define PLATFORM_WINDOWS
|
||||
#else
|
||||
#pragma message("Compiling on unknown platform...")
|
||||
#endif
|
||||
|
||||
// Check compiler
|
||||
#if defined(_MSC_VER)
|
||||
#pragma message("Compiling with VC++...")
|
||||
#define COMPILER_VISUAL_CPP
|
||||
#else
|
||||
#pragma message("Compiling with unknown compiler...")
|
||||
#endif
|
||||
|
||||
// Check compiler options. If this file is included in user-apps, this
|
||||
// shouldn't be needed, so that they can use what they like best.
|
||||
#ifndef ICE_DONT_CHECK_COMPILER_OPTIONS
|
||||
#ifdef COMPILER_VISUAL_CPP
|
||||
#if defined(_CHAR_UNSIGNED)
|
||||
#endif
|
||||
|
||||
#if defined(_CPPRTTI)
|
||||
#error Please disable RTTI...
|
||||
#endif
|
||||
|
||||
#if defined(_CPPUNWIND)
|
||||
#error Please disable exceptions...
|
||||
#endif
|
||||
|
||||
#if defined(_MT)
|
||||
// Multithreading
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Check debug mode
|
||||
#ifdef DEBUG // May be defined instead of _DEBUG. Let's fix it.
|
||||
#ifndef _DEBUG
|
||||
#define _DEBUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Here you may define items for debug builds
|
||||
#endif
|
||||
|
||||
#ifndef THIS_FILE
|
||||
#define THIS_FILE __FILE__
|
||||
#endif
|
||||
|
||||
#ifndef ICE_NO_DLL
|
||||
#ifdef ICECORE_EXPORTS
|
||||
#define ICECORE_API __declspec(dllexport)
|
||||
#else
|
||||
#define ICECORE_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define ICECORE_API
|
||||
#endif
|
||||
|
||||
// Don't override new/delete
|
||||
// #define DEFAULT_NEWDELETE
|
||||
#define DONT_TRACK_MEMORY_LEAKS
|
||||
|
||||
#define FUNCTION extern "C"
|
||||
|
||||
// Cosmetic stuff [mainly useful with multiple inheritance]
|
||||
#define override(base_class) virtual
|
||||
|
||||
// Our own inline keyword, so that:
|
||||
// - we can switch to __forceinline to check it's really better or not
|
||||
// - we can remove __forceinline if the compiler doesn't support it
|
||||
// #define inline_ __forceinline
|
||||
// #define inline_ inline
|
||||
|
||||
// Contributed by Bruce Mitchener
|
||||
#if defined(COMPILER_VISUAL_CPP)
|
||||
#define inline_ __forceinline
|
||||
// #define inline_ inline
|
||||
#elif defined(__GNUC__) && __GNUC__ < 3
|
||||
#define inline_ inline
|
||||
#elif defined(__GNUC__)
|
||||
#define inline_ inline __attribute__ ((always_inline))
|
||||
#else
|
||||
#define inline_ inline
|
||||
#endif
|
||||
|
||||
// Down the hatch
|
||||
#pragma inline_depth( 255 )
|
||||
|
||||
#ifdef COMPILER_VISUAL_CPP
|
||||
#pragma intrinsic(memcmp)
|
||||
#pragma intrinsic(memcpy)
|
||||
#pragma intrinsic(memset)
|
||||
#pragma intrinsic(strcat)
|
||||
#pragma intrinsic(strcmp)
|
||||
#pragma intrinsic(strcpy)
|
||||
#pragma intrinsic(strlen)
|
||||
#pragma intrinsic(abs)
|
||||
#pragma intrinsic(labs)
|
||||
#endif
|
||||
|
||||
// ANSI compliance
|
||||
#ifdef _DEBUG
|
||||
// Remove painful warning in debug
|
||||
inline_ bool __False__(){ return false; }
|
||||
#define for if(__False__()){} else for
|
||||
#else
|
||||
#define for if(0){} else for
|
||||
#endif
|
||||
|
||||
#endif // __ICEPREPROCESSOR_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains preprocessor stuff. This should be the first included header.
|
||||
* \file IcePreprocessor.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEPREPROCESSOR_H__
|
||||
#define __ICEPREPROCESSOR_H__
|
||||
|
||||
// Check platform
|
||||
#if defined( _WIN32 ) || defined( WIN32 )
|
||||
#pragma message("Compiling on Windows...")
|
||||
#define PLATFORM_WINDOWS
|
||||
#else
|
||||
#pragma message("Compiling on unknown platform...")
|
||||
#endif
|
||||
|
||||
// Check compiler
|
||||
#if defined(_MSC_VER)
|
||||
#pragma message("Compiling with VC++...")
|
||||
#define COMPILER_VISUAL_CPP
|
||||
#else
|
||||
#pragma message("Compiling with unknown compiler...")
|
||||
#endif
|
||||
|
||||
// Check compiler options. If this file is included in user-apps, this
|
||||
// shouldn't be needed, so that they can use what they like best.
|
||||
#ifndef ICE_DONT_CHECK_COMPILER_OPTIONS
|
||||
#ifdef COMPILER_VISUAL_CPP
|
||||
#if defined(_CHAR_UNSIGNED)
|
||||
#endif
|
||||
|
||||
#if defined(_CPPRTTI)
|
||||
#error Please disable RTTI...
|
||||
#endif
|
||||
|
||||
#if defined(_CPPUNWIND)
|
||||
#error Please disable exceptions...
|
||||
#endif
|
||||
|
||||
#if defined(_MT)
|
||||
// Multithreading
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Check debug mode
|
||||
#ifdef DEBUG // May be defined instead of _DEBUG. Let's fix it.
|
||||
#ifndef _DEBUG
|
||||
#define _DEBUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Here you may define items for debug builds
|
||||
#endif
|
||||
|
||||
#ifndef THIS_FILE
|
||||
#define THIS_FILE __FILE__
|
||||
#endif
|
||||
|
||||
#ifndef ICE_NO_DLL
|
||||
#ifdef ICECORE_EXPORTS
|
||||
#define ICECORE_API __declspec(dllexport)
|
||||
#else
|
||||
#define ICECORE_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define ICECORE_API
|
||||
#endif
|
||||
|
||||
// Don't override new/delete
|
||||
// #define DEFAULT_NEWDELETE
|
||||
#define DONT_TRACK_MEMORY_LEAKS
|
||||
|
||||
#define FUNCTION extern "C"
|
||||
|
||||
// Cosmetic stuff [mainly useful with multiple inheritance]
|
||||
#define override(base_class) virtual
|
||||
|
||||
// Our own inline keyword, so that:
|
||||
// - we can switch to __forceinline to check it's really better or not
|
||||
// - we can remove __forceinline if the compiler doesn't support it
|
||||
// #define inline_ __forceinline
|
||||
// #define inline_ inline
|
||||
|
||||
// Contributed by Bruce Mitchener
|
||||
#if defined(COMPILER_VISUAL_CPP)
|
||||
#define inline_ __forceinline
|
||||
// #define inline_ inline
|
||||
#elif defined(__GNUC__) && __GNUC__ < 3
|
||||
#define inline_ inline
|
||||
#elif defined(__GNUC__)
|
||||
#define inline_ inline __attribute__ ((always_inline))
|
||||
#else
|
||||
#define inline_ inline
|
||||
#endif
|
||||
|
||||
// Down the hatch
|
||||
#pragma inline_depth( 255 )
|
||||
|
||||
#ifdef COMPILER_VISUAL_CPP
|
||||
#pragma intrinsic(memcmp)
|
||||
#pragma intrinsic(memcpy)
|
||||
#pragma intrinsic(memset)
|
||||
#pragma intrinsic(strcat)
|
||||
#pragma intrinsic(strcmp)
|
||||
#pragma intrinsic(strcpy)
|
||||
#pragma intrinsic(strlen)
|
||||
#pragma intrinsic(abs)
|
||||
#pragma intrinsic(labs)
|
||||
#endif
|
||||
|
||||
// ANSI compliance
|
||||
#ifdef _DEBUG
|
||||
// Remove painful warning in debug
|
||||
inline_ bool __False__(){ return false; }
|
||||
#define for if(__False__()){} else for
|
||||
#else
|
||||
#define for if(0){} else for
|
||||
#endif
|
||||
|
||||
#endif // __ICEPREPROCESSOR_H__
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,81 +1,81 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains source code from the article "Radix Sort Revisited".
|
||||
* \file IceRevisitedRadix.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICERADIXSORT_H__
|
||||
#define __ICERADIXSORT_H__
|
||||
|
||||
//! Allocate histograms & offsets locally
|
||||
#define RADIX_LOCAL_RAM
|
||||
|
||||
enum RadixHint
|
||||
{
|
||||
RADIX_SIGNED, //!< Input values are signed
|
||||
RADIX_UNSIGNED, //!< Input values are unsigned
|
||||
|
||||
RADIX_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
class ICECORE_API RadixSort
|
||||
{
|
||||
public:
|
||||
// Constructor/Destructor
|
||||
RadixSort();
|
||||
~RadixSort();
|
||||
// Sorting methods
|
||||
RadixSort& Sort(const udword* input, udword nb, RadixHint hint=RADIX_SIGNED);
|
||||
RadixSort& Sort(const float* input, udword nb);
|
||||
|
||||
//! Access to results. mRanks is a list of indices in sorted order, i.e. in the order you may further process your data
|
||||
inline_ const udword* GetRanks() const { return mRanks; }
|
||||
|
||||
//! mIndices2 gets trashed on calling the sort routine, but otherwise you can recycle it the way you want.
|
||||
inline_ udword* GetRecyclable() const { return mRanks2; }
|
||||
|
||||
// Stats
|
||||
udword GetUsedRam() const;
|
||||
//! Returns the total number of calls to the radix sorter.
|
||||
inline_ udword GetNbTotalCalls() const { return mTotalCalls; }
|
||||
//! Returns the number of eraly exits due to temporal coherence.
|
||||
inline_ udword GetNbHits() const { return mNbHits; }
|
||||
|
||||
private:
|
||||
#ifndef RADIX_LOCAL_RAM
|
||||
udword* mHistogram; //!< Counters for each byte
|
||||
udword* mOffset; //!< Offsets (nearly a cumulative distribution function)
|
||||
#endif
|
||||
udword mCurrentSize; //!< Current size of the indices list
|
||||
udword* mRanks; //!< Two lists, swapped each pass
|
||||
udword* mRanks2;
|
||||
// Stats
|
||||
udword mTotalCalls; //!< Total number of calls to the sort routine
|
||||
udword mNbHits; //!< Number of early exits due to coherence
|
||||
// Internal methods
|
||||
void CheckResize(udword nb);
|
||||
bool Resize(udword nb);
|
||||
};
|
||||
|
||||
#endif // __ICERADIXSORT_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains source code from the article "Radix Sort Revisited".
|
||||
* \file IceRevisitedRadix.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICERADIXSORT_H__
|
||||
#define __ICERADIXSORT_H__
|
||||
|
||||
//! Allocate histograms & offsets locally
|
||||
#define RADIX_LOCAL_RAM
|
||||
|
||||
enum RadixHint
|
||||
{
|
||||
RADIX_SIGNED, //!< Input values are signed
|
||||
RADIX_UNSIGNED, //!< Input values are unsigned
|
||||
|
||||
RADIX_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
class ICECORE_API RadixSort
|
||||
{
|
||||
public:
|
||||
// Constructor/Destructor
|
||||
RadixSort();
|
||||
~RadixSort();
|
||||
// Sorting methods
|
||||
RadixSort& Sort(const udword* input, udword nb, RadixHint hint=RADIX_SIGNED);
|
||||
RadixSort& Sort(const float* input, udword nb);
|
||||
|
||||
//! Access to results. mRanks is a list of indices in sorted order, i.e. in the order you may further process your data
|
||||
inline_ const udword* GetRanks() const { return mRanks; }
|
||||
|
||||
//! mIndices2 gets trashed on calling the sort routine, but otherwise you can recycle it the way you want.
|
||||
inline_ udword* GetRecyclable() const { return mRanks2; }
|
||||
|
||||
// Stats
|
||||
udword GetUsedRam() const;
|
||||
//! Returns the total number of calls to the radix sorter.
|
||||
inline_ udword GetNbTotalCalls() const { return mTotalCalls; }
|
||||
//! Returns the number of eraly exits due to temporal coherence.
|
||||
inline_ udword GetNbHits() const { return mNbHits; }
|
||||
|
||||
private:
|
||||
#ifndef RADIX_LOCAL_RAM
|
||||
udword* mHistogram; //!< Counters for each byte
|
||||
udword* mOffset; //!< Offsets (nearly a cumulative distribution function)
|
||||
#endif
|
||||
udword mCurrentSize; //!< Current size of the indices list
|
||||
udword* mRanks; //!< Two lists, swapped each pass
|
||||
udword* mRanks2;
|
||||
// Stats
|
||||
udword mTotalCalls; //!< Total number of calls to the sort routine
|
||||
udword mNbHits; //!< Number of early exits due to coherence
|
||||
// Internal methods
|
||||
void CheckResize(udword nb);
|
||||
bool Resize(udword nb);
|
||||
};
|
||||
|
||||
#endif // __ICERADIXSORT_H__
|
||||
|
||||
@@ -1,173 +1,173 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains custom types.
|
||||
* \file IceTypes.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICETYPES_H__
|
||||
#define __ICETYPES_H__
|
||||
|
||||
#define USE_HANDLE_MANAGER
|
||||
|
||||
// Constants
|
||||
#define PI 3.1415926535897932384626433832795028841971693993751f //!< PI
|
||||
#define HALFPI 1.57079632679489661923f //!< 0.5 * PI
|
||||
#define TWOPI 6.28318530717958647692f //!< 2.0 * PI
|
||||
#define INVPI 0.31830988618379067154f //!< 1.0 / PI
|
||||
|
||||
#define RADTODEG 57.2957795130823208768f //!< 180.0 / PI, convert radians to degrees
|
||||
#define DEGTORAD 0.01745329251994329577f //!< PI / 180.0, convert degrees to radians
|
||||
|
||||
#define EXP 2.71828182845904523536f //!< e
|
||||
#define INVLOG2 3.32192809488736234787f //!< 1.0 / log10(2)
|
||||
#define LN2 0.693147180559945f //!< ln(2)
|
||||
#define INVLN2 1.44269504089f //!< 1.0f / ln(2)
|
||||
|
||||
#define INV3 0.33333333333333333333f //!< 1/3
|
||||
#define INV6 0.16666666666666666666f //!< 1/6
|
||||
#define INV7 0.14285714285714285714f //!< 1/7
|
||||
#define INV9 0.11111111111111111111f //!< 1/9
|
||||
#define INV255 0.00392156862745098039f //!< 1/255
|
||||
|
||||
#define SQRT2 1.41421356237f //!< sqrt(2)
|
||||
#define INVSQRT2 0.707106781188f //!< 1 / sqrt(2)
|
||||
|
||||
#define SQRT3 1.73205080757f //!< sqrt(3)
|
||||
#define INVSQRT3 0.577350269189f //!< 1 / sqrt(3)
|
||||
|
||||
#define null 0 //!< our own NULL pointer
|
||||
|
||||
// Custom types used in ICE
|
||||
typedef signed char sbyte; //!< sizeof(sbyte) must be 1
|
||||
typedef unsigned char ubyte; //!< sizeof(ubyte) must be 1
|
||||
typedef signed short sword; //!< sizeof(sword) must be 2
|
||||
typedef unsigned short uword; //!< sizeof(uword) must be 2
|
||||
typedef signed int sdword; //!< sizeof(sdword) must be 4
|
||||
typedef unsigned int udword; //!< sizeof(udword) must be 4
|
||||
typedef signed __int64 sqword; //!< sizeof(sqword) must be 8
|
||||
typedef unsigned __int64 uqword; //!< sizeof(uqword) must be 8
|
||||
typedef float float32; //!< sizeof(float32) must be 4
|
||||
typedef double float64; //!< sizeof(float64) must be 4
|
||||
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(bool)==1); // ...otherwise things might fail with VC++ 4.2 !
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(ubyte)==1);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sbyte)==1);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sword)==2);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(uword)==2);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(udword)==4);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sdword)==4);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(uqword)==8);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sqword)==8);
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
#define DECLARE_ICE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
|
||||
|
||||
typedef udword DynID; //!< Dynamic identifier
|
||||
#ifdef USE_HANDLE_MANAGER
|
||||
typedef udword KID; //!< Kernel ID
|
||||
// DECLARE_ICE_HANDLE(KID);
|
||||
#else
|
||||
typedef uword KID; //!< Kernel ID
|
||||
#endif
|
||||
typedef udword RTYPE; //!< Relationship-type (!) between owners and references
|
||||
#define INVALID_ID 0xffffffff //!< Invalid dword ID (counterpart of null pointers)
|
||||
#ifdef USE_HANDLE_MANAGER
|
||||
#define INVALID_KID 0xffffffff //!< Invalid Kernel ID
|
||||
#else
|
||||
#define INVALID_KID 0xffff //!< Invalid Kernel ID
|
||||
#endif
|
||||
#define INVALID_NUMBER 0xDEADBEEF //!< Standard junk value
|
||||
|
||||
// Define BOOL if needed
|
||||
#ifndef BOOL
|
||||
typedef int BOOL; //!< Another boolean type.
|
||||
#endif
|
||||
|
||||
//! Union of a float and a sdword
|
||||
typedef union {
|
||||
float f; //!< The float
|
||||
sdword d; //!< The integer
|
||||
}scell;
|
||||
|
||||
//! Union of a float and a udword
|
||||
typedef union {
|
||||
float f; //!< The float
|
||||
udword d; //!< The integer
|
||||
}ucell;
|
||||
|
||||
// Type ranges
|
||||
#define MAX_SBYTE 0x7f //!< max possible sbyte value
|
||||
#define MIN_SBYTE 0x80 //!< min possible sbyte value
|
||||
#define MAX_UBYTE 0xff //!< max possible ubyte value
|
||||
#define MIN_UBYTE 0x00 //!< min possible ubyte value
|
||||
#define MAX_SWORD 0x7fff //!< max possible sword value
|
||||
#define MIN_SWORD 0x8000 //!< min possible sword value
|
||||
#define MAX_UWORD 0xffff //!< max possible uword value
|
||||
#define MIN_UWORD 0x0000 //!< min possible uword value
|
||||
#define MAX_SDWORD 0x7fffffff //!< max possible sdword value
|
||||
#define MIN_SDWORD 0x80000000 //!< min possible sdword value
|
||||
#define MAX_UDWORD 0xffffffff //!< max possible udword value
|
||||
#define MIN_UDWORD 0x00000000 //!< min possible udword value
|
||||
#define MAX_FLOAT FLT_MAX //!< max possible float value
|
||||
#define MIN_FLOAT (-FLT_MAX) //!< min possible loat value
|
||||
#define IEEE_1_0 0x3f800000 //!< integer representation of 1.0
|
||||
#define IEEE_255_0 0x437f0000 //!< integer representation of 255.0
|
||||
#define IEEE_MAX_FLOAT 0x7f7fffff //!< integer representation of MAX_FLOAT
|
||||
#define IEEE_MIN_FLOAT 0xff7fffff //!< integer representation of MIN_FLOAT
|
||||
#define IEEE_UNDERFLOW_LIMIT 0x1a000000
|
||||
|
||||
#define ONE_OVER_RAND_MAX (1.0f / float(RAND_MAX)) //!< Inverse of the max possible value returned by rand()
|
||||
|
||||
typedef int (__stdcall* PROC)(); //!< A standard procedure call.
|
||||
typedef bool (*ENUMERATION)(udword value, udword param, udword context); //!< ICE standard enumeration call
|
||||
typedef void** VTABLE; //!< A V-Table.
|
||||
|
||||
#undef MIN
|
||||
#undef MAX
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b)) //!< Returns the min value between a and b
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b)) //!< Returns the max value between a and b
|
||||
#define MAXMAX(a,b,c) ((a) > (b) ? MAX (a,c) : MAX (b,c)) //!< Returns the max value between a, b and c
|
||||
|
||||
template<class T> inline_ const T& TMin (const T& a, const T& b) { return b < a ? b : a; }
|
||||
template<class T> inline_ const T& TMax (const T& a, const T& b) { return a < b ? b : a; }
|
||||
template<class T> inline_ void TSetMin (T& a, const T& b) { if(a>b) a = b; }
|
||||
template<class T> inline_ void TSetMax (T& a, const T& b) { if(a<b) a = b; }
|
||||
|
||||
#define SQR(x) ((x)*(x)) //!< Returns x square
|
||||
#define CUBE(x) ((x)*(x)*(x)) //!< Returns x cube
|
||||
|
||||
#define AND & //!< ...
|
||||
#define OR | //!< ...
|
||||
#define XOR ^ //!< ...
|
||||
|
||||
#define QUADRAT(x) ((x)*(x)) //!< Returns x square
|
||||
|
||||
#ifdef _WIN32
|
||||
# define srand48(x) srand((unsigned int) (x))
|
||||
# define srandom(x) srand((unsigned int) (x))
|
||||
# define random() ((double) rand())
|
||||
# define drand48() ((double) (((double) rand()) / ((double) RAND_MAX)))
|
||||
#endif
|
||||
|
||||
#endif // __ICETYPES_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains custom types.
|
||||
* \file IceTypes.h
|
||||
* \author Pierre Terdiman
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICETYPES_H__
|
||||
#define __ICETYPES_H__
|
||||
|
||||
#define USE_HANDLE_MANAGER
|
||||
|
||||
// Constants
|
||||
#define PI 3.1415926535897932384626433832795028841971693993751f //!< PI
|
||||
#define HALFPI 1.57079632679489661923f //!< 0.5 * PI
|
||||
#define TWOPI 6.28318530717958647692f //!< 2.0 * PI
|
||||
#define INVPI 0.31830988618379067154f //!< 1.0 / PI
|
||||
|
||||
#define RADTODEG 57.2957795130823208768f //!< 180.0 / PI, convert radians to degrees
|
||||
#define DEGTORAD 0.01745329251994329577f //!< PI / 180.0, convert degrees to radians
|
||||
|
||||
#define EXP 2.71828182845904523536f //!< e
|
||||
#define INVLOG2 3.32192809488736234787f //!< 1.0 / log10(2)
|
||||
#define LN2 0.693147180559945f //!< ln(2)
|
||||
#define INVLN2 1.44269504089f //!< 1.0f / ln(2)
|
||||
|
||||
#define INV3 0.33333333333333333333f //!< 1/3
|
||||
#define INV6 0.16666666666666666666f //!< 1/6
|
||||
#define INV7 0.14285714285714285714f //!< 1/7
|
||||
#define INV9 0.11111111111111111111f //!< 1/9
|
||||
#define INV255 0.00392156862745098039f //!< 1/255
|
||||
|
||||
#define SQRT2 1.41421356237f //!< sqrt(2)
|
||||
#define INVSQRT2 0.707106781188f //!< 1 / sqrt(2)
|
||||
|
||||
#define SQRT3 1.73205080757f //!< sqrt(3)
|
||||
#define INVSQRT3 0.577350269189f //!< 1 / sqrt(3)
|
||||
|
||||
#define null 0 //!< our own NULL pointer
|
||||
|
||||
// Custom types used in ICE
|
||||
typedef signed char sbyte; //!< sizeof(sbyte) must be 1
|
||||
typedef unsigned char ubyte; //!< sizeof(ubyte) must be 1
|
||||
typedef signed short sword; //!< sizeof(sword) must be 2
|
||||
typedef unsigned short uword; //!< sizeof(uword) must be 2
|
||||
typedef signed int sdword; //!< sizeof(sdword) must be 4
|
||||
typedef unsigned int udword; //!< sizeof(udword) must be 4
|
||||
typedef signed __int64 sqword; //!< sizeof(sqword) must be 8
|
||||
typedef unsigned __int64 uqword; //!< sizeof(uqword) must be 8
|
||||
typedef float float32; //!< sizeof(float32) must be 4
|
||||
typedef double float64; //!< sizeof(float64) must be 4
|
||||
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(bool)==1); // ...otherwise things might fail with VC++ 4.2 !
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(ubyte)==1);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sbyte)==1);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sword)==2);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(uword)==2);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(udword)==4);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sdword)==4);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(uqword)==8);
|
||||
ICE_COMPILE_TIME_ASSERT(sizeof(sqword)==8);
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
#define DECLARE_ICE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
|
||||
|
||||
typedef udword DynID; //!< Dynamic identifier
|
||||
#ifdef USE_HANDLE_MANAGER
|
||||
typedef udword KID; //!< Kernel ID
|
||||
// DECLARE_ICE_HANDLE(KID);
|
||||
#else
|
||||
typedef uword KID; //!< Kernel ID
|
||||
#endif
|
||||
typedef udword RTYPE; //!< Relationship-type (!) between owners and references
|
||||
#define INVALID_ID 0xffffffff //!< Invalid dword ID (counterpart of null pointers)
|
||||
#ifdef USE_HANDLE_MANAGER
|
||||
#define INVALID_KID 0xffffffff //!< Invalid Kernel ID
|
||||
#else
|
||||
#define INVALID_KID 0xffff //!< Invalid Kernel ID
|
||||
#endif
|
||||
#define INVALID_NUMBER 0xDEADBEEF //!< Standard junk value
|
||||
|
||||
// Define BOOL if needed
|
||||
#ifndef BOOL
|
||||
typedef int BOOL; //!< Another boolean type.
|
||||
#endif
|
||||
|
||||
//! Union of a float and a sdword
|
||||
typedef union {
|
||||
float f; //!< The float
|
||||
sdword d; //!< The integer
|
||||
}scell;
|
||||
|
||||
//! Union of a float and a udword
|
||||
typedef union {
|
||||
float f; //!< The float
|
||||
udword d; //!< The integer
|
||||
}ucell;
|
||||
|
||||
// Type ranges
|
||||
#define MAX_SBYTE 0x7f //!< max possible sbyte value
|
||||
#define MIN_SBYTE 0x80 //!< min possible sbyte value
|
||||
#define MAX_UBYTE 0xff //!< max possible ubyte value
|
||||
#define MIN_UBYTE 0x00 //!< min possible ubyte value
|
||||
#define MAX_SWORD 0x7fff //!< max possible sword value
|
||||
#define MIN_SWORD 0x8000 //!< min possible sword value
|
||||
#define MAX_UWORD 0xffff //!< max possible uword value
|
||||
#define MIN_UWORD 0x0000 //!< min possible uword value
|
||||
#define MAX_SDWORD 0x7fffffff //!< max possible sdword value
|
||||
#define MIN_SDWORD 0x80000000 //!< min possible sdword value
|
||||
#define MAX_UDWORD 0xffffffff //!< max possible udword value
|
||||
#define MIN_UDWORD 0x00000000 //!< min possible udword value
|
||||
#define MAX_FLOAT FLT_MAX //!< max possible float value
|
||||
#define MIN_FLOAT (-FLT_MAX) //!< min possible loat value
|
||||
#define IEEE_1_0 0x3f800000 //!< integer representation of 1.0
|
||||
#define IEEE_255_0 0x437f0000 //!< integer representation of 255.0
|
||||
#define IEEE_MAX_FLOAT 0x7f7fffff //!< integer representation of MAX_FLOAT
|
||||
#define IEEE_MIN_FLOAT 0xff7fffff //!< integer representation of MIN_FLOAT
|
||||
#define IEEE_UNDERFLOW_LIMIT 0x1a000000
|
||||
|
||||
#define ONE_OVER_RAND_MAX (1.0f / float(RAND_MAX)) //!< Inverse of the max possible value returned by rand()
|
||||
|
||||
typedef int (__stdcall* PROC)(); //!< A standard procedure call.
|
||||
typedef bool (*ENUMERATION)(udword value, udword param, udword context); //!< ICE standard enumeration call
|
||||
typedef void** VTABLE; //!< A V-Table.
|
||||
|
||||
#undef MIN
|
||||
#undef MAX
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b)) //!< Returns the min value between a and b
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b)) //!< Returns the max value between a and b
|
||||
#define MAXMAX(a,b,c) ((a) > (b) ? MAX (a,c) : MAX (b,c)) //!< Returns the max value between a, b and c
|
||||
|
||||
template<class T> inline_ const T& TMin (const T& a, const T& b) { return b < a ? b : a; }
|
||||
template<class T> inline_ const T& TMax (const T& a, const T& b) { return a < b ? b : a; }
|
||||
template<class T> inline_ void TSetMin (T& a, const T& b) { if(a>b) a = b; }
|
||||
template<class T> inline_ void TSetMax (T& a, const T& b) { if(a<b) a = b; }
|
||||
|
||||
#define SQR(x) ((x)*(x)) //!< Returns x square
|
||||
#define CUBE(x) ((x)*(x)*(x)) //!< Returns x cube
|
||||
|
||||
#define AND & //!< ...
|
||||
#define OR | //!< ...
|
||||
#define XOR ^ //!< ...
|
||||
|
||||
#define QUADRAT(x) ((x)*(x)) //!< Returns x square
|
||||
|
||||
#ifdef _WIN32
|
||||
# define srand48(x) srand((unsigned int) (x))
|
||||
# define srandom(x) srand((unsigned int) (x))
|
||||
# define random() ((double) rand())
|
||||
# define drand48() ((double) (((double) rand()) / ((double) RAND_MAX)))
|
||||
#endif
|
||||
|
||||
#endif // __ICETYPES_H__
|
||||
|
||||
@@ -1,272 +1,272 @@
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains misc. useful macros & defines.
|
||||
* \file IceUtils.h
|
||||
* \author Pierre Terdiman (collected from various sources)
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEUTILS_H__
|
||||
#define __ICEUTILS_H__
|
||||
|
||||
#define START_RUNONCE { static bool __RunOnce__ = false; if(!__RunOnce__){
|
||||
#define END_RUNONCE __RunOnce__ = true;}}
|
||||
|
||||
//! Reverse all the bits in a 32 bit word (from Steve Baker's Cute Code Collection)
|
||||
//! (each line can be done in any order.
|
||||
inline_ void ReverseBits(udword& n)
|
||||
{
|
||||
n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
|
||||
n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
|
||||
n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
|
||||
n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
|
||||
n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
|
||||
// Etc for larger intergers (64 bits in Java)
|
||||
// NOTE: the >> operation must be unsigned! (>>> in java)
|
||||
}
|
||||
|
||||
//! Count the number of '1' bits in a 32 bit word (from Steve Baker's Cute Code Collection)
|
||||
inline_ udword CountBits(udword n)
|
||||
{
|
||||
// This relies of the fact that the count of n bits can NOT overflow
|
||||
// an n bit interger. EG: 1 bit count takes a 1 bit interger, 2 bit counts
|
||||
// 2 bit interger, 3 bit count requires only a 2 bit interger.
|
||||
// So we add all bit pairs, then each nible, then each byte etc...
|
||||
n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1);
|
||||
n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2);
|
||||
n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4);
|
||||
n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8);
|
||||
n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16);
|
||||
// Etc for larger intergers (64 bits in Java)
|
||||
// NOTE: the >> operation must be unsigned! (>>> in java)
|
||||
return n;
|
||||
}
|
||||
|
||||
//! Even faster?
|
||||
inline_ udword CountBits2(udword bits)
|
||||
{
|
||||
bits = bits - ((bits >> 1) & 0x55555555);
|
||||
bits = ((bits >> 2) & 0x33333333) + (bits & 0x33333333);
|
||||
bits = ((bits >> 4) + bits) & 0x0F0F0F0F;
|
||||
return (bits * 0x01010101) >> 24;
|
||||
}
|
||||
|
||||
//! Spread out bits. EG 00001111 -> 0101010101
|
||||
//! 00001010 -> 0100010000
|
||||
//! This is used to interleve to intergers to produce a `Morten Key'
|
||||
//! used in Space Filling Curves (See DrDobbs Journal, July 1999)
|
||||
//! Order is important.
|
||||
inline_ void SpreadBits(udword& n)
|
||||
{
|
||||
n = ( n & 0x0000ffff) | (( n & 0xffff0000) << 16);
|
||||
n = ( n & 0x000000ff) | (( n & 0x0000ff00) << 8);
|
||||
n = ( n & 0x000f000f) | (( n & 0x00f000f0) << 4);
|
||||
n = ( n & 0x03030303) | (( n & 0x0c0c0c0c) << 2);
|
||||
n = ( n & 0x11111111) | (( n & 0x22222222) << 1);
|
||||
}
|
||||
|
||||
// Next Largest Power of 2
|
||||
// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
|
||||
// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
|
||||
// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
|
||||
// largest power of 2. For a 32-bit value:
|
||||
inline_ udword nlpo2(udword x)
|
||||
{
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
return x+1;
|
||||
}
|
||||
|
||||
//! Test to see if a number is an exact power of two (from Steve Baker's Cute Code Collection)
|
||||
inline_ bool IsPowerOfTwo(udword n) { return ((n&(n-1))==0); }
|
||||
|
||||
//! Zero the least significant '1' bit in a word. (from Steve Baker's Cute Code Collection)
|
||||
inline_ void ZeroLeastSetBit(udword& n) { n&=(n-1); }
|
||||
|
||||
//! Set the least significant N bits in a word. (from Steve Baker's Cute Code Collection)
|
||||
inline_ void SetLeastNBits(udword& x, udword n) { x|=~(~0<<n); }
|
||||
|
||||
//! Classic XOR swap (from Steve Baker's Cute Code Collection)
|
||||
//! x ^= y; /* x' = (x^y) */
|
||||
//! y ^= x; /* y' = (y^(x^y)) = x */
|
||||
//! x ^= y; /* x' = (x^y)^x = y */
|
||||
inline_ void Swap(udword& x, udword& y) { x ^= y; y ^= x; x ^= y; }
|
||||
|
||||
//! Little/Big endian (from Steve Baker's Cute Code Collection)
|
||||
//!
|
||||
//! Extra comments by Kenny Hoff:
|
||||
//! Determines the byte-ordering of the current machine (little or big endian)
|
||||
//! by setting an integer value to 1 (so least significant bit is now 1); take
|
||||
//! the address of the int and cast to a byte pointer (treat integer as an
|
||||
//! array of four bytes); check the value of the first byte (must be 0 or 1).
|
||||
//! If the value is 1, then the first byte least significant byte and this
|
||||
//! implies LITTLE endian. If the value is 0, the first byte is the most
|
||||
//! significant byte, BIG endian. Examples:
|
||||
//! integer 1 on BIG endian: 00000000 00000000 00000000 00000001
|
||||
//! integer 1 on LITTLE endian: 00000001 00000000 00000000 00000000
|
||||
//!---------------------------------------------------------------------------
|
||||
//! int IsLittleEndian() { int x=1; return ( ((char*)(&x))[0] ); }
|
||||
inline_ char LittleEndian() { int i = 1; return *((char*)&i); }
|
||||
|
||||
//!< Alternative abs function
|
||||
inline_ udword abs_(sdword x) { sdword y= x >> 31; return (x^y)-y; }
|
||||
|
||||
//!< Alternative min function
|
||||
inline_ sdword min_(sdword a, sdword b) { sdword delta = b-a; return a + (delta&(delta>>31)); }
|
||||
|
||||
// Determine if one of the bytes in a 4 byte word is zero
|
||||
inline_ BOOL HasNullByte(udword x) { return ((x + 0xfefefeff) & (~x) & 0x80808080); }
|
||||
|
||||
// To find the smallest 1 bit in a word EG: ~~~~~~10---0 => 0----010---0
|
||||
inline_ udword LowestOneBit(udword w) { return ((w) & (~(w)+1)); }
|
||||
// inline_ udword LowestOneBit_(udword w) { return ((w) & (-(w))); }
|
||||
|
||||
// Most Significant 1 Bit
|
||||
// Given a binary integer value x, the most significant 1 bit (highest numbered element of a bit set)
|
||||
// can be computed using a SWAR algorithm that recursively "folds" the upper bits into the lower bits.
|
||||
// This process yields a bit vector with the same most significant 1 as x, but all 1's below it.
|
||||
// Bitwise AND of the original value with the complement of the "folded" value shifted down by one
|
||||
// yields the most significant bit. For a 32-bit value:
|
||||
inline_ udword msb32(udword x)
|
||||
{
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
return (x & ~(x >> 1));
|
||||
}
|
||||
|
||||
/*
|
||||
"Just call it repeatedly with various input values and always with the same variable as "memory".
|
||||
The sharpness determines the degree of filtering, where 0 completely filters out the input, and 1
|
||||
does no filtering at all.
|
||||
|
||||
I seem to recall from college that this is called an IIR (Infinite Impulse Response) filter. As opposed
|
||||
to the more typical FIR (Finite Impulse Response).
|
||||
|
||||
Also, I'd say that you can make more intelligent and interesting filters than this, for example filters
|
||||
that remove wrong responses from the mouse because it's being moved too fast. You'd want such a filter
|
||||
to be applied before this one, of course."
|
||||
|
||||
(JCAB on Flipcode)
|
||||
*/
|
||||
inline_ float FeedbackFilter(float val, float& memory, float sharpness)
|
||||
{
|
||||
ASSERT(sharpness>=0.0f && sharpness<=1.0f && "Invalid sharpness value in feedback filter");
|
||||
if(sharpness<0.0f) sharpness = 0.0f;
|
||||
else if(sharpness>1.0f) sharpness = 1.0f;
|
||||
return memory = val * sharpness + memory * (1.0f - sharpness);
|
||||
}
|
||||
|
||||
//! If you can guarantee that your input domain (i.e. value of x) is slightly
|
||||
//! limited (abs(x) must be < ((1<<31u)-32767)), then you can use the
|
||||
//! following code to clamp the resulting value into [-32768,+32767] range:
|
||||
inline_ int ClampToInt16(int x)
|
||||
{
|
||||
// ASSERT(abs(x) < (int)((1<<31u)-32767));
|
||||
|
||||
int delta = 32767 - x;
|
||||
x += (delta>>31) & delta;
|
||||
delta = x + 32768;
|
||||
x -= (delta>>31) & delta;
|
||||
return x;
|
||||
}
|
||||
|
||||
// Generic functions
|
||||
template<class Type> inline_ void TSwap(Type& a, Type& b) { const Type c = a; a = b; b = c; }
|
||||
template<class Type> inline_ Type TClamp(const Type& x, const Type& lo, const Type& hi) { return ((x<lo) ? lo : (x>hi) ? hi : x); }
|
||||
|
||||
template<class Type> inline_ void TSort(Type& a, Type& b)
|
||||
{
|
||||
if(a>b) TSwap(a, b);
|
||||
}
|
||||
|
||||
template<class Type> inline_ void TSort(Type& a, Type& b, Type& c)
|
||||
{
|
||||
if(a>b) TSwap(a, b);
|
||||
if(b>c) TSwap(b, c);
|
||||
if(a>b) TSwap(a, b);
|
||||
if(b>c) TSwap(b, c);
|
||||
}
|
||||
|
||||
// Prevent nasty user-manipulations (strategy borrowed from Charles Bloom)
|
||||
// #define PREVENT_COPY(curclass) void operator = (const curclass& object) { ASSERT(!"Bad use of operator ="); }
|
||||
// ... actually this is better !
|
||||
#define PREVENT_COPY(cur_class) private: cur_class(const cur_class& object); cur_class& operator=(const cur_class& object);
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
#define OFFSET_OF(Class, Member) (size_t)&(((Class*)0)->Member)
|
||||
//! TO BE DOCUMENTED
|
||||
#define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0]))
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns the alignment of the input address.
|
||||
* \fn Alignment()
|
||||
* \param address [in] address to check
|
||||
* \return the best alignment (e.g. 1 for odd addresses, etc)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
FUNCTION ICECORE_API udword Alignment(udword address);
|
||||
|
||||
#define IS_ALIGNED_2(x) ((x&1)==0)
|
||||
#define IS_ALIGNED_4(x) ((x&3)==0)
|
||||
#define IS_ALIGNED_8(x) ((x&7)==0)
|
||||
|
||||
inline_ void _prefetch(void const* ptr) { (void)*(char const volatile *)ptr; }
|
||||
|
||||
// Compute implicit coords from an index:
|
||||
// The idea is to get back 2D coords from a 1D index.
|
||||
// For example:
|
||||
//
|
||||
// 0 1 2 ... nbu-1
|
||||
// nbu nbu+1 i ...
|
||||
//
|
||||
// We have i, we're looking for the equivalent (u=2, v=1) location.
|
||||
// i = u + v*nbu
|
||||
// <=> i/nbu = u/nbu + v
|
||||
// Since 0 <= u < nbu, u/nbu = 0 (integer)
|
||||
// Hence: v = i/nbu
|
||||
// Then we simply put it back in the original equation to compute u = i - v*nbu
|
||||
inline_ void Compute2DCoords(udword& u, udword& v, udword i, udword nbu)
|
||||
{
|
||||
v = i / nbu;
|
||||
u = i - (v * nbu);
|
||||
}
|
||||
|
||||
// In 3D: i = u + v*nbu + w*nbu*nbv
|
||||
// <=> i/(nbu*nbv) = u/(nbu*nbv) + v/nbv + w
|
||||
// u/(nbu*nbv) is null since u/nbu was null already.
|
||||
// v/nbv is null as well for the same reason.
|
||||
// Hence w = i/(nbu*nbv)
|
||||
// Then we're left with a 2D problem: i' = i - w*nbu*nbv = u + v*nbu
|
||||
inline_ void Compute3DCoords(udword& u, udword& v, udword& w, udword i, udword nbu, udword nbu_nbv)
|
||||
{
|
||||
w = i / (nbu_nbv);
|
||||
Compute2DCoords(u, v, i - (w * nbu_nbv), nbu);
|
||||
}
|
||||
|
||||
#endif // __ICEUTILS_H__
|
||||
/*
|
||||
* ICE / OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains misc. useful macros & defines.
|
||||
* \file IceUtils.h
|
||||
* \author Pierre Terdiman (collected from various sources)
|
||||
* \date April, 4, 2000
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __ICEUTILS_H__
|
||||
#define __ICEUTILS_H__
|
||||
|
||||
#define START_RUNONCE { static bool __RunOnce__ = false; if(!__RunOnce__){
|
||||
#define END_RUNONCE __RunOnce__ = true;}}
|
||||
|
||||
//! Reverse all the bits in a 32 bit word (from Steve Baker's Cute Code Collection)
|
||||
//! (each line can be done in any order.
|
||||
inline_ void ReverseBits(udword& n)
|
||||
{
|
||||
n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
|
||||
n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
|
||||
n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
|
||||
n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
|
||||
n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
|
||||
// Etc for larger intergers (64 bits in Java)
|
||||
// NOTE: the >> operation must be unsigned! (>>> in java)
|
||||
}
|
||||
|
||||
//! Count the number of '1' bits in a 32 bit word (from Steve Baker's Cute Code Collection)
|
||||
inline_ udword CountBits(udword n)
|
||||
{
|
||||
// This relies of the fact that the count of n bits can NOT overflow
|
||||
// an n bit interger. EG: 1 bit count takes a 1 bit interger, 2 bit counts
|
||||
// 2 bit interger, 3 bit count requires only a 2 bit interger.
|
||||
// So we add all bit pairs, then each nible, then each byte etc...
|
||||
n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1);
|
||||
n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2);
|
||||
n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4);
|
||||
n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8);
|
||||
n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16);
|
||||
// Etc for larger intergers (64 bits in Java)
|
||||
// NOTE: the >> operation must be unsigned! (>>> in java)
|
||||
return n;
|
||||
}
|
||||
|
||||
//! Even faster?
|
||||
inline_ udword CountBits2(udword bits)
|
||||
{
|
||||
bits = bits - ((bits >> 1) & 0x55555555);
|
||||
bits = ((bits >> 2) & 0x33333333) + (bits & 0x33333333);
|
||||
bits = ((bits >> 4) + bits) & 0x0F0F0F0F;
|
||||
return (bits * 0x01010101) >> 24;
|
||||
}
|
||||
|
||||
//! Spread out bits. EG 00001111 -> 0101010101
|
||||
//! 00001010 -> 0100010000
|
||||
//! This is used to interleve to intergers to produce a `Morten Key'
|
||||
//! used in Space Filling Curves (See DrDobbs Journal, July 1999)
|
||||
//! Order is important.
|
||||
inline_ void SpreadBits(udword& n)
|
||||
{
|
||||
n = ( n & 0x0000ffff) | (( n & 0xffff0000) << 16);
|
||||
n = ( n & 0x000000ff) | (( n & 0x0000ff00) << 8);
|
||||
n = ( n & 0x000f000f) | (( n & 0x00f000f0) << 4);
|
||||
n = ( n & 0x03030303) | (( n & 0x0c0c0c0c) << 2);
|
||||
n = ( n & 0x11111111) | (( n & 0x22222222) << 1);
|
||||
}
|
||||
|
||||
// Next Largest Power of 2
|
||||
// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
|
||||
// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
|
||||
// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
|
||||
// largest power of 2. For a 32-bit value:
|
||||
inline_ udword nlpo2(udword x)
|
||||
{
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
return x+1;
|
||||
}
|
||||
|
||||
//! Test to see if a number is an exact power of two (from Steve Baker's Cute Code Collection)
|
||||
inline_ bool IsPowerOfTwo(udword n) { return ((n&(n-1))==0); }
|
||||
|
||||
//! Zero the least significant '1' bit in a word. (from Steve Baker's Cute Code Collection)
|
||||
inline_ void ZeroLeastSetBit(udword& n) { n&=(n-1); }
|
||||
|
||||
//! Set the least significant N bits in a word. (from Steve Baker's Cute Code Collection)
|
||||
inline_ void SetLeastNBits(udword& x, udword n) { x|=~(~0<<n); }
|
||||
|
||||
//! Classic XOR swap (from Steve Baker's Cute Code Collection)
|
||||
//! x ^= y; /* x' = (x^y) */
|
||||
//! y ^= x; /* y' = (y^(x^y)) = x */
|
||||
//! x ^= y; /* x' = (x^y)^x = y */
|
||||
inline_ void Swap(udword& x, udword& y) { x ^= y; y ^= x; x ^= y; }
|
||||
|
||||
//! Little/Big endian (from Steve Baker's Cute Code Collection)
|
||||
//!
|
||||
//! Extra comments by Kenny Hoff:
|
||||
//! Determines the byte-ordering of the current machine (little or big endian)
|
||||
//! by setting an integer value to 1 (so least significant bit is now 1); take
|
||||
//! the address of the int and cast to a byte pointer (treat integer as an
|
||||
//! array of four bytes); check the value of the first byte (must be 0 or 1).
|
||||
//! If the value is 1, then the first byte least significant byte and this
|
||||
//! implies LITTLE endian. If the value is 0, the first byte is the most
|
||||
//! significant byte, BIG endian. Examples:
|
||||
//! integer 1 on BIG endian: 00000000 00000000 00000000 00000001
|
||||
//! integer 1 on LITTLE endian: 00000001 00000000 00000000 00000000
|
||||
//!---------------------------------------------------------------------------
|
||||
//! int IsLittleEndian() { int x=1; return ( ((char*)(&x))[0] ); }
|
||||
inline_ char LittleEndian() { int i = 1; return *((char*)&i); }
|
||||
|
||||
//!< Alternative abs function
|
||||
inline_ udword abs_(sdword x) { sdword y= x >> 31; return (x^y)-y; }
|
||||
|
||||
//!< Alternative min function
|
||||
inline_ sdword min_(sdword a, sdword b) { sdword delta = b-a; return a + (delta&(delta>>31)); }
|
||||
|
||||
// Determine if one of the bytes in a 4 byte word is zero
|
||||
inline_ BOOL HasNullByte(udword x) { return ((x + 0xfefefeff) & (~x) & 0x80808080); }
|
||||
|
||||
// To find the smallest 1 bit in a word EG: ~~~~~~10---0 => 0----010---0
|
||||
inline_ udword LowestOneBit(udword w) { return ((w) & (~(w)+1)); }
|
||||
// inline_ udword LowestOneBit_(udword w) { return ((w) & (-(w))); }
|
||||
|
||||
// Most Significant 1 Bit
|
||||
// Given a binary integer value x, the most significant 1 bit (highest numbered element of a bit set)
|
||||
// can be computed using a SWAR algorithm that recursively "folds" the upper bits into the lower bits.
|
||||
// This process yields a bit vector with the same most significant 1 as x, but all 1's below it.
|
||||
// Bitwise AND of the original value with the complement of the "folded" value shifted down by one
|
||||
// yields the most significant bit. For a 32-bit value:
|
||||
inline_ udword msb32(udword x)
|
||||
{
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
return (x & ~(x >> 1));
|
||||
}
|
||||
|
||||
/*
|
||||
"Just call it repeatedly with various input values and always with the same variable as "memory".
|
||||
The sharpness determines the degree of filtering, where 0 completely filters out the input, and 1
|
||||
does no filtering at all.
|
||||
|
||||
I seem to recall from college that this is called an IIR (Infinite Impulse Response) filter. As opposed
|
||||
to the more typical FIR (Finite Impulse Response).
|
||||
|
||||
Also, I'd say that you can make more intelligent and interesting filters than this, for example filters
|
||||
that remove wrong responses from the mouse because it's being moved too fast. You'd want such a filter
|
||||
to be applied before this one, of course."
|
||||
|
||||
(JCAB on Flipcode)
|
||||
*/
|
||||
inline_ float FeedbackFilter(float val, float& memory, float sharpness)
|
||||
{
|
||||
ASSERT(sharpness>=0.0f && sharpness<=1.0f && "Invalid sharpness value in feedback filter");
|
||||
if(sharpness<0.0f) sharpness = 0.0f;
|
||||
else if(sharpness>1.0f) sharpness = 1.0f;
|
||||
return memory = val * sharpness + memory * (1.0f - sharpness);
|
||||
}
|
||||
|
||||
//! If you can guarantee that your input domain (i.e. value of x) is slightly
|
||||
//! limited (abs(x) must be < ((1<<31u)-32767)), then you can use the
|
||||
//! following code to clamp the resulting value into [-32768,+32767] range:
|
||||
inline_ int ClampToInt16(int x)
|
||||
{
|
||||
// ASSERT(abs(x) < (int)((1<<31u)-32767));
|
||||
|
||||
int delta = 32767 - x;
|
||||
x += (delta>>31) & delta;
|
||||
delta = x + 32768;
|
||||
x -= (delta>>31) & delta;
|
||||
return x;
|
||||
}
|
||||
|
||||
// Generic functions
|
||||
template<class Type> inline_ void TSwap(Type& a, Type& b) { const Type c = a; a = b; b = c; }
|
||||
template<class Type> inline_ Type TClamp(const Type& x, const Type& lo, const Type& hi) { return ((x<lo) ? lo : (x>hi) ? hi : x); }
|
||||
|
||||
template<class Type> inline_ void TSort(Type& a, Type& b)
|
||||
{
|
||||
if(a>b) TSwap(a, b);
|
||||
}
|
||||
|
||||
template<class Type> inline_ void TSort(Type& a, Type& b, Type& c)
|
||||
{
|
||||
if(a>b) TSwap(a, b);
|
||||
if(b>c) TSwap(b, c);
|
||||
if(a>b) TSwap(a, b);
|
||||
if(b>c) TSwap(b, c);
|
||||
}
|
||||
|
||||
// Prevent nasty user-manipulations (strategy borrowed from Charles Bloom)
|
||||
// #define PREVENT_COPY(curclass) void operator = (const curclass& object) { ASSERT(!"Bad use of operator ="); }
|
||||
// ... actually this is better !
|
||||
#define PREVENT_COPY(cur_class) private: cur_class(const cur_class& object); cur_class& operator=(const cur_class& object);
|
||||
|
||||
//! TO BE DOCUMENTED
|
||||
#define OFFSET_OF(Class, Member) (size_t)&(((Class*)0)->Member)
|
||||
//! TO BE DOCUMENTED
|
||||
#define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0]))
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns the alignment of the input address.
|
||||
* \fn Alignment()
|
||||
* \param address [in] address to check
|
||||
* \return the best alignment (e.g. 1 for odd addresses, etc)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
FUNCTION ICECORE_API udword Alignment(udword address);
|
||||
|
||||
#define IS_ALIGNED_2(x) ((x&1)==0)
|
||||
#define IS_ALIGNED_4(x) ((x&3)==0)
|
||||
#define IS_ALIGNED_8(x) ((x&7)==0)
|
||||
|
||||
inline_ void _prefetch(void const* ptr) { (void)*(char const volatile *)ptr; }
|
||||
|
||||
// Compute implicit coords from an index:
|
||||
// The idea is to get back 2D coords from a 1D index.
|
||||
// For example:
|
||||
//
|
||||
// 0 1 2 ... nbu-1
|
||||
// nbu nbu+1 i ...
|
||||
//
|
||||
// We have i, we're looking for the equivalent (u=2, v=1) location.
|
||||
// i = u + v*nbu
|
||||
// <=> i/nbu = u/nbu + v
|
||||
// Since 0 <= u < nbu, u/nbu = 0 (integer)
|
||||
// Hence: v = i/nbu
|
||||
// Then we simply put it back in the original equation to compute u = i - v*nbu
|
||||
inline_ void Compute2DCoords(udword& u, udword& v, udword i, udword nbu)
|
||||
{
|
||||
v = i / nbu;
|
||||
u = i - (v * nbu);
|
||||
}
|
||||
|
||||
// In 3D: i = u + v*nbu + w*nbu*nbv
|
||||
// <=> i/(nbu*nbv) = u/(nbu*nbv) + v/nbv + w
|
||||
// u/(nbu*nbv) is null since u/nbu was null already.
|
||||
// v/nbv is null as well for the same reason.
|
||||
// Hence w = i/(nbu*nbv)
|
||||
// Then we're left with a 2D problem: i' = i - w*nbu*nbv = u + v*nbu
|
||||
inline_ void Compute3DCoords(udword& u, udword& v, udword& w, udword i, udword nbu, udword nbu_nbv)
|
||||
{
|
||||
w = i / (nbu_nbv);
|
||||
Compute2DCoords(u, v, i - (w * nbu_nbv), nbu);
|
||||
}
|
||||
|
||||
#endif // __ICEUTILS_H__
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,106 +1,106 @@
|
||||
/*
|
||||
* OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for an AABB collider.
|
||||
* \file OPC_AABBCollider.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 1st, 2002
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __OPC_AABBCOLLIDER_H__
|
||||
#define __OPC_AABBCOLLIDER_H__
|
||||
|
||||
struct OPCODE_API AABBCache : VolumeCache
|
||||
{
|
||||
AABBCache() : FatCoeff(1.1f)
|
||||
{
|
||||
FatBox.mCenter.Zero();
|
||||
FatBox.mExtents.Zero();
|
||||
}
|
||||
|
||||
// Cached faces signature
|
||||
CollisionAABB FatBox; //!< Box used when performing the query resulting in cached faces
|
||||
// User settings
|
||||
float FatCoeff; //!< mRadius2 multiplier used to create a fat sphere
|
||||
};
|
||||
|
||||
class OPCODE_API AABBCollider : public VolumeCollider
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
AABBCollider();
|
||||
virtual ~AABBCollider();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Generic collision query for generic OPCODE models. After the call, access the results:
|
||||
* - with GetContactStatus()
|
||||
* - with GetNbTouchedPrimitives()
|
||||
* - with GetTouchedPrimitives()
|
||||
*
|
||||
* \param cache [in/out] a box cache
|
||||
* \param box [in] collision AABB in world space
|
||||
* \param model [in] Opcode model to collide with
|
||||
* \return true if success
|
||||
* \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Collide(AABBCache& cache, const CollisionAABB& box, const Model& model);
|
||||
//
|
||||
bool Collide(AABBCache& cache, const CollisionAABB& box, const AABBTree* tree);
|
||||
protected:
|
||||
CollisionAABB mBox; //!< Query box in (center, extents) form
|
||||
Point mMin; //!< Query box min point
|
||||
Point mMax; //!< Query box max point
|
||||
// Leaf description
|
||||
Point mLeafVerts[3]; //!< Triangle vertices
|
||||
// Internal methods
|
||||
void _Collide(const AABBCollisionNode* node);
|
||||
void _Collide(const AABBNoLeafNode* node);
|
||||
void _Collide(const AABBQuantizedNode* node);
|
||||
void _Collide(const AABBQuantizedNoLeafNode* node);
|
||||
void _Collide(const AABBTreeNode* node);
|
||||
void _CollideNoPrimitiveTest(const AABBCollisionNode* node);
|
||||
void _CollideNoPrimitiveTest(const AABBNoLeafNode* node);
|
||||
void _CollideNoPrimitiveTest(const AABBQuantizedNode* node);
|
||||
void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node);
|
||||
// Overlap tests
|
||||
inline_ BOOL AABBContainsBox(const Point& bc, const Point& be);
|
||||
inline_ BOOL AABBAABBOverlap(const Point& b, const Point& Pb);
|
||||
inline_ BOOL TriBoxOverlap();
|
||||
// Init methods
|
||||
BOOL InitQuery(AABBCache& cache, const CollisionAABB& box);
|
||||
};
|
||||
|
||||
class OPCODE_API HybridAABBCollider : public AABBCollider
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
HybridAABBCollider();
|
||||
virtual ~HybridAABBCollider();
|
||||
|
||||
bool Collide(AABBCache& cache, const CollisionAABB& box, const HybridModel& model);
|
||||
protected:
|
||||
Container mTouchedBoxes;
|
||||
};
|
||||
|
||||
#endif // __OPC_AABBCOLLIDER_H__
|
||||
/*
|
||||
* OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for an AABB collider.
|
||||
* \file OPC_AABBCollider.h
|
||||
* \author Pierre Terdiman
|
||||
* \date January, 1st, 2002
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __OPC_AABBCOLLIDER_H__
|
||||
#define __OPC_AABBCOLLIDER_H__
|
||||
|
||||
struct OPCODE_API AABBCache : VolumeCache
|
||||
{
|
||||
AABBCache() : FatCoeff(1.1f)
|
||||
{
|
||||
FatBox.mCenter.Zero();
|
||||
FatBox.mExtents.Zero();
|
||||
}
|
||||
|
||||
// Cached faces signature
|
||||
CollisionAABB FatBox; //!< Box used when performing the query resulting in cached faces
|
||||
// User settings
|
||||
float FatCoeff; //!< mRadius2 multiplier used to create a fat sphere
|
||||
};
|
||||
|
||||
class OPCODE_API AABBCollider : public VolumeCollider
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
AABBCollider();
|
||||
virtual ~AABBCollider();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Generic collision query for generic OPCODE models. After the call, access the results:
|
||||
* - with GetContactStatus()
|
||||
* - with GetNbTouchedPrimitives()
|
||||
* - with GetTouchedPrimitives()
|
||||
*
|
||||
* \param cache [in/out] a box cache
|
||||
* \param box [in] collision AABB in world space
|
||||
* \param model [in] Opcode model to collide with
|
||||
* \return true if success
|
||||
* \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Collide(AABBCache& cache, const CollisionAABB& box, const Model& model);
|
||||
//
|
||||
bool Collide(AABBCache& cache, const CollisionAABB& box, const AABBTree* tree);
|
||||
protected:
|
||||
CollisionAABB mBox; //!< Query box in (center, extents) form
|
||||
Point mMin; //!< Query box min point
|
||||
Point mMax; //!< Query box max point
|
||||
// Leaf description
|
||||
Point mLeafVerts[3]; //!< Triangle vertices
|
||||
// Internal methods
|
||||
void _Collide(const AABBCollisionNode* node);
|
||||
void _Collide(const AABBNoLeafNode* node);
|
||||
void _Collide(const AABBQuantizedNode* node);
|
||||
void _Collide(const AABBQuantizedNoLeafNode* node);
|
||||
void _Collide(const AABBTreeNode* node);
|
||||
void _CollideNoPrimitiveTest(const AABBCollisionNode* node);
|
||||
void _CollideNoPrimitiveTest(const AABBNoLeafNode* node);
|
||||
void _CollideNoPrimitiveTest(const AABBQuantizedNode* node);
|
||||
void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node);
|
||||
// Overlap tests
|
||||
inline_ BOOL AABBContainsBox(const Point& bc, const Point& be);
|
||||
inline_ BOOL AABBAABBOverlap(const Point& b, const Point& Pb);
|
||||
inline_ BOOL TriBoxOverlap();
|
||||
// Init methods
|
||||
BOOL InitQuery(AABBCache& cache, const CollisionAABB& box);
|
||||
};
|
||||
|
||||
class OPCODE_API HybridAABBCollider : public AABBCollider
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
HybridAABBCollider();
|
||||
virtual ~HybridAABBCollider();
|
||||
|
||||
bool Collide(AABBCache& cache, const CollisionAABB& box, const HybridModel& model);
|
||||
protected:
|
||||
Container mTouchedBoxes;
|
||||
};
|
||||
|
||||
#endif // __OPC_AABBCOLLIDER_H__
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,146 +1,146 @@
|
||||
/*
|
||||
* OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for a versatile AABB tree.
|
||||
* \file OPC_AABBTree.h
|
||||
* \author Pierre Terdiman
|
||||
* \date March, 20, 2001
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __OPC_AABBTREE_H__
|
||||
#define __OPC_AABBTREE_H__
|
||||
|
||||
#ifdef OPC_NO_NEG_VANILLA_TREE
|
||||
//! TO BE DOCUMENTED
|
||||
#define IMPLEMENT_TREE(base_class, volume) \
|
||||
public: \
|
||||
/* Constructor / Destructor */ \
|
||||
base_class(); \
|
||||
~base_class(); \
|
||||
/* Data access */ \
|
||||
inline_ const volume* Get##volume() const { return &mBV; } \
|
||||
/* Clear the last bit */ \
|
||||
inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \
|
||||
inline_ const base_class* GetNeg() const { const base_class* P = GetPos(); return P ? P+1 : null;} \
|
||||
\
|
||||
/* We don't need to test both nodes since we can't have one without the other */ \
|
||||
inline_ bool IsLeaf() const { return !GetPos(); } \
|
||||
\
|
||||
/* Stats */ \
|
||||
inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \
|
||||
protected: \
|
||||
/* Tree-independent data */ \
|
||||
/* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \
|
||||
/* Whatever happens we need the two children and the enclosing volume.*/ \
|
||||
volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \
|
||||
udword mPos; /* "Positive" & "Negative" children */
|
||||
#else
|
||||
//! TO BE DOCUMENTED
|
||||
#define IMPLEMENT_TREE(base_class, volume) \
|
||||
public: \
|
||||
/* Constructor / Destructor */ \
|
||||
base_class(); \
|
||||
~base_class(); \
|
||||
/* Data access */ \
|
||||
inline_ const volume* Get##volume() const { return &mBV; } \
|
||||
/* Clear the last bit */ \
|
||||
inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \
|
||||
inline_ const base_class* GetNeg() const { return (const base_class*)(mNeg&~1); } \
|
||||
\
|
||||
/* inline_ bool IsLeaf() const { return (!GetPos() && !GetNeg()); } */ \
|
||||
/* We don't need to test both nodes since we can't have one without the other */ \
|
||||
inline_ bool IsLeaf() const { return !GetPos(); } \
|
||||
\
|
||||
/* Stats */ \
|
||||
inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \
|
||||
protected: \
|
||||
/* Tree-independent data */ \
|
||||
/* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \
|
||||
/* Whatever happens we need the two children and the enclosing volume.*/ \
|
||||
volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \
|
||||
udword mPos; /* "Positive" child */ \
|
||||
udword mNeg; /* "Negative" child */
|
||||
#endif
|
||||
|
||||
typedef void (*CullingCallback) (udword nb_primitives, udword* node_primitives, BOOL need_clipping, void* user_data);
|
||||
|
||||
class OPCODE_API AABBTreeNode
|
||||
{
|
||||
IMPLEMENT_TREE(AABBTreeNode, AABB)
|
||||
public:
|
||||
// Data access
|
||||
inline_ const udword* GetPrimitives() const { return mNodePrimitives; }
|
||||
inline_ udword GetNbPrimitives() const { return mNbPrimitives; }
|
||||
|
||||
protected:
|
||||
// Tree-dependent data
|
||||
udword* mNodePrimitives; //!< Node-related primitives (shortcut to a position in mIndices below)
|
||||
udword mNbPrimitives; //!< Number of primitives for this node
|
||||
// Internal methods
|
||||
udword Split(udword axis, AABBTreeBuilder* builder);
|
||||
bool Subdivide(AABBTreeBuilder* builder);
|
||||
void _BuildHierarchy(AABBTreeBuilder* builder);
|
||||
void _Refit(AABBTreeBuilder* builder);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* User-callback, called for each node by the walking code.
|
||||
* \param current [in] current node
|
||||
* \param depth [in] current node's depth
|
||||
* \param user_data [in] user-defined data
|
||||
* \return true to recurse through children, else false to bypass them
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
typedef bool (*WalkingCallback) (const AABBTreeNode* current, udword depth, void* user_data);
|
||||
|
||||
class OPCODE_API AABBTree : public AABBTreeNode
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
AABBTree();
|
||||
~AABBTree();
|
||||
// Build
|
||||
bool Build(AABBTreeBuilder* builder);
|
||||
void Release();
|
||||
|
||||
// Data access
|
||||
inline_ const udword* GetIndices() const { return mIndices; } //!< Catch the indices
|
||||
inline_ udword GetNbNodes() const { return mTotalNbNodes; } //!< Catch the number of nodes
|
||||
|
||||
// Infos
|
||||
bool IsComplete() const;
|
||||
// Stats
|
||||
udword ComputeDepth() const;
|
||||
udword GetUsedBytes() const;
|
||||
udword Walk(WalkingCallback callback, void* user_data) const;
|
||||
|
||||
bool Refit(AABBTreeBuilder* builder);
|
||||
bool Refit2(AABBTreeBuilder* builder);
|
||||
private:
|
||||
udword* mIndices; //!< Indices in the app list. Indices are reorganized during build (permutation).
|
||||
AABBTreeNode* mPool; //!< Linear pool of nodes for complete trees. Null otherwise. [Opcode 1.3]
|
||||
// Stats
|
||||
udword mTotalNbNodes; //!< Number of nodes in the tree.
|
||||
};
|
||||
|
||||
#endif // __OPC_AABBTREE_H__
|
||||
/*
|
||||
* OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains code for a versatile AABB tree.
|
||||
* \file OPC_AABBTree.h
|
||||
* \author Pierre Terdiman
|
||||
* \date March, 20, 2001
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __OPC_AABBTREE_H__
|
||||
#define __OPC_AABBTREE_H__
|
||||
|
||||
#ifdef OPC_NO_NEG_VANILLA_TREE
|
||||
//! TO BE DOCUMENTED
|
||||
#define IMPLEMENT_TREE(base_class, volume) \
|
||||
public: \
|
||||
/* Constructor / Destructor */ \
|
||||
base_class(); \
|
||||
~base_class(); \
|
||||
/* Data access */ \
|
||||
inline_ const volume* Get##volume() const { return &mBV; } \
|
||||
/* Clear the last bit */ \
|
||||
inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \
|
||||
inline_ const base_class* GetNeg() const { const base_class* P = GetPos(); return P ? P+1 : null;} \
|
||||
\
|
||||
/* We don't need to test both nodes since we can't have one without the other */ \
|
||||
inline_ bool IsLeaf() const { return !GetPos(); } \
|
||||
\
|
||||
/* Stats */ \
|
||||
inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \
|
||||
protected: \
|
||||
/* Tree-independent data */ \
|
||||
/* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \
|
||||
/* Whatever happens we need the two children and the enclosing volume.*/ \
|
||||
volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \
|
||||
udword mPos; /* "Positive" & "Negative" children */
|
||||
#else
|
||||
//! TO BE DOCUMENTED
|
||||
#define IMPLEMENT_TREE(base_class, volume) \
|
||||
public: \
|
||||
/* Constructor / Destructor */ \
|
||||
base_class(); \
|
||||
~base_class(); \
|
||||
/* Data access */ \
|
||||
inline_ const volume* Get##volume() const { return &mBV; } \
|
||||
/* Clear the last bit */ \
|
||||
inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \
|
||||
inline_ const base_class* GetNeg() const { return (const base_class*)(mNeg&~1); } \
|
||||
\
|
||||
/* inline_ bool IsLeaf() const { return (!GetPos() && !GetNeg()); } */ \
|
||||
/* We don't need to test both nodes since we can't have one without the other */ \
|
||||
inline_ bool IsLeaf() const { return !GetPos(); } \
|
||||
\
|
||||
/* Stats */ \
|
||||
inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \
|
||||
protected: \
|
||||
/* Tree-independent data */ \
|
||||
/* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \
|
||||
/* Whatever happens we need the two children and the enclosing volume.*/ \
|
||||
volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \
|
||||
udword mPos; /* "Positive" child */ \
|
||||
udword mNeg; /* "Negative" child */
|
||||
#endif
|
||||
|
||||
typedef void (*CullingCallback) (udword nb_primitives, udword* node_primitives, BOOL need_clipping, void* user_data);
|
||||
|
||||
class OPCODE_API AABBTreeNode
|
||||
{
|
||||
IMPLEMENT_TREE(AABBTreeNode, AABB)
|
||||
public:
|
||||
// Data access
|
||||
inline_ const udword* GetPrimitives() const { return mNodePrimitives; }
|
||||
inline_ udword GetNbPrimitives() const { return mNbPrimitives; }
|
||||
|
||||
protected:
|
||||
// Tree-dependent data
|
||||
udword* mNodePrimitives; //!< Node-related primitives (shortcut to a position in mIndices below)
|
||||
udword mNbPrimitives; //!< Number of primitives for this node
|
||||
// Internal methods
|
||||
udword Split(udword axis, AABBTreeBuilder* builder);
|
||||
bool Subdivide(AABBTreeBuilder* builder);
|
||||
void _BuildHierarchy(AABBTreeBuilder* builder);
|
||||
void _Refit(AABBTreeBuilder* builder);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* User-callback, called for each node by the walking code.
|
||||
* \param current [in] current node
|
||||
* \param depth [in] current node's depth
|
||||
* \param user_data [in] user-defined data
|
||||
* \return true to recurse through children, else false to bypass them
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
typedef bool (*WalkingCallback) (const AABBTreeNode* current, udword depth, void* user_data);
|
||||
|
||||
class OPCODE_API AABBTree : public AABBTreeNode
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
AABBTree();
|
||||
~AABBTree();
|
||||
// Build
|
||||
bool Build(AABBTreeBuilder* builder);
|
||||
void Release();
|
||||
|
||||
// Data access
|
||||
inline_ const udword* GetIndices() const { return mIndices; } //!< Catch the indices
|
||||
inline_ udword GetNbNodes() const { return mTotalNbNodes; } //!< Catch the number of nodes
|
||||
|
||||
// Infos
|
||||
bool IsComplete() const;
|
||||
// Stats
|
||||
udword ComputeDepth() const;
|
||||
udword GetUsedBytes() const;
|
||||
udword Walk(WalkingCallback callback, void* user_data) const;
|
||||
|
||||
bool Refit(AABBTreeBuilder* builder);
|
||||
bool Refit2(AABBTreeBuilder* builder);
|
||||
private:
|
||||
udword* mIndices; //!< Indices in the app list. Indices are reorganized during build (permutation).
|
||||
AABBTreeNode* mPool; //!< Linear pool of nodes for complete trees. Null otherwise. [Opcode 1.3]
|
||||
// Stats
|
||||
udword mTotalNbNodes; //!< Number of nodes in the tree.
|
||||
};
|
||||
|
||||
#endif // __OPC_AABBTREE_H__
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,159 +1,159 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* OPCODE - Optimized Collision Detection
|
||||
* Copyright (C) 2001 Pierre Terdiman
|
||||
* Homepage: http://www.codercorner.com/Opcode.htm
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains an array-based version of the sweep-and-prune algorithm
|
||||
* \file OPC_ArraySAP.h
|
||||
* \author Pierre Terdiman
|
||||
* \date December, 2, 2007
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef OPC_ARRAYSAP_H
|
||||
#define OPC_ARRAYSAP_H
|
||||
|
||||
#pragma pack(1)
|
||||
struct OPCODE_API ASAP_Pair
|
||||
{
|
||||
uword id0;
|
||||
uword id1;
|
||||
const void* object0;
|
||||
const void* object1;
|
||||
//#ifdef PAIR_USER_DATA
|
||||
void* userData;
|
||||
//#endif
|
||||
inline_ const void* GetObject0() const { return (const void*)(size_t(object0) & ~3); }
|
||||
inline_ const void* GetObject1() const { return (const void*)(size_t(object1) & ~3); }
|
||||
inline_ size_t IsInArray() const { return size_t(object0) & 1; }
|
||||
inline_ size_t IsRemoved() const { return size_t(object1) & 1; }
|
||||
inline_ size_t IsNew() const { return size_t(object0) & 2; }
|
||||
private:
|
||||
inline_ void SetInArray() { object0 = (const void*)(size_t(object0) | 1); }
|
||||
inline_ void SetRemoved() { object1 = (const void*)(size_t(object1) | 1); }
|
||||
inline_ void SetNew() { object0 = (const void*)(size_t(object0) | 2); }
|
||||
inline_ void ClearInArray() { object0 = (const void*)(size_t(object0) & ~1); }
|
||||
inline_ void ClearRemoved() { object1 = (const void*)(size_t(object1) & ~1); }
|
||||
inline_ void ClearNew() { object0 = (const void*)(size_t(object0) & ~2); }
|
||||
|
||||
friend class ArraySAP;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
class OPCODE_API ASAP_PairManager
|
||||
{
|
||||
public:
|
||||
ASAP_PairManager();
|
||||
~ASAP_PairManager();
|
||||
|
||||
void Purge();
|
||||
void ShrinkMemory();
|
||||
|
||||
const ASAP_Pair* AddPair (uword id0, uword id1, const void* object0, const void* object1);
|
||||
bool RemovePair (uword id0, uword id1);
|
||||
bool RemovePairs (const BitArray& array);
|
||||
const ASAP_Pair* FindPair (uword id0, uword id1) const;
|
||||
inline_ udword GetPairIndex(const ASAP_Pair* pair) const
|
||||
{
|
||||
return ((udword)((size_t(pair) - size_t(mActivePairs)))/sizeof(ASAP_Pair));
|
||||
}
|
||||
|
||||
udword mHashSize;
|
||||
udword mMask;
|
||||
udword mNbActivePairs;
|
||||
udword* mHashTable;
|
||||
udword* mNext;
|
||||
ASAP_Pair* mActivePairs;
|
||||
inline_ ASAP_Pair* FindPair(uword id0, uword id1, udword hash_value) const;
|
||||
void RemovePair(uword id0, uword id1, udword hash_value, udword pair_index);
|
||||
void ReallocPairs();
|
||||
};
|
||||
|
||||
typedef void* (*SAP_CreatePair)(const void* object0, const void* object1, void* user_data);
|
||||
typedef void (*SAP_DeletePair)(const void* object0, const void* object1, void* user_data, void* pair_user_data);
|
||||
|
||||
// Forward declarations
|
||||
class ASAP_EndPoint;
|
||||
class ASAP_Box;
|
||||
struct IAABB;
|
||||
struct CreateData;
|
||||
|
||||
class OPCODE_API ArraySAP : public Allocateable
|
||||
{
|
||||
public:
|
||||
ArraySAP();
|
||||
~ArraySAP();
|
||||
|
||||
udword AddObject(void* object, uword guid, const AABB& box);
|
||||
bool RemoveObject(udword handle);
|
||||
bool UpdateObject(udword handle, const AABB& box);
|
||||
|
||||
udword DumpPairs(SAP_CreatePair create_cb, SAP_DeletePair delete_cb, void* cb_user_data, ASAP_Pair** pairs=null);
|
||||
private:
|
||||
Container mData;
|
||||
ASAP_PairManager mPairs;
|
||||
|
||||
inline_ void AddPair(const void* object0, const void* object1, uword id0, uword id1)
|
||||
{
|
||||
ASSERT(object0);
|
||||
ASAP_Pair* UP = (ASAP_Pair*)mPairs.AddPair(id0, id1, null, null);
|
||||
ASSERT(UP);
|
||||
|
||||
if(UP->object0)
|
||||
{
|
||||
// Persistent pair
|
||||
}
|
||||
else
|
||||
{
|
||||
// New pair
|
||||
ASSERT(!(int(object0)&1));
|
||||
ASSERT(!(int(object1)&1));
|
||||
UP->object0 = object0;
|
||||
UP->object1 = object1;
|
||||
UP->SetInArray();
|
||||
mData.Add(mPairs.GetPairIndex(UP));
|
||||
UP->SetNew();
|
||||
}
|
||||
UP->ClearRemoved();
|
||||
}
|
||||
|
||||
inline_ void RemovePair(const void* object0, const void* object1, uword id0, uword id1)
|
||||
{
|
||||
ASAP_Pair* UP = (ASAP_Pair*)mPairs.FindPair(id0, id1);
|
||||
if(UP)
|
||||
{
|
||||
if(!UP->IsInArray())
|
||||
{
|
||||
UP->SetInArray();
|
||||
mData.Add(mPairs.GetPairIndex(UP));
|
||||
}
|
||||
UP->SetRemoved();
|
||||
}
|
||||
}
|
||||
|
||||
udword mNbBoxes;
|
||||
udword mMaxNbBoxes;
|
||||
ASAP_Box* mBoxes;
|
||||
ASAP_EndPoint* mEndPoints[3];
|
||||
udword mFirstFree;
|
||||
|
||||
void ResizeBoxArray();
|
||||
// For batch creation
|
||||
Container mCreated;
|
||||
void BatchCreate();
|
||||
void InsertEndPoints(udword axis, const ASAP_EndPoint* end_points, udword nb_endpoints);
|
||||
bool CompleteBoxPruning2(udword nb, const IAABB* array, const Axes& axes, const CreateData* batched);
|
||||
bool BipartiteBoxPruning2(udword nb0, const IAABB* array0, udword nb1, const IAABB* array1, const Axes& axes, const CreateData* batched, const udword* box_indices);
|
||||
// For batch removal
|
||||
Container mRemoved;
|
||||
void BatchRemove();
|
||||
};
|
||||
|
||||
#endif // OPC_ARRAYSAP_H
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* OPCODE - Optimized Collision Detection
|
||||
* Copyright (C) 2001 Pierre Terdiman
|
||||
* Homepage: http://www.codercorner.com/Opcode.htm
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains an array-based version of the sweep-and-prune algorithm
|
||||
* \file OPC_ArraySAP.h
|
||||
* \author Pierre Terdiman
|
||||
* \date December, 2, 2007
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef OPC_ARRAYSAP_H
|
||||
#define OPC_ARRAYSAP_H
|
||||
|
||||
#pragma pack(1)
|
||||
struct OPCODE_API ASAP_Pair
|
||||
{
|
||||
uword id0;
|
||||
uword id1;
|
||||
const void* object0;
|
||||
const void* object1;
|
||||
//#ifdef PAIR_USER_DATA
|
||||
void* userData;
|
||||
//#endif
|
||||
inline_ const void* GetObject0() const { return (const void*)(size_t(object0) & ~3); }
|
||||
inline_ const void* GetObject1() const { return (const void*)(size_t(object1) & ~3); }
|
||||
inline_ size_t IsInArray() const { return size_t(object0) & 1; }
|
||||
inline_ size_t IsRemoved() const { return size_t(object1) & 1; }
|
||||
inline_ size_t IsNew() const { return size_t(object0) & 2; }
|
||||
private:
|
||||
inline_ void SetInArray() { object0 = (const void*)(size_t(object0) | 1); }
|
||||
inline_ void SetRemoved() { object1 = (const void*)(size_t(object1) | 1); }
|
||||
inline_ void SetNew() { object0 = (const void*)(size_t(object0) | 2); }
|
||||
inline_ void ClearInArray() { object0 = (const void*)(size_t(object0) & ~1); }
|
||||
inline_ void ClearRemoved() { object1 = (const void*)(size_t(object1) & ~1); }
|
||||
inline_ void ClearNew() { object0 = (const void*)(size_t(object0) & ~2); }
|
||||
|
||||
friend class ArraySAP;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
class OPCODE_API ASAP_PairManager
|
||||
{
|
||||
public:
|
||||
ASAP_PairManager();
|
||||
~ASAP_PairManager();
|
||||
|
||||
void Purge();
|
||||
void ShrinkMemory();
|
||||
|
||||
const ASAP_Pair* AddPair (uword id0, uword id1, const void* object0, const void* object1);
|
||||
bool RemovePair (uword id0, uword id1);
|
||||
bool RemovePairs (const BitArray& array);
|
||||
const ASAP_Pair* FindPair (uword id0, uword id1) const;
|
||||
inline_ udword GetPairIndex(const ASAP_Pair* pair) const
|
||||
{
|
||||
return ((udword)((size_t(pair) - size_t(mActivePairs)))/sizeof(ASAP_Pair));
|
||||
}
|
||||
|
||||
udword mHashSize;
|
||||
udword mMask;
|
||||
udword mNbActivePairs;
|
||||
udword* mHashTable;
|
||||
udword* mNext;
|
||||
ASAP_Pair* mActivePairs;
|
||||
inline_ ASAP_Pair* FindPair(uword id0, uword id1, udword hash_value) const;
|
||||
void RemovePair(uword id0, uword id1, udword hash_value, udword pair_index);
|
||||
void ReallocPairs();
|
||||
};
|
||||
|
||||
typedef void* (*SAP_CreatePair)(const void* object0, const void* object1, void* user_data);
|
||||
typedef void (*SAP_DeletePair)(const void* object0, const void* object1, void* user_data, void* pair_user_data);
|
||||
|
||||
// Forward declarations
|
||||
class ASAP_EndPoint;
|
||||
class ASAP_Box;
|
||||
struct IAABB;
|
||||
struct CreateData;
|
||||
|
||||
class OPCODE_API ArraySAP : public Allocateable
|
||||
{
|
||||
public:
|
||||
ArraySAP();
|
||||
~ArraySAP();
|
||||
|
||||
udword AddObject(void* object, uword guid, const AABB& box);
|
||||
bool RemoveObject(udword handle);
|
||||
bool UpdateObject(udword handle, const AABB& box);
|
||||
|
||||
udword DumpPairs(SAP_CreatePair create_cb, SAP_DeletePair delete_cb, void* cb_user_data, ASAP_Pair** pairs=null);
|
||||
private:
|
||||
Container mData;
|
||||
ASAP_PairManager mPairs;
|
||||
|
||||
inline_ void AddPair(const void* object0, const void* object1, uword id0, uword id1)
|
||||
{
|
||||
ASSERT(object0);
|
||||
ASAP_Pair* UP = (ASAP_Pair*)mPairs.AddPair(id0, id1, null, null);
|
||||
ASSERT(UP);
|
||||
|
||||
if(UP->object0)
|
||||
{
|
||||
// Persistent pair
|
||||
}
|
||||
else
|
||||
{
|
||||
// New pair
|
||||
ASSERT(!(int(object0)&1));
|
||||
ASSERT(!(int(object1)&1));
|
||||
UP->object0 = object0;
|
||||
UP->object1 = object1;
|
||||
UP->SetInArray();
|
||||
mData.Add(mPairs.GetPairIndex(UP));
|
||||
UP->SetNew();
|
||||
}
|
||||
UP->ClearRemoved();
|
||||
}
|
||||
|
||||
inline_ void RemovePair(const void* object0, const void* object1, uword id0, uword id1)
|
||||
{
|
||||
ASAP_Pair* UP = (ASAP_Pair*)mPairs.FindPair(id0, id1);
|
||||
if(UP)
|
||||
{
|
||||
if(!UP->IsInArray())
|
||||
{
|
||||
UP->SetInArray();
|
||||
mData.Add(mPairs.GetPairIndex(UP));
|
||||
}
|
||||
UP->SetRemoved();
|
||||
}
|
||||
}
|
||||
|
||||
udword mNbBoxes;
|
||||
udword mMaxNbBoxes;
|
||||
ASAP_Box* mBoxes;
|
||||
ASAP_EndPoint* mEndPoints[3];
|
||||
udword mFirstFree;
|
||||
|
||||
void ResizeBoxArray();
|
||||
// For batch creation
|
||||
Container mCreated;
|
||||
void BatchCreate();
|
||||
void InsertEndPoints(udword axis, const ASAP_EndPoint* end_points, udword nb_endpoints);
|
||||
bool CompleteBoxPruning2(udword nb, const IAABB* array, const Axes& axes, const CreateData* batched);
|
||||
bool BipartiteBoxPruning2(udword nb0, const IAABB* array0, udword nb1, const IAABB* array1, const Axes& axes, const CreateData* batched, const udword* box_indices);
|
||||
// For batch removal
|
||||
Container mRemoved;
|
||||
void BatchRemove();
|
||||
};
|
||||
|
||||
#endif // OPC_ARRAYSAP_H
|
||||
|
||||
@@ -1,147 +1,147 @@
|
||||
/*
|
||||
* OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains base model interface.
|
||||
* \file OPC_BaseModel.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date May, 18, 2003
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* The base class for collision models.
|
||||
*
|
||||
* \class BaseModel
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.3
|
||||
* \date May, 18, 2003
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
OPCODECREATE::OPCODECREATE()
|
||||
{
|
||||
mIMesh = null;
|
||||
mSettings.mRules = SPLIT_SPLATTER_POINTS | SPLIT_GEOM_CENTER;
|
||||
mSettings.mLimit = 1; // Mandatory for complete trees
|
||||
mNoLeaf = true;
|
||||
mQuantized = true;
|
||||
#ifdef __MESHMERIZER_H__
|
||||
mCollisionHull = false;
|
||||
#endif // __MESHMERIZER_H__
|
||||
mKeepOriginal = false;
|
||||
mCanRemap = false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BaseModel::BaseModel() : mIMesh(null), mModelCode(0), mSource(null), mTree(null)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BaseModel::~BaseModel()
|
||||
{
|
||||
ReleaseBase();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Releases everything.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void BaseModel::ReleaseBase()
|
||||
{
|
||||
DELETESINGLE(mSource);
|
||||
DELETESINGLE(mTree);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Creates an optimized tree according to user-settings, and setups mModelCode.
|
||||
* \param no_leaf [in] true for "no leaf" tree
|
||||
* \param quantized [in] true for quantized tree
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool BaseModel::CreateTree(bool no_leaf, bool quantized)
|
||||
{
|
||||
DELETESINGLE(mTree);
|
||||
|
||||
// Setup model code
|
||||
if(no_leaf) mModelCode |= OPC_NO_LEAF;
|
||||
else mModelCode &= ~OPC_NO_LEAF;
|
||||
|
||||
if(quantized) mModelCode |= OPC_QUANTIZED;
|
||||
else mModelCode &= ~OPC_QUANTIZED;
|
||||
|
||||
// Create the correct class
|
||||
if(mModelCode & OPC_NO_LEAF)
|
||||
{
|
||||
if(mModelCode & OPC_QUANTIZED) mTree = new AABBQuantizedNoLeafTree;
|
||||
else mTree = new AABBNoLeafTree;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mModelCode & OPC_QUANTIZED) mTree = new AABBQuantizedTree;
|
||||
else mTree = new AABBCollisionTree;
|
||||
}
|
||||
CHECKALLOC(mTree);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the collision model. This can be used to handle dynamic meshes. Usage is:
|
||||
* 1. modify your mesh vertices (keep the topology constant!)
|
||||
* 2. refit the tree (call this method)
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool BaseModel::Refit()
|
||||
{
|
||||
// Refit the optimized tree
|
||||
return mTree->Refit(mIMesh);
|
||||
|
||||
// Old code kept for reference : refit the source tree then rebuild !
|
||||
// if(!mSource) return false;
|
||||
// // Ouch...
|
||||
// mSource->Refit(&mTB);
|
||||
// // Ouch...
|
||||
// return mTree->Build(mSource);
|
||||
}
|
||||
/*
|
||||
* OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains base model interface.
|
||||
* \file OPC_BaseModel.cpp
|
||||
* \author Pierre Terdiman
|
||||
* \date May, 18, 2003
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* The base class for collision models.
|
||||
*
|
||||
* \class BaseModel
|
||||
* \author Pierre Terdiman
|
||||
* \version 1.3
|
||||
* \date May, 18, 2003
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Precompiled Header
|
||||
#include "Stdafx.h"
|
||||
|
||||
using namespace Opcode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
OPCODECREATE::OPCODECREATE()
|
||||
{
|
||||
mIMesh = null;
|
||||
mSettings.mRules = SPLIT_SPLATTER_POINTS | SPLIT_GEOM_CENTER;
|
||||
mSettings.mLimit = 1; // Mandatory for complete trees
|
||||
mNoLeaf = true;
|
||||
mQuantized = true;
|
||||
#ifdef __MESHMERIZER_H__
|
||||
mCollisionHull = false;
|
||||
#endif // __MESHMERIZER_H__
|
||||
mKeepOriginal = false;
|
||||
mCanRemap = false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BaseModel::BaseModel() : mIMesh(null), mModelCode(0), mSource(null), mTree(null)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BaseModel::~BaseModel()
|
||||
{
|
||||
ReleaseBase();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Releases everything.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void BaseModel::ReleaseBase()
|
||||
{
|
||||
DELETESINGLE(mSource);
|
||||
DELETESINGLE(mTree);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Creates an optimized tree according to user-settings, and setups mModelCode.
|
||||
* \param no_leaf [in] true for "no leaf" tree
|
||||
* \param quantized [in] true for quantized tree
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool BaseModel::CreateTree(bool no_leaf, bool quantized)
|
||||
{
|
||||
DELETESINGLE(mTree);
|
||||
|
||||
// Setup model code
|
||||
if(no_leaf) mModelCode |= OPC_NO_LEAF;
|
||||
else mModelCode &= ~OPC_NO_LEAF;
|
||||
|
||||
if(quantized) mModelCode |= OPC_QUANTIZED;
|
||||
else mModelCode &= ~OPC_QUANTIZED;
|
||||
|
||||
// Create the correct class
|
||||
if(mModelCode & OPC_NO_LEAF)
|
||||
{
|
||||
if(mModelCode & OPC_QUANTIZED) mTree = new AABBQuantizedNoLeafTree;
|
||||
else mTree = new AABBNoLeafTree;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mModelCode & OPC_QUANTIZED) mTree = new AABBQuantizedTree;
|
||||
else mTree = new AABBCollisionTree;
|
||||
}
|
||||
CHECKALLOC(mTree);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the collision model. This can be used to handle dynamic meshes. Usage is:
|
||||
* 1. modify your mesh vertices (keep the topology constant!)
|
||||
* 2. refit the tree (call this method)
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool BaseModel::Refit()
|
||||
{
|
||||
// Refit the optimized tree
|
||||
return mTree->Refit(mIMesh);
|
||||
|
||||
// Old code kept for reference : refit the source tree then rebuild !
|
||||
// if(!mSource) return false;
|
||||
// // Ouch...
|
||||
// mSource->Refit(&mTB);
|
||||
// // Ouch...
|
||||
// return mTree->Build(mSource);
|
||||
}
|
||||
|
||||
@@ -1,184 +1,184 @@
|
||||
/*
|
||||
* OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains base model interface.
|
||||
* \file OPC_BaseModel.h
|
||||
* \author Pierre Terdiman
|
||||
* \date May, 18, 2003
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __OPC_BASEMODEL_H__
|
||||
#define __OPC_BASEMODEL_H__
|
||||
|
||||
//! Model creation structure
|
||||
struct OPCODE_API OPCODECREATE
|
||||
{
|
||||
//! Constructor
|
||||
OPCODECREATE();
|
||||
|
||||
MeshInterface* mIMesh; //!< Mesh interface (access to triangles & vertices) (*)
|
||||
BuildSettings mSettings; //!< Builder's settings
|
||||
bool mNoLeaf; //!< true => discard leaf nodes (else use a normal tree)
|
||||
bool mQuantized; //!< true => quantize the tree (else use a normal tree)
|
||||
#ifdef __MESHMERIZER_H__
|
||||
bool mCollisionHull; //!< true => use convex hull + GJK
|
||||
#endif // __MESHMERIZER_H__
|
||||
bool mKeepOriginal; //!< true => keep a copy of the original tree (debug purpose)
|
||||
bool mCanRemap; //!< true => allows OPCODE to reorganize client arrays
|
||||
|
||||
// (*) This pointer is saved internally and used by OPCODE until collision structures are released,
|
||||
// so beware of the object's lifetime.
|
||||
};
|
||||
|
||||
enum ModelFlag
|
||||
{
|
||||
OPC_QUANTIZED = (1<<0), //!< Compressed/uncompressed tree
|
||||
OPC_NO_LEAF = (1<<1), //!< Leaf/NoLeaf tree
|
||||
OPC_SINGLE_NODE = (1<<2) //!< Special case for 1-node models
|
||||
};
|
||||
|
||||
class OPCODE_API BaseModel
|
||||
{
|
||||
public:
|
||||
// Constructor/Destructor
|
||||
BaseModel();
|
||||
virtual ~BaseModel();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Builds a collision model.
|
||||
* \param create [in] model creation structure
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual bool Build(const OPCODECREATE& create) = 0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the number of bytes used by the tree.
|
||||
* \return amount of bytes used
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual udword GetUsedBytes() const = 0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the collision model. This can be used to handle dynamic meshes. Usage is:
|
||||
* 1. modify your mesh vertices (keep the topology constant!)
|
||||
* 2. refit the tree (call this method)
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual bool Refit();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the source tree.
|
||||
* \return generic tree
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ const AABBTree* GetSourceTree() const { return mSource; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the tree.
|
||||
* \return the collision tree
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ const AABBOptimizedTree* GetTree() const { return mTree; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the tree.
|
||||
* \return the collision tree
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ AABBOptimizedTree* GetTree() { return mTree; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the number of nodes in the tree.
|
||||
* Should be 2*N-1 for normal trees and N-1 for optimized ones.
|
||||
* \return number of nodes
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetNbNodes() const { return mTree->GetNbNodes(); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks whether the tree has leaf nodes or not.
|
||||
* \return true if the tree has leaf nodes (normal tree), else false (optimized tree)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL HasLeafNodes() const { return !(mModelCode & OPC_NO_LEAF); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks whether the tree is quantized or not.
|
||||
* \return true if the tree is quantized
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL IsQuantized() const { return mModelCode & OPC_QUANTIZED; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks whether the model has a single node or not. This special case must be handled separately.
|
||||
* \return true if the model has only 1 node
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL HasSingleNode() const { return mModelCode & OPC_SINGLE_NODE; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the model's code.
|
||||
* \return model's code
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetModelCode() const { return mModelCode; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the mesh interface.
|
||||
* \return mesh interface
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ const MeshInterface* GetMeshInterface() const { return mIMesh; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Sets the mesh interface.
|
||||
* \param imesh [in] mesh interface
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetMeshInterface(const MeshInterface* imesh) { mIMesh = imesh; }
|
||||
|
||||
protected:
|
||||
const MeshInterface* mIMesh; //!< User-defined mesh interface
|
||||
udword mModelCode; //!< Model code = combination of ModelFlag(s)
|
||||
AABBTree* mSource; //!< Original source tree
|
||||
AABBOptimizedTree* mTree; //!< Optimized tree owned by the model
|
||||
// Internal methods
|
||||
void ReleaseBase();
|
||||
bool CreateTree(bool no_leaf, bool quantized);
|
||||
};
|
||||
|
||||
/*
|
||||
* OPCODE - Optimized Collision Detection
|
||||
* http://www.codercorner.com/Opcode.htm
|
||||
*
|
||||
* Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.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.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Contains base model interface.
|
||||
* \file OPC_BaseModel.h
|
||||
* \author Pierre Terdiman
|
||||
* \date May, 18, 2003
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include Guard
|
||||
#ifndef __OPC_BASEMODEL_H__
|
||||
#define __OPC_BASEMODEL_H__
|
||||
|
||||
//! Model creation structure
|
||||
struct OPCODE_API OPCODECREATE
|
||||
{
|
||||
//! Constructor
|
||||
OPCODECREATE();
|
||||
|
||||
MeshInterface* mIMesh; //!< Mesh interface (access to triangles & vertices) (*)
|
||||
BuildSettings mSettings; //!< Builder's settings
|
||||
bool mNoLeaf; //!< true => discard leaf nodes (else use a normal tree)
|
||||
bool mQuantized; //!< true => quantize the tree (else use a normal tree)
|
||||
#ifdef __MESHMERIZER_H__
|
||||
bool mCollisionHull; //!< true => use convex hull + GJK
|
||||
#endif // __MESHMERIZER_H__
|
||||
bool mKeepOriginal; //!< true => keep a copy of the original tree (debug purpose)
|
||||
bool mCanRemap; //!< true => allows OPCODE to reorganize client arrays
|
||||
|
||||
// (*) This pointer is saved internally and used by OPCODE until collision structures are released,
|
||||
// so beware of the object's lifetime.
|
||||
};
|
||||
|
||||
enum ModelFlag
|
||||
{
|
||||
OPC_QUANTIZED = (1<<0), //!< Compressed/uncompressed tree
|
||||
OPC_NO_LEAF = (1<<1), //!< Leaf/NoLeaf tree
|
||||
OPC_SINGLE_NODE = (1<<2) //!< Special case for 1-node models
|
||||
};
|
||||
|
||||
class OPCODE_API BaseModel
|
||||
{
|
||||
public:
|
||||
// Constructor/Destructor
|
||||
BaseModel();
|
||||
virtual ~BaseModel();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Builds a collision model.
|
||||
* \param create [in] model creation structure
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual bool Build(const OPCODECREATE& create) = 0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the number of bytes used by the tree.
|
||||
* \return amount of bytes used
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual udword GetUsedBytes() const = 0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the collision model. This can be used to handle dynamic meshes. Usage is:
|
||||
* 1. modify your mesh vertices (keep the topology constant!)
|
||||
* 2. refit the tree (call this method)
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual bool Refit();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the source tree.
|
||||
* \return generic tree
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ const AABBTree* GetSourceTree() const { return mSource; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the tree.
|
||||
* \return the collision tree
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ const AABBOptimizedTree* GetTree() const { return mTree; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the tree.
|
||||
* \return the collision tree
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ AABBOptimizedTree* GetTree() { return mTree; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the number of nodes in the tree.
|
||||
* Should be 2*N-1 for normal trees and N-1 for optimized ones.
|
||||
* \return number of nodes
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetNbNodes() const { return mTree->GetNbNodes(); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks whether the tree has leaf nodes or not.
|
||||
* \return true if the tree has leaf nodes (normal tree), else false (optimized tree)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL HasLeafNodes() const { return !(mModelCode & OPC_NO_LEAF); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks whether the tree is quantized or not.
|
||||
* \return true if the tree is quantized
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL IsQuantized() const { return mModelCode & OPC_QUANTIZED; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks whether the model has a single node or not. This special case must be handled separately.
|
||||
* \return true if the model has only 1 node
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL HasSingleNode() const { return mModelCode & OPC_SINGLE_NODE; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the model's code.
|
||||
* \return model's code
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetModelCode() const { return mModelCode; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the mesh interface.
|
||||
* \return mesh interface
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ const MeshInterface* GetMeshInterface() const { return mIMesh; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Sets the mesh interface.
|
||||
* \param imesh [in] mesh interface
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetMeshInterface(const MeshInterface* imesh) { mIMesh = imesh; }
|
||||
|
||||
protected:
|
||||
const MeshInterface* mIMesh; //!< User-defined mesh interface
|
||||
udword mModelCode; //!< Model code = combination of ModelFlag(s)
|
||||
AABBTree* mSource; //!< Original source tree
|
||||
AABBOptimizedTree* mTree; //!< Optimized tree owned by the model
|
||||
// Internal methods
|
||||
void ReleaseBase();
|
||||
bool CreateTree(bool no_leaf, bool quantized);
|
||||
};
|
||||
|
||||
#endif //__OPC_BASEMODEL_H__
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user