forked from metin2/client
Solution refactoring and restructuring, removed Boost dependency, removed unused tools
This commit is contained in:
394
src/SphereLib/SphereLib.vcxproj
Normal file
394
src/SphereLib/SphereLib.vcxproj
Normal file
@ -0,0 +1,394 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Distribute|Win32">
|
||||
<Configuration>Distribute</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="MfcDebug|Win32">
|
||||
<Configuration>MfcDebug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="MfcRelease|Win32">
|
||||
<Configuration>MfcRelease</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="VTune|Win32">
|
||||
<Configuration>VTune</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<ProjectName>SphereLib</ProjectName>
|
||||
<ProjectGuid>{A5D7AF9F-0A4F-4ED3-B209-2553B1ADD17D}</ProjectGuid>
|
||||
<RootNamespace>SphereLib</RootNamespace>
|
||||
<SccProjectName>SAK</SccProjectName>
|
||||
<SccAuxPath>SAK</SccAuxPath>
|
||||
<SccLocalPath>SAK</SccLocalPath>
|
||||
<SccProvider>SAK</SccProvider>
|
||||
<Keyword>MFCProj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MfcRelease|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='MfcRelease|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>17.0.32203.90</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune|Win32'">
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MfcRelease|Win32'">
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<VcpkgUseStatic>true</VcpkgUseStatic>
|
||||
<VcpkgConfiguration>$(Configuration)</VcpkgConfiguration>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">
|
||||
<VcpkgUseStatic>true</VcpkgUseStatic>
|
||||
<VcpkgConfiguration>$(Configuration)</VcpkgConfiguration>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<VcpkgUseStatic>true</VcpkgUseStatic>
|
||||
<VcpkgConfiguration>$(Configuration)</VcpkgConfiguration>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='VTune|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/Gs %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<AdditionalIncludeDirectories>.;../../extern/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<FloatingPointModel>Strict</FloatingPointModel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>.\VTune/SphereLib.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerOutput>All</AssemblerOutput>
|
||||
<AssemblerListingLocation>.\VTune/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\VTune/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\VTune/</ProgramDataBaseFileName>
|
||||
<BrowseInformation />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0412</Culture>
|
||||
</ResourceCompile>
|
||||
<Lib>
|
||||
<OutputFile>.\VTune\SphereLib.lib</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)extern\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<FloatingPointModel>Strict</FloatingPointModel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>.\Release/SphereLib.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\Release/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
|
||||
<BrowseInformation />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0412</Culture>
|
||||
</ResourceCompile>
|
||||
<Lib>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)extern\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<FloatingPointModel>Strict</FloatingPointModel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>.\Distribute/SphereLib.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerOutput>All</AssemblerOutput>
|
||||
<AssemblerListingLocation>.\Distribute/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\Distribute/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\Distribute/</ProgramDataBaseFileName>
|
||||
<BrowseInformation />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0412</Culture>
|
||||
</ResourceCompile>
|
||||
<Lib>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='MfcRelease|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<AdditionalIncludeDirectories>.;../../extern/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<FloatingPointModel>Strict</FloatingPointModel>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>.\SphereLib___Win32_MfcRelease/SphereLib.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerOutput>All</AssemblerOutput>
|
||||
<AssemblerListingLocation>.\SphereLib___Win32_MfcRelease/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\SphereLib___Win32_MfcRelease/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\SphereLib___Win32_MfcRelease/</ProgramDataBaseFileName>
|
||||
<BrowseInformation />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0412</Culture>
|
||||
</ResourceCompile>
|
||||
<Lib>
|
||||
<OutputFile>.\SphereLib___Win32_MfcRelease\SphereLib.lib</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)extern\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<FloatingPointModel>Strict</FloatingPointModel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>.\Debug/SphereLib.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\Debug/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
|
||||
<BrowseInformation />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0412</Culture>
|
||||
</ResourceCompile>
|
||||
<Lib>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>.;../../extern/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<FloatingPointModel>Strict</FloatingPointModel>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>.\SphereLib___Win32_MfcDebug/SphereLib.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\SphereLib___Win32_MfcDebug/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\SphereLib___Win32_MfcDebug/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\SphereLib___Win32_MfcDebug/</ProgramDataBaseFileName>
|
||||
<BrowseInformation />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0412</Culture>
|
||||
</ResourceCompile>
|
||||
<Lib>
|
||||
<OutputFile>.\SphereLib___Win32_MfcDebug\SphereLib.lib</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="frustum.cpp">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
|
||||
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
|
||||
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">MaxSpeed</Optimization>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">Disabled</Optimization>
|
||||
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">EnableFastChecks</BasicRuntimeChecks>
|
||||
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">true</BrowseInformation>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='MfcRelease|Win32'">MaxSpeed</Optimization>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
|
||||
<FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='VTune|Win32'">Size</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sphere.cpp">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
|
||||
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
|
||||
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">MaxSpeed</Optimization>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">Disabled</Optimization>
|
||||
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">EnableFastChecks</BasicRuntimeChecks>
|
||||
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">true</BrowseInformation>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='MfcRelease|Win32'">MaxSpeed</Optimization>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
|
||||
<FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='VTune|Win32'">Size</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<ClCompile Include="spherepack.cpp">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
|
||||
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
|
||||
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">MaxSpeed</Optimization>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">Disabled</Optimization>
|
||||
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">EnableFastChecks</BasicRuntimeChecks>
|
||||
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">true</BrowseInformation>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='MfcRelease|Win32'">MaxSpeed</Optimization>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
|
||||
<FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='VTune|Win32'">Size</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StdAfx.cpp">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
|
||||
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">MaxSpeed</Optimization>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">Create</PrecompiledHeader>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">Disabled</Optimization>
|
||||
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">EnableFastChecks</BasicRuntimeChecks>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">Create</PrecompiledHeader>
|
||||
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='MfcDebug|Win32'">true</BrowseInformation>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='MfcRelease|Win32'">MaxSpeed</Optimization>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='MfcRelease|Win32'">Create</PrecompiledHeader>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='VTune|Win32'">Size</FavorSizeOrSpeed>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='VTune|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="frustum.h" />
|
||||
<ClInclude Include="pool.h" />
|
||||
<ClInclude Include="sphere.h" />
|
||||
<ClInclude Include="spherepack.h" />
|
||||
<ClInclude Include="StdAfx.h" />
|
||||
<ClInclude Include="vector.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
47
src/SphereLib/SphereLib.vcxproj.filters
Normal file
47
src/SphereLib/SphereLib.vcxproj.filters
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{46750b70-f67e-4be6-a0b9-c27dc7fba6cd}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{33f6f3b6-787d-496f-8f89-d1dcf9dcd171}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="frustum.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sphere.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="spherepack.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StdAfx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="frustum.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pool.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sphere.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="spherepack.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="StdAfx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="vector.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
6
src/SphereLib/StdAfx.cpp
Normal file
6
src/SphereLib/StdAfx.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// SphereLib.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
16
src/SphereLib/StdAfx.h
Normal file
16
src/SphereLib/StdAfx.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
//#define SPHERELIB_STRICT
|
||||
//#include <crtdbg.h>
|
||||
|
||||
#include <d3d8.h>
|
||||
#include <d3dx8.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "../eterBase/StdAfx.h"
|
93
src/SphereLib/frustum.cpp
Normal file
93
src/SphereLib/frustum.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
/* Copyright (C) John W. Ratcliff, 2001.
|
||||
* All rights reserved worldwide.
|
||||
*
|
||||
* This software is provided "as is" without express or implied
|
||||
* warranties. You may freely copy and compile this source into
|
||||
* applications you distribute provided that the copyright text
|
||||
* below is included in the resulting source code, for example:
|
||||
* "Portions Copyright (C) John W. Ratcliff, 2001"
|
||||
*/
|
||||
|
||||
#include "Stdafx.h"
|
||||
#include "frustum.h"
|
||||
|
||||
//#include "frustum.h"
|
||||
|
||||
/*void Frustum::Set(int x1,int y1,int x2,int y2)
|
||||
{
|
||||
mX1 = x1;
|
||||
mY1 = y1;
|
||||
mX2 = x2;
|
||||
mY2 = y2;
|
||||
}
|
||||
|
||||
*/
|
||||
ViewState Frustum::ViewVolumeTest(const Vector3d &c_v3Center,const float c_fRadius) const
|
||||
{
|
||||
if (m_bUsingSphere)
|
||||
{
|
||||
D3DXVECTOR3 v(
|
||||
c_v3Center.x-m_v3Center.x,
|
||||
c_v3Center.y-m_v3Center.y,
|
||||
c_v3Center.z-m_v3Center.z);
|
||||
|
||||
if ((c_fRadius + m_fRadius) * (c_fRadius + m_fRadius) < D3DXVec3LengthSq(&v))
|
||||
{
|
||||
return VS_OUTSIDE;
|
||||
}
|
||||
}
|
||||
|
||||
const int count=6;
|
||||
|
||||
D3DXVECTOR3 center = c_v3Center;
|
||||
//center.y *=-1;
|
||||
|
||||
int i;
|
||||
|
||||
float distance[count];
|
||||
for(i=0;i<count;i++)
|
||||
{
|
||||
distance[i] = D3DXPlaneDotCoord(&m_plane[i],¢er);
|
||||
if (distance[i]<=-c_fRadius)
|
||||
return VS_OUTSIDE;
|
||||
}
|
||||
|
||||
//return VS_INSIDE;
|
||||
|
||||
for(i=0;i<count;i++)
|
||||
{
|
||||
if (distance[i]<=c_fRadius)
|
||||
return VS_PARTIAL;
|
||||
}
|
||||
|
||||
return VS_INSIDE;
|
||||
}
|
||||
|
||||
void Frustum::BuildViewFrustum(D3DXMATRIX & mat)
|
||||
{
|
||||
m_bUsingSphere = false;
|
||||
m_plane[0] = D3DXPLANE( mat._13, mat._23, mat._33, mat._43);
|
||||
m_plane[1] = D3DXPLANE(mat._14 - mat._13, mat._24 - mat._23, mat._34 - mat._33, mat._44 - mat._43);
|
||||
//m_plane[0] = D3DXPLANE(mat._14 + mat._13, mat._24 + mat._23, mat._34 + mat._33, mat._44 + mat._43);
|
||||
m_plane[2] = D3DXPLANE(mat._14 + mat._11, mat._24 + mat._21, mat._34 + mat._31, mat._44 + mat._41);
|
||||
m_plane[3] = D3DXPLANE(mat._14 - mat._11, mat._24 - mat._21, mat._34 - mat._31, mat._44 - mat._41);
|
||||
m_plane[4] = D3DXPLANE(mat._14 + mat._12, mat._24 + mat._22, mat._34 + mat._32, mat._44 + mat._42);
|
||||
m_plane[5] = D3DXPLANE(mat._14 - mat._12, mat._24 - mat._22, mat._34 - mat._32, mat._44 - mat._42);
|
||||
|
||||
for(int i=0;i<6;i++)
|
||||
D3DXPlaneNormalize(&m_plane[i],&m_plane[i]);
|
||||
}
|
||||
|
||||
void Frustum::BuildViewFrustum2(D3DXMATRIX & mat, float fNear, float fFar, float fFov, float fAspect, const D3DXVECTOR3 & vCamera, const D3DXVECTOR3 & vLook)
|
||||
{
|
||||
float fViewLen = fFar-fNear;
|
||||
float fH = fViewLen * tan(fFov*0.5f);
|
||||
float fW = fH*fAspect;
|
||||
D3DXVECTOR3 P(0.0f, 0.0f, fNear+fViewLen*0.5f);
|
||||
D3DXVECTOR3 Q(fW, fH, fViewLen);
|
||||
D3DXVECTOR3 PQ = P-Q;
|
||||
m_fRadius = D3DXVec3Length(&PQ);
|
||||
m_v3Center = vCamera + vLook * (fNear+fViewLen*0.5f);
|
||||
BuildViewFrustum(mat);
|
||||
m_bUsingSphere = true;
|
||||
}
|
41
src/SphereLib/frustum.h
Normal file
41
src/SphereLib/frustum.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* Copyright (C) John W. Ratcliff, 2001.
|
||||
* All rights reserved worldwide.
|
||||
*
|
||||
* This software is provided "as is" without express or implied
|
||||
* warranties. You may freely copy and compile this source into
|
||||
* applications you distribute provided that the copyright text
|
||||
* below is included in the resulting source code, for example:
|
||||
* "Portions Copyright (C) John W. Ratcliff, 2001"
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/***********************************************************************/
|
||||
/** FRUSTUM.H : Represents a clipping frustum. */
|
||||
/** You should replace this with your own more robust */
|
||||
/** view frustum clipper. */
|
||||
/** */
|
||||
/** Written by John W. Ratcliff jratcliff@att.net */
|
||||
/***********************************************************************/
|
||||
|
||||
#include "vector.h"
|
||||
|
||||
enum ViewState
|
||||
{
|
||||
VS_INSIDE, // completely inside the frustum.
|
||||
VS_PARTIAL, // partially inside and partially outside the frustum.
|
||||
VS_OUTSIDE // completely outside the frustum
|
||||
};
|
||||
|
||||
class Frustum
|
||||
{
|
||||
public:
|
||||
void BuildViewFrustum(D3DXMATRIX & mat);
|
||||
void BuildViewFrustum2(D3DXMATRIX & mat, float fNear, float fFar, float fFov, float fAspect, const D3DXVECTOR3 & vCamera, const D3DXVECTOR3 & vLook);
|
||||
ViewState ViewVolumeTest(const Vector3d &c_v3Center,const float c_fRadius) const;
|
||||
|
||||
private:
|
||||
bool m_bUsingSphere;
|
||||
D3DXVECTOR3 m_v3Center;
|
||||
float m_fRadius;
|
||||
D3DXPLANE m_plane[6];
|
||||
};
|
247
src/SphereLib/pool.h
Normal file
247
src/SphereLib/pool.h
Normal file
@ -0,0 +1,247 @@
|
||||
/* Copyright (C) John W. Ratcliff, 2001.
|
||||
* All rights reserved worldwide.
|
||||
*
|
||||
* This software is provided "as is" without express or implied
|
||||
* warranties. You may freely copy and compile this source into
|
||||
* applications you distribute provided that the copyright text
|
||||
* below is included in the resulting source code, for example:
|
||||
* "Portions Copyright (C) John W. Ratcliff, 2001"
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/***********************************************************************/
|
||||
/** POOL : Template class to manage a fixed pool of items for */
|
||||
/** extremely fast allocation and deallocation. */
|
||||
/** */
|
||||
/** Written by John W. Ratcliff jratcliff@att.net */
|
||||
/***********************************************************************/
|
||||
|
||||
template <class Type> class Pool
|
||||
{
|
||||
public:
|
||||
Pool(void)
|
||||
{
|
||||
mHead = 0;
|
||||
mFree = 0;
|
||||
mData = 0;
|
||||
mCurrent = 0;
|
||||
mFreeCount = 0;
|
||||
mUsedCount = 0;
|
||||
};
|
||||
|
||||
~Pool(void)
|
||||
{
|
||||
if (mData)
|
||||
delete [] mData;
|
||||
};
|
||||
|
||||
|
||||
void Release(void)
|
||||
{
|
||||
if (mData)
|
||||
delete [] mData;
|
||||
|
||||
mHead = 0;
|
||||
mFree = 0;
|
||||
|
||||
mData = 0;
|
||||
mCurrent = 0;
|
||||
mFreeCount = 0;
|
||||
mUsedCount = 0;
|
||||
};
|
||||
|
||||
void Set(int maxitems)
|
||||
{
|
||||
if (mData)
|
||||
delete [] mData; // delete any previous incarnation.
|
||||
mMaxItems = maxitems;
|
||||
mData = new Type[mMaxItems];
|
||||
mFree = mData;
|
||||
mHead = 0;
|
||||
int loopValue = (mMaxItems-1);
|
||||
for (int i=0; i<loopValue; i++)
|
||||
{
|
||||
mData[i].SetNext( &mData[i+1] );
|
||||
if ( i == 0 )
|
||||
mData[i].SetPrevious( 0 );
|
||||
else
|
||||
mData[i].SetPrevious( &mData[i-1] );
|
||||
}
|
||||
|
||||
mData[loopValue].SetNext(0);
|
||||
mData[loopValue].SetPrevious( &mData[loopValue-1] );
|
||||
mCurrent = 0; // there is no current, currently. <g>
|
||||
mFreeCount = maxitems;
|
||||
mUsedCount = 0;
|
||||
};
|
||||
|
||||
|
||||
Type * GetNext(bool &looped)
|
||||
{
|
||||
|
||||
looped = false; //default value
|
||||
|
||||
if ( !mHead ) return 0; // there is no data to process.
|
||||
Type *ret;
|
||||
|
||||
if ( !mCurrent )
|
||||
{
|
||||
ret = mHead;
|
||||
looped = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = mCurrent;
|
||||
}
|
||||
|
||||
if ( ret ) mCurrent = ret->GetNext();
|
||||
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
bool IsEmpty(void) const
|
||||
{
|
||||
if ( !mHead ) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
int Begin(void)
|
||||
{
|
||||
mCurrent = mHead;
|
||||
return mUsedCount;
|
||||
};
|
||||
|
||||
int GetUsedCount(void) const { return mUsedCount; };
|
||||
int GetFreeCount(void) const { return mFreeCount; };
|
||||
|
||||
Type * GetNext(void)
|
||||
{
|
||||
if ( !mHead ) return 0; // there is no data to process.
|
||||
|
||||
Type *ret;
|
||||
|
||||
if ( !mCurrent )
|
||||
{
|
||||
ret = mHead;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = mCurrent;
|
||||
}
|
||||
|
||||
if ( ret ) mCurrent = ret->GetNext();
|
||||
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
void Release(Type *t)
|
||||
{
|
||||
|
||||
if ( t == mCurrent ) mCurrent = t->GetNext();
|
||||
|
||||
// first patch old linked list.. his previous now points to his next
|
||||
Type *prev = t->GetPrevious();
|
||||
|
||||
if ( prev )
|
||||
{
|
||||
Type *next = t->GetNext();
|
||||
prev->SetNext( next ); // my previous now points to my next
|
||||
if ( next ) next->SetPrevious(prev);
|
||||
// list is patched!
|
||||
}
|
||||
else
|
||||
{
|
||||
Type *next = t->GetNext();
|
||||
mHead = next;
|
||||
if ( mHead ) mHead->SetPrevious(0);
|
||||
}
|
||||
|
||||
Type *temp = mFree; // old head of free list.
|
||||
mFree = t; // new head of linked list.
|
||||
t->SetPrevious(0);
|
||||
t->SetNext(temp);
|
||||
|
||||
mUsedCount--;
|
||||
mFreeCount++;
|
||||
};
|
||||
|
||||
Type * GetFreeNoLink(void) // get free, but don't link it to the used list!!
|
||||
{
|
||||
// Free allocated items are always added to the head of the list
|
||||
if ( !mFree ) return 0;
|
||||
Type *ret = mFree;
|
||||
mFree = ret->GetNext(); // new head of free list
|
||||
mUsedCount++;
|
||||
mFreeCount--;
|
||||
ret->SetNext(0);
|
||||
ret->SetPrevious(0);
|
||||
return ret;
|
||||
};
|
||||
|
||||
Type * GetFreeLink(void)
|
||||
{
|
||||
// Free allocated items are always added to the head of the list
|
||||
if ( !mFree ) return 0;
|
||||
Type *ret = mFree;
|
||||
mFree = ret->GetNext(); // new head of free list
|
||||
Type *temp = mHead; // current head of list
|
||||
mHead = ret; // new head of list is this free one
|
||||
if ( temp ) temp->SetPrevious(ret);
|
||||
mHead->SetNext(temp);
|
||||
mHead->SetPrevious(0);
|
||||
mUsedCount++;
|
||||
mFreeCount--;
|
||||
return ret;
|
||||
};
|
||||
|
||||
void AddAfter(Type *e,Type *item)
|
||||
{
|
||||
// Add 'item' after 'e'
|
||||
if ( e )
|
||||
{
|
||||
Type *eprev = e->GetPrevious();
|
||||
Type *enext = e->GetNext();
|
||||
e->SetNext(item);
|
||||
item->SetNext(enext);
|
||||
item->SetPrevious(e);
|
||||
if ( enext ) enext->SetPrevious(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
mHead = item;
|
||||
item->SetPrevious(0);
|
||||
item->SetNext(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AddBefore(Type *e,Type *item)
|
||||
{
|
||||
// Add 'item' before 'e'
|
||||
Type *eprev = e->GetPrevious();
|
||||
Type *enext = e->GetNext();
|
||||
|
||||
if ( !eprev )
|
||||
mHead = item;
|
||||
else
|
||||
eprev->SetNext(item);
|
||||
|
||||
item->SetPrevious(eprev);
|
||||
item->SetNext(e);
|
||||
|
||||
e->SetPrevious(item);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
int mMaxItems;
|
||||
Type *mCurrent; // current iteration location.
|
||||
Type *mData;
|
||||
Type *mHead; // head of used list.
|
||||
Type *mFree; // head of free list.
|
||||
int mUsedCount;
|
||||
int mFreeCount;
|
||||
};
|
248
src/SphereLib/sphere.cpp
Normal file
248
src/SphereLib/sphere.cpp
Normal file
@ -0,0 +1,248 @@
|
||||
/* Copyright (C) John W. Ratcliff, 2001.
|
||||
* All rights reserved worldwide.
|
||||
*
|
||||
* This software is provided "as is" without express or implied
|
||||
* warranties. You may freely copy and compile this source into
|
||||
* applications you distribute provided that the copyright text
|
||||
* below is included in the resulting source code, for example:
|
||||
* "Portions Copyright (C) John W. Ratcliff, 2001"
|
||||
*/
|
||||
|
||||
#include "Stdafx.h"
|
||||
#include "sphere.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
bool Vector3d::IsInStaticRange() const
|
||||
{
|
||||
const float LIMIT = 3276700.0f;
|
||||
if (x<LIMIT && x>-LIMIT)
|
||||
if (y<LIMIT && y>-LIMIT)
|
||||
if (z<LIMIT && z>-LIMIT)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Sphere::Set(const Vector3d ¢er, float radius)
|
||||
{
|
||||
#ifdef __STATIC_RANGE__
|
||||
assert(center.IsInStaticRange());
|
||||
#endif
|
||||
mCenter = center;
|
||||
mRadius = radius;
|
||||
mRadius2 = radius*radius;
|
||||
}
|
||||
|
||||
|
||||
//ray-sphere intersection test from Graphics Gems p.388
|
||||
// **NOTE** There is a bug in this Graphics Gem. If the origin
|
||||
// of the ray is *inside* the sphere being tested, it reports the
|
||||
// wrong intersection location. This code has a fix for the bug.
|
||||
bool Sphere::RayIntersection(const Vector3d &rayOrigin,
|
||||
const Vector3d &dir,
|
||||
Vector3d *intersect)
|
||||
{
|
||||
//notation:
|
||||
//point E = rayOrigin
|
||||
//point O = sphere center
|
||||
|
||||
Vector3d EO = mCenter - rayOrigin;
|
||||
Vector3d V = dir;
|
||||
float dist2 = EO.x*EO.x + EO.y*EO.y + EO.z * EO.z;
|
||||
// Bug Fix For Gem, if origin is *inside* the sphere, invert the
|
||||
// direction vector so that we get a valid intersection location.
|
||||
if ( dist2 < mRadius2 ) V*=-1;
|
||||
|
||||
float v = EO.Dot(V);
|
||||
|
||||
float disc = mRadius2 - (EO.Length2() - v*v);
|
||||
|
||||
if (disc > 0.0f)
|
||||
{
|
||||
|
||||
if ( intersect )
|
||||
{
|
||||
|
||||
float d = sqrtf(disc);
|
||||
|
||||
//float dist2 = rayOrigin.DistanceSq(mCenter);
|
||||
|
||||
*intersect = rayOrigin + V*(v-d);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
bool Sphere::RayIntersection(const Vector3d &rayOrigin,
|
||||
const Vector3d &V,
|
||||
float distance,
|
||||
Vector3d *intersect)
|
||||
{
|
||||
Vector3d sect;
|
||||
bool hit = RayIntersectionInFront(rayOrigin,V,§);
|
||||
|
||||
if ( hit )
|
||||
{
|
||||
float d = rayOrigin.DistanceSq(sect);
|
||||
if ( d > (distance*distance) ) return false;
|
||||
if ( intersect ) *intersect = sect;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Sphere::RayIntersectionInFront(const Vector3d &rayOrigin,
|
||||
const Vector3d &V,
|
||||
Vector3d *intersect)
|
||||
{
|
||||
Vector3d sect;
|
||||
bool hit = RayIntersection(rayOrigin,V,§);
|
||||
|
||||
if ( hit )
|
||||
{
|
||||
|
||||
Vector3d dir = sect - rayOrigin;
|
||||
|
||||
float dot = dir.Dot(V);
|
||||
|
||||
if ( dot >= 0 ) // then it's in front!
|
||||
{
|
||||
if ( intersect ) *intersect = sect;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Sphere::Report(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
An Efficient Bounding Sphere
|
||||
by Jack Ritter
|
||||
from "Graphics Gems", Academic Press, 1990
|
||||
*/
|
||||
|
||||
/* Routine to calculate tight bounding sphere over */
|
||||
/* a set of points in 3D */
|
||||
/* This contains the routine find_bounding_sphere(), */
|
||||
/* the struct definition, and the globals used for parameters. */
|
||||
/* The abs() of all coordinates must be < BIGNUMBER */
|
||||
/* Code written by Jack Ritter and Lyle Rains. */
|
||||
|
||||
#define BIGNUMBER 100000000.0 /* hundred million */
|
||||
|
||||
void Sphere::Compute(const SphereInterface &source)
|
||||
{
|
||||
|
||||
Vector3d xmin,xmax,ymin,ymax,zmin,zmax,dia1,dia2;
|
||||
|
||||
/* FIRST PASS: find 6 minima/maxima points */
|
||||
xmin.Set(BIGNUMBER,BIGNUMBER,BIGNUMBER);
|
||||
xmax.Set(-BIGNUMBER,-BIGNUMBER,-BIGNUMBER);
|
||||
ymin.Set(BIGNUMBER,BIGNUMBER,BIGNUMBER);
|
||||
ymax.Set(-BIGNUMBER,-BIGNUMBER,-BIGNUMBER);
|
||||
zmin.Set(BIGNUMBER,BIGNUMBER,BIGNUMBER);
|
||||
zmax.Set(-BIGNUMBER,-BIGNUMBER,-BIGNUMBER);
|
||||
|
||||
int count = source.GetVertexCount();
|
||||
|
||||
for (int i=0; i<count; i++)
|
||||
{
|
||||
Vector3d caller_p;
|
||||
source.GetVertex(i,caller_p);
|
||||
|
||||
if (caller_p.GetX()<xmin.GetX()) xmin = caller_p; /* New xminimum point */
|
||||
if (caller_p.GetX()>xmax.GetX()) xmax = caller_p;
|
||||
if (caller_p.GetY()<ymin.GetY()) ymin = caller_p;
|
||||
if (caller_p.GetY()>ymax.GetY()) ymax = caller_p;
|
||||
if (caller_p.GetZ()<zmin.GetZ()) zmin = caller_p;
|
||||
if (caller_p.GetZ()>zmax.GetZ()) zmax = caller_p;
|
||||
}
|
||||
|
||||
/* Set xspan = distance between the 2 points xmin & xmax (squared) */
|
||||
float dx = xmax.GetX() - xmin.GetX();
|
||||
float dy = xmax.GetY() - xmin.GetY();
|
||||
float dz = xmax.GetZ() - xmin.GetZ();
|
||||
float xspan = dx*dx + dy*dy + dz*dz;
|
||||
|
||||
/* Same for y & z spans */
|
||||
dx = ymax.GetX() - ymin.GetX();
|
||||
dy = ymax.GetY() - ymin.GetY();
|
||||
dz = ymax.GetZ() - ymin.GetZ();
|
||||
float yspan = dx*dx + dy*dy + dz*dz;
|
||||
|
||||
dx = zmax.GetX() - zmin.GetX();
|
||||
dy = zmax.GetY() - zmin.GetY();
|
||||
dz = zmax.GetZ() - zmin.GetZ();
|
||||
float zspan = dx*dx + dy*dy + dz*dz;
|
||||
|
||||
/* Set points dia1 & dia2 to the maximally separated pair */
|
||||
dia1 = xmin;
|
||||
dia2 = xmax; /* assume xspan biggest */
|
||||
float maxspan = xspan;
|
||||
|
||||
if (yspan>maxspan)
|
||||
{
|
||||
maxspan = yspan;
|
||||
dia1 = ymin;
|
||||
dia2 = ymax;
|
||||
}
|
||||
|
||||
if (zspan>maxspan)
|
||||
{
|
||||
dia1 = zmin;
|
||||
dia2 = zmax;
|
||||
}
|
||||
|
||||
|
||||
/* dia1,dia2 is a diameter of initial sphere */
|
||||
/* calc initial center */
|
||||
mCenter.SetX( (dia1.GetX()+dia2.GetX())*0.5f );
|
||||
mCenter.SetY( (dia1.GetY()+dia2.GetY())*0.5f );
|
||||
mCenter.SetZ( (dia1.GetZ()+dia2.GetZ())*0.5f );
|
||||
/* calculate initial radius**2 and radius */
|
||||
dx = dia2.GetX()-mCenter.GetX(); /* x component of radius vector */
|
||||
dy = dia2.GetY()-mCenter.GetY(); /* y component of radius vector */
|
||||
dz = dia2.GetZ()-mCenter.GetZ(); /* z component of radius vector */
|
||||
mRadius2 = dx*dx + dy*dy + dz*dz;
|
||||
mRadius = float(sqrt(mRadius2));
|
||||
|
||||
/* SECOND PASS: increment current sphere */
|
||||
|
||||
for (int j=0; j<count; j++)
|
||||
{
|
||||
Vector3d caller_p;
|
||||
source.GetVertex(j,caller_p);
|
||||
dx = caller_p.GetX()-mCenter.GetX();
|
||||
dy = caller_p.GetY()-mCenter.GetY();
|
||||
dz = caller_p.GetZ()-mCenter.GetZ();
|
||||
float old_to_p_sq = dx*dx + dy*dy + dz*dz;
|
||||
if (old_to_p_sq > mRadius2) /* do r**2 test first */
|
||||
{ /* this point is outside of current sphere */
|
||||
float old_to_p = float(sqrt(old_to_p_sq));
|
||||
/* calc radius of new sphere */
|
||||
mRadius = (mRadius + old_to_p) * 0.5f;
|
||||
mRadius2 = mRadius*mRadius; /* for next r**2 compare */
|
||||
float old_to_new = old_to_p - mRadius;
|
||||
/* calc center of new sphere */
|
||||
float recip = 1.0f /old_to_p;
|
||||
|
||||
float cx = (mRadius*mCenter.GetX() + old_to_new*caller_p.GetX()) * recip;
|
||||
float cy = (mRadius*mCenter.GetY() + old_to_new*caller_p.GetY()) * recip;
|
||||
float cz = (mRadius*mCenter.GetZ() + old_to_new*caller_p.GetZ()) * recip;
|
||||
|
||||
mCenter.Set(cx,cy,cz);
|
||||
}
|
||||
}
|
||||
}
|
106
src/SphereLib/sphere.h
Normal file
106
src/SphereLib/sphere.h
Normal file
@ -0,0 +1,106 @@
|
||||
/* Copyright (C) John W. Ratcliff, 2001.
|
||||
* All rights reserved worldwide.
|
||||
*
|
||||
* This software is provided "as is" without express or implied
|
||||
* warranties. You may freely copy and compile this source into
|
||||
* applications you distribute provided that the copyright text
|
||||
* below is included in the resulting source code, for example:
|
||||
* "Portions Copyright (C) John W. Ratcliff, 2001"
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "vector.h"
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/** SPHERE.H : Base class to represent a Sphere in 3 space. */
|
||||
/** */
|
||||
/** Written by John W. Ratcliff jratcliff@att.net */
|
||||
/***********************************************************************/
|
||||
|
||||
class SphereInterface
|
||||
{
|
||||
public:
|
||||
SphereInterface();
|
||||
virtual ~SphereInterface();
|
||||
virtual int GetVertexCount(void) const = 0;
|
||||
virtual bool GetVertex(int i,Vector3d &vect) const = 0;
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Sphere
|
||||
{
|
||||
public:
|
||||
Sphere();
|
||||
Sphere(const Vector3d ¢er, float radius);
|
||||
|
||||
virtual ~Sphere() {}
|
||||
|
||||
void Set(const Vector3d ¢er, float radius);
|
||||
|
||||
void Compute(const SphereInterface &source);
|
||||
|
||||
float GetRadius(void) const { return mRadius; };
|
||||
float GetRadius2(void) const { return mRadius2; };
|
||||
const Vector3d& GetCenter(void) const { return mCenter; };
|
||||
|
||||
bool RayIntersection(const Vector3d &rayOrigin,
|
||||
const Vector3d &V,
|
||||
float distance,
|
||||
Vector3d *intersect);
|
||||
|
||||
|
||||
bool RayIntersection(const Vector3d &rayOrigin,
|
||||
const Vector3d &rayDirection,
|
||||
Vector3d *intersect);
|
||||
|
||||
bool RayIntersectionInFront(const Vector3d &rayOrigin,
|
||||
const Vector3d &rayDirection,
|
||||
Vector3d *intersect);
|
||||
|
||||
void Report(void);
|
||||
|
||||
void SetRadius(float radius)
|
||||
{
|
||||
mRadius = radius;
|
||||
mRadius2 = radius*radius;
|
||||
}
|
||||
|
||||
|
||||
bool InSphereXY(const Vector3d &pos,float distance) const
|
||||
{
|
||||
float dx = pos.x - mCenter.x;
|
||||
float dy = pos.y - mCenter.y;
|
||||
float dist = sqrtf( dx*dx + dy*dy );
|
||||
if ( dist < (mRadius+distance) ) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
bool InSphere(const Vector3d &pos,float distance) const
|
||||
{
|
||||
float dx = pos.x - mCenter.x;
|
||||
float dy = pos.y - mCenter.y;
|
||||
float dz = pos.z - mCenter.z;
|
||||
|
||||
float dist = sqrtf( dx*dx + dy*dy + dz*dz );
|
||||
if ( dist < (mRadius+distance) ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
Vector3d mCenter;
|
||||
private:
|
||||
float mRadius;
|
||||
float mRadius2; // radius squared.
|
||||
};
|
||||
|
||||
|
||||
inline Sphere::Sphere()
|
||||
: mCenter(Vector3d(0.0f, 0.0f, 0.0f)), mRadius(0.0f), mRadius2(0.0f) { };
|
||||
|
||||
inline Sphere::Sphere(const Vector3d ¢er, float radius)
|
||||
: mCenter(center), mRadius(radius), mRadius2(radius*radius) { };
|
878
src/SphereLib/spherepack.cpp
Normal file
878
src/SphereLib/spherepack.cpp
Normal file
@ -0,0 +1,878 @@
|
||||
/* Copyright (C) John W. Ratcliff, 2001.
|
||||
* All rights reserved worldwide.
|
||||
*
|
||||
* This software is provided "as is" without express or implied
|
||||
* warranties. You may freely copy and compile this source into
|
||||
* applications you distribute provided that the copyright text
|
||||
* below is included in the resulting source code, for example:
|
||||
* "Portions Copyright (C) John W. Ratcliff, 2001"
|
||||
*/
|
||||
|
||||
#include "Stdafx.h"
|
||||
#include "spherepack.h"
|
||||
|
||||
#if DEMO
|
||||
int PrintText(int x, int y, int color, char* output, ...);
|
||||
int DrawLine(int x1, int y1, int x2, int y2, int color);
|
||||
int DrawCircle(int locx, int locy, int radius, int color);
|
||||
#endif
|
||||
|
||||
SpherePackFactory::SpherePackFactory(int maxspheres, float rootsize, float leafsize, float gravy)
|
||||
{
|
||||
NANOBEGIN
|
||||
maxspheres *= 4; // include room for both trees, the root node and leaf node tree, and the superspheres
|
||||
mMaxRootSize = rootsize;
|
||||
mMaxLeafSize = leafsize;
|
||||
mSuperSphereGravy = gravy;
|
||||
mIntegrate = new SpherePackFifo(maxspheres);
|
||||
mRecompute = new SpherePackFifo(maxspheres);
|
||||
|
||||
mSpheres.Set(maxspheres); // init pool to hold all possible SpherePack instances.
|
||||
|
||||
Vector3d p(0,0,0);
|
||||
|
||||
mRoot = mSpheres.GetFreeLink(); // initially empty
|
||||
mRoot->Init(this,p,6553600,0, false);
|
||||
mRoot->SetSpherePackFlag(SpherePackFlag(SPF_SUPERSPHERE | SPF_ROOTNODE | SPF_ROOT_TREE));
|
||||
|
||||
#if DEMO
|
||||
mRoot->SetColor(0x00FFFFFF);
|
||||
#endif
|
||||
|
||||
mLeaf = mSpheres.GetFreeLink();; // initially empty
|
||||
mLeaf->Init(this,p,1638400,0,false);
|
||||
mLeaf->SetSpherePackFlag(SpherePackFlag(SPF_SUPERSPHERE | SPF_ROOTNODE | SPF_LEAF_TREE));
|
||||
|
||||
#if DEMO
|
||||
mLeaf->SetColor(0x00FFFFFF);
|
||||
mColorCount = 0;
|
||||
|
||||
mColors[0] = 0x00FF0000;
|
||||
mColors[1] = 0x0000FF00;
|
||||
mColors[2] = 0x000000FF;
|
||||
mColors[3] = 0x00FFFF00;
|
||||
mColors[4] = 0x00FF00FF;
|
||||
mColors[5] = 0x0000FFFF;
|
||||
mColors[6] = 0x00FF8080;
|
||||
mColors[7] = 0x0000FF80;
|
||||
mColors[8] = 0x000080FF;
|
||||
mColors[9] = 0x00FFFF80;
|
||||
mColors[10] = 0x00FF80FF;
|
||||
mColors[11] = 0x0080FFFF;
|
||||
|
||||
#endif
|
||||
NANOEND
|
||||
}
|
||||
|
||||
SpherePackFactory::~SpherePackFactory(void)
|
||||
{
|
||||
delete mIntegrate; // free up integration fifo
|
||||
delete mRecompute; // free up recomputation fifo.
|
||||
}
|
||||
|
||||
void SpherePackFactory::Process(void)
|
||||
{
|
||||
{
|
||||
// First recompute anybody that needs to be recomputed!!
|
||||
// When leaf node spheres exit their parent sphere, then the parent sphere needs to be rebalanced. In fact,it may now be empty and
|
||||
// need to be removed.
|
||||
// This is the location where (n) number of spheres in the recomputation FIFO are allowed to be rebalanced in the tree.
|
||||
int maxrecompute = mRecompute->GetCount();
|
||||
for (int i = 0; i < maxrecompute; ++i)
|
||||
{
|
||||
SpherePack * pack = mRecompute->Pop();
|
||||
if (!pack) break;
|
||||
pack->SetFifo1(0); // no longer on the fifo!!
|
||||
bool kill = pack->Recompute(mSuperSphereGravy);
|
||||
if (kill) Remove(pack);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Now, process the integration step.
|
||||
int maxintegrate = mIntegrate->GetCount();
|
||||
|
||||
for (int i = 0; i < maxintegrate; ++i)
|
||||
{
|
||||
SpherePack * pack = mIntegrate->Pop();
|
||||
if (!pack)
|
||||
break;
|
||||
pack->SetFifo2(0);
|
||||
|
||||
if (pack->HasSpherePackFlag(SPF_ROOT_TREE))
|
||||
Integrate(pack,mRoot,mMaxRootSize); // integrate this one single dude against the root node.
|
||||
else
|
||||
Integrate(pack,mLeaf,mMaxLeafSize); // integrate this one single dude against the root node.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
SpherePack * SpherePackFactory::AddSphere_(const Vector3d &pos,
|
||||
float radius,
|
||||
void *userdata,
|
||||
bool isSphere,
|
||||
int flags)
|
||||
{
|
||||
|
||||
SpherePack *pack = mSpheres.GetFreeLink();
|
||||
|
||||
assert(pack);
|
||||
|
||||
if (pack)
|
||||
{
|
||||
if (flags & SPF_ROOT_TREE)
|
||||
{
|
||||
pack->Init(this,pos,radius,userdata, isSphere);
|
||||
pack->SetSpherePackFlag(SPF_ROOT_TREE); // member of the leaf node tree!
|
||||
AddIntegrate(pack); // add to integration list.
|
||||
}
|
||||
else
|
||||
{
|
||||
pack->Init(this,pos,radius,userdata, isSphere);
|
||||
pack->SetSpherePackFlag(SPF_LEAF_TREE); // member of the leaf node tree!
|
||||
AddIntegrate(pack); // add to integration list.
|
||||
}
|
||||
}
|
||||
|
||||
return pack;
|
||||
}
|
||||
|
||||
void SpherePackFactory::AddIntegrate(SpherePack *pack)
|
||||
{
|
||||
if (pack->HasSpherePackFlag(SPF_ROOT_TREE))
|
||||
mRoot->AddChild(pack);
|
||||
else
|
||||
mLeaf->AddChild(pack);
|
||||
|
||||
pack->SetSpherePackFlag(SPF_INTEGRATE); // still needs to be integrated!
|
||||
SpherePack **fifo = mIntegrate->Push(pack); // add it to the integration stack.
|
||||
pack->SetFifo2(fifo);
|
||||
}
|
||||
|
||||
void SpherePackFactory::AddRecompute(SpherePack *recompute)
|
||||
{
|
||||
if (!recompute->HasSpherePackFlag(SPF_RECOMPUTE))
|
||||
{
|
||||
if (recompute->GetChildCount())
|
||||
{
|
||||
recompute->SetSpherePackFlag(SPF_RECOMPUTE); // needs to be recalculated!
|
||||
SpherePack **fifo = mRecompute->Push(recompute);
|
||||
recompute->SetFifo1(fifo);
|
||||
}
|
||||
else
|
||||
{
|
||||
Remove(recompute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpherePackFactory::Render(void)
|
||||
{
|
||||
#if DEMO
|
||||
mRoot->Render(mRoot->GetColor());
|
||||
mLeaf->Render(mLeaf->GetColor());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void SpherePack::Render(unsigned int /*color*/)
|
||||
{
|
||||
#if DEMO
|
||||
if (!HasSpherePackFlag(SPF_ROOTNODE))
|
||||
{
|
||||
|
||||
if (HasSpherePackFlag(SPF_SUPERSPHERE))
|
||||
{
|
||||
color = mColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mParent->HasSpherePackFlag(SPF_ROOTNODE)) color = 0x00FFFFFF;
|
||||
}
|
||||
#if DEMO
|
||||
DrawCircle(int(mCenter.x), int(mCenter.y),int(GetRadius()),color);
|
||||
#endif
|
||||
if (HasSpherePackFlag(SPF_SUPERSPHERE))
|
||||
{
|
||||
if (HasSpherePackFlag(SPF_LEAF_TREE))
|
||||
{
|
||||
|
||||
#if DEMO
|
||||
DrawCircle(int(mCenter.x), int(mCenter.y),int(GetRadius()),color);
|
||||
#endif
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (!sphere->IS_SPHERE)
|
||||
puts("SpherePack::Render");
|
||||
#endif
|
||||
SpherePack *link = (SpherePack *) GetUserData();
|
||||
|
||||
link = link->GetParent();
|
||||
|
||||
if (link && !link->HasSpherePackFlag(SPF_ROOTNODE))
|
||||
{
|
||||
DrawLine(int(mCenter.x), int(mCenter.y),
|
||||
int(link->mCenter.x), int(link->mCenter.y),
|
||||
link->GetColor());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if DEMO
|
||||
DrawCircle(int(mCenter.x), int(mCenter.y),int(GetRadius())+3,color);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (mChildren)
|
||||
{
|
||||
SpherePack *pack = mChildren;
|
||||
|
||||
while (pack)
|
||||
{
|
||||
pack->Render(color);
|
||||
pack = pack->_GetNextSibling();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SpherePack::Recompute(float gravy)
|
||||
{
|
||||
if (!mChildren) return true; // kill it!
|
||||
if (HasSpherePackFlag(SPF_ROOTNODE)) return false; // don't recompute root nodes!
|
||||
|
||||
#if 1
|
||||
// recompute bounding sphere!
|
||||
Vector3d total(0,0,0);
|
||||
int count=0;
|
||||
SpherePack *pack = mChildren;
|
||||
while (pack)
|
||||
{
|
||||
total+=pack->mCenter;
|
||||
count++;
|
||||
pack = pack->_GetNextSibling();
|
||||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
float recip = 1.0f / float(count);
|
||||
total*=recip;
|
||||
|
||||
Vector3d oldpos = mCenter;
|
||||
|
||||
#ifdef __STATIC_RANGE__
|
||||
assert(total.IsInStaticRange());
|
||||
#endif
|
||||
mCenter = total; // new origin!
|
||||
float maxradius = 0;
|
||||
|
||||
pack = mChildren;
|
||||
|
||||
while (pack)
|
||||
{
|
||||
float dist = DistanceSquared(pack);
|
||||
float radius = sqrtf(dist) + pack->GetRadius();
|
||||
if (radius > maxradius)
|
||||
{
|
||||
maxradius = radius;
|
||||
if ((maxradius+gravy) >= GetRadius())
|
||||
{
|
||||
#ifdef __STATIC_RANGE__
|
||||
assert(oldpos.IsInStaticRange());
|
||||
#endif
|
||||
mCenter = oldpos;
|
||||
ClearSpherePackFlag(SPF_RECOMPUTE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pack = pack->_GetNextSibling();
|
||||
}
|
||||
|
||||
maxradius+=gravy;
|
||||
|
||||
SetRadius(maxradius);
|
||||
|
||||
// now all children have to recompute binding distance!!
|
||||
pack = mChildren;
|
||||
|
||||
while (pack)
|
||||
{
|
||||
pack->ComputeBindingDistance(this);
|
||||
pack = pack->_GetNextSibling();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ClearSpherePackFlag(SPF_RECOMPUTE);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void SpherePack::LostChild(SpherePack *t)
|
||||
{
|
||||
assert(mChildCount);
|
||||
assert(mChildren);
|
||||
|
||||
#ifdef _DEBUG // debug validation code.
|
||||
|
||||
SpherePack *pack = mChildren;
|
||||
bool found = false;
|
||||
while (pack)
|
||||
{
|
||||
if (pack == t)
|
||||
{
|
||||
assert(!found);
|
||||
found = true;
|
||||
}
|
||||
pack = pack->_GetNextSibling();
|
||||
}
|
||||
assert(found);
|
||||
|
||||
#endif
|
||||
|
||||
// first patch old linked list.. his previous now points to his next
|
||||
SpherePack *prev = t->_GetPrevSibling();
|
||||
|
||||
if (prev)
|
||||
{
|
||||
SpherePack *next = t->_GetNextSibling();
|
||||
prev->SetNextSibling(next); // my previous now points to my next
|
||||
if (next) next->SetPrevSibling(prev);
|
||||
// list is patched!
|
||||
}
|
||||
else
|
||||
{
|
||||
SpherePack *next = t->_GetNextSibling();
|
||||
mChildren = next;
|
||||
if (mChildren) mChildren->SetPrevSibling(0);
|
||||
}
|
||||
|
||||
mChildCount--;
|
||||
|
||||
if (!mChildCount && HasSpherePackFlag(SPF_SUPERSPHERE))
|
||||
{
|
||||
mFactory->Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
void SpherePackFactory::Remove(SpherePack*pack)
|
||||
{
|
||||
|
||||
if (pack->HasSpherePackFlag(SPF_ROOTNODE)) return; // CAN NEVER REMOVE THE ROOT NODE EVER!!!
|
||||
|
||||
if (pack->HasSpherePackFlag(SPF_SUPERSPHERE) && pack->HasSpherePackFlag(SPF_LEAF_TREE))
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (!pack->IS_SPHERE)
|
||||
puts("SpherePackFactory::Remove");
|
||||
#endif
|
||||
SpherePack *link = (SpherePack *) pack->GetUserData();
|
||||
|
||||
Remove(link);
|
||||
}
|
||||
|
||||
pack->Unlink();
|
||||
|
||||
mSpheres.Release(pack);
|
||||
}
|
||||
|
||||
#if DEMO
|
||||
unsigned int SpherePackFactory::GetColor(void)
|
||||
{
|
||||
unsigned int ret = mColors[mColorCount];
|
||||
mColorCount++;
|
||||
if (mColorCount == MAXCOLORS) mColorCount = 0;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void SpherePackFactory::Integrate(SpherePack *pack,
|
||||
SpherePack *supersphere,
|
||||
float node_size)
|
||||
{
|
||||
// ok..time to integrate this sphere with the tree
|
||||
// first find which supersphere we are closest to the center of
|
||||
|
||||
SpherePack *search = supersphere->GetChildren();
|
||||
|
||||
SpherePack *nearest1 = 0; // nearest supersphere we are completely
|
||||
float neardist1 = 1e38f; // enclosed within
|
||||
|
||||
SpherePack *nearest2 = 0; // supersphere we must grow the least to
|
||||
float neardist2 = 1e38f; // add ourselves to.
|
||||
|
||||
//int scount = 1;
|
||||
|
||||
while (search)
|
||||
{
|
||||
if (search->HasSpherePackFlag(SPF_SUPERSPHERE) && !search->HasSpherePackFlag(SPF_ROOTNODE) && search->GetChildCount())
|
||||
{
|
||||
|
||||
float dist = pack->DistanceSquared(search);
|
||||
|
||||
if (nearest1)
|
||||
{
|
||||
if (dist < neardist1)
|
||||
{
|
||||
|
||||
float d = sqrtf(dist)+pack->GetRadius();
|
||||
|
||||
if (d <= search->GetRadius())
|
||||
{
|
||||
neardist1 = dist;
|
||||
nearest1 = search;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
float d = (sqrtf(dist) + pack->GetRadius())-search->GetRadius();
|
||||
|
||||
if (d < neardist2)
|
||||
{
|
||||
if (d < 0)
|
||||
{
|
||||
neardist1 = dist;
|
||||
nearest1 = search;
|
||||
}
|
||||
else
|
||||
{
|
||||
neardist2 = d;
|
||||
nearest2 = search;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
search = search->_GetNextSibling();
|
||||
}
|
||||
|
||||
// ok...now..on exit let's see what we got.
|
||||
if (nearest1)
|
||||
{
|
||||
// if we are inside an existing supersphere, we are all good!
|
||||
// we need to detach item from wherever it is, and then add it to
|
||||
// this supersphere as a child.
|
||||
pack->Unlink();
|
||||
nearest1->AddChild(pack);
|
||||
pack->ComputeBindingDistance(nearest1);
|
||||
nearest1->Recompute(mSuperSphereGravy);
|
||||
|
||||
if (nearest1->HasSpherePackFlag(SPF_LEAF_TREE))
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (!nearest1->IS_SPHERE)
|
||||
puts("SpherePackFactory::Integrate1");
|
||||
#endif
|
||||
SpherePack *link = (SpherePack *) nearest1->GetUserData();
|
||||
link->NewPosRadius(nearest1->GetPos(), nearest1->GetRadius());
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
bool newsphere = true;
|
||||
|
||||
if (nearest2)
|
||||
{
|
||||
float newsize = neardist2 + nearest2->GetRadius() + mSuperSphereGravy;
|
||||
|
||||
if (newsize <= node_size)
|
||||
{
|
||||
pack->Unlink();
|
||||
|
||||
nearest2->SetRadius(newsize);
|
||||
nearest2->AddChild(pack);
|
||||
nearest2->Recompute(mSuperSphereGravy);
|
||||
pack->ComputeBindingDistance(nearest2);
|
||||
|
||||
if (nearest2->HasSpherePackFlag(SPF_LEAF_TREE))
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (!nearest2->IS_SPHERE)
|
||||
puts("SpherePackFactory::Integrate2");
|
||||
#endif
|
||||
SpherePack *link = (SpherePack *) nearest2->GetUserData();
|
||||
link->NewPosRadius(nearest2->GetPos(), nearest2->GetRadius());
|
||||
}
|
||||
|
||||
newsphere = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (newsphere)
|
||||
{
|
||||
assert(supersphere->HasSpherePackFlag(SPF_ROOTNODE));
|
||||
// we are going to create a new superesphere around this guy!
|
||||
pack->Unlink();
|
||||
|
||||
SpherePack *parent = mSpheres.GetFreeLink();
|
||||
assert(parent);
|
||||
parent->Init(this, pack->GetPos(), pack->GetRadius()+mSuperSphereGravy, 0, false);
|
||||
|
||||
if (supersphere->HasSpherePackFlag(SPF_ROOT_TREE))
|
||||
parent->SetSpherePackFlag(SPF_ROOT_TREE);
|
||||
else
|
||||
parent->SetSpherePackFlag(SPF_LEAF_TREE);
|
||||
|
||||
parent->SetSpherePackFlag(SPF_SUPERSPHERE);
|
||||
#if DEMO
|
||||
parent->SetColor(GetColor());
|
||||
#endif
|
||||
parent->AddChild(pack);
|
||||
|
||||
supersphere->AddChild(parent);
|
||||
|
||||
parent->Recompute(mSuperSphereGravy);
|
||||
pack->ComputeBindingDistance(parent);
|
||||
|
||||
if (parent->HasSpherePackFlag(SPF_LEAF_TREE))
|
||||
{
|
||||
// need to create parent association!
|
||||
SpherePack *link = AddSphere_(parent->GetPos(), parent->GetRadius(), parent, true, SPF_ROOT_TREE);
|
||||
parent->SetUserData(link, true); // hook him up!!
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pack->ClearSpherePackFlag(SPF_INTEGRATE); // we've been integrated!
|
||||
}
|
||||
|
||||
|
||||
void SpherePackFactory::FrustumTest(const Frustum &f,SpherePackCallback *callback)
|
||||
{
|
||||
// test case here, just traverse children.
|
||||
mCallback = callback;
|
||||
mRoot->VisibilityTest(f,this,VS_PARTIAL);
|
||||
}
|
||||
|
||||
|
||||
void SpherePack::VisibilityTest(const Frustum &f,SpherePackCallback *callback,ViewState state)
|
||||
{
|
||||
|
||||
if (state == VS_PARTIAL)
|
||||
{
|
||||
state = f.ViewVolumeTest(mCenter, GetRadius());
|
||||
#if DEMO
|
||||
if (state != VS_OUTSIDE)
|
||||
{
|
||||
DrawCircle(int(mCenter.x), int(mCenter.y), int(GetRadius()), 0x404040);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (HasSpherePackFlag(SPF_SUPERSPHERE))
|
||||
{
|
||||
|
||||
|
||||
if (state == VS_OUTSIDE)
|
||||
{
|
||||
if (HasSpherePackFlag(SPF_HIDDEN)) return; // no state change
|
||||
ClearSpherePackFlag(SpherePackFlag(SPF_INSIDE | SPF_PARTIAL));
|
||||
SetSpherePackFlag(SPF_HIDDEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state == VS_INSIDE)
|
||||
{
|
||||
if (HasSpherePackFlag(SPF_INSIDE)) return; // no state change
|
||||
ClearSpherePackFlag(SpherePackFlag(SPF_PARTIAL | SPF_HIDDEN));
|
||||
SetSpherePackFlag(SPF_INSIDE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearSpherePackFlag(SpherePackFlag(SPF_HIDDEN | SPF_INSIDE));
|
||||
SetSpherePackFlag(SPF_PARTIAL);
|
||||
}
|
||||
}
|
||||
|
||||
SpherePack *pack = mChildren;
|
||||
|
||||
while (pack)
|
||||
{
|
||||
pack->VisibilityTest(f,callback,state);
|
||||
pack = pack->_GetNextSibling();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case VS_INSIDE:
|
||||
if (!HasSpherePackFlag(SPF_INSIDE))
|
||||
{
|
||||
ClearSpherePackFlag(SpherePackFlag(SPF_HIDDEN | SPF_PARTIAL));
|
||||
SetSpherePackFlag(SPF_INSIDE);
|
||||
callback->VisibilityCallback(f,this,state);
|
||||
}
|
||||
break;
|
||||
case VS_OUTSIDE:
|
||||
if (!HasSpherePackFlag(SPF_HIDDEN))
|
||||
{
|
||||
ClearSpherePackFlag(SpherePackFlag(SPF_INSIDE | SPF_PARTIAL));
|
||||
SetSpherePackFlag(SPF_HIDDEN);
|
||||
callback->VisibilityCallback(f,this,state);
|
||||
}
|
||||
break;
|
||||
case VS_PARTIAL:
|
||||
//if (!HasSpherePackFlag(SPF_PARTIAL))
|
||||
{
|
||||
ClearSpherePackFlag(SpherePackFlag(SPF_INSIDE | SPF_HIDDEN));
|
||||
SetSpherePackFlag(SPF_PARTIAL);
|
||||
callback->VisibilityCallback(f,this,state);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SpherePackFactory::RayTrace(const Vector3d &p1,
|
||||
const Vector3d &p2,
|
||||
SpherePackCallback *callback)
|
||||
{
|
||||
// test case here, just traverse children.
|
||||
Vector3d dir = p2;
|
||||
float dist = dir.Normalize();
|
||||
mCallback = callback;
|
||||
mRoot->RayTrace(p1,dir,dist,this);
|
||||
}
|
||||
|
||||
#include "../EterBase/Debug.h"
|
||||
|
||||
void SpherePackFactory::RangeTest(const Vector3d ¢er,float radius,SpherePackCallback *callback)
|
||||
{
|
||||
#ifdef __STATIC_RANGE__
|
||||
if (!center.IsInStaticRange())
|
||||
{
|
||||
TraceError("SpherePackFactory::RangeTest - RANGE ERROR %f, %f, %f",
|
||||
center.x, center.y, center.z);
|
||||
assert("SpherePackFactory::RangeTest - RANGE ERROR");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
mCallback = callback;
|
||||
mRoot->RangeTest(center,radius,this,VS_PARTIAL);
|
||||
}
|
||||
|
||||
void SpherePackFactory::PointTest2d(const Vector3d ¢er, SpherePackCallback *callback)
|
||||
{
|
||||
#ifdef __STATIC_RANGE__
|
||||
if (!center.IsInStaticRange())
|
||||
{
|
||||
TraceError("SpherePackFactory::RangeTest2d - RANGE ERROR %f, %f, %f",
|
||||
center.x, center.y, center.z);
|
||||
assert("SpherePackFactory::RangeTest2d - RANGE ERROR");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
mCallback = callback;
|
||||
|
||||
#ifdef SPHERELIB_STRICT
|
||||
mRoot->PointTest2d(center, this,VS_PARTIAL);
|
||||
extern bool MAPOUTDOOR_GET_HEIGHT_TRACE;
|
||||
if (MAPOUTDOOR_GET_HEIGHT_TRACE)
|
||||
puts("================================================");
|
||||
#else
|
||||
mRoot->PointTest2d(center, this,VS_PARTIAL);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void SpherePack::RangeTest(const Vector3d &p,
|
||||
float distance,
|
||||
SpherePackCallback *callback,
|
||||
ViewState state)
|
||||
{
|
||||
|
||||
if (state == VS_PARTIAL)
|
||||
{
|
||||
float d = p.Distance(mCenter);
|
||||
if ((d-distance) > GetRadius()) return;;
|
||||
if ((GetRadius()+d) < distance) state = VS_INSIDE;
|
||||
}
|
||||
|
||||
if (HasSpherePackFlag(SPF_SUPERSPHERE))
|
||||
{
|
||||
#if DEMO
|
||||
if (state == VS_PARTIAL)
|
||||
{
|
||||
DrawCircle(int(mCenter.x), int(mCenter.y), int(GetRadius()), 0x404040);
|
||||
}
|
||||
#endif
|
||||
SpherePack *pack = mChildren;
|
||||
while (pack)
|
||||
{
|
||||
pack->RangeTest(p,distance,callback,state);
|
||||
pack = pack->_GetNextSibling();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
callback->RangeTestCallback(p,distance,this,state);
|
||||
}
|
||||
}
|
||||
|
||||
void SpherePack::PointTest2d(const Vector3d &p,
|
||||
SpherePackCallback *callback,
|
||||
ViewState state)
|
||||
{
|
||||
if (state == VS_PARTIAL)
|
||||
{
|
||||
float dx=p.x-mCenter.x;
|
||||
float dy=p.y-mCenter.y;
|
||||
float distSquare = (dx*dx)+(dy*dy);
|
||||
|
||||
if (distSquare > GetRadius2()) return;;
|
||||
if (GetRadius2() < -distSquare) state = VS_INSIDE;
|
||||
}
|
||||
|
||||
if (HasSpherePackFlag(SPF_SUPERSPHERE))
|
||||
{
|
||||
#if DEMO
|
||||
if (state == VS_PARTIAL)
|
||||
{
|
||||
DrawCircle(int(mCenter.x), int(mCenter.y), int(GetRadius()), 0x404040);
|
||||
}
|
||||
#endif
|
||||
SpherePack *pack = mChildren;
|
||||
while (pack)
|
||||
{
|
||||
pack->PointTest2d(p, callback, state);
|
||||
pack = pack->_GetNextSibling();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
extern bool MAPOUTDOOR_GET_HEIGHT_TRACE;
|
||||
if (MAPOUTDOOR_GET_HEIGHT_TRACE)
|
||||
{
|
||||
float dx=p.x-mCenter.x;
|
||||
float dy=p.y-mCenter.y;
|
||||
float distSquare = (dx*dx)+(dy*dy);
|
||||
printf("--- (%f, %f) dist %f radius %f isSphere %d\n", mCenter.x, mCenter.y, distSquare, GetRadius(), IS_SPHERE);
|
||||
}
|
||||
#endif
|
||||
callback->PointTest2dCallback(p, this, state);
|
||||
}
|
||||
}
|
||||
|
||||
void SpherePackFactory::RangeTestCallback(const Vector3d &p,float distance,SpherePack *sphere,ViewState state)
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (!sphere->IS_SPHERE)
|
||||
puts("SpherePackFactory::RangeTestCallback");
|
||||
#endif
|
||||
SpherePack *link = (SpherePack *) sphere->GetUserData();
|
||||
if (link) link->RangeTest(p,distance,mCallback,state);
|
||||
};
|
||||
|
||||
void SpherePackFactory::PointTest2dCallback(const Vector3d &p, SpherePack *sphere,ViewState state)
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (!sphere->IS_SPHERE)
|
||||
puts("SpherePackFactory::PointTest2dCallback");
|
||||
#endif
|
||||
SpherePack *link = (SpherePack *) sphere->GetUserData();
|
||||
if (link) link->PointTest2d(p, mCallback,state);
|
||||
};
|
||||
|
||||
void SpherePack::RayTrace(const Vector3d &p1,
|
||||
const Vector3d &dir,
|
||||
float distance,
|
||||
SpherePackCallback *callback)
|
||||
{
|
||||
bool hit = false;
|
||||
|
||||
if (HasSpherePackFlag(SPF_SUPERSPHERE))
|
||||
{
|
||||
|
||||
hit = RayIntersectionInFront(p1,dir,0);
|
||||
|
||||
if (hit)
|
||||
{
|
||||
#if DEMO
|
||||
DrawCircle(int(mCenter.x), int(mCenter.y), int(GetRadius()), 0x404040);
|
||||
#endif
|
||||
SpherePack *pack = mChildren;
|
||||
|
||||
while (pack)
|
||||
{
|
||||
pack->RayTrace(p1,dir,distance,callback);
|
||||
pack = pack->_GetNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector3d sect;
|
||||
hit = RayIntersection(p1,dir,distance,§);
|
||||
if (hit)
|
||||
{
|
||||
callback->RayTraceCallback(p1,dir,distance,sect,this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpherePackFactory::RayTraceCallback(const Vector3d &p1, // source pos of ray
|
||||
const Vector3d &dir, // direction of ray
|
||||
float distance, // distance of ray
|
||||
const Vector3d &/*sect*/, // intersection location
|
||||
SpherePack *sphere)
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (!sphere->IS_SPHERE)
|
||||
puts("SpherePackFactory::RayTraceCallback");
|
||||
#endif
|
||||
SpherePack *link = (SpherePack *) sphere->GetUserData();
|
||||
if (link) link->RayTrace(p1,dir,distance,mCallback);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
void SpherePackFactory::Reset(void)
|
||||
{
|
||||
mRoot->Reset();
|
||||
mLeaf->Reset();
|
||||
}
|
||||
|
||||
|
||||
void SpherePack::Reset(void)
|
||||
{
|
||||
ClearSpherePackFlag(SpherePackFlag(SPF_HIDDEN | SPF_PARTIAL | SPF_INSIDE));
|
||||
|
||||
SpherePack *pack = mChildren;
|
||||
while (pack)
|
||||
{
|
||||
pack->Reset();
|
||||
pack = pack->_GetNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
void SpherePackFactory::VisibilityCallback(const Frustum &f,SpherePack *sphere,ViewState state)
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (!sphere->IS_SPHERE)
|
||||
puts("SpherePackFactory::VisibilityCallback");
|
||||
#endif
|
||||
SpherePack *link = (SpherePack *) sphere->GetUserData();
|
||||
if (link) link->VisibilityTest(f,mCallback,state);
|
||||
}
|
492
src/SphereLib/spherepack.h
Normal file
492
src/SphereLib/spherepack.h
Normal file
@ -0,0 +1,492 @@
|
||||
/* Copyright (C) John W. Ratcliff, 2001.
|
||||
* All rights reserved worldwide.
|
||||
*
|
||||
* This software is provided "as is" without express or implied
|
||||
* warranties. You may freely copy and compile this source into
|
||||
* applications you distribute provided that the copyright text
|
||||
* below is included in the resulting source code, for example:
|
||||
* "Portions Copyright (C) John W. Ratcliff, 2001"
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/***********************************************************************/
|
||||
/** SPHEREPACK.H: Contains all of the support code for Sphere Trees. */
|
||||
/** */
|
||||
/** Written by John W. Ratcliff jratcliff@att.net */
|
||||
/***********************************************************************/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "vector.h" // need 3d vector support.
|
||||
#include "pool.h" // need memory pool template class.
|
||||
#include "sphere.h" // Need sphere base class.
|
||||
#include "frustum.h" // Need to know what a frustum is.
|
||||
|
||||
#define DEMO 0// true if running in windows test app
|
||||
|
||||
enum SpherePackFlag
|
||||
{
|
||||
|
||||
SPF_SUPERSPHERE =(1<<0), // this is a supersphere, allocated and deleted by us
|
||||
SPF_ROOT_TREE =(1<<1), // member of the root tree
|
||||
SPF_LEAF_TREE =(1<<2), // member of the leaf node tree
|
||||
SPF_ROOTNODE =(1<<3), // this is the root node
|
||||
SPF_RECOMPUTE =(1<<4), // needs recomputed bounding sphere
|
||||
SPF_INTEGRATE =(1<<5), // needs to be reintegrated into tree
|
||||
// Frame-to-frame view frustum status. Only does callbacks when a
|
||||
// state change occurs.
|
||||
SPF_HIDDEN =(1<<6), // outside of view frustum
|
||||
SPF_PARTIAL =(1<<7), // partially inside view frustum
|
||||
SPF_INSIDE =(1<<8) // completely inside view frustum
|
||||
};
|
||||
|
||||
class SpherePackFactory; // forward reference the factory.
|
||||
class SpherePack; // forward reference the sphere package
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4100)
|
||||
|
||||
// Virtual base class, used to implement callbacks for RayTracing,
|
||||
// range testing, and frustum culling.
|
||||
class SpherePackCallback
|
||||
{
|
||||
public:
|
||||
SpherePackCallback() {}
|
||||
virtual ~SpherePackCallback() {}
|
||||
|
||||
virtual void VisibilityCallback(const Frustum &f, // frustum clipped against
|
||||
SpherePack *sphere, // leaf node sphere in question
|
||||
ViewState state) // new state it is in.
|
||||
{};
|
||||
|
||||
virtual void RayTraceCallback(const Vector3d &p1, // source pos of ray
|
||||
const Vector3d &dir, // direction of ray
|
||||
float distance, // distance of ray
|
||||
const Vector3d §, // intersection location
|
||||
SpherePack *sphere) // sphere ray hit
|
||||
{};
|
||||
|
||||
virtual void RangeTestCallback(const Vector3d &searchpos, // position we are performing range test against.
|
||||
float distance, // squared distance we are range searching against.
|
||||
SpherePack *sphere,
|
||||
ViewState state) // sphere within range, VS_PARTIAL if sphere straddles range test
|
||||
{};
|
||||
|
||||
virtual void PointTest2dCallback(const Vector3d &searchpos, // position we are performing range test against.
|
||||
SpherePack *sphere,
|
||||
ViewState state) // sphere within range, VS_PARTIAL if sphere straddles range test
|
||||
{};
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
class SpherePack : public Sphere
|
||||
{
|
||||
public:
|
||||
SpherePack(void)
|
||||
{
|
||||
mUserData = 0; // default user data is null
|
||||
mFactory = 0; // factory we are a member of
|
||||
mNext = 0; // linked list pointers
|
||||
mPrevious = 0;
|
||||
mParent = 0;
|
||||
mNextSibling = 0; // our brothers and sisters at this level.
|
||||
mPrevSibling = 0;
|
||||
mChildren = 0; // our children.
|
||||
mChildCount = 0; // number of children we have.
|
||||
mFifo1 = 0; // our FIFO1 location if we have one.
|
||||
mFifo2 = 0; // our FIFO2 location if we have one.
|
||||
SetRadius(0); // default radius
|
||||
mCenter.Set(0,0,0); // default center position.
|
||||
IS_SPHERE = false;
|
||||
};
|
||||
virtual ~SpherePack()
|
||||
{
|
||||
}
|
||||
|
||||
void Init(SpherePackFactory *factory, // factory we belong to
|
||||
const Vector3d &pos, // center of sphere
|
||||
float radius, // radius of sphere
|
||||
void *userdata, bool isSphere) // user data
|
||||
{
|
||||
IS_SPHERE = isSphere;
|
||||
mUserData = userdata;
|
||||
mParent = 0;
|
||||
mNextSibling = 0;
|
||||
mPrevSibling = 0;
|
||||
mFlags = 0;
|
||||
mFifo1 = 0;
|
||||
mFifo2 = 0;
|
||||
mFactory = factory;
|
||||
mCenter = pos;
|
||||
SetRadius(radius);
|
||||
};
|
||||
|
||||
// Access to SpherePack bit flags.
|
||||
void SetSpherePackFlag(SpherePackFlag flag) { mFlags|=flag; };
|
||||
void ClearSpherePackFlag(SpherePackFlag flag) { mFlags&=~flag; };
|
||||
bool HasSpherePackFlag(SpherePackFlag flag) const
|
||||
{
|
||||
if ( mFlags & flag ) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
void SetParent(SpherePack *pack) { mParent = pack; };
|
||||
SpherePack * GetParent(void) const { return mParent; };
|
||||
|
||||
// Sphere has a new position.
|
||||
inline void NewPos(const Vector3d &pos);
|
||||
// Sphere has a new position and radius
|
||||
inline void NewPosRadius(const Vector3d &pos,float radius);
|
||||
|
||||
void Unlink(void)
|
||||
{
|
||||
if ( mFifo1 ) // if we belong to fifo1, null us out
|
||||
{
|
||||
*mFifo1 = 0;
|
||||
mFifo1 = 0;
|
||||
}
|
||||
|
||||
if ( mFifo2 ) // if we belong to fifo2, null us out
|
||||
{
|
||||
*mFifo2 = 0;
|
||||
mFifo2 = 0;
|
||||
}
|
||||
|
||||
if ( mParent ) mParent->LostChild(this);
|
||||
|
||||
assert( !mChildren ); // can't unlink guys with children!
|
||||
|
||||
mParent = 0; // got no father anymore
|
||||
}
|
||||
|
||||
|
||||
void AddChild(SpherePack *pack)
|
||||
{
|
||||
|
||||
SpherePack *my_child = mChildren;
|
||||
mChildren = pack; // new head of list
|
||||
|
||||
pack->SetNextSibling(my_child); // his next is my old next
|
||||
pack->SetPrevSibling(0); // at head of list, no previous
|
||||
pack->SetParent(this);
|
||||
|
||||
if ( my_child ) my_child->SetPrevSibling(pack); // previous now this..
|
||||
|
||||
mChildCount++;
|
||||
|
||||
#if defined(_DEBUG)
|
||||
float dist = DistanceSquared(pack);
|
||||
float radius = sqrtf(dist) + pack->GetRadius();
|
||||
|
||||
assert( radius <= GetRadius()+0.0001f );
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetNextSibling(SpherePack *child) { mNextSibling = child; }
|
||||
void SetPrevSibling(SpherePack *child) { mPrevSibling = child; }
|
||||
|
||||
SpherePack * _GetNextSibling(void) const
|
||||
{
|
||||
return mNextSibling;
|
||||
}
|
||||
SpherePack * _GetPrevSibling(void) const
|
||||
{
|
||||
return mPrevSibling;
|
||||
}
|
||||
SpherePack * GetChildren(void) const { return mChildren; }
|
||||
|
||||
SpherePack * GetNext(void) const { return mNext; };
|
||||
SpherePack * GetPrevious(void) const { return mPrevious; };
|
||||
|
||||
void SetNext(SpherePack *pack) { mNext = pack; };
|
||||
void SetPrevious(SpherePack *pack) { mPrevious = pack; };
|
||||
|
||||
void * GetUserData(void) const { return mUserData; };
|
||||
void SetUserData(void *data, bool isSphere) { mUserData = data; IS_SPHERE=isSphere;};
|
||||
|
||||
float DistanceSquared(const SpherePack *pack) const { return mCenter.DistanceSq( pack->mCenter ); };
|
||||
|
||||
inline void LostChild(SpherePack *pack);
|
||||
|
||||
const Vector3d& GetPos(void) const { return mCenter; };
|
||||
|
||||
inline void Render(unsigned int color);
|
||||
|
||||
inline bool Recompute(float gravy);
|
||||
|
||||
int GetChildCount(void) const { return mChildCount; };
|
||||
|
||||
#if DEMO
|
||||
void SetColor(unsigned int color) { mColor = color; };
|
||||
unsigned int GetColor(void) const { return mColor; };
|
||||
#endif
|
||||
|
||||
void SetFifo1(SpherePack **fifo)
|
||||
{
|
||||
mFifo1 = fifo;
|
||||
};
|
||||
|
||||
void SetFifo2(SpherePack **fifo)
|
||||
{
|
||||
mFifo2 = fifo;
|
||||
};
|
||||
|
||||
void ComputeBindingDistance(SpherePack *parent)
|
||||
{
|
||||
mBindingDistance = parent->GetRadius() - GetRadius();
|
||||
if ( mBindingDistance <= 0 )
|
||||
mBindingDistance = 0;
|
||||
else
|
||||
mBindingDistance*=mBindingDistance;
|
||||
}
|
||||
|
||||
void VisibilityTest(const Frustum &f,
|
||||
SpherePackCallback *callback,
|
||||
ViewState state);
|
||||
|
||||
void RayTrace(const Vector3d &p1, // origin of Ray
|
||||
const Vector3d &dir, // direction of Ray
|
||||
float distance, // length of ray.
|
||||
SpherePackCallback *callback);
|
||||
|
||||
|
||||
void RangeTest(const Vector3d &p,
|
||||
float distance,
|
||||
SpherePackCallback *callback,
|
||||
ViewState state);
|
||||
|
||||
void PointTest2d(const Vector3d &p,
|
||||
SpherePackCallback *callback,
|
||||
ViewState state);
|
||||
|
||||
void Reset(void);
|
||||
|
||||
private:
|
||||
SpherePack *mNext;
|
||||
SpherePack *mPrevious; // used by pool memory management linked list code
|
||||
|
||||
SpherePack *mParent;
|
||||
SpherePack *mChildren; // *my* children
|
||||
|
||||
SpherePack *mNextSibling; // doubly linked list of my brothers
|
||||
SpherePack *mPrevSibling; // and sisters
|
||||
|
||||
SpherePack **mFifo1; // address of location inside of fifo1
|
||||
SpherePack **mFifo2; // address of location inside of fifo2
|
||||
|
||||
long mFlags; // my bit flags.
|
||||
long mChildCount; // number of children
|
||||
|
||||
float mBindingDistance;
|
||||
|
||||
void *mUserData;
|
||||
|
||||
SpherePackFactory *mFactory; // the factory we are a member of.
|
||||
#if DEMO
|
||||
unsigned long mColor;
|
||||
#endif
|
||||
|
||||
public:
|
||||
bool IS_SPHERE;
|
||||
};
|
||||
|
||||
class SpherePackFifo
|
||||
{
|
||||
public:
|
||||
SpherePackFifo(int fifosize)
|
||||
{
|
||||
mCount = 0;
|
||||
mSP = 0;
|
||||
mBottom = 0;
|
||||
mFifoSize = fifosize;
|
||||
mFifo = new SpherePack *[mFifoSize];
|
||||
};
|
||||
|
||||
virtual ~SpherePackFifo(void)
|
||||
{
|
||||
delete [] mFifo;
|
||||
};
|
||||
|
||||
SpherePack ** Push(SpherePack *sphere)
|
||||
{
|
||||
mCount++;
|
||||
SpherePack **ret = &mFifo[mSP];
|
||||
mFifo[mSP] = sphere;
|
||||
mSP++;
|
||||
if ( mSP == mFifoSize ) mSP = 0;
|
||||
return ret;
|
||||
};
|
||||
|
||||
SpherePack * Pop(void)
|
||||
{
|
||||
while ( mSP != mBottom )
|
||||
{
|
||||
mCount--;
|
||||
SpherePack *ret = mFifo[mBottom];
|
||||
mBottom++;
|
||||
if ( mBottom == mFifoSize ) mBottom = 0;
|
||||
if ( ret ) return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Flush(SpherePack *pack)
|
||||
{
|
||||
if ( mSP == mBottom ) return false;
|
||||
int i = mBottom;
|
||||
while ( i != mSP )
|
||||
{
|
||||
if ( mFifo[i] == pack )
|
||||
{
|
||||
mFifo[i] = 0;
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
if ( i == mFifoSize ) i = 0;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
int GetCount(void) const { return mCount; };
|
||||
|
||||
private:
|
||||
int mCount;
|
||||
int mSP; // stack pointer
|
||||
int mBottom;
|
||||
int mFifoSize;
|
||||
SpherePack **mFifo;
|
||||
};
|
||||
|
||||
|
||||
class SpherePackFactory : public SpherePackCallback
|
||||
{
|
||||
public:
|
||||
|
||||
SpherePackFactory(int maxspheres,
|
||||
float rootsize,
|
||||
float leafsize,
|
||||
float gravy);
|
||||
|
||||
|
||||
virtual ~SpherePackFactory(void);
|
||||
|
||||
void Process(void);
|
||||
|
||||
SpherePack *AddSphere_(const Vector3d &pos,
|
||||
float radius,
|
||||
void *userdata,
|
||||
bool isSphere,
|
||||
int flags=SPF_LEAF_TREE);
|
||||
|
||||
void AddIntegrate(SpherePack *pack); // add to the integration FIFO
|
||||
void AddRecompute(SpherePack *recompute); // add to the recomputation (balancing) FIFO.
|
||||
|
||||
void Integrate(SpherePack *pack,SpherePack *supersphere,float node_size);
|
||||
|
||||
void Render(void);
|
||||
|
||||
void Remove(SpherePack *pack);
|
||||
// see if any other spheres are contained within this one, if so
|
||||
// collapse them and inherit their children.
|
||||
#if DEMO
|
||||
unsigned int GetColor(void);
|
||||
#endif
|
||||
|
||||
void FrustumTest(const Frustum &f,SpherePackCallback *callback);
|
||||
|
||||
void RayTrace(const Vector3d &p1, // source
|
||||
const Vector3d &p2, // dest
|
||||
SpherePackCallback *callback);
|
||||
|
||||
void RangeTest(const Vector3d ¢er,float radius,SpherePackCallback *callback);
|
||||
void PointTest2d(const Vector3d ¢er, SpherePackCallback *callback);
|
||||
|
||||
virtual void RayTraceCallback(const Vector3d &p1, // source pos of ray
|
||||
const Vector3d &dir, // direction of ray
|
||||
float distance, // distance of ray
|
||||
const Vector3d §, // intersection location
|
||||
SpherePack *sphere);
|
||||
|
||||
virtual void RangeTestCallback(const Vector3d &p,float distance,SpherePack *sphere,ViewState state);
|
||||
virtual void PointTest2dCallback(const Vector3d &p, SpherePack *sphere,ViewState state);
|
||||
|
||||
virtual void VisibilityCallback(const Frustum &f,SpherePack *sphere,ViewState state);
|
||||
|
||||
|
||||
void Reset(void);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
SpherePack *mRoot; // 1024x1024 root node of all active spheres.
|
||||
SpherePack *mLeaf; // 1024x1024 root node of all active spheres.
|
||||
SpherePackCallback *mCallback;
|
||||
|
||||
Pool< SpherePack > mSpheres; // all spheres possibly represented.
|
||||
|
||||
SpherePackFifo *mIntegrate; // integration fifo
|
||||
SpherePackFifo *mRecompute; // recomputation fifo
|
||||
|
||||
#if DEMO
|
||||
#define MAXCOLORS 12
|
||||
int mColorCount;
|
||||
unsigned int mColors[MAXCOLORS];
|
||||
#endif
|
||||
|
||||
float mMaxRootSize; // maximum size of a root node supersphere
|
||||
float mMaxLeafSize; // maximum size of the leaf node supersphere
|
||||
float mSuperSphereGravy; // binding distance gravy.
|
||||
};
|
||||
|
||||
//*** Source code placed in header file so that it will be inlined!
|
||||
void SpherePack::NewPos(const Vector3d &pos)
|
||||
{
|
||||
mCenter = pos; // set our new center position.
|
||||
|
||||
// is we have a parent (meaning we are a valid leaf node) and we have not already been flagged for re-integration, then.....
|
||||
if (mParent && !HasSpherePackFlag(SPF_INTEGRATE))
|
||||
{
|
||||
float dist = DistanceSquared(mParent); // compute squared distance to our parent.
|
||||
|
||||
if (dist >= mBindingDistance) // if that exceeds our binding distance...
|
||||
{
|
||||
// If our parent, is not already marked to be recomputed (rebalance the sphere), then add him to the recomputation fifo.
|
||||
mFactory->AddRecompute(mParent);
|
||||
|
||||
// Unlink ourselves from the parent sphere and place ourselves into the root node.
|
||||
Unlink();
|
||||
mFactory->AddIntegrate(this); // add ourselves to the re-integration fifo.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SpherePack::NewPosRadius(const Vector3d &pos,float radius)
|
||||
{
|
||||
// New position and, possibly, a new radius.
|
||||
mCenter = pos;
|
||||
|
||||
if (mParent && !HasSpherePackFlag(SPF_INTEGRATE))
|
||||
{
|
||||
if (radius != GetRadius())
|
||||
{
|
||||
SetRadius(radius);
|
||||
ComputeBindingDistance(mParent);
|
||||
}
|
||||
|
||||
mFactory->AddRecompute(mParent);
|
||||
|
||||
float dist = DistanceSquared(mParent);
|
||||
|
||||
if (dist >= mBindingDistance)
|
||||
{
|
||||
Unlink();
|
||||
mFactory->AddIntegrate(this);
|
||||
}
|
||||
}
|
||||
}
|
225
src/SphereLib/vector.h
Normal file
225
src/SphereLib/vector.h
Normal file
@ -0,0 +1,225 @@
|
||||
/* Copyright (C) John W. Ratcliff, 2001.
|
||||
* All rights reserved worldwide.
|
||||
*
|
||||
* This software is provided "as is" without express or implied
|
||||
* warranties. You may freely copy and compile this source into
|
||||
* applications you distribute provided that the copyright text
|
||||
* below is included in the resulting source code, for example:
|
||||
* "Portions Copyright (C) John W. Ratcliff, 2001"
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <math.h>
|
||||
#include <vector>
|
||||
//#include "stl.h"
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/** VECTOR.H : Template class to represent a 2d and 3d vector type. */
|
||||
/** */
|
||||
/** Written by John W. Ratcliff jratcliff@att.net */
|
||||
/***********************************************************************/
|
||||
|
||||
class Vector3d : public D3DXVECTOR3
|
||||
{
|
||||
public:
|
||||
Vector3d(void) { }; // null constructor, does not inialize point.
|
||||
|
||||
Vector3d(const Vector3d &a) // constructor copies existing vector.
|
||||
{
|
||||
x = a.x;
|
||||
y = a.y;
|
||||
z = a.z;
|
||||
};
|
||||
|
||||
Vector3d(float a,float b,float c) // construct with initial point.
|
||||
{
|
||||
x = a;
|
||||
y = b;
|
||||
z = c;
|
||||
};
|
||||
|
||||
bool operator==(const Vector3d &a) const
|
||||
{
|
||||
if ( a.x == x && a.y == y && a.z == z ) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
bool operator!=(const Vector3d &a) const
|
||||
{
|
||||
if ( a.x != x || a.y != y || a.z != z ) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
// Operators
|
||||
Vector3d& operator = (const Vector3d& A) // ASSIGNMENT (=)
|
||||
{ x=A.x; y=A.y; z=A.z;
|
||||
return(*this); };
|
||||
|
||||
Vector3d operator + (const Vector3d& A) const // ADDITION (+)
|
||||
{ Vector3d Sum(x+A.x, y+A.y, z+A.z);
|
||||
return(Sum); };
|
||||
|
||||
Vector3d operator - (const Vector3d& A) const // SUBTRACTION (-)
|
||||
{ Vector3d Diff(x-A.x, y-A.y, z-A.z);
|
||||
return(Diff); };
|
||||
|
||||
Vector3d operator * (const float s) const // MULTIPLY BY SCALAR (*)
|
||||
{ Vector3d Scaled(x*s, y*s, z*s);
|
||||
return(Scaled); };
|
||||
|
||||
Vector3d operator / (const float s) const // DIVIDE BY SCALAR (/)
|
||||
{
|
||||
float r = 1.0f / s;
|
||||
Vector3d Scaled(x*r, y*r, z*r);
|
||||
return(Scaled);
|
||||
};
|
||||
|
||||
void operator += (const Vector3d A) // ACCUMULATED VECTOR ADDITION (+=)
|
||||
{ x+=A.x; y+=A.y; z+=A.z; };
|
||||
void operator -= (const Vector3d A) // ACCUMULATED VECTOR SUBTRACTION (+=)
|
||||
{ x-=A.x; y-=A.y; z-=A.z; };
|
||||
void operator *= (const float s) // ACCUMULATED SCALAR MULTIPLICATION (*=) (bpc 4/24/2000)
|
||||
{x*=s; y*=s; z*=s;}
|
||||
|
||||
Vector3d operator - (void) const // NEGATION (-)
|
||||
{ Vector3d Negated(-x, -y, -z);
|
||||
return(Negated); };
|
||||
|
||||
float operator [] (const int i) const // ALLOWS VECTOR ACCESS AS AN ARRAY.
|
||||
{ return( (i==0)?x:((i==1)?y:z) ); };
|
||||
float & operator [] (const int i)
|
||||
{ return( (i==0)?x:((i==1)?y:z) ); };
|
||||
//
|
||||
|
||||
// accessor methods.
|
||||
float GetX(void) const { return x; };
|
||||
float GetY(void) const { return y; };
|
||||
float GetZ(void) const { return z; };
|
||||
|
||||
void SetX(float t) { x = t; };
|
||||
void SetY(float t) { y = t; };
|
||||
void SetZ(float t) { z = t; };
|
||||
|
||||
void Set(float a,float b,float c)
|
||||
{
|
||||
x = a;
|
||||
y = b;
|
||||
z = c;
|
||||
};
|
||||
|
||||
void Zero(void)
|
||||
{
|
||||
x = y = z = 0;
|
||||
};
|
||||
|
||||
// return -(*this).
|
||||
Vector3d negative(void) const
|
||||
{
|
||||
Vector3d result;
|
||||
result.x = -x;
|
||||
result.y = -y;
|
||||
result.z = -z;
|
||||
return result;
|
||||
}
|
||||
|
||||
float Magnitude(void) const
|
||||
{
|
||||
return (sqrtf(x * x + y * y + z * z));
|
||||
};
|
||||
|
||||
void Lerp(const Vector3d& from,const Vector3d& to,float slerp)
|
||||
{
|
||||
*this = to-from; // delta on all 3 axis
|
||||
*this*=slerp; // times interpolant distance.
|
||||
*this+=from; // plus source
|
||||
};
|
||||
|
||||
float Length(void) const // length of vector.
|
||||
{
|
||||
return float(sqrtf( x*x + y*y + z*z ));
|
||||
};
|
||||
|
||||
float Length2(void) const // squared distance, prior to square root.
|
||||
{
|
||||
float l2 = x*x+y*y+z*z;
|
||||
return l2;
|
||||
};
|
||||
|
||||
inline float Distance(const Vector3d &a) const // distance between two points.
|
||||
{
|
||||
return sqrtf(DistanceSq(a));
|
||||
}
|
||||
|
||||
inline float Distance2d(const Vector3d &a) const // distance between two points.
|
||||
{
|
||||
return sqrtf(DistanceSq2d(a));
|
||||
}
|
||||
|
||||
float DistanceXY(const Vector3d &a) const
|
||||
{
|
||||
float dx = a.x - x;
|
||||
float dy = a.y - y;
|
||||
float dist = dx*dx + dy*dy;
|
||||
return dist;
|
||||
}
|
||||
|
||||
float DistanceSq(const Vector3d &a) const // squared distance.
|
||||
{
|
||||
float dx = a.x - x;
|
||||
float dy = a.y - y;
|
||||
float dz = a.z - z;
|
||||
return dx*dx + dy*dy + dz*dz;
|
||||
};
|
||||
|
||||
float DistanceSq2d(const Vector3d &a) const // squared distance.
|
||||
{
|
||||
float dx = a.x - x;
|
||||
float dy = a.y - y;
|
||||
return dx*dx + dy*dy;
|
||||
};
|
||||
|
||||
float Normalize(void) // normalize to a unit vector, returns distance.
|
||||
{
|
||||
float l = Length(); // get length.
|
||||
if ( l != 0 )
|
||||
{
|
||||
x/=l;
|
||||
y/=l;
|
||||
z/=l;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = y = z = 0;
|
||||
}
|
||||
return l;
|
||||
};
|
||||
|
||||
float Dot(const Vector3d &a) const // computes dot product.
|
||||
{
|
||||
return (x * a.x + y * a.y + z * a.z );
|
||||
};
|
||||
bool IsInStaticRange() const;
|
||||
void Cross(const Vector3d &a,const Vector3d &b) // cross two vectors result in this one.
|
||||
{
|
||||
x = a.y*b.z - a.z*b.y;
|
||||
y = a.z*b.x - a.x*b.z;
|
||||
z = a.x*b.y - a.y*b.x;
|
||||
};
|
||||
|
||||
//private:
|
||||
|
||||
// float x;
|
||||
// float y;
|
||||
// float z;
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector< Vector3d > Vector3dVector;
|
||||
|
||||
inline Vector3d operator * (float s, const Vector3d &v )
|
||||
{ Vector3d Scaled(v.x*s, v.y*s, v.z*s);
|
||||
return(Scaled); };
|
||||
|
||||
|
Reference in New Issue
Block a user