absence_thelab

changeset 0:1cffe3409164

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 23 Oct 2014 01:46:07 +0300
parents
children 4d5933c261c3
files .hgignore TheLabDemo.sln TheLabDemo.vcproj fmod.dll libs/fmod/fmod.h libs/fmod/fmodvc.lib n3dinit.conf readme.txt resource.h resources.rc src/3deng/3deng.h src/3deng/3dengine.cpp src/3deng/3dengine.h src/3deng/3dengtypes.h src/3deng/3dgeom.cpp src/3deng/3dgeom.h src/3deng/3dscene.cpp src/3deng/3dscene.h src/3deng/3dschunks.h src/3deng/SceneLoader.h src/3deng/camera.cpp src/3deng/camera.h src/3deng/exceptions.cpp src/3deng/exceptions.h src/3deng/lights.cpp src/3deng/lights.h src/3deng/material.cpp src/3deng/material.h src/3deng/motion.cpp src/3deng/motion.h src/3deng/objectgen.cpp src/3deng/objectgen.h src/3deng/objects.cpp src/3deng/objects.h src/3deng/particles.cpp src/3deng/particles.h src/3deng/sceneloader.cpp src/3deng/switches.h src/3deng/textureman.cpp src/3deng/textureman.h src/beginpart.cpp src/beginpart.h src/common/color.cpp src/common/color.h src/common/curves.cpp src/common/curves.h src/common/hashtable.h src/common/linkedlist.h src/common/n3dmath.cpp src/common/n3dmath.h src/common/n3dmath.inl src/common/timing.cpp src/common/timing.h src/common/typedefs.h src/demo.cpp src/demonpart.cpp src/demonpart.h src/demosystem/demosys.cpp src/demosystem/demosys.h src/dungeonpart.cpp src/dungeonpart.h src/greetspart.cpp src/greetspart.h src/hellpart.cpp src/hellpart.h src/nwt/nucwin.cpp src/nwt/nucwin.h src/nwt/startup.h src/nwt/widget.cpp src/nwt/widget.h src/treepart.cpp src/treepart.h src/tunnelpart.cpp src/tunnelpart.h thelab.ico
diffstat 74 files changed, 13203 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/TheLabDemo.sln	Thu Oct 23 01:46:07 2014 +0300
     1.3 @@ -0,0 +1,19 @@
     1.4 +Microsoft Visual Studio Solution File, Format Version 10.00
     1.5 +# Visual Studio 2008
     1.6 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TheLabDemo", "TheLabDemo.vcproj", "{5346BE25-4A84-4401-82EB-88E9E6B9009D}"
     1.7 +EndProject
     1.8 +Global
     1.9 +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    1.10 +		Debug|Win32 = Debug|Win32
    1.11 +		Release|Win32 = Release|Win32
    1.12 +	EndGlobalSection
    1.13 +	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    1.14 +		{5346BE25-4A84-4401-82EB-88E9E6B9009D}.Debug|Win32.ActiveCfg = Debug|Win32
    1.15 +		{5346BE25-4A84-4401-82EB-88E9E6B9009D}.Debug|Win32.Build.0 = Debug|Win32
    1.16 +		{5346BE25-4A84-4401-82EB-88E9E6B9009D}.Release|Win32.ActiveCfg = Release|Win32
    1.17 +		{5346BE25-4A84-4401-82EB-88E9E6B9009D}.Release|Win32.Build.0 = Release|Win32
    1.18 +	EndGlobalSection
    1.19 +	GlobalSection(SolutionProperties) = preSolution
    1.20 +		HideSolutionNode = FALSE
    1.21 +	EndGlobalSection
    1.22 +EndGlobal
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/TheLabDemo.vcproj	Thu Oct 23 01:46:07 2014 +0300
     2.3 @@ -0,0 +1,493 @@
     2.4 +<?xml version="1.0" encoding="Windows-1252"?>
     2.5 +<VisualStudioProject
     2.6 +	ProjectType="Visual C++"
     2.7 +	Version="9.00"
     2.8 +	Name="TheLabDemo"
     2.9 +	ProjectGUID="{5346BE25-4A84-4401-82EB-88E9E6B9009D}"
    2.10 +	Keyword="Win32Proj"
    2.11 +	TargetFrameworkVersion="131072"
    2.12 +	>
    2.13 +	<Platforms>
    2.14 +		<Platform
    2.15 +			Name="Win32"
    2.16 +		/>
    2.17 +	</Platforms>
    2.18 +	<ToolFiles>
    2.19 +	</ToolFiles>
    2.20 +	<Configurations>
    2.21 +		<Configuration
    2.22 +			Name="Debug|Win32"
    2.23 +			OutputDirectory="Debug"
    2.24 +			IntermediateDirectory="Debug"
    2.25 +			ConfigurationType="1"
    2.26 +			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
    2.27 +			CharacterSet="2"
    2.28 +			>
    2.29 +			<Tool
    2.30 +				Name="VCPreBuildEventTool"
    2.31 +			/>
    2.32 +			<Tool
    2.33 +				Name="VCCustomBuildTool"
    2.34 +			/>
    2.35 +			<Tool
    2.36 +				Name="VCXMLDataGeneratorTool"
    2.37 +			/>
    2.38 +			<Tool
    2.39 +				Name="VCWebServiceProxyGeneratorTool"
    2.40 +			/>
    2.41 +			<Tool
    2.42 +				Name="VCMIDLTool"
    2.43 +			/>
    2.44 +			<Tool
    2.45 +				Name="VCCLCompilerTool"
    2.46 +				Optimization="0"
    2.47 +				AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\src&quot;;&quot;$(SolutionDir)\src\3deng&quot;;&quot;$(SolutionDir)\src\common&quot;;&quot;$(SolutionDir)\libs\fmod&quot;"
    2.48 +				PreprocessorDefinitions="NUC3D_VER_DIRECT3D"
    2.49 +				MinimalRebuild="true"
    2.50 +				BasicRuntimeChecks="3"
    2.51 +				RuntimeLibrary="1"
    2.52 +				UsePrecompiledHeader="0"
    2.53 +				WarningLevel="3"
    2.54 +				Detect64BitPortabilityProblems="false"
    2.55 +				DebugInformationFormat="4"
    2.56 +				DisableSpecificWarnings="4996;4244"
    2.57 +			/>
    2.58 +			<Tool
    2.59 +				Name="VCManagedResourceCompilerTool"
    2.60 +			/>
    2.61 +			<Tool
    2.62 +				Name="VCResourceCompilerTool"
    2.63 +			/>
    2.64 +			<Tool
    2.65 +				Name="VCPreLinkEventTool"
    2.66 +			/>
    2.67 +			<Tool
    2.68 +				Name="VCLinkerTool"
    2.69 +				AdditionalDependencies="d3d8.lib d3dx8.lib fmodvc.lib"
    2.70 +				OutputFile="$(OutDir)/TheLabDemo.exe"
    2.71 +				LinkIncremental="2"
    2.72 +				AdditionalLibraryDirectories="$(SolutionDir)\libs\fmod"
    2.73 +				IgnoreDefaultLibraryNames="libci.lib"
    2.74 +				GenerateDebugInformation="true"
    2.75 +				ProgramDatabaseFile="$(OutDir)/TheLabDemo.pdb"
    2.76 +				SubSystem="2"
    2.77 +				RandomizedBaseAddress="1"
    2.78 +				DataExecutionPrevention="0"
    2.79 +				TargetMachine="1"
    2.80 +			/>
    2.81 +			<Tool
    2.82 +				Name="VCALinkTool"
    2.83 +			/>
    2.84 +			<Tool
    2.85 +				Name="VCManifestTool"
    2.86 +			/>
    2.87 +			<Tool
    2.88 +				Name="VCXDCMakeTool"
    2.89 +			/>
    2.90 +			<Tool
    2.91 +				Name="VCBscMakeTool"
    2.92 +			/>
    2.93 +			<Tool
    2.94 +				Name="VCFxCopTool"
    2.95 +			/>
    2.96 +			<Tool
    2.97 +				Name="VCAppVerifierTool"
    2.98 +			/>
    2.99 +			<Tool
   2.100 +				Name="VCPostBuildEventTool"
   2.101 +			/>
   2.102 +		</Configuration>
   2.103 +		<Configuration
   2.104 +			Name="Release|Win32"
   2.105 +			OutputDirectory="Release"
   2.106 +			IntermediateDirectory="Release"
   2.107 +			ConfigurationType="1"
   2.108 +			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
   2.109 +			CharacterSet="2"
   2.110 +			>
   2.111 +			<Tool
   2.112 +				Name="VCPreBuildEventTool"
   2.113 +			/>
   2.114 +			<Tool
   2.115 +				Name="VCCustomBuildTool"
   2.116 +			/>
   2.117 +			<Tool
   2.118 +				Name="VCXMLDataGeneratorTool"
   2.119 +			/>
   2.120 +			<Tool
   2.121 +				Name="VCWebServiceProxyGeneratorTool"
   2.122 +			/>
   2.123 +			<Tool
   2.124 +				Name="VCMIDLTool"
   2.125 +			/>
   2.126 +			<Tool
   2.127 +				Name="VCCLCompilerTool"
   2.128 +				Optimization="2"
   2.129 +				InlineFunctionExpansion="1"
   2.130 +				OmitFramePointers="true"
   2.131 +				AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\src&quot;;&quot;$(SolutionDir)\src\3deng&quot;;&quot;$(SolutionDir)\src\common&quot;;&quot;$(SolutionDir)\libs\fmod&quot;"
   2.132 +				PreprocessorDefinitions="NUC3D_VER_DIRECT3D"
   2.133 +				StringPooling="true"
   2.134 +				RuntimeLibrary="0"
   2.135 +				EnableFunctionLevelLinking="true"
   2.136 +				UsePrecompiledHeader="0"
   2.137 +				WarningLevel="3"
   2.138 +				Detect64BitPortabilityProblems="true"
   2.139 +				DebugInformationFormat="3"
   2.140 +				DisableSpecificWarnings="4996;4244"
   2.141 +			/>
   2.142 +			<Tool
   2.143 +				Name="VCManagedResourceCompilerTool"
   2.144 +			/>
   2.145 +			<Tool
   2.146 +				Name="VCResourceCompilerTool"
   2.147 +			/>
   2.148 +			<Tool
   2.149 +				Name="VCPreLinkEventTool"
   2.150 +			/>
   2.151 +			<Tool
   2.152 +				Name="VCLinkerTool"
   2.153 +				AdditionalDependencies="d3d8.lib d3dx8.lib fmodvc.lib"
   2.154 +				OutputFile="$(OutDir)/TheLabDemo.exe"
   2.155 +				LinkIncremental="1"
   2.156 +				AdditionalLibraryDirectories="$(SolutionDir)\libs\fmod"
   2.157 +				IgnoreDefaultLibraryNames="libci.lib"
   2.158 +				GenerateDebugInformation="true"
   2.159 +				SubSystem="2"
   2.160 +				OptimizeReferences="2"
   2.161 +				EnableCOMDATFolding="2"
   2.162 +				RandomizedBaseAddress="1"
   2.163 +				DataExecutionPrevention="0"
   2.164 +				TargetMachine="1"
   2.165 +			/>
   2.166 +			<Tool
   2.167 +				Name="VCALinkTool"
   2.168 +			/>
   2.169 +			<Tool
   2.170 +				Name="VCManifestTool"
   2.171 +			/>
   2.172 +			<Tool
   2.173 +				Name="VCXDCMakeTool"
   2.174 +			/>
   2.175 +			<Tool
   2.176 +				Name="VCBscMakeTool"
   2.177 +			/>
   2.178 +			<Tool
   2.179 +				Name="VCFxCopTool"
   2.180 +			/>
   2.181 +			<Tool
   2.182 +				Name="VCAppVerifierTool"
   2.183 +			/>
   2.184 +			<Tool
   2.185 +				Name="VCPostBuildEventTool"
   2.186 +			/>
   2.187 +		</Configuration>
   2.188 +	</Configurations>
   2.189 +	<References>
   2.190 +	</References>
   2.191 +	<Files>
   2.192 +		<Filter
   2.193 +			Name="Source Files"
   2.194 +			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;h;hpp"
   2.195 +			>
   2.196 +			<File
   2.197 +				RelativePath=".\src\demo.cpp"
   2.198 +				>
   2.199 +			</File>
   2.200 +			<File
   2.201 +				RelativePath=".\src\common\hashtable.h"
   2.202 +				>
   2.203 +			</File>
   2.204 +			<File
   2.205 +				RelativePath=".\src\common\linkedlist.h"
   2.206 +				>
   2.207 +			</File>
   2.208 +			<File
   2.209 +				RelativePath=".\src\common\timing.cpp"
   2.210 +				>
   2.211 +			</File>
   2.212 +			<File
   2.213 +				RelativePath=".\src\common\timing.h"
   2.214 +				>
   2.215 +			</File>
   2.216 +			<File
   2.217 +				RelativePath=".\src\common\typedefs.h"
   2.218 +				>
   2.219 +			</File>
   2.220 +		</Filter>
   2.221 +		<Filter
   2.222 +			Name="3D Engine"
   2.223 +			>
   2.224 +			<File
   2.225 +				RelativePath=".\src\3deng\3deng.h"
   2.226 +				>
   2.227 +			</File>
   2.228 +			<File
   2.229 +				RelativePath=".\src\3deng\3dengine.cpp"
   2.230 +				>
   2.231 +			</File>
   2.232 +			<File
   2.233 +				RelativePath=".\src\3deng\3dengine.h"
   2.234 +				>
   2.235 +			</File>
   2.236 +			<File
   2.237 +				RelativePath=".\src\3deng\3dengtypes.h"
   2.238 +				>
   2.239 +			</File>
   2.240 +			<File
   2.241 +				RelativePath=".\src\3deng\3dgeom.cpp"
   2.242 +				>
   2.243 +			</File>
   2.244 +			<File
   2.245 +				RelativePath=".\src\3deng\3dgeom.h"
   2.246 +				>
   2.247 +			</File>
   2.248 +			<File
   2.249 +				RelativePath=".\src\3deng\3dscene.cpp"
   2.250 +				>
   2.251 +			</File>
   2.252 +			<File
   2.253 +				RelativePath=".\src\3deng\3dscene.h"
   2.254 +				>
   2.255 +			</File>
   2.256 +			<File
   2.257 +				RelativePath=".\src\3deng\3dschunks.h"
   2.258 +				>
   2.259 +			</File>
   2.260 +			<File
   2.261 +				RelativePath=".\src\3deng\camera.cpp"
   2.262 +				>
   2.263 +			</File>
   2.264 +			<File
   2.265 +				RelativePath=".\src\3deng\camera.h"
   2.266 +				>
   2.267 +			</File>
   2.268 +			<File
   2.269 +				RelativePath=".\src\common\color.cpp"
   2.270 +				>
   2.271 +			</File>
   2.272 +			<File
   2.273 +				RelativePath=".\src\common\color.h"
   2.274 +				>
   2.275 +			</File>
   2.276 +			<File
   2.277 +				RelativePath=".\src\common\curves.cpp"
   2.278 +				>
   2.279 +			</File>
   2.280 +			<File
   2.281 +				RelativePath=".\src\common\curves.h"
   2.282 +				>
   2.283 +			</File>
   2.284 +			<File
   2.285 +				RelativePath=".\src\3deng\exceptions.cpp"
   2.286 +				>
   2.287 +			</File>
   2.288 +			<File
   2.289 +				RelativePath=".\src\3deng\exceptions.h"
   2.290 +				>
   2.291 +			</File>
   2.292 +			<File
   2.293 +				RelativePath=".\src\3deng\lights.cpp"
   2.294 +				>
   2.295 +			</File>
   2.296 +			<File
   2.297 +				RelativePath=".\src\3deng\lights.h"
   2.298 +				>
   2.299 +			</File>
   2.300 +			<File
   2.301 +				RelativePath=".\src\3deng\material.cpp"
   2.302 +				>
   2.303 +			</File>
   2.304 +			<File
   2.305 +				RelativePath=".\src\3deng\material.h"
   2.306 +				>
   2.307 +			</File>
   2.308 +			<File
   2.309 +				RelativePath=".\src\3deng\motion.cpp"
   2.310 +				>
   2.311 +			</File>
   2.312 +			<File
   2.313 +				RelativePath=".\src\3deng\motion.h"
   2.314 +				>
   2.315 +			</File>
   2.316 +			<File
   2.317 +				RelativePath=".\src\common\n3dmath.cpp"
   2.318 +				>
   2.319 +			</File>
   2.320 +			<File
   2.321 +				RelativePath=".\src\common\n3dmath.h"
   2.322 +				>
   2.323 +			</File>
   2.324 +			<File
   2.325 +				RelativePath=".\src\common\n3dmath.inl"
   2.326 +				>
   2.327 +			</File>
   2.328 +			<File
   2.329 +				RelativePath=".\src\3deng\objectgen.cpp"
   2.330 +				>
   2.331 +			</File>
   2.332 +			<File
   2.333 +				RelativePath=".\src\3deng\objectgen.h"
   2.334 +				>
   2.335 +			</File>
   2.336 +			<File
   2.337 +				RelativePath=".\src\3deng\objects.cpp"
   2.338 +				>
   2.339 +			</File>
   2.340 +			<File
   2.341 +				RelativePath=".\src\3deng\objects.h"
   2.342 +				>
   2.343 +			</File>
   2.344 +			<File
   2.345 +				RelativePath=".\src\3deng\Particles.cpp"
   2.346 +				>
   2.347 +			</File>
   2.348 +			<File
   2.349 +				RelativePath=".\src\3deng\Particles.h"
   2.350 +				>
   2.351 +			</File>
   2.352 +			<File
   2.353 +				RelativePath=".\src\3deng\SceneLoader.cpp"
   2.354 +				>
   2.355 +			</File>
   2.356 +			<File
   2.357 +				RelativePath=".\src\3deng\SceneLoader.h"
   2.358 +				>
   2.359 +			</File>
   2.360 +			<File
   2.361 +				RelativePath=".\src\3deng\switches.h"
   2.362 +				>
   2.363 +			</File>
   2.364 +			<File
   2.365 +				RelativePath=".\src\3deng\textureman.cpp"
   2.366 +				>
   2.367 +			</File>
   2.368 +			<File
   2.369 +				RelativePath=".\src\3deng\textureman.h"
   2.370 +				>
   2.371 +			</File>
   2.372 +		</Filter>
   2.373 +		<Filter
   2.374 +			Name="nwt"
   2.375 +			>
   2.376 +			<File
   2.377 +				RelativePath=".\src\nwt\nucwin.cpp"
   2.378 +				>
   2.379 +			</File>
   2.380 +			<File
   2.381 +				RelativePath=".\src\nwt\nucwin.h"
   2.382 +				>
   2.383 +			</File>
   2.384 +			<File
   2.385 +				RelativePath=".\src\nwt\startup.h"
   2.386 +				>
   2.387 +			</File>
   2.388 +			<File
   2.389 +				RelativePath=".\src\nwt\widget.cpp"
   2.390 +				>
   2.391 +			</File>
   2.392 +			<File
   2.393 +				RelativePath=".\src\nwt\widget.h"
   2.394 +				>
   2.395 +			</File>
   2.396 +		</Filter>
   2.397 +		<Filter
   2.398 +			Name="demosystem"
   2.399 +			>
   2.400 +			<File
   2.401 +				RelativePath=".\src\demosystem\demosys.cpp"
   2.402 +				>
   2.403 +			</File>
   2.404 +			<File
   2.405 +				RelativePath=".\src\demosystem\demosys.h"
   2.406 +				>
   2.407 +			</File>
   2.408 +		</Filter>
   2.409 +		<Filter
   2.410 +			Name="Resources"
   2.411 +			>
   2.412 +			<File
   2.413 +				RelativePath=".\resource.h"
   2.414 +				>
   2.415 +			</File>
   2.416 +			<File
   2.417 +				RelativePath="resources.rc"
   2.418 +				>
   2.419 +			</File>
   2.420 +			<File
   2.421 +				RelativePath="thelab.ico"
   2.422 +				>
   2.423 +			</File>
   2.424 +		</Filter>
   2.425 +		<Filter
   2.426 +			Name="DemoParts"
   2.427 +			>
   2.428 +			<File
   2.429 +				RelativePath=".\src\beginpart.cpp"
   2.430 +				>
   2.431 +			</File>
   2.432 +			<File
   2.433 +				RelativePath=".\src\beginpart.h"
   2.434 +				>
   2.435 +			</File>
   2.436 +			<File
   2.437 +				RelativePath=".\src\demonpart.cpp"
   2.438 +				>
   2.439 +			</File>
   2.440 +			<File
   2.441 +				RelativePath=".\src\demonpart.h"
   2.442 +				>
   2.443 +			</File>
   2.444 +			<File
   2.445 +				RelativePath=".\src\dungeonpart.cpp"
   2.446 +				>
   2.447 +			</File>
   2.448 +			<File
   2.449 +				RelativePath=".\src\dungeonpart.h"
   2.450 +				>
   2.451 +			</File>
   2.452 +			<File
   2.453 +				RelativePath=".\src\greetspart.cpp"
   2.454 +				>
   2.455 +			</File>
   2.456 +			<File
   2.457 +				RelativePath=".\src\greetspart.h"
   2.458 +				>
   2.459 +			</File>
   2.460 +			<File
   2.461 +				RelativePath=".\src\hellpart.cpp"
   2.462 +				>
   2.463 +			</File>
   2.464 +			<File
   2.465 +				RelativePath=".\src\hellpart.h"
   2.466 +				>
   2.467 +			</File>
   2.468 +			<File
   2.469 +				RelativePath=".\src\treepart.cpp"
   2.470 +				>
   2.471 +			</File>
   2.472 +			<File
   2.473 +				RelativePath=".\src\treepart.h"
   2.474 +				>
   2.475 +			</File>
   2.476 +			<File
   2.477 +				RelativePath=".\src\tunnelpart.cpp"
   2.478 +				>
   2.479 +			</File>
   2.480 +			<File
   2.481 +				RelativePath=".\src\tunnelpart.h"
   2.482 +				>
   2.483 +			</File>
   2.484 +		</Filter>
   2.485 +		<File
   2.486 +			RelativePath=".\libs\fmod\fmod.h"
   2.487 +			>
   2.488 +		</File>
   2.489 +		<File
   2.490 +			RelativePath="n3dinit.conf"
   2.491 +			>
   2.492 +		</File>
   2.493 +	</Files>
   2.494 +	<Globals>
   2.495 +	</Globals>
   2.496 +</VisualStudioProject>
     3.1 Binary file fmod.dll has changed
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/libs/fmod/fmod.h	Thu Oct 23 01:46:07 2014 +0300
     4.3 @@ -0,0 +1,802 @@
     4.4 +//==========================================================================================
     4.5 +// FMOD Main header file. Copyright (c), FireLight Multimedia 1999-2000.
     4.6 +//==========================================================================================
     4.7 +
     4.8 +#ifndef _FMOD_H_
     4.9 +#define _FMOD_H_
    4.10 +
    4.11 +//===============================================================================================
    4.12 +// DEFINITIONS
    4.13 +//===============================================================================================
    4.14 +
    4.15 +#if defined(__GNUC__) && defined(WIN32)
    4.16 +       #define _cdecl
    4.17 +#endif /* defined(__GNUC__) && defined(WIN32) */
    4.18 +
    4.19 +#if defined(PLATFORM_LINUX)
    4.20 +       #define _cdecl 
    4.21 +       #define _stdcall
    4.22 +       #define __cdecl 
    4.23 +       #define __stdcall
    4.24 +       #define __declspec(x)
    4.25 +       #define __PS __attribute__((packed)) /* gcc packed */
    4.26 +#else 
    4.27 +       #define __PS /*dummy*/
    4.28 +#endif 
    4.29 +
    4.30 +#define F_API _stdcall
    4.31 +
    4.32 +#ifdef DLL_EXPORTS
    4.33 +	#define DLL_API __declspec(dllexport)
    4.34 +#else
    4.35 +	#ifdef __LCC__
    4.36 +		#define DLL_API F_API
    4.37 +	#else
    4.38 +		#define DLL_API
    4.39 +	#endif // __LCC__
    4.40 +#endif //DLL_EXPORTS
    4.41 +
    4.42 +
    4.43 +#define FMOD_VERSION	3.32f
    4.44 +
    4.45 +
    4.46 +// fmod defined types
    4.47 +typedef struct FSOUND_MATERIAL  FSOUND_MATERIAL;
    4.48 +typedef struct FSOUND_GEOMLIST  FSOUND_GEOMLIST;
    4.49 +typedef struct FSOUND_SAMPLE	FSOUND_SAMPLE;
    4.50 +typedef struct FSOUND_STREAM	FSOUND_STREAM;
    4.51 +typedef struct FSOUND_DSPUNIT	FSOUND_DSPUNIT;
    4.52 +typedef struct FMUSIC_MODULE	FMUSIC_MODULE;
    4.53 +
    4.54 +// callback types
    4.55 +typedef signed char (_cdecl *FSOUND_STREAMCALLBACK)	(FSOUND_STREAM *stream, void *buff, int len, int param);
    4.56 +typedef void *		(_cdecl *FSOUND_DSPCALLBACK)	(void *originalbuffer, void *newbuffer, int length, int param);
    4.57 +typedef void		(_cdecl *FMUSIC_CALLBACK)		(FMUSIC_MODULE *mod, unsigned char param);
    4.58 +
    4.59 +
    4.60 +/*
    4.61 +[ENUM]
    4.62 +[
    4.63 +	[DESCRIPTION]	
    4.64 +	On failure of commands in FMOD, use FSOUND_GetError to attain what happened.
    4.65 +	
    4.66 +	[SEE_ALSO]		
    4.67 +	FSOUND_GetError
    4.68 +]
    4.69 +*/
    4.70 +enum FMOD_ERRORS 
    4.71 +{
    4.72 +	FMOD_ERR_NONE,			   // No errors
    4.73 +	FMOD_ERR_BUSY,             // Cannot call this command after FSOUND_Init.  Call FSOUND_Close first.
    4.74 +	FMOD_ERR_UNINITIALIZED,	   // This command failed because FSOUND_Init or FSOUND_SetOutput was not called
    4.75 +	FMOD_ERR_INIT,			   // Error initializing output device.
    4.76 +	FMOD_ERR_ALLOCATED,		   // Error initializing output device, but more specifically, the output device is already in use and cannot be reused.
    4.77 +	FMOD_ERR_PLAY,			   // Playing the sound failed.
    4.78 +	FMOD_ERR_OUTPUT_FORMAT,	   // Soundcard does not support the features needed for this soundsystem (16bit stereo output)
    4.79 +	FMOD_ERR_COOPERATIVELEVEL, // Error setting cooperative level for hardware.
    4.80 +	FMOD_ERR_CREATEBUFFER,	   // Error creating hardware sound buffer.
    4.81 +	FMOD_ERR_FILE_NOTFOUND,	   // File not found
    4.82 +	FMOD_ERR_FILE_FORMAT,	   // Unknown file format
    4.83 +	FMOD_ERR_FILE_BAD,		   // Error loading file
    4.84 +	FMOD_ERR_MEMORY,           // Not enough memory 
    4.85 +	FMOD_ERR_VERSION,		   // The version number of this file format is not supported
    4.86 +	FMOD_ERR_INVALID_PARAM,	   // An invalid parameter was passed to this function
    4.87 +	FMOD_ERR_NO_EAX,		   // Tried to use an EAX command on a non EAX enabled channel or output.
    4.88 +	FMOD_ERR_NO_EAX2,		   // Tried to use an advanced EAX2 command on a non EAX2 enabled channel or output.
    4.89 +	FMOD_ERR_CHANNEL_ALLOC,	   // Failed to allocate a new channel
    4.90 +	FMOD_ERR_RECORD,		   // Recording is not supported on this machine
    4.91 +	FMOD_ERR_MEDIAPLAYER,	   // Windows Media Player not installed so cant play wma or use internet streaming.
    4.92 +};
    4.93 +
    4.94 +
    4.95 +/*
    4.96 +[ENUM]
    4.97 +[
    4.98 +	[DESCRIPTION]	
    4.99 +	These output types are used with FSOUND_SetOutput, to choose which output driver to use.
   4.100 +	
   4.101 +	FSOUND_OUTPUT_A3D will cause FSOUND_Init to FAIL if you have not got a vortex 
   4.102 +	based A3D card.  The suggestion for this is to immediately try and reinitialize FMOD with
   4.103 +	FSOUND_OUTPUT_DSOUND, and if this fails, try initializing FMOD with	FSOUND_OUTPUT_WAVEOUT.
   4.104 +	
   4.105 +	FSOUND_OUTPUT_DSOUND will not support hardware 3d acceleration if the sound card driver 
   4.106 +	does not support DirectX 6 Voice Manager Extensions.
   4.107 +
   4.108 +	[SEE_ALSO]		
   4.109 +	FSOUND_SetOutput
   4.110 +	FSOUND_GetOutput
   4.111 +]
   4.112 +*/
   4.113 +enum FSOUND_OUTPUTTYPES
   4.114 +{
   4.115 +	FSOUND_OUTPUT_NOSOUND,    // NoSound driver, all calls to this succeed but do nothing.
   4.116 +	FSOUND_OUTPUT_WINMM,      // Windows Multimedia driver.
   4.117 +	FSOUND_OUTPUT_DSOUND,     // DirectSound driver.  You need this to get EAX or EAX2 support.
   4.118 +	FSOUND_OUTPUT_A3D,        // A3D driver.  You need this to get geometry support.
   4.119 +    FSOUND_OUTPUT_OSS,        // Linux/Unix OSS (Open Sound System) driver, i.e. the kernel sound drivers.
   4.120 +    FSOUND_OUTPUT_ESD,        // Linux/Unix ESD (Enlightment Sound Daemon) driver.
   4.121 +    FSOUND_OUTPUT_ALSA        // Linux Alsa driver.
   4.122 +};
   4.123 +
   4.124 +
   4.125 +/*
   4.126 +[ENUM]
   4.127 +[
   4.128 +	[DESCRIPTION]	
   4.129 +	These mixer types are used with FSOUND_SetMixer, to choose which mixer to use, or to act 
   4.130 +	upon for other reasons using FSOUND_GetMixer.
   4.131 +
   4.132 +	[SEE_ALSO]		
   4.133 +	FSOUND_SetMixer
   4.134 +	FSOUND_GetMixer
   4.135 +]
   4.136 +*/
   4.137 +enum FSOUND_MIXERTYPES
   4.138 +{
   4.139 +	FSOUND_MIXER_AUTODETECT,		// Enables autodetection of the fastest mixer based on your cpu.
   4.140 +	FSOUND_MIXER_BLENDMODE,			// Enables the standard non mmx, blendmode mixer.
   4.141 +	FSOUND_MIXER_MMXP5,				// Enables the mmx, pentium optimized blendmode mixer.
   4.142 +	FSOUND_MIXER_MMXP6,				// Enables the mmx, ppro/p2/p3 optimized mixer.
   4.143 +
   4.144 +	FSOUND_MIXER_QUALITY_AUTODETECT,// Enables autodetection of the fastest quality mixer based on your cpu.
   4.145 +	FSOUND_MIXER_QUALITY_FPU,		// Enables the interpolating/volume ramping FPU mixer. 
   4.146 +	FSOUND_MIXER_QUALITY_MMXP5,		// Enables the interpolating/volume ramping p5 MMX mixer. 
   4.147 +	FSOUND_MIXER_QUALITY_MMXP6,		// Enables the interpolating/volume ramping ppro/p2/p3+ MMX mixer. 
   4.148 +};
   4.149 +
   4.150 +/*
   4.151 +[ENUM]
   4.152 +[
   4.153 +	[DESCRIPTION]	
   4.154 +	These definitions describe the type of song being played.
   4.155 +
   4.156 +	[SEE_ALSO]		
   4.157 +	FMUSIC_GetType	
   4.158 +]
   4.159 +*/
   4.160 +enum FMUSIC_TYPES
   4.161 +{
   4.162 +	FMUSIC_TYPE_NONE,		
   4.163 +	FMUSIC_TYPE_MOD,		// Protracker / Fasttracker
   4.164 +	FMUSIC_TYPE_S3M,		// ScreamTracker 3
   4.165 +	FMUSIC_TYPE_XM,			// FastTracker 2
   4.166 +	FMUSIC_TYPE_IT,			// Impulse Tracker.
   4.167 +	FMUSIC_TYPE_MIDI,		// MIDI file
   4.168 +};
   4.169 +
   4.170 +
   4.171 +/*
   4.172 +[DEFINE_START] 
   4.173 +[
   4.174 + 	[NAME] 
   4.175 +	FSOUND_DSP_PRIORITIES
   4.176 +
   4.177 +	[DESCRIPTION]	
   4.178 +	These default priorities are 
   4.179 +
   4.180 +	[SEE_ALSO]		
   4.181 +	FSOUND_DSP_Create
   4.182 +	FSOUND_DSP_SetPriority
   4.183 +]
   4.184 +*/
   4.185 +#define FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT		0		// DSP CLEAR unit - done first
   4.186 +#define FSOUND_DSP_DEFAULTPRIORITY_SFXUNIT			100		// DSP SFX unit - done second
   4.187 +#define FSOUND_DSP_DEFAULTPRIORITY_MUSICUNIT		200		// DSP MUSIC unit - done third
   4.188 +#define FSOUND_DSP_DEFAULTPRIORITY_USER				300		// User priority, use this as reference
   4.189 +#define FSOUND_DSP_DEFAULTPRIORITY_CLIPANDCOPYUNIT	1000	// DSP CLIP AND COPY unit - last
   4.190 +// [DEFINE_END]
   4.191 +
   4.192 +
   4.193 +/*
   4.194 +[DEFINE_START] 
   4.195 +[
   4.196 + 	[NAME] 
   4.197 +	FSOUND_CAPS
   4.198 +
   4.199 +	[DESCRIPTION]	
   4.200 +	Driver description bitfields.  Use FSOUND_Driver_GetCaps to determine if a driver enumerated
   4.201 +	has the settings you are after.  The enumerated driver depends on the output mode, see
   4.202 +	FSOUND_OUTPUTTYPES
   4.203 +
   4.204 +	[SEE_ALSO]
   4.205 +	FSOUND_GetDriverCaps
   4.206 +	FSOUND_OUTPUTTYPES
   4.207 +]
   4.208 +*/
   4.209 +#define FSOUND_CAPS_HARDWARE				0x1		// This driver supports hardware accelerated 3d sound.
   4.210 +#define FSOUND_CAPS_EAX						0x2		// This driver supports EAX reverb
   4.211 +#define FSOUND_CAPS_GEOMETRY_OCCLUSIONS		0x4		// This driver supports (A3D) geometry occlusions
   4.212 +#define FSOUND_CAPS_GEOMETRY_REFLECTIONS	0x8		// This driver supports (A3D) geometry reflections
   4.213 +#define FSOUND_CAPS_EAX2					0x10	// This driver supports EAX2/A3D3 reverb
   4.214 +// [DEFINE_END]
   4.215 +
   4.216 +
   4.217 +/*
   4.218 +[DEFINE_START] 
   4.219 +[
   4.220 + 	[NAME] 
   4.221 +	FSOUND_MODES
   4.222 +	
   4.223 +	[DESCRIPTION]	
   4.224 +	Sample description bitfields, OR them together for loading and describing samples.
   4.225 +]
   4.226 +*/
   4.227 +#define FSOUND_LOOP_OFF		0x00000001	// For non looping samples.
   4.228 +#define FSOUND_LOOP_NORMAL	0x00000002	// For forward looping samples.
   4.229 +#define FSOUND_LOOP_BIDI	0x00000004	// For bidirectional looping samples.  (no effect if in hardware).
   4.230 +#define FSOUND_8BITS		0x00000008	// For 8 bit samples.
   4.231 +#define FSOUND_16BITS		0x00000010	// For 16 bit samples.
   4.232 +#define FSOUND_MONO			0x00000020	// For mono samples.
   4.233 +#define FSOUND_STEREO		0x00000040	// For stereo samples.
   4.234 +#define FSOUND_UNSIGNED		0x00000080	// For source data containing unsigned samples.
   4.235 +#define FSOUND_SIGNED		0x00000100	// For source data containing signed data.
   4.236 +#define FSOUND_DELTA		0x00000200	// For source data stored as delta values.
   4.237 +#define FSOUND_IT214		0x00000400	// For source data stored using IT214 compression.
   4.238 +#define FSOUND_IT215		0x00000800	// For source data stored using IT215 compression.
   4.239 +#define FSOUND_HW3D			0x00001000	// Attempts to make samples use 3d hardware acceleration. (if the card supports it)
   4.240 +#define FSOUND_2D			0x00002000	// Ignores any 3d processing.  overrides FSOUND_HW3D.  Located in software.
   4.241 +#define FSOUND_STREAMABLE	0x00004000	// For a streamable sound where you feed the data to it.  If you dont supply this sound may come out corrupted.  (only affects a3d output)
   4.242 +#define FSOUND_LOADMEMORY	0x00008000	// 'name' will be interpreted as a pointer to data for streaming and samples.
   4.243 +#define FSOUND_LOADRAW		0x00010000	// For  will ignore file format and treat as raw pcm.
   4.244 +#define FSOUND_MPEGACCURATE	0x00020000	// For FSOUND_Stream_OpenFile - for accurate FSOUND_Stream_GetLengthMs/FSOUND_Stream_SetTime.  WARNING, see FSOUNDStream_OpenFile for inital opening time performance issues.
   4.245 +
   4.246 +// Default sample type.  Loop off, 8bit mono, signed, not hardware accelerated.  
   4.247 +// Some API functions ignore 8bits and mono, as it may be an mpeg/wav/etc which has its format predetermined.
   4.248 +#define FSOUND_NORMAL		(FSOUND_LOOP_OFF | FSOUND_8BITS | FSOUND_MONO)		
   4.249 +// [DEFINE_END]
   4.250 +
   4.251 +
   4.252 +/*
   4.253 +[DEFINE_START] 
   4.254 +[
   4.255 + 	[NAME] 
   4.256 +	FSOUND_CDPLAYMODES
   4.257 +	
   4.258 +	[DESCRIPTION]	
   4.259 +	Playback method for a CD Audio track, using FSOUND_CD_Play
   4.260 +
   4.261 +	[SEE_ALSO]		
   4.262 +	FSOUND_CD_Play
   4.263 +]
   4.264 +*/
   4.265 +#define FSOUND_CD_PLAYCONTINUOUS	0	// Starts from the current track and plays to end of CD.
   4.266 +#define FSOUND_CD_PLAYONCE			1	// Plays the specified track then stops.
   4.267 +#define FSOUND_CD_PLAYLOOPED		2	// Plays the specified track looped, forever until stopped manually.
   4.268 +#define FSOUND_CD_PLAYRANDOM		3	// Plays tracks in random order
   4.269 +// [DEFINE_END]
   4.270 +
   4.271 +
   4.272 +/*
   4.273 +[DEFINE_START] 
   4.274 +[
   4.275 + 	[NAME] 
   4.276 +	FSOUND_CHANNELSAMPLEMODE
   4.277 +	
   4.278 +	[DESCRIPTION]
   4.279 +	Miscellaneous values for FMOD functions.
   4.280 +
   4.281 +	[SEE_ALSO]
   4.282 +	FSOUND_PlaySound
   4.283 +	FSOUND_PlaySound3DAttrib
   4.284 +
   4.285 +	FSOUND_Sample_Alloc
   4.286 +	FSOUND_Sample_Load
   4.287 +	FSOUND_SetPan
   4.288 +]
   4.289 +*/
   4.290 +#define FSOUND_FREE			-1	// value to play on any free channel, or to allocate a sample in a free sample slot.
   4.291 +#define FSOUND_UNMANAGED	-2	// value to allocate a sample that is NOT managed by FSOUND or placed in a sample slot.
   4.292 +#define FSOUND_ALL			-3	// for a channel index , this flag will affect ALL channels available!  Not supported by every function.
   4.293 +#define FSOUND_STEREOPAN	-1	// value for FSOUND_SetPan so that stereo sounds are not played at half volume.  See FSOUND_SetPan for more on this.
   4.294 +// [DEFINE_END]
   4.295 +
   4.296 +
   4.297 +/*
   4.298 +[ENUM]
   4.299 +[
   4.300 +	[DESCRIPTION]	
   4.301 +	These are environment types defined for use with the FSOUND_Reverb API.
   4.302 +
   4.303 +	[SEE_ALSO]		
   4.304 +	FSOUND_Reverb_SetEnvironment
   4.305 +	FSOUND_Reverb_SetEnvironmentAdvanced
   4.306 +]
   4.307 +*/
   4.308 +enum FSOUND_REVERB_ENVIRONMENTS
   4.309 +{
   4.310 +    FSOUND_ENVIRONMENT_GENERIC,
   4.311 +    FSOUND_ENVIRONMENT_PADDEDCELL,
   4.312 +    FSOUND_ENVIRONMENT_ROOM,
   4.313 +    FSOUND_ENVIRONMENT_BATHROOM,
   4.314 +    FSOUND_ENVIRONMENT_LIVINGROOM,
   4.315 +    FSOUND_ENVIRONMENT_STONEROOM,
   4.316 +    FSOUND_ENVIRONMENT_AUDITORIUM,
   4.317 +    FSOUND_ENVIRONMENT_CONCERTHALL,
   4.318 +    FSOUND_ENVIRONMENT_CAVE,
   4.319 +    FSOUND_ENVIRONMENT_ARENA,
   4.320 +    FSOUND_ENVIRONMENT_HANGAR,
   4.321 +    FSOUND_ENVIRONMENT_CARPETEDHALLWAY,
   4.322 +    FSOUND_ENVIRONMENT_HALLWAY,
   4.323 +    FSOUND_ENVIRONMENT_STONECORRIDOR,
   4.324 +    FSOUND_ENVIRONMENT_ALLEY,
   4.325 +    FSOUND_ENVIRONMENT_FOREST,
   4.326 +    FSOUND_ENVIRONMENT_CITY,
   4.327 +    FSOUND_ENVIRONMENT_MOUNTAINS,
   4.328 +    FSOUND_ENVIRONMENT_QUARRY,
   4.329 +    FSOUND_ENVIRONMENT_PLAIN,
   4.330 +    FSOUND_ENVIRONMENT_PARKINGLOT,
   4.331 +    FSOUND_ENVIRONMENT_SEWERPIPE,
   4.332 +    FSOUND_ENVIRONMENT_UNDERWATER,
   4.333 +    FSOUND_ENVIRONMENT_DRUGGED,
   4.334 +    FSOUND_ENVIRONMENT_DIZZY,
   4.335 +    FSOUND_ENVIRONMENT_PSYCHOTIC,
   4.336 +
   4.337 +    FSOUND_ENVIRONMENT_COUNT
   4.338 +};
   4.339 +
   4.340 +/*
   4.341 +[DEFINE_START] 
   4.342 +[
   4.343 + 	[NAME] 
   4.344 +	FSOUND_REVERBMIX_USEDISTANCE
   4.345 +	
   4.346 +	[DESCRIPTION]	
   4.347 +	Used with FSOUND_Reverb_SetMix, this setting allows reverb to attenuate based on distance from the listener.
   4.348 +	Instead of hard coding a value with FSOUND_Reverb_SetMix, this value can be used instead, for a more natural
   4.349 +	reverb dropoff.
   4.350 +
   4.351 +	[SEE_ALSO]
   4.352 +	FSOUND_Reverb_SetMix
   4.353 +]
   4.354 +*/
   4.355 +#define FSOUND_REVERBMIX_USEDISTANCE	-1.0f	// used with FSOUND_Reverb_SetMix to scale reverb by distance
   4.356 +// [DEFINE_END]
   4.357 +
   4.358 +
   4.359 +/*
   4.360 +[DEFINE_START] 
   4.361 +[
   4.362 + 	[NAME] 
   4.363 +	FSOUND_REVERB_IGNOREPARAM
   4.364 +	
   4.365 +	[DESCRIPTION]	
   4.366 +	Used with FSOUND_Reverb_SetEnvironment and FSOUND_Reverb_SetEnvironmentAdvanced, this can
   4.367 +	be placed in the place of a specific parameter for the reverb setting.  It allows you to 
   4.368 +	not set any parameters except the ones you are interested in .. and example would be this.
   4.369 +	FSOUND_Reverb_SetEnvironment(FSOUND_REVERB_IGNOREPARAM,
   4.370 +								 FSOUND_REVERB_IGNOREPARAM,
   4.371 +								 FSOUND_REVERB_IGNOREPARAM,  
   4.372 +								 0.0f);
   4.373 +	This means env, vol and decay are left alone, but 'damp' is set to 0.
   4.374 +
   4.375 +	[SEE_ALSO]
   4.376 +	FSOUND_Reverb_SetEnvironment
   4.377 +	FSOUND_Reverb_SetEnvironmentAdvanced
   4.378 +]
   4.379 +*/
   4.380 +#define FSOUND_REVERB_IGNOREPARAM	-9999999	// used with FSOUND_Reverb_SetEnvironmentAdvanced to ignore certain parameters by choice.
   4.381 +// [DEFINE_END]
   4.382 +
   4.383 +
   4.384 +/*
   4.385 +[DEFINE_START] 
   4.386 +[
   4.387 + 	[NAME] 
   4.388 +	FSOUND_REVERB_PRESETS
   4.389 +	
   4.390 +	[DESCRIPTION]	
   4.391 +	A set of predefined environment PARAMETERS, created by Creative Labs
   4.392 +	These can be placed directly into the FSOUND_Reverb_SetEnvironment call
   4.393 +
   4.394 +	[SEE_ALSO]
   4.395 +	FSOUND_Reverb_SetEnvironment
   4.396 +]
   4.397 +*/
   4.398 +#define FSOUND_PRESET_OFF			  FSOUND_ENVIRONMENT_GENERIC,0.0f,0.0f,0.0f
   4.399 +#define FSOUND_PRESET_GENERIC         FSOUND_ENVIRONMENT_GENERIC,0.5f,1.493f,0.5f
   4.400 +#define FSOUND_PRESET_PADDEDCELL      FSOUND_ENVIRONMENT_PADDEDCELL,0.25f,0.1f,0.0f
   4.401 +#define FSOUND_PRESET_ROOM            FSOUND_ENVIRONMENT_ROOM,0.417f,0.4f,0.666f
   4.402 +#define FSOUND_PRESET_BATHROOM        FSOUND_ENVIRONMENT_BATHROOM,0.653f,1.499f,0.166f
   4.403 +#define FSOUND_PRESET_LIVINGROOM      FSOUND_ENVIRONMENT_LIVINGROOM,0.208f,0.478f,0.0f
   4.404 +#define FSOUND_PRESET_STONEROOM       FSOUND_ENVIRONMENT_STONEROOM,0.5f,2.309f,0.888f
   4.405 +#define FSOUND_PRESET_AUDITORIUM      FSOUND_ENVIRONMENT_AUDITORIUM,0.403f,4.279f,0.5f
   4.406 +#define FSOUND_PRESET_CONCERTHALL     FSOUND_ENVIRONMENT_CONCERTHALL,0.5f,3.961f,0.5f
   4.407 +#define FSOUND_PRESET_CAVE            FSOUND_ENVIRONMENT_CAVE,0.5f,2.886f,1.304f
   4.408 +#define FSOUND_PRESET_ARENA           FSOUND_ENVIRONMENT_ARENA,0.361f,7.284f,0.332f
   4.409 +#define FSOUND_PRESET_HANGAR          FSOUND_ENVIRONMENT_HANGAR,0.5f,10.0f,0.3f
   4.410 +#define FSOUND_PRESET_CARPETEDHALLWAY FSOUND_ENVIRONMENT_CARPETEDHALLWAY,0.153f,0.259f,2.0f
   4.411 +#define FSOUND_PRESET_HALLWAY         FSOUND_ENVIRONMENT_HALLWAY,0.361f,1.493f,0.0f
   4.412 +#define FSOUND_PRESET_STONECORRIDOR   FSOUND_ENVIRONMENT_STONECORRIDOR,0.444f,2.697f,0.638f
   4.413 +#define FSOUND_PRESET_ALLEY           FSOUND_ENVIRONMENT_ALLEY,0.25f,1.752f,0.776f
   4.414 +#define FSOUND_PRESET_FOREST          FSOUND_ENVIRONMENT_FOREST,0.111f,3.145f,0.472f
   4.415 +#define FSOUND_PRESET_CITY            FSOUND_ENVIRONMENT_CITY,0.111f,2.767f,0.224f
   4.416 +#define FSOUND_PRESET_MOUNTAINS       FSOUND_ENVIRONMENT_MOUNTAINS,0.194f,7.841f,0.472f
   4.417 +#define FSOUND_PRESET_QUARRY          FSOUND_ENVIRONMENT_QUARRY,1.0f,1.499f,0.5f
   4.418 +#define FSOUND_PRESET_PLAIN           FSOUND_ENVIRONMENT_PLAIN,0.097f,2.767f,0.224f
   4.419 +#define FSOUND_PRESET_PARKINGLOT      FSOUND_ENVIRONMENT_PARKINGLOT,0.208f,1.652f,1.5f
   4.420 +#define FSOUND_PRESET_SEWERPIPE       FSOUND_ENVIRONMENT_SEWERPIPE,0.652f,2.886f,0.25f
   4.421 +#define FSOUND_PRESET_UNDERWATER      FSOUND_ENVIRONMENT_UNDERWATER,1.0f,1.499f,0.0f
   4.422 +#define FSOUND_PRESET_DRUGGED         FSOUND_ENVIRONMENT_DRUGGED,0.875f, 8.392f,1.388f
   4.423 +#define FSOUND_PRESET_DIZZY           FSOUND_ENVIRONMENT_DIZZY,0.139f,17.234f,0.666f
   4.424 +#define FSOUND_PRESET_PSYCHOTIC       FSOUND_ENVIRONMENT_PSYCHOTIC,0.486f,7.563f,0.806f
   4.425 +// [DEFINE_END]
   4.426 +
   4.427 +
   4.428 +/*
   4.429 +[DEFINE_START] 
   4.430 +[
   4.431 + 	[NAME] 
   4.432 +	FSOUND_GEOMETRY_MODES
   4.433 +	
   4.434 +	[DESCRIPTION]	
   4.435 +	Geometry flags, used as the mode flag in FSOUND_Geometry_AddPolygon
   4.436 +
   4.437 +	[SEE_ALSO]
   4.438 +	FSOUND_Geometry_AddPolygon
   4.439 +]
   4.440 +*/
   4.441 +#define FSOUND_GEOMETRY_NORMAL				0x0		// Default geometry type.  Occluding polygon
   4.442 +#define FSOUND_GEOMETRY_REFLECTIVE			0x01	// This polygon is reflective
   4.443 +#define FSOUND_GEOMETRY_OPENING				0x02	// Overlays a transparency over the previous polygon.  The 'openingfactor' value supplied is copied internally.
   4.444 +#define FSOUND_GEOMETRY_OPENING_REFERENCE	0x04	// Overlays a transparency over the previous polygon.  The 'openingfactor' supplied is pointed to (for access when building a list)
   4.445 +// [DEFINE_END]
   4.446 +
   4.447 +/*
   4.448 +[DEFINE_START] 
   4.449 +[
   4.450 + 	[NAME] 
   4.451 +	FSOUND_INIT_FLAGS
   4.452 +	
   4.453 +	[DESCRIPTION]	
   4.454 +	Initialization flags.  Use them with FSOUND_Init in the flags parameter to change various behaviour.
   4.455 +
   4.456 +	[SEE_ALSO]
   4.457 +	FSOUND_Init
   4.458 +]
   4.459 +*/
   4.460 +#define FSOUND_INIT_USEDEFAULTMIDISYNTH		0x01	// Causes MIDI playback to force software decoding.
   4.461 +#define FSOUND_INIT_GLOBALFOCUS				0x02	// For DirectSound output - sound is not muted when window is out of focus.
   4.462 +// [DEFINE_END]
   4.463 +
   4.464 +
   4.465 +
   4.466 +
   4.467 +//===============================================================================================
   4.468 +// FUNCTION PROTOTYPES
   4.469 +//===============================================================================================
   4.470 +
   4.471 +#ifdef __cplusplus
   4.472 +extern "C" {
   4.473 +#endif
   4.474 +
   4.475 +// ==================================
   4.476 +// Initialization / Global functions.
   4.477 +// ==================================
   4.478 +
   4.479 +// *Pre* FSOUND_Init functions. These can't be called after FSOUND_Init is 
   4.480 +// called (they will fail). They set up FMOD system functionality. 
   4.481 +DLL_API signed char		F_API FSOUND_SetOutput(int outputtype);
   4.482 +DLL_API signed char		F_API FSOUND_SetDriver(int driver);
   4.483 +DLL_API signed char		F_API FSOUND_SetMixer(int mixer);
   4.484 +DLL_API signed char		F_API FSOUND_SetBufferSize(int len_ms);
   4.485 +DLL_API signed char		F_API FSOUND_SetHWND(void *hwnd);
   4.486 +DLL_API	signed char		F_API FSOUND_SetMinHardwareChannels(int min);
   4.487 +DLL_API	signed char		F_API FSOUND_SetMaxHardwareChannels(int max);
   4.488 +
   4.489 +// Main initialization / closedown functions.
   4.490 +// Note : Use FSOUND_INIT_USEDEFAULTMIDISYNTH with FSOUND_Init for software override with MIDI playback.
   4.491 +//      : Use FSOUND_INIT_GLOBALFOCUS with FSOUND_Init to make sound audible no matter which window is in focus.
   4.492 +DLL_API signed char		F_API FSOUND_Init(int mixrate, int maxsoftwarechannels, unsigned int flags);
   4.493 +DLL_API void			F_API FSOUND_Close();
   4.494 +
   4.495 +// Runtime
   4.496 +DLL_API void			F_API FSOUND_SetSFXMasterVolume(int volume);
   4.497 +DLL_API void			F_API FSOUND_SetPanSeperation(float pansep);
   4.498 +
   4.499 +// System information.
   4.500 +DLL_API int				F_API FSOUND_GetError();
   4.501 +DLL_API float			F_API FSOUND_GetVersion();
   4.502 +DLL_API int				F_API FSOUND_GetOutput();
   4.503 +DLL_API int				F_API FSOUND_GetDriver();
   4.504 +DLL_API int				F_API FSOUND_GetMixer();
   4.505 +DLL_API int				F_API FSOUND_GetNumDrivers();
   4.506 +DLL_API signed char *	F_API FSOUND_GetDriverName(int id);
   4.507 +DLL_API signed char 	F_API FSOUND_GetDriverCaps(int id, unsigned int *caps);
   4.508 +DLL_API int				F_API FSOUND_GetOutputRate();
   4.509 +DLL_API int				F_API FSOUND_GetMaxChannels();
   4.510 +DLL_API int				F_API FSOUND_GetMaxSamples();
   4.511 +DLL_API int				F_API FSOUND_GetSFXMasterVolume();
   4.512 +DLL_API int				F_API FSOUND_GetNumHardwareChannels();
   4.513 +DLL_API int				F_API FSOUND_GetChannelsPlaying();
   4.514 +DLL_API float			F_API FSOUND_GetCPUUsage();
   4.515 +
   4.516 +// ===================================
   4.517 +// Sample management / load functions.
   4.518 +// ===================================
   4.519 +
   4.520 +// Note : Use FSOUND_LOADMEMORY   flag with FSOUND_Sample_Load to load from memory.
   4.521 +//        Use FSOUND_LOADRAW      flag with FSOUND_Sample_Load to treat as as raw pcm data.
   4.522 +
   4.523 +// Sample creation and management functions
   4.524 +DLL_API FSOUND_SAMPLE *	F_API FSOUND_Sample_Load(int index, const char *name, unsigned int mode, int memlength);
   4.525 +DLL_API FSOUND_SAMPLE *	F_API FSOUND_Sample_Alloc(int index, int length, unsigned int mode, int deffreq, int defvol, int defpan, int defpri);
   4.526 +DLL_API void			F_API FSOUND_Sample_Free(FSOUND_SAMPLE *sptr);
   4.527 +DLL_API signed char		F_API FSOUND_Sample_Upload(FSOUND_SAMPLE *sptr, void *srcdata, unsigned int mode);
   4.528 +DLL_API signed char		F_API FSOUND_Sample_Lock(FSOUND_SAMPLE *sptr, int offset, int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
   4.529 +DLL_API signed char		F_API FSOUND_Sample_Unlock(FSOUND_SAMPLE *sptr, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
   4.530 +
   4.531 +// Sample control functions
   4.532 +DLL_API signed char		F_API FSOUND_Sample_SetLoopMode(FSOUND_SAMPLE *sptr, unsigned int loopmode);
   4.533 +DLL_API signed char		F_API FSOUND_Sample_SetLoopPoints(FSOUND_SAMPLE *sptr, int loopstart, int loopend);
   4.534 +DLL_API signed char		F_API FSOUND_Sample_SetDefaults(FSOUND_SAMPLE *sptr, int deffreq, int defvol, int defpan, int defpri);
   4.535 +DLL_API signed char		F_API FSOUND_Sample_SetMinMaxDistance(FSOUND_SAMPLE *sptr, float min, float max);
   4.536 +
   4.537 +// Sample information 
   4.538 +DLL_API FSOUND_SAMPLE * F_API FSOUND_Sample_Get(int sampno);
   4.539 +DLL_API char *			F_API FSOUND_Sample_GetName(FSOUND_SAMPLE *sptr);
   4.540 +DLL_API unsigned int	F_API FSOUND_Sample_GetLength(FSOUND_SAMPLE *sptr);
   4.541 +DLL_API signed char		F_API FSOUND_Sample_GetLoopPoints(FSOUND_SAMPLE *sptr, int *loopstart, int *loopend);
   4.542 +DLL_API signed char		F_API FSOUND_Sample_GetDefaults(FSOUND_SAMPLE *sptr, int *deffreq, int *defvol, int *defpan, int *defpri);
   4.543 +DLL_API unsigned int	F_API FSOUND_Sample_GetMode(FSOUND_SAMPLE *sptr);
   4.544 +  
   4.545 +// ============================
   4.546 +// Channel control functions.
   4.547 +// ============================
   4.548 +
   4.549 +// Playing and stopping sounds.  
   4.550 +DLL_API int				F_API FSOUND_PlaySound(int channel, FSOUND_SAMPLE *sptr);
   4.551 +DLL_API int				F_API FSOUND_PlaySound3DAttrib(int channel, FSOUND_SAMPLE *sptr, int freq, int vol, int pan, float *pos, float *vel);
   4.552 +DLL_API signed char		F_API FSOUND_StopSound(int channel);
   4.553 +
   4.554 +// Functions to control playback of a channel.
   4.555 +DLL_API signed char		F_API FSOUND_SetFrequency(int channel, int freq);
   4.556 +DLL_API signed char		F_API FSOUND_SetVolume(int channel, int vol);
   4.557 +DLL_API signed char 	F_API FSOUND_SetVolumeAbsolute(int channel, int vol);
   4.558 +DLL_API signed char		F_API FSOUND_SetPan(int channel, int pan);
   4.559 +DLL_API signed char		F_API FSOUND_SetSurround(int channel, signed char surround);
   4.560 +DLL_API signed char		F_API FSOUND_SetMute(int channel, signed char mute);
   4.561 +DLL_API signed char		F_API FSOUND_SetPriority(int channel, int priority);
   4.562 +DLL_API signed char		F_API FSOUND_SetReserved(int channel, signed char reserved);
   4.563 +DLL_API signed char		F_API FSOUND_SetPaused(int channel, signed char paused);
   4.564 +DLL_API signed char		F_API FSOUND_SetLoopMode(int channel, unsigned int loopmode);
   4.565 +
   4.566 +// Channel information
   4.567 +DLL_API signed char		F_API FSOUND_IsPlaying(int channel);
   4.568 +DLL_API int				F_API FSOUND_GetFrequency(int channel);
   4.569 +DLL_API int				F_API FSOUND_GetVolume(int channel);
   4.570 +DLL_API int				F_API FSOUND_GetPan(int channel);
   4.571 +DLL_API signed char		F_API FSOUND_GetSurround(int channel);
   4.572 +DLL_API signed char		F_API FSOUND_GetMute(int channel);
   4.573 +DLL_API int				F_API FSOUND_GetPriority(int channel);
   4.574 +DLL_API signed char		F_API FSOUND_GetReserved(int channel);
   4.575 +DLL_API signed char		F_API FSOUND_GetPaused(int channel);
   4.576 +DLL_API unsigned int	F_API FSOUND_GetCurrentPosition(int channel);
   4.577 +DLL_API FSOUND_SAMPLE *	F_API FSOUND_GetCurrentSample(int channel);
   4.578 +DLL_API float			F_API FSOUND_GetCurrentVU(int channel);
   4.579 + 
   4.580 +// ===================
   4.581 +// 3D sound functions.
   4.582 +// ===================
   4.583 +// see also FSOUND_PlaySound3DAttrib (above)
   4.584 +// see also FSOUND_Sample_SetMinMaxDistance (above)
   4.585 +DLL_API void			F_API FSOUND_3D_Update();
   4.586 +DLL_API signed char		F_API FSOUND_3D_SetAttributes(int channel, float *pos, float *vel);
   4.587 +DLL_API signed char		F_API FSOUND_3D_GetAttributes(int channel, float *pos, float *vel);
   4.588 +DLL_API void			F_API FSOUND_3D_Listener_SetAttributes(float *pos, float *vel, float fx, float fy, float fz, float tx, float ty, float tz);
   4.589 +DLL_API void			F_API FSOUND_3D_Listener_GetAttributes(float *pos, float *vel, float *fx, float *fy, float *fz, float *tx, float *ty, float *tz);
   4.590 +DLL_API void			F_API FSOUND_3D_Listener_SetDopplerFactor(float scale);
   4.591 +DLL_API void			F_API FSOUND_3D_Listener_SetDistanceFactor(float scale);
   4.592 +DLL_API void			F_API FSOUND_3D_Listener_SetRolloffFactor(float scale);
   4.593 + 
   4.594 +// =========================
   4.595 +// File Streaming functions.
   4.596 +// =========================
   4.597 +
   4.598 +// Note : Use FSOUND_LOADMEMORY   flag with FSOUND_Stream_OpenFile to stream from memory.
   4.599 +//        Use FSOUND_LOADRAW      flag with FSOUND_Stream_OpenFile to treat stream as raw pcm data.
   4.600 +//        Use FSOUND_MPEGACCURATE flag with FSOUND_Stream_OpenFile to open mpegs in 'accurate mode' for seeking etc.
   4.601 +
   4.602 +DLL_API FSOUND_STREAM *	F_API FSOUND_Stream_OpenFile(const char *filename, unsigned int mode, int memlength);
   4.603 +DLL_API FSOUND_STREAM *	F_API FSOUND_Stream_Create(FSOUND_STREAMCALLBACK callback, int length, unsigned int mode, int samplerate, int userdata);
   4.604 +DLL_API int 			F_API FSOUND_Stream_Play(int channel, FSOUND_STREAM *stream);
   4.605 +DLL_API int				F_API FSOUND_Stream_Play3DAttrib(int channel, FSOUND_STREAM *stream, int freq, int vol, int pan, float *pos, float *vel);
   4.606 +DLL_API signed char		F_API FSOUND_Stream_Stop(FSOUND_STREAM *stream);
   4.607 +DLL_API signed char		F_API FSOUND_Stream_Close(FSOUND_STREAM *stream);
   4.608 +DLL_API signed char		F_API FSOUND_Stream_SetEndCallback(FSOUND_STREAM *stream, FSOUND_STREAMCALLBACK callback, int userdata);
   4.609 +DLL_API signed char		F_API FSOUND_Stream_SetSynchCallback(FSOUND_STREAM *stream, FSOUND_STREAMCALLBACK callback, int userdata);
   4.610 +DLL_API FSOUND_SAMPLE * F_API FSOUND_Stream_GetSample(FSOUND_STREAM *stream);
   4.611 +DLL_API FSOUND_DSPUNIT *F_API FSOUND_Stream_CreateDSP(FSOUND_STREAM *stream, FSOUND_DSPCALLBACK callback, int priority, int param);
   4.612 +
   4.613 +DLL_API signed char		F_API FSOUND_Stream_SetPaused(FSOUND_STREAM *stream, signed char paused);
   4.614 +DLL_API signed char		F_API FSOUND_Stream_GetPaused(FSOUND_STREAM *stream);
   4.615 +DLL_API signed char		F_API FSOUND_Stream_SetPosition(FSOUND_STREAM *stream, int position);
   4.616 +DLL_API int				F_API FSOUND_Stream_GetPosition(FSOUND_STREAM *stream);
   4.617 +DLL_API signed char		F_API FSOUND_Stream_SetTime(FSOUND_STREAM *stream, int ms);
   4.618 +DLL_API int				F_API FSOUND_Stream_GetTime(FSOUND_STREAM *stream);
   4.619 +DLL_API int				F_API FSOUND_Stream_GetLength(FSOUND_STREAM *stream);
   4.620 +DLL_API int				F_API FSOUND_Stream_GetLengthMs(FSOUND_STREAM *stream);
   4.621 +
   4.622 +// ===================
   4.623 +// CD audio functions.
   4.624 +// ===================
   4.625 +
   4.626 +DLL_API signed char		F_API FSOUND_CD_Play(int track);
   4.627 +DLL_API void			F_API FSOUND_CD_SetPlayMode(signed char mode);
   4.628 +DLL_API signed char		F_API FSOUND_CD_Stop();
   4.629 +DLL_API signed char		F_API FSOUND_CD_SetPaused(signed char paused);
   4.630 +DLL_API	signed char		F_API FSOUND_CD_SetVolume(int volume);
   4.631 +DLL_API signed char		F_API FSOUND_CD_Eject();
   4.632 +
   4.633 +DLL_API signed char		F_API FSOUND_CD_GetPaused();
   4.634 +DLL_API int				F_API FSOUND_CD_GetTrack();
   4.635 +DLL_API int				F_API FSOUND_CD_GetNumTracks();
   4.636 +DLL_API	int				F_API FSOUND_CD_GetVolume();
   4.637 +DLL_API int				F_API FSOUND_CD_GetTrackLength(int track); 
   4.638 +DLL_API int				F_API FSOUND_CD_GetTrackTime();
   4.639 +
   4.640 +
   4.641 +// ==============
   4.642 +// DSP functions.
   4.643 +// ==============
   4.644 +
   4.645 +// DSP Unit control and information functions.
   4.646 +DLL_API FSOUND_DSPUNIT *F_API FSOUND_DSP_Create(FSOUND_DSPCALLBACK callback, int priority, int param);
   4.647 +DLL_API void			F_API FSOUND_DSP_Free(FSOUND_DSPUNIT *unit);
   4.648 +DLL_API void			F_API FSOUND_DSP_SetPriority(FSOUND_DSPUNIT *unit, int priority);
   4.649 +DLL_API int				F_API FSOUND_DSP_GetPriority(FSOUND_DSPUNIT *unit);
   4.650 +DLL_API void			F_API FSOUND_DSP_SetActive(FSOUND_DSPUNIT *unit, signed char active);
   4.651 +DLL_API signed char		F_API FSOUND_DSP_GetActive(FSOUND_DSPUNIT *unit);
   4.652 +
   4.653 +// Functions to get hold of FSOUND 'system DSP unit' handles.
   4.654 +DLL_API FSOUND_DSPUNIT *F_API FSOUND_DSP_GetClearUnit();
   4.655 +DLL_API FSOUND_DSPUNIT *F_API FSOUND_DSP_GetSFXUnit();
   4.656 +DLL_API FSOUND_DSPUNIT *F_API FSOUND_DSP_GetMusicUnit();
   4.657 +DLL_API FSOUND_DSPUNIT *F_API FSOUND_DSP_GetClipAndCopyUnit();
   4.658 +
   4.659 +// misc DSP functions
   4.660 +DLL_API signed char		F_API FSOUND_DSP_MixBuffers(void *destbuffer, void *srcbuffer, int len, int freq, int vol, int pan, unsigned int mode);
   4.661 +DLL_API void			F_API FSOUND_DSP_ClearMixBuffer();
   4.662 +DLL_API int				F_API FSOUND_DSP_GetBufferLength();
   4.663 +
   4.664 +// =============================================
   4.665 +// Geometry functions.  (NOT SUPPORTED IN LINUX)
   4.666 +// =============================================
   4.667 +
   4.668 +// scene/polygon functions
   4.669 +DLL_API signed char		F_API FSOUND_Geometry_AddPolygon(float *p1, float *p2, float *p3, float *p4, float *normal, unsigned int mode, float *openingfactor);
   4.670 +DLL_API int				F_API FSOUND_Geometry_AddList(FSOUND_GEOMLIST *geomlist);
   4.671 +
   4.672 +// polygon list functions
   4.673 +DLL_API FSOUND_GEOMLIST * F_API FSOUND_Geometry_List_Create(signed char boundingvolume);
   4.674 +DLL_API signed char		F_API FSOUND_Geometry_List_Free(FSOUND_GEOMLIST *geomlist);
   4.675 +DLL_API signed char		F_API FSOUND_Geometry_List_Begin(FSOUND_GEOMLIST *geomlist);
   4.676 +DLL_API signed char		F_API FSOUND_Geometry_List_End(FSOUND_GEOMLIST *geomlist);
   4.677 +
   4.678 +// material functions
   4.679 +DLL_API FSOUND_MATERIAL *	F_API FSOUND_Geometry_Material_Create();
   4.680 +DLL_API signed char		F_API FSOUND_Geometry_Material_Free(FSOUND_MATERIAL *material);
   4.681 +DLL_API signed char		F_API FSOUND_Geometry_Material_SetAttributes(FSOUND_MATERIAL *material, float reflectancegain, float reflectancefreq, float transmittancegain, float transmittancefreq);
   4.682 +DLL_API signed char		F_API FSOUND_Geometry_Material_GetAttributes(FSOUND_MATERIAL *material, float *reflectancegain, float *reflectancefreq, float *transmittancegain, float *transmittancefreq);
   4.683 +DLL_API signed char		F_API FSOUND_Geometry_Material_Set(FSOUND_MATERIAL *material);
   4.684 +
   4.685 +// ========================================================================
   4.686 +// Reverb functions. (eax, eax2, a3d 3.0 reverb)  (NOT SUPPORTED IN LINUX)
   4.687 +// ========================================================================
   4.688 +
   4.689 +// eax1, eax2, a3d 3.0 (use FSOUND_REVERB_PRESETS if you like), (eax2 support through emulation/parameter conversion)
   4.690 +DLL_API signed char		F_API FSOUND_Reverb_SetEnvironment(int env, float vol, float decay, float damp);			
   4.691 +// eax2, a3d 3.0 only, does not work on eax1
   4.692 +DLL_API signed char		F_API FSOUND_Reverb_SetEnvironmentAdvanced(
   4.693 +								int	  env,
   4.694 +								int   Room,					// [-10000, 0]     default: -10000 mB	or use FSOUND_REVERB_IGNOREPARAM
   4.695 +								int   RoomHF,				// [-10000, 0]     default: 0 mB		or use FSOUND_REVERB_IGNOREPARAM
   4.696 +								float RoomRolloffFactor,	// [0.0, 10.0]     default: 0.0			or use FSOUND_REVERB_IGNOREPARAM
   4.697 +								float DecayTime,			// [0.1, 20.0]     default: 1.0 s		or use FSOUND_REVERB_IGNOREPARAM
   4.698 +								float DecayHFRatio,			// [0.1, 2.0]      default: 0.5			or use FSOUND_REVERB_IGNOREPARAM
   4.699 +								int   Reflections,			// [-10000, 1000]  default: -10000 mB	or use FSOUND_REVERB_IGNOREPARAM
   4.700 +								float ReflectionsDelay,		// [0.0, 0.3]      default: 0.02 s		or use FSOUND_REVERB_IGNOREPARAM
   4.701 +								int   Reverb,				// [-10000, 2000]  default: -10000 mB	or use FSOUND_REVERB_IGNOREPARAM
   4.702 +								float ReverbDelay,			// [0.0, 0.1]      default: 0.04 s		or use FSOUND_REVERB_IGNOREPARAM
   4.703 +								float EnvironmentSize,		// [0.0, 100.0]    default: 100.0 %		or use FSOUND_REVERB_IGNOREPARAM
   4.704 +								float EnvironmentDiffusion,	// [0.0, 100.0]    default: 100.0 %		or use FSOUND_REVERB_IGNOREPARAM
   4.705 +								float AirAbsorptionHF);		// [20.0, 20000.0] default: 5000.0 Hz	or use FSOUND_REVERB_IGNOREPARAM
   4.706 +
   4.707 +DLL_API signed char		F_API FSOUND_Reverb_SetMix(int channel, float mix);
   4.708 +
   4.709 +// information functions
   4.710 +DLL_API signed char		F_API FSOUND_Reverb_GetEnvironment(int *env, float *vol, float *decay, float *damp);			
   4.711 +DLL_API signed char		F_API FSOUND_Reverb_GetEnvironmentAdvanced(
   4.712 +								int   *env,
   4.713 +								int   *Room,				
   4.714 +								int   *RoomHF,				
   4.715 +								float *RoomRolloffFactor,	
   4.716 +								float *DecayTime,			
   4.717 +								float *DecayHFRatio,		
   4.718 +								int   *Reflections,			
   4.719 +								float *ReflectionsDelay,	
   4.720 +								int   *Reverb,				
   4.721 +								float *ReverbDelay,			
   4.722 +								float *EnvironmentSize,		
   4.723 +								float *EnvironmentDiffusion,
   4.724 +								float *AirAbsorptionHF);	
   4.725 +DLL_API signed char		F_API FSOUND_Reverb_GetMix(int channel, float *mix);
   4.726 +
   4.727 +// =============================================
   4.728 +// Recording functions  (NOT SUPPORTED IN LINUX)
   4.729 +// =============================================
   4.730 +
   4.731 +// recording initialization functions
   4.732 +DLL_API signed char		F_API FSOUND_Record_SetDriver(int outputtype);
   4.733 +DLL_API int				F_API FSOUND_Record_GetNumDrivers();
   4.734 +DLL_API signed char *	F_API FSOUND_Record_GetDriverName(int id);
   4.735 +DLL_API int				F_API FSOUND_Record_GetDriver();
   4.736 +
   4.737 +// recording functionality.  Only one recording session will work at a time
   4.738 +DLL_API signed char		F_API FSOUND_Record_StartSample(FSOUND_SAMPLE *sptr, signed char loop);// record to sample
   4.739 +DLL_API signed char		F_API FSOUND_Record_Stop();	// stop recording
   4.740 +DLL_API int				F_API FSOUND_Record_GetPosition();	// offset in sample, or wav file
   4.741 +
   4.742 +// =========================
   4.743 +// File system override
   4.744 +// =========================
   4.745 +
   4.746 +DLL_API void F_API FSOUND_File_SetCallbacks(unsigned int (_cdecl *OpenCallback)(const char *name),
   4.747 +                                            void         (_cdecl *CloseCallback)(unsigned int handle),
   4.748 +                                            int          (_cdecl *ReadCallback)(void *buffer, int size, unsigned int handle),
   4.749 +                                            int          (_cdecl *SeekCallback)(unsigned int handle, int pos, signed char mode),
   4.750 +                                            int          (_cdecl *TellCallback)(unsigned int handle));
   4.751 +
   4.752 +// =============================================================================================
   4.753 +// FMUSIC API
   4.754 +// =============================================================================================
   4.755 +
   4.756 +// Song management / playback functions.
   4.757 +DLL_API FMUSIC_MODULE * F_API FMUSIC_LoadSong(const char *name);
   4.758 +DLL_API FMUSIC_MODULE * F_API FMUSIC_LoadSongMemory(void *data, int length);
   4.759 +DLL_API signed char		F_API FMUSIC_FreeSong(FMUSIC_MODULE *mod);
   4.760 +DLL_API signed char		F_API FMUSIC_PlaySong(FMUSIC_MODULE *mod);
   4.761 +DLL_API signed char		F_API FMUSIC_StopSong(FMUSIC_MODULE *mod);
   4.762 +DLL_API void			F_API FMUSIC_StopAllSongs();
   4.763 +DLL_API signed char		F_API FMUSIC_SetZxxCallback(FMUSIC_MODULE *mod, FMUSIC_CALLBACK callback);
   4.764 +DLL_API signed char		F_API FMUSIC_SetRowCallback(FMUSIC_MODULE *mod, FMUSIC_CALLBACK callback, int rowstep);
   4.765 +DLL_API signed char		F_API FMUSIC_SetOrderCallback(FMUSIC_MODULE *mod, FMUSIC_CALLBACK callback, int orderstep);
   4.766 +DLL_API signed char		F_API FMUSIC_SetInstCallback(FMUSIC_MODULE *mod, FMUSIC_CALLBACK callback, int instrument);
   4.767 +DLL_API signed char		F_API FMUSIC_SetSample(FMUSIC_MODULE *mod, int sampno, FSOUND_SAMPLE *sptr);
   4.768 +DLL_API signed char		F_API FMUSIC_OptimizeChannels(FMUSIC_MODULE *mod, int maxchannels, int minvolume);
   4.769 +
   4.770 +// Runtime song functions.
   4.771 +DLL_API signed char		F_API FMUSIC_SetReverb(signed char reverb);				// MIDI only.
   4.772 +DLL_API signed char		F_API FMUSIC_SetOrder(FMUSIC_MODULE *mod, int order);
   4.773 +DLL_API signed char		F_API FMUSIC_SetPaused(FMUSIC_MODULE *mod, signed char pause);
   4.774 +DLL_API signed char		F_API FMUSIC_SetMasterVolume(FMUSIC_MODULE *mod, int volume);
   4.775 +DLL_API signed char		F_API FMUSIC_SetPanSeperation(FMUSIC_MODULE *mod, float pansep);
   4.776 + 
   4.777 +// Static song information functions.
   4.778 +DLL_API char *			F_API FMUSIC_GetName(FMUSIC_MODULE *mod);
   4.779 +DLL_API signed char		F_API FMUSIC_GetType(FMUSIC_MODULE *mod);
   4.780 +DLL_API int				F_API FMUSIC_GetNumOrders(FMUSIC_MODULE *mod);
   4.781 +DLL_API int				F_API FMUSIC_GetNumPatterns(FMUSIC_MODULE *mod);
   4.782 +DLL_API int				F_API FMUSIC_GetNumInstruments(FMUSIC_MODULE *mod);
   4.783 +DLL_API int				F_API FMUSIC_GetNumSamples(FMUSIC_MODULE *mod);
   4.784 +DLL_API int				F_API FMUSIC_GetNumChannels(FMUSIC_MODULE *mod);
   4.785 +DLL_API FSOUND_SAMPLE * F_API FMUSIC_GetSample(FMUSIC_MODULE *mod, int sampno);
   4.786 +DLL_API int				F_API FMUSIC_GetPatternLength(FMUSIC_MODULE *mod, int orderno);
   4.787 + 
   4.788 +// Runtime song information.
   4.789 +DLL_API signed char		F_API FMUSIC_IsFinished(FMUSIC_MODULE *mod);
   4.790 +DLL_API signed char		F_API FMUSIC_IsPlaying(FMUSIC_MODULE *mod);
   4.791 +DLL_API int				F_API FMUSIC_GetMasterVolume(FMUSIC_MODULE *mod);
   4.792 +DLL_API int				F_API FMUSIC_GetGlobalVolume(FMUSIC_MODULE *mod);
   4.793 +DLL_API int				F_API FMUSIC_GetOrder(FMUSIC_MODULE *mod);
   4.794 +DLL_API int				F_API FMUSIC_GetPattern(FMUSIC_MODULE *mod);
   4.795 +DLL_API int				F_API FMUSIC_GetSpeed(FMUSIC_MODULE *mod);
   4.796 +DLL_API int				F_API FMUSIC_GetBPM(FMUSIC_MODULE *mod);
   4.797 +DLL_API int				F_API FMUSIC_GetRow(FMUSIC_MODULE *mod);
   4.798 +DLL_API signed char		F_API FMUSIC_GetPaused(FMUSIC_MODULE *mod);
   4.799 +DLL_API int				F_API FMUSIC_GetTime(FMUSIC_MODULE *mod);
   4.800 +
   4.801 +#ifdef __cplusplus
   4.802 +}
   4.803 +#endif
   4.804 +
   4.805 +#endif
     5.1 Binary file libs/fmod/fmodvc.lib has changed
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/n3dinit.conf	Thu Oct 23 01:46:07 2014 +0300
     6.3 @@ -0,0 +1,20 @@
     6.4 +; The Lab Demos
     6.5 +; 3D Engine Configuration File
     6.6 +; You are advised not to mess with this file :)
     6.7 +; -- Nuclear / the Lab --
     6.8 +
     6.9 +fullscreen = false
    6.10 +resolution = 800x600
    6.11 +bpp = 32
    6.12 +zbufferdepth = 32
    6.13 +device = hal
    6.14 +tnl = hw
    6.15 +refresh = 60
    6.16 +antialiasing = high
    6.17 +flipchain = doublebuffering
    6.18 +vsync = false
    6.19 +dontcareabout = zbufferdepth, tnl, alpha
    6.20 +
    6.21 +; -- syntax reminder --
    6.22 +; dontcareflags: bpp, refresh, alpha, zbufferdepth, tnl, flipchain, aamode, vsync
    6.23 +; antialiasing: none / low / high
    6.24 \ No newline at end of file
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/readme.txt	Thu Oct 23 01:46:07 2014 +0300
     7.3 @@ -0,0 +1,25 @@
     7.4 +---------------------------------------------------------------
     7.5 + The Lab Demos presents a rather unfinished demo in ReAct 2003
     7.6 +---------------------------------------------------------------
     7.7 +                    - a B s e n c e -
     7.8 +                     (final version)
     7.9 +
    7.10 +          Code: Nuclear
    7.11 +           Gfx: RawNoise
    7.12 +         Music: Amigo
    7.13 +Additional Gfx: Amoivikos / ASD
    7.14 +
    7.15 +A big thank you to the ReAct organizers (nlogn) for organizing
    7.16 +once again a great party.
    7.17 +
    7.18 +We want to personally greet:
    7.19 +Nina, Eva-S, Amoivikos, vvas, Navis, Alias Medron, Zouzoulos
    7.20 +j0bo, Psyche, Raoul, zafos, moT, emc, Outsider, imak, Thor
    7.21 +^gfx, Fubyo, Apomakros, Palmuter, nagz, night, aMUSiC, Optimus
    7.22 +Badsector and all the demosceners around the world.
    7.23 +
    7.24 +contact: nuclear@siggraph.org
    7.25 +
    7.26 +---------------------------------------------------------------
    7.27 +----------------  http://thelab.demoscene.gr  -----------------
    7.28 +---------------------------------------------------------------
    7.29 \ No newline at end of file
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/resource.h	Thu Oct 23 01:46:07 2014 +0300
     8.3 @@ -0,0 +1,16 @@
     8.4 +//{{NO_DEPENDENCIES}}
     8.5 +// Microsoft Visual C++ generated include file.
     8.6 +// Used by resources.rc
     8.7 +//
     8.8 +#define IDI_ICON1                       101
     8.9 +
    8.10 +// Next default values for new objects
    8.11 +// 
    8.12 +#ifdef APSTUDIO_INVOKED
    8.13 +#ifndef APSTUDIO_READONLY_SYMBOLS
    8.14 +#define _APS_NEXT_RESOURCE_VALUE        102
    8.15 +#define _APS_NEXT_COMMAND_VALUE         40001
    8.16 +#define _APS_NEXT_CONTROL_VALUE         1001
    8.17 +#define _APS_NEXT_SYMED_VALUE           101
    8.18 +#endif
    8.19 +#endif
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/resources.rc	Thu Oct 23 01:46:07 2014 +0300
     9.3 @@ -0,0 +1,5 @@
     9.4 +// Microsoft Visual C++ generated resource script.
     9.5 +//
     9.6 +#include "resource.h"
     9.7 +
     9.8 +IDI_ICON1               ICON                    "thelab.ico"
     9.9 \ No newline at end of file
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/3deng/3deng.h	Thu Oct 23 01:46:07 2014 +0300
    10.3 @@ -0,0 +1,17 @@
    10.4 +#ifndef _3DENG_H_
    10.5 +#define _3DENG_H_
    10.6 +
    10.7 +#include "switches.h"
    10.8 +#include "3dengine.h"
    10.9 +#include "exceptions.h"
   10.10 +#include "n3dmath.h"
   10.11 +#include "3dengtypes.h"
   10.12 +#include "lights.h"
   10.13 +#include "objects.h"
   10.14 +#include "camera.h"
   10.15 +#include "objectgen.h"
   10.16 +#include "3dscene.h"
   10.17 +#include "sceneloader.h"
   10.18 +#include "particles.h"
   10.19 +
   10.20 +#endif	// _3DENG_H_
   10.21 \ No newline at end of file
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/3deng/3dengine.cpp	Thu Oct 23 01:46:07 2014 +0300
    11.3 @@ -0,0 +1,1388 @@
    11.4 +#include <fstream>
    11.5 +#include <string>
    11.6 +#include <cmath>
    11.7 +#include <cassert>
    11.8 +#include "d3dx8.h"
    11.9 +#include "3dengine.h"
   11.10 +#include "exceptions.h"
   11.11 +#include "3dgeom.h"
   11.12 +#include "lights.h"
   11.13 +
   11.14 +// local helper functions
   11.15 +ColorDepth GetColorDepthFromPixelFormat(D3DFORMAT fmt);
   11.16 +D3DFORMAT GetPixelFormatFromColorDepth(ColorDepth cd, bool noalpha=false);
   11.17 +D3DFORMAT GetDepthStencilFormat(int depthbits, bool stencil);
   11.18 +
   11.19 +///////////// Graphics Context Member Functions /////////////////
   11.20 +
   11.21 +GraphicsContext::GraphicsContext() {
   11.22 +	D3DDevice = 0;
   11.23 +	BackfaceCulling = true;
   11.24 +}
   11.25 +
   11.26 +///////////////////////////////////
   11.27 +// ----==( SetDefaultStates )==----
   11.28 +// (Public Member Function)
   11.29 +// Sets the default render states
   11.30 +///////////////////////////////////
   11.31 +void GraphicsContext::SetDefaultStates() {
   11.32 +	D3DDevice->SetRenderState(D3DRS_LOCALVIEWER, true);
   11.33 +	SetPrimitiveType(TriangleList);
   11.34 +	SetBackfaceCulling(true);
   11.35 +	SetFrontFace(Clockwise);
   11.36 +	SetLighting(true);
   11.37 +	SetColorVertex(false);
   11.38 +	SetAmbientLight(0.0f);
   11.39 +	SetMipMapping(true);
   11.40 +	SetTextureFiltering(BilinearFiltering);
   11.41 +	SetBillboarding(false);
   11.42 +	SetSpecular(true);
   11.43 +
   11.44 +	Matrix4x4 ProjMat;
   11.45 +	CreateProjectionMatrix(&ProjMat, QuarterPi, 1.33333333f, 1.0f, 10000.0f);
   11.46 +	SetProjectionMatrix(ProjMat);
   11.47 +}
   11.48 +
   11.49 +
   11.50 +bool GraphicsContext::CreateVertexBuffer(uint32 VertexCount, UsageFlags usage, VertexBuffer **vb) const {
   11.51 +	long hr = D3DDevice->CreateVertexBuffer(VertexCount * sizeof(Vertex), (dword)usage, VertexFormat, D3DPOOL_DEFAULT, vb);
   11.52 +	return (hr == D3D_OK);
   11.53 +}
   11.54 +
   11.55 +bool GraphicsContext::CreateIndexBuffer(uint32 IndexCount, UsageFlags usage, IndexBuffer **ib) const {
   11.56 +	long hr = D3DDevice->CreateIndexBuffer(IndexCount * IndexSize, (dword)usage, IndexFormat, D3DPOOL_DEFAULT, ib);
   11.57 +	return (hr == D3D_OK);
   11.58 +}
   11.59 +
   11.60 +bool GraphicsContext::CreateSurface(uint32 Width, uint32 Height, Surface **surf) const {
   11.61 +	long hr = D3DDevice->CreateImageSurface(Width, Height, ColorFormat, surf);
   11.62 +	return (hr == D3D_OK);
   11.63 +}
   11.64 +
   11.65 +bool GraphicsContext::CreateDepthStencil(uint32 Width, uint32 Height, Surface **zsurf) const {
   11.66 +	long hr = D3DDevice->CreateDepthStencilSurface(Width, Height, ZFormat, (D3DMULTISAMPLE_TYPE)AASamples, zsurf);
   11.67 +	return (hr == D3D_OK);
   11.68 +}
   11.69 +
   11.70 +void GraphicsContext::Clear(dword color) const {
   11.71 +	D3DDevice->Clear(0, 0, D3DCLEAR_TARGET, color, 1.0f, 0);
   11.72 +}
   11.73 +
   11.74 +void GraphicsContext::ClearZBuffer(float zval) const {
   11.75 +	D3DDevice->Clear(0, 0, D3DCLEAR_ZBUFFER, 0, zval, 0);
   11.76 +}
   11.77 +
   11.78 +void GraphicsContext::ClearStencil(byte sval) const {
   11.79 +	D3DDevice->Clear(0, 0, D3DCLEAR_STENCIL, 0, 1.0f, sval);
   11.80 +}
   11.81 +
   11.82 +void GraphicsContext::ClearZBufferStencil(float zval, byte sval) const {
   11.83 +	D3DDevice->Clear(0, 0, D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0, zval, sval);
   11.84 +}
   11.85 +
   11.86 +void GraphicsContext::Flip() const {
   11.87 +	D3DDevice->Present(0, 0, 0, 0);
   11.88 +}
   11.89 +
   11.90 +
   11.91 +bool GraphicsContext::Draw(VertexBuffer *vb) {
   11.92 +	D3DVERTEXBUFFER_DESC desc;
   11.93 +	vb->GetDesc(&desc);
   11.94 +	unsigned int verts = desc.Size / sizeof(Vertex);
   11.95 +
   11.96 +	D3DDevice->SetStreamSource(0, vb, sizeof(Vertex));
   11.97 +	long res = D3DDevice->DrawPrimitive((D3DPRIMITIVETYPE)ptype, 0, verts / 3);
   11.98 +	D3DDevice->SetStreamSource(0, 0, 0);
   11.99 +    return res == D3D_OK;
  11.100 +}
  11.101 +
  11.102 +bool GraphicsContext::Draw(Vertex *varray, unsigned int VertexCount) {
  11.103 +	long res = D3DDevice->DrawPrimitiveUP((D3DPRIMITIVETYPE)ptype, VertexCount / 3, varray, sizeof(Vertex));
  11.104 +	return res == D3D_OK;
  11.105 +}
  11.106 +
  11.107 +bool GraphicsContext::Draw(VertexBuffer *vb, IndexBuffer *ib) {
  11.108 +	D3DVERTEXBUFFER_DESC vbdesc;
  11.109 +	vb->GetDesc(&vbdesc);
  11.110 +	unsigned int verts = vbdesc.Size / sizeof(Vertex);
  11.111 +
  11.112 +	D3DINDEXBUFFER_DESC ibdesc;
  11.113 +	ib->GetDesc(&ibdesc);
  11.114 +	unsigned int indices = ibdesc.Size / sizeof(Index);
  11.115 +
  11.116 +	D3DDevice->SetStreamSource(0, vb, sizeof(Vertex));
  11.117 +	D3DDevice->SetIndices(ib, 0);
  11.118 +	long res = D3DDevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)ptype, 0, verts, 0, indices / 3);
  11.119 +	D3DDevice->SetIndices(0, 0);
  11.120 +	D3DDevice->SetStreamSource(0, 0, 0);
  11.121 +	return res == D3D_OK;
  11.122 +}
  11.123 +
  11.124 +bool GraphicsContext::Draw(Vertex *varray, Index *iarray, unsigned int VertexCount, unsigned int IndexCount) {
  11.125 +	long res = D3DDevice->DrawIndexedPrimitiveUP((D3DPRIMITIVETYPE)ptype, 0, VertexCount, IndexCount / 3, iarray, IndexFormat, varray, sizeof(Vertex));
  11.126 +	return res == D3D_OK;
  11.127 +}
  11.128 +
  11.129 +bool GraphicsContext::Draw(Vertex *varray, Triangle *triarray, unsigned int VertexCount, unsigned int TriCount) {
  11.130 +	unsigned int IndexCount = TriCount * 3;
  11.131 +	Index *iarray = new Index[IndexCount];
  11.132 +	for(dword i=0; i<TriCount; i++) {
  11.133 +		iarray[i*3] = triarray[i].vertices[0];
  11.134 +		iarray[i*3+1] = triarray[i].vertices[1];
  11.135 +		iarray[i*3+2] = triarray[i].vertices[2];
  11.136 +	}
  11.137 +	long res = Draw(varray, iarray, VertexCount, IndexCount);
  11.138 +	return res == D3D_OK;
  11.139 +}
  11.140 +
  11.141 +////////////// State Setting Interface ///////////////
  11.142 +
  11.143 +void GraphicsContext::SetPrimitiveType(PrimitiveType pt) {
  11.144 +	ptype = pt;
  11.145 +}
  11.146 +
  11.147 +void GraphicsContext::SetBackfaceCulling(bool enable) {
  11.148 +	if(enable) {
  11.149 +		D3DDevice->SetRenderState(D3DRS_CULLMODE, CullOrder);
  11.150 +	} else {
  11.151 +		D3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  11.152 +	}
  11.153 +	BackfaceCulling = enable;
  11.154 +}
  11.155 +
  11.156 +void GraphicsContext::SetFrontFace(FaceOrder order) {
  11.157 +	if(order == Clockwise) {
  11.158 +		CullOrder = CounterClockwise;
  11.159 +	} else {
  11.160 +		CullOrder = Clockwise;
  11.161 +	}
  11.162 +	if(BackfaceCulling) SetBackfaceCulling(BackfaceCulling);
  11.163 +}
  11.164 +
  11.165 +void GraphicsContext::SetAutoNormalize(bool enable) {
  11.166 +	D3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, enable);
  11.167 +}
  11.168 +
  11.169 +void GraphicsContext::SetBillboarding(bool enable) {
  11.170 +	BillBoardingEnabled = enable;
  11.171 +	if(enable) {
  11.172 +
  11.173 +		Vector3 pos;
  11.174 +		pos.Transform(WorldMat[0]);
  11.175 +	
  11.176 +		Matrix4x4 world;
  11.177 +		world.Translate(pos.x, pos.y, pos.z);
  11.178 +		Matrix4x4 BillBoardRot;
  11.179 +
  11.180 +		Vector3 dir = ViewMat.Inverse().GetRowVector(2);
  11.181 +		float yangle = dir.x > 0.0f ? -atanf(dir.z / dir.x) + HalfPi : -atanf(dir.z / dir.x) - HalfPi;
  11.182 +
  11.183 +		BillBoardRot.Rotate(0.0f, yangle, 0.0f);
  11.184 +		Vector3 xaxis = VECTOR3_I;
  11.185 +		Vector3 normal = -VECTOR3_K;
  11.186 +		xaxis.Transform(BillBoardRot);
  11.187 +		normal.Transform(BillBoardRot);
  11.188 +
  11.189 +		// find angle between quad normal and view direction
  11.190 +		float xangle = acosf(DotProduct(normal, dir.Normalized()));
  11.191 +		BillBoardRot.Rotate(xaxis, xangle);
  11.192 +
  11.193 +		world = BillBoardRot * world;
  11.194 +
  11.195 +		D3DDevice->SetTransform(D3DTS_WORLD, &world);
  11.196 +		//D3DDevice->SetTransform(D3DTS_VIEW, &BillboardViewMatrix);
  11.197 +	} else {
  11.198 +		D3DDevice->SetTransform(D3DTS_WORLD, &WorldMat[0]);
  11.199 +		//D3DDevice->SetTransform(D3DTS_VIEW, &ViewMat);
  11.200 +	}
  11.201 +}
  11.202 +
  11.203 +void GraphicsContext::SetColorWrite(bool red, bool green, bool blue, bool alpha) {
  11.204 +	dword channels = 0;
  11.205 +	if(red) channels |= D3DCOLORWRITEENABLE_RED;
  11.206 +	if(green) channels |= D3DCOLORWRITEENABLE_GREEN;
  11.207 +	if(blue) channels |= D3DCOLORWRITEENABLE_BLUE;
  11.208 +	if(alpha) channels |= D3DCOLORWRITEENABLE_ALPHA;
  11.209 +
  11.210 +	D3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, channels);
  11.211 +}
  11.212 +
  11.213 +// blending states
  11.214 +void GraphicsContext::SetAlphaBlending(bool enable) {
  11.215 +	D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, enable);
  11.216 +}
  11.217 +
  11.218 +void GraphicsContext::SetBlendFunc(BlendingFactor src, BlendingFactor dest) {
  11.219 +	D3DDevice->SetRenderState(D3DRS_SRCBLEND, src);
  11.220 +	D3DDevice->SetRenderState(D3DRS_DESTBLEND, dest);
  11.221 +}
  11.222 +
  11.223 +// zbuffer states
  11.224 +void GraphicsContext::SetZBuffering(bool enable) {
  11.225 +	D3DDevice->SetRenderState(D3DRS_ZENABLE, enable);
  11.226 +}
  11.227 +
  11.228 +void GraphicsContext::SetZWrite(bool enable) {
  11.229 +	D3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, enable);
  11.230 +}
  11.231 +
  11.232 +void GraphicsContext::SetZFunc(CmpFunc func) {
  11.233 +	D3DDevice->SetRenderState(D3DRS_ZFUNC, func);
  11.234 +}
  11.235 +
  11.236 +// set stencil buffer states
  11.237 +void GraphicsContext::SetStencilBuffering(bool enable) {
  11.238 +	D3DDevice->SetRenderState(D3DRS_STENCILENABLE, enable);
  11.239 +}
  11.240 +
  11.241 +void GraphicsContext::SetStencilPassOp(StencilOp sop) {
  11.242 +	D3DDevice->SetRenderState(D3DRS_STENCILPASS, sop);
  11.243 +}
  11.244 +
  11.245 +void GraphicsContext::SetStencilFailOp(StencilOp sop) {
  11.246 +	D3DDevice->SetRenderState(D3DRS_STENCILFAIL, sop);
  11.247 +}
  11.248 +
  11.249 +void GraphicsContext::SetStencilPassZFailOp(StencilOp sop) {
  11.250 +	D3DDevice->SetRenderState(D3DRS_STENCILZFAIL, sop);
  11.251 +}
  11.252 +
  11.253 +void GraphicsContext::SetStencilOp(StencilOp Fail, StencilOp StencilPassZFail, StencilOp Pass) {
  11.254 +	D3DDevice->SetRenderState(D3DRS_STENCILPASS, Pass);
  11.255 +	D3DDevice->SetRenderState(D3DRS_STENCILFAIL, Fail);
  11.256 +	D3DDevice->SetRenderState(D3DRS_STENCILZFAIL, StencilPassZFail);
  11.257 +}
  11.258 +
  11.259 +void GraphicsContext::SetStencilFunc(CmpFunc func) {
  11.260 +	D3DDevice->SetRenderState(D3DRS_STENCILFUNC, func);
  11.261 +}
  11.262 +
  11.263 +void GraphicsContext::SetStencilReference(dword value) {
  11.264 +	D3DDevice->SetRenderState(D3DRS_STENCILREF, value);
  11.265 +}
  11.266 +
  11.267 +// texture & material states
  11.268 +
  11.269 +void GraphicsContext::SetTextureFactor(dword factor) {
  11.270 +	D3DDevice->SetRenderState(D3DRS_TEXTUREFACTOR, factor);
  11.271 +}
  11.272 +
  11.273 +void GraphicsContext::SetTextureFiltering(TextureFilteringType texfilter, int TextureStage) {
  11.274 +	dword TexFilter, MipFilter;
  11.275 +
  11.276 +	switch(texfilter) {
  11.277 +	case PointSampling:
  11.278 +		TexFilter = MipFilter = D3DTEXF_POINT;
  11.279 +		break;
  11.280 +
  11.281 +	case BilinearFiltering:
  11.282 +		TexFilter = D3DTEXF_LINEAR;
  11.283 +		MipFilter = D3DTEXF_POINT;
  11.284 +		break;
  11.285 +
  11.286 +	case TrilinearFiltering:
  11.287 +		TexFilter = MipFilter = D3DTEXF_LINEAR;
  11.288 +		break;
  11.289 +
  11.290 +	case AnisotropicFiltering:
  11.291 +		TexFilter = D3DTEXF_ANISOTROPIC;
  11.292 +		MipFilter = D3DTEXF_LINEAR;
  11.293 +		break;
  11.294 +
  11.295 +	default: break;
  11.296 +	}
  11.297 +
  11.298 +	this->MipFilter = MipFilter;
  11.299 +
  11.300 +	if(!MipMapEnabled) MipFilter = D3DTEXF_NONE;
  11.301 +
  11.302 +	if(TextureStage == 0xa11) {
  11.303 +		for(int i=0; i<MaxTextureStages; i++) {
  11.304 +			D3DDevice->SetTextureStageState(i, D3DTSS_MINFILTER, TexFilter);
  11.305 +			D3DDevice->SetTextureStageState(i, D3DTSS_MAGFILTER, TexFilter);
  11.306 +			D3DDevice->SetTextureStageState(i, D3DTSS_MIPFILTER, MipFilter);
  11.307 +		}
  11.308 +	} else {
  11.309 +		D3DDevice->SetTextureStageState(TextureStage, D3DTSS_MINFILTER, TexFilter);
  11.310 +		D3DDevice->SetTextureStageState(TextureStage, D3DTSS_MAGFILTER, TexFilter);
  11.311 +		D3DDevice->SetTextureStageState(TextureStage, D3DTSS_MIPFILTER, MipFilter);
  11.312 +	}
  11.313 +}
  11.314 +
  11.315 +void GraphicsContext::SetTextureAddressing(TextureAddressing uaddr, TextureAddressing vaddr, int TextureStage) {
  11.316 +	if(TextureStage == 0xa11) {
  11.317 +        for(int i=0; i<MaxTextureStages; i++) {
  11.318 +			D3DDevice->SetTextureStageState(i, D3DTSS_ADDRESSU, uaddr);
  11.319 +			D3DDevice->SetTextureStageState(i, D3DTSS_ADDRESSV, vaddr);
  11.320 +		}
  11.321 +	} else {
  11.322 +		D3DDevice->SetTextureStageState(TextureStage, D3DTSS_ADDRESSU, uaddr);
  11.323 +		D3DDevice->SetTextureStageState(TextureStage, D3DTSS_ADDRESSV, vaddr);
  11.324 +	}
  11.325 +}
  11.326 +
  11.327 +void GraphicsContext::SetTextureBorderColor(dword color, int TextureStage) {
  11.328 +	if(TextureStage == 0xa11) {
  11.329 +		for(int i=0; i<MaxTextureStages; i++) {
  11.330 +			D3DDevice->SetTextureStageState(i, D3DTSS_BORDERCOLOR, color);
  11.331 +		}
  11.332 +	} else {
  11.333 +		D3DDevice->SetTextureStageState(TextureStage, D3DTSS_BORDERCOLOR, color);
  11.334 +	}
  11.335 +}
  11.336 +
  11.337 +void GraphicsContext::SetTexture(int index, Texture *tex) {
  11.338 +	D3DDevice->SetTexture(index, tex);
  11.339 +}
  11.340 +
  11.341 +void GraphicsContext::SetMipMapping(bool enable, int TextureStage) {
  11.342 +	MipMapEnabled = enable;
  11.343 +	dword mip = (enable ? MipFilter : D3DTEXF_NONE);
  11.344 +
  11.345 +	if(TextureStage == 0xa11) {
  11.346 +        for(int i=0; i<MaxTextureStages; i++) {
  11.347 +			D3DDevice->SetTextureStageState(i, D3DTSS_MIPFILTER, mip);
  11.348 +		}
  11.349 +	} else {
  11.350 +		D3DDevice->SetTextureStageState(TextureStage, D3DTSS_MIPFILTER, mip);
  11.351 +	}
  11.352 +}
  11.353 +
  11.354 +void GraphicsContext::SetMaterial(const Material &mat) {
  11.355 +	D3DDevice->SetMaterial(&mat);
  11.356 +}
  11.357 +
  11.358 +static unsigned long TLVertexFVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1;
  11.359 +
  11.360 +struct TLVertex {
  11.361 +	Vector3 pos;
  11.362 +	float rhw;
  11.363 +	unsigned long color;
  11.364 +	TexCoord tex;
  11.365 +
  11.366 +	TLVertex() {
  11.367 +		pos = Vector3(0.0f, 0.0f, 0.0f);
  11.368 +		color = 0xffffffff;
  11.369 +		tex.u = tex.v = 0.0f;
  11.370 +		rhw = pos.z;
  11.371 +	}
  11.372 +
  11.373 +	TLVertex(const Vector3 &pos, const Color &col, float u=0.0f, float v=0.0f) {
  11.374 +		this->pos = pos;
  11.375 +		rhw = pos.z;
  11.376 +		color = col.GetPacked32();
  11.377 +		tex.u = u;
  11.378 +		tex.v = v;
  11.379 +	}
  11.380 +};
  11.381 +
  11.382 +void GraphicsContext::BlitTexture(const Texture *texture, RECT *rect, const Color &col) {
  11.383 +	bool norect = rect ? false : true;
  11.384 +	if(norect) {
  11.385 +		rect = new RECT;
  11.386 +		rect->left = rect->top = 0;
  11.387 +		rect->right = ContextParams.x;
  11.388 +		rect->bottom = ContextParams.y;
  11.389 +	}
  11.390 +
  11.391 +	SetVertexProgram(TLVertexFVF);
  11.392 +
  11.393 +	TLVertex tlverts[4];
  11.394 +	tlverts[0] = TLVertex(Vector3((float)rect->right, (float)rect->top, 1.0f), col, 1.0f, 0.0f);
  11.395 +	tlverts[1] = TLVertex(Vector3((float)rect->right, (float)rect->bottom, 1.0f), col, 1.0f, 1.0f);
  11.396 +	tlverts[2] = TLVertex(Vector3((float)rect->left, (float)rect->top, 1.0f), col, 0.0f, 0.0f);
  11.397 +	tlverts[3] = TLVertex(Vector3((float)rect->left, (float)rect->bottom, 1.0f), col, 0.0f, 1.0f);
  11.398 +
  11.399 +	EnableTextureStage(0);
  11.400 +	DisableTextureStage(1);
  11.401 +	SetTexture(0, const_cast<Texture*>(texture));
  11.402 +	
  11.403 +	SetZBuffering(false);
  11.404 +	D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, tlverts, sizeof(TLVertex));
  11.405 +	SetZBuffering(true);
  11.406 +
  11.407 +	SetTexture(0, 0);
  11.408 +
  11.409 +	SetVertexProgram(VertexFormat);
  11.410 +
  11.411 +	if(norect) {
  11.412 +		delete rect;
  11.413 +	}
  11.414 +}
  11.415 +
  11.416 +// multitexturing interface
  11.417 +void GraphicsContext::EnableTextureStage(int stage) {
  11.418 +	SetTextureStageColor(stage, TexBlendModulate, TexArgTexture, TexArgCurrent);
  11.419 +}
  11.420 +
  11.421 +void GraphicsContext::DisableTextureStage(int stage) {
  11.422 +	D3DDevice->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_DISABLE);
  11.423 +}
  11.424 +
  11.425 +void GraphicsContext::SetTextureStageColor(int stage, TextureBlendFunction op, TextureBlendArgument arg1, TextureBlendArgument arg2, TextureBlendArgument arg3) {
  11.426 +	D3DDevice->SetTextureStageState(stage, D3DTSS_COLOROP, op);
  11.427 +	D3DDevice->SetTextureStageState(stage, D3DTSS_COLORARG1, arg1);
  11.428 +	D3DDevice->SetTextureStageState(stage, D3DTSS_COLORARG2, arg2);
  11.429 +	if(arg3) D3DDevice->SetTextureStageState(stage, D3DTSS_COLORARG0, arg3);
  11.430 +}
  11.431 +
  11.432 +void GraphicsContext::SetTextureStageAlpha(int stage, TextureBlendFunction op, TextureBlendArgument arg1, TextureBlendArgument arg2, TextureBlendArgument arg3) {
  11.433 +	D3DDevice->SetTextureStageState(stage, D3DTSS_ALPHAOP, op);
  11.434 +	D3DDevice->SetTextureStageState(stage, D3DTSS_ALPHAARG1, arg1);
  11.435 +	D3DDevice->SetTextureStageState(stage, D3DTSS_ALPHAARG2, arg2);
  11.436 +	if(arg3) D3DDevice->SetTextureStageState(stage, D3DTSS_ALPHAARG0, arg3);
  11.437 +}
  11.438 +
  11.439 +void GraphicsContext::SetTextureCoordIndex(int stage, int index) {
  11.440 +	D3DDevice->SetTextureStageState(stage, D3DTSS_TEXCOORDINDEX, index);
  11.441 +}
  11.442 +
  11.443 +void GraphicsContext::SetTextureTransformState(int stage, TexTransformState TexXForm) {
  11.444 +	D3DDevice->SetTextureStageState(stage, D3DTSS_TEXTURETRANSFORMFLAGS, TexXForm);
  11.445 +}
  11.446 +
  11.447 +// programmable pipeline interface
  11.448 +void GraphicsContext::SetVertexProgram(dword vs) {
  11.449 +	D3DDevice->SetVertexShader(vs);
  11.450 +}
  11.451 +
  11.452 +void GraphicsContext::SetPixelProgram(dword ps) {
  11.453 +	D3DDevice->SetPixelShader(ps);
  11.454 +}
  11.455 +
  11.456 +dword GraphicsContext::CreateVertexProgram(const char *fname) {
  11.457 +
  11.458 +	// vertex format declaration
  11.459 +	dword VertDecl[] = {
  11.460 +		D3DVSD_STREAM(0), 
  11.461 +		D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
  11.462 +		D3DVSD_REG(D3DVSDE_BLENDWEIGHT, D3DVSDT_FLOAT1),
  11.463 +		D3DVSD_REG(D3DVSDE_BLENDINDICES, D3DVSDT_UBYTE4),
  11.464 +		D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3),
  11.465 +		D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
  11.466 +		D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
  11.467 +		D3DVSD_REG(D3DVSDE_TEXCOORD1, D3DVSDT_FLOAT2),
  11.468 +		D3DVSD_REG(D3DVSDE_TEXCOORD2, D3DVSDT_FLOAT2),
  11.469 +		D3DVSD_REG(D3DVSDE_TEXCOORD3, D3DVSDT_FLOAT2),
  11.470 +		D3DVSD_END()
  11.471 +	};
  11.472 +
  11.473 +
  11.474 +	ID3DXBuffer *code, *errors;
  11.475 +	if(D3DXAssembleShaderFromFile(fname, 0, 0, &code, &errors) != D3D_OK) {
  11.476 +		return 0xffffffff;
  11.477 +	}
  11.478 +
  11.479 +	dword vprog;
  11.480 +	if(D3DDevice->CreateVertexShader(VertDecl, (dword*)code->GetBufferPointer(), &vprog, 0) != D3D_OK) {
  11.481 +		// could not create hardware vertex shader, try driver emulation...
  11.482 +		if(D3DDevice->CreateVertexShader(VertDecl, (dword*)code->GetBufferPointer(), &vprog, D3DUSAGE_SOFTWAREPROCESSING) != D3D_OK) {
  11.483 +			throw EngineGeneralException("The system lacks required programmable vertex processing unit support");
  11.484 +		}		
  11.485 +	}
  11.486 +
  11.487 +	return vprog;
  11.488 +}
  11.489 +
  11.490 +void GraphicsContext::DestroyVertexProgram(dword vprog) {
  11.491 +	D3DDevice->DeleteVertexShader(vprog);
  11.492 +}
  11.493 +
  11.494 +void GraphicsContext::SetVertexProgramConstant(dword creg, float val) {
  11.495 +	float block[4] = {val, 0.0f, 0.0f, 1.0f};
  11.496 +	D3DDevice->SetVertexShaderConstant(creg, &block, 1);
  11.497 +}
  11.498 +
  11.499 +void GraphicsContext::SetVertexProgramConstant(dword creg, const Vector3 &val) {
  11.500 +	Vector4 vec(val);
  11.501 +	D3DDevice->SetVertexShaderConstant(creg, &vec, 1);
  11.502 +}
  11.503 +
  11.504 +void GraphicsContext::SetVertexProgramConstant(dword creg, const Vector4 &val) {
  11.505 +	D3DDevice->SetVertexShaderConstant(creg, &val, 1);
  11.506 +}
  11.507 +
  11.508 +void GraphicsContext::SetVertexProgramConstant(dword creg, const Color &val) {
  11.509 +	D3DDevice->SetVertexShaderConstant(creg, &val, 1);
  11.510 +}
  11.511 +
  11.512 +void GraphicsContext::SetVertexProgramConstant(dword creg, const Matrix4x4 &val) {
  11.513 +	D3DDevice->SetVertexShaderConstant(creg, &val, 4);
  11.514 +}
  11.515 +
  11.516 +void GraphicsContext::SetVertexProgramConstant(dword creg, const void *data, dword size) {
  11.517 +	D3DDevice->SetVertexShaderConstant(creg, data, size);
  11.518 +}
  11.519 +
  11.520 +
  11.521 +// Lighting states
  11.522 +void GraphicsContext::SetLighting(bool enable) {
  11.523 +	D3DDevice->SetRenderState(D3DRS_LIGHTING, enable);
  11.524 +}
  11.525 +
  11.526 +void GraphicsContext::SetColorVertex(bool enable) {
  11.527 +	D3DDevice->SetRenderState(D3DRS_COLORVERTEX, enable);
  11.528 +}
  11.529 +
  11.530 +void GraphicsContext::SetAmbientLight(Color AmbientColor) {
  11.531 +	D3DDevice->SetRenderState(D3DRS_AMBIENT, AmbientColor.GetPacked32());
  11.532 +}
  11.533 +
  11.534 +void GraphicsContext::SetShadingMode(ShadeMode mode) {
  11.535 +	D3DDevice->SetRenderState(D3DRS_SHADEMODE, mode);
  11.536 +}
  11.537 +
  11.538 +void GraphicsContext::SetSpecular(bool enable) {
  11.539 +	D3DDevice->SetRenderState(D3DRS_SPECULARENABLE, enable);
  11.540 +}
  11.541 +
  11.542 +// transformation states
  11.543 +void GraphicsContext::SetWorldMatrix(const Matrix4x4 &WorldMat, unsigned int BlendIndex) {
  11.544 +	assert(BlendIndex < 256);
  11.545 +	this->WorldMat[BlendIndex] = WorldMat;
  11.546 +	if(!BillBoardingEnabled) {
  11.547 +		D3DDevice->SetTransform(D3DTS_WORLDMATRIX(BlendIndex), &WorldMat);
  11.548 +	} else {
  11.549 +        SetBillboarding(true);
  11.550 +	}
  11.551 +}
  11.552 +
  11.553 +void GraphicsContext::SetViewMatrix(const Matrix4x4 &ViewMat) {
  11.554 +	this->ViewMat = ViewMat;
  11.555 +	if(!BillBoardingEnabled) {
  11.556 +		D3DDevice->SetTransform(D3DTS_VIEW, &ViewMat);
  11.557 +	} else {
  11.558 +		SetBillboarding(true);
  11.559 +	}
  11.560 +}
  11.561 +
  11.562 +void GraphicsContext::SetProjectionMatrix(const Matrix4x4 &ProjMat) {
  11.563 +	this->ProjMat = ProjMat;
  11.564 +	D3DDevice->SetTransform(D3DTS_PROJECTION, &ProjMat);
  11.565 +}
  11.566 +
  11.567 +void GraphicsContext::SetTextureMatrix(const Matrix4x4 &TexMat, unsigned int TextureStage) {
  11.568 +	assert(TextureStage < 8);
  11.569 +	this->TexMat[TextureStage] = TexMat;
  11.570 +	D3DDevice->SetTransform((D3DTRANSFORMSTATETYPE)((int)D3DTS_TEXTURE0 + TextureStage), &TexMat);
  11.571 +}
  11.572 +
  11.573 +void GraphicsContext::SetViewport(unsigned int x, unsigned int y, unsigned int xsize, unsigned int ysize, float MinZ, float MaxZ) {
  11.574 +	D3DVIEWPORT8 viewport;
  11.575 +	viewport.X = x;
  11.576 +	viewport.Y = y;
  11.577 +	viewport.Width = xsize;
  11.578 +	viewport.Height = ysize;
  11.579 +	viewport.MinZ = MinZ;
  11.580 +	viewport.MaxZ = MaxZ;
  11.581 +
  11.582 +	D3DDevice->SetViewport(&viewport);
  11.583 +}
  11.584 +
  11.585 +
  11.586 +const Matrix4x4 &GraphicsContext::GetWorldMatrix(unsigned int BlendIndex) {
  11.587 +	assert(BlendIndex < 256);
  11.588 +	return WorldMat[BlendIndex];
  11.589 +}
  11.590 +
  11.591 +const Matrix4x4 &GraphicsContext::GetViewMatrix() {
  11.592 +	return ViewMat;
  11.593 +}
  11.594 +
  11.595 +const Matrix4x4 &GraphicsContext::GetProjectionMatrix() {
  11.596 +	return ProjMat;
  11.597 +}
  11.598 +
  11.599 +const Matrix4x4 &GraphicsContext::GetTextureMatrix(unsigned int TextureStage) {
  11.600 +	assert(TextureStage < 8);
  11.601 +	return TexMat[TextureStage];
  11.602 +}
  11.603 +
  11.604 +
  11.605 +// render target
  11.606 +void GraphicsContext::ResetRenderTarget() {
  11.607 +	D3DDevice->SetRenderTarget(MainRenderTarget.ColorSurface, MainRenderTarget.DepthStencilSurface);
  11.608 +}
  11.609 +
  11.610 +void GraphicsContext::SetRenderTarget(RenderTarget &rtarg) {
  11.611 +	D3DDevice->SetRenderTarget(rtarg.ColorSurface, rtarg.DepthStencilSurface);
  11.612 +}
  11.613 +
  11.614 +void GraphicsContext::SetRenderTarget(Texture *rtarg, Texture *ztarg) {
  11.615 +	Surface *rendsurf, *zsurf = 0;
  11.616 +	rtarg->GetSurfaceLevel(0, &rendsurf);
  11.617 +	if(ztarg) ztarg->GetSurfaceLevel(0, &zsurf);
  11.618 +
  11.619 +	D3DDevice->SetRenderTarget(rendsurf, zsurf);
  11.620 +}
  11.621 +
  11.622 +void GraphicsContext::SetRenderTarget(Texture *rtarg, Surface *ztarg) {
  11.623 +	Surface *rendsurf;
  11.624 +	rtarg->GetSurfaceLevel(0, &rendsurf);
  11.625 +
  11.626 +	D3DDevice->SetRenderTarget(rendsurf, ztarg);
  11.627 +}
  11.628 +
  11.629 +
  11.630 +////////////////////////////////////////////////////
  11.631 +//////////// Engine3D Member Functions /////////////
  11.632 +////////////////////////////////////////////////////
  11.633 +
  11.634 +Engine3D::Engine3D() {
  11.635 +
  11.636 +	if(!(d3d = Direct3DCreate8(D3D_SDK_VERSION))) {
  11.637 +		// actually this will never occur, if directx8 is not available in the system then
  11.638 +		// the OS loader will hit the problem first when it'll try to load d3d8.dll that is
  11.639 +		// linked through d3d8.lib, and complain for missing imports
  11.640 +		throw EngineInitException("DirectX 8.1 is required to run this program");
  11.641 +	}
  11.642 +
  11.643 +	RetrieveAdapterInfo();
  11.644 +}
  11.645 +
  11.646 +Engine3D::~Engine3D() {
  11.647 +
  11.648 +	GraphicsContexts.erase(GraphicsContexts.begin(), GraphicsContexts.end());
  11.649 +
  11.650 +	if(d3d) {
  11.651 +        d3d->Release();
  11.652 +		d3d = 0;
  11.653 +	}
  11.654 +}
  11.655 +
  11.656 +
  11.657 +////////////////////////////////////
  11.658 +// ----==( RetrieveAdapterInfo )==----
  11.659 +// (Private Member Function)
  11.660 +// Gets the list of adapters on the system and additional
  11.661 +// information for each adapter including its capabilities
  11.662 +////////////////////////////////////
  11.663 +void Engine3D::RetrieveAdapterInfo() {
  11.664 +
  11.665 +	// retrieve adapter list
  11.666 +	AdapterCount = d3d->GetAdapterCount();
  11.667 +	adapters = new Adapter[AdapterCount];
  11.668 +
  11.669 +	for(unsigned int i=0; i<AdapterCount; i++) {
  11.670 +
  11.671 +		// get adapter identifier and driver information
  11.672 +		D3DADAPTER_IDENTIFIER8 AdapterIdentifier;
  11.673 +		d3d->GetAdapterIdentifier(i, D3DENUM_NO_WHQL_LEVEL, &AdapterIdentifier);
  11.674 +		adapters[i].Description = new char[strlen(AdapterIdentifier.Description)+1];
  11.675 +		strcpy(adapters[i].Description, AdapterIdentifier.Description);
  11.676 +		adapters[i].Driver = new char[strlen(AdapterIdentifier.Driver)+1];
  11.677 +		strcpy(adapters[i].Driver, AdapterIdentifier.Driver);
  11.678 +
  11.679 +		adapters[i].DeviceGUID = AdapterIdentifier.DeviceIdentifier;
  11.680 +		adapters[i].DeviceID = AdapterIdentifier.DeviceId;
  11.681 +		adapters[i].DriverVersion = AdapterIdentifier.DriverVersion.QuadPart;
  11.682 +		adapters[i].Revision = AdapterIdentifier.Revision;
  11.683 +		adapters[i].SubSysID = AdapterIdentifier.SubSysId;
  11.684 +		adapters[i].VentorID = AdapterIdentifier.VendorId;
  11.685 +
  11.686 +		// get a list of display modes for this adapter
  11.687 +		LinkedList<DisplayMode> dmlist;
  11.688 +		adapters[i].ModeCount = d3d->GetAdapterModeCount(i);
  11.689 +		for(unsigned int j=0; j<adapters[i].ModeCount; j++) {
  11.690 +			D3DDISPLAYMODE d3dmode;
  11.691 +			DisplayMode mode;
  11.692 +			d3d->EnumAdapterModes(i, j, &d3dmode);			
  11.693 +			mode.XRes = d3dmode.Width;
  11.694 +			mode.YRes = d3dmode.Height;
  11.695 +			mode.RefreshRate = d3dmode.RefreshRate;
  11.696 +			mode.ColorFormat = GetColorDepthFromPixelFormat(d3dmode.Format);
  11.697 +
  11.698 +			// check if this mode is supported from the HAL device
  11.699 +			D3DFORMAT dispfmt = GetPixelFormatFromColorDepth(mode.ColorFormat, true);
  11.700 +			if(d3d->CheckDeviceType(i, D3DDEVTYPE_HAL, dispfmt, d3dmode.Format, false) == D3D_OK) {
  11.701 +				dmlist.PushBack(mode);
  11.702 +			}
  11.703 +		}
  11.704 +		adapters[i].ModeCount = dmlist.Size();	// count of the modes that are supported through HW
  11.705 +		adapters[i].Modes = new DisplayMode[adapters[i].ModeCount];
  11.706 +		ListNode<DisplayMode> *iter = dmlist.Begin();
  11.707 +		int j = 0;
  11.708 +		while(iter) {
  11.709 +			adapters[i].Modes[j++] = iter->data;
  11.710 +			iter = iter->next;
  11.711 +		}
  11.712 +
  11.713 +		// get the device capabilities
  11.714 +		d3d->GetDeviceCaps(i, D3DDEVTYPE_HAL, &adapters[i].Capabilities);
  11.715 +		int vsver_major = D3DSHADER_VERSION_MAJOR(adapters[i].Capabilities.VertexShaderVersion);
  11.716 +		int vsver_minor = D3DSHADER_VERSION_MINOR(adapters[i].Capabilities.VertexShaderVersion);
  11.717 +	}
  11.718 +}
  11.719 +
  11.720 +////////////////////////////////////
  11.721 +// ----==( CreateModesList )==----
  11.722 +// (Private Member Function)
  11.723 +// Creates a linked list of the available modes 
  11.724 +// of a single adapter for further processing
  11.725 +////////////////////////////////////
  11.726 +LinkedList<DisplayMode> *Engine3D::CreateModesList(unsigned int AdapterID) const {
  11.727 +
  11.728 +	if(AdapterID >= AdapterCount) return 0;
  11.729 +
  11.730 +	LinkedList<DisplayMode> *newlist = new LinkedList<DisplayMode>;
  11.731 +	for(unsigned int i=0; i<adapters[AdapterID].ModeCount; i++) {
  11.732 +		newlist->PushBack(adapters[AdapterID].Modes[i]);
  11.733 +	}
  11.734 +	return newlist;
  11.735 +}
  11.736 +
  11.737 +////////////////////////////////////
  11.738 +// ----==( NarrowModesList )==----
  11.739 +// (Private Member Function)
  11.740 +// Narrows down the list of available modes
  11.741 +// to those that have the requested item
  11.742 +////////////////////////////////////
  11.743 +void Engine3D::NarrowModesList(LinkedList<DisplayMode> *list, DisplayModeItem item, long value, long value2) const {
  11.744 +
  11.745 +	ListNode<DisplayMode> *iter = list->Begin();
  11.746 +	while(iter) {
  11.747 +		switch(item) {
  11.748 +		case ModeItemSize:
  11.749 +			if(iter->data.XRes != value || iter->data.YRes != value2) {
  11.750 +				iter = list->Erase(iter);
  11.751 +			} else {
  11.752 +				if(iter) iter = iter->next;
  11.753 +			}
  11.754 +			break;
  11.755 +
  11.756 +		case ModeItemBpp:
  11.757 +			if(iter->data.ColorFormat.bpp != value) {
  11.758 +				iter = list->Erase(iter);
  11.759 +			} else {
  11.760 +				if(iter) iter = iter->next;
  11.761 +			}
  11.762 +			break;
  11.763 +
  11.764 +		case ModeItemAlpha:
  11.765 +			if(!iter->data.ColorFormat.alpha && value) {
  11.766 +				iter = list->Erase(iter);
  11.767 +			} else {
  11.768 +				if(iter) iter = iter->next;
  11.769 +			}
  11.770 +			break;
  11.771 +
  11.772 +		case ModeItemRefresh:
  11.773 +			if(iter->data.RefreshRate != value) {
  11.774 +				iter = list->Erase(iter);
  11.775 +			} else {
  11.776 +				if(iter) iter = iter->next;
  11.777 +			}
  11.778 +			break;
  11.779 +
  11.780 +		default: break;
  11.781 +		}
  11.782 +	}
  11.783 +}
  11.784 +
  11.785 +///////////////////////////////////
  11.786 +// ----==( ChooseBestMode )==----
  11.787 +// (Private Member Function)
  11.788 +// given a (ideally) narrowed down modes list
  11.789 +// choose the best possible among them
  11.790 +///////////////////////////////////
  11.791 +DisplayMode Engine3D::ChooseBestMode(LinkedList<DisplayMode> *modes) const {
  11.792 +
  11.793 +	DisplayMode dmode;
  11.794 +	memset(&dmode, 0, sizeof(DisplayMode));
  11.795 +
  11.796 +	if(!modes || !modes->Size()) return dmode;
  11.797 +
  11.798 +	// find the highest resolution and get only the modes with that resolution
  11.799 +	ListNode<DisplayMode> *iter = modes->Begin();
  11.800 +	unsigned int maxx = 0, maxy = 0;
  11.801 +	while(iter) {
  11.802 +		if(iter->data.XRes > maxx) maxx = iter->data.XRes;
  11.803 +		if(iter->data.YRes > maxy) maxy = iter->data.YRes;
  11.804 +		iter = iter->next;
  11.805 +	}
  11.806 +	NarrowModesList(modes, ModeItemSize, maxx, maxy);
  11.807 +
  11.808 +	// find the modes with alpha if any
  11.809 +	iter = modes->Begin();
  11.810 +	bool AnyWithAlpha = false;
  11.811 +	while(iter) {
  11.812 +		if(iter->data.ColorFormat.alpha) {
  11.813 +			AnyWithAlpha = true;
  11.814 +			break;
  11.815 +		}
  11.816 +		iter = iter->next;
  11.817 +	}
  11.818 +	if(AnyWithAlpha) NarrowModesList(modes, ModeItemAlpha, 1);
  11.819 +
  11.820 +	// find the modes with the highest bpp
  11.821 +	iter = modes->Begin();
  11.822 +	int maxbpp = 0;
  11.823 +	while(iter) {
  11.824 +		if(iter->data.ColorFormat.bpp > maxbpp) maxbpp = iter->data.ColorFormat.bpp;
  11.825 +		iter = iter->next;
  11.826 +	}
  11.827 +	NarrowModesList(modes, ModeItemBpp, maxbpp);
  11.828 +
  11.829 +	// find the modes with the highest refresh rate
  11.830 +	iter = modes->Begin();
  11.831 +	unsigned int maxrefresh = 0;
  11.832 +	while(iter) {
  11.833 +		if(iter->data.RefreshRate > maxrefresh) maxrefresh = iter->data.RefreshRate;
  11.834 +		iter = iter->next;
  11.835 +	}
  11.836 +	NarrowModesList(modes, ModeItemRefresh, maxrefresh);
  11.837 +
  11.838 +	// if there is more than one mode left, then there is a problem :)
  11.839 +	assert(modes->Size() == 1);
  11.840 +	
  11.841 +	dmode = modes->Begin()->data;
  11.842 +	return dmode;
  11.843 +}
  11.844 +
  11.845 +//////////////////////////////////////////
  11.846 +// ----==( CreateGraphicsContext )==----
  11.847 +// (Public Member Function)
  11.848 +// Creates a graphics context with the specified parameters
  11.849 +//////////////////////////////////////////
  11.850 +GraphicsContext *Engine3D::CreateGraphicsContext(HWND WindowHandle, unsigned int AdapterID, ContextInitParameters *GCParams) {
  11.851 +
  11.852 +	if(AdapterID >= AdapterCount) return 0;
  11.853 +
  11.854 +	// check adapter's Transformation & Lighting capability
  11.855 +	bool hwtnl = (bool)(adapters[AdapterID].Capabilities.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT);	
  11.856 +	if(!(GCParams->DontCareFlags & GCPDONTCARE_TNL)) {	// bit not set, we want specific TnL mode
  11.857 +		if(hwtnl != GCParams->HardwareTnL && !hwtnl) return 0;	// we asked for hw tnl and is not available
  11.858 +		// else either we asked for sw and found hw so we continue with our initial sw setting
  11.859 +		// or we found exactly what we asked, so we still continue with our choice
  11.860 +	} else {
  11.861 +		GCParams->HardwareTnL = hwtnl;	// if we don't care use what we have available
  11.862 +	}
  11.863 +
  11.864 +	// decide which mode to use
  11.865 +	LinkedList<DisplayMode> *modes = CreateModesList(AdapterID);
  11.866 +	NarrowModesList(modes, ModeItemSize, GCParams->x, GCParams->y);
  11.867 +
  11.868 +	if(!(GCParams->DontCareFlags & GCPDONTCARE_BPP)) {	// we want specific bpp
  11.869 +		NarrowModesList(modes, ModeItemBpp, GCParams->bpp);
  11.870 +	}
  11.871 +
  11.872 +	if(!(GCParams->DontCareFlags & GCPDONTCARE_ALPHA)) {	// alpha setting exactly as asked
  11.873 +		NarrowModesList(modes, ModeItemAlpha, (long)GCParams->AlphaChannel);
  11.874 +	}
  11.875 +
  11.876 +	if(!(GCParams->DontCareFlags & GCPDONTCARE_REFRESH)) {	// specific refresh rate
  11.877 +		NarrowModesList(modes, ModeItemRefresh, GCParams->RefreshRate);
  11.878 +	}
  11.879 +
  11.880 +	if(!modes->Size()) {	// didn't find any mode with the properties that we asked
  11.881 +		throw EngineInitException("Requested video mode parameters not available");
  11.882 +	}
  11.883 +
  11.884 +	DisplayMode mode = ChooseBestMode(modes);
  11.885 +	delete modes;	// delete the list of modes
  11.886 +
  11.887 +	D3DFORMAT PixelFormat = GetPixelFormatFromColorDepth(mode.ColorFormat);
  11.888 +
  11.889 +	// find out if we have the requested zbuffer format avaialble
  11.890 +	if(!GCParams->DepthBits) GCParams->DepthBits = 32;	// not specified, trying highest possible first
  11.891 +	D3DFORMAT zfmt = GetDepthStencilFormat(GCParams->DepthBits, true);
  11.892 +
  11.893 +	bool res = !(bool)d3d->CheckDeviceFormat(AdapterID, (D3DDEVTYPE)GCParams->DevType, PixelFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, zfmt);
  11.894 +	if(!res) {	// try a format without stencil
  11.895 +		zfmt = GetDepthStencilFormat(GCParams->DepthBits, false);
  11.896 +		res = !(bool)d3d->CheckDeviceFormat(AdapterID, (D3DDEVTYPE)GCParams->DevType, PixelFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, zfmt);
  11.897 +	}
  11.898 +
  11.899 +	if(!res) {	// didn't find requested zbuffer even with no stencil
  11.900 +		// if we asked for specific zformat and didn't find it or if the zbuffer that
  11.901 +		// we failed to set was 16bits and can't go less, bail out
  11.902 +		if(!(GCParams->DontCareFlags & GCPDONTCARE_DEPTH) || GCParams->DepthBits == 16) return 0;
  11.903 +
  11.904 +		// try to set a smaller zbuffer with stencil
  11.905 +		GCParams->DepthBits = 16;
  11.906 +		zfmt = GetDepthStencilFormat(GCParams->DepthBits, true);
  11.907 +		res = !(bool)d3d->CheckDeviceFormat(AdapterID, (D3DDEVTYPE)GCParams->DevType, PixelFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, zfmt);
  11.908 +		if(!res) {	// try a format without stencil
  11.909 +			zfmt = GetDepthStencilFormat(GCParams->DepthBits, false);
  11.910 +			res = !(bool)d3d->CheckDeviceFormat(AdapterID, (D3DDEVTYPE)GCParams->DevType, PixelFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, zfmt);
  11.911 +		}
  11.912 +
  11.913 +		if(!res) throw EngineInitException("Requested ZBuffer depth not available");
  11.914 +	}
  11.915 +
  11.916 +	int AASamples = 0;
  11.917 +	if(GCParams->Antialiasing) {
  11.918 +		if(GCParams->BestAA) {
  11.919 +            // find the best supported AA mode
  11.920 +			for(AASamples=16; AASamples > 0; AASamples--) {
  11.921 +				long result = d3d->CheckDeviceMultiSampleType(AdapterID, (D3DDEVTYPE)GCParams->DevType, PixelFormat, !GCParams->FullScreen, (D3DMULTISAMPLE_TYPE)AASamples);
  11.922 +				if(result == D3D_OK) break;
  11.923 +			}
  11.924 +		} else {
  11.925 +			// check for cheap AA
  11.926 +			AASamples = 2;
  11.927 +			long result = d3d->CheckDeviceMultiSampleType(AdapterID, (D3DDEVTYPE)GCParams->DevType, PixelFormat, !GCParams->FullScreen, (D3DMULTISAMPLE_TYPE)AASamples);
  11.928 +			if(result != D3D_OK) AASamples = 0;
  11.929 +		}
  11.930 +
  11.931 +		if(!AASamples && !(GCParams->DontCareFlags & GCPDONTCARE_AA)) {
  11.932 +			throw EngineInitException("Requested Antialiasing mode not available");
  11.933 +		}
  11.934 +	}	
  11.935 +
  11.936 +	D3DFORMAT FinalColorFormat;
  11.937 +	if(GCParams->FullScreen) {
  11.938 +        FinalColorFormat = GetPixelFormatFromColorDepth(mode.ColorFormat);
  11.939 +	} else {
  11.940 +		D3DDISPLAYMODE CurrentMode;
  11.941 +		d3d->GetAdapterDisplayMode(AdapterID, &CurrentMode);
  11.942 +		FinalColorFormat = CurrentMode.Format;
  11.943 +	}
  11.944 +
  11.945 +	// if everything went well, now we can set that mode
  11.946 +	D3DPRESENT_PARAMETERS d3dppar;
  11.947 +	d3dppar.BackBufferWidth = GCParams->x;
  11.948 +	d3dppar.BackBufferHeight = GCParams->y;
  11.949 +	d3dppar.BackBufferFormat = FinalColorFormat;
  11.950 +	d3dppar.BackBufferCount = (unsigned int)GCParams->Buffers;
  11.951 +	d3dppar.MultiSampleType = (D3DMULTISAMPLE_TYPE)AASamples;
  11.952 +	d3dppar.SwapEffect = D3DSWAPEFFECT_DISCARD;
  11.953 +	d3dppar.hDeviceWindow = WindowHandle;
  11.954 +	d3dppar.Windowed = !GCParams->FullScreen;
  11.955 +	d3dppar.EnableAutoDepthStencil = true;
  11.956 +	d3dppar.AutoDepthStencilFormat = zfmt;
  11.957 +	d3dppar.Flags = 0;
  11.958 +	d3dppar.FullScreen_RefreshRateInHz = (GCParams->FullScreen) ? mode.RefreshRate : 0;
  11.959 +	if(GCParams->FullScreen) {
  11.960 +		d3dppar.FullScreen_PresentationInterval = (GCParams->VSync) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
  11.961 +	} else {
  11.962 +		d3dppar.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
  11.963 +	}
  11.964 +
  11.965 +	// create the rendering context
  11.966 +	GraphicsContext *gc = new GraphicsContext;
  11.967 +
  11.968 +	TnLMode tnlmode = (GCParams->HardwareTnL) ? HardwareTnL : SoftwareTnL;
  11.969 +
  11.970 +	long result = d3d->CreateDevice(AdapterID, (D3DDEVTYPE)GCParams->DevType, WindowHandle, tnlmode, &d3dppar, &gc->D3DDevice);
  11.971 +	if(result != D3D_OK) {
  11.972 +		if(d3dppar.BackBufferCount != GCParams->Buffers) {
  11.973 +            if((GCParams->DontCareFlags & GCPDONTCARE_BUFFERS)) {
  11.974 +				result = d3d->CreateDevice(AdapterID, (D3DDEVTYPE)GCParams->DevType, WindowHandle, tnlmode, &d3dppar, &gc->D3DDevice);
  11.975 +			} else {
  11.976 +				throw EngineInitException("Could not create Direct3D device");
  11.977 +			}
  11.978 +		}
  11.979 +	}
  11.980 +
  11.981 +	if(result != D3D_OK) {
  11.982 +		throw EngineInitException("Could not create Direct3D device");
  11.983 +	}
  11.984 +
  11.985 +	gc->WindowHandle = WindowHandle;
  11.986 +	gc->D3DDevice->GetRenderTarget(&gc->MainRenderTarget.ColorSurface);
  11.987 +	gc->D3DDevice->GetDepthStencilSurface(&gc->MainRenderTarget.DepthStencilSurface);
  11.988 +	gc->ContextParams = *GCParams;
  11.989 +	gc->ZFormat = zfmt;
  11.990 +	gc->AASamples = AASamples;
  11.991 +	gc->ColorFormat = FinalColorFormat;
  11.992 +	gc->MaxTextureStages = adapters[AdapterID].Capabilities.MaxSimultaneousTextures;
  11.993 +	gc->texman = new TextureManager(gc);
  11.994 +
  11.995 +	gc->SetDefaultStates();
  11.996 +	
  11.997 +	GraphicsContexts.push_back(gc);
  11.998 +
  11.999 +	return gc;	
 11.1000 +}
 11.1001 +
 11.1002 +//////////////////////////////////////////
 11.1003 +// ----==( CreateGraphicsContext )==----
 11.1004 +// (Public Member Function)
 11.1005 +// Creates a graphics context with the specified parameters
 11.1006 +// Light version, basic info passed, fills in the rest
 11.1007 +//////////////////////////////////////////
 11.1008 +GraphicsContext *Engine3D::CreateGraphicsContext(HWND WindowHandle, int x, int y, int bpp, word flags) {
 11.1009 +
 11.1010 +	ContextInitParameters gcp;
 11.1011 +	gcp.x = x;
 11.1012 +	gcp.y = y;
 11.1013 +	gcp.bpp = bpp;
 11.1014 +	gcp.DepthBits = 24;
 11.1015 +	gcp.DevType = DeviceHardware;
 11.1016 +	gcp.FullScreen = (flags & GCCREATE_FULLSCREEN) ? true : false;
 11.1017 +	gcp.HardwareTnL = true;
 11.1018 +	gcp.RefreshRate = 75;
 11.1019 +	gcp.Antialiasing = false;
 11.1020 +	gcp.Buffers = DoubleBuffering;
 11.1021 +	gcp.VSync = false;
 11.1022 +	gcp.DontCareFlags = GCPDONTCARE_DEPTH | GCPDONTCARE_REFRESH | GCPDONTCARE_ALPHA | GCPDONTCARE_VSYNC;
 11.1023 +
 11.1024 +	return CreateGraphicsContext(WindowHandle, D3DADAPTER_DEFAULT, &gcp);
 11.1025 +}
 11.1026 +
 11.1027 +using std::string;
 11.1028 +using std::getline;
 11.1029 +
 11.1030 +string GetValue(string line) {
 11.1031 +	int nexttoken = (int)line.find("=") + 1;
 11.1032 +	while(line[++nexttoken] == ' ');
 11.1033 +	int tokenend = (int)line.find_first_of(" \n\r\t");
 11.1034 +	return line.substr(nexttoken, tokenend - nexttoken);
 11.1035 +}
 11.1036 +
 11.1037 +ContextInitParameters Engine3D::LoadContextParamsConfigFile(const char *cfgfilename) {
 11.1038 +	ContextInitParameters cip;
 11.1039 +	memset(&cip, 0, sizeof(ContextInitParameters));
 11.1040 +
 11.1041 +	std::ifstream file(cfgfilename);
 11.1042 +	if(!file.is_open()) throw EngineInitException("Could not open configuration file");
 11.1043 +
 11.1044 +	string line;
 11.1045 +	getline(file, line);
 11.1046 +	while(!file.eof()) {
 11.1047 +		if(line[0] != ';' && line[0] != '\n' && line[0] != '\r' && line[0] != ' ') {
 11.1048 +			int tokenend = (int)line.find(" ");
 11.1049 +			string token = line.substr(0, tokenend);
 11.1050 +
 11.1051 +			if(token == "fullscreen") {
 11.1052 +				string value = GetValue(line);
 11.1053 +				cip.FullScreen = (value == "true") ? true : false;
 11.1054 +			} else if(token == "resolution") {
 11.1055 +                string value = GetValue(line);
 11.1056 +				int x = (int)value.find("x");
 11.1057 +				cip.x = atoi(value.substr(0, x).c_str());
 11.1058 +				cip.y = atoi(value.substr(x+1, value.size()).c_str());
 11.1059 +			} else if(token == "bpp") {
 11.1060 +				cip.bpp = atoi(GetValue(line).c_str());
 11.1061 +			} else if(token == "zbufferdepth") {
 11.1062 +				cip.DepthBits = atoi(GetValue(line).c_str());
 11.1063 +			} else if(token == "device") {
 11.1064 +				cip.DevType = (GetValue(line) == "ref") ? DeviceReference : DeviceHardware;
 11.1065 +			} else if(token == "tnl") {
 11.1066 +				cip.HardwareTnL = (GetValue(line) == "false") ? false : true;
 11.1067 +			} else if(token == "refresh") {
 11.1068 +				cip.RefreshRate = atoi(GetValue(line).c_str());
 11.1069 +			} else if(token == "antialiasing") {
 11.1070 +				string value = GetValue(line);
 11.1071 +				cip.Antialiasing = (value == "none") ? false : true;
 11.1072 +				if(cip.Antialiasing) {
 11.1073 +					cip.BestAA = (value == "speed" || value == "low") ? false : true;
 11.1074 +				}
 11.1075 +			} else if(token == "flipchain") {
 11.1076 +				cip.Buffers = (GetValue(line) == "triplebuffering") ? TripleBuffering : DoubleBuffering;
 11.1077 +			} else if(token == "vsync") {
 11.1078 +				cip.VSync = (GetValue(line) == "true") ? true : false;
 11.1079 +			} else if(token == "dontcareabout") {
 11.1080 +				cip.DontCareFlags = 0;
 11.1081 +				string flags = GetValue(line);
 11.1082 +                string part;
 11.1083 +				while(1) {
 11.1084 +					int begin = (int)flags.find_first_not_of(", ");
 11.1085 +					int end = (int)flags.find(",", begin) - begin;
 11.1086 +					part = flags.substr(begin, end);
 11.1087 +					//part = flags.substr(0, flags.find(","));// \n\r\t"));
 11.1088 +					if(part.empty()) break;
 11.1089 +					if(part == "bpp") cip.DontCareFlags |= GCPDONTCARE_BPP;
 11.1090 +					if(part == "refresh") cip.DontCareFlags |= GCPDONTCARE_REFRESH;
 11.1091 +					if(part == "alpha") cip.DontCareFlags |= GCPDONTCARE_ALPHA;
 11.1092 +					if(part == "zbufferdepth") cip.DontCareFlags |= GCPDONTCARE_DEPTH;
 11.1093 +					if(part == "tnl") cip.DontCareFlags |= GCPDONTCARE_TNL;
 11.1094 +					if(part == "flipchain") cip.DontCareFlags |= GCPDONTCARE_BUFFERS;
 11.1095 +					if(part == "aamode") cip.DontCareFlags |= GCPDONTCARE_AA;
 11.1096 +					if(part == "vsync") cip.DontCareFlags |= GCPDONTCARE_VSYNC;
 11.1097 +					int temp = (int)flags.find_first_of(",\n\r");
 11.1098 +					if(temp == string::npos) break;
 11.1099 +					flags.erase(0, temp+1);
 11.1100 +				}
 11.1101 +			}
 11.1102 +
 11.1103 +		}
 11.1104 +		        
 11.1105 +		getline(file, line);
 11.1106 +	}
 11.1107 +
 11.1108 +	return cip;
 11.1109 +}
 11.1110 +
 11.1111 +void Engine3D::DestroyGraphicsContext(GraphicsContext *gc) {
 11.1112 +	gc->D3DDevice->Release();
 11.1113 +}
 11.1114 +
 11.1115 +int Engine3D::GetAdapterCount() const {
 11.1116 +	return AdapterCount;
 11.1117 +}
 11.1118 +
 11.1119 +const Adapter *Engine3D::GetAdapterInfo(int adapter) const {
 11.1120 +	return &adapters[adapter];
 11.1121 +}
 11.1122 +
 11.1123 +
 11.1124 +//////////////////////////////////////////////////////////////////////////////
 11.1125 +// helper functions
 11.1126 +
 11.1127 +bool Lock(VertexBuffer *vb, Vertex **data) {
 11.1128 +	D3DVERTEXBUFFER_DESC desc;
 11.1129 +	vb->GetDesc(&desc);
 11.1130 +	dword flags = (desc.Usage & D3DUSAGE_DYNAMIC) ? D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE : 0;
 11.1131 +	
 11.1132 +	return (vb->Lock(0, 0, (byte**)data, flags) == D3D_OK);
 11.1133 +}
 11.1134 +
 11.1135 +bool Lock(IndexBuffer *ib, Index **data) {
 11.1136 +	D3DINDEXBUFFER_DESC desc;
 11.1137 +	ib->GetDesc(&desc);
 11.1138 +	dword flags = (desc.Usage & D3DUSAGE_DYNAMIC) ? D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE : 0;
 11.1139 +
 11.1140 +	return (ib->Lock(0, 0, (byte**)data, flags) == D3D_OK);
 11.1141 +}
 11.1142 +
 11.1143 +void Unlock(VertexBuffer *vb) {
 11.1144 +	vb->Unlock();
 11.1145 +}
 11.1146 +
 11.1147 +void Unlock(IndexBuffer *ib) {
 11.1148 +	ib->Unlock();
 11.1149 +}
 11.1150 +
 11.1151 +
 11.1152 +void CreateProjectionMatrix(Matrix4x4 *mat, float yFOV, float Aspect, float NearClip, float FarClip) {
 11.1153 +
 11.1154 +    float h, w, Q;
 11.1155 +	float xFOV = yFOV * Aspect;
 11.1156 + 
 11.1157 +    w = (float)(1.0f/tan(xFOV*0.5f));		// 1/tan(x) == cot(x)
 11.1158 +    h = (float)(1.0f/tan(yFOV*0.5f));		// 1/tan(x) == cot(x)
 11.1159 +    Q = FarClip / (FarClip - NearClip);
 11.1160 +	
 11.1161 +	/*	Projection Matrix
 11.1162 +	[ w     0.0f      0.0f      0.0f]
 11.1163 +	|0.0f    h        0.0f      0.0f|
 11.1164 +	|0.0f   0.0f       Q        1.0f|
 11.1165 +	[0.0f   0.0f  -Q*NearClip   0.0f]
 11.1166 +	*/
 11.1167 +
 11.1168 +	mat->ResetIdentity();
 11.1169 +    mat->m[0][0] = w;
 11.1170 +	mat->m[1][1] = h;
 11.1171 +	mat->m[2][2] = Q;
 11.1172 +	mat->m[3][2] = -Q*NearClip;
 11.1173 +	mat->m[2][3] = 1.0f;
 11.1174 +}
 11.1175 +
 11.1176 +dword PackVector(const Vector3 &vec, float Height) {
 11.1177 +	dword r = (dword)(127.0f * vec.x + 128.0f);
 11.1178 +	dword g = (dword)(127.0f * vec.y + 128.0f);
 11.1179 +	dword b = (dword)(127.0f * vec.z + 128.0f);
 11.1180 +	dword a = (dword)(255.0f * Height);
 11.1181 +    
 11.1182 +	return( (a<<24L) + (r<<16L) + (g<<8L) + (b<<0L) );
 11.1183 +}
 11.1184 +
 11.1185 +void NormalMapFromHeightField(Texture *tex) {
 11.1186 +	
 11.1187 +	// Lock the texture
 11.1188 +	D3DLOCKED_RECT d3dlr;
 11.1189 +	D3DSURFACE_DESC d3dsd;
 11.1190 +
 11.1191 +	int LevelCount = tex->GetLevelCount();
 11.1192 +	for(int i=0; i<LevelCount; i++) {
 11.1193 +		
 11.1194 +		tex->GetLevelDesc(i, &d3dsd);
 11.1195 +		tex->LockRect(i, &d3dlr, 0, 0);
 11.1196 +		DWORD* pPixel = (DWORD*)d3dlr.pBits;
 11.1197 +
 11.1198 +		// For each pixel, generate a vector normal that represents the change
 11.1199 +		// in thea height field at that pixel
 11.1200 +		for( DWORD j=0; j<d3dsd.Height; j++  ) {
 11.1201 +			for( DWORD i=0; i<d3dsd.Width; i++ ) {
 11.1202 +				DWORD color00 = pPixel[0];
 11.1203 +				DWORD color10 = pPixel[1];
 11.1204 +				DWORD color01 = pPixel[d3dlr.Pitch/sizeof(DWORD)];
 11.1205 +
 11.1206 +				float fHeight00 = (float)((color00 & 0x00ff0000) >> 16) / 255.0f;
 11.1207 +				float fHeight10 = (float)((color10 & 0x00ff0000) >> 16) / 255.0f;
 11.1208 +				float fHeight01 = (float)((color01 & 0x00ff0000) >> 16) / 255.0f;
 11.1209 +
 11.1210 +				Vector3 vPoint00(i+0.0f, j+0.0f, fHeight00);
 11.1211 +				Vector3 vPoint10(i+1.0f, j+0.0f, fHeight10);
 11.1212 +				Vector3 vPoint01(i+0.0f, j+1.0f, fHeight01);
 11.1213 +				Vector3 v10 = vPoint10 - vPoint00;
 11.1214 +				Vector3 v01 = vPoint01 - vPoint00;
 11.1215 +
 11.1216 +				Vector3 Normal = v10.CrossProduct(v01);
 11.1217 +				Normal.Normalize();
 11.1218 +
 11.1219 +				// Store the normal as an RGBA value in the normal map
 11.1220 +				*pPixel++ = PackVector(Normal, fHeight00);
 11.1221 +			}
 11.1222 +		}
 11.1223 +		tex->UnlockRect(i);
 11.1224 +	}
 11.1225 +}
 11.1226 +
 11.1227 +void UpdateMipmapChain(Texture *tex) {
 11.1228 +	D3DXFilterTexture(tex, 0, 0, D3DX_FILTER_BOX);
 11.1229 +}
 11.1230 +
 11.1231 +dword AddEdge(Edge *edges, dword EdgeCount, const Edge &newedge) {
 11.1232 +	// remove internal edges
 11.1233 +	for(dword i=0; i<EdgeCount; i++) {
 11.1234 +		if((edges[i].vertices[0] == newedge.vertices[0] && edges[i].vertices[1] == newedge.vertices[1]) || (edges[i].vertices[0] == newedge.vertices[1] && edges[i].vertices[1] == newedge.vertices[0])) {
 11.1235 +			edges[i] = edges[--EdgeCount];
 11.1236 +			return EdgeCount;
 11.1237 +		}
 11.1238 +	}
 11.1239 +
 11.1240 +    edges[EdgeCount++] = newedge;
 11.1241 +	return EdgeCount;
 11.1242 +}
 11.1243 +
 11.1244 +//#define LIGHTDIR(l, p)  (l->GetType() == LTDir ? l->GetDirection() : p - l->GetPosition())
 11.1245 +inline Vector3 GetLightDir(const Light *light, const Vector3 &pos, const Matrix4x4 &mat) {
 11.1246 +	if(light->GetType() == LTDir) {
 11.1247 +		return light->GetDirection();
 11.1248 +	} else {
 11.1249 +		Vector3 lpos = light->GetPosition();
 11.1250 +		lpos.Transform(mat);
 11.1251 +		return pos - lpos;
 11.1252 +	}
 11.1253 +	return Vector3();
 11.1254 +}
 11.1255 +		
 11.1256 +
 11.1257 +//////////////////////////////////////////
 11.1258 +// ----==( CreateShadowVolume )==----
 11.1259 +// (Helper Function)
 11.1260 +// Creates a graphics context with the specified parameters
 11.1261 +// Light version, basic info passed, fills in the rest
 11.1262 +//////////////////////////////////////////
 11.1263 +
 11.1264 +TriMesh *CreateShadowVolume(const TriMesh &mesh, const Light *light, const Matrix4x4 &MeshXForm, bool WorldCoords) {
 11.1265 +
 11.1266 +	// transform light into object's local coordinate system
 11.1267 +	//const_cast<Light*>(light)->Transform(MeshXForm.Inverse());
 11.1268 +	Matrix4x4 InvXForm = MeshXForm.Inverse();
 11.1269 +
 11.1270 +	const Vertex *varray = mesh.GetVertexArray();
 11.1271 +	const Triangle *triarray = mesh.GetTriangleArray();
 11.1272 +
 11.1273 +	dword VertexCount = mesh.GetVertexCount();
 11.1274 +	dword TriangleCount = mesh.GetTriangleCount();
 11.1275 +
 11.1276 +	Edge *edges = new Edge[TriangleCount];
 11.1277 +	dword EdgeCount = 0;
 11.1278 +
 11.1279 +	// first find the contour edges
 11.1280 +
 11.1281 +	for(dword i=0; i<TriangleCount; i++) {
 11.1282 +
 11.1283 +		// find the light vector incident at this triangle
 11.1284 +		Vertex TriVerts[3];
 11.1285 +		TriVerts[0] = varray[triarray[i].vertices[0]];
 11.1286 +		TriVerts[1] = varray[triarray[i].vertices[1]];
 11.1287 +		TriVerts[2] = varray[triarray[i].vertices[2]];
 11.1288 +
 11.1289 +		Vector3 pos = (TriVerts[0].pos + TriVerts[1].pos + TriVerts[2].pos) / 3.0f;
 11.1290 +		//Vector3 LightDir = LIGHTDIR(light, pos);
 11.1291 +		Vector3 LightDir = GetLightDir(light, pos, InvXForm);
 11.1292 +
 11.1293 +		// if it looks away from the light...
 11.1294 +		if(DotProduct(triarray[i].normal, LightDir) >= 0.0f) {
 11.1295 +			EdgeCount = AddEdge(edges, EdgeCount, Edge(triarray[i].vertices[0], triarray[i].vertices[1]));
 11.1296 +			EdgeCount = AddEdge(edges, EdgeCount, Edge(triarray[i].vertices[1], triarray[i].vertices[2]));
 11.1297 +			EdgeCount = AddEdge(edges, EdgeCount, Edge(triarray[i].vertices[2], triarray[i].vertices[0]));
 11.1298 +		}
 11.1299 +	}
 11.1300 +
 11.1301 +	// now extract the contour edges to build the shadow volume boundrary
 11.1302 +	const float ExtrudeMagnitude = 100000.0f;
 11.1303 +	Vertex *ShadowVertices = new Vertex[EdgeCount * 6];
 11.1304 +
 11.1305 +	for(dword i=0; i<EdgeCount; i++) {
 11.1306 +		Vertex QuadVert[4];
 11.1307 +		QuadVert[0] = varray[edges[i].vertices[0]];
 11.1308 +		QuadVert[1] = varray[edges[i].vertices[1]];
 11.1309 +		//QuadVert[2] = QuadVert[1].pos + (Vector3)LIGHTDIR(light, QuadVert[1].pos) * ExtrudeMagnitude;
 11.1310 +		//QuadVert[3] = QuadVert[0].pos + (Vector3)LIGHTDIR(light, QuadVert[0].pos) * ExtrudeMagnitude;
 11.1311 +		QuadVert[2] = QuadVert[1].pos + GetLightDir(light, QuadVert[1].pos, InvXForm) * ExtrudeMagnitude;
 11.1312 +		QuadVert[3] = QuadVert[0].pos + GetLightDir(light, QuadVert[0].pos, InvXForm) * ExtrudeMagnitude;
 11.1313 +
 11.1314 +        ShadowVertices[i*6] = QuadVert[0];
 11.1315 +		ShadowVertices[i*6+1] = QuadVert[1];
 11.1316 +		ShadowVertices[i*6+2] = QuadVert[2];
 11.1317 +
 11.1318 +		ShadowVertices[i*6+3] = QuadVert[0];
 11.1319 +		ShadowVertices[i*6+4] = QuadVert[2];
 11.1320 +		ShadowVertices[i*6+5] = QuadVert[3];
 11.1321 +
 11.1322 +		if(WorldCoords) {
 11.1323 +			for(int j=0; j<6; j++) {
 11.1324 +				ShadowVertices[i*6+j].pos.Transform(MeshXForm);
 11.1325 +			}
 11.1326 +		}
 11.1327 +	}
 11.1328 +
 11.1329 +	TriMesh *ShadowMesh = new TriMesh(1);
 11.1330 +	ShadowMesh->SetData(ShadowVertices, 0, EdgeCount * 6, 0);
 11.1331 +
 11.1332 +	delete [] ShadowVertices;
 11.1333 +	delete [] edges;
 11.1334 +
 11.1335 +	//const_cast<Light*>(light)->Transform(MeshXForm);	// return light to world coordinate system
 11.1336 +
 11.1337 +	return ShadowMesh;	
 11.1338 +}
 11.1339 +
 11.1340 +
 11.1341 +///////////// local //////////////
 11.1342 +
 11.1343 +ColorDepth GetColorDepthFromPixelFormat(D3DFORMAT fmt) {
 11.1344 +	switch(fmt) {
 11.1345 +	case D3DFMT_R8G8B8: return ColorDepth(24, 24, 0);
 11.1346 +	case D3DFMT_A8R8G8B8: return ColorDepth(32, 24, 8);
 11.1347 +	case D3DFMT_X8R8G8B8: return ColorDepth(32, 24, 0);
 11.1348 +	case D3DFMT_R5G6B5: return ColorDepth(16, 16, 0);
 11.1349 +	case D3DFMT_X1R5G5B5: return ColorDepth(16, 15, 0);
 11.1350 +	case D3DFMT_A1R5G5B5: return ColorDepth(16, 15, 1);
 11.1351 +	case D3DFMT_P8: return ColorDepth(8, 8, 0);
 11.1352 +	default: return ColorDepth(0, 0, 0);
 11.1353 +	}
 11.1354 +}
 11.1355 +
 11.1356 +bool operator ==(const ColorDepth &lhs, const ColorDepth &rhs) {
 11.1357 +	return (lhs.bpp == rhs.bpp && lhs.colorbits == rhs.colorbits && lhs.alpha == rhs.alpha);
 11.1358 +}
 11.1359 +
 11.1360 +D3DFORMAT GetPixelFormatFromColorDepth(ColorDepth cd, bool noalpha) {
 11.1361 +	if(cd == ColorDepth(24, 24, 0)) return D3DFMT_R8G8B8;
 11.1362 +	if(cd == ColorDepth(32, 24, 8)) return noalpha ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8;
 11.1363 +	if(cd == ColorDepth(32, 24, 0)) return D3DFMT_X8R8G8B8;
 11.1364 +	if(cd == ColorDepth(16, 16, 0)) return D3DFMT_R5G6B5;
 11.1365 +	if(cd == ColorDepth(16, 15, 0)) return D3DFMT_X1R5G5B5;
 11.1366 +	if(cd == ColorDepth(16, 15, 1)) return noalpha ? D3DFMT_X1R5G5B5 : D3DFMT_A1R5G5B5;
 11.1367 +	if(cd == ColorDepth(8, 8, 0)) return D3DFMT_P8;
 11.1368 +	return (D3DFORMAT)0;
 11.1369 +}
 11.1370 +
 11.1371 +
 11.1372 +D3DFORMAT GetDepthStencilFormat(int depthbits, bool stencil) {
 11.1373 +	switch(depthbits) {
 11.1374 +	case 32: 
 11.1375 +		return (stencil) ? D3DFMT_D24S8 : D3DFMT_D32;
 11.1376 +		break;
 11.1377 +
 11.1378 +	case 24:
 11.1379 +		return (stencil) ? D3DFMT_D24S8 : D3DFMT_D24X8;
 11.1380 +		break;
 11.1381 +
 11.1382 +	case 16:
 11.1383 +		return (stencil) ? D3DFMT_D15S1 : D3DFMT_D16;
 11.1384 +		break;
 11.1385 +
 11.1386 +	default:
 11.1387 +		break;
 11.1388 +	}
 11.1389 +
 11.1390 +	return (D3DFORMAT)0;
 11.1391 +}
 11.1392 \ No newline at end of file
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/3deng/3dengine.h	Thu Oct 23 01:46:07 2014 +0300
    12.3 @@ -0,0 +1,391 @@
    12.4 +#ifndef _3DENGINE_H_
    12.5 +#define _3DENGINE_H_
    12.6 +
    12.7 +// standard includes
    12.8 +#include <vector>
    12.9 +// system includes
   12.10 +#include "d3d8.h"
   12.11 +// includes from my codebase
   12.12 +#include "typedefs.h"
   12.13 +#include "linkedlist.h"
   12.14 +#include "color.h"
   12.15 +// 3d engine includes
   12.16 +#include "n3dmath.h"
   12.17 +#include "switches.h"
   12.18 +#include "3dengtypes.h"
   12.19 +#include "material.h"
   12.20 +#include "textureman.h"
   12.21 +#include "3dgeom.h"
   12.22 +
   12.23 +enum DeviceType {DeviceHardware = D3DDEVTYPE_HAL, DeviceReference = D3DDEVTYPE_REF};
   12.24 +enum TnLMode {HardwareTnL = D3DCREATE_HARDWARE_VERTEXPROCESSING, SoftwareTnL = D3DCREATE_SOFTWARE_VERTEXPROCESSING};
   12.25 +enum BufferChainMode {DoubleBuffering = 1, TripleBuffering = 2};
   12.26 +enum UsageFlags {UsageStatic = 0, UsageDynamic = D3DUSAGE_DYNAMIC};
   12.27 +enum ShadeMode {FlatShading = D3DSHADE_FLAT, GouraudShading = D3DSHADE_GOURAUD};
   12.28 +enum FaceOrder {Clockwise = D3DCULL_CW, CounterClockwise = D3DCULL_CCW};
   12.29 +
   12.30 +enum PhongComponent {Ambient, Diffuse, Specular};
   12.31 +
   12.32 +enum PrimitiveType {
   12.33 +	TriangleList	= D3DPT_TRIANGLELIST,
   12.34 +	TriangleStrip	= D3DPT_TRIANGLESTRIP,
   12.35 +	TriangleFan		= D3DPT_TRIANGLEFAN,
   12.36 +	LineList		= D3DPT_LINELIST,
   12.37 +	LineStrip		= D3DPT_LINESTRIP,
   12.38 +	PointList		= D3DPT_POINTLIST
   12.39 +};
   12.40 +
   12.41 +enum BlendingFactor {
   12.42 +	BLEND_ZERO			= D3DBLEND_ZERO,
   12.43 +	BLEND_ONE			= D3DBLEND_ONE,
   12.44 +	BLEND_SRCCOLOR		= D3DBLEND_SRCCOLOR,
   12.45 +	BLEND_INVSRCCOLOR	= D3DBLEND_INVSRCCOLOR,
   12.46 +	BLEND_SRCALPHA		= D3DBLEND_SRCALPHA,
   12.47 +	BLEND_INVSRCALPHA	= D3DBLEND_INVSRCALPHA,
   12.48 +	BLEND_DESTCOLOR		= D3DBLEND_DESTCOLOR,
   12.49 +	BLEND_INVDESTCOLOR	= D3DBLEND_INVDESTCOLOR,
   12.50 +	BLEND_DESTALPHA		= D3DBLEND_DESTALPHA,
   12.51 +	BLEND_INVDESTALPHA	= D3DBLEND_INVDESTALPHA,
   12.52 +	BLEND_SRCALPHASAT	= D3DBLEND_SRCALPHASAT
   12.53 +};
   12.54 +
   12.55 +enum CmpFunc {
   12.56 +	CMP_NEVER		= D3DCMP_NEVER,
   12.57 +    CMP_LESS		= D3DCMP_LESS,
   12.58 +    CMP_EQUAL		= D3DCMP_EQUAL,
   12.59 +    CMP_LEQUAL		= D3DCMP_LESSEQUAL,
   12.60 +    CMP_GREATER		= D3DCMP_GREATER,
   12.61 +    CMP_NOTEQUAL	= D3DCMP_NOTEQUAL,
   12.62 +    CMP_GEQUAL		= D3DCMP_GREATEREQUAL,
   12.63 +    CMP_ALWAYS		= D3DCMP_ALWAYS
   12.64 +};
   12.65 +
   12.66 +enum StencilOp {
   12.67 +	SOP_KEEP		= D3DSTENCILOP_KEEP,
   12.68 +    SOP_ZERO		= D3DSTENCILOP_ZERO,
   12.69 +    SOP_REPLACE		= D3DSTENCILOP_REPLACE,
   12.70 +    SOP_INCSAT		= D3DSTENCILOP_INCRSAT,
   12.71 +    SOP_DECSAT		= D3DSTENCILOP_DECRSAT,
   12.72 +    SOP_INVERT		= D3DSTENCILOP_INVERT,
   12.73 +    SOP_INC			= D3DSTENCILOP_INCR,
   12.74 +    SOP_DEC			= D3DSTENCILOP_DECR
   12.75 +};
   12.76 +
   12.77 +enum TextureBlendFunction {
   12.78 +	TexBlendSelectArg1			= D3DTOP_SELECTARG1,			// S[rgba] = Arg1
   12.79 +	TexBlendSelectArg2			= D3DTOP_SELECTARG2,			// S[rgba] = Arg2
   12.80 +	TexBlendAdd					= D3DTOP_ADD,					// S[rgba] = Arg1 + Arg2
   12.81 +	TexBlendAddSigned			= D3DTOP_ADDSIGNED,				// S[rgba] = Arg1 + Arg2 - 0.5
   12.82 +	TexBlendAddSigned2x			= D3DTOP_ADDSIGNED2X,			// S[rgba] = (Arg1 + Arg2 - 0.5) << 1
   12.83 +	TexBlendSubtract			= D3DTOP_SUBTRACT,				// S[rgba] = Arg1 - Arg2
   12.84 +	TexBlendAddSmooth			= D3DTOP_ADDSMOOTH,				// S[rgba] = (Arg1 + Arg2) - (Arg1 * Arg2)
   12.85 +	TexBlendModulate			= D3DTOP_MODULATE,				// S[rgba] = Arg1 * Arg2
   12.86 +	TexBlendModulate2x			= D3DTOP_MODULATE2X,			// S[rgba] = (Arg1 * Arg2) << 1
   12.87 +	TexBlendModulate4x			= D3DTOP_MODULATE4X,			// S[rgba] = (Arg1 * Arg2) << 2
   12.88 +	TexBlendVertexAlpha			= D3DTOP_BLENDDIFFUSEALPHA,		// S[rgba] = Arg1*Alpha + Arg2*(1-Alpha)
   12.89 +	TexBlendTextureAlpha		= D3DTOP_BLENDTEXTUREALPHA,		// S[rgba] = Arg1*Alpha + Arg2*(1-Alpha)
   12.90 +	TexBlendFactorAlpha			= D3DTOP_BLENDFACTORALPHA,		// S[rgba] = Arg1*Alpha + Arg2*(1-Alpha)
   12.91 +	TexBlendPrevAlpha			= D3DTOP_BLENDFACTORALPHA,		// S[rgba] = Arg1*Alpha + Arg2*(1-Alpha)
   12.92 +	TexBlendPreMulAlpha			= D3DTOP_BLENDTEXTUREALPHAPM,	// S[rgba] = Arg1 + Arg2*(1-Alpha)
   12.93 +	TexBlendPreModulate			= D3DTOP_PREMODULATE,
   12.94 +	TexBlendModAlphaAddColor	= D3DTOP_MODULATEALPHA_ADDCOLOR,// S[rgba] = Arg1[rgb] + Arg1[a] * Arg2[rgb]
   12.95 +	TexBlendModulateAddAlpha	= D3DTOP_MODULATECOLOR_ADDALPHA,// S[rgba] = Arg1[rgb] * Arg2[rgb] + Arg1[a]
   12.96 +	TexBlendModInvAlphaAddColor	= D3DTOP_MODULATEINVALPHA_ADDCOLOR,	// S[rgba] = Arg1[rgb] + (1-Arg1[a]) * Arg2[rgb]
   12.97 +	TexBlendModulateInvAddAlpha	= D3DTOP_MODULATEINVCOLOR_ADDALPHA,	// S[rgba] = (1-Arg1[rgb]) * Arg2[rgb] + Arg1[a]
   12.98 +	TexBlendBumpEnv				= D3DTOP_BUMPENVMAP,			// bump mapping with next stage's env map
   12.99 +	TexBlendBumpEnvLuminance	= D3DTOP_BUMPENVMAPLUMINANCE,	// bump mapping with next stage's env map with luminance
  12.100 +	TexBlendDotProduct			= D3DTOP_DOTPRODUCT3,			// S[rgba] = Arg1[rgb] (dot) Arg2[rgb]
  12.101 +	TexBlendMultiplyAdd			= D3DTOP_MULTIPLYADD,			// S[rgba] = Arg1 + Arg2 * Arg3
  12.102 +	TexBlendLerp				= D3DTOP_LERP					// S[rgba] = Arg2 + (Arg3 - Arg2) * Arg1
  12.103 +};
  12.104 +
  12.105 +enum TextureBlendArgument {
  12.106 +	TexArgNone			= 0,	// valid only for arg3
  12.107 +	TexArgCurrent		= D3DTA_CURRENT,	// the color from the previous stage output (diffuse for 1st)
  12.108 +	TexArgDiffuseColor	= D3DTA_DIFFUSE,	// the diffuse interpolated color
  12.109 +	TexArgSpecularColor	= D3DTA_SPECULAR,	// the specular interpolated color
  12.110 +	TexArgTexture		= D3DTA_TEXTURE,	// the texture bound to this stage
  12.111 +	TexArgFactor		= D3DTA_TFACTOR,	// a user defined factor
  12.112 +	TexArgTemp			= D3DTA_TEMP		// temp register
  12.113 +};
  12.114 +
  12.115 +enum TextureFilteringType {
  12.116 +	PointSampling,
  12.117 +	BilinearFiltering, 
  12.118 +	TrilinearFiltering, 
  12.119 +	AnisotropicFiltering
  12.120 +};
  12.121 +
  12.122 +enum TextureAddressing {
  12.123 +    TexAddrWrap			= D3DTADDRESS_WRAP,
  12.124 +    TexAddrMirror		= D3DTADDRESS_MIRROR,
  12.125 +    TexAddrClamp		= D3DTADDRESS_CLAMP,
  12.126 +    TexAddrBorder		= D3DTADDRESS_BORDER,
  12.127 +    TexAddrMirrorOnce	= D3DTADDRESS_MIRRORONCE
  12.128 +};
  12.129 +
  12.130 +enum TexTransformState {
  12.131 +	TexTransformDisable		= D3DTTFF_DISABLE,
  12.132 +	TexTransform1D			= D3DTTFF_COUNT1,
  12.133 +	TexTransform2D			= D3DTTFF_COUNT2,
  12.134 +	TexTransform3D			= D3DTTFF_COUNT3,
  12.135 +	TexTransform4D			= D3DTTFF_COUNT4,
  12.136 +	TexTransformProjected	= D3DTTFF_PROJECTED
  12.137 +};
  12.138 +
  12.139 +// don't care flags for context creation
  12.140 +const unsigned short GCPDONTCARE_NONE		= 0;	// 0000000000000000
  12.141 +const unsigned short GCPDONTCARE_BPP		= 1;	// 0000000000000001
  12.142 +const unsigned short GCPDONTCARE_REFRESH	= 2;	// 0000000000000010
  12.143 +const unsigned short GCPDONTCARE_ALPHA		= 4;	// 0000000000000100
  12.144 +const unsigned short GCPDONTCARE_DEPTH		= 8;	// 0000000000001000
  12.145 +const unsigned short GCPDONTCARE_TNL		= 16;	// 0000000000010000
  12.146 +const unsigned short GCPDONTCARE_BUFFERS	= 32;	// 0000000000100000
  12.147 +const unsigned short GCPDONTCARE_AA			= 64;	// 0000000001000000
  12.148 +const unsigned short GCPDONTCARE_VSYNC		= 128;	// 0000000010000000
  12.149 +
  12.150 +// fullscreen / windowed flags
  12.151 +const unsigned short GCCREATE_WINDOWED		= 0;
  12.152 +const unsigned short GCCREATE_FULLSCREEN	= 1;
  12.153 +
  12.154 +
  12.155 +
  12.156 +class Vertex;
  12.157 +
  12.158 +struct ColorDepth {
  12.159 +	int bpp, colorbits, alpha;
  12.160 +
  12.161 +	ColorDepth(int bits=0, int c=0, int a=0) {colorbits = c; alpha = a; bpp = bits; }
  12.162 +};
  12.163 +
  12.164 +struct DisplayMode {
  12.165 +	unsigned int XRes, YRes, RefreshRate;
  12.166 +	ColorDepth ColorFormat;
  12.167 +};
  12.168 +
  12.169 +enum DisplayModeItem {ModeItemSize, ModeItemBpp, ModeItemAlpha, ModeItemRefresh};
  12.170 +
  12.171 +struct Adapter {
  12.172 +	char *Driver, *Description;	
  12.173 +	int64 DriverVersion;
  12.174 +	dword VentorID, DeviceID, SubSysID, Revision;
  12.175 +	GUID DeviceGUID;
  12.176 +
  12.177 +	unsigned int ModeCount;
  12.178 +	DisplayMode *Modes;
  12.179 +	D3DCAPS8 Capabilities;
  12.180 +};
  12.181 +
  12.182 +struct RenderTarget {
  12.183 +	Surface *ColorSurface, *DepthStencilSurface;
  12.184 +};
  12.185 +
  12.186 +struct RenderParams {
  12.187 +	ShadeMode Shading;
  12.188 +	bool Billboarded;
  12.189 +	dword VertexProgram;
  12.190 +	dword PixelProgram;
  12.191 +	bool ZWrite;
  12.192 +	BlendingFactor SourceBlendFactor, DestBlendFactor;
  12.193 +};
  12.194 +
  12.195 +struct ContextInitParameters {
  12.196 +	int x, y;
  12.197 +	int bpp;
  12.198 +	int RefreshRate;
  12.199 +	bool AlphaChannel;
  12.200 +	int DepthBits;
  12.201 +	DeviceType DevType;
  12.202 +	bool HardwareTnL;
  12.203 +	bool FullScreen;
  12.204 +	bool Antialiasing;
  12.205 +	bool BestAA;
  12.206 +	bool VSync;
  12.207 +	BufferChainMode Buffers;
  12.208 +	unsigned short DontCareFlags;
  12.209 +};
  12.210 +
  12.211 +
  12.212 +class GraphicsContext {
  12.213 +private:
  12.214 +	PrimitiveType ptype;
  12.215 +	FaceOrder CullOrder;
  12.216 +	bool BackfaceCulling;
  12.217 +	bool MipMapEnabled;
  12.218 +	bool BillBoardingEnabled;
  12.219 +	dword MipFilter;
  12.220 +	
  12.221 +	// cache of current transformation matrices
  12.222 +	Matrix4x4 WorldMat[256], ViewMat, ProjMat, TexMat[8];
  12.223 +
  12.224 +	// disable copying contexts by making copy constructor and assignment private
  12.225 +	GraphicsContext(const GraphicsContext &gc);
  12.226 +	const GraphicsContext &operator =(const GraphicsContext &gc);
  12.227 +
  12.228 +public:
  12.229 +	HWND WindowHandle;
  12.230 +	RenderTarget MainRenderTarget;
  12.231 +	IDirect3DDevice8 *D3DDevice;
  12.232 +	ContextInitParameters ContextParams;
  12.233 +	D3DFORMAT ColorFormat, ZFormat;
  12.234 +	int AASamples;
  12.235 +	int MaxTextureStages;
  12.236 +
  12.237 +	TextureManager *texman;		// texture manager
  12.238 +	
  12.239 +	GraphicsContext();
  12.240 +
  12.241 +	void SetDefaultStates();
  12.242 +
  12.243 +	bool CreateVertexBuffer(uint32 VertexCount, UsageFlags usage, VertexBuffer **vb) const;
  12.244 +	bool CreateIndexBuffer(uint32 IndexCount, UsageFlags usage, IndexBuffer **ib) const;
  12.245 +
  12.246 +	bool CreateSurface(uint32 Width, uint32 Height, Surface **surf) const;
  12.247 +	bool CreateDepthStencil(uint32 Width, uint32 Height, Surface **zsurf) const;
  12.248 +
  12.249 +	void Clear(dword color) const;
  12.250 +	void ClearZBuffer(float zval) const;
  12.251 +	void ClearStencil(byte sval) const;
  12.252 +	void ClearZBufferStencil(float zval, byte sval) const;
  12.253 +
  12.254 +	void Flip() const;
  12.255 +
  12.256 +	bool Draw(VertexBuffer *vb);
  12.257 +	bool Draw(Vertex *varray, unsigned int VertexCount);
  12.258 +	bool Draw(VertexBuffer *vb, IndexBuffer *ib);
  12.259 +	bool Draw(Vertex *varray, Index *iarray, unsigned int VertexCount, unsigned int IndexCount);
  12.260 +	bool Draw(Vertex *varray, Triangle *triarray, unsigned int VertexCount, unsigned int TriCount);
  12.261 +
  12.262 +	IDirect3DDevice8 *GetDevice() const;
  12.263 +	int GetTextureStageNumber() const {return MaxTextureStages;}
  12.264 +
  12.265 +	////// render states //////
  12.266 +	void SetPrimitiveType(PrimitiveType pt);
  12.267 +	void SetBackfaceCulling(bool enable);
  12.268 +	void SetFrontFace(FaceOrder order);
  12.269 +	void SetAutoNormalize(bool enable);
  12.270 +	void SetBillboarding(bool enable);
  12.271 +	void SetColorWrite(bool red, bool green, bool blue, bool alpha);
  12.272 +
  12.273 +	// blending states
  12.274 +	void SetAlphaBlending(bool enable);
  12.275 +	void SetBlendFunc(BlendingFactor src, BlendingFactor dest);
  12.276 +
  12.277 +	// zbuffer states
  12.278 +	void SetZBuffering(bool enable);
  12.279 +	void SetZWrite(bool enable);
  12.280 +	void SetZFunc(CmpFunc func);
  12.281 +
  12.282 +	// set stencil buffer states
  12.283 +	void SetStencilBuffering(bool enable);
  12.284 +	void SetStencilPassOp(StencilOp sop);
  12.285 +	void SetStencilFailOp(StencilOp sop);
  12.286 +	void SetStencilPassZFailOp(StencilOp sop);
  12.287 +	void SetStencilOp(StencilOp Fail, StencilOp StencilPassZFail, StencilOp Pass);
  12.288 +	void SetStencilFunc(CmpFunc func);
  12.289 +	void SetStencilReference(dword value);
  12.290 +
  12.291 +	// texture & material states
  12.292 +	void SetTextureFiltering(TextureFilteringType texfilter, int TextureStage = 0xa11);
  12.293 +	void SetTextureAddressing(TextureAddressing uaddr, TextureAddressing vaddr, int TextureStage = 0xa11);
  12.294 +	void SetTextureBorderColor(dword color, int TextureStage = 0xa11);
  12.295 +	void SetTexture(int index, Texture *tex);
  12.296 +	void SetTextureFactor(dword factor);
  12.297 +	void SetMipMapping(bool enable, int TextureStage = 0xa11);
  12.298 +	void SetMaterial(const Material &mat);
  12.299 +
  12.300 +	void BlitTexture(const Texture *texture, RECT *rect, const Color &col = Color(1.0f));
  12.301 +	
  12.302 +	// multitexturing interface
  12.303 +	void EnableTextureStage(int stage);
  12.304 +	void DisableTextureStage(int stage);
  12.305 +	void SetTextureStageColor(int stage, TextureBlendFunction op, TextureBlendArgument arg1, TextureBlendArgument arg2, TextureBlendArgument arg3 = TexArgNone);
  12.306 +	void SetTextureStageAlpha(int stage, TextureBlendFunction op, TextureBlendArgument arg1, TextureBlendArgument arg2, TextureBlendArgument arg3 = TexArgNone);
  12.307 +	void SetTextureCoordIndex(int stage, int index);
  12.308 +	void SetTextureTransformState(int stage, TexTransformState TexXForm);
  12.309 +	//void SetTextureCoordGenerator(int stage, TexGen tgen);
  12.310 +
  12.311 +	// programmable interface
  12.312 +	void SetVertexProgram(dword vs);
  12.313 +	void SetPixelProgram(dword ps);
  12.314 +
  12.315 +	dword CreateVertexProgram(const char *fname);
  12.316 +	void DestroyVertexProgram(dword vprog);
  12.317 +	void SetVertexProgramConstant(dword creg, float val);
  12.318 +	void SetVertexProgramConstant(dword creg, const Vector3 &val);
  12.319 +	void SetVertexProgramConstant(dword creg, const Vector4 &val);
  12.320 +	void SetVertexProgramConstant(dword creg, const Color &val);
  12.321 +	void SetVertexProgramConstant(dword creg, const Matrix4x4 &val);
  12.322 +	void SetVertexProgramConstant(dword creg, const void *data, dword size);
  12.323 +
  12.324 +
  12.325 +	// lighting states
  12.326 +	void SetLighting(bool enable);
  12.327 +	void SetColorVertex(bool enable);
  12.328 +	void SetAmbientLight(Color AmbientColor);
  12.329 +	void SetShadingMode(ShadeMode mode);
  12.330 +	void SetSpecular(bool enable);
  12.331 +
  12.332 +	// Transformation Matrices
  12.333 +	void SetWorldMatrix(const Matrix4x4 &WorldMat, unsigned int BlendIndex = 0);
  12.334 +	void SetViewMatrix(const Matrix4x4 &ViewMat);
  12.335 +	void SetProjectionMatrix(const Matrix4x4 &ProjMat);
  12.336 +	void SetTextureMatrix(const Matrix4x4 &TexMat, unsigned int TextureStage = 0);
  12.337 +	void SetViewport(unsigned int x, unsigned int y, unsigned int xsize, unsigned int ysize, float MinZ = 0.0f, float MaxZ = 1.0f);
  12.338 +
  12.339 +	const Matrix4x4 &GetWorldMatrix(unsigned int BlendIndex = 0);
  12.340 +	const Matrix4x4 &GetViewMatrix();
  12.341 +	const Matrix4x4 &GetProjectionMatrix();
  12.342 +	const Matrix4x4 &GetTextureMatrix(unsigned int TextureStage = 0);
  12.343 +
  12.344 +	// render target
  12.345 +	void ResetRenderTarget();
  12.346 +	void SetRenderTarget(RenderTarget &rtarg);
  12.347 +	void SetRenderTarget(Texture *rtarg, Texture *ztarg);
  12.348 +	void SetRenderTarget(Texture *rtarg, Surface *ztarg);
  12.349 +	//RenderTarget GetRenderTarget() const;
  12.350 +};
  12.351 +
  12.352 +
  12.353 +
  12.354 +class Engine3D {
  12.355 +private:
  12.356 +	IDirect3D8 *d3d;
  12.357 +	unsigned int AdapterCount;
  12.358 +	Adapter *adapters;	// array of adapters (filled in at the constructor)
  12.359 +	std::vector<GraphicsContext*> GraphicsContexts;	// a list of active graphics contexts
  12.360 +	
  12.361 +	void RetrieveAdapterInfo();
  12.362 +	LinkedList<DisplayMode> *CreateModesList(unsigned int AdapterID) const;
  12.363 +	void NarrowModesList(LinkedList<DisplayMode> *list, DisplayModeItem item, long value, long value2=0) const;
  12.364 +	DisplayMode ChooseBestMode(LinkedList<DisplayMode> *modes) const;
  12.365 +	int MaxAntialiasingSamples() const;
  12.366 +	
  12.367 +public:
  12.368 +
  12.369 +	Engine3D();
  12.370 +	~Engine3D();
  12.371 +
  12.372 +	int GetAdapterCount() const;
  12.373 +	const Adapter *GetAdapterInfo(int adapter) const;
  12.374 +
  12.375 +	GraphicsContext *CreateGraphicsContext(HWND WindowHandle, int x, int y, int bpp, word flags);
  12.376 +	GraphicsContext *CreateGraphicsContext(HWND WindowHandle, unsigned int AdapterID, ContextInitParameters *GCParams);
  12.377 +	ContextInitParameters LoadContextParamsConfigFile(const char *cfgfilename);
  12.378 +
  12.379 +	void DestroyGraphicsContext(GraphicsContext *gc);
  12.380 +};
  12.381 +
  12.382 +class Light;
  12.383 +
  12.384 +// helper functions
  12.385 +bool Lock(VertexBuffer *vb, Vertex **data);
  12.386 +bool Lock(IndexBuffer *ib, Index **data);
  12.387 +void Unlock(VertexBuffer *vb);
  12.388 +void Unlock(IndexBuffer *ib);
  12.389 +void CreateProjectionMatrix(Matrix4x4 *mat, float yFOV, float Aspect, float NearClip, float FarClip);
  12.390 +void NormalMapFromHeightField(Texture *tex);
  12.391 +void UpdateMipmapChain(Texture *tex);
  12.392 +TriMesh *CreateShadowVolume(const TriMesh &mesh, const Light *light, const Matrix4x4 &MeshXForm, bool WorldCoords = false);
  12.393 +
  12.394 +#endif	// _3DENGINE_H_
  12.395 \ No newline at end of file
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/3deng/3dengtypes.h	Thu Oct 23 01:46:07 2014 +0300
    13.3 @@ -0,0 +1,22 @@
    13.4 +#ifndef _3DENGTYPES_H_
    13.5 +#define _3DENGTYPES_H_
    13.6 +
    13.7 +#include "d3d8.h"
    13.8 +#include "typedefs.h"
    13.9 +
   13.10 +typedef IDirect3DSurface8 Surface;
   13.11 +typedef IDirect3DTexture8 Texture;
   13.12 +typedef IDirect3DVertexBuffer8 VertexBuffer;
   13.13 +typedef IDirect3DIndexBuffer8 IndexBuffer;
   13.14 +
   13.15 +#define FixedFunction VertexFormat
   13.16 +
   13.17 +//const dword VertexFormat = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX4;
   13.18 +//const dword VertexFormat = D3DFVF_XYZ | D3DFVF_XYZB1 | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX4;
   13.19 +const dword VertexFormat = D3DFVF_XYZB2 | D3DFVF_LASTBETA_UBYTE4 | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX4;
   13.20 +const D3DFORMAT IndexFormat = D3DFMT_INDEX16;
   13.21 +const dword IndexSize = 2;
   13.22 +typedef uint16 Index;
   13.23 +
   13.24 +
   13.25 +#endif	// _3DENGTYPES_H_
   13.26 \ No newline at end of file
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/src/3deng/3dgeom.cpp	Thu Oct 23 01:46:07 2014 +0300
    14.3 @@ -0,0 +1,478 @@
    14.4 +#include <cassert>
    14.5 +#include "3dgeom.h"
    14.6 +#include "3dengine.h"
    14.7 +
    14.8 +using std::vector;
    14.9 +
   14.10 +TexCoord::TexCoord(float u, float v) {
   14.11 +	this->u = u;
   14.12 +	this->v = v;
   14.13 +}
   14.14 +
   14.15 +// Vertex class implementation
   14.16 +
   14.17 +Vertex::Vertex() {
   14.18 +	color = 0x00ffffff;
   14.19 +	memset(tex, 0, 4*sizeof(TexCoord));
   14.20 +}
   14.21 +
   14.22 +Vertex::Vertex(const Vector3 &position, float tu, float tv, dword color) {
   14.23 +	pos = position;
   14.24 +	tex[0].u = tex[1].u = tex[2].u = tex[3].u = tu;
   14.25 +	tex[0].v = tex[1].v = tex[2].v = tex[3].v = tv;
   14.26 +	this->color = color;
   14.27 +}
   14.28 +
   14.29 +void Vertex::CalculateNormal(const Vertex *vbuffer, const Triangle *triangles, long trinum) {
   14.30 +
   14.31 +	// find the position of the curent vertex in the vertex buffer
   14.32 +	dword index = (dword)(this - vbuffer);
   14.33 +	
   14.34 +	normal = Vector3(0, 0, 0);
   14.35 +	const Triangle *tri = triangles;
   14.36 +	for(int i=0; i<trinum; i++, tri++) {
   14.37 +		if(tri->vertices[0] == index || tri->vertices[1] == index || tri->vertices[2] == index) {
   14.38 +			normal += tri->normal;
   14.39 +		}
   14.40 +	}
   14.41 +
   14.42 +	normal.Normalize();
   14.43 +}
   14.44 +
   14.45 +/////////// Edge class implementation ///////////
   14.46 +
   14.47 +Edge::Edge() {
   14.48 +	vertices[0] = vertices[1] = adjfaces[0] = adjfaces[1] = 0;
   14.49 +}
   14.50 +
   14.51 +Edge::Edge(Index v1, Index v2, Index af1, Index af2) {
   14.52 +	vertices[0] = v1;
   14.53 +	vertices[1] = v2;
   14.54 +	adjfaces[0] = af1;
   14.55 +	adjfaces[1] = af2;
   14.56 +}
   14.57 +
   14.58 +/////////// Triangle class implementation /////////////
   14.59 +Triangle::Triangle(Index v1, Index v2, Index v3) {
   14.60 +	vertices[0] = v1;
   14.61 +	vertices[1] = v2;
   14.62 +	vertices[2] = v3;
   14.63 +}
   14.64 +
   14.65 +void Triangle::CalculateNormal(Vertex *vbuffer, bool normalize) {
   14.66 +	Vector3 v1 = vbuffer[vertices[1]].pos - vbuffer[vertices[0]].pos;
   14.67 +	Vector3 v2 = vbuffer[vertices[2]].pos - vbuffer[vertices[0]].pos;
   14.68 +	normal = v1.CrossProduct(v2);
   14.69 +	if(normalize) normal.Normalize();
   14.70 +}
   14.71 +
   14.72 +
   14.73 +/////////////// Triangular Mesh implementation /////////////
   14.74 +
   14.75 +TriMesh::TriMesh(byte LODLevels, GraphicsContext *gc) {
   14.76 +	memset(this, 0, sizeof(TriMesh));
   14.77 +	this->gc = gc;
   14.78 +	Levels = LODLevels;
   14.79 +
   14.80 +	varray = new Vertex*[Levels];
   14.81 +	memset(varray, 0, Levels * sizeof(Vertex*));
   14.82 +	
   14.83 +	triarray = new Triangle*[Levels];
   14.84 +	memset(triarray, 0, Levels * sizeof(Triangle*));
   14.85 +	
   14.86 +	vbuffer = new VertexBuffer*[Levels];
   14.87 +	memset(vbuffer, 0, Levels * sizeof(VertexBuffer*));
   14.88 +
   14.89 +	ibuffer = new IndexBuffer*[Levels];
   14.90 +	memset(ibuffer, 0, Levels * sizeof(IndexBuffer*));
   14.91 +
   14.92 +	AdjTriangles = new std::vector<dword>*[Levels];
   14.93 +	memset(AdjTriangles, 0, Levels * sizeof(std::vector<dword>*));
   14.94 +
   14.95 +	VertexCount = new dword[Levels];
   14.96 +	TriCount = new dword[Levels];
   14.97 +
   14.98 +	BuffersValid = new bool[Levels];
   14.99 +	memset(BuffersValid, 0, Levels * sizeof(bool));
  14.100 +
  14.101 +	AdjValid = new bool[Levels];
  14.102 +	memset(AdjValid, 0, Levels * sizeof(bool));
  14.103 +}
  14.104 +
  14.105 +TriMesh::TriMesh(const TriMesh &mesh) {
  14.106 +
  14.107 +	memcpy(this, &mesh, sizeof(TriMesh));
  14.108 +
  14.109 +	BuffersValid = new bool[Levels];
  14.110 +	memset(BuffersValid, 0, Levels * sizeof(bool));
  14.111 +    
  14.112 +	varray = new Vertex*[Levels];
  14.113 +	triarray = new Triangle*[Levels];
  14.114 +	vbuffer = new VertexBuffer*[Levels];
  14.115 +	ibuffer = new IndexBuffer*[Levels];
  14.116 +
  14.117 +	VertexCount = new dword[Levels];
  14.118 +	TriCount = new dword[Levels];
  14.119 +
  14.120 +	for(int i=0; i<Levels; i++) {
  14.121 +		
  14.122 +		VertexCount[i] = mesh.VertexCount[i];
  14.123 +		TriCount[i] = mesh.TriCount[i];
  14.124 +		
  14.125 +        varray[i] = new Vertex[VertexCount[i]];
  14.126 +		triarray[i] = new Triangle[TriCount[i]];
  14.127 +		
  14.128 +		memcpy(varray[i], mesh.varray[i], VertexCount[i] * sizeof(Vertex));
  14.129 +		memcpy(triarray[i], mesh.triarray[i], TriCount[i] * sizeof(Triangle));
  14.130 +
  14.131 +		vbuffer[i] = 0;
  14.132 +		ibuffer[i] = 0;
  14.133 +
  14.134 +		UpdateSystemBuffers(i);
  14.135 +	}
  14.136 +}
  14.137 +
  14.138 +TriMesh::~TriMesh() {
  14.139 +	if(varray) {
  14.140 +		for(int i=0; i<Levels; i++) {
  14.141 +            delete [] varray[i];
  14.142 +		}
  14.143 +		delete [] varray;
  14.144 +	}
  14.145 +
  14.146 +	if(triarray) {
  14.147 +		for(int i=0; i<Levels; i++) {
  14.148 +			delete [] triarray[i];
  14.149 +		}
  14.150 +		delete triarray;
  14.151 +	}
  14.152 +	
  14.153 +	if(vbuffer) {
  14.154 +		for(int i=0; i<Levels; i++) {
  14.155 +			if(vbuffer[i]) vbuffer[i]->Release();
  14.156 +		}
  14.157 +	}
  14.158 +	if(ibuffer) {
  14.159 +		for(int i=0; i<Levels; i++) {
  14.160 +			if(ibuffer[i]) ibuffer[i]->Release();
  14.161 +		}
  14.162 +	}
  14.163 +
  14.164 +	if(AdjTriangles) {
  14.165 +		for(int i=0; i<Levels; i++) {
  14.166 +			delete [] AdjTriangles[i];
  14.167 +		}
  14.168 +		delete AdjTriangles;
  14.169 +	}
  14.170 +}
  14.171 +
  14.172 +const TriMesh &TriMesh::operator =(const TriMesh &mesh) {
  14.173 +	memcpy(this, &mesh, sizeof(TriMesh));
  14.174 +
  14.175 +	BuffersValid = new bool[Levels];
  14.176 +	memset(BuffersValid, 0, Levels * sizeof(bool));
  14.177 +    
  14.178 +	varray = new Vertex*[Levels];
  14.179 +	triarray = new Triangle*[Levels];
  14.180 +	vbuffer = new VertexBuffer*[Levels];
  14.181 +	ibuffer = new IndexBuffer*[Levels];
  14.182 +
  14.183 +	VertexCount = new dword[Levels];
  14.184 +	TriCount = new dword[Levels];
  14.185 +
  14.186 +	for(int i=0; i<Levels; i++) {
  14.187 +		
  14.188 +		VertexCount[i] = mesh.VertexCount[i];
  14.189 +		TriCount[i] = mesh.TriCount[i];
  14.190 +		
  14.191 +        varray[i] = new Vertex[VertexCount[i]];
  14.192 +		triarray[i] = new Triangle[TriCount[i]];
  14.193 +		
  14.194 +		memcpy(varray[i], mesh.varray[i], VertexCount[i] * sizeof(Vertex));
  14.195 +		memcpy(triarray[i], mesh.triarray[i], TriCount[i] * sizeof(Triangle));
  14.196 +
  14.197 +		vbuffer[i] = 0;
  14.198 +		ibuffer[i] = 0;
  14.199 +
  14.200 +		UpdateSystemBuffers(i);
  14.201 +	}
  14.202 +	return mesh;
  14.203 +}
  14.204 +
  14.205 +
  14.206 +const Vertex *TriMesh::GetVertexArray(byte level) const {
  14.207 +	if(level >= Levels) return 0;
  14.208 +	return varray[level];
  14.209 +}
  14.210 +
  14.211 +const Triangle *TriMesh::GetTriangleArray(byte level) const {
  14.212 +	if(level >= Levels) return 0;
  14.213 +	return triarray[level];
  14.214 +}
  14.215 +	
  14.216 +
  14.217 +Vertex *TriMesh::GetModVertexArray() {
  14.218 +	memset(BuffersValid, 0, Levels * sizeof(bool));
  14.219 +	return varray[0];
  14.220 +}
  14.221 +
  14.222 +Triangle *TriMesh::GetModTriangleArray() {
  14.223 +	memset(BuffersValid, 0, Levels * sizeof(bool));
  14.224 +	memset(AdjValid, 0, Levels * sizeof(bool));
  14.225 +	return triarray[0];
  14.226 +}
  14.227 +
  14.228 +const VertexBuffer *TriMesh::GetVertexBuffer(byte level) const {
  14.229 +	if(level >= Levels) return 0;
  14.230 +
  14.231 +	if(!BuffersValid[level]) {
  14.232 +		const_cast<TriMesh*>(this)->UpdateSystemBuffers(level);
  14.233 +	}
  14.234 +	return vbuffer[level];
  14.235 +}
  14.236 +
  14.237 +const IndexBuffer *TriMesh::GetIndexBuffer(byte level) const {
  14.238 +	if(level >= Levels) return 0;
  14.239 +
  14.240 +	if(!BuffersValid[level]) {
  14.241 +		const_cast<TriMesh*>(this)->UpdateSystemBuffers(level);
  14.242 +	}
  14.243 +
  14.244 +	return ibuffer[level];
  14.245 +}
  14.246 +
  14.247 +		
  14.248 +dword TriMesh::GetVertexCount(byte level) const {
  14.249 +	if(level >= Levels) return 0xdeadbeef;
  14.250 +	return VertexCount[level];
  14.251 +}
  14.252 +
  14.253 +dword TriMesh::GetTriangleCount(byte level) const {
  14.254 +	if(level >= Levels) return 0xdeadbeef;
  14.255 +	return TriCount[level];
  14.256 +}
  14.257 +
  14.258 +byte TriMesh::GetLevelCount() const {
  14.259 +	return Levels;
  14.260 +}
  14.261 +
  14.262 +void TriMesh::SetGraphicsContext(GraphicsContext *gc) {
  14.263 +	this->gc = gc;
  14.264 +	memset(BuffersValid, 0, Levels * sizeof(bool));	// invalidate all system buffers in all levels
  14.265 +}
  14.266 +
  14.267 +void TriMesh::SetData(const Vertex *vdata, const Triangle *tridata, dword vcount, dword tricount) {
  14.268 +
  14.269 +	memset(BuffersValid, 0, Levels * sizeof(bool));
  14.270 +	memset(AdjValid, 0, Levels * sizeof(bool));
  14.271 +	
  14.272 +	if(varray[0]) delete [] varray[0];
  14.273 +	if(triarray[0]) delete [] triarray[0];
  14.274 +	varray[0] = new Vertex[vcount];
  14.275 +	triarray[0] = new Triangle[tricount];
  14.276 +
  14.277 +	if(vdata) memcpy(varray[0], vdata, vcount * sizeof(Vertex));
  14.278 +	if(tridata) memcpy(triarray[0], tridata, tricount * sizeof(Triangle));
  14.279 +	VertexCount[0] = vcount;
  14.280 +	TriCount[0] = tricount;
  14.281 +
  14.282 +	UpdateLODChain();
  14.283 +}
  14.284 +
  14.285 +bool TriMesh::UpdateSystemBuffers(byte level) {
  14.286 +
  14.287 +	if(!gc || level >= Levels) return false;
  14.288 +
  14.289 +	if(vbuffer[level]) {
  14.290 +		D3DVERTEXBUFFER_DESC vbdesc;
  14.291 +		vbuffer[level]->GetDesc(&vbdesc);
  14.292 +		if(vbdesc.Size / sizeof(Vertex) != VertexCount[level]) {
  14.293 +			vbuffer[level]->Release();
  14.294 +
  14.295 +			if(gc->D3DDevice->CreateVertexBuffer(VertexCount[level] * sizeof(Vertex), dynamic ? D3DUSAGE_DYNAMIC : 0, VertexFormat, D3DPOOL_DEFAULT, &vbuffer[level]) != D3D_OK) {
  14.296 +				return false;
  14.297 +			}
  14.298 +		}
  14.299 +	} else {
  14.300 +		if(gc->D3DDevice->CreateVertexBuffer(VertexCount[level] * sizeof(Vertex), dynamic ? D3DUSAGE_DYNAMIC : 0, VertexFormat, D3DPOOL_DEFAULT, &vbuffer[level]) != D3D_OK) {
  14.301 +			return false;
  14.302 +		}
  14.303 +	}
  14.304 +	
  14.305 +	Vertex *vbdata;
  14.306 +	Lock(vbuffer[level], &vbdata);
  14.307 +	memcpy(vbdata, varray[level], VertexCount[level] * sizeof(Vertex));
  14.308 +	Unlock(vbuffer[level]);
  14.309 +
  14.310 +	if(ibuffer[level]) {
  14.311 +		D3DINDEXBUFFER_DESC ibdesc;
  14.312 +		ibuffer[level]->GetDesc(&ibdesc);
  14.313 +		if(ibdesc.Size / IndexSize != TriCount[level] * 3) {
  14.314 +			ibuffer[level]->Release();
  14.315 +
  14.316 +			if(gc->D3DDevice->CreateIndexBuffer(TriCount[level] * 3 * IndexSize, dynamic ? D3DUSAGE_DYNAMIC : 0, IndexFormat, D3DPOOL_DEFAULT, &ibuffer[level]) != D3D_OK) {
  14.317 +				return false;
  14.318 +			}
  14.319 +		}
  14.320 +	} else {
  14.321 +		if(gc->D3DDevice->CreateIndexBuffer(TriCount[level] * 3 * IndexSize, dynamic ? D3DUSAGE_DYNAMIC : 0, IndexFormat, D3DPOOL_DEFAULT, &ibuffer[level]) != D3D_OK) {
  14.322 +			return false;
  14.323 +		}
  14.324 +	}
  14.325 +
  14.326 +
  14.327 +	Index *ibdata;
  14.328 +	Lock(ibuffer[level], &ibdata);
  14.329 +	for(dword i=0; i<TriCount[level]; i++) {
  14.330 +		*ibdata++ = triarray[level][i].vertices[0];
  14.331 +		*ibdata++ = triarray[level][i].vertices[1];
  14.332 +		*ibdata++ = triarray[level][i].vertices[2];
  14.333 +	}
  14.334 +	Unlock(ibuffer[level]);
  14.335 +
  14.336 +	BuffersValid[level] = true;
  14.337 +	return true;
  14.338 +}
  14.339 +
  14.340 +void TriMesh::UpdateLODChain() {
  14.341 +	for(byte i=1; i<Levels; i++) {
  14.342 +		// TODO: apply mesh optimization, for now, just copy as it is
  14.343 +		VertexCount[i] = VertexCount[0];
  14.344 +		TriCount[i] = TriCount[0];
  14.345 +		
  14.346 +		if(!varray[i]) varray[i] = new Vertex[VertexCount[i]];
  14.347 +		memcpy(varray[i], varray[0], VertexCount[i] * sizeof(Vertex));
  14.348 +
  14.349 +		if(!triarray[i]) triarray[i] = new Triangle[TriCount[i]];
  14.350 +		memcpy(triarray[i], triarray[0], TriCount[i] * sizeof(Triangle));
  14.351 +
  14.352 +		UpdateSystemBuffers(i);
  14.353 +	}
  14.354 +
  14.355 +	if(!BuffersValid[0]) UpdateSystemBuffers(0);
  14.356 +}
  14.357 +
  14.358 +// TODO: this will brake currently with multiple LOD levels, revise LOD normal calculation
  14.359 +// and revise UpdateLODChain() too
  14.360 +void TriMesh::CalculateNormals() {
  14.361 +	memset(BuffersValid, 0, Levels * sizeof(bool));
  14.362 +
  14.363 +	Triangle *tri = triarray[0];
  14.364 +	Triangle *tend = tri + TriCount[0];
  14.365 +
  14.366 +	while(tri != tend) {
  14.367 +		(*tri++).CalculateNormal(varray[0], false);
  14.368 +	}
  14.369 +
  14.370 +	/*
  14.371 +	Vertex *vert = varray[0];
  14.372 +	Vertex *vend = vert + VertexCount[0];
  14.373 +
  14.374 +	while(vert != vend) {
  14.375 +		(*vert++).CalculateNormal(varray[0], triarray[0], TriCount[0]);
  14.376 +	}
  14.377 +	*/
  14.378 +
  14.379 +	if(!AdjValid[0]) {
  14.380 +        if(AdjTriangles[0]) delete [] AdjTriangles[0];
  14.381 +		AdjTriangles[0] = new std::vector<dword>[VertexCount[0]];
  14.382 +	}
  14.383 +
  14.384 +	for(dword i=0; i<VertexCount[0]; i++) {
  14.385 +		if(AdjValid[0]) {
  14.386 +			assert(AdjTriangles[0]);
  14.387 +			Vector3 normal(0.0f, 0.0f, 0.0f);
  14.388 +			for(dword j=0; j<AdjTriangles[0][i].size(); j++) {
  14.389 +				normal += triarray[0][AdjTriangles[0][i][j]].normal;
  14.390 +			}
  14.391 +			normal.Normalize();
  14.392 +			varray[0][i].normal = normal;
  14.393 +		} else {
  14.394 +
  14.395 +			AdjTriangles[0][i].erase(AdjTriangles[0][i].begin(), AdjTriangles[0][i].end());
  14.396 +			Vector3 normal(0.0f, 0.0f, 0.0f);
  14.397 +			for(dword j=0; j<TriCount[0]; j++) {
  14.398 +				if(triarray[0][j].vertices[0] == i || triarray[0][j].vertices[1] == i || triarray[0][j].vertices[2] == i) {
  14.399 +					AdjTriangles[0][i].push_back(j);
  14.400 +					normal += triarray[0][j].normal;
  14.401 +				}
  14.402 +			}
  14.403 +			normal.Normalize();
  14.404 +			varray[0][i].normal = normal;
  14.405 +		}
  14.406 +	}
  14.407 +
  14.408 +	AdjValid[0] = true;
  14.409 +	
  14.410 +	UpdateLODChain();
  14.411 +}
  14.412 +
  14.413 +void TriMesh::CalculateNormalsFast() {
  14.414 +	memset(BuffersValid, 0, Levels * sizeof(bool));
  14.415 +
  14.416 +	Triangle *tri = triarray[0];
  14.417 +	Triangle *tend = tri + TriCount[0];
  14.418 +
  14.419 +	while(tri != tend) {
  14.420 +		tri->CalculateNormal(varray[0], true);
  14.421 +		varray[0][tri->vertices[0]].normal = tri->normal;
  14.422 +		varray[0][tri->vertices[1]].normal = tri->normal;
  14.423 +		varray[0][tri->vertices[2]].normal = tri->normal;
  14.424 +		tri++;
  14.425 +	}
  14.426 +
  14.427 +	UpdateLODChain();
  14.428 +}
  14.429 +
  14.430 +void TriMesh::ChangeMode(TriMeshMode mode) {
  14.431 +	dynamic = mode == TriMeshDynamic;
  14.432 +}
  14.433 +
  14.434 +/*
  14.435 +
  14.436 +void TriMesh::CalculateEdges() {
  14.437 +
  14.438 +	//build a list of triangles that share each vertex
  14.439 +	std::list<Triangle*> *ShareTris = new std::list<Triangle*>[VertexCount[0]];
  14.440 +
  14.441 +	for(dword i=0; i<VertexCount[0]; i++) {
  14.442 +        for(dword j=0; j<TriCount[0]; j++) {
  14.443 +			Index VertexIndex = (Index)((Vertex*)&varray[0][i] - (Vertex*)&varray[0][0]);
  14.444 +			if(triarray[0][j].vertices[0] == VertexIndex || triarray[0][j].vertices[1] == VertexIndex || triarray[0][j].vertices[2] == VertexIndex) {
  14.445 +				ShareTris[i].push_back(&triarray[0][j]);	// if it references this vertex add it
  14.446 +			}
  14.447 +		}
  14.448 +	}
  14.449 +
  14.450 +	// find the adjacent triangles of each edge
  14.451 +	for(dword i=0; i<TriCount[0]; i++) {
  14.452 +		Triangle *tri = &triarray[0][i];
  14.453 +
  14.454 +		for(int j=0; j<3; j++) {
  14.455 +			tri->edges[j].vertices[0] = tri->vertices[j];
  14.456 +			tri->edges[j].vertices[1] = tri->vertices[(j+1) % 3];
  14.457 +			tri->edges[j].adjfaces[0] = (Index)i;
  14.458 +		}
  14.459 +
  14.460 +		for(int j=0; j<3; j++) {
  14.461 +			Index v0 = (Index)((Vertex*)&varray[0][tri->edges[j].vertices[0]] - (Vertex*)&varray[0][0]);
  14.462 +			Index v1 = (Index)((Vertex*)&varray[0][tri->edges[j].vertices[1]] - (Vertex*)&varray[0][0]);
  14.463 +
  14.464 +			std::list<Triangle*>::iterator iter = ShareTris[v0].begin();
  14.465 +			while(iter != ShareTris[v0].end()) {
  14.466 +				Index TriIndex = (Index)(*iter - &triarray[0][0]);
  14.467 +				
  14.468 +				if((TriIndex != i) && ((*iter)->vertices[0] == v1 || (*iter)->vertices[1] == v1 || (*iter)->vertices[2] == v1)) {
  14.469 +					tri->edges[j].adjfaces[1] = TriIndex;
  14.470 +					break;
  14.471 +				}
  14.472 +				iter++;
  14.473 +			}
  14.474 +			if(iter == ShareTris[v0].end()) tri->edges[j].adjfaces[1] = (Index)0xffffffff;
  14.475 +		}
  14.476 +	}
  14.477 +
  14.478 +	// TODO: wield duplicate edges
  14.479 +}
  14.480 +
  14.481 +*/
  14.482 \ No newline at end of file
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/src/3deng/3dgeom.h	Thu Oct 23 01:46:07 2014 +0300
    15.3 @@ -0,0 +1,112 @@
    15.4 +#ifndef _3DGEOM_H_
    15.5 +#define _3DGEOM_H_
    15.6 +
    15.7 +#include <vector>
    15.8 +#include "n3dmath.h"
    15.9 +#include "3dengtypes.h"
   15.10 +#include "switches.h"
   15.11 +
   15.12 +struct TexCoord {
   15.13 +	float u, v;
   15.14 +
   15.15 +	TexCoord(float u = 0.0f, float v = 0.0f);
   15.16 +};
   15.17 +
   15.18 +class Triangle;	// fwd declaration
   15.19 +
   15.20 +class Vertex {
   15.21 +public:
   15.22 +	Vector3 pos;
   15.23 +	float BlendFactor;
   15.24 +	dword BlendIndex;
   15.25 +	Vector3 normal;
   15.26 +	dword color;
   15.27 +	TexCoord tex[4];
   15.28 +
   15.29 +	Vertex();
   15.30 +	Vertex(const Vector3 &position, float tu = 0.0f, float tv = 0.0f, dword color = 0x00ffffff);
   15.31 +
   15.32 +	void CalculateNormal(const Vertex *vbuffer, const Triangle *triangles, long trinum);
   15.33 +};
   15.34 +
   15.35 +
   15.36 +class Edge {
   15.37 +public:
   15.38 +	Index vertices[2];
   15.39 +	Index adjfaces[2];
   15.40 +
   15.41 +	Edge();
   15.42 +	Edge(Index v1, Index v2, Index af1 = 0, Index af2 = 0);
   15.43 +};
   15.44 +
   15.45 +
   15.46 +class Triangle {
   15.47 +public:
   15.48 +	Index vertices[3];
   15.49 +	Vector3 normal;
   15.50 +	dword SmoothingGroup;
   15.51 +
   15.52 +	Triangle(Index v1 = 0, Index v2 = 0, Index v3 = 0);
   15.53 +
   15.54 +	void CalculateNormal(Vertex *vbuffer, bool normalize=0);
   15.55 +};
   15.56 +
   15.57 +
   15.58 +enum TriMeshMode {TriMeshDynamic, TriMeshStatic};
   15.59 +
   15.60 +class GraphicsContext;
   15.61 +
   15.62 +class TriMesh {
   15.63 +private:
   15.64 +	GraphicsContext *gc;
   15.65 +
   15.66 +	// LOD arrays of vertex and triangle arrays for the mesh
   15.67 +	Vertex **varray;
   15.68 +	Triangle **triarray;
   15.69 +	// system managed copy of the data (probably on the video ram or something)
   15.70 +	VertexBuffer **vbuffer;
   15.71 +	IndexBuffer **ibuffer;
   15.72 +
   15.73 +	std::vector<dword> **AdjTriangles;
   15.74 +	bool *AdjValid;
   15.75 +	
   15.76 +	dword *VertexCount, *TriCount;
   15.77 +	byte Levels;
   15.78 +
   15.79 +	bool *BuffersValid;
   15.80 +	bool dynamic;
   15.81 +
   15.82 +	// synchronizes the system managed copy of vertices/indices with the local data
   15.83 +	bool UpdateSystemBuffers(byte level);
   15.84 +	void UpdateLODChain();
   15.85 +
   15.86 +public:
   15.87 +	TriMesh(byte LODLevels, GraphicsContext *gc = 0);
   15.88 +	TriMesh(const TriMesh &mesh);
   15.89 +	~TriMesh();
   15.90 +
   15.91 +	const TriMesh &operator =(const TriMesh &mesh);
   15.92 +
   15.93 +	const Vertex *GetVertexArray(byte level = 0) const;
   15.94 +	const Triangle *GetTriangleArray(byte level = 0) const;
   15.95 +	
   15.96 +	Vertex *GetModVertexArray();
   15.97 +	Triangle *GetModTriangleArray();
   15.98 +
   15.99 +	const VertexBuffer *GetVertexBuffer(byte level = 0) const;
  15.100 +	const IndexBuffer *GetIndexBuffer(byte level = 0) const;
  15.101 +
  15.102 +	dword GetVertexCount(byte level = 0) const;
  15.103 +	dword GetTriangleCount(byte level = 0) const;
  15.104 +	byte GetLevelCount() const;
  15.105 +
  15.106 +	void ChangeMode(TriMeshMode mode);
  15.107 +	void SetGraphicsContext(GraphicsContext *gc);
  15.108 +	void SetData(const Vertex *vdata, const Triangle *tridata, dword vcount, dword tricount);
  15.109 +
  15.110 +	void CalculateNormals();
  15.111 +	void CalculateNormalsFast();
  15.112 +	//void CalculateEdges();
  15.113 +};
  15.114 +
  15.115 +#endif	// _3DGEOM_H_
  15.116 \ No newline at end of file
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/src/3deng/3dscene.cpp	Thu Oct 23 01:46:07 2014 +0300
    16.3 @@ -0,0 +1,351 @@
    16.4 +#include <string>
    16.5 +#include "3dscene.h"
    16.6 +
    16.7 +using std::string;
    16.8 +
    16.9 +Scene::Scene(GraphicsContext *gc) {
   16.10 +	this->gc = gc;
   16.11 +
   16.12 +	ActiveCamera = 0;
   16.13 +	Shadows = false;
   16.14 +	LightHalos = false;
   16.15 +	HaloSize = 10.0f;
   16.16 +	UseFog = false;
   16.17 +
   16.18 +	memset(lights, 0, 8 * sizeof(Light*));
   16.19 +
   16.20 +	AmbientLight = Color(0.0f, 0.0f, 0.0f);
   16.21 +	ManageData = true;
   16.22 +}
   16.23 +
   16.24 +Scene::~Scene() {
   16.25 +
   16.26 +	if(ManageData) {
   16.27 +		std::list<Object*>::iterator obj = objects.begin();
   16.28 +		while(obj != objects.end()) {
   16.29 +			delete *obj++;
   16.30 +		}
   16.31 +
   16.32 +		std::list<Camera*>::iterator cam = cameras.begin();
   16.33 +		while(cam != cameras.end()) {
   16.34 +			delete *cam++;
   16.35 +		}
   16.36 +
   16.37 +		for(int i=0; i<8; i++) {
   16.38 +			delete lights[i];
   16.39 +		}
   16.40 +
   16.41 +		std::list<Curve*>::iterator citer = curves.begin();
   16.42 +		while(citer != curves.end()) {
   16.43 +			delete *citer++;
   16.44 +		}
   16.45 +
   16.46 +		std::list<ShadowVolume>::iterator sv = StaticShadowVolumes.begin();
   16.47 +		while(sv != StaticShadowVolumes.end()) {
   16.48 +			delete (*sv++).shadow_mesh;
   16.49 +		}
   16.50 +	}
   16.51 +
   16.52 +}
   16.53 +
   16.54 +void Scene::SetGraphicsContext(GraphicsContext *gc) {
   16.55 +	this->gc = gc;
   16.56 +}
   16.57 +
   16.58 +void Scene::AddCamera(Camera *cam) {
   16.59 +	cameras.push_back(cam);
   16.60 +	if(!ActiveCamera) ActiveCamera = cam;
   16.61 +}
   16.62 +
   16.63 +void Scene::AddLight(Light *light) {
   16.64 +	for(int i=0; i<8; i++) {
   16.65 +		if(!lights[i]) {
   16.66 +			lights[i] = light;
   16.67 +			break;
   16.68 +		}
   16.69 +	}
   16.70 +}
   16.71 +
   16.72 +void Scene::AddObject(Object *obj) {
   16.73 +	if(obj->material.Alpha < 1.0f) {
   16.74 +        objects.push_back(obj);
   16.75 +	} else {
   16.76 +		objects.push_front(obj);
   16.77 +	}
   16.78 +}
   16.79 +
   16.80 +void Scene::AddStaticShadowVolume(TriMesh *mesh, const Light *light) {
   16.81 +	ShadowVolume svol;
   16.82 +	svol.shadow_mesh = mesh;
   16.83 +	svol.light = light;
   16.84 +	StaticShadowVolumes.push_back(svol);
   16.85 +}
   16.86 +
   16.87 +void Scene::AddCurve(Curve *curve) {
   16.88 +	curves.push_back(curve);
   16.89 +}
   16.90 +
   16.91 +
   16.92 +void Scene::RemoveObject(const Object *obj) {
   16.93 +	std::list<Object *>::iterator iter = objects.begin();
   16.94 +	while(iter != objects.end()) {
   16.95 +		if(obj == *iter) {
   16.96 +			objects.erase(iter);
   16.97 +			return;
   16.98 +		}
   16.99 +		iter++;
  16.100 +	}
  16.101 +}
  16.102 +
  16.103 +void Scene::RemoveLight(const Light *light) {
  16.104 +	for(int i=0; i<8; i++) {
  16.105 +		if(light = lights[i]) {
  16.106 +			lights[i] = 0;
  16.107 +			return;
  16.108 +		}
  16.109 +	}
  16.110 +}
  16.111 +
  16.112 +
  16.113 +Camera *Scene::GetCamera(const char *name) {
  16.114 +	std::list<Camera *>::iterator iter = cameras.begin();
  16.115 +	while(iter != cameras.end()) {
  16.116 +		if(!strcmp((*iter)->name.c_str(), name)) return *iter;
  16.117 +		iter++;
  16.118 +	}
  16.119 +	return 0;
  16.120 +}
  16.121 +
  16.122 +Light *Scene::GetLight(const char *name) {
  16.123 +	for(int i=0; i<8; i++) {
  16.124 +		if(!strcmp(lights[i]->name.c_str(), name)) return lights[i];
  16.125 +	}
  16.126 +	return 0;
  16.127 +}
  16.128 +
  16.129 +Object *Scene::GetObject(const char *name) {
  16.130 +	std::list<Object *>::iterator iter = objects.begin();
  16.131 +	while(iter != objects.end()) {
  16.132 +		if(!strcmp((*iter)->name.c_str(), name)) return *iter;
  16.133 +		iter++;
  16.134 +	}
  16.135 +	return 0;
  16.136 +}
  16.137 +
  16.138 +Curve *Scene::GetCurve(const char *name) {
  16.139 +	std::list<Curve *>::iterator iter = curves.begin();
  16.140 +	while(iter != curves.end()) {
  16.141 +		if(!strcmp((*iter)->name.c_str(), name)) return *iter;
  16.142 +		iter++;
  16.143 +	}
  16.144 +	return 0;
  16.145 +}
  16.146 +
  16.147 +
  16.148 +std::list<Object*> *Scene::GetObjectsList() {
  16.149 +	return &objects;
  16.150 +}
  16.151 +
  16.152 +
  16.153 +void Scene::SetActiveCamera(Camera *cam) {
  16.154 +	ActiveCamera = cam;
  16.155 +}
  16.156 +
  16.157 +Camera *Scene::GetActiveCamera() const {
  16.158 +	return ActiveCamera;
  16.159 +}
  16.160 +
  16.161 +void Scene::SetShadows(bool enable) {
  16.162 +	Shadows = enable;
  16.163 +}
  16.164 +
  16.165 +void Scene::SetHaloDrawing(bool enable) {
  16.166 +	LightHalos = enable;
  16.167 +}
  16.168 +
  16.169 +void Scene::SetHaloSize(float size) {
  16.170 +	HaloSize = size;
  16.171 +}
  16.172 +
  16.173 +void Scene::SetAmbientLight(Color ambient) {
  16.174 +	AmbientLight = ambient;
  16.175 +}
  16.176 +
  16.177 +Color Scene::GetAmbientLight() const {
  16.178 +	return AmbientLight;
  16.179 +}
  16.180 +
  16.181 +void Scene::SetFog(bool enable, Color FogColor, float Near, float Far) {
  16.182 +	UseFog = enable;
  16.183 +	if(enable) {
  16.184 +		this->FogColor = FogColor;
  16.185 +		NearFogRange = Near;
  16.186 +		FarFogRange = Far;
  16.187 +	}
  16.188 +}
  16.189 +
  16.190 +
  16.191 +void Scene::SetupLights() const {
  16.192 +	int LightIndex = 0;
  16.193 +	for(int i=0; i<8; i++) {
  16.194 +		if(lights[i]) {
  16.195 +			lights[i]->SetLight(LightIndex++, gc);
  16.196 +		}
  16.197 +	}
  16.198 +	gc->D3DDevice->LightEnable(LightIndex, false);
  16.199 +}
  16.200 +
  16.201 +
  16.202 +void Scene::RenderShadows() const {
  16.203 +	
  16.204 +	for(int i=0, slight=0; i<8; i++) {
  16.205 +		if(!lights[i] || !lights[i]->GetShadowCasting()) continue;
  16.206 +
  16.207 +		// disable shadow casting light and render the scene (first pass)
  16.208 +		gc->SetAlphaBlending(true);
  16.209 +		gc->D3DDevice->LightEnable(i, false);
  16.210 +		std::list<Object*>::const_iterator iter = objects.begin();
  16.211 +		while(iter != objects.end()) {
  16.212 +			Object *obj = *iter++;
  16.213 +			obj->Render();
  16.214 +		}
  16.215 +		gc->D3DDevice->LightEnable(i, true);
  16.216 +		gc->SetAlphaBlending(false);
  16.217 +
  16.218 +		// shadow volume front faces
  16.219 +		gc->SetZWrite(false);
  16.220 +		gc->SetColorWrite(false, false, false, false);
  16.221 +		gc->SetLighting(false);
  16.222 +	
  16.223 +		gc->SetStencilBuffering(true);
  16.224 +		gc->SetStencilFunc(CMP_ALWAYS);
  16.225 +		gc->SetStencilOp(SOP_KEEP, SOP_KEEP, SOP_INC);
  16.226 +
  16.227 +		iter = objects.begin();
  16.228 +		while(iter != objects.end()) {
  16.229 +			Object *obj = *iter++;
  16.230 +			TriMesh *mesh = obj->GetShadowVolume(slight);
  16.231 +			if(mesh) {
  16.232 +				gc->SetWorldMatrix(obj->GetWorldTransform());
  16.233 +				gc->Draw(const_cast<Vertex*>(mesh->GetVertexArray()), mesh->GetVertexCount());
  16.234 +
  16.235 +				// back faces pass
  16.236 +				//gc->SetFrontFace(CounterClockwise);
  16.237 +				//gc->SetStencilOp(SOP_KEEP, SOP_KEEP, SOP_DEC);
  16.238 +
  16.239 +				//gc->Draw(const_cast<Vertex*>(mesh->GetVertexArray()), mesh->GetVertexCount());
  16.240 +			}
  16.241 +		}
  16.242 +
  16.243 +		// static shadow volumes
  16.244 +		gc->SetWorldMatrix(Matrix4x4());
  16.245 +		std::list<ShadowVolume>::const_iterator shadow_iter = StaticShadowVolumes.begin();
  16.246 +		while(shadow_iter != StaticShadowVolumes.end()) {
  16.247 +			if(shadow_iter->light == lights[i]) {
  16.248 +				gc->Draw(const_cast<Vertex*>(shadow_iter->shadow_mesh->GetVertexArray()), shadow_iter->shadow_mesh->GetVertexCount());
  16.249 +			}
  16.250 +			shadow_iter++;
  16.251 +		}
  16.252 +
  16.253 +		// back faces pass
  16.254 +		gc->SetFrontFace(CounterClockwise);
  16.255 +		gc->SetStencilOp(SOP_KEEP, SOP_KEEP, SOP_DEC);
  16.256 +
  16.257 +		iter = objects.begin();
  16.258 +		while(iter != objects.end()) {
  16.259 +			Object *obj = *iter++;
  16.260 +			TriMesh *mesh = obj->GetShadowVolume(slight);
  16.261 +			if(mesh) {
  16.262 +				gc->SetWorldMatrix(obj->GetWorldTransform());
  16.263 +				gc->Draw(const_cast<Vertex*>(mesh->GetVertexArray()), mesh->GetVertexCount());
  16.264 +			}
  16.265 +		}
  16.266 +
  16.267 +		// static shadow volumes
  16.268 +		gc->SetWorldMatrix(Matrix4x4());
  16.269 +		shadow_iter = StaticShadowVolumes.begin();
  16.270 +		while(shadow_iter != StaticShadowVolumes.end()) {
  16.271 +			if(shadow_iter->light == lights[i]) {
  16.272 +				gc->Draw(const_cast<Vertex*>(shadow_iter->shadow_mesh->GetVertexArray()), shadow_iter->shadow_mesh->GetVertexCount());
  16.273 +			}
  16.274 +			shadow_iter++;
  16.275 +		}
  16.276 +
  16.277 +		gc->SetFrontFace(Clockwise);
  16.278 +
  16.279 +		gc->SetLighting(true);
  16.280 +		gc->SetZWrite(true);
  16.281 +		gc->SetColorWrite(true, true, true, true);
  16.282 +
  16.283 +		gc->SetStencilOp(SOP_KEEP, SOP_KEEP, SOP_KEEP);
  16.284 +		gc->SetStencilFunc(CMP_EQUAL);
  16.285 +		gc->SetStencilReference(0);
  16.286 +
  16.287 +		gc->SetLighting(true);
  16.288 +		//SetupLights();
  16.289 +
  16.290 +		slight++;
  16.291 +	}
  16.292 +}
  16.293 +
  16.294 +void Scene::Render() const {
  16.295 +	gc->SetAmbientLight(AmbientLight);
  16.296 +
  16.297 +	// set camera
  16.298 +	if(!ActiveCamera) return;
  16.299 +	ActiveCamera->CreateCameraMatrix();
  16.300 +	gc->SetViewMatrix(ActiveCamera->GetCameraMatrix());
  16.301 +
  16.302 +	// set projection matrix
  16.303 +	float NearClip, FarClip;
  16.304 +	Matrix4x4 ProjMat;
  16.305 +	ActiveCamera->GetClippingPlanes(&NearClip, &FarClip);
  16.306 +	CreateProjectionMatrix(&ProjMat, ActiveCamera->GetFOV(), 1.3333333f, NearClip, FarClip);
  16.307 +	gc->SetProjectionMatrix(ProjMat);	
  16.308 +
  16.309 +	SetupLights();
  16.310 +
  16.311 +	// render shadows
  16.312 +	if(Shadows) {
  16.313 +
  16.314 +		// make array of shadow-casting lights
  16.315 +		Light *ShadowCasters[8];
  16.316 +		Light **lptr = ShadowCasters;
  16.317 +		for(int i=0; i<8; i++) {
  16.318 +			if(lights[i] && lights[i]->GetShadowCasting()) {
  16.319 +				*lptr++ = lights[i];
  16.320 +			}
  16.321 +		}
  16.322 +		int ShadowCasterCount = (int)(lptr - ShadowCasters);
  16.323 +
  16.324 +		std::list<Object *>::const_iterator iter = objects.begin();
  16.325 +		while(iter != objects.end()) {
  16.326 +			Object *obj = *iter++;
  16.327 +			
  16.328 +			if(obj->GetShadowCasting()) {
  16.329 +                obj->CalculateShadows((const Light**)ShadowCasters, ShadowCasterCount);
  16.330 +			}
  16.331 +		}
  16.332 +
  16.333 +		RenderShadows();
  16.334 +	}
  16.335 +
  16.336 +	// render objects
  16.337 +	std::list<Object *>::const_iterator iter = objects.begin();
  16.338 +	while(iter != objects.end()) {
  16.339 +		Object *obj = *iter++;
  16.340 +
  16.341 +		obj->Render();
  16.342 +	}
  16.343 +
  16.344 +	if(Shadows) {
  16.345 +		gc->SetStencilBuffering(false);
  16.346 +		gc->SetStencilFunc(CMP_ALWAYS);
  16.347 +	}
  16.348 +
  16.349 +	if(LightHalos) {
  16.350 +		for(int i=0; i<8; i++) {
  16.351 +			if(lights[i]) lights[i]->Draw(gc, HaloSize);
  16.352 +		}
  16.353 +	}
  16.354 +}
  16.355 \ No newline at end of file
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/src/3deng/3dscene.h	Thu Oct 23 01:46:07 2014 +0300
    17.3 @@ -0,0 +1,81 @@
    17.4 +#ifndef _3DSCENE_H_
    17.5 +#define _3DSCENE_H_
    17.6 +
    17.7 +#include <list>
    17.8 +#include "3dengine.h"
    17.9 +#include "camera.h"
   17.10 +#include "lights.h"
   17.11 +#include "objects.h"
   17.12 +#include "curves.h"
   17.13 +
   17.14 +struct ShadowVolume {
   17.15 +	TriMesh *shadow_mesh;
   17.16 +	const Light *light;
   17.17 +};
   17.18 +
   17.19 +class Scene {
   17.20 +private:
   17.21 +	GraphicsContext *gc;
   17.22 +
   17.23 +	Light *lights[8];
   17.24 +	std::list<Camera *> cameras;
   17.25 +	std::list<Object *> objects;
   17.26 +	std::list<ShadowVolume> StaticShadowVolumes;
   17.27 +	std::list<Curve *> curves;
   17.28 +	bool ManageData;
   17.29 +
   17.30 +	Camera *ActiveCamera;
   17.31 +
   17.32 +	bool Shadows;
   17.33 +	bool LightHalos;
   17.34 +	float HaloSize;
   17.35 +
   17.36 +	Color AmbientLight;
   17.37 +	
   17.38 +	bool UseFog;
   17.39 +	Color FogColor;
   17.40 +	float NearFogRange, FarFogRange;
   17.41 +		
   17.42 +public:
   17.43 +
   17.44 +	Scene(GraphicsContext *gc = 0);
   17.45 +	~Scene();
   17.46 +
   17.47 +	void SetGraphicsContext(GraphicsContext *gc);
   17.48 +
   17.49 +	void AddCamera(Camera *cam);
   17.50 +	void AddLight(Light *light);
   17.51 +	void AddObject(Object *obj);
   17.52 +	void AddStaticShadowVolume(TriMesh *mesh, const Light *light);
   17.53 +	void AddCurve(Curve *curve);
   17.54 +
   17.55 +	void RemoveObject(const Object *obj);
   17.56 +	void RemoveLight(const Light *light);
   17.57 +
   17.58 +	Camera *GetCamera(const char *name);
   17.59 +	Light *GetLight(const char *name);
   17.60 +	Object *GetObject(const char *name);
   17.61 +	Curve *GetCurve(const char *name);
   17.62 +
   17.63 +	std::list<Object*> *GetObjectsList();
   17.64 +
   17.65 +	void SetActiveCamera(Camera *cam);
   17.66 +	Camera *GetActiveCamera() const;
   17.67 +
   17.68 +	void SetShadows(bool enable);
   17.69 +	void SetHaloDrawing(bool enable);
   17.70 +	void SetHaloSize(float size);
   17.71 +	void SetAmbientLight(Color ambient);
   17.72 +	Color GetAmbientLight() const;
   17.73 +	void SetFog(bool enable, Color FogColor = Color(0l), float Near = 0.0f, float Far = 1000.0f);
   17.74 +
   17.75 +	// render states
   17.76 +	void SetupLights() const;
   17.77 +
   17.78 +	void RenderShadows() const;
   17.79 +	void Render() const;
   17.80 +};
   17.81 +	
   17.82 +
   17.83 +
   17.84 +#endif	// _3DSCENE_H_
   17.85 \ No newline at end of file
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/src/3deng/3dschunks.h	Thu Oct 23 01:46:07 2014 +0300
    18.3 @@ -0,0 +1,160 @@
    18.4 +#ifndef _3DSCHUNKS_H_
    18.5 +#define _3DSCHUNKS_H_
    18.6 +
    18.7 +enum ChunkID {
    18.8 +	Chunk_Color_Float3					= 0x0010,	// o Floating point color
    18.9 +	Chunk_Color_Byte3					= 0x0011,	// o 24bit color
   18.10 +	Chunk_Color_GammaByte3				= 0x0012,	// o 24bit gamma corrected
   18.11 +	Chunk_Color_GammaFloat3				= 0x0013,	// o Floating point gamma corrected
   18.12 +	Chunk_PercentInt					= 0x0030,	// o Percent Chunk int 0 - 100
   18.13 +	Chunk_PercentFloat					= 0x0031,	// o Percent Chunk float 0 - 1
   18.14 +
   18.15 +	Chunk_3DSMain						= 0x4D4D,	// + Root Chunk
   18.16 +	Chunk_Main_3DSVersion				= 0x0002,	//   - 3DS Version
   18.17 +	Chunk_Main_3DEditor					= 0x3D3D,	//   + 3D Editor Chunk
   18.18 +	Chunk_Edit_Unit						= 0x0100,	//     - Unit
   18.19 +	Chunk_Edit_BGBitmap					= 0x1100,	//     - Background Bitmap
   18.20 +	Chunk_Edit_UseBGBitmap				= 0x1101,	//     - Use Background Bitmap
   18.21 +	Chunk_Edit_BGColor					= 0x1200,	//     - Background Color
   18.22 +	Chunk_Edit_UseBGColor				= 0x1201,	//     - Use Background Color
   18.23 +	Chunk_Edit_GradColor				= 0x1300,	//     - Background Gradient
   18.24 +	Chunk_Edit_UseGradColor				= 0x1301,	//     - Use Gradient Color
   18.25 +	Chunk_Edit_ShadowMapBias			= 0x1400,	//     - Shadow map bias
   18.26 +	Chunk_Edit_ShadowMapSize			= 0x1420,	//     - Shadow map size
   18.27 +	Chunk_Edit_ShadowMapSampleRange		= 0x1450,	//     - Shadow map sample range
   18.28 +	Chunk_Edit_RaytraceBias				= 0x1460,	//     - Raytrace bias
   18.29 +	Chunk_Edit_UseRaytrace				= 0x1470,	//     - Use Raytrace
   18.30 +	Chunk_Edit_AmbientColor				= 0x2100,	//     - Ambient Color
   18.31 +	Chunk_Edit_Fog						= 0x2200,	//     + Fog
   18.32 +	Chunk_Fog_FogColor					= 0x2210,	//	     - Fog Color
   18.33 +	Chunk_Edit_UseFog					= 0x2201,	//     - Use Fog
   18.34 +	Chunk_Edit_DistanceQue				= 0x2300,	//     + Distance que
   18.35 +	Chunk_Dist_DimBackground			= 0x2310,	//       - Dim Background
   18.36 +	Chunk_Edit_UseDistanceQue			= 0x2301,	//     - Use distance que
   18.37 +	Chunk_Edit_LayeredFogOptions		= 0x2302,	//     - Layered fog options
   18.38 +	Chunk_Edit_UseLayeredFog			= 0x2303,	//     - Use Layered Fog
   18.39 +	Chunk_Edit_MeshVersion				= 0x3D3E,	//     - Mesh Version
   18.40 +
   18.41 +	Chunk_Edit_Object					= 0x4000,	//     + Object
   18.42 +	Chunk_Obj_Hidden					= 0x4010,	//       - Hidden
   18.43 +	Chunk_Obj_DontCastShadows			= 0x4012,	//       - Object doesn't cast shadows
   18.44 +	Chunk_Obj_MatteObject				= 0x4013,	//       - Matte
   18.45 +	Chunk_Obj_ExternalProcessOn			= 0x4015,	//       - External Process on (?)
   18.46 +	Chunk_Obj_DontReceiveShadows		= 0x4017,	//       - doesn't reseive shadows
   18.47 +	Chunk_Obj_TriMesh					= 0x4100,	//       + TriMesh
   18.48 +	Chunk_TriMesh_VertexList			= 0x4110,	//         - Vertex List
   18.49 +	Chunk_TriMesh_FaceDesc				= 0x4120,	//         + Faces description
   18.50 +	Chunk_Face_Material					= 0x4130,	//           - Face Materials*
   18.51 +	Chunk_TriMesh_TexCoords				= 0x4140,	//         - Texture Coordinates
   18.52 +	Chunk_TriMesh_SmoothingGroup		= 0x4150,	//         - Smoothing group
   18.53 +	Chunk_TriMesh_WorldTransform		= 0x4160,	//         - Position and Orientation
   18.54 +	Chunk_TriMesh_Color					= 0x4165,   //         - Object color
   18.55 +	Chunk_TriMesh_ExternalProcessName	= 0x4181,	//         - External Process name (?)
   18.56 +	Chunk_TriMesh_ExternalProcessParams	= 0x4182,	//         - External Process parameters (?)
   18.57 +
   18.58 +	Chunk_Obj_Light						= 0x4600,	//       + Light
   18.59 +	Chunk_Light_SpotLight				= 0x4610,	//         + SpotLight
   18.60 +	Chunk_Spot_Raytrace					= 0x4627,	//           - Raytrace
   18.61 +	Chunk_Spot_CastShadows				= 0x4630,	//           - Light casts shadows
   18.62 +	Chunk_Spot_ShadowMap				= 0x4641,	//           - Shadow Map
   18.63 +	Chunk_Spot_ShowCone					= 0x4650,	//           - Show Cone
   18.64 +	Chunk_Spot_Rectangular				= 0x4651,	//           - Rectangular shaped spotlight
   18.65 +	Chunk_Spot_OverShoot				= 0x4652,	//           - Overshoot
   18.66 +	Chunk_Spot_ProjMap					= 0x4653,	//           - Projector Map
   18.67 +	Chunk_Spot_Roll						= 0x4656,	//           - Roll around dir
   18.68 +	Chunk_Spot_RaytraceBias				= 0x4658,	//           - Raytrace Bias
   18.69 +	Chunk_Light_Off						= 0x4620,	//         - Light is disabled
   18.70 +	Chunk_Light_Attenuation				= 0x4625,	//         - Attenuation enabled
   18.71 +	Chunk_Light_AttenuationStart		= 0x4659,	//         - Attenuation Start Range
   18.72 +	Chunk_Light_AttenuationEnd			= 0x465A,	//         - Attenuation End Range
   18.73 +	Chunk_Light_Intensity				= 0x465B,	//         - Light Intensity
   18.74 +
   18.75 +	Chunk_Obj_Camera					= 0x4700,	//       - Camera
   18.76 +	Chunk_Edit_ViewSettings				= 0x7001,	//     - View Settings
   18.77 +	Chunk_Edit_ViewDesc2				= 0x7011,	//     - View Description 2
   18.78 +	Chunk_Edit_ViewDesc1				= 0x7012,	//     - View Description 1
   18.79 +	Chunk_Edit_MeshWindows				= 0x7020,	//     - Mesh Windows (?)
   18.80 +
   18.81 +	Chunk_Edit_Material					= 0xAFFF,	//     + Material Block
   18.82 +	Chunk_Mat_Name						= 0xA000,	//       - Material Name
   18.83 +	Chunk_Mat_AmbientColor				= 0xA010,	//       - Ambient Color
   18.84 +	Chunk_Mat_DiffuseColor				= 0xA020,	//       - Diffuse Color
   18.85 +	Chunk_Mat_SpecularColor				= 0xA030,	//       - Specular Color
   18.86 +	Chunk_Mat_Specular					= 0xA040,	//       - Shininness (Specular Power)
   18.87 +	Chunk_Mat_SpecularIntensity			= 0xA041,	//       - Shininness Strength (specular intensity)
   18.88 +	Chunk_Mat_Transparency				= 0xA050,	//       - Transparency (alpha)
   18.89 +	Chunk_Mat_TransparencyFalloff		= 0xA052,	//       - Transparency Falloff
   18.90 +	Chunk_Mat_ReflectionBlur			= 0xA053,	//       - Reflection Blur
   18.91 +	Chunk_Mat_TwoSided					= 0xA081,	//       - Two Sided
   18.92 +	Chunk_Mat_AddTransparency			= 0xA083,	//       - ?
   18.93 +	Chunk_Mat_SelfIllumination			= 0xA084,	//       - Self Illumination (emissive)
   18.94 +	Chunk_Mat_Wireframe					= 0xA085,	//       - Render in wireframe
   18.95 +	Chunk_Mat_WireframeThickness		= 0xA087,	//       - Wire thickness
   18.96 +	Chunk_Mat_FaceMapping				= 0xA088,	//       - Apply maps to faces seperatly (ignore uv)
   18.97 +	Chunk_Mat_InTranc					= 0xA08A,	// ?
   18.98 +	Chunk_Mat_Soften					= 0xA08C,	//       - Soft Shading
   18.99 +	Chunk_Mat_WireUnits					= 0xA08E,	//       - Wire units (?)
  18.100 +	Chunk_Mat_RenderType				= 0xA100,	//       - Render Type
  18.101 +	Chunk_Mat_BumpMapPercent			= 0xA252,	//       - Bump map intensity
  18.102 +	Chunk_Mat_TextureMap				= 0xA200,	//       + Texture Map
  18.103 +	Chunk_Mat_TextureMap2				= 0xA33A,	//       + Texture Map 2
  18.104 +	Chunk_Mat_OpacityMap				= 0xA210,	//       + Opacity Map
  18.105 +	Chunk_Mat_BumpMap					= 0xA230,	//       + Bump Map
  18.106 +	Chunk_Mat_SpecularMap				= 0xA33C,	//       + Specular Intensity map
  18.107 +	Chunk_Mat_SpecularColorMap			= 0xA204,	//       + Specular color (texture) map
  18.108 +	Chunk_Mat_SelfIlluminationMap		= 0xA33D,	//       + Self Illumination Map
  18.109 +	Chunk_Mat_ReflectionMap				= 0xA220,	//       + Reflection Map
  18.110 +	Chunk_Mat_TextureMask				= 0xA33E,	//       - Texture Mask
  18.111 +	Chunk_Mat_Texture2Mask				= 0xA340,	//       - Texture 2 Mask
  18.112 +	Chunk_Mat_OpacityMask				= 0xA342,	//       - Opacity Mask
  18.113 +	Chunk_Mat_BumpMask					= 0xA344,	//       - Bump Mask
  18.114 +	Chunk_Mat_SpecularMask				= 0xA346,	//       - Specular Mask
  18.115 +	Chunk_Mat_SpecularColorMask			= 0xA348,	//       - Specular color mask
  18.116 +	Chunk_Mat_SelfIlluminationMask		= 0xA34A,	//       - Self Illumination mask
  18.117 +	Chunk_Mat_ReflectionMask			= 0xA34C,	//       - Reflection mask
  18.118 +	
  18.119 +	// map subchunks								// -----------------------
  18.120 +	Chunk_Map_FileName					= 0xA300,	//         - Filename
  18.121 +	Chunk_Map_Params					= 0xA351,	//         - Parameters
  18.122 +	Chunk_Map_BlurPercent				= 0xA353,	//         - Blur ammount
  18.123 +	Chunk_Map_VScale					= 0xA354,	//         - Texture V Scale
  18.124 +	Chunk_Map_UScale					= 0xA356,	//         - Texture U Scale
  18.125 +	Chunk_Map_UOffset					= 0xA358,	//         - Texture U Offset
  18.126 +	Chunk_MAP_VOffset					= 0xA35A,	//         - Texture V Offset
  18.127 +	Chunk_Map_RotationAngle				= 0xA35C,	//         - Texture Rotation Angle
  18.128 +	Chunk_Map_RGBLumAlphaTint1			= 0xA360,	//         - RGB Luminance Alpha Tint 1
  18.129 +	Chunk_Map_RGBLumAlphaTint2			= 0xA362,	//         - RGB Luminance Alpha Tint 2
  18.130 +	Chunk_Map_RGBTintR					= 0xA364,	//         - RGB Tint R
  18.131 +	Chunk_Map_RGBTintG					= 0xA366,	//         - RGB Tint G
  18.132 +	Chunk_Map_RGBTintB					= 0xA368,	//         - RGB Tint B
  18.133 +	// map subchunks end							// -----------------------
  18.134 +
  18.135 +	Chunk_Main_Keyframer				= 0xB000,	//     + Keyframer Chunk
  18.136 +	Chunk_Key_AmbientInfo				= 0xB001,	//       - Ambient animation info
  18.137 +	Chunk_Key_MeshInfo					= 0xB002,	//       - Mesh animation info
  18.138 +	Chunk_Key_CameraInfo				= 0xB003,	//       - Camera animation info
  18.139 +	Chunk_Key_CameraTargetInfo			= 0xB004,	//       - Camera Target animation info
  18.140 +	Chunk_Key_OmniLightInfo				= 0xB005,	//       - Omni Light animation info
  18.141 +	Chunk_Key_SpotLightTargetInfo		= 0xB006,	//       - Spotlight target animation info
  18.142 +	Chunk_Key_SpotLightInfo				= 0xB007,	//       - Spotlight animation info
  18.143 +	Chunk_Key_Frames					= 0xB008,	//       - Animation Frames
  18.144 +	
  18.145 +	// animation information subchunks				// -----------------------
  18.146 +	Chunk_Info_Object					= 0xB010,	//         - Object information
  18.147 +	Chunk_Info_ObjectPivot				= 0xB013,	//         - Object Pivot
  18.148 +	Chunk_Info_ObjectMorphAngle			= 0xB015,	//         - Object Morph Angle
  18.149 +	Chunk_Info_PositionTrack			= 0xB020,	//         - Position Track
  18.150 +	Chunk_Info_RotationTrack			= 0xB021,	//         - Rotation Track
  18.151 +	Chunk_Info_ScaleTrack				= 0xB022,	//         - Scaling Track
  18.152 +	Chunk_Info_FOVTrack					= 0xB023,	//         - FOV Track
  18.153 +	Chunk_Info_RollTrack				= 0xB024,	//         - Roll Track
  18.154 +	Chunk_Info_ColorTrack				= 0xB025,	//         - Color Track
  18.155 +	Chunk_Info_MorphTrack				= 0xB026,	//         - Morph Track
  18.156 +	Chunk_Info_HotSpotTrack				= 0xB027,	//         - HotSpot Track
  18.157 +	Chunk_Info_FalloffTrack				= 0xB028,	//         - Falloff Track
  18.158 +	Chunk_Info_HideTrack				= 0xB029,	//         - Hide Track
  18.159 +	Chunk_Info_HierarchyPosition		= 0xB030	//         - Hierarchy Position
  18.160 +};
  18.161 +
  18.162 +#endif	// _3DSCHUNKS_H_
  18.163 +
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/src/3deng/SceneLoader.h	Thu Oct 23 01:46:07 2014 +0300
    19.3 @@ -0,0 +1,18 @@
    19.4 +#ifndef _SCENELOADER_H_
    19.5 +#define _SCENELOADER_H_
    19.6 +
    19.7 +#include "3deng/objects.h"
    19.8 +#include "3deng/3dscene.h"
    19.9 +#include "3deng/material.h"
   19.10 +
   19.11 +namespace SceneLoader {
   19.12 +	void SetGraphicsContext(GraphicsContext *gfx);
   19.13 +	void SetDataPath(const char *path);
   19.14 +	void SetNormalFileSaving(bool enable);
   19.15 +
   19.16 +	bool LoadObject(const char *fname, const char *ObjectName, Object **obj);
   19.17 +	bool LoadScene(const char *fname, Scene **scene);
   19.18 +	bool LoadMaterials(const char *fname, Material **materials);
   19.19 +}
   19.20 +
   19.21 +#endif	// _SCENELOADER_H_
   19.22 \ No newline at end of file
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/src/3deng/camera.cpp	Thu Oct 23 01:46:07 2014 +0300
    20.3 @@ -0,0 +1,228 @@
    20.4 +#include "camera.h"
    20.5 +
    20.6 +// camera constructor
    20.7 +Camera::Camera() {
    20.8 +	Pos = Vector3(0.0f, 0.0f, 0.0f);
    20.9 +	LookAt = Vector3(0.0f, 0.0f, 5.0f);
   20.10 +	Up = Vector3(0.0f, 1.0f, 0.0f);
   20.11 +	FOV = QuarterPi;		// 45 deg
   20.12 +	CreateCameraMatrix();
   20.13 +
   20.14 +	FlipRight = false;
   20.15 +
   20.16 +	path = 0;
   20.17 +	targpath = 0;
   20.18 +
   20.19 +	NearClip = 1.0f;
   20.20 +	FarClip = 10000.0f;
   20.21 +}
   20.22 +
   20.23 +void Camera::SetCamera(const Vector3 &pos, const Vector3 &lookat, const Vector3 &up) {
   20.24 +	Pos = pos;
   20.25 +	LookAt = lookat;
   20.26 +	Up = up;
   20.27 +}
   20.28 +
   20.29 +void Camera::SetClippingPlanes(float NearClip, float FarClip) {
   20.30 +	this->NearClip = NearClip;
   20.31 +	this->FarClip = FarClip;
   20.32 +}
   20.33 +
   20.34 +void Camera::GetClippingPlanes(float *NearClip, float *FarClip) const {
   20.35 +	*NearClip = this->NearClip;
   20.36 +	*FarClip = this->FarClip;
   20.37 +}
   20.38 +
   20.39 +Matrix4x4 &Camera::GetCameraMatrix() {
   20.40 +	return CCSmat;
   20.41 +}
   20.42 +
   20.43 +Vector3 Camera::GetViewVector() const {
   20.44 +	return LookAt - Pos;
   20.45 +}
   20.46 +
   20.47 +Vector3 Camera::GetPosition() const {
   20.48 +	return Pos;
   20.49 +}
   20.50 +
   20.51 +Vector3 Camera::GetUpVector() const {
   20.52 +	return Up;
   20.53 +}
   20.54 +
   20.55 +Vector3 Camera::GetTargetPosition() const {
   20.56 +	return LookAt;
   20.57 +}
   20.58 +
   20.59 +Base Camera::GetCameraBase() const {
   20.60 +	Base base;
   20.61 +	base.k = (LookAt - Pos).Normalized();
   20.62 +	base.j = Up.Normalized();
   20.63 +	base.i = CrossProduct(base.j, base.k);
   20.64 +	base.j = CrossProduct(base.i, base.k);
   20.65 +
   20.66 +	return base;
   20.67 +}
   20.68 +
   20.69 +//////////////////////////////////////////////////////////////
   20.70 +// Create a camera matrix from 3 vectors position/lookat/up //
   20.71 +//////////////////////////////////////////////////////////////
   20.72 +void Camera::CreateCameraMatrix(Matrix4x4 *matrix, const Vector3 &Pos, const Vector3 &LookAt, const Vector3 &Up) const {
   20.73 +
   20.74 +	Vector3 n = LookAt - Pos;
   20.75 +	n.Normalize();
   20.76 +	Vector3 u = Up.CrossProduct(n);
   20.77 +	u.Normalize();
   20.78 +	Vector3 v = n.CrossProduct(u);
   20.79 +	float Tx = -(u.DotProduct(Pos));
   20.80 +	float Ty = -(v.DotProduct(Pos));
   20.81 +	float Tz = -(n.DotProduct(Pos));
   20.82 +	
   20.83 +	matrix->ResetIdentity();
   20.84 +	matrix->m[0][0] = u.x;	matrix->m[0][1] = v.x;	matrix->m[0][2] = n.x;
   20.85 +	matrix->m[1][0] = u.y;	matrix->m[1][1] = v.y;	matrix->m[1][2] = n.y;
   20.86 +	matrix->m[2][0] = u.z;	matrix->m[2][1] = v.z;	matrix->m[2][2] = n.z;
   20.87 +	matrix->m[3][0] = Tx;	matrix->m[3][1] = Ty;	matrix->m[3][2] = Tz;
   20.88 +}
   20.89 +
   20.90 +void Camera::CreateCameraMatrix() {
   20.91 +	CreateCameraMatrix(&CCSmat, Pos, LookAt, Up);
   20.92 +}
   20.93 +
   20.94 +///////////////////////////////////////////////////////
   20.95 +// controling the camera
   20.96 +
   20.97 +// moves the camera x/y/z units
   20.98 +void Camera::Move(float x, float y, float z) {
   20.99 +	PosTranslate.Translate(x,y,z);
  20.100 +	LookTranslate.Translate(x,y,z);
  20.101 +	UpTranslate.Translate(x,y,z);
  20.102 +}
  20.103 +
  20.104 +// moves the camera TO the new coords
  20.105 +void Camera::MoveTo(float x, float y, float z) {
  20.106 +	Vector3 newpos = Vector3(x,y,z);
  20.107 +	// find the difference between the old and new position
  20.108 +	Vector3 translation = newpos - Pos;
  20.109 +	PosTranslate.Translate(translation.x, translation.y, translation.z);
  20.110 +	LookTranslate.Translate(translation.x, translation.y, translation.z);
  20.111 +	UpTranslate.Translate(translation.x, translation.y, translation.z);
  20.112 +}
  20.113 +
  20.114 +void Camera::Rotate(float x, float y, float z) {
  20.115 +	// find the inverted lookat vector
  20.116 +	Vector3 ilook = Pos - LookAt;
  20.117 +	Vector3 newilook = ilook;
  20.118 +	// rotate it
  20.119 +	Matrix4x4 rot;
  20.120 +	rot.ResetIdentity();
  20.121 +	rot.Rotate(x,y,z);
  20.122 +	newilook.Transform(rot);
  20.123 +	// find the translation difference between the two vectors
  20.124 +	Vector3 transl = newilook - ilook;
  20.125 +	//do it
  20.126 +	PosTranslate.ResetIdentity();
  20.127 +	PosTranslate.Translate(transl.x, transl.y, transl.z);
  20.128 +	UpRotate.ResetIdentity();
  20.129 +	UpRotate.Rotate(x, y, z);
  20.130 +
  20.131 +	// apply the transformation
  20.132 +	Pos.Transform(PosTranslate);
  20.133 +	Up.Transform(UpRotate);
  20.134 +}
  20.135 +	
  20.136 +
  20.137 +////////////////// rotates the camera around the target ///////////////
  20.138 +
  20.139 +inline void Camera::RotateTarget(float x, float y, float z) {
  20.140 +	LookRotate.Rotate(x, y, z);
  20.141 +}
  20.142 +
  20.143 +inline void Camera::MoveTarget(float x, float y, float z) {
  20.144 +	LookTranslate.Translate(x,y,z);
  20.145 +}
  20.146 +
  20.147 +// moves the look at point at the point specified
  20.148 +inline void Camera::MoveTargetTo(float x, float y, float z) {
  20.149 +	Vector3 translation = Vector3(x,y,z) - LookAt;
  20.150 +	LookTranslate.Translate(translation.x, translation.y, translation.z);
  20.151 +}
  20.152 +
  20.153 +void Camera::Zoom(float factor) {
  20.154 +	// find the new vector between the camera and the target
  20.155 +	Vector3 offset = (LookAt - Pos) * factor;
  20.156 +	Vector3 diff = offset - LookAt;
  20.157 +	Pos += offset;
  20.158 +
  20.159 +	//PosTranslate.ResetIdentity();
  20.160 +	//PosTranslate.Translate(diff.x, diff.y, diff.z);
  20.161 +	//Pos.Transform(PosTranslate);
  20.162 +}
  20.163 +
  20.164 +void Camera::Spin(float rads) {
  20.165 +	Up.Rotate((LookAt - Pos).Normalized(), rads);
  20.166 +}
  20.167 +
  20.168 +void Camera::SetRightFlipping(bool enable) {
  20.169 +	FlipRight = enable;
  20.170 +}
  20.171 +void Camera::SetPosition(const Vector3 &pos) {
  20.172 +	this->Pos = pos;
  20.173 +}
  20.174 +
  20.175 +void Camera::SetUpVector(const Vector3 &up) {
  20.176 +	Up = up;
  20.177 +}
  20.178 +
  20.179 +void Camera::SetTarget(const Vector3 &targ) {
  20.180 +	this->LookAt = targ;
  20.181 +}
  20.182 +
  20.183 +
  20.184 +void Camera::ResetRotation() {
  20.185 +	PosRotate.ResetIdentity();
  20.186 +}
  20.187 +
  20.188 +
  20.189 +void Camera::SetCameraPath(const Curve *path, const Curve *tpath, dword StartTime, dword EndTime) {
  20.190 +	this->path = path;
  20.191 +	this->targpath = tpath;
  20.192 +	this->StartTime = StartTime;
  20.193 +	this->EndTime = EndTime;
  20.194 +}
  20.195 +
  20.196 +void Camera::FollowPath(dword time, bool Cycle) {
  20.197 +	if(Cycle || (!Cycle && time >= StartTime && time < EndTime)) {
  20.198 +		float t = (float)(time - StartTime) / (float)(EndTime - StartTime);
  20.199 +		if(Cycle) {
  20.200 +			t = (float)fmod(t, 1.0f);
  20.201 +		} else {
  20.202 +            if(t < 0.0f) t = 0.0f;
  20.203 +			if(t > 1.0f) t = 1.0f;
  20.204 +		}
  20.205 +		if(path) {
  20.206 +			SetPosition(const_cast<Curve*>(path)->Interpolate(t));
  20.207 +		}
  20.208 +		if(targpath) {
  20.209 +			SetTarget(const_cast<Curve*>(targpath)->Interpolate(t));
  20.210 +		}
  20.211 +	}
  20.212 +}
  20.213 +
  20.214 +void Camera::FollowPath(float t) {
  20.215 +	if(t < 0.0f) t = 0.0f;
  20.216 +	if(t > 1.0f) t = 1.0f;
  20.217 +	if(path) {
  20.218 +		SetPosition(const_cast<Curve*>(path)->Interpolate(t));
  20.219 +	}
  20.220 +	if(targpath) {
  20.221 +		SetTarget(const_cast<Curve*>(targpath)->Interpolate(t));
  20.222 +	}
  20.223 +}
  20.224 +
  20.225 +dword Camera::GetStartTime() const {
  20.226 +	return StartTime;
  20.227 +}
  20.228 +
  20.229 +dword Camera::GetEndTime() const {
  20.230 +	return EndTime;
  20.231 +}
  20.232 \ No newline at end of file
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/src/3deng/camera.h	Thu Oct 23 01:46:07 2014 +0300
    21.3 @@ -0,0 +1,77 @@
    21.4 +#ifndef _CAMERA_H_
    21.5 +#define _CAMERA_H_
    21.6 +
    21.7 +#include <string>
    21.8 +#include "switches.h"
    21.9 +#include "n3dmath.h"
   21.10 +#include "curves.h"
   21.11 +#include "typedefs.h"
   21.12 +
   21.13 +class Camera {
   21.14 +private:
   21.15 +	Vector3 Pos, LookAt, Up;
   21.16 +	float FOV;
   21.17 +	float NearClip, FarClip;
   21.18 +	// transformation matrices for each vector
   21.19 +	Matrix4x4 PosTranslate, LookTranslate, UpTranslate;
   21.20 +	Matrix4x4 PosRotate, LookRotate, UpRotate;
   21.21 +	Matrix4x4 PosScale, LookScale, UpScale;
   21.22 +
   21.23 +	bool FlipRight;
   21.24 +
   21.25 +	const Curve *path, *targpath;
   21.26 +	dword StartTime, EndTime;
   21.27 +
   21.28 +public:
   21.29 +	std::string name;
   21.30 +	Matrix4x4 CCSmat;
   21.31 +
   21.32 +	Camera();
   21.33 +	float GetFOV() const {return FOV;}
   21.34 +	void SetFOV(float FOV) {this->FOV = FOV;}
   21.35 +
   21.36 +	void SetClippingPlanes(float NearClip, float FarClip);
   21.37 +	void GetClippingPlanes(float *NearClip, float *FarClip) const;
   21.38 +
   21.39 +	void SetCamera(const Vector3 &pos, const Vector3 &lookat, const Vector3 &up);
   21.40 +	Matrix4x4 &GetCameraMatrix();
   21.41 +
   21.42 +	// camera controls
   21.43 +	void Move(float x, float y, float z);
   21.44 +	void MoveTo(float x, float y, float z);
   21.45 +	void Rotate(float x, float y, float z);
   21.46 +	void Zoom(float factor);
   21.47 +
   21.48 +	// haphazard additions
   21.49 +	void SetRightFlipping(bool enable);
   21.50 +	void SetPosition(const Vector3 &pos);
   21.51 +	void SetUpVector(const Vector3 &up);
   21.52 +	void SetTarget(const Vector3 &targ);
   21.53 +
   21.54 +	Vector3 GetViewVector() const;
   21.55 +	Vector3 GetPosition() const;
   21.56 +	Vector3 GetUpVector() const;
   21.57 +	Vector3 GetTargetPosition() const;
   21.58 +
   21.59 +	Base GetCameraBase() const;
   21.60 +		
   21.61 +	inline void MoveTarget(float x, float y, float z);
   21.62 +	inline void MoveTargetTo(float x, float y, float z);
   21.63 +	inline void RotateTarget(float x, float y, float z);
   21.64 +
   21.65 +	void ResetRotation();
   21.66 +
   21.67 +	void CreateCameraMatrix();
   21.68 +	void CreateCameraMatrix(Matrix4x4 *matrix, const Vector3 &Pos, const Vector3 &LookAt, const Vector3 &Up) const;
   21.69 +	
   21.70 +	void Spin(float rads);
   21.71 +
   21.72 +	void SetCameraPath(const Curve *path, const Curve *tpath, dword StartTime, dword EndTime);
   21.73 +	void FollowPath(dword time, bool Cycle = false);
   21.74 +	void FollowPath(float t);
   21.75 +
   21.76 +	dword GetStartTime() const;
   21.77 +	dword GetEndTime() const;
   21.78 +};
   21.79 +
   21.80 +#endif	// _CAMERA_H_
   21.81 \ No newline at end of file
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/src/3deng/exceptions.cpp	Thu Oct 23 01:46:07 2014 +0300
    22.3 @@ -0,0 +1,44 @@
    22.4 +#include "exceptions.h"
    22.5 +
    22.6 +EngineInitException::EngineInitException() {
    22.7 +	str = "Unknown";
    22.8 +}
    22.9 +
   22.10 +EngineInitException::EngineInitException(string reason) {
   22.11 +	str = reason;
   22.12 +}
   22.13 +
   22.14 +string EngineInitException::GetReason() const {
   22.15 +	string tmp = "An error occured while initializing the 3D Engine\nReason: ";
   22.16 +	tmp += str;
   22.17 +	return tmp;
   22.18 +}
   22.19 +
   22.20 +EngineModuleNotFoundException::EngineModuleNotFoundException() {
   22.21 +	str = "Unknown Module";
   22.22 +}
   22.23 +
   22.24 +EngineModuleNotFoundException::EngineModuleNotFoundException(string modulename) {
   22.25 +	str = modulename;
   22.26 +}
   22.27 +
   22.28 +string EngineModuleNotFoundException::GetReason() const {
   22.29 +	string tmp = "The 3D Engine could not link a required module.\n";
   22.30 +	tmp += "Please contact the program ventor to obtain the missing file.\nMissing File: ";
   22.31 +	tmp += str;
   22.32 +	return tmp;
   22.33 +}
   22.34 +
   22.35 +EngineGeneralException::EngineGeneralException() {
   22.36 +	str = "Unknown";
   22.37 +}
   22.38 +
   22.39 +EngineGeneralException::EngineGeneralException(string reason) {
   22.40 +	str = reason;
   22.41 +}
   22.42 +
   22.43 +string EngineGeneralException::GetReason() const {
   22.44 +	string tmp = "An error occured in the 3D Engine\nReason: ";
   22.45 +	tmp += str;
   22.46 +	return tmp;
   22.47 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/src/3deng/exceptions.h	Thu Oct 23 01:46:07 2014 +0300
    23.3 @@ -0,0 +1,41 @@
    23.4 +#ifndef _EXCEPTIONS_H_
    23.5 +#define _EXCEPTIONS_H_
    23.6 +
    23.7 +#include <string>
    23.8 +
    23.9 +using std::string;
   23.10 +
   23.11 +class EngineBaseException {
   23.12 +protected:
   23.13 +	string str;
   23.14 +
   23.15 +public:
   23.16 +
   23.17 +	virtual string GetReason() const = 0;
   23.18 +};
   23.19 +
   23.20 +class EngineInitException : protected EngineBaseException {
   23.21 +public:
   23.22 +	EngineInitException();
   23.23 +	EngineInitException(string reason);
   23.24 +
   23.25 +	virtual string GetReason() const;
   23.26 +};
   23.27 +
   23.28 +class EngineModuleNotFoundException : protected EngineBaseException {
   23.29 +public:
   23.30 +	EngineModuleNotFoundException();
   23.31 +	EngineModuleNotFoundException(string modulename);
   23.32 +
   23.33 +	virtual string GetReason() const;
   23.34 +};
   23.35 +
   23.36 +class EngineGeneralException : protected EngineBaseException {
   23.37 +public:
   23.38 +	EngineGeneralException();
   23.39 +	EngineGeneralException(string reason);
   23.40 +
   23.41 +	virtual string GetReason() const;
   23.42 +};
   23.43 +
   23.44 +#endif	// _EXCEPTIONS_H_
   23.45 \ No newline at end of file
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/src/3deng/lights.cpp	Thu Oct 23 01:46:07 2014 +0300
    24.3 @@ -0,0 +1,586 @@
    24.4 +#include "lights.h"
    24.5 +#include <cmath>
    24.6 +
    24.7 +Light::Light() {
    24.8 +	intensity = 1.0f;
    24.9 +	ambient_color = 0.0f;
   24.10 +	diffuse_color = specular_color = 1.0f;
   24.11 +	CastShadows = false;
   24.12 +}
   24.13 +
   24.14 +void Light::SetIntensity(float intensity) {
   24.15 +	this->intensity = intensity;
   24.16 +}
   24.17 +
   24.18 +float Light::GetIntensity() const {
   24.19 +	return intensity;
   24.20 +}
   24.21 +
   24.22 +void Light::SetColor(const Color &color, PhongComponent comp) {
   24.23 +	if(comp == (PhongComponent)-1) {
   24.24 +        diffuse_color = specular_color = color;
   24.25 +	} else {
   24.26 +		switch(comp) {
   24.27 +		case Ambient:
   24.28 +			ambient_color = color;
   24.29 +			break;
   24.30 +		case Diffuse:
   24.31 +			diffuse_color = color;
   24.32 +			break;
   24.33 +		case Specular:
   24.34 +			specular_color = color;
   24.35 +			break;
   24.36 +		}
   24.37 +	}
   24.38 +}
   24.39 +
   24.40 +const Color &Light::GetColor(PhongComponent comp) const {
   24.41 +	switch(comp) {
   24.42 +	case Ambient:
   24.43 +		return ambient_color;
   24.44 +	case Diffuse:
   24.45 +		return diffuse_color;
   24.46 +	case Specular:
   24.47 +		return specular_color;
   24.48 +	}
   24.49 +}
   24.50 +
   24.51 +void Light::SetShadowCasting(bool enable) {
   24.52 +	CastShadows = enable;
   24.53 +}
   24.54 +
   24.55 +bool Light::GetShadowCasting() const {
   24.56 +	return CastShadows;
   24.57 +}
   24.58 +
   24.59 +////////// Directional Light ///////////
   24.60 +
   24.61 +// Non-Applicable functions for this type of light
   24.62 +void DirLight::SetPosition(const Vector3 &pos) {}
   24.63 +void DirLight::SetRange(float range) {}
   24.64 +void DirLight::SetAttenuation(float att0, float att1, float att2) {}
   24.65 +Vector3 DirLight::GetPosition() const {return Direction;}
   24.66 +float DirLight::GetRange() const {return 0.0f;}
   24.67 +float DirLight::GetAttenuation(int degree) const {return 0.0f;}
   24.68 +void DirLight::ResetTransform() {}
   24.69 +void DirLight::ResetTranslation() {}
   24.70 +void DirLight::ResetRotation() {}
   24.71 +void DirLight::Transform(const Matrix4x4 &matrix) {}
   24.72 +void DirLight::Translate(float x, float y, float z) {}
   24.73 +void DirLight::Rotate(float x, float y, float z) {}
   24.74 +void DirLight::Rotate(const Vector3 &axis, float angle) {}
   24.75 +void DirLight::SetCone(float InnerCone, float OuterCone) {}
   24.76 +float DirLight::GetInnerCone() const {return 0.0f;}
   24.77 +float DirLight::GetOuterCone() const {return 0.0f;}
   24.78 +void DirLight::SetFalloff(float falloff) {}
   24.79 +float DirLight::GetFalloff() const {return 0.0f;}
   24.80 +void DirLight::ResetTargetTransform() {}
   24.81 +void DirLight::ResetTargetTranslation() {}
   24.82 +void DirLight::ResetTargetRotation() {}
   24.83 +void DirLight::TargetTransform(const Matrix4x4 &matrix) {}
   24.84 +void DirLight::TargetTranslate(float x, float y, float z) {}
   24.85 +void DirLight::TargetRotate(float x, float y, float z) {}
   24.86 +void DirLight::TargetRotate(const Vector3 &axis, float angle) {}
   24.87 +
   24.88 +
   24.89 +
   24.90 +DirLight::DirLight() {
   24.91 +	Direction = Vector3(0, -1, 0);
   24.92 +}
   24.93 +
   24.94 +DirLight::DirLight(const Vector3 &dir) {
   24.95 +	Direction = dir;
   24.96 +}
   24.97 +
   24.98 +
   24.99 +void DirLight::SetDirection(const Vector3 &dir) {
  24.100 +	Direction = dir;
  24.101 +}
  24.102 +
  24.103 +Vector3 DirLight::GetDirection() const {
  24.104 +	Vector3 dir = Direction;
  24.105 +	dir.Transform(DirRot);
  24.106 +	return dir;
  24.107 +}
  24.108 +
  24.109 +LightType DirLight::GetType() const {
  24.110 +	return LTDir;
  24.111 +}
  24.112 +
  24.113 +// direction transformations
  24.114 +void DirLight::ResetDirTransform() {
  24.115 +	DirRot.ResetIdentity();
  24.116 +}
  24.117 +
  24.118 +void DirLight::ResetDirRotation() {
  24.119 +	DirRot.ResetIdentity();
  24.120 +}
  24.121 +
  24.122 +void DirLight::TransformDir(const Matrix4x4 &matrix) {
  24.123 +	DirRot *= matrix;
  24.124 +}
  24.125 +
  24.126 +void DirLight::RotateDir(float x, float y, float z) {
  24.127 +	DirRot.Rotate(x, y, z);
  24.128 +}
  24.129 +
  24.130 +void DirLight::RotateDir(const Vector3 &axis, float angle) {
  24.131 +	DirRot.Rotate(axis, angle);
  24.132 +}
  24.133 +
  24.134 +
  24.135 +void DirLight::SetLight(dword index, GraphicsContext *gc) const {
  24.136 +
  24.137 +	Vector3 dir = Direction;
  24.138 +	dir.Transform(DirRot);
  24.139 +
  24.140 +	D3DLIGHT8 light;
  24.141 +	memset(&light, 0, sizeof(D3DLIGHT8));
  24.142 +	light.Ambient.r = ambient_color.r * intensity;
  24.143 +	light.Diffuse.r = diffuse_color.r * intensity;
  24.144 +	light.Specular.r = specular_color.r * intensity;
  24.145 +	light.Ambient.g = ambient_color.g * intensity;
  24.146 +	light.Diffuse.g = diffuse_color.g * intensity;
  24.147 +	light.Specular.g = specular_color.g * intensity;
  24.148 +	light.Ambient.b = ambient_color.b * intensity;
  24.149 +	light.Diffuse.b = diffuse_color.b * intensity;
  24.150 +	light.Specular.b = specular_color.b * intensity;
  24.151 +	light.Direction = dir;
  24.152 +	light.Type = (D3DLIGHTTYPE)LTDir;
  24.153 +	
  24.154 +	gc->D3DDevice->SetLight(index, &light);
  24.155 +	gc->D3DDevice->LightEnable(index, true);
  24.156 +}
  24.157 +
  24.158 +Vertex DirLightVisVertices[] = {
  24.159 +	Vertex(Vector3(0.0f, 0.0f, 0.1f), 0.0f, 0.0f, 0x00ff0000),
  24.160 +	Vertex(Vector3(0.03f, 0.03f, 0.0f), 0.0f, 0.0f, 0x000000ff),
  24.161 +	Vertex(Vector3(-0.03f, 0.03f, 0.0f), 0.0f, 0.0f, 0x000000ff),
  24.162 +	Vertex(Vector3(0.0f, -0.03f, 0.0f), 0.0f, 0.0f, 0x000000ff)
  24.163 +};
  24.164 +
  24.165 +Index DirLightVisIndices[] = {
  24.166 +	0, 1, 2,
  24.167 +	0, 2, 3,
  24.168 +	0, 3, 1,
  24.169 +	1, 3, 2
  24.170 +};
  24.171 +
  24.172 +
  24.173 +void DirLight::Draw(GraphicsContext *gc, float size) {
  24.174 +	
  24.175 +	Material mat(0.9f, 0.8f, 0.3f);
  24.176 +	gc->SetMaterial(mat);
  24.177 +	gc->SetTexture(0, 0);
  24.178 +	gc->SetColorVertex(true);
  24.179 +	gc->SetLighting(false);
  24.180 +	gc->SetZBuffering(false);
  24.181 +
  24.182 +	Matrix4x4 WorldMat = (Matrix4x4)Base(Direction).CreateRotationMatrix() * DirRot;
  24.183 +	gc->SetWorldMatrix(WorldMat);
  24.184 +
  24.185 +	Matrix4x4 ViewMat = gc->GetViewMatrix();
  24.186 +	Matrix4x4 AugViewMat;
  24.187 +
  24.188 +	for(int i=0; i<4; i++) {
  24.189 +        AugViewMat.SetRowVector(ViewMat.GetRowVector(i).Normalized(), i);
  24.190 +	}
  24.191 +
  24.192 +	gc->SetViewMatrix(AugViewMat);
  24.193 +
  24.194 +	gc->Draw(DirLightVisVertices, DirLightVisIndices, 4, 12);
  24.195 +
  24.196 +	gc->SetViewMatrix(ViewMat);
  24.197 +
  24.198 +	gc->SetZBuffering(true);
  24.199 +	gc->SetLighting(true);
  24.200 +	gc->SetColorVertex(false);
  24.201 +
  24.202 +}
  24.203 +
  24.204 +/////////// Point Light //////////////
  24.205 +
  24.206 +// Non-Applicable member functions
  24.207 +void PointLight::SetDirection(const Vector3 &dir) {}
  24.208 +Vector3 PointLight::GetDirection() const {return Position;}
  24.209 +void PointLight::ResetDirTransform() {}
  24.210 +void PointLight::ResetDirRotation() {}
  24.211 +void PointLight::TransformDir(const Matrix4x4 &matrix) {}
  24.212 +void PointLight::RotateDir(float x, float y, float z) {}
  24.213 +void PointLight::RotateDir(const Vector3 &axis, float angle) {}
  24.214 +void PointLight::SetCone(float InnerCone, float OuterCone) {}
  24.215 +float PointLight::GetInnerCone() const {return 0.0f;}
  24.216 +float PointLight::GetOuterCone() const {return 0.0f;}
  24.217 +void PointLight::SetFalloff(float falloff) {}
  24.218 +float PointLight::GetFalloff() const {return 0.0f;}
  24.219 +void PointLight::ResetTargetTransform() {}
  24.220 +void PointLight::ResetTargetTranslation() {}
  24.221 +void PointLight::ResetTargetRotation() {}
  24.222 +void PointLight::TargetTransform(const Matrix4x4 &matrix) {}
  24.223 +void PointLight::TargetTranslate(float x, float y, float z) {}
  24.224 +void PointLight::TargetRotate(float x, float y, float z) {}
  24.225 +void PointLight::TargetRotate(const Vector3 &axis, float angle) {}
  24.226 +
  24.227 +
  24.228 +
  24.229 +PointLight::PointLight() {
  24.230 +	Position = Vector3(0, 100, 0);
  24.231 +	Range = 300.0f;
  24.232 +	Attenuation[0] = 1.0f;
  24.233 +	Attenuation[1] = 0.0f;
  24.234 +	Attenuation[2] = 0.0f;
  24.235 +}
  24.236 +
  24.237 +PointLight::PointLight(const Vector3 &pos, float range, float att0, float att1, float att2) {
  24.238 +	Position = pos;
  24.239 +	Range = range;
  24.240 +	Attenuation[0] = att0;
  24.241 +	Attenuation[1] = att1;
  24.242 +	Attenuation[2] = att2;
  24.243 +}
  24.244 +
  24.245 +Matrix4x4 PointLight::GetTransform() const {
  24.246 +	return PosXForm * PosRot * PosTrans;
  24.247 +}
  24.248 +
  24.249 +void PointLight::SetPosition(const Vector3 &pos) {
  24.250 +	Position = pos;
  24.251 +}
  24.252 +
  24.253 +void PointLight::SetRange(float range) {
  24.254 +	Range = range;
  24.255 +}
  24.256 +
  24.257 +void PointLight::SetAttenuation(float att0, float att1, float att2) {
  24.258 +	Attenuation[0] = att0;
  24.259 +	Attenuation[1] = att1;
  24.260 +	Attenuation[2] = att2;
  24.261 +}
  24.262 +
  24.263 +Vector3 PointLight::GetPosition() const {
  24.264 +	Vector3 pos = Position;
  24.265 +	pos.Transform(GetTransform());
  24.266 +	return pos;
  24.267 +}
  24.268 +
  24.269 +float PointLight::GetRange() const {
  24.270 +	return Range;
  24.271 +}
  24.272 +
  24.273 +float PointLight::GetAttenuation(int degree) const {
  24.274 +	return Attenuation[degree];
  24.275 +}
  24.276 +
  24.277 +LightType PointLight::GetType() const {
  24.278 +	return LTPoint;
  24.279 +}
  24.280 +
  24.281 +// position transformations
  24.282 +void PointLight::ResetTransform() {
  24.283 +	PosRot.ResetIdentity();
  24.284 +	PosTrans.ResetIdentity();
  24.285 +	PosXForm.ResetIdentity();
  24.286 +}
  24.287 +
  24.288 +void PointLight::ResetTranslation() {
  24.289 +	PosTrans.ResetIdentity();
  24.290 +}
  24.291 +
  24.292 +void PointLight::ResetRotation() {
  24.293 +	PosRot.ResetIdentity();
  24.294 +}
  24.295 +
  24.296 +void PointLight::Transform(const Matrix4x4 &matrix) {
  24.297 +	PosXForm *= matrix;
  24.298 +}
  24.299 +
  24.300 +void PointLight::Translate(float x, float y, float z) {
  24.301 +	PosTrans.Translate(x, y, z);
  24.302 +}
  24.303 +
  24.304 +void PointLight::Rotate(float x, float y, float z) {
  24.305 +	PosRot.Rotate(x, y, z);
  24.306 +}
  24.307 +
  24.308 +void PointLight::Rotate(const Vector3 &axis, float angle) {
  24.309 +	PosRot.Rotate(axis, angle);
  24.310 +}
  24.311 +
  24.312 +
  24.313 +void PointLight::SetLight(dword index, GraphicsContext *gc) const {
  24.314 +
  24.315 +	Vector3 pos = Position;
  24.316 +	pos.Transform(GetTransform());
  24.317 +
  24.318 +	D3DLIGHT8 light;
  24.319 +	memset(&light, 0, sizeof(D3DLIGHT8));
  24.320 +	light.Ambient.r = ambient_color.r * intensity;
  24.321 +	light.Diffuse.r = diffuse_color.r * intensity;
  24.322 +	light.Specular.r = specular_color.r * intensity;
  24.323 +	light.Ambient.g = ambient_color.g * intensity;
  24.324 +	light.Diffuse.g = diffuse_color.g * intensity;
  24.325 +	light.Specular.g = specular_color.g * intensity;
  24.326 +	light.Ambient.b = ambient_color.b * intensity;
  24.327 +	light.Diffuse.b = diffuse_color.b * intensity;
  24.328 +	light.Specular.b = specular_color.b * intensity;
  24.329 +	light.Position = pos;
  24.330 +	light.Range = Range;
  24.331 +	light.Attenuation0 = Attenuation[0];
  24.332 +	light.Attenuation1 = Attenuation[1];
  24.333 +	light.Attenuation2 = Attenuation[2];
  24.334 +	light.Type = (D3DLIGHTTYPE)LTPoint;
  24.335 +
  24.336 +	gc->D3DDevice->SetLight(index, &light);
  24.337 +	gc->D3DDevice->LightEnable(index, true);
  24.338 +}
  24.339 +
  24.340 +
  24.341 +
  24.342 +Index PointLightVisIndices[] = {0, 2, 1, 0, 3, 2};
  24.343 +
  24.344 +void PointLight::Draw(GraphicsContext *gc, float size) {
  24.345 +
  24.346 +	dword color = (diffuse_color * intensity).GetPacked32();
  24.347 +
  24.348 +	float PtHalfSz = size / 2.0f;
  24.349 +	Vertex PointLightVisVertices[] = {
  24.350 +		Vertex(Vector3(-PtHalfSz, PtHalfSz, 0.0f), 0.0f, 0.0f, color),
  24.351 +		Vertex(Vector3(PtHalfSz, PtHalfSz, 0.0f), 1.0f, 0.0f, color),
  24.352 +		Vertex(Vector3(PtHalfSz, -PtHalfSz, 0.0f), 1.0f, 1.0f, color),
  24.353 +		Vertex(Vector3(-PtHalfSz, -PtHalfSz, 0.0f), 0.0f, 1.0f, color)
  24.354 +	};
  24.355 +
  24.356 +	Texture *tex = gc->texman->LoadTexture("STOCKTEX_BLOB");
  24.357 +	gc->SetTexture(0, tex);
  24.358 +	gc->SetTextureStageColor(0, TexBlendModulate, TexArgTexture, TexArgCurrent);
  24.359 +	gc->SetTexture(1, 0);
  24.360 +	
  24.361 +	gc->SetAlphaBlending(true);
  24.362 +	gc->SetBlendFunc(BLEND_ONE, BLEND_ONE);
  24.363 +	
  24.364 +	gc->SetColorVertex(true);
  24.365 +	gc->SetLighting(false);
  24.366 +
  24.367 +	Matrix4x4 InvPos;
  24.368 +	InvPos.Translate(Position.x, Position.y, Position.z);
  24.369 +	gc->SetWorldMatrix(InvPos * GetTransform());
  24.370 +
  24.371 +	gc->SetZWrite(false);
  24.372 +	gc->SetBillboarding(true);
  24.373 +	gc->Draw(PointLightVisVertices, PointLightVisIndices, 4, 6);
  24.374 +	gc->SetBillboarding(false);
  24.375 +	gc->SetZWrite(true);
  24.376 +
  24.377 +	gc->SetAlphaBlending(false);	
  24.378 +	gc->SetLighting(true);
  24.379 +	gc->SetColorVertex(false);
  24.380 +	gc->SetTexture(0, 0);
  24.381 +}
  24.382 +
  24.383 +
  24.384 +////////////// Spot Light ////////////////
  24.385 +void SpotLight::ResetTargetTransform() {}
  24.386 +void SpotLight::ResetTargetTranslation() {}
  24.387 +void SpotLight::ResetTargetRotation() {}
  24.388 +void SpotLight::TargetTransform(const Matrix4x4 &matrix) {}
  24.389 +void SpotLight::TargetTranslate(float x, float y, float z) {}
  24.390 +void SpotLight::TargetRotate(float x, float y, float z) {}
  24.391 +void SpotLight::TargetRotate(const Vector3 &axis, float angle) {}
  24.392 +
  24.393 +SpotLight::SpotLight() {
  24.394 +	Position = Vector3(0, 100, 0);
  24.395 +	Direction = Vector3(0, -1, 0);
  24.396 +	Falloff = 1.0f;
  24.397 +	Phi = QuarterPi;
  24.398 +	Theta = Phi - (Phi / 9.0f);
  24.399 +}
  24.400 +
  24.401 +SpotLight::SpotLight(const Vector3 &pos, const Vector3 &dir, float InnerCone, float OuterCone, float range, float att0, float att1, float att2) {
  24.402 +	Position = pos;
  24.403 +	Direction = dir;
  24.404 +	SetCone(InnerCone, OuterCone);
  24.405 +	Range = range;
  24.406 +	Attenuation[0] = att0;
  24.407 +	Attenuation[1] = att1;
  24.408 +	Attenuation[2] = att2;
  24.409 +	Falloff = 1.0f;
  24.410 +}
  24.411 +
  24.412 +void SpotLight::SetDirection(const Vector3 &dir) {
  24.413 +	Direction = dir;
  24.414 +}
  24.415 +
  24.416 +Vector3 SpotLight::GetDirection() const {
  24.417 +	Vector3 dir = Direction;
  24.418 +	dir.Transform(DirRot);
  24.419 +	return dir;
  24.420 +}
  24.421 +
  24.422 +// direction transformations
  24.423 +void SpotLight::ResetDirTransform() {
  24.424 +	DirRot.ResetIdentity();
  24.425 +}
  24.426 +
  24.427 +void SpotLight::ResetDirRotation() {
  24.428 +	DirRot.ResetIdentity();
  24.429 +}
  24.430 +
  24.431 +void SpotLight::TransformDir(const Matrix4x4 &matrix) {
  24.432 +	DirRot *= matrix;
  24.433 +}
  24.434 +
  24.435 +void SpotLight::RotateDir(float x, float y, float z) {
  24.436 +	DirRot.Rotate(x, y, z);
  24.437 +}
  24.438 +
  24.439 +void SpotLight::RotateDir(const Vector3 &axis, float angle) {
  24.440 +	DirRot.Rotate(axis, angle);
  24.441 +}
  24.442 +
  24.443 +
  24.444 +LightType SpotLight::GetType() const {
  24.445 +	return LTSpot;
  24.446 +}
  24.447 +
  24.448 +void SpotLight::SetCone(float InnerCone, float OuterCone) {
  24.449 +	Theta = InnerCone;
  24.450 +	Phi = OuterCone;
  24.451 +}
  24.452 +
  24.453 +float SpotLight::GetInnerCone() const {
  24.454 +	return Theta;
  24.455 +}
  24.456 +
  24.457 +float SpotLight::GetOuterCone() const {
  24.458 +	return Phi;
  24.459 +}
  24.460 +
  24.461 +void SpotLight::SetFalloff(float falloff) {
  24.462 +	Falloff = falloff;
  24.463 +}
  24.464 +
  24.465 +float SpotLight::GetFalloff() const {
  24.466 +	return Falloff;
  24.467 +}
  24.468 +
  24.469 +
  24.470 +void SpotLight::SetLight(dword index, GraphicsContext *gc) const {
  24.471 +	
  24.472 +	Vector3 pos = Position;
  24.473 +	pos.Transform(GetTransform());
  24.474 +
  24.475 +	Vector3 dir = Direction;
  24.476 +	dir.Transform(DirRot);
  24.477 +
  24.478 +	D3DLIGHT8 light;
  24.479 +	memset(&light, 0, sizeof(D3DLIGHT8));
  24.480 +	light.Ambient.r = ambient_color.r * intensity;
  24.481 +	light.Diffuse.r = diffuse_color.r * intensity;
  24.482 +	light.Specular.r = specular_color.r * intensity;
  24.483 +	light.Ambient.g = ambient_color.g * intensity;
  24.484 +	light.Diffuse.g = diffuse_color.g * intensity;
  24.485 +	light.Specular.g = specular_color.g * intensity;
  24.486 +	light.Ambient.b = ambient_color.b * intensity;
  24.487 +	light.Diffuse.b = diffuse_color.b * intensity;
  24.488 +	light.Specular.b = specular_color.b * intensity;
  24.489 +	light.Position = pos;
  24.490 +	light.Direction = dir;
  24.491 +	light.Range = Range;
  24.492 +	light.Attenuation0 = Attenuation[0];
  24.493 +	light.Attenuation1 = Attenuation[1];
  24.494 +	light.Attenuation2 = Attenuation[2];
  24.495 +	light.Falloff = Falloff;
  24.496 +	light.Theta = Theta;
  24.497 +	light.Phi = Phi;
  24.498 +	light.Type = (D3DLIGHTTYPE)LTSpot;
  24.499 +
  24.500 +	gc->D3DDevice->SetLight(index, &light);
  24.501 +	gc->D3DDevice->LightEnable(index, true);
  24.502 +}
  24.503 +
  24.504 +void SpotLight::Draw(GraphicsContext *gc, float size) {
  24.505 +	PointLight::Draw(gc, size);
  24.506 +}
  24.507 +
  24.508 +//////////////// Target Spot Light ////////////////////
  24.509 +void TargetSpotLight::SetDirection(const Vector3 &dir) {}
  24.510 +Vector3 TargetSpotLight::GetDirection() const {return Vector3();}
  24.511 +void TargetSpotLight::ResetDirTransform() {}
  24.512 +void TargetSpotLight::ResetDirRotation() {}
  24.513 +void TargetSpotLight::TransformDir(const Matrix4x4 &matrix) {}
  24.514 +void TargetSpotLight::RotateDir(float x, float y, float z) {}
  24.515 +void TargetSpotLight::RotateDir(const Vector3 &axis, float angle) {}
  24.516 +
  24.517 +TargetSpotLight::TargetSpotLight() {
  24.518 +	Target = Vector3(0.0f, 0.0f, 0.0f);
  24.519 +}
  24.520 +
  24.521 +TargetSpotLight::TargetSpotLight(const Vector3 &pos, const Vector3 &target, float InnerCone, float OuterCone, float range, float att0, float att1, float att2) {
  24.522 +	Position = pos;
  24.523 +	Target = target;
  24.524 +	SetCone(InnerCone, OuterCone);
  24.525 +	Range = range;
  24.526 +	Attenuation[0] = att0;
  24.527 +	Attenuation[1] = att1;
  24.528 +	Attenuation[2] = att2;
  24.529 +	Falloff = 1.0f;
  24.530 +}
  24.531 +
  24.532 +Matrix4x4 TargetSpotLight::GetTargetTransform() const {
  24.533 +	return TargXForm * TargRot * TargTrans;
  24.534 +}
  24.535 +
  24.536 +void TargetSpotLight::ResetTargetTransform() {
  24.537 +	TargRot.ResetIdentity();
  24.538 +	TargTrans.ResetIdentity();
  24.539 +	TargXForm.ResetIdentity();
  24.540 +}
  24.541 +
  24.542 +void TargetSpotLight::ResetTargetTranslation() {
  24.543 +	TargTrans.ResetIdentity();
  24.544 +}
  24.545 +
  24.546 +void TargetSpotLight::ResetTargetRotation() {
  24.547 +	TargRot.ResetIdentity();
  24.548 +}
  24.549 +
  24.550 +void TargetSpotLight::TargetTransform(const Matrix4x4 &matrix) {
  24.551 +	TargXForm *= matrix;
  24.552 +}
  24.553 +
  24.554 +void TargetSpotLight::TargetTranslate(float x, float y, float z) {
  24.555 +	TargTrans.Translate(x, y, z);
  24.556 +}
  24.557 +
  24.558 +void TargetSpotLight::TargetRotate(float x, float y, float z) {
  24.559 +	TargRot.Rotate(x, y, z);
  24.560 +}
  24.561 +
  24.562 +void TargetSpotLight::TargetRotate(const Vector3 &axis, float angle) {
  24.563 +	TargRot.Rotate(axis, angle);
  24.564 +}
  24.565 +
  24.566 +
  24.567 +void TargetSpotLight::SetLight(dword index, GraphicsContext *gc) const {
  24.568 +	Vector3 targ = Target;
  24.569 +	targ.Transform(GetTargetTransform());
  24.570 +
  24.571 +	Vector3 pos = Position;
  24.572 +	pos.Transform(GetTransform());
  24.573 +
  24.574 +	Vector3 *dir = const_cast<Vector3*>(&Direction);
  24.575 +	*dir = (targ - pos).Normalized();
  24.576 +
  24.577 +	SpotLight::SetLight(index, gc);
  24.578 +}
  24.579 +
  24.580 +void TargetSpotLight::Draw(GraphicsContext *gc, float size) {
  24.581 +	Vector3 targ = Target;
  24.582 +	targ.Transform(GetTargetTransform());
  24.583 +
  24.584 +	Vector3 pos = Position;
  24.585 +	pos.Transform(GetTransform());
  24.586 +
  24.587 +	Direction = (targ - pos).Normalized();
  24.588 +	SpotLight::Draw(gc, size);
  24.589 +}
  24.590 \ No newline at end of file
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/src/3deng/lights.h	Thu Oct 23 01:46:07 2014 +0300
    25.3 @@ -0,0 +1,296 @@
    25.4 +#ifndef _LIGHTS_H_
    25.5 +#define _LIGHTS_H_
    25.6 +
    25.7 +#include <string>
    25.8 +#include "switches.h"
    25.9 +#include "n3dmath.h"
   25.10 +#include "3dengine.h"
   25.11 +
   25.12 +enum LightType {
   25.13 +	LTDir = D3DLIGHT_DIRECTIONAL, 
   25.14 +	LTSpot = D3DLIGHT_SPOT, 
   25.15 +	LTPoint = D3DLIGHT_POINT
   25.16 +};
   25.17 +
   25.18 +/////////////////////////////////////////////////////////////////////
   25.19 +//                 -- Abstract Base class Light --                 //
   25.20 +// pure virtual functions for every possible light parameter,      //
   25.21 +// implement non-applicable functions as private in each subclass. //
   25.22 +/////////////////////////////////////////////////////////////////////
   25.23 +
   25.24 +class Light {
   25.25 +protected:
   25.26 +	float intensity;
   25.27 +	Color ambient_color, diffuse_color, specular_color;
   25.28 +	bool CastShadows;
   25.29 +
   25.30 +public:
   25.31 +	std::string name;
   25.32 +
   25.33 +	Light();
   25.34 +
   25.35 +	// set parameters
   25.36 +	virtual void SetPosition(const Vector3 &pos) = 0;
   25.37 +	virtual void SetDirection(const Vector3 &dir) = 0;
   25.38 +	virtual void SetColor(const Color &color, PhongComponent comp = (PhongComponent)-1);
   25.39 +	virtual void SetIntensity(float intensity);
   25.40 +	virtual void SetRange(float range) = 0;
   25.41 +	virtual void SetAttenuation(float att0, float att1, float att2) = 0;
   25.42 +	virtual void SetShadowCasting(bool enable);
   25.43 +
   25.44 +	// get parameters
   25.45 +	virtual Vector3 GetPosition() const = 0;
   25.46 +	virtual Vector3 GetDirection() const = 0;
   25.47 +	virtual const Color &GetColor(PhongComponent comp = Diffuse) const;
   25.48 +	virtual float GetIntensity() const;
   25.49 +	virtual float GetRange() const = 0;
   25.50 +	virtual float GetAttenuation(int degree) const = 0;
   25.51 +	virtual bool GetShadowCasting() const;
   25.52 +	
   25.53 +	virtual LightType GetType() const = 0;
   25.54 +
   25.55 +	virtual void SetCone(float InnerCone, float OuterCone) = 0;
   25.56 +	virtual float GetInnerCone() const = 0;
   25.57 +	virtual float GetOuterCone() const = 0;
   25.58 +
   25.59 +	virtual void SetFalloff(float falloff) = 0;
   25.60 +	virtual float GetFalloff() const = 0;
   25.61 +	
   25.62 +	// position transformations
   25.63 +	virtual void ResetTransform() = 0;
   25.64 +	virtual void ResetTranslation() = 0;
   25.65 +	virtual void ResetRotation() = 0;
   25.66 +
   25.67 +	virtual void Transform(const Matrix4x4 &matrix) = 0;
   25.68 +	virtual void Translate(float x, float y, float z) = 0;
   25.69 +	virtual void Rotate(float x, float y, float z) = 0;
   25.70 +	virtual void Rotate(const Vector3 &axis, float angle) = 0;
   25.71 +
   25.72 +	// direction transformations
   25.73 +	virtual void ResetDirTransform() = 0;
   25.74 +	virtual void ResetDirRotation() = 0;
   25.75 +
   25.76 +	virtual void TransformDir(const Matrix4x4 &matrix) = 0;
   25.77 +	virtual void RotateDir(float x, float y, float z) = 0;
   25.78 +	virtual void RotateDir(const Vector3 &axis, float angle) = 0;
   25.79 +
   25.80 +	// target transformations
   25.81 +	virtual void ResetTargetTransform() = 0;
   25.82 +	virtual void ResetTargetTranslation() = 0;
   25.83 +	virtual void ResetTargetRotation() = 0;
   25.84 +	virtual void TargetTransform(const Matrix4x4 &matrix) = 0;
   25.85 +	virtual void TargetTranslate(float x, float y, float z) = 0;
   25.86 +	virtual void TargetRotate(float x, float y, float z) = 0;
   25.87 +	virtual void TargetRotate(const Vector3 &axis, float angle) = 0;
   25.88 +
   25.89 +	virtual void SetLight(dword index, GraphicsContext *gc) const = 0;
   25.90 +
   25.91 +	virtual void Draw(GraphicsContext *gc, float size = 1.0f) = 0;
   25.92 +};
   25.93 +
   25.94 +// Directional Light
   25.95 +class DirLight : public Light {
   25.96 +private:
   25.97 +	// Non-Applicable functions for this type of light
   25.98 +	virtual void SetPosition(const Vector3 &pos);
   25.99 +	virtual void SetRange(float range);
  25.100 +	virtual void SetAttenuation(float att0, float att1, float att2);
  25.101 +	virtual Vector3 GetPosition() const;
  25.102 +	virtual float GetRange() const;
  25.103 +	virtual float GetAttenuation(int degree) const;
  25.104 +	virtual void ResetTransform();
  25.105 +	virtual void ResetTranslation();
  25.106 +	virtual void ResetRotation();
  25.107 +	virtual void Transform(const Matrix4x4 &matrix);
  25.108 +	virtual void Translate(float x, float y, float z);
  25.109 +	virtual void Rotate(float x, float y, float z);
  25.110 +	virtual void Rotate(const Vector3 &axis, float angle);
  25.111 +	virtual void ResetTargetTransform();
  25.112 +	virtual void ResetTargetTranslation();
  25.113 +	virtual void ResetTargetRotation();
  25.114 +	virtual void TargetTransform(const Matrix4x4 &matrix);
  25.115 +	virtual void TargetTranslate(float x, float y, float z);
  25.116 +	virtual void TargetRotate(float x, float y, float z);
  25.117 +	virtual void TargetRotate(const Vector3 &axis, float angle);
  25.118 +	virtual void SetCone(float InnerCone, float OuterCone);
  25.119 +	virtual float GetInnerCone() const;
  25.120 +	virtual float GetOuterCone() const;
  25.121 +	virtual void SetFalloff(float falloff);
  25.122 +	virtual float GetFalloff() const;
  25.123 +
  25.124 +
  25.125 +protected:
  25.126 +	Vector3 Direction;
  25.127 +	Matrix4x4 DirRot;
  25.128 +	
  25.129 +public:
  25.130 +	DirLight();
  25.131 +	DirLight(const Vector3 &dir);
  25.132 +
  25.133 +	// accessors
  25.134 +	virtual void SetDirection(const Vector3 &dir);
  25.135 +	virtual Vector3 GetDirection() const;
  25.136 +	
  25.137 +	virtual LightType GetType() const;
  25.138 +	
  25.139 +	// direction transformations
  25.140 +	virtual void ResetDirTransform();
  25.141 +	virtual void ResetDirRotation();
  25.142 +
  25.143 +	virtual void TransformDir(const Matrix4x4 &matrix);
  25.144 +	virtual void RotateDir(float x, float y, float z);
  25.145 +	virtual void RotateDir(const Vector3 &axis, float angle);
  25.146 +
  25.147 +	virtual void SetLight(dword index, GraphicsContext *gc) const;
  25.148 +
  25.149 +	virtual void Draw(GraphicsContext *gc, float size = 1.0f);
  25.150 +};
  25.151 +
  25.152 +// Point Light (omni)
  25.153 +class PointLight : public Light {
  25.154 +private:
  25.155 +	// Non-Applicable member functions
  25.156 +	virtual void SetDirection(const Vector3 &dir);
  25.157 +	virtual Vector3 GetDirection() const;
  25.158 +	virtual void ResetDirTransform();
  25.159 +	virtual void ResetDirRotation();
  25.160 +	virtual void TransformDir(const Matrix4x4 &matrix);
  25.161 +	virtual void RotateDir(float x, float y, float z);
  25.162 +	virtual void RotateDir(const Vector3 &axis, float angle);
  25.163 +	virtual void ResetTargetTransform();
  25.164 +	virtual void ResetTargetTranslation();
  25.165 +	virtual void ResetTargetRotation();
  25.166 +	virtual void TargetTransform(const Matrix4x4 &matrix);
  25.167 +	virtual void TargetTranslate(float x, float y, float z);
  25.168 +	virtual void TargetRotate(float x, float y, float z);
  25.169 +	virtual void TargetRotate(const Vector3 &axis, float angle);
  25.170 +	virtual void SetCone(float InnerCone, float OuterCone);
  25.171 +	virtual float GetInnerCone() const;
  25.172 +	virtual float GetOuterCone() const;
  25.173 +	virtual void SetFalloff(float falloff);
  25.174 +	virtual float GetFalloff() const;
  25.175 +
  25.176 +protected:
  25.177 +	Vector3 Position;
  25.178 +	float Range;
  25.179 +	float Attenuation[3];
  25.180 +
  25.181 +	Matrix4x4 PosRot, PosTrans, PosXForm;
  25.182 +
  25.183 +	virtual Matrix4x4 GetTransform() const;
  25.184 +
  25.185 +public:
  25.186 +	PointLight();
  25.187 +	PointLight(const Vector3 &pos, float range = 1000.0f, float att0 = 1.0f, float att1 = 0.0f, float att2 = 0.0f);
  25.188 +
  25.189 +	// accessors
  25.190 +	virtual void SetPosition(const Vector3 &pos);
  25.191 +	virtual void SetRange(float range);
  25.192 +	virtual void SetAttenuation(float att0, float att1, float att2);
  25.193 +
  25.194 +	virtual Vector3 GetPosition() const;
  25.195 +	virtual float GetRange() const;
  25.196 +	virtual float GetAttenuation(int degree) const;
  25.197 +	
  25.198 +	virtual LightType GetType() const;
  25.199 +	
  25.200 +	// position transformations
  25.201 +	virtual void ResetTransform();
  25.202 +	virtual void ResetTranslation();
  25.203 +	virtual void ResetRotation();
  25.204 +
  25.205 +	virtual void Transform(const Matrix4x4 &matrix);
  25.206 +	virtual void Translate(float x, float y, float z);
  25.207 +	virtual void Rotate(float x, float y, float z);
  25.208 +	virtual void Rotate(const Vector3 &axis, float angle);
  25.209 +
  25.210 +	virtual void SetLight(dword index, GraphicsContext *gc) const;
  25.211 +
  25.212 +	virtual void Draw(GraphicsContext *gc, float size = 100.0f);
  25.213 +};
  25.214 +
  25.215 +// Spotlight
  25.216 +class SpotLight : public PointLight {
  25.217 +private:
  25.218 +	virtual void ResetTargetTransform();
  25.219 +	virtual void ResetTargetTranslation();
  25.220 +	virtual void ResetTargetRotation();
  25.221 +	virtual void TargetTransform(const Matrix4x4 &matrix);
  25.222 +	virtual void TargetTranslate(float x, float y, float z);
  25.223 +	virtual void TargetRotate(float x, float y, float z);
  25.224 +	virtual void TargetRotate(const Vector3 &axis, float angle);
  25.225 +
  25.226 +protected:
  25.227 +	Vector3 Direction;
  25.228 +	Matrix4x4 DirRot;
  25.229 +
  25.230 +	float Falloff;
  25.231 +	float Theta, Phi;
  25.232 +
  25.233 +public:
  25.234 +	SpotLight();
  25.235 +	SpotLight(const Vector3 &pos, const Vector3 &dir, float InnerCone, float OuterCone, float range = 1000.0f, float att0 = 1.0f, float att1 = 0.0f, float att2 = 0.0f);
  25.236 +
  25.237 +	// accessors
  25.238 +	virtual void SetDirection(const Vector3 &dir);
  25.239 +	virtual Vector3 GetDirection() const;
  25.240 +	
  25.241 +	// direction transformations
  25.242 +	virtual void ResetDirTransform();
  25.243 +	virtual void ResetDirRotation();
  25.244 +
  25.245 +	virtual void TransformDir(const Matrix4x4 &matrix);
  25.246 +	virtual void RotateDir(float x, float y, float z);
  25.247 +	virtual void RotateDir(const Vector3 &axis, float angle);
  25.248 +
  25.249 +	virtual LightType GetType() const;
  25.250 +
  25.251 +	virtual void SetCone(float InnerCone, float OuterCone);
  25.252 +	virtual float GetInnerCone() const;
  25.253 +	virtual float GetOuterCone() const;
  25.254 +
  25.255 +	virtual void SetFalloff(float falloff);
  25.256 +	virtual float GetFalloff() const;
  25.257 +
  25.258 +	virtual void SetLight(dword index, GraphicsContext *gc) const;
  25.259 +
  25.260 +	virtual void Draw(GraphicsContext *gc, float size = 100.0f);
  25.261 +};
  25.262 +
  25.263 +class TargetSpotLight : public SpotLight {
  25.264 +private:
  25.265 +	// Non-Applicable shit
  25.266 +	virtual void SetDirection(const Vector3 &dir);
  25.267 +	virtual Vector3 GetDirection() const;
  25.268 +	virtual void ResetDirTransform();
  25.269 +	virtual void ResetDirRotation();
  25.270 +	virtual void TransformDir(const Matrix4x4 &matrix);
  25.271 +	virtual void RotateDir(float x, float y, float z);
  25.272 +	virtual void RotateDir(const Vector3 &axis, float angle);
  25.273 +
  25.274 +protected:
  25.275 +	Vector3 Target;
  25.276 +	Matrix4x4 TargRot, TargTrans, TargXForm;
  25.277 +
  25.278 +	virtual Matrix4x4 GetTargetTransform() const;
  25.279 +
  25.280 +public:
  25.281 +
  25.282 +	TargetSpotLight();
  25.283 +	TargetSpotLight(const Vector3 &pos, const Vector3 &target, float InnerCone, float OuterCone, float range = 1000.0f, float att0 = 1.0f, float att1 = 0.0f, float att2 = 0.0f);
  25.284 +
  25.285 +	virtual void ResetTargetTransform();
  25.286 +	virtual void ResetTargetTranslation();
  25.287 +	virtual void ResetTargetRotation();
  25.288 +
  25.289 +	virtual void TargetTransform(const Matrix4x4 &matrix);
  25.290 +	virtual void TargetTranslate(float x, float y, float z);
  25.291 +	virtual void TargetRotate(float x, float y, float z);
  25.292 +	virtual void TargetRotate(const Vector3 &axis, float angle);
  25.293 +
  25.294 +	virtual void SetLight(dword index, GraphicsContext *gc) const;
  25.295 +
  25.296 +	virtual void Draw(GraphicsContext *gc, float size = 100.0f);
  25.297 +};
  25.298 +
  25.299 +#endif	// _LIGHTS_H_
  25.300 \ No newline at end of file
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/src/3deng/material.cpp	Thu Oct 23 01:46:07 2014 +0300
    26.3 @@ -0,0 +1,99 @@
    26.4 +#include "material.h"
    26.5 +
    26.6 +Material::Material() {
    26.7 +	memset(this, 0, sizeof(Material));
    26.8 +	Diffuse.r = Ambient.r = 1.0f;
    26.9 +	Diffuse.g = Ambient.g = 1.0f;
   26.10 +	Diffuse.b = Ambient.b = 1.0f;
   26.11 +	Diffuse.a = Ambient.a = 1.0f;
   26.12 +	Specular.r = Specular.g = Specular.b = 1.0f;
   26.13 +	EnvBlend = 1.0f;
   26.14 +	Alpha = 1.0f;
   26.15 +}
   26.16 +
   26.17 +Material::Material(float r, float g, float b, float a) {
   26.18 +
   26.19 +	memset(this, 0, sizeof(Material));
   26.20 +	Diffuse.r = Ambient.r = r;
   26.21 +	Diffuse.g = Ambient.g = g;
   26.22 +	Diffuse.b = Ambient.b = b;
   26.23 +	Diffuse.a = Ambient.a = a;
   26.24 +	Specular.r = Specular.g = Specular.b = 1.0f;
   26.25 +	EnvBlend = 1.0f;
   26.26 +	Alpha = 1.0f;
   26.27 +}
   26.28 +
   26.29 +void Material::SetAmbient(float r, float g, float b) {
   26.30 +	Ambient.r = r;
   26.31 +	Ambient.g = g;
   26.32 +	Ambient.b = b;
   26.33 +	Ambient.a = 1.0f;
   26.34 +}
   26.35 +
   26.36 +void Material::SetAmbient(const Color &col) {
   26.37 +	Ambient.r = col.r;
   26.38 +	Ambient.g = col.g;
   26.39 +	Ambient.b = col.b;
   26.40 +	Ambient.a = col.a;
   26.41 +}
   26.42 +
   26.43 +
   26.44 +void Material::SetDiffuse(float r, float g, float b) {
   26.45 +	Diffuse.r = r;
   26.46 +	Diffuse.g = g;
   26.47 +	Diffuse.b = b;
   26.48 +	Diffuse.a = 1.0f;
   26.49 +}
   26.50 +
   26.51 +void Material::SetDiffuse(const Color &col) {
   26.52 +	Diffuse.r = col.r;
   26.53 +	Diffuse.g = col.g;
   26.54 +	Diffuse.b = col.b;
   26.55 +	Diffuse.a = col.a;
   26.56 +}
   26.57 +
   26.58 +
   26.59 +void Material::SetSpecular(float r, float g, float b) {
   26.60 +	Specular.r = r;
   26.61 +	Specular.g = g;
   26.62 +	Specular.b = b;
   26.63 +	Specular.a = 1.0f;
   26.64 +}
   26.65 +
   26.66 +void Material::SetSpecular(const Color &col) {
   26.67 +	Specular.r = col.r;
   26.68 +	Specular.g = col.g;
   26.69 +	Specular.b = col.b;
   26.70 +	Specular.a = col.a;
   26.71 +}
   26.72 +
   26.73 +void Material::SetEmissive(float r, float g, float b) {
   26.74 +	Emissive.r = r;
   26.75 +	Emissive.g = g;
   26.76 +	Emissive.b = b;
   26.77 +	Emissive.a = 1.0f;
   26.78 +}
   26.79 +
   26.80 +void Material::SetEmissive(const Color &col) {
   26.81 +	Emissive.r = col.r;
   26.82 +	Emissive.g = col.g;
   26.83 +	Emissive.b = col.b;
   26.84 +	Emissive.a = col.a;
   26.85 +}
   26.86 +
   26.87 +void Material::SetEnvBlend(float value) {
   26.88 +	EnvBlend = value;
   26.89 +}
   26.90 +
   26.91 +void Material::SetSpecularPower(float pow) {
   26.92 +	Power = pow;
   26.93 +	SpecularEnable = pow > 0.0f ? true : false;
   26.94 +}
   26.95 +
   26.96 +void Material::SetAlpha(float alpha) {
   26.97 +	Alpha = alpha;
   26.98 +}
   26.99 +
  26.100 +void Material::SetTexture(Texture *texture, TextureType type) {
  26.101 +    Maps[type] = texture;	
  26.102 +}
  26.103 \ No newline at end of file
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/src/3deng/material.h	Thu Oct 23 01:46:07 2014 +0300
    27.3 @@ -0,0 +1,49 @@
    27.4 +#ifndef _MATERIAL_H_
    27.5 +#define _MATERIAL_H_
    27.6 +
    27.7 +#include <string>
    27.8 +#include <vector>
    27.9 +#include "d3d8.h"
   27.10 +#include "3dengtypes.h"
   27.11 +#include "color.h"
   27.12 +
   27.13 +enum TextureType { 
   27.14 +	TextureMap = 0,
   27.15 +	DetailMap,
   27.16 +	OpacityMap, 
   27.17 +	LightMap, 
   27.18 +	BumpMap, 
   27.19 +	EnvironmentMap,
   27.20 +	SpecularMap
   27.21 +};
   27.22 +
   27.23 +const int NumberOfTextureTypes = 7;
   27.24 +
   27.25 +class Material : public D3DMATERIAL8 {
   27.26 +public:
   27.27 +	std::string name;
   27.28 +	Texture *Maps[NumberOfTextureTypes];
   27.29 +	float EnvBlend, BumpIntensity;
   27.30 +	float Alpha;
   27.31 +	bool SpecularEnable;
   27.32 +
   27.33 +	Material();
   27.34 +	Material(float r, float g, float b, float a=1.0f);
   27.35 +
   27.36 +	void SetAmbient(float r, float g, float b);
   27.37 +	void SetAmbient(const Color &col);
   27.38 +	void SetDiffuse(float r, float g, float b);
   27.39 +	void SetDiffuse(const Color &col);
   27.40 +	void SetSpecular(float r, float g, float b);
   27.41 +	void SetSpecular(const Color &col);
   27.42 +	void SetEmissive(float r, float g, float b);
   27.43 +	void SetEmissive(const Color &col);
   27.44 +	void SetSpecularPower(float pow);
   27.45 +	void SetAlpha(float alpha);
   27.46 +	void SetEnvBlend(float value);	
   27.47 +
   27.48 +	void SetTexture(Texture *texture, TextureType type);
   27.49 +};
   27.50 +
   27.51 +
   27.52 +#endif	// _MATERIAL_H_
   27.53 \ No newline at end of file
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/src/3deng/motion.cpp	Thu Oct 23 01:46:07 2014 +0300
    28.3 @@ -0,0 +1,50 @@
    28.4 +#include "motion.h"
    28.5 +
    28.6 +MotionController::MotionController() {
    28.7 +	memset(this, 0, sizeof(MotionController));
    28.8 +}
    28.9 +
   28.10 +void MotionController::SetTranslation(float (*xtrans)(float), float (*ytrans)(float), float (*ztrans)(float), float ScaleInput) {
   28.11 +	XTranslation = xtrans;
   28.12 +	YTranslation = ytrans;
   28.13 +	ZTranslation = ytrans;
   28.14 +	ScaleInputTrans = ScaleInput;
   28.15 +}
   28.16 +
   28.17 +void MotionController::SetRotation(float (*xrot)(float), float (*yrot)(float), float (*zrot)(float), float ScaleInput) {
   28.18 +	XRotation = xrot;
   28.19 +	YRotation = yrot;
   28.20 +	ZRotation = zrot;
   28.21 +	ScaleInputRot = ScaleInput;
   28.22 +}
   28.23 +
   28.24 +void MotionController::SetScaling(float (*xscale)(float), float (*yscale)(float), float (*zscale)(float), float ScaleInput) {
   28.25 +	XScaling = xscale;
   28.26 +	YScaling = yscale;
   28.27 +	ZScaling = zscale;
   28.28 +	ScaleInputScale = ScaleInput;
   28.29 +}
   28.30 +
   28.31 +void MotionController::SetPath(const Curve &path) {
   28.32 +	FollowPath = true;
   28.33 +	// TODO
   28.34 +}
   28.35 +
   28.36 +const Matrix4x4 &MotionController::GetTransformation(float t) {
   28.37 +	MotionXForm.ResetIdentity();
   28.38 +
   28.39 +	if(FollowPath) {
   28.40 +		// TODO
   28.41 +	} else {
   28.42 +		float tt = t * ScaleInputTrans;
   28.43 +		float tr = t * ScaleInputRot;
   28.44 +		float ts = t * ScaleInputScale;
   28.45 +        MotionXForm.Scale(XScaling ? XScaling(tt) : 0, YScaling ? YScaling(tt) : 0, ZScaling ? ZScaling(tt) : 0);
   28.46 +		MotionXForm.Rotate(XRotation ? XRotation(tr) : 0, YRotation ? YRotation(tr) : 0, ZRotation ? ZRotation(tr) : 0);
   28.47 +		MotionXForm.Translate(XTranslation ? XTranslation(ts) : 0, YTranslation ? YTranslation(ts) : 0, ZTranslation ? ZTranslation(ts) : 0);
   28.48 +	}
   28.49 +
   28.50 +	return MotionXForm;
   28.51 +}
   28.52 +
   28.53 +	
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/src/3deng/motion.h	Thu Oct 23 01:46:07 2014 +0300
    29.3 @@ -0,0 +1,37 @@
    29.4 +#ifndef _MOTION_H_
    29.5 +#define _MOTION_H_
    29.6 +
    29.7 +#include "n3dmath.h"
    29.8 +#include "curves.h"
    29.9 +
   29.10 +class MotionController {
   29.11 +private:
   29.12 +	Matrix4x4 MotionXForm;
   29.13 +	bool FollowPath;
   29.14 +	float ScaleInputTrans, ScaleInputRot, ScaleInputScale;
   29.15 +	
   29.16 +	float (*XTranslation)(float);
   29.17 +	float (*YTranslation)(float);
   29.18 +	float (*ZTranslation)(float);
   29.19 +	float (*XRotation)(float);
   29.20 +	float (*YRotation)(float);
   29.21 +	float (*ZRotation)(float);
   29.22 +	float (*XScaling)(float);
   29.23 +	float (*YScaling)(float);
   29.24 +	float (*ZScaling)(float);
   29.25 +
   29.26 +public:
   29.27 +
   29.28 +	MotionController();
   29.29 +	
   29.30 +	void SetTranslation(float (*xtrans)(float), float (*ytrans)(float), float (*ztrans)(float), float ScaleInput = 1.0f);
   29.31 +	void SetRotation(float (*xrot)(float), float (*yrot)(float), float (*zrot)(float), float ScaleInput = 1.0f);
   29.32 +	void SetScaling(float (*xscale)(float), float (*yscale)(float), float (*zscale)(float), float ScaleInput = 1.0f);
   29.33 +	void SetPath(const Curve &path);
   29.34 +
   29.35 +	const Matrix4x4 &GetTransformation(float t);
   29.36 +};
   29.37 +
   29.38 +
   29.39 +
   29.40 +#endif	// _MOTION_H_
   29.41 \ No newline at end of file
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/src/3deng/objectgen.cpp	Thu Oct 23 01:46:07 2014 +0300
    30.3 @@ -0,0 +1,155 @@
    30.4 +#include "objectgen.h"
    30.5 +#include "n3dmath.h"
    30.6 +
    30.7 +struct Quad {
    30.8 +	Index verts[4];
    30.9 +	Vector3 norm;
   30.10 +};
   30.11 +
   30.12 +///////////////////////////////////////////////
   30.13 +//  --==( Generate a tesselated plane )==--  //
   30.14 +///////////////////////////////////////////////
   30.15 +
   30.16 +void ObjGen::CreatePlane(GraphicsContext *gc, float size, dword subdivisions, TriMesh **mesh, byte LODLevels) {
   30.17 +
   30.18 +	dword VertexNum = (subdivisions+2) * (subdivisions+2);
   30.19 +	dword TriNum = ((subdivisions+1) * (subdivisions+1)) << 1;
   30.20 +	int QuadNum = TriNum >> 1;
   30.21 +	int QuadsRow = subdivisions+1;		// quads per row
   30.22 +	int VertsRow = subdivisions+2;		// vertices per row
   30.23 +	int VertsCol = VertsRow;
   30.24 +
   30.25 +    Vertex *varray = new Vertex[VertexNum];
   30.26 +	Triangle *tarray = new Triangle[TriNum];
   30.27 +
   30.28 +	for(int j=0; j<VertsCol; j++) {
   30.29 +		for(int i=0; i<VertsRow; i++) {
   30.30 +
   30.31 +			float u = (float)i/(float)QuadsRow;
   30.32 +			float v = (float)j/(float)QuadsRow;
   30.33 +			varray[j*VertsRow+i] = Vertex(Vector3(u - 0.5f, 1.0f - v - 0.5f, 0), u, v, 0x00ffffff);
   30.34 +			varray[j*VertsRow+i].pos *= size;
   30.35 +		}
   30.36 +	}
   30.37 +
   30.38 +	// first seperate the quads and then triangulate
   30.39 +	Quad *quads = new Quad[QuadNum];
   30.40 +
   30.41 +	for(int i=0; i<QuadNum; i++) {
   30.42 +		quads[i].verts[0] = i + i/QuadsRow;
   30.43 +		quads[i].verts[1] = quads[i].verts[0] + 1;
   30.44 +		quads[i].verts[2] = quads[i].verts[0] + VertsRow;
   30.45 +		quads[i].verts[3] = quads[i].verts[1] + VertsRow;
   30.46 +	}
   30.47 +
   30.48 +	for(int i=0; i<QuadNum; i++) {
   30.49 +		tarray[i<<1] = Triangle(quads[i].verts[0], quads[i].verts[1], quads[i].verts[3]);
   30.50 +		tarray[(i<<1)+1] = Triangle(quads[i].verts[0], quads[i].verts[3], quads[i].verts[2]);
   30.51 +	}
   30.52 +
   30.53 +	for(dword i=0; i<VertexNum; i++) {
   30.54 +		varray[i].normal = Vector3(0, 0, -1);
   30.55 +	}
   30.56 +
   30.57 +	*mesh = new TriMesh(LODLevels, gc);
   30.58 +	(*mesh)->SetData(varray, tarray, VertexNum, TriNum);
   30.59 +
   30.60 +	delete [] quads;
   30.61 +	delete [] varray;
   30.62 +	delete [] tarray;
   30.63 +}
   30.64 +
   30.65 +	
   30.66 +
   30.67 +
   30.68 +/////////////////////////////////////////////////////////
   30.69 +//  --==( Generate Cube without shared vertices )==--  //
   30.70 +/////////////////////////////////////////////////////////
   30.71 +
   30.72 +void ObjGen::CreateCube(GraphicsContext *gc, float size, TriMesh **mesh, byte LODLevels) {
   30.73 +
   30.74 +	Vertex verts[36];
   30.75 +	verts[0] = Vertex(Vector3(-1, +1, -1),	0, 0);
   30.76 +	verts[1] = Vertex(Vector3(+1, +1, -1),	1, 0);
   30.77 +	verts[2] = Vertex(Vector3(+1, -1, -1),	1, 1);
   30.78 +	verts[3] = Vertex(Vector3(-1, +1, -1),	0, 0);
   30.79 +	verts[4] = Vertex(Vector3(+1, -1, -1),	1, 1);
   30.80 +	verts[5] = Vertex(Vector3(-1, -1, -1),	0, 1);
   30.81 +	verts[6] = Vertex(Vector3(-1, +1, +1),	0, 0);
   30.82 +	verts[7] = Vertex(Vector3(-1, +1, -1),	1, 0);
   30.83 +	verts[8] = Vertex(Vector3(-1, -1, -1),	1, 1);
   30.84 +	verts[9] = Vertex(Vector3(-1, +1, +1),	0, 0);
   30.85 +	verts[10] = Vertex(Vector3(-1, -1, -1),	1, 1);
   30.86 +	verts[11] = Vertex(Vector3(-1, -1, +1),	0, 1);
   30.87 +	verts[12] = Vertex(Vector3(-1, +1, +1),	1, 0);
   30.88 +	verts[13] = Vertex(Vector3(-1, -1, +1),	1, 1);
   30.89 +	verts[14] = Vertex(Vector3(+1, +1, +1),	0, 0);
   30.90 +	verts[15] = Vertex(Vector3(+1, +1, +1),	0, 0);
   30.91 +	verts[16] = Vertex(Vector3(-1, -1, +1),	1, 1);
   30.92 +	verts[17] = Vertex(Vector3(+1, -1, +1),	0, 1);
   30.93 +	verts[18] = Vertex(Vector3(+1, +1, -1),	0, 0);
   30.94 +	verts[19] = Vertex(Vector3(+1, +1, +1),	1, 0);
   30.95 +	verts[20] = Vertex(Vector3(+1, -1, +1),	1, 1);
   30.96 +	verts[21] = Vertex(Vector3(+1, +1, -1),	0, 0);
   30.97 +	verts[22] = Vertex(Vector3(+1, -1, +1),	1, 1);
   30.98 +	verts[23] = Vertex(Vector3(+1, -1, -1),	0, 1);
   30.99 +	verts[24] = Vertex(Vector3(-1, +1, -1),	0, 1);
  30.100 +	verts[25] = Vertex(Vector3(+1, +1, +1),	1, 0);
  30.101 +	verts[26] = Vertex(Vector3(+1, +1, -1),	1, 1);
  30.102 +	verts[27] = Vertex(Vector3(-1, +1, +1),	0, 0);
  30.103 +	verts[28] = Vertex(Vector3(+1, +1, +1),	1, 0);
  30.104 +	verts[29] = Vertex(Vector3(-1, +1, -1),	0, 1);
  30.105 +	verts[30] = Vertex(Vector3(-1, -1, +1),	0, 1);
  30.106 +	verts[31] = Vertex(Vector3(-1, -1, -1),	0, 0);
  30.107 +	verts[32] = Vertex(Vector3(+1, -1, +1),	1, 1);
  30.108 +	verts[33] = Vertex(Vector3(-1, -1, -1),	0, 0);
  30.109 +	verts[34] = Vertex(Vector3(+1, -1, -1),	1, 0);
  30.110 +	verts[35] = Vertex(Vector3(+1, -1, +1),	1, 1);
  30.111 +
  30.112 +	Triangle tri[12];
  30.113 +	for(int i=0; i<12; i++) {
  30.114 +		tri[i].vertices[0] = i*3;
  30.115 +		tri[i].vertices[1] = i*3+1;
  30.116 +		tri[i].vertices[2] = i*3+2;
  30.117 +	}	
  30.118 +
  30.119 +	for(int i=0; i<36; i++) {
  30.120 +		verts[i].pos *= size / 2.0f;
  30.121 +		verts[i].color = 0x00ffffff;
  30.122 +	}
  30.123 +
  30.124 +	TriMesh *tmpmesh = new TriMesh(LODLevels, gc);
  30.125 +	tmpmesh->SetData(verts, tri, 36, 12);
  30.126 +
  30.127 +	tmpmesh->CalculateNormals();
  30.128 +
  30.129 +	*mesh = tmpmesh;
  30.130 +}
  30.131 +
  30.132 +
  30.133 +/////////////////////////////////////
  30.134 +//  --==( Generate Cylinder )==--  //
  30.135 +/////////////////////////////////////
  30.136 +/*
  30.137 +void ObjGen::CreateCylinder(float radius, float height, int sides, int hsegs, bool caps, TriMesh **mesh, byte LODLevels) {
  30.138 +
  30.139 +	int slices = hsegs + 1;
  30.140 +	unsigned long vertex_count = sides * slices + (caps ? (sides + 1)<<1 : 0);
  30.141 +	unsigned long tri_count = (sides << 1) * (slices - 1) + (caps ? sides : 0);
  30.142 +
  30.143 +	Vertex *varray = new Vertex[vertex_count];
  30.144 +	Triangle *tarray = new Triangle[tri_count];
  30.145 +
  30.146 +	Vertex *vptr = varray;
  30.147 +	Triangle *tptr = tarray;
  30.148 +	
  30.149 +	// create a circle by rotating a vector around the y axis
  30.150 +	Vector3 x_axis(radius, 0, 0);
  30.151 +		
  30.152 +	float rot_rads = TwoPi / (float)sides;
  30.153 +	for(int i=0; i<sides; i++) {
  30.154 +		Vector3 pos = x_axis;
  30.155 +		pos.Rotate(0, rot_rads * (float)i, 0);
  30.156 +
  30.157 +		*vptr++ = pos;
  30.158 +*/
  30.159 \ No newline at end of file
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/src/3deng/objectgen.h	Thu Oct 23 01:46:07 2014 +0300
    31.3 @@ -0,0 +1,13 @@
    31.4 +#ifndef _OBJECTGEN_H_
    31.5 +#define _OBJECTGEN_H_
    31.6 +
    31.7 +#include "3dgeom.h"
    31.8 +
    31.9 +namespace ObjGen {
   31.10 +	void CreatePlane(GraphicsContext *gc, float size, dword subdivisions, TriMesh **mesh, byte LODLevels = 0);
   31.11 +	void CreateCube(GraphicsContext *gc, float size, TriMesh **mesh, byte LODLevels = 0);
   31.12 +	void CreateCylinder(float radius, float height, int sides, int hsegs, TriMesh **mesh, byte LODLevels = 0);
   31.13 +	void CreateSphere(float radius, float segments, bool caps, TriMesh **mesh, byte LODLevels = 0);
   31.14 +}
   31.15 +
   31.16 +#endif	// _OBJECTGEN_H_
   31.17 \ No newline at end of file
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/src/3deng/objects.cpp	Thu Oct 23 01:46:07 2014 +0300
    32.3 @@ -0,0 +1,557 @@
    32.4 +#include "objects.h"
    32.5 +#include "3dengine.h"
    32.6 +#include "objectgen.h"
    32.7 +
    32.8 +Object::Object(GraphicsContext *gc, byte DetailLevels) {
    32.9 +	this->gc = gc;
   32.10 +
   32.11 +	mesh = new TriMesh(DetailLevels, gc);
   32.12 +
   32.13 +	SetShadingMode(GouraudShading);
   32.14 +	SetVertexProgram(FixedFunction);
   32.15 +	SetPixelProgram(0);
   32.16 +	rendp.Billboarded = false;
   32.17 +	rendp.SourceBlendFactor = BLEND_SRCALPHA;
   32.18 +	rendp.DestBlendFactor = BLEND_INVSRCALPHA;
   32.19 +	rendp.ZWrite = true;
   32.20 +	ShadowCount = 0;
   32.21 +	UseTextureMatrix = false;
   32.22 +
   32.23 +	ShadowVolumes = 0;
   32.24 +	CastShadows = false;
   32.25 +
   32.26 +	AutoSetZWrite = true;
   32.27 +}
   32.28 +
   32.29 +Object::~Object() {
   32.30 +	delete mesh;
   32.31 +	if(rendp.VertexProgram != FixedFunction) gc->DestroyVertexProgram(rendp.VertexProgram);
   32.32 +}
   32.33 +
   32.34 +TriMesh *Object::GetTriMesh() {
   32.35 +	return mesh;
   32.36 +}
   32.37 +
   32.38 +
   32.39 +// Reset Transformation Matrices
   32.40 +void Object::ResetTransform() {
   32.41 +	TransMat.ResetIdentity();
   32.42 +	RotMat.ResetIdentity();
   32.43 +	GRotMat.ResetIdentity();
   32.44 +	ScaleMat.ResetIdentity();
   32.45 +}
   32.46 +
   32.47 +void Object::ResetTranslation() { 
   32.48 +	TransMat.ResetIdentity();
   32.49 +}
   32.50 +
   32.51 +void Object::ResetRotation() {
   32.52 +	RotMat.ResetIdentity();
   32.53 +}
   32.54 +
   32.55 +void Object::ResetGlobalRotation() {
   32.56 +	GRotMat.ResetIdentity();
   32.57 +}
   32.58 +
   32.59 +void Object::ResetScaling() {
   32.60 +	ScaleMat.ResetIdentity();
   32.61 +}
   32.62 +
   32.63 +// Concatenate additional transformations
   32.64 +void Object::Translate(float tx, float ty, float tz) {
   32.65 +	TransMat.Translate(tx, ty, tz);
   32.66 +}
   32.67 +
   32.68 +void Object::Rotate(float rx, float ry, float rz) {
   32.69 +	RotMat.Rotate(rx, ry, rz);
   32.70 +}
   32.71 +
   32.72 +void Object::Rotate(const Vector3 &axis, float angle) {
   32.73 +	RotMat.Rotate(axis, angle);
   32.74 +}
   32.75 +
   32.76 +void Object::Rotate(const Matrix4x4 &rot) {
   32.77 +	RotMat *= rot;
   32.78 +}
   32.79 +
   32.80 +void Object::GlobalRotate(float rx, float ry, float rz) {
   32.81 +	GRotMat.Rotate(rx, ry, rz);
   32.82 +}
   32.83 +
   32.84 +void Object::GlobalRotate(const Vector3 &axis, float angle) {
   32.85 +	GRotMat.Rotate(axis, angle);
   32.86 +}
   32.87 +
   32.88 +void Object::GlobalRotate(const Matrix4x4 &rot) {
   32.89 +	GRotMat *= rot;
   32.90 +}
   32.91 +
   32.92 +void Object::Scale(float sx, float sy, float sz) {
   32.93 +	ScaleMat.Scale(sx, sy, sz);
   32.94 +}
   32.95 +
   32.96 +void Object::SetTranslation(float tx, float ty, float tz) {
   32.97 +	TransMat.SetTranslation(tx, ty, tz);
   32.98 +}
   32.99 +
  32.100 +void Object::SetRotation(float rx, float ry, float rz) {
  32.101 +	RotMat.Rotate(rx, ry, rz);
  32.102 +}
  32.103 +
  32.104 +void Object::SetRotation(const Vector3 &axis, float angle) {
  32.105 +	RotMat.Rotate(axis, angle);
  32.106 +}
  32.107 +
  32.108 +void Object::SetRotation(const Matrix4x4 &rot) {
  32.109 +	RotMat = rot;
  32.110 +}
  32.111 +
  32.112 +void Object::SetGlobalRotation(float rx, float ry, float rz) {
  32.113 +	GRotMat.Rotate(rx, ry, rz);
  32.114 +}
  32.115 +
  32.116 +void Object::SetGlobalRotation(const Vector3 &axis, float angle) {
  32.117 +	GRotMat.Rotate(axis, angle);
  32.118 +}
  32.119 +
  32.120 +void Object::SetGlobalRotation(const Matrix4x4 &rot) {
  32.121 +	GRotMat = rot;
  32.122 +}
  32.123 +
  32.124 +void Object::SetScaling(float sx, float sy, float sz) {
  32.125 +	ScaleMat.Scale(sx, sy, sz);
  32.126 +}
  32.127 +
  32.128 +const Matrix4x4 Object::GetWorldTransform() const {
  32.129 +	return ScaleMat * RotMat * TransMat * GRotMat;
  32.130 +}
  32.131 +
  32.132 +void Object::SetTextureMatrix(Matrix4x4 mat) {
  32.133 +	UseTextureMatrix = true;
  32.134 +	TextureMatrix = mat;
  32.135 +}
  32.136 +
  32.137 +Matrix4x4 Object::GetTextureMatrix() const {
  32.138 +	return TextureMatrix;
  32.139 +}
  32.140 +
  32.141 +void Object::SetVertexProgram(dword VertexProgram) {
  32.142 +	rendp.VertexProgram = VertexProgram;
  32.143 +}
  32.144 +
  32.145 +void Object::SetPixelProgram(dword PixelProgram) {
  32.146 +	rendp.PixelProgram = PixelProgram;
  32.147 +}
  32.148 +
  32.149 +void Object::SetShadingMode(ShadeMode smode) {
  32.150 +	rendp.Shading = smode;
  32.151 +}
  32.152 +
  32.153 +void Object::SetWriteZBuffer(bool enable) {
  32.154 +	rendp.ZWrite = enable;
  32.155 +	AutoSetZWrite = false;
  32.156 +}
  32.157 +
  32.158 +void Object::SetBlendFunc(BlendingFactor src, BlendingFactor dest) {
  32.159 +	rendp.SourceBlendFactor = src;
  32.160 +	rendp.DestBlendFactor = dest;
  32.161 +}
  32.162 +
  32.163 +void Object::GetBlendFunc(BlendingFactor *src, BlendingFactor *dest) {
  32.164 +	*src = rendp.SourceBlendFactor;
  32.165 +	*dest = rendp.DestBlendFactor;
  32.166 +}
  32.167 +
  32.168 +void Object::CalculateShadows(const Light **lights, int LightCount) {
  32.169 +	if(ShadowVolumes) {
  32.170 +		for(int i=0; i<ShadowCount; i++) {
  32.171 +			delete ShadowVolumes[i];
  32.172 +		}
  32.173 +		delete ShadowVolumes;
  32.174 +	}
  32.175 +
  32.176 +	ShadowVolumes = new TriMesh*[LightCount];
  32.177 +	for(int i=0; i<LightCount; i++) {
  32.178 +		ShadowVolumes[i] = CreateShadowVolume(*mesh, lights[i], GetWorldTransform());
  32.179 +	}
  32.180 +
  32.181 +	ShadowCount = LightCount;
  32.182 +}
  32.183 +
  32.184 +TriMesh *Object::GetShadowVolume(int light) {
  32.185 +	if(light >= ShadowCount) return 0;
  32.186 +	return ShadowVolumes[light];
  32.187 +}
  32.188 +
  32.189 +void Object::SetShadowCasting(bool enable) {
  32.190 +	CastShadows = enable;
  32.191 +}
  32.192 +
  32.193 +bool Object::GetShadowCasting() const {
  32.194 +	return CastShadows;
  32.195 +}
  32.196 +
  32.197 +///////////////////////////
  32.198 +
  32.199 +void Object::SetRenderStates() {
  32.200 +	gc->SetWorldMatrix(GetWorldTransform());
  32.201 +	
  32.202 +	gc->SetMaterial(material);
  32.203 +	if(AutoSetZWrite && material.Alpha < 0.991f) rendp.ZWrite = false;
  32.204 +	gc->SetSpecular(material.SpecularEnable);
  32.205 +
  32.206 +	gc->SetVertexProgram(rendp.VertexProgram);
  32.207 +	gc->SetPixelProgram(rendp.PixelProgram);
  32.208 +	gc->SetShadingMode(rendp.Shading);
  32.209 +}
  32.210 +
  32.211 +void Object::Render() {
  32.212 +	int TexUnits = gc->GetTextureStageNumber();
  32.213 +
  32.214 +	if(TexUnits < 4) {
  32.215 +		Render2TexUnits();
  32.216 +	} else if(TexUnits < 8) {
  32.217 +		Render4TexUnits();
  32.218 +	} else {
  32.219 +		Render8TexUnits();
  32.220 +	}
  32.221 +}
  32.222 +
  32.223 +void Object::Render2TexUnits() {
  32.224 +
  32.225 +	SetRenderStates();
  32.226 +
  32.227 +	VertexBuffer *vb = const_cast<VertexBuffer*>(mesh->GetVertexBuffer());
  32.228 +	IndexBuffer *ib = const_cast<IndexBuffer*>(mesh->GetIndexBuffer());
  32.229 +
  32.230 +	Material mat = material;
  32.231 +
  32.232 +	int TexCount = 0;
  32.233 +	for(int i=0; i<NumberOfTextureTypes; i++) {
  32.234 +		if(mat.Maps[i]) TexCount++;
  32.235 +	}
  32.236 +
  32.237 +	if(!rendp.ZWrite) gc->SetZWrite(false);
  32.238 +
  32.239 +	if(!TexCount) {
  32.240 +		// render without any texture
  32.241 +		gc->SetTexture(0, 0);
  32.242 +		gc->SetTextureStageColor(0, TexBlendSelectArg1, TexArgDiffuseColor, TexArgTexture);
  32.243 +		if(mat.Alpha < 1.0f) {
  32.244 +			gc->SetTextureFactor(Color(mat.Alpha, mat.Alpha, mat.Alpha, mat.Alpha).GetPacked32());
  32.245 +			gc->SetTextureStageAlpha(0, TexBlendSelectArg1, TexArgFactor, TexArgDiffuseColor);
  32.246 +		} else {
  32.247 +			gc->SetTextureStageAlpha(0, TexBlendSelectArg1, TexArgCurrent, TexArgTexture);
  32.248 +		}
  32.249 +		gc->DisableTextureStage(1);
  32.250 +		
  32.251 +		gc->SetAlphaBlending(true);
  32.252 +		gc->SetBlendFunc(rendp.SourceBlendFactor, rendp.DestBlendFactor);
  32.253 +		gc->Draw(vb, ib);
  32.254 +		gc->SetAlphaBlending(false);
  32.255 +	} else {
  32.256 +        
  32.257 +		////////// pass 1 (texture & env) ///////////
  32.258 +		int stage = 0;
  32.259 +		if(mat.Maps[TextureMap]) {
  32.260 +			if(UseTextureMatrix) gc->SetTextureMatrix(TextureMatrix, 0);
  32.261 +            gc->SetTexture(stage, mat.Maps[TextureMap]);
  32.262 +			gc->SetTextureStageColor(stage, TexBlendModulate, TexArgCurrent, TexArgTexture);
  32.263 +			if(mat.Alpha < 1.0f) {
  32.264 +				gc->SetTextureFactor(Color(mat.Alpha, mat.Alpha, mat.Alpha, mat.Alpha).GetPacked32());
  32.265 +				gc->SetTextureStageAlpha(stage, TexBlendModulate, TexArgTexture, TexArgFactor);
  32.266 +			} else {
  32.267 +				gc->SetTextureStageAlpha(stage, TexBlendSelectArg2, TexArgCurrent, TexArgTexture);
  32.268 +			}
  32.269 +			gc->SetTextureCoordIndex(stage, 0);
  32.270 +			stage++;
  32.271 +		}
  32.272 +
  32.273 +		if(mat.Maps[EnvironmentMap]) {
  32.274 +			gc->SetTexture(stage, mat.Maps[EnvironmentMap]);
  32.275 +			gc->SetTextureStageColor(stage, TexBlendAdd, TexArgCurrent, TexArgTexture);
  32.276 +			gc->SetTextureStageAlpha(stage, TexBlendSelectArg1, TexArgCurrent, TexArgTexture);
  32.277 +			Matrix4x4 TexMat = Matrix4x4(0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.0f, 1.0f);
  32.278 +            gc->SetTextureMatrix(TexMat, stage);
  32.279 +			gc->D3DDevice->SetTextureStageState(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
  32.280 +			gc->D3DDevice->SetTextureStageState(stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL);
  32.281 +			stage++;
  32.282 +		}
  32.283 +
  32.284 +		gc->SetTexture(stage, 0);
  32.285 +		gc->DisableTextureStage(stage);
  32.286 +
  32.287 +		if(stage > 0) {
  32.288 +			gc->SetAlphaBlending(true);
  32.289 +			gc->SetBlendFunc(rendp.SourceBlendFactor, rendp.DestBlendFactor);
  32.290 +			gc->Draw(vb, ib);
  32.291 +			gc->SetAlphaBlending(false);
  32.292 +
  32.293 +			gc->SetTextureMatrix(Matrix4x4(), 0);
  32.294 +			gc->SetTextureMatrix(Matrix4x4(), 1);
  32.295 +		}
  32.296 +
  32.297 +		////////// pass 2 (Bump & Lightmap) //////////
  32.298 +		if(stage > 0) {	// did a first pass
  32.299 +			gc->SetAlphaBlending(true);
  32.300 +			gc->SetBlendFunc(BLEND_DESTCOLOR, BLEND_ZERO);		// mult blend
  32.301 +			mat.Emissive = Color(1.0f);	// do not recalculate lighting
  32.302 +		}
  32.303 +
  32.304 +		stage = 0;
  32.305 +		if(mat.Maps[LightMap]) {
  32.306 +            gc->SetTexture(stage, mat.Maps[LightMap]);
  32.307 +			gc->SetTextureStageColor(stage, TexBlendSelectArg2, TexArgCurrent, TexArgTexture);
  32.308 +			gc->SetTextureStageAlpha(stage, TexBlendSelectArg1, TexArgCurrent, TexArgTexture);
  32.309 +			gc->SetTextureCoordIndex(stage, 1);
  32.310 +			stage++;
  32.311 +		}
  32.312 +
  32.313 +		if(mat.Maps[BumpMap]) {
  32.314 +			// re-implementation due
  32.315 +		}
  32.316 +
  32.317 +		gc->SetTexture(stage, 0);
  32.318 +		gc->DisableTextureStage(stage);
  32.319 +
  32.320 +		if(stage > 0) gc->Draw(vb, ib);
  32.321 +
  32.322 +		gc->SetAlphaBlending(false);
  32.323 +	}
  32.324 +
  32.325 +	if(!rendp.ZWrite) gc->SetZWrite(true);
  32.326 +}
  32.327 +
  32.328 +
  32.329 +void Object::Render4TexUnits() {
  32.330 +	SetRenderStates();
  32.331 +
  32.332 +	VertexBuffer *vb = const_cast<VertexBuffer*>(mesh->GetVertexBuffer());
  32.333 +	IndexBuffer *ib = const_cast<IndexBuffer*>(mesh->GetIndexBuffer());
  32.334 +
  32.335 +	Material mat = material;
  32.336 +
  32.337 +	int TexCount = 0;
  32.338 +	for(int i=0; i<NumberOfTextureTypes; i++) {
  32.339 +		if(mat.Maps[i]) TexCount++;
  32.340 +	}
  32.341 +
  32.342 +	if(!rendp.ZWrite) gc->SetZWrite(false);
  32.343 +
  32.344 +	if(!TexCount) {
  32.345 +		// render without any texture
  32.346 +		gc->SetTexture(0, 0);
  32.347 +		gc->SetTextureStageColor(0, TexBlendSelectArg1, TexArgDiffuseColor, TexArgTexture);
  32.348 +		if(mat.Alpha < 1.0f) {
  32.349 +			gc->SetTextureFactor(Color(mat.Alpha, mat.Alpha, mat.Alpha, mat.Alpha).GetPacked32());
  32.350 +			gc->SetTextureStageAlpha(0, TexBlendSelectArg1, TexArgFactor, TexArgDiffuseColor);
  32.351 +		} else {
  32.352 +			gc->SetTextureStageAlpha(0, TexBlendSelectArg1, TexArgCurrent, TexArgTexture);
  32.353 +		}
  32.354 +		gc->DisableTextureStage(1);
  32.355 +		
  32.356 +		gc->SetAlphaBlending(true);
  32.357 +		gc->SetBlendFunc(rendp.SourceBlendFactor, rendp.DestBlendFactor);
  32.358 +		gc->Draw(vb, ib);
  32.359 +		gc->SetAlphaBlending(false);
  32.360 +	} else {
  32.361 +        
  32.362 +		////////// pass 1 (texture, detail, env, bump) ///////////
  32.363 +		int stage = 0;
  32.364 +		if(mat.Maps[TextureMap]) {
  32.365 +			if(UseTextureMatrix) gc->SetTextureMatrix(TextureMatrix, 0);
  32.366 +            gc->SetTexture(stage, mat.Maps[TextureMap]);
  32.367 +			gc->SetTextureStageColor(stage, TexBlendModulate, TexArgCurrent, TexArgTexture);
  32.368 +			if(mat.Alpha < 1.0f) {
  32.369 +				gc->SetTextureFactor(Color(mat.Alpha, mat.Alpha, mat.Alpha, mat.Alpha).GetPacked32());
  32.370 +				gc->SetTextureStageAlpha(stage, TexBlendModulate, TexArgTexture, TexArgFactor);
  32.371 +			} else {
  32.372 +				gc->SetTextureStageAlpha(stage, TexBlendSelectArg2, TexArgCurrent, TexArgTexture);
  32.373 +			}
  32.374 +			gc->SetTextureCoordIndex(stage, 0);
  32.375 +			stage++;
  32.376 +		}
  32.377 +
  32.378 +		if(mat.Maps[DetailMap]) {
  32.379 +            gc->SetTexture(stage, mat.Maps[DetailMap]);
  32.380 +			gc->SetTextureStageColor(stage, TexBlendAdd, TexArgCurrent, TexArgTexture);
  32.381 +			gc->SetTextureStageAlpha(stage, TexBlendSelectArg1, TexArgCurrent, TexArgTexture);
  32.382 +			gc->SetTextureCoordIndex(stage, 1);
  32.383 +			stage++;
  32.384 +		}
  32.385 +
  32.386 +		if(mat.Maps[EnvironmentMap]) {
  32.387 +			gc->SetTexture(stage, mat.Maps[EnvironmentMap]);
  32.388 +			gc->SetTextureStageColor(stage, TexBlendAdd, TexArgCurrent, TexArgTexture);
  32.389 +			gc->SetTextureStageAlpha(stage, TexBlendSelectArg1, TexArgCurrent, TexArgTexture);
  32.390 +			Matrix4x4 TexMat = Matrix4x4(0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.0f, 1.0f);
  32.391 +            gc->SetTextureMatrix(TexMat, stage);
  32.392 +			gc->D3DDevice->SetTextureStageState(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
  32.393 +			gc->D3DDevice->SetTextureStageState(stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL);
  32.394 +			stage++;
  32.395 +		}
  32.396 +
  32.397 +		if(mat.Maps[BumpMap]) {
  32.398 +			// re-implementation due
  32.399 +		}
  32.400 +
  32.401 +		gc->SetTexture(stage, 0);
  32.402 +		gc->DisableTextureStage(stage);
  32.403 +
  32.404 +		if(stage > 0) {
  32.405 +			gc->SetAlphaBlending(true);
  32.406 +			gc->SetBlendFunc(rendp.SourceBlendFactor, rendp.DestBlendFactor);
  32.407 +			gc->Draw(vb, ib);
  32.408 +			gc->SetAlphaBlending(false);
  32.409 +
  32.410 +			gc->SetTextureMatrix(Matrix4x4(), 0);
  32.411 +			gc->SetTextureMatrix(Matrix4x4(), 1);
  32.412 +			gc->SetTextureMatrix(Matrix4x4(), 2);
  32.413 +		}
  32.414 +
  32.415 +		////////// pass 2 (Bump & Lightmap) //////////
  32.416 +		if(stage > 0) {	// did a first pass
  32.417 +			gc->SetAlphaBlending(true);
  32.418 +			gc->SetBlendFunc(BLEND_DESTCOLOR, BLEND_ZERO);		// mult blend
  32.419 +			mat.Emissive = Color(1.0f);	// do not recalculate lighting
  32.420 +		}
  32.421 +
  32.422 +		stage = 0;
  32.423 +		if(mat.Maps[LightMap]) {
  32.424 +            gc->SetTexture(stage, mat.Maps[LightMap]);
  32.425 +			gc->SetTextureStageColor(stage, TexBlendSelectArg2, TexArgCurrent, TexArgTexture);
  32.426 +			gc->SetTextureStageAlpha(stage, TexBlendSelectArg1, TexArgCurrent, TexArgTexture);
  32.427 +			gc->SetTextureCoordIndex(stage, 1);
  32.428 +			stage++;
  32.429 +		}
  32.430 +
  32.431 +		gc->SetTexture(stage, 0);
  32.432 +		gc->DisableTextureStage(stage);
  32.433 +
  32.434 +		if(stage > 0) gc->Draw(vb, ib);
  32.435 +
  32.436 +		gc->SetAlphaBlending(false);
  32.437 +	}
  32.438 +
  32.439 +	if(!rendp.ZWrite) gc->SetZWrite(false);
  32.440 +}
  32.441 +
  32.442 +
  32.443 +void Object::Render8TexUnits() {Render4TexUnits();}
  32.444 +
  32.445 +
  32.446 +
  32.447 +/*
  32.448 +void Object::Render() {
  32.449 +
  32.450 +	SetRenderStates();
  32.451 +	
  32.452 +	VertexBuffer *vb = const_cast<VertexBuffer*>(mesh->GetVertexBuffer());
  32.453 +	IndexBuffer *ib = const_cast<IndexBuffer*>(mesh->GetIndexBuffer());
  32.454 +
  32.455 +	Material mat = material;
  32.456 +	int MapsCount = 0, ActiveTex = 0;
  32.457 +	for(int i=0; i<NumberOfTextureTypes; i++) {
  32.458 +		if(mat.Maps[i]) MapsCount++;
  32.459 +	}
  32.460 +
  32.461 +	if(!MapsCount) {
  32.462 +		gc->SetTexture(0, 0);
  32.463 +		gc->DisableTextureStage(0);
  32.464 +		gc->Draw(vb, ib);
  32.465 +	} else {
  32.466 +		int pass = 1;
  32.467 +		TextureType PassFirstTexture;
  32.468 +		while(MapsCount) {
  32.469 +			
  32.470 +			if(mat.Maps[BumpMap]) {
  32.471 +				gc->SetTexture(ActiveTex, mat.Maps[BumpMap]);
  32.472 +				//gc->SetTextureFactor() TODO
  32.473 +				gc->SetTextureStageColor(ActiveTex, TexBlendDotProduct, TexArgFactor, TexArgTexture);
  32.474 +				mat.Maps[BumpMap] = 0;
  32.475 +				if(!ActiveTex) PassFirstTexture = BumpMap;
  32.476 +			} else if(mat.Maps[TextureMap]) {
  32.477 +				gc->SetTexture(ActiveTex, mat.Maps[TextureMap]);
  32.478 +				gc->SetTextureStageColor(ActiveTex, TexBlendModulate, TexArgCurrent, TexArgTexture);
  32.479 +				//gc->SetTextureStageColor(ActiveTex, TexBlendSelectArg2, TexArgCurrent, TexArgTexture);
  32.480 +				gc->SetTextureCoordIndex(ActiveTex, 0);
  32.481 +				mat.Maps[TextureMap] = 0;
  32.482 +				if(!ActiveTex) PassFirstTexture = TextureMap;
  32.483 +			} else if(mat.Maps[DetailMap]) {
  32.484 +				gc->SetTexture(ActiveTex, mat.Maps[DetailMap]);
  32.485 +				gc->SetTextureStageColor(ActiveTex, TexBlendAdd, TexArgCurrent, TexArgTexture);
  32.486 +				gc->SetTextureCoordIndex(ActiveTex, 1);
  32.487 +				mat.Maps[DetailMap] = 0;
  32.488 +				if(!ActiveTex) PassFirstTexture = DetailMap;
  32.489 +			} else if(mat.Maps[EnvironmentMap]) {
  32.490 +				gc->SetTexture(ActiveTex, mat.Maps[EnvironmentMap]);
  32.491 +				gc->SetTextureStageColor(ActiveTex, TexBlendAdd, TexArgCurrent, TexArgTexture);
  32.492 +
  32.493 +				//gc->SetTextureCoordGenerator(TexGenSpherical); TODO
  32.494 +				Matrix4x4 TexMat = Matrix4x4(0.5f,	0.0f,	0.0f,	0.0f,
  32.495 +											0.0f,	-0.5f,	0.0f,	0.0f,
  32.496 +											0.0f,	0.0f,	1.0f,	0.0f,
  32.497 +											0.5f,	0.5f,	0.0f,	1.0f ); 
  32.498 +				gc->SetTextureMatrix(TexMat, ActiveTex);
  32.499 +				gc->D3DDevice->SetTextureStageState(ActiveTex, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
  32.500 +				gc->D3DDevice->SetTextureStageState(ActiveTex, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL);
  32.501 +
  32.502 +				mat.Maps[EnvironmentMap] = 0;
  32.503 +				if(!ActiveTex) PassFirstTexture = EnvironmentMap;
  32.504 +			} else if(mat.Maps[LightMap]) {
  32.505 +				gc->SetTexture(ActiveTex, mat.Maps[LightMap]);
  32.506 +				gc->SetTextureStageColor(ActiveTex, TexBlendModulate, TexArgCurrent, TexArgTexture);
  32.507 +				gc->SetTextureCoordIndex(ActiveTex, 2);
  32.508 +				mat.Maps[LightMap] = 0;
  32.509 +				if(!ActiveTex) PassFirstTexture = LightMap;
  32.510 +			}
  32.511 +
  32.512 +			MapsCount--;
  32.513 +			ActiveTex++;
  32.514 +
  32.515 +			if(!MapsCount) {
  32.516 +				gc->SetTextureStageColor(ActiveTex, TexBlendModulate, TexArgCurrent, TexArgDiffuseColor);
  32.517 +			}
  32.518 +
  32.519 +			if(ActiveTex >= gc->GetTextureStageNumber() || !MapsCount) {
  32.520 +				if(pass++ > 1) {
  32.521 +					gc->SetAlphaBlending(true);
  32.522 +					if(PassFirstTexture == DetailMap || PassFirstTexture == EnvironmentMap) {
  32.523 +						gc->SetBlendFunc(BLEND_ONE, BLEND_ONE);
  32.524 +					} else {
  32.525 +                        gc->SetBlendFunc(BLEND_DESTCOLOR, BLEND_ZERO);
  32.526 +					}
  32.527 +                    gc->Draw(vb, ib);
  32.528 +					gc->SetAlphaBlending(false);
  32.529 +				} else {
  32.530 +					gc->Draw(vb, ib);
  32.531 +				}
  32.532 +				ActiveTex = 0;
  32.533 +				for(int i=0; i<gc->GetTextureStageNumber(); i++) {
  32.534 +					gc->SetTextureMatrix(Matrix4x4(), i);
  32.535 +				}
  32.536 +			}
  32.537 +		}
  32.538 +	}
  32.539 +
  32.540 +	if(material.SpecularEnable) gc->SetSpecular(false);
  32.541 +}
  32.542 +*/
  32.543 +
  32.544 +
  32.545 +
  32.546 +void Object::RenderBare() {
  32.547 +	VertexBuffer *vb = const_cast<VertexBuffer*>(mesh->GetVertexBuffer());
  32.548 +	IndexBuffer *ib = const_cast<IndexBuffer*>(mesh->GetIndexBuffer());
  32.549 +	gc->Draw(vb, ib);
  32.550 +}
  32.551 +
  32.552 +
  32.553 +// generate geometry
  32.554 +void Object::CreatePlane(float size, dword subdivisions) {
  32.555 +	ObjGen::CreatePlane(gc, size, subdivisions, &mesh, mesh->GetLevelCount());
  32.556 +}
  32.557 +
  32.558 +void Object::CreateCube(float size) {
  32.559 +	ObjGen::CreateCube(gc, size, &mesh, mesh->GetLevelCount());
  32.560 +}
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/src/3deng/objects.h	Thu Oct 23 01:46:07 2014 +0300
    33.3 @@ -0,0 +1,97 @@
    33.4 +#ifndef _OBJECTS_H_
    33.5 +#define _OBJECTS_H_
    33.6 +
    33.7 +#include <string>
    33.8 +#include "3dengine.h"
    33.9 +#include "n3dmath.h"
   33.10 +#include "3dgeom.h"
   33.11 +#include "material.h"
   33.12 +#include "motion.h"
   33.13 +
   33.14 +class Object {
   33.15 +protected:
   33.16 +	GraphicsContext *gc;
   33.17 +	RenderParams rendp;
   33.18 +
   33.19 +	TriMesh *mesh;
   33.20 +	TriMesh **ShadowVolumes;
   33.21 +	int ShadowCount;
   33.22 +	bool CastShadows;
   33.23 +	
   33.24 +	Matrix4x4 WorldXForm;
   33.25 +//	Matrix4x4 TransMat, RotMat, ScaleMat, GRotMat;
   33.26 +	Matrix4x4 TextureMatrix;
   33.27 +	bool UseTextureMatrix;
   33.28 +
   33.29 +	bool AutoSetZWrite;
   33.30 +
   33.31 +	void Render2TexUnits();
   33.32 +	void Render4TexUnits();
   33.33 +	void Render8TexUnits();
   33.34 +
   33.35 +public:
   33.36 +	std::string name;
   33.37 +	Material material;
   33.38 +	MotionController controller;
   33.39 +
   33.40 +	Matrix4x4 TransMat, RotMat, ScaleMat, GRotMat;
   33.41 +
   33.42 +	Object(GraphicsContext *gc, byte DetailLevels = 1);
   33.43 +	~Object();
   33.44 +
   33.45 +	TriMesh *GetTriMesh();
   33.46 +	
   33.47 +	void ResetTransform();
   33.48 +	void ResetTranslation();
   33.49 +	void ResetRotation();
   33.50 +	void ResetGlobalRotation();
   33.51 +	void ResetScaling();
   33.52 +
   33.53 +	void Translate(float tx, float ty, float tz);
   33.54 +	void Rotate(float rx, float ry, float rz);
   33.55 +	void Rotate(const Vector3 &axis, float angle);
   33.56 +	void Rotate(const Matrix4x4 &rot);
   33.57 +	void GlobalRotate(float rx, float ry, float rz);
   33.58 +	void GlobalRotate(const Vector3 &axis, float angle);
   33.59 +	void GlobalRotate(const Matrix4x4 &rot);
   33.60 +	void Scale(float sx, float sy, float sz);
   33.61 +
   33.62 +	void SetTranslation(float tx, float ty, float tz);
   33.63 +	void SetRotation(float rx, float ry, float rz);
   33.64 +	void SetRotation(const Vector3 &axis, float angle);
   33.65 +	void SetRotation(const Matrix4x4 &rot);
   33.66 +	void SetGlobalRotation(float rx, float ry, float rz);
   33.67 +	void SetGlobalRotation(const Vector3 &axis, float angle);
   33.68 +	void SetGlobalRotation(const Matrix4x4 &rot);
   33.69 +	void SetScaling(float sx, float sy, float sz);
   33.70 +
   33.71 +    const Matrix4x4 GetWorldTransform() const;
   33.72 +
   33.73 +	void SetTextureMatrix(Matrix4x4 mat);
   33.74 +	Matrix4x4 GetTextureMatrix() const;
   33.75 +
   33.76 +	// set render parameters
   33.77 +	void SetVertexProgram(dword VertexProgram);
   33.78 +	void SetPixelProgram(dword PixelProgram);
   33.79 +	void SetShadingMode(ShadeMode smode);
   33.80 +	void SetWriteZBuffer(bool enable);
   33.81 +	void SetBlendFunc(BlendingFactor src, BlendingFactor dest);
   33.82 +	void GetBlendFunc(BlendingFactor *src, BlendingFactor *dest);
   33.83 +
   33.84 +	// about shadows
   33.85 +	void CalculateShadows(const Light **lights, int LightCount);
   33.86 +	TriMesh *GetShadowVolume(int light);
   33.87 +	void SetShadowCasting(bool enable);
   33.88 +	bool GetShadowCasting() const;
   33.89 +
   33.90 +	void SetRenderStates();
   33.91 +	void Render();
   33.92 +	void RenderBare();
   33.93 +
   33.94 +	// generate geometry
   33.95 +	void CreatePlane(float size, dword subdivisions);
   33.96 +	void CreateCube(float size);
   33.97 +};
   33.98 +
   33.99 +
  33.100 +#endif	// _OBJECTS_H_
  33.101 \ No newline at end of file
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/src/3deng/particles.cpp	Thu Oct 23 01:46:07 2014 +0300
    34.3 @@ -0,0 +1,325 @@
    34.4 +#include "particles.h"
    34.5 +#include "3deng.h"
    34.6 +#include <cassert>
    34.7 +
    34.8 +//////////////////////////////////////////////////////
    34.9 +//    --==( Particle class implementation )==--     //
   34.10 +//////////////////////////////////////////////////////
   34.11 +using namespace std;
   34.12 +
   34.13 +Particle::Particle(int life) {
   34.14 +	pos = Vector3(0, 0, 0);
   34.15 +	vel = Vector3(0, 0, 0);
   34.16 +	this->life = life;
   34.17 +}
   34.18 +
   34.19 +Particle::Particle(const Vector3 &pos, int life) {
   34.20 +	this->pos = pos;
   34.21 +	vel = Vector3(0, 0, 0);
   34.22 +	this->life = life;
   34.23 +}
   34.24 +
   34.25 +Particle::Particle(const Vector3 &pos, const Vector3 &vel, int life) {
   34.26 +	this->pos = pos;
   34.27 +	this->vel = vel;
   34.28 +	this->life = life;
   34.29 +}
   34.30 +
   34.31 +void Particle::Update(const Vector3 &forces, float friction) {
   34.32 +	if(!life) return;
   34.33 +	vel *= 1.0f - friction;
   34.34 +	pos += vel + forces;
   34.35 +	life--;
   34.36 +}
   34.37 +
   34.38 +///////////////////////////////////////////////////////
   34.39 +//    --==( Particle System implementation )==--     //
   34.40 +///////////////////////////////////////////////////////
   34.41 +
   34.42 +ParticleSystem::ParticleSystem(GraphicsContext *gc) {
   34.43 +	this->gc = gc;
   34.44 +	pos = prevpos = Vector3(0, 0, 0);
   34.45 +	size = 1.0f;
   34.46 +	friction = 0.0f;
   34.47 +	SpawnRate = 5;
   34.48 +	life = 100;
   34.49 +	EmmiterAffectsParticleTrajectory = false;
   34.50 +	varray = 0;
   34.51 +	tarray = 0;
   34.52 +	texture = 0;
   34.53 +	obj = 0;
   34.54 +
   34.55 +	SetShootDirection(Vector3(0, 0, 0));
   34.56 +	SetMaxDispersionAngle(0.01f);
   34.57 +	SetInitialColor(1, 1, 1);
   34.58 +	SetDeathColor(0, 0, 0);
   34.59 +
   34.60 +	// initialize the shape of the particles
   34.61 +	pquad[0] = Vertex(Vector3(-0.5f, 0.5f, 0), 0, 0, 0xffffffff);
   34.62 +	pquad[1] = Vertex(Vector3(0.5f, 0.5f, 1), 1, 0, 0xffffffff);
   34.63 +	pquad[2] = Vertex(Vector3(0.5f, -0.5f, 1), 1, 1, 0xffffffff);
   34.64 +	pquad[3] = Vertex(Vector3(-0.5f, -0.5f, 0), 0, 1, 0xffffffff);
   34.65 +	
   34.66 +	ptris[0] = Triangle(0, 1, 2);
   34.67 +	ptris[1] = Triangle(0, 2, 3);
   34.68 +
   34.69 +	for(int i=0; i<4; i++) {
   34.70 +		pquad[i].normal = Vector3(0, 0, -1);
   34.71 +	}
   34.72 +
   34.73 +	SetBlendingMode(BLEND_ONE, BLEND_ONE);
   34.74 +	SpawnDiffDispersion = 0.0f;
   34.75 +
   34.76 +	FixedUpdateRate = true;
   34.77 +	UpdateRate = 30.0f;
   34.78 +	LastUpdate = -(1.0f / UpdateRate);
   34.79 +
   34.80 +	SpawnRateChange = 0;
   34.81 +}
   34.82 +
   34.83 +ParticleSystem::~ParticleSystem() {
   34.84 +}
   34.85 +
   34.86 +void ParticleSystem::SetGraphicsContext(GraphicsContext *gc) {
   34.87 +	this->gc = gc;
   34.88 +}
   34.89 +
   34.90 +void ParticleSystem::SetParticleSize(float psize) {
   34.91 +	size = psize;
   34.92 +}
   34.93 +
   34.94 +void ParticleSystem::SetParticleLife(int life) {
   34.95 +	this->life = life;
   34.96 +}
   34.97 +
   34.98 +void ParticleSystem::SetFriction(float friction) {
   34.99 +	this->friction = friction;
  34.100 +}
  34.101 +
  34.102 +void ParticleSystem::SetSpawnRate(float spawnrate) {
  34.103 +	SpawnRate = (int)spawnrate;
  34.104 +}
  34.105 +
  34.106 +void ParticleSystem::SetSpawnRadius(float radius) {
  34.107 +	SpawnRadius = radius;
  34.108 +}
  34.109 +
  34.110 +void ParticleSystem::SetTexture(Texture *texture) {
  34.111 +	this->texture = texture;
  34.112 +}
  34.113 +
  34.114 +void ParticleSystem::SetObject(Object *obj) {
  34.115 +	this->obj = obj;
  34.116 +}
  34.117 +
  34.118 +void ParticleSystem::SetPosition(const Vector3 &pos) {
  34.119 +	this->pos = pos;
  34.120 +}
  34.121 +
  34.122 +void ParticleSystem::SetShootDirection(const Vector3 &dir) {
  34.123 +	ShootDirection = dir;
  34.124 +}
  34.125 +
  34.126 +void ParticleSystem::SetGravitualForce(float grav) {
  34.127 +	GravForce = grav;
  34.128 +}
  34.129 +
  34.130 +void ParticleSystem::SetEmmiterDependence(bool dep) {
  34.131 +	EmmiterAffectsParticleTrajectory = dep;
  34.132 +}
  34.133 +
  34.134 +void ParticleSystem::SetMaxDispersionAngle(float maxdisp) {
  34.135 +	DispRads = maxdisp;
  34.136 +}
  34.137 +
  34.138 +void ParticleSystem::SetInitialColor(float r, float g, float b) {
  34.139 +	StartRed = r;
  34.140 +	StartGreen = g;
  34.141 +	StartBlue = b;
  34.142 +}
  34.143 +
  34.144 +void ParticleSystem::SetDeathColor(float r, float g, float b) {
  34.145 +	EndRed = r;
  34.146 +	EndGreen = g;
  34.147 +	EndBlue = b;
  34.148 +}
  34.149 +
  34.150 +void ParticleSystem::SetBlendingMode(BlendingFactor src, BlendingFactor dest) {
  34.151 +	SourceBlend = src;
  34.152 +	DestBlend = dest;
  34.153 +}
  34.154 +
  34.155 +void ParticleSystem::SetSpawningDifferenceDispersion(float val) {
  34.156 +	SpawnDiffDispersion = val;
  34.157 +}
  34.158 +
  34.159 +void ParticleSystem::SetSpawnRateChange(int change) {
  34.160 +	SpawnRateChange = change;
  34.161 +}
  34.162 +
  34.163 +// transformation stuff
  34.164 +void ParticleSystem::Translate(float x, float y, float z) {
  34.165 +	Translation.Translate(x, y, z);
  34.166 +}
  34.167 +
  34.168 +void ParticleSystem::Rotate(float x, float y, float z) {
  34.169 +	OrbitRot.Rotate(x, y, z);
  34.170 +}
  34.171 +
  34.172 +void ParticleSystem::Rotate(const Vector3 &axis, float angle) {
  34.173 +	OrbitRot.Rotate(axis, angle);
  34.174 +}
  34.175 +
  34.176 +void ParticleSystem::ResetRotation() {
  34.177 +	OrbitRot.ResetIdentity();
  34.178 +}
  34.179 +
  34.180 +void ParticleSystem::ResetTranslation() {
  34.181 +	Translation.ResetIdentity();
  34.182 +}
  34.183 +
  34.184 +int ParticleSystem::CountParticles() {
  34.185 +	ParticleCount = (int)particles.size();
  34.186 +	TriCount = ParticleCount << 1;
  34.187 +	VertexCount = ParticleCount << 2;
  34.188 +	IndexCount = TriCount * 3;
  34.189 +	
  34.190 +	return ParticleCount;
  34.191 +}
  34.192 +
  34.193 +void ParticleSystem::Update(float t) {
  34.194 +
  34.195 +	if(FixedUpdateRate && t-LastUpdate < 1.0f/UpdateRate) return;
  34.196 +	LastUpdate = t;
  34.197 +
  34.198 +	// remove all particles that are dead
  34.199 +	list<Particle>::iterator iter = particles.begin();
  34.200 +	while(iter != particles.end()) {
  34.201 +		if(!iter->life) {
  34.202 +			iter = particles.erase(iter);
  34.203 +			// if we erase the iterator points to the next so no need to advance explicitly
  34.204 +		} else {
  34.205 +			iter++;
  34.206 +		}
  34.207 +	}
  34.208 +
  34.209 +	
  34.210 +	// spawn the new particles according to spawn rate
  34.211 +	int LeftToSpawn = SpawnRate;
  34.212 +	Vector3 ShootDir = ShootDirection;
  34.213 +	Matrix4x4 dispxform;
  34.214 +	
  34.215 +	Vector3 forces = Vector3(0.0f, -GravForce, 0.0f);
  34.216 +
  34.217 +	// find the velocity of the system by differenciating between the
  34.218 +	// last and the current position (time interval is considered constant)
  34.219 +	Vector3 velocity = (pos - prevpos) * 0.1f;
  34.220 +	
  34.221 +	// adjust the shoot vector to take under consideration the velocity of the system
  34.222 +	if(EmmiterAffectsParticleTrajectory) ShootDir += velocity;
  34.223 +
  34.224 +
  34.225 +	while(LeftToSpawn--) {
  34.226 +		Vector3 dir = ShootDir;
  34.227 +		dispxform.Rotate(frand(DispRads) - DispRads/2.0f, frand(DispRads) - DispRads/2.0f, frand(DispRads) - DispRads/2.0f);
  34.228 +		dir.Transform(dispxform);
  34.229 +
  34.230 +		Vector3 SpawnOffset(frand(SpawnRadius) - SpawnRadius / 2.0f, frand(SpawnRadius) - SpawnRadius / 2.0f, frand(SpawnRadius) - SpawnRadius / 2.0f);
  34.231 +        Vector3 SpawnDisp(0.0f, 0.0f, 0.0f);
  34.232 +		if(SpawnDiffDispersion > 0.0f) {
  34.233 +			SpawnDisp = Vector3(frand(1.0f) - 0.5f, frand(1.0f) - 0.5f, frand(1.0f) - 0.5f);
  34.234 +			SpawnDisp.Normalize();
  34.235 +			SpawnDisp *= SpawnDiffDispersion;
  34.236 +		}
  34.237 +		particles.insert(particles.end(), Particle(pos + SpawnOffset, dir + SpawnDisp, life));
  34.238 +	}		
  34.239 +
  34.240 +
  34.241 +	//if(EmmiterAffectsParticleTrajectory) forces += velocity;
  34.242 +
  34.243 +	iter = particles.begin();
  34.244 +	while(iter != particles.end()) {
  34.245 +		iter->Update(forces, friction);
  34.246 +		iter++;
  34.247 +	}
  34.248 +
  34.249 +	SpawnRate += SpawnRateChange;
  34.250 +	if(SpawnRate < 0) SpawnRate = 0;
  34.251 +}
  34.252 +
  34.253 +inline dword FtoDW(float f) { return *((dword*)&f); }
  34.254 +
  34.255 +void ParticleSystem::Render() {
  34.256 +
  34.257 +	CountParticles();
  34.258 +	if(!ParticleCount) return;
  34.259 +
  34.260 +	list<Particle>::iterator iter = particles.begin();
  34.261 +
  34.262 +	if(!obj) {
  34.263 +
  34.264 +		// ----- Render Billboarded Textured Quads -----
  34.265 +
  34.266 +        VertexBuffer *vb;
  34.267 +		gc->CreateVertexBuffer(ParticleCount, UsageStatic, &vb);
  34.268 +		Vertex *vbptr;
  34.269 +		Lock(vb, &vbptr);
  34.270 +
  34.271 +		for(int i=0; i<ParticleCount; i++) {
  34.272 +			vbptr[i].pos = iter->pos;
  34.273 +	
  34.274 +			float t = 1.0f - (float)iter->life / (float)life;
  34.275 +			float red = StartRed + (EndRed - StartRed) * t;
  34.276 +			float green = StartGreen + (EndGreen - StartGreen) * t;
  34.277 +			float blue = StartBlue + (EndBlue - StartBlue) * t;
  34.278 +			
  34.279 +			vbptr[i].color = Color(red, green, blue).GetPacked32();
  34.280 +
  34.281 +			iter++;
  34.282 +		}
  34.283 +		Unlock(vb);
  34.284 +
  34.285 +		gc->SetWorldMatrix(Matrix4x4());
  34.286 +		gc->SetLighting(false);
  34.287 +		gc->SetZWrite(false);
  34.288 +		gc->SetTexture(0, texture);
  34.289 +		gc->SetTextureStageColor(0, TexBlendModulate, TexArgCurrent, TexArgTexture);
  34.290 +		gc->SetAlphaBlending(true);
  34.291 +		gc->SetBlendFunc(SourceBlend, DestBlend);
  34.292 +		gc->SetVertexProgram(FixedFunction);
  34.293 +
  34.294 +		gc->SetColorVertex(true);
  34.295 +
  34.296 +		gc->D3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, true);
  34.297 +		gc->D3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, true);
  34.298 +		gc->D3DDevice->SetRenderState(D3DRS_POINTSIZE, FtoDW(size));
  34.299 +		gc->D3DDevice->SetRenderState(D3DRS_POINTSCALE_A, FtoDW(0.0f));
  34.300 +		gc->D3DDevice->SetRenderState(D3DRS_POINTSCALE_B, FtoDW(0.0f));
  34.301 +		gc->D3DDevice->SetRenderState(D3DRS_POINTSCALE_C, FtoDW(1.0f));
  34.302 +
  34.303 +		gc->D3DDevice->SetStreamSource(0, vb, sizeof(Vertex));
  34.304 +		gc->D3DDevice->DrawPrimitive(D3DPT_POINTLIST, 0, ParticleCount);
  34.305 +
  34.306 +		gc->D3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, false);
  34.307 +		gc->D3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, false);
  34.308 +	
  34.309 +		gc->SetColorVertex(false);
  34.310 +
  34.311 +		gc->SetLighting(true);
  34.312 +		gc->SetZWrite(true);
  34.313 +		gc->SetAlphaBlending(false);
  34.314 +
  34.315 +		vb->Release();
  34.316 +	} else {
  34.317 +
  34.318 +		// ---- Render Mesh Objects ----
  34.319 +		for(int i=0; i<ParticleCount; i++) {
  34.320 +			obj->ResetTranslation();
  34.321 +			obj->Translate(iter->pos.x, iter->pos.y, iter->pos.z);
  34.322 +			obj->Render();
  34.323 +			iter++;
  34.324 +		}
  34.325 +	}
  34.326 +
  34.327 +
  34.328 +}
  34.329 \ No newline at end of file
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/src/3deng/particles.h	Thu Oct 23 01:46:07 2014 +0300
    35.3 @@ -0,0 +1,99 @@
    35.4 +#ifndef _PARTICLES_H_
    35.5 +#define _PARTICLES_H_
    35.6 +
    35.7 +#include <list>
    35.8 +#include "n3dmath.h"
    35.9 +#include "3dgeom.h"
   35.10 +#include "objects.h"
   35.11 +
   35.12 +enum BlendingFactor;
   35.13 +
   35.14 +class Particle {
   35.15 +public:
   35.16 +	Vector3 pos;
   35.17 +	Vector3 vel;
   35.18 +	unsigned int life;
   35.19 +
   35.20 +	Particle(int life=0);
   35.21 +	Particle(const Vector3 &pos, int life=0);
   35.22 +	Particle(const Vector3 &pos, const Vector3 &vel, int life=0);
   35.23 +
   35.24 +	void Update(const Vector3 &forces, float friction=0);
   35.25 +};
   35.26 +
   35.27 +class ParticleSystem {
   35.28 +private:
   35.29 +	GraphicsContext *gc;
   35.30 +	bool FixedUpdateRate;
   35.31 +	float UpdateRate;
   35.32 +	float LastUpdate;
   35.33 +
   35.34 +	BlendingFactor SourceBlend, DestBlend;
   35.35 +
   35.36 +	Vector3 pos, prevpos;			// position of the emmiter (world space)
   35.37 +	Vector3 ShootDirection;			// an initial velocity vector for the particles
   35.38 +	std::list<Particle> particles;	// a list of particles
   35.39 +	Vertex pquad[4];				// the basic particle quad vertices
   35.40 +	Triangle ptris[2];				// the basic particle quad triangles
   35.41 +	float size;						// size of the particles
   35.42 +	float friction;					// friction impeding particle movement
   35.43 +	int SpawnRate;					// rate of particle generation
   35.44 +	float SpawnRadius;				// spawning radius around the emmiter
   35.45 +	float GravForce;				// Gravitual force
   35.46 +	float DispRads;
   35.47 +	int life;						// particle life
   35.48 +	bool EmmiterAffectsParticleTrajectory;	// ehm ... yeah
   35.49 +	float SpawnDiffDispersion;
   35.50 +	int SpawnRateChange;			// if 0 then spawn rate constant
   35.51 +
   35.52 +	float StartRed, StartGreen, StartBlue;
   35.53 +	float EndRed, EndGreen, EndBlue;
   35.54 +
   35.55 +	int VertsToRender, TrianglesToRender;
   35.56 +	int vbsize, ibsize, maxprimitives;
   35.57 +	Texture *texture;				// the particles' texture
   35.58 +	Object *obj;					// the particles' mesh object (if present don't render quads)
   35.59 +	Vertex *varray;					// secondary vertex array (ease of development)
   35.60 +	Triangle *tarray;				// the triangles
   35.61 +
   35.62 +	int VertexCount, IndexCount, TriCount, ParticleCount;
   35.63 +
   35.64 +public:
   35.65 +	Matrix4x4 Translation, OrbitRot;
   35.66 +
   35.67 +	ParticleSystem(GraphicsContext *gc);
   35.68 +	~ParticleSystem();
   35.69 +
   35.70 +	void SetGraphicsContext(GraphicsContext *gc);
   35.71 +	void SetParticleSize(float psize);
   35.72 +	void SetParticleLife(int life);
   35.73 +	void SetFriction(float friction);
   35.74 +	void SetSpawnRate(float spawnrate);
   35.75 +	void SetSpawnRadius(float radius);
   35.76 +	void SetTexture(Texture *texture);
   35.77 +	void SetObject(Object *obj);
   35.78 +	void SetPosition(const Vector3 &pos);
   35.79 +	void SetShootDirection(const Vector3 &dir);
   35.80 +	void SetGravitualForce(float grav);
   35.81 +	void SetEmmiterDependence(bool dep);
   35.82 +	void SetMaxDispersionAngle(float maxdisp);
   35.83 +	void SetInitialColor(float r, float g, float b);
   35.84 +	void SetDeathColor(float r, float g, float b);
   35.85 +	void SetBlendingMode(BlendingFactor src, BlendingFactor dest);
   35.86 +	void SetSpawningDifferenceDispersion(float val);
   35.87 +	void SetSpawnRateChange(int change);
   35.88 +
   35.89 +	void Translate(float x, float y, float z);
   35.90 +	void Rotate(float x, float y, float z);
   35.91 +	void Rotate(const Vector3 &axis, float angle);
   35.92 +	void ResetTranslation();
   35.93 +	void ResetRotation();	
   35.94 +
   35.95 +	int CountParticles();
   35.96 +			
   35.97 +	void Update(float t = 0.0f);
   35.98 +	void Render();
   35.99 +};
  35.100 +	
  35.101 +
  35.102 +#endif	// _PARTICLES_H_
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/src/3deng/sceneloader.cpp	Thu Oct 23 01:46:07 2014 +0300
    36.3 @@ -0,0 +1,923 @@
    36.4 +//#include <fstream>
    36.5 +#include <windows.h>
    36.6 +#include <string>
    36.7 +#include <cassert>
    36.8 +#include "sceneloader.h"
    36.9 +#include "3dschunks.h"
   36.10 +#include "typedefs.h"
   36.11 +
   36.12 +using std::ifstream;
   36.13 +using std::string;
   36.14 +
   36.15 +namespace SceneLoader {
   36.16 +    GraphicsContext *gc;
   36.17 +	dword ReadCounter;
   36.18 +	Material *mat;
   36.19 +	dword MatCount;
   36.20 +
   36.21 +	bool eof = false;
   36.22 +
   36.23 +	string datapath = "";
   36.24 +
   36.25 +	string SceneFileName;
   36.26 +	string ObjectName;
   36.27 +
   36.28 +	bool SaveNormalFile = false;
   36.29 +}
   36.30 +
   36.31 +using namespace SceneLoader;
   36.32 +
   36.33 +struct ChunkHeader {
   36.34 +	ChunkID id;
   36.35 +	dword size;
   36.36 +};
   36.37 +
   36.38 +struct Percent {
   36.39 +	int IntPercent;
   36.40 +	float FloatPercent;
   36.41 +
   36.42 +	Percent(int p = 0) {IntPercent = p; FloatPercent = (float)p / 100.0f; }
   36.43 +	Percent(float p) {FloatPercent = p; IntPercent = (int)(p * 100.0f); }
   36.44 +};
   36.45 +
   36.46 +struct TexMap {
   36.47 +	string filename;
   36.48 +	TextureType type;
   36.49 +	float intensity;
   36.50 +	float rotation;
   36.51 +	Vector2 offset;
   36.52 +	Vector2 scale;
   36.53 +};
   36.54 +
   36.55 +const dword HeaderSize = 6;
   36.56 +
   36.57 +enum {OBJ_MESH, OBJ_PTLIGHT, OBJ_SPLIGHT, OBJ_CAMERA, OBJ_CURVE};
   36.58 +
   36.59 +// local function prototypes
   36.60 +byte ReadByte(HANDLE file);
   36.61 +word ReadWord(HANDLE file);
   36.62 +dword ReadDword(HANDLE file);
   36.63 +float ReadFloat(HANDLE file);
   36.64 +Vector3 ReadVector(HANDLE file, bool FlipYZ = true);
   36.65 +string ReadString(HANDLE file);
   36.66 +Color ReadColor(HANDLE file);
   36.67 +Percent ReadPercent(HANDLE file);
   36.68 +ChunkHeader ReadChunkHeader(HANDLE file);
   36.69 +void SkipChunk(HANDLE file, const ChunkHeader &chunk);
   36.70 +void SkipBytes(HANDLE file, dword bytes);
   36.71 +
   36.72 +int ReadObject(HANDLE file, const ChunkHeader &ch, void **obj);
   36.73 +int ReadLight(HANDLE file, const ChunkHeader &ch, Light **lt);
   36.74 +Material ReadMaterial(HANDLE file, const ChunkHeader &ch);
   36.75 +TexMap ReadTextureMap(HANDLE file, const ChunkHeader &ch);
   36.76 +
   36.77 +Material *FindMaterial(string name);
   36.78 +
   36.79 +bool LoadNormalsFromFile(const char *fname, Scene *scene);
   36.80 +void SaveNormalsToFile(const char *fname, Scene *scene);
   36.81 +
   36.82 +
   36.83 +void SceneLoader::SetGraphicsContext(GraphicsContext *gfx) {
   36.84 +	gc = gfx;
   36.85 +}
   36.86 +
   36.87 +
   36.88 +void SceneLoader::SetDataPath(const char *path) {
   36.89 +	datapath = path;
   36.90 +}
   36.91 +
   36.92 +void SceneLoader::SetNormalFileSaving(bool enable) {
   36.93 +	SaveNormalFile = enable;
   36.94 +}
   36.95 +
   36.96 +
   36.97 +
   36.98 +////////////////////////////////////////
   36.99 +//   --==( function LoadScene )==--   //
  36.100 +// ---------------------------------- //
  36.101 +// Creates a Scene instance and loads //
  36.102 +// the data from specified file       //
  36.103 +////////////////////////////////////////
  36.104 +
  36.105 +bool SceneLoader::LoadScene(const char *fname, Scene **scene) {
  36.106 +	if(!gc) return false;
  36.107 +
  36.108 +	if(!LoadMaterials(fname, &mat)) return false;
  36.109 +
  36.110 +	//ifstream file(fname);
  36.111 +	//if(!file.is_open()) return false;
  36.112 +	HANDLE file = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
  36.113 +	assert(file != NULL);
  36.114 +	eof = false;
  36.115 +
  36.116 +	SceneFileName = string(fname);
  36.117 +
  36.118 +	ChunkHeader chunk;
  36.119 +	Scene *scn = new Scene(gc);		// new scene instance
  36.120 +	
  36.121 +	chunk = ReadChunkHeader(file);
  36.122 +	if(chunk.id != Chunk_3DSMain) {
  36.123 +		CloseHandle(file);
  36.124 +		return false;
  36.125 +	}
  36.126 +
  36.127 +	//while(!file.eof()) {
  36.128 +	while(!eof) {
  36.129 +
  36.130 +		chunk = ReadChunkHeader(file);
  36.131 +
  36.132 +		void *objptr;
  36.133 +		int type;
  36.134 +
  36.135 +		switch(chunk.id) {
  36.136 +		case Chunk_Main_3DEditor:
  36.137 +			break;	// dont skip
  36.138 +
  36.139 +		case Chunk_Edit_AmbientColor:
  36.140 +			scn->SetAmbientLight(ReadColor(file));
  36.141 +			break;
  36.142 +
  36.143 +		case Chunk_Edit_Fog:
  36.144 +			// **TODO** find out chunk structure
  36.145 +			break;
  36.146 +
  36.147 +		case Chunk_Edit_Object:
  36.148 +			type = ReadObject(file, chunk, &objptr);
  36.149 +			switch(type) {
  36.150 +			case OBJ_MESH:
  36.151 +				{
  36.152 +					Object *object = (Object*)objptr;
  36.153 +					scn->AddObject(object);
  36.154 +				}
  36.155 +				break;
  36.156 +
  36.157 +			case OBJ_CAMERA:
  36.158 +				{
  36.159 +					Camera *cam = (Camera*)objptr;
  36.160 +					scn->AddCamera(cam);
  36.161 +				}
  36.162 +				break;
  36.163 +
  36.164 +			case OBJ_PTLIGHT:
  36.165 +				{
  36.166 +					PointLight *lt = (PointLight*)objptr;
  36.167 +					scn->AddLight(lt);
  36.168 +				}
  36.169 +				break;
  36.170 +
  36.171 +			case OBJ_SPLIGHT:
  36.172 +				{
  36.173 +					SpotLight *lt = (SpotLight*)objptr;
  36.174 +					scn->AddLight(lt);
  36.175 +				}
  36.176 +				break;
  36.177 +
  36.178 +			case OBJ_CURVE:
  36.179 +				{
  36.180 +                    CatmullRomSpline *spline = (CatmullRomSpline*)objptr;
  36.181 +					scn->AddCurve(spline);
  36.182 +				}
  36.183 +				break;
  36.184 +			}
  36.185 +
  36.186 +			break;
  36.187 +
  36.188 +		default:
  36.189 +			SkipChunk(file, chunk);
  36.190 +		}
  36.191 +	}
  36.192 +
  36.193 +	CloseHandle(file);
  36.194 +	
  36.195 +
  36.196 +	// check if there is a normals file in the same dir and load them, or else calculate them
  36.197 +	if(!LoadNormalsFromFile((SceneFileName + string(".normals")).c_str(), scn)) {
  36.198 +		std::list<Object*>::iterator objiter = scn->GetObjectsList()->begin();
  36.199 +		while(objiter != scn->GetObjectsList()->end()) {
  36.200 +			(*objiter++)->GetTriMesh()->CalculateNormals();
  36.201 +		}
  36.202 +		if(SaveNormalFile) SaveNormalsToFile((SceneFileName + string(".normals")).c_str(), scn);
  36.203 +	}
  36.204 +
  36.205 +	*scene = scn;
  36.206 +    return true;
  36.207 +}
  36.208 +
  36.209 +
  36.210 +
  36.211 +bool SceneLoader::LoadObject(const char *fname, const char *ObjectName, Object **obj) {
  36.212 +	if(!gc) return false;
  36.213 +
  36.214 +	if(!LoadMaterials(fname, &mat)) return false;
  36.215 +
  36.216 +	//ifstream file(fname);
  36.217 +	//if(!file.is_open()) return false;
  36.218 +	HANDLE file = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
  36.219 +	assert(file != NULL);
  36.220 +	eof = false;
  36.221 +
  36.222 +	ChunkHeader chunk = ReadChunkHeader(file);
  36.223 +	if(chunk.id != Chunk_3DSMain) {
  36.224 +		CloseHandle(file);
  36.225 +		return false;
  36.226 +	}
  36.227 +
  36.228 +	while(!eof) {
  36.229 +
  36.230 +		chunk = ReadChunkHeader(file);
  36.231 +
  36.232 +		void *objptr;
  36.233 +		int type;
  36.234 +
  36.235 +		switch(chunk.id) {
  36.236 +		case Chunk_Main_3DEditor:
  36.237 +			break;	// dont skip
  36.238 +
  36.239 +		case Chunk_Edit_Object:
  36.240 +			type = ReadObject(file, chunk, &objptr);
  36.241 +			if(type == OBJ_MESH) {
  36.242 +				Object *object = (Object*)objptr;
  36.243 +				if(!strcmp(object->name.c_str(), ObjectName)) {
  36.244 +					object->GetTriMesh()->CalculateNormals();
  36.245 +					*obj = object;
  36.246 +					CloseHandle(file);
  36.247 +                    return true;
  36.248 +				}
  36.249 +			}
  36.250 +			break;
  36.251 +
  36.252 +		default:
  36.253 +			SkipChunk(file, chunk);
  36.254 +		}
  36.255 +	}
  36.256 +
  36.257 +	CloseHandle(file);
  36.258 +	return false;
  36.259 +}
  36.260 +
  36.261 +
  36.262 +
  36.263 +bool FindChunk(HANDLE file, word ChunkID) {
  36.264 +
  36.265 +	ChunkHeader chunk = ReadChunkHeader(file);
  36.266 +
  36.267 +	while(chunk.id != ChunkID) {
  36.268 +		SkipChunk(file, chunk);
  36.269 +		chunk = ReadChunkHeader(file);
  36.270 +	}
  36.271 +
  36.272 +	return chunk.id == ChunkID;
  36.273 +}
  36.274 +
  36.275 +
  36.276 +
  36.277 +bool SceneLoader::LoadMaterials(const char *fname, Material **materials) {
  36.278 +	if(!materials) return false;
  36.279 +
  36.280 +	//ifstream file(fname);
  36.281 +	//if(!file.is_open()) return false;
  36.282 +	HANDLE file = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
  36.283 +	assert(file != NULL);
  36.284 +	eof = false;
  36.285 +
  36.286 +	ChunkHeader chunk;
  36.287 +
  36.288 +	chunk = ReadChunkHeader(file);
  36.289 +	if(chunk.id != Chunk_3DSMain) {
  36.290 +		CloseHandle(file);
  36.291 +		return false;
  36.292 +	}
  36.293 +
  36.294 +	if(!FindChunk(file, Chunk_Main_3DEditor)) {
  36.295 +		CloseHandle(file);
  36.296 +		return false;
  36.297 +	}
  36.298 +
  36.299 +	std::vector<Material> mats;
  36.300 +	
  36.301 +	while(!eof) {
  36.302 +
  36.303 +		chunk = ReadChunkHeader(file);
  36.304 +
  36.305 +		if(chunk.id == Chunk_Edit_Material) {
  36.306 +            Material mat = ReadMaterial(file, chunk);
  36.307 +			mats.push_back(mat);
  36.308 +		} else {
  36.309 +			SkipChunk(file, chunk);
  36.310 +		}
  36.311 +	}
  36.312 +
  36.313 +	MatCount = (dword)mats.size();
  36.314 +
  36.315 +	if(*materials) delete [] *materials;
  36.316 +	Material *m = new Material[MatCount];
  36.317 +
  36.318 +	for(dword i=0; i<MatCount; i++) {
  36.319 +		m[i] = mats[i];
  36.320 +	}
  36.321 +
  36.322 +	*materials = m;
  36.323 +
  36.324 +	CloseHandle(file);
  36.325 +	return true;
  36.326 +}
  36.327 +
  36.328 +
  36.329 +TexMap ReadTextureMap(HANDLE file, const ChunkHeader &ch) {
  36.330 +	assert(ch.id == Chunk_Mat_TextureMap || ch.id == Chunk_Mat_TextureMap2 || ch.id == Chunk_Mat_OpacityMap || ch.id == Chunk_Mat_BumpMap || ch.id == Chunk_Mat_ReflectionMap || ch.id == Chunk_Mat_SelfIlluminationMap);
  36.331 +
  36.332 +	TexMap map;
  36.333 +	Percent p = ReadPercent(file);
  36.334 +	map.intensity = p.FloatPercent;	
  36.335 +
  36.336 +	switch(ch.id) {
  36.337 +	case Chunk_Mat_TextureMap:
  36.338 +		map.type = TextureMap;
  36.339 +		break;
  36.340 +
  36.341 +	case Chunk_Mat_TextureMap2:
  36.342 +		map.type = DetailMap;
  36.343 +		break;
  36.344 +
  36.345 +	case Chunk_Mat_OpacityMap:
  36.346 +		map.type = OpacityMap;
  36.347 +		break;
  36.348 +
  36.349 +	case Chunk_Mat_BumpMap:
  36.350 +		map.type = BumpMap;
  36.351 +		break;
  36.352 +
  36.353 +	case Chunk_Mat_ReflectionMap:
  36.354 +		map.type = EnvironmentMap;
  36.355 +		break;
  36.356 +
  36.357 +	case Chunk_Mat_SelfIlluminationMap:
  36.358 +		map.type = LightMap;
  36.359 +		break;
  36.360 +	default:
  36.361 +		assert(0);
  36.362 +	}
  36.363 +
  36.364 +	ChunkHeader chunk = ReadChunkHeader(file);
  36.365 +	assert(chunk.id == Chunk_Map_FileName);
  36.366 +
  36.367 +	map.filename = ReadString(file);
  36.368 +	return map;
  36.369 +}
  36.370 +
  36.371 +
  36.372 +
  36.373 +
  36.374 +
  36.375 +Material ReadMaterial(HANDLE file, const ChunkHeader &ch) {
  36.376 +
  36.377 +	Material mat;
  36.378 +
  36.379 +	assert(ch.id == Chunk_Edit_Material);
  36.380 +
  36.381 +	ReadCounter = HeaderSize;
  36.382 +	dword ChunkSize = ch.size;
  36.383 +
  36.384 +	while(ReadCounter < ChunkSize) {
  36.385 +		ChunkHeader chunk = ReadChunkHeader(file);
  36.386 +
  36.387 +		Percent p;
  36.388 +		TexMap map;
  36.389 +
  36.390 +		switch(chunk.id) {
  36.391 +		case Chunk_Mat_Name:
  36.392 +			mat.name = ReadString(file);
  36.393 +			break;
  36.394 +
  36.395 +		case Chunk_Mat_AmbientColor:
  36.396 +			mat.Ambient = ReadColor(file);
  36.397 +			break;
  36.398 +
  36.399 +		case Chunk_Mat_DiffuseColor:
  36.400 +			mat.Diffuse = ReadColor(file);
  36.401 +			break;
  36.402 +
  36.403 +		case Chunk_Mat_SpecularColor:
  36.404 +			mat.Specular = ReadColor(file);
  36.405 +			break;
  36.406 +
  36.407 +		case Chunk_Mat_Specular:
  36.408 +			p = ReadPercent(file);
  36.409 +			mat.Power = (float)p.IntPercent;
  36.410 +			if(mat.Power > 0.0f) mat.SpecularEnable = true;
  36.411 +			break;
  36.412 +
  36.413 +		case Chunk_Mat_SpecularIntensity:
  36.414 +			p = ReadPercent(file);
  36.415 +			mat.Specular.r *= p.FloatPercent;
  36.416 +			mat.Specular.g *= p.FloatPercent;
  36.417 +			mat.Specular.b *= p.FloatPercent;
  36.418 +			break;
  36.419 +
  36.420 +		case Chunk_Mat_Transparency:
  36.421 +			p = ReadPercent(file);
  36.422 +			mat.Alpha = 1.0f - p.FloatPercent;
  36.423 +			break;
  36.424 +
  36.425 +		case Chunk_Mat_SelfIllumination:
  36.426 +			p = ReadPercent(file);
  36.427 +			mat.Emissive = Color(p.FloatPercent);
  36.428 +			break;
  36.429 +
  36.430 +		case Chunk_Mat_TextureMap:
  36.431 +		case Chunk_Mat_TextureMap2:
  36.432 +		case Chunk_Mat_OpacityMap:
  36.433 +		case Chunk_Mat_SelfIlluminationMap:
  36.434 +			map = ReadTextureMap(file, chunk);
  36.435 +			mat.SetTexture(gc->texman->LoadTexture((datapath + map.filename).c_str()), map.type);
  36.436 +            break;
  36.437 +
  36.438 +		case Chunk_Mat_ReflectionMap:
  36.439 +			map = ReadTextureMap(file, chunk);
  36.440 +			mat.SetTexture(gc->texman->LoadTexture((datapath + map.filename).c_str()), map.type);
  36.441 +			mat.EnvBlend = map.intensity;
  36.442 +            break;
  36.443 +
  36.444 +		case Chunk_Mat_BumpMap:
  36.445 +			map = ReadTextureMap(file, chunk);
  36.446 +			mat.SetTexture(gc->texman->LoadTexture((datapath + map.filename).c_str()), map.type);
  36.447 +			mat.BumpIntensity = map.intensity;
  36.448 +            break;
  36.449 +
  36.450 +		default:
  36.451 +			SkipChunk(file, chunk);
  36.452 +		}
  36.453 +	}
  36.454 +
  36.455 +	return mat;
  36.456 +}            
  36.457 +
  36.458 +
  36.459 +
  36.460 +
  36.461 +
  36.462 +////////////////////////////////////////////////////
  36.463 +byte ReadByte(HANDLE file) {
  36.464 +	byte val;
  36.465 +	dword numread;
  36.466 +	ReadFile(file, &val, sizeof(byte), &numread, NULL);
  36.467 +	if(numread < sizeof(byte)) eof = true;
  36.468 +	ReadCounter++;
  36.469 +	return val;
  36.470 +}
  36.471 +
  36.472 +word ReadWord(HANDLE file) {
  36.473 +	word val;
  36.474 +	dword numread;
  36.475 +	ReadFile(file, &val, sizeof(word), &numread, NULL);
  36.476 +	if(numread < sizeof(word)) eof = true;
  36.477 +	ReadCounter += sizeof(word);
  36.478 +	return val;
  36.479 +}
  36.480 +
  36.481 +dword ReadDword(HANDLE file) {
  36.482 +	dword val;
  36.483 +	dword numread;
  36.484 +	ReadFile(file, &val, sizeof(dword), &numread, NULL);
  36.485 +	if(numread < sizeof(dword)) eof = true;
  36.486 +	ReadCounter += sizeof(dword);
  36.487 +	return val;
  36.488 +}
  36.489 +
  36.490 +float ReadFloat(HANDLE file) {
  36.491 +	float val;
  36.492 +	dword numread;
  36.493 +	ReadFile(file, &val, sizeof(float), &numread, NULL);
  36.494 +	if(numread < sizeof(float)) eof = true;
  36.495 +	ReadCounter += sizeof(float);
  36.496 +	return val;
  36.497 +}
  36.498 +/*
  36.499 +byte ReadByte(HANDLE file) {
  36.500 +	byte val;
  36.501 +	file.read((char*)&val, 1);
  36.502 +	ReadCounter++;
  36.503 +	return val;
  36.504 +}
  36.505 +
  36.506 +word ReadWord(HANDLE file) {
  36.507 +	word val;
  36.508 +	file.read((char*)&val, sizeof(word));
  36.509 +	ReadCounter += sizeof(word);
  36.510 +	return val;
  36.511 +}
  36.512 +
  36.513 +dword ReadDword(HANDLE file) {
  36.514 +	dword val;
  36.515 +	file.read((char*)&val, sizeof(dword));
  36.516 +	ReadCounter += sizeof(dword);
  36.517 +	return val;
  36.518 +}
  36.519 +
  36.520 +float ReadFloat(HANDLE file) {
  36.521 +	float val;
  36.522 +	file.read((char*)&val, sizeof(float));
  36.523 +	ReadCounter += sizeof(float);
  36.524 +	return val;
  36.525 +}
  36.526 +*/
  36.527 +Vector3 ReadVector(HANDLE file, bool FlipYZ) {
  36.528 +	Vector3 vector;
  36.529 +	vector.x = ReadFloat(file);
  36.530 +	if(!FlipYZ) vector.y = ReadFloat(file);
  36.531 +	vector.z = ReadFloat(file);
  36.532 +	if(FlipYZ) vector.y = ReadFloat(file);
  36.533 +	return vector;		
  36.534 +}
  36.535 +
  36.536 +string ReadString(HANDLE file) {
  36.537 +	string str;
  36.538 +	char c;
  36.539 +	while(c = (char)ReadByte(file)) {
  36.540 +		str.push_back(c);
  36.541 +	}
  36.542 +	str.push_back('\0');
  36.543 +	ReadCounter++;
  36.544 +
  36.545 +	return str;
  36.546 +}
  36.547 +/*
  36.548 +string ReadString(HANDLE file) {
  36.549 +	string str;
  36.550 +	char c;
  36.551 +	while(c = file.get()) {
  36.552 +		str.push_back(c);
  36.553 +		ReadCounter++;
  36.554 +	}
  36.555 +	str.push_back('\0');
  36.556 +	ReadCounter++;
  36.557 +
  36.558 +	return str;
  36.559 +}
  36.560 +*/
  36.561 +
  36.562 +Color ReadColor(HANDLE file) {
  36.563 +	ChunkHeader chunk = ReadChunkHeader(file);
  36.564 +	if(chunk.id < 0x0010 || chunk.id > 0x0013) return Color(-1.0f, -1.0f, -1.0f);
  36.565 +
  36.566 +	Color color;
  36.567 +
  36.568 +	if(chunk.id == Chunk_Color_Byte3 || chunk.id == Chunk_Color_GammaByte3) {
  36.569 +		byte r = ReadByte(file);
  36.570 +		byte g = ReadByte(file);
  36.571 +		byte b = ReadByte(file);
  36.572 +		color = Color(r, g, b);
  36.573 +	} else {
  36.574 +		color.r = ReadFloat(file);
  36.575 +		color.g = ReadFloat(file);
  36.576 +		color.b = ReadFloat(file);
  36.577 +	}
  36.578 +
  36.579 +	return color;
  36.580 +}
  36.581 +
  36.582 +Percent ReadPercent(HANDLE file) {
  36.583 +	ChunkHeader chunk = ReadChunkHeader(file);
  36.584 +	Percent p;
  36.585 +	if(chunk.id != Chunk_PercentInt && chunk.id != Chunk_PercentFloat) return p;
  36.586 +
  36.587 +	if(chunk.id == Chunk_PercentInt) {
  36.588 +		p = Percent(ReadWord(file));
  36.589 +	} else {
  36.590 +		p = Percent(ReadFloat(file));
  36.591 +	}
  36.592 +
  36.593 +	return p;
  36.594 +}
  36.595 +
  36.596 +
  36.597 +ChunkHeader ReadChunkHeader(HANDLE file) {
  36.598 +	ChunkHeader chunk;
  36.599 +	chunk.id = (ChunkID)ReadWord(file);
  36.600 +	chunk.size = ReadDword(file);
  36.601 +	return chunk;
  36.602 +}
  36.603 +
  36.604 +void SkipChunk(HANDLE file, const ChunkHeader &chunk) {
  36.605 +	//file.ignore(chunk.size - HeaderSize);
  36.606 +	SetFilePointer(file, chunk.size - HeaderSize, 0, FILE_CURRENT);
  36.607 +	ReadCounter += chunk.size - HeaderSize;
  36.608 +}
  36.609 +
  36.610 +void SkipBytes(HANDLE file, dword bytes) {
  36.611 +	SetFilePointer(file, bytes, 0, FILE_CURRENT);
  36.612 +	ReadCounter += bytes;
  36.613 +}
  36.614 +
  36.615 +Material *FindMaterial(string name) {
  36.616 +	dword i=0;
  36.617 +	while(i < MatCount) {
  36.618 +		if(mat[i].name == name) return &mat[i];
  36.619 +		i++;
  36.620 +	}
  36.621 +
  36.622 +	return 0;
  36.623 +}
  36.624 +
  36.625 +///////////////////// Read Object Function //////////////////////
  36.626 +int ReadObject(HANDLE file, const ChunkHeader &ch, void **obj) {
  36.627 +	if(!obj || !gc) return -1;
  36.628 +
  36.629 +	ReadCounter = HeaderSize;	// reset the global read counter
  36.630 +
  36.631 +	string name = ReadString(file);
  36.632 +
  36.633 +	ChunkHeader chunk;
  36.634 +	chunk = ReadChunkHeader(file);
  36.635 +	if(chunk.id == Chunk_Obj_TriMesh) {
  36.636 +		// object is a trimesh... load it
  36.637 +		Vertex *varray;
  36.638 +		Triangle *tarray;
  36.639 +		dword VertexCount=0, TriCount=0;
  36.640 +		Material mat;
  36.641 +		Base base;
  36.642 +		Vector3 translation;
  36.643 +
  36.644 +		bool curve = true;
  36.645 +
  36.646 +		dword ObjChunkSize = ch.size;
  36.647 +
  36.648 +		while(ReadCounter < ObjChunkSize) {	// make sure we only read subchunks of this object chunk
  36.649 +			//assert(!file.eof());
  36.650 +			assert(!eof);
  36.651 +			chunk = ReadChunkHeader(file);
  36.652 +
  36.653 +            switch(chunk.id) {
  36.654 +			case Chunk_TriMesh_VertexList:
  36.655 +				VertexCount = (dword)ReadWord(file);
  36.656 +				varray = new Vertex[VertexCount];
  36.657 +
  36.658 +				for(dword i=0; i<VertexCount; i++) {
  36.659 +					varray[i].pos = ReadVector(file);
  36.660 +				}
  36.661 +
  36.662 +				break;
  36.663 +
  36.664 +			case Chunk_TriMesh_FaceDesc:
  36.665 +				curve = false;	// it is a real object not a curve since it has triangles
  36.666 +				TriCount = (dword)ReadWord(file);
  36.667 +				tarray = new Triangle[TriCount];
  36.668 +
  36.669 +				for(dword i=0; i<TriCount; i++) {
  36.670 +					tarray[i].vertices[0] = (Index)ReadWord(file);	// 
  36.671 +					tarray[i].vertices[2] = (Index)ReadWord(file);	// flip order to CW
  36.672 +					tarray[i].vertices[1] = (Index)ReadWord(file);	//
  36.673 +					ReadWord(file);	// discard edge visibility flags
  36.674 +				}
  36.675 +				break;
  36.676 +
  36.677 +			case Chunk_Face_Material:
  36.678 +				mat = *FindMaterial(ReadString(file));
  36.679 +
  36.680 +				SkipBytes(file, ReadWord(file)<<1);
  36.681 +				break;
  36.682 +
  36.683 +			case Chunk_TriMesh_TexCoords:
  36.684 +				assert((dword)ReadWord(file) == VertexCount);
  36.685 +
  36.686 +				for(dword i=0; i<VertexCount; i++) {
  36.687 +					varray[i].tex[0].u = varray[i].tex[1].u = ReadFloat(file);
  36.688 +					varray[i].tex[0].v = varray[i].tex[1].v = -ReadFloat(file);
  36.689 +				}
  36.690 +				break;
  36.691 +
  36.692 +			case Chunk_TriMesh_SmoothingGroup:
  36.693 +				// **TODO** abide by smoothing groups duplicate vertices, weld others etc
  36.694 +				SkipChunk(file, chunk);
  36.695 +				break;
  36.696 +
  36.697 +			case Chunk_TriMesh_WorldTransform:
  36.698 +				base.i = ReadVector(file);
  36.699 +				base.k = ReadVector(file);	// flip
  36.700 +				base.j = ReadVector(file);
  36.701 +				translation = ReadVector(file);
  36.702 +				break;
  36.703 +
  36.704 +			default:
  36.705 +				SkipChunk(file, chunk);
  36.706 +			}
  36.707 +		}
  36.708 +
  36.709 +		if(curve) {
  36.710 +			CatmullRomSpline *spline = new CatmullRomSpline;
  36.711 +			spline->name = name;
  36.712 +			for(dword i=0; i<VertexCount; i++) {
  36.713 +				spline->AddControlPoint(varray[i].pos);
  36.714 +			}
  36.715 +
  36.716 +			*obj = spline;
  36.717 +			return OBJ_CURVE;
  36.718 +		} else {
  36.719 +
  36.720 +			base.i.Normalize();
  36.721 +			base.j.Normalize();
  36.722 +			base.k.Normalize();
  36.723 +			Matrix3x3 RotXForm = base.CreateRotationMatrix();
  36.724 +			RotXForm.OrthoNormalize();
  36.725 +			
  36.726 +			for(dword i=0; i<VertexCount; i++) {
  36.727 +				varray[i].pos.Translate(-translation.x, -translation.y, -translation.z);
  36.728 +				varray[i].pos.Transform(RotXForm.Transposed());
  36.729 +			}
  36.730 +
  36.731 +            Object *object = new Object(gc);
  36.732 +			object->name = name;
  36.733 +			object->GetTriMesh()->SetData(varray, tarray, VertexCount, TriCount);
  36.734 +			object->material = mat;
  36.735 +			object->SetRotation(RotXForm);
  36.736 +			object->SetTranslation(translation.x, translation.y, translation.z);
  36.737 +			*obj = object;
  36.738 +
  36.739 +			return OBJ_MESH;
  36.740 +		}
  36.741 +	} else {
  36.742 +
  36.743 +		if(chunk.id == Chunk_Obj_Light) {
  36.744 +
  36.745 +			dword ObjChunkSize = ch.size;
  36.746 +
  36.747 +			Vector3 pos = ReadVector(file);
  36.748 +			Color color = ReadColor(file);
  36.749 +
  36.750 +			Vector3 SpotTarget;
  36.751 +			float InnerCone, OuterCone;
  36.752 +			bool spot = false;
  36.753 +			bool att = false;
  36.754 +			bool CastShadows = false;
  36.755 +			float AttEnd = 10000.0f;
  36.756 +			float Intensity = 1.0f;
  36.757 +
  36.758 +			while(ReadCounter < ObjChunkSize) {
  36.759 +
  36.760 +				chunk = ReadChunkHeader(file);
  36.761 +
  36.762 +				switch(chunk.id) {
  36.763 +				case Chunk_Light_SpotLight:
  36.764 +					spot = true;
  36.765 +					SpotTarget = ReadVector(file);
  36.766 +					InnerCone = ReadFloat(file) / 180.0f;
  36.767 +					OuterCone = ReadFloat(file) / 180.0f;
  36.768 +					break;
  36.769 +
  36.770 +				case Chunk_Light_Attenuation:
  36.771 +					att = true;
  36.772 +					break;
  36.773 +				
  36.774 +				case Chunk_Light_AttenuationEnd:
  36.775 +					AttEnd = ReadFloat(file);
  36.776 +					break;
  36.777 +
  36.778 +				case Chunk_Light_Intensity:
  36.779 +					Intensity = ReadFloat(file);
  36.780 +					break;
  36.781 +
  36.782 +				case Chunk_Spot_CastShadows:
  36.783 +					CastShadows = true;
  36.784 +					break;
  36.785 +
  36.786 +				default:
  36.787 +					SkipChunk(file, chunk);
  36.788 +				}
  36.789 +			}
  36.790 +
  36.791 +			Light *light;
  36.792 +			if(spot) {
  36.793 +				light = new TargetSpotLight(pos, SpotTarget, InnerCone, OuterCone);
  36.794 +			} else {
  36.795 +				light = new PointLight(pos);
  36.796 +			}
  36.797 +			light->SetColor(color);			
  36.798 +			light->SetShadowCasting(CastShadows);
  36.799 +			light->SetIntensity(Intensity);
  36.800 +			light->name = name;
  36.801 +
  36.802 +			*obj = light;
  36.803 +			return spot ? OBJ_SPLIGHT : OBJ_PTLIGHT;
  36.804 +		}
  36.805 +
  36.806 +		if(chunk.id == Chunk_Obj_Camera) {
  36.807 +			Camera *cam = new Camera;
  36.808 +			Vector3 pos = ReadVector(file);
  36.809 +			Vector3 targ = ReadVector(file);
  36.810 +			float roll = ReadFloat(file);
  36.811 +			float FOV = ReadFloat(file);
  36.812 +
  36.813 +			Vector3 up = VECTOR3_J;
  36.814 +			Vector3 view = targ - pos;
  36.815 +			up.Rotate(view.Normalized(), roll);
  36.816 +
  36.817 +			cam->SetCamera(pos, targ, up);
  36.818 +			cam->name = name;
  36.819 +			cam->SetFOV(DEGTORAD(FOV) / 1.33333f);
  36.820 +
  36.821 +			*obj = cam;
  36.822 +			return OBJ_CAMERA;
  36.823 +		}
  36.824 +	}
  36.825 +
  36.826 +	return -1;  // should have already left by now, if not something is wrong
  36.827 +}
  36.828 +
  36.829 +
  36.830 +////////////////////////////////////////////////////////////////////////////////
  36.831 +// functions to save/load normals from file
  36.832 +
  36.833 +void WriteByte(HANDLE file, byte val) {
  36.834 +	dword junk;
  36.835 +	WriteFile(file, &val, sizeof(byte), &junk, 0);
  36.836 +}
  36.837 +
  36.838 +void WriteDword(HANDLE file, dword val) {
  36.839 +	dword junk;
  36.840 +	WriteFile(file, &val, sizeof(dword), &junk, 0);
  36.841 +	assert(junk == sizeof(dword));
  36.842 +}
  36.843 +
  36.844 +void WriteFloat(HANDLE file, float val) {
  36.845 +	dword junk;
  36.846 +	WriteFile(file, &val, sizeof(float), &junk, 0);
  36.847 +	assert(junk == sizeof(float));
  36.848 +}
  36.849 +
  36.850 +void WriteString(HANDLE file, string str) {
  36.851 +	dword junk;
  36.852 +	for(dword i=0; i<(dword)str.size(); i++) {
  36.853 +		WriteFile(file, &str[i], sizeof(char), &junk, 0);
  36.854 +	}
  36.855 +}
  36.856 +
  36.857 +
  36.858 +void SaveNormalsToFile(const char *fname, Scene *scene) {
  36.859 +
  36.860 +	HANDLE file = CreateFile(fname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  36.861 +	assert(file);
  36.862 +
  36.863 +	WriteDword(file, (dword)scene->GetObjectsList()->size());
  36.864 +
  36.865 +	std::list<Object*>::iterator objiter = scene->GetObjectsList()->begin();
  36.866 +	while(objiter != scene->GetObjectsList()->end()) {
  36.867 +		WriteString(file, (*objiter)->name);
  36.868 +		dword VertexCount = (*objiter)->GetTriMesh()->GetVertexCount();
  36.869 +		WriteDword(file, VertexCount);
  36.870 +
  36.871 +		const Vertex *varray = (*objiter)->GetTriMesh()->GetVertexArray();
  36.872 +		for(dword i=0; i<VertexCount; i++) {
  36.873 +			WriteFloat(file, varray[i].normal.x);
  36.874 +			WriteFloat(file, varray[i].normal.y);
  36.875 +			WriteFloat(file, varray[i].normal.z);
  36.876 +		}
  36.877 +
  36.878 +		objiter++;
  36.879 +	}
  36.880 +
  36.881 +	CloseHandle(file);
  36.882 +}
  36.883 +
  36.884 +bool LoadNormalsFromFile(const char *fname, Scene *scene) {
  36.885 +
  36.886 +	HANDLE file = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
  36.887 +	if(!file) return false;
  36.888 +
  36.889 +	eof = false;
  36.890 +	ReadCounter = 0;
  36.891 +
  36.892 +	dword FileSize = SetFilePointer(file, 0, 0, FILE_END) - SetFilePointer(file, 0, 0, FILE_BEGIN);
  36.893 +
  36.894 +	SetFilePointer(file, 0, 0, FILE_BEGIN);
  36.895 +
  36.896 +	dword ObjectCount = ReadDword(file);
  36.897 +	if(ObjectCount != scene->GetObjectsList()->size()) {	// detect changes
  36.898 +		CloseHandle(file);
  36.899 +		return false;
  36.900 +	}
  36.901 +    
  36.902 +	while(SceneLoader::ReadCounter < FileSize) {
  36.903 +		string name = ReadString(file);
  36.904 +		dword VertexCount = ReadDword(file);
  36.905 +		
  36.906 +		Object *obj = scene->GetObject(name.c_str());
  36.907 +		if(!obj) {
  36.908 +			CloseHandle(file);
  36.909 +			return false;
  36.910 +		}
  36.911 +
  36.912 +		if(VertexCount != obj->GetTriMesh()->GetVertexCount()) {	// again detect changes
  36.913 +			CloseHandle(file);
  36.914 +			return false;
  36.915 +		}
  36.916 +        
  36.917 +		Vertex *varray = obj->GetTriMesh()->GetModVertexArray();
  36.918 +		for(dword i=0; i<VertexCount; i++) {
  36.919 +			varray[i].normal = ReadVector(file, false);
  36.920 +		}
  36.921 +	}
  36.922 +
  36.923 +	CloseHandle(file);
  36.924 +	return true;
  36.925 +}
  36.926 +
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/src/3deng/switches.h	Thu Oct 23 01:46:07 2014 +0300
    37.3 @@ -0,0 +1,10 @@
    37.4 +#ifndef _SWITCHES_H_
    37.5 +#define _SWITCHES_H_
    37.6 +
    37.7 +#define ENGINE_VER_DIRECT3D
    37.8 +
    37.9 +#pragma conform(forScope, on)
   37.10 +#pragma warning(disable:4258)	// dissable conformance warning about for loop variable scope
   37.11 +#pragma warning(disable:4800)	// dissable force value to bool perf. warning
   37.12 +
   37.13 +#endif	// _SWITCHES_H_
   37.14 \ No newline at end of file
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/src/3deng/textureman.cpp	Thu Oct 23 01:46:07 2014 +0300
    38.3 @@ -0,0 +1,199 @@
    38.4 +#include "textureman.h"
    38.5 +#include "3dengine.h"
    38.6 +#include "d3dx8.h"
    38.7 +
    38.8 +using std::string;
    38.9 +
   38.10 +template <class KeyType>
   38.11 +unsigned int Hash(const KeyType &key, unsigned long size) {
   38.12 +	string str = (string)key;
   38.13 +	return ((unsigned int)str[0] + (unsigned int)str[1] + (unsigned int)str[2]) % size;
   38.14 +}
   38.15 +
   38.16 +TextureManager::TextureManager(GraphicsContext *gc) {
   38.17 +	this->gc = gc;
   38.18 +	notfilecount = 0;
   38.19 +
   38.20 +	textures.SetHashFunction(Hash);
   38.21 +
   38.22 +	CreateStockTextures();
   38.23 +}
   38.24 +
   38.25 +TextureManager::~TextureManager() {}
   38.26 +
   38.27 +#define STOCKSIZE	256
   38.28 +#include <cassert>
   38.29 +
   38.30 +void TextureManager::CreateStockTextures() {
   38.31 +	Surface *surf;
   38.32 +
   38.33 +	// ----- 1/d^2 blob texture -----
   38.34 +	Texture *tmp = CreateTexture(STOCKSIZE, STOCKSIZE, 0, true, true);
   38.35 +	tmp->GetSurfaceLevel(0, &surf);
   38.36 +	
   38.37 +	dword *ptr, offs;
   38.38 +	D3DLOCKED_RECT d3dlock;
   38.39 +	assert(surf->LockRect(&d3dlock, 0, 0) == D3D_OK);
   38.40 +	ptr = (dword*)d3dlock.pBits;
   38.41 +	offs = (d3dlock.Pitch >> 2) - STOCKSIZE;
   38.42 +
   38.43 +	Vector2 Center((float)(STOCKSIZE>>1), (float)(STOCKSIZE>>1));
   38.44 +
   38.45 +	for(int y=0; y<STOCKSIZE; y++) {
   38.46 +		for(int x=0; x<STOCKSIZE; x++) {
   38.47 +			Vector2 pos((float)x, (float)y);
   38.48 +			float p = 100.0f / (pos - Center).LengthSq();
   38.49 +
   38.50 +			Color col(p, p, p, p);
   38.51 +			*ptr++ = col.GetPacked32();
   38.52 +		}
   38.53 +		ptr += offs;
   38.54 +	}
   38.55 +
   38.56 +	surf->UnlockRect();
   38.57 +
   38.58 +	Texture *Blob = CreateTexture(STOCKSIZE, STOCKSIZE, 0, true);
   38.59 +	gc->D3DDevice->UpdateTexture(tmp, Blob);
   38.60 +
   38.61 +	UpdateMipmapChain(Blob);
   38.62 +
   38.63 +	AddTexture(Blob, "STOCKTEX_BLOB");
   38.64 +	tmp->Release();
   38.65 +
   38.66 +	// ----- chessboard texture -----
   38.67 +
   38.68 +	tmp = CreateTexture(STOCKSIZE, STOCKSIZE, 0, true, true);
   38.69 +	tmp->GetSurfaceLevel(0, &surf);
   38.70 +	
   38.71 +	assert(surf->LockRect(&d3dlock, 0, 0) == D3D_OK);
   38.72 +	ptr = (dword*)d3dlock.pBits;
   38.73 +	offs = (d3dlock.Pitch >> 2) - STOCKSIZE;
   38.74 +
   38.75 +	for(int y=0; y<STOCKSIZE; y++) {
   38.76 +		for(int x=0; x<STOCKSIZE; x++) {
   38.77 +			int dx = x - (STOCKSIZE>>1);
   38.78 +			int dy = y - (STOCKSIZE>>1);
   38.79 +			if((dx > 0 && dy > 0) || (dx < 0 && dy < 0)) {
   38.80 +				*ptr++ = 0xffffffff;
   38.81 +			} else {
   38.82 +				*ptr++ = 0xff000000;
   38.83 +			}
   38.84 +		}
   38.85 +		ptr += offs;
   38.86 +	}
   38.87 +
   38.88 +	surf->UnlockRect();
   38.89 +
   38.90 +	Texture *ChessBoard = CreateTexture(STOCKSIZE, STOCKSIZE, 0, true);
   38.91 +	gc->D3DDevice->UpdateTexture(tmp, ChessBoard);
   38.92 +
   38.93 +	UpdateMipmapChain(ChessBoard);
   38.94 +
   38.95 +	AddTexture(ChessBoard, "STOCKTEX_CHESSBOARD");
   38.96 +	tmp->Release();
   38.97 +
   38.98 +	// ----- grid texture -----
   38.99 +
  38.100 +	tmp = CreateTexture(STOCKSIZE, STOCKSIZE, 0, true, true);
  38.101 +	tmp->GetSurfaceLevel(0, &surf);
  38.102 +	
  38.103 +	assert(surf->LockRect(&d3dlock, 0, 0) == D3D_OK);
  38.104 +	ptr = (dword*)d3dlock.pBits;
  38.105 +	offs = (d3dlock.Pitch >> 2) - STOCKSIZE;
  38.106 +
  38.107 +	for(int y=0; y<STOCKSIZE; y++) {
  38.108 +		for(int x=0; x<STOCKSIZE; x++) {
  38.109 +			if(x == 0 || x == STOCKSIZE-1 || y == 0 || y == STOCKSIZE-1) {
  38.110 +				*ptr++ = 0xffffffff;
  38.111 +			} else {
  38.112 +				*ptr++ = 0xff000000;
  38.113 +			}
  38.114 +		}
  38.115 +		ptr += offs;
  38.116 +	}
  38.117 +
  38.118 +	surf->UnlockRect();
  38.119 +
  38.120 +	Texture *Grid = CreateTexture(STOCKSIZE, STOCKSIZE, 0, true);
  38.121 +	gc->D3DDevice->UpdateTexture(tmp, Grid);
  38.122 +
  38.123 +	UpdateMipmapChain(Grid);
  38.124 +
  38.125 +	AddTexture(Grid, "STOCKTEX_GRID");
  38.126 +	tmp->Release();
  38.127 +
  38.128 +
  38.129 +	// ---------- biased linear falloff ---------
  38.130 +	tmp = CreateTexture(STOCKSIZE, STOCKSIZE, 0, true, true);
  38.131 +	tmp->GetSurfaceLevel(0, &surf);
  38.132 +	
  38.133 +	assert(surf->LockRect(&d3dlock, 0, 0) == D3D_OK);
  38.134 +	ptr = (dword*)d3dlock.pBits;
  38.135 +	offs = (d3dlock.Pitch >> 2) - STOCKSIZE;
  38.136 +
  38.137 +	Center = Vector2((float)(STOCKSIZE>>1), (float)(STOCKSIZE>>1));
  38.138 +
  38.139 +	for(int y=0; y<STOCKSIZE; y++) {
  38.140 +		for(int x=0; x<STOCKSIZE; x++) {
  38.141 +			Vector2 pos((float)x, (float)y);
  38.142 +			float dist = (pos - Center).Length();
  38.143 +			// f[x] / ((1/b - 2) * (1 - f[x]) + 1)
  38.144 +			float b = 0.3f;
  38.145 +			float p = dist ? ((STOCKSIZE - dist) / STOCKSIZE) / ((1/b-2) * (1-((STOCKSIZE - dist) / STOCKSIZE)) + 1) : 1.0f;
  38.146 +			
  38.147 +			Color col(p, p, p, p);
  38.148 +			*ptr++ = col.GetPacked32();
  38.149 +		}
  38.150 +		ptr += offs;
  38.151 +	}
  38.152 +
  38.153 +	surf->UnlockRect();
  38.154 +
  38.155 +	Texture *Blofm = CreateTexture(STOCKSIZE, STOCKSIZE, 0, true);
  38.156 +	gc->D3DDevice->UpdateTexture(tmp, Blofm);
  38.157 +
  38.158 +	UpdateMipmapChain(Blofm);
  38.159 +
  38.160 +	AddTexture(Blofm, "STOCKTEX_BLOFM");
  38.161 +	tmp->Release();
  38.162 +}
  38.163 +
  38.164 +void TextureManager::SetGraphicsContext(GraphicsContext *gc) {
  38.165 +	this->gc = gc;
  38.166 +}
  38.167 +
  38.168 +Texture *TextureManager::LoadTexture(const char *fname) {
  38.169 +	if(!gc || !fname) return 0;
  38.170 +
  38.171 +	Texture *tex;
  38.172 +
  38.173 +	Pair<string, Texture*> *p;
  38.174 +	if(!(p = textures.Find(fname))) {
  38.175 +        if(D3DXCreateTextureFromFile(gc->D3DDevice, fname, &tex) != D3D_OK) return 0;
  38.176 +		textures.Insert(fname, tex);
  38.177 +	} else {
  38.178 +		tex = p->val;
  38.179 +	}
  38.180 +
  38.181 +	return tex;
  38.182 +}
  38.183 +
  38.184 +Texture *TextureManager::CreateTexture(dword x, dword y, dword usage, bool mipmaps, bool local) {
  38.185 +	if(!gc) return 0;
  38.186 +	Texture *tex;
  38.187 +	D3DPOOL pool = local ? D3DPOOL_SYSTEMMEM : D3DPOOL_DEFAULT;
  38.188 +	D3DFORMAT fmt = usage == UsageDepthStencil ? gc->ZFormat : D3DFMT_A8R8G8B8;
  38.189 +	if(usage == UsageDepthStencil) pool = D3DPOOL_MANAGED;
  38.190 +	if(gc->D3DDevice->CreateTexture(x, y, (int)(!mipmaps), usage, fmt, pool, &tex) != D3D_OK) return 0;
  38.191 +	return tex;
  38.192 +}
  38.193 +
  38.194 +Texture *TextureManager::AddTexture(Texture *tex, const char *name) {
  38.195 +	string fname = name ? name : "not_a_file_" + notfilecount;
  38.196 +	textures.Insert(fname, tex);
  38.197 +	return tex;
  38.198 +}
  38.199 +
  38.200 +Texture *TextureManager::AddTexture(const char *fname) {
  38.201 +	return LoadTexture(fname);
  38.202 +}
  38.203 \ No newline at end of file
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/src/3deng/textureman.h	Thu Oct 23 01:46:07 2014 +0300
    39.3 @@ -0,0 +1,39 @@
    39.4 +#ifndef _TEXTUREMAN_H_
    39.5 +#define _TEXTUREMAN_H_
    39.6 +
    39.7 +#include <string>
    39.8 +#include "hashtable.h"
    39.9 +#include "typedefs.h"
   39.10 +#include "d3d8.h"
   39.11 +#include "3dengtypes.h"
   39.12 +
   39.13 +class GraphicsContext;
   39.14 +
   39.15 +const dword UsageRenderTarget	= D3DUSAGE_RENDERTARGET;
   39.16 +const dword UsageDepthStencil	= D3DUSAGE_DEPTHSTENCIL;
   39.17 +
   39.18 +class TextureManager {
   39.19 +private:
   39.20 +	GraphicsContext *gc;
   39.21 +	HashTable<std::string, Texture*> textures;
   39.22 +	int notfilecount;
   39.23 +
   39.24 +	// private copy constructor and assignment op, to prohibit copying
   39.25 +	TextureManager(const TextureManager &tm) {}
   39.26 +	void operator =(const TextureManager &tm) {}
   39.27 +
   39.28 +	void CreateStockTextures();
   39.29 +
   39.30 +public:
   39.31 +	TextureManager(GraphicsContext *gc = 0);
   39.32 +	~TextureManager();
   39.33 +
   39.34 +	void SetGraphicsContext(GraphicsContext *gc);
   39.35 +
   39.36 +	Texture *LoadTexture(const char *fname);
   39.37 +	Texture *CreateTexture(dword x, dword y, dword usage, bool mipmaps, bool local=false);
   39.38 +	Texture *AddTexture(Texture *tex, const char *name=0);
   39.39 +	Texture *AddTexture(const char *fname);
   39.40 +};
   39.41 +
   39.42 +#endif	// _TEXTUREMAN_H_
   39.43 \ No newline at end of file
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/src/beginpart.cpp	Thu Oct 23 01:46:07 2014 +0300
    40.3 @@ -0,0 +1,135 @@
    40.4 +#include "beginpart.h"
    40.5 +
    40.6 +BeginPart::BeginPart(GraphicsContext *gc) {
    40.7 +	this->gc = gc;
    40.8 +
    40.9 +	this->gc = gc;
   40.10 +
   40.11 +	SceneLoader::SetNormalFileSaving(true);
   40.12 +	SceneLoader::SetDataPath("data/textures/");
   40.13 +	SceneLoader::LoadScene("data/geometry/begin.3ds", &scene);
   40.14 +
   40.15 +	light = new DirLight(Vector3(0.0f, 0.0f, 1.0f));
   40.16 +	light->SetIntensity(1.5f);
   40.17 +	scene->AddLight(light);
   40.18 +
   40.19 +	// get stuff
   40.20 +	Logo1 = scene->GetObject("LogoT");
   40.21 +	scene->RemoveObject(Logo1);
   40.22 +
   40.23 +	Logo2 = scene->GetObject("LogoB");
   40.24 +	scene->RemoveObject(Logo2);
   40.25 +
   40.26 +	VolumeLogo = scene->GetObject("VolumeLogo");
   40.27 +	scene->RemoveObject(VolumeLogo);
   40.28 +	
   40.29 +	Latin1 = scene->GetObject("Latin1");	
   40.30 +	Latin2 = scene->GetObject("Latin2");	
   40.31 +	Lines[0] = scene->GetObject("Lines1");
   40.32 +	Lines[1] = scene->GetObject("Lines2");
   40.33 +	TheLabText[0] = scene->GetObject("LabText1");
   40.34 +	TheLabText[1] = scene->GetObject("LabText2");
   40.35 +
   40.36 +	scene->RemoveObject(scene->GetObject("Plane01"));
   40.37 +
   40.38 +	gc->SetTextureTransformState(0, TexTransform2D);
   40.39 +}
   40.40 +
   40.41 +BeginPart::~BeginPart() {
   40.42 +	delete scene;
   40.43 +}
   40.44 +
   40.45 +#define psin(x) (sinf(x) / 2.0f + 0.5f)
   40.46 +#define pcos(x) (cosf(x) / 2.0f + 0.5f)
   40.47 +
   40.48 +void BeginPart::MainLoop() {
   40.49 +	dword msec = timer.GetMilliSec();
   40.50 +	float t = (float)msec / 1000.0f;
   40.51 +
   40.52 +	const float StartCycle = 2.5f;
   40.53 +	const float EndCycle = 5.0f;
   40.54 +	const float StartFade = 9.0f;
   40.55 +
   40.56 +
   40.57 +	Latin1->SetTextureMatrix(Matrix3x3(1,0,0, 0,1,0, 0,t/4,1));
   40.58 +	Latin2->SetTextureMatrix(Matrix3x3(1,0,0, 0,1,0, 0,t/2,1));
   40.59 +	Lines[0]->SetTextureMatrix(Matrix3x3(1,0,0, 0,1,0, t*2.0f,0,1));
   40.60 +	Lines[1]->SetTextureMatrix(Matrix3x3(1,0,0, 0,1,0, t/2.0f,0,1));
   40.61 +	TheLabText[0]->SetTextureMatrix(Matrix3x3(1,0,0, 0,1,0, t,0,1));
   40.62 +	TheLabText[1]->SetTextureMatrix(Matrix3x3(1,0,0, 0,1,0, t/3,0,1));
   40.63 +
   40.64 +	gc->Clear(0);
   40.65 +	gc->ClearZBufferStencil(1.0f, 0);
   40.66 +
   40.67 +	gc->SetZBuffering(false);
   40.68 +
   40.69 +	scene->Render();
   40.70 +
   40.71 +	gc->SetAlphaBlending(true);
   40.72 +	gc->SetTextureStageColor(0, TexBlendModulate, TexArgCurrent, TexArgTexture);
   40.73 +	gc->SetTextureStageAlpha(0, TexBlendModulate, TexArgCurrent, TexArgTexture);
   40.74 +	gc->SetBlendFunc(BLEND_ONE, BLEND_ONE);
   40.75 +
   40.76 +	Matrix3x3 TexMat;
   40.77 +	
   40.78 +	// render shit
   40.79 +	Logo1->SetTranslation(0.0f, max(0.8f - t, 0) * 50.0f, 0.0f);
   40.80 +	Logo2->SetTranslation(0.0f, -max(0.8f - t, 0) * 50.0f, 0.0f);
   40.81 +	
   40.82 +	if(t > StartCycle) {
   40.83 +        Logo1->material.Diffuse.r += (t-StartCycle) * 0.005f;
   40.84 +		Logo1->material.Diffuse.g -= (t-StartCycle) * 0.005f;
   40.85 +		Logo1->material.Diffuse.b -= (t-StartCycle) * 0.005f;
   40.86 +		if(Logo1->material.Diffuse.r > 0.5f) Logo1->material.Diffuse.r = 0.5f;
   40.87 +		if(Logo1->material.Diffuse.g < 0.0f) Logo1->material.Diffuse.g = 0.0f;
   40.88 +		if(Logo1->material.Diffuse.b < 0.0f) Logo1->material.Diffuse.b = 0.0f;
   40.89 +
   40.90 +		Logo2->material.Diffuse.r += (t-StartCycle) * 0.005f;
   40.91 +		Logo2->material.Diffuse.g -= (t-StartCycle) * 0.005f;
   40.92 +		Logo2->material.Diffuse.b -= (t-StartCycle) * 0.005f;
   40.93 +		if(Logo2->material.Diffuse.r > 0.5f) Logo2->material.Diffuse.r = 0.5f;
   40.94 +		if(Logo2->material.Diffuse.g < 0.0f) Logo2->material.Diffuse.g = 0.0f;
   40.95 +		if(Logo2->material.Diffuse.b < 0.0f) Logo2->material.Diffuse.b = 0.0f;
   40.96 +	}
   40.97 +	
   40.98 +	gc->SetMaterial(Logo1->material);
   40.99 +	gc->SetTexture(0, Logo1->material.Maps[TextureMap]);
  40.100 +	
  40.101 +	gc->SetWorldMatrix(Logo1->GetWorldTransform());
  40.102 +	Logo1->RenderBare();
  40.103 +
  40.104 +	gc->SetWorldMatrix(Logo2->GetWorldTransform());
  40.105 +	Logo2->RenderBare();
  40.106 +
  40.107 +	if(t > EndCycle) {
  40.108 +		Color color(Logo1->material.Diffuse.r, Logo1->material.Diffuse.g, Logo1->material.Diffuse.b);
  40.109 +		VolumeLogo->material.SetDiffuse(color);
  40.110 +		gc->SetTexture(0, VolumeLogo->material.Maps[TextureMap]);
  40.111 +		
  40.112 +		float xoffs = sinf(t/2.0f) * 4.0f;
  40.113 +		float yoffs = sinf(t) * 1.5f;//-(t - 2.0f*EndCycle);
  40.114 +		for(int i=0; i<min(10, (int)((t-EndCycle)*30.0f)); i++) {
  40.115 +			Matrix4x4 mat;
  40.116 +			mat.SetTranslation(xoffs * ((float)i * 0.5f), yoffs * ((float)i * 0.5f), 0.0f);
  40.117 +
  40.118 +			float ScaleFactor = 1.0f + (float)i * 0.2f;
  40.119 +			Matrix4x4 ScaleMat;
  40.120 +			ScaleMat.SetScaling(ScaleFactor, ScaleFactor, ScaleFactor);
  40.121 +
  40.122 +			VolumeLogo->material.Diffuse.r -= 0.08f;
  40.123 +			VolumeLogo->material.Diffuse.g -= 0.08f;
  40.124 +			VolumeLogo->material.Diffuse.b -= 0.08f;
  40.125 +
  40.126 +			gc->SetWorldMatrix(VolumeLogo->GetWorldTransform() * mat * ScaleMat);
  40.127 +			VolumeLogo->RenderBare();
  40.128 +		}
  40.129 +	}
  40.130 +
  40.131 +	Material OrigMat = VolumeLogo->material;
  40.132 +	VolumeLogo->material = Material(0.0f, 0.0f, 0.0f, max((t - StartFade) / 2.0f, 0.0f));
  40.133 +	VolumeLogo->Render();
  40.134 +	VolumeLogo->material = OrigMat;
  40.135 +
  40.136 +	gc->SetZBuffering(true);
  40.137 +	gc->SetAlphaBlending(false);
  40.138 +}
  40.139 \ No newline at end of file
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/src/beginpart.h	Thu Oct 23 01:46:07 2014 +0300
    41.3 @@ -0,0 +1,23 @@
    41.4 +#ifndef _BEGINPART_H_
    41.5 +#define _BEGINPART_H_
    41.6 +
    41.7 +#include "demosystem/demosys.h"
    41.8 +
    41.9 +class BeginPart : public Part {
   41.10 +private:
   41.11 +    //Scene *scene;
   41.12 +
   41.13 +	Object *Logo1, *Logo2, *Latin1, *Latin2, *Lines[2], *TheLabText[2], *VolumeLogo;
   41.14 +	DirLight *light;
   41.15 +	Camera *cam;
   41.16 +
   41.17 +public:
   41.18 +
   41.19 +	BeginPart(GraphicsContext *gc);
   41.20 +	~BeginPart();
   41.21 +
   41.22 +	void MainLoop();
   41.23 +};
   41.24 +
   41.25 +
   41.26 +#endif	// _BEGINPART_H_
   41.27 \ No newline at end of file
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/src/common/color.cpp	Thu Oct 23 01:46:07 2014 +0300
    42.3 @@ -0,0 +1,125 @@
    42.4 +#include <cmath>
    42.5 +#include "color.h"
    42.6 +
    42.7 +template <class T>
    42.8 +const T &clamp(const T &val, const T &low, const T &high) {
    42.9 +	if(val > high) return high;
   42.10 +	if(val < low) return low;
   42.11 +	return val;
   42.12 +}
   42.13 +
   42.14 +Color::Color(float_t intensity) {
   42.15 +	r = g = b = clamp<float_t>(intensity, 0.0f, 1.0f);
   42.16 +	a = 1.0f;
   42.17 +}
   42.18 +
   42.19 +Color::Color(float_t r, float_t g, float_t b, float_t a) {
   42.20 +	this->r = clamp<float_t>(r, 0.0f, 1.0f);
   42.21 +	this->g = clamp<float_t>(g, 0.0f, 1.0f);
   42.22 +	this->b = clamp<float_t>(b, 0.0f, 1.0f);
   42.23 +	this->a = clamp<float_t>(a, 0.0f, 1.0f);
   42.24 +}
   42.25 +
   42.26 +Color::Color(unsigned int r, unsigned int g, unsigned int b, unsigned int a) {
   42.27 +	this->r = (float_t)clamp<unsigned int>(r, 0, 255) / 255.0f;
   42.28 +	this->g = (float_t)clamp<unsigned int>(g, 0, 255) / 255.0f;
   42.29 +	this->b = (float_t)clamp<unsigned int>(b, 0, 255) / 255.0f;
   42.30 +	this->a = (float_t)clamp<unsigned int>(a, 0, 255) / 255.0f;
   42.31 +}
   42.32 +
   42.33 +Color::Color(int r, int g, int b, int a) {
   42.34 +	this->r = (float_t)clamp<int>(r, 0, 255) / 255.0f;
   42.35 +	this->g = (float_t)clamp<int>(g, 0, 255) / 255.0f;
   42.36 +	this->b = (float_t)clamp<int>(b, 0, 255) / 255.0f;
   42.37 +	this->a = (float_t)clamp<int>(a, 0, 255) / 255.0f;
   42.38 +}
   42.39 +
   42.40 +Color::Color(long pcol) {
   42.41 +	a = (float_t)(((dword)pcol >> 24) & 0xff) / 255.0f;
   42.42 +	r = (float_t)(((dword)pcol >> 16) & 0xff) / 255.0f;
   42.43 +	g = (float_t)(((dword)pcol >> 8) & 0xff) / 255.0f;
   42.44 +	b = (float_t)((dword)pcol & 0xff) / 255.0f;
   42.45 +}
   42.46 +
   42.47 +Color::Color(dword pcol) {
   42.48 +	a = (float_t)((pcol >> 24) & 0xff) / 255.0f;
   42.49 +	r = (float_t)((pcol >> 16) & 0xff) / 255.0f;
   42.50 +	g = (float_t)((pcol >> 8) & 0xff) / 255.0f;
   42.51 +	b = (float_t)(pcol & 0xff) / 255.0f;
   42.52 +}
   42.53 +
   42.54 +dword Color::GetPacked32() const {
   42.55 +	return	(((dword)(a * 255.0f) << 24) & 0xff000000) | 
   42.56 +			(((dword)(r * 255.0f) << 16) & 0x00ff0000) | 
   42.57 +			(((dword)(g * 255.0f) << 8) & 0x0000ff00) | 
   42.58 +			((dword)(b * 255.0f) & 0x000000ff);
   42.59 +}
   42.60 +
   42.61 +word Color::GetPacked16() const {
   42.62 +	return (word)(r * 32.0f) << 11 | (word)(g * 64.0f) << 5 | (word)(b * 32.0f);
   42.63 +}
   42.64 +
   42.65 +word Color::GetPacked15() const {
   42.66 +	return (word)a << 15 | (word)(r * 32.0f) << 10 | (word)(g * 32.0f) << 5 | (word)(b * 32.0f);
   42.67 +}
   42.68 +
   42.69 +#ifndef HalfPi
   42.70 +const float_t HalfPi = 1.5707963268f;
   42.71 +#endif	// HalfPi
   42.72 +
   42.73 +byte Color::GetNearest8(const byte **pal) const {
   42.74 +	float_t Score[256];
   42.75 +	for(int i=0; i<256; i++) {
   42.76 +		Color palcol = Color(pal[i][0], pal[i][1], pal[i][2]);
   42.77 +		float_t NearR = (float_t)cos(fabs(r - palcol.r) * HalfPi);
   42.78 +		float_t NearG = (float_t)cos(fabs(g - palcol.g) * HalfPi);
   42.79 +		float_t NearB = (float_t)cos(fabs(b - palcol.b) * HalfPi);
   42.80 +		Score[i] = NearR + NearG + NearB;
   42.81 +	}
   42.82 +
   42.83 +	int nearest = 0;
   42.84 +	for(int i=0; i<256; i++) {
   42.85 +		if(Score[i] > Score[nearest]) nearest = i;
   42.86 +	}
   42.87 +	return nearest;
   42.88 +}
   42.89 +
   42.90 +Color Color::operator +(const Color &col) const {
   42.91 +	return Color(r + col.r, g + col.g, b + col.b, a + col.a);
   42.92 +}
   42.93 +
   42.94 +Color Color::operator -(const Color &col) const {
   42.95 +	return Color(r - col.r, g - col.g, b - col.b, a - col.a);
   42.96 +}
   42.97 +
   42.98 +Color Color::operator *(const Color &col) const {
   42.99 +	return Color(r * col.r, g * col.g, b * col.b, a * col.a);
  42.100 +}
  42.101 +	
  42.102 +Color Color::operator *(float_t scalar) const {
  42.103 +	return Color(r * scalar, g * scalar, b * scalar, a);
  42.104 +}
  42.105 +
  42.106 +
  42.107 +void Color::operator +=(const Color &col) {
  42.108 +	*this = Color(r + col.r, g + col.g, b + col.b, a + col.a);
  42.109 +}
  42.110 +
  42.111 +void Color::operator -=(const Color &col) {
  42.112 +	*this = Color(r - col.r, g - col.g, b - col.b, a - col.a);
  42.113 +}
  42.114 +
  42.115 +void Color::operator *=(const Color &col) {
  42.116 +	*this = Color(r * col.r, g * col.g, b * col.b, a * col.a);
  42.117 +}
  42.118 +
  42.119 +void Color::operator *=(float_t scalar) {
  42.120 +	*this = Color(r * scalar, g * scalar, b * scalar, a);
  42.121 +}
  42.122 +
  42.123 +Color BlendColors(const Color &c1, const Color &c2, float_t t) {
  42.124 +	float_t r = c1.r + (c2.r - c1.r) * t;
  42.125 +	float_t g = c1.g + (c2.g - c1.g) * t;
  42.126 +	float_t b = c1.b + (c2.b - c1.b) * t;
  42.127 +	return Color(r, g, b);
  42.128 +}
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/src/common/color.h	Thu Oct 23 01:46:07 2014 +0300
    43.3 @@ -0,0 +1,55 @@
    43.4 +#ifndef _COLORS_H_
    43.5 +#define _COLORS_H_
    43.6 +
    43.7 +#include <cmath>
    43.8 +#include "typedefs.h"
    43.9 +
   43.10 +#ifdef _MSC_VER
   43.11 +#ifdef DOUBLE_PRECISION_MATH
   43.12 +typedef double float_t;
   43.13 +#else
   43.14 +typedef float float_t;
   43.15 +#endif	// DOUBLE_PRECISION_MATH
   43.16 +#endif	// _MSC_VER
   43.17 +
   43.18 +#ifdef NUC3D_VER_DIRECT3D
   43.19 +
   43.20 +#include "d3d8.h"
   43.21 +
   43.22 +class Color : public D3DCOLORVALUE {
   43.23 +public:
   43.24 +
   43.25 +#else
   43.26 +
   43.27 +class Color {
   43.28 +public:
   43.29 +	float_t r, g, b, a;
   43.30 +
   43.31 +#endif	// NUC3D_VER_DIRECT3D
   43.32 +
   43.33 +	Color(float_t intensity = 1.0f);
   43.34 +	Color(float_t r, float_t g, float_t b, float_t a = 1.0f);
   43.35 +	Color(unsigned int r, unsigned int g, unsigned int b, unsigned int a = 255);
   43.36 +	Color(int r, int g, int b, int a = 255);
   43.37 +	Color(dword pcol);
   43.38 +	Color(long pcol);
   43.39 +
   43.40 +	Color operator +(const Color &col) const;
   43.41 +	Color operator -(const Color &col) const;
   43.42 +	Color operator *(const Color &col) const;
   43.43 +	Color operator *(float_t scalar) const;
   43.44 +
   43.45 +	void operator +=(const Color &col);
   43.46 +	void operator -=(const Color &col);
   43.47 +	void operator *=(const Color &col);
   43.48 +	void operator *=(float_t scalar);
   43.49 +
   43.50 +	dword GetPacked32() const;
   43.51 +	word GetPacked16() const;
   43.52 +	word GetPacked15() const;
   43.53 +	byte GetNearest8(const byte **pal) const;
   43.54 +};
   43.55 +
   43.56 +Color BlendColors(const Color &c1, const Color &c2, float_t t);
   43.57 +
   43.58 +#endif	// _COLORS_H_
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/src/common/curves.cpp	Thu Oct 23 01:46:07 2014 +0300
    44.3 @@ -0,0 +1,240 @@
    44.4 +#include <cmath>
    44.5 +#include "curves.h"
    44.6 +
    44.7 +Curve::Curve() {
    44.8 +	ArcParametrize = false;
    44.9 +	ease_curve = 0;
   44.10 +	Samples = 0;
   44.11 +
   44.12 +	SetEaseSampleCount(100);
   44.13 +}
   44.14 +
   44.15 +Curve::~Curve() {
   44.16 +	delete [] Samples;
   44.17 +	
   44.18 +}
   44.19 +
   44.20 +void Curve::SetArcParametrization(bool state) {
   44.21 +	ArcParametrize = state;
   44.22 +}
   44.23 +
   44.24 +#define Param	0
   44.25 +#define ArcLen	1
   44.26 +
   44.27 +void Curve::SampleArcLengths() {
   44.28 +	const int SamplesPerSegment = 30;
   44.29 +	SampleCount = GetSegmentCount() * SamplesPerSegment;
   44.30 +
   44.31 +	ArcParametrize = false;	// to be able to interpolate with the original values
   44.32 +
   44.33 +	Samples = new Vector2[SampleCount];
   44.34 +	Vector3 prevpos;
   44.35 +	float step = 1.0f / (float)(SampleCount-1);
   44.36 +	for(int i=0; i<SampleCount; i++) {
   44.37 +		float t = step * (float)i;
   44.38 +		Vector3 pos = Interpolate(t);
   44.39 +		Samples[i][Param] = t;
   44.40 +		if(!i) {
   44.41 +			Samples[i][ArcLen] = 0.0f;
   44.42 +		} else {
   44.43 +			Samples[i][ArcLen] = (pos - prevpos).Length() + Samples[i-1][ArcLen];
   44.44 +		}
   44.45 +		prevpos = pos;
   44.46 +	}
   44.47 +
   44.48 +	// normalize arc lenghts
   44.49 +	float maxlen = Samples[SampleCount-1][ArcLen];
   44.50 +	for(int i=0; i<SampleCount; i++) {
   44.51 +		Samples[i][ArcLen] /= maxlen;
   44.52 +	}
   44.53 +
   44.54 +	ArcParametrize = true;
   44.55 +}
   44.56 +
   44.57 +int BinarySearch(Vector2 *array, float key, int begin, int end) {
   44.58 +	int middle = begin + ((end - begin)>>1);
   44.59 +
   44.60 +	if(array[middle][ArcLen] == key) return middle;
   44.61 +	if(end == begin) return middle;
   44.62 +
   44.63 +	if(key < array[middle][ArcLen]) return BinarySearch(array, key, begin, middle);
   44.64 +	if(key > array[middle][ArcLen]) return BinarySearch(array, key, middle+1, end);
   44.65 +	return -1;	// just to make the compiler shut the fuck up
   44.66 +}
   44.67 +
   44.68 +float Curve::Parametrize(float t) {
   44.69 +	if(!Samples) SampleArcLengths();
   44.70 +
   44.71 +	int samplepos = BinarySearch(Samples, t, 0, SampleCount);
   44.72 +	float par = Samples[samplepos][Param];
   44.73 +	float len = Samples[samplepos][ArcLen];
   44.74 +	if((len - t) < XSmallNumber) return par;
   44.75 +
   44.76 +	if(len < t) {
   44.77 +		if(!samplepos) return par;
   44.78 +		float prevlen = Samples[samplepos-1][ArcLen];
   44.79 +		float prevpar = Samples[samplepos-1][Param];
   44.80 +		float p = (t - prevlen) / (len - prevlen);
   44.81 +		return prevpar + (par - prevpar) * p;
   44.82 +	} else {
   44.83 +		if(samplepos >= SampleCount) return par;
   44.84 +		float nextlen = Samples[samplepos+1][ArcLen];
   44.85 +		float nextpar = Samples[samplepos+1][Param];
   44.86 +		float p = (t - len) / (nextlen - len);
   44.87 +		return par + (nextpar - par) * p;
   44.88 +	}
   44.89 +
   44.90 +	return par;	// not gonna happen
   44.91 +}
   44.92 +
   44.93 +
   44.94 +#define MIN(a, b) ((a) < (b) ? (a) : (b))
   44.95 +#define MAX(a, b) ((a) > (b) ? (a) : (b))
   44.96 +
   44.97 +float Curve::Ease(float t) {
   44.98 +	if(!ease_curve) return t;
   44.99 +
  44.100 +	ease_curve->SetArcParametrization(true);
  44.101 +	float et = ease_curve->Interpolate(t).y;
  44.102 +
  44.103 +	return MIN(MAX(et, 0.0f), 1.0f);
  44.104 +}
  44.105 +
  44.106 +
  44.107 +void Curve::AddControlPoint(const Vector3 &cp) {
  44.108 +	ControlPoints.PushBack(cp);
  44.109 +	delete [] Samples;
  44.110 +	Samples = 0;
  44.111 +}
  44.112 +
  44.113 +void Curve::SetEaseCurve(Curve *curve) {
  44.114 +	ease_curve = curve;
  44.115 +}
  44.116 +
  44.117 +void Curve::SetEaseSampleCount(int count) {
  44.118 +	ease_sample_count = count;
  44.119 +	ease_step = 1.0f / ease_sample_count;
  44.120 +}
  44.121 +
  44.122 +
  44.123 +///////////////// B-Spline implementation ////////////////////
  44.124 +
  44.125 +int BSpline::GetSegmentCount() const {
  44.126 +	return ControlPoints.Size() - 3;
  44.127 +}
  44.128 +
  44.129 +Vector3 BSpline::Interpolate(float t) {
  44.130 +
  44.131 +	if(ControlPoints.Size() < 4) return Vector3(0, 0, 0);
  44.132 +
  44.133 +	if(ArcParametrize) {
  44.134 +		t = Ease(Parametrize(t));
  44.135 +	}
  44.136 +
  44.137 +	// find the appropriate segment of the spline that t lies and calculate the piecewise parameter
  44.138 +	t = (float)(ControlPoints.Size() - 3) * t;
  44.139 +	int seg = (int)t;
  44.140 +	t -= (float)floor(t);
  44.141 +	if(seg >= GetSegmentCount()) {
  44.142 +		seg = GetSegmentCount() - 1;
  44.143 +		t = 1.0f;
  44.144 +	}
  44.145 +	
  44.146 +	ListNode<Vector3> *iter = ControlPoints.Begin();
  44.147 +	for(int i=0; i<seg; i++) iter = iter->next;
  44.148 +
  44.149 +	Vector3 Cp[4];
  44.150 +	for(int i=0; i<4; i++) {
  44.151 +        Cp[i] = iter->data;
  44.152 +		iter = iter->next;
  44.153 +	}
  44.154 +
  44.155 +	Matrix4x4 BSplineMat(-1, 3, -3, 1, 3, -6, 3, 0, -3, 0, 3, 0, 1, 4, 1, 0);
  44.156 +	BSplineMat.Transpose();
  44.157 +	Vector4 Params(t*t*t, t*t, t, 1);
  44.158 +	Vector4 CpX(Cp[0].x, Cp[1].x, Cp[2].x, Cp[3].x);
  44.159 +	Vector4 CpY(Cp[0].y, Cp[1].y, Cp[2].y, Cp[3].y);
  44.160 +	Vector4 CpZ(Cp[0].z, Cp[1].z, Cp[2].z, Cp[3].z);
  44.161 +
  44.162 +	CpX.Transform(BSplineMat);
  44.163 +	CpY.Transform(BSplineMat);
  44.164 +	CpZ.Transform(BSplineMat);
  44.165 +
  44.166 +	CpX /= 6.0f;
  44.167 +	CpY /= 6.0f;
  44.168 +	CpZ /= 6.0f;
  44.169 +
  44.170 +	Vector3 res;
  44.171 +
  44.172 +	res.x = Params.DotProduct(CpX);
  44.173 +	res.y = Params.DotProduct(CpY);
  44.174 +	res.z = Params.DotProduct(CpZ);
  44.175 +
  44.176 +	return res;
  44.177 +}
  44.178 +
  44.179 +//////////////// Catmull-Rom Spline implementation //////////////////
  44.180 +
  44.181 +int CatmullRomSpline::GetSegmentCount() const {
  44.182 +	return ControlPoints.Size() - 1;
  44.183 +}
  44.184 +
  44.185 +Vector3 CatmullRomSpline::Interpolate(float t) {
  44.186 +
  44.187 +	if(ControlPoints.Size() < 2) return Vector3(0, 0, 0);
  44.188 +
  44.189 +	if(ArcParametrize) {
  44.190 +		t = Ease(Parametrize(t));
  44.191 +	}
  44.192 +
  44.193 +	// find the appropriate segment of the spline that t lies and calculate the piecewise parameter
  44.194 +	t = (float)(ControlPoints.Size() - 1) * t;
  44.195 +	int seg = (int)t;
  44.196 +	t -= (float)floor(t);
  44.197 +	if(seg >= GetSegmentCount()) {
  44.198 +		seg = GetSegmentCount() - 1;
  44.199 +		t = 1.0f;
  44.200 +	}
  44.201 +
  44.202 +	Vector3 Cp[4];
  44.203 +	ListNode<Vector3> *iter = ControlPoints.Begin();
  44.204 +	for(int i=0; i<seg; i++) iter = iter->next;
  44.205 +
  44.206 +	Cp[1] = iter->data;
  44.207 +	Cp[2] = iter->next->data;
  44.208 +	
  44.209 +	if(!seg) {
  44.210 +		Cp[0] = Cp[1];
  44.211 +	} else {
  44.212 +		Cp[0] = iter->prev->data;
  44.213 +	}
  44.214 +	
  44.215 +	if(seg == ControlPoints.Size() - 2) {
  44.216 +		Cp[3] = Cp[2];
  44.217 +	} else {
  44.218 +		Cp[3] = iter->next->next->data;
  44.219 +	}
  44.220 +
  44.221 +	Matrix4x4 BSplineMat(-1, 3, -3, 1, 2, -5, 4, -1, -1, 0, 1, 0, 0, 2, 0, 0);
  44.222 +	BSplineMat.Transpose();
  44.223 +	Vector4 Params(t*t*t, t*t, t, 1);
  44.224 +	Vector4 CpX(Cp[0].x, Cp[1].x, Cp[2].x, Cp[3].x);
  44.225 +	Vector4 CpY(Cp[0].y, Cp[1].y, Cp[2].y, Cp[3].y);
  44.226 +	Vector4 CpZ(Cp[0].z, Cp[1].z, Cp[2].z, Cp[3].z);
  44.227 +
  44.228 +	CpX.Transform(BSplineMat);
  44.229 +	CpY.Transform(BSplineMat);
  44.230 +	CpZ.Transform(BSplineMat);
  44.231 +
  44.232 +	CpX /= 2.0f;
  44.233 +	CpY /= 2.0f;
  44.234 +	CpZ /= 2.0f;
  44.235 +
  44.236 +	Vector3 res;
  44.237 +
  44.238 +	res.x = Params.DotProduct(CpX);
  44.239 +	res.y = Params.DotProduct(CpY);
  44.240 +	res.z = Params.DotProduct(CpZ);
  44.241 +
  44.242 +	return res;
  44.243 +}
  44.244 \ No newline at end of file
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/src/common/curves.h	Thu Oct 23 01:46:07 2014 +0300
    45.3 @@ -0,0 +1,50 @@
    45.4 +#ifndef _CURVES_H_
    45.5 +#define _CURVES_H_
    45.6 +
    45.7 +#include <string>
    45.8 +#include "n3dmath.h"
    45.9 +#include "linkedlist.h"
   45.10 +
   45.11 +class Curve {
   45.12 +protected:
   45.13 +	LinkedList<Vector3> ControlPoints;
   45.14 +	Vector2 *Samples;	// used for parametrizing by arc length
   45.15 +	int SampleCount;
   45.16 +	bool ArcParametrize;
   45.17 +
   45.18 +	Curve *ease_curve;	// ease in/out curve (1D, x&z discarded)
   45.19 +	int ease_sample_count, ease_step;
   45.20 +	
   45.21 +	void SampleArcLengths();
   45.22 +	float Parametrize(float t);
   45.23 +	float Ease(float t);
   45.24 +
   45.25 +public:
   45.26 +	std::string name;
   45.27 +
   45.28 +	Curve();
   45.29 +	~Curve();
   45.30 +	virtual void AddControlPoint(const Vector3 &cp);
   45.31 +
   45.32 +	virtual int GetSegmentCount() const = 0;
   45.33 +	virtual void SetArcParametrization(bool state);
   45.34 +	virtual void SetEaseCurve(Curve *curve);
   45.35 +	virtual void SetEaseSampleCount(int count);
   45.36 +
   45.37 +	virtual Vector3 Interpolate(float t) = 0;
   45.38 +};
   45.39 +
   45.40 +class BSpline : public Curve {
   45.41 +public:
   45.42 +	virtual int GetSegmentCount() const;
   45.43 +	virtual Vector3 Interpolate(float t);	
   45.44 +};
   45.45 +
   45.46 +class CatmullRomSpline : public Curve {
   45.47 +public:
   45.48 +	virtual int GetSegmentCount() const;
   45.49 +	virtual Vector3 Interpolate(float t);
   45.50 +};
   45.51 +
   45.52 +
   45.53 +#endif	// _CURVES_H_
   45.54 \ No newline at end of file
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/src/common/hashtable.h	Thu Oct 23 01:46:07 2014 +0300
    46.3 @@ -0,0 +1,103 @@
    46.4 +#ifndef HASHTABLE_H_
    46.5 +#define HASHTABLE_H_
    46.6 +
    46.7 +#include <list>
    46.8 +#include <vector>
    46.9 +
   46.10 +template <class KeyT, class ValT> 
   46.11 +struct Pair {
   46.12 +	KeyT key; 
   46.13 +	ValT val;
   46.14 +};
   46.15 +
   46.16 +template <class KeyType, class ValType>
   46.17 +class HashTable {
   46.18 +private:
   46.19 +
   46.20 +	size_t size;
   46.21 +	std::vector<std::list<Pair<KeyType, ValType> > > table;
   46.22 +	//std::list<Pair<KeyType, ValType> > table[100];
   46.23 +
   46.24 +	unsigned int (*HashFunc)(const KeyType &key, unsigned long size);
   46.25 +	unsigned int Hash(const KeyType &key) {return (unsigned int)HashFunc(key, (unsigned long)size);}
   46.26 +
   46.27 +public:
   46.28 +
   46.29 +	HashTable(unsigned long size = 101);
   46.30 +	~HashTable();
   46.31 +
   46.32 +	void SetHashFunction(unsigned int (*HashFunc)(const KeyType&, unsigned long));
   46.33 +
   46.34 +	void Insert(KeyType key, ValType value);
   46.35 +	void Remove(KeyType key);
   46.36 +
   46.37 +	Pair<KeyType, ValType> *Find(KeyType key);
   46.38 +};
   46.39 +
   46.40 +//// std hash function
   46.41 +//template <class KeyType>
   46.42 +//unsigned int _HashFunction(const KeyType &key, unsigned long size) {
   46.43 +//	return (size_t)key % size;
   46.44 +//}
   46.45 +
   46.46 +// hash table member functions
   46.47 +template <class KeyType, class ValType>
   46.48 +HashTable<KeyType, ValType>::HashTable(unsigned long size) {
   46.49 +	this->size = size;
   46.50 +	//HashFunc = _HashFunction;
   46.51 +	table.resize(size);
   46.52 +}
   46.53 +
   46.54 +template <class KeyType, class ValType>
   46.55 +HashTable<KeyType, ValType>::~HashTable() {
   46.56 +	for(unsigned long i=0; i<size; i++) {
   46.57 +		table[i].erase(table[i].begin(), table[i].end());
   46.58 +	}
   46.59 +}
   46.60 +
   46.61 +template <class KeyType, class ValType>
   46.62 +void HashTable<KeyType, ValType>::SetHashFunction(unsigned int (*HashFunc)(const KeyType&, unsigned long)) {
   46.63 +	this->HashFunc = HashFunc;
   46.64 +}
   46.65 +
   46.66 +template <class KeyType, class ValType>
   46.67 +void HashTable<KeyType, ValType>::Insert(KeyType key, ValType value) {
   46.68 +	Pair<KeyType, ValType> newpair;
   46.69 +	newpair.key = key;
   46.70 +	newpair.val = value;
   46.71 +
   46.72 +	table[Hash(key)].push_back(newpair);
   46.73 +}
   46.74 +
   46.75 +template <class KeyType, class ValType>
   46.76 +void HashTable<KeyType, ValType>::Remove(KeyType key) {
   46.77 +
   46.78 +	unsigned int pos = Hash(key);
   46.79 +
   46.80 +	std::list<Pair<KeyType, ValType> >::iterator iter = table[pos].begin();
   46.81 +	while(iter != table[pos].end()) {
   46.82 +		if(iter->key == key) {
   46.83 +			table[pos].erase(iter);
   46.84 +			return;
   46.85 +		}
   46.86 +		iter++;
   46.87 +	}
   46.88 +}
   46.89 +
   46.90 +template <class KeyType, class ValType>
   46.91 +Pair<KeyType, ValType> *HashTable<KeyType, ValType>::Find(KeyType key) {
   46.92 +
   46.93 +	unsigned int pos = Hash(key);
   46.94 +
   46.95 +	std::list<Pair<KeyType, ValType> >::iterator iter = table[pos].begin();
   46.96 +	while(iter != table[pos].end()) {
   46.97 +		if(iter->key == key) {
   46.98 +			return &(*iter);
   46.99 +		}
  46.100 +		iter++;
  46.101 +	}
  46.102 +
  46.103 +	return 0;
  46.104 +}
  46.105 +
  46.106 +#endif	// HASHTABLE_H_
  46.107 \ No newline at end of file
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/src/common/linkedlist.h	Thu Oct 23 01:46:07 2014 +0300
    47.3 @@ -0,0 +1,229 @@
    47.4 +#ifndef _LINKEDLIST_H_
    47.5 +#define _LINKEDLIST_H_
    47.6 +
    47.7 +template <class T>
    47.8 +struct ListNode {
    47.9 +	T data;
   47.10 +	ListNode<T> *next, *prev;
   47.11 +};
   47.12 +
   47.13 +
   47.14 +template <class T>
   47.15 +class LinkedList {
   47.16 +private:
   47.17 +	ListNode<T> *head, *tail;
   47.18 +	int size;
   47.19 +
   47.20 +public:
   47.21 +
   47.22 +	LinkedList();
   47.23 +	~LinkedList();
   47.24 +
   47.25 +	inline ListNode<T> *Begin();
   47.26 +	inline ListNode<T> *End();
   47.27 +
   47.28 +	void PushBack(ListNode<T> *node);
   47.29 +	void PushBack(T data);
   47.30 +
   47.31 +	void Insert(ListNode<T> *pos, ListNode<T> *node);
   47.32 +	void Insert(ListNode<T> *pos, T data);
   47.33 +
   47.34 +	void Remove(ListNode<T> *node);
   47.35 +	ListNode<T> *Erase(ListNode<T> *node);
   47.36 +
   47.37 +	ListNode<T> *Find(T key);
   47.38 +
   47.39 +	int CountNodes();
   47.40 +	inline int Size() const;
   47.41 +
   47.42 +	void operator =(LinkedList &rhs);
   47.43 +};
   47.44 +
   47.45 +
   47.46 +/////////// implementation //////////
   47.47 +template <class T>
   47.48 +LinkedList<T>::LinkedList() {
   47.49 +	head = tail = 0;
   47.50 +	size = 0;
   47.51 +}
   47.52 +
   47.53 +
   47.54 +template <class T>
   47.55 +LinkedList<T>::~LinkedList() {
   47.56 +
   47.57 +	while(head) {
   47.58 +		Erase(head);
   47.59 +	}
   47.60 +}
   47.61 +
   47.62 +template <class T>
   47.63 +ListNode<T> *LinkedList<T>::Begin() {
   47.64 +	return head;
   47.65 +}
   47.66 +
   47.67 +template <class T>
   47.68 +ListNode<T> *LinkedList<T>::End() {
   47.69 +	return tail;
   47.70 +}
   47.71 +
   47.72 +template <class T>
   47.73 +void LinkedList<T>::PushBack(ListNode<T> *node) {
   47.74 +
   47.75 +	if(!head) {		// empty list
   47.76 +		head = tail = node;
   47.77 +		node->next = node->prev = 0;
   47.78 +	} else {
   47.79 +		tail->next = node;
   47.80 +		node->prev = tail;
   47.81 +		tail = node;
   47.82 +		node->next = 0;
   47.83 +	}
   47.84 +
   47.85 +	size++;
   47.86 +}
   47.87 +
   47.88 +template <class T>
   47.89 +void LinkedList<T>::PushBack(T data) {
   47.90 +
   47.91 +	ListNode<T> *node = new ListNode<T>;
   47.92 +	node->data = data;
   47.93 +
   47.94 +	if(!head) {		// empty list
   47.95 +		head = tail = node;
   47.96 +		node->next = node->prev = 0;
   47.97 +	} else {
   47.98 +		tail->next = node;
   47.99 +		node->prev = tail;
  47.100 +		tail = node;
  47.101 +		node->next = 0;
  47.102 +	}
  47.103 +
  47.104 +	size++;
  47.105 +}
  47.106 +
  47.107 +template <class T>
  47.108 +void LinkedList<T>::Insert(ListNode<T> *pos, ListNode<T> *node) {
  47.109 +
  47.110 +	if(!head) {
  47.111 +		head = tail = node;
  47.112 +		node->next = node->prev = 0;
  47.113 +	} else {
  47.114 +		node->prev = pos->prev;
  47.115 +		pos->prev = node;
  47.116 +		node->next = pos;
  47.117 +		if(head == pos) head = node; else node->prev->next = node;
  47.118 +	}
  47.119 +
  47.120 +	size++;
  47.121 +}
  47.122 +
  47.123 +template <class T>
  47.124 +void LinkedList<T>::Insert(ListNode<T> *pos, T data) {
  47.125 +
  47.126 +	ListNode<T> *node = new ListNode<T>;
  47.127 +	node->data = data;
  47.128 +
  47.129 +	if(!head) {
  47.130 +		head = tail = node;
  47.131 +		node->next = node->prev = 0;
  47.132 +	} else {
  47.133 +		node->prev = pos->prev;
  47.134 +		pos->prev = node;
  47.135 +		node->next = pos;
  47.136 +		if(head == pos) head = node; else node->prev->next = node;
  47.137 +	}
  47.138 +
  47.139 +	size++;
  47.140 +}
  47.141 +
  47.142 +template <class T>
  47.143 +void LinkedList<T>::Remove(ListNode<T> *node) {
  47.144 +
  47.145 +	if(!node) return;	// e.g. Remove(head) on an empty list
  47.146 +
  47.147 +	if(node->prev) {
  47.148 +		node->prev->next = node->next;
  47.149 +	} else {
  47.150 +		head = node->next;
  47.151 +	}
  47.152 +
  47.153 +	if(node->next) {
  47.154 +		node->next->prev = node->prev;
  47.155 +	} else {
  47.156 +		tail = node->prev;
  47.157 +	}
  47.158 +
  47.159 +	size--;
  47.160 +}
  47.161 +
  47.162 +template <class T>
  47.163 +ListNode<T> *LinkedList<T>::Erase(ListNode<T> *node) {
  47.164 +
  47.165 +	if(!node) return 0;	// e.g. Erase(head) on an empty list
  47.166 +
  47.167 +	if(node->prev) {
  47.168 +		node->prev->next = node->next;
  47.169 +	} else {
  47.170 +		head = node->next;
  47.171 +	}
  47.172 +
  47.173 +	if(node->next) {
  47.174 +		node->next->prev = node->prev;
  47.175 +	} else {
  47.176 +		tail = node->prev;
  47.177 +	}
  47.178 +
  47.179 +	ListNode<T> *destr = node;
  47.180 +	node = node->next;
  47.181 +	
  47.182 +	delete destr;
  47.183 +
  47.184 +	size--;
  47.185 +
  47.186 +	return node;
  47.187 +}
  47.188 +
  47.189 +template <class T>
  47.190 +ListNode<T> *LinkedList<T>::Find(T key) {
  47.191 +	
  47.192 +	ListNode<T> *iter = head;
  47.193 +	while(iter) {
  47.194 +		if(iter->data == key) return iter;
  47.195 +		iter = iter->next;
  47.196 +	}
  47.197 +
  47.198 +	return 0;	// null pointer if not found
  47.199 +}
  47.200 +
  47.201 +template <class T>
  47.202 +int LinkedList<T>::CountNodes() {
  47.203 +
  47.204 +	size = 0;
  47.205 +
  47.206 +	ListNode<T> *iter = head;
  47.207 +	while(iter) {
  47.208 +		size++;
  47.209 +		iter = iter->next;
  47.210 +	}
  47.211 +
  47.212 +	return size;
  47.213 +}
  47.214 +
  47.215 +template <class T>
  47.216 +int LinkedList<T>::Size() const {
  47.217 +	return size;
  47.218 +}
  47.219 +
  47.220 +
  47.221 +template <class T>
  47.222 +void LinkedList<T>::operator =(LinkedList<T> &rhs) {
  47.223 +	
  47.224 +	ListNode<T> *src = rhs.Begin();
  47.225 +	while(src) {
  47.226 +		PushBack(src->data);
  47.227 +		src = src->next;
  47.228 +	}
  47.229 +}
  47.230 +
  47.231 +
  47.232 +#endif	// _LINKEDLIST_H_
  47.233 \ No newline at end of file
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/src/common/n3dmath.cpp	Thu Oct 23 01:46:07 2014 +0300
    48.3 @@ -0,0 +1,1370 @@
    48.4 +#include "n3dmath.h"
    48.5 +
    48.6 +#define fsin (float)sin
    48.7 +#define fcos (float)cos
    48.8 +
    48.9 +float frand(float range) {
   48.10 +	return ((float)rand() / (float)RAND_MAX) * range;
   48.11 +}
   48.12 +
   48.13 +Vector3::Vector3() {
   48.14 +	x = y = z = 0.0f;
   48.15 +}
   48.16 +
   48.17 +Vector3::Vector3(float x, float y, float z) {
   48.18 +	this->x = x;
   48.19 +	this->y = y;
   48.20 +	this->z = z;
   48.21 +}
   48.22 +/*  inlined
   48.23 +float Vector3::DotProduct(const Vector3 &vec) const {
   48.24 +	return x * vec.x + y * vec.y + z * vec.z;
   48.25 +}
   48.26 +
   48.27 +float DotProduct(const Vector3 &vec1, const Vector3 &vec2) {
   48.28 +	return vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z;
   48.29 +}
   48.30 +
   48.31 +Vector3 Vector3::CrossProduct(const Vector3 &vec) const {
   48.32 +	return Vector3(y * vec.z - z * vec.y,  z * vec.x - x * vec.z,  x * vec.y - y * vec.x);
   48.33 +}
   48.34 +
   48.35 +Vector3 CrossProduct(const Vector3 &vec1, const Vector3 &vec2) {
   48.36 +	return Vector3(vec1.y * vec2.z - vec1.z * vec2.y,  vec1.z * vec2.x - vec1.x * vec2.z,  vec1.x * vec2.y - vec1.y * vec2.x);
   48.37 +}
   48.38 +
   48.39 +Vector3 Vector3::operator +(const Vector3 &vec) const {
   48.40 +	return Vector3(x + vec.x, y + vec.y, z + vec.z);
   48.41 +}
   48.42 +
   48.43 +Vector3 Vector3::operator -(const Vector3 &vec) const {
   48.44 +	return Vector3(x - vec.x, y - vec.y, z - vec.z);
   48.45 +}
   48.46 +
   48.47 +Vector3 Vector3::operator *(float scalar) const {
   48.48 +	return Vector3(x * scalar, y * scalar, z * scalar);
   48.49 +}
   48.50 +
   48.51 +Vector3 Vector3::operator /(float scalar) const {
   48.52 +	return Vector3(x / scalar, y / scalar, z / scalar);
   48.53 +}
   48.54 +
   48.55 +void Vector3::operator +=(const Vector3 &vec) {
   48.56 +	x += vec.x;
   48.57 +	y += vec.y;
   48.58 +	z += vec.z;
   48.59 +}
   48.60 +
   48.61 +void Vector3::operator -=(const Vector3 &vec) {
   48.62 +	x -= vec.x;
   48.63 +	y -= vec.y;
   48.64 +	z -= vec.z;
   48.65 +}
   48.66 +
   48.67 +void Vector3::operator *=(float scalar) {
   48.68 +	x *= scalar;
   48.69 +	y *= scalar;
   48.70 +	z *= scalar;
   48.71 +}
   48.72 +
   48.73 +void Vector3::operator /=(float scalar) {
   48.74 +	x /= scalar;
   48.75 +	y /= scalar;
   48.76 +	z /= scalar;
   48.77 +}
   48.78 +
   48.79 +Vector3 Vector3::operator -() const {
   48.80 +	return Vector3(-x, -y, -z);
   48.81 +}
   48.82 +
   48.83 +bool Vector3::operator >(const Vector3 &vec) const {
   48.84 +	return LengthSq() > vec.LengthSq();
   48.85 +}
   48.86 +
   48.87 +bool Vector3::operator <(const Vector3 &vec) const {
   48.88 +	return LengthSq() < vec.LengthSq();
   48.89 +}
   48.90 +
   48.91 +bool Vector3::operator >(float len) const {
   48.92 +	return LengthSq() > len;
   48.93 +}
   48.94 +
   48.95 +bool Vector3::operator <(float len) const {
   48.96 +	return LengthSq() < len;
   48.97 +}
   48.98 +
   48.99 +bool Vector3::operator ==(const Vector3 &vec) const {
  48.100 +	return ((*this - vec).Length() < XSmallNumber);
  48.101 +}
  48.102 +
  48.103 +bool Vector3::operator ==(float len) const {
  48.104 +	return ((this->Length() - len) < XSmallNumber);
  48.105 +}
  48.106 +
  48.107 +Vector3::operator Vector2() const {
  48.108 +	return Vector2(x, y);
  48.109 +}
  48.110 +
  48.111 +Vector3::operator Vector4() const {
  48.112 +	return Vector4(x, y, z, 1.0f);
  48.113 +}
  48.114 +
  48.115 +
  48.116 +float Vector3::Length() const {
  48.117 +	return (float)sqrt(x*x + y*y + z*z);
  48.118 +}
  48.119 +
  48.120 +float Vector3::LengthSq() const {
  48.121 +	return x*x + y*y + z*z;
  48.122 +}
  48.123 +
  48.124 +void Vector3::Normalize() {
  48.125 +	float len = (float)sqrt(x*x + y*y + z*z);
  48.126 +	x /= len;
  48.127 +	y /= len;
  48.128 +	z /= len;
  48.129 +}
  48.130 +
  48.131 +Vector3 Vector3::Normalized() const {
  48.132 +	float len = (float)sqrt(x*x + y*y + z*z);
  48.133 +	return Vector3(x / len, y / len, z / len);
  48.134 +}
  48.135 +
  48.136 +Vector3 Vector3::Reflection(const Vector3 &normal) const {
  48.137 +	return normal * this->DotProduct(normal) * 2.0f - *this;
  48.138 +}
  48.139 +*/
  48.140 +Vector3 Vector3::Refraction(const Vector3 &normal, float FromIOR, float ToIOR) const {
  48.141 +	float m = FromIOR / ToIOR;
  48.142 +	Vector3 dir = *this;
  48.143 +	dir.Normalize();
  48.144 +	float CosAngleIncoming = dir.DotProduct(normal);
  48.145 +	float CosAngleRefr = (1.0f / (m*m)) * (float)sqrt(1.0f - m*m * (1 - CosAngleIncoming * CosAngleIncoming));
  48.146 +
  48.147 +	return dir * m - normal * (CosAngleRefr + m * CosAngleIncoming);
  48.148 +}
  48.149 +
  48.150 +void Vector3::Transform(const Matrix4x4 &mat) {
  48.151 +	// assume row vectors
  48.152 +	float nx = x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + mat.m[3][0];
  48.153 +	float ny = x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + mat.m[3][1];
  48.154 +	z  = x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + mat.m[3][2];
  48.155 +	x = nx;
  48.156 +	y = ny;
  48.157 +}
  48.158 +
  48.159 +void Vector3::Transform(const Quaternion &quat) {
  48.160 +	Quaternion vq(0.0f, *this);
  48.161 +	vq = quat * vq * quat.Inverse();
  48.162 +	*this = vq.v;
  48.163 +}
  48.164 +
  48.165 +// direct transformations
  48.166 +
  48.167 +void Vector3::Translate(float x, float y, float z) {
  48.168 +	this->x += x;
  48.169 +	this->y += y;
  48.170 +	this->z += z;
  48.171 +}
  48.172 +
  48.173 +void Vector3::Rotate(float x, float y, float z) {
  48.174 +	
  48.175 +	Matrix4x4 xform;
  48.176 +	xform.SetRotation(x, y, z);
  48.177 +	
  48.178 +	Transform(xform);
  48.179 +}
  48.180 +
  48.181 +void Vector3::Rotate(const Vector3 &axis, float angle) {
  48.182 +
  48.183 +	Matrix4x4 xform;
  48.184 +	xform.SetRotation(axis, angle);
  48.185 +
  48.186 +	Transform(xform);
  48.187 +}
  48.188 +
  48.189 +void Vector3::Scale(float x, float y, float z) {
  48.190 +	this->x *= x;
  48.191 +	this->y *= y;
  48.192 +	this->z *= z;
  48.193 +}
  48.194 +
  48.195 +float &Vector3::operator [](int index) {
  48.196 +	return !index ? x : index == 1 ? y : z;
  48.197 +}
  48.198 +
  48.199 +std::ostream &operator <<(std::ostream &out, const Vector3 &vec) {
  48.200 +	out << vec.x << ", " << vec.y << ", " << vec.z;
  48.201 +	return out;
  48.202 +}
  48.203 +
  48.204 +// ------------- Vector4 implementation ---------------
  48.205 +
  48.206 +Vector4::Vector4() {
  48.207 +	x = y = z = 0.0f;
  48.208 +}
  48.209 +
  48.210 +Vector4::Vector4(const Vector4 &vec) {
  48.211 +	x = vec.x;
  48.212 +	y = vec.y;
  48.213 +	z = vec.z;
  48.214 +	w = vec.w;
  48.215 +}
  48.216 +
  48.217 +Vector4::Vector4(const Vector3 &vec) {
  48.218 +	x = vec.x;
  48.219 +	y = vec.y;
  48.220 +	z = vec.z;
  48.221 +	w = 1.0f;
  48.222 +}
  48.223 +
  48.224 +Vector4::Vector4(float x, float y, float z, float w) {
  48.225 +	this->x = x;
  48.226 +	this->y = y;
  48.227 +	this->z = z;
  48.228 +	this->w = w;
  48.229 +}
  48.230 +
  48.231 +float Vector4::DotProduct(const Vector4 &vec) const {
  48.232 +	return x * vec.x + y * vec.y + z * vec.z + w * vec.w;
  48.233 +}
  48.234 +
  48.235 +float DotProduct(const Vector4 &vec1, const Vector4 &vec2) {
  48.236 +	return vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z + vec1.w * vec2.w;
  48.237 +}
  48.238 +
  48.239 +Vector4 Vector4::CrossProduct(const Vector4 &vec1, const Vector4 &vec2) const {
  48.240 +    float  A, B, C, D, E, F;       // Intermediate Values
  48.241 +    Vector4 result;
  48.242 +
  48.243 +    // Calculate intermediate values.
  48.244 +    A = (vec1.x * vec2.y) - (vec1.y * vec2.x);
  48.245 +    B = (vec1.x * vec2.z) - (vec1.z * vec2.x);
  48.246 +    C = (vec1.x * vec2.w) - (vec1.w * vec2.x);
  48.247 +    D = (vec1.y * vec2.z) - (vec1.z * vec2.y);
  48.248 +    E = (vec1.y * vec2.w) - (vec1.w * vec2.y);
  48.249 +    F = (vec1.z * vec2.w) - (vec1.w * vec2.z);
  48.250 +
  48.251 +    // Calculate the result-vector components.
  48.252 +    result.x =   (y * F) - (z * E) + (w * D);
  48.253 +    result.y = - (x * F) + (z * C) - (w * B);
  48.254 +    result.z =   (x * E) - (y * C) + (w * A);
  48.255 +    result.w = - (x * D) + (y * B) - (z * A);
  48.256 +    return result;
  48.257 +}
  48.258 +
  48.259 +Vector4 CrossProduct(const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3) {
  48.260 +    float  A, B, C, D, E, F;       // Intermediate Values
  48.261 +    Vector4 result;
  48.262 +
  48.263 +    // Calculate intermediate values.
  48.264 +    A = (vec2.x * vec3.y) - (vec2.y * vec3.x);
  48.265 +    B = (vec2.x * vec3.z) - (vec2.z * vec3.x);
  48.266 +    C = (vec2.x * vec3.w) - (vec2.w * vec3.x);
  48.267 +    D = (vec2.y * vec3.z) - (vec2.z * vec3.y);
  48.268 +    E = (vec2.y * vec3.w) - (vec2.w * vec3.y);
  48.269 +    F = (vec2.z * vec3.w) - (vec2.w * vec3.z);
  48.270 +
  48.271 +    // Calculate the result-vector components.
  48.272 +    result.x =   (vec1.y * F) - (vec1.z * E) + (vec1.w * D);
  48.273 +    result.y = - (vec1.x * F) + (vec1.z * C) - (vec1.w * B);
  48.274 +    result.z =   (vec1.x * E) - (vec1.y * C) + (vec1.w * A);
  48.275 +    result.w = - (vec1.x * D) + (vec1.y * B) - (vec1.z * A);
  48.276 +    return result;
  48.277 +}
  48.278 +
  48.279 +Vector4 Vector4::operator +(const Vector4 &vec) const {
  48.280 +	return Vector4(x + vec.x, y + vec.y, z + vec.z, w + vec.w);
  48.281 +}
  48.282 +
  48.283 +Vector4 Vector4::operator -(const Vector4 &vec) const {
  48.284 +	return Vector4(x - vec.x, y - vec.y, z - vec.z, w - vec.w);
  48.285 +}
  48.286 +
  48.287 +Vector4 Vector4::operator *(float scalar) const {
  48.288 +	return Vector4(x * scalar, y * scalar, z * scalar, w * scalar);
  48.289 +}
  48.290 +
  48.291 +Vector4 Vector4::operator /(float scalar) const {
  48.292 +	return Vector4(x / scalar, y / scalar, z / scalar, w / scalar);
  48.293 +}
  48.294 +
  48.295 +void Vector4::operator +=(const Vector4 &vec) {
  48.296 +	x += vec.x;
  48.297 +	y += vec.y;
  48.298 +	z += vec.z;
  48.299 +	w += vec.w;
  48.300 +}
  48.301 +
  48.302 +void Vector4::operator -=(const Vector4 &vec) {
  48.303 +	x -= vec.x;
  48.304 +	y -= vec.y;
  48.305 +	z -= vec.z;
  48.306 +	w -= vec.w;
  48.307 +}
  48.308 +
  48.309 +void Vector4::operator *=(float scalar) {
  48.310 +	x *= scalar;
  48.311 +	y *= scalar;
  48.312 +	z *= scalar;
  48.313 +	w *= scalar;
  48.314 +}
  48.315 +
  48.316 +void Vector4::operator /=(float scalar) {
  48.317 +	x /= scalar;
  48.318 +	y /= scalar;
  48.319 +	z /= scalar;
  48.320 +	w /= scalar;
  48.321 +}
  48.322 +
  48.323 +Vector4 Vector4::operator -() const {
  48.324 +	return Vector4(-x, -y, -z, -w);
  48.325 +}
  48.326 +
  48.327 +
  48.328 +bool Vector4::operator >(const Vector4 &vec) const {
  48.329 +	return LengthSq() > vec.LengthSq();
  48.330 +}
  48.331 +
  48.332 +bool Vector4::operator <(const Vector4 &vec) const {
  48.333 +	return LengthSq() < vec.LengthSq();
  48.334 +}
  48.335 +
  48.336 +bool Vector4::operator >(float len) const {
  48.337 +	return LengthSq() > len;
  48.338 +}
  48.339 +
  48.340 +bool Vector4::operator <(float len) const {
  48.341 +	return LengthSq() < len;
  48.342 +}
  48.343 +
  48.344 +bool Vector4::operator ==(const Vector4 &vec) const {
  48.345 +	return ((*this - vec).Length() < XSmallNumber);
  48.346 +}
  48.347 +
  48.348 +bool Vector4::operator ==(float len) const {
  48.349 +	return ((this->Length() - len) < XSmallNumber);
  48.350 +}
  48.351 +
  48.352 +Vector4::operator Vector3() const {
  48.353 +	return Vector3(x, y, z);
  48.354 +}
  48.355 +
  48.356 +
  48.357 +float Vector4::Length() const {
  48.358 +	return (float)sqrt(x*x + y*y + z*z + w*w);
  48.359 +}
  48.360 +
  48.361 +float Vector4::LengthSq() const {
  48.362 +	return x*x + y*y + z*z + w*w;
  48.363 +}
  48.364 +
  48.365 +void Vector4::Normalize() {
  48.366 +	float len = (float)sqrt(x*x + y*y + z*z + w*w);
  48.367 +	x /= len;
  48.368 +	y /= len;
  48.369 +	z /= len;
  48.370 +	w /= len;
  48.371 +}
  48.372 +
  48.373 +Vector4 Vector4::Normalized() const {
  48.374 +	float len = (float)sqrt(x*x + y*y + z*z + w*w);
  48.375 +	return Vector4(x / len, y / len, z / len, w / len);
  48.376 +}
  48.377 +
  48.378 +void Vector4::Transform(const Matrix4x4 &mat) {
  48.379 +	// assume row vectors
  48.380 +	float nx = x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + w * mat.m[3][0];
  48.381 +	float ny = x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + w * mat.m[3][1];
  48.382 +	float nz = x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + w * mat.m[3][2];
  48.383 +	w = x * mat.m[0][3] + y * mat.m[1][3] + z * mat.m[2][3] + w * mat.m[3][3];
  48.384 +	x = nx;
  48.385 +	y = ny;
  48.386 +	z = nz;
  48.387 +}
  48.388 +
  48.389 +
  48.390 +// Direct transformations on the vector
  48.391 +void Vector4::Translate(float x, float y, float z, float w) {
  48.392 +	x += x;
  48.393 +	y += y;
  48.394 +	z += z;
  48.395 +	w += w;
  48.396 +}
  48.397 +
  48.398 +void Vector4::Rotate(float x, float y, float z) {
  48.399 +	Matrix4x4 xform;
  48.400 +	xform.SetRotation(x, y, z);
  48.401 +	Transform(xform);
  48.402 +}
  48.403 +
  48.404 +void Vector4::Rotate(const Vector3 &axis, float angle) {
  48.405 +	Matrix4x4 xform;
  48.406 +	xform.SetRotation(axis, angle);
  48.407 +	Transform(xform);
  48.408 +}
  48.409 +
  48.410 +void Vector4::Scale(float x, float y, float z, float w) {
  48.411 +	this->x *= x;
  48.412 +	this->y *= y;
  48.413 +	this->z *= z;
  48.414 +	this->w *= w;
  48.415 +}
  48.416 +
  48.417 +float &Vector4::operator [](int index) {
  48.418 +	return !index ? x : index == 1 ? y : index == 2 ? z : w;
  48.419 +}
  48.420 +
  48.421 +std::ostream &operator <<(std::ostream &out, const Vector4 &vec) {
  48.422 +	out << vec.x << ", " << vec.y << ", " << vec.z << ", " << vec.w;
  48.423 +	return out;
  48.424 +}
  48.425 +
  48.426 +// ------------- Vector2 implementation ---------------
  48.427 +
  48.428 +Vector2::Vector2() {
  48.429 +	x = y = 0.0f;
  48.430 +}
  48.431 +
  48.432 +Vector2::Vector2(const Vector2 &vec) {
  48.433 +	x = vec.x;
  48.434 +	y = vec.y;
  48.435 +}
  48.436 +
  48.437 +Vector2::Vector2(float x, float y) {
  48.438 +	this->x = x;
  48.439 +	this->y = y;
  48.440 +}
  48.441 +
  48.442 +float Vector2::DotProduct(const Vector2 &vec) const {
  48.443 +	return x * vec.x + y * vec.y;
  48.444 +}
  48.445 +
  48.446 +float DotProduct(const Vector2 &vec1, const Vector2 &vec2) {
  48.447 +	return vec1.x * vec2.x + vec1.y + vec2.y;
  48.448 +}
  48.449 +
  48.450 +Vector2 Vector2::operator +(const Vector2 &vec) const {
  48.451 +	return Vector2(x + vec.x, y + vec.y);
  48.452 +}
  48.453 +
  48.454 +Vector2 Vector2::operator -(const Vector2 &vec) const {
  48.455 +	return Vector2(x - vec.x, y - vec.y);
  48.456 +}
  48.457 +
  48.458 +Vector2 Vector2::operator *(float scalar) const {
  48.459 +	return Vector2(x * scalar, y * scalar);
  48.460 +}
  48.461 +
  48.462 +Vector2 Vector2::operator /(float scalar) const {
  48.463 +	return Vector2(x / scalar, y / scalar);
  48.464 +}
  48.465 +
  48.466 +void Vector2::operator +=(const Vector2 &vec) {
  48.467 +	x += vec.x;
  48.468 +	y += vec.y;
  48.469 +}
  48.470 +
  48.471 +void Vector2::operator -=(const Vector2 &vec) {
  48.472 +	x -= vec.x;
  48.473 +	y -= vec.y;
  48.474 +}
  48.475 +
  48.476 +void Vector2::operator *=(float scalar) {
  48.477 +	x *= scalar;
  48.478 +	y *= scalar;
  48.479 +}
  48.480 +
  48.481 +void Vector2::operator /=(float scalar) {
  48.482 +	x /= scalar;
  48.483 +	y /= scalar;
  48.484 +}
  48.485 +
  48.486 +Vector2 Vector2::operator -() const {
  48.487 +	return Vector2(-x, -y);
  48.488 +}
  48.489 +
  48.490 +bool Vector2::operator >(const Vector2 &vec) const {
  48.491 +	return LengthSq() > vec.LengthSq();
  48.492 +}
  48.493 +
  48.494 +bool Vector2::operator <(const Vector2 &vec) const {
  48.495 +	return LengthSq() < vec.LengthSq();
  48.496 +}
  48.497 +
  48.498 +bool Vector2::operator >(float len) const {
  48.499 +	return LengthSq() > len;
  48.500 +}
  48.501 +
  48.502 +bool Vector2::operator <(float len) const {
  48.503 +	return LengthSq() < len;
  48.504 +}
  48.505 +
  48.506 +bool Vector2::operator ==(const Vector2 &vec) const {
  48.507 +	return ((*this - vec).Length() < XSmallNumber);
  48.508 +}
  48.509 +
  48.510 +bool Vector2::operator ==(float len) const {
  48.511 +	return ((this->Length() - len) < XSmallNumber);
  48.512 +}
  48.513 +
  48.514 +Vector2::operator Vector3() const {
  48.515 +	return Vector3(x, y, 1.0f);
  48.516 +}
  48.517 +
  48.518 +float Vector2::Length() const {
  48.519 +	return (float)sqrt(x * x + y * y);
  48.520 +}
  48.521 +
  48.522 +float Vector2::LengthSq() const {
  48.523 +	return x * x + y * y;
  48.524 +}
  48.525 +	
  48.526 +void Vector2::Normalize() {
  48.527 +	float len = (float)sqrt(x * x + y * y);
  48.528 +	x /= len;
  48.529 +	y /= len;
  48.530 +}
  48.531 +
  48.532 +Vector2 Vector2::Normalized() const {
  48.533 +	float len = (float)sqrt(x * x + y * y);
  48.534 +	return Vector2(x / len, y / len);
  48.535 +}
  48.536 +
  48.537 +//Vector2 Vector2::Reflection(const Vector2 &normal) const;
  48.538 +//Vector2 Vector2::Refraction(const Vector2 &normal, float FromIOR, float ToIOR) const;
  48.539 +	
  48.540 +void Vector2::Transform(const Matrix3x3 &mat) {
  48.541 +	float nx = x * mat.m[0][0] + y * mat.m[1][0] + mat.m[2][0];
  48.542 +	y = x * mat.m[0][1] + y * mat.m[1][1] + mat.m[2][1];
  48.543 +	x = nx;
  48.544 +}
  48.545 +
  48.546 +void Vector2::Translate(float x, float y) {
  48.547 +	this->x += x;
  48.548 +	this->y += y;
  48.549 +}
  48.550 +
  48.551 +void Vector2::Rotate(float angle) {
  48.552 +	Matrix3x3 xform;
  48.553 +	xform.SetRotation(angle);
  48.554 +
  48.555 +	Transform(xform);
  48.556 +}
  48.557 +
  48.558 +void Vector2::Scale(float x, float y) {
  48.559 +	this->x *= x;
  48.560 +	this->y *= y;
  48.561 +}
  48.562 +
  48.563 +float &Vector2::operator [](int index) {
  48.564 +	return !index ? x : y;
  48.565 +}
  48.566 +
  48.567 +std::ostream &operator <<(std::ostream &out, const Vector2 &vec) {
  48.568 +	out << vec.x << ", " << vec.y;
  48.569 +	return out;
  48.570 +}
  48.571 +
  48.572 +
  48.573 +// --------------- Quaternion implementation ---------------
  48.574 +
  48.575 +Quaternion::Quaternion() {
  48.576 +	s = 1.0f;
  48.577 +	v.x = v.y = v.z = 0.0f;
  48.578 +}
  48.579 +
  48.580 +Quaternion::Quaternion(float s, float x, float y, float z) {
  48.581 +	v.x = x;
  48.582 +	v.y = y;
  48.583 +	v.z = z;
  48.584 +	this->s = s;
  48.585 +}
  48.586 +
  48.587 +Quaternion::Quaternion(float s, const Vector3 &v) {
  48.588 +	this->s = s;
  48.589 +	this->v = v;
  48.590 +}
  48.591 +
  48.592 +Quaternion Quaternion::operator +(const Quaternion &quat) const {
  48.593 +	return Quaternion(s + quat.s, v + quat.v);
  48.594 +}
  48.595 +
  48.596 +Quaternion Quaternion::operator -(const Quaternion &quat) const {
  48.597 +	return Quaternion(s - quat.s, v - quat.v);
  48.598 +}
  48.599 +
  48.600 +Quaternion Quaternion::operator -() const {
  48.601 +	return Quaternion(-s, -v);
  48.602 +}
  48.603 +
  48.604 +// Quaternion Multiplication:
  48.605 +// Q1*Q2 = [s1*s2 - v1.v2,  s1*v2 + s2*v1 + v1(x)v2]
  48.606 +Quaternion Quaternion::operator *(const Quaternion &quat) const {
  48.607 +	Quaternion newq;	
  48.608 +	newq.s = s * quat.s - DotProduct(v, quat.v);
  48.609 +	newq.v = quat.v * s + v * quat.s + CrossProduct(v, quat.v);	
  48.610 +	return newq;
  48.611 +}
  48.612 +
  48.613 +void Quaternion::operator +=(const Quaternion &quat) {
  48.614 +	*this = Quaternion(s + quat.s, v + quat.v);
  48.615 +}
  48.616 +
  48.617 +void Quaternion::operator -=(const Quaternion &quat) {
  48.618 +	*this = Quaternion(s - quat.s, v - quat.v);
  48.619 +}
  48.620 +
  48.621 +void Quaternion::operator *=(const Quaternion &quat) {
  48.622 +	*this = *this * quat;
  48.623 +}
  48.624 +
  48.625 +void Quaternion::ResetIdentity() {
  48.626 +	s = 1.0f;
  48.627 +	v.x = v.y = v.z = 0.0f;
  48.628 +}
  48.629 +
  48.630 +Quaternion Quaternion::Conjugate() const {
  48.631 +	return Quaternion(s, -v);
  48.632 +}
  48.633 +
  48.634 +float Quaternion::Length() const {
  48.635 +	return (float)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s);
  48.636 +}
  48.637 +
  48.638 +// Q * ~Q = ||Q||^2
  48.639 +float Quaternion::LengthSq() const {
  48.640 +	return v.x*v.x + v.y*v.y + v.z*v.z + s*s;
  48.641 +}
  48.642 +
  48.643 +void Quaternion::Normalize() {
  48.644 +	float len = (float)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s);
  48.645 +	v.x /= len;
  48.646 +	v.y /= len;
  48.647 +	v.z /= len;
  48.648 +	s /= len;
  48.649 +}
  48.650 +
  48.651 +Quaternion Quaternion::Normalized() const {
  48.652 +	Quaternion nq = *this;
  48.653 +	float len = (float)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s);
  48.654 +	nq.v.x /= len;
  48.655 +	nq.v.y /= len;
  48.656 +	nq.v.z /= len;
  48.657 +	nq.s /= len;
  48.658 +	return nq;
  48.659 +}
  48.660 +
  48.661 +// Quaternion Inversion: Q^-1 = ~Q / ||Q||^2
  48.662 +Quaternion Quaternion::Inverse() const {
  48.663 +	Quaternion inv = Conjugate();
  48.664 +	float lensq = LengthSq();
  48.665 +	inv.v /= lensq;
  48.666 +	inv.s /= lensq;
  48.667 +
  48.668 +	return inv;
  48.669 +}
  48.670 +
  48.671 +
  48.672 +void Quaternion::SetRotation(const Vector3 &axis, float angle) {
  48.673 +	float HalfAngle = angle / 2.0f;
  48.674 +	s = cosf(HalfAngle);
  48.675 +	v = axis * sinf(HalfAngle);
  48.676 +}
  48.677 +
  48.678 +void Quaternion::Rotate(const Vector3 &axis, float angle) {
  48.679 +	Quaternion q;
  48.680 +	float HalfAngle = angle / 2.0f;
  48.681 +	q.s = cosf(HalfAngle);
  48.682 +	q.v = axis * sinf(HalfAngle);
  48.683 +
  48.684 +	*this *= q;
  48.685 +}
  48.686 +
  48.687 +
  48.688 +Matrix3x3 Quaternion::GetRotationMatrix() const {
  48.689 +	return Matrix3x3(1.0f - 2.0f * v.y*v.y - 2.0f * v.z*v.z,		2.0f * v.x * v.y + 2.0f * s * v.z,			2.0f * v.z * v.x - 2.0f * s * v.y,
  48.690 +						2.0f * v.x * v.y - 2.0f * s * v.z,		1.0f - 2.0f * v.x*v.x - 2.0f * v.z*v.z,			2.0f * v.y * v.z + 2.0f * s * v.x,
  48.691 +						2.0f * v.z * v.x + 2.0f * s * v.y,			2.0f * v.y * v.z - 2.0f * s * v.x,		1.0f - 2.0f * v.x*v.x - 2.0f * v.y*v.y);
  48.692 +}
  48.693 +
  48.694 +
  48.695 +// ------------- Matrix implementation ---------------
  48.696 +
  48.697 +Matrix4x4::Matrix4x4() {
  48.698 +	memset(m, 0, 16*sizeof(float));
  48.699 +	m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
  48.700 +}
  48.701 +
  48.702 +Matrix4x4::Matrix4x4(const Matrix4x4 &mat) {
  48.703 +	memcpy(m, mat.m, 16*sizeof(float));
  48.704 +}
  48.705 +
  48.706 +Matrix4x4::Matrix4x4(const Matrix3x3 &mat) {
  48.707 +	for(int i=0; i<3; i++) {
  48.708 +		for(int j=0; j<3; j++) {
  48.709 +			m[i][j] = mat.m[i][j];
  48.710 +		}
  48.711 +	}
  48.712 +	m[3][0] = m[3][1] = m[3][2] = m[0][3] = m[1][3] = m[2][3] = 0.0f;
  48.713 +	m[3][3] = 1.0f;
  48.714 +}
  48.715 +
  48.716 +Matrix4x4::Matrix4x4(	float m00, float m01, float m02, float m03,
  48.717 +						float m10, float m11, float m12, float m13,
  48.718 +						float m20, float m21, float m22, float m23,
  48.719 +						float m30, float m31, float m32, float m33 ) {
  48.720 +
  48.721 +	memcpy(m, &m00, 16*sizeof(float));	// arguments are adjacent in stack
  48.722 +}
  48.723 +
  48.724 +Matrix4x4 Matrix4x4::operator +(const Matrix4x4 &mat) const {
  48.725 +
  48.726 +	Matrix4x4 tmp;
  48.727 +
  48.728 +	const float *op1 = (float*)m;
  48.729 +	const float *op2 = (float*)mat.m;
  48.730 +	float *dst = (float*)tmp.m;
  48.731 +
  48.732 +	for(int i=0; i<16; i++) *dst++ = *op1++ + *op2++;
  48.733 +
  48.734 +	return tmp;
  48.735 +}
  48.736 +
  48.737 +Matrix4x4 Matrix4x4::operator -(const Matrix4x4 &mat) const {
  48.738 +
  48.739 +	Matrix4x4 tmp;
  48.740 +
  48.741 +	const float *op1 = (float*)m;
  48.742 +	const float *op2 = (float*)mat.m;
  48.743 +	float *dst = (float*)tmp.m;
  48.744 +
  48.745 +	for(int i=0; i<16; i++) *dst++ = *op1++ - *op2++;
  48.746 +
  48.747 +	return tmp;
  48.748 +}
  48.749 +
  48.750 +Matrix4x4 Matrix4x4::operator *(float scalar) const {
  48.751 +
  48.752 +	Matrix4x4 tmp;
  48.753 +
  48.754 +	const float *op1 = (float*)m;
  48.755 +	float *dst = (float*)tmp.m;
  48.756 +
  48.757 +	for(int i=0; i<16; i++) *dst++ = *op1++ * scalar;
  48.758 +
  48.759 +	return tmp;
  48.760 +}
  48.761 +
  48.762 +Matrix4x4 Matrix4x4::operator *(const Matrix4x4 &mat) const {
  48.763 +	Matrix4x4 tmp;
  48.764 +
  48.765 +	for(int i=0; i<4; i++) {
  48.766 +		for(int j=0; j<4; j++) {
  48.767 +			tmp.m[i][j] = m[i][0]*mat.m[0][j] + m[i][1]*mat.m[1][j] + m[i][2]*mat.m[2][j] + m[i][3]*mat.m[3][j];
  48.768 +		}
  48.769 +	}
  48.770 +
  48.771 +	return tmp;
  48.772 +}
  48.773 +
  48.774 +void Matrix4x4::operator +=(const Matrix4x4 &mat) {
  48.775 +
  48.776 +	const float *op2 = (float*)mat.m;
  48.777 +	float *dst = (float*)m;
  48.778 +
  48.779 +	for(int i=0; i<16; i++) *dst++ += *op2++;
  48.780 +}
  48.781 +
  48.782 +void Matrix4x4::operator -=(const Matrix4x4 &mat) {
  48.783 +
  48.784 +	const float *op2 = (float*)mat.m;
  48.785 +	float *dst = (float*)m;
  48.786 +
  48.787 +	for(int i=0; i<16; i++) *dst++ -= *op2++;
  48.788 +}
  48.789 +
  48.790 +void Matrix4x4::operator *=(float scalar) {
  48.791 +
  48.792 +	float *dst = (float*)m;
  48.793 +
  48.794 +	for(int i=0; i<16; i++) *dst++ *= scalar;
  48.795 +}
  48.796 +
  48.797 +void Matrix4x4::operator *=(const Matrix4x4 &mat) {
  48.798 +	Matrix4x4 tmp;
  48.799 +
  48.800 +	for(int i=0; i<4; i++) {
  48.801 +		for(int j=0; j<4; j++) {
  48.802 +			tmp.m[i][j] = m[i][0]*mat.m[0][j] + m[i][1]*mat.m[1][j] + m[i][2]*mat.m[2][j] + m[i][3]*mat.m[3][j];
  48.803 +		}
  48.804 +	}
  48.805 +
  48.806 +	memcpy(m, tmp.m, 16*sizeof(float));
  48.807 +}
  48.808 +
  48.809 +
  48.810 +void Matrix4x4::ResetIdentity() {
  48.811 +	memset(m, 0, 16*sizeof(float));
  48.812 +	m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
  48.813 +}
  48.814 +
  48.815 +
  48.816 +// Transformations (assuming column vectors)
  48.817 +
  48.818 +void Matrix4x4::Translate(float x, float y, float z) {
  48.819 +	
  48.820 +	Matrix4x4 tmp(	1, 0, 0, 0,
  48.821 +					0, 1, 0, 0,
  48.822 +					0, 0, 1, 0,
  48.823 +					x, y, z, 1 );
  48.824 +	*this *= tmp;
  48.825 +}
  48.826 +
  48.827 +void Matrix4x4::Rotate(float x, float y, float z) {
  48.828 +
  48.829 +	*this *= Matrix4x4(	1,	0,			0,			0,
  48.830 +						0,	fcos(x),	fsin(x),	0,
  48.831 +						0,	-fsin(x),	fcos(x),	0,
  48.832 +						0,	0,			0,			1 );
  48.833 +	
  48.834 +	*this *= Matrix4x4(	fcos(y),	0,	-fsin(y),	0,
  48.835 +						0,			1,	0,			0,
  48.836 +						fsin(y),	0,	fcos(y),	0,
  48.837 +						0,			0,	0,			1 );
  48.838 +
  48.839 +	*this *= Matrix4x4(	fcos(z),	fsin(z),	0,	0,
  48.840 +						-fsin(z),	fcos(z),	0,	0,
  48.841 +						0,			0,			1,	0,
  48.842 +						0,			0,			0,	1 );
  48.843 +}
  48.844 +
  48.845 +void Matrix4x4::Rotate(const Vector3 &axis, float angle) {
  48.846 +
  48.847 +	float sina = fsin(angle);
  48.848 +	float cosa = fcos(angle);
  48.849 +	float invcosa = 1-cosa;
  48.850 +	float nxsq = axis.x * axis.x;
  48.851 +	float nysq = axis.y * axis.y;
  48.852 +	float nzsq = axis.z * axis.z;
  48.853 +
  48.854 +	Matrix4x4 xform;
  48.855 +	xform.m[0][0] = nxsq + (1-nxsq) * cosa;
  48.856 +	xform.m[0][1] = axis.x * axis.y * invcosa - axis.z * sina;
  48.857 +	xform.m[0][2] = axis.x * axis.z * invcosa + axis.y * sina;
  48.858 +	xform.m[1][0] = axis.x * axis.y * invcosa + axis.z * sina;
  48.859 +	xform.m[1][1] = nysq + (1-nysq) * cosa;
  48.860 +	xform.m[1][2] = axis.y * axis.z * invcosa - axis.x * sina;
  48.861 +	xform.m[2][0] = axis.x * axis.z * invcosa - axis.y * sina;
  48.862 +	xform.m[2][1] = axis.y * axis.z * invcosa + axis.x * sina;
  48.863 +	xform.m[2][2] = nzsq + (1-nzsq) * cosa;
  48.864 +
  48.865 +	*this *= xform;
  48.866 +}
  48.867 +
  48.868 +void Matrix4x4::Scale(float x, float y, float z) {
  48.869 +	
  48.870 +	Matrix4x4 xform(x, 0, 0, 0,
  48.871 +					0, y, 0, 0,
  48.872 +					0, 0, z, 0,
  48.873 +					0, 0, 0, 1 );
  48.874 +	*this *= xform;
  48.875 +}
  48.876 +
  48.877 +
  48.878 +//////////////////////////////
  48.879 +
  48.880 +void Matrix4x4::SetTranslation(float x, float y, float z) {
  48.881 +	
  48.882 +	*this = Matrix4x4(	1, 0, 0, 0,
  48.883 +						0, 1, 0, 0,
  48.884 +						0, 0, 1, 0,
  48.885 +						x, y, z, 1 );
  48.886 +}
  48.887 +
  48.888 +void Matrix4x4::SetRotation(float x, float y, float z) {
  48.889 +
  48.890 +	*this = Matrix4x4(	1,	0,			0,			0,
  48.891 +						0,	fcos(x),	fsin(x),	0,
  48.892 +						0,	-fsin(x),	fcos(x),	0,
  48.893 +						0,	0,			0,			1 );
  48.894 +	
  48.895 +	*this *= Matrix4x4(	fcos(y),	0,	-fsin(y),	0,
  48.896 +						0,			1,	0,			0,
  48.897 +						fsin(y),	0,	fcos(y),	0,
  48.898 +						0,			0,	0,			1 );
  48.899 +
  48.900 +	*this *= Matrix4x4(	fcos(z),	fsin(z),	0,	0,
  48.901 +						-fsin(z),	fcos(z),	0,	0,
  48.902 +						0,			0,			1,	0,
  48.903 +						0,			0,			0,	1 );
  48.904 +}
  48.905 +
  48.906 +void Matrix4x4::SetRotation(const Vector3 &axis, float angle) {
  48.907 +
  48.908 +	// caching of multiply used function results (opt)
  48.909 +	float sina = fsin(angle);
  48.910 +	float cosa = fcos(angle);
  48.911 +	float invcosa = 1-cosa;
  48.912 +	float nxsq = axis.x * axis.x;
  48.913 +	float nysq = axis.y * axis.y;
  48.914 +	float nzsq = axis.z * axis.z;
  48.915 +
  48.916 +	Matrix4x4 xform;
  48.917 +	xform.m[0][0] = nxsq + (1-nxsq) * cosa;
  48.918 +	xform.m[0][1] = axis.x * axis.y * invcosa - axis.z * sina;
  48.919 +	xform.m[0][2] = axis.x * axis.z * invcosa + axis.y * sina;
  48.920 +	xform.m[1][0] = axis.x * axis.y * invcosa + axis.z * sina;
  48.921 +	xform.m[1][1] = nysq + (1-nysq) * cosa;
  48.922 +	xform.m[1][2] = axis.y * axis.z * invcosa - axis.x * sina;
  48.923 +	xform.m[2][0] = axis.x * axis.z * invcosa - axis.y * sina;
  48.924 +	xform.m[2][1] = axis.y * axis.z * invcosa + axis.x * sina;
  48.925 +	xform.m[2][2] = nzsq + (1-nzsq) * cosa;
  48.926 +
  48.927 +	*this = xform;
  48.928 +}
  48.929 +
  48.930 +void Matrix4x4::SetScaling(float x, float y, float z) {
  48.931 +	
  48.932 +	Matrix4x4 xform(x, 0, 0, 0,
  48.933 +					0, y, 0, 0,
  48.934 +					0, 0, z, 0,
  48.935 +					0, 0, 0, 1 );
  48.936 +	*this = xform;
  48.937 +}
  48.938 +
  48.939 +void Matrix4x4::SetColumnVector(const Vector4 &vec, int columnindex) {
  48.940 +	
  48.941 +	m[0][columnindex] = vec.x;
  48.942 +	m[1][columnindex] = vec.y;
  48.943 +	m[2][columnindex] = vec.z;
  48.944 +	m[3][columnindex] = vec.w;
  48.945 +}
  48.946 +
  48.947 +void Matrix4x4::SetRowVector(const Vector4 &vec, int rowindex) {
  48.948 +
  48.949 +	m[rowindex][0] = vec.x;
  48.950 +	m[rowindex][1] = vec.y;
  48.951 +	m[rowindex][2] = vec.z;
  48.952 +	m[rowindex][3] = vec.w;
  48.953 +}
  48.954 +
  48.955 +Vector4 Matrix4x4::GetColumnVector(int columnindex) const {
  48.956 +
  48.957 +	return Vector4(m[0][columnindex], m[1][columnindex], m[2][columnindex], m[3][columnindex]);
  48.958 +}
  48.959 +
  48.960 +Vector4 Matrix4x4::GetRowVector(int rowindex) const {
  48.961 +
  48.962 +	return Vector4(m[rowindex][0], m[rowindex][1], m[rowindex][2], m[rowindex][3]);
  48.963 +}
  48.964 +
  48.965 +// other operations on matrices
  48.966 +
  48.967 +void Matrix4x4::Transpose() {
  48.968 +	Matrix4x4 mat = *this;
  48.969 +
  48.970 +	for(int i=0; i<4; i++) {
  48.971 +		for(int j=0; j<4; j++) {
  48.972 +			m[i][j] = mat.m[j][i];
  48.973 +		}
  48.974 +	}
  48.975 +}
  48.976 +
  48.977 +Matrix4x4 Matrix4x4::Transposed() const {
  48.978 +	Matrix4x4 mat = *this;
  48.979 +
  48.980 +	for(int i=0; i<4; i++) {
  48.981 +		for(int j=0; j<4; j++) {
  48.982 +			mat.m[i][j] = m[j][i];
  48.983 +		}
  48.984 +	}
  48.985 +
  48.986 +	return mat;
  48.987 +}
  48.988 +
  48.989 +
  48.990 +float Matrix4x4::Determinant() const {
  48.991 +
  48.992 +	float det11 =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  48.993 +					(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
  48.994 +					(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
  48.995 +
  48.996 +	float det12 =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  48.997 +					(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
  48.998 +					(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
  48.999 +
 48.1000 +	float det13 =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
 48.1001 +					(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 48.1002 +					(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 48.1003 +
 48.1004 +	float det14 =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
 48.1005 +					(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
 48.1006 +					(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 48.1007 +
 48.1008 +	return m[0][0] * det11 - m[0][1] * det12 + m[0][2] * det13 - m[0][3] * det14;
 48.1009 +}
 48.1010 +
 48.1011 +
 48.1012 +Matrix4x4 Matrix4x4::Adjoint() const {
 48.1013 +
 48.1014 +	Matrix4x4 coef;
 48.1015 +
 48.1016 +	coef.m[0][0] =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 48.1017 +					(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
 48.1018 +					(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
 48.1019 +	coef.m[0][1] =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 48.1020 +					(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 48.1021 +					(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
 48.1022 +	coef.m[0][2] =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
 48.1023 +					(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 48.1024 +					(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 48.1025 +	coef.m[0][3] =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
 48.1026 +					(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
 48.1027 +					(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 48.1028 +
 48.1029 +	coef.m[1][0] =	(m[0][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 48.1030 +					(m[0][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
 48.1031 +					(m[0][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
 48.1032 +	coef.m[1][1] =	(m[0][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 48.1033 +					(m[0][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 48.1034 +					(m[0][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
 48.1035 +	coef.m[1][2] =	(m[0][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
 48.1036 +					(m[0][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 48.1037 +					(m[0][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 48.1038 +	coef.m[1][3] =	(m[0][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
 48.1039 +					(m[0][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
 48.1040 +					(m[0][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 48.1041 +
 48.1042 +	coef.m[2][0] =	(m[0][1] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
 48.1043 +					(m[0][2] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) +
 48.1044 +					(m[0][3] * (m[1][1] * m[3][2] - m[3][1] * m[1][2]));
 48.1045 +	coef.m[2][1] =	(m[0][0] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
 48.1046 +					(m[0][2] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
 48.1047 +					(m[0][3] * (m[1][0] * m[3][2] - m[3][0] * m[1][2]));
 48.1048 +	coef.m[2][2] =	(m[0][0] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) -
 48.1049 +					(m[0][1] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
 48.1050 +					(m[0][3] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
 48.1051 +	coef.m[2][3] =	(m[0][0] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])) -
 48.1052 +					(m[0][1] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])) +
 48.1053 +					(m[0][2] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
 48.1054 +
 48.1055 +	coef.m[3][0] =	(m[0][1] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
 48.1056 +					(m[0][2] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) +
 48.1057 +					(m[0][3] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]));
 48.1058 +	coef.m[3][1] =	(m[0][0] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
 48.1059 +					(m[0][2] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
 48.1060 +					(m[0][3] * (m[1][0] * m[2][2] - m[2][0] * m[1][2]));
 48.1061 +	coef.m[3][2] =	(m[0][0] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) -
 48.1062 +					(m[0][1] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
 48.1063 +					(m[0][3] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
 48.1064 +	coef.m[3][3] =	(m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])) -
 48.1065 +					(m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])) +
 48.1066 +					(m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
 48.1067 +
 48.1068 +	coef.Transpose();
 48.1069 +
 48.1070 +	float *elem = (float*)coef.m;
 48.1071 +	for(int i=0; i<4; i++) {
 48.1072 +		for(int j=0; j<4; j++) {
 48.1073 +			coef.m[i][j] = j%2 ? -coef.m[i][j] : coef.m[i][j];
 48.1074 +			if(i%2) coef.m[i][j] = -coef.m[i][j];
 48.1075 +		}
 48.1076 +	}
 48.1077 +
 48.1078 +	return coef;
 48.1079 +}
 48.1080 +
 48.1081 +Matrix4x4 Matrix4x4::Inverse() const {
 48.1082 +
 48.1083 +	Matrix4x4 AdjMat = Adjoint();
 48.1084 +
 48.1085 +	return AdjMat * (1.0f / Determinant());
 48.1086 +}
 48.1087 +
 48.1088 +
 48.1089 +// --------- 3 by 3 matrices implementation --------------
 48.1090 +
 48.1091 +Matrix3x3::Matrix3x3() {
 48.1092 +	memset(m, 0, 9 * sizeof(float));
 48.1093 +	m[0][0] = m[1][1] = m[2][2] = 1.0f;
 48.1094 +}
 48.1095 +
 48.1096 +Matrix3x3::Matrix3x3(const Matrix3x3 &mat) {
 48.1097 +	memcpy(m, mat.m, 9 * sizeof(float));
 48.1098 +}
 48.1099 +
 48.1100 +Matrix3x3::Matrix3x3(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22) {
 48.1101 +	memcpy(m, &m00, 9*sizeof(float));	// arguments are adjacent in stack
 48.1102 +}
 48.1103 +
 48.1104 +Matrix3x3 Matrix3x3::operator +(const Matrix3x3 &mat) const {
 48.1105 +	Matrix3x3 tmp;
 48.1106 +
 48.1107 +	const float *op1 = (float*)m;
 48.1108 +	const float *op2 = (float*)mat.m;
 48.1109 +	float *dst = (float*)tmp.m;
 48.1110 +
 48.1111 +	for(int i=0; i<9; i++) *dst++ = *op1++ + *op2++;
 48.1112 +
 48.1113 +	return tmp;
 48.1114 +}
 48.1115 +
 48.1116 +Matrix3x3 Matrix3x3::operator -(const Matrix3x3 &mat) const {
 48.1117 +	Matrix3x3 tmp;
 48.1118 +
 48.1119 +	const float *op1 = (float*)m;
 48.1120 +	const float *op2 = (float*)mat.m;
 48.1121 +	float *dst = (float*)tmp.m;
 48.1122 +
 48.1123 +	for(int i=0; i<9; i++) *dst++ = *op1++ - *op2++;
 48.1124 +
 48.1125 +	return tmp;
 48.1126 +}
 48.1127 +
 48.1128 +Matrix3x3 Matrix3x3::operator *(const Matrix3x3 &mat) const {
 48.1129 +	Matrix3x3 tmp;
 48.1130 +
 48.1131 +	for(int i=0; i<3; i++) {
 48.1132 +		for(int j=0; j<3; j++) {
 48.1133 +			tmp.m[i][j] = m[i][0]*mat.m[0][j] + m[i][1]*mat.m[1][j] + m[i][2]*mat.m[2][j];
 48.1134 +		}
 48.1135 +	}
 48.1136 +
 48.1137 +	return tmp;
 48.1138 +}
 48.1139 +
 48.1140 +Matrix3x3 Matrix3x3::operator *(float scalar) const {
 48.1141 +	Matrix3x3 tmp;
 48.1142 +
 48.1143 +	const float *op1 = (float*)m;
 48.1144 +	float *dst = (float*)tmp.m;
 48.1145 +
 48.1146 +	for(int i=0; i<9; i++) *dst++ = *op1++ * scalar;
 48.1147 +
 48.1148 +	return tmp;
 48.1149 +}
 48.1150 +
 48.1151 +void Matrix3x3::operator +=(const Matrix3x3 &mat) {
 48.1152 +	const float *op = (float*)mat.m;
 48.1153 +	float *dst = (float*)m;
 48.1154 +
 48.1155 +	for(int i=0; i<9; i++) *dst++ += *op++;
 48.1156 +}
 48.1157 +
 48.1158 +void Matrix3x3::operator -=(const Matrix3x3 &mat) {
 48.1159 +	const float *op = (float*)mat.m;
 48.1160 +	float *dst = (float*)m;
 48.1161 +
 48.1162 +	for(int i=0; i<9; i++) *dst++ -= *op++;
 48.1163 +}
 48.1164 +
 48.1165 +void Matrix3x3::operator *=(const Matrix3x3 &mat) {
 48.1166 +	Matrix4x4 tmp;
 48.1167 +
 48.1168 +	for(int i=0; i<3; i++) {
 48.1169 +		for(int j=0; j<3; j++) {
 48.1170 +			tmp.m[i][j] = m[i][0]*mat.m[0][j] + m[i][1]*mat.m[1][j] + m[i][2]*mat.m[2][j];
 48.1171 +		}
 48.1172 +	}
 48.1173 +
 48.1174 +	memcpy(m, tmp.m, 9*sizeof(float));
 48.1175 +}
 48.1176 +
 48.1177 +void Matrix3x3::operator *=(float scalar) {
 48.1178 +	float *dst = (float*)m;
 48.1179 +
 48.1180 +	for(int i=0; i<9; i++) *dst++ *= scalar;
 48.1181 +}
 48.1182 +
 48.1183 +
 48.1184 +void Matrix3x3::ResetIdentity() {
 48.1185 +	memset(m, 0, 9 * sizeof(float));
 48.1186 +	m[0][0] = m[1][1] = m[2][2] = 1.0f;
 48.1187 +}
 48.1188 +
 48.1189 +void Matrix3x3::Translate(float x, float y) {
 48.1190 +	Matrix3x3 tmp(	1, 0, 0,
 48.1191 +					0, 1, 0,
 48.1192 +					x, y, 1 );
 48.1193 +	*this *= tmp;	
 48.1194 +}
 48.1195 +
 48.1196 +void Matrix3x3::Rotate(float angle) {
 48.1197 +	Matrix3x3 tmp(	fcos(angle), fsin(angle),	0,
 48.1198 +					-fsin(angle), fcos(angle),	0,
 48.1199 +						0,				0,		1 );
 48.1200 +	*this *= tmp;
 48.1201 +}
 48.1202 +
 48.1203 +void Matrix3x3::Scale(float x, float y) {
 48.1204 +	Matrix3x3 tmp(	x, 0, 0,
 48.1205 +					0, y, 0,
 48.1206 +					0, 0, 1);
 48.1207 +
 48.1208 +	*this *= tmp;
 48.1209 +}
 48.1210 +
 48.1211 +void Matrix3x3::SetTranslation(float x, float y) {
 48.1212 +	Matrix3x3(	1, 0, 0,
 48.1213 +				0, 1, 0,
 48.1214 +				x, y, 1 );
 48.1215 +}
 48.1216 +
 48.1217 +void Matrix3x3::SetRotation(float angle) {
 48.1218 +	Matrix3x3(	fcos(angle),	fsin(angle),	0,
 48.1219 +				-fsin(angle),	fcos(angle),	0,
 48.1220 +					0,				0,			1 );
 48.1221 +}
 48.1222 +
 48.1223 +void Matrix3x3::SetScaling(float x, float y) {
 48.1224 +	Matrix3x3(	x, 0, 0,
 48.1225 +				0, y, 0,
 48.1226 +				0, 0, 1 );
 48.1227 +}
 48.1228 +
 48.1229 +void Matrix3x3::SetColumnVector(const Vector3 &vec, int columnindex) {
 48.1230 +	m[columnindex][0] = vec.x;
 48.1231 +	m[columnindex][1] = vec.y;
 48.1232 +	m[columnindex][2] = vec.z;
 48.1233 +}
 48.1234 +
 48.1235 +void Matrix3x3::SetRowVector(const Vector3 &vec, int rowindex) {
 48.1236 +	m[0][rowindex] = vec.x;
 48.1237 +	m[1][rowindex] = vec.y;
 48.1238 +	m[2][rowindex] = vec.z;
 48.1239 +}
 48.1240 +
 48.1241 +Vector3 Matrix3x3::GetColumnVector(int columnindex) const {
 48.1242 +	return Vector3(m[columnindex][0], m[columnindex][1], m[columnindex][2]);
 48.1243 +}
 48.1244 +
 48.1245 +Vector3 Matrix3x3::GetRowVector(int rowindex) const {
 48.1246 +	return Vector3(m[0][rowindex], m[1][rowindex], m[2][rowindex]);
 48.1247 +}
 48.1248 +
 48.1249 +void Matrix3x3::Transpose() {
 48.1250 +	Matrix3x3 mat = *this;
 48.1251 +
 48.1252 +	for(int i=0; i<3; i++) {
 48.1253 +		for(int j=0; j<3; j++) {
 48.1254 +			m[i][j] = mat.m[j][i];
 48.1255 +		}
 48.1256 +	}	
 48.1257 +}
 48.1258 +
 48.1259 +Matrix3x3 Matrix3x3::Transposed() const {
 48.1260 +	Matrix3x3 mat;
 48.1261 +
 48.1262 +	for(int i=0; i<3; i++) {
 48.1263 +		for(int j=0; j<3; j++) {
 48.1264 +			mat.m[i][j] = m[j][i];
 48.1265 +		}
 48.1266 +	}
 48.1267 +
 48.1268 +	return mat;
 48.1269 +}
 48.1270 +
 48.1271 +
 48.1272 +void Matrix3x3::OrthoNormalize() {
 48.1273 +	Vector3 i, j, k;
 48.1274 +	i = GetRowVector(0);
 48.1275 +	j = GetRowVector(1);
 48.1276 +	k = GetRowVector(2);
 48.1277 +
 48.1278 +	i = CrossProduct(j, k);
 48.1279 +	j = CrossProduct(k, i);
 48.1280 +	k = CrossProduct(i, j);
 48.1281 +
 48.1282 +	SetRowVector(i, 0);
 48.1283 +	SetRowVector(j, 1);
 48.1284 +	SetRowVector(k, 2);
 48.1285 +}
 48.1286 +
 48.1287 +Matrix3x3 Matrix3x3::OrthoNormalized() {
 48.1288 +	Vector3 i, j, k;
 48.1289 +	i = GetRowVector(0);
 48.1290 +	j = GetRowVector(1);
 48.1291 +	k = GetRowVector(2);
 48.1292 +
 48.1293 +	i = CrossProduct(j, k);
 48.1294 +	j = CrossProduct(k, i);
 48.1295 +	k = CrossProduct(i, j);
 48.1296 +
 48.1297 +	Matrix3x3 newmat;
 48.1298 +	newmat.SetRowVector(i, 0);
 48.1299 +	newmat.SetRowVector(j, 1);
 48.1300 +	newmat.SetRowVector(k, 2);
 48.1301 +
 48.1302 +	return newmat;
 48.1303 +}
 48.1304 +
 48.1305 +
 48.1306 +
 48.1307 +// ----------- Ray implementation --------------
 48.1308 +Ray::Ray() {
 48.1309 +	Origin = Vector3(0.0f, 0.0f, 0.0f);
 48.1310 +	Direction = Vector3(0.0f, 0.0f, 1.0f);
 48.1311 +	Energy = 1.0f;
 48.1312 +	CurrentIOR = 1.0f;
 48.1313 +}
 48.1314 +
 48.1315 +Ray::Ray(const Vector3 &origin, const Vector3 &direction) {
 48.1316 +	Origin = origin;
 48.1317 +	Direction = direction;
 48.1318 +}
 48.1319 +
 48.1320 +// ----------- Base implementation --------------
 48.1321 +Base::Base() {
 48.1322 +	i = Vector3(1, 0, 0);
 48.1323 +	j = Vector3(0, 1, 0);
 48.1324 +	k = Vector3(0, 0, 1);
 48.1325 +}
 48.1326 +
 48.1327 +Base::Base(const Vector3 &i, const Vector3 &j, const Vector3 &k) {
 48.1328 +	this->i = i;
 48.1329 +	this->j = j;
 48.1330 +	this->k = k;
 48.1331 +}
 48.1332 +
 48.1333 +Base::Base(const Vector3 &dir, bool LeftHanded) {
 48.1334 +	k = dir;
 48.1335 +	j = VECTOR3_J;
 48.1336 +	i = CrossProduct(j, k);
 48.1337 +	j = CrossProduct(k, i);
 48.1338 +}
 48.1339 +
 48.1340 +
 48.1341 +void Base::Rotate(float x, float y, float z) {
 48.1342 +	Matrix4x4 RotMat;
 48.1343 +	RotMat.SetRotation(x, y, z);
 48.1344 +	i.Transform(RotMat);
 48.1345 +	j.Transform(RotMat);
 48.1346 +	k.Transform(RotMat);
 48.1347 +}
 48.1348 +
 48.1349 +void Base::Rotate(const Vector3 &axis, float angle) {
 48.1350 +	Quaternion q;
 48.1351 +	q.SetRotation(axis, angle);
 48.1352 +	i.Transform(q);
 48.1353 +	j.Transform(q);
 48.1354 +	k.Transform(q);
 48.1355 +}
 48.1356 +
 48.1357 +void Base::Rotate(const Matrix4x4 &mat) {
 48.1358 +	i.Transform(mat);
 48.1359 +	j.Transform(mat);
 48.1360 +	k.Transform(mat);
 48.1361 +}
 48.1362 +
 48.1363 +void Base::Rotate(const Quaternion &quat) {
 48.1364 +	i.Transform(quat);
 48.1365 +	j.Transform(quat);
 48.1366 +	k.Transform(quat);
 48.1367 +}
 48.1368 +
 48.1369 +Matrix3x3 Base::CreateRotationMatrix() const {
 48.1370 +	return Matrix3x3(	i.x, i.y, i.z,
 48.1371 +						j.x, j.y, j.z,
 48.1372 +						k.x, k.y, k.z);
 48.1373 +}
 48.1374 \ No newline at end of file
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/src/common/n3dmath.h	Thu Oct 23 01:46:07 2014 +0300
    49.3 @@ -0,0 +1,425 @@
    49.4 +#ifndef _N3DMATH_H_
    49.5 +#define _N3DMATH_H_
    49.6 +
    49.7 +//	- n3dmath.h - 
    49.8 +//	Nuc3D 2 Header File
    49.9 +//	written by: John Tsiombikas (10 Sep 2002)
   49.10 +//	Last Modification: 14 April 2002
   49.11 +//	---------------------------
   49.12 +//	Mathematical stuff
   49.13 +
   49.14 +#include <iostream>
   49.15 +#include <cmath>
   49.16 +
   49.17 +#ifdef NUC3D_VER_DIRECT3D
   49.18 +#include "d3d8.h"	// Direct3D type definitions (D3DMATRIX)
   49.19 +#endif	//NUC3D_VER_DIRECT3D
   49.20 +
   49.21 +// forward declarations
   49.22 +class Matrix4x4;
   49.23 +class Matrix3x3;
   49.24 +class Vector3;
   49.25 +class Vector2;
   49.26 +class Vector4;
   49.27 +class Quaternion;
   49.28 +
   49.29 +// mathematical constants
   49.30 +const float Pi = 3.1415926535897932f;
   49.31 +const float TwoPi = 6.2831853071795865f;// Pi * 2.0f;
   49.32 +const float HalfPi = 1.5707963267948965f; //Pi * 0.5f;
   49.33 +const float QuarterPi = 0.7853981633974483f; //Pi * 0.25f;
   49.34 +const float ThreeQuartersPi = 2.3561944901923450f; //QuarterPi * 3.0f;
   49.35 +
   49.36 +const float XSmallNumber = 1.e-8f;
   49.37 +const float SmallNumber = 1.e-4f;
   49.38 +
   49.39 +// basis vectors
   49.40 +#define VECTOR3_I	(Vector3(1.0f, 0.0f, 0.0f))
   49.41 +#define VECTOR3_J	(Vector3(0.0f, 1.0f, 0.0f))
   49.42 +#define VECTOR3_K	(Vector3(0.0f, 0.0f, 1.0f))
   49.43 +
   49.44 +#define VECTOR2_I	(Vector2(1.0f, 0.0f))
   49.45 +#define VECTOR2_J	(Vector2(0.0f, 1.0f))
   49.46 +
   49.47 +// angle conversion
   49.48 +#define DEGTORAD(a)	(Pi * (a) / 180)
   49.49 +#define RADTODEG(a) ((a) * 180 / Pi)
   49.50 +
   49.51 +
   49.52 +
   49.53 +// ------------- Vector3 class -------------
   49.54 +
   49.55 +#ifdef NUC3D_VER_DIRECT3D	// if we are using Direct3D version
   49.56 +
   49.57 +class Vector3 : public D3DVECTOR {
   49.58 +public:
   49.59 +
   49.60 +#else	// not D3D
   49.61 +
   49.62 +class Vector3 {
   49.63 +public:
   49.64 +	float x, y, z;
   49.65 +
   49.66 +#endif	//NUC3D_VER_DIRECT3D
   49.67 +
   49.68 +	Vector3();
   49.69 +	Vector3(float x, float y, float z);
   49.70 +
   49.71 +	inline float DotProduct(const Vector3 &vec) const;
   49.72 +	inline Vector3 CrossProduct(const Vector3 &vec) const;
   49.73 +
   49.74 +	inline Vector3 operator +(const Vector3 &vec) const;
   49.75 +	inline Vector3 operator -(const Vector3 &vec) const;
   49.76 +	inline Vector3 operator *(float scalar) const;
   49.77 +	inline Vector3 operator /(float scalar) const;
   49.78 +	inline void operator +=(const Vector3 &vec);
   49.79 +	inline void operator -=(const Vector3 &vec);
   49.80 +	inline void operator *=(float scalar);
   49.81 +	inline void operator /=(float scalar);
   49.82 +	inline Vector3 operator -() const;	// unary minus for inversion
   49.83 +
   49.84 +	inline bool operator >(const Vector3 &vec) const;
   49.85 +	inline bool operator <(const Vector3 &vec) const;
   49.86 +	inline bool operator >(float len) const;
   49.87 +	inline bool operator <(float len) const;
   49.88 +	inline bool operator ==(const Vector3 &vec) const;
   49.89 +	inline bool operator ==(float len) const;
   49.90 +
   49.91 +	inline operator Vector2() const;
   49.92 +	inline operator Vector4() const;
   49.93 +
   49.94 +	inline float Length() const;
   49.95 +	inline float LengthSq() const;
   49.96 +	
   49.97 +	inline void Normalize();
   49.98 +	inline Vector3 Normalized() const;
   49.99 +
  49.100 +	inline Vector3 Reflection(const Vector3 &normal) const;
  49.101 +	Vector3 Refraction(const Vector3 &normal, float FromIOR, float ToIOR) const;
  49.102 +	
  49.103 +	void Transform(const Matrix4x4 &mat);	// transform a vector using a transformation matrix
  49.104 +	void Transform(const Quaternion &quat);	// transform by a quaternion
  49.105 +
  49.106 +	// Direct transformations on the vector
  49.107 +	void Translate(float x, float y, float z);
  49.108 +	void Rotate(float x, float y, float z);
  49.109 +	void Rotate(const Vector3 &axis, float angle);
  49.110 +	void Scale(float x, float y, float z);
  49.111 +
  49.112 +	float &operator [](int index);
  49.113 +
  49.114 +	friend std::ostream &operator <<(std::ostream &out, const Vector3 &vec);
  49.115 +};
  49.116 +
  49.117 +inline float DotProduct(const Vector3 &vec1, const Vector3 &vec2);
  49.118 +inline Vector3 CrossProduct(const Vector3 &vec1, const Vector3 &vec2);
  49.119 +
  49.120 +////////////////////// 4-dimensional vectors ////////////////////////////
  49.121 +class Vector4 {
  49.122 +public:
  49.123 +	float x, y, z, w;
  49.124 +
  49.125 +	Vector4();
  49.126 +	Vector4(const Vector4 &vec);
  49.127 +	Vector4(const Vector3 &vec);	// create from a 3 dimensional vector setting w=1
  49.128 +	Vector4(float x, float y, float z, float w);
  49.129 +
  49.130 +	float DotProduct(const Vector4 &vec) const;
  49.131 +	Vector4 CrossProduct(const Vector4 &vec1, const Vector4 &vec2) const;
  49.132 +
  49.133 +	Vector4 operator +(const Vector4 &vec) const;
  49.134 +	Vector4 operator -(const Vector4 &vec) const;
  49.135 +	Vector4 operator *(float scalar) const;
  49.136 +	Vector4 operator /(float scalar) const;
  49.137 +	void operator +=(const Vector4 &vec);
  49.138 +	void operator -=(const Vector4 &vec);
  49.139 +	void operator *=(float scalar);
  49.140 +	void operator /=(float scalar);
  49.141 +	Vector4 operator -() const;	// unary minus for inversion
  49.142 +
  49.143 +	bool operator >(const Vector4 &vec) const;
  49.144 +	bool operator <(const Vector4 &vec) const;
  49.145 +	bool operator >(float len) const;
  49.146 +	bool operator <(float len) const;
  49.147 +	bool operator ==(const Vector4 &vec) const;
  49.148 +	bool operator ==(float len) const;
  49.149 +
  49.150 +	operator Vector3() const;
  49.151 +
  49.152 +	float Length() const;
  49.153 +	float LengthSq() const;
  49.154 +	
  49.155 +	void Normalize();
  49.156 +	Vector4 Normalized() const;
  49.157 +
  49.158 +	void Transform(const Matrix4x4 &mat);	// transform a vector using a transformation matrix
  49.159 +
  49.160 +	// Direct transformations on the vector
  49.161 +	void Translate(float x, float y, float z, float w);
  49.162 +	void Rotate(float x, float y, float z);
  49.163 +	void Rotate(const Vector3 &axis, float angle);
  49.164 +	void Scale(float x, float y, float z, float w);
  49.165 +
  49.166 +	float &operator [](int index);
  49.167 +
  49.168 +	friend std::ostream &operator <<(std::ostream &out, const Vector3 &vec);
  49.169 +};
  49.170 +
  49.171 +float DotProduct(const Vector4 &vec1, const Vector4 &vec2);
  49.172 +Vector4 CrossProduct(const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3);
  49.173 +
  49.174 +///////////////////////////
  49.175 +
  49.176 +class Vector2 {
  49.177 +public:
  49.178 +	float x, y;
  49.179 +
  49.180 +	Vector2();
  49.181 +	Vector2(const Vector2 &vec);
  49.182 +	Vector2(float x, float y);
  49.183 +
  49.184 +	float DotProduct(const Vector2 &vec) const;
  49.185 +	//Vector2 CrossProduct(const Vector2 &vec) const;
  49.186 +
  49.187 +	Vector2 operator +(const Vector2 &vec) const;
  49.188 +	Vector2 operator -(const Vector2 &vec) const;
  49.189 +	Vector2 operator *(float scalar) const;
  49.190 +	Vector2 operator /(float scalar) const;
  49.191 +	void operator +=(const Vector2 &vec);
  49.192 +	void operator -=(const Vector2 &vec);
  49.193 +	void operator *=(float scalar);
  49.194 +	void operator /=(float scalar);
  49.195 +	Vector2 operator -() const;	// unary minus for inversion
  49.196 +
  49.197 +	bool operator >(const Vector2 &vec) const;
  49.198 +	bool operator <(const Vector2 &vec) const;
  49.199 +	bool operator >(float len) const;
  49.200 +	bool operator <(float len) const;
  49.201 +	bool operator ==(const Vector2 &vec) const;
  49.202 +	bool operator ==(float len) const;
  49.203 +
  49.204 +	operator Vector3() const;
  49.205 +	    
  49.206 +	float Length() const;
  49.207 +	float LengthSq() const;
  49.208 +	
  49.209 +	void Normalize();
  49.210 +	Vector2 Normalized() const;
  49.211 +
  49.212 +	Vector2 Reflection(const Vector2 &normal) const;
  49.213 +	Vector2 Refraction(const Vector2 &normal, float FromIOR, float ToIOR) const;
  49.214 +	
  49.215 +	void Transform(const Matrix3x3 &mat);	// transform a vector using a transformation matrix
  49.216 +
  49.217 +	// Direct transformations on the vector
  49.218 +	void Translate(float x, float y);
  49.219 +	void Rotate(float angle);
  49.220 +	void Scale(float x, float y);
  49.221 +
  49.222 +	float &operator [](int index);
  49.223 +
  49.224 +	friend std::ostream &operator <<(std::ostream &out, const Vector2 &vec);
  49.225 +};
  49.226 +
  49.227 +float DotProduct(const Vector3 &vec1, const Vector3 &vec2);
  49.228 +
  49.229 +
  49.230 +struct Vector2i {
  49.231 +	int x, y;
  49.232 +
  49.233 +	Vector2i(int x=0, int y=0) {this->x = x; this->y = y;}
  49.234 +};
  49.235 +
  49.236 +
  49.237 +////////////////// Quaternion ///////////////////////
  49.238 +
  49.239 +class Quaternion {
  49.240 +public:
  49.241 +	float s;
  49.242 +	Vector3 v;
  49.243 +
  49.244 +	Quaternion();
  49.245 +	Quaternion(float s, const Vector3 &v);
  49.246 +	Quaternion(float s, float x, float y, float z);	
  49.247 +
  49.248 +	Quaternion operator +(const Quaternion &quat) const;
  49.249 +	Quaternion operator -(const Quaternion &quat) const;
  49.250 +	Quaternion operator -() const;
  49.251 +	Quaternion operator *(const Quaternion &quat) const;
  49.252 +	
  49.253 +	void operator +=(const Quaternion &quat);
  49.254 +	void operator -=(const Quaternion &quat);
  49.255 +	void operator *=(const Quaternion &quat);
  49.256 +
  49.257 +	void ResetIdentity();
  49.258 +
  49.259 +	Quaternion Conjugate() const;
  49.260 +
  49.261 +	float Length() const;
  49.262 +	float LengthSq() const;
  49.263 +	
  49.264 +	void Normalize();
  49.265 +	Quaternion Normalized() const;
  49.266 +
  49.267 +	Quaternion Inverse() const;
  49.268 +
  49.269 +	void SetRotation(const Vector3 &axis, float angle);
  49.270 +	void Rotate(const Vector3 &axis, float angle);
  49.271 +
  49.272 +	Matrix3x3 GetRotationMatrix() const;
  49.273 +};
  49.274 +
  49.275 +	
  49.276 +
  49.277 +////////////////////////// Matrices //////////////////////////////
  49.278 +
  49.279 +#ifdef NUC3D_VER_DIRECT3D	// if we are using Direct3D version
  49.280 +
  49.281 +class Matrix4x4 : public D3DMATRIX {
  49.282 +public:
  49.283 +
  49.284 +#else	// Software or OpenGL version
  49.285 +
  49.286 +class Matrix4x4 {
  49.287 +public:
  49.288 +	float m[4][4];
  49.289 +
  49.290 +#endif	//NUC3D_VER_DIRECT3D
  49.291 +
  49.292 +	Matrix4x4();
  49.293 +	Matrix4x4(const Matrix4x4 &mat);
  49.294 +	Matrix4x4(const Matrix3x3 &mat);
  49.295 +	Matrix4x4(	float m00, float m01, float m02, float m03,
  49.296 +				float m10, float m11, float m12, float m13,
  49.297 +				float m20, float m21, float m22, float m23,
  49.298 +				float m30, float m31, float m32, float m33 );
  49.299 +
  49.300 +	// basic operations on matrices
  49.301 +	Matrix4x4 operator +(const Matrix4x4 &mat) const;
  49.302 +	Matrix4x4 operator -(const Matrix4x4 &mat) const;
  49.303 +	Matrix4x4 operator *(const Matrix4x4 &mat) const;
  49.304 +	Matrix4x4 operator *(float scalar) const;
  49.305 +	void operator +=(const Matrix4x4 &mat);
  49.306 +	void operator -=(const Matrix4x4 &mat);
  49.307 +	void operator *=(const Matrix4x4 &mat);
  49.308 +	void operator *=(float scalar);
  49.309 +
  49.310 +	void ResetIdentity();
  49.311 +
  49.312 +	// concatenate various transformation matrices with our current matrix
  49.313 +	void Translate(float x, float y, float z);
  49.314 +	void Rotate(float x, float y, float z);
  49.315 +	void Rotate(const Vector3 &axis, float rads);
  49.316 +	void Scale(float x, float y, float z);
  49.317 +
  49.318 +	// set the matrix to a specific transformation matrix
  49.319 +	void SetTranslation(float x, float y, float z);
  49.320 +	void SetRotation(float x, float y, float z);
  49.321 +	void SetRotation(const Vector3 &axis, float angle);
  49.322 +	void SetScaling(float x, float y, float z);
  49.323 +
  49.324 +	// row and column accessors
  49.325 +	void SetColumnVector(const Vector4 &vec, int columnindex);
  49.326 +	void SetRowVector(const Vector4 &vec, int rowindex);
  49.327 +	Vector4 GetColumnVector(int columnindex) const;
  49.328 +	Vector4 GetRowVector(int rowindex) const;
  49.329 +
  49.330 +	// other operations on matrices
  49.331 +	void Transpose();
  49.332 +	Matrix4x4 Transposed() const;
  49.333 +
  49.334 +	float Determinant() const;
  49.335 +	Matrix4x4 Adjoint() const;
  49.336 +	Matrix4x4 Inverse() const;
  49.337 +};
  49.338 +
  49.339 +
  49.340 +////////////////// Matrix3x3 //////////////////
  49.341 +class Matrix3x3 {
  49.342 +public:
  49.343 +	float m[3][3];
  49.344 +
  49.345 +	Matrix3x3();
  49.346 +	Matrix3x3(const Matrix3x3 &mat);
  49.347 +	Matrix3x3(	float m00, float m01, float m02,
  49.348 +				float m10, float m11, float m12,
  49.349 +				float m20, float m21, float m22 );
  49.350 +
  49.351 +	// basic operations on matrices
  49.352 +	Matrix3x3 operator +(const Matrix3x3 &mat) const;
  49.353 +	Matrix3x3 operator -(const Matrix3x3 &mat) const;
  49.354 +	Matrix3x3 operator *(const Matrix3x3 &mat) const;
  49.355 +	Matrix3x3 operator *(float scalar) const;
  49.356 +	void operator +=(const Matrix3x3 &mat);
  49.357 +	void operator -=(const Matrix3x3 &mat);
  49.358 +	void operator *=(const Matrix3x3 &mat);
  49.359 +	void operator *=(float scalar);
  49.360 +
  49.361 +	void ResetIdentity();
  49.362 +
  49.363 +	// concatenate various transformation matrices with our current matrix
  49.364 +	void Translate(float x, float y);
  49.365 +	void Rotate(float angle);
  49.366 +	void Scale(float x, float y);
  49.367 +	
  49.368 +	// set the matrix to a specific transformation matrix
  49.369 +	void SetTranslation(float x, float y);
  49.370 +	void SetRotation(float angle);
  49.371 +	void SetScaling(float x, float y);
  49.372 +
  49.373 +	// row and column accessors
  49.374 +	void SetColumnVector(const Vector3 &vec, int columnindex);
  49.375 +	void SetRowVector(const Vector3 &vec, int rowindex);
  49.376 +	Vector3 GetColumnVector(int columnindex) const;
  49.377 +	Vector3 GetRowVector(int rowindex) const;
  49.378 +
  49.379 +	// other operations on matrices
  49.380 +	void Transpose();
  49.381 +	Matrix3x3 Transposed() const;
  49.382 +
  49.383 +	void OrthoNormalize();
  49.384 +	Matrix3x3 OrthoNormalized();
  49.385 +
  49.386 +	//float Determinant() const; // NYI
  49.387 +	//Matrix3x3 Adjoint() const;
  49.388 +	//Matrix3x3 Inverse() const;
  49.389 +};
  49.390 +
  49.391 +///////////////// ray /////////////////
  49.392 +
  49.393 +class Ray {
  49.394 +public:
  49.395 +	Vector3 Origin;
  49.396 +	Vector3 Direction;
  49.397 +	float Energy;
  49.398 +	float CurrentIOR;
  49.399 +
  49.400 +	Ray();
  49.401 +	Ray(const Vector3 &origin, const Vector3 &direction);
  49.402 +};
  49.403 +
  49.404 +// a coordinate system basis
  49.405 +class Base {
  49.406 +public:
  49.407 +	Vector3 i, j, k;
  49.408 +
  49.409 +	Base();
  49.410 +	Base(const Vector3 &i, const Vector3 &j, const Vector3 &k);
  49.411 +	Base(const Vector3 &dir, bool LeftHanded=true);
  49.412 +
  49.413 +	void Rotate(float x, float y, float z);
  49.414 +	void Rotate(const Vector3 &axis, float angle);
  49.415 +	void Rotate(const Matrix4x4 &mat);
  49.416 +	void Rotate(const Quaternion &quat);
  49.417 +
  49.418 +	Matrix3x3 CreateRotationMatrix() const;
  49.419 +};
  49.420 +
  49.421 +
  49.422 +
  49.423 +float frand(float range);
  49.424 +
  49.425 +
  49.426 +#include "n3dmath.inl"
  49.427 +
  49.428 +#endif	// _N3DMATH_H_
  49.429 \ No newline at end of file
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/src/common/n3dmath.inl	Thu Oct 23 01:46:07 2014 +0300
    50.3 @@ -0,0 +1,116 @@
    50.4 +float Vector3::DotProduct(const Vector3 &vec) const {
    50.5 +	return x * vec.x + y * vec.y + z * vec.z;
    50.6 +}
    50.7 +
    50.8 +float DotProduct(const Vector3 &vec1, const Vector3 &vec2) {
    50.9 +	return vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z;
   50.10 +}
   50.11 +
   50.12 +Vector3 Vector3::CrossProduct(const Vector3 &vec) const {
   50.13 +	return Vector3(y * vec.z - z * vec.y,  z * vec.x - x * vec.z,  x * vec.y - y * vec.x);
   50.14 +}
   50.15 +
   50.16 +Vector3 CrossProduct(const Vector3 &vec1, const Vector3 &vec2) {
   50.17 +	return Vector3(vec1.y * vec2.z - vec1.z * vec2.y,  vec1.z * vec2.x - vec1.x * vec2.z,  vec1.x * vec2.y - vec1.y * vec2.x);
   50.18 +}
   50.19 +
   50.20 +Vector3 Vector3::operator +(const Vector3 &vec) const {
   50.21 +	return Vector3(x + vec.x, y + vec.y, z + vec.z);
   50.22 +}
   50.23 +
   50.24 +Vector3 Vector3::operator -(const Vector3 &vec) const {
   50.25 +	return Vector3(x - vec.x, y - vec.y, z - vec.z);
   50.26 +}
   50.27 +
   50.28 +Vector3 Vector3::operator *(float scalar) const {
   50.29 +	return Vector3(x * scalar, y * scalar, z * scalar);
   50.30 +}
   50.31 +
   50.32 +Vector3 Vector3::operator /(float scalar) const {
   50.33 +	return Vector3(x / scalar, y / scalar, z / scalar);
   50.34 +}
   50.35 +
   50.36 +void Vector3::operator +=(const Vector3 &vec) {
   50.37 +	x += vec.x;
   50.38 +	y += vec.y;
   50.39 +	z += vec.z;
   50.40 +}
   50.41 +
   50.42 +void Vector3::operator -=(const Vector3 &vec) {
   50.43 +	x -= vec.x;
   50.44 +	y -= vec.y;
   50.45 +	z -= vec.z;
   50.46 +}
   50.47 +
   50.48 +void Vector3::operator *=(float scalar) {
   50.49 +	x *= scalar;
   50.50 +	y *= scalar;
   50.51 +	z *= scalar;
   50.52 +}
   50.53 +
   50.54 +void Vector3::operator /=(float scalar) {
   50.55 +	x /= scalar;
   50.56 +	y /= scalar;
   50.57 +	z /= scalar;
   50.58 +}
   50.59 +
   50.60 +Vector3 Vector3::operator -() const {
   50.61 +	return Vector3(-x, -y, -z);
   50.62 +}
   50.63 +
   50.64 +bool Vector3::operator >(const Vector3 &vec) const {
   50.65 +	return LengthSq() > vec.LengthSq();
   50.66 +}
   50.67 +
   50.68 +bool Vector3::operator <(const Vector3 &vec) const {
   50.69 +	return LengthSq() < vec.LengthSq();
   50.70 +}
   50.71 +
   50.72 +bool Vector3::operator >(float len) const {
   50.73 +	return LengthSq() > len;
   50.74 +}
   50.75 +
   50.76 +bool Vector3::operator <(float len) const {
   50.77 +	return LengthSq() < len;
   50.78 +}
   50.79 +
   50.80 +bool Vector3::operator ==(const Vector3 &vec) const {
   50.81 +	return ((*this - vec).Length() < XSmallNumber);
   50.82 +}
   50.83 +
   50.84 +bool Vector3::operator ==(float len) const {
   50.85 +	return ((this->Length() - len) < XSmallNumber);
   50.86 +}
   50.87 +
   50.88 +Vector3::operator Vector2() const {
   50.89 +	return Vector2(x, y);
   50.90 +}
   50.91 +
   50.92 +Vector3::operator Vector4() const {
   50.93 +	return Vector4(x, y, z, 1.0f);
   50.94 +}
   50.95 +
   50.96 +
   50.97 +float Vector3::Length() const {
   50.98 +	return (float)sqrt(x*x + y*y + z*z);
   50.99 +}
  50.100 +
  50.101 +float Vector3::LengthSq() const {
  50.102 +	return x*x + y*y + z*z;
  50.103 +}
  50.104 +
  50.105 +void Vector3::Normalize() {
  50.106 +	float len = (float)sqrt(x*x + y*y + z*z);
  50.107 +	x /= len;
  50.108 +	y /= len;
  50.109 +	z /= len;
  50.110 +}
  50.111 +
  50.112 +Vector3 Vector3::Normalized() const {
  50.113 +	float len = (float)sqrt(x*x + y*y + z*z);
  50.114 +	return Vector3(x / len, y / len, z / len);
  50.115 +}
  50.116 +
  50.117 +Vector3 Vector3::Reflection(const Vector3 &normal) const {
  50.118 +	return normal * this->DotProduct(normal) * 2.0f - *this;
  50.119 +}
  50.120 \ No newline at end of file
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/src/common/timing.cpp	Thu Oct 23 01:46:07 2014 +0300
    51.3 @@ -0,0 +1,46 @@
    51.4 +#include "timing.h"
    51.5 +
    51.6 +Timer::Timer() {
    51.7 +	QueryPerformanceFrequency(&freq);
    51.8 +	PauseTime.QuadPart = 0;
    51.9 +	paused = false;
   51.10 +}
   51.11 +
   51.12 +void Timer::Start() {
   51.13 +	PauseTime.QuadPart = 0;
   51.14 +	QueryPerformanceCounter(&start);
   51.15 +}
   51.16 +
   51.17 +void Timer::Stop() {
   51.18 +	QueryPerformanceCounter(&LastStop);
   51.19 +}
   51.20 +
   51.21 +void Timer::Resume() {
   51.22 +	LARGE_INTEGER resume;
   51.23 +
   51.24 +	QueryPerformanceCounter(&resume);
   51.25 +
   51.26 +	PauseTime.QuadPart += resume.QuadPart - LastStop.QuadPart;
   51.27 +}
   51.28 +
   51.29 +
   51.30 +unsigned long Timer::GetTicks() const {
   51.31 +	LARGE_INTEGER ticks;
   51.32 +
   51.33 +	QueryPerformanceCounter(&ticks);
   51.34 +	return (unsigned long)(ticks.QuadPart - start.QuadPart - PauseTime.QuadPart);
   51.35 +}
   51.36 +
   51.37 +unsigned long Timer::GetSec() const {
   51.38 +	LARGE_INTEGER ticks;
   51.39 +
   51.40 +	QueryPerformanceCounter(&ticks);
   51.41 +	return (unsigned long)((ticks.QuadPart - start.QuadPart - PauseTime.QuadPart)/freq.QuadPart);
   51.42 +}
   51.43 +
   51.44 +unsigned long Timer::GetMilliSec() const {
   51.45 +	LARGE_INTEGER ticks;
   51.46 +
   51.47 +	QueryPerformanceCounter(&ticks);
   51.48 +	return (unsigned long)((ticks.QuadPart - start.QuadPart - PauseTime.QuadPart)/(freq.QuadPart/1000));
   51.49 +}
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/src/common/timing.h	Thu Oct 23 01:46:07 2014 +0300
    52.3 @@ -0,0 +1,24 @@
    52.4 +#ifndef _TIMING_H_
    52.5 +#define _TIMING_H_
    52.6 +
    52.7 +#include <windows.h>
    52.8 +
    52.9 +class Timer {
   52.10 +private:
   52.11 +	LARGE_INTEGER start, freq;
   52.12 +	LARGE_INTEGER PauseTime, LastStop;
   52.13 +	bool paused;
   52.14 +
   52.15 +public:
   52.16 +
   52.17 +	Timer();
   52.18 +	
   52.19 +	void Start();
   52.20 +	void Stop();
   52.21 +	void Resume();
   52.22 +	unsigned long GetTicks() const;
   52.23 +	unsigned long GetMilliSec() const;
   52.24 +	unsigned long GetSec() const;
   52.25 +};
   52.26 +
   52.27 +#endif	//_TIMING_H_
   52.28 \ No newline at end of file
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/src/common/typedefs.h	Thu Oct 23 01:46:07 2014 +0300
    53.3 @@ -0,0 +1,38 @@
    53.4 +#ifndef _TYPEDEFS_H_
    53.5 +#define _TYPEDEFS_H_
    53.6 +
    53.7 +typedef char int8;
    53.8 +typedef short int16;
    53.9 +typedef long int32;
   53.10 +
   53.11 +typedef unsigned char uint8;
   53.12 +typedef unsigned short uint16;
   53.13 +typedef unsigned long uint32;
   53.14 +
   53.15 +#ifdef _MSC_VER
   53.16 +typedef __int64 int64;
   53.17 +typedef unsigned __int64 uint64;
   53.18 +#else
   53.19 +typedef unsigned long long uint64;
   53.20 +typedef long long int64;
   53.21 +#endif	// _MSC_VER
   53.22 +
   53.23 +typedef uint8	BYTE;
   53.24 +typedef uint16	WORD;
   53.25 +typedef uint32	DWORD;
   53.26 +
   53.27 +typedef uint8	byte;
   53.28 +typedef uint16	word;
   53.29 +typedef uint32	dword;
   53.30 +typedef uint64	qword;
   53.31 +
   53.32 +// Define NULL pointer value 
   53.33 +#ifndef NULL
   53.34 +#ifdef  __cplusplus
   53.35 +#define NULL    0
   53.36 +#else
   53.37 +#define NULL    ((void *)0)
   53.38 +#endif	//__cplusplus
   53.39 +#endif	//NULL
   53.40 +
   53.41 +#endif	//_TYPEDEFS_H_
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/src/demo.cpp	Thu Oct 23 01:46:07 2014 +0300
    54.3 @@ -0,0 +1,242 @@
    54.4 +#include "nwt/startup.h"
    54.5 +#include "nwt/nucwin.h"
    54.6 +#include "3deng/3deng.h"
    54.7 +#include "demosystem/demosys.h"
    54.8 +#include "fmod.h"
    54.9 +
   54.10 +// parts
   54.11 +#include "beginpart.h"
   54.12 +#include "dungeonpart.h"
   54.13 +#include "treepart.h"
   54.14 +#include "tunnelpart.h"
   54.15 +#include "hellpart.h"
   54.16 +#include "greetspart.h"
   54.17 +#include "demonpart.h"
   54.18 +
   54.19 +int ScreenX;
   54.20 +int ScreenY;
   54.21 +
   54.22 +Widget *win;
   54.23 +Engine3D eng3d;
   54.24 +GraphicsContext *gc;
   54.25 +DemoSystem *demo;
   54.26 +FMUSIC_MODULE *mod;
   54.27 +
   54.28 +
   54.29 +// parts
   54.30 +DungeonPart *dungeonpart;
   54.31 +BeginPart *beginpart;
   54.32 +TreePart *treepart;
   54.33 +TunnelPart *tunnelpart;
   54.34 +HellPart *hellpart;
   54.35 +GreetsPart *greetspart;
   54.36 +DemonPart *demonpart;
   54.37 +
   54.38 +bool Init();
   54.39 +void MainLoop();
   54.40 +void CleanUp();
   54.41 +int KeyHandler(Widget *win, int key);
   54.42 +int CloseHandler(Widget *win, int arg);
   54.43 +int MouseHandler(Widget *win, int x, int y, bool left, bool middle, bool right);
   54.44 +int WheelHandler(Widget *win, int x, int y, int rot);
   54.45 +
   54.46 +
   54.47 +int main() {
   54.48 +
   54.49 +	win = NWCreateWindow("The Lab Demos", NWT_CENTERX, NWT_CENTERY, 100, 50, 0);
   54.50 +	SetMainLoopFunc(MainLoop);
   54.51 +	SetHandler(HANDLER_KEY, KeyHandler);
   54.52 +	SetHandler(HANDLER_CLOSE, CloseHandler);
   54.53 +	
   54.54 +	SetHandler(HANDLER_MOUSE, (HandlerFunctionPtr)MouseHandler);
   54.55 +	SetHandler(HANDLER_WHEEL, (HandlerFunctionPtr)WheelHandler);
   54.56 +
   54.57 +
   54.58 +	if(!Init()) return 0;
   54.59 +
   54.60 +	return NWMainLoop(RealTimeLoop);
   54.61 +}
   54.62 +
   54.63 +bool Init() {
   54.64 +
   54.65 +	ContextInitParameters cip;
   54.66 +	try {
   54.67 +		cip = eng3d.LoadContextParamsConfigFile("n3dinit.conf");
   54.68 +		gc = eng3d.CreateGraphicsContext(win, 0, &cip);
   54.69 +	}
   54.70 +	catch(EngineInitException except) {
   54.71 +		MessageBox(win, except.GetReason().c_str(), "Fatal Error", MB_OK | MB_ICONSTOP);
   54.72 +		return false;
   54.73 +	}
   54.74 +	ScreenX = cip.x;
   54.75 +	ScreenY = cip.y;
   54.76 +	NWResize(win, ScreenX, ScreenY);
   54.77 +	NWResizeClientArea(win, WS_OVERLAPPEDWINDOW);
   54.78 +
   54.79 +	ShowCursor(false);
   54.80 +
   54.81 +	// Loading pics....
   54.82 +	Texture *loading[9];
   54.83 +	loading[0] = gc->texman->AddTexture("data/textures/Loading/loading0.jpg");
   54.84 +	loading[1] = gc->texman->AddTexture("data/textures/Loading/loading1.jpg");
   54.85 +	loading[2] = gc->texman->AddTexture("data/textures/Loading/loading2.jpg");
   54.86 +	loading[3] = gc->texman->AddTexture("data/textures/Loading/loading3.jpg");
   54.87 +	loading[4] = gc->texman->AddTexture("data/textures/Loading/loading4.jpg");
   54.88 +	loading[5] = gc->texman->AddTexture("data/textures/Loading/loading5.jpg");
   54.89 +	loading[6] = gc->texman->AddTexture("data/textures/Loading/loading6.jpg");
   54.90 +	loading[7] = gc->texman->AddTexture("data/textures/Loading/loading7.jpg");
   54.91 +	loading[8] = gc->texman->AddTexture("data/textures/Loading/loading8.jpg");
   54.92 +
   54.93 +	demo = new DemoSystem(gc);
   54.94 +	SceneLoader::SetGraphicsContext(gc);
   54.95 +
   54.96 +	Object *quad = new Object(gc);
   54.97 +	quad->CreatePlane(4.0f, 0);
   54.98 +	quad->Scale(1.3333f, 1.0f, 1.0f);
   54.99 +	quad->material = Material(1.0f, 1.0f, 1.0f);
  54.100 +
  54.101 +	Matrix4x4 ViewMat;
  54.102 +	ViewMat.Translate(0.0f, 0.0f, 3.6f);
  54.103 +	gc->SetViewMatrix(ViewMat);
  54.104 +	
  54.105 +	gc->SetZBuffering(false);
  54.106 +	gc->SetLighting(false);
  54.107 +
  54.108 +	quad->material.SetTexture(loading[0], TextureMap);
  54.109 +	quad->Render();
  54.110 +	gc->Flip();
  54.111 +	beginpart = new BeginPart(gc);
  54.112 +	beginpart->SetTimingRel(0, 11000);
  54.113 +	demo->AddPart(beginpart);
  54.114 +
  54.115 +	quad->material.SetTexture(loading[1], TextureMap);
  54.116 +	quad->Render();
  54.117 +	gc->Flip();
  54.118 +	dungeonpart = new DungeonPart(gc);
  54.119 +	dungeonpart->SetTimingRel(11000, 75000);
  54.120 +	demo->AddPart(dungeonpart);
  54.121 +
  54.122 +	quad->material.SetTexture(loading[2], TextureMap);
  54.123 +	quad->Render();
  54.124 +	gc->Flip();
  54.125 +	treepart = new TreePart(gc);
  54.126 +	treepart->SetTimingRel(85900, 40000);
  54.127 +    demo->AddPart(treepart);
  54.128 +
  54.129 +	quad->material.SetTexture(loading[3], TextureMap);
  54.130 +	quad->Render();
  54.131 +	gc->Flip();
  54.132 +	tunnelpart = new TunnelPart(gc);
  54.133 +	tunnelpart->SetTimingRel(125900, 30000);
  54.134 +	demo->AddPart(tunnelpart);
  54.135 +
  54.136 +	quad->material.SetTexture(loading[4], TextureMap);
  54.137 +	quad->Render();
  54.138 +	gc->Flip();
  54.139 +	hellpart = new HellPart(gc);
  54.140 +	hellpart->SetTimingRel(155900, 40000);
  54.141 +	demo->AddPart(hellpart);
  54.142 +
  54.143 +	quad->material.SetTexture(loading[5], TextureMap);
  54.144 +	quad->Render();
  54.145 +	gc->Flip();
  54.146 +	greetspart = new GreetsPart(gc);
  54.147 +	greetspart->SetTimingRel(196000, 12000);
  54.148 +	demo->AddPart(greetspart);
  54.149 +
  54.150 +	quad->material.SetTexture(loading[6], TextureMap);
  54.151 +	quad->Render();
  54.152 +	gc->Flip();
  54.153 +	demonpart = new DemonPart(gc);
  54.154 +	demonpart->SetTimingRel(208000, 2000);
  54.155 +	demo->AddPart(demonpart);
  54.156 +
  54.157 +	quad->material.SetTexture(loading[7], TextureMap);
  54.158 +	quad->Render();
  54.159 +	gc->Flip();
  54.160 +	FSOUND_SetHWND(win);
  54.161 +	FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND);
  54.162 +	FSOUND_SetBufferSize(200);
  54.163 +	FSOUND_Init(44100, 32, FSOUND_INIT_GLOBALFOCUS);
  54.164 +	mod = FMUSIC_LoadSong("data/GOTH03.XM");
  54.165 +	FMUSIC_SetMasterVolume(mod, 250);
  54.166 +
  54.167 +	quad->material.SetTexture(loading[8], TextureMap);
  54.168 +	quad->Render();
  54.169 +	gc->Flip();
  54.170 +	gc->SetBackfaceCulling(true);
  54.171 +	gc->SetZBuffering(true);
  54.172 +	gc->SetLighting(true);
  54.173 +
  54.174 +	Sleep(800);
  54.175 +	
  54.176 +	demo->Run();
  54.177 +
  54.178 +	FMUSIC_PlaySong(mod);
  54.179 +
  54.180 +	return true;
  54.181 +}
  54.182 +
  54.183 +void MainLoop() {
  54.184 +	demo->Update();
  54.185 +	gc->Flip();
  54.186 +}
  54.187 +
  54.188 +void CleanUp() {
  54.189 +	ShowCursor(true);
  54.190 +	FMUSIC_FreeSong(mod);
  54.191 +	FSOUND_Close();
  54.192 +	delete demo;
  54.193 +}
  54.194 +
  54.195 +///////// handlers /////////
  54.196 +int KeyHandler(Widget *win, int key) {
  54.197 +	switch(key) {
  54.198 +	case VK_ESCAPE:
  54.199 +		NWCloseWindow(win);
  54.200 +		break;
  54.201 +
  54.202 +	}
  54.203 +	return 0;
  54.204 +}
  54.205 +
  54.206 +int CloseHandler(Widget *win, int arg) {
  54.207 +	CleanUp();
  54.208 +	return 0;
  54.209 +}
  54.210 +
  54.211 +int WheelHandler(Widget *win, int x, int y, int rot) {
  54.212 +/*	float tr = rot > 0 ? 0.05f : -0.05f;
  54.213 +
  54.214 +	Camera *cam = const_cast<Camera*>(demo->GetActivePath()->GetScene()->GetActiveCamera());
  54.215 +	cam->SetCameraPath(0, 0, 0, 0);
  54.216 +
  54.217 +	cam->Zoom(tr);
  54.218 +*/	
  54.219 +	return 0;
  54.220 +}
  54.221 +
  54.222 +
  54.223 +int MouseHandler(Widget *win, int x, int y, bool left, bool middle, bool right) {
  54.224 +/*	static POINT PrevPos;
  54.225 +	POINT MoveDiff;
  54.226 +
  54.227 +	if(right) {
  54.228 +		MoveDiff.x = x - PrevPos.x;
  54.229 +		MoveDiff.y = y - PrevPos.y;
  54.230 +		float xangle = (float)MoveDiff.x / 50.0f;
  54.231 +		float dy = (float)MoveDiff.y;
  54.232 +
  54.233 +		Camera *cam = const_cast<Camera*>(demo->GetActivePath()->GetScene()->GetActiveCamera());
  54.234 +		cam->SetCameraPath(0, 0, 0, 0);
  54.235 +
  54.236 +		cam->Rotate(0.0f, xangle, 0.0f);
  54.237 +		cam->SetPosition(cam->GetPosition() + Vector3(0.0f, dy, 0.0f));
  54.238 +	}
  54.239 +
  54.240 +
  54.241 +	PrevPos.x = x;
  54.242 +	PrevPos.y = y;
  54.243 +*/
  54.244 +	return 0;
  54.245 +}
  54.246 \ No newline at end of file
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/src/demonpart.cpp	Thu Oct 23 01:46:07 2014 +0300
    55.3 @@ -0,0 +1,40 @@
    55.4 +#include "demonpart.h"
    55.5 +#include "nwt/widget.h"
    55.6 +#include "fmod.h"
    55.7 +
    55.8 +extern Widget *win;
    55.9 +extern FMUSIC_MODULE *mod;
   55.10 +
   55.11 +DemonPart::DemonPart(GraphicsContext *gc) {
   55.12 +	this->gc = gc;
   55.13 +
   55.14 +	//SceneLoader::SetNormalFileSaving(true);
   55.15 +	SceneLoader::SetDataPath("data/textures/");
   55.16 +	SceneLoader::LoadScene("data/geometry/demon.3ds", &scene);
   55.17 +
   55.18 +	curve = scene->GetCurve("Line01");
   55.19 +	curve->SetArcParametrization(true);
   55.20 +	cam = scene->GetCamera("Camera01");
   55.21 +	cam->SetCameraPath(curve, 0, 0, 1500);
   55.22 +}
   55.23 +
   55.24 +DemonPart::~DemonPart() {
   55.25 +	delete scene;
   55.26 +}
   55.27 +
   55.28 +void DemonPart::MainLoop() {
   55.29 +	dword msec = timer.GetMilliSec();
   55.30 +	float t = msec / 1000.0f;
   55.31 +
   55.32 +	FMUSIC_SetMasterVolume(mod, (1500 - msec) / 6);
   55.33 +
   55.34 +	gc->Clear(0);
   55.35 +	gc->ClearZBufferStencil(1.0f, 0);
   55.36 +
   55.37 +	if(t > 1.5f) {
   55.38 +		PostMessage(win, WM_CLOSE, 0, 0);
   55.39 +	}
   55.40 +
   55.41 +	cam->FollowPath(msec);
   55.42 +	scene->Render();
   55.43 +}
   55.44 \ No newline at end of file
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/src/demonpart.h	Thu Oct 23 01:46:07 2014 +0300
    56.3 @@ -0,0 +1,18 @@
    56.4 +#ifndef _DEMONPART_H_
    56.5 +#define _DEMONPART_H_
    56.6 +
    56.7 +#include "demosystem/demosys.h"
    56.8 +
    56.9 +class DemonPart : public Part {
   56.10 +private:
   56.11 +	Camera *cam;
   56.12 +	Curve *curve;
   56.13 +
   56.14 +public:
   56.15 +	DemonPart(GraphicsContext *gc);
   56.16 +	~DemonPart();
   56.17 +
   56.18 +	void MainLoop();
   56.19 +};
   56.20 +
   56.21 +#endif	// _DEMONPART_H_
   56.22 \ No newline at end of file
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/src/demosystem/demosys.cpp	Thu Oct 23 01:46:07 2014 +0300
    57.3 @@ -0,0 +1,212 @@
    57.4 +#include "demosys.h"
    57.5 +
    57.6 +/////////////// Part base class implementation ///////////////
    57.7 +
    57.8 +Part::Part() {
    57.9 +	gc = 0;
   57.10 +
   57.11 +	rmode = RenderModeNormal;
   57.12 +	RenderTexture = 0;
   57.13 +
   57.14 +	SetTimingAbs(0, 0);
   57.15 +	paused = false;
   57.16 +}
   57.17 +
   57.18 +void Part::SetGraphicsContext(GraphicsContext *gc) {
   57.19 +	this->gc = gc;
   57.20 +}
   57.21 +
   57.22 +GraphicsContext *Part::GetGraphicsContext() {
   57.23 +	return gc;
   57.24 +}
   57.25 +
   57.26 +void Part::SetTimingAbs(dword start, dword end) {
   57.27 +	StartTime = start;
   57.28 +	EndTime = end;
   57.29 +	Duration = EndTime - StartTime;
   57.30 +}
   57.31 +
   57.32 +void Part::SetTimingRel(dword start, dword dur) {
   57.33 +	StartTime = start;
   57.34 +	Duration = dur;
   57.35 +	EndTime = StartTime + Duration;
   57.36 +}
   57.37 +
   57.38 +void Part::Pause() {
   57.39 +	if(paused) return;
   57.40 +	timer.Stop();
   57.41 +	paused = true;
   57.42 +}
   57.43 +
   57.44 +void Part::Resume() {
   57.45 +	if(!paused) return;
   57.46 +	timer.Resume();
   57.47 +	paused = false;
   57.48 +}
   57.49 +
   57.50 +dword Part::GetStartTime() const {
   57.51 +	return StartTime;
   57.52 +}
   57.53 +
   57.54 +dword Part::GetEndTime() const {
   57.55 +	return EndTime;
   57.56 +}
   57.57 +
   57.58 +dword Part::GetDuration() const {
   57.59 +	return Duration;
   57.60 +}
   57.61 +
   57.62 +dword Part::GetTimePosition() const {
   57.63 +	return timer.GetMilliSec();
   57.64 +}
   57.65 +
   57.66 +float Part::GetParametricPosition() const {
   57.67 +	return (float)timer.GetMilliSec() / (float)Duration;
   57.68 +}
   57.69 +
   57.70 +void Part::SetRenderMode(RenderMode rmode) {
   57.71 +	this->rmode = rmode;
   57.72 +}
   57.73 +
   57.74 +void Part::SetRenderTexture(Texture *tex) {
   57.75 +	RenderTexture = tex;
   57.76 +}
   57.77 +
   57.78 +RenderMode Part::GetRenderMode() const {
   57.79 +	return rmode;
   57.80 +}
   57.81 +
   57.82 +Texture *Part::GetRenderTexture() const {
   57.83 +	return RenderTexture;
   57.84 +}
   57.85 +
   57.86 +
   57.87 +void Part::Launch() {
   57.88 +	timer.Start();
   57.89 +}
   57.90 +
   57.91 +void Part::ShutDown() {
   57.92 +	// do nothing
   57.93 +}
   57.94 +
   57.95 +Scene *Part::GetScene() {
   57.96 +	return scene;
   57.97 +}
   57.98 +
   57.99 +
  57.100 +/////////////// main Demo System class implementation ///////////////
  57.101 +
  57.102 +DemoSystem::DemoSystem(GraphicsContext *gc) {
  57.103 +	this->gc = gc;
  57.104 +	state = DemoStateStopped;
  57.105 +}
  57.106 +
  57.107 +void DemoSystem::AddPart(Part *part) {
  57.108 +
  57.109 +	if(state != DemoStateStopped) return;
  57.110 +
  57.111 +	if(!part->GetGraphicsContext()) part->SetGraphicsContext(gc);
  57.112 +
  57.113 +	parts.push_back(part);
  57.114 +	inactive.push_back(part);
  57.115 +}
  57.116 +
  57.117 +Part *DemoSystem::GetActivePart() {
  57.118 +	return *active.begin();
  57.119 +}
  57.120 +
  57.121 +//// demo flow control ////
  57.122 +
  57.123 +// Run demo from the beggining
  57.124 +void DemoSystem::Run() {
  57.125 +
  57.126 +	if(state != DemoStateStopped) return;
  57.127 +
  57.128 +	state = DemoStateRunning;
  57.129 +	timer.Start();
  57.130 +}
  57.131 +
  57.132 +// Stop the execution of the demo, discard any sequencing information
  57.133 +void DemoSystem::Stop() {
  57.134 +
  57.135 +	if(state == DemoStateStopped) return;
  57.136 +
  57.137 +	while(active.size()) {
  57.138 +		active.erase(active.begin());
  57.139 +	}
  57.140 +
  57.141 +	inactive = parts;
  57.142 +
  57.143 +	state = DemoStateStopped;
  57.144 +}
  57.145 +
  57.146 +// Pause the demo (freeze the timers)
  57.147 +void DemoSystem::Pause() {
  57.148 +
  57.149 +	if(state != DemoStateRunning) return;
  57.150 +
  57.151 +	std::list<Part*>::iterator iter = active.begin();
  57.152 +	while(iter != active.end()) {
  57.153 +		(*iter++)->Pause();
  57.154 +	}	
  57.155 +	timer.Stop();
  57.156 +	
  57.157 +	state = DemoStatePaused;
  57.158 +}
  57.159 +
  57.160 +void DemoSystem::Resume() {
  57.161 +
  57.162 +	if(state != DemoStatePaused) return;
  57.163 +
  57.164 +	std::list<Part*>::iterator iter = active.begin();
  57.165 +	while(iter != active.end()) {
  57.166 +		(*iter++)->Resume();
  57.167 +	}	
  57.168 +	timer.Resume();
  57.169 +
  57.170 +	state = DemoStateRunning;
  57.171 +}
  57.172 +
  57.173 +
  57.174 +void DemoSystem::Update() {
  57.175 +
  57.176 +	if(state != DemoStateRunning) return;
  57.177 +
  57.178 +	dword time = timer.GetMilliSec();
  57.179 +
  57.180 +	// Check if there are any inactive parts to launch
  57.181 +	std::list<Part*>::iterator iter = inactive.begin();
  57.182 +	while(iter != inactive.end()) {
  57.183 +		if(time >= (*iter)->GetStartTime()) {
  57.184 +			(*iter)->Launch();
  57.185 +			active.push_back(*iter);
  57.186 +			iter = inactive.erase(iter);
  57.187 +		} else {
  57.188 +			iter++;
  57.189 +		}
  57.190 +	}
  57.191 +
  57.192 +	// check if there are any parts to close and close them, and run the valid ones
  57.193 +	iter = active.begin();
  57.194 +	while(iter != active.end()) {
  57.195 +		if(time >= (*iter)->GetEndTime()) {
  57.196 +			(*iter)->ShutDown();
  57.197 +			iter = active.erase(iter);
  57.198 +		} else {
  57.199 +			// run the part
  57.200 +			if((*iter)->GetRenderMode() == RenderModeTexture) {
  57.201 +				gc->SetRenderTarget((*iter)->GetRenderTexture(), (Texture*)0);
  57.202 +				gc->Clear(0);
  57.203 +				gc->ClearZBufferStencil(1.0f, 0);
  57.204 +			}
  57.205 +
  57.206 +			(*iter)->MainLoop();
  57.207 +
  57.208 +			if((*iter)->GetRenderMode() == RenderModeTexture) {
  57.209 +				gc->ResetRenderTarget();
  57.210 +			}
  57.211 +
  57.212 +			iter++;
  57.213 +		}
  57.214 +	}
  57.215 +}
  57.216 \ No newline at end of file
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/src/demosystem/demosys.h	Thu Oct 23 01:46:07 2014 +0300
    58.3 @@ -0,0 +1,97 @@
    58.4 +#ifndef _DEMOSYS_H_
    58.5 +#define _DEMOSYS_H_
    58.6 +
    58.7 +#include <list>
    58.8 +#include "typedefs.h"
    58.9 +#include "timing.h"
   58.10 +
   58.11 +#ifdef NUC3D_API_OPENGL
   58.12 +#include "n3dgl/nuc3dhw.h"
   58.13 +#else
   58.14 +#include "3deng/3deng.h"
   58.15 +#endif
   58.16 +
   58.17 +enum {TIMETYPE_ABSOLUTE, TIMETYPE_RELATIVE};
   58.18 +enum RenderMode {RenderModeNormal, RenderModeTexture};
   58.19 +
   58.20 +// ----- Abstract Base Class Part -----
   58.21 +class Part {
   58.22 +protected:
   58.23 +	GraphicsContext *gc;
   58.24 +	Scene *scene;	// REMOVE
   58.25 +
   58.26 +	dword StartTime, EndTime, Duration;		// in milliseconds
   58.27 +	Timer timer;		// local part timer
   58.28 +
   58.29 +	Texture *RenderTexture;
   58.30 +	RenderMode rmode;
   58.31 +
   58.32 +	bool paused;
   58.33 +
   58.34 +public:
   58.35 +
   58.36 +	Part();
   58.37 +
   58.38 +	virtual void SetGraphicsContext(GraphicsContext *gc);
   58.39 +	virtual GraphicsContext *GetGraphicsContext();
   58.40 +
   58.41 +	virtual void SetTimingAbs(dword start, dword end);
   58.42 +	virtual void SetTimingRel(dword start, dword dur);
   58.43 +	virtual void Pause();
   58.44 +	virtual void Resume();
   58.45 +
   58.46 +	virtual dword GetStartTime() const;
   58.47 +	virtual dword GetEndTime() const;
   58.48 +	virtual dword GetDuration() const;
   58.49 +	virtual dword GetTimePosition() const;
   58.50 +	virtual float GetParametricPosition() const;
   58.51 +
   58.52 +	virtual void SetRenderMode(RenderMode rmode);
   58.53 +	virtual void SetRenderTexture(Texture *tex);
   58.54 +
   58.55 +	virtual RenderMode GetRenderMode() const;
   58.56 +	virtual Texture *GetRenderTexture() const;
   58.57 +
   58.58 +	virtual void Launch();
   58.59 +	virtual void ShutDown();
   58.60 +	virtual void MainLoop() = 0;
   58.61 +
   58.62 +	virtual Scene *GetScene();
   58.63 +};
   58.64 +
   58.65 +enum DemoState {DemoStateRunning, DemoStateStopped, DemoStatePaused};
   58.66 +
   58.67 +class DemoSystem {
   58.68 +private:
   58.69 +	GraphicsContext *gc;
   58.70 +
   58.71 +	std::list<Part*> parts;		// list of all parts
   58.72 +	std::list<Part*> active;	// currently running
   58.73 +	std::list<Part*> inactive;	// waiting to run
   58.74 +
   58.75 +	Timer timer;	// global demo timer
   58.76 +	DemoState state;
   58.77 +
   58.78 +public:
   58.79 +
   58.80 +	DemoSystem(GraphicsContext *gc);
   58.81 +
   58.82 +	void AddPart(Part *part);
   58.83 +	Part *GetActivePart();
   58.84 +
   58.85 +	void Run();
   58.86 +	void Pause();
   58.87 +	void Resume();
   58.88 +	void Stop();
   58.89 +
   58.90 +	void Update();
   58.91 +
   58.92 +	int LoadTiming(const char *filename);
   58.93 +};
   58.94 +
   58.95 +
   58.96 +/////////////// exceptions //////////////
   58.97 +class InvalidParam{};
   58.98 +
   58.99 +
  58.100 +#endif	//_DEMOSYS_H_
  58.101 \ No newline at end of file
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/src/dungeonpart.cpp	Thu Oct 23 01:46:07 2014 +0300
    59.3 @@ -0,0 +1,321 @@
    59.4 +#include "dungeonpart.h"
    59.5 +#include "d3dx8.h"
    59.6 +
    59.7 +DungeonPart::DungeonPart(GraphicsContext *gc) {
    59.8 +
    59.9 +	this->gc = gc;
   59.10 +
   59.11 +	SceneLoader::SetNormalFileSaving(true);
   59.12 +	SceneLoader::SetDataPath("data/textures/");
   59.13 +	SceneLoader::LoadScene("data/geometry/scene2.3ds", &scene);
   59.14 +	
   59.15 +	// setup camera paths
   59.16 +	CamPath[0] = scene->GetCurve("cpath01");
   59.17 +	CamPath[1] = scene->GetCurve("cpath02");
   59.18 +	CamPath[2] = scene->GetCurve("cpath03");
   59.19 +	TargPath[0] = scene->GetCurve("ctarget01");
   59.20 +    TargPath[1] = scene->GetCurve("ctarget03");
   59.21 +
   59.22 +	CamPath[0]->SetArcParametrization(true);
   59.23 +	CamPath[1]->SetArcParametrization(true);
   59.24 +	CamPath[2]->SetArcParametrization(true);
   59.25 +	TargPath[0]->SetArcParametrization(true);
   59.26 +	TargPath[1]->SetArcParametrization(true);
   59.27 +
   59.28 +
   59.29 +	cam[0] = scene->GetCamera("Camera01");
   59.30 +	cam[1] = scene->GetCamera("Camera02");
   59.31 +	cam[2] = scene->GetCamera("Camera03");
   59.32 +	cam[3] = scene->GetCamera("FreeCam");
   59.33 +	
   59.34 +	cam[0]->SetCameraPath(CamPath[0], TargPath[0], 0, 40000);
   59.35 +	cam[1]->SetCameraPath(CamPath[1], 0, 40000, 45000);
   59.36 +	cam[2]->SetCameraPath(CamPath[2], TargPath[1], 45000, 75000);
   59.37 +	
   59.38 +	// get the lava crust under control
   59.39 +	LavaCrust = scene->GetObject("Plane02");
   59.40 +	scene->RemoveObject(LavaCrust);
   59.41 +
   59.42 +	// get the shadow-map walls under control
   59.43 +	ShadowObj[0] = scene->GetObject("TunnelLigh");
   59.44 +	scene->RemoveObject(ShadowObj[0]);
   59.45 +	ShadowObj[1] = scene->GetObject("TunnelLig0");
   59.46 +	scene->RemoveObject(ShadowObj[1]);
   59.47 +
   59.48 +	// load the flame textures
   59.49 +	for(int i=0; i<FLAME_TEXTURES; i++) {
   59.50 +		char num[3];
   59.51 +		itoa(i, num, 10);
   59.52 +		string fname = string("data/textures/flame/flame") + (i < 10 ? string("0") : string("")) + string(num) + string(".jpg");
   59.53 +		FlameTex[i] = gc->texman->AddTexture(fname.c_str());
   59.54 +	}
   59.55 +
   59.56 +	// get the flame objects and remove them from the scene (to take over the rendering)
   59.57 +	for(int i=0; i<16; i++) {
   59.58 +		char num[3];
   59.59 +		itoa(i, num, 10);
   59.60 +		string name = string("Fire") + (i < 10 ? string("0") : string("")) + string(num);
   59.61 +		
   59.62 +		Flame[i] = scene->GetObject(name.c_str());
   59.63 +		scene->RemoveObject(Flame[i]);
   59.64 +	}
   59.65 +
   59.66 +	LightRays = scene->GetObject("LightRays");
   59.67 +	scene->RemoveObject(LightRays);
   59.68 +
   59.69 +	Floor[0] = scene->GetObject("floor1");
   59.70 +	Floor[1] = scene->GetObject("floor2");
   59.71 +	Floor[2] = scene->GetObject("floor3");
   59.72 +	for(int i=0; i<3; i++) scene->RemoveObject(Floor[i]);
   59.73 +
   59.74 +	Obj = scene->GetObject("DefSphere");
   59.75 +	scene->RemoveObject(Obj);
   59.76 +
   59.77 +	mobj = new Object(gc);
   59.78 +	mobj->GetTriMesh()->SetData(Obj->GetTriMesh()->GetVertexArray(), Obj->GetTriMesh()->GetTriangleArray(), Obj->GetTriMesh()->GetVertexCount(), Obj->GetTriMesh()->GetTriangleCount());
   59.79 +
   59.80 +	Obj->material.SetTexture(gc->texman->AddTexture("data/textures/rusty01.jpg"), TextureMap);
   59.81 +	Obj->material.SetTexture(gc->texman->AddTexture("data/textures/refmap1.jpg"), EnvironmentMap);
   59.82 +
   59.83 +	Obj->material.SetAmbient(Color(0.5f));
   59.84 +	Obj->material.SetDiffuse(Color(0.5f));
   59.85 +	Obj->material.SetSpecular(Color(175.0f / 256.0f, 95.0f / 256.0f, 17.0f / 256.0f));
   59.86 +	Obj->material.SetSpecularPower(90.0f);
   59.87 +	Obj->material.SpecularEnable = true;
   59.88 +	mobj->material = Obj->material;
   59.89 +
   59.90 +	Obj->GetTriMesh()->ChangeMode(TriMeshDynamic);
   59.91 +	mobj->GetTriMesh()->ChangeMode(TriMeshDynamic);
   59.92 +
   59.93 +	Crystals[0] = scene->GetObject("Box114");
   59.94 +	Crystals[1] = scene->GetObject("Box115");
   59.95 +	Crystals[2] = scene->GetObject("Box116");
   59.96 +	Crystals[3] = scene->GetObject("Box117");
   59.97 +	Crystals[4] = scene->GetObject("Box118");
   59.98 +
   59.99 +	for(int i=0; i<5; i++) {
  59.100 +		scene->RemoveObject(Crystals[i]);
  59.101 +	}
  59.102 +
  59.103 +	Name = new Object(gc);
  59.104 +	Name->CreatePlane(1.7f, 0);
  59.105 +	Name->Scale(1.0f, 0.3f, 1.0f);
  59.106 +
  59.107 +	Fade = new Object(gc);
  59.108 +	Fade->CreatePlane(3.0f, 0);
  59.109 +	Fade->material = Material(0.0f, 0.0f, 0.0f);
  59.110 +	
  59.111 +	// load name textures
  59.112 +	for(int i=0; i<8; i++) {
  59.113 +		char fname[] = "data/textures/Absence/abx.jpg";
  59.114 +		fname[24] = '1' + i;
  59.115 +		NameTex[i] = gc->texman->AddTexture(fname);
  59.116 +	}
  59.117 +
  59.118 +	cam[3]->Zoom(-1.0f);
  59.119 +}
  59.120 +
  59.121 +DungeonPart::~DungeonPart() {
  59.122 +	delete scene;
  59.123 +}
  59.124 +
  59.125 +#define INRANGE(a, b) (msec >= a && msec < b)
  59.126 +
  59.127 +void DungeonPart::MainLoop() {
  59.128 +	dword msec = timer.GetMilliSec();
  59.129 +	float t = (float)msec / 1000.0f;
  59.130 +
  59.131 +    // set the active camera
  59.132 +	for(int i=0; i<3; i++) {
  59.133 +		cam[i]->FollowPath(msec);
  59.134 +	}
  59.135 +	Vector3 Cam3Pos = cam[3]->GetPosition();
  59.136 +	
  59.137 +	if(msec >= 0 && msec < 40000) {
  59.138 +		scene->SetActiveCamera(cam[0]);
  59.139 +	}
  59.140 +	if(msec >= 39990 && msec < 45000) {
  59.141 +		scene->SetActiveCamera(cam[1]);
  59.142 +	}
  59.143 +	if(msec >= 45000 && msec < 75000) {
  59.144 +		scene->SetActiveCamera(cam[2]);
  59.145 +	}
  59.146 +
  59.147 +	if(INRANGE(17000, 18000) || INRANGE(22000, 23000)) {
  59.148 +		if(INRANGE(22000, 23000)) {
  59.149 +            cam[3]->Rotate(0.0f, t, 0.0f);
  59.150 +		} else {
  59.151 +			cam[3]->Rotate(0.0f, -t, 0.0f);
  59.152 +		}
  59.153 +		scene->SetActiveCamera(cam[3]);
  59.154 +	}
  59.155 +
  59.156 +	gc->Clear(0);
  59.157 +	gc->ClearZBufferStencil(1.0f, 0);
  59.158 +
  59.159 +
  59.160 +	scene->Render();
  59.161 +
  59.162 +	// Render flames
  59.163 +	gc->SetLighting(false);
  59.164 +	gc->SetZWrite(false);
  59.165 +	int ftexnum = (int)((float)msec / 33.35f) % FLAME_TEXTURES;
  59.166 +	gc->SetAlphaBlending(true);
  59.167 +	gc->SetBackfaceCulling(false);
  59.168 +	gc->SetBlendFunc(BLEND_ONE, BLEND_ONE);
  59.169 +	gc->SetTextureStageColor(0, TexBlendModulate, TexArgTexture, TexArgCurrent);
  59.170 +	gc->SetTextureStageAlpha(0, TexBlendSelectArg1, TexArgTexture, TexArgTexture);
  59.171 +	gc->SetMaterial(Flame[0]->material);
  59.172 +	gc->SetTexture(1, 0);
  59.173 +	for(int i=0; i<16; i++) {		
  59.174 +		gc->SetTexture(0, FlameTex[ftexnum]);
  59.175 +		gc->SetWorldMatrix(Flame[i]->GetWorldTransform());
  59.176 +		Flame[i]->RenderBare();
  59.177 +	}
  59.178 +	gc->SetBackfaceCulling(true);
  59.179 +	gc->SetAlphaBlending(false);
  59.180 +	gc->SetZWrite(true);
  59.181 +	gc->SetLighting(true);
  59.182 +
  59.183 +	// render the shadow walls
  59.184 +	gc->SetAlphaBlending(true);
  59.185 +	gc->SetBlendFunc(BLEND_DESTCOLOR, BLEND_ZERO);
  59.186 +	gc->SetTexture(0, ShadowObj[0]->material.Maps[0]);
  59.187 +	gc->SetTextureStageColor(0, TexBlendModulate, TexArgTexture, TexArgDiffuseColor);
  59.188 +	gc->SetMaterial(ShadowObj[0]->material);
  59.189 +	gc->SetWorldMatrix(ShadowObj[0]->GetWorldTransform());
  59.190 +	ShadowObj[0]->RenderBare();
  59.191 +	gc->SetWorldMatrix(ShadowObj[1]->GetWorldTransform());
  59.192 +	ShadowObj[1]->RenderBare();
  59.193 +	gc->SetAlphaBlending(false);
  59.194 +
  59.195 +	// render volumetric light
  59.196 +	gc->SetAlphaBlending(true);
  59.197 +	gc->SetZWrite(false);
  59.198 +
  59.199 +
  59.200 +	LightRays->ResetScaling();
  59.201 +	
  59.202 +	LightRays->material.Alpha = 0.02f;
  59.203 +	LightRays->material.SetEmissive(1.0f, 1.0f, 1.0f);
  59.204 +    for(int i=0; i<14; i++) {
  59.205 +		LightRays->Scale(0.975f, 1.0f, 0.975f);
  59.206 +        LightRays->Render();
  59.207 +	}
  59.208 +	gc->SetZWrite(true);
  59.209 +	gc->SetAlphaBlending(false);
  59.210 +
  59.211 +
  59.212 +	// The Morphing Object
  59.213 +
  59.214 +	Obj->GetTriMesh()->SetData(mobj->GetTriMesh()->GetVertexArray(), mobj->GetTriMesh()->GetTriangleArray(), mobj->GetTriMesh()->GetVertexCount(), mobj->GetTriMesh()->GetTriangleCount());
  59.215 +	
  59.216 +	dword VertCount = Obj->GetTriMesh()->GetVertexCount();
  59.217 +	Vertex *verts = Obj->GetTriMesh()->GetModVertexArray();
  59.218 +	for(dword i=0; i<VertCount; i++) {
  59.219 +		float uangle = DotProduct(verts[i].pos.Normalized(), VECTOR3_I);
  59.220 +		float vangle = DotProduct(verts[i].pos.Normalized(), VECTOR3_J);
  59.221 +
  59.222 +		float sfact = 0.3f * (sinf(uangle * cosf(t) * 5.0f) + sinf(vangle * 7.0f * sinf(t)) + cosf(uangle * cosf(t*2.0f) * 3.0f) * 1.5f);
  59.223 +		verts[i].pos += verts[i].pos * sfact;
  59.224 +	}
  59.225 +	
  59.226 +
  59.227 +	Obj->GetTriMesh()->CalculateNormals();
  59.228 +	Obj->Render();
  59.229 +    
  59.230 +
  59.231 +	// make the lava move
  59.232 +	Matrix3x3 TexMat;
  59.233 +	TexMat.m[2][0] = t/50.0f;
  59.234 +	TexMat.m[2][1] = t/70.0f;
  59.235 +	gc->SetTextureMatrix(TexMat);
  59.236 +	LavaCrust->Render();
  59.237 +	gc->SetTextureMatrix(Matrix4x4());
  59.238 +
  59.239 +	/////// Render the Crystals ///////////
  59.240 +/*
  59.241 +	float StartRise = 4;//53.0f;
  59.242 +	float EndRise = 8;//57.0f;
  59.243 +	float yoffset = -355.0f;
  59.244 +
  59.245 +	if(t >= StartRise && t < EndRise) {
  59.246 +		for(int i=0; i<5; i++) Crystals[i]->SetTranslation(0.0f, (t - StartRise) / (EndRise - StartRise), 0.0f);
  59.247 +	}
  59.248 +*/
  59.249 +	gc->SetShadingMode(FlatShading);
  59.250 +	for(int i=0; i<5; i++) {
  59.251 +		Crystals[i]->Render();
  59.252 +	}
  59.253 +	gc->SetShadingMode(GouraudShading);
  59.254 +
  59.255 +
  59.256 +	//////////////// render the mirroring marble floor ///////////////
  59.257 +
  59.258 +	// burn the stencil baby
  59.259 +	gc->SetZWrite(false);
  59.260 +	gc->SetColorWrite(false, false, false, false);
  59.261 +	gc->SetStencilBuffering(true);
  59.262 +	gc->SetStencilFunc(CMP_ALWAYS);
  59.263 +	gc->SetStencilOp(SOP_KEEP, SOP_KEEP, SOP_INC);
  59.264 +	
  59.265 +	for(int i=0; i<3; i++) Floor[i]->Render();
  59.266 +	gc->SetZWrite(true);
  59.267 +	gc->SetColorWrite(true, true, true, true);
  59.268 +	gc->SetStencilOp(SOP_KEEP, SOP_KEEP, SOP_KEEP);
  59.269 +
  59.270 +	// render the rest of the floor normally
  59.271 +	Floor[0]->ResetRotation();
  59.272 +	Floor[0]->Rotate(0.0f, t/2.0f, 0.0f);
  59.273 +	Floor[1]->ResetRotation();
  59.274 +	Floor[1]->Rotate(0.0f, -t/4.0f, 0.0f);
  59.275 +
  59.276 +	for(int i=0; i<3; i++) Floor[i]->Render();
  59.277 +
  59.278 +	// render the reflection where stencil > 0
  59.279 +	gc->SetStencilFunc(CMP_EQUAL);
  59.280 +	gc->SetStencilReference(1);
  59.281 +	gc->ClearZBuffer(1.0f);
  59.282 +
  59.283 +	gc->SetFrontFace(CounterClockwise);
  59.284 +	
  59.285 +	std::list<Object*> *objlist = scene->GetObjectsList();
  59.286 +	std::list<Object*>::iterator iter = objlist->begin();
  59.287 +	while(iter != objlist->end()) {
  59.288 +		(*iter)->Scale(1.0f, -1.0f, 1.0f);
  59.289 +		float alpha = (*iter)->material.Alpha;
  59.290 +		(*iter)->material.Alpha = 0.25f;
  59.291 +		(*iter)->Render();
  59.292 +		(*iter)->material.Alpha = alpha;
  59.293 +		(*iter++)->Scale(1.0f, -1.0f, 1.0f);
  59.294 +	}
  59.295 +
  59.296 +	gc->SetFrontFace(Clockwise);
  59.297 +	gc->SetStencilBuffering(false);
  59.298 +
  59.299 +	if(t < 6.0f) {
  59.300 +        gc->SetAlphaBlending(true);
  59.301 +		gc->SetLighting(false);
  59.302 +		gc->SetZBuffering(false);
  59.303 +		gc->SetBlendFunc(BLEND_ONE, BLEND_ONE);
  59.304 +		gc->SetMaterial(Material(1.0f, 1.0f, 1.0f));
  59.305 +		gc->SetTexture(0, NameTex[(msec >> 6) % 8]);
  59.306 +		gc->SetTextureStageColor(0, TexBlendSelectArg1, TexArgTexture, TexArgTexture);
  59.307 +		gc->SetTextureStageAlpha(0, TexBlendSelectArg1, TexArgTexture, TexArgTexture);
  59.308 +        gc->SetWorldMatrix(Name->GetWorldTransform());
  59.309 +		Matrix4x4 ViewMat;
  59.310 +		ViewMat.Translate(0.0f, 0.0f, 1.0f);
  59.311 +		gc->SetViewMatrix(ViewMat);
  59.312 +		Name->RenderBare();
  59.313 +		gc->SetLighting(true);
  59.314 +	
  59.315 +		// fade in
  59.316 +		Fade->material.Alpha = min(max(0.0f, (2.0f - t)), 1.0f);
  59.317 +		Fade->Render();
  59.318 +
  59.319 +		gc->SetZBuffering(true);
  59.320 +		gc->SetAlphaBlending(false);
  59.321 +	}
  59.322 +
  59.323 +	cam[3]->SetPosition(Cam3Pos);
  59.324 +}
  59.325 \ No newline at end of file
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/src/dungeonpart.h	Thu Oct 23 01:46:07 2014 +0300
    60.3 @@ -0,0 +1,32 @@
    60.4 +#ifndef _DUNGEONPART_H_
    60.5 +#define _DUNGEONPART_H_
    60.6 +
    60.7 +#include "demosystem/demosys.h"
    60.8 +
    60.9 +#define FLAME_TEXTURES 52
   60.10 +
   60.11 +class DungeonPart : public Part {
   60.12 +private:
   60.13 +	//Scene *scene;
   60.14 +	Texture *FlameTex[FLAME_TEXTURES];
   60.15 +
   60.16 +	Curve *CamPath[4], *TargPath[2];
   60.17 +	Camera *cam[4];
   60.18 +
   60.19 +	Object *Flame[16], *LavaCrust, *ShadowObj[2], *LightRays;
   60.20 +	Object *Floor[3], *Obj, *mobj, *Crystals[5];
   60.21 +
   60.22 +	Object *Name, *Fade;
   60.23 +	Texture *NameTex[8];
   60.24 +
   60.25 +	dword CamTimeSeg[3][2];
   60.26 +
   60.27 +public:
   60.28 +
   60.29 +	DungeonPart(GraphicsContext *gc);
   60.30 +	~DungeonPart();
   60.31 +
   60.32 +	virtual void MainLoop();
   60.33 +};
   60.34 +
   60.35 +#endif	// _DUNGEONPART_H_
   60.36 \ No newline at end of file
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/src/greetspart.cpp	Thu Oct 23 01:46:07 2014 +0300
    61.3 @@ -0,0 +1,97 @@
    61.4 +#include "greetspart.h"
    61.5 +#include "nwt/widget.h"
    61.6 +
    61.7 +extern Widget *win;
    61.8 +
    61.9 +GreetsPart::GreetsPart(GraphicsContext *gc) {
   61.10 +	this->gc = gc;
   61.11 +
   61.12 +	gc->Clear(0);
   61.13 +	gc->ClearZBufferStencil(1.0f, 0);
   61.14 +
   61.15 +
   61.16 +	SceneLoader::SetNormalFileSaving(false);
   61.17 +	SceneLoader::SetDataPath("data/textures/");
   61.18 +	SceneLoader::LoadScene("data/geometry/greets.3ds", &scene);
   61.19 +	SceneLoader::SetNormalFileSaving(true);
   61.20 +
   61.21 +	Parchment = scene->GetObject("Plane01");
   61.22 +	//Scroll1 = scene->GetObject("Object01");
   61.23 +	//Scroll2 = scene->GetObject("Object02");
   61.24 +
   61.25 +	// load the flame textures
   61.26 +	for(int i=0; i<52; i++) {
   61.27 +		char num[3];
   61.28 +		itoa(i, num, 10);
   61.29 +		string fname = string("data/textures/flame/flame") + (i < 10 ? string("0") : string("")) + string(num) + string(".jpg");
   61.30 +		FlameTex[i] = gc->texman->LoadTexture(fname.c_str());
   61.31 +	}
   61.32 +
   61.33 +	flame = scene->GetObject("Plane02");
   61.34 +	scene->RemoveObject(flame);
   61.35 +
   61.36 +	Parchment->SetScaling(9.0f, 1.0f, 1.0f);
   61.37 +
   61.38 +	Bottle = scene->GetObject("Bottle");
   61.39 +	scene->RemoveObject(Bottle);
   61.40 +
   61.41 +	light = scene->GetLight("Omni01");
   61.42 +
   61.43 +    scene->SetShadows(true);
   61.44 +	light->SetShadowCasting(true);
   61.45 +	//scene->GetObject("CHolder")->SetShadowCasting(true);
   61.46 +	scene->GetObject("Candle")->SetShadowCasting(true);
   61.47 +	//scene->GetObject("Bottle01")->SetShadowCasting(true);
   61.48 +
   61.49 +	const Light *l[] = {light};
   61.50 +	scene->GetObject("Cylinder01")->CalculateShadows(l, 1);
   61.51 +	scene->GetObject("Cylinder02")->CalculateShadows(l, 1);
   61.52 +	scene->GetObject("Bottle01")->CalculateShadows(l, 1);
   61.53 +	scene->GetObject("Plane01")->CalculateShadows(l, 1);
   61.54 +
   61.55 +	scene->SetAmbientLight(Color(0.58f, 0.3f, 0.3f));
   61.56 +
   61.57 +	LightPos = light->GetPosition();
   61.58 +	light->SetIntensity(0.5f);
   61.59 +	light->SetAttenuation(0.0f, 0.1f, 0.0f);
   61.60 +
   61.61 +}
   61.62 +
   61.63 +GreetsPart::~GreetsPart() {
   61.64 +	delete scene;
   61.65 +}
   61.66 +
   61.67 +void GreetsPart::MainLoop() {
   61.68 +
   61.69 +	gc->Clear(0);
   61.70 +	gc->ClearZBufferStencil(1.0f, 0);
   61.71 +
   61.72 +	Vector3 LightPosDiff(frand(0.005f) - 0.0025f, frand(0.005f) - 0.0025f, frand(0.005f) - 0.0025f);
   61.73 +	light->SetPosition(LightPos + LightPosDiff);
   61.74 +
   61.75 +	light->SetIntensity(0.5f + (frand(0.1f) - 0.05f));
   61.76 +
   61.77 +	dword msec = timer.GetMilliSec();
   61.78 +	float t = msec / 1000.0f;
   61.79 +
   61.80 +	scene->Render();
   61.81 +
   61.82 +	Bottle->Render();
   61.83 +
   61.84 +	gc->SetLighting(false);
   61.85 +	int ftexnum = (int)((float)msec / 33.35f) % 52;
   61.86 +	gc->SetAlphaBlending(true);
   61.87 +	gc->SetBackfaceCulling(false);
   61.88 +	gc->SetBlendFunc(BLEND_ONE, BLEND_ONE);
   61.89 +	gc->SetTextureStageColor(0, TexBlendSelectArg1, TexArgTexture, TexArgCurrent);
   61.90 +	gc->SetTextureStageAlpha(0, TexBlendSelectArg1, TexArgTexture, TexArgTexture);
   61.91 +	gc->SetMaterial(Material(1.0f, 1.0f, 1.0f));
   61.92 +	gc->SetTextureCoordIndex(0, 0);
   61.93 +	gc->SetTexture(1, 0);
   61.94 +    gc->SetTexture(0, FlameTex[ftexnum]);
   61.95 +	gc->SetWorldMatrix(flame->GetWorldTransform());
   61.96 +	flame->RenderBare();
   61.97 +	gc->SetBackfaceCulling(true);
   61.98 +	gc->SetAlphaBlending(false);
   61.99 +	gc->SetLighting(true);	
  61.100 +}
  61.101 \ No newline at end of file
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/src/greetspart.h	Thu Oct 23 01:46:07 2014 +0300
    62.3 @@ -0,0 +1,24 @@
    62.4 +#ifndef _GREETSPART_H_
    62.5 +#define _GREETSPART_H_
    62.6 +
    62.7 +#include "demosystem/demosys.h"
    62.8 +
    62.9 +class GreetsPart : public Part {
   62.10 +private:
   62.11 +	Camera *cam;
   62.12 +	Object *Parchment, *Scroll1, *Scroll2;
   62.13 +	Texture *FlameTex[52];
   62.14 +	Object *flame, *Bottle;
   62.15 +
   62.16 +	Light *light;
   62.17 +	Vector3 LightPos;
   62.18 +    
   62.19 +
   62.20 +public:
   62.21 +	GreetsPart(GraphicsContext *gc);
   62.22 +	~GreetsPart();
   62.23 +
   62.24 +	void MainLoop();
   62.25 +};
   62.26 +
   62.27 +#endif	// _GREETSPART_H_
   62.28 \ No newline at end of file
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/src/hellpart.cpp	Thu Oct 23 01:46:07 2014 +0300
    63.3 @@ -0,0 +1,225 @@
    63.4 +#include <cassert>
    63.5 +#include "hellpart.h"
    63.6 +
    63.7 +HellPart::HellPart(GraphicsContext *gc) {
    63.8 +	this->gc = gc;
    63.9 +
   63.10 +	SceneLoader::SetNormalFileSaving(true);
   63.11 +	SceneLoader::SetDataPath("data/textures/");
   63.12 +	SceneLoader::LoadScene("data/geometry/hell.3ds", &scene);
   63.13 +
   63.14 +	CamPath = scene->GetCurve("CamPath");
   63.15 +	cam = const_cast<Camera*>(scene->GetActiveCamera());
   63.16 +	cam->SetCameraPath(CamPath, 0, 0, 30000);
   63.17 +	cam->SetClippingPlanes(1.0f, 100000.0f);
   63.18 +
   63.19 +	cam2 = scene->GetCamera("Camera02");
   63.20 +	cam3 = scene->GetCamera("Camera03");
   63.21 +	cam2->SetClippingPlanes(1.0f, 100000.0f);
   63.22 +	cam3->SetClippingPlanes(1.0f, 100000.0f);
   63.23 +
   63.24 +	Thunder = scene->GetLight("Omni01");
   63.25 +	Thunder->SetIntensity(0.0f);
   63.26 +
   63.27 +	ThundEnv[0] = scene->GetObject("b1");
   63.28 +	ThundEnv[1] = scene->GetObject("b2");
   63.29 +	ThundEnv[2] = scene->GetObject("b3");
   63.30 +	ThundEnv[3] = scene->GetObject("b4");
   63.31 +	ThundEnv[4] = scene->GetObject("b5");
   63.32 +	for(int i=0; i<5; i++) {
   63.33 +		scene->RemoveObject(ThundEnv[i]);
   63.34 +	}
   63.35 +
   63.36 +	Stones[0] = scene->GetObject("Box01");
   63.37 +	Stones[1] = scene->GetObject("Box02");
   63.38 +	Stones[2] = scene->GetObject("Box03");
   63.39 +	Stones[3] = scene->GetObject("Box04");
   63.40 +	Stones[4] = scene->GetObject("Box05");
   63.41 +	for(int i=0; i<5; i++) {
   63.42 +		scene->RemoveObject(Stones[i]);
   63.43 +		Stones[i]->SetShadingMode(FlatShading);
   63.44 +	}
   63.45 +
   63.46 +	Rings[0] = scene->GetObject("Tube01");
   63.47 +	Rings[1] = scene->GetObject("Tube02");
   63.48 +	Rings[2] = scene->GetObject("Tube03");
   63.49 +	Rings[3] = scene->GetObject("Tube04");
   63.50 +	Rings[4] = scene->GetObject("Tube05");
   63.51 +	for(int i=0; i<5; i++) {
   63.52 +		scene->RemoveObject(Rings[i]);
   63.53 +	}
   63.54 +
   63.55 +	// Load Credits
   63.56 +	dbgtex = gc->texman->AddTexture("data/textures/psys02.jpg");
   63.57 +	CredNuc[0] = gc->texman->AddTexture("data/textures/credits/nuc1.jpg");
   63.58 +	CredNuc[1] = gc->texman->AddTexture("data/textures/credits/nuc2.jpg");
   63.59 +	CredNuc[2] = gc->texman->AddTexture("data/textures/credits/nuc3.jpg");
   63.60 +	CredNuc[3] = gc->texman->AddTexture("data/textures/credits/nuc4.jpg");
   63.61 +	CredNuc[4] = gc->texman->AddTexture("data/textures/credits/nuc5.jpg");
   63.62 +	CredNuc[5] = gc->texman->AddTexture("data/textures/credits/nuc6.jpg");
   63.63 +	CredNuc[6] = gc->texman->AddTexture("data/textures/credits/nuc7.jpg");
   63.64 +
   63.65 +	CredRaw[0] = gc->texman->AddTexture("data/textures/credits/raw1.jpg");
   63.66 +	CredRaw[1] = gc->texman->AddTexture("data/textures/credits/raw2.jpg");
   63.67 +	CredRaw[2] = gc->texman->AddTexture("data/textures/credits/raw3.jpg");
   63.68 +	CredRaw[3] = gc->texman->AddTexture("data/textures/credits/raw4.jpg");
   63.69 +	CredRaw[4] = gc->texman->AddTexture("data/textures/credits/raw5.jpg");
   63.70 +	CredRaw[5] = gc->texman->AddTexture("data/textures/credits/raw6.jpg");
   63.71 +	CredRaw[6] = gc->texman->AddTexture("data/textures/credits/raw7.jpg");
   63.72 +
   63.73 +	CredAmi[0] = gc->texman->AddTexture("data/textures/credits/am1.jpg");
   63.74 +	CredAmi[1] = gc->texman->AddTexture("data/textures/credits/am2.jpg");
   63.75 +	CredAmi[2] = gc->texman->AddTexture("data/textures/credits/am3.jpg");
   63.76 +	CredAmi[3] = gc->texman->AddTexture("data/textures/credits/am4.jpg");
   63.77 +	CredAmi[4] = gc->texman->AddTexture("data/textures/credits/am5.jpg");
   63.78 +	CredAmi[5] = gc->texman->AddTexture("data/textures/credits/am6.jpg");
   63.79 +	CredAmi[6] = gc->texman->AddTexture("data/textures/credits/am7.jpg");
   63.80 +
   63.81 +	CredAmv[0] = gc->texman->AddTexture("data/textures/credits/amv1.jpg");
   63.82 +	CredAmv[1] = gc->texman->AddTexture("data/textures/credits/amv2.jpg");
   63.83 +	CredAmv[2] = gc->texman->AddTexture("data/textures/credits/amv3.jpg");
   63.84 +	CredAmv[3] = gc->texman->AddTexture("data/textures/credits/amv4.jpg");
   63.85 +	CredAmv[4] = gc->texman->AddTexture("data/textures/credits/amv5.jpg");
   63.86 +	CredAmv[5] = gc->texman->AddTexture("data/textures/credits/amv6.jpg");
   63.87 +	CredAmv[6] = gc->texman->AddTexture("data/textures/credits/amv7.jpg");
   63.88 +
   63.89 +	Credits = new Object(gc);
   63.90 +	Credits->CreatePlane(1.7f, 0);
   63.91 +	Credits->Scale(1.0f, 0.3f, 1.0f);
   63.92 +
   63.93 +	Blood = scene->GetObject("Blood");
   63.94 +	scene->RemoveObject(Blood);
   63.95 +	Grail = scene->GetObject("Object13");
   63.96 +	//scene->RemoveObject(Grail);
   63.97 +}
   63.98 +
   63.99 +HellPart::~HellPart() {
  63.100 +	delete scene;
  63.101 +}
  63.102 +
  63.103 +void HellPart::MainLoop() {
  63.104 +	dword msec = timer.GetMilliSec();
  63.105 +	float t = msec / 1000.0f;
  63.106 +
  63.107 +	// deform blood surface
  63.108 +	Vertex *BloodVerts = Blood->GetTriMesh()->GetModVertexArray();
  63.109 +	dword VertexCount = Blood->GetTriMesh()->GetVertexCount();
  63.110 +
  63.111 +	for(dword i=0; i<VertexCount; i++) {
  63.112 +		Vector2 pos2d(BloodVerts[i].pos.x, BloodVerts[i].pos.z);
  63.113 +		float dist = pos2d.Length();
  63.114 +		BloodVerts[i].pos.y = (1.5f * sinf(dist - t*3.0f)) * (dist > 0.0f ? (1.0f / (dist*1.5f)) : 1.0f);
  63.115 +	}
  63.116 +	Blood->GetTriMesh()->CalculateNormals();
  63.117 +
  63.118 +	
  63.119 +	////////////////////////
  63.120 +
  63.121 +	gc->Clear(0);
  63.122 +	gc->ClearZBufferStencil(1.0f, 0);
  63.123 +
  63.124 +	scene->SetActiveCamera(cam);
  63.125 +
  63.126 +	if(t >= 18.0f && t < 22.0f) {
  63.127 +		scene->SetActiveCamera(cam2);
  63.128 +		Credits->material.SetTexture(CredNuc[(int)(t * 20.0f) % 7], TextureMap);
  63.129 +	}
  63.130 +	if(t >= 24.0f && t < 28.0f) {
  63.131 +		scene->SetActiveCamera(cam3);
  63.132 +		Credits->material.SetTexture(CredRaw[(int)(t * 20.0f) % 7], TextureMap);
  63.133 +	}
  63.134 +	if(t >= 30.0f && t < 34.0f) {
  63.135 +		scene->SetActiveCamera(cam2);
  63.136 +		Credits->material.SetTexture(CredAmi[(int)(t * 20.0f) % 7], TextureMap);
  63.137 +	}
  63.138 +	if(t >= 36.0f && t < 40.0f) {
  63.139 +		scene->SetActiveCamera(cam3);
  63.140 +		Credits->material.SetTexture(CredAmv[(int)(t * 20.0f) % 7], TextureMap);
  63.141 +	}
  63.142 +
  63.143 +	cam->FollowPath(msec);
  63.144 +
  63.145 +	gc->SetAmbientLight(Color(0.5f));
  63.146 +
  63.147 +	scene->Render();
  63.148 +
  63.149 +	for(int i=0; i<5; i++) {
  63.150 +		Matrix4x4 tmat = Stones[i]->TransMat, rmat = Stones[i]->GRotMat;
  63.151 +		Stones[i]->Translate(0.0f, sinf(t) * 54.0f, 0.0f);
  63.152 +		Stones[i]->GlobalRotate(0.0f, t/4.0f, 0.0f);
  63.153 +		
  63.154 +		Stones[i]->Render();
  63.155 +		
  63.156 +		Stones[i]->TransMat = tmat;
  63.157 +		Stones[i]->GRotMat = rmat;
  63.158 +	}
  63.159 +
  63.160 +	float Rot = t / 2.0f;
  63.161 +
  63.162 +	for(int i=0; i<5; i++) {
  63.163 +		Rings[i]->ResetRotation();
  63.164 +	}
  63.165 +
  63.166 +	Rings[0]->Rotate(Rot, 0.0f, 0.0f);
  63.167 +
  63.168 +	Rings[1]->Rotate(0.0f, 0.0f, Rot);
  63.169 +
  63.170 +	Vector3 axis(1.0f, 0.0f, 0.0f);
  63.171 +	axis.Rotate(0.0f, 0.0f, QuarterPi);
  63.172 +	Rings[2]->Rotate(0.0f, 0.0f, QuarterPi);
  63.173 +	Rings[2]->Rotate(axis, Rot);
  63.174 +
  63.175 +	axis = Vector3(0.0f, 0.0f, 1.0f);
  63.176 +	axis.Rotate(QuarterPi, 0.0f, 0.0f);
  63.177 +	Rings[3]->Rotate(QuarterPi, 0.0f, 0.0f);
  63.178 +	Rings[3]->Rotate(axis, Rot);
  63.179 +
  63.180 +	Rings[4]->Rotate(Rot, 0.0f, Rot);
  63.181 +
  63.182 +	gc->SetZWrite(false);
  63.183 +	for(int i=0; i<5; i++) {
  63.184 +		Rings[i]->Render();
  63.185 +	}
  63.186 +	gc->SetZWrite(true);
  63.187 +
  63.188 +	Light *light = scene->GetLight("Spot01");
  63.189 +	light->SetRange(100000.0f);
  63.190 +	light->SetIntensity(0.5f);
  63.191 +	light->SetLight(0, gc);
  63.192 +	Blood->Render();
  63.193 +	light->SetRange(100.0f);
  63.194 +	light->SetLight(0, gc);
  63.195 +
  63.196 +	gc->SetAmbientLight(Color(0.0f));
  63.197 +
  63.198 +	if((t >= 18.0f && t < 22.0f) || (t >= 24.0f && t < 28.0f) || (t >= 30.0f && t < 34.0f) || (t >= 36.0f && t < 40.0f)) {
  63.199 +		gc->SetAlphaBlending(true);
  63.200 +		gc->SetLighting(false);
  63.201 +		gc->SetZBuffering(false);
  63.202 +		gc->SetBlendFunc(BLEND_ONE, BLEND_ONE);
  63.203 +		gc->SetMaterial(Material(1.0f, 1.0f, 1.0f));
  63.204 +		gc->SetTexture(0, Credits->material.Maps[TextureMap]);
  63.205 +		gc->SetTexture(1, 0);
  63.206 +		gc->SetTextureCoordIndex(0, 0);
  63.207 +
  63.208 +		gc->SetTextureStageColor(0, TexBlendSelectArg1, TexArgTexture, TexArgCurrent);
  63.209 +		gc->SetTextureStageAlpha(0, TexBlendSelectArg1, TexArgTexture, TexArgCurrent);
  63.210 +		Matrix4x4 WorldMat;
  63.211 +		WorldMat.Scale(1.0f, 0.3f, 1.0f);
  63.212 +		gc->SetWorldMatrix(WorldMat);
  63.213 +		Matrix4x4 ViewMat;
  63.214 +		ViewMat.Translate(0.0f, 0.0f, 2.0f);
  63.215 +		gc->SetViewMatrix(ViewMat);
  63.216 +		Matrix4x4 ProjMat, OldProj;
  63.217 +		OldProj = gc->GetProjectionMatrix();
  63.218 +		CreateProjectionMatrix(&ProjMat, QuarterPi, 1.333333f, 1.0f, 10.0f);
  63.219 +		gc->SetProjectionMatrix(ProjMat);
  63.220 +
  63.221 +        Credits->RenderBare();
  63.222 +
  63.223 +		gc->SetProjectionMatrix(OldProj);
  63.224 +		gc->SetLighting(true);
  63.225 +		gc->SetZBuffering(true);
  63.226 +		gc->SetAlphaBlending(false);
  63.227 +	}
  63.228 +}
  63.229 \ No newline at end of file
    64.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.2 +++ b/src/hellpart.h	Thu Oct 23 01:46:07 2014 +0300
    64.3 @@ -0,0 +1,31 @@
    64.4 +#ifndef _HELLPART_H_
    64.5 +#define _HELLPART_H_
    64.6 +
    64.7 +#include "demosystem/demosys.h"
    64.8 +
    64.9 +class HellPart : public Part {
   64.10 +private:
   64.11 +	Curve *CamPath;
   64.12 +	Camera *cam, *cam2, *cam3;
   64.13 +	Object *Stones[5];
   64.14 +	Object *Rings[5];
   64.15 +	Light *Thunder;
   64.16 +	Object *ThundEnv[5];
   64.17 +	Object *Credits;
   64.18 +	Object *Blood, *Grail;
   64.19 +	Texture *dbgtex;
   64.20 +	Texture *CredNuc[7];
   64.21 +	Texture *CredAmi[7];
   64.22 +	Texture *CredRaw[7];
   64.23 +	Texture *CredAmv[7];
   64.24 +
   64.25 +
   64.26 +
   64.27 +public:
   64.28 +	HellPart(GraphicsContext *gc);
   64.29 +	~HellPart();
   64.30 +
   64.31 +	void MainLoop();
   64.32 +};
   64.33 +
   64.34 +#endif	// _HELLPART_H_
   64.35 \ No newline at end of file
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/src/nwt/nucwin.cpp	Thu Oct 23 01:46:07 2014 +0300
    65.3 @@ -0,0 +1,174 @@
    65.4 +#include "nucwin.h"
    65.5 +#include <windows.h>
    65.6 +#include <winuser.h>
    65.7 +
    65.8 +#ifndef WM_MOUSEWHEEL
    65.9 +#define WM_MOUSEWHEEL 0x020A
   65.10 +#endif	// WM_MOUSEWHEEL
   65.11 +
   65.12 +MainLoopMode loopmode;
   65.13 +char *Arguments;
   65.14 +
   65.15 +int (*KeyHandlerFunc)(Widget*, int) = 0;
   65.16 +int (*CloseHandlerFunc)(Widget*, int) = 0;
   65.17 +int (*MouseHandlerFunc)(Widget*, int, int, bool, bool, bool) = 0;
   65.18 +int (*MouseUpHandlerFunc)(Widget*, int, int, bool, bool, bool) = 0;
   65.19 +int (*MouseWheelHandlerFunc)(Widget*, int, int, int) = 0;
   65.20 +int (*WinMoveHandlerFunc)(Widget*, int, int) = 0;
   65.21 +int (*PaintHandlerFunc)(Widget*) = 0;
   65.22 +
   65.23 +void (*RealTimeLoopFunc)() = 0;
   65.24 +
   65.25 +void SetHandler(HandlerType htype, int (*Handler)(Widget*, int)) {
   65.26 +	switch(htype) {
   65.27 +	case HANDLER_KEY:
   65.28 +		KeyHandlerFunc = Handler;
   65.29 +		break;
   65.30 +
   65.31 +	case HANDLER_CLOSE:
   65.32 +		CloseHandlerFunc = Handler;
   65.33 +		break;
   65.34 +
   65.35 +	case HANDLER_MOUSE:
   65.36 +		MouseHandlerFunc = (int (*)(Widget*, int, int, bool, bool, bool))Handler;
   65.37 +		break;
   65.38 +
   65.39 +	case HANDLER_MOUSEUP:
   65.40 +		MouseUpHandlerFunc = (int (*)(Widget*, int, int, bool, bool, bool))Handler;
   65.41 +		break;
   65.42 +
   65.43 +	case HANDLER_WHEEL:
   65.44 +		MouseWheelHandlerFunc = (int (*)(Widget*, int, int, int))Handler;
   65.45 +		break;
   65.46 +
   65.47 +	case HANDLER_WINMOVE:
   65.48 +		WinMoveHandlerFunc = (int (*)(Widget*, int, int))Handler;
   65.49 +		break;
   65.50 +
   65.51 +	case HANDLER_PAINT:
   65.52 +		PaintHandlerFunc = (int (*)(Widget*))Handler;
   65.53 +		break;
   65.54 +
   65.55 +	default: break;
   65.56 +	}
   65.57 +}
   65.58 +
   65.59 +void SetMainLoopFunc(void (*func)()) {
   65.60 +	RealTimeLoopFunc = func;
   65.61 +}
   65.62 +
   65.63 +int NWMainLoop(MainLoopMode mode) {
   65.64 +
   65.65 +	MSG msg;
   65.66 +	loopmode = mode;
   65.67 +
   65.68 +	if(mode == RealTimeLoop) {
   65.69 +		while(1) {
   65.70 +			if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
   65.71 +				if(msg.message == WM_QUIT) break;
   65.72 +				TranslateMessage(&msg);
   65.73 +				DispatchMessage(&msg);
   65.74 +			} else {
   65.75 +				if(RealTimeLoopFunc) RealTimeLoopFunc();
   65.76 +			}
   65.77 +		}
   65.78 +	} else {
   65.79 +		while(GetMessage(&msg, 0, 0, 0)) {
   65.80 +			TranslateMessage(&msg);
   65.81 +			DispatchMessage(&msg);
   65.82 +		}
   65.83 +	}
   65.84 +
   65.85 +	return (int)msg.wParam;
   65.86 +}
   65.87 +
   65.88 +bool NWCheckForMessages() {
   65.89 +	MSG msg;
   65.90 +	return (bool)PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE);
   65.91 +}
   65.92 +
   65.93 +
   65.94 +LRESULT CALLBACK MainHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
   65.95 +	switch(msg) {
   65.96 +	case WM_KEYDOWN:
   65.97 +		if(KeyHandlerFunc) return KeyHandlerFunc(hWnd, (int)wParam);
   65.98 +		break;
   65.99 +
  65.100 +	case WM_CLOSE:
  65.101 +		if(CloseHandlerFunc) CloseHandlerFunc(0, 0);
  65.102 +		DestroyWindow(hWnd);
  65.103 +		PostQuitMessage(0);
  65.104 +		return 0;
  65.105 +		break;
  65.106 +
  65.107 +	case WM_MOUSEMOVE:
  65.108 +		if(MouseHandlerFunc) MouseHandlerFunc(hWnd, LOWORD(lParam), HIWORD(lParam), (bool)(wParam & MK_LBUTTON), (bool)(wParam & MK_MBUTTON), (bool)(wParam & MK_RBUTTON));
  65.109 +		break;
  65.110 +
  65.111 +	case WM_LBUTTONDOWN:
  65.112 +		if(MouseHandlerFunc) MouseHandlerFunc(hWnd, LOWORD(lParam), HIWORD(lParam), true, false, false);
  65.113 +		break;
  65.114 +
  65.115 +	case WM_MBUTTONDOWN:
  65.116 +		if(MouseHandlerFunc) MouseHandlerFunc(hWnd, LOWORD(lParam), HIWORD(lParam), false, true, false);
  65.117 +		break;
  65.118 +
  65.119 +	case WM_RBUTTONDOWN:
  65.120 +		if(MouseHandlerFunc) MouseHandlerFunc(hWnd, LOWORD(lParam), HIWORD(lParam), false, false, true);
  65.121 +		break;
  65.122 +
  65.123 +	case WM_LBUTTONUP:
  65.124 +		if(MouseUpHandlerFunc) MouseUpHandlerFunc(hWnd, LOWORD(lParam), HIWORD(lParam), true, false, false);
  65.125 +		break;
  65.126 +
  65.127 +	case WM_MBUTTONUP:
  65.128 +		if(MouseUpHandlerFunc) MouseUpHandlerFunc(hWnd, LOWORD(lParam), HIWORD(lParam), false, true, false);
  65.129 +		break;
  65.130 +
  65.131 +	case WM_RBUTTONUP:
  65.132 +		if(MouseUpHandlerFunc) MouseUpHandlerFunc(hWnd, LOWORD(lParam), HIWORD(lParam), false, false, true);
  65.133 +		break;
  65.134 +
  65.135 +	case WM_MOUSEWHEEL:
  65.136 +		if(MouseWheelHandlerFunc) MouseWheelHandlerFunc(hWnd, LOWORD(lParam), HIWORD(lParam), (short)HIWORD(wParam));
  65.137 +		break;
  65.138 +
  65.139 +	case WM_MOVE:
  65.140 +		if(WinMoveHandlerFunc) WinMoveHandlerFunc(hWnd, LOWORD(lParam), HIWORD(lParam));
  65.141 +		break;
  65.142 +
  65.143 +	case WM_PAINT:
  65.144 +		if(PaintHandlerFunc) PaintHandlerFunc(hWnd);
  65.145 +	}
  65.146 +
  65.147 +	return DefWindowProc(hWnd, msg, wParam, lParam);
  65.148 +}
  65.149 +
  65.150 +Point NWGetScreenSize() {
  65.151 +	return Point(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
  65.152 +}
  65.153 +
  65.154 +void NWCloseWindow(Widget *win) {
  65.155 +	PostMessage(win, WM_CLOSE, 0, 0);
  65.156 +}
  65.157 +
  65.158 +std::string NWFileSaveChooser(Widget *win, const char *title, const char *filetypes, const char *defext) {
  65.159 +	
  65.160 +	char fname[512];
  65.161 +	fname[0] = 0;
  65.162 +
  65.163 +	OPENFILENAME ofn;
  65.164 +	memset(&ofn, 0, sizeof(OPENFILENAME));
  65.165 +	ofn.lStructSize = sizeof(OPENFILENAME);
  65.166 +	ofn.hwndOwner = win;
  65.167 +	ofn.lpstrFilter = filetypes;
  65.168 +	ofn.lpstrFile = fname;
  65.169 +	ofn.nMaxFile = 512;
  65.170 +	ofn.lpstrTitle = title;
  65.171 +	ofn.lpstrDefExt = defext;
  65.172 +	ofn.Flags = OFN_PATHMUSTEXIST;
  65.173 +
  65.174 +	if(!GetSaveFileName(&ofn)) return "";
  65.175 +
  65.176 +	return fname;
  65.177 +}
  65.178 \ No newline at end of file
    66.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.2 +++ b/src/nwt/nucwin.h	Thu Oct 23 01:46:07 2014 +0300
    66.3 @@ -0,0 +1,47 @@
    66.4 +#ifndef _NUCWIN_H_
    66.5 +#define _NUCWIN_H_
    66.6 +
    66.7 +#include <string>
    66.8 +#include "widget.h"
    66.9 +
   66.10 +struct Point {
   66.11 +	int x, y;
   66.12 +	inline Point(int x=0, int y=0) {this->x = x; this->y = y;}
   66.13 +};
   66.14 +
   66.15 +struct Rect : public RECT {
   66.16 +	inline Rect() {}
   66.17 +	inline Rect(int l, int t, int r, int b) {left=l; top=t; right=r; bottom=b;}
   66.18 +};
   66.19 +
   66.20 +
   66.21 +#define HandlerFunctionPtr int (*)(Widget*, int)
   66.22 +
   66.23 +extern char *Arguments;
   66.24 +
   66.25 +enum HandlerType {
   66.26 +	HANDLER_KEY, 
   66.27 +	HANDLER_CLOSE, 
   66.28 +	HANDLER_MOUSE, 
   66.29 +	HANDLER_WHEEL, 
   66.30 +	HANDLER_WINMOVE,
   66.31 +	HANDLER_MOUSEUP,
   66.32 +	HANDLER_PAINT
   66.33 +};
   66.34 +enum MainLoopMode {EventLoop, RealTimeLoop};
   66.35 +
   66.36 +void SetHandler(HandlerType htype, int (*Handler)(Widget*, int));
   66.37 +
   66.38 +void SetMainLoopFunc(void (*func)());
   66.39 +
   66.40 +Point NWGetScreenSize();
   66.41 +
   66.42 +int NWMainLoop(MainLoopMode mode = EventLoop);
   66.43 +bool NWCheckForMessages();
   66.44 +LRESULT CALLBACK MainHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
   66.45 +
   66.46 +void NWCloseWindow(Widget *win);
   66.47 +
   66.48 +std::string NWFileSaveChooser(Widget *win, const char *title, const char *filetypes, const char *defext);
   66.49 +
   66.50 +#endif	// _NUCWIN_H_
   66.51 \ No newline at end of file
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/src/nwt/startup.h	Thu Oct 23 01:46:07 2014 +0300
    67.3 @@ -0,0 +1,33 @@
    67.4 +#ifndef _STARTUP_H_
    67.5 +#define _STARTUP_H_
    67.6 +
    67.7 +#include <windows.h>
    67.8 +#include "nucwin.h"
    67.9 +
   67.10 +int main();
   67.11 +void RegisterWindowClasses();
   67.12 +
   67.13 +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR CmdLine, int ShowCmd) {
   67.14 +	Arguments = CmdLine;
   67.15 +	RegisterWindowClasses();
   67.16 +	return main();
   67.17 +}
   67.18 +
   67.19 +void RegisterWindowClasses() {
   67.20 +	WNDCLASSEX wc;
   67.21 +	wc.cbSize = sizeof(WNDCLASSEX);
   67.22 +	wc.cbClsExtra = 0;
   67.23 +	wc.cbWndExtra = 0;
   67.24 +	wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
   67.25 +	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
   67.26 +	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
   67.27 +	wc.hIconSm = wc.hIcon;
   67.28 +	wc.hInstance = GetModuleHandle(0);
   67.29 +	wc.lpfnWndProc = MainHandler;
   67.30 +	wc.lpszClassName = "NucWin";
   67.31 +	wc.lpszMenuName = NULL;
   67.32 +	wc.style = CS_HREDRAW | CS_VREDRAW;
   67.33 +	RegisterClassEx(&wc);
   67.34 +}
   67.35 +
   67.36 +#endif	// _STARTUP_H_
   67.37 \ No newline at end of file
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/src/nwt/widget.cpp	Thu Oct 23 01:46:07 2014 +0300
    68.3 @@ -0,0 +1,49 @@
    68.4 +#include "widget.h"
    68.5 +#include "nucwin.h"
    68.6 +
    68.7 +Widget *NWCreateWindow(const char *name, int x, int y, int xsz, int ysz, uint16 flags) {
    68.8 +	if(x == NWT_CENTERX) {
    68.9 +		x = (GetSystemMetrics(SM_CXSCREEN) - xsz) >> 1;
   68.10 +	}
   68.11 +	if(y == NWT_CENTERY) {
   68.12 +		y = (GetSystemMetrics(SM_CYSCREEN) - ysz) >> 1;
   68.13 +	}
   68.14 +
   68.15 +	HINSTANCE AppInstance = GetModuleHandle(0);
   68.16 +	unsigned long ex_style = flags & NWT_WIN_TOPMOST ? WS_EX_TOPMOST : 0;
   68.17 +	return CreateWindowEx(ex_style, "NucWin", name, WS_OVERLAPPEDWINDOW | WS_VISIBLE, x, y, xsz, ysz, 0, 0, AppInstance, 0);
   68.18 +}
   68.19 +
   68.20 +
   68.21 +void NWResize(Widget *wdg, int nx, int ny) {
   68.22 +	int xpos = (GetSystemMetrics(SM_CXSCREEN) - nx) >> 1;
   68.23 +	int ypos = (GetSystemMetrics(SM_CYSCREEN) - ny) >> 1;
   68.24 +	MoveWindow(wdg, xpos, ypos, nx, ny, true);
   68.25 +}
   68.26 +
   68.27 +void NWResizeClientArea(Widget *wdg, uint32 WinStyle) {
   68.28 +    RECT rect;
   68.29 +	GetWindowRect(wdg, &rect);
   68.30 +	AdjustWindowRectEx(&rect, WinStyle, false, 0);
   68.31 +	MoveWindow(wdg, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, true);
   68.32 +}
   68.33 +
   68.34 +void NWSetWindowPos(Widget *wdg, const Point &pos) {
   68.35 +	Point sz = NWGetWindowSize(wdg);
   68.36 +	MoveWindow(wdg, pos.x, pos.y, sz.x, sz.y, true);
   68.37 +}
   68.38 +
   68.39 +Point NWGetWindowPos(Widget *wdg) {
   68.40 +	Rect rect;
   68.41 +	GetWindowRect(wdg, &rect);
   68.42 +
   68.43 +	return Point(rect.left, rect.top);
   68.44 +}
   68.45 +
   68.46 +Point NWGetWindowSize(Widget *wdg) {
   68.47 +	Rect rect;
   68.48 +	GetWindowRect(wdg, &rect);
   68.49 +
   68.50 +	return Point(rect.right - rect.left, rect.bottom - rect.top);
   68.51 +}
   68.52 +	
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/src/nwt/widget.h	Thu Oct 23 01:46:07 2014 +0300
    69.3 @@ -0,0 +1,26 @@
    69.4 +#ifndef _WIDGET_H_
    69.5 +#define _WIDGET_H_
    69.6 +
    69.7 +#include <windows.h>
    69.8 +#include "typedefs.h"
    69.9 +
   69.10 +struct Point;
   69.11 +struct Rect;
   69.12 +
   69.13 +#define NWT_CENTERX	-0xdead
   69.14 +#define NWT_CENTERY -0xbeef
   69.15 +
   69.16 +typedef HWND__ Widget;
   69.17 +
   69.18 +#define NWT_WIN_TOPMOST	1
   69.19 +
   69.20 +Widget *NWCreateWindow(const char *name, int x, int y, int xsz, int ysz, uint16 flags);
   69.21 +void NWResize(Widget *wdg, int nx, int ny);
   69.22 +void NWResizeClientArea(Widget *wdg, uint32 WinStyle);
   69.23 +
   69.24 +void NWSetWindowPos(Widget *wdg, const Point &pos);
   69.25 +
   69.26 +Point NWGetWindowPos(Widget *wdg);
   69.27 +Point NWGetWindowSize(Widget *wdg);
   69.28 +
   69.29 +#endif	// _WIDGET_H_
   69.30 \ No newline at end of file
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/src/treepart.cpp	Thu Oct 23 01:46:07 2014 +0300
    70.3 @@ -0,0 +1,156 @@
    70.4 +#include "treepart.h"
    70.5 +
    70.6 +TreePart::TreePart(GraphicsContext *gc) {
    70.7 +	this->gc = gc;
    70.8 +
    70.9 +	scene = new Scene(gc);
   70.10 +/*
   70.11 +	LeavesParticle = gc->texman->AddTexture("data/textures/leaf.png");
   70.12 +
   70.13 +	leaves = new ParticleSystem(gc);
   70.14 +	leaves->SetPosition(Vector3(0.0f, 800.0f, 0.0f));
   70.15 +	leaves->SetGravitualForce(0.8f);
   70.16 +	leaves->SetFriction(0.05f);
   70.17 +	leaves->SetInitialColor(0.6f, 0.5f, 0.5f);
   70.18 +	leaves->SetDeathColor(0.6f, 0.5f, 0.5f);
   70.19 +	leaves->SetParticleSize(6.0f);
   70.20 +	leaves->SetParticleLife(1000);
   70.21 +	leaves->SetSpawnRadius(1500.0f);
   70.22 +	leaves->SetSpawnRate(20.0f);
   70.23 +	leaves->SetTexture(LeavesParticle);
   70.24 +	leaves->SetShootDirection(Vector3(0.0f, -10.0f, 0.0f));
   70.25 +	leaves->SetMaxDispersionAngle(QuarterPi / 2.0f);
   70.26 +	leaves->SetBlendingMode(BLEND_SRCALPHA, BLEND_INVSRCALPHA);
   70.27 +*/
   70.28 +	WispParticle = gc->texman->AddTexture("data/textures/psys02.jpg");
   70.29 +    
   70.30 +	for(int i=0; i<4; i++) {
   70.31 +        WispParticles[i] = new ParticleSystem(gc);
   70.32 +		WispParticles[i]->SetGravitualForce(0.8f);
   70.33 +		WispParticles[i]->SetFriction(0.06f);
   70.34 +		WispParticles[i]->SetInitialColor(0.7f, 0.8f, 1.0f);
   70.35 +		WispParticles[i]->SetDeathColor(0.2f, 0.2f, 0.5f);
   70.36 +		WispParticles[i]->SetParticleSize(7.5f);
   70.37 +		WispParticles[i]->SetParticleLife(15);
   70.38 +		WispParticles[i]->SetSpawnRadius(0.2f);
   70.39 +		WispParticles[i]->SetSpawnRate(4.0f);
   70.40 +		WispParticles[i]->SetTexture(WispParticle);
   70.41 +		WispParticles[i]->SetShootDirection(Vector3(0.0f, 0.0f, 0.0f));
   70.42 +		WispParticles[i]->SetMaxDispersionAngle(QuarterPi / 2.0f);
   70.43 +		WispParticles[i]->SetBlendingMode(BLEND_ONE, BLEND_ONE);
   70.44 +		WispParticles[i]->SetSpawningDifferenceDispersion(1.0f);
   70.45 +	}
   70.46 +	
   70.47 +	SceneLoader::SetNormalFileSaving(true);
   70.48 +	SceneLoader::SetDataPath("data/textures/");
   70.49 +	SceneLoader::LoadScene("data/geometry/tree2.3ds", &scene);
   70.50 +
   70.51 +	Trees = scene->GetObject("Trees");
   70.52 +	scene->RemoveObject(Trees);
   70.53 +
   70.54 +	for(int i=0; i<3; i++) {
   70.55 +		dummy[i] = new Camera;
   70.56 +	}
   70.57 +
   70.58 +	Object *graves = scene->GetObject("Graves");
   70.59 +	//graves->SetShadowCasting(true);
   70.60 +    
   70.61 +	WispPath[0] = scene->GetCurve("wisp1");
   70.62 +	WispPath[1] = scene->GetCurve("wisp2");
   70.63 +	WispPath[2] = scene->GetCurve("wisp3");
   70.64 +	
   70.65 +	WispPath[0]->SetArcParametrization(true);
   70.66 +	WispPath[1]->SetArcParametrization(true);
   70.67 +	WispPath[2]->SetArcParametrization(true);
   70.68 +
   70.69 +	dummy[0]->SetCameraPath(WispPath[0], 0, 0, 8000);
   70.70 +	dummy[1]->SetCameraPath(WispPath[1], 0, 0, 7000);
   70.71 +	dummy[2]->SetCameraPath(WispPath[2], 0, 0, 10000);
   70.72 +	
   70.73 +	lights[0] = scene->GetLight("wispl1");
   70.74 +	lights[1] = scene->GetLight("wispl2");
   70.75 +	lights[2] = scene->GetLight("wispl3");
   70.76 +	lights[3] = scene->GetLight("wispl04");
   70.77 +
   70.78 +	for(int i=0; i<3; i++) {
   70.79 +		lights[i]->SetRange(250.0f);
   70.80 +		lights[i]->SetColor(Color(0.6f, 0.6f, 0.9f));
   70.81 +	}
   70.82 +	lights[3]->SetColor(Color(0.6f, 0.6f, 0.9f));
   70.83 +
   70.84 +	CamPath = scene->GetCurve("cpath01");
   70.85 +	TargPath = scene->GetCurve("ctarget01");
   70.86 +	
   70.87 +	CamPath->SetArcParametrization(true);
   70.88 +	TargPath->SetArcParametrization(true);
   70.89 +
   70.90 +	cam = scene->GetCamera("Camera02");
   70.91 +	cam->SetClippingPlanes(1.0f, 80000.0f);
   70.92 +	cam->SetCameraPath(CamPath, TargPath, 0, 40000);
   70.93 +	scene->SetActiveCamera(cam);
   70.94 +
   70.95 +	//scene->SetShadows(true);
   70.96 +	//lights[3]->SetShadowCasting(true);
   70.97 +
   70.98 +	Moon = scene->GetObject("Moon");
   70.99 +	scene->RemoveObject(Moon);
  70.100 +
  70.101 +	Stars = scene->GetObject("StarDome");
  70.102 +	scene->RemoveObject(Stars);
  70.103 +
  70.104 +}
  70.105 +
  70.106 +TreePart::~TreePart() {
  70.107 +	delete scene;
  70.108 +	delete leaves;
  70.109 +}
  70.110 +
  70.111 +void TreePart::MainLoop() {
  70.112 +	dword msec = timer.GetMilliSec();
  70.113 +	float t = msec / 1000.0f;
  70.114 +
  70.115 +	float start = 10.0f;
  70.116 +	float end = 10500.0f;
  70.117 +	
  70.118 +	gc->D3DDevice->SetRenderState(D3DRS_FOGENABLE, true);
  70.119 +	gc->D3DDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
  70.120 +	gc->D3DDevice->SetRenderState(D3DRS_FOGCOLOR, 0);
  70.121 +    gc->D3DDevice->SetRenderState(D3DRS_FOGSTART, *(dword*)(&start));
  70.122 +	gc->D3DDevice->SetRenderState(D3DRS_FOGEND, *(dword*)(&end));
  70.123 +
  70.124 +	cam->FollowPath(msec);
  70.125 +	for(int i=0; i<3; i++) {
  70.126 +		dummy[i]->FollowPath(msec, true);
  70.127 +		lights[i]->SetPosition(dummy[i]->GetPosition());
  70.128 +	}
  70.129 +	lights[3]->SetPosition(cam->GetTargetPosition());
  70.130 +
  70.131 +	gc->Clear(0);
  70.132 +	gc->ClearZBufferStencil(1.0f, 0);
  70.133 +
  70.134 +	scene->Render();
  70.135 +	
  70.136 +	gc->SetZWrite(false);
  70.137 +	Trees->Render();
  70.138 +	gc->SetZWrite(true);
  70.139 +
  70.140 +	//for(int i=0; i<3; i++) {
  70.141 +	//	lights[i]->Draw(gc, 20.0f);
  70.142 +	//}
  70.143 +	//lights[3]->Draw(gc, 30.0f);
  70.144 +
  70.145 +	gc->D3DDevice->SetRenderState(D3DRS_FOGENABLE, false);
  70.146 +
  70.147 +	//leaves->Update(t);
  70.148 +	//leaves->Render();
  70.149 +
  70.150 +	Stars->Render();
  70.151 +	Moon->Render();
  70.152 +
  70.153 +	for(int i=0; i<4; i++) {
  70.154 +        WispParticles[i]->SetPosition(Vector3(lights[i]->GetPosition()));
  70.155 +		WispParticles[i]->Update(t);
  70.156 +		WispParticles[i]->Render();
  70.157 +	}
  70.158 +}
  70.159 +
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/src/treepart.h	Thu Oct 23 01:46:07 2014 +0300
    71.3 @@ -0,0 +1,25 @@
    71.4 +#ifndef _TREEPART_H_
    71.5 +#define _TREEPART_H_
    71.6 +
    71.7 +#include "demosystem/demosys.h"
    71.8 +#include "3deng/particles.h"
    71.9 +
   71.10 +class TreePart : public Part {
   71.11 +private:
   71.12 +	//Scene *scene;
   71.13 +	ParticleSystem *leaves, *WispParticles[4];
   71.14 +	Texture *WispParticle, *LeavesParticle;
   71.15 +	Camera *cam, *dummy[3];
   71.16 +	Curve *CamPath, *TargPath, *WispPath[3];
   71.17 +	Light *lights[4];
   71.18 +
   71.19 +	Object *Trees, *Moon, *Stars;
   71.20 +public:
   71.21 +
   71.22 +	TreePart(GraphicsContext *gc);
   71.23 +	~TreePart();
   71.24 +
   71.25 +	void MainLoop();
   71.26 +};
   71.27 +
   71.28 +#endif	// _TREEPART_H_
   71.29 \ No newline at end of file
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/src/tunnelpart.cpp	Thu Oct 23 01:46:07 2014 +0300
    72.3 @@ -0,0 +1,34 @@
    72.4 +#include "tunnelpart.h"
    72.5 +
    72.6 +TunnelPart::TunnelPart(GraphicsContext *gc) {
    72.7 +	this->gc = gc;
    72.8 +
    72.9 +	SceneLoader::SetNormalFileSaving(true);
   72.10 +	SceneLoader::SetDataPath("data/textures/");
   72.11 +	SceneLoader::LoadScene("data/geometry/tunnel.3ds", &scene);
   72.12 +
   72.13 +	CamPath = scene->GetCurve("Line01");
   72.14 +	TargPath = scene->GetCurve("Line02");
   72.15 +
   72.16 +	CamPath->SetArcParametrization(true);
   72.17 +	TargPath->SetArcParametrization(true);
   72.18 +    
   72.19 +	cam = scene->GetCamera("Camera02");
   72.20 +	cam->SetCameraPath(CamPath, TargPath, 0, 30000);
   72.21 +}
   72.22 +
   72.23 +TunnelPart::~TunnelPart() {
   72.24 +	delete scene;
   72.25 +}
   72.26 +
   72.27 +void TunnelPart::MainLoop() {
   72.28 +	dword msec = timer.GetMilliSec();
   72.29 +	float t = msec / 1000.0f;
   72.30 +
   72.31 +	gc->Clear(0);
   72.32 +	gc->ClearZBufferStencil(1.0f, 0);
   72.33 +
   72.34 +	cam->FollowPath(msec);
   72.35 +
   72.36 +	scene->Render();
   72.37 +}
   72.38 \ No newline at end of file
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/src/tunnelpart.h	Thu Oct 23 01:46:07 2014 +0300
    73.3 @@ -0,0 +1,19 @@
    73.4 +#ifndef _TUNNELPART_H_
    73.5 +#define _TUNNELPART_H_
    73.6 +
    73.7 +#include "demosystem/demosys.h"
    73.8 +
    73.9 +class TunnelPart : public Part {
   73.10 +private:
   73.11 +	Curve *CamPath, *TargPath;
   73.12 +	Camera *cam;
   73.13 +
   73.14 +public:
   73.15 +
   73.16 +	TunnelPart(GraphicsContext *gc);
   73.17 +	~TunnelPart();
   73.18 +
   73.19 +	void MainLoop();
   73.20 +};
   73.21 +
   73.22 +#endif	// _TUNNELPART_H_
   73.23 \ No newline at end of file
    74.1 Binary file thelab.ico has changed