GL - merge with bullet physics and updated server

This commit is contained in:
lindaandersson 2014-02-10 14:41:43 +01:00
commit 49d29d87a5
447 changed files with 99818 additions and 3872 deletions

View File

@ -39,20 +39,26 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GameProtocols", "Game\GameP
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DanBiasServerLauncher", "Game\DanBiasServerLauncher\DanBiasServerLauncher.vcxproj", "{060B1890-CBF3-4808-BA99-A4776222093B}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DanBiasServerLauncher", "Game\DanBiasServerLauncher\DanBiasServerLauncher.vcxproj", "{060B1890-CBF3-4808-BA99-A4776222093B}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Physics lab", "Physics lab\Physics lab.vcxproj", "{5128BD77-6472-4C4A-BE6F-724AD0E589C2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GameServer", "Game\GameServer\GameServer.vcxproj", "{143BD516-20A1-4890-A3E4-F8BFD02220E7}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GameServer", "Game\GameServer\GameServer.vcxproj", "{143BD516-20A1-4890-A3E4-F8BFD02220E7}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aDanBiasGameLauncher", "Game\aDanBiasGameLauncher\aDanBiasGameLauncher.vcxproj", "{666FEA52-975F-41CD-B224-B19AF3C0ABBA}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aDanBiasGameLauncher", "Game\aDanBiasGameLauncher\aDanBiasGameLauncher.vcxproj", "{666FEA52-975F-41CD-B224-B19AF3C0ABBA}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Physics", "Physics", "{0D86E569-9C74-47F0-BDB2-390C0C9A084B}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Mixed Platforms = Debug|Mixed Platforms Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
MinSizeRel|Mixed Platforms = MinSizeRel|Mixed Platforms
MinSizeRel|Win32 = MinSizeRel|Win32
MinSizeRel|x64 = MinSizeRel|x64
Release|Mixed Platforms = Release|Mixed Platforms Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32 Release|Win32 = Release|Win32
Release|x64 = Release|x64 Release|x64 = Release|x64
RelWithDebInfo|Mixed Platforms = RelWithDebInfo|Mixed Platforms
RelWithDebInfo|Win32 = RelWithDebInfo|Win32
RelWithDebInfo|x64 = RelWithDebInfo|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
@ -61,240 +67,438 @@ Global
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Win32.Build.0 = Debug|Win32 {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Win32.Build.0 = Debug|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|x64.ActiveCfg = Debug|x64 {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|x64.ActiveCfg = Debug|x64
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|x64.Build.0 = Debug|x64 {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|x64.Build.0 = Debug|x64
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.MinSizeRel|Win32.Build.0 = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.MinSizeRel|x64.ActiveCfg = Release|x64
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.MinSizeRel|x64.Build.0 = Release|x64
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Mixed Platforms.Build.0 = Release|Win32 {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Mixed Platforms.Build.0 = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Win32.ActiveCfg = Release|Win32 {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Win32.ActiveCfg = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Win32.Build.0 = Release|Win32 {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Win32.Build.0 = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|x64.ActiveCfg = Release|x64 {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|x64.ActiveCfg = Release|x64
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|x64.Build.0 = Release|x64 {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|x64.Build.0 = Release|x64
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.RelWithDebInfo|x64.Build.0 = Release|x64
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Win32.ActiveCfg = Debug|Win32 {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Win32.ActiveCfg = Debug|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Win32.Build.0 = Debug|Win32 {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Win32.Build.0 = Debug|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|x64.ActiveCfg = Debug|x64 {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|x64.ActiveCfg = Debug|x64
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|x64.Build.0 = Debug|x64 {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|x64.Build.0 = Debug|x64
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.MinSizeRel|Win32.Build.0 = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.MinSizeRel|x64.ActiveCfg = Release|x64
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.MinSizeRel|x64.Build.0 = Release|x64
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Mixed Platforms.Build.0 = Release|Win32 {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Mixed Platforms.Build.0 = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Win32.ActiveCfg = Release|Win32 {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Win32.ActiveCfg = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Win32.Build.0 = Release|Win32 {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Win32.Build.0 = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|x64.ActiveCfg = Release|x64 {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|x64.ActiveCfg = Release|x64
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|x64.Build.0 = Release|x64 {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|x64.Build.0 = Release|x64
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.RelWithDebInfo|x64.Build.0 = Release|x64
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Win32.ActiveCfg = Debug|Win32 {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Win32.ActiveCfg = Debug|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Win32.Build.0 = Debug|Win32 {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Win32.Build.0 = Debug|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|x64.ActiveCfg = Debug|x64 {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|x64.ActiveCfg = Debug|x64
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|x64.Build.0 = Debug|x64 {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|x64.Build.0 = Debug|x64
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.MinSizeRel|Win32.Build.0 = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.MinSizeRel|x64.ActiveCfg = Release|x64
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.MinSizeRel|x64.Build.0 = Release|x64
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Mixed Platforms.Build.0 = Release|Win32 {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Mixed Platforms.Build.0 = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Win32.ActiveCfg = Release|Win32 {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Win32.ActiveCfg = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Win32.Build.0 = Release|Win32 {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Win32.Build.0 = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|x64.ActiveCfg = Release|x64 {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|x64.ActiveCfg = Release|x64
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|x64.Build.0 = Release|x64 {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|x64.Build.0 = Release|x64
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.RelWithDebInfo|x64.Build.0 = Release|x64
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Win32.ActiveCfg = Debug|Win32 {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Win32.ActiveCfg = Debug|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Win32.Build.0 = Debug|Win32 {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Win32.Build.0 = Debug|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|x64.ActiveCfg = Debug|x64 {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|x64.ActiveCfg = Debug|x64
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|x64.Build.0 = Debug|x64 {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|x64.Build.0 = Debug|x64
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.MinSizeRel|Win32.Build.0 = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.MinSizeRel|x64.ActiveCfg = Release|x64
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.MinSizeRel|x64.Build.0 = Release|x64
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Mixed Platforms.Build.0 = Release|Win32 {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Mixed Platforms.Build.0 = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Win32.ActiveCfg = Release|Win32 {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Win32.ActiveCfg = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Win32.Build.0 = Release|Win32 {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Win32.Build.0 = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|x64.ActiveCfg = Release|x64 {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|x64.ActiveCfg = Release|x64
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|x64.Build.0 = Release|x64 {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|x64.Build.0 = Release|x64
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.RelWithDebInfo|x64.Build.0 = Release|x64
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Win32.ActiveCfg = Debug|Win32 {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Win32.ActiveCfg = Debug|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Win32.Build.0 = Debug|Win32 {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Win32.Build.0 = Debug|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|x64.ActiveCfg = Debug|x64 {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|x64.ActiveCfg = Debug|x64
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|x64.Build.0 = Debug|x64 {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|x64.Build.0 = Debug|x64
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.MinSizeRel|Win32.Build.0 = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.MinSizeRel|x64.ActiveCfg = Release|x64
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.MinSizeRel|x64.Build.0 = Release|x64
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Mixed Platforms.Build.0 = Release|Win32 {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Mixed Platforms.Build.0 = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Win32.ActiveCfg = Release|Win32 {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Win32.ActiveCfg = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Win32.Build.0 = Release|Win32 {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Win32.Build.0 = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|x64.ActiveCfg = Release|x64 {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|x64.ActiveCfg = Release|x64
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|x64.Build.0 = Release|x64 {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|x64.Build.0 = Release|x64
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.RelWithDebInfo|x64.Build.0 = Release|x64
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Win32.ActiveCfg = Debug|Win32 {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Win32.ActiveCfg = Debug|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Win32.Build.0 = Debug|Win32 {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Win32.Build.0 = Debug|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|x64.ActiveCfg = Debug|x64 {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|x64.ActiveCfg = Debug|x64
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|x64.Build.0 = Debug|x64 {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|x64.Build.0 = Debug|x64
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.MinSizeRel|Win32.Build.0 = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.MinSizeRel|x64.ActiveCfg = Release|x64
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.MinSizeRel|x64.Build.0 = Release|x64
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Mixed Platforms.Build.0 = Release|Win32 {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Mixed Platforms.Build.0 = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Win32.ActiveCfg = Release|Win32 {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Win32.ActiveCfg = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Win32.Build.0 = Release|Win32 {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Win32.Build.0 = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|x64.ActiveCfg = Release|x64 {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|x64.ActiveCfg = Release|x64
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|x64.Build.0 = Release|x64 {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|x64.Build.0 = Release|x64
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.RelWithDebInfo|x64.Build.0 = Release|x64
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Win32.ActiveCfg = Debug|Win32 {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Win32.ActiveCfg = Debug|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Win32.Build.0 = Debug|Win32 {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Win32.Build.0 = Debug|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|x64.ActiveCfg = Debug|x64 {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|x64.ActiveCfg = Debug|x64
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|x64.Build.0 = Debug|x64 {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|x64.Build.0 = Debug|x64
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.MinSizeRel|Win32.Build.0 = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.MinSizeRel|x64.ActiveCfg = Release|x64
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.MinSizeRel|x64.Build.0 = Release|x64
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Mixed Platforms.Build.0 = Release|Win32 {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Mixed Platforms.Build.0 = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Win32.ActiveCfg = Release|Win32 {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Win32.ActiveCfg = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Win32.Build.0 = Release|Win32 {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Win32.Build.0 = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|x64.ActiveCfg = Release|x64 {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|x64.ActiveCfg = Release|x64
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|x64.Build.0 = Release|x64 {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|x64.Build.0 = Release|x64
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.RelWithDebInfo|x64.Build.0 = Release|x64
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Win32.ActiveCfg = Debug|Win32 {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Win32.ActiveCfg = Debug|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Win32.Build.0 = Debug|Win32 {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Win32.Build.0 = Debug|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|x64.ActiveCfg = Debug|x64 {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|x64.ActiveCfg = Debug|x64
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|x64.Build.0 = Debug|x64 {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|x64.Build.0 = Debug|x64
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.MinSizeRel|x64.ActiveCfg = Release|x64
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Mixed Platforms.Build.0 = Release|Win32 {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Mixed Platforms.Build.0 = Release|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Win32.ActiveCfg = Release|Win32 {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Win32.ActiveCfg = Release|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Win32.Build.0 = Release|Win32 {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Win32.Build.0 = Release|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|x64.ActiveCfg = Release|x64 {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|x64.ActiveCfg = Release|x64
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|x64.Build.0 = Release|x64 {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|x64.Build.0 = Release|x64
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Win32.ActiveCfg = Debug|Win32 {6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Win32.ActiveCfg = Debug|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Win32.Build.0 = Debug|Win32 {6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Win32.Build.0 = Debug|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Debug|x64.ActiveCfg = Debug|x64 {6A066806-F43F-4B31-A4E3-57179674F460}.Debug|x64.ActiveCfg = Debug|x64
{6A066806-F43F-4B31-A4E3-57179674F460}.Debug|x64.Build.0 = Debug|x64 {6A066806-F43F-4B31-A4E3-57179674F460}.Debug|x64.Build.0 = Debug|x64
{6A066806-F43F-4B31-A4E3-57179674F460}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.MinSizeRel|x64.ActiveCfg = Release|x64
{6A066806-F43F-4B31-A4E3-57179674F460}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {6A066806-F43F-4B31-A4E3-57179674F460}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Release|Mixed Platforms.Build.0 = Release|Win32 {6A066806-F43F-4B31-A4E3-57179674F460}.Release|Mixed Platforms.Build.0 = Release|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Release|Win32.ActiveCfg = Release|Win32 {6A066806-F43F-4B31-A4E3-57179674F460}.Release|Win32.ActiveCfg = Release|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Release|Win32.Build.0 = Release|Win32 {6A066806-F43F-4B31-A4E3-57179674F460}.Release|Win32.Build.0 = Release|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Release|x64.ActiveCfg = Release|x64 {6A066806-F43F-4B31-A4E3-57179674F460}.Release|x64.ActiveCfg = Release|x64
{6A066806-F43F-4B31-A4E3-57179674F460}.Release|x64.Build.0 = Release|x64 {6A066806-F43F-4B31-A4E3-57179674F460}.Release|x64.Build.0 = Release|x64
{6A066806-F43F-4B31-A4E3-57179674F460}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Win32.ActiveCfg = Debug|Win32 {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Win32.ActiveCfg = Debug|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Win32.Build.0 = Debug|Win32 {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Win32.Build.0 = Debug|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|x64.ActiveCfg = Debug|x64 {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|x64.ActiveCfg = Debug|x64
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|x64.Build.0 = Debug|x64 {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|x64.Build.0 = Debug|x64
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.MinSizeRel|x64.ActiveCfg = Release|x64
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Mixed Platforms.Build.0 = Release|Win32 {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Mixed Platforms.Build.0 = Release|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Win32.ActiveCfg = Release|Win32 {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Win32.ActiveCfg = Release|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Win32.Build.0 = Release|Win32 {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Win32.Build.0 = Release|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|x64.ActiveCfg = Release|x64 {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|x64.ActiveCfg = Release|x64
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|x64.Build.0 = Release|x64 {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|x64.Build.0 = Release|x64
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Debug|Win32.ActiveCfg = Debug|Win32 {104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Debug|Win32.ActiveCfg = Debug|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Debug|Win32.Build.0 = Debug|Win32 {104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Debug|Win32.Build.0 = Debug|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Debug|x64.ActiveCfg = Debug|x64 {104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Debug|x64.ActiveCfg = Debug|x64
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Debug|x64.Build.0 = Debug|x64 {104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Debug|x64.Build.0 = Debug|x64
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.MinSizeRel|Win32.Build.0 = Release|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.MinSizeRel|x64.ActiveCfg = Release|x64
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.MinSizeRel|x64.Build.0 = Release|x64
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Release|Mixed Platforms.Build.0 = Release|Win32 {104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Release|Mixed Platforms.Build.0 = Release|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Release|Win32.ActiveCfg = Release|Win32 {104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Release|Win32.ActiveCfg = Release|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Release|Win32.Build.0 = Release|Win32 {104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Release|Win32.Build.0 = Release|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Release|x64.ActiveCfg = Release|x64 {104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Release|x64.ActiveCfg = Release|x64
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Release|x64.Build.0 = Release|x64 {104FA3E9-94D9-4E1D-A941-28A03BC8A095}.Release|x64.Build.0 = Release|x64
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{104FA3E9-94D9-4E1D-A941-28A03BC8A095}.RelWithDebInfo|x64.Build.0 = Release|x64
{2A1BC987-AF42-4500-802D-89CD32FC1309}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {2A1BC987-AF42-4500-802D-89CD32FC1309}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {2A1BC987-AF42-4500-802D-89CD32FC1309}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.Debug|Win32.ActiveCfg = Debug|Win32 {2A1BC987-AF42-4500-802D-89CD32FC1309}.Debug|Win32.ActiveCfg = Debug|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.Debug|Win32.Build.0 = Debug|Win32 {2A1BC987-AF42-4500-802D-89CD32FC1309}.Debug|Win32.Build.0 = Debug|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.Debug|x64.ActiveCfg = Debug|x64 {2A1BC987-AF42-4500-802D-89CD32FC1309}.Debug|x64.ActiveCfg = Debug|x64
{2A1BC987-AF42-4500-802D-89CD32FC1309}.Debug|x64.Build.0 = Debug|x64 {2A1BC987-AF42-4500-802D-89CD32FC1309}.Debug|x64.Build.0 = Debug|x64
{2A1BC987-AF42-4500-802D-89CD32FC1309}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.MinSizeRel|Win32.Build.0 = Release|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.MinSizeRel|x64.ActiveCfg = Release|x64
{2A1BC987-AF42-4500-802D-89CD32FC1309}.MinSizeRel|x64.Build.0 = Release|x64
{2A1BC987-AF42-4500-802D-89CD32FC1309}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {2A1BC987-AF42-4500-802D-89CD32FC1309}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.Release|Mixed Platforms.Build.0 = Release|Win32 {2A1BC987-AF42-4500-802D-89CD32FC1309}.Release|Mixed Platforms.Build.0 = Release|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.Release|Win32.ActiveCfg = Release|Win32 {2A1BC987-AF42-4500-802D-89CD32FC1309}.Release|Win32.ActiveCfg = Release|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.Release|Win32.Build.0 = Release|Win32 {2A1BC987-AF42-4500-802D-89CD32FC1309}.Release|Win32.Build.0 = Release|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.Release|x64.ActiveCfg = Release|x64 {2A1BC987-AF42-4500-802D-89CD32FC1309}.Release|x64.ActiveCfg = Release|x64
{2A1BC987-AF42-4500-802D-89CD32FC1309}.Release|x64.Build.0 = Release|x64 {2A1BC987-AF42-4500-802D-89CD32FC1309}.Release|x64.Build.0 = Release|x64
{2A1BC987-AF42-4500-802D-89CD32FC1309}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{2A1BC987-AF42-4500-802D-89CD32FC1309}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{2A1BC987-AF42-4500-802D-89CD32FC1309}.RelWithDebInfo|x64.Build.0 = Release|x64
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Debug|Win32.ActiveCfg = Debug|Win32 {B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Debug|Win32.ActiveCfg = Debug|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Debug|Win32.Build.0 = Debug|Win32 {B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Debug|Win32.Build.0 = Debug|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Debug|x64.ActiveCfg = Debug|x64 {B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Debug|x64.ActiveCfg = Debug|x64
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Debug|x64.Build.0 = Debug|x64 {B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Debug|x64.Build.0 = Debug|x64
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.MinSizeRel|Win32.Build.0 = Release|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.MinSizeRel|x64.ActiveCfg = Release|x64
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.MinSizeRel|x64.Build.0 = Release|x64
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Release|Mixed Platforms.Build.0 = Release|Win32 {B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Release|Mixed Platforms.Build.0 = Release|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Release|Win32.ActiveCfg = Release|Win32 {B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Release|Win32.ActiveCfg = Release|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Release|Win32.Build.0 = Release|Win32 {B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Release|Win32.Build.0 = Release|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Release|x64.ActiveCfg = Release|x64 {B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Release|x64.ActiveCfg = Release|x64
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Release|x64.Build.0 = Release|x64 {B1195BB9-B3A5-47F0-906C-8DEA384D1520}.Release|x64.Build.0 = Release|x64
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{B1195BB9-B3A5-47F0-906C-8DEA384D1520}.RelWithDebInfo|x64.Build.0 = Release|x64
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Debug|Win32.ActiveCfg = Debug|Win32 {8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Debug|Win32.ActiveCfg = Debug|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Debug|Win32.Build.0 = Debug|Win32 {8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Debug|Win32.Build.0 = Debug|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Debug|x64.ActiveCfg = Debug|x64 {8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Debug|x64.ActiveCfg = Debug|x64
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Debug|x64.Build.0 = Debug|x64 {8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Debug|x64.Build.0 = Debug|x64
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.MinSizeRel|Win32.Build.0 = Release|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.MinSizeRel|x64.ActiveCfg = Release|x64
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.MinSizeRel|x64.Build.0 = Release|x64
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Release|Mixed Platforms.Build.0 = Release|Win32 {8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Release|Mixed Platforms.Build.0 = Release|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Release|Win32.ActiveCfg = Release|Win32 {8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Release|Win32.ActiveCfg = Release|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Release|Win32.Build.0 = Release|Win32 {8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Release|Win32.Build.0 = Release|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Release|x64.ActiveCfg = Release|x64 {8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Release|x64.ActiveCfg = Release|x64
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Release|x64.Build.0 = Release|x64 {8690FDDF-C5B7-4C42-A337-BD5243F29B85}.Release|x64.Build.0 = Release|x64
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{8690FDDF-C5B7-4C42-A337-BD5243F29B85}.RelWithDebInfo|x64.Build.0 = Release|x64
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Debug|Win32.ActiveCfg = Debug|Win32 {460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Debug|Win32.ActiveCfg = Debug|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Debug|Win32.Build.0 = Debug|Win32 {460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Debug|Win32.Build.0 = Debug|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Debug|x64.ActiveCfg = Debug|x64 {460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Debug|x64.ActiveCfg = Debug|x64
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Debug|x64.Build.0 = Debug|x64 {460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Debug|x64.Build.0 = Debug|x64
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.MinSizeRel|Win32.Build.0 = Release|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.MinSizeRel|x64.ActiveCfg = Release|x64
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.MinSizeRel|x64.Build.0 = Release|x64
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Release|Mixed Platforms.Build.0 = Release|Win32 {460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Release|Mixed Platforms.Build.0 = Release|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Release|Win32.ActiveCfg = Release|Win32 {460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Release|Win32.ActiveCfg = Release|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Release|Win32.Build.0 = Release|Win32 {460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Release|Win32.Build.0 = Release|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Release|x64.ActiveCfg = Release|x64 {460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Release|x64.ActiveCfg = Release|x64
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Release|x64.Build.0 = Release|x64 {460D625F-2AC9-4559-B809-0BA89CEAEDF4}.Release|x64.Build.0 = Release|x64
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{460D625F-2AC9-4559-B809-0BA89CEAEDF4}.RelWithDebInfo|x64.Build.0 = Release|x64
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Debug|Win32.ActiveCfg = Debug|Win32 {DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Debug|Win32.ActiveCfg = Debug|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Debug|Win32.Build.0 = Debug|Win32 {DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Debug|Win32.Build.0 = Debug|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Debug|x64.ActiveCfg = Debug|x64 {DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Debug|x64.ActiveCfg = Debug|x64
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Debug|x64.Build.0 = Debug|x64 {DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Debug|x64.Build.0 = Debug|x64
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.MinSizeRel|Win32.Build.0 = Release|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.MinSizeRel|x64.ActiveCfg = Release|x64
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.MinSizeRel|x64.Build.0 = Release|x64
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Release|Mixed Platforms.Build.0 = Release|Win32 {DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Release|Mixed Platforms.Build.0 = Release|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Release|Win32.ActiveCfg = Release|Win32 {DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Release|Win32.ActiveCfg = Release|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Release|Win32.Build.0 = Release|Win32 {DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Release|Win32.Build.0 = Release|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Release|x64.ActiveCfg = Release|x64 {DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Release|x64.ActiveCfg = Release|x64
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Release|x64.Build.0 = Release|x64 {DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.Release|x64.Build.0 = Release|x64
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{DA2AA800-ED64-4649-8B3B-E7F1E3968B78}.RelWithDebInfo|x64.Build.0 = Release|x64
{060B1890-CBF3-4808-BA99-A4776222093B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {060B1890-CBF3-4808-BA99-A4776222093B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{060B1890-CBF3-4808-BA99-A4776222093B}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {060B1890-CBF3-4808-BA99-A4776222093B}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{060B1890-CBF3-4808-BA99-A4776222093B}.Debug|Win32.ActiveCfg = Debug|Win32 {060B1890-CBF3-4808-BA99-A4776222093B}.Debug|Win32.ActiveCfg = Debug|Win32
{060B1890-CBF3-4808-BA99-A4776222093B}.Debug|Win32.Build.0 = Debug|Win32 {060B1890-CBF3-4808-BA99-A4776222093B}.Debug|Win32.Build.0 = Debug|Win32
{060B1890-CBF3-4808-BA99-A4776222093B}.Debug|x64.ActiveCfg = Debug|x64 {060B1890-CBF3-4808-BA99-A4776222093B}.Debug|x64.ActiveCfg = Debug|x64
{060B1890-CBF3-4808-BA99-A4776222093B}.Debug|x64.Build.0 = Debug|x64 {060B1890-CBF3-4808-BA99-A4776222093B}.Debug|x64.Build.0 = Debug|x64
{060B1890-CBF3-4808-BA99-A4776222093B}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{060B1890-CBF3-4808-BA99-A4776222093B}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{060B1890-CBF3-4808-BA99-A4776222093B}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{060B1890-CBF3-4808-BA99-A4776222093B}.MinSizeRel|Win32.Build.0 = Release|Win32
{060B1890-CBF3-4808-BA99-A4776222093B}.MinSizeRel|x64.ActiveCfg = Release|x64
{060B1890-CBF3-4808-BA99-A4776222093B}.MinSizeRel|x64.Build.0 = Release|x64
{060B1890-CBF3-4808-BA99-A4776222093B}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {060B1890-CBF3-4808-BA99-A4776222093B}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{060B1890-CBF3-4808-BA99-A4776222093B}.Release|Mixed Platforms.Build.0 = Release|Win32 {060B1890-CBF3-4808-BA99-A4776222093B}.Release|Mixed Platforms.Build.0 = Release|Win32
{060B1890-CBF3-4808-BA99-A4776222093B}.Release|Win32.ActiveCfg = Release|Win32 {060B1890-CBF3-4808-BA99-A4776222093B}.Release|Win32.ActiveCfg = Release|Win32
{060B1890-CBF3-4808-BA99-A4776222093B}.Release|Win32.Build.0 = Release|Win32 {060B1890-CBF3-4808-BA99-A4776222093B}.Release|Win32.Build.0 = Release|Win32
{060B1890-CBF3-4808-BA99-A4776222093B}.Release|x64.ActiveCfg = Release|x64 {060B1890-CBF3-4808-BA99-A4776222093B}.Release|x64.ActiveCfg = Release|x64
{060B1890-CBF3-4808-BA99-A4776222093B}.Release|x64.Build.0 = Release|x64 {060B1890-CBF3-4808-BA99-A4776222093B}.Release|x64.Build.0 = Release|x64
{5128BD77-6472-4C4A-BE6F-724AD0E589C2}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {060B1890-CBF3-4808-BA99-A4776222093B}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{5128BD77-6472-4C4A-BE6F-724AD0E589C2}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {060B1890-CBF3-4808-BA99-A4776222093B}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{5128BD77-6472-4C4A-BE6F-724AD0E589C2}.Debug|Win32.ActiveCfg = Debug|Win32 {060B1890-CBF3-4808-BA99-A4776222093B}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{5128BD77-6472-4C4A-BE6F-724AD0E589C2}.Debug|Win32.Build.0 = Debug|Win32 {060B1890-CBF3-4808-BA99-A4776222093B}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{5128BD77-6472-4C4A-BE6F-724AD0E589C2}.Debug|x64.ActiveCfg = Debug|x64 {060B1890-CBF3-4808-BA99-A4776222093B}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{5128BD77-6472-4C4A-BE6F-724AD0E589C2}.Debug|x64.Build.0 = Debug|x64 {060B1890-CBF3-4808-BA99-A4776222093B}.RelWithDebInfo|x64.Build.0 = Release|x64
{5128BD77-6472-4C4A-BE6F-724AD0E589C2}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{5128BD77-6472-4C4A-BE6F-724AD0E589C2}.Release|Mixed Platforms.Build.0 = Release|Win32
{5128BD77-6472-4C4A-BE6F-724AD0E589C2}.Release|Win32.ActiveCfg = Release|Win32
{5128BD77-6472-4C4A-BE6F-724AD0E589C2}.Release|Win32.Build.0 = Release|Win32
{5128BD77-6472-4C4A-BE6F-724AD0E589C2}.Release|x64.ActiveCfg = Release|x64
{5128BD77-6472-4C4A-BE6F-724AD0E589C2}.Release|x64.Build.0 = Release|x64
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {143BD516-20A1-4890-A3E4-F8BFD02220E7}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {143BD516-20A1-4890-A3E4-F8BFD02220E7}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.Debug|Win32.ActiveCfg = Debug|Win32 {143BD516-20A1-4890-A3E4-F8BFD02220E7}.Debug|Win32.ActiveCfg = Debug|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.Debug|Win32.Build.0 = Debug|Win32 {143BD516-20A1-4890-A3E4-F8BFD02220E7}.Debug|Win32.Build.0 = Debug|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.Debug|x64.ActiveCfg = Debug|x64 {143BD516-20A1-4890-A3E4-F8BFD02220E7}.Debug|x64.ActiveCfg = Debug|x64
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.Debug|x64.Build.0 = Debug|x64 {143BD516-20A1-4890-A3E4-F8BFD02220E7}.Debug|x64.Build.0 = Debug|x64
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.MinSizeRel|Win32.Build.0 = Release|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.MinSizeRel|x64.ActiveCfg = Release|x64
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.MinSizeRel|x64.Build.0 = Release|x64
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {143BD516-20A1-4890-A3E4-F8BFD02220E7}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.Release|Mixed Platforms.Build.0 = Release|Win32 {143BD516-20A1-4890-A3E4-F8BFD02220E7}.Release|Mixed Platforms.Build.0 = Release|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.Release|Win32.ActiveCfg = Release|Win32 {143BD516-20A1-4890-A3E4-F8BFD02220E7}.Release|Win32.ActiveCfg = Release|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.Release|Win32.Build.0 = Release|Win32 {143BD516-20A1-4890-A3E4-F8BFD02220E7}.Release|Win32.Build.0 = Release|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.Release|x64.ActiveCfg = Release|x64 {143BD516-20A1-4890-A3E4-F8BFD02220E7}.Release|x64.ActiveCfg = Release|x64
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.Release|x64.Build.0 = Release|x64 {143BD516-20A1-4890-A3E4-F8BFD02220E7}.Release|x64.Build.0 = Release|x64
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{143BD516-20A1-4890-A3E4-F8BFD02220E7}.RelWithDebInfo|x64.Build.0 = Release|x64
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Debug|Win32.ActiveCfg = Debug|Win32 {666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Debug|Win32.ActiveCfg = Debug|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Debug|Win32.Build.0 = Debug|Win32 {666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Debug|Win32.Build.0 = Debug|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Debug|x64.ActiveCfg = Debug|x64 {666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Debug|x64.ActiveCfg = Debug|x64
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Debug|x64.Build.0 = Debug|x64 {666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Debug|x64.Build.0 = Debug|x64
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.MinSizeRel|Mixed Platforms.ActiveCfg = Release|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.MinSizeRel|Win32.Build.0 = Release|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.MinSizeRel|x64.ActiveCfg = Release|x64
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.MinSizeRel|x64.Build.0 = Release|x64
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Release|Mixed Platforms.Build.0 = Release|Win32 {666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Release|Mixed Platforms.Build.0 = Release|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Release|Win32.ActiveCfg = Release|Win32 {666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Release|Win32.ActiveCfg = Release|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Release|Win32.Build.0 = Release|Win32 {666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Release|Win32.Build.0 = Release|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Release|x64.ActiveCfg = Release|x64 {666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Release|x64.ActiveCfg = Release|x64
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Release|x64.Build.0 = Release|x64 {666FEA52-975F-41CD-B224-B19AF3C0ABBA}.Release|x64.Build.0 = Release|x64
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.RelWithDebInfo|Mixed Platforms.ActiveCfg = Release|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.RelWithDebInfo|Win32.Build.0 = Release|Win32
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{666FEA52-975F-41CD-B224-B19AF3C0ABBA}.RelWithDebInfo|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -56,6 +56,7 @@ namespace DanBias
{ {
WindowShell::CreateConsoleWindow(); WindowShell::CreateConsoleWindow();
//if(! m_data->window->CreateWin(WindowShell::WINDOW_INIT_DESC(L"Window", cPOINT(1600, 900), cPOINT())))
if(! m_data->window->CreateWin(WindowShell::WINDOW_INIT_DESC())) if(! m_data->window->CreateWin(WindowShell::WINDOW_INIT_DESC()))
return DanBiasClientReturn_Error; return DanBiasClientReturn_Error;
@ -114,6 +115,10 @@ namespace DanBias
{ {
if(Oyster::Graphics::API::Init(m_data->window->GetHWND(), false, false, Oyster::Math::Float2( 1024, 768)) != Oyster::Graphics::API::Sucsess) if(Oyster::Graphics::API::Init(m_data->window->GetHWND(), false, false, Oyster::Math::Float2( 1024, 768)) != Oyster::Graphics::API::Sucsess)
return E_FAIL; return E_FAIL;
Oyster::Graphics::API::Option p;
p.modelPath = L"..\\Content\\Models\\";
p.texturePath = L"..\\Content\\Textures\\";
Oyster::Graphics::API::SetOptions(p);
return S_OK; return S_OK;
} }
@ -147,6 +152,7 @@ namespace DanBias
if(state != Client::GameClientState::ClientState_Same) if(state != Client::GameClientState::ClientState_Same)
{ {
bool stateVal = false;
m_data->recieverObj->gameClientState->Release(); m_data->recieverObj->gameClientState->Release();
delete m_data->recieverObj->gameClientState; delete m_data->recieverObj->gameClientState;
m_data->recieverObj->gameClientState = NULL; m_data->recieverObj->gameClientState = NULL;
@ -155,23 +161,27 @@ namespace DanBias
{ {
case Client::GameClientState::ClientState_LobbyCreated: case Client::GameClientState::ClientState_LobbyCreated:
m_data->serverOwner = true; m_data->serverOwner = true;
stateVal = true;
case Client::GameClientState::ClientState_Lobby: case Client::GameClientState::ClientState_Lobby:
m_data->recieverObj->gameClientState = new Client::LobbyState(); m_data->recieverObj->gameClientState = new Client::LobbyState();
stateVal = true;
break; break;
case Client::GameClientState::ClientState_Game: case Client::GameClientState::ClientState_Game:
if(m_data->serverOwner)
DanBias::GameServerAPI::GameStart();
m_data->recieverObj->gameClientState = new Client::GameState();
if(m_data->serverOwner)
((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(0);
else
((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(1);
break; break;
default: default:
return E_FAIL; return E_FAIL;
break; break;
} }
m_data->recieverObj->gameClientState->Init(m_data->recieverObj); // send game client
if(stateVal)
{
m_data->recieverObj->gameClientState->Init(m_data->recieverObj); // send game client
}
else
{
}
} }
return S_OK; return S_OK;
@ -179,15 +189,7 @@ namespace DanBias
HRESULT DanBiasGame::Render(float deltaTime) HRESULT DanBiasGame::Render(float deltaTime)
{ {
int isPressed = 0;
if(m_data->inputObj->IsKeyPressed(DIK_A))
{
isPressed = 1;
}
wchar_t title[255];
swprintf(title, sizeof(title), L"| Pressing A: %d | \n", (int)(isPressed));
SetWindowText(m_data->window->GetHWND(), title);
m_data->recieverObj->gameClientState->Render(); m_data->recieverObj->gameClientState->Render();
@ -202,9 +204,11 @@ namespace DanBias
delete m_data->recieverObj; delete m_data->recieverObj;
delete m_data->inputObj; delete m_data->inputObj;
delete m_data; delete m_data;
Oyster::Graphics::API::Clean(); Oyster::Graphics::API::Clean();
GameServerAPI::ServerStop();
return S_OK; return S_OK;
} }

View File

@ -4,6 +4,8 @@
//WTF!? No headers included??? //WTF!? No headers included???
#include "../DanBiasGame/Include/DanBiasGame.h" #include "../DanBiasGame/Include/DanBiasGame.h"
#include "../GameProtocols/GeneralProtocols.h" #include "../GameProtocols/GeneralProtocols.h"
#include "..\GameProtocols\Protocols.h"
#include <Utilities.h>
namespace DanBias namespace DanBias
{ {
@ -14,9 +16,15 @@ namespace DanBias
// receiver function for server messages // receiver function for server messages
// parsing protocols and sending it to the gameState // parsing protocols and sending it to the gameState
void NetworkCallback(Oyster::Network::CustomNetProtocol& p) override //void NetworkCallback(Oyster::Network::CustomNetProtocol& p) override
void GameRecieverObject::DataRecieved(Oyster::Network::NetEvent<Oyster::Network::NetworkClient*, Oyster::Network::NetworkClient::ClientEventArgs> e) override
{ {
Oyster::Network::CustomNetProtocol p = e.args.data.protocol;
int pType = p[0].value.netInt; int pType = p[0].value.netInt;
//printf("Message(%i) arrived at client(%i)\n", pType, this->GetID());
switch (pType) switch (pType)
{ {
case protocol_General_Status: case protocol_General_Status:
@ -60,20 +68,20 @@ namespace DanBias
case protocol_Gameplay_ObjectCreate: case protocol_Gameplay_ObjectCreate:
{ {
Client::GameClientState::NewObj* protocolData = new Client::GameClientState::NewObj; Client::GameClientState::NewObj protocolData;// = new Client::GameClientState::NewObj;
protocolData->object_ID = p[1].value.netInt; protocolData.object_ID = p[1].value.netInt;
protocolData->path = p[2].value.netCharPtr; protocolData.path = p[2].value.netCharPtr;
for(int i = 0; i< 16; i++) for(int i = 0; i< 16; i++)
{ {
protocolData->worldPos[i] = p[i+3].value.netFloat; protocolData.worldPos[i] = p[i+3].value.netFloat;
} }
if(dynamic_cast<Client::GameState*>(gameClientState)) if(dynamic_cast<Client::GameState*>(gameClientState))
((Client::GameState*)gameClientState)->Protocol(protocolData); ((Client::GameState*)gameClientState)->Protocol(&protocolData);
delete p[2].value.netCharPtr; //delete char array //delete p[2].value.netCharPtr; //delete char array
delete protocolData; //delete protocolData;
protocolData = NULL; //protocolData = NULL;
} }
break; break;
case protocol_Gameplay_ObjectDisabled: case protocol_Gameplay_ObjectDisabled:
@ -102,16 +110,42 @@ namespace DanBias
((Client::GameState*)gameClientState)->Protocol(&protocolData); ((Client::GameState*)gameClientState)->Protocol(&protocolData);
} }
break; break;
case protocol_Lobby_Start: case protocol_Lobby_Create:
{ {
/*
if(dynamic_cast<Client::LobbyState*>(gameClientState)) if(dynamic_cast<Client::LobbyState*>(gameClientState))
{ {
GameLogic::Protocol_LobbyCreateGame tp();
int id = p.Get(1).value.netInt;
std::string name = p.Get(19).value.netCharPtr;
Oyster::Math::Float4x4 w;
for(int i = 0; i< 16; i++)
{
w[i] = p[i+2].value.netFloat;
}
gameClientState->Release(); gameClientState->Release();
delete gameClientState; delete gameClientState;
gameClientState = new Client::GameState(); gameClientState = new Client::GameState();
gameClientState->Init(m_data->recieverObj); gameClientState->Init(this);
}*/ std::wstring temp;
Utility::String::StringToWstring(name, temp);
((Client::GameState*)gameClientState)->InitiatePlayer(id, temp, w);
//Do some wait state?
}
}
break;
case protocol_Lobby_Start:
{
if(dynamic_cast<Client::GameState*>(gameClientState))
{
//Game state should start in n seconds
GameLogic::Protocol_LobbyStartGame p(p);
p.seconds;
//Sleep((int)(p.seconds * 1000));
}
} }
break; break;

View File

@ -68,4 +68,7 @@ Oyster::Math::Float3 C_Object::getScale() const
{ {
return this->scale; return this->scale;
} }
//int C_Object::GetId() const
//{
// return
//}

View File

@ -42,6 +42,6 @@ public:
virtual void Render() = 0; virtual void Render() = 0;
virtual void Release() = 0; virtual void Release() = 0;
int GetId(); virtual int GetId() = 0;
};};}; };};};
#endif #endif

View File

@ -2,7 +2,7 @@
Camera::Camera() Camera::Camera()
{ {
this->m_position = Oyster::Math::Float3(0, 50, 0); this->m_position = Oyster::Math::Float3(0, 600, 0);
this->mRight = Oyster::Math::Float3(1, 0, 0); this->mRight = Oyster::Math::Float3(1, 0, 0);
this->mUp = Oyster::Math::Float3(0, 1, 0); this->mUp = Oyster::Math::Float3(0, 1, 0);
this->mLook = Oyster::Math::Float3(0, 0, 1); this->mLook = Oyster::Math::Float3(0, 0, 1);

View File

@ -29,7 +29,8 @@ GameState::GameState(void)
GameState::~GameState(void) GameState::~GameState(void)
{ {
delete this->camera;
delete this->privData;
} }
bool GameState::Init(Oyster::Network::NetworkClient* nwClient) bool GameState::Init(Oyster::Network::NetworkClient* nwClient)
{ {
@ -40,6 +41,10 @@ bool GameState::Init(Oyster::Network::NetworkClient* nwClient)
privData->nwClient = nwClient; privData->nwClient = nwClient;
privData->state = LoadGame(); privData->state = LoadGame();
pitch = 0; pitch = 0;
//tELL SERver ready
nwClient->Send(GameLogic::Protocol_General_Status(GameLogic::Protocol_General_Status::States_ready));
return true; return true;
} }
GameState::gameStateState GameState::LoadGame() GameState::gameStateState GameState::LoadGame()
@ -164,16 +169,18 @@ bool GameState::LoadModels(std::string mapFile)
/*// open file /*// open file
// read file // read file
// init models // init models
int nrOfBoxex = 20; int nrOfBoxex = 5;
privData->modelCount = 3+nrOfBoxex; int id = 100;
myId += privData->modelCount;
int id = 0; // add world model
// add world model
ModelInitData modelData; ModelInitData modelData;
Oyster::Math3D::Float4x4 translate; Oyster::Math3D::Float4x4 translate;
C_Object* obj; C_Object* obj;
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0,0,0)); translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0,0,0));
modelData.world = translate ;//modelData.world * translate modelData.world = translate ;//modelData.world * translate
modelData.world.v[0].x = 2;
modelData.world.v[1].y = 2;
modelData.world.v[2].z = 2;
modelData.modelPath = L"world_earth.dan"; modelData.modelPath = L"world_earth.dan";
modelData.id = id++; modelData.id = id++;
@ -181,7 +188,8 @@ bool GameState::LoadModels(std::string mapFile)
privData->object.push_back(obj); privData->object.push_back(obj);
privData->object[privData->object.size() -1 ]->Init(modelData); privData->object[privData->object.size() -1 ]->Init(modelData);
// add box model
// add box model
modelData.world = Oyster::Math3D::Float4x4::identity; modelData.world = Oyster::Math3D::Float4x4::identity;
modelData.modelPath = L"crate_colonists.dan"; modelData.modelPath = L"crate_colonists.dan";
@ -198,6 +206,7 @@ bool GameState::LoadModels(std::string mapFile)
modelData.world = Oyster::Math3D::Float4x4::identity; modelData.world = Oyster::Math3D::Float4x4::identity;
} }
// add crystal model // add crystal model
modelData.world = Oyster::Math3D::Float4x4::identity; modelData.world = Oyster::Math3D::Float4x4::identity;
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(10, 301, 0)); translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(10, 301, 0));
@ -280,6 +289,7 @@ bool GameState::LoadModels(std::string mapFile)
obj = new C_Player(); obj = new C_Player();
privData->object.push_back(obj); privData->object.push_back(obj);
privData->object[privData->object.size() -1 ]->Init(modelData); */ privData->object[privData->object.size() -1 ]->Init(modelData); */
} }
bool GameState::InitCamera(Float3 startPos) bool GameState::InitCamera(Float3 startPos)
{ {
@ -293,15 +303,58 @@ bool GameState::InitCamera(Float3 startPos)
return true; return true;
} }
void GameState::setClientId(int id) void GameState::InitiatePlayer(int id, std::wstring modelName, Oyster::Math::Float4x4 world)
{ {
myId = id; myId = id;
ModelInitData modelData;
C_Object* obj;
modelData.visible = true;
//modelData.world = world;
//modelData.position = ;
//modelData.rotation = Oyster::Math::Quaternion(Oyster::Math::Float3(2,2,-2), 1);
//modelData.scale = Oyster::Math::Float3(2,2,2);
modelData.modelPath = modelName;
modelData.id = myId;
obj = new C_Player();
this->dynamicObjects.Push(obj);
this->dynamicObjects[this->dynamicObjects.Size() -1 ]->Init(modelData);
Oyster::Math::Float3 right = Oyster::Math::Float3(world[0], world[1], world[2]);
Oyster::Math::Float3 up = Oyster::Math::Float3(world[4], world[5], world[6]);
Oyster::Math::Float3 objForward = (Oyster::Math::Float3(world[8], world[9], world[10]));
Oyster::Math::Float3 pos = Oyster::Math::Float3(world[12], world[13], world[14]);
Oyster::Math::Float3 cameraLook = camera->GetLook();
Oyster::Math::Float3 cameraUp = camera->GetUp();
/*Oyster::Math::Float3 newUp = cameraUp.Dot(up);
up *= newUp;
up.Normalize();
Oyster::Math::Float3 newLook = up.Cross(right);
newLook.Normalize();*/
camera->setRight(right);
camera->setUp(up);
camera->setLook(objForward);
up *= 2;
objForward *= -3;
Oyster::Math::Float3 cameraPos = up + pos + objForward;
camera->SetPosition(cameraPos);
camera->UpdateViewMatrix();
} }
GameClientState::ClientState GameState::Update(float deltaTime, InputClass* KeyInput) GameClientState::ClientState GameState::Update(float deltaTime, InputClass* KeyInput)
{ {
switch (privData->state) switch (privData->state)
{ {
case gameStateState_loading: case gameStateState_loading: //Will this ever happen in this scope??
{ {
// load map // load map
// wait for all players // wait for all players
@ -427,7 +480,7 @@ void GameState::readKeyInput(InputClass* KeyInput)
} }
//send delta mouse movement //send delta mouse movement
if (KeyInput->IsMousePressed()) //if (KeyInput->IsMousePressed())
{ {
camera->Yaw(-KeyInput->GetYaw()); camera->Yaw(-KeyInput->GetYaw());
camera->Pitch(KeyInput->GetPitch()); camera->Pitch(KeyInput->GetPitch());
@ -561,14 +614,14 @@ void GameState::Protocol( ObjPos* pos )
camera->setRight(right); camera->setRight(right);
camera->setUp(up); camera->setUp(up);
camera->setLook(objForward); //camera->setLook(objForward);
up *= 1; up *= 1;
objForward *= -2; objForward *= -2;
Oyster::Math::Float3 cameraPos = up + pos + objForward; Oyster::Math::Float3 cameraPos = pos + up + objForward;
camera->SetPosition(cameraPos); camera->SetPosition(cameraPos);
camera->UpdateViewMatrix(); camera->UpdateViewMatrix();
} }
} }
} }

View File

@ -36,8 +36,8 @@ private:
struct myData; struct myData;
myData* privData; myData* privData;
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<C_StaticObj>> staticObjects; Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<C_StaticObj>> staticObjects;
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<C_DynamicObj>> dynamicObjects; Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<C_Object>> dynamicObjects;
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<C_DynamicObj>> playObjects; //Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<C_Player>> playObjects;
public: public:
GameState(void); GameState(void);
~GameState(void); ~GameState(void);
@ -45,8 +45,8 @@ public:
GameClientState::ClientState Update(float deltaTime, InputClass* KeyInput) override; GameClientState::ClientState Update(float deltaTime, InputClass* KeyInput) override;
bool LoadModels(std::string mapFile) ; bool LoadModels(std::string mapFile) ;
bool InitCamera(Oyster::Math::Float3 startPos) ; bool InitCamera(Oyster::Math::Float3 startPos) ;
void InitiatePlayer(int id, std::wstring modelName, Oyster::Math::Float4x4 world);
gameStateState LoadGame(); gameStateState LoadGame();
void setClientId(int id);
void readKeyInput(InputClass* KeyInput); void readKeyInput(InputClass* KeyInput);
bool Render()override; bool Render()override;
bool Release()override; bool Release()override;

View File

@ -5,6 +5,7 @@
#include "C_obj/C_StaticObj.h" #include "C_obj/C_StaticObj.h"
#include "C_obj/C_DynamicObj.h" #include "C_obj/C_DynamicObj.h"
#include <GameServerAPI.h> #include <GameServerAPI.h>
#include <Protocols.h>
using namespace DanBias::Client; using namespace DanBias::Client;
@ -57,7 +58,7 @@ bool LobbyState::LoadModels(std::wstring file)
modelData.rotation = Oyster::Math::Quaternion::identity; modelData.rotation = Oyster::Math::Quaternion::identity;
modelData.scale = Oyster::Math::Float3(1,1,1); modelData.scale = Oyster::Math::Float3(1,1,1);
modelData.visible = true; modelData.visible = true;
modelData.modelPath = L"..\\Content\\Models\\box_2.dan"; modelData.modelPath = L"crate_colonists.dan";
// load models // load models
privData->object[0] = new C_StaticObj(); privData->object[0] = new C_StaticObj();
privData->object[0]->Init(modelData); privData->object[0]->Init(modelData);
@ -89,9 +90,15 @@ GameClientState::ClientState LobbyState::Update(float deltaTime, InputClass* Key
// send data to server // send data to server
// check data from server // check data from server
if( KeyInput->IsKeyPressed(DIK_G)) if(GameServerAPI::ServerIsRunning() && GameServerAPI::ServerIsRunning()) //May be a problem if server is not shut down properly after lan session.
{ {
return ClientState_Game; if( KeyInput->IsKeyPressed(DIK_G))
{
if(!DanBias::GameServerAPI::GameStart())
{
//this->nwClient->Send(GameLogic::Protocol_LobbyStartGame());
}
}
} }
return ClientState_Same; return ClientState_Same;

View File

@ -56,14 +56,14 @@ bool LoginState::LoadModels(std::wstring file)
modelData.rotation = Oyster::Math::Quaternion::identity; modelData.rotation = Oyster::Math::Quaternion::identity;
modelData.scale = Oyster::Math::Float3(1,1,1); modelData.scale = Oyster::Math::Float3(1,1,1);
modelData.visible = true; modelData.visible = true;
modelData.modelPath = L"identityPlane.dan"; modelData.modelPath = L"box.dan";
modelData.position = Oyster::Math::Float3(2,2,2); modelData.position = Oyster::Math::Float3(2,2,2);
privData->object[0] = new C_StaticObj(); privData->object[0] = new C_StaticObj();
privData->object[0]->Init(modelData); privData->object[0]->Init(modelData);
modelData.position = Oyster::Math::Float3(0,0,-2); modelData.position = Oyster::Math::Float3(-2,0,-2);
privData->object[1] = new C_StaticObj(); privData->object[1] = new C_StaticObj();
privData->object[1]->Init(modelData); privData->object[1]->Init(modelData);
return true; return true;
@ -97,7 +97,7 @@ GameClientState::ClientState LoginState::Update(float deltaTime, InputClass* Key
DanBias::GameServerAPI::ServerInitiate(desc); DanBias::GameServerAPI::ServerInitiate(desc);
DanBias::GameServerAPI::ServerStart(); DanBias::GameServerAPI::ServerStart();
// my ip // my ip
nwClient->Connect(15151, "127.0.0.1"); nwClient->Connect(15152, "127.0.0.1");
if (!nwClient->IsConnected()) if (!nwClient->IsConnected())
{ {
@ -110,7 +110,7 @@ GameClientState::ClientState LoginState::Update(float deltaTime, InputClass* Key
if( KeyInput->IsKeyPressed(DIK_J)) if( KeyInput->IsKeyPressed(DIK_J))
{ {
// game ip // game ip
nwClient->Connect(15151, "127.0.0.1"); nwClient->Connect(15152, "127.0.0.1");
if (!nwClient->IsConnected()) if (!nwClient->IsConnected())
{ {

View File

@ -64,11 +64,11 @@ void AttatchmentMassDriver::Update(float dt)
state = heldObject->GetState(); state = heldObject->GetState();
Oyster::Math::Float3 ownerPos = owner->GetPosition(); Oyster::Math::Float3 ownerPos = owner->GetPosition();
Oyster::Physics::ICustomBody::State ownerState = owner->GetRigidBody()->GetState(); Oyster::Physics::ICustomBody::State ownerState = owner->GetRigidBody()->GetState();
Oyster::Math::Float3 up = -ownerState.GetGravityNormal(); Oyster::Math::Float3 up = -ownerState.GetOrientation().v[2];
up *= -0.3; up *= -0.3;
Oyster::Math::Float3 pos = ownerPos + up + (owner->GetLookDir().GetNormalized()*5); Oyster::Math::Float3 pos = ownerPos + up + (owner->GetLookDir().GetNormalized()*5);
state.SetCenterPosition(pos); state.centerPos = pos;
heldObject->SetState(state); heldObject->SetState(state);
} }
@ -88,7 +88,7 @@ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float
Oyster::Physics::API::Instance().ReleaseFromLimbo(heldObject); Oyster::Physics::API::Instance().ReleaseFromLimbo(heldObject);
pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (700); pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (700);
Oyster::Physics::ICustomBody::State state = heldObject->GetState(); Oyster::Physics::ICustomBody::State state = heldObject->GetState();
state.ApplyLinearImpulse((Oyster::Math::Float3)pushForce); //state.ApplyLinearImpulse((Oyster::Math::Float3)pushForce);
heldObject->SetState(state); heldObject->SetState(state);
hasObject = false; hasObject = false;
@ -118,7 +118,7 @@ void AttatchmentMassDriver::ForceZip(const WEAPON_FIRE &usage, float dt)
Oyster::Physics::Struct::CustomBodyState state = this->owner->GetRigidBody()->GetState(); Oyster::Physics::Struct::CustomBodyState state = this->owner->GetRigidBody()->GetState();
//do something with state //do something with state
state.ApplyLinearImpulse(Oyster::Math::Float3(this->owner->GetLookDir()) * (500 * dt)); //state.ApplyLinearImpulse(Oyster::Math::Float3(this->owner->GetLookDir()) * (500 * dt));
this->owner->GetRigidBody()->SetState(state); this->owner->GetRigidBody()->SetState(state);
} }
@ -135,7 +135,7 @@ void AttatchmentMassDriver::ForcePull(const WEAPON_FIRE &usage, float dt)
//if no object has been picked up then suck objects towards you //if no object has been picked up then suck objects towards you
Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (100 * dt); Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (100 * dt);
Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition()); Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetState().GetOrientation().v[2].xyz, owner->GetPosition());
Oyster::Math::Float4x4 hitSpace = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/4,1,1,20); Oyster::Math::Float4x4 hitSpace = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/4,1,1,20);
Oyster::Collision3D::Frustrum hitFrustum = Oyster::Collision3D::Frustrum(Oyster::Math3D::ViewProjectionMatrix(aim,hitSpace)); Oyster::Collision3D::Frustrum hitFrustum = Oyster::Collision3D::Frustrum(Oyster::Math3D::ViewProjectionMatrix(aim,hitSpace));

View File

@ -14,7 +14,10 @@ AttatchmentSocket::AttatchmentSocket(void)
AttatchmentSocket::~AttatchmentSocket(void) AttatchmentSocket::~AttatchmentSocket(void)
{ {
if(this->attatchment)
delete this->attatchment;
this->attatchment = 0;
} }
IAttatchment* AttatchmentSocket::GetAttatchment() IAttatchment* AttatchmentSocket::GetAttatchment()

View File

@ -68,7 +68,7 @@ using namespace GameLogic;
Oyster::Physics::ICustomBody::State state; Oyster::Physics::ICustomBody::State state;
state = obj.GetState(); state = obj.GetState();
state.ApplyLinearImpulse(force); //state.ApplyLinearImpulse(force);
obj.SetState(state); obj.SetState(state);
} }
@ -83,7 +83,7 @@ using namespace GameLogic;
if(kineticEnergyLoss > forceThreashHold) //should only take damage if the force is high enough if(kineticEnergyLoss > forceThreashHold) //should only take damage if the force is high enough
{ {
damageDone = kineticEnergyLoss * 0.10f; damageDone = (int)(kineticEnergyLoss * 0.10f);
//player.DamageLife(damageDone); //player.DamageLife(damageDone);
} }
@ -130,7 +130,7 @@ using namespace GameLogic;
return; return;
state = obj->GetState(); state = obj->GetState();
state.ApplyLinearImpulse(((forcePushData*)(args))->pushForce); //state.ApplyLinearImpulse(((forcePushData*)(args))->pushForce);
obj->SetState(state); obj->SetState(state);
} }

View File

@ -68,12 +68,12 @@ void Game::GetAllPlayerPositions() const
Game::PlayerData* Game::CreatePlayer() Game::PlayerData* Game::CreatePlayer()
{ {
// Find a free space in array or insert at end // Find a free space in array or insert at end
int id = InsertObject(this->players, (PlayerData*)0); int i = InsertObject(this->players, (PlayerData*)0);
this->players[id] = new PlayerData(); this->players[i] = new PlayerData();
this->players[id]->player->GetRigidBody()->SetSubscription(Game::PhysicsOnMove); this->players[i]->player->GetRigidBody()->SetSubscription(Game::PhysicsOnMove);
return this->players[id]; return this->players[i];
} }
Game::LevelData* Game::CreateLevel() Game::LevelData* Game::CreateLevel()
@ -94,42 +94,23 @@ void Game::CreateTeam()
bool Game::NewFrame() bool Game::NewFrame()
{ {
for (unsigned int i = 0; i < this->players.Size(); i++) for (unsigned int i = 0; i < this->players.Size(); i++)
{ {
if(this->players[i]->player) this->players[i]->player->BeginFrame(); if(this->players[i]->player) this->players[i]->player->BeginFrame();
} }
API::Instance().Update(); API::Instance().UpdateWorld();
for (unsigned int i = 0; i < this->players.Size(); i++) for (unsigned int i = 0; i < this->players.Size(); i++)
{ {
if(this->players[i]->player) this->players[i]->player->EndFrame(); if(this->players[i]->player) this->players[i]->player->EndFrame();
gameInstance.onMoveFnc(this->players[i]);
} }
for (unsigned int i = 0; i < this->players.Size(); i++) for (unsigned int i = 0; i < this->level->level->dynamicObjects.Size(); i++)
{ {
if(this->players[i]->player) this->players[i]->player->BeginFrame(); gameInstance.onMoveFnc(this->level->level->dynamicObjects[i]);
} }
API::Instance().Update();
for (unsigned int i = 0; i < this->players.Size(); i++)
{
if(this->players[i]->player) this->players[i]->player->EndFrame();
}
for (unsigned int i = 0; i < this->players.Size(); i++)
{
if(this->players[i]->player) this->players[i]->player->BeginFrame();
}
API::Instance().Update();
for (unsigned int i = 0; i < this->players.Size(); i++)
{
if(this->players[i]->player) this->players[i]->player->EndFrame();
}
gameInstance.onMoveFnc(this->level);
return true; return true;
} }
@ -144,24 +125,21 @@ void Game::SetFrameTimeLength( float seconds )
this->frameTime = seconds; this->frameTime = seconds;
} }
void Game::SetSubscription(GameEvent::ObjectEventFunctionType type, GameEvent::ObjectEventFunction functionPointer) void Game::SetSubscription(GameEvent::ObjectMovedFunction functionPointer)
{ {
switch (type) this->onMoveFnc = functionPointer;
{ }
case GameLogic::GameEvent::ObjectEventFunctionType_OnMove: void Game::SetSubscription(GameEvent::ObjectDisabledFunction functionPointer)
this->onMoveFnc = functionPointer; {
break; this->onDisableFnc = functionPointer;
case GameLogic::GameEvent::ObjectEventFunctionType_OnDead:
this->onDisableFnc = functionPointer;
break;
}
} }
bool Game::Initiate() bool Game::Initiate()
{ {
API::Instance().Init((int)pow(2u, 9u), 1u, Oyster::Math::Float3()); API::Instance().Init();
API::Instance().SetSubscription(Game::PhysicsOnDestroy); //API::Instance().SetSubscription(Game::PhysicsOnDestroy);
//API::Instance().SetFrameTimeLength(this->frameTime);
this->initiated = true; this->initiated = true;
return true; return true;
} }
@ -184,6 +162,6 @@ void Game::PhysicsOnMove(const ICustomBody *object)
} }
void Game::PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer<ICustomBody> proto) void Game::PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer<ICustomBody> proto)
{ {
if(gameInstance.onDisableFnc) gameInstance.onDisableFnc(0); if(gameInstance.onDisableFnc) gameInstance.onDisableFnc(0, 0);
} }

View File

@ -69,7 +69,8 @@ namespace GameLogic
bool NewFrame() override; bool NewFrame() override;
void SetFPS( int FPS ) override; void SetFPS( int FPS ) override;
void SetFrameTimeLength( float seconds ) override; void SetFrameTimeLength( float seconds ) override;
void SetSubscription(GameEvent::ObjectEventFunctionType type, GameEvent::ObjectEventFunction functionPointer) override; void SetSubscription(GameEvent::ObjectMovedFunction functionPointer) override;
void SetSubscription(GameEvent::ObjectDisabledFunction functionPointer) override;
bool Initiate() override; bool Initiate() override;
float GetFrameTime() const; float GetFrameTime() const;
@ -81,8 +82,8 @@ namespace GameLogic
LevelData* level; LevelData* level;
float frameTime; float frameTime;
bool initiated; bool initiated;
GameEvent::ObjectEventFunction onDisableFnc; GameEvent::ObjectDisabledFunction onDisableFnc;
GameEvent::ObjectEventFunction onMoveFnc; GameEvent::ObjectMovedFunction onMoveFnc;
}; };
} }

View File

@ -23,16 +23,8 @@ namespace GameLogic
*/ */
namespace GameEvent namespace GameEvent
{ {
/** typedef void(*ObjectMovedFunction)(IObjectData* object); // Callback method that recieves and object
* The type of event to listen on. typedef void(*ObjectDisabledFunction)(IObjectData* object, float seconds); // Callback method that recieves and object
*/
enum ObjectEventFunctionType
{
ObjectEventFunctionType_OnMove,
ObjectEventFunctionType_OnDead,
};
typedef void(*ObjectEventFunction)(IObjectData* object); // Callback method that recieves and object
//etc... //etc...
}; };
@ -147,17 +139,22 @@ namespace GameLogic
/** Set the frame time in fps /** Set the frame time in fps
* @param FPS The fps to set * @param FPS The fps to set
*/ */
virtual void SetFPS( int FPS = 60 ) = 0; virtual void SetFPS( int FPS = 120 ) = 0;
/** Set the frames time in seconds /** Set the frames time in seconds
* @param seconds The frame length * @param seconds The frame length
*/ */
virtual void SetFrameTimeLength( float seconds ) = 0; virtual void SetFrameTimeLength( float seconds = (1.0f/120.0f) ) = 0;
/** Set a specific object event subscription callback /** Set a specific object event subscription callback
* @param * @param
*/ */
virtual void SetSubscription(GameEvent::ObjectEventFunctionType type, GameEvent::ObjectEventFunction functionPointer) = 0; virtual void SetSubscription(GameEvent::ObjectMovedFunction functionPointer) = 0;
/** Set a specific object event subscription callback
* @param
*/
virtual void SetSubscription(GameEvent::ObjectDisabledFunction functionPointer) = 0;
}; };
} }

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<ShowAllFiles>false</ShowAllFiles> <ShowAllFiles>true</ShowAllFiles>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory> <LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>

View File

@ -6,26 +6,26 @@ using namespace GameLogic;
Game::PlayerData::PlayerData() Game::PlayerData::PlayerData()
{ {
//set some stats that are appropriate to a player //set some stats that are appropriate to a player
Oyster::Physics::API::SimpleBodyDescription sbDesc; Oyster::Math::Float3 centerPosition = Oyster::Math::Float3(0,608,-5);
sbDesc.centerPosition = Oyster::Math::Float3(0,308,0); Oyster::Math::Float3 size = Oyster::Math::Float3(0.25f,1.0f,0.5f);
sbDesc.size = Oyster::Math::Float3(0.5f,2,1); Oyster::Math::Float mass = 15;
sbDesc.mass = 70; Oyster::Math::Float restitutionCoeff = 0.5;
sbDesc.restitutionCoeff = 0.5; Oyster::Math::Float frictionCoeff_Static = 0.4;
sbDesc.frictionCoeff_Static = 0.4; Oyster::Math::Float frictionCoeff_Dynamic = 0.3;
sbDesc.frictionCoeff_Dynamic = 0.3; //sbDesc.quaternion = Oyster::Math::Float3(0, Oyster::Math::pi, 0);
sbDesc.rotation = Oyster::Math::Float3(0, Oyster::Math::pi, 0);
//create rigid body //create rigid body
Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); Oyster::Physics::ICustomBody* rigidBody = Oyster::Physics::API::Instance().AddCollisionBox(size, Oyster::Math::Float4(0, 0, 0, 1), centerPosition, mass);
//create player with this rigid body //create player with this rigid body
this->player = new Player(rigidBody,Level::LevelCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER); this->player = new Player(rigidBody,Level::LevelCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER);
this->player->GetRigidBody()->SetCustomTag(this); this->player->GetRigidBody()->SetCustomTag(this);
/*Oyster::Physics::ICustomBody::State state;
Oyster::Physics::ICustomBody::State state;
this->player->GetRigidBody()->GetState(state); this->player->GetRigidBody()->GetState(state);
state.SetRotation(Oyster::Math::Float3(0, Oyster::Math::pi, 0)); //state.SetRotation(Oyster::Math::Float3(0, Oyster::Math::pi, 0));
this->player->GetRigidBody()->SetState(state); this->player->GetRigidBody()->SetState(state);
player->EndFrame();*/ player->EndFrame();
} }
Game::PlayerData::PlayerData(int playerID,int teamID) Game::PlayerData::PlayerData(int playerID,int teamID)
{ {

View File

@ -1,5 +1,6 @@
#include "Level.h" #include "Level.h"
#include "CollisionManager.h" #include "CollisionManager.h"
#include "Game.h"
using namespace GameLogic; using namespace GameLogic;
using namespace Utility::DynamicMemory; using namespace Utility::DynamicMemory;
@ -12,6 +13,8 @@ Level::Level(void)
} }
Level::~Level(void) Level::~Level(void)
{ {
delete this->levelObj;
this->levelObj = NULL;
} }
void Level::parseObjectType(ObjectTypeHeader* obj) void Level::parseObjectType(ObjectTypeHeader* obj)
{ {
@ -37,7 +40,7 @@ void Level::parseObjectType(ObjectTypeHeader* obj)
break; break;
}*/ }*/
} }
void Level::parsePhysicsObj(PhysicsObject* obj) void Level::parsePhysicsObj(LevelLoaderInternal::PhysicsObject* obj)
{ {
// offset physObj med modelObj // offset physObj med modelObj
} }
@ -65,122 +68,124 @@ void Level::InitiateLevel(std::string levelPath)
{ {
ObjectHeader* staticObjData = ((ObjectHeader*)obj); ObjectHeader* staticObjData = ((ObjectHeader*)obj);
PhysicsObject* staticObjPhysicData = ((ObjectHeader*)obj); LevelLoaderInternal::PhysicsObject* staticObjPhysicData = ((ObjectHeader*)obj);
staticObjData->ModelFile; staticObjData->ModelFile;
ICustomBody* rigidBody_Static; ICustomBody* rigidBody_Static;
if( staticObjPhysicData->geometryType = CollisionGeometryType_Box) //if( staticObjPhysicData->geometryType = CollisionGeometryType_Box)
{ //{
API::SimpleBodyDescription sbDesc_Static; // //API::SimpleBodyDescription sbDesc_Static;
sbDesc_Static.centerPosition = staticObjData->position; // //sbDesc_Static.centerPosition = staticObjData->position;
sbDesc_Static.ignoreGravity = false; // because it is static // //sbDesc_Static.ignoreGravity = false; // because it is static
sbDesc_Static.rotation = Oyster::Math::Float3(staticObjData->rotation[0], staticObjData->rotation[1],staticObjData->rotation[2]);//Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0); // //sbDesc_Static.rotation = Oyster::Math::Float3(staticObjData->rotation[0], staticObjData->rotation[1],staticObjData->rotation[2]);//Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0);
//sbDesc_Static.inertiaTensor.Cuboid(staticObjPhysicData->mass); // ////sbDesc_Static.inertiaTensor.Cuboid(staticObjPhysicData->mass);
sbDesc_Static.mass = staticObjPhysicData->mass; // //sbDesc_Static.mass = staticObjPhysicData->mass;
sbDesc_Static.frictionCoeff_Static = staticObjPhysicData->frictionCoeffStatic; // //sbDesc_Static.frictionCoeff_Static = staticObjPhysicData->frictionCoeffStatic;
sbDesc_Static.frictionCoeff_Dynamic = staticObjPhysicData->frictionCoeffDynamic; // //sbDesc_Static.frictionCoeff_Dynamic = staticObjPhysicData->frictionCoeffDynamic;
//sbDesc_Static.restitutionCoeff = // ////sbDesc_Static.restitutionCoeff =
sbDesc_Static.size = Oyster::Math::Float3(40,40,40); // //sbDesc_Static.size = Oyster::Math::Float3(40,40,40);
rigidBody_Static = API::Instance().CreateRigidBody(sbDesc_Static).Release(); // //rigidBody_Static = API::Instance().CreateRigidBody(sbDesc_Static).Release();
if(rigidBody_Static) // //if(rigidBody_Static)
{ // //{
this->staticObjects.Push(new StaticObject(rigidBody_Static,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC)); // // this->staticObjects.Push(new StaticObject(rigidBody_Static,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC));
int id = this->staticObjects.Size()-1; // // int id = this->staticObjects.Size()-1;
rigidBody_Static->SetCustomTag(this->staticObjects[this->staticObjects.Size()-1]); // // rigidBody_Static->SetCustomTag(this->staticObjects[this->staticObjects.Size()-1]);
} // //}
} //}
if( staticObjPhysicData->geometryType = CollisionGeometryType_Sphere) //if( staticObjPhysicData->geometryType = CollisionGeometryType_Sphere)
{ //{
API::SphericalBodyDescription sbDesc_Static; // //API::SphericalBodyDescription sbDesc_Static;
sbDesc_Static.centerPosition = staticObjData->position; // //sbDesc_Static.centerPosition = staticObjData->position;
sbDesc_Static.ignoreGravity = true; // because it is static // //sbDesc_Static.ignoreGravity = true; // because it is static
sbDesc_Static.rotation = Oyster::Math::Float3(staticObjData->rotation[0], staticObjData->rotation[1],staticObjData->rotation[2]);//Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0); // //sbDesc_Static.rotation = Oyster::Math::Float3(staticObjData->rotation[0], staticObjData->rotation[1],staticObjData->rotation[2]);//Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0);
//sbDesc_Static.inertiaTensor.Sphere(staticObjPhysicData->mass); // ////sbDesc_Static.inertiaTensor.Sphere(staticObjPhysicData->mass);
sbDesc_Static.mass = staticObjPhysicData->mass; // //sbDesc_Static.mass = staticObjPhysicData->mass;
sbDesc_Static.frictionCoeff_Static = staticObjPhysicData->frictionCoeffStatic; // //sbDesc_Static.frictionCoeff_Static = staticObjPhysicData->frictionCoeffStatic;
sbDesc_Static.frictionCoeff_Dynamic = staticObjPhysicData->frictionCoeffDynamic; // //sbDesc_Static.frictionCoeff_Dynamic = staticObjPhysicData->frictionCoeffDynamic;
//sbDesc_Static.restitutionCoeff = // ////sbDesc_Static.restitutionCoeff =
//sbDesc_Static.radius = // ////sbDesc_Static.radius =
rigidBody_Static = API::Instance().CreateRigidBody(sbDesc_Static).Release(); // //rigidBody_Static = API::Instance().CreateRigidBody(sbDesc_Static).Release();
if(rigidBody_Static) // if(rigidBody_Static)
{ // {
this->staticObjects.Push(new StaticObject(rigidBody_Static,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC)); // this->staticObjects.Push(new StaticObject(rigidBody_Static,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC));
int id = this->staticObjects.Size()-1; // int id = this->staticObjects.Size()-1;
rigidBody_Static->SetCustomTag(this->staticObjects[this->staticObjects.Size()-1]); // rigidBody_Static->SetCustomTag(this->staticObjects[this->staticObjects.Size()-1]);
} // }
if (OBJECT_TYPE::OBJECT_TYPE_WORLD) // if (OBJECT_TYPE::OBJECT_TYPE_WORLD)
{ // {
API::Gravity gravityWell; // /*API::Gravity gravityWell;
gravityWell.gravityType = API::Gravity::GravityType_Well; // gravityWell.gravityType = API::Gravity::GravityType_Well;
gravityWell.well.mass = 1e17f; // gravityWell.well.mass = 1e17f;
gravityWell.well.position = Oyster::Math::Float4(0,0,0,1); // gravityWell.well.position = Oyster::Math::Float4(0,0,0,1);
API::Instance().AddGravity(gravityWell); // API::Instance().AddGravity(gravityWell);*/
} // }
} //}
} }
break; break;
case ObjectType::ObjectType_Dynamic: case ObjectType::ObjectType_Dynamic:
{ {
ObjectHeader* staticObjData = ((ObjectHeader*)obj); ObjectHeader* staticObjData = ((ObjectHeader*)obj);
PhysicsObject* staticObjPhysicData = ((ObjectHeader*)obj); LevelLoaderInternal::PhysicsObject* staticObjPhysicData = ((ObjectHeader*)obj);
staticObjData->ModelFile; staticObjData->ModelFile;
ICustomBody* rigidBody_Dynamic; ICustomBody* rigidBody_Dynamic;
if( staticObjPhysicData->geometryType = CollisionGeometryType_Box) //if( staticObjPhysicData->geometryType = CollisionGeometryType_Box)
{ //{
API::SimpleBodyDescription sbDesc_Dynamic; // //API::Instance().AddCollisionBox()
// //API::SimpleBodyDescription sbDesc_Dynamic;
sbDesc_Dynamic.centerPosition = staticObjData->position; // //sbDesc_Dynamic.centerPosition = staticObjData->position;
sbDesc_Dynamic.ignoreGravity = false; // because it is static // //sbDesc_Dynamic.ignoreGravity = false; // because it is static
sbDesc_Dynamic.rotation = Oyster::Math::Float3(staticObjData->rotation[0], staticObjData->rotation[1],staticObjData->rotation[2]);//Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0); // //sbDesc_Dynamic.rotation = Oyster::Math::Float3(staticObjData->rotation[0], staticObjData->rotation[1],staticObjData->rotation[2]);//Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0);
//sbDesc_Static.inertiaTensor.Cuboid(staticObjPhysicData->mass); // ////sbDesc_Static.inertiaTensor.Cuboid(staticObjPhysicData->mass);
sbDesc_Dynamic.mass = staticObjPhysicData->mass; // //sbDesc_Dynamic.mass = staticObjPhysicData->mass;
sbDesc_Dynamic.frictionCoeff_Static = staticObjPhysicData->frictionCoeffStatic; // //sbDesc_Dynamic.frictionCoeff_Static = staticObjPhysicData->frictionCoeffStatic;
sbDesc_Dynamic.frictionCoeff_Dynamic = staticObjPhysicData->frictionCoeffDynamic; // //sbDesc_Dynamic.frictionCoeff_Dynamic = staticObjPhysicData->frictionCoeffDynamic;
//sbDesc_Static.restitutionCoeff = // ////sbDesc_Static.restitutionCoeff =
sbDesc_Dynamic.size = Oyster::Math::Float3(40,40,40); // //sbDesc_Dynamic.size = Oyster::Math::Float3(40,40,40);
rigidBody_Dynamic = API::Instance().CreateRigidBody(sbDesc_Dynamic).Release(); // //rigidBody_Dynamic = API::Instance().CreateRigidBody(sbDesc_Dynamic).Release();
if(rigidBody_Dynamic) // //if(rigidBody_Dynamic)
{ // //{
rigidBody_Dynamic->SetSubscription(Level::PhysicsOnMoveLevel); // // rigidBody_Dynamic->SetSubscription(Level::PhysicsOnMoveLevel);
this->dynamicObjects.Push(new DynamicObject(rigidBody_Dynamic,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC)); // // this->dynamicObjects.Push(new DynamicObject(rigidBody_Dynamic,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC));
int id = this->dynamicObjects.Size()-1; // // int id = this->dynamicObjects.Size()-1;
rigidBody_Dynamic->SetCustomTag(this->dynamicObjects[this->dynamicObjects.Size()-1]); // // rigidBody_Dynamic->SetCustomTag(this->dynamicObjects[this->dynamicObjects.Size()-1]);
} // //}
} //}
if( staticObjPhysicData->geometryType = CollisionGeometryType_Sphere) //if( staticObjPhysicData->geometryType = CollisionGeometryType_Sphere)
{ //{
API::SphericalBodyDescription sbDesc_Dynamic; // //API::Instance().AddCollisionBox()
// //API::SphericalBodyDescription sbDesc_Dynamic;
sbDesc_Dynamic.centerPosition = staticObjData->position; // //sbDesc_Dynamic.centerPosition = staticObjData->position;
sbDesc_Dynamic.ignoreGravity = false; // use gravity on dynamic obj // //sbDesc_Dynamic.ignoreGravity = false; // use gravity on dynamic obj
sbDesc_Dynamic.rotation = Oyster::Math::Float3(staticObjData->rotation[0], staticObjData->rotation[1],staticObjData->rotation[2]);//Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0); // //sbDesc_Dynamic.rotation = Oyster::Math::Float3(staticObjData->rotation[0], staticObjData->rotation[1],staticObjData->rotation[2]);//Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0);
//sbDesc_Static.inertiaTensor.Sphere(staticObjPhysicData->mass); // ////sbDesc_Static.inertiaTensor.Sphere(staticObjPhysicData->mass);
sbDesc_Dynamic.mass = staticObjPhysicData->mass; // //sbDesc_Dynamic.mass = staticObjPhysicData->mass;
sbDesc_Dynamic.frictionCoeff_Static = staticObjPhysicData->frictionCoeffStatic; // //sbDesc_Dynamic.frictionCoeff_Static = staticObjPhysicData->frictionCoeffStatic;
sbDesc_Dynamic.frictionCoeff_Dynamic = staticObjPhysicData->frictionCoeffDynamic; // //sbDesc_Dynamic.frictionCoeff_Dynamic = staticObjPhysicData->frictionCoeffDynamic;
//sbDesc_Static.restitutionCoeff = // ////sbDesc_Static.restitutionCoeff =
//sbDesc_Static.radius = // ////sbDesc_Static.radius =
rigidBody_Dynamic = API::Instance().CreateRigidBody(sbDesc_Dynamic).Release(); // //rigidBody_Dynamic = API::Instance().CreateRigidBody(sbDesc_Dynamic).Release();
if(rigidBody_Dynamic) // //if(rigidBody_Dynamic)
{ // //{
rigidBody_Dynamic->SetSubscription(Level::PhysicsOnMoveLevel); // // rigidBody_Dynamic->SetSubscription(Level::PhysicsOnMoveLevel);
this->dynamicObjects.Push(new DynamicObject(rigidBody_Dynamic,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC)); // // this->dynamicObjects.Push(new DynamicObject(rigidBody_Dynamic,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC));
int id = this->dynamicObjects.Size()-1; // // int id = this->dynamicObjects.Size()-1;
rigidBody_Dynamic->SetCustomTag(this->dynamicObjects[this->dynamicObjects.Size()-1]); // // rigidBody_Dynamic->SetCustomTag(this->dynamicObjects[this->dynamicObjects.Size()-1]);
} // //}
} //}
} }
break; break;
case ObjectType::ObjectType_Light: case ObjectType::ObjectType_Light:
@ -223,33 +228,17 @@ void Level::InitiateLevel(float radius)
z /= norm; z /= norm;
} }
int idCount = 100;
// add level sphere // add level sphere
API::SphericalBodyDescription sbDesc; ICustomBody* rigidBody = API::Instance().AddCollisionSphere(599.2f, Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(0, 0, 0), 0);
sbDesc.centerPosition = Oyster::Math::Float4(0,0,0,1);
sbDesc.ignoreGravity = true;
sbDesc.radius = 300;
sbDesc.mass = 100;
sbDesc.frictionCoeff_Static = 0;
sbDesc.frictionCoeff_Dynamic = 0;
//sbDesc.rotation =
ICustomBody* rigidBody = API::Instance().CreateRigidBody(sbDesc).Release();
ICustomBody::State state; ICustomBody::State state;
rigidBody->GetState(state); rigidBody->GetState(state);
state.SetRestitutionCoeff(0.2); state.restitutionCoeff = 0.2f;
rigidBody->SetState(state); rigidBody->SetState(state);
levelObj = new StaticObject(rigidBody, LevelCollisionBefore, LevelCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_WORLD); levelObj = new StaticObject(rigidBody, LevelCollisionBefore, LevelCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_WORLD);
this->levelObj->objectID = idCount++;
rigidBody->SetCustomTag(levelObj); rigidBody->SetCustomTag(levelObj);
//this->dynamicObjects = new DynamicArray< DynamicObject>;
// add box
API::SimpleBodyDescription sbDesc_TestBox;
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(10,320,0,0);
sbDesc_TestBox.ignoreGravity = false;
sbDesc_TestBox.mass = 20;
sbDesc_TestBox.size = Oyster::Math::Float4(2,2,2,0);
ICustomBody* rigidBody_TestBox; ICustomBody* rigidBody_TestBox;
@ -258,85 +247,57 @@ void Level::InitiateLevel(float radius)
int offset = 0; int offset = 0;
for(int i =0; i< nrOfBoxex; i ++) for(int i =0; i< nrOfBoxex; i ++)
{ {
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(0,305 + i*5,5,1); rigidBody_TestBox = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(0, 605 + i*5, 10), 5);
rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX)); this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX));
this->dynamicObjects[i]->objectID = idCount++;
rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i]); rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i]);
} }
offset += nrOfBoxex; /*offset += nrOfBoxex;
for(int i =0; i< nrOfBoxex; i ++) for(int i =0; i< nrOfBoxex; i ++)
{ {
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(-20,320, -200 +( i*7),0); rigidBody_TestBox = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(0,5, -605 -( i*5)), 5);
rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX)); this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX));
rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i+offset]); rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i+offset]);
} }
offset += nrOfBoxex; offset += nrOfBoxex;
for(int i =0; i< nrOfBoxex; i ++) for(int i =0; i< nrOfBoxex; i ++)
{ {
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(200,320 + ( i*7),0,0); rigidBody_TestBox = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(200, 620 + ( i*7), 0), 5);
rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX)); this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX));
rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i+offset]); rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i+offset]);
} }
offset += nrOfBoxex; offset += nrOfBoxex;
for(int i =0; i< nrOfBoxex; i ++) for(int i =0; i< nrOfBoxex; i ++)
{ {
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(5,305 + i*5,0,0); rigidBody_TestBox = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(5, 605 + i*5, 0), 5);
rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX)); this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX));
rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i]); rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i]);
}
}*/
// add crystal //// add crystal
API::SimpleBodyDescription sbDesc_Crystal;
sbDesc_Crystal.centerPosition = Oyster::Math::Float4(10, 305, 0, 1);
sbDesc_Crystal.ignoreGravity = false;
sbDesc_Crystal.mass = 80;
sbDesc_Crystal.size = Oyster::Math::Float3(2,3,2);
ICustomBody* rigidBody_Crystal = API::Instance().CreateRigidBody(sbDesc_Crystal).Release(); //ICustomBody* rigidBody_Crystal = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(10, 605, 0), 5);
rigidBody_Crystal->SetSubscription(Level::PhysicsOnMoveLevel);
this->dynamicObjects.Push(new DynamicObject(rigidBody_Crystal,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX)); //this->dynamicObjects.Push(new DynamicObject(rigidBody_Crystal,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX));
rigidBody_Crystal->SetCustomTag(this->dynamicObjects[nrOfBoxex]); //rigidBody_Crystal->SetCustomTag(this->dynamicObjects[nrOfBoxex]);
//
// add house //// add house
API::SimpleBodyDescription sbDesc_House; //ICustomBody* rigidBody_House =API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(10, 905, 0), 0);
//sbDesc_House.centerPosition = Oyster::Math::Float4(212, 212, 0, 0); //this->staticObjects.Push(new StaticObject(rigidBody_House,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC));
sbDesc_House.centerPosition = Oyster::Math::Float4(-50, 290, 0, 1); //rigidBody_House->SetCustomTag(this->staticObjects[0]);
sbDesc_House.ignoreGravity = false;
sbDesc_House.rotation = Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0);
sbDesc_House.mass = 90;
sbDesc_House.size = Oyster::Math::Float3(40,40,40);
ICustomBody* rigidBody_House = API::Instance().CreateRigidBody(sbDesc_House).Release();
rigidBody_House->SetSubscription(Level::PhysicsOnMoveLevel);
this->staticObjects.Push(new StaticObject(rigidBody_House,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC));
rigidBody_House->SetCustomTag(this->staticObjects[0]);
rigidBody_House->GetState(state);
Oyster::Math::Float4x4 world = state.GetOrientation();
// add gravitation
API::Gravity gravityWell;
gravityWell.gravityType = API::Gravity::GravityType_Well;
gravityWell.well.mass = 1e17f;
gravityWell.well.position = Oyster::Math::Float4(0,0,0,1);
API::Instance().AddGravity(gravityWell);
} }
void Level::AddPlayerToTeam(Player *player, int teamID) void Level::AddPlayerToTeam(Player *player, int teamID)
@ -371,4 +332,6 @@ void Level::PhysicsOnMoveLevel(const ICustomBody *object)
{ {
// function call from physics update when object was moved // function call from physics update when object was moved
Object* temp = (Object*)object->GetCustomTag(); Object* temp = (Object*)object->GetCustomTag();
((Game*)&Game::Instance())->onMoveFnc(temp);
} }

View File

@ -33,7 +33,7 @@ namespace GameLogic
void InitiateLevel(float radius); void InitiateLevel(float radius);
void parseObjectType(ObjectTypeHeader* obj); void parseObjectType(ObjectTypeHeader* obj);
void parsePhysicsObj(PhysicsObject* obj); void parsePhysicsObj(LevelLoaderInternal::PhysicsObject* obj);
/******************************************************** /********************************************************
* Creates a team in the level * Creates a team in the level
* @param teamSize: The size of the team you want to create * @param teamSize: The size of the team you want to create
@ -68,7 +68,7 @@ namespace GameLogic
static void PhysicsOnMoveLevel(const Oyster::Physics::ICustomBody *object); static void PhysicsOnMoveLevel(const Oyster::Physics::ICustomBody *object);
private: //private:
TeamManager teamManager; TeamManager teamManager;
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<StaticObject>> staticObjects; Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<StaticObject>> staticObjects;
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<DynamicObject>> dynamicObjects; Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<DynamicObject>> dynamicObjects;

View File

@ -15,10 +15,8 @@ const Game *Object::gameInstance = (Game*)(&Game::Instance());
Object::Object() Object::Object()
{ {
API::SimpleBodyDescription sbDesc;
this->rigidBody = API::Instance().CreateRigidBody(sbDesc).Release(); this->rigidBody = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.0f, 0.0f, 0.0f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(0, 0, 0), 0);
Oyster::Physics::API::Instance().AddObject(rigidBody);
this->type = OBJECT_TYPE::OBJECT_TYPE_UNKNOWN; this->type = OBJECT_TYPE::OBJECT_TYPE_UNKNOWN;
this->objectID = GID(); this->objectID = GID();
@ -28,10 +26,7 @@ Object::Object()
Object::Object(OBJECT_TYPE type) Object::Object(OBJECT_TYPE type)
{ {
API::SimpleBodyDescription sbDesc; this->rigidBody = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.0f, 0.0f, 0.0f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(0, 0, 0), 0);
this->rigidBody = API::Instance().CreateRigidBody(sbDesc).Release();
Oyster::Physics::API::Instance().AddObject(rigidBody);
this->type = type; this->type = type;
this->objectID = GID(); this->objectID = GID();
this->currPhysicsState = this->rigidBody->GetState(); this->currPhysicsState = this->rigidBody->GetState();
@ -40,7 +35,6 @@ Object::Object(OBJECT_TYPE type)
Object::Object(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type) Object::Object(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type)
{ {
Oyster::Physics::API::Instance().AddObject(rigidBody);
this->rigidBody = rigidBody; this->rigidBody = rigidBody;
this->type = type; this->type = type;
this->objectID = GID(); this->objectID = GID();
@ -50,10 +44,7 @@ Object::Object(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type)
Object::Object(void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type) Object::Object(void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type)
{ {
API::SimpleBodyDescription sbDesc; this->rigidBody = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.0f, 0.0f, 0.0f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(0, 0, 0), 0);
this->rigidBody = API::Instance().CreateRigidBody(sbDesc).Release();
Oyster::Physics::API::Instance().AddObject(rigidBody);
this->type = type; this->type = type;
this->objectID = GID(); this->objectID = GID();
@ -63,11 +54,7 @@ Object::Object(void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE
Object::Object(Oyster::Physics::ICustomBody *rigidBody ,void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type) Object::Object(Oyster::Physics::ICustomBody *rigidBody ,void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type)
{ {
Oyster::Physics::API::Instance().AddObject(rigidBody);
this->rigidBody = rigidBody; this->rigidBody = rigidBody;
this->rigidBody->SetSubscription((Oyster::Physics::ICustomBody::EventAction_BeforeCollisionResponse)(collisionFuncBefore));
this->rigidBody->SetSubscription((Oyster::Physics::ICustomBody::EventAction_AfterCollisionResponse)(collisionFuncAfter));
this->type = type; this->type = type;
this->objectID = GID(); this->objectID = GID();
@ -77,11 +64,7 @@ Object::Object(Oyster::Physics::ICustomBody *rigidBody ,void* collisionFuncBefor
Object::Object(Oyster::Physics::ICustomBody *rigidBody ,Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter), Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncAfter)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), OBJECT_TYPE type) Object::Object(Oyster::Physics::ICustomBody *rigidBody ,Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter), Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncAfter)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), OBJECT_TYPE type)
{ {
Oyster::Physics::API::Instance().AddObject(rigidBody);
this->rigidBody = rigidBody; this->rigidBody = rigidBody;
this->rigidBody->SetSubscription((Oyster::Physics::ICustomBody::EventAction_BeforeCollisionResponse)(collisionFuncBefore));
this->rigidBody->SetSubscription((Oyster::Physics::ICustomBody::EventAction_AfterCollisionResponse)(collisionFuncAfter));
this->type = type; this->type = type;
@ -92,7 +75,7 @@ Object::Object(Oyster::Physics::ICustomBody *rigidBody ,Oyster::Physics::ICustom
void Object::ApplyLinearImpulse(Oyster::Math::Float3 force) void Object::ApplyLinearImpulse(Oyster::Math::Float3 force)
{ {
newPhysicsState.ApplyLinearImpulse(force);
} }
@ -119,86 +102,17 @@ Oyster::Physics::ICustomBody* Object::GetRigidBody()
void Object::BeginFrame() void Object::BeginFrame()
{ {
if(currPhysicsState.GetLinearMomentum() !=currPhysicsState.GetLinearMomentum())
{
//error
int i =0 ;
}
if(currPhysicsState.GetCenterPosition() !=currPhysicsState.GetCenterPosition())
{
//error
int i =0 ;
}
if(currPhysicsState.GetAngularAxis() !=currPhysicsState.GetAngularAxis())
{
//error
int i =0 ;
}
this->rigidBody->SetState(this->newPhysicsState); this->rigidBody->SetState(this->newPhysicsState);
} }
// update physic // update physic
void Object::EndFrame() void Object::EndFrame()
{ {
if(currPhysicsState.GetLinearMomentum() !=currPhysicsState.GetLinearMomentum())
{
//error
int i =0 ;
}
this->currPhysicsState = this->rigidBody->GetState();
if(currPhysicsState.GetLinearMomentum() !=currPhysicsState.GetLinearMomentum())
{
//error
int i =0 ;
}
if(currPhysicsState.GetGravityNormal() !=currPhysicsState.GetGravityNormal())
{
//error
int i =0 ;
}
if(currPhysicsState.GetGravityNormal()!= Float3::null)
{
Oyster::Math::Float4 axis;
Oyster::Math3D::SnapAngularAxis(Oyster::Math::Float4(currPhysicsState.GetAngularAxis(), 0), Oyster::Math::Float4::standard_unit_y, -Oyster::Math::Float4(currPhysicsState.GetGravityNormal()), axis);
if(axis !=axis)
{
//error
int i =0 ;
}
axis.Normalize();
currPhysicsState.SetRotation(axis.xyz);
currPhysicsState.SetAngularMomentum(Float3::null);
Oyster::Math::Float3 debug = ::LinearAlgebra3D::WorldAxisOf(::LinearAlgebra3D::Rotation(axis.xyz), Oyster::Math::Float3::standard_unit_y);
debug += currPhysicsState.GetGravityNormal();
}
Oyster::Math::Float3 pos = currPhysicsState.GetCenterPosition();
Oyster::Math::Float3 up = -currPhysicsState.GetGravityNormal();
//300, 0,0,
//1,0,0
if( pos.GetLength() < 303.5f)
{
Oyster::Math::Float moveUp = 303.5 - pos.GetLength();
up *= moveUp;
currPhysicsState.SetCenterPosition(pos + up);
}
if(currPhysicsState.GetLinearMomentum() !=currPhysicsState.GetLinearMomentum())
{
//error
int i =0 ;
}
this->newPhysicsState = this->currPhysicsState; this->newPhysicsState = this->currPhysicsState;
} }
void Object::setBeforeCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter)) void Object::setBeforeCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter))
{ {
this->rigidBody->SetSubscription((Oyster::Physics::ICustomBody::EventAction_BeforeCollisionResponse)(collisionFuncBefore)); //this->rigidBody->SetSubscription((Oyster::Physics::ICustomBody::EventAction_BeforeCollisionResponse)(collisionFuncBefore));
} }
void Object::setAfterCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncAfter)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss)) void Object::setAfterCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncAfter)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss))
{ {
@ -209,7 +123,7 @@ Oyster::Math::Float3 Object::GetPosition()
{ {
Oyster::Physics::ICustomBody::State state; Oyster::Physics::ICustomBody::State state;
state = this->rigidBody->GetState(); state = this->rigidBody->GetState();
return state.GetCenterPosition(); return state.centerPos;
} }
Oyster::Math::Float4x4 Object::GetOrientation() Oyster::Math::Float4x4 Object::GetOrientation()
{ {

View File

@ -44,7 +44,8 @@ namespace GameLogic
static Oyster::Physics::ICustomBody::SubscriptMessage DefaultCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj); static Oyster::Physics::ICustomBody::SubscriptMessage DefaultCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj);
static Oyster::Physics::ICustomBody::SubscriptMessage DefaultCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss); static Oyster::Physics::ICustomBody::SubscriptMessage DefaultCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss);
private:
public: //TODO: Hax This should be private when level is dynamic
OBJECT_TYPE type; OBJECT_TYPE type;
int objectID; int objectID;

View File

@ -73,7 +73,7 @@ void Player::EndFrame()
Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1];
Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ; Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ;
currPhysicsState.AddRotation(deltaAxis); //currPhysicsState.AddRotation(deltaAxis);
dx = 0; dx = 0;
this->newPhysicsState = this->currPhysicsState; this->newPhysicsState = this->currPhysicsState;
} }
@ -108,21 +108,21 @@ void Player::MoveForward()
{ {
Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2];
//Oyster::Math::Float3 forward = lookDir; //Oyster::Math::Float3 forward = lookDir;
newPhysicsState.ApplyLinearImpulse(forward * (MOVE_FORCE * this->gameInstance->GetFrameTime())); //newPhysicsState.ApplyLinearImpulse(forward * (MOVE_FORCE * this->gameInstance->GetFrameTime()));
} }
void Player::MoveBackwards() void Player::MoveBackwards()
{ {
Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2];
//Oyster::Math::Float3 forward = lookDir; //Oyster::Math::Float3 forward = lookDir;
newPhysicsState.ApplyLinearImpulse(-forward * MOVE_FORCE * this->gameInstance->GetFrameTime()); //newPhysicsState.ApplyLinearImpulse(-forward * MOVE_FORCE * this->gameInstance->GetFrameTime());
} }
void Player::MoveRight() void Player::MoveRight()
{ {
//Do cross product with forward vector and negative gravity vector //Do cross product with forward vector and negative gravity vector
Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2];
//Oyster::Math::Float3 forward = lookDir; //Oyster::Math::Float3 forward = lookDir;
Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward); //Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward);
newPhysicsState.ApplyLinearImpulse(-r * MOVE_FORCE * this->gameInstance->GetFrameTime()); //newPhysicsState.ApplyLinearImpulse(-r * MOVE_FORCE * this->gameInstance->GetFrameTime());
} }
void Player::MoveLeft() void Player::MoveLeft()
@ -130,8 +130,8 @@ void Player::MoveLeft()
//Do cross product with forward vector and negative gravity vector //Do cross product with forward vector and negative gravity vector
Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2];
//Oyster::Math::Float3 forward = lookDir; //Oyster::Math::Float3 forward = lookDir;
Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward); //Still get zero //Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward); //Still get zero
newPhysicsState.ApplyLinearImpulse(r * MOVE_FORCE * this->gameInstance->GetFrameTime()); //newPhysicsState.ApplyLinearImpulse(r * MOVE_FORCE * this->gameInstance->GetFrameTime());
} }
void Player::UseWeapon(const WEAPON_FIRE &usage) void Player::UseWeapon(const WEAPON_FIRE &usage)
@ -144,7 +144,7 @@ void Player::Respawn(Oyster::Math::Float3 spawnPoint)
this->life = 100; this->life = 100;
this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE; this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE;
this->lookDir = Oyster::Math::Float4(1,0,0); this->lookDir = Oyster::Math::Float4(1,0,0);
this->newPhysicsState.SetCenterPosition(spawnPoint); this->newPhysicsState.centerPos = spawnPoint;
} }
void Player::Rotate(const Oyster::Math3D::Float4 lookDir) void Player::Rotate(const Oyster::Math3D::Float4 lookDir)
@ -162,7 +162,7 @@ void Player::Rotate(const Oyster::Math3D::Float4 lookDir)
void Player::Jump() void Player::Jump()
{ {
Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1];
newPhysicsState.ApplyLinearImpulse(up * MOVE_FORCE * this->gameInstance->GetFrameTime()); //newPhysicsState.ApplyLinearImpulse(up * MOVE_FORCE * this->gameInstance->GetFrameTime());
} }
bool Player::IsWalking() bool Player::IsWalking()
@ -180,7 +180,7 @@ bool Player::IsIdle()
Oyster::Math::Float3 Player::GetPosition() const Oyster::Math::Float3 Player::GetPosition() const
{ {
return (Oyster::Math::Float3)currPhysicsState.GetCenterPosition(); return (Oyster::Math::Float3)currPhysicsState.centerPos;
} }
Oyster::Math::Float4x4 Player::GetOrientation() const Oyster::Math::Float4x4 Player::GetOrientation() const
{ {
@ -208,7 +208,7 @@ void Player::DamageLife(int damage)
{ {
this->life = 0; this->life = 0;
playerState = PLAYER_STATE_DEAD; playerState = PLAYER_STATE_DEAD;
this->gameInstance->onDisableFnc(this); this->gameInstance->onDisableFnc(this, 0.0f);
} }
} }

View File

@ -85,8 +85,8 @@ namespace GameLogic
int teamID; int teamID;
Weapon *weapon; Weapon *weapon;
PLAYER_STATE playerState; PLAYER_STATE playerState;
Oyster::Math::Float3 lookDir; Oyster::Math::Float3 lookDir; //Duplicate in Object.h?
Oyster::Math::Float dx; Oyster::Math::Float dx; //dx of what?
bool hasTakenDamage; bool hasTakenDamage;
float invincibleCooldown; float invincibleCooldown;

View File

@ -18,8 +18,8 @@ StaticObject::StaticObject(OBJECT_TYPE type)
StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type) StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type)
:Object(rigidBody,type) :Object(rigidBody,type)
{ {
this->rigidBody->SetGravity(true); //this->rigidBody->SetGravity(true);
this->rigidBody->SetSubscription((Oyster::Physics::ICustomBody::EventAction_BeforeCollisionResponse)(CollisionManager::IgnoreCollision)); //this->rigidBody->SetSubscription((Oyster::Physics::ICustomBody::EventAction_BeforeCollisionResponse)(CollisionManager::IgnoreCollision));
} }
StaticObject::StaticObject(void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type) StaticObject::StaticObject(void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type)

View File

@ -35,13 +35,11 @@ TeamManager::~TeamManager(void)
void TeamManager::RespawnPlayerRandom(Player *player) void TeamManager::RespawnPlayerRandom(Player *player)
{ {
// Whats going on here? int teamID = player->GetTeamID();
int teamID = player->GetTeamID(); // ?
// ? Player *respawnOnThis = this->teams[teamID]->GetPlayer(0);
Player *respawnOnThis = this->teams[teamID]->GetPlayer(0); // ?
// ? player->Respawn(respawnOnThis->GetPosition());
player->Respawn(respawnOnThis->GetPosition()); // ?
// player->Respawn(player->GetPosition()); ?
} }
void TeamManager::CreateTeam(int teamSize) void TeamManager::CreateTeam(int teamSize)

View File

@ -18,9 +18,17 @@ Weapon::Weapon()
Weapon::Weapon(int MaxNrOfSockets,Player *owner) Weapon::Weapon(int MaxNrOfSockets,Player *owner)
{ {
if(MaxNrOfSockets > 1) return;
attatchmentSockets.Resize(MaxNrOfSockets); attatchmentSockets.Resize(MaxNrOfSockets);
attatchmentSockets[0] = new AttatchmentSocket(); attatchmentSockets[0] = new AttatchmentSocket();
for (int i = 0; i < MaxNrOfSockets; i++)
{
this->attatchmentSockets[i] = 0;
}
weaponState = WEAPON_STATE_IDLE; weaponState = WEAPON_STATE_IDLE;
currentNrOfAttatchments = 0; currentNrOfAttatchments = 0;
selectedAttatchment = 0; selectedAttatchment = 0;
@ -36,7 +44,11 @@ Weapon::Weapon(int MaxNrOfSockets,Player *owner)
Weapon::~Weapon(void) Weapon::~Weapon(void)
{ {
for (unsigned int i = 0; i < this->attatchmentSockets.Size(); i++)
{
delete this->attatchmentSockets[i];
this->attatchmentSockets[i] = 0;
}
} }
/******************************************************** /********************************************************
@ -129,5 +141,7 @@ void Weapon::SelectAttatchment(int socketID)
void Weapon::Update(float dt) void Weapon::Update(float dt)
{ {
if(!selectedAttatchment) return;
selectedAttatchment->Update(dt); selectedAttatchment->Update(dt);
} }

View File

@ -69,25 +69,25 @@
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir> <OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir> <IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName> <TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
<IncludePath>$(SolutionDir)Network\NetworkAPI\;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)Network\NetworkAPI\;$(SolutionDir)Misc;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir> <OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir> <IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName> <TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
<IncludePath>$(SolutionDir)Network\NetworkAPI\;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)Network\NetworkAPI\;$(SolutionDir)Misc;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir> <OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir> <IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName> <TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
<IncludePath>$(SolutionDir)Network\NetworkAPI\;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)Network\NetworkAPI\;$(SolutionDir)Misc;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir> <OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir> <IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName> <TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
<IncludePath>$(SolutionDir)Network\NetworkAPI\;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)Network\NetworkAPI\;$(SolutionDir)Misc;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>

View File

@ -24,23 +24,24 @@ namespace GameLogic
this->protocol[1].type = Oyster::Network::NetAttributeType_Short; this->protocol[1].type = Oyster::Network::NetAttributeType_Short;
} }
Protocol_General_Status(Oyster::Network::CustomNetProtocol& p)
{
this->protocol = p;
status = (States)p[1].value.netShort;
}
Protocol_General_Status(States state) Protocol_General_Status(States state)
{ {
this->protocol[0].value = protocol_General_Status; this->protocol[0].value = protocol_General_Status;
this->protocol[0].type = Oyster::Network::NetAttributeType_Short; this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
this->status = state;
this->protocol[1].type = Oyster::Network::NetAttributeType_Short; this->protocol[1].type = Oyster::Network::NetAttributeType_Short;
this->status = state;
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override
Protocol_General_Status(Oyster::Network::CustomNetProtocol& p)
{
status = (States)this->protocol[1].value.netShort;
}
Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol[1].value = status; this->protocol[1].value = status;
return &protocol; return protocol;
} }
private: private:
@ -59,12 +60,12 @@ namespace GameLogic
destination = p.Get(1).value.netInt; destination = p.Get(1).value.netInt;
text = p.Get(2).value.netCharPtr; text = p.Get(2).value.netCharPtr;
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol.Set(0, protocol_General_Text, Oyster::Network::NetAttributeType_Short); this->protocol.Set(0, protocol_General_Text, Oyster::Network::NetAttributeType_Short);
this->protocol.Set(1, destination, Oyster::Network::NetAttributeType_Int); this->protocol.Set(1, destination, Oyster::Network::NetAttributeType_Int);
this->protocol.Set(2, text); this->protocol.Set(2, text);
return &protocol; return protocol;
} }
private: private:

View File

@ -12,61 +12,111 @@
#include <DynamicArray.h> #include <DynamicArray.h>
/** OBS!
** It seems like if a string is set in the middle of a data set,
** the reciever will crach when trying to use the protocol.
** Only tested on Protocol_LobbyStartGame.
**/
namespace GameLogic namespace GameLogic
{ {
/*
struct Protocol_LobbyCreateGame :public Oyster::Network::CustomProtocolObject struct Protocol_LobbyCreateGame :public Oyster::Network::CustomProtocolObject
{ {
char* mapName; short clientID; // The unuiqe id reprsenting a specific client
char gameId; std::string modelName;
float worldMatrix[16];
Protocol_LobbyCreateGame() Protocol_LobbyCreateGame()
{ {
this->protocol[0].value = protocol_Lobby_Create; int c = 0;
this->protocol[0].type = Oyster::Network::NetAttributeType_Short; this->protocol[c].value = protocol_Lobby_Create;
this->protocol[c++].type = Oyster::Network::NetAttributeType_Short;
this->protocol[1].type = Oyster::Network::NetAttributeType_CharArray; this->protocol[c++].type = Oyster::Network::NetAttributeType_Short;
this->protocol[2].type = Oyster::Network::NetAttributeType_Char; for (int i = 0; i <= 16; i++)
{
this->protocol[c++].type = Oyster::Network::NetAttributeType_Float;
}
this->protocol[c++].type = Oyster::Network::NetAttributeType_CharArray;
} }
Protocol_LobbyCreateGame(Oyster::Network::CustomNetProtocol& o) Protocol_LobbyCreateGame(short _clientID, std::string name, float world[16])
{ {
mapName = o[1].value.netCharPtr; int c = 0;
gameId = o[2].value.netChar; this->protocol[c].value = protocol_Lobby_Create;
this->protocol[c++].type = Oyster::Network::NetAttributeType_Short;
this->protocol[c++].type = Oyster::Network::NetAttributeType_Short;
for (int i = 0; i <= 16; i++)
{
this->protocol[c++].type = Oyster::Network::NetAttributeType_Float;
}
this->protocol[c++].type = Oyster::Network::NetAttributeType_CharArray;
clientID = _clientID;
modelName = name;
memcpy(&worldMatrix[0], &world[0], sizeof(float) * 16);
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Protocol_LobbyCreateGame(Oyster::Network::CustomNetProtocol o)
{ {
protocol[1].value = mapName; int c = 1;
protocol[2].value = gameId; clientID = o[c++].value.netInt;
return &protocol; for (int i = 0; i <= 16; i++)
{
this->worldMatrix[i] = o[c++].value.netFloat;
}
modelName.assign(o[c++].value.netCharPtr);
}
Oyster::Network::CustomNetProtocol GetProtocol() override
{
int c = 1;
protocol[c++].value = clientID;
for (int i = 0; i <= 16; i++)
{
this->protocol[c++].value = this->worldMatrix[i];
}
protocol.Set(c++, this->modelName);
return protocol;
} }
private: private:
Oyster::Network::CustomNetProtocol protocol; Oyster::Network::CustomNetProtocol protocol;
}; };
*/
struct Protocol_LobbyStartGame :public Oyster::Network::CustomProtocolObject struct Protocol_LobbyStartGame :public Oyster::Network::CustomProtocolObject
{ {
short gameId; float seconds;
Protocol_LobbyStartGame() Protocol_LobbyStartGame()
{ {
this->protocol[0].value = protocol_Lobby_Start; this->protocol[0].value = protocol_Lobby_Start;
this->protocol[0].type = Oyster::Network::NetAttributeType_Short; this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
this->protocol[1].type = Oyster::Network::NetAttributeType_Float;
this->protocol[1].type = Oyster::Network::NetAttributeType_Short; seconds = 0;
}
Protocol_LobbyStartGame(float _seconds)
{
this->protocol[0].value = protocol_Lobby_Start;
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
this->protocol[1].type = Oyster::Network::NetAttributeType_Float;
seconds = _seconds;
} }
Protocol_LobbyStartGame(Oyster::Network::CustomNetProtocol& o) Protocol_LobbyStartGame(Oyster::Network::CustomNetProtocol& o)
{ {
gameId = o[1].value.netInt; seconds = o[1].value.netFloat;
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
protocol[1].value = gameId; this->protocol[1].value = seconds;
return &protocol; return protocol;
} }
private: private:
Oyster::Network::CustomNetProtocol protocol; Oyster::Network::CustomNetProtocol protocol;
}; };
struct Protocol_LobbyLogin :public Oyster::Network::CustomProtocolObject struct Protocol_LobbyLogin :public Oyster::Network::CustomProtocolObject
@ -83,9 +133,9 @@ namespace GameLogic
{ {
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
return &protocol; return protocol;
} }
private: private:
@ -109,7 +159,7 @@ namespace GameLogic
// this->protocol[1].type = Oyster::Network::NetAttributeType_Short; // this->protocol[1].type = Oyster::Network::NetAttributeType_Short;
// value = p[1].value.netShort; // value = p[1].value.netShort;
// } // }
// Oyster::Network::CustomNetProtocol* GetProtocol() override // Oyster::Network::CustomNetProtocol GetProtocol() override
// { // {
// protocol[1].value = value; // protocol[1].value = value;
// return &protocol; // return &protocol;
@ -130,8 +180,8 @@ namespace GameLogic
{ {
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ return &protocol; } { return protocol; }
private: private:
Oyster::Network::CustomNetProtocol protocol; Oyster::Network::CustomNetProtocol protocol;
@ -175,7 +225,7 @@ namespace GameLogic
list.Push(d); list.Push(d);
} }
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol[1].value = list.Size(); this->protocol[1].value = list.Size();
@ -195,7 +245,7 @@ namespace GameLogic
this->protocol.Set(a++, list[i].ip); this->protocol.Set(a++, list[i].ip);
} }
return &protocol; return protocol;
} }
private: private:
@ -223,13 +273,13 @@ namespace GameLogic
minorVersion = (int)p.Get(2).value.netInt; minorVersion = (int)p.Get(2).value.netInt;
mapName = p.Get(3).value.netCharPtr; mapName = p.Get(3).value.netCharPtr;
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol[1].value = majorVersion; this->protocol[1].value = majorVersion;
this->protocol[2].value = minorVersion; this->protocol[2].value = minorVersion;
this->protocol.Set(3, mapName.c_str()); this->protocol.Set(3, mapName.c_str());
return &protocol; return protocol;
} }
private: private:
@ -254,7 +304,7 @@ namespace GameLogic
// { // {
// //
// } // }
// Oyster::Network::CustomNetProtocol* GetProtocol() override // Oyster::Network::CustomNetProtocol GetProtocol() override
// { // {
// return &protocol; // return &protocol;
// } // }

View File

@ -39,11 +39,11 @@ namespace GameLogic
pickup_ID = pickupID; pickup_ID = pickupID;
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol[1].value = object_ID; this->protocol[1].value = object_ID;
this->protocol[2].value = pickup_ID; this->protocol[2].value = pickup_ID;
return &protocol; return protocol;
} }
private: private:
@ -80,11 +80,11 @@ namespace GameLogic
object_ID = id; object_ID = id;
health = hp; health = hp;
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol[1].value = object_ID; this->protocol[1].value = object_ID;
this->protocol[2].value = health; this->protocol[2].value = health;
return &protocol; return protocol;
} }
private: private:
@ -129,14 +129,14 @@ namespace GameLogic
object_ID = id; object_ID = id;
memcpy(&worldMatrix[0], &m[0], sizeof(float)*16); memcpy(&worldMatrix[0], &m[0], sizeof(float)*16);
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol[1].value = object_ID; this->protocol[1].value = object_ID;
for (int i = 2; i <= 17; i++) for (int i = 2; i <= 17; i++)
{ {
this->protocol[i].value = worldMatrix[i-2]; this->protocol[i].value = worldMatrix[i-2];
} }
return &protocol; return protocol;
} }
private: private:
@ -179,14 +179,14 @@ namespace GameLogic
object_ID = id; object_ID = id;
memcpy(&worldMatrix[0], &m[0], sizeof(float)*16); memcpy(&worldMatrix[0], &m[0], sizeof(float)*16);
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol[1].value = object_ID; this->protocol[1].value = object_ID;
for (int i = 2; i <= 17; i++) for (int i = 2; i <= 17; i++)
{ {
this->protocol[i].value = worldMatrix[i-2]; this->protocol[i].value = worldMatrix[i-2];
} }
return &protocol; return protocol;
} }
private: private:
@ -221,11 +221,11 @@ namespace GameLogic
object_ID = id; object_ID = id;
timer = time; timer = time;
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol[1].value = object_ID; this->protocol[1].value = object_ID;
this->protocol[2].value = timer; this->protocol[2].value = timer;
return &protocol; return protocol;
} }
private: private:
@ -234,8 +234,9 @@ namespace GameLogic
struct Protocol_ObjectCreate :public Oyster::Network::CustomProtocolObject struct Protocol_ObjectCreate :public Oyster::Network::CustomProtocolObject
{ {
//ObjectType type; //ie player, box or whatever
int object_ID; int object_ID;
char *name; std::string name;
float worldMatrix[16]; float worldMatrix[16];
Protocol_ObjectCreate() Protocol_ObjectCreate()
@ -244,7 +245,7 @@ namespace GameLogic
this->protocol[0].type = Oyster::Network::NetAttributeType_Short; this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
this->protocol[1].type = Oyster::Network::NetAttributeType_Int; this->protocol[1].type = Oyster::Network::NetAttributeType_Int;
this->protocol[2].type = Oyster::Network::NetAttributeType_CharArray; this->protocol[2].type = Oyster::Network::NetAttributeType_CharArray;
for (int i = 3; i <= 18; i++) for (int i = 3; i <= 18; i++)
{ {
@ -272,11 +273,11 @@ namespace GameLogic
this->name = path; this->name = path;
memcpy(&worldMatrix[0], &m[0], sizeof(float)*16); memcpy(&worldMatrix[0], &m[0], sizeof(float)*16);
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol[1].value = object_ID; this->protocol[1].value = object_ID;
this->protocol[2].value = name; this->protocol.Set(2, name);
this->protocol[3].value = worldMatrix[0]; this->protocol[3].value = worldMatrix[0];
this->protocol[4].value = worldMatrix[1]; this->protocol[4].value = worldMatrix[1];
this->protocol[5].value = worldMatrix[2]; this->protocol[5].value = worldMatrix[2];
@ -297,7 +298,7 @@ namespace GameLogic
return &protocol; return protocol;
} }
private: private:

View File

@ -49,14 +49,14 @@ namespace GameLogic
return *this; return *this;
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol[1].value = bForward; this->protocol[1].value = bForward;
this->protocol[2].value = bBackward; this->protocol[2].value = bBackward;
this->protocol[3].value = bLeft; this->protocol[3].value = bLeft;
this->protocol[4].value = bRight; this->protocol[4].value = bRight;
return &protocol; return protocol;
} }
private: private:
@ -98,7 +98,7 @@ namespace GameLogic
return *this; return *this;
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol[1].value = lookDirX; this->protocol[1].value = lookDirX;
this->protocol[2].value = lookDirY; this->protocol[2].value = lookDirY;
@ -106,7 +106,7 @@ namespace GameLogic
this->protocol[4].value = deltaX; this->protocol[4].value = deltaX;
return &protocol; return protocol;
} }
private: private:
@ -131,9 +131,9 @@ namespace GameLogic
{ {
return *this; return *this;
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
return &protocol; return protocol;
} }
private: private:
@ -168,12 +168,12 @@ namespace GameLogic
utilityPressed = val[3].value.netBool; utilityPressed = val[3].value.netBool;
return *this; return *this;
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol[1].value = primaryPressed; this->protocol[1].value = primaryPressed;
this->protocol[2].value = secondaryPressed; this->protocol[2].value = secondaryPressed;
this->protocol[3].value = utilityPressed; this->protocol[3].value = utilityPressed;
return &protocol; return protocol;
} }
private: private:
@ -200,10 +200,10 @@ namespace GameLogic
hasJumped = val[1].value.netBool; hasJumped = val[1].value.netBool;
return *this; return *this;
} }
Oyster::Network::CustomNetProtocol* GetProtocol() override Oyster::Network::CustomNetProtocol GetProtocol() override
{ {
this->protocol[1].value = hasJumped; this->protocol[1].value = hasJumped;
return &protocol; return protocol;
} }
private: private:

View File

@ -24,14 +24,19 @@ namespace DanBias
GameLogic::IPlayerData* ReleasePlayer(); GameLogic::IPlayerData* ReleasePlayer();
Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> GetClient(); Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> GetClient();
Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> ReleaseClient(); Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> ReleaseClient();
int GetID() const;
float GetSinceLastResponse() const;
bool IsReady() const;
bool Equals(const Oyster::Network::NetworkClient* c); bool Equals(const Oyster::Network::NetworkClient* c);
void SetReadyState(bool isReady);
void SetSinceLastResponse(float seconds);
private: private:
GameLogic::IPlayerData* player; GameLogic::IPlayerData* player;
Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> client; Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> client;
int id; bool isReady;
float secondsSinceLastResponse;
}; };
}//End namespace DanBias }//End namespace DanBias

View File

@ -52,8 +52,10 @@ namespace DanBias
private: private:
Utility::WinTimer timer; Utility::WinTimer timer;
float refreshFrequency; float refreshFrequency;
GameSession gameSession; GameSession gameSession;
LobbyLevelData description; LobbyLevelData description;
Utility::DynamicMemory::SmartPointer<DanBias::GameClient> sessionOwner;
}; };
}//End namespace DanBias }//End namespace DanBias
#endif // !DANBIASGAME_GAMELOBBY_H #endif // !DANBIASGAME_GAMELOBBY_H

View File

@ -32,9 +32,11 @@ namespace DanBias
{ {
char* serverName; char* serverName;
int listenPort; int listenPort;
bool broadcast; //Not fully implemented!
ServerInitDesc() ServerInitDesc()
: serverName("Game Server") : serverName("Game Server")
, listenPort(15151) , listenPort(15152)
, broadcast(true)
{}; {};
}; };
struct GameServerInfo struct GameServerInfo
@ -49,6 +51,7 @@ namespace DanBias
static void ServerStop(); static void ServerStop();
static void ServerUpdate(); static void ServerUpdate();
static GameServerInfo ServerGetInfo(); static GameServerInfo ServerGetInfo();
static bool ServerIsRunning();
static void GameSetMapId(const int& val); static void GameSetMapId(const int& val);
static void GameSetMaxClients(const int& val); static void GameSetMaxClients(const int& val);

View File

@ -52,24 +52,27 @@ namespace DanBias
* @param client The client to attach to the session * @param client The client to attach to the session
*/ */
bool Attach(Oyster::Network::NetClient client) override; bool Attach(Oyster::Network::NetClient client) override;
void CloseSession( bool dissconnectClients ) override;
inline bool IsCreated() const { return this->isCreated; } inline bool IsCreated() const { return this->isCreated; }
inline bool IsRunning() const { return this->isRunning; } inline bool IsRunning() const { return this->isRunning; }
operator bool() { return (this->isCreated && this->isCreated); }
//Private member functions //Private member functions
private: private:
// TODO: find out what this method does.. // TODO: find out what this method does..
void ClientEventCallback(Oyster::Network::NetEvent<Oyster::Network::NetworkClient*, Oyster::Network::NetworkClient::ClientEventArgs> e) override; void ClientEventCallback(Oyster::Network::NetEvent<Oyster::Network::NetworkClient*, Oyster::Network::NetworkClient::ClientEventArgs> e) override;
//Sends a client to the owner, if obj is NULL then all clients is sent //Sends a client to the owner, if obj is NULL then all clients is sent
void SendToOwner(DanBias::GameClient* obj); void SendToOwner(DanBias::GameClient* obj);
//Frame function, derived from IThreadObject //Derived from IThreadObject
void ThreadEntry() override;
bool DoWork ( ) override; bool DoWork ( ) override;
private: private:
void ParseProtocol (Oyster::Network::CustomNetProtocol& p, DanBias::GameClient* c); void ParseProtocol ( Oyster::Network::CustomNetProtocol& p, DanBias::GameClient* c );
void Gameplay_PlayerMovement ( GameLogic::Protocol_PlayerMovement& p, DanBias::GameClient* c ); void Gameplay_PlayerMovement ( GameLogic::Protocol_PlayerMovement& p, DanBias::GameClient* c );
void Gameplay_PlayerLookDir ( GameLogic::Protocol_PlayerLook& p, DanBias::GameClient* c ); void Gameplay_PlayerLookDir ( GameLogic::Protocol_PlayerLook& p, DanBias::GameClient* c );
@ -86,18 +89,23 @@ namespace DanBias
void General_Text ( GameLogic::Protocol_General_Text& p, DanBias::GameClient* c ); void General_Text ( GameLogic::Protocol_General_Text& p, DanBias::GameClient* c );
//Callback method recieving from gamelogic //Callback method recieving from gamelogic
static void ObjectMove(GameLogic::IObjectData* movedObject); static void ObjectMove ( GameLogic::IObjectData* movedObject );
static void ObjectDisabled ( GameLogic::IObjectData* movedObject, float seconds );
//Private member variables //Private member variables
private: private:
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<GameClient>> clients; Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<GameClient>> clients;
Utility::DynamicMemory::SmartPointer<DanBias::GameClient> sessionOwner;
Oyster::Thread::OysterThread worker; Oyster::Thread::OysterThread worker;
GameLogic::GameAPI& gameInstance; GameLogic::GameAPI& gameInstance;
GameLogic::ILevelData *levelData; GameLogic::ILevelData *levelData;
NetworkSession* owner; NetworkSession* owner;
bool isCreated; bool isCreated;
bool isRunning; bool isRunning;
Utility::WinTimer timer; float logicFrameTime;
float networkFrameTime;
Utility::WinTimer logicTimer;
Utility::WinTimer networkTimer;
GameDescription description; GameDescription description;
//TODO: Remove this uggly hax //TODO: Remove this uggly hax

View File

@ -11,19 +11,18 @@ using namespace Oyster::Network;
using namespace DanBias; using namespace DanBias;
using namespace GameLogic; using namespace GameLogic;
static int gameClientIDCount = 1;
GameClient::GameClient(SmartPointer<NetworkClient> client, GameLogic::IPlayerData* player) GameClient::GameClient(SmartPointer<NetworkClient> client, GameLogic::IPlayerData* player)
{ {
this->client = client; this->client = client;
this->id = gameClientIDCount++;
this->player = player; this->player = player;
isReady = false;
} }
GameClient::~GameClient() GameClient::~GameClient()
{ {
this->client->Disconnect(); this->client->Disconnect();
this->player = 0; this->player = 0;
this->id = -1; isReady = false;
} }
GameLogic::IPlayerData* GameClient::GetPlayer() GameLogic::IPlayerData* GameClient::GetPlayer()
@ -46,13 +45,26 @@ SmartPointer<Oyster::Network::NetworkClient> GameClient::ReleaseClient()
this->client = 0; this->client = 0;
return temp; return temp;
} }
int GameClient::GetID() const
float GameClient::GetSinceLastResponse() const
{ {
return this->id; return this->secondsSinceLastResponse;
}
bool GameClient::IsReady() const
{
return this->isReady;
} }
bool GameClient::Equals(const NetworkClient* c) bool GameClient::Equals(const NetworkClient* c)
{ {
return (c->GetID() == this->client->GetID()); return (c->GetID() == this->client->GetID());
} }
void GameClient::SetReadyState(bool r)
{
this->isReady = r;
}
void GameClient::SetSinceLastResponse(float s)
{
this->secondsSinceLastResponse = s;
}

View File

@ -17,18 +17,18 @@ namespace DanBias
{ } { }
GameLobby::~GameLobby() GameLobby::~GameLobby()
{ } {
this->clients.Clear();
}
void GameLobby::Release() void GameLobby::Release()
{ {
NetworkSession::CloseSession(true); NetworkSession::CloseSession(true);
this->gameSession.CloseSession(true);
} }
void GameLobby::Update() void GameLobby::Update()
{ {
if(GetAsyncKeyState(VK_DOWN)) //TODO: Dont forget to remove this...
this->Send(*GameLogic::Protocol_General_Status().GetProtocol());
this->ProcessClients(); this->ProcessClients();
} }
void GameLobby::SetGameDesc(const LobbyLevelData& desc) void GameLobby::SetGameDesc(const LobbyLevelData& desc)
@ -45,20 +45,21 @@ namespace DanBias
desc.mapNumber = this->description.mapNumber; desc.mapNumber = this->description.mapNumber;
desc.maxClients = this->description.maxClients; desc.maxClients = this->description.maxClients;
} }
bool GameLobby::StartGameSession() bool GameLobby::StartGameSession( )
{ {
GameSession::GameDescription desc; GameSession::GameDescription desc;
desc.gameMode = this->description.gameMode; desc.gameMode = this->description.gameMode;
desc.gameTime = this->description.gameTime; desc.gameTime = this->description.gameTime;
desc.mapNumber = this->description.mapNumber; desc.mapNumber = this->description.mapNumber;
desc.owner = this; desc.owner = this;
desc.clients = this->clients; desc.clients = this->clients;
this->clients.Clear(); this->clients.Clear(); //Remove clients from lobby list
if(this->gameSession.Create(desc)) if(this->gameSession.Create(desc))
{ {
this->gameSession.Run(); this->gameSession.Run();
return true; return true;
} }
return false; return false;
@ -85,29 +86,36 @@ namespace DanBias
void GameLobby::ClientConnectedEvent(Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> client) void GameLobby::ClientConnectedEvent(Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> client)
{ {
printf("New client(%i) connected - %s \n", client->GetID(), client->GetIpAddress().c_str()); printf("New client(%i) connected - %s \n", client->GetID(), client->GetIpAddress().c_str());
Attach(client);
Protocol_LobbyClientData p1; if(this->gameSession)
Protocol_LobbyGameData p2;
for (unsigned int i = 0; i < this->clients.Size(); i++)
{ {
if(this->clients[i]) this->gameSession.Attach(client);
{
Protocol_LobbyClientData::PlayerData t;
t.id = this->clients[i]->GetID();
t.ip = this->clients[i]->GetIpAddress();
t.team = 0;
t.name = "DennisÄrKung";
p1.list.Push(t);
}
} }
p2.majorVersion = 1; else
p2.minorVersion = 0; {
p2.mapName = "BetsMap"; Attach(client);
Protocol_LobbyClientData p1;
Protocol_LobbyGameData p2;
for (unsigned int i = 0; i < this->clients.Size(); i++)
{
if(this->clients[i])
{
Protocol_LobbyClientData::PlayerData t;
t.id = this->clients[i]->GetID();
t.ip = this->clients[i]->GetIpAddress();
t.team = 0;
t.name = "Dennis är kung tycker Erik!";
p1.list.Push(t);
}
}
p2.majorVersion = 1;
p2.minorVersion = 0;
p2.mapName = "Dennis är kung tycker Erik!";
client->Send(p1.GetProtocol()); client->Send(p1.GetProtocol());
client->Send(p2.GetProtocol()); client->Send(p2.GetProtocol());
}
} }
}//End namespace DanBias }//End namespace DanBias

View File

@ -62,7 +62,14 @@ void GameLobby::GeneralText(GameLogic::Protocol_General_Text& p, Oyster::Network
//} //}
void GameLobby::LobbyStartGame(GameLogic::Protocol_LobbyStartGame& p, Oyster::Network::NetworkClient* c) void GameLobby::LobbyStartGame(GameLogic::Protocol_LobbyStartGame& p, Oyster::Network::NetworkClient* c)
{ {
//TODO: Prio 1 if(this->sessionOwner->GetClient()->GetID() == c->GetID())
{
}
else
{
//Someone else tried to start the server..
}
} }
//void GameLobby::LobbyJoin(GameLogic::Protocol_LobbyJoin& p, Oyster::Network::NetworkClient* c) //void GameLobby::LobbyJoin(GameLogic::Protocol_LobbyJoin& p, Oyster::Network::NetworkClient* c)
//{ //{

View File

@ -53,6 +53,7 @@ void GameServerAPI::ServerStart()
} }
void GameServerAPI::ServerStop() void GameServerAPI::ServerStop()
{ {
if(!server.IsRunning()) return;
lobby.Release(); lobby.Release();
server.Shutdown(); server.Shutdown();
@ -61,19 +62,19 @@ void GameServerAPI::ServerStop()
int time = (int)total; int time = (int)total;
int hour, min, sec; int hour, min, sec;
hour=time / 3600; hour = time / 3600;
time=time % 3600; time = time % 3600;
min=time / 60; min = time / 60;
time=time % 60; time = time % 60;
sec = time; sec = time;
printf( "Server has been running for: %i:%i:%i - [hh:mm:ss] \n\n", hour, min, sec ); printf( "Server has been running for: %i:%i:%i - [hh:mm:ss] \n\n", hour, min, sec );
printf( "Terminating in : "); //printf( "Terminating in : ");
for (int i = 0; i < 3; i++) //for (int i = 0; i < 3; i++)
{ //{
printf( "%i ", 3-i ); // printf( "%i ", 3-i );
Sleep(1000); // Sleep(1000);
} //}
printf( "\nServer terminated!" ); printf( "\nServer terminated!" );
} }
void GameServerAPI::ServerUpdate() void GameServerAPI::ServerUpdate()
@ -82,7 +83,6 @@ void GameServerAPI::ServerUpdate()
lobby.Update(); lobby.Update();
} }
GameServerAPI::GameServerInfo GameServerAPI::ServerGetInfo() GameServerAPI::GameServerInfo GameServerAPI::ServerGetInfo()
{ {
GameServerAPI::GameServerInfo i; GameServerAPI::GameServerInfo i;
@ -90,6 +90,11 @@ GameServerAPI::GameServerInfo GameServerAPI::ServerGetInfo()
i.listenPort = server.GetPort(); i.listenPort = server.GetPort();
return i; return i;
} }
bool GameServerAPI::ServerIsRunning()
{
return server.IsRunning();
}
void GameServerAPI::GameSetMapId(const int& val) void GameServerAPI::GameSetMapId(const int& val)
{ {
LobbyLevelData d; LobbyLevelData d;
@ -150,6 +155,11 @@ const char* GameServerAPI::GameGetGameName()
} }
bool GameServerAPI::GameStart() bool GameServerAPI::GameStart()
{ {
return lobby.StartGameSession(); if(lobby.StartGameSession())
{
return true;
}
return false;
} }

View File

@ -3,19 +3,16 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#include "..\GameSession.h" #include "..\GameSession.h"
#include "..\GameClient.h" #include "..\GameClient.h"
#include <WinTimer.h>
#include <Protocols.h> #include <Protocols.h>
#include <PostBox\PostBox.h> #include <PostBox\PostBox.h>
#include <GameLogicStates.h> #include <GameLogicStates.h>
#include <OysterMath.h> #include <OysterMath.h>
#define NOMINMAX #define NOMINMAX
#include <Windows.h> #include <Windows.h>
#define DELTA_TIME_20 0.05f
#define DELTA_TIME_24 0.04166666666666666666666666666667f
#define DELTA_TIME_30 0.03333333333333333333333333333333f
#define DELTA_TIME_60 0.01666666666666666666666666666667f
#define DELTA_TIME_120 0.00833333333333333333333333333333f
using namespace Utility::DynamicMemory; using namespace Utility::DynamicMemory;
using namespace Oyster; using namespace Oyster;
@ -25,20 +22,20 @@ using namespace GameLogic;
namespace DanBias namespace DanBias
{ {
Utility::WinTimer testTimer;
int testID = -1;
bool GameSession::DoWork( ) bool GameSession::DoWork( )
{ {
if(this->isRunning) if(this->isRunning)
{ {
double dt = this->timer.getElapsedSeconds(); float dt = (float)this->logicTimer.getElapsedSeconds();
gameInstance.SetFrameTimeLength((float)dt); if( dt >= this->logicFrameTime )
if(dt >= DELTA_TIME_20)
{ {
this->ProcessClients(); this->ProcessClients();
this->gameInstance.NewFrame(); this->gameInstance.NewFrame();
this->timer.reset(); this->logicTimer.reset();
} }
} }
@ -71,11 +68,16 @@ namespace DanBias
case NetworkClient::ClientEventArgs::EventType_ProtocolFailedToRecieve: case NetworkClient::ClientEventArgs::EventType_ProtocolFailedToRecieve:
break; break;
case NetworkClient::ClientEventArgs::EventType_ProtocolFailedToSend: case NetworkClient::ClientEventArgs::EventType_ProtocolFailedToSend:
printf("\t(%i : %s) - EventType_ProtocolFailedToSend\n", e.sender->GetID(), e.sender->GetIpAddress().c_str()); printf("\t(%i : %s) - EventType_ProtocolFailedToSend\n", cl->GetClient()->GetID(), e.sender->GetIpAddress().c_str());
this->Detach(e.sender)->Disconnect(); this->Detach(e.sender);
break; break;
case NetworkClient::ClientEventArgs::EventType_ProtocolRecieved: case NetworkClient::ClientEventArgs::EventType_ProtocolRecieved:
printf("\t(%i : %s) - EventType_ProtocolRecieved\n", e.sender->GetID(), e.sender->GetIpAddress().c_str()); printf("\t(%i : %s) - EventType_ProtocolRecieved\n", cl->GetClient()->GetID(), e.sender->GetIpAddress().c_str());
testID = 2;
if(cl->GetPlayer()->GetID() == testID)//TODO: TEST
{
testTimer.reset();
}
this->ParseProtocol(e.args.data.protocol, cl); this->ParseProtocol(e.args.data.protocol, cl);
break; break;
} }
@ -83,38 +85,47 @@ namespace DanBias
void GameSession::ObjectMove(GameLogic::IObjectData* movedObject) void GameSession::ObjectMove(GameLogic::IObjectData* movedObject)
{ {
if(dynamic_cast<IPlayerData*> (movedObject)) float dt = GameSession::gameSession->networkTimer.getElapsedSeconds();
//Duh... This was causing alot of problems, it's in the wrong place...
//Need to figure out where to put this frame locker.
//We only need to send network packages when necessary, ie not 120 times per frame.
//I think it would be enough with 60-70 packages per second due to the nature of
//graphics update (60 fps) on the client side. To send more than this would be lost
//bandwidth.
//if( dt >= GameSession::gameSession->networkFrameTime )
{ {
IPlayerData* temp = (IPlayerData*)movedObject; GameSession::gameSession->networkTimer.reset();
int id = temp->GetID();
Oyster::Math::Float4x4 world = temp->GetOrientation();
Protocol_ObjectPosition p(world, id);
GameSession::gameSession->Send(*p.GetProtocol());
}
GameLogic::IObjectData* obj = NULL; GameLogic::IObjectData* obj = movedObject;
if(dynamic_cast<GameLogic::ILevelData*>(movedObject)) if(movedObject->GetID() == testID) //TODO: TEST
{
obj = ((GameLogic::ILevelData*)movedObject)->GetObjectAt(0);
if(obj)
{ {
if(obj->GetObjectType() == OBJECT_TYPE_WORLD) float sec = (float)testTimer.getElapsedSeconds();
{ sec = 0;
int id = obj->GetID();
Oyster::Math::Float4x4 world =obj->GetOrientation();
Protocol_ObjectPosition p(world, id);
//GameSession::gameSession->Send(*p.GetProtocol());
}
} }
obj = NULL; int id = obj->GetID();
int count = ((GameLogic::ILevelData*)movedObject)->getNrOfDynamicObj(); Protocol_ObjectPosition p(obj->GetOrientation(), id);
for( int i = 0; i < count; i++ ) //if(id != 1)
GameSession::gameSession->Send(p.GetProtocol());
/*
if(dynamic_cast<GameLogic::ILevelData*>(obj))
{ {
obj =((GameLogic::ILevelData*)movedObject)->GetObjectAt(i+1); obj = ((GameLogic::ILevelData*)movedObject)->GetObjectAt(0);
if(obj)
{
if(obj->GetObjectType() == OBJECT_TYPE_WORLD)
{
int id = obj->GetID();
Oyster::Math::Float4x4 world =obj->GetOrientation();
Protocol_ObjectPosition p(world, id);
gameSession->Send(p.GetProtocol());
}
}
obj =((GameLogic::ILevelData*)movedObject)->GetObjectAt(1);
if(obj) if(obj)
{ {
if(obj->GetObjectType() == OBJECT_TYPE_BOX) if(obj->GetObjectType() == OBJECT_TYPE_BOX)
@ -122,13 +133,30 @@ namespace DanBias
int id = obj->GetID(); int id = obj->GetID();
Oyster::Math::Float4x4 world = obj->GetOrientation(); Oyster::Math::Float4x4 world = obj->GetOrientation();
Protocol_ObjectPosition p(world, id); Protocol_ObjectPosition p(world, id);
GameSession::gameSession->Send(*p.GetProtocol()); gameSession->Send(p.GetProtocol());
}
}
obj =((GameLogic::ILevelData*)movedObject)->GetObjectAt(2);
if(obj)
{
if(obj->GetObjectType() == OBJECT_TYPE_BOX)
{
int id = obj->GetID();
Oyster::Math::Float4x4 world = obj->GetOrientation();
Protocol_ObjectPosition p(world, id);
GameSession::gameSession->Send(p.GetProtocol());
} }
} }
} }
*/
} }
} }
void GameSession::ObjectDisabled( GameLogic::IObjectData* movedObject, float seconds )
{
GameSession::gameSession->Send(Protocol_ObjectDisable(movedObject->GetID(), seconds).GetProtocol());
}
//*****************************************************// //*****************************************************//
//****************** Protocol methods *****************// //****************** Protocol methods *****************//
@ -136,6 +164,8 @@ namespace DanBias
void GameSession::ParseProtocol(Oyster::Network::CustomNetProtocol& p, DanBias::GameClient* c) void GameSession::ParseProtocol(Oyster::Network::CustomNetProtocol& p, DanBias::GameClient* c)
{ {
//TODO: Update response timer
switch (p[0].value.netShort) switch (p[0].value.netShort)
{ {
case protocol_Gameplay_PlayerMovement: this->Gameplay_PlayerMovement ( Protocol_PlayerMovement (p), c ); case protocol_Gameplay_PlayerMovement: this->Gameplay_PlayerMovement ( Protocol_PlayerMovement (p), c );
@ -228,6 +258,8 @@ namespace DanBias
{ {
case GameLogic::Protocol_General_Status::States_disconected: case GameLogic::Protocol_General_Status::States_disconected:
printf("Client with ID [%i] dissconnected\n", c->GetClient()->GetID()); printf("Client with ID [%i] dissconnected\n", c->GetClient()->GetID());
//TODO: Tell other clients
//Protocol_
this->Detach(c->GetClient()->GetID()); this->Detach(c->GetClient()->GetID());
break; break;
@ -236,7 +268,7 @@ namespace DanBias
break; break;
case GameLogic::Protocol_General_Status::States_ready: case GameLogic::Protocol_General_Status::States_ready:
c->SetReadyState(true);
break; break;
case GameLogic::Protocol_General_Status::States_leave: case GameLogic::Protocol_General_Status::States_leave:
@ -246,7 +278,7 @@ namespace DanBias
} }
void GameSession::General_Text ( Protocol_General_Text& p, DanBias::GameClient* c ) void GameSession::General_Text ( Protocol_General_Text& p, DanBias::GameClient* c )
{ {
printf("Message recieved from (%i):\t %s\n", c->GetID(), p.text.c_str()); printf("Message recieved from (%i):\t %s\n", c->GetClient()->GetID(), p.text.c_str());
} }
}//End namespace DanBias }//End namespace DanBias

View File

@ -9,6 +9,13 @@
#define NOMINMAX #define NOMINMAX
#include <Windows.h> #include <Windows.h>
#include <Queue.h>
#define DELTA_TIME_20 0.05f
#define DELTA_TIME_24 0.04166666666666666666666666666667f
#define DELTA_TIME_30 0.03333333333333333333333333333333f
#define DELTA_TIME_60 0.01666666666666666666666666666667f
#define DELTA_TIME_120 0.00833333333333333333333333333333f
using namespace Utility::DynamicMemory; using namespace Utility::DynamicMemory;
@ -28,6 +35,10 @@ namespace DanBias
this->isCreated = false; this->isCreated = false;
this->isRunning = false; this->isRunning = false;
this->gameSession = this; this->gameSession = this;
this->logicFrameTime = DELTA_TIME_20;
this->networkFrameTime = DELTA_TIME_20;
this->networkTimer.reset();
this->logicTimer.reset();
memset(&this->description, 0, sizeof(GameDescription)); memset(&this->description, 0, sizeof(GameDescription));
} }
@ -45,37 +56,30 @@ namespace DanBias
bool GameSession::Create(GameDescription& desc) bool GameSession::Create(GameDescription& desc)
{ {
this->description = desc; this->description = desc;
/* Do some error checking */ /* Do some error checking */
if(desc.clients.Size() == 0) return false; if(desc.clients.Size() == 0) return false;
if(!desc.owner) return false; if(!desc.owner) return false;
if(this->isCreated) return false; if(this->isCreated) return false;
/* standard initialization of some data */ /* standard initialization of some data */
NetworkSession::clients = desc.clients; NetworkSession::clients = desc.clients;
this->clients.Resize(desc.clients.Size()); this->clients.Reserve(desc.clients.Size());
this->owner = desc.owner; this->owner = desc.owner;
/* Initiate the game instance */ /* Initiate the game instance */
if(!this->gameInstance.Initiate()) if(!this->gameInstance.Initiate())
{ {
printf("Failed to initiate the game instance\n"); printf("Failed to initiate the game instance\n");
} }
/* Create the game level */ /* Create the players in the game instance */
if(!(this->levelData = this->gameInstance.CreateLevel()))
{
printf("Level not created!");
return false;
}
/* Create the players in the game instance */
GameLogic::IPlayerData* p = 0; GameLogic::IPlayerData* p = 0;
for (unsigned int i = 0; i < desc.clients.Size(); i++) for (unsigned int i = 0; i < desc.clients.Size(); i++)
{ {
if( (p = this->gameInstance.CreatePlayer()) ) if( (p = this->gameInstance.CreatePlayer()) )
{ {
desc.clients[i]->SetOwner(this); desc.clients[i]->SetOwner(this);
this->clients[i] = new GameClient(desc.clients[i], p); this->clients.Push(new GameClient(desc.clients[i], p));
} }
else else
{ {
@ -83,16 +87,26 @@ namespace DanBias
} }
} }
/* Create the game level */
if(!(this->levelData = this->gameInstance.CreateLevel()))
{
printf("Level not created!");
return false;
}
/* Set some game instance data options */
this->gameInstance.SetSubscription(GameSession::ObjectMove);
this->gameInstance.SetSubscription(GameSession::ObjectDisabled);
this->gameInstance.SetFPS(60);
this->description.clients.Clear();
this->isCreated = true;
/* Create the worker thread */ /* Create the worker thread */
if(this->worker.Create(this, false) != OYSTER_THREAD_ERROR_SUCCESS) if(this->worker.Create(this, false) != OYSTER_THREAD_ERROR_SUCCESS)
return false; return false;
this->worker.SetPriority(Oyster::Thread::OYSTER_THREAD_PRIORITY_3);
/* Set some game instance data options */
this->gameInstance.SetSubscription(GameLogic::GameEvent::ObjectEventFunctionType_OnMove, GameSession::ObjectMove);
this->isCreated = true;
return this->isCreated; return this->isCreated;
} }
@ -108,14 +122,71 @@ namespace DanBias
} }
} }
void GameSession::ThreadEntry( )
{
//List with clients that we are waiting on..
DynamicArray<SmartPointer<GameClient>> readyList = this->clients;
//First we need to clean invalid clients, if any, and tell them to start loading game data
for (unsigned int i = 0; i < readyList.Size(); i++)
{
if(!readyList[i])
{
readyList.Remove(i);
}
else
{
Protocol_LobbyCreateGame p(readyList[i]->GetPlayer()->GetID(), "char_white.dan", readyList[i]->GetPlayer()->GetOrientation());
readyList[i]->GetClient()->Send(p);
}
}
unsigned int readyCounter = readyList.Size();
//Sync with clients
while (readyCounter != 0)
{
this->ProcessClients();
for (unsigned int i = 0; i < readyList.Size(); i++)
{
if(readyList[i] && readyList[i]->IsReady())
{
//Need to send information about other players, to all players
for (unsigned int k = 0; k < this->clients.Size(); k++)
{
if((this->clients[k] && readyList[i]) && readyList[i]->GetClient()->GetID() != this->clients[k]->GetClient()->GetID())
{
Protocol_ObjectCreate p(this->clients[k]->GetPlayer()->GetOrientation(), this->clients[k]->GetPlayer()->GetID(), "char_white.dan"); //The model name will be custom later..
readyList[i]->GetClient()->Send(p);
}
}
readyCounter-- ;
readyList[i] = 0;
}
}
Sleep(5); //TODO: This might not be needed here.
}
for (unsigned int i = 0; i < this->clients.Size(); i++)
{
if(this->clients[i])
{
this->clients[i]->GetClient()->Send(GameLogic::Protocol_LobbyStartGame(5));
}
}
}
bool GameSession::Attach(Utility::DynamicMemory::SmartPointer<NetworkClient> client) bool GameSession::Attach(Utility::DynamicMemory::SmartPointer<NetworkClient> client)
{ {
if(!this->isCreated) return false; if(!this->isCreated) return false;
client->SetOwner(this); client->SetOwner(this);
SmartPointer<GameClient> obj = new GameClient(client, this->gameInstance.CreatePlayer());
IPlayerData* player = this->gameInstance.CreatePlayer();
if(!player) return false;
SmartPointer<GameClient> obj = new GameClient(client, player);
for (unsigned int i = 0; i < clients.Size(); i++) for (unsigned int i = 0; i < clients.Size(); i++)
{ {
@ -131,6 +202,13 @@ namespace DanBias
return true; return true;
} }
void GameSession::CloseSession( bool dissconnectClients )
{
this->worker.Terminate();
NetworkSession::CloseSession(true);
this->clients.Clear();
}
}//End namespace DanBias }//End namespace DanBias

View File

@ -89,7 +89,7 @@
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(SolutionDir)Misc;$(SolutionDir)OysterMath;$(SolutionDir)OysterPhysics3D;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc;$(SolutionDir)OysterMath;$(SolutionDir)OysterPhysics3D;$(SolutionDir)Physics\Bullet Source\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WINDLL;PHYSICS_DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_WINDLL;PHYSICS_DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<GenerateXMLDocumentationFiles>false</GenerateXMLDocumentationFiles> <GenerateXMLDocumentationFiles>false</GenerateXMLDocumentationFiles>
</ClCompile> </ClCompile>
@ -97,6 +97,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<ModuleDefinitionFile> <ModuleDefinitionFile>
</ModuleDefinitionFile> </ModuleDefinitionFile>
<AdditionalDependencies>$(SolutionDir)Physics/lib/debug/BulletCollision_Debug.lib;$(SolutionDir)Physics/lib/debug/BulletDynamics_Debug.lib;$(SolutionDir)Physics/lib/debug/LinearMath_Debug.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -119,7 +120,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)Misc;$(SolutionDir)OysterMath;$(SolutionDir)OysterPhysics3D;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc;$(SolutionDir)OysterMath;$(SolutionDir)OysterPhysics3D;$(SolutionDir)Physics\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WINDLL;PHYSICS_DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_WINDLL;PHYSICS_DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<GenerateXMLDocumentationFiles>false</GenerateXMLDocumentationFiles> <GenerateXMLDocumentationFiles>false</GenerateXMLDocumentationFiles>
</ClCompile> </ClCompile>

View File

@ -31,11 +31,11 @@ Octree& Octree::operator=(const Octree& orig)
void Octree::AddObject(UniquePointer< ICustomBody > customBodyRef) void Octree::AddObject(UniquePointer< ICustomBody > customBodyRef)
{ {
customBodyRef->SetScene( this ); //customBodyRef->SetScene( this );
Data data; Data data;
//Data* tempPtr = this->worldNode.dataPtr; //Data* tempPtr = this->worldNode.dataPtr;
data.container = customBodyRef->GetBoundingSphere(); //data.container = customBodyRef->GetBoundingSphere();
data.queueRef = -1; data.queueRef = -1;
data.next = NULL; data.next = NULL;
data.prev = NULL; data.prev = NULL;
@ -140,6 +140,7 @@ void Octree::Visit(ICustomBody* customBodyRef, VisitorAction hitAction )
{ {
auto object = this->mapReferences.find(customBodyRef); auto object = this->mapReferences.find(customBodyRef);
// If rigid body is not found
if(object == this->mapReferences.end()) if(object == this->mapReferences.end())
{ {
return; return;
@ -147,8 +148,10 @@ void Octree::Visit(ICustomBody* customBodyRef, VisitorAction hitAction )
unsigned int tempRef = object->second; unsigned int tempRef = object->second;
// Go through all object and test for intersection
for(unsigned int i = 0; i<this->leafData.size(); i++) for(unsigned int i = 0; i<this->leafData.size(); i++)
{ {
// If objects intersect call collision response function
if(tempRef != i && !this->leafData[i].limbo) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container)) if(tempRef != i && !this->leafData[i].limbo) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container))
{ {
hitAction(*this, tempRef, i); hitAction(*this, tempRef, i);
@ -213,7 +216,7 @@ unsigned int Octree::GetTemporaryReferenceOf( const ICustomBody* objRef ) const
void Octree::SetAsAltered( unsigned int tempRef ) void Octree::SetAsAltered( unsigned int tempRef )
{ {
this->leafData[tempRef].container = this->leafData[tempRef].customBodyRef->GetBoundingSphere(); //this->leafData[tempRef].container = this->leafData[tempRef].customBodyRef->GetBoundingSphere();
//! @todo TODO: implement stub //! @todo TODO: implement stub
} }

View File

@ -12,324 +12,6 @@ using namespace ::Utility::Value;
API_Impl API_instance; API_Impl API_instance;
namespace
{
/*void OnPossibleCollision( Octree& worldScene, unsigned int protoTempRef, unsigned int deuterTempRef )
{
auto proto = worldScene.GetCustomBody( protoTempRef );
auto deuter = worldScene.GetCustomBody( deuterTempRef );
Float4 worldPointOfContact;
if( proto->Intersects(*deuter, worldPointOfContact) )
{
// Apply CollisionResponse in pure gather pattern
ICustomBody::State protoState; proto->GetState( protoState );
ICustomBody::State deuterState; deuter->GetState( deuterState );
// calc from perspective of deuter.
Float4 normal = (worldPointOfContact - Float4(deuterState.GetCenterPosition(), 1.0f )); // Init value is only borrowed
//if( normal.Dot(normal) > 0.0f )
{
deuter->GetNormalAt( worldPointOfContact, normal );
}
//else
//{ // special case: deuter is completly contained within proto or they have overlapping centers.
// normal = Float4( protoState.GetCenterPosition() - deuterState.GetCenterPosition(), 0.0f );
// if( normal.Dot(normal) == 0.0f )
// { // they have overlapping centers. Rebound at least
// // calculate and store time interpolation value, for later rebound.
// proto->SetTimeOfContact( worldPointOfContact );
// return;
// }
//
// // borrowing the negated normal of proto.
// proto->GetNormalAt( worldPointOfContact, normal );
// normal = -normal;
//}
normal.Normalize();
Float4 protoG = Float4(protoState.GetLinearMomentum( worldPointOfContact.xyz ), 0),
deuterG = Float4(deuterState.GetLinearMomentum( worldPointOfContact.xyz ), 0);
if( normal != normal ) // debug: trap
const char *breakpoint = "This should never happen";
if( protoG != protoG ) // debug: trap
const char *breakpoint = "This should never happen";
if( deuterG != deuterG ) // debug: trap
const char *breakpoint = "This should never happen";
Float protoG_Magnitude = protoG.Dot( normal ),
deuterG_Magnitude = deuterG.Dot( normal );
// if they are not relatively moving towards eachother, there is no collision
Float deltaPos = normal.Dot( Float4(deuterState.GetCenterPosition(), 1) - Float4(protoState.GetCenterPosition(), 1) );
if( deltaPos < 0.0f )
{
if( protoG_Magnitude >= deuterG_Magnitude )
{
return;
}
}
else if( deltaPos > 0.0f )
{
if( protoG_Magnitude <= deuterG_Magnitude )
{
return;
}
}
else
{
return;
}
if( proto->CallSubscription_BeforeCollisionResponse(proto) == ICustomBody::SubscriptMessage_ignore_collision_response )
{
return;
}
// PLayerHAck
if( proto->CallSubscription_BeforeCollisionResponse(proto) == ICustomBody::SubscriptMessage_player_collision_response )
{
//Float3 linearMomentum = protoState.GetLinearMomentum();
//Float3 up = -protoState.GetGravityNormal();
//Float3 upForce = (linearMomentum.Dot(up) * up);
//Float3 noBounceForce = linearMomentum - upForce;
//protoState.SetLinearMomentum(noBounceForce);
//proto->SetState(protoState);
return;
}
// calculate and store time interpolation value, for later rebound.
proto->SetTimeOfContact( worldPointOfContact );
// bounce
Float4 bounceD = normal * -Formula::CollisionResponse::Bounce( deuterState.GetRestitutionCoeff(),
deuterState.GetMass(), deuterG_Magnitude,
protoState.GetMass(), protoG_Magnitude );
// calc from perspective of proto
normal = (worldPointOfContact - Float4(protoState.GetCenterPosition(), 1.0f )).GetNormalized();
//if( normal.Dot(normal) > 0.0f )
{
proto->GetNormalAt( worldPointOfContact, normal );
protoG_Magnitude = protoG.Dot( normal );
deuterG_Magnitude = deuterG.Dot( normal );
normal.Normalize();
}
//else
//{ // special case: proto is completly contained within deuter.
// // borrowing the negated normal of deuter.
// deuter->GetNormalAt( worldPointOfContact, normal );
// normal = -normal;
// protoG_Magnitude = -protoG_Magnitude;
// deuterG_Magnitude = -deuterG_Magnitude;
//}
if( normal != normal ) // debug: trap
const char *breakpoint = "This should never happen";
// bounce
Float4 bounceP = normal * Formula::CollisionResponse::Bounce( protoState.GetRestitutionCoeff(),
protoState.GetMass(), protoG_Magnitude,
deuterState.GetMass(), deuterG_Magnitude );
Float4 bounce = Average( bounceD, bounceP );
Float4 friction = Formula::CollisionResponse::Friction( protoG_Magnitude, normal,
Float4(protoState.GetLinearMomentum(), 0), protoState.GetFrictionCoeff_Static(), protoState.GetFrictionCoeff_Kinetic(), protoState.GetMass(),
Float4(deuterState.GetLinearMomentum(), 0), deuterState.GetFrictionCoeff_Static(), deuterState.GetFrictionCoeff_Kinetic(), deuterState.GetMass());
if(protoState.GetMass() == 70)
{
const char* breakPoint = "here";
}
Float kineticEnergyPBefore = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), protoState.GetLinearMomentum()/protoState.GetMass() );
protoState.ApplyImpulse( bounce.xyz, worldPointOfContact.xyz, normal.xyz );
proto->SetState( protoState );
Float kineticEnergyPAFter = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), (protoState.GetLinearMomentum() + protoState.GetLinearImpulse())/protoState.GetMass() );
proto->CallSubscription_AfterCollisionResponse( deuter, kineticEnergyPBefore - kineticEnergyPAFter );
}
}*/
void OnPossibleCollision( Octree& worldScene, unsigned int protoTempRef, unsigned int deuterTempRef )
{
auto proto = worldScene.GetCustomBody( protoTempRef );
auto deuter = worldScene.GetCustomBody( deuterTempRef );
if(proto->GetState().GetMass() == 70)
{
const char *breakpoint = "STOP";
}
Float4 worldPointOfContact;
if( proto->Intersects(*deuter, worldPointOfContact) )
{
// Apply CollisionResponse in pure gather pattern
ICustomBody::State protoState; proto->GetState( protoState );
ICustomBody::State deuterState; deuter->GetState( deuterState );
// calc from perspective of deuter.
// calc from perspective of deuter.
Float4 normal = (worldPointOfContact - Float4(deuterState.GetCenterPosition(), 1.0f )).GetNormalized(); // Init value is only borrowed
if( normal.Dot(normal) > 0.0f )
{
deuter->GetNormalAt( worldPointOfContact, normal );
}
else
{ // special case: deuter is completly contained within proto or they have overlapping centers.
normal = Float4( protoState.GetCenterPosition() - deuterState.GetCenterPosition(), 0.0f );
if( normal.Dot(normal) == 0.0f )
{ // they have overlapping centers. Rebound at least
// calculate and store time interpolation value, for later rebound.
proto->SetTimeOfContact( worldPointOfContact );
return;
}
// borrowing the negated normal of proto.
proto->GetNormalAt( worldPointOfContact, normal );
normal = -normal;
}
normal.Normalize();
Float4 protoG = Float4(protoState.GetLinearMomentum( worldPointOfContact.xyz ), 0),
deuterG = Float4(deuterState.GetLinearMomentum( worldPointOfContact.xyz ), 0);
Float protoG_Magnitude = protoG.Dot( normal ),
deuterG_Magnitude = deuterG.Dot( normal );
if(protoState.GetMass() == 70)
{
const char *breakpoint = "STOP";
}
// if they are not relatively moving towards eachother, there is no collision
Float deltaPos = normal.Dot( Float4(deuterState.GetCenterPosition(), 1) - Float4(protoState.GetCenterPosition(), 1) );
if( deltaPos < 0.0f )
{
if( protoG_Magnitude >= deuterG_Magnitude )
{
return;
}
}
else if( deltaPos > 0.0f )
{
if( protoG_Magnitude <= deuterG_Magnitude )
{
return;
}
}
else
{
return;
}
// calc from perspective of proto
normal = (worldPointOfContact - Float4(protoState.GetCenterPosition(), 1.0f )).GetNormalized();
if( normal.Dot(normal) > 0.0f )
{
proto->GetNormalAt( worldPointOfContact, normal );
protoG_Magnitude = protoG.Dot( normal );
deuterG_Magnitude = deuterG.Dot( normal );
normal.Normalize();
}
else
{ // special case: proto is completly contained within deuter.
// borrowing the negated normal of deuter.
deuter->GetNormalAt( worldPointOfContact, normal );
normal = -normal;
protoG_Magnitude = -protoG_Magnitude;
deuterG_Magnitude = -deuterG_Magnitude;
}
normal.Normalize();
if( normal != normal ) // debug: trap
const char *breakpoint = "This should never happen";
Float4 friction = Formula::CollisionResponse::Friction( protoG_Magnitude, normal,
Float4(protoState.GetLinearMomentum(), 0), protoState.GetFrictionCoeff_Static(), protoState.GetFrictionCoeff_Kinetic(), protoState.GetMass(),
Float4(deuterState.GetLinearMomentum(), 0), deuterState.GetFrictionCoeff_Static(), deuterState.GetFrictionCoeff_Kinetic(), deuterState.GetMass());
if(protoState.GetMass() == 70)
{
const char *breakpoint = "STOP";
}
protoState.ApplyFriction( -friction.xyz );
if( proto->CallSubscription_BeforeCollisionResponse(proto) == ICustomBody::SubscriptMessage_ignore_collision_response )
{
return;
}
// PLayerHAck
if( proto->CallSubscription_BeforeCollisionResponse(proto) == ICustomBody::SubscriptMessage_player_collision_response )
{
return;
}
if(protoState.GetMass() == 50)
{
const char* breakPoint = "Break";
}
// bounce
Float4 bounceD = normal * -Formula::CollisionResponse::Bounce( deuterState.GetRestitutionCoeff(),
deuterState.GetMass(), deuterG_Magnitude,
protoState.GetMass(), protoG_Magnitude );
// calc from perspective of proto
proto->GetNormalAt( worldPointOfContact, normal );
normal.Normalize();
protoG_Magnitude = protoG.Dot( normal );
deuterG_Magnitude = deuterG.Dot( normal );
// bounce
Float4 bounceP = normal * Formula::CollisionResponse::Bounce( protoState.GetRestitutionCoeff(),
protoState.GetMass(), protoG_Magnitude,
deuterState.GetMass(), deuterG_Magnitude );
Float4 bounce = bounceP;
//LinearAlgebra3D::InterpolateAxisYToNormal_UsingNlerp(state.SetOrientation(, Float4(state.GetGravityNormal(), 0.0f), 1.0f);
if( abs(bounce.x) < 0.001 )
{
bounce.x = 0;
}
if( abs(bounce.y) < 0.001 )
{
bounce.y = 0;
}
if( abs(bounce.z) < 0.001 )
{
bounce.z = 0;
}
Float kineticEnergyPBefore = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), protoState.GetLinearMomentum()/protoState.GetMass() );
protoState.ApplyImpulse( bounce.xyz, worldPointOfContact.xyz, normal.xyz );
proto->SetState( protoState );
Float kineticEnergyPAFter = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), (protoState.GetLinearMomentum() + protoState.GetLinearImpulse())/protoState.GetMass() );
proto->CallSubscription_AfterCollisionResponse( deuter, kineticEnergyPBefore - kineticEnergyPAFter );
}
}
}
API & API::Instance() API & API::Instance()
{ {
return API_instance; return API_instance;
@ -337,319 +19,190 @@ API & API::Instance()
API_Impl::API_Impl() API_Impl::API_Impl()
{ {
this->gravityConstant = Constant::gravity_constant; this->broadphase = NULL;
this->epsilon = Constant::epsilon; this->collisionConfiguration = NULL;
this->updateFrameLength = 1.0f / 120.0f; this->dispatcher = NULL;
this->destructionAction = Default::EventAction_Destruction; this->solver = NULL;
this->gravity = ::std::vector<Gravity>(); this->dynamicsWorld = NULL;
this->worldScene = Octree();
} }
API_Impl::~API_Impl() {} API_Impl::~API_Impl()
void API_Impl::Init( unsigned int numObjects, unsigned int numGravityWells , const Float3 &worldSize )
{ {
unsigned char numLayers = 4; //!< @todo TODO: calc numLayers from worldSize delete this->dynamicsWorld;
this->gravity.resize( 0 ); this->dynamicsWorld = NULL;
this->gravity.reserve( numGravityWells ); delete this->solver;
this->worldScene = Octree( numObjects, numLayers, worldSize ); this->solver = NULL;
} delete this->dispatcher;
this->dispatcher = NULL;
delete this->collisionConfiguration;
this->collisionConfiguration = NULL;
delete this->broadphase;
this->broadphase = NULL;
void API_Impl::SetFrameTimeLength( float deltaTime ) for(int i = 0; i < this->customBodies.size(); i++)
{
this->updateFrameLength = deltaTime;
}
void API_Impl::SetGravityConstant( float g )
{
this->gravityConstant = g;
}
void API_Impl::SetEpsilon( float e )
{
this->epsilon = e;
}
void API_Impl::SetSubscription( API::EventAction_Destruction functionPointer )
{
if( functionPointer )
{ {
this->destructionAction = functionPointer; delete this->customBodies[i];
} this->customBodies[i] = NULL;
else
{
this->destructionAction = Default::EventAction_Destruction;
} }
} }
float API_Impl::GetFrameTimeLength() const // Bullet physics
ICustomBody* API_Impl::AddCollisionSphere(float radius, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass)
{ {
return this->updateFrameLength; SimpleRigidBody* body = new SimpleRigidBody;
// Add collision shape
btCollisionShape* collisionShape = new btSphereShape(radius);
body->SetCollisionShape(collisionShape);
// Add motion state
btDefaultMotionState* motionState = new btDefaultMotionState(btTransform(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w),btVector3(position.x, position.y, position.z)));
body->SetMotionState(motionState);
// Add rigid body
btVector3 fallInertia(0, 0, 0);
collisionShape->calculateLocalInertia(mass, fallInertia);
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, motionState, collisionShape, fallInertia);
btRigidBody* rigidBody = new btRigidBody(rigidBodyCI);
rigidBody->setUserPointer(body);
body->SetRigidBody(rigidBody);
// Add rigid body to world
this->dynamicsWorld->addRigidBody(rigidBody);
this->customBodies.push_back(body);
return body;
}
ICustomBody* API_Impl::AddCollisionBox(Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass)
{
SimpleRigidBody* body = new SimpleRigidBody;
// Add collision shape
btCollisionShape* collisionShape = new btBoxShape(btVector3(halfSize.x, halfSize.y, halfSize.z));
body->SetCollisionShape(collisionShape);
// Add motion state
btDefaultMotionState* motionState = new btDefaultMotionState(btTransform(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w),btVector3(position.x, position.y, position.z)));
body->SetMotionState(motionState);
// Add rigid body
btVector3 fallInertia(0, 0, 0);
collisionShape->calculateLocalInertia(mass, fallInertia);
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, motionState, collisionShape, fallInertia);
btRigidBody* rigidBody = new btRigidBody(rigidBodyCI);
rigidBody->setUserPointer(body);
body->SetRigidBody(rigidBody);
// Add rigid body to world
this->dynamicsWorld->addRigidBody(rigidBody);
this->customBodies.push_back(body);
return body;
} }
void API_Impl::Update() void API_Impl::UpdateWorld()
{ /** @todo TODO: Update is a temporary solution .*/ {
::std::vector<ICustomBody*> updateList; this->dynamicsWorld->stepSimulation(1.0f/60.0f, 1.0f, 1.0f/60.0f);
auto proto = this->worldScene.Sample( Universe(), updateList ).begin();
ICustomBody::State state; ICustomBody::State state;
for( ; proto != updateList.end(); ++proto )
for(unsigned int i = 0; i < this->customBodies.size(); i++ )
{ {
// Step 1: Apply Gravity this->customBodies[i]->GetState(state);
Float4 gravityImpulse = Float4::null;
(*proto)->GetState( state ); btTransform trans;
for( ::std::vector<Gravity>::size_type i = 0; i < this->gravity.size(); ++i ) dynamic_cast<SimpleRigidBody*>(this->customBodies[i])->GetMotionState()->getWorldTransform(trans);
state.centerPos = Float3(trans.getOrigin().x(), trans.getOrigin().y(), trans.getOrigin().z());
state.quaternion = Quaternion(Float3(trans.getRotation().x(), trans.getRotation().y(), trans.getRotation().z()), trans.getRotation().w());
if(dynamic_cast<SimpleRigidBody*>(this->customBodies[i])->GetRigidBody()->getActivationState() == ACTIVE_TAG)
{ {
switch( this->gravity[i].gravityType ) dynamic_cast<SimpleRigidBody*>(this->customBodies[i])->CallSubscription_Move();
{ }
case Gravity::GravityType_Well:
{ this->customBodies[i]->SetState(state);
Float4 d = Float4( this->gravity[i].well.position, 1.0f ) - Float4( state.GetCenterPosition(), 1.0f ); }
Float rSquared = d.Dot( d );
if( rSquared != 0.0 ) int numManifolds = this->dynamicsWorld->getDispatcher()->getNumManifolds();
{ for (int i=0;i<numManifolds;i++)
if(state.GetMass() == 70) {
{ btPersistentManifold* contactManifold = this->dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
const char *breakpoint = "STOP"; const btCollisionObject* obA = contactManifold->getBody0();
} const btCollisionObject* obB = contactManifold->getBody1();
Float force = Physics3D::Formula::ForceField( this->gravityConstant, state.GetMass(), this->gravity[i].well.mass, rSquared );
gravityImpulse += ((this->updateFrameLength * force)) * d.GetNormalized(); ICustomBody* bodyA = (ICustomBody*)obA->getUserPointer();
} ICustomBody* bodyB = (ICustomBody*)obB->getUserPointer();
break;
} dynamic_cast<SimpleRigidBody*>(bodyA)->CallSubscription_AfterCollisionResponse(bodyA, bodyB, 0.0f);
case Gravity::GravityType_Directed: dynamic_cast<SimpleRigidBody*>(bodyB)->CallSubscription_AfterCollisionResponse(bodyB, bodyA, 0.0f);
gravityImpulse += Float4( this->gravity[i].directed.impulse, 0.0f );
break; int numContacts = contactManifold->getNumContacts();
// case Gravity::GravityType_DirectedField: for (int j=0;j<numContacts;j++)
// //this->gravity[i].directedField. {
// //! TODO: @todo rethink btManifoldPoint& pt = contactManifold->getContactPoint(j);
// break; if (pt.getDistance()<0.f)
default: break; {
const btVector3& ptA = pt.getPositionWorldOnA();
const btVector3& ptB = pt.getPositionWorldOnB();
const btVector3& normalOnB = pt.m_normalWorldOnB;
} }
} }
if( gravityImpulse != gravityImpulse ) // debug: trap
const char *breakpoint = "This should never happen";
Float posLength = state.GetCenterPosition().GetLength();
if( gravityImpulse != Float4::null && posLength - 300 > 3.5 )
{
state.ApplyLinearImpulse( gravityImpulse.xyz );
state.SetGravityNormal( gravityImpulse.GetNormalized().xyz );
(*proto)->SetState( state );
}
if(state.GetMass() == 70)
{
const char *breakpoint = "STOP";
}
// Step 2: Apply Collision Response
this->worldScene.Visit( *proto, OnPossibleCollision );
} }
proto = updateList.begin();
for( ; proto != updateList.end(); ++proto )
{
(*proto)->GetState( state );
Float3 lM = state.GetLinearMomentum();
//LinearAlgebra3D::InterpolateAxisYToNormal_UsingNlerp(state.SetOrientation(, Float4(state.GetGravityNormal(), 0.0f), 1.0f);
/*if( abs(lM.x) < this->epsilon )
{
state.linearMomentum.x = 0;
}
if( abs(lM.y) < this->epsilon )
{
state.linearMomentum.y = 0;
}
if( abs(lM.z) < this->epsilon )
{
state.linearMomentum.z = 0;
}*/
(*proto)->SetState( state );
switch( (*proto)->Update(this->updateFrameLength) )
{
case UpdateState_altered:
this->worldScene.SetAsAltered( this->worldScene.GetTemporaryReferenceOf(*proto) );
(*proto)->CallSubscription_Move();
case UpdateState_resting:
default:
break;
}
}
} }
void API_Impl::Init()
{
this->broadphase = new btDbvtBroadphase();
this->collisionConfiguration = new btDefaultCollisionConfiguration();
this->dispatcher = new btCollisionDispatcher(this->collisionConfiguration);
this->solver = new btSequentialImpulseConstraintSolver;
this->dynamicsWorld = new btDiscreteDynamicsWorld(this->dispatcher,this->broadphase,this->solver,this->collisionConfiguration);
this->dynamicsWorld->setGravity(btVector3(0,-10,0));
}
bool API_Impl::IsInLimbo( const ICustomBody* objRef ) bool API_Impl::IsInLimbo( const ICustomBody* objRef )
{ {
return this->worldScene.IsInLimbo( objRef ); return true;
} }
void API_Impl::MoveToLimbo( const ICustomBody* objRef ) void API_Impl::MoveToLimbo( const ICustomBody* objRef )
{ {
this->worldScene.MoveToLimbo( objRef );
} }
void API_Impl::ReleaseFromLimbo( const ICustomBody* objRef ) void API_Impl::ReleaseFromLimbo( const ICustomBody* objRef )
{ {
this->worldScene.ReleaseFromLimbo( objRef );
}
void API_Impl::AddObject( ::Utility::DynamicMemory::UniquePointer<ICustomBody> handle )
{
this->worldScene.AddObject( handle );
}
UniquePointer<ICustomBody> API_Impl::ExtractObject( const ICustomBody* objRef )
{
return this->worldScene.Extract( objRef );
}
void API_Impl::DestroyObject( const ICustomBody* objRef )
{
UniquePointer<ICustomBody> object = this->worldScene.Extract( objRef );
if( object )
{
this->destructionAction( object );
}
}
void API_Impl::AddGravity( const API::Gravity &g )
{
this->gravity.push_back( g );
}
void API_Impl::RemoveGravity( const API::Gravity &g )
{
for( ::std::vector<Gravity>::size_type i = this->gravity.size() - 1; i >= 0; --i )
{
if( g == this->gravity[i] )
{
int end = this->gravity.size() - 1;
this->gravity[i] = this->gravity[end];
this->gravity.resize( end );
}
}
} }
void API_Impl::ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void* args, void(hitAction)(ICustomBody*, void*) ) void API_Impl::ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void* args, void(hitAction)(ICustomBody*, void*) )
{ {
this->worldScene.Visit(collideable, args, hitAction);
} }
//void API_Impl::ApplyForceAt( const ICustomBody* objRef, const Float3 &worldPos, const Float3 &worldF ) namespace Oyster
//{ {
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef ); namespace Physics
// if( tempRef != this->worldScene.invalid_ref )
// {
// //this->worldScene.GetCustomBody( tempRef )->Apply //!< @todo TODO: need function
// this->worldScene.SetAsAltered( tempRef );
// }
//}
//
//void API_Impl::SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const Float4x4 &localI )
//{ // deprecated
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
// if( tempRef != this->worldScene.invalid_ref )
// {
// this->worldScene.GetCustomBody( tempRef )->SetMomentOfInertiaTensor_KeepVelocity( localI );
// }
//}
//
//void API_Impl::SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const Float4x4 &localI )
//{ // deprecated
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
// if( tempRef != this->worldScene.invalid_ref )
// {
// this->worldScene.GetCustomBody( tempRef )->SetMomentOfInertiaTensor_KeepMomentum( localI );
// }
//}
//
//void API_Impl::SetMass_KeepVelocity( const ICustomBody* objRef, Float m )
//{ // deprecated
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
// if( tempRef != this->worldScene.invalid_ref )
// {
// this->worldScene.GetCustomBody( tempRef )->SetMass_KeepVelocity( m );
// }
//}
//
//void API_Impl::SetMass_KeepMomentum( const ICustomBody* objRef, Float m )
//{ // deprecated
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
// if( tempRef != this->worldScene.invalid_ref )
// {
// this->worldScene.GetCustomBody( tempRef )->SetMass_KeepMomentum( m );
// }
//}
//
//void API_Impl::SetCenter( const ICustomBody* objRef, const Float3 &worldPos )
//{
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
// if( tempRef != this->worldScene.invalid_ref )
// {
// //this->worldScene.GetCustomBody( tempRef )->Set //!< @todo TODO: need function
// this->worldScene.EvaluatePosition( tempRef );
// }
//}
//
//void API_Impl::SetRotation( const ICustomBody* objRef, const Float4x4 &rotation )
//{
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
// if( tempRef != this->worldScene.invalid_ref )
// {
// this->worldScene.GetCustomBody( tempRef )->SetRotation( rotation );
// this->worldScene.EvaluatePosition( tempRef );
// }
//}
//
//void API_Impl::SetOrientation( const ICustomBody* objRef, const Float4x4 &orientation )
//{
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
// if( tempRef != this->worldScene.invalid_ref )
// {
// this->worldScene.GetCustomBody( tempRef )->SetOrientation( orientation );
// this->worldScene.EvaluatePosition( tempRef );
// }
//}
//
//void API_Impl::SetSize( const ICustomBody* objRef, const Float3 &size )
//{
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
// if( tempRef != this->worldScene.invalid_ref )
// {
// this->worldScene.GetCustomBody( tempRef )->SetSize( size );
// this->worldScene.EvaluatePosition( tempRef );
// }
//}
UniquePointer<ICustomBody> API_Impl::CreateRigidBody( const API::SimpleBodyDescription &desc ) const
{
return new SimpleRigidBody( desc );
}
UniquePointer<ICustomBody> API_Impl::CreateRigidBody( const API::SphericalBodyDescription &desc ) const
{
return new SphericalRigidBody( desc );
}
namespace Oyster { namespace Physics
{
namespace Default
{ {
void EventAction_Destruction( ::Utility::DynamicMemory::UniquePointer<::Oyster::Physics::ICustomBody> proto ) namespace Default
{ /* Do nothing except allowing the proto uniquePointer destroy itself. */ } {
void EventAction_Destruction( ::Utility::DynamicMemory::UniquePointer<::Oyster::Physics::ICustomBody> proto )
{ /* Do nothing except allowing the proto uniquePointer destroy itself. */ }
::Oyster::Physics::ICustomBody::SubscriptMessage EventAction_BeforeCollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter ) ::Oyster::Physics::ICustomBody::SubscriptMessage EventAction_BeforeCollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter )
{ /* Do nothing except returning business as usual. */ { /* Do nothing except returning business as usual. */
return ::Oyster::Physics::ICustomBody::SubscriptMessage_none; return ::Oyster::Physics::ICustomBody::SubscriptMessage_none;
}
void EventAction_AfterCollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss )
{ /* Do nothing except returning business as usual. */
}
void EventAction_Move( const ::Oyster::Physics::ICustomBody *object )
{ /* Do nothing. */ }
} }
}
void EventAction_AfterCollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ) }
{ /* Do nothing except returning business as usual. */
}
void EventAction_Move( const ::Oyster::Physics::ICustomBody *object )
{ /* Do nothing. */ }
}
} }

View File

@ -3,6 +3,7 @@
#include "../PhysicsAPI.h" #include "../PhysicsAPI.h"
#include "Octree.h" #include "Octree.h"
#include <btBulletDynamicsCommon.h>
namespace Oyster namespace Oyster
{ {
@ -14,49 +15,27 @@ namespace Oyster
API_Impl(); API_Impl();
virtual ~API_Impl(); virtual ~API_Impl();
void Init( unsigned int numObjects, unsigned int numGravityWells , const ::Oyster::Math::Float3 &worldSize ); void Init();
void SetFrameTimeLength( float deltaTime );
void SetGravityConstant( float g );
void SetEpsilon( float e );
void SetSubscription( EventAction_Destruction functionPointer );
float GetFrameTimeLength() const;
void Update();
bool IsInLimbo( const ICustomBody* objRef ); bool IsInLimbo( const ICustomBody* objRef );
void MoveToLimbo( const ICustomBody* objRef ); void MoveToLimbo( const ICustomBody* objRef );
void ReleaseFromLimbo( const ICustomBody* objRef ); void ReleaseFromLimbo( const ICustomBody* objRef );
void AddObject( ::Utility::DynamicMemory::UniquePointer<ICustomBody> handle ); // Bullet physics
::Utility::DynamicMemory::UniquePointer<ICustomBody> ExtractObject( const ICustomBody* objRef ); ICustomBody* AddCollisionSphere(float radius, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass);
void DestroyObject( const ICustomBody* objRef ); ICustomBody* AddCollisionBox(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass);
void AddGravity( const API::Gravity &g ); void UpdateWorld();
void RemoveGravity( const API::Gravity &g );
void ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void* args, void(hitAction)(ICustomBody*, void*) ); void ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void* args, void(hitAction)(ICustomBody*, void*) );
//void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF );
//void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI );
//void SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI );
//void SetMass_KeepVelocity( const ICustomBody* objRef, ::Oyster::Math::Float m );
//void SetMass_KeepMomentum( const ICustomBody* objRef, ::Oyster::Math::Float m );
//void SetCenter( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos );
//void SetRotation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &rotation );
//void SetOrientation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &orientation );
//void SetSize( const ICustomBody* objRef, const ::Oyster::Math::Float3 &size );
::Utility::DynamicMemory::UniquePointer<ICustomBody> CreateRigidBody( const SimpleBodyDescription &desc ) const;
::Utility::DynamicMemory::UniquePointer<ICustomBody> CreateRigidBody( const SphericalBodyDescription &desc ) const;
private: private:
::Oyster::Math::Float gravityConstant, updateFrameLength, epsilon; btBroadphaseInterface* broadphase;
EventAction_Destruction destructionAction; btDefaultCollisionConfiguration* collisionConfiguration;
::std::vector<API::Gravity> gravity; btCollisionDispatcher* dispatcher;
Octree worldScene; btSequentialImpulseConstraintSolver* solver;
btDiscreteDynamicsWorld* dynamicsWorld;
std::vector<ICustomBody*> customBodies;
}; };
namespace Default namespace Default

View File

@ -8,291 +8,103 @@ using namespace ::Oyster::Collision3D;
using namespace ::Utility::DynamicMemory; using namespace ::Utility::DynamicMemory;
using namespace ::Utility::Value; using namespace ::Utility::Value;
namespace Private
{
const Float epsilon = (const Float)1e-20;
// Float calculations can suffer roundingerrors. Which is where epsilon = 1e-20 comes into the picture
inline bool EqualsZero( const Float &value )
{ // by Dan Andersson
return Abs( value ) < epsilon;
}
inline bool Contains( const Plane &container, const Float4 &pos )
{ // by Dan Andersson
return EqualsZero( container.normal.Dot( pos ) + container.phasing );
}
// revision of Ray Vs Plane intersect test, there ray is more of an axis
bool Intersects( const Ray &axis, const Plane &plane, Float &connectDistance )
{ // by Dan Andersson
Float c = plane.normal.Dot(axis.direction);
if( EqualsZero(c) )
{ // axis is parallell with the plane. (axis direction orthogonal with the planar normal)
connectDistance = 0.0f;
return Contains( plane, axis.origin );
}
connectDistance = -plane.phasing;
connectDistance -= plane.normal.Dot( axis.origin );
connectDistance /= c;
return true;
}
}
SimpleRigidBody::SimpleRigidBody() SimpleRigidBody::SimpleRigidBody()
{ {
this->rigid = RigidBody(); this->collisionShape = NULL;
this->rigid.SetMass_KeepMomentum( 16.0f ); this->motionState = NULL;
this->gravityNormal = Float3::null; this->rigidBody = NULL;
this->onCollision = Default::EventAction_BeforeCollisionResponse;
this->onCollisionResponse = Default::EventAction_AfterCollisionResponse; this->state.centerPos = Float3(0.0f, 0.0f, 0.0f);
this->onMovement = Default::EventAction_Move; this->state.quaternion = Quaternion(Float3(0.0f, 0.0f, 0.0f), 1.0f);
this->state.dynamicFrictionCoeff = 0.0f;
this->collisionRebound.previousSpatial.center = this->rigid.centerPos; this->state.staticFrictionCoeff = 0.0f;
this->collisionRebound.previousSpatial.axis = this->rigid.axis; this->state.mass = 0.0f;
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach; this->state.restitutionCoeff = 0.0f;
this->collisionRebound.timeOfContact = 1.0f; this->state.reach = Float3(0.0f, 0.0f, 0.0f);
this->afterCollision = NULL;
this->onMovement = NULL;
this->scene = nullptr;
this->customTag = nullptr; this->customTag = nullptr;
this->ignoreGravity = this->isForwarded = false;
} }
SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc ) SimpleRigidBody::~SimpleRigidBody()
{ {
this->rigid = RigidBody(); delete this->motionState;
this->rigid.SetRotation( desc.rotation ); this->motionState = NULL;
this->rigid.centerPos = desc.centerPosition; delete this->collisionShape;
this->rigid.SetSize( desc.size ); this->collisionShape = NULL;
this->rigid.restitutionCoeff = desc.restitutionCoeff; delete this->rigidBody;
this->rigid.frictionCoeff_Static = desc.frictionCoeff_Static; this->rigidBody = NULL;
this->rigid.frictionCoeff_Kinetic = desc.frictionCoeff_Dynamic; }
this->rigid.SetMass_KeepMomentum( desc.mass );
this->rigid.SetMomentOfInertia_KeepMomentum( desc.inertiaTensor );
this->deltaPos = Float4::null;
this->deltaAxis = Float4::null;
this->gravityNormal = Float3::null; void SimpleRigidBody::SetCollisionShape(btCollisionShape* shape)
{
this->collisionShape = shape;
}
void SimpleRigidBody::SetMotionState(btDefaultMotionState* motionState)
{
this->motionState = motionState;
}
void SimpleRigidBody::SetRigidBody(btRigidBody* rigidBody)
{
this->rigidBody = rigidBody;
this->collisionRebound.previousSpatial.center = this->rigid.centerPos;
this->collisionRebound.previousSpatial.axis = this->rigid.axis;
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach;
this->collisionRebound.timeOfContact = 1.0f;
if( desc.subscription_onCollision )
{
this->onCollision = desc.subscription_onCollision;
}
else
{
this->onCollision = Default::EventAction_BeforeCollisionResponse;
}
if( desc.subscription_onCollisionResponse )
{
this->onCollisionResponse = desc.subscription_onCollisionResponse;
}
else
{
this->onCollisionResponse = Default::EventAction_AfterCollisionResponse;
}
if( desc.subscription_onMovement )
{
this->onMovement= desc.subscription_onMovement;
}
else
{
this->onMovement = Default::EventAction_Move;
}
this->scene = nullptr;
this->customTag = nullptr;
this->ignoreGravity = desc.ignoreGravity;
} }
SimpleRigidBody::~SimpleRigidBody() {} void SimpleRigidBody::SetSubscription(EventAction_AfterCollisionResponse function)
UniquePointer<ICustomBody> SimpleRigidBody::Clone() const
{ {
return new SimpleRigidBody( *this ); this->afterCollision = function;
} }
SimpleRigidBody::State SimpleRigidBody::GetState() const void SimpleRigidBody::SetSubscription(EventAction_Move function)
{ {
return State( this->rigid.GetMass(), this->rigid.restitutionCoeff, this->onMovement = function;
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
this->rigid.GetMomentOfInertia(), this->rigid.boundingReach,
this->rigid.centerPos, this->rigid.axis,
this->rigid.momentum_Linear, this->rigid.momentum_Angular,
this->rigid.gravityNormal );
} }
SimpleRigidBody::State & SimpleRigidBody::GetState( SimpleRigidBody::State &targetMem ) const void SimpleRigidBody::CallSubscription_AfterCollisionResponse(ICustomBody* bodyA, ICustomBody* bodyB, Oyster::Math::Float kineticEnergyLoss)
{ {
return targetMem = State( this->rigid.GetMass(), this->rigid.restitutionCoeff, if(this->onMovement)
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic, this->afterCollision(bodyA, bodyB, kineticEnergyLoss);
this->rigid.GetMomentOfInertia(), this->rigid.boundingReach,
this->rigid.centerPos, this->rigid.axis,
this->rigid.momentum_Linear, this->rigid.momentum_Angular,
this->rigid.gravityNormal );
}
void SimpleRigidBody::SetState( const SimpleRigidBody::State &state )
{
this->rigid.centerPos = state.GetCenterPosition();
this->rigid.axis = state.GetAngularAxis();
this->rigid.boundingReach = state.GetReach();
this->rigid.momentum_Linear = state.GetLinearMomentum();
this->rigid.momentum_Angular = state.GetAngularMomentum();
this->rigid.impulse_Linear += state.GetLinearImpulse();
this->rigid.impulse_Angular += state.GetAngularImpulse();
this->rigid.restitutionCoeff = state.GetRestitutionCoeff();
this->rigid.frictionCoeff_Static = state.GetFrictionCoeff_Static();
this->rigid.frictionCoeff_Kinetic = state.GetFrictionCoeff_Kinetic();
this->rigid.SetMass_KeepMomentum( state.GetMass() );
this->rigid.SetMomentOfInertia_KeepMomentum( state.GetMomentOfInertia() );
this->rigid.gravityNormal = state.GetGravityNormal();
if( state.IsForwarded() )
{
this->deltaPos += Float4(state.GetForward_DeltaPos(), 0);
this->deltaAxis += Float4(state.GetForward_DeltaAxis(), 0);
this->isForwarded;
}
if( this->scene )
{
if( state.IsSpatiallyAltered() )
{
unsigned int tempRef = this->scene->GetTemporaryReferenceOf( this );
this->scene->SetAsAltered( tempRef );
this->scene->EvaluatePosition( tempRef );
}
else if( state.IsDisturbed() )
{
this->scene->SetAsAltered( this->scene->GetTemporaryReferenceOf(this) );
}
}
}
ICustomBody::SubscriptMessage SimpleRigidBody::CallSubscription_BeforeCollisionResponse( const ICustomBody *deuter )
{
return this->onCollision( this, deuter );
}
void SimpleRigidBody::CallSubscription_AfterCollisionResponse( const ICustomBody *deuter, Float kineticEnergyLoss )
{
return this->onCollisionResponse( this, deuter, kineticEnergyLoss );
} }
void SimpleRigidBody::CallSubscription_Move() void SimpleRigidBody::CallSubscription_Move()
{ {
this->onMovement( this ); if(this->onMovement)
this->onMovement(this);
} }
bool SimpleRigidBody::IsAffectedByGravity() const btCollisionShape* SimpleRigidBody::GetCollisionShape() const
{ {
return !this->ignoreGravity; return this->collisionShape;
} }
bool SimpleRigidBody::Intersects( const ICollideable &shape ) const btDefaultMotionState* SimpleRigidBody::GetMotionState() const
{ {
return Box( this->rigid.GetRotationMatrix(), this->rigid.centerPos, this->rigid.GetSize() ).Intersects( shape ); return this->motionState;
} }
bool SimpleRigidBody::Intersects( const ICollideable &shape, Float4 &worldPointOfContact ) const btRigidBody* SimpleRigidBody::GetRigidBody() const
{ {
return Box( this->rigid.GetRotationMatrix(), this->rigid.centerPos, this->rigid.GetSize() ).Intersects( shape, worldPointOfContact ); return this->rigidBody;
} }
bool SimpleRigidBody::Intersects( const ICustomBody &object, Float4 &worldPointOfContact ) const SimpleRigidBody::State SimpleRigidBody::GetState() const
{ {
return object.Intersects( Box(this->rigid.GetRotationMatrix(), this->rigid.centerPos, this->rigid.GetSize()), worldPointOfContact ); return this->state;
} }
void SimpleRigidBody::SetTimeOfContact( Float4 &worldPointOfContact ) SimpleRigidBody::State & SimpleRigidBody::GetState( SimpleRigidBody::State &targetMem ) const
{ {
Point pointOfContact = Point( worldPointOfContact ); targetMem = this->state;
Box start = Box();
{
start.rotation = RotationMatrix( this->collisionRebound.previousSpatial.axis );
start.center = this->collisionRebound.previousSpatial.center;
start.boundingOffset = this->collisionRebound.previousSpatial.reach;
}
Box end = Box();
{
end.rotation = RotationMatrix( this->rigid.axis );
end.center = this->rigid.centerPos;
end.boundingOffset = this->rigid.boundingReach;
}
Float timeOfContact = ::Oyster::Collision3D::Utility::TimeOfContact( start, end, pointOfContact );
this->collisionRebound.timeOfContact = Min( this->collisionRebound.timeOfContact, timeOfContact );
}
Sphere & SimpleRigidBody::GetBoundingSphere( Sphere &targetMem ) const
{
return targetMem = Sphere( this->rigid.centerPos, this->rigid.boundingReach.GetMagnitude() );
}
Float4 & SimpleRigidBody::GetNormalAt( const Float4 &worldPos, Float4 &targetMem ) const
{
Float4 offset = worldPos.xyz - this->rigid.centerPos;
Float distance = offset.Dot( offset );
Float3 normal = Float3::null;
if( distance != 0.0f )
{ // sanity check
Ray axis( Float4::standard_unit_w, offset / (Float)::std::sqrt(distance) );
Float minDistance = numeric_limits<Float>::max();
Float4x4 rotationMatrix = this->rigid.GetRotationMatrix();
if( Private::Intersects(axis, Plane(rotationMatrix.v[0], -this->rigid.boundingReach.x), axis.collisionDistance) )
{ // check along x-axis
if( axis.collisionDistance < 0.0f )
normal = -rotationMatrix.v[0].xyz;
else
normal = rotationMatrix.v[0].xyz;
minDistance = Abs( axis.collisionDistance );
}
if( Private::Intersects(axis, Plane(rotationMatrix.v[1], -this->rigid.boundingReach.y), axis.collisionDistance) )
{ // check along y-axis
distance = Abs( axis.collisionDistance ); // recycling memory
if( minDistance > distance )
{
if( axis.collisionDistance < 0.0f )
normal = -rotationMatrix.v[1].xyz;
else
normal = rotationMatrix.v[1].xyz;
minDistance = distance;
}
}
if( Private::Intersects(axis, Plane(rotationMatrix.v[2], -this->rigid.boundingReach.z), axis.collisionDistance) )
{ // check along z-axis
if( minDistance > Abs( axis.collisionDistance ) )
{
if( axis.collisionDistance < 0.0f )
normal = -rotationMatrix.v[2].xyz;
else
normal = rotationMatrix.v[2].xyz;
}
}
}
targetMem.xyz = normal;
targetMem.w = 0.0f;
return targetMem; return targetMem;
} }
Float3 & SimpleRigidBody::GetGravityNormal( Float3 &targetMem ) const void SimpleRigidBody::SetState( const SimpleRigidBody::State &state )
{ {
return targetMem = this->gravityNormal; this->state = state;
} }
void * SimpleRigidBody::GetCustomTag() const void * SimpleRigidBody::GetCustomTag() const
@ -300,182 +112,10 @@ void * SimpleRigidBody::GetCustomTag() const
return this->customTag; return this->customTag;
} }
//Float3 & SimpleRigidBody::GetCenter( Float3 &targetMem ) const
//{
// return targetMem = this->rigid.centerPos;
//}
//
//Float4x4 & SimpleRigidBody::GetRotation( Float4x4 &targetMem ) const
//{
// return targetMem = this->rigid.box.rotation;
//}
//
//Float4x4 & SimpleRigidBody::GetOrientation( Float4x4 &targetMem ) const
//{
// return targetMem = this->rigid.GetOrientation();
//}
//
//Float4x4 & SimpleRigidBody::GetView( Float4x4 &targetMem ) const
//{
// return targetMem = this->rigid.GetView();
//}
//Float3 SimpleRigidBody::GetRigidLinearVelocity() const
//{
// return this->rigid.GetLinearVelocity();
//}
UpdateState SimpleRigidBody::Update( Float timeStepLength )
{
if( this->collisionRebound.timeOfContact < 1.0f )
{ // Rebound if needed
this->rigid.centerPos = Lerp( this->collisionRebound.previousSpatial.center, this->rigid.centerPos, this->collisionRebound.timeOfContact );
this->rigid.SetRotation( Lerp(this->collisionRebound.previousSpatial.axis, this->rigid.axis, this->collisionRebound.timeOfContact) );
this->rigid.boundingReach = Lerp( this->collisionRebound.previousSpatial.reach, this->rigid.boundingReach, this->collisionRebound.timeOfContact );
timeStepLength *= 2.0f - this->collisionRebound.timeOfContact; // compensate for rebounded time
this->collisionRebound.timeOfContact = 1.0f;
}
// Maintain rotation resolution by keeping axis within [0, 2pi] (trigonometric methods gets faster too)
Float4 temp;
::std::modf( this->rigid.axis * (0.5f / pi), temp.xyz );
this->rigid.axis -= ((2.0f * pi) * temp).xyz;
// Update rebound data
this->collisionRebound.previousSpatial.center = this->rigid.centerPos;
this->collisionRebound.previousSpatial.axis = this->rigid.axis;
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach;
// Check if this is close enough to be set resting
temp = Float4( this->rigid.impulse_Linear, 0.0f ) + Float4( this->rigid.impulse_Angular, 0.0f );
if( temp.Dot(temp) <= (Constant::epsilon * Constant::epsilon) )
{
unsigned char resting = 0;
if( this->rigid.momentum_Linear.Dot(this->rigid.momentum_Linear) <= (Constant::epsilon * Constant::epsilon) )
{
this->rigid.momentum_Linear = Float3::null;
resting = 1;
}
if( this->rigid.momentum_Angular.Dot(this->rigid.momentum_Angular) <= (Constant::epsilon * Constant::epsilon) )
{
this->rigid.momentum_Angular = Float3::null;
++resting;
}
if( resting == 2 )
{
this->rigid.impulse_Linear = this->rigid.impulse_Angular = Float3::null;
return UpdateState_resting;
}
}
this->rigid.Update_LeapFrog( timeStepLength );
return UpdateState_altered;
}
void SimpleRigidBody::Predict( Float4 &outDeltaPos, Float4 &outDeltaAxis, const Float4 &actingLinearImpulse, const Float4 &actingAngularImpulse, Float deltaTime )
{
this->rigid.Predict_LeapFrog( outDeltaPos.xyz, outDeltaAxis.xyz, actingLinearImpulse.xyz, actingAngularImpulse.xyz, deltaTime );
}
void SimpleRigidBody::SetScene( void *scene )
{
this->scene = (Octree*)scene;
}
void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_BeforeCollisionResponse functionPointer )
{
if( functionPointer )
{
this->onCollision = functionPointer;
}
else
{
this->onCollision = Default::EventAction_BeforeCollisionResponse;
}
}
void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_AfterCollisionResponse functionPointer )
{
if( functionPointer )
{
this->onCollisionResponse = functionPointer;
}
else
{
this->onCollisionResponse = Default::EventAction_AfterCollisionResponse;
}
}
void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_Move functionPointer )
{
if( functionPointer )
{
this->onMovement = functionPointer;
}
else
{
this->onMovement = Default::EventAction_Move;
}
}
void SimpleRigidBody::SetGravity( bool ignore)
{
this->ignoreGravity = ignore;
this->gravityNormal = Float3::null;
}
void SimpleRigidBody::SetGravityNormal( const Float3 &normalizedVector )
{
this->gravityNormal = normalizedVector;
this->rigid.gravityNormal = Float4( this->gravityNormal, 0 );
}
void SimpleRigidBody::SetCustomTag( void *ref ) void SimpleRigidBody::SetCustomTag( void *ref )
{ {
this->customTag = ref; this->customTag = ref;
} }
//void SimpleRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
//{
// this->rigid.SetMomentOfInertia_KeepVelocity( localI );
//}
//
//void SimpleRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI )
//{
// this->rigid.SetMomentOfInertia_KeepMomentum( localI );
//}
//
//void SimpleRigidBody::SetMass_KeepVelocity( Float m )
//{
// this->rigid.SetMass_KeepVelocity( m );
//}
//
//void SimpleRigidBody::SetMass_KeepMomentum( Float m )
//{
// this->rigid.SetMass_KeepMomentum( m );
//}
//
//void SimpleRigidBody::SetCenter( const Float3 &worldPos )
//{
// this->rigid.SetCenter( worldPos );
//}
//
//void SimpleRigidBody::SetRotation( const Float4x4 &rotation )
//{
// this->rigid.SetRotation( rotation );
//}
//
//void SimpleRigidBody::SetOrientation( const Float4x4 &orientation )
//{
// this->rigid.SetOrientation( orientation );
//}
//
//void SimpleRigidBody::SetSize( const Float3 &size )
//{
// this->rigid.SetSize( size );
//}
//
//void SimpleRigidBody::SetMomentum( const Float3 &worldG )
//{
// this->rigid.SetLinearMomentum( worldG );
//}

View File

@ -2,86 +2,52 @@
#define OYSTER_PHYSICS_SIMPLE_RIGIDBODY_H #define OYSTER_PHYSICS_SIMPLE_RIGIDBODY_H
#include "..\PhysicsAPI.h" #include "..\PhysicsAPI.h"
#include "RigidBody.h" #include <btBulletDynamicsCommon.h>
#include "Octree.h"
namespace Oyster { namespace Physics namespace Oyster
{ {
class SimpleRigidBody : public ICustomBody namespace Physics
{ {
public: class SimpleRigidBody : public ICustomBody
SimpleRigidBody();
SimpleRigidBody( const API::SimpleBodyDescription &desc );
virtual ~SimpleRigidBody();
::Utility::DynamicMemory::UniquePointer<ICustomBody> Clone() const;
State GetState() const;
State & GetState( State &targetMem ) const;
void SetState( const State &state );
//::Oyster::Math::Float3 GetRigidLinearVelocity() const;
SubscriptMessage CallSubscription_BeforeCollisionResponse( const ICustomBody *deuter );
void CallSubscription_AfterCollisionResponse( const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss );
void CallSubscription_Move();
bool IsAffectedByGravity() const;
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const;
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const;
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const;
void SetTimeOfContact( ::Oyster::Math::Float4 &worldPointOfContact );
::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) const;
::Oyster::Math::Float4 & GetNormalAt( const ::Oyster::Math::Float4 &worldPos, ::Oyster::Math::Float4 &targetMem = ::Oyster::Math::Float4() ) const;
::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
void * GetCustomTag() const;
//::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
//::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
//::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
//::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
UpdateState Update( ::Oyster::Math::Float timeStepLength );
void Predict( ::Oyster::Math::Float4 &outDeltaPos, ::Oyster::Math::Float4 &outDeltaAxis, const ::Oyster::Math::Float4 &actingLinearImpulse, const ::Oyster::Math::Float4 &actingAngularImpulse, ::Oyster::Math::Float deltaTime );
void SetScene( void *scene );
void SetSubscription( EventAction_BeforeCollisionResponse functionPointer );
void SetSubscription( EventAction_AfterCollisionResponse functionPointer );
void SetSubscription( EventAction_Move functionPointer );
void SetGravity( bool ignore);
void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector );
void SetCustomTag( void *ref );
//void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
//void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
//void SetMass_KeepVelocity( ::Oyster::Math::Float m );
//void SetMass_KeepMomentum( ::Oyster::Math::Float m );
//void SetCenter( const ::Oyster::Math::Float3 &worldPos );
//void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
//void SetOrientation( const ::Oyster::Math::Float4x4 &orientation );
//void SetSize( const ::Oyster::Math::Float3 &size );
//void SetMomentum( const ::Oyster::Math::Float3 &worldG );
private:
::Oyster::Physics3D::RigidBody rigid;
::Oyster::Math::Float4 deltaPos, deltaAxis;
::Oyster::Math::Float3 gravityNormal;
struct
{ {
struct { ::Oyster::Math::Float3 center, axis, reach; } previousSpatial; public:
::Oyster::Math::Float timeOfContact; SimpleRigidBody();
} collisionRebound; virtual ~SimpleRigidBody();
EventAction_BeforeCollisionResponse onCollision; void SetCollisionShape(btCollisionShape* shape);
EventAction_AfterCollisionResponse onCollisionResponse; void SetMotionState(btDefaultMotionState* motionState);
EventAction_Move onMovement; void SetRigidBody(btRigidBody* rigidBody);
void SetSubscription(EventAction_AfterCollisionResponse function);
void SetSubscription(EventAction_Move function);
Octree *scene; void CallSubscription_AfterCollisionResponse(ICustomBody* bodyA, ICustomBody* bodyB, Math::Float kineticEnergyLoss);
void *customTag; void CallSubscription_Move();
bool ignoreGravity, isForwarded;
}; State GetState() const;
} } State & GetState( State &targetMem ) const;
void SetState( const State &state );
btCollisionShape* GetCollisionShape() const;
btDefaultMotionState* GetMotionState() const;
btRigidBody* GetRigidBody() const;
void SetCustomTag( void *ref );
void* GetCustomTag() const;
private:
btCollisionShape* collisionShape;
btDefaultMotionState* motionState;
btRigidBody* rigidBody;
Struct::CustomBodyState state;
EventAction_AfterCollisionResponse afterCollision;
EventAction_Move onMovement;
void *customTag;
};
}
}
#endif #endif

View File

@ -1,405 +0,0 @@
#include "SphericalRigidBody.h"
#include "PhysicsAPI_Impl.h"
using namespace ::Oyster::Physics;
using namespace ::Oyster::Physics3D;
using namespace ::Oyster::Math3D;
using namespace ::Oyster::Collision3D;
using namespace ::Utility::DynamicMemory;
using namespace ::Utility::Value;
SphericalRigidBody::SphericalRigidBody()
{
this->rigid = RigidBody();
this->rigid.SetMass_KeepMomentum( 16.0f );
this->gravityNormal = Float3::null;
this->onCollision = Default::EventAction_BeforeCollisionResponse;
this->onCollisionResponse = Default::EventAction_AfterCollisionResponse;
this->onMovement = Default::EventAction_Move;
this->collisionRebound.previousSpatial.center = this->rigid.centerPos;
this->collisionRebound.previousSpatial.axis = this->rigid.axis;
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach;
this->collisionRebound.timeOfContact = 1.0f;
this->scene = nullptr;
this->customTag = nullptr;
this->ignoreGravity = this->isForwarded = false;
}
SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &desc )
{
this->rigid = RigidBody();
this->rigid.SetRotation( desc.rotation );
this->rigid.centerPos = desc.centerPosition;
this->rigid.boundingReach = Float4( desc.radius, desc.radius, desc.radius, 0.0f );
this->rigid.restitutionCoeff = desc.restitutionCoeff;
this->rigid.frictionCoeff_Static = desc.frictionCoeff_Static;
this->rigid.frictionCoeff_Kinetic = desc.frictionCoeff_Dynamic;
this->rigid.SetMass_KeepMomentum( desc.mass );
this->rigid.SetMomentOfInertia_KeepMomentum( MomentOfInertia::Sphere(desc.mass, desc.radius) );
this->deltaPos = Float4::null;
this->deltaAxis = Float4::null;
this->gravityNormal = Float3::null;
this->collisionRebound.previousSpatial.center = this->rigid.centerPos;
this->collisionRebound.previousSpatial.axis = this->rigid.axis;
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach;
this->collisionRebound.timeOfContact = 1.0f;
if( desc.subscription_onCollision )
{
this->onCollision = desc.subscription_onCollision;
}
else
{
this->onCollision = Default::EventAction_BeforeCollisionResponse;
}
if( desc.subscription_onCollisionResponse )
{
this->onCollisionResponse = desc.subscription_onCollisionResponse;
}
else
{
this->onCollisionResponse = Default::EventAction_AfterCollisionResponse;
}
if( desc.subscription_onMovement )
{
this->onMovement= desc.subscription_onMovement;
}
else
{
this->onMovement = Default::EventAction_Move;
}
this->scene = nullptr;
this->customTag = nullptr;
this->ignoreGravity = desc.ignoreGravity;
this->collisionRebound.previousSpatial.center = this->rigid.centerPos;
this->collisionRebound.previousSpatial.axis = this->rigid.axis;
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach;
this->collisionRebound.timeOfContact = 1.0f;
}
SphericalRigidBody::~SphericalRigidBody() {}
UniquePointer<ICustomBody> SphericalRigidBody::Clone() const
{
return new SphericalRigidBody( *this );
}
SphericalRigidBody::State SphericalRigidBody::GetState() const
{
return State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
this->rigid.GetMomentOfInertia(), this->rigid.boundingReach,
this->rigid.centerPos, this->rigid.axis,
this->rigid.momentum_Linear, this->rigid.momentum_Angular );
}
SphericalRigidBody::State & SphericalRigidBody::GetState( SphericalRigidBody::State &targetMem ) const
{
return targetMem = State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
this->rigid.GetMomentOfInertia(), this->rigid.boundingReach,
this->rigid.centerPos, this->rigid.axis,
this->rigid.momentum_Linear, this->rigid.momentum_Angular );
}
void SphericalRigidBody::SetState( const SphericalRigidBody::State &state )
{
this->rigid.centerPos = state.GetCenterPosition();
this->rigid.axis = state.GetAngularAxis();
this->rigid.boundingReach = state.GetReach();
this->rigid.momentum_Linear = state.GetLinearMomentum();
this->rigid.momentum_Angular = state.GetAngularMomentum();
this->rigid.impulse_Linear += state.GetLinearImpulse();
this->rigid.impulse_Angular += state.GetAngularImpulse();
this->rigid.restitutionCoeff = state.GetRestitutionCoeff();
this->rigid.frictionCoeff_Static = state.GetFrictionCoeff_Static();
this->rigid.frictionCoeff_Kinetic = state.GetFrictionCoeff_Kinetic();
this->rigid.SetMass_KeepMomentum( state.GetMass() );
this->rigid.SetMomentOfInertia_KeepMomentum( state.GetMomentOfInertia() );
this->rigid.gravityNormal = state.GetGravityNormal();
if( state.IsForwarded() )
{
this->deltaPos += Float4(state.GetForward_DeltaPos(), 0);
this->deltaAxis += Float4(state.GetForward_DeltaAxis());
this->isForwarded = false;
}
if( this->scene )
{
if( state.IsSpatiallyAltered() )
{
unsigned int tempRef = this->scene->GetTemporaryReferenceOf( this );
this->scene->SetAsAltered( tempRef );
this->scene->EvaluatePosition( tempRef );
}
else if( state.IsDisturbed() )
{
this->scene->SetAsAltered( this->scene->GetTemporaryReferenceOf(this) );
}
}
}
ICustomBody::SubscriptMessage SphericalRigidBody::CallSubscription_BeforeCollisionResponse( const ICustomBody *deuter )
{
return this->onCollision( this, deuter );
}
void SphericalRigidBody::CallSubscription_AfterCollisionResponse( const ICustomBody *deuter, Float kineticEnergyLoss )
{
this->onCollisionResponse( this, deuter, kineticEnergyLoss);
}
void SphericalRigidBody::CallSubscription_Move()
{
this->onMovement( this );
}
bool SphericalRigidBody::IsAffectedByGravity() const
{
return !this->ignoreGravity;
}
bool SphericalRigidBody::Intersects( const ICollideable &shape ) const
{
return Sphere( this->rigid.centerPos, this->rigid.boundingReach.x ).Intersects( shape );
}
bool SphericalRigidBody::Intersects( const ICollideable &shape, Float4 &worldPointOfContact ) const
{
return Sphere( this->rigid.centerPos, this->rigid.boundingReach.x ).Intersects( shape, worldPointOfContact );
}
bool SphericalRigidBody::Intersects( const ICustomBody &object, Float4 &worldPointOfContact ) const
{
return object.Intersects( Sphere(this->rigid.centerPos, this->rigid.boundingReach.x), worldPointOfContact );
}
void SphericalRigidBody::SetTimeOfContact( Float4 &worldPointOfContact )
{
Point pointOfContact = Point( worldPointOfContact );
Sphere start = Sphere( this->collisionRebound.previousSpatial.center, this->collisionRebound.previousSpatial.reach.x );
Sphere end = Sphere( this->rigid.centerPos, this->rigid.boundingReach.x );
Float timeOfContact = ::Oyster::Collision3D::Utility::TimeOfContact( start, end, pointOfContact );
this->collisionRebound.timeOfContact = Min( this->collisionRebound.timeOfContact, timeOfContact );
}
Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
{
return targetMem = Sphere( this->rigid.centerPos, this->rigid.boundingReach.x );
}
Float4 & SphericalRigidBody::GetNormalAt( const Float4 &worldPos, Float4 &targetMem ) const
{
targetMem = Float4( worldPos.xyz - this->rigid.centerPos, 0);
Float magnitude = targetMem.GetMagnitude();
if( magnitude != 0.0f )
{ // sanity check
targetMem.Normalize();
}
return targetMem;
}
Float3 & SphericalRigidBody::GetGravityNormal( Float3 &targetMem ) const
{
return targetMem = this->gravityNormal;
}
void * SphericalRigidBody::GetCustomTag() const
{
return this->customTag;
}
//Float3 & SphericalRigidBody::GetCenter( Float3 &targetMem ) const
//{
// return targetMem = this->rigid.centerPos;
//}
//
//Float4x4 & SphericalRigidBody::GetRotation( Float4x4 &targetMem ) const
//{
// return targetMem = this->rigid.box.rotation;
//}
//
//Float4x4 & SphericalRigidBody::GetOrientation( Float4x4 &targetMem ) const
//{
// return targetMem = this->rigid.GetOrientation();
//}
//
//Float4x4 & SphericalRigidBody::GetView( Float4x4 &targetMem ) const
//{
// return targetMem = this->rigid.GetView();
//}
//Float3 SphericalRigidBody::GetRigidLinearVelocity() const
//{
// return this->rigid.GetLinearVelocity();
//}
UpdateState SphericalRigidBody::Update( Float timeStepLength )
{
if( this->collisionRebound.timeOfContact < 1.0f )
{ // Rebound if needed
this->rigid.centerPos = Lerp( this->collisionRebound.previousSpatial.center, this->rigid.centerPos, this->collisionRebound.timeOfContact );
this->rigid.SetRotation( Lerp(this->collisionRebound.previousSpatial.axis, this->rigid.axis, this->collisionRebound.timeOfContact) );
this->rigid.boundingReach = Lerp( this->collisionRebound.previousSpatial.reach, this->rigid.boundingReach, this->collisionRebound.timeOfContact );
timeStepLength *= 2.0f - this->collisionRebound.timeOfContact; // compensate for rebounded time
this->collisionRebound.timeOfContact = 1.0f;
}
// Maintain rotation resolution by keeping axis within [0, 2pi] (trigonometric methods gets faster too)
Float4 temp;
::std::modf( this->rigid.axis * (0.5f / pi), temp.xyz );
this->rigid.axis -= ((2.0f * pi) * temp).xyz;
// Update rebound data
this->collisionRebound.previousSpatial.center = this->rigid.centerPos;
this->collisionRebound.previousSpatial.axis = this->rigid.axis;
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach;
// Check if this is close enough to be set resting
temp = Float4( this->rigid.impulse_Linear, 0.0f ) + Float4( this->rigid.impulse_Angular, 0.0f );
if( temp.Dot(temp) <= (Constant::epsilon * Constant::epsilon) )
{
unsigned char resting = 0;
if( this->rigid.momentum_Linear.Dot(this->rigid.momentum_Linear) <= (Constant::epsilon * Constant::epsilon) )
{
this->rigid.momentum_Linear = Float3::null;
resting = 1;
}
if( this->rigid.momentum_Angular.Dot(this->rigid.momentum_Angular) <= (Constant::epsilon * Constant::epsilon) )
{
this->rigid.momentum_Angular = Float3::null;
++resting;
}
if( resting == 2 )
{
this->rigid.impulse_Linear = this->rigid.impulse_Angular = Float3::null;
return UpdateState_resting;
}
}
this->rigid.Update_LeapFrog( timeStepLength );
return UpdateState_altered;
}
void SphericalRigidBody::Predict( ::Oyster::Math::Float4 &outDeltaPos, ::Oyster::Math::Float4 &outDeltaAxis, const ::Oyster::Math::Float4 &actingLinearImpulse, const ::Oyster::Math::Float4 &actingAngularImpulse, ::Oyster::Math::Float deltaTime )
{
this->rigid.Predict_LeapFrog( outDeltaPos.xyz, outDeltaAxis.xyz, actingLinearImpulse.xyz, actingAngularImpulse.xyz, deltaTime );
}
void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_BeforeCollisionResponse functionPointer )
{
if( functionPointer )
{
this->onCollision = functionPointer;
}
else
{
this->onCollision = Default::EventAction_BeforeCollisionResponse;
}
}
void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_AfterCollisionResponse functionPointer )
{
if( functionPointer )
{
this->onCollisionResponse = functionPointer;
}
else
{
this->onCollisionResponse = Default::EventAction_AfterCollisionResponse;
}
}
void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_Move functionPointer )
{
if( functionPointer )
{
this->onMovement = functionPointer;
}
else
{
this->onMovement = Default::EventAction_Move;
}
}
void SphericalRigidBody::SetScene( void *scene )
{
this->scene = (Octree*)scene;
}
void SphericalRigidBody::SetGravity( bool ignore )
{
this->ignoreGravity = ignore;
this->gravityNormal = Float3::null;
}
void SphericalRigidBody::SetGravityNormal( const Float3 &normalizedVector )
{
this->gravityNormal = normalizedVector;
}
void SphericalRigidBody::SetCustomTag( void *ref )
{
this->customTag = ref;
}
//void SphericalRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
//{
// this->rigid.SetMomentOfInertia_KeepVelocity( localI );
//}
//
//void SphericalRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI )
//{
// this->rigid.SetMomentOfInertia_KeepMomentum( localI );
//}
//
//void SphericalRigidBody::SetMass_KeepVelocity( Float m )
//{
// this->rigid.SetMass_KeepVelocity( m );
//}
//
//void SphericalRigidBody::SetMass_KeepMomentum( Float m )
//{
// this->rigid.SetMass_KeepMomentum( m );
//}
//
//void SphericalRigidBody::SetCenter( const Float3 &worldPos )
//{
// this->rigid.SetCenter( worldPos );
// this->body.center = worldPos;
//}
//
//void SphericalRigidBody::SetRotation( const Float4x4 &rotation )
//{
// this->rigid.SetRotation( rotation );
//}
//
//void SphericalRigidBody::SetOrientation( const Float4x4 &orientation )
//{
// this->rigid.SetOrientation( orientation );
// this->body.center = orientation.v[3].xyz;
//}
//
//void SphericalRigidBody::SetSize( const Float3 &size )
//{
// this->rigid.SetSize( size );
// this->body.radius = 0.5f * Min( Min( size.x, size.y ), size.z ); // inline Min( FloatN )?
//}
//
//void SphericalRigidBody::SetMomentum( const Float3 &worldG )
//{
// this->rigid.SetLinearMomentum( worldG );
//}

View File

@ -1,87 +0,0 @@
#ifndef OYSTER_PHYSICS_SPHERICAL_RIGIDBODY_H
#define OYSTER_PHYSICS_SPHERICAL_RIGIDBODY_H
#include "..\PhysicsAPI.h"
#include "RigidBody.h"
#include "Sphere.h"
#include "Octree.h"
namespace Oyster { namespace Physics
{
class SphericalRigidBody : public ICustomBody
{
public:
SphericalRigidBody();
SphericalRigidBody( const API::SphericalBodyDescription &desc );
virtual ~SphericalRigidBody();
::Utility::DynamicMemory::UniquePointer<ICustomBody> Clone() const;
State GetState() const;
State & GetState( State &targetMem = State() ) const;
void SetState( const State &state );
//::Oyster::Math::Float3 GetRigidLinearVelocity() const;
SubscriptMessage CallSubscription_BeforeCollisionResponse( const ICustomBody *deuter );
void CallSubscription_AfterCollisionResponse( const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss );
void CallSubscription_Move();
bool IsAffectedByGravity() const;
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const;
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const;
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const;
void SetTimeOfContact( ::Oyster::Math::Float4 &worldPointOfContact );
::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) const;
::Oyster::Math::Float4 & GetNormalAt( const ::Oyster::Math::Float4 &worldPos, ::Oyster::Math::Float4 &targetMem = ::Oyster::Math::Float4() ) const;
::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
void * GetCustomTag() const;
//::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
//::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
//::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
//::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
UpdateState Update( ::Oyster::Math::Float timeStepLength );
void Predict( ::Oyster::Math::Float4 &outDeltaPos, ::Oyster::Math::Float4 &outDeltaAxis, const ::Oyster::Math::Float4 &actingLinearImpulse, const ::Oyster::Math::Float4 &actingAngularImpulse, ::Oyster::Math::Float deltaTime );
void SetScene( void *scene );
void SetSubscription( EventAction_BeforeCollisionResponse functionPointer );
void SetSubscription( EventAction_AfterCollisionResponse functionPointer );
void SetSubscription( EventAction_Move functionPointer );
void SetGravity( bool ignore);
void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector );
void SetCustomTag( void *ref );
//void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
//void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
//void SetMass_KeepVelocity( ::Oyster::Math::Float m );
//void SetMass_KeepMomentum( ::Oyster::Math::Float m );
//void SetCenter( const ::Oyster::Math::Float3 &worldPos );
//void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
//void SetOrientation( const ::Oyster::Math::Float4x4 &orientation );
//void SetSize( const ::Oyster::Math::Float3 &size );
//void SetMomentum( const ::Oyster::Math::Float3 &worldG );
private:
::Oyster::Physics3D::RigidBody rigid;
::Oyster::Math::Float4 deltaPos, deltaAxis;
::Oyster::Math::Float3 gravityNormal;
struct
{
struct { ::Oyster::Math::Float3 center, axis, reach; } previousSpatial;
::Oyster::Math::Float timeOfContact;
} collisionRebound;
EventAction_BeforeCollisionResponse onCollision;
EventAction_AfterCollisionResponse onCollisionResponse;
EventAction_Move onMovement;
Octree *scene;
void *customTag;
bool ignoreGravity, isForwarded;
};
} }
#endif

View File

@ -55,35 +55,7 @@ namespace Oyster
* @param numGravityWells: The predicted max number of active gravity wells. * @param numGravityWells: The predicted max number of active gravity wells.
* @param worldSize: The size of acceptable physics space. * @param worldSize: The size of acceptable physics space.
********************************************************/ ********************************************************/
virtual void Init( unsigned int numObjects, unsigned int numGravityWells , const ::Oyster::Math::Float3 &worldSize ) = 0; virtual void Init() = 0;
/********************************************************
* Sets the time length of each physics update frame.
********************************************************/
virtual void SetFrameTimeLength( float seconds ) = 0;
/********************************************************
* Sets the Gravityconstant in the physics that will be
* used in ForceField calculations.
* @param g: Default is the real world Constant::gravity_constant [N(m/kg)^2]
********************************************************/
virtual void SetGravityConstant( float g ) = 0;
/********************************************************
* Sets the function that will be called by the engine
* whenever an object is being destroyed for some reason.
* - Because DestroyObject(...) were called.
* - Out of memory forced engine to destroy an object.
* @param functionPointer: If NULL, an empty default function will be set.
********************************************************/
virtual void SetSubscription( EventAction_Destruction functionPointer ) = 0;
/********************************************************
* Triggers the engine to run next update frame.
* All accumulated forces and changes will be consumed.
* EventAction functions might be called.
********************************************************/
virtual void Update() = 0;
/******************************************************** /********************************************************
* An object in limbo state will be ignored during the physics frame Update. * An object in limbo state will be ignored during the physics frame Update.
@ -106,36 +78,15 @@ namespace Oyster
********************************************************/ ********************************************************/
virtual void ReleaseFromLimbo( const ICustomBody* objRef ) = 0; virtual void ReleaseFromLimbo( const ICustomBody* objRef ) = 0;
/********************************************************
* Introduces a new object into the engine.
* @param handle: A pointer along with the responsibility to delete.
********************************************************/
virtual void AddObject( ::Utility::DynamicMemory::UniquePointer<ICustomBody> handle ) = 0;
/******************************************************** // Bullet physics
* Fetches and removes an object from the engine. virtual ICustomBody* AddCollisionSphere(float radius, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass) = 0;
* Will not call the provided EventAction_Destruction method.
* @param objRef: A pointer to the ICustomBody representing a physical object.
* @return A pointer along with the responsibility to delete. NULL if faulty objRef.
********************************************************/
virtual ::Utility::DynamicMemory::UniquePointer<ICustomBody> ExtractObject( const ICustomBody* objRef ) = 0;
/******************************************************** virtual ICustomBody* AddCollisionBox(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass) = 0;
* Removes an object from the engine.
* Will call the provided EventAction_Destruction method. Not if objRef is faulty. virtual void UpdateWorld() = 0;
* @param objRef: A pointer to the ICustomBody representing a physical object.
********************************************************/
virtual void DestroyObject( const ICustomBody* objRef ) = 0;
/********************************************************
* TODO: @todo doc
********************************************************/
virtual void AddGravity( const API::Gravity &g ) = 0;
/********************************************************
* TODO: @todo doc
********************************************************/
virtual void RemoveGravity( const API::Gravity &g ) = 0;
/******************************************************** /********************************************************
* Applies an effect to objects that collide with the set volume. * Applies an effect to objects that collide with the set volume.
@ -146,88 +97,6 @@ namespace Oyster
********************************************************/ ********************************************************/
virtual void ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void* args, void(hitAction)(ICustomBody*, void*) ) = 0; virtual void ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void* args, void(hitAction)(ICustomBody*, void*) ) = 0;
///********************************************************
// * Apply force on an object.
// * @param objRef: A pointer to the ICustomBody representing a physical object.
// * @param worldPos: Relative to the world origo. (Not relative to object) [m]
// * @param worldF: Vector with the direction and magnitude of the force. [N]
// ********************************************************/
//virtual void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF ) = 0;
///********************************************************
// * Sets the MomentOfInertia tensor matrix of an object without changing it's angular velocity.
// * Noticeable effect: The angular momentum will change. Changing the amount of kinetic energy.
// * @param objRef: A pointer to the ICustomBody representing a physical object.
// * @param localI: The tensor matrix relative to the axises of the object. @see MomentOfInertia namespace.
// ********************************************************/
//virtual void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI ) = 0;
//
///********************************************************
// * Sets the MomentOfInertia tensor matrix of an object without changing it's angular momentum.
// * Noticeable effect: The angular velocity will change. Can be used to create slow effects.
// * @param objRef: A pointer to the ICustomBody representing a physical object.
// * @param localI: The tensor matrix relative to the axises of the object. @see MomentOfInertia namespace.
// ********************************************************/
//virtual void SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI ) = 0;
//
///********************************************************
// * Sets the mass of an object without changing it's linear velocity.
// * Noticeable effect: The linear momentum will change. Changing the amount of kinetic energy.
// * @param objRef: A pointer to the ICustomBody representing a physical object.
// * @param m: [kg]
// ********************************************************/
//virtual void SetMass_KeepVelocity( const ICustomBody* objRef, ::Oyster::Math::Float m ) = 0;
//
///********************************************************
// * Sets the mass of an object without changing it's linear velocity.
// * Noticeable effect: The linear velocity will change. Can be used to create slow effects.
// * @param objRef: A pointer to the ICustomBody representing a physical object.
// * @param m: [kg]
// ********************************************************/
//virtual void SetMass_KeepMomentum( const ICustomBody* objRef, ::Oyster::Math::Float m ) = 0;
//
///********************************************************
// * Instantly moves an object.
// * @param objRef: A pointer to the ICustomBody representing a physical object.
// * @param worldPos: Relative to the world origo. (Not relative to object) [m]
// ********************************************************/
//virtual void SetCenter( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos ) = 0;
//
///********************************************************
// * Instantly redirects object.
// * @param objRef: A pointer to the ICustomBody representing a physical object.
// * @param rotation: New rotation.
// ********************************************************/
//virtual void SetRotation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &rotation ) = 0;
//
///********************************************************
// * Instantly moves and redirects object.
// * @param objRef: A pointer to the ICustomBody representing a physical object.
// * @param orientation: New orientation.
// ********************************************************/
//virtual void SetOrientation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &orientation ) = 0;
//
///********************************************************
// * Resizes the boundingBox.
// * @param objRef: A pointer to the ICustomBody representing a physical object.
// * @param size: New size of this [m]
// ********************************************************/
//virtual void SetSize( const ICustomBody* objRef, const ::Oyster::Math::Float3 &size ) = 0;
/********************************************************
* Creates a new dynamically allocated object that can be used as a component for more complex ICustomBodies.
* @param desc: @see API::SimpleBodyDescription
* @return A pointer along with the responsibility to delete.
********************************************************/
virtual ::Utility::DynamicMemory::UniquePointer<ICustomBody> CreateRigidBody( const SimpleBodyDescription &desc ) const = 0;
/********************************************************
* Creates a new dynamically allocated object that can be used as a component for more complex ICustomBodies.
* @param desc: @see API::SphericalBodyDescription
* @return A pointer along with the responsibility to delete.
********************************************************/
virtual ::Utility::DynamicMemory::UniquePointer<ICustomBody> CreateRigidBody( const SphericalBodyDescription &desc ) const = 0;
protected: protected:
virtual ~API() {} virtual ~API() {}
}; };
@ -246,190 +115,41 @@ namespace Oyster
SubscriptMessage_player_collision_response SubscriptMessage_player_collision_response
}; };
typedef SubscriptMessage (*EventAction_BeforeCollisionResponse)( const ICustomBody *proto, const ICustomBody *deuter ); typedef SubscriptMessage (*EventAction_BeforeCollisionResponse)( const ICustomBody *proto, const ICustomBody *deuter );
typedef void (*EventAction_AfterCollisionResponse)( const ICustomBody *proto, const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ); typedef void (*EventAction_AfterCollisionResponse)( const ICustomBody *proto, const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss );
typedef void (*EventAction_Move)( const ICustomBody *object ); typedef void (*EventAction_Move)( const ICustomBody *object );
typedef Struct::SimpleBodyDescription SimpleBodyDescription;
typedef Struct::SphericalBodyDescription SphericalBodyDescription;
typedef Struct::CustomBodyState State; typedef Struct::CustomBodyState State;
virtual ~ICustomBody() {}; virtual ~ICustomBody() {};
/******************************************************** /********************************************************
* Creates a complete copy of the current (type)object. * Gets the current state of the rigid body
* @return An ICustomBody pointer along with the responsibility to delete. * @return the current state of the rigid body
********************************************************/
virtual ::Utility::DynamicMemory::UniquePointer<ICustomBody> Clone() const = 0;
/********************************************************
* @todo TODO: need doc
********************************************************/
virtual SubscriptMessage CallSubscription_BeforeCollisionResponse( const ICustomBody *deuter ) = 0;
/********************************************************
* @todo TODO: need doc
********************************************************/
virtual void CallSubscription_AfterCollisionResponse( const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ) = 0;
/********************************************************
* @todo TODO: need doc
********************************************************/
virtual void CallSubscription_Move() = 0;
/********************************************************
* @todo TODO: need doc
********************************************************/ ********************************************************/
virtual State GetState() const = 0; virtual State GetState() const = 0;
/******************************************************** /********************************************************
* @todo TODO: need doc * Gets the current state of the rigid body
* @param targetMem: The state is copied into targetMem
* @return the current state of the rigid body
********************************************************/ ********************************************************/
virtual State & GetState( State &targetMem ) const = 0; virtual State & GetState( State &targetMem ) const = 0;
/******************************************************** /********************************************************
* @return the linear velocity of the rigid body in a vector. * Sets the current state of the rigid body
********************************************************/ ********************************************************/
//virtual Math::Float3 GetRigidLinearVelocity() const = 0; virtual void SetState( const State &state ) = 0;
/******************************************************** virtual void SetSubscription(EventAction_AfterCollisionResponse function) = 0;
* @todo TODO: need doc virtual void SetSubscription(EventAction_Move function) = 0;
********************************************************/
virtual void SetState( const State &state ) = 0;
/********************************************************
* @return true if Engine should apply gravity on this object.
********************************************************/
virtual bool IsAffectedByGravity() const = 0;
/********************************************************
* param shape: Any defined sample shape.
* @return true if this truly intersects with shape.
********************************************************/
virtual bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const = 0;
/********************************************************
* Performs a detailed Intersect test and returns if, when and where.
* @param shape: Any defined sample shape.
* @param worldPointOfContact: Where at timeOfContact, this and object touches eachother.
* @return true if this truly intersects with object.
********************************************************/
virtual bool Intersects( const ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const = 0;
/********************************************************
* Performs a detailed Intersect test and returns if, when and where.
* @param object: What this is intersect testing against.
* @param worldPointOfContact: Where at timeOfContact, this and object touches eachother.
* @return true if this truly intersects with object.
********************************************************/
virtual bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const = 0;
/********************************************************
* Sets how far back it needs to be interpolated to not be overlapping worldPointOfContact.
********************************************************/
virtual void SetTimeOfContact( ::Oyster::Math::Float4 &worldPointOfContact ) = 0;
/********************************************************
* Required by Engine's Collision Search.
* @param targetMem: Provided memory that written into and then returned.
* @return a sphere shape that contains the ICustomBody.
********************************************************/
virtual ::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) const = 0;
/********************************************************
* Required by Engine's Collision Responsing.
* @param worldPos: Should be worldPointOfContact from Intersects( ... )
* @param targetMem: Provided memory that written into and then returned.
* @return a surface normal in worldSpace.
********************************************************/
virtual ::Oyster::Math::Float4 & GetNormalAt( const ::Oyster::Math::Float4 &worldPos, ::Oyster::Math::Float4 &targetMem = ::Oyster::Math::Float4() ) const = 0;
/********************************************************
* The gravity normal will have same direction as the total gravity force pulling on this and have the magnitude of 1.0f.
* @param targetMem: Provided memory that written into and then returned.
* @return a normalized vector in worldSpace. Exception: Null vector if no gravity been applied.
********************************************************/
virtual ::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0;
/******************************************************** /********************************************************
* @return the void pointer set by SetCustomTag. * @return the void pointer set by SetCustomTag.
* nullptr if none is set. * nullptr if none is set.
********************************************************/ ********************************************************/
virtual void * GetCustomTag() const = 0; virtual void* GetCustomTag() const = 0;
///********************************************************
// * The world position of this center of gravity.
// * @param targetMem: Provided memory that written into and then returned.
// * @return a position in worldSpace.
// ********************************************************/
//virtual ::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0;
//
///********************************************************
// * @param targetMem: Provided memory that written into and then returned.
// * @return a copy of this's rotation matrix.
// ********************************************************/
//virtual ::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
//
///********************************************************
// * @param targetMem: Provided memory that written into and then returned.
// * @return a copy of this's orientation matrix.
// ********************************************************/
//virtual ::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
//
///********************************************************
// * @param targetMem: Provided memory that written into and then returned.
// * @return a copy of this's view matrix.
// ********************************************************/
//virtual ::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
/********************************************************
* To not be called if is in Engine
* Is called during API::Update
********************************************************/
virtual UpdateState Update( ::Oyster::Math::Float timeStepLength ) = 0;
/********************************************************
* @todo TODO: add doc
********************************************************/
virtual void Predict( ::Oyster::Math::Float4 &outDeltaPos, ::Oyster::Math::Float4 &outDeltaAxis, const ::Oyster::Math::Float4 &actingLinearImpulse, const ::Oyster::Math::Float4 &actingAngularImpulse, ::Oyster::Math::Float deltaTime ) = 0;
/********************************************************
* Sets which scene this ICustomBody is within.
* Reserved to only be used by the scene.
* @todo TODO: create an IScene interface
********************************************************/
virtual void SetScene( void *scene ) = 0;
/********************************************************
* Sets the function that will be called by the engine
* whenever a collision occurs.
* @param functionPointer: If NULL, an empty default function will be set.
********************************************************/
virtual void SetSubscription( EventAction_BeforeCollisionResponse functionPointer ) = 0;
/********************************************************
* Sets the function that will be called by the engine
* whenever a collision has finished.
* @param functionPointer: If NULL, an empty default function will be set.
********************************************************/
virtual void SetSubscription( EventAction_AfterCollisionResponse functionPointer ) = 0;
/********************************************************
* Sets the function that will be called by the engine
* whenever an object have moved.
* @param functionPointer: If NULL, an empty default function will be set.
********************************************************/
virtual void SetSubscription( EventAction_Move functionPointer ) = 0;
/********************************************************
* @param ignore: True if Engine should not apply Gravity.
********************************************************/
virtual void SetGravity( bool ignore) = 0;
/********************************************************
* Used by Engine
* @param normalizedVector: Should have same direction as the pullinggravity.
********************************************************/
virtual void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector ) = 0;
/******************************************************** /********************************************************
* Not used by the engine itself. Just a quality of life feature * Not used by the engine itself. Just a quality of life feature
@ -437,60 +157,6 @@ namespace Oyster
* @param ref: Anything castable to a void pointer, the engine won't care. * @param ref: Anything castable to a void pointer, the engine won't care.
********************************************************/ ********************************************************/
virtual void SetCustomTag( void *ref ) = 0; virtual void SetCustomTag( void *ref ) = 0;
///********************************************************
// * To not be called if is in Engine
// * Use API::SetMomentOfInertiaTensor_KeepVelocity(...) instead
// ********************************************************/
//virtual void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI ) = 0;
//
///********************************************************
// * To not be called if is in Engine
// * Use API::SetMomentOfInertiaTensor_KeepMomentum(...)
// ********************************************************/
//virtual void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI ) = 0;
//
///********************************************************
// * To not be called if is in Engine
// * Use API::SetMass_KeepVelocity(...)
// ********************************************************/
//virtual void SetMass_KeepVelocity( ::Oyster::Math::Float m ) = 0;
//
///********************************************************
// * To not be called if is in Engine
// * Use API::SetMass_KeepMomentum(...)
// ********************************************************/
//virtual void SetMass_KeepMomentum( ::Oyster::Math::Float m ) = 0;
//
///********************************************************
// * To not be called if is in Engine
// * Use API::SetCenter(...)
// ********************************************************/
//virtual void SetCenter( const ::Oyster::Math::Float3 &worldPos ) = 0;
//
///********************************************************
// * To not be called if is in Engine
// * Use API::SetRotation(...)
// ********************************************************/
//virtual void SetRotation( const ::Oyster::Math::Float4x4 &rotation ) = 0;
//
///********************************************************
// * To not be called if is in Engine
// * Use API::SetOrientation(...)
// ********************************************************/
//virtual void SetOrientation( const ::Oyster::Math::Float4x4 &orientation ) = 0;
///********************************************************
// * To not be called if is in Engine
// * Use API::SetSize(...)
// ********************************************************/
//virtual void SetSize( const ::Oyster::Math::Float3 &size ) = 0;
///********************************************************
// * To not be called if is in Engine
// * Use API::?? @todo TODO:
// ********************************************************/
//virtual void SetMomentum( const ::Oyster::Math::Float3 &worldG ) = 0;
}; };
} }
} }

View File

@ -10,53 +10,14 @@ namespace Oyster
{ {
namespace Struct namespace Struct
{ {
inline SimpleBodyDescription::SimpleBodyDescription() inline CustomBodyState::CustomBodyState( ::Oyster::Math::Float mass, ::Oyster::Math::Float restitutionCoeff, ::Oyster::Math::Float staticFrictionCoeff, ::Oyster::Math::Float dynamicFrictionCoeff, const ::Oyster::Math::Float3 &centerPos, const ::Oyster::Math::Quaternion& quaternion)
{
this->rotation = ::Oyster::Math::Float3::null;
this->centerPosition = ::Oyster::Math::Float3::null;
this->size = ::Oyster::Math::Float3( 1.0f );
this->mass = 6.0f;
this->restitutionCoeff = 1.0f;
this->frictionCoeff_Dynamic = 0.5f;
this->frictionCoeff_Static = 0.5f;
this->inertiaTensor = ::Oyster::Physics3D::MomentOfInertia();
this->subscription_onCollision = NULL;
this->subscription_onCollisionResponse = NULL;
this->subscription_onMovement = NULL;
this->ignoreGravity = false;
}
inline SphericalBodyDescription::SphericalBodyDescription()
{
this->rotation = ::Oyster::Math::Float3::null;
this->centerPosition = ::Oyster::Math::Float3::null;
this->radius = 0.5f;
this->mass = 10.0f;
this->restitutionCoeff = 1.0f;
this->frictionCoeff_Dynamic = 0.5f;
this->frictionCoeff_Static = 0.5f;
this->subscription_onCollision = NULL;
this->subscription_onCollisionResponse = NULL;
this->subscription_onMovement = NULL;
this->ignoreGravity = false;
}
inline CustomBodyState::CustomBodyState( ::Oyster::Math::Float mass, ::Oyster::Math::Float restitutionCoeff, ::Oyster::Math::Float staticFrictionCoeff, ::Oyster::Math::Float kineticFrictionCoeff, const ::Oyster::Physics3D::MomentOfInertia &inertiaTensor, const ::Oyster::Math::Float3 &reach, const ::Oyster::Math::Float3 &centerPos, const ::Oyster::Math::Float3 &rotation, const ::Oyster::Math::Float3 &linearMomentum, const ::Oyster::Math::Float3 &angularMomentum, const ::Oyster::Math::Float3 &gravityNormal )
{ {
this->mass = mass; this->mass = mass;
this->restitutionCoeff = restitutionCoeff; this->restitutionCoeff = restitutionCoeff;
this->staticFrictionCoeff = staticFrictionCoeff; this->staticFrictionCoeff = staticFrictionCoeff;
this->kineticFrictionCoeff = kineticFrictionCoeff; this->dynamicFrictionCoeff = dynamicFrictionCoeff;
this->inertiaTensor = inertiaTensor;
this->reach = reach;
this->centerPos = centerPos; this->centerPos = centerPos;
this->angularAxis = rotation; this->quaternion = quaternion;
this->linearMomentum = linearMomentum;
this->angularMomentum = angularMomentum;
this->linearImpulse = this->angularImpulse = ::Oyster::Math::Float3::null;
this->deltaPos = this->deltaAxis = ::Oyster::Math::Float3::null;
this->isSpatiallyAltered = this->isDisturbed = this->isForwarded = false;
this->gravityNormal = gravityNormal;
} }
inline CustomBodyState & CustomBodyState::operator = ( const CustomBodyState &state ) inline CustomBodyState & CustomBodyState::operator = ( const CustomBodyState &state )
@ -64,489 +25,34 @@ namespace Oyster
this->mass = state.mass; this->mass = state.mass;
this->restitutionCoeff = state.restitutionCoeff; this->restitutionCoeff = state.restitutionCoeff;
this->staticFrictionCoeff = state.staticFrictionCoeff; this->staticFrictionCoeff = state.staticFrictionCoeff;
this->kineticFrictionCoeff = state.kineticFrictionCoeff; this->dynamicFrictionCoeff = state.dynamicFrictionCoeff;
this->inertiaTensor = state.inertiaTensor;
this->reach = state.reach;
this->centerPos = state.centerPos; this->centerPos = state.centerPos;
this->angularAxis = state.angularAxis; this->quaternion = state.quaternion;
this->linearMomentum = state.linearMomentum;
this->angularMomentum = state.angularMomentum;
this->linearImpulse = state.linearImpulse;
this->angularImpulse = state.angularImpulse;
this->deltaPos = state.deltaPos;
this->deltaAxis = state.deltaAxis;
this->isSpatiallyAltered = state.isSpatiallyAltered;
this->isDisturbed = state.isDisturbed;
this->isForwarded = state.isForwarded;
this->gravityNormal = state.gravityNormal;
return *this; return *this;
} }
inline const ::Oyster::Math::Float CustomBodyState::GetMass() const
{
return this->mass;
}
inline const ::Oyster::Math::Float CustomBodyState::GetRestitutionCoeff() const
{
return this->restitutionCoeff;
}
inline const ::Oyster::Math::Float CustomBodyState::GetFrictionCoeff_Static() const
{
return this->staticFrictionCoeff;
}
inline const ::Oyster::Math::Float CustomBodyState::GetFrictionCoeff_Kinetic() const
{
return this->kineticFrictionCoeff;
}
inline const ::Oyster::Physics3D::MomentOfInertia & CustomBodyState::GetMomentOfInertia() const
{
return this->inertiaTensor;
}
inline const ::Oyster::Math::Float3 & CustomBodyState::GetReach() const
{
return this->reach;
}
inline ::Oyster::Math::Float3 CustomBodyState::GetSize() const
{
return 2.0f * this->GetReach();
}
inline const ::Oyster::Math::Float3 & CustomBodyState::GetCenterPosition() const
{
return this->centerPos;
}
inline const ::Oyster::Math::Float3 & CustomBodyState::GetAngularAxis() const
{
return this->angularAxis;
}
inline ::Oyster::Math::Float4x4 CustomBodyState::GetRotation() const inline ::Oyster::Math::Float4x4 CustomBodyState::GetRotation() const
{ {
return ::Oyster::Math3D::RotationMatrix( this->GetAngularAxis() ); return ::Oyster::Math3D::RotationMatrix( this->quaternion );
} }
inline ::Oyster::Math::Float4x4 CustomBodyState::GetOrientation() const inline ::Oyster::Math::Float4x4 CustomBodyState::GetOrientation() const
{ {
return ::Oyster::Math3D::OrientationMatrix( this->angularAxis, this->centerPos ); return ::Oyster::Math3D::OrientationMatrix( this->quaternion, this->centerPos );
}
inline ::Oyster::Math::Float4x4 CustomBodyState::GetOrientation( const ::Oyster::Math::Float3 &offset ) const
{
return ::Oyster::Math3D::OrientationMatrix( this->angularAxis, (this->centerPos + offset) );
} }
inline ::Oyster::Math::Float4x4 CustomBodyState::GetView() const inline ::Oyster::Math::Float4x4 CustomBodyState::GetView() const
{ {
return ::Oyster::Math3D::ViewMatrix( this->angularAxis, this->centerPos ); return ::Oyster::Math3D::ViewMatrix( this->quaternion, this->centerPos );
} }
inline ::Oyster::Math::Float4x4 CustomBodyState::GetView( const ::Oyster::Math::Float3 &offset ) const inline ::Oyster::Math::Float4x4 CustomBodyState::GetView( const ::Oyster::Math::Float3 &offset ) const
{ {
return ::Oyster::Math3D::ViewMatrix( this->angularAxis, (this->centerPos + offset) ); return ::Oyster::Math3D::ViewMatrix( this->quaternion, (this->centerPos + offset) );
} }
inline const ::Oyster::Math::Float3 & CustomBodyState::GetLinearMomentum() const
{
return this->linearMomentum;
}
inline ::Oyster::Math::Float3 CustomBodyState::GetLinearMomentum( const ::Oyster::Math::Float3 &at ) const
{
::Oyster::Math::Float3 offset = at - this->centerPos;
if( offset.Dot(offset) > 0.0f )
{
return this->linearMomentum + ::Oyster::Physics3D::Formula::TangentialLinearMomentum( this->angularMomentum, offset );
}
return this->linearMomentum;
}
inline const ::Oyster::Math::Float3 & CustomBodyState::GetAngularMomentum() const
{
return this->angularMomentum;
}
inline const ::Oyster::Math::Float3 & CustomBodyState::GetLinearImpulse() const
{
return this->linearImpulse;
}
inline const ::Oyster::Math::Float3 & CustomBodyState::GetAngularImpulse() const
{
return this->angularImpulse;
}
inline const ::Oyster::Math::Float3 & CustomBodyState::GetForward_DeltaPos() const
{
return this->deltaPos;
}
inline const ::Oyster::Math::Float3 & CustomBodyState::GetForward_DeltaAxis() const
{
return this->deltaAxis;
}
inline const ::Oyster::Math::Float3 & CustomBodyState::GetGravityNormal() const
{
return this->gravityNormal;
}
inline void CustomBodyState::SetMass_KeepMomentum( ::Oyster::Math::Float m )
{
this->mass = m;
}
inline void CustomBodyState::SetMass_KeepVelocity( ::Oyster::Math::Float m )
{
if( m != 0.0f )
{ // sanity block!
this->linearMomentum *= (m / this->mass);
this->mass = m;
}
}
inline void CustomBodyState::SetRestitutionCoeff( ::Oyster::Math::Float e )
{
this->restitutionCoeff = e;
}
inline void CustomBodyState::SetFrictionCoeff( ::Oyster::Math::Float staticU, ::Oyster::Math::Float kineticU )
{
this->staticFrictionCoeff = staticU;
this->kineticFrictionCoeff = kineticU;
}
inline void CustomBodyState::SetMomentOfInertia_KeepMomentum( const ::Oyster::Physics3D::MomentOfInertia &tensor )
{
this->inertiaTensor = tensor;
}
inline void CustomBodyState::SetMomentOfInertia_KeepVelocity( const ::Oyster::Physics3D::MomentOfInertia &tensor )
{
::Oyster::Math::Quaternion rotation = ::Oyster::Math3D::Rotation(this->angularAxis);
::Oyster::Math::Float3 w = this->inertiaTensor.CalculateAngularVelocity( rotation, this->angularMomentum );
this->inertiaTensor = tensor;
this->angularMomentum = this->inertiaTensor.CalculateAngularMomentum( rotation, w );
}
inline void CustomBodyState::SetSize( const ::Oyster::Math::Float3 &size )
{
this->SetReach( 0.5f * size );
}
inline void CustomBodyState::SetReach( const ::Oyster::Math::Float3 &halfSize )
{
this->reach = halfSize;
this->reach = ::Utility::Value::Max( this->reach, ::Oyster::Math::Float3::null );
this->isSpatiallyAltered = this->isDisturbed = true;
}
inline void CustomBodyState::SetCenterPosition( const ::Oyster::Math::Float3 &centerPos )
{
this->centerPos = centerPos;
this->isSpatiallyAltered = this->isDisturbed = true;
}
inline void CustomBodyState::SetRotation( const ::Oyster::Math::Float3 &angularAxis )
{
this->angularAxis = angularAxis;
this->isSpatiallyAltered = this->isDisturbed = true;
}
inline void CustomBodyState::SetOrientation( const ::Oyster::Math::Float3 &angularAxis, const ::Oyster::Math::Float3 &translation )
{
this->angularAxis = angularAxis ;
this->centerPos = translation;
this->isSpatiallyAltered = this->isDisturbed = true;
}
inline void CustomBodyState::SetLinearMomentum( const ::Oyster::Math::Float3 &g )
{
this->linearMomentum = g;
this->isDisturbed = true;
}
inline void CustomBodyState::SetAngularMomentum( const ::Oyster::Math::Float3 &h )
{
this->angularMomentum = h;
this->isDisturbed = true;
}
inline void CustomBodyState::SetLinearImpulse( const ::Oyster::Math::Float3 &j )
{
this->linearImpulse = j;
this->isDisturbed = true;
}
inline void CustomBodyState::SetAngularImpulse( const ::Oyster::Math::Float3 &j )
{
this->angularImpulse = j;
this->isDisturbed = true;
}
inline void CustomBodyState::SetGravityNormal( const ::Oyster::Math::Float3 &gravityNormal )
{
this->gravityNormal = gravityNormal;
}
inline void CustomBodyState::AddRotation( const ::Oyster::Math::Float3 &angularAxis )
{
this->angularAxis += angularAxis;
this->isSpatiallyAltered = this->isDisturbed = true;
}
inline void CustomBodyState::AddTranslation( const ::Oyster::Math::Float3 &deltaPos )
{
this->centerPos += deltaPos;
this->isSpatiallyAltered = this->isDisturbed = true;
}
inline void CustomBodyState::ApplyLinearImpulse( const ::Oyster::Math::Float3 &j )
{
this->linearImpulse += j;
this->isDisturbed = true;
}
inline void CustomBodyState::ApplyAngularImpulse( const ::Oyster::Math::Float3 &j )
{
this->angularImpulse += j;
this->isDisturbed = true;
}
inline void CustomBodyState::ApplyImpulse( const ::Oyster::Math::Float3 &j, const ::Oyster::Math::Float3 &at, const ::Oyster::Math::Float3 &normal )
{
::Oyster::Math::Float3 offset = at - this->centerPos;
if( offset.Dot(offset) > 0.0f )
{
::Oyster::Math::Float3 deltaAngularImpulse = ::Oyster::Physics3D::Formula::AngularMomentum( j, offset );
this->linearImpulse -= ::Oyster::Physics3D::Formula::TangentialLinearMomentum( deltaAngularImpulse, offset );
this->angularImpulse += deltaAngularImpulse;
}
this->linearImpulse += j;
this->isDisturbed = true;
}
inline void CustomBodyState::ApplyFriction( const ::Oyster::Math::Float3 &j )
{
this->linearImpulse += j;
this->isDisturbed = true;
}
inline void CustomBodyState::ApplyForwarding( const ::Oyster::Math::Float3 &deltaPos, const ::Oyster::Math::Float3 &deltaAxis )
{
this->deltaPos += deltaPos;
this->deltaAxis += deltaAxis;
this->isDisturbed = this->isForwarded = true;
}
inline bool CustomBodyState::IsSpatiallyAltered() const
{
return this->isSpatiallyAltered;
}
inline bool CustomBodyState::IsDisturbed() const
{
return this->isDisturbed;
}
inline bool CustomBodyState::IsForwarded() const
{
return this->isForwarded;
}
inline GravityWell::GravityWell( )
{
this->position = ::Oyster::Math::Float3::null;
this->mass = 0.0f;
}
inline GravityWell::GravityWell( const GravityWell &gravityWell )
{
this->position = gravityWell.position;
this->mass = gravityWell.mass;
}
inline GravityWell & GravityWell::operator = ( const GravityWell &gravityWell )
{
this->position = gravityWell.position;
this->mass = gravityWell.mass;
return *this;
}
inline bool GravityWell::operator == ( const GravityWell &gravity ) const
{
if( this->position == gravity.position )
if( this->mass == gravity.mass )
{
return true;
}
return false;
}
inline bool GravityWell::operator != ( const GravityWell &gravity ) const
{
if( this->position == gravity.position )
if( this->mass == gravity.mass )
{
return false;
}
return true;
}
inline GravityDirected::GravityDirected( )
{
this->impulse = ::Oyster::Math::Float3::null;
}
inline GravityDirected::GravityDirected( const GravityDirected &gravityDirected )
{
this->impulse = gravityDirected.impulse;
}
inline GravityDirected & GravityDirected::operator = ( const GravityDirected &gravityDirected )
{
this->impulse = gravityDirected.impulse;
return *this;
}
inline bool GravityDirected::operator == ( const GravityDirected &gravity ) const
{
return this->impulse == gravity.impulse;
}
inline bool GravityDirected::operator != ( const GravityDirected &gravity ) const
{
return this->impulse != gravity.impulse;
}
inline GravityDirectedField::GravityDirectedField( )
{
this->normalizedDirection = ::Oyster::Math::Float3::null;
this->mass = 0.0f;
this->magnitude = 0.0f;
}
inline GravityDirectedField::GravityDirectedField( const GravityDirectedField &gravityDirectedField )
{
this->normalizedDirection = gravityDirectedField.normalizedDirection;
this->mass = gravityDirectedField.mass;
this->magnitude = gravityDirectedField.magnitude;
}
inline GravityDirectedField & GravityDirectedField::operator = ( const GravityDirectedField &gravityDirectedField )
{
this->normalizedDirection = gravityDirectedField.normalizedDirection;
this->mass = gravityDirectedField.mass;
this->magnitude = gravityDirectedField.magnitude;
return *this;
}
inline bool GravityDirectedField::operator == ( const GravityDirectedField &gravity ) const
{
if( this->normalizedDirection == gravity.normalizedDirection )
if( this->mass == gravity.mass )
if( this->magnitude == gravity.magnitude )
{
return true;
}
return false;
}
inline bool GravityDirectedField::operator != ( const GravityDirectedField &gravity ) const
{
if( this->normalizedDirection == gravity.normalizedDirection )
if( this->mass == gravity.mass )
if( this->magnitude == gravity.magnitude )
{
return false;
}
return true;
}
inline Gravity::Gravity()
{
this->gravityType = GravityType_Undefined;
}
inline Gravity::Gravity( const Gravity &gravity )
{
this->gravityType = gravity.gravityType;
switch( gravity.gravityType )
{
case GravityType_Well:
this->well = gravity.well;
break;
case GravityType_Directed:
this->directed = gravity.directed;
break;
case GravityType_DirectedField:
this->directedField = gravity.directedField;
break;
default: break;
}
}
inline Gravity & Gravity::operator = ( const Gravity &gravity )
{
this->gravityType = gravity.gravityType;
switch( gravity.gravityType )
{
case GravityType_Well:
this->well = gravity.well;
break;
case GravityType_Directed:
this->directed = gravity.directed;
break;
case GravityType_DirectedField:
this->directedField = gravity.directedField;
break;
default: break;
}
return *this;
}
inline bool Gravity::operator == ( const Gravity &gravity ) const
{
if( this->gravityType == gravity.gravityType )
{
switch( this->gravityType )
{
case GravityType_Well: return this->well == gravity.well;
case GravityType_Directed: return this->directed == gravity.directed;
case GravityType_DirectedField: return this->directedField == gravity.directedField;
default: return true;
}
}
return false;
}
inline bool Gravity::operator != ( const Gravity &gravity ) const
{
if( this->gravityType == gravity.gravityType )
{
switch( this->gravityType )
{
case GravityType_Well: return this->well != gravity.well;
case GravityType_Directed: return this->directed != gravity.directed;
case GravityType_DirectedField: return this->directedField != gravity.directedField;
default: return false;
}
}
return true;
}
} }
} }
} }

View File

@ -5,212 +5,41 @@
#include "PhysicsAPI.h" #include "PhysicsAPI.h"
#include "Inertia.h" #include "Inertia.h"
namespace Oyster { namespace Physics namespace Oyster
{ {
namespace Struct namespace Physics
{ {
struct SimpleBodyDescription namespace Struct
{ {
::Oyster::Math::Float3 rotation; struct CustomBodyState
::Oyster::Math::Float3 centerPosition; {
::Oyster::Math::Float3 size; public:
::Oyster::Math::Float mass; // Default constructor
::Oyster::Math::Float restitutionCoeff; CustomBodyState( ::Oyster::Math::Float mass = 1.0f,
::Oyster::Math::Float frictionCoeff_Static; ::Oyster::Math::Float restitutionCoeff = 1.0f,
::Oyster::Math::Float frictionCoeff_Dynamic; ::Oyster::Math::Float staticFrictionCoeff = 1.0f,
::Oyster::Physics3D::MomentOfInertia inertiaTensor; ::Oyster::Math::Float dynamicFrictionCoeff = 1.0f,
::Oyster::Physics::ICustomBody::EventAction_BeforeCollisionResponse subscription_onCollision; const ::Oyster::Math::Float3 &centerPos = ::Oyster::Math::Float3::null,
::Oyster::Physics::ICustomBody::EventAction_AfterCollisionResponse subscription_onCollisionResponse; const ::Oyster::Math::Quaternion &quaternion = ::Oyster::Math::Quaternion(::Oyster::Math::Float3(0, 0, 0), 1));
::Oyster::Physics::ICustomBody::EventAction_Move subscription_onMovement;
bool ignoreGravity;
SimpleBodyDescription(); // Assignment operator
}; CustomBodyState & operator = ( const CustomBodyState &state );
struct SphericalBodyDescription // Get functions that calculate matrices that do not exist as variables
{ ::Oyster::Math::Float4x4 GetRotation() const;
::Oyster::Math::Float3 rotation; ::Oyster::Math::Float4x4 GetOrientation() const;
::Oyster::Math::Float3 centerPosition; ::Oyster::Math::Float4x4 GetView() const;
::Oyster::Math::Float radius; ::Oyster::Math::Float4x4 GetView( const ::Oyster::Math::Float3 &offset ) const;
::Oyster::Math::Float mass;
::Oyster::Math::Float restitutionCoeff;
::Oyster::Math::Float frictionCoeff_Static;
::Oyster::Math::Float frictionCoeff_Dynamic;
::Oyster::Physics::ICustomBody::EventAction_BeforeCollisionResponse subscription_onCollision;
::Oyster::Physics::ICustomBody::EventAction_AfterCollisionResponse subscription_onCollisionResponse;
::Oyster::Physics::ICustomBody::EventAction_Move subscription_onMovement;
bool ignoreGravity;
SphericalBodyDescription();
};
struct CustomBodyState
{
public:
CustomBodyState( ::Oyster::Math::Float mass = 1.0f,
::Oyster::Math::Float restitutionCoeff = 1.0f,
::Oyster::Math::Float staticFrictionCoeff = 1.0f,
::Oyster::Math::Float kineticFrictionCoeff = 1.0f,
const ::Oyster::Physics3D::MomentOfInertia &inertiaTensor = ::Oyster::Physics3D::MomentOfInertia(),
const ::Oyster::Math::Float3 &reach = ::Oyster::Math::Float3::null,
const ::Oyster::Math::Float3 &centerPos = ::Oyster::Math::Float3::null,
const ::Oyster::Math::Float3 &rotation = ::Oyster::Math::Float3::null,
const ::Oyster::Math::Float3 &linearMomentum = ::Oyster::Math::Float3::null,
const ::Oyster::Math::Float3 &angularMomentum = ::Oyster::Math::Float3::null,
const ::Oyster::Math::Float3 &gravityNormal = ::Oyster::Math::Float3::null);
CustomBodyState & operator = ( const CustomBodyState &state );
const ::Oyster::Math::Float GetMass() const;
const ::Oyster::Math::Float GetRestitutionCoeff() const;
const ::Oyster::Math::Float GetFrictionCoeff_Static() const;
const ::Oyster::Math::Float GetFrictionCoeff_Kinetic() const;
const ::Oyster::Physics3D::MomentOfInertia & GetMomentOfInertia() const;
const ::Oyster::Math::Float3 & GetReach() const;
::Oyster::Math::Float3 GetSize() const;
const ::Oyster::Math::Float3 & GetCenterPosition() const;
const ::Oyster::Math::Float3 & GetAngularAxis() const;
::Oyster::Math::Float4x4 GetRotation() const;
::Oyster::Math::Float4x4 GetOrientation() const;
::Oyster::Math::Float4x4 GetOrientation( const ::Oyster::Math::Float3 &offset ) const;
::Oyster::Math::Float4x4 GetView() const;
::Oyster::Math::Float4x4 GetView( const ::Oyster::Math::Float3 &offset ) const;
const ::Oyster::Math::Float3 & GetLinearMomentum() const;
::Oyster::Math::Float3 GetLinearMomentum( const ::Oyster::Math::Float3 &at ) const;
const ::Oyster::Math::Float3 & GetAngularMomentum() const;
const ::Oyster::Math::Float3 & GetLinearImpulse() const;
const ::Oyster::Math::Float3 & GetAngularImpulse() const;
const ::Oyster::Math::Float3 & GetForward_DeltaPos() const;
const ::Oyster::Math::Float3 & GetForward_DeltaAxis() const;
const ::Oyster::Math::Float3 & GetGravityNormal() const;
void SetMass_KeepMomentum( ::Oyster::Math::Float m );
void SetMass_KeepVelocity( ::Oyster::Math::Float m );
void SetRestitutionCoeff( ::Oyster::Math::Float e );
void SetFrictionCoeff( ::Oyster::Math::Float staticU, ::Oyster::Math::Float kineticU );
void SetMomentOfInertia_KeepMomentum( const ::Oyster::Physics3D::MomentOfInertia &tensor );
void SetMomentOfInertia_KeepVelocity( const ::Oyster::Physics3D::MomentOfInertia &tensor );
void SetSize( const ::Oyster::Math::Float3 &size );
void SetReach( const ::Oyster::Math::Float3 &halfSize );
void SetCenterPosition( const ::Oyster::Math::Float3 &centerPos );
void SetRotation( const ::Oyster::Math::Float3 &angularAxis );
//void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
//void SetOrientation( const ::Oyster::Math::Float4x4 &orientation );
void SetOrientation( const ::Oyster::Math::Float3 &angularAxis, const ::Oyster::Math::Float3 &translation );
void SetLinearMomentum( const ::Oyster::Math::Float3 &g );
void SetAngularMomentum( const ::Oyster::Math::Float3 &h );
void SetLinearImpulse( const ::Oyster::Math::Float3 &j );
void SetAngularImpulse( const ::Oyster::Math::Float3 &j );
void SetGravityNormal( const ::Oyster::Math::Float3 &gravityNormal );
void AddRotation( const ::Oyster::Math::Float3 &angularAxis );
void AddTranslation( const ::Oyster::Math::Float3 &deltaPos );
void ApplyLinearImpulse( const ::Oyster::Math::Float3 &j );
void ApplyAngularImpulse( const ::Oyster::Math::Float3 &j );
void ApplyImpulse( const ::Oyster::Math::Float3 &j, const ::Oyster::Math::Float3 &at, const ::Oyster::Math::Float3 &normal );
void CustomBodyState::ApplyFriction( const ::Oyster::Math::Float3 &j); void CustomBodyState::ApplyFriction( const ::Oyster::Math::Float3 &j);
void ApplyForwarding( const ::Oyster::Math::Float3 &deltaPos, const ::Oyster::Math::Float3 &deltaAxis );
bool IsSpatiallyAltered() const; // Variables for state
bool IsDisturbed() const; ::Oyster::Math::Float mass, restitutionCoeff, staticFrictionCoeff, dynamicFrictionCoeff;
bool IsForwarded() const; ::Oyster::Math::Float3 reach, centerPos;
::Oyster::Math::Quaternion quaternion;
::Oyster::Math::Float3 linearMomentum; };
}
private: }
::Oyster::Math::Float mass, restitutionCoeff, staticFrictionCoeff, kineticFrictionCoeff; }
::Oyster::Physics3D::MomentOfInertia inertiaTensor;
::Oyster::Math::Float3 reach, centerPos, angularAxis;
::Oyster::Math::Float3 angularMomentum;
::Oyster::Math::Float3 linearImpulse, angularImpulse;
::Oyster::Math::Float3 deltaPos, deltaAxis; // Forwarding data sum
::Oyster::Math::Float3 gravityNormal;
bool isSpatiallyAltered, isDisturbed, isForwarded;
};
/**
###############################################################################
Can't define structs inside structs in a union therefor they are declared here.
###############################################################################
*/
struct GravityWell
{
::Oyster::Math::Float3 position;
::Oyster::Math::Float mass;
GravityWell( );
GravityWell( const GravityWell &gravityWell );
GravityWell & operator = ( const GravityWell &gravityWell );
bool operator == ( const GravityWell &gravity ) const;
bool operator != ( const GravityWell &gravity ) const;
};
struct GravityDirected
{
::Oyster::Math::Float3 impulse;
GravityDirected( );
GravityDirected( const GravityDirected &gravityDirected );
GravityDirected & operator = ( const GravityDirected &gravityDirected );
bool operator == ( const GravityDirected &gravity ) const;
bool operator != ( const GravityDirected &gravity ) const;
};
struct GravityDirectedField
{
::Oyster::Math::Float3 normalizedDirection;
::Oyster::Math::Float mass;
::Oyster::Math::Float magnitude;
GravityDirectedField( );
GravityDirectedField( const GravityDirectedField &gravityDirectedField );
GravityDirectedField & operator = ( const GravityDirectedField &gravityDirectedField );
bool operator == ( const GravityDirectedField &gravity ) const;
bool operator != ( const GravityDirectedField &gravity ) const;
};
struct Gravity
{
enum GravityType
{
GravityType_Undefined = -1,
GravityType_Well = 0,
GravityType_Directed = 1,
GravityType_DirectedField = 2,
} gravityType;
union
{
struct
{
GravityWell well;
};
struct
{
GravityDirected directed;
};
struct
{
GravityDirectedField directedField;
};
};
Gravity( );
Gravity( const Gravity &gravity );
Gravity & operator = ( const Gravity &gravity );
bool operator == ( const Gravity &gravity ) const;
bool operator != ( const Gravity &gravity ) const;
};
}
} }
#include "PhysicsStructs-Impl.h" #include "PhysicsStructs-Impl.h"

View File

@ -44,6 +44,11 @@ namespace Utility
unsigned int Size() const; unsigned int Size() const;
unsigned int Capacity() const; unsigned int Capacity() const;
bool IsEmpty() const;
T* begin();
T* end();
private: private:
void Expand(int elements = 0); void Expand(int elements = 0);
@ -112,7 +117,7 @@ namespace Utility
template <typename T> const T& DynamicArray<T>::operator[](unsigned int index) const template <typename T> const T& DynamicArray<T>::operator[](unsigned int index) const
{ {
assert(index < this->size); assert((int)index < this->size);
return this->data[index]; return this->data[index];
} }
@ -165,7 +170,7 @@ namespace Utility
template <typename T> void DynamicArray<T>::Remove(unsigned int index) template <typename T> void DynamicArray<T>::Remove(unsigned int index)
{ {
assert(index > this->size); assert(index > (unsigned int) this->size);
T* temp = new T[this->capacity - 1]; T* temp = new T[this->capacity - 1];
@ -181,7 +186,8 @@ namespace Utility
template <typename T> void DynamicArray<T>::Clear() template <typename T> void DynamicArray<T>::Clear()
{ {
delete [] this->data; if(this->data)
delete [] this->data;
this->data = 0; this->data = 0;
this->size = 0; this->size = 0;
@ -227,6 +233,11 @@ namespace Utility
return (unsigned int)this->capacity; return (unsigned int)this->capacity;
} }
template <typename T> bool DynamicArray<T>::IsEmpty() const
{
return (this->size == 0);
}
template <typename T> void DynamicArray<T>::Expand(int elements) template <typename T> void DynamicArray<T>::Expand(int elements)
{ {
if(elements < 1) return; if(elements < 1) return;
@ -248,6 +259,18 @@ namespace Utility
} }
} }
template <typename T> T* DynamicArray<T>::begin()
{
if(this->size == 0) return 0;
return &this->data[0];
}
template <typename T> T* DynamicArray<T>::end()
{
if(this->size == 0) return 0;
return ((&this->data[this->size - 1]) + 1);
}
#pragma endregion #pragma endregion
} }
} }

View File

@ -152,8 +152,10 @@
<ClCompile Include="Resource\OResourceHandler.cpp" /> <ClCompile Include="Resource\OResourceHandler.cpp" />
<ClCompile Include="Resource\OResource.cpp" /> <ClCompile Include="Resource\OResource.cpp" />
<ClCompile Include="Resource\ResourceManager.cpp"> <ClCompile Include="Resource\ResourceManager.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="Thread\OysterMutex.cpp" /> <ClCompile Include="Thread\OysterMutex.cpp" />
<ClCompile Include="Thread\OysterThread_Impl.cpp" /> <ClCompile Include="Thread\OysterThread_Impl.cpp" />
@ -172,8 +174,10 @@
<ClInclude Include="Resource\OysterResource.h" /> <ClInclude Include="Resource\OysterResource.h" />
<ClInclude Include="Resource\OResource.h" /> <ClInclude Include="Resource\OResource.h" />
<ClInclude Include="Resource\ResourceManager.h"> <ClInclude Include="Resource\ResourceManager.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
</ClInclude> </ClInclude>
<ClInclude Include="ThreadSafeQueue.h" /> <ClInclude Include="ThreadSafeQueue.h" />
<ClInclude Include="Thread\IThreadObject.h" /> <ClInclude Include="Thread\IThreadObject.h" />

View File

@ -108,7 +108,7 @@ void SaveResource( std::map<std::wstring, ResourceData*>& resources, ResourceDat
} }
bool Release(std::map<std::wstring, ResourceData*>& resources, ResourceData* resource) bool Release(std::map<std::wstring, ResourceData*>& resources, ResourceData* resource)
{ {
if(resource->referenceCount.Decref() == 0) if(resource->referenceCount.Decref() < 1)
{ {
const wchar_t* temp = FindResourceKey(resources, resource->resource); const wchar_t* temp = FindResourceKey(resources, resource->resource);
@ -123,7 +123,7 @@ bool Release(std::map<std::wstring, ResourceData*>& resources, ResourceData* res
resource->resource = 0; resource->resource = 0;
break; break;
case Oyster::Resource::ResourceType_UNKNOWN: case Oyster::Resource::ResourceType_CUSTOM:
resource->unloadFnc(resource->resource); resource->unloadFnc(resource->resource);
resource->resource = 0; resource->resource = 0;
break; break;
@ -137,6 +137,13 @@ bool Release(std::map<std::wstring, ResourceData*>& resources, ResourceData* res
} }
ResourceData* Load(/*Out*/ResourceData* targetMem, /*in*/const wchar_t source[], /*in*/ResourceType type) ResourceData* Load(/*Out*/ResourceData* targetMem, /*in*/const wchar_t source[], /*in*/ResourceType type)
{ {
targetMem->resource = 0;
targetMem->loadFnc = 0;
targetMem->unloadFnc = 0;
targetMem->resourceID = 0;
targetMem->resourcetype = type;
targetMem->resourceSize = 0;
std::string sOut; std::string sOut;
bool success = false; bool success = false;
@ -182,13 +189,20 @@ ResourceData* Load(/*Out*/ResourceData* targetMem, /*in*/const wchar_t source[],
} }
ResourceData* Load(/*Out*/ResourceData* targetMem, /*in*/const wchar_t source[], LoadFunction loadFnc, UnloadFunction unloadFnc) ResourceData* Load(/*Out*/ResourceData* targetMem, /*in*/const wchar_t source[], LoadFunction loadFnc, UnloadFunction unloadFnc)
{ {
targetMem->resource = 0;
targetMem->loadFnc = 0;
targetMem->unloadFnc = 0;
targetMem->resourceID = 0;
targetMem->resourcetype = ResourceType_CUSTOM;
targetMem->resourceSize = 0;
if(loadFnc) if(loadFnc)
{ {
targetMem->resource = loadFnc(source); targetMem->resource = loadFnc(source);
if(targetMem->resource) if(targetMem->resource)
{ {
targetMem->resourceSize = 0; targetMem->resourceSize = 0;
targetMem->resourcetype = ResourceType_UNKNOWN; targetMem->resourcetype = ResourceType_CUSTOM;
targetMem->loadFnc = loadFnc; targetMem->loadFnc = loadFnc;
targetMem->unloadFnc = unloadFnc; targetMem->unloadFnc = unloadFnc;
} }
@ -208,7 +222,7 @@ ResourceData* Reload(std::map<std::wstring, ResourceData*> resources, ResourceDa
return Load(resource, filename, resource->loadFnc, resource->unloadFnc); return Load(resource, filename, resource->loadFnc, resource->unloadFnc);
break; break;
case Oyster::Resource::ResourceType_UNKNOWN: case Oyster::Resource::ResourceType_CUSTOM:
{ {
resource->unloadFnc(resource->resource); resource->unloadFnc(resource->resource);
@ -270,7 +284,7 @@ HRESOURCE ResourceManager::LoadResource(const wchar_t filename[], LoadFunction l
{ {
return 0; return 0;
} }
if(!loadFnc) if(!loadFnc || !unloadFnc)
{ {
return 0; return 0;
} }
@ -278,6 +292,8 @@ HRESOURCE ResourceManager::LoadResource(const wchar_t filename[], LoadFunction l
ResourceData *t = FindResource(this->resources, filename); ResourceData *t = FindResource(this->resources, filename);
if(t) if(t)
{ {
t->loadFnc = loadFnc;
t->unloadFnc = unloadFnc;
if(force) if(force)
{ {
return ResourceManager::ReloadResource(filename); return ResourceManager::ReloadResource(filename);
@ -292,7 +308,7 @@ HRESOURCE ResourceManager::LoadResource(const wchar_t filename[], LoadFunction l
else else
{ {
t = Load(new ResourceData(), filename, loadFnc, unloadFnc ); t = Load(new ResourceData(), filename, loadFnc, unloadFnc );
if(t) if(t && t->resource)
{ {
t->resourceID = (customId); t->resourceID = (customId);
SaveResource(this->resources, t, filename, true); SaveResource(this->resources, t, filename, true);
@ -300,6 +316,7 @@ HRESOURCE ResourceManager::LoadResource(const wchar_t filename[], LoadFunction l
else else
{ {
delete t; delete t;
t = 0;
} }
} }
if(!t) if(!t)
@ -333,24 +350,20 @@ void ResourceManager::Clean()
for (i; i != last; i++) for (i; i != last; i++)
{ {
//Remove all the references //Remove all the references
while (!Release(this->resources, i->second)); while (!Release(resources, i->second));
} }
resources.clear(); resources.clear();
} }
void ResourceManager::ReleaseResource(const HRESOURCE& resourceData) void ResourceManager::ReleaseResource(const HRESOURCE& resourceData)
{ {
ResourceData *t = FindResource(this->resources, resourceData); const wchar_t* temp = FindResourceKey(resources, resourceData);
if(t)
if(temp)
{ {
ResourceData *t = FindResource(this->resources, resourceData);
if(Release(resources, t)) if(Release(resources, t))
{ {
const wchar_t* temp = 0; resources.erase(temp);
if((temp = FindResourceKey(resources, resourceData)))
{
std::wstring ws = std::wstring(temp);
delete resources[ws];
resources.erase(ws);
}
} }
} }
} }
@ -361,7 +374,6 @@ void ResourceManager::ReleaseResource(const wchar_t filename[])
{ {
if(Release(resources, t)) if(Release(resources, t))
{ {
delete resources[filename];
resources.erase(filename); resources.erase(filename);
} }
} }

View File

@ -29,10 +29,8 @@ namespace Oyster
ResourceType_Byte_UNICODE, /**< Handle can be interpeted as char[] or char* */ ResourceType_Byte_UNICODE, /**< Handle can be interpeted as char[] or char* */
ResourceType_Byte_UTF16LE, /**< Handle can be interpeted as char[] or char* */ ResourceType_Byte_UTF16LE, /**< Handle can be interpeted as char[] or char* */
ResourceType_COUNT, /**< Handle can be interpeted as ? */ ResourceType_CUSTOM, /**< Handle can be interpeted as whatever */
ResourceType_INVALID, /**< Handle can be interpeted as whatever */
ResourceType_UNKNOWN = -1, /**< Handle can be interpeted as void* */
ResourceType_INVALID = -2, /**< Invalid or non existing resource */
}; };
/** A resource handler interface to interact with when loading resources. /** A resource handler interface to interact with when loading resources.

View File

@ -42,15 +42,10 @@ using namespace Utility::DynamicMemory;
}; };
struct ThreadData struct ThreadData
{ {
OYSTER_THREAD_STATE state; //<! The current thread state. OYSTER_THREAD_STATE state; //<! The current thread state.
OYSTER_THREAD_PRIORITY prio; //<! The thread priority OYSTER_THREAD_PRIORITY prio; //<! The thread priority
//IThreadObject *owner; //<! The worker object. OwnerContainer ownerObj; //
//Oyster::Callback::OysterCallback<bool, void> ownerObj; // int msec; //<! A timer in miliseconds.
OwnerContainer ownerObj; //
std::atomic<int> msec; //<! A timer in miliseconds.
//std::timed_mutex threadFunctionLock;
std::mutex threadStopMutex;
}; };
/** A typical Oyster thread function */ /** A typical Oyster thread function */
@ -58,7 +53,6 @@ using namespace Utility::DynamicMemory;
struct RefData struct RefData
{ {
std::mutex threadWaitFunctionLock;
bool isCreated; bool isCreated;
bool isAlive; bool isAlive;
ThreadData *threadData; ThreadData *threadData;
@ -79,11 +73,30 @@ using namespace Utility::DynamicMemory;
{ {
if(!threadData) return OYSTER_THREAD_ERROR_SUCCESS; if(!threadData) return OYSTER_THREAD_ERROR_SUCCESS;
this->threadData->state = OYSTER_THREAD_STATE_DEAD; if(std::this_thread::get_id() != this->workerThread.get_id())
if(this->workerThread.joinable())
{ {
this->workerThread.join(); //this->threadData->threadDataAcces.lock();
//{
this->threadData->state = OYSTER_THREAD_STATE_DEAD;
if(this->workerThread.joinable())
{
this->workerThread.join();
}
this->isCreated = false;
delete this->threadData;
this->threadData = 0;
//} this->threadData->threadDataAcces.unlock();
}
else
{
this->threadData->state = OYSTER_THREAD_STATE_DEAD;
if(this->workerThread.joinable())
{
this->workerThread.join();
}
this->isCreated = false; this->isCreated = false;
delete this->threadData; delete this->threadData;
this->threadData = 0; this->threadData = 0;
@ -102,12 +115,10 @@ using namespace Utility::DynamicMemory;
this->threadData->state = OYSTER_THREAD_STATE_IDLE; this->threadData->state = OYSTER_THREAD_STATE_IDLE;
threadData->ownerObj = worker; threadData->ownerObj = worker;
threadData->prio = OYSTER_THREAD_PRIORITY_2; threadData->prio = OYSTER_THREAD_PRIORITY_2;
threadData->msec = 0;
workerThread = std::thread(fnc, this->threadData); workerThread = std::thread(fnc, this->threadData);
//if(detach)
// this->workerThread.detach();
isCreated = true; isCreated = true;
return OYSTER_THREAD_ERROR_SUCCESS; return OYSTER_THREAD_ERROR_SUCCESS;
@ -145,6 +156,9 @@ using namespace Utility::DynamicMemory;
public: public:
static void CheckPriority(ThreadData* w) static void CheckPriority(ThreadData* w)
{ {
Oyster::Thread::OYSTER_THREAD_PRIORITY temp = w->prio;
switch (w->prio) switch (w->prio)
{ {
case Oyster::Thread::OYSTER_THREAD_PRIORITY_1: case Oyster::Thread::OYSTER_THREAD_PRIORITY_1:
@ -190,16 +204,18 @@ using namespace Utility::DynamicMemory;
while (w->state == OYSTER_THREAD_STATE_NORMAL) while (w->state == OYSTER_THREAD_STATE_NORMAL)
{ {
CheckPriority(w); //while (!w->threadDataAcces.try_lock());
if(!DoWork(w)) break;
CheckStatus(w); CheckPriority(w);
if(!DoWork(w)) break;
CheckStatus(w);
//w->threadDataAcces.unlock();
} }
if(w->ownerObj.value.obj) w->ownerObj.value.obj->ThreadExit(); if(w->ownerObj.value.obj) w->ownerObj.value.obj->ThreadExit();
w->state = OYSTER_THREAD_STATE_DEAD; w->state = OYSTER_THREAD_STATE_DEAD;
//delete w;
} }
}; };
@ -247,79 +263,114 @@ OYSTER_THREAD_ERROR OysterThread::Create(ThreadFnc worker, bool start, bool deta
OYSTER_THREAD_ERROR OysterThread::Start() OYSTER_THREAD_ERROR OysterThread::Start()
{ {
if(!this->privateData->data->threadData->ownerObj) OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS;
return OYSTER_THREAD_ERROR_ThreadHasNoWorker; //this->privateData->data->threadData->threadDataAcces.lock();{
if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD) if(!this->privateData->data->threadData->ownerObj)
return OYSTER_THREAD_ERROR_ThreadIsDead; val = OYSTER_THREAD_ERROR_ThreadHasNoWorker;
this->privateData->data->threadData->state = OYSTER_THREAD_STATE_NORMAL; if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD)
val = OYSTER_THREAD_ERROR_ThreadIsDead;
return OYSTER_THREAD_ERROR_SUCCESS; this->privateData->data->threadData->state = OYSTER_THREAD_STATE_NORMAL;
//} this->privateData->data->threadData->threadDataAcces.unlock();
return val;
} }
OYSTER_THREAD_ERROR OysterThread::Stop() OYSTER_THREAD_ERROR OysterThread::Stop()
{ {
this->privateData->data->threadData->state = OYSTER_THREAD_STATE_IDLE; OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS;
return OYSTER_THREAD_ERROR_SUCCESS; //this->privateData->data->threadData->threadDataAcces.lock(); {
this->privateData->data->threadData->state = OYSTER_THREAD_STATE_IDLE;
//} this->privateData->data->threadData->threadDataAcces.unlock();
return val;
} }
OYSTER_THREAD_ERROR OysterThread::Stop(int msec) OYSTER_THREAD_ERROR OysterThread::Stop(int msec)
{ {
this->privateData->data->threadData->msec = msec; OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS;
return OYSTER_THREAD_ERROR_SUCCESS; //this->privateData->data->threadData->threadDataAcces.lock(); {
this->privateData->data->threadData->msec = msec;
//} this->privateData->data->threadData->threadDataAcces.unlock();
return val;
} }
OYSTER_THREAD_ERROR OysterThread::Resume() OYSTER_THREAD_ERROR OysterThread::Resume()
{ {
if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD) OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS;
return OYSTER_THREAD_ERROR_ThreadIsDead; //this->privateData->data->threadData->threadDataAcces.lock(); {
if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD)
val = OYSTER_THREAD_ERROR_ThreadIsDead;
this->privateData->data->threadData->state = OYSTER_THREAD_STATE_NORMAL; this->privateData->data->threadData->state = OYSTER_THREAD_STATE_NORMAL;
//} this->privateData->data->threadData->threadDataAcces.unlock();
return OYSTER_THREAD_ERROR_SUCCESS; return val;
} }
OYSTER_THREAD_ERROR OysterThread::SetWorker(IThreadObject* worker) OYSTER_THREAD_ERROR OysterThread::SetWorker(IThreadObject* worker)
{ {
this->privateData->data->threadData->ownerObj.value = worker; OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS;
this->privateData->data->threadData->ownerObj.type = Oyster::Callback::CallbackType_Object; //this->privateData->data->threadData->threadDataAcces.lock();{
this->privateData->data->threadData->msec = 0; this->privateData->data->threadData->ownerObj.value = worker;
this->privateData->data->threadData->ownerObj.type = Oyster::Callback::CallbackType_Object;
return OYSTER_THREAD_ERROR_SUCCESS;; this->privateData->data->threadData->msec = 0;
//} this->privateData->data->threadData->threadDataAcces.unlock();
return val;;
} }
OYSTER_THREAD_ERROR OysterThread::SetWorker(ThreadFnc worker) OYSTER_THREAD_ERROR OysterThread::SetWorker(ThreadFnc worker)
{ {
this->privateData->data->threadData->ownerObj.value = worker; OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS;
this->privateData->data->threadData->ownerObj.type = Oyster::Callback::CallbackType_Function; //this->privateData->data->threadData->threadDataAcces.lock();{
this->privateData->data->threadData->msec = 0; this->privateData->data->threadData->ownerObj.value = worker;
this->privateData->data->threadData->ownerObj.type = Oyster::Callback::CallbackType_Function;
return OYSTER_THREAD_ERROR_SUCCESS;; this->privateData->data->threadData->msec = 0;
//} this->privateData->data->threadData->threadDataAcces.unlock();
return val;;
} }
OYSTER_THREAD_ERROR OysterThread::Terminate() OYSTER_THREAD_ERROR OysterThread::Terminate()
{ {
if(this->privateData) if(this->privateData)
return this->privateData->Terminate(); return this->privateData->Terminate();
return OYSTER_THREAD_ERROR_SUCCESS; return OYSTER_THREAD_ERROR_SUCCESS;
} }
OYSTER_THREAD_ERROR OysterThread::Wait() OYSTER_THREAD_ERROR OysterThread::Wait()
{ {
if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD) OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS;
return OYSTER_THREAD_ERROR_ThreadIsDead;
if( this->privateData->data->workerThread.get_id() == std::this_thread::get_id()) //this->privateData->data->threadData->threadDataAcces.lock();{
return OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe;
return OYSTER_THREAD_ERROR_SUCCESS; if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD)
val = OYSTER_THREAD_ERROR_ThreadIsDead;
if( this->privateData->data->workerThread.get_id() == std::this_thread::get_id())
val = OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe;
//} this->privateData->data->threadData->threadDataAcces.unlock();
return val;
} }
OYSTER_THREAD_ERROR OysterThread::Wait(int msec) OYSTER_THREAD_ERROR OysterThread::Wait(int msec)
{ {
if(this->privateData->data->workerThread.get_id() == std::this_thread::get_id()) OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS;
return OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe;
//this->privateData->data->threadData->threadDataAcces.lock();{
return OYSTER_THREAD_ERROR_SUCCESS; if(this->privateData->data->workerThread.get_id() == std::this_thread::get_id())
val = OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe;
//} this->privateData->data->threadData->threadDataAcces.unlock();
return val;
} }
OYSTER_THREAD_ERROR OysterThread::Swap(const OysterThread* other) OYSTER_THREAD_ERROR OysterThread::Swap(const OysterThread* other)
{ {
this->privateData->data->workerThread.swap(other->privateData->data->workerThread); //this->privateData->data->threadData->threadDataAcces.lock();{
this->privateData->data->workerThread.swap(other->privateData->data->workerThread);
//} this->privateData->data->threadData->threadDataAcces.unlock();
return OYSTER_THREAD_ERROR_SUCCESS; return OYSTER_THREAD_ERROR_SUCCESS;
} }

View File

@ -34,12 +34,15 @@ namespace Utility
virtual bool IsEmpty(); virtual bool IsEmpty();
virtual void Swap( IQueue<Type> &queue ); virtual void Swap( IQueue<Type> &queue );
virtual void Clear();
private: private:
class Node class Node
{ {
public: public:
Type item; Type item;
Node *next; Node *next;
Node(){ this->next = NULL; };
Node(Type item){ this->item = item; this->next = NULL; }; Node(Type item){ this->item = item; this->next = NULL; };
~Node() {}; ~Node() {};
}; };
@ -215,6 +218,15 @@ namespace Utility
stdMutex.unlock(); stdMutex.unlock();
} }
template < typename Type >
void ThreadSafeQueue<Type>::Clear()
{
while (!IsEmpty())
{
Pop();
}
}
} }
} }

View File

@ -374,7 +374,191 @@ namespace Utility
return (this->_ptr != NULL) ? true : false; return (this->_ptr != NULL) ? true : false;
} }
#pragma endregion #pragma endregion
}
namespace Thread
{
#pragma region ThreadSafeSmartPointer
template<typename T> void ThreadSafeSmartPointer<T>::Destroy()
{
delete this->_rc.load();
this->_rc = NULL;
//Use default function for memory deallocation.
SafeDeleteInstance<T>(this->_ptr.load());
this->_ptr = NULL;
}
template<typename T> ThreadSafeSmartPointer<T>::ThreadSafeSmartPointer()
:_rc(0), _ptr(0)
{ }
template<typename T> ThreadSafeSmartPointer<T>::ThreadSafeSmartPointer(UniquePointer<T>& p)
:_ptr(p.Release())
{
this->_rc = new ReferenceCount();
this->_rc->Incref();
}
template<typename T> ThreadSafeSmartPointer<T>::ThreadSafeSmartPointer(T* p)
:_ptr(p)
{
this->_rc.store = new ReferenceCount();
this->_rc->Incref();
}
template<typename T> ThreadSafeSmartPointer<T>::ThreadSafeSmartPointer(const ThreadSafeSmartPointer& d)
:_ptr(d._ptr), _rc(d._rc)
{
if(this->_rc)
this->_rc->Incref();
}
template<typename T> ThreadSafeSmartPointer<T>::~ThreadSafeSmartPointer()
{
this->Release();
}
template<typename T> ThreadSafeSmartPointer<T>& ThreadSafeSmartPointer<T>::operator= (const ThreadSafeSmartPointer<T>& p)
{
if (this != &p)
{
//Last to go?
if(this->_rc.load() && this->_rc.load()->Decref() == 0)
{
//Call child specific
Destroy();
}
this->_ptr.store(p._ptr.load());
this->_rc.store(p._rc.load());
if(this->_rc.load()) this->_rc.load()->Incref();
}
return *this;
}
template<typename T> ThreadSafeSmartPointer<T>& ThreadSafeSmartPointer<T>::operator= (UniquePointer<T>& p)
{
//Last to go?
if(this->_rc)
{
if(this->_rc->Decref() == 0)
{
//Call child specific
Destroy();
this->_rc = new ReferenceCount();
}
}
else
{
if(p) this->_rc = new ReferenceCount();
}
if(this->_rc)
this->_rc->Incref();
this->_ptr = p.Release();
return *this;
}
template<typename T> ThreadSafeSmartPointer<T>& ThreadSafeSmartPointer<T>::operator= (T* p)
{
if (this->_ptr != p)
{
//Last to go?
if(this->_rc.load())
{
if(this->_rc.load()->Decref() == 0)
{
//Call child specific
Destroy();
if(p) this->_rc = new ReferenceCount();
}
}
else if(p)
{
this->_rc = new ReferenceCount();
}
this->_ptr = p;
if(p) this->_rc.load()->Incref();
else this->_rc = 0;
}
return *this;
}
template<typename T> inline bool ThreadSafeSmartPointer<T>::operator== (const ThreadSafeSmartPointer<T>& d) const
{
return d._ptr == this->_ptr;
}
template<typename T> inline bool ThreadSafeSmartPointer<T>::operator== (const T& p) const
{
return &p == this->_ptr;
}
template<typename T> inline bool ThreadSafeSmartPointer<T>::operator!= (const ThreadSafeSmartPointer<T>& d) const
{
return d._ptr != this->_ptr;
}
template<typename T> inline bool ThreadSafeSmartPointer<T>::operator!= (const T& p) const
{
return &p != this->_ptr;
}
template<typename T> inline T& ThreadSafeSmartPointer<T>::operator* ()
{
return *this->_ptr;
}
template<typename T> inline const T& ThreadSafeSmartPointer<T>::operator* () const
{
return *this->_ptr;
}
template<typename T> inline T* ThreadSafeSmartPointer<T>::operator-> ()
{
return this->_ptr;
}
template<typename T> inline const T* ThreadSafeSmartPointer<T>::operator-> () const
{
return this->_ptr;
}
template<typename T> inline ThreadSafeSmartPointer<T>::operator T* () const
{
return this->_ptr;
}
template<typename T> inline ThreadSafeSmartPointer<T>::operator const T* () const
{
return this->_ptr;
}
template<typename T> inline ThreadSafeSmartPointer<T>::operator T& () const
{
return *this->_ptr;
}
template<typename T> inline ThreadSafeSmartPointer<T>::operator bool() const
{
return (this->_ptr != 0);
}
template<typename T> inline T* ThreadSafeSmartPointer<T>::Get()
{
return this->_ptr;
}
template<typename T> inline T* ThreadSafeSmartPointer<T>::Get() const
{
return this->_ptr;
}
template<typename T> int ThreadSafeSmartPointer<T>::Release()
{
int returnVal = 0;
if(this->_rc.load() && ((returnVal = this->_rc.load()->Decref()) == 0))
{
Destroy();
}
return returnVal;
}
template<typename T> int ThreadSafeSmartPointer<T>::ReleaseDummy()
{
int val = this->_rc->Decref();
this->_rc->Incref();
return val;
}
template<typename T> inline bool ThreadSafeSmartPointer<T>::IsValid() const
{
return (this->_ptr != NULL) ? true : false;
}
#pragma endregion
} }
} }

View File

@ -300,7 +300,7 @@ namespace Utility
//To wstring //To wstring
::std::wstring & StringToWString( const ::std::string &str, ::std::wstring &wstr ) ::std::wstring & StringToWstring( const ::std::string &str, ::std::wstring &wstr )
{ {
const char *orig = str.c_str(); const char *orig = str.c_str();

View File

@ -408,7 +408,59 @@ namespace Utility
namespace Thread namespace Thread
{ {
//Utilities for threading using namespace DynamicMemory;
//! Wrapper to manage references on a pointer.
template<typename T> struct ThreadSafeSmartPointer
{
private:
std::atomic<ReferenceCount*> _rc;
std::atomic<T*> _ptr;
/** Destroys the pointer and returns the memory allocated. */
void Destroy();
public:
ThreadSafeSmartPointer();
ThreadSafeSmartPointer(UniquePointer<T>& up);
ThreadSafeSmartPointer(T* p);
ThreadSafeSmartPointer(const ThreadSafeSmartPointer& d);
virtual~ThreadSafeSmartPointer();
ThreadSafeSmartPointer<T>& operator= (const ThreadSafeSmartPointer<T>& p);
ThreadSafeSmartPointer<T>& operator= (UniquePointer<T>& p);
ThreadSafeSmartPointer<T>& operator= (T* p);
bool operator== (const ThreadSafeSmartPointer<T>& d) const;
bool operator== (const T& p) const;
bool operator!= (const ThreadSafeSmartPointer<T>& d) const;
bool operator!= (const T& p) const;
T& operator* ();
const T& operator* () const;
T* operator-> ();
const T* operator-> () const;
operator T* () const;
operator const T* () const;
operator T& () const;
operator bool() const;
/**
* Returns the connected pointer
*/
T* Get();
T* Get() const;
/**
* Releases one reference of the pointer and set value to null, making the current ThreadSafeSmartPointer invalid.
*/
int Release();
/**
* Only test to release to check reference count.
*/
int ReleaseDummy();
/** Checks if the pointer is valid (not NULL)
* Returns true for valid, else false.
*/
bool IsValid() const;
};
} }
} }

View File

@ -4,42 +4,31 @@
#include "CustomNetProtocol.h" #include "CustomNetProtocol.h"
#include <map> #include <map>
#include "Translator.h" #include "Translator.h"
#include "Utilities.h" #include <DynamicArray.h>
using namespace Oyster::Network; using namespace Oyster::Network;
using namespace Utility::DynamicMemory; using namespace Utility::DynamicMemory;
struct CustomNetProtocol::PrivateData struct CustomNetProtocol::PrivateData
{ {
std::map<int, NetAttributeContainer> attributes; //...Im an idiot //std::map<int, NetAttributeContainer> attributes; //...Im an idiot
Utility::DynamicMemory::ReferenceCount *c; DynamicArray<NetAttributeContainer> attributes; //...Im an idiot
PrivateData() PrivateData()
{ { }
//this->attributes = new std::map<int, NetAttributeContainer>();
this->c = new ReferenceCount();
c->Incref();
}
~PrivateData() ~PrivateData()
{ {
delete c; attributes.Clear();
c = 0;
for (auto i = attributes.begin(); i != attributes.end(); i++)
{
RemoveAttribute(i->first);
}
attributes.clear();
} }
void RemoveAttribute(int ID) void RemoveAttribute(NetAttributeContainer* i)
{ {
auto i = attributes.find(ID); if(!i) return;
if(i == attributes.end()) return;
switch (i->second.type) switch (i->type)
{ {
case NetAttributeType_CharArray: case NetAttributeType_CharArray:
delete [] i->second.value.netCharPtr; delete [] i->value.netCharPtr;
break; break;
} }
} }
@ -47,55 +36,42 @@ struct CustomNetProtocol::PrivateData
//Do network stuff //Do network stuff
}; };
CustomNetProtocol::CustomNetProtocol() CustomNetProtocol::CustomNetProtocol()
{ {
this->privateData = new PrivateData(); this->privateData = new PrivateData();
} }
CustomNetProtocol::CustomNetProtocol(const CustomNetProtocol& o) CustomNetProtocol::CustomNetProtocol(CustomNetProtocol& o)
{ {
this->privateData = o.privateData; this->privateData = new PrivateData();
if(this->privateData) this->privateData->attributes = o.privateData->attributes;
{
this->privateData->c = o.privateData->c;
this->privateData->c->Incref();
}
} }
const CustomNetProtocol& CustomNetProtocol::operator=(const CustomNetProtocol& o) const CustomNetProtocol& CustomNetProtocol::operator=(CustomNetProtocol& o)
{ {
if(this->privateData && this->privateData->c) if(this->privateData)
{ {
if(this->privateData->c->Decref() == 0) delete this->privateData;
{ this->privateData = 0;
delete this->privateData;
}
}
this->privateData = o.privateData;
if(this->privateData)
{
this->privateData->c = o.privateData->c;
this->privateData->c->Incref();
} }
this->privateData = new PrivateData();
this->privateData->attributes = o.privateData->attributes;
return *this; return *this;
} }
CustomNetProtocol::~CustomNetProtocol() CustomNetProtocol::~CustomNetProtocol()
{ {
if(this->privateData && this->privateData->c) delete this->privateData;
{ this->privateData = 0;
if(this->privateData->c->Decref() == 0)
{
delete this->privateData;
}
}
} }
NetAttributeContainer& CustomNetProtocol::operator[](int ID) NetAttributeContainer& CustomNetProtocol::operator[](int ID)
{ {
if(this->privateData->attributes.find(ID) == this->privateData->attributes.end()) //if(!this->privateData) this->privateData = new PrivateData();
if((unsigned int)ID >= this->privateData->attributes.Size())
{ {
this->privateData->attributes[ID]; NetAttributeContainer temp;
this->privateData->attributes[ID].type = NetAttributeType_UNKNOWN;
memset(&this->privateData->attributes[ID].value, 0, sizeof(NetAttributeValue)); temp.type = NetAttributeType_UNKNOWN;
memset(&temp.value, 0, sizeof(NetAttributeValue));
this->privateData->attributes.Push(ID, temp);
} }
return this->privateData->attributes[ID]; return this->privateData->attributes[ID];
@ -134,4 +110,115 @@ void CustomNetProtocol::Set(int ID, std::string s)
const NetAttributeContainer& CustomNetProtocol::Get(int id) const NetAttributeContainer& CustomNetProtocol::Get(int id)
{ {
return this->privateData->attributes[id]; return this->privateData->attributes[id];
} }
///////////////////////////////////////////////////////////////////////
//// Created by [Dennis Andersen] [2013]
///////////////////////////////////////////////////////////////////////
//#include "CustomNetProtocol.h"
//#include <map>
//#include "Translator.h"
//#include <DynamicArray.h>
//using namespace Oyster::Network;
//using namespace Utility::DynamicMemory;
//
//
//
//struct CustomNetProtocol::PrivateData
//{
// Utility::DynamicMemory::DynamicArray<NetAttributeContainer> attributes; //...Im an idiot
//
// PrivateData()
// { }
//
// ~PrivateData()
// {
// for (unsigned int i = 0; i < attributes.Size(); i++)
// {
// RemoveAttribute(i);
// }
//
// attributes.Clear();
// }
// void RemoveAttribute(int i)
// {
// switch (attributes[i].type)
// {
// case NetAttributeType_CharArray:
// delete [] attributes[i].value.netCharPtr;
// break;
// }
// }
//
// //Do network stuff
//};
//
//
//CustomNetProtocol::CustomNetProtocol()
//{
// this->privateData = new PrivateData();
//}
//CustomNetProtocol::CustomNetProtocol(const CustomNetProtocol& o)
//{
// this->privateData = o.privateData;
//}
//const CustomNetProtocol& CustomNetProtocol::operator=(const CustomNetProtocol& o)
//{
// this->privateData = o.privateData;
// return *this;
//}
//CustomNetProtocol::~CustomNetProtocol()
//{
//}
//NetAttributeContainer& CustomNetProtocol::operator[](int ID)
//{
// if(ID >= this->privateData->attributes.Size())
// this->privateData->attributes.Resize(
// if(this->privateData->attributes.find(ID) == this->privateData->attributes.end())
// {
// this->privateData->attributes[ID];
// this->privateData->attributes[ID].type = NetAttributeType_UNKNOWN;
// memset(&this->privateData->attributes[ID].value, 0, sizeof(NetAttributeValue));
// }
//
// return this->privateData->attributes[ID];
//}
//
//void CustomNetProtocol::Set(int ID, Oyster::Network::NetAttributeValue val, Oyster::Network::NetAttributeType type)
//{
// this->privateData->attributes[ID].type = type;
//
// switch (type)
// {
// case Oyster::Network::NetAttributeType_Bool:
// case Oyster::Network::NetAttributeType_Char:
// case Oyster::Network::NetAttributeType_UnsignedChar:
// case Oyster::Network::NetAttributeType_Short:
// case Oyster::Network::NetAttributeType_UnsignedShort:
// case Oyster::Network::NetAttributeType_Int:
// case Oyster::Network::NetAttributeType_UnsignedInt:
// case Oyster::Network::NetAttributeType_Int64:
// case Oyster::Network::NetAttributeType_UnsignedInt64:
// case Oyster::Network::NetAttributeType_Float:
// case Oyster::Network::NetAttributeType_Double:
// this->privateData->attributes[ID].value = val;
// break;
// }
//}
//void CustomNetProtocol::Set(int ID, std::string s)
//{
// if(s.size() == 0) return;
//
// this->privateData->attributes[ID].type = Oyster::Network::NetAttributeType_CharArray;
//
// this->privateData->attributes[ID].value.netCharPtr = new char[s.size() + 1];
// memcpy(&this->privateData->attributes[ID].value.netCharPtr[0], &s[0], s.size() + 1);
//}
//const NetAttributeContainer& CustomNetProtocol::Get(int id)
//{
// return this->privateData->attributes[id];
//}

View File

@ -4,7 +4,11 @@
#ifndef NETWORK_CUSTOM_NETWORK_PROTOCOL_H #ifndef NETWORK_CUSTOM_NETWORK_PROTOCOL_H
#define NETWORK_CUSTOM_NETWORK_PROTOCOL_H #define NETWORK_CUSTOM_NETWORK_PROTOCOL_H
//needs to have dll-interface to be used by clients of class 'Oyster::Network::NetworkSession'
#pragma warning(disable : 4251)
#include <string> #include <string>
#include "Utilities.h"
//#include <vld.h> //#include <vld.h>
#include "NetworkAPI_Preprocessor.h" #include "NetworkAPI_Preprocessor.h"
@ -65,12 +69,60 @@ namespace Oyster
{ {
NetAttributeType type; NetAttributeType type;
NetAttributeValue value; NetAttributeValue value;
NetAttributeContainer() { type = NetAttributeType_UNKNOWN; } NetAttributeContainer()
{ type = NetAttributeType_UNKNOWN; }
~NetAttributeContainer()
{
if (this->type == NetAttributeType_CharArray)
{
delete this->value.netCharPtr;
this->value.netCharPtr = 0;
}
}
NetAttributeContainer(NetAttributeContainer& p)
{
type = p.type;
if(type == NetAttributeType_CharArray && p.value.netCharPtr)
{
int len = 0;
if((len = strlen(p.value.netCharPtr)) == 0) return;
len++;
value.netCharPtr = new char[len];
memcpy(&value.netCharPtr[0], &p.value.netCharPtr[0], sizeof(p.value.netCharPtr[0]) * len);
}
else
{
value = p.value;
}
}
const NetAttributeContainer& operator=(const NetAttributeContainer& p)
{
if(this->type == NetAttributeType_CharArray)
{
delete this->value.netCharPtr;
this->value.netCharPtr = 0;
}
type = p.type;
if(type == NetAttributeType_CharArray && p.value.netCharPtr)
{
int len = 0;
if((len = strlen(p.value.netCharPtr)) == 0) return *this;
len++;
value.netCharPtr = new char[len];
memcpy(&value.netCharPtr[0], &p.value.netCharPtr[0], sizeof(p.value.netCharPtr[0]) * len);
}
else
{
value = p.value;
}
return *this;
}
}; };
class CustomNetProtocol; class CustomNetProtocol;
struct CustomProtocolObject struct CustomProtocolObject
{ {
virtual CustomNetProtocol* GetProtocol() = 0; virtual CustomNetProtocol GetProtocol() = 0;
}; };
class NET_API_EXPORT CustomNetProtocol class NET_API_EXPORT CustomNetProtocol
@ -78,8 +130,8 @@ namespace Oyster
public: public:
CustomNetProtocol(); CustomNetProtocol();
~CustomNetProtocol(); ~CustomNetProtocol();
CustomNetProtocol(const CustomNetProtocol& o); CustomNetProtocol(CustomNetProtocol& o);
const CustomNetProtocol& operator=(const CustomNetProtocol& o); const CustomNetProtocol& operator=(CustomNetProtocol& o);
NetAttributeContainer& operator[](int ID); NetAttributeContainer& operator[](int ID);
void Set(int id, Oyster::Network::NetAttributeValue val, Oyster::Network::NetAttributeType type); void Set(int id, Oyster::Network::NetAttributeValue val, Oyster::Network::NetAttributeType type);
@ -88,6 +140,8 @@ namespace Oyster
private: private:
struct PrivateData; struct PrivateData;
//Utility::DynamicMemory::SmartPointer<PrivateData> privateData;
//Utility::Thread::ThreadSafeSmartPointer<PrivateData> privateData;
PrivateData* privateData; PrivateData* privateData;
friend class Translator; friend class Translator;

View File

@ -19,6 +19,7 @@
#include "../../Misc/Packing/Packing.h" #include "../../Misc/Packing/Packing.h"
#include <queue> #include <queue>
#include <WinSock2.h>
using namespace Oyster::Network; using namespace Oyster::Network;
using namespace Oyster::Thread; using namespace Oyster::Thread;
@ -61,9 +62,10 @@ struct NetworkClient::PrivateData : public IThreadObject
} }
~PrivateData() ~PrivateData()
{ {
this->thread.Terminate();
ShutdownWinSock(); ShutdownWinSock();
this->connection.Disconnect(); this->connection.Disconnect();
this->thread.Terminate();
this->owner = 0; this->owner = 0;
this->parent = 0; this->parent = 0;
} }
@ -83,12 +85,13 @@ struct NetworkClient::PrivateData : public IThreadObject
if(!this->sendQueue.IsEmpty()) if(!this->sendQueue.IsEmpty())
{ {
SmartPointer<OysterByte> temp = new OysterByte(); //printf("\t(%i)\n", this->sendQueue.Size());
OysterByte temp;
CustomNetProtocol p = this->sendQueue.Pop(); CustomNetProtocol p = this->sendQueue.Pop();
this->translator.Pack(temp, p); this->translator.Pack(temp, p);
errorCode = this->connection.Send(temp); errorCode = this->connection.Send(temp);
if(errorCode != 0) if(errorCode != 0 && errorCode != WSAEWOULDBLOCK)
{ {
CEA parg; CEA parg;
parg.type = CEA::EventType_ProtocolFailedToSend; parg.type = CEA::EventType_ProtocolFailedToSend;
@ -204,7 +207,11 @@ struct NetworkClient::PrivateData : public IThreadObject
CEA parg; CEA parg;
parg.type = CEA::EventType_ProtocolRecieved; parg.type = CEA::EventType_ProtocolRecieved;
parg.data.protocol = protocol; parg.data.protocol = protocol;
NetEvent<NetworkClient*, NetworkClient::ClientEventArgs> e = { this->parent, parg }; NetEvent<NetworkClient*, NetworkClient::ClientEventArgs> e;
e.sender = this->parent;
e.args.data.protocol = parg.data.protocol;
e.args.type = parg.type;
this->recieveQueue.Push(e); this->recieveQueue.Push(e);
} }
} }
@ -247,9 +254,6 @@ void NetworkClient::Update()
this->DataRecieved(temp); this->DataRecieved(temp);
//--------- Deprecate ---------
this->NetworkCallback(temp.args.data.protocol);
//------------------------------
} }
} }
@ -291,18 +295,23 @@ bool NetworkClient::Connect(unsigned short port, const char serverIP[])
void NetworkClient::Disconnect() void NetworkClient::Disconnect()
{ {
privateData->connection.Disconnect(); if(!privateData) return;
privateData->thread.Terminate(); privateData->thread.Terminate();
privateData->connection.Disconnect();
this->privateData->sendQueue.Clear();
this->privateData->recieveQueue.Clear();
} }
void NetworkClient::Send(CustomProtocolObject& protocol) void NetworkClient::Send(CustomProtocolObject& protocol)
{ {
this->privateData->sendQueue.Push(*protocol.GetProtocol()); this->privateData->sendQueue.Push(protocol.GetProtocol());
} }
void NetworkClient::Send(CustomNetProtocol* protocol) void NetworkClient::Send(CustomNetProtocol& protocol)
{ {
this->privateData->sendQueue.Push(*protocol); this->privateData->sendQueue.Push(protocol);
} }
void NetworkClient::SetOwner(NetworkSession* owner) void NetworkClient::SetOwner(NetworkSession* owner)
@ -329,8 +338,8 @@ void NetworkClient::DataRecieved(NetEvent<NetworkClient*, ClientEventArgs> e)
} }
} }
void NetworkClient::NetworkCallback(Oyster::Network::CustomNetProtocol& p) //void NetworkClient::NetworkCallback(Oyster::Network::CustomNetProtocol& p)
{} //{}
std::string NetworkClient::GetIpAddress() std::string NetworkClient::GetIpAddress()
{ {

View File

@ -36,7 +36,33 @@ namespace Oyster
{ {
struct { Oyster::Network::CustomNetProtocol protocol; }; struct { Oyster::Network::CustomNetProtocol protocol; };
void * nothing; void * nothing;
EventData(){}
EventData(Oyster::Network::CustomNetProtocol& o)
{
protocol = o;
}
const EventData& operator=(EventData& o)
{
protocol = o.protocol;
return *this;
}
const EventData& operator=(Oyster::Network::CustomNetProtocol& o)
{
protocol = o; return *this;
}
} data; } data;
ClientEventArgs(){}
ClientEventArgs(ClientEventArgs& o)
{
type = o.type;
data = o.data;
}
const ClientEventArgs& operator=(ClientEventArgs& o)
{
type = o.type;
data = o.data;
return *this;
}
}; };
typedef void(*ClientEventFunction)(NetEvent<NetworkClient*, ClientEventArgs> e); typedef void(*ClientEventFunction)(NetEvent<NetworkClient*, ClientEventArgs> e);
@ -75,7 +101,7 @@ namespace Oyster
/** /**
* *
*/ */
void Send(CustomNetProtocol* protocol); void Send(CustomNetProtocol& protocol);
/** /**
* *
@ -101,7 +127,7 @@ namespace Oyster
* Do not use this furthermore, instead use void DataRecieved(NetEvent<NetworkClient*, ClientEventArgs> e); * Do not use this furthermore, instead use void DataRecieved(NetEvent<NetworkClient*, ClientEventArgs> e);
* @see DataRecieved * @see DataRecieved
*/ */
virtual void NetworkCallback(Oyster::Network::CustomNetProtocol& p); //virtual void NetworkCallback(Oyster::Network::CustomNetProtocol& p);
virtual std::string GetIpAddress(); virtual std::string GetIpAddress();

View File

@ -261,7 +261,7 @@ NetworkSession const* NetworkServer::ReleaseMainSession()
return temp; return temp;
} }
bool NetworkServer::IsStarted() const bool NetworkServer::IsRunning() const
{ {
return this->privateData->isRunning; return this->privateData->isRunning;
} }

View File

@ -77,7 +77,7 @@ namespace Oyster
/** /**
* *
*/ */
bool IsStarted() const; bool IsRunning() const;
/** /**
* *

View File

@ -26,7 +26,15 @@ struct NetworkSession::PrivateSessionData
{} {}
}; };
int FindClient(NetClientList& list, NetClient c)
{
for (unsigned int i = 0; i < list.Size(); i++)
{
if(c == list[i])
return i;
}
return -1;
}
NetworkSession::NetworkSession() NetworkSession::NetworkSession()
: data(new PrivateSessionData()) : data(new PrivateSessionData())
@ -125,7 +133,7 @@ NetClient NetworkSession::Detach(const NetworkClient* client)
for (unsigned int i = 0; i < this->clients.Size(); i++) for (unsigned int i = 0; i < this->clients.Size(); i++)
{ {
if(this->clients[i] && this->clients[0]->GetID() == client->GetID()) if(this->clients[i] && this->clients[i]->GetID() == client->GetID())
{ {
val = this->clients[i]; val = this->clients[i];
this->clients[i] = 0; this->clients[i] = 0;
@ -188,7 +196,7 @@ bool NetworkSession::Send(Oyster::Network::CustomNetProtocol& protocol)
{ {
if(this->clients[i]) if(this->clients[i])
{ {
this->clients[i]->Send(&protocol); this->clients[i]->Send(protocol);
returnValue = true; returnValue = true;
} }
} }
@ -202,7 +210,7 @@ bool NetworkSession::Send(Oyster::Network::CustomNetProtocol& protocol, int ID)
{ {
if(this->clients[i] && this->clients[i]->GetID() == ID) if(this->clients[i] && this->clients[i]->GetID() == ID)
{ {
this->clients[i]->Send(&protocol); this->clients[i]->Send(protocol);
return true; return true;
} }
} }
@ -237,5 +245,8 @@ void NetworkSession::SetOwner(NetworkSession* owner)
void NetworkSession::ClientConnectedEvent(NetClient client) void NetworkSession::ClientConnectedEvent(NetClient client)
{ {
this->Attach(client); this->Attach(client);
if(FindClient(this->clients, client) == -1)
NetworkSession::Attach(client);
} }

View File

@ -8,17 +8,18 @@
#include "../../Misc/Utilities.h" #include "../../Misc/Utilities.h"
#include "../NetworkDependencies/Messages/MessageHeader.h" #include "../NetworkDependencies/Messages/MessageHeader.h"
#include "../NetworkDependencies/OysterByte.h" #include "../NetworkDependencies/OysterByte.h"
#include <DynamicArray.h>
using namespace Oyster::Network; using namespace Oyster::Network;
using namespace ::Messages; using namespace ::Messages;
using namespace Utility::DynamicMemory; using namespace Utility::DynamicMemory;
using namespace std; using namespace std;
//TODO: Fix this uggly hack
struct MyCastingStruct struct MyCastingStruct
{ {
std::map<int, NetAttributeContainer> attributes; Utility::DynamicMemory::DynamicArray<NetAttributeContainer> attributes;
Utility::DynamicMemory::ReferenceCount *c;
}; };
// TODO: Check if the package has been packed correctly. // TODO: Check if the package has been packed correctly.
@ -43,7 +44,7 @@ struct Translator::PrivateData
//Find all the data types //Find all the data types
for(; it != end; it++) for(; it != end; it++)
{ {
headerString.push_back(it->second.type); headerString.push_back(it->type);
} }
message.PackShort(headerString.size(), bytes); message.PackShort(headerString.size(), bytes);
@ -68,40 +69,40 @@ struct Translator::PrivateData
switch((int)headerString.at(i)) switch((int)headerString.at(i))
{ {
case NetAttributeType_Bool: case NetAttributeType_Bool:
message.PackBool(it->second.value.netBool, bytes); message.PackBool(it->value.netBool, bytes);
break; break;
case NetAttributeType_Char: case NetAttributeType_Char:
message.PackChar(it->second.value.netChar, bytes); message.PackChar(it->value.netChar, bytes);
break; break;
case NetAttributeType_UnsignedChar: case NetAttributeType_UnsignedChar:
message.PackUnsignedChar(it->second.value.netUChar, bytes); message.PackUnsignedChar(it->value.netUChar, bytes);
break; break;
case NetAttributeType_Short: case NetAttributeType_Short:
message.PackShort(it->second.value.netShort, bytes); message.PackShort(it->value.netShort, bytes);
break; break;
case NetAttributeType_UnsignedShort: case NetAttributeType_UnsignedShort:
message.PackUnsignedShort(it->second.value.netUShort, bytes); message.PackUnsignedShort(it->value.netUShort, bytes);
break; break;
case NetAttributeType_Int: case NetAttributeType_Int:
message.PackInt(it->second.value.netInt, bytes); message.PackInt(it->value.netInt, bytes);
break; break;
case NetAttributeType_UnsignedInt: case NetAttributeType_UnsignedInt:
message.PackUnsignedInt(it->second.value.netUInt, bytes); message.PackUnsignedInt(it->value.netUInt, bytes);
break; break;
case NetAttributeType_Int64: case NetAttributeType_Int64:
message.PackInt64(it->second.value.netInt64, bytes); message.PackInt64(it->value.netInt64, bytes);
break; break;
case NetAttributeType_UnsignedInt64: case NetAttributeType_UnsignedInt64:
message.PackUnsignedInt64(it->second.value.netUInt64, bytes); message.PackUnsignedInt64(it->value.netUInt64, bytes);
break; break;
case NetAttributeType_Float: case NetAttributeType_Float:
message.PackFloat(it->second.value.netFloat, bytes); message.PackFloat(it->value.netFloat, bytes);
break; break;
case NetAttributeType_Double: case NetAttributeType_Double:
message.PackDouble(it->second.value.netDouble, bytes); message.PackDouble(it->value.netDouble, bytes);
break; break;
case NetAttributeType_CharArray: case NetAttributeType_CharArray:
message.PackStr(it->second.value.netCharPtr, bytes); message.PackStr(it->value.netCharPtr, bytes);
break; break;
default: default:
numberOfUnknownTypes++; numberOfUnknownTypes++;
@ -215,6 +216,7 @@ const Translator& Translator::operator=(const Translator& obj)
void Translator::Pack(OysterByte &bytes, CustomNetProtocol& protocol) void Translator::Pack(OysterByte &bytes, CustomNetProtocol& protocol)
{ {
privateData->headerString.clear(); privateData->headerString.clear();
privateData->PackHeader(bytes, protocol); privateData->PackHeader(bytes, protocol);

View File

@ -15,6 +15,11 @@ IDXGISwapChain* Core::swapChain = NULL;
std::stringstream Core::log; std::stringstream Core::log;
Oyster::Resource::ResourceManager Core::loader;
std::wstring Core::modelPath;
std::wstring Core::texturePath;
ID3D11RenderTargetView* Core::backBufferRTV = NULL; ID3D11RenderTargetView* Core::backBufferRTV = NULL;
ID3D11UnorderedAccessView* Core::backBufferUAV = NULL; ID3D11UnorderedAccessView* Core::backBufferUAV = NULL;

View File

@ -7,6 +7,7 @@
#include "Dx11Includes.h" #include "Dx11Includes.h"
#include <sstream> #include <sstream>
#include "OysterMath.h" #include "OysterMath.h"
#include "../Misc/Resource/ResourceManager.h"
//#include <vld.h> //#include <vld.h>
namespace Oyster namespace Oyster
@ -25,6 +26,10 @@ namespace Oyster
static std::stringstream log; static std::stringstream log;
static Resource::ResourceManager loader;
static std::wstring modelPath, texturePath;
//BackBufferRTV //BackBufferRTV
static ID3D11RenderTargetView* backBufferRTV; static ID3D11RenderTargetView* backBufferRTV;
//BackBufferUAV //BackBufferUAV

View File

@ -2,7 +2,6 @@
#include <fstream> #include <fstream>
#include <map> #include <map>
#include "../FileLoader/GeneralLoader.h" #include "../FileLoader/GeneralLoader.h"
#include "Resource\OysterResource.h"
const char* ShaderFunction = "main"; const char* ShaderFunction = "main";
@ -49,7 +48,7 @@ namespace Oyster
case Oyster::Graphics::Core::PipelineManager::Vertex: case Oyster::Graphics::Core::PipelineManager::Vertex:
if(!VSMap.count(name) || ForceReload) if(!VSMap.count(name) || ForceReload)
{ {
data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderV, -1, ForceReload); data = Core::loader.LoadResource(filename.c_str(),Loading::LoadShaderV, Loading::UnloadShaderV, -1, ForceReload);
if(data) if(data)
{ {
if(ForceReload && VSMap.count(name)) if(ForceReload && VSMap.count(name))
@ -65,7 +64,7 @@ namespace Oyster
} }
break; break;
case Oyster::Graphics::Core::PipelineManager::Hull: case Oyster::Graphics::Core::PipelineManager::Hull:
data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderH, -1, ForceReload); data = Core::loader.LoadResource(filename.c_str(),Loading::LoadShaderH, Loading::UnloadShaderH, -1, ForceReload);
if(!HSMap.count(name) || ForceReload) if(!HSMap.count(name) || ForceReload)
{ {
if(data!=0) if(data!=0)
@ -84,7 +83,7 @@ namespace Oyster
} }
break; break;
case Oyster::Graphics::Core::PipelineManager::Domain: case Oyster::Graphics::Core::PipelineManager::Domain:
data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderD, -1, ForceReload); data = Core::loader.LoadResource(filename.c_str(),Loading::LoadShaderD, Loading::UnloadShaderD, -1, ForceReload);
if(!DSMap.count(name) || ForceReload) if(!DSMap.count(name) || ForceReload)
{ {
if(data!=0) if(data!=0)
@ -102,7 +101,7 @@ namespace Oyster
} }
break; break;
case Oyster::Graphics::Core::PipelineManager::Geometry: case Oyster::Graphics::Core::PipelineManager::Geometry:
data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderG, -1, ForceReload); data = Core::loader.LoadResource(filename.c_str(),Loading::LoadShaderG, Loading::UnloadShaderG, -1, ForceReload);
if(!GSMap.count(name) || ForceReload) if(!GSMap.count(name) || ForceReload)
{ {
if(data!=0) if(data!=0)
@ -120,7 +119,7 @@ namespace Oyster
} }
break; break;
case Oyster::Graphics::Core::PipelineManager::Pixel: case Oyster::Graphics::Core::PipelineManager::Pixel:
data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderP, -1, ForceReload); data = Core::loader.LoadResource(filename.c_str(),Loading::LoadShaderP, Loading::UnloadShaderP, -1, ForceReload);
if(!PSMap.count(name) || ForceReload) if(!PSMap.count(name) || ForceReload)
{ {
if(data!=0) if(data!=0)
@ -138,7 +137,7 @@ namespace Oyster
} }
break; break;
case Oyster::Graphics::Core::PipelineManager::Compute: case Oyster::Graphics::Core::PipelineManager::Compute:
data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderC, -1, ForceReload); data = Core::loader.LoadResource(filename.c_str(),Loading::LoadShaderC, Loading::UnloadShaderC, -1, ForceReload);
if(!CSMap.count(name) || ForceReload) if(!CSMap.count(name) || ForceReload)
{ {
if(data!=0) if(data!=0)

View File

@ -14,12 +14,6 @@ namespace Oyster
Oyster::Math::Float3 normal; Oyster::Math::Float3 normal;
}; };
struct VP
{
Oyster::Math::Matrix V;
Oyster::Math::Matrix P;
};
struct PerModel struct PerModel
{ {
Math::Matrix WV; Math::Matrix WV;
@ -55,6 +49,13 @@ namespace Oyster
float Bright; float Bright;
}; };
struct AnimationData
{
Math::Float4x4 animatedData[100];
int Animated;
Math::Float3 Pad;
};
} }
} }
} }

View File

@ -4,7 +4,8 @@
#include "../Render/Resources/Deffered.h" #include "../Render/Resources/Deffered.h"
#include "../Render/Rendering/Render.h" #include "../Render/Rendering/Render.h"
#include "../FileLoader/ObjReader.h" #include "../FileLoader/ObjReader.h"
#include "../../Misc/Resource/OysterResource.h" //#include "../../Misc/Resource/OysterResource.h"
#include "../../Misc/Resource/ResourceManager.h"
#include "../FileLoader/GeneralLoader.h" #include "../FileLoader/GeneralLoader.h"
#include "../Model/ModelInfo.h" #include "../Model/ModelInfo.h"
#include <vld.h> #include <vld.h>
@ -73,6 +74,8 @@ namespace Oyster
API::State API::SetOptions(API::Option option) API::State API::SetOptions(API::Option option)
{ {
Core::modelPath = option.modelPath;
Core::texturePath = option.texturePath;
return API::Sucsess; return API::Sucsess;
} }
@ -82,8 +85,8 @@ namespace Oyster
Model::Model* m = new Model::Model(); Model::Model* m = new Model::Model();
m->WorldMatrix = Oyster::Math::Float4x4::identity; m->WorldMatrix = Oyster::Math::Float4x4::identity;
m->Visible = true; m->Visible = true;
m->AnimationPlaying = -1;
m->info = Oyster::Resource::OysterResource::LoadResource(filename.c_str(),Oyster::Graphics::Loading::LoadDAN); m->info = (Model::ModelInfo*)Core::loader.LoadResource((Core::modelPath + filename).c_str(),Oyster::Graphics::Loading::LoadDAN, Oyster::Graphics::Loading::UnloadDAN);
Model::ModelInfo* mi = (Model::ModelInfo*)m->info; Model::ModelInfo* mi = (Model::ModelInfo*)m->info;
if(!mi || mi->Vertices->GetBufferPointer() == NULL) if(!mi || mi->Vertices->GetBufferPointer() == NULL)
@ -101,13 +104,13 @@ namespace Oyster
return; return;
Model::ModelInfo* info = (Model::ModelInfo*)model->info; Model::ModelInfo* info = (Model::ModelInfo*)model->info;
delete model; delete model;
Oyster::Resource::OysterResource::ReleaseResource((Oyster::Resource::OHRESOURCE)info); Core::loader.ReleaseResource(info);
} }
void API::Clean() void API::Clean()
{ {
SAFE_DELETE(Core::viewPort); SAFE_DELETE(Core::viewPort);
Oyster::Resource::OysterResource::Clean(); Core::loader.Clean();
Oyster::Graphics::Core::PipelineManager::Clean(); Oyster::Graphics::Core::PipelineManager::Clean();
Oyster::Graphics::Render::Resources::Deffered::Clean(); Oyster::Graphics::Render::Resources::Deffered::Clean();

View File

@ -26,6 +26,7 @@ namespace Oyster
}; };
struct Option struct Option
{ {
std::wstring modelPath, texturePath;
}; };
static State Init(HWND Window, bool MSAA_Quality, bool Fullscreen, Oyster::Math::Float2 StartResulotion); static State Init(HWND Window, bool MSAA_Quality, bool Fullscreen, Oyster::Math::Float2 StartResulotion);

View File

@ -102,211 +102,320 @@ struct MaterialHeader
/// ///
struct SkeletonHeader struct SkeletonHeader
{ {
// do this... unsigned int numBones;
///
SkeletonHeader(char* data)
{
memcpy(&numBones, data, sizeof(unsigned int));
}
}; };
/// ///
struct AnimationHeader struct AnimationHeader
{ {
// do this... unsigned int numAnims;
};
struct Frame
{ AnimationHeader(char* data)
// do this... {
memcpy(&numAnims, data, sizeof(unsigned int));
}
}; };
/// ///
void Oyster::Graphics::Loading::UnloadDAN(void* data) void Oyster::Graphics::Loading::UnloadDAN(void* data)
{
Model::ModelInfo* info = (Model::ModelInfo*) data;
SAFE_DELETE(info->Vertices);
if(info->Indexed)
{
SAFE_DELETE(info->Indecies);
}
for(int i =0;i<info->Material.size();++i)
{
Oyster::Resource::OysterResource::ReleaseResource(info->Material[i]);
}
delete info;
}
static std::wstring charToWChar(const char* text)
{ {
// Convert to a wchar_t* Model::ModelInfo* info = (Model::ModelInfo*) data;
size_t origsize = strlen(text) + 1; SAFE_DELETE(info->Vertices);
size_t convertedChars = 0; if(info->Indexed)
//wchar_t* wcstring = new wchar_t[origsize]; {
std::wstring wcstring; wcstring.resize(origsize); SAFE_DELETE(info->Indecies);
mbstowcs_s(&convertedChars, &wcstring[0], origsize, text, _TRUNCATE); }
if(info->Animated)
{
//clean animation
delete[] info->bones;
for(int a = 0; a < info->AnimationCount; ++a)
{
for(int x = 0; x < info->Animations[a].Bones; ++x)
{
delete[] info->Animations[a].Keyframes[x];
}
delete[] info->Animations[a].Frames;
delete[] info->Animations[a].Keyframes;
}
delete[] info->Animations;
}
for(int i =0;i<info->Material.size();++i)
{
Core::loader.ReleaseResource(info->Material[i]);
}
delete info;
}
static wchar_t* charToWChar(const char* text)
{
// Convert to a wchar_t*
size_t origsize = strlen(text) + 1;
size_t convertedChars = 0;
wchar_t* wcstring = new wchar_t[origsize];
mbstowcs_s(&convertedChars, wcstring, origsize, text, _TRUNCATE);
return wcstring; return wcstring;
} }
/// static void ReadData(void* Destination, std::ifstream& file, int size)
void Oyster::Graphics::Loading::LoadDAN(const wchar_t filename[], Oyster::Resource::CustomData& out) {
{ char* buffer = new char[size];
// file.read(buffer,size);
Oyster::Graphics::Model::ModelInfo* modelInfo = new Oyster::Graphics::Model::ModelInfo(); memcpy(Destination,buffer,size);
modelInfo->Indexed = false; delete[] buffer;
// Open file in binary mode }
///
void* Oyster::Graphics::Loading::LoadDAN(const wchar_t filename[])
{
//
Oyster::Graphics::Model::ModelInfo* modelInfo = new Oyster::Graphics::Model::ModelInfo();
modelInfo->Indexed = false;
modelInfo->Animated = false;
// Open file in binary mode
std::ifstream danFile; std::ifstream danFile;
danFile.open(filename, std::ios::binary); danFile.open(filename, std::ios::binary);
if (!danFile.is_open()) if (!danFile.is_open())
return; return NULL;
// Read file header
char* buffer = new char[sizeof(FileHeader)];
danFile.read(buffer, sizeof(FileHeader));
FileHeader fileHeader(buffer);
delete[] buffer; // ( note: may crash here.)
// If problem with compatability then close file and return from method
if (fileHeader.versionMajor != DANFILEVERSIONMAJOR)
{
danFile.close();
return;
}
// Read the .dan-file
while (!danFile.eof())
{
// read header type
unsigned int headerType;
buffer = new char[4];
danFile.read(buffer, 4);
memcpy(&headerType, buffer, 4);
delete[] buffer; // ( note: may crash here.)
// handle header type
switch ((HeaderType)headerType)
{
// vertex header
case HeaderType::VERTEXHEADER:
{
// Fetch vertex header, number of vertices
buffer = new char[4];
danFile.read(buffer, 4);
VertexHeader vertexHeader(buffer);
delete[] buffer; // ( note: may crash here.)
// Fetch all vertices
Vertex* vertices = new Vertex[vertexHeader.numVertices];
unsigned int bufferSize = VERTEXSIZE * vertexHeader.numVertices;
buffer = new char[bufferSize];
danFile.read(buffer, bufferSize);
memcpy(vertices, buffer, bufferSize);
delete[] buffer; // ( note: may crash here.)
// Do the deed
Oyster::Graphics::Core::Buffer* vertexBuffer = new Oyster::Graphics::Core::Buffer();
Oyster::Graphics::Core::Buffer::BUFFER_INIT_DESC bufferInitDesc;
bufferInitDesc.ElementSize = sizeof(Vertex);
bufferInitDesc.InitData = vertices;
bufferInitDesc.NumElements = vertexHeader.numVertices;
bufferInitDesc.Type = Oyster::Graphics::Core::Buffer::BUFFER_TYPE::VERTEX_BUFFER;
bufferInitDesc.Usage = Oyster::Graphics::Core::Buffer::BUFFER_USAGE::BUFFER_DEFAULT;
vertexBuffer->Init(bufferInitDesc);
modelInfo->VertexCount = vertexHeader.numVertices;
modelInfo->Vertices = vertexBuffer;
delete[] vertices; // ( note: may crash here.)
break;
}
case HeaderType::INDEXHEADER:
{
// Fetch vertex header, number of vertices
buffer = new char[4];
danFile.read(buffer, 4);
IndexHeader indexHeader(buffer);
delete[] buffer; // ( note: may crash here.)
// Fetch all indices
unsigned int* indices = new unsigned int[indexHeader.numIndices];
unsigned int bufferSize = sizeof(unsigned int) * indexHeader.numIndices;
buffer = new char[bufferSize];
danFile.read(buffer, bufferSize);
memcpy(indices, buffer, bufferSize);
delete[] buffer; // ( note: may crash here.)
// Do the deed
Oyster::Graphics::Core::Buffer* indexBuffer = new Oyster::Graphics::Core::Buffer();
Oyster::Graphics::Core::Buffer::BUFFER_INIT_DESC bufferInitDesc;
bufferInitDesc.ElementSize = sizeof(unsigned int);
bufferInitDesc.InitData = indices;
bufferInitDesc.NumElements = indexHeader.numIndices;
bufferInitDesc.Type = Oyster::Graphics::Core::Buffer::BUFFER_TYPE::INDEX_BUFFER;
bufferInitDesc.Usage = Oyster::Graphics::Core::Buffer::BUFFER_USAGE::BUFFER_DEFAULT;
indexBuffer->Init(bufferInitDesc);
modelInfo->IndexCount = indexHeader.numIndices;
modelInfo->Indecies = indexBuffer;
modelInfo->Indexed = true;
delete[] indices; // ( note: may crash here.)
break;
}
// material header
case HeaderType::MATERIALHEADER:
{
// Fetch material header, 2 texture path strings
MaterialHeader materialHeader;
buffer = new char[4];
danFile.read(buffer, 4);
memcpy(&materialHeader.diffuseMapPathLength, buffer, 4);
delete[] buffer; // ( note: may crash here.)
buffer = new char[materialHeader.diffuseMapPathLength]; // Read file header
danFile.read(buffer, materialHeader.diffuseMapPathLength); char* buffer = new char[sizeof(FileHeader)];
danFile.read(buffer, sizeof(FileHeader));
FileHeader fileHeader(buffer);
delete[] buffer; // ( note: may crash here.)
// If problem with compatability then close file and return from method
if (fileHeader.versionMajor != DANFILEVERSIONMAJOR)
{
danFile.close();
return NULL;
}
// Read the .dan-file
while (!danFile.eof())
{
// read header type
unsigned int headerType;
ReadData(&headerType,danFile,4);
// handle header type
switch ((HeaderType)headerType)
{
// vertex header
case HeaderType::VERTEXHEADER:
{
// Fetch vertex header, number of vertices
buffer = new char[4];
danFile.read(buffer, 4);
VertexHeader vertexHeader(buffer);
delete[] buffer; // ( note: may crash here.)
// Fetch all vertices
unsigned int bufferSize = VERTEXSIZE * vertexHeader.numVertices;
buffer = new char[bufferSize];
danFile.read(buffer, bufferSize);
// Do the deed
Oyster::Graphics::Core::Buffer* vertexBuffer = new Oyster::Graphics::Core::Buffer();
Oyster::Graphics::Core::Buffer::BUFFER_INIT_DESC bufferInitDesc;
bufferInitDesc.ElementSize = sizeof(Vertex);
bufferInitDesc.InitData = buffer;
bufferInitDesc.NumElements = vertexHeader.numVertices;
bufferInitDesc.Type = Oyster::Graphics::Core::Buffer::BUFFER_TYPE::VERTEX_BUFFER;
bufferInitDesc.Usage = Oyster::Graphics::Core::Buffer::BUFFER_USAGE::BUFFER_DEFAULT;
vertexBuffer->Init(bufferInitDesc);
modelInfo->VertexCount = vertexHeader.numVertices;
modelInfo->Vertices = vertexBuffer;
delete[] buffer; // ( note: may crash here.)
break;
}
case HeaderType::INDEXHEADER:
{
// Fetch vertex header, number of vertices
buffer = new char[4];
danFile.read(buffer, 4);
IndexHeader indexHeader(buffer);
delete[] buffer; // ( note: may crash here.)
// Fetch all indices
unsigned int* indices = new unsigned int[indexHeader.numIndices];
unsigned int bufferSize = sizeof(unsigned int) * indexHeader.numIndices;
ReadData(indices,danFile,bufferSize);
// Do the deed
Oyster::Graphics::Core::Buffer* indexBuffer = new Oyster::Graphics::Core::Buffer();
Oyster::Graphics::Core::Buffer::BUFFER_INIT_DESC bufferInitDesc;
bufferInitDesc.ElementSize = sizeof(unsigned int);
bufferInitDesc.InitData = indices;
bufferInitDesc.NumElements = indexHeader.numIndices;
bufferInitDesc.Type = Oyster::Graphics::Core::Buffer::BUFFER_TYPE::INDEX_BUFFER;
bufferInitDesc.Usage = Oyster::Graphics::Core::Buffer::BUFFER_USAGE::BUFFER_DEFAULT;
indexBuffer->Init(bufferInitDesc);
modelInfo->IndexCount = indexHeader.numIndices;
modelInfo->Indecies = indexBuffer;
modelInfo->Indexed = true;
delete[] indices; // ( note: may crash here.)
break;
}
// material header
case HeaderType::MATERIALHEADER:
{
// Fetch material header, 2 texture path strings
MaterialHeader materialHeader;
//read difuse map name length
ReadData(&materialHeader.diffuseMapPathLength,danFile,4);
//read diffuse map name
materialHeader.diffuseMapPath = new char[materialHeader.diffuseMapPathLength+1]; materialHeader.diffuseMapPath = new char[materialHeader.diffuseMapPathLength+1];
memcpy(materialHeader.diffuseMapPath, buffer, materialHeader.diffuseMapPathLength); ReadData(materialHeader.diffuseMapPath,danFile,materialHeader.diffuseMapPathLength);
materialHeader.diffuseMapPath[materialHeader.diffuseMapPathLength] = 0; //null terminate
delete[] buffer; // ( note: may crash here.) materialHeader.diffuseMapPath[materialHeader.diffuseMapPathLength] = 0;
buffer = new char[4]; //read normal map name length
danFile.read(buffer, 4); ReadData(&materialHeader.normalMapPathLength,danFile,4);
memcpy(&materialHeader.normalMapPathLength, buffer, 4);
delete[] buffer; // ( note: may crash here.)
buffer = new char[materialHeader.normalMapPathLength]; //read difuse map name
danFile.read(buffer, materialHeader.normalMapPathLength);
materialHeader.normalMapPath = new char[materialHeader.normalMapPathLength + 1]; materialHeader.normalMapPath = new char[materialHeader.normalMapPathLength + 1];
memcpy(materialHeader.normalMapPath, buffer, materialHeader.normalMapPathLength); ReadData(materialHeader.normalMapPath,danFile,materialHeader.normalMapPathLength);
materialHeader.normalMapPath[materialHeader.normalMapPathLength] = 0; materialHeader.normalMapPath[materialHeader.normalMapPathLength] = 0;
delete[] buffer; // ( note: may crash here.)
//load diffuse map
// wchar_t* path = charToWChar(materialHeader.diffuseMapPath);
ID3D11ShaderResourceView* diffuseMap = (ID3D11ShaderResourceView*)Oyster::Resource::OysterResource::LoadResource(charToWChar(materialHeader.diffuseMapPath).c_str(), Oyster::Graphics::Loading::LoadTexture); ID3D11ShaderResourceView* diffuseMap = (ID3D11ShaderResourceView*)Core::loader.LoadResource((Core::texturePath + path).c_str(), Oyster::Graphics::Loading::LoadTexture, Oyster::Graphics::Loading::UnloadTexture);
ID3D11ShaderResourceView* normalMap = (ID3D11ShaderResourceView*)Oyster::Resource::OysterResource::LoadResource(charToWChar(materialHeader.normalMapPath).c_str(), Oyster::Graphics::Loading::LoadTexture); delete[] path;
modelInfo->Material.push_back(diffuseMap);
modelInfo->Material.push_back(normalMap); //load normal map
path = charToWChar(materialHeader.normalMapPath);
delete materialHeader.normalMapPath; ID3D11ShaderResourceView* normalMap = (ID3D11ShaderResourceView*)Core::loader.LoadResource((Core::texturePath + path).c_str(), Oyster::Graphics::Loading::LoadTexture, Oyster::Graphics::Loading::UnloadTexture);
delete materialHeader.diffuseMapPath; delete[] path;
break; //add to model
} modelInfo->Material.push_back(diffuseMap);
// skeleton header modelInfo->Material.push_back(normalMap);
case HeaderType::SKELETONHEADER:
{ //clean up
// not implemented... delete[] materialHeader.diffuseMapPath;
break; delete[] materialHeader.normalMapPath;
}
// animation header break;
case HeaderType::ANIMATIONHEADER: }
{
// not implemented... // skeleton header
break; case HeaderType::SKELETONHEADER:
} {
} // Fetch Skeleton header, number of Bones
} buffer = new char[4];
danFile.read(buffer, 4);
SkeletonHeader skeletonHeader(buffer);
// close file delete[] buffer; // ( note: may crash here.)
danFile.close();
//array for bone data
// Set modelinfo as output data Oyster::Graphics::Model::Bone* bones = new Oyster::Graphics::Model::Bone[skeletonHeader.numBones];
out.loadedData = modelInfo;
out.resourceUnloadFnc = Oyster::Graphics::Loading::UnloadDAN; //read bones
ReadData(bones,danFile,skeletonHeader.numBones * sizeof(Oyster::Graphics::Model::Bone));
//read skeleton Hiarchy
modelInfo->BoneCount = skeletonHeader.numBones;
modelInfo->bones = bones;
break;
}
// animation header
case HeaderType::ANIMATIONHEADER:
{
//get num anims
buffer = new char[4];
danFile.read(buffer, 4);
AnimationHeader animationHeader(buffer);
delete[] buffer;
Oyster::Graphics::Model::Animation* anims = new Oyster::Graphics::Model::Animation[animationHeader.numAnims];
for(int a = 0; a < animationHeader.numAnims; ++a)
{
//read name of animation
int nameLength;
ReadData(&nameLength,danFile,4);
char* name = new char[nameLength + 1];
ReadData(name,danFile,nameLength);
name[nameLength] = 0;
wchar_t* wName = charToWChar(name);
anims[a].name = std::wstring(wName);
delete[] wName;
delete name;
//read nr of bones in animation
ReadData(&anims[a].Bones,danFile,4);
//read duration
ReadData(&anims[a].duration,danFile,8);
//create Frame array and Bone part of KeyFrameArray;
anims[a].Frames = new int[anims[a].Bones];
anims[a].Keyframes = new Oyster::Graphics::Model::Frame*[anims[a].Bones];
//loop per bone and gather data
for(int b = 0; b < anims[a].Bones; ++b)
{
//read bone index
int boneIndex;
ReadData(&boneIndex,danFile,4);
//read nr of frames per bone
ReadData(&anims[a].Frames[b],danFile,4);
//create frame matrix
anims[a].Keyframes[b] = new Oyster::Graphics::Model::Frame[anims[a].Frames[b]];
for(int f = 0; f < anims[a].Frames[b]; ++f)
{
//write index of bone
anims[a].Keyframes[b][f].bone.Parent = boneIndex;
//read bone transform
ReadData(&anims[a].Keyframes[b][f].bone.Transform,danFile,sizeof(Oyster::Math::Matrix));
ReadData(&anims[a].Keyframes[b][f].time,danFile,sizeof(double));
}
}
}
modelInfo->AnimationCount = animationHeader.numAnims;
modelInfo->Animations = anims;
modelInfo->Animated = true;
break;
}
}
}
// close file
danFile.close();
// Set modelinfo as output data
return modelInfo;
} }

View File

@ -1,5 +1,4 @@
#pragma once #pragma once
#include "..\..\Misc\Resource\OysterResource.h"
namespace Oyster namespace Oyster
{ {
namespace Graphics namespace Graphics
@ -7,31 +6,31 @@ namespace Oyster
namespace Loading namespace Loading
{ {
void UnloadTexture(void* loadedData); void UnloadTexture(void* loadedData);
void LoadTexture(const wchar_t filename[], Oyster::Resource::CustomData& out); void* LoadTexture(const wchar_t filename[]);
void UnloadShaderP(void* loadedData); void UnloadShaderP(void* loadedData);
void LoadShaderP(const wchar_t filename[], Oyster::Resource::CustomData& out); void* LoadShaderP(const wchar_t filename[]);
void UnloadShaderG(void* loadedData); void UnloadShaderG(void* loadedData);
void LoadShaderG(const wchar_t filename[], Oyster::Resource::CustomData& out); void* LoadShaderG(const wchar_t filename[]);
void UnloadShaderC(void* loadedData); void UnloadShaderC(void* loadedData);
void LoadShaderC(const wchar_t filename[], Oyster::Resource::CustomData& out); void* LoadShaderC(const wchar_t filename[]);
void UnloadShaderV(void* loadedData); void UnloadShaderV(void* loadedData);
void LoadShaderV(const wchar_t filename[], Oyster::Resource::CustomData& out); void* LoadShaderV(const wchar_t filename[]);
void UnloadShaderH(void* loadedData); void UnloadShaderH(void* loadedData);
void LoadShaderH(const wchar_t filename[], Oyster::Resource::CustomData& out); void* LoadShaderH(const wchar_t filename[]);
void UnloadShaderD(void* loadedData); void UnloadShaderD(void* loadedData);
void LoadShaderD(const wchar_t filename[], Oyster::Resource::CustomData& out); void* LoadShaderD(const wchar_t filename[]);
void UnloadOBJ(void* loadedData); void UnloadOBJ(void* loadedData);
void LoadOBJ(const wchar_t filename[], Oyster::Resource::CustomData& out); void* LoadOBJ(const wchar_t filename[]);
void UnloadDAN(void* loadedData); void UnloadDAN(void* loadedData);
void LoadDAN(const wchar_t filename[], Oyster::Resource::CustomData& out); void* LoadDAN(const wchar_t filename[]);
} }
} }
} }

View File

@ -2,7 +2,6 @@
#include "..\Core\Dx11Includes.h" #include "..\Core\Dx11Includes.h"
#include "..\Core\Core.h" #include "..\Core\Core.h"
#include "ObjReader.h" #include "ObjReader.h"
#include "..\..\Misc\Resource\OysterResource.h"
HRESULT CreateWICTextureFromFileEx( ID3D11Device* d3dDevice, HRESULT CreateWICTextureFromFileEx( ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext, ID3D11DeviceContext* d3dContext,
@ -16,18 +15,17 @@ HRESULT CreateWICTextureFromFileEx( ID3D11Device* d3dDevice,
ID3D11Resource** texture, ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView ); ID3D11ShaderResourceView** textureView );
void Oyster::Graphics::Loading::LoadTexture(const wchar_t filename[], Oyster::Resource::CustomData& out) void* Oyster::Graphics::Loading::LoadTexture(const wchar_t filename[])
{ {
ID3D11ShaderResourceView* srv = NULL; ID3D11ShaderResourceView* srv = NULL;
HRESULT hr = CreateWICTextureFromFileEx(Core::device,Core::deviceContext,filename,0,D3D11_USAGE_DEFAULT,D3D11_BIND_SHADER_RESOURCE,0,0,false,NULL,&srv); HRESULT hr = CreateWICTextureFromFileEx(Core::device,Core::deviceContext,filename,0,D3D11_USAGE_DEFAULT,D3D11_BIND_SHADER_RESOURCE,0,0,false,NULL,&srv);
if(hr!=S_OK) if(hr!=S_OK)
{ {
memset(&out,0,sizeof(out)); return NULL;
} }
else else
{ {
out.loadedData = (void*)srv; return srv;
out.resourceUnloadFnc = Loading::UnloadTexture;
} }
} }
@ -37,7 +35,7 @@ void Oyster::Graphics::Loading::UnloadTexture(void* data)
SAFE_RELEASE(srv); SAFE_RELEASE(srv);
} }
void Oyster::Graphics::Loading::LoadOBJ(const wchar_t filename[], Oyster::Resource::CustomData& out) void* Oyster::Graphics::Loading::LoadOBJ(const wchar_t filename[])
{ {
FileLoaders::ObjReader obj; FileLoaders::ObjReader obj;
obj.LoadFile(filename); obj.LoadFile(filename);
@ -57,12 +55,11 @@ void Oyster::Graphics::Loading::LoadOBJ(const wchar_t filename[], Oyster::Resour
info->Vertices->Init(desc); info->Vertices->Init(desc);
info->Indexed = false; info->Indexed = false;
void* texture = Oyster::Resource::OysterResource::LoadResource((std::wstring(filename)+ L".png").c_str(),Graphics::Loading::LoadTexture); void* texture = Core::loader.LoadResource((std::wstring(filename)+ L".png").c_str(),Graphics::Loading::LoadTexture, Graphics::Loading::UnloadTexture);
info->Material.push_back((ID3D11ShaderResourceView*)texture); info->Material.push_back((ID3D11ShaderResourceView*)texture);
out.loadedData = info; return info;
out.resourceUnloadFnc = Oyster::Graphics::Loading::UnloadOBJ;
} }
void Oyster::Graphics::Loading::UnloadOBJ(void* data) void Oyster::Graphics::Loading::UnloadOBJ(void* data)
@ -75,7 +72,7 @@ void Oyster::Graphics::Loading::UnloadOBJ(void* data)
} }
for(int i =0;i<info->Material.size();++i) for(int i =0;i<info->Material.size();++i)
{ {
Oyster::Resource::OysterResource::ReleaseResource(info->Material[i]); Core::loader.ReleaseResource(info->Material[i]);
} }
delete info; delete info;
} }

View File

@ -10,7 +10,7 @@ namespace Oyster
{ {
namespace Loading namespace Loading
{ {
void LoadShader(const wchar_t filename[], Oyster::Resource::CustomData& out, int type); void* LoadShader(const wchar_t filename[], int type);
void UnloadShaderP(void* loadedData) void UnloadShaderP(void* loadedData)
{ {
@ -48,78 +48,41 @@ namespace Oyster
SAFE_RELEASE(ps); SAFE_RELEASE(ps);
} }
void LoadShaderP(const wchar_t filename[], Oyster::Resource::CustomData& out) void* LoadShaderP(const wchar_t filename[])
{ {
LoadShader(filename,out,Core::PipelineManager::Pixel); return LoadShader(filename,Core::PipelineManager::Pixel);
if(out.loadedData==NULL)
{
memset(&out,0,sizeof(out));
return;
}
out.resourceUnloadFnc = UnloadShaderP;
} }
void LoadShaderG(const wchar_t filename[], Oyster::Resource::CustomData& out) void* LoadShaderG(const wchar_t filename[])
{ {
LoadShader(filename,out,Core::PipelineManager::Geometry); return LoadShader(filename,Core::PipelineManager::Geometry);
if(out.loadedData==NULL)
{
memset(&out,0,sizeof(out));
return;
}
out.resourceUnloadFnc = UnloadShaderG;
} }
void LoadShaderC(const wchar_t filename[], Oyster::Resource::CustomData& out) void* LoadShaderC(const wchar_t filename[])
{ {
LoadShader(filename,out,Core::PipelineManager::Compute); return LoadShader(filename,Core::PipelineManager::Compute);
if(out.loadedData==NULL)
{
memset(&out,0,sizeof(out));
return;
}
out.resourceUnloadFnc = UnloadShaderC;
} }
void LoadShaderH(const wchar_t filename[], Oyster::Resource::CustomData& out) void* LoadShaderH(const wchar_t filename[])
{ {
LoadShader(filename,out,Core::PipelineManager::Hull); return LoadShader(filename,Core::PipelineManager::Hull);
if(out.loadedData==NULL)
{
memset(&out,0,sizeof(out));
return;
}
out.resourceUnloadFnc = UnloadShaderH;
} }
void LoadShaderD(const wchar_t filename[], Oyster::Resource::CustomData& out) void* LoadShaderD(const wchar_t filename[])
{ {
LoadShader(filename,out,Core::PipelineManager::Domain); return LoadShader(filename,Core::PipelineManager::Domain);
if(out.loadedData==NULL)
{
memset(&out,0,sizeof(out));
return;
}
out.resourceUnloadFnc = UnloadShaderD;
} }
void LoadShaderV(const wchar_t filename[], Oyster::Resource::CustomData& out) void* LoadShaderV(const wchar_t filename[])
{ {
return LoadShader(filename,Core::PipelineManager::Vertex);
LoadShader(filename,out,Core::PipelineManager::Vertex);
if(out.loadedData==NULL)
{
memset(&out,0,sizeof(out));
return;
}
out.resourceUnloadFnc = UnloadShaderV;
} }
void LoadShader(const wchar_t filename[], Oyster::Resource::CustomData& out, int type) void* LoadShader(const wchar_t filename[], int type)
{ {
Core::PipelineManager::ShaderData data; Core::PipelineManager::ShaderData data;
#ifdef _DEBUG #ifdef _DEBUG
@ -159,8 +122,7 @@ namespace Oyster
{ {
Shader->Release(); Shader->Release();
} }
memset(&out,0,sizeof(out)); return NULL;
return;
} }
data.size = Shader->GetBufferSize(); data.size = Shader->GetBufferSize();
@ -181,11 +143,10 @@ namespace Oyster
} }
else else
{ {
memset(&out,0,sizeof(out)); return NULL;
return;
} }
#endif #endif
out.loadedData = Core::PipelineManager::CreateShader(data, Core::PipelineManager::ShaderType(type)); return Core::PipelineManager::CreateShader(data, Core::PipelineManager::ShaderType(type));
} }
} }
} }

View File

@ -9,14 +9,14 @@ namespace Oyster
{ {
namespace Model namespace Model
{ {
//struct ModelInfo; struct ModelInfo;
struct Model struct Model
{ {
//! do not Edit, linked to render data ModelInfo* info;
//ModelInfo* info;
void* info;
Oyster::Math::Float4x4 WorldMatrix; Oyster::Math::Float4x4 WorldMatrix;
bool Visible; bool Visible, LoopAnimation;
int AnimationPlaying;
float AnimationTime;
}; };
} }

View File

@ -11,12 +11,32 @@ namespace Oyster
{ {
namespace Model namespace Model
{ {
struct Bone
{
Math::Float4x4 Transform;
int Parent;
};
struct Frame
{
Bone bone;
double time;
};
struct Animation
{
std::wstring name;
int Bones;
int* Frames; //! Bone as index
Frame** Keyframes; //! @brief [Bone][Frame]
double duration;
};
struct ModelInfo struct ModelInfo
{ {
std::vector<ID3D11ShaderResourceView*> Material; std::vector<ID3D11ShaderResourceView*> Material;
Core::Buffer *Vertices,*Indecies; Core::Buffer *Vertices,*Indecies;
bool Indexed; bool Indexed, Animated;
int VertexCount, IndexCount; int VertexCount, IndexCount, BoneCount, AnimationCount;
Bone* bones;
Animation* Animations;
}; };
} }
} }

View File

@ -18,16 +18,10 @@ namespace Oyster
void Basic::NewFrame(Oyster::Math::Float4x4 View, Oyster::Math::Float4x4 Projection, Definitions::Pointlight* Lights, int numLights) void Basic::NewFrame(Oyster::Math::Float4x4 View, Oyster::Math::Float4x4 Projection, Definitions::Pointlight* Lights, int numLights)
{ {
Preparations::Basic::ClearBackBuffer(Oyster::Math::Float4(1,0,0,1)); Preparations::Basic::ClearBackBuffer(Oyster::Math::Float4(1,0,0,1));
Preparations::Basic::ClearRTV(Resources::Deffered::GBufferRTV,Resources::Deffered::GBufferSize,Math::Float4(1,0,0,1)); Preparations::Basic::ClearRTV(Resources::Deffered::GBufferRTV,Resources::Deffered::GBufferSize,Math::Float4(0,0,0,1));
Core::PipelineManager::SetRenderPass(Graphics::Render::Resources::Deffered::GeometryPass); Core::PipelineManager::SetRenderPass(Graphics::Render::Resources::Deffered::GeometryPass);
Definitions::VP vp; void* data;
vp.V = View;
vp.P = Projection;
void* data = Resources::Deffered::VPData.Map();
memcpy(data, &vp, sizeof(Definitions::VP));
Resources::Deffered::VPData.Unmap();
Definitions::LightConstants lc; Definitions::LightConstants lc;
lc.InvProj = Projection.GetInverse(); lc.InvProj = Projection.GetInverse();
@ -61,10 +55,79 @@ namespace Oyster
void* data = Resources::Deffered::ModelData.Map(); void* data = Resources::Deffered::ModelData.Map();
memcpy(data,&(pm),sizeof(pm)); memcpy(data,&(pm),sizeof(pm));
Resources::Deffered::ModelData.Unmap(); Resources::Deffered::ModelData.Unmap();
Model::ModelInfo* info = (Model::ModelInfo*)models[i].info; Model::ModelInfo* info = (Model::ModelInfo*)models[i].info;
Definitions::AnimationData am;
if(info->Animated && models[i].AnimationPlaying != -1)
{
Definitions::AnimationData am2;
//write default data
for (int b = 0; b < info->BoneCount; b++)
{
am2.animatedData[b] = info->bones[b].Transform;
}
//loop bones in animation
am.Animated = 1;
Model::Frame Prev, Next;
models[i].AnimationTime = fmod(models[i].AnimationTime,info->Animations[models[i].AnimationPlaying].duration);
for(int x = 0; x < info->Animations[models[i].AnimationPlaying].Bones; ++x)
{
//loop frame per bone
Prev.bone.Parent = 0;
Next = Prev;
for(int y = 0; y < info->Animations[models[i].AnimationPlaying].Frames[x]; ++y)
{
///TODO replace with binary search?
Model::Frame f = info->Animations[models[i].AnimationPlaying].Keyframes[x][y];
//if we hit frame
if(models[i].AnimationTime == f.time)
{
Prev = f;
Next = f;
break;
}
//if time is larger than frame time, store frames
if(models[i].AnimationTime < f.time)
{
Next = f;
Prev = info->Animations[models[i].AnimationPlaying].Keyframes[x][y-1];
break;
}
}
//calculate interpolated bone position
//rebase model time to between prev and next
float interpoation =(models[i].AnimationTime - Prev.time) / (Next.time - Prev.time);
//interpolate
Math::Matrix Interpolated;
Math3D::InterpolateOrientation_UsingNonRigidNlerp(Prev.bone.Transform,Next.bone.Transform,interpoation, Interpolated);
//write magic to animated data
am2.animatedData[Prev.bone.Parent] = Interpolated * am2.animatedData[info->bones[Prev.bone.Parent].Parent];
//sneaky write do correct data buffer
am.animatedData[x] = (am2.animatedData[Prev.bone.Parent] * info->bones[Prev.bone.Parent].Transform.GetInverse());
}
}
else
am.Animated = 0;
data = Resources::Deffered::AnimationData.Map();
memcpy(data,&am,sizeof(Definitions::AnimationData));
Resources::Deffered::AnimationData.Unmap();
if(info->Material.size()) if(info->Material.size())
{ {
Core::deviceContext->PSSetShaderResources(0,(UINT)info->Material.size(),&(info->Material[0])); Core::deviceContext->PSSetShaderResources(0,(UINT)info->Material.size(),&(info->Material[0]));
@ -84,6 +147,8 @@ namespace Oyster
} }
} }
} }
void Basic::EndFrame() void Basic::EndFrame()
{ {
Core::PipelineManager::SetRenderPass(Resources::Deffered::LightPass); Core::PipelineManager::SetRenderPass(Resources::Deffered::LightPass);

View File

@ -12,7 +12,7 @@ const std::wstring PathToHLSL = L"..\\..\\Code\\OysterGraphics\\Shader\\HLSL\\De
const std::wstring PathToCSO = L"..\\Content\\Shaders\\"; const std::wstring PathToCSO = L"..\\Content\\Shaders\\";
const int KernelSize = 10; const int KernelSize = 10;
const int SampleSpread = 8; const int SampleSpread = 16;
namespace Oyster namespace Oyster
{ {
@ -34,7 +34,7 @@ namespace Oyster
Shader::RenderPass Deffered::PostPass; Shader::RenderPass Deffered::PostPass;
Buffer Deffered::ModelData = Buffer(); Buffer Deffered::ModelData = Buffer();
Buffer Deffered::VPData = Buffer(); Buffer Deffered::AnimationData = Buffer();
Buffer Deffered::LightConstantsData = Buffer(); Buffer Deffered::LightConstantsData = Buffer();
Buffer Deffered::PointLightsData = Buffer(); Buffer Deffered::PointLightsData = Buffer();
@ -74,8 +74,9 @@ namespace Oyster
ModelData.Init(desc); ModelData.Init(desc);
desc.NumElements = 2; desc.NumElements = 1;
VPData.Init(desc); desc.ElementSize = sizeof(Definitions::AnimationData);
AnimationData.Init(desc);
desc.ElementSize = sizeof(Definitions::LightConstants); desc.ElementSize = sizeof(Definitions::LightConstants);
desc.NumElements = 1; desc.NumElements = 1;
@ -156,6 +157,7 @@ namespace Oyster
Core::Init::CreateLinkedShaderResourceFromStructuredBuffer(&b,&PointLightView,NULL); Core::Init::CreateLinkedShaderResourceFromStructuredBuffer(&b,&PointLightView,NULL);
srand((unsigned int)time(0)); srand((unsigned int)time(0));
//SSAO //SSAO
Math::Vector3 kernel[KernelSize]; Math::Vector3 kernel[KernelSize];
Math::Vector3 random[SampleSpread]; Math::Vector3 random[SampleSpread];
@ -186,13 +188,12 @@ namespace Oyster
{ {
random[i] = Oyster::Math::Vector3( random[i] = Oyster::Math::Vector3(
(float)rand() / (RAND_MAX + 1) * (1 - -1)+ -1, (float)rand() / (RAND_MAX + 1) * (1 - -1)+ -1,
(float)rand() / (RAND_MAX + 1) * (1 - -1)+ -1, /*(float)rand() / (RAND_MAX + 1) * (1 - -1)+ -1,*/
1.0f,
0.0f); 0.0f);
} }
random[i].Normalize(); random[i].Normalize();
} }
//kernel[0] = Math::Vector3(0,1,1);
//kernel[0].Normalize();
D3D11_TEXTURE1D_DESC T1desc; D3D11_TEXTURE1D_DESC T1desc;
T1desc.Width = KernelSize; T1desc.Width = KernelSize;
@ -208,17 +209,32 @@ namespace Oyster
D3D11_SUBRESOURCE_DATA rnd; D3D11_SUBRESOURCE_DATA rnd;
rnd.pSysMem = random; rnd.pSysMem = random;
rnd.SysMemPitch = sqrt(SampleSpread) * sizeof(Oyster::Math::Vector3);
ID3D11Texture1D *pTexture1[2]; ID3D11Texture1D *pTexture1;
Core::device->CreateTexture1D( &T1desc, &sphere, &pTexture1[0] ); Core::device->CreateTexture1D( &T1desc, &sphere, &pTexture1 );
Core::device->CreateShaderResourceView( pTexture1[0], 0, &SSAOKernel ); Core::device->CreateShaderResourceView( pTexture1, 0, &SSAOKernel );
pTexture1[0]->Release(); pTexture1->Release();
T1desc.Width = SampleSpread; D3D11_TEXTURE2D_DESC T2desc;
Core::device->CreateTexture1D( &T1desc, &rnd, &pTexture1[1] ); T2desc.Width = KernelSize;
Core::device->CreateShaderResourceView( (pTexture1[1]), 0, &SSAORandom ); T2desc.MipLevels = T2desc.ArraySize = 1;
pTexture1[1]->Release(); T2desc.Format = DXGI_FORMAT_R32G32B32_FLOAT;
T2desc.Usage = D3D11_USAGE_DEFAULT;
T2desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
T2desc.CPUAccessFlags = 0;
T2desc.MiscFlags = 0;
T2desc.Height = sqrt(SampleSpread);
T2desc.Width = SampleSpread/sqrt(SampleSpread);
T2desc.SampleDesc.Quality = 0;
T2desc.SampleDesc.Count = 1;
ID3D11Texture2D *pTexture2;
Core::device->CreateTexture2D( &T2desc, &rnd, &pTexture2 );
Core::device->CreateShaderResourceView( (pTexture2), 0, &SSAORandom );
pTexture2->Release();
////Create ShaderEffects ////Create ShaderEffects
@ -239,7 +255,7 @@ namespace Oyster
Shader::CreateInputLayout(indesc,7,GetShader::Vertex(L"Geometry"),GeometryPass.IAStage.Layout); Shader::CreateInputLayout(indesc,7,GetShader::Vertex(L"Geometry"),GeometryPass.IAStage.Layout);
GeometryPass.IAStage.Topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; GeometryPass.IAStage.Topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
GeometryPass.CBuffers.Vertex.push_back(VPData); GeometryPass.CBuffers.Vertex.push_back(AnimationData);
GeometryPass.CBuffers.Vertex.push_back(ModelData); GeometryPass.CBuffers.Vertex.push_back(ModelData);
GeometryPass.RenderStates.Rasterizer = rs; GeometryPass.RenderStates.Rasterizer = rs;
GeometryPass.RenderStates.SampleCount = 1; GeometryPass.RenderStates.SampleCount = 1;
@ -281,7 +297,7 @@ namespace Oyster
void Deffered::Clean() void Deffered::Clean()
{ {
Resources::Deffered::ModelData.~Buffer(); Resources::Deffered::ModelData.~Buffer();
Resources::Deffered::VPData.~Buffer(); Resources::Deffered::AnimationData.~Buffer();
Resources::Deffered::LightConstantsData.~Buffer(); Resources::Deffered::LightConstantsData.~Buffer();
Resources::Deffered::PointLightsData.~Buffer(); Resources::Deffered::PointLightsData.~Buffer();
SAFE_RELEASE(Resources::Deffered::PointLightView); SAFE_RELEASE(Resources::Deffered::PointLightView);

View File

@ -18,12 +18,15 @@ namespace Oyster
static const int LBufferSize = 3; static const int LBufferSize = 3;
static const int MaxLightSize = 100; static const int MaxLightSize = 100;
//! GBuffers //! GBuffers
//! 0 = Diffuse + SpecKoeff //! 0 = Diffuse + Glow
//! 1 = Normal + Glow //! 1 = Normal + Spec
static ID3D11RenderTargetView* GBufferRTV[GBufferSize]; static ID3D11RenderTargetView* GBufferRTV[GBufferSize];
static ID3D11ShaderResourceView* GBufferSRV[GBufferSize]; static ID3D11ShaderResourceView* GBufferSRV[GBufferSize];
//! LBuffer
//! 0 = Diffuse
//! 1 = Specular
//! 2 = SSAO
static ID3D11UnorderedAccessView* LBufferUAV[LBufferSize]; static ID3D11UnorderedAccessView* LBufferUAV[LBufferSize];
static ID3D11ShaderResourceView* LBufferSRV[LBufferSize]; static ID3D11ShaderResourceView* LBufferSRV[LBufferSize];
@ -33,7 +36,7 @@ namespace Oyster
static Core::Buffer ModelData; static Core::Buffer ModelData;
static Core::Buffer VPData; static Core::Buffer AnimationData;
static Core::Buffer LightConstantsData; static Core::Buffer LightConstantsData;

View File

@ -32,10 +32,10 @@ Texture2D DepthTexture : register(t2);
StructuredBuffer<PointLight> Points : register(t3); StructuredBuffer<PointLight> Points : register(t3);
Texture1D SSAOKernel : register(t4); Texture1D SSAOKernel : register(t4);
Texture1D SSAORand : register(t5); Texture2D SSAORand : register(t5);
RWTexture2D<float4> Diffuse : register(u0); RWTexture2D<float4> Diffuse : register(u0);
RWTexture2D<float4> Specular : register(u1); RWTexture2D<float4> Specular : register(u1);
RWTexture2D<float> Ambient : register(u2); RWTexture2D<float4> Ambient : register(u2);
#endif #endif

View File

@ -30,11 +30,11 @@ Texture2D Normal : register(t1);
SamplerState S1 : register(s0); SamplerState S1 : register(s0);
cbuffer PerFrame : register(b0) cbuffer Animation : register(b0)
{ {
matrix View; float4x4 BoneAnimation[100];
float4x4 Projection; int Animated;
matrix VP; float3 Pad;
} }
cbuffer PerModel : register(b1) cbuffer PerModel : register(b1)

View File

@ -21,8 +21,8 @@ DiffSpec LightCalc(PointLight pl, float3 pos, int2 texCoord)
output.Specular * 0; output.Specular * 0;
if(d > pl.Radius) if(d > pl.Radius)
{ {
output.Diffuse = float4(0,0,0,1); output.Diffuse = float3(0,0,0);
output.Specular = float4(0,0,0,1); output.Specular = float3(0,0,0);
} }
return output; return output;
} }

View File

@ -12,13 +12,13 @@
[numthreads(16, 16, 1)] [numthreads(16, 16, 1)]
void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID ) void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID )
{ {
float2 UV = DTid / Pixels; float2 UV = DTid.xy / Pixels;
UV.x = UV.x * 2 - 1; UV.x = UV.x * 2 - 1;
UV.y = 1 - 2 * UV.y; UV.y = 1 - 2 * UV.y;
float3 ViewPos = ToVpos(DTid.xy, UV); float3 ViewPos = ToVpos(DTid.xy, UV);
DiffSpec Shaded; DiffSpec Shaded;
Shaded.Diffuse = float4(0,0,0,0); Shaded.Diffuse = float3(0,0,0);
Shaded.Specular = float4(0,0,0,0); Shaded.Specular = float3(0,0,0);
for(int i = 0; i < Lights; ++i) for(int i = 0; i < Lights; ++i)
{ {
@ -33,10 +33,10 @@ void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID )
Specular[DTid.xy] = float4(Shaded.Specular, 1); Specular[DTid.xy] = float4(Shaded.Specular, 1);
if((DTid.x + DTid.y) %4 == 0 ) if(DTid.x & 1 && DTid.y & 1 )
{ {
float AmbValue = GetSSAO(ViewPos, UV, DTid.xy, GTid.xy); float AmbValue = GetSSAO(ViewPos, UV, DTid.xy, GTid.xy/2);
Ambient[DTid.xy/4] = AmbValue; Ambient[DTid.xy/2] = AmbValue;
} }
} }

View File

@ -7,8 +7,7 @@ RWTexture2D<float4> Output;
[numthreads(16, 16, 1)] [numthreads(16, 16, 1)]
void main( uint3 DTid : SV_DispatchThreadID ) void main( uint3 DTid : SV_DispatchThreadID )
{ {
Output[DTid.xy] = Diffuse[DTid.xy] + Specular[DTid.xy] + Diffuse[DTid.xy] * Ambient[DTid.xy/4].w;// + float4(Ambient[DTid.xy/4].xyz,1); GLOW //Output[DTid.xy] = Diffuse[DTid.xy] + Specular[DTid.xy] + Diffuse[DTid.xy] * Ambient[DTid.xy/2].w;// + float4(Ambient[DTid.xy/4].xyz,1); GLOW
//Output[DTid.xy] = Diffuse[DTid.xy] + Diffuse[DTid.xy] * Ambient[DTid.xy/4].w;// + float4(Ambient[DTid.xy/4].xyz,1); GLOW //Output[DTid.xy] = Ambient[DTid.xy/2];
Output[DTid.xy] = Diffuse[DTid.xy] + Specular[DTid.xy];
//Output[DTid.xy] = Diffuse[DTid.xy];
} }

View File

@ -1,30 +1,33 @@
#include "Defines.hlsli" #include "Defines.hlsli"
#include "PosManipulation.hlsli" #include "PosManipulation.hlsli"
static float Radius =5; static float Radius = 100;
float GetSSAO(float3 pos, float2 uv, int2 texCoord2, uint2 rndID) float GetSSAO(float3 pos, float2 uv, int2 texCoord2, uint2 rndID)
{ {
float occlusion = 0.0f; float occlusion = 0.0f;
//create sample coordinate system //create sample coordinate system
float4 rnd = float4( SSAORand[(rndID.x + rndID.y) % SSAORand.Length.x].xyz, 0.0f ); float4 rnd = float4( SSAORand[int2(rndID.x % (SSAORand.Length.x), rndID.y % (SSAORand.Length.y))].xyz, 0.0f );
rnd = normalize(rnd); rnd = normalize(rnd);
float3 normal = NormalSpec[uv].xyz; float3 normal = NormalSpec[texCoord2].xyz;
float4 tangent = float4( normalize(rnd.xyz - (normal * dot(rnd.xyz, normal))), 0.0f ); float3 tangent = float3( normalize(rnd.xyz - (normal * dot(rnd.xyz, normal))));
float4 biTangent = float4( cross(tangent.xyz, normal), 0.0f ); float3 biTangent = float3( cross(tangent.xyz, normal));
float4x4 tbn = float4x4(tangent, biTangent, float4(normal,0), float4(pos*Radius,1)); float3x3 tbn = float3x3(tangent, biTangent, normal);
for( uint i = 0; i < SSAOKernel.Length.x; ++i ) for( uint i = 0; i < SSAOKernel.Length.x; ++i )
{ {
//int i = 0;
//take sample from localspace to viewspace //take sample from localspace to viewspace
float4 sampled = mul(tbn, float4(SSAOKernel[i].xyz,1));
float3 sampled = mul(tbn, SSAOKernel[i].xyz);
sampled = sampled * Radius + pos;
//project sample to get uv.xy //project sample to get uv.xy
float4 ProjOffset = sampled; float4 ProjOffset = float4(sampled,1);
ProjOffset = mul(Proj, ProjOffset); ProjOffset = mul(Proj, ProjOffset);
float4 offset = ProjOffset; float4 offset = ProjOffset;
float2 UV = offset; float2 UV = offset.xy;
offset /= offset.w; offset /= offset.w;
offset.xyz = offset.xyz * 0.5f + 0.5f; offset.xyz = offset.xyz * 0.5f + 0.5f;
//extra invert y axis, DX11 //extra invert y axis, DX11
@ -39,7 +42,7 @@ float GetSSAO(float3 pos, float2 uv, int2 texCoord2, uint2 rndID)
//compare to depth from sample //compare to depth from sample
float rangeCheck = (abs(pos.z - sampleDepth) < Radius) ? 1.0f : 0.0f; float rangeCheck = (abs(pos.z - sampleDepth) < Radius) ? 1.0f : 0.0f;
occlusion += (sampleDepth >= sampled.z ? 1.0f : 0.0f) * rangeCheck; occlusion += (sampleDepth <= sampled.z ? 1.0f : 0.0f) * rangeCheck;
} }
occlusion /= (float)(SSAOKernel.Length.x); occlusion /= (float)(SSAOKernel.Length.x);
occlusion = 1.0f - occlusion; occlusion = 1.0f - occlusion;

View File

@ -3,6 +3,20 @@
VertexOut main( VertexIn input ) VertexOut main( VertexIn input )
{ {
VertexOut output; VertexOut output;
/*input.pos = (
(mul(BoneAnimation[input.boneIndex.x], input.pos) * input.boneWeight.x) +
(mul(BoneAnimation[input.boneIndex.y], input.pos) * input.boneWeight.y) +
(mul(BoneAnimation[input.boneIndex.z], input.pos) * input.boneWeight.z) +
(mul(BoneAnimation[input.boneIndex.w], input.pos) * input.boneWeight.w)
* Animated) + input.pos * int(1-Animated);*/
input.pos = (
(mul(BoneAnimation[input.boneIndex.x], input.pos)/* * input.boneWeight.x*/)
* Animated) + input.pos * int(1-Animated);
//float4x4 m = matrix(float4(1,0,0,0),float4(0,1,0,0), float4(0,0,1,0), float4(0,0,0,1));
//input.pos = mul(BoneAnimation[0], float4(input.pos,1));
//input.pos = mul(m, float4(input.pos,1));
output.pos = mul(WVP, float4(input.pos,1)); output.pos = mul(WVP, float4(input.pos,1));
output.normal = mul(WV, float4(input.normal,0)).xyz; output.normal = mul(WV, float4(input.normal,0)).xyz;
output.UV = input.UV; output.UV = input.UV;

View File

@ -13,7 +13,7 @@ using namespace ::Utility::Value;
RigidBody::RigidBody( ) RigidBody::RigidBody( )
{ // by Dan Andersson { // by Dan Andersson
this->centerPos = Float4::standard_unit_w; this->centerPos = Float4::standard_unit_w;
this->axis = Float4::null; this->quaternion = Quaternion(Float3(0, 0, 0), 1);
this->boundingReach = Float4( 0.5f, 0.5f, 0.5f, 0.0f ); this->boundingReach = Float4( 0.5f, 0.5f, 0.5f, 0.0f );
this->momentum_Linear = Float4::null; this->momentum_Linear = Float4::null;
this->momentum_Angular = Float4::null; this->momentum_Angular = Float4::null;
@ -24,13 +24,12 @@ RigidBody::RigidBody( )
this->frictionCoeff_Kinetic = 1.0f; this->frictionCoeff_Kinetic = 1.0f;
this->mass = 10; this->mass = 10;
this->momentOfInertiaTensor = MomentOfInertia(); this->momentOfInertiaTensor = MomentOfInertia();
this->rotation = Quaternion::identity;
} }
RigidBody & RigidBody::operator = ( const RigidBody &body ) RigidBody & RigidBody::operator = ( const RigidBody &body )
{ // by Dan Andersson { // by Dan Andersson
this->centerPos = body.centerPos; this->centerPos = body.centerPos;
this->axis = body.axis; this->quaternion = body.quaternion;
this->boundingReach = body.boundingReach; this->boundingReach = body.boundingReach;
this->momentum_Linear = body.momentum_Linear; this->momentum_Linear = body.momentum_Linear;
this->momentum_Angular = body.momentum_Angular; this->momentum_Angular = body.momentum_Angular;
@ -41,7 +40,6 @@ RigidBody & RigidBody::operator = ( const RigidBody &body )
this->frictionCoeff_Kinetic = body.frictionCoeff_Kinetic; this->frictionCoeff_Kinetic = body.frictionCoeff_Kinetic;
this->mass = body.mass; this->mass = body.mass;
this->momentOfInertiaTensor = body.momentOfInertiaTensor; this->momentOfInertiaTensor = body.momentOfInertiaTensor;
this->rotation = body.rotation;
return *this; return *this;
} }
@ -55,19 +53,14 @@ void RigidBody::Update_LeapFrog( Float updateFrameLength )
this->momentum_Angular = this->momentum_Angular*0.99f; this->momentum_Angular = this->momentum_Angular*0.99f;
// ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G // ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G
Float3 delta = AverageWithDelta( this->momentum_Linear, this->impulse_Linear ); Float3 delta = this->momentum_Linear;
Float3 newPos = ( updateFrameLength)*this->momentum_Linear; Float3 newPos = (updateFrameLength)*this->momentum_Linear;
this->centerPos += newPos; this->centerPos += newPos;
if(this->mass == 70)
{
const char *breakpoint = "STOP";
}
// updating the angular // updating the angular
// dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H // dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H
this->axis += updateFrameLength * this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, AverageWithDelta(this->momentum_Angular, this->impulse_Angular) ); /*this->axis += updateFrameLength*this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, this->momentum_Angular );
this->rotation = Rotation( this->axis ); this->rotation = Rotation( this->axis );*/
// update momentums and clear impulse_Linear and impulse_Angular // update momentums and clear impulse_Linear and impulse_Angular
this->momentum_Linear += this->impulse_Linear; this->momentum_Linear += this->impulse_Linear;
@ -89,14 +82,14 @@ void RigidBody::Predict_LeapFrog( Float3 &outDeltaPos, Float3 &outDeltaAxis, con
// dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H // dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H
//outDeltaAxis = Formula::AngularVelocity( wMomentOfInertiaTensor.GetInverse(), AverageWithDelta(this->momentum_Angular, actingAngularImpulse) ); //outDeltaAxis = Formula::AngularVelocity( wMomentOfInertiaTensor.GetInverse(), AverageWithDelta(this->momentum_Angular, actingAngularImpulse) );
outDeltaAxis = this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, AverageWithDelta(this->momentum_Angular, this->impulse_Angular) ); //utDeltaAxis = this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, AverageWithDelta(this->momentum_Angular, this->impulse_Angular) );
} }
void RigidBody::Move( const Float3 &deltaPos, const Float3 &deltaAxis ) void RigidBody::Move( const Float3 &deltaPos, const Float3 &deltaAxis )
{ {
this->centerPos += deltaPos; //this->centerPos += deltaPos;
this->axis += deltaAxis; //this->axis += deltaAxis;
this->rotation = Rotation( this->axis ); //this->rotation = Rotation( this->axis );
} }
void RigidBody::ApplyImpulse( const Float3 &worldJ, const Float3 &atWorldPos ) void RigidBody::ApplyImpulse( const Float3 &worldJ, const Float3 &atWorldPos )
@ -125,22 +118,22 @@ Float RigidBody::GetMass() const
const Quaternion & RigidBody::GetRotationQuaternion() const const Quaternion & RigidBody::GetRotationQuaternion() const
{ // by Dan Andersson { // by Dan Andersson
return this->rotation; return this->quaternion;
} }
Float4x4 RigidBody::GetRotationMatrix() const Float4x4 RigidBody::GetRotationMatrix() const
{ // by Dan Andersson { // by Dan Andersson
return RotationMatrix( this->rotation ); return RotationMatrix( quaternion );
} }
Float4x4 RigidBody::GetOrientation() const Float4x4 RigidBody::GetOrientation() const
{ // by Dan Andersson { // by Dan Andersson
return ::Oyster::Math3D::OrientationMatrix( this->rotation, this->centerPos ); return ::Oyster::Math3D::OrientationMatrix( this->quaternion, this->centerPos );
} }
Float4x4 RigidBody::GetView() const Float4x4 RigidBody::GetView() const
{ // by Dan Andersson { // by Dan Andersson
return ViewMatrix( this->rotation, this->centerPos ); return ViewMatrix( this->quaternion, this->centerPos );
} }
Float3 RigidBody::GetVelocity_Linear() const Float3 RigidBody::GetVelocity_Linear() const
@ -150,7 +143,7 @@ Float3 RigidBody::GetVelocity_Linear() const
Float3 RigidBody::GetVelocity_Angular() const Float3 RigidBody::GetVelocity_Angular() const
{ // by Dan Andersson { // by Dan Andersson
return this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, this->momentum_Angular ); return Float3(0, 0, 0);
} }
Float3 RigidBody::GetLinearMomentum( const Float3 &atWorldPos ) const Float3 RigidBody::GetLinearMomentum( const Float3 &atWorldPos ) const
@ -165,9 +158,7 @@ Float3 RigidBody::GetLinearMomentum( const Float3 &atWorldPos ) const
void RigidBody::SetMomentOfInertia_KeepVelocity( const MomentOfInertia &localTensorI ) void RigidBody::SetMomentOfInertia_KeepVelocity( const MomentOfInertia &localTensorI )
{ // by Dan Andersson { // by Dan Andersson
Float3 w = this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, this->momentum_Angular );
this->momentOfInertiaTensor = localTensorI;
this->momentum_Angular = this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, w );
} }
void RigidBody::SetMomentOfInertia_KeepMomentum( const MomentOfInertia &localTensorI ) void RigidBody::SetMomentOfInertia_KeepMomentum( const MomentOfInertia &localTensorI )
@ -193,10 +184,9 @@ void RigidBody::SetMass_KeepMomentum( const Float &m )
} }
} }
void RigidBody::SetRotation( const Float3 &axis ) void RigidBody::SetRotation( const ::Oyster::Math::Quaternion &quaternion )
{ // by Dan Andersson { // by Dan Andersson
this->axis = axis; this->quaternion = quaternion;
this->rotation = Rotation( this->axis );
} }
void RigidBody::SetMomentum_Linear( const Float3 &worldG, const Float3 &atWorldPos ) void RigidBody::SetMomentum_Linear( const Float3 &worldG, const Float3 &atWorldPos )
@ -215,12 +205,12 @@ void RigidBody::SetVelocity_Linear( const Float3 &worldV, const Float3 &atWorldP
{ // by Dan Andersson { // by Dan Andersson
Float3 worldOffset = atWorldPos - this->centerPos; Float3 worldOffset = atWorldPos - this->centerPos;
this->momentum_Linear = Formula::LinearMomentum( this->mass, VectorProjection(worldV, worldOffset) ); this->momentum_Linear = Formula::LinearMomentum( this->mass, VectorProjection(worldV, worldOffset) );
this->momentum_Angular = this->momentOfInertiaTensor.CalculateAngularMomentum( this->rotation, Formula::AngularVelocity(worldV, worldOffset) ); this->momentum_Angular = this->momentOfInertiaTensor.CalculateAngularMomentum( this->quaternion, Formula::AngularVelocity(worldV, worldOffset) );
} }
void RigidBody::SetVelocity_Angular( const Float3 &worldW ) void RigidBody::SetVelocity_Angular( const Float3 &worldW )
{ // by Dan Andersson { // by Dan Andersson
this->momentum_Angular = this->momentOfInertiaTensor.CalculateAngularMomentum( this->rotation, worldW ); this->momentum_Angular = this->momentOfInertiaTensor.CalculateAngularMomentum( this->quaternion, worldW );
} }
void RigidBody::SetImpulse_Linear( const Float3 &worldJ, const Float3 &atWorldPos ) void RigidBody::SetImpulse_Linear( const Float3 &worldJ, const Float3 &atWorldPos )

View File

@ -15,8 +15,8 @@ namespace Oyster { namespace Physics3D
struct RigidBody struct RigidBody
{ //! A struct of a simple rigid body. { //! A struct of a simple rigid body.
public: public:
::Oyster::Math::Quaternion quaternion;
::Oyster::Math::Float3 centerPos, //!< Location of the body's center in the world. ::Oyster::Math::Float3 centerPos, //!< Location of the body's center in the world.
axis, //!< Euler rotationAxis of the body.
boundingReach, //!< boundingReach, //!<
momentum_Linear, //!< The linear momentum G (kg*m/s). momentum_Linear, //!< The linear momentum G (kg*m/s).
momentum_Angular, //!< The angular momentum H (Nm*s) around an parallell axis. momentum_Angular, //!< The angular momentum H (Nm*s) around an parallell axis.
@ -64,7 +64,7 @@ namespace Oyster { namespace Physics3D
void SetMass_KeepMomentum( const ::Oyster::Math::Float &m ); void SetMass_KeepMomentum( const ::Oyster::Math::Float &m );
//void SetOrientation( const ::Oyster::Math::Float4x4 &o ); //void SetOrientation( const ::Oyster::Math::Float4x4 &o );
void SetRotation( const ::Oyster::Math::Float3 &axis ); void SetRotation( const ::Oyster::Math::Quaternion &quaternion );
void SetSize( const ::Oyster::Math::Float3 &widthHeight ); void SetSize( const ::Oyster::Math::Float3 &widthHeight );
void SetMomentum_Linear( const ::Oyster::Math::Float3 &worldG, const ::Oyster::Math::Float3 &atWorldPos ); void SetMomentum_Linear( const ::Oyster::Math::Float3 &worldG, const ::Oyster::Math::Float3 &atWorldPos );
@ -81,7 +81,7 @@ namespace Oyster { namespace Physics3D
::Oyster::Math::Float mass; //!< m (kg) ::Oyster::Math::Float mass; //!< m (kg)
//::Oyster::Math::Float4x4 momentOfInertiaTensor; //!< I (Nm*s) Tensor matrix ( only need to be 3x3 matrix, but is 4x4 for future hardware acceleration ) (localValue) //::Oyster::Math::Float4x4 momentOfInertiaTensor; //!< I (Nm*s) Tensor matrix ( only need to be 3x3 matrix, but is 4x4 for future hardware acceleration ) (localValue)
::Oyster::Physics3D::MomentOfInertia momentOfInertiaTensor; ::Oyster::Physics3D::MomentOfInertia momentOfInertiaTensor;
::Oyster::Math::Quaternion rotation; //!< RotationAxis of the body. //::Oyster::Math::Quaternion rotation; //!< RotationAxis of the body.
}; };
} } } }

View File

@ -0,0 +1,176 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's.
Work in progress, functionality will be added on demand.
If possible, use the richer Bullet C++ API, by including "btBulletDynamicsCommon.h"
*/
#ifndef BULLET_C_API_H
#define BULLET_C_API_H
#define PL_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
#ifdef BT_USE_DOUBLE_PRECISION
typedef double plReal;
#else
typedef float plReal;
#endif
typedef plReal plVector3[3];
typedef plReal plQuaternion[4];
#ifdef __cplusplus
extern "C" {
#endif
/** Particular physics SDK (C-API) */
PL_DECLARE_HANDLE(plPhysicsSdkHandle);
/** Dynamics world, belonging to some physics SDK (C-API)*/
PL_DECLARE_HANDLE(plDynamicsWorldHandle);
/** Rigid Body that can be part of a Dynamics World (C-API)*/
PL_DECLARE_HANDLE(plRigidBodyHandle);
/** Collision Shape/Geometry, property of a Rigid Body (C-API)*/
PL_DECLARE_HANDLE(plCollisionShapeHandle);
/** Constraint for Rigid Bodies (C-API)*/
PL_DECLARE_HANDLE(plConstraintHandle);
/** Triangle Mesh interface (C-API)*/
PL_DECLARE_HANDLE(plMeshInterfaceHandle);
/** Broadphase Scene/Proxy Handles (C-API)*/
PL_DECLARE_HANDLE(plCollisionBroadphaseHandle);
PL_DECLARE_HANDLE(plBroadphaseProxyHandle);
PL_DECLARE_HANDLE(plCollisionWorldHandle);
/**
Create and Delete a Physics SDK
*/
extern plPhysicsSdkHandle plNewBulletSdk(void); //this could be also another sdk, like ODE, PhysX etc.
extern void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk);
/** Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */
typedef void(*btBroadphaseCallback)(void* clientData, void* object1,void* object2);
extern plCollisionBroadphaseHandle plCreateSapBroadphase(btBroadphaseCallback beginCallback,btBroadphaseCallback endCallback);
extern void plDestroyBroadphase(plCollisionBroadphaseHandle bp);
extern plBroadphaseProxyHandle plCreateProxy(plCollisionBroadphaseHandle bp, void* clientData, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);
extern void plDestroyProxy(plCollisionBroadphaseHandle bp, plBroadphaseProxyHandle proxyHandle);
extern void plSetBoundingBox(plBroadphaseProxyHandle proxyHandle, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);
/* todo: add pair cache support with queries like add/remove/find pair */
extern plCollisionWorldHandle plCreateCollisionWorld(plPhysicsSdkHandle physicsSdk);
/* todo: add/remove objects */
/* Dynamics World */
extern plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdk);
extern void plDeleteDynamicsWorld(plDynamicsWorldHandle world);
extern void plStepSimulation(plDynamicsWorldHandle, plReal timeStep);
extern void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);
extern void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);
/* Rigid Body */
extern plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionShapeHandle cshape );
extern void plDeleteRigidBody(plRigidBodyHandle body);
/* Collision Shape definition */
extern plCollisionShapeHandle plNewSphereShape(plReal radius);
extern plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z);
extern plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewConeShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewCompoundShape(void);
extern void plAddChildShape(plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn);
extern void plDeleteShape(plCollisionShapeHandle shape);
/* Convex Meshes */
extern plCollisionShapeHandle plNewConvexHullShape(void);
extern void plAddVertex(plCollisionShapeHandle convexHull, plReal x,plReal y,plReal z);
/* Concave static triangle meshes */
extern plMeshInterfaceHandle plNewMeshInterface(void);
extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2);
extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle);
extern void plSetScaling(plCollisionShapeHandle shape, plVector3 scaling);
/* SOLID has Response Callback/Table/Management */
/* PhysX has Triggers, User Callbacks and filtering */
/* ODE has the typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2); */
/* typedef void plUpdatedPositionCallback(void* userData, plRigidBodyHandle rbHandle, plVector3 pos); */
/* typedef void plUpdatedOrientationCallback(void* userData, plRigidBodyHandle rbHandle, plQuaternion orientation); */
/* get world transform */
extern void plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix);
extern void plGetPosition(plRigidBodyHandle object,plVector3 position);
extern void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation);
/* set world transform (position/orientation) */
extern void plSetPosition(plRigidBodyHandle object, const plVector3 position);
extern void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation);
extern void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient);
extern void plSetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix);
typedef struct plRayCastResult {
plRigidBodyHandle m_body;
plCollisionShapeHandle m_shape;
plVector3 m_positionWorld;
plVector3 m_normalWorld;
} plRayCastResult;
extern int plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plRayCastResult res);
/* Sweep API */
/* extern plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); */
/* Continuous Collision Detection API */
// needed for source/blender/blenkernel/intern/collision.c
double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]);
#ifdef __cplusplus
}
#endif
#endif //BULLET_C_API_H

View File

@ -0,0 +1,37 @@
//Bullet Continuous Collision Detection and Physics Library
//Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
//
// btAxisSweep3
//
// Copyright (c) 2006 Simon Hobbs
//
// This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
#include "btAxisSweep3.h"
btAxisSweep3::btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache, bool disableRaycastAccelerator)
:btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache,disableRaycastAccelerator)
{
// 1 handle is reserved as sentinel
btAssert(maxHandles > 1 && maxHandles < 32767);
}
bt32BitAxisSweep3::bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)
:btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache,disableRaycastAccelerator)
{
// 1 handle is reserved as sentinel
btAssert(maxHandles > 1 && maxHandles < 2147483647);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,82 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_BROADPHASE_INTERFACE_H
#define BT_BROADPHASE_INTERFACE_H
struct btDispatcherInfo;
class btDispatcher;
#include "btBroadphaseProxy.h"
class btOverlappingPairCache;
struct btBroadphaseAabbCallback
{
virtual ~btBroadphaseAabbCallback() {}
virtual bool process(const btBroadphaseProxy* proxy) = 0;
};
struct btBroadphaseRayCallback : public btBroadphaseAabbCallback
{
///added some cached data to accelerate ray-AABB tests
btVector3 m_rayDirectionInverse;
unsigned int m_signs[3];
btScalar m_lambda_max;
virtual ~btBroadphaseRayCallback() {}
};
#include "LinearMath/btVector3.h"
///The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
///Some implementations for this broadphase interface include btAxisSweep3, bt32BitAxisSweep3 and btDbvtBroadphase.
///The actual overlapping pair management, storage, adding and removing of pairs is dealt by the btOverlappingPairCache class.
class btBroadphaseInterface
{
public:
virtual ~btBroadphaseInterface() {}
virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy) =0;
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0;
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0;
virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const =0;
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) = 0;
virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) = 0;
///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
virtual void calculateOverlappingPairs(btDispatcher* dispatcher)=0;
virtual btOverlappingPairCache* getOverlappingPairCache()=0;
virtual const btOverlappingPairCache* getOverlappingPairCache() const =0;
///getAabb returns the axis aligned bounding box in the 'global' coordinate frame
///will add some transform later
virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const =0;
///reset broadphase internal structures, to ensure determinism/reproducability
virtual void resetPool(btDispatcher* dispatcher) { (void) dispatcher; };
virtual void printStats() = 0;
};
#endif //BT_BROADPHASE_INTERFACE_H

View File

@ -0,0 +1,17 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "btBroadphaseProxy.h"

View File

@ -0,0 +1,270 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_BROADPHASE_PROXY_H
#define BT_BROADPHASE_PROXY_H
#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedAllocator.h"
/// btDispatcher uses these types
/// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave
/// to facilitate type checking
/// CUSTOM_POLYHEDRAL_SHAPE_TYPE,CUSTOM_CONVEX_SHAPE_TYPE and CUSTOM_CONCAVE_SHAPE_TYPE can be used to extend Bullet without modifying source code
enum BroadphaseNativeTypes
{
// polyhedral convex shapes
BOX_SHAPE_PROXYTYPE,
TRIANGLE_SHAPE_PROXYTYPE,
TETRAHEDRAL_SHAPE_PROXYTYPE,
CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE,
CONVEX_HULL_SHAPE_PROXYTYPE,
CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE,
CUSTOM_POLYHEDRAL_SHAPE_TYPE,
//implicit convex shapes
IMPLICIT_CONVEX_SHAPES_START_HERE,
SPHERE_SHAPE_PROXYTYPE,
MULTI_SPHERE_SHAPE_PROXYTYPE,
CAPSULE_SHAPE_PROXYTYPE,
CONE_SHAPE_PROXYTYPE,
CONVEX_SHAPE_PROXYTYPE,
CYLINDER_SHAPE_PROXYTYPE,
UNIFORM_SCALING_SHAPE_PROXYTYPE,
MINKOWSKI_SUM_SHAPE_PROXYTYPE,
MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
BOX_2D_SHAPE_PROXYTYPE,
CONVEX_2D_SHAPE_PROXYTYPE,
CUSTOM_CONVEX_SHAPE_TYPE,
//concave shapes
CONCAVE_SHAPES_START_HERE,
//keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
TRIANGLE_MESH_SHAPE_PROXYTYPE,
SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE,
///used for demo integration FAST/Swift collision library and Bullet
FAST_CONCAVE_MESH_PROXYTYPE,
//terrain
TERRAIN_SHAPE_PROXYTYPE,
///Used for GIMPACT Trimesh integration
GIMPACT_SHAPE_PROXYTYPE,
///Multimaterial mesh
MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE,
EMPTY_SHAPE_PROXYTYPE,
STATIC_PLANE_PROXYTYPE,
CUSTOM_CONCAVE_SHAPE_TYPE,
CONCAVE_SHAPES_END_HERE,
COMPOUND_SHAPE_PROXYTYPE,
SOFTBODY_SHAPE_PROXYTYPE,
HFFLUID_SHAPE_PROXYTYPE,
HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE,
INVALID_SHAPE_PROXYTYPE,
MAX_BROADPHASE_COLLISION_TYPES
};
///The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
///It stores collision shape type information, collision filter information and a client object, typically a btCollisionObject or btRigidBody.
ATTRIBUTE_ALIGNED16(struct) btBroadphaseProxy
{
BT_DECLARE_ALIGNED_ALLOCATOR();
///optional filtering to cull potential collisions
enum CollisionFilterGroups
{
DefaultFilter = 1,
StaticFilter = 2,
KinematicFilter = 4,
DebrisFilter = 8,
SensorTrigger = 16,
CharacterFilter = 32,
AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger
};
//Usually the client btCollisionObject or Rigidbody class
void* m_clientObject;
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
void* m_multiSapParentProxy;
int m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc.
btVector3 m_aabbMin;
btVector3 m_aabbMax;
SIMD_FORCE_INLINE int getUid() const
{
return m_uniqueId;
}
//used for memory pools
btBroadphaseProxy() :m_clientObject(0),m_multiSapParentProxy(0)
{
}
btBroadphaseProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0)
:m_clientObject(userPtr),
m_collisionFilterGroup(collisionFilterGroup),
m_collisionFilterMask(collisionFilterMask),
m_aabbMin(aabbMin),
m_aabbMax(aabbMax)
{
m_multiSapParentProxy = multiSapParentProxy;
}
static SIMD_FORCE_INLINE bool isPolyhedral(int proxyType)
{
return (proxyType < IMPLICIT_CONVEX_SHAPES_START_HERE);
}
static SIMD_FORCE_INLINE bool isConvex(int proxyType)
{
return (proxyType < CONCAVE_SHAPES_START_HERE);
}
static SIMD_FORCE_INLINE bool isNonMoving(int proxyType)
{
return (isConcave(proxyType) && !(proxyType==GIMPACT_SHAPE_PROXYTYPE));
}
static SIMD_FORCE_INLINE bool isConcave(int proxyType)
{
return ((proxyType > CONCAVE_SHAPES_START_HERE) &&
(proxyType < CONCAVE_SHAPES_END_HERE));
}
static SIMD_FORCE_INLINE bool isCompound(int proxyType)
{
return (proxyType == COMPOUND_SHAPE_PROXYTYPE);
}
static SIMD_FORCE_INLINE bool isSoftBody(int proxyType)
{
return (proxyType == SOFTBODY_SHAPE_PROXYTYPE);
}
static SIMD_FORCE_INLINE bool isInfinite(int proxyType)
{
return (proxyType == STATIC_PLANE_PROXYTYPE);
}
static SIMD_FORCE_INLINE bool isConvex2d(int proxyType)
{
return (proxyType == BOX_2D_SHAPE_PROXYTYPE) || (proxyType == CONVEX_2D_SHAPE_PROXYTYPE);
}
}
;
class btCollisionAlgorithm;
struct btBroadphaseProxy;
///The btBroadphasePair class contains a pair of aabb-overlapping objects.
///A btDispatcher can search a btCollisionAlgorithm that performs exact/narrowphase collision detection on the actual collision shapes.
ATTRIBUTE_ALIGNED16(struct) btBroadphasePair
{
btBroadphasePair ()
:
m_pProxy0(0),
m_pProxy1(0),
m_algorithm(0),
m_internalInfo1(0)
{
}
BT_DECLARE_ALIGNED_ALLOCATOR();
btBroadphasePair(const btBroadphasePair& other)
: m_pProxy0(other.m_pProxy0),
m_pProxy1(other.m_pProxy1),
m_algorithm(other.m_algorithm),
m_internalInfo1(other.m_internalInfo1)
{
}
btBroadphasePair(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1)
{
//keep them sorted, so the std::set operations work
if (proxy0.m_uniqueId < proxy1.m_uniqueId)
{
m_pProxy0 = &proxy0;
m_pProxy1 = &proxy1;
}
else
{
m_pProxy0 = &proxy1;
m_pProxy1 = &proxy0;
}
m_algorithm = 0;
m_internalInfo1 = 0;
}
btBroadphaseProxy* m_pProxy0;
btBroadphaseProxy* m_pProxy1;
mutable btCollisionAlgorithm* m_algorithm;
union { void* m_internalInfo1; int m_internalTmpValue;};//don't use this data, it will be removed in future version.
};
/*
//comparison for set operation, see Solid DT_Encounter
SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePair& b)
{
return a.m_pProxy0 < b.m_pProxy0 ||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 < b.m_pProxy1);
}
*/
class btBroadphasePairSortPredicate
{
public:
bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b ) const
{
const int uidA0 = a.m_pProxy0 ? a.m_pProxy0->m_uniqueId : -1;
const int uidB0 = b.m_pProxy0 ? b.m_pProxy0->m_uniqueId : -1;
const int uidA1 = a.m_pProxy1 ? a.m_pProxy1->m_uniqueId : -1;
const int uidB1 = b.m_pProxy1 ? b.m_pProxy1->m_uniqueId : -1;
return uidA0 > uidB0 ||
(a.m_pProxy0 == b.m_pProxy0 && uidA1 > uidB1) ||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm);
}
};
SIMD_FORCE_INLINE bool operator==(const btBroadphasePair& a, const btBroadphasePair& b)
{
return (a.m_pProxy0 == b.m_pProxy0) && (a.m_pProxy1 == b.m_pProxy1);
}
#endif //BT_BROADPHASE_PROXY_H

Some files were not shown because too many files have changed in this diff Show More