1
0
forked from metin2/client

Solution refactoring and restructuring, removed Boost dependency, removed unused tools

This commit is contained in:
2022-11-21 23:42:01 +02:00
parent 33f19f9ff6
commit 9ef9f39e88
817 changed files with 326 additions and 59698 deletions

View 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>

View 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
View 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
View 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
View 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],&center);
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
View 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
View 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
View 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 &center, 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,&sect);
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,&sect);
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
View 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 &center, float radius);
virtual ~Sphere() {}
void Set(const Vector3d &center, 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 &center, float radius)
: mCenter(center), mRadius(radius), mRadius2(radius*radius) { };

View 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 &center,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 &center, 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,&sect);
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
View 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 &sect, // 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 &center,float radius,SpherePackCallback *callback);
void PointTest2d(const Vector3d &center, 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 &sect, // 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
View 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); };