New initial commit with reorganized structer
This commit is contained in:
parent
94c1ae23f1
commit
9ee656d270
|
@ -0,0 +1,165 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 2012
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterGraphics", "OysterGraphics\OysterGraphics.vcxproj", "{0EC83E64-230E-48EF-B08C-6AC9651B4F82}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterMath", "OysterMath\OysterMath.vcxproj", "{F10CBC03-9809-4CBA-95D8-327C287B18EE}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterPhysics3D", "OysterPhysics3D\OysterPhysics3D.vcxproj", "{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sound", "Sound\Sound.vcxproj", "{34D6295A-00DD-4B1A-8258-97DA2818EC26}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowManager", "WindowManager\WindowManager.vcxproj", "{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Input", "Input\Input.vcxproj", "{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Misc", "Misc\Misc.vcxproj", "{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Network", "Network", "{C27B926E-B3EF-4990-8822-47580E43A0BE}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterNetworkClient", "Network\OysterNetworkClient\OysterNetworkClient.vcxproj", "{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterNetworkServer", "Network\OysterNetworkServer\OysterNetworkServer.vcxproj", "{6A066806-F43F-4B31-A4E3-57179674F460}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NetworkDependencies", "Network\NetworkDependencies\NetworkDependencies.vcxproj", "{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Mixed Platforms = Debug|Mixed Platforms
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|Mixed Platforms = Release|Mixed Platforms
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
||||||
|
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||||
|
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Win32.ActiveCfg = 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.Build.0 = Debug|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Release|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Debug|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Release|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Debug|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Release|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Debug|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Release|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Debug|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Release|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Debug|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Release|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Debug|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Release|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Debug|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Release|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Debug|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Release|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Debug|x64
|
||||||
|
{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|Win32.ActiveCfg = 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.Build.0 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8} = {C27B926E-B3EF-4990-8822-47580E43A0BE}
|
||||||
|
{6A066806-F43F-4B31-A4E3-57179674F460} = {C27B926E-B3EF-4990-8822-47580E43A0BE}
|
||||||
|
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50} = {C27B926E-B3EF-4990-8822-47580E43A0BE}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,428 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<diagram program="umlet" version="12.1">
|
||||||
|
<zoom_level>9</zoom_level>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>675</x>
|
||||||
|
<y>342</y>
|
||||||
|
<w>108</w>
|
||||||
|
<h>27</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Graphics</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>441</x>
|
||||||
|
<y>342</y>
|
||||||
|
<w>108</w>
|
||||||
|
<h>27</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Sound</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>531</x>
|
||||||
|
<y>279</y>
|
||||||
|
<w>108</w>
|
||||||
|
<h>27</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Physics / Math</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>684</x>
|
||||||
|
<y>153</y>
|
||||||
|
<w>99</w>
|
||||||
|
<h>27</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Game client</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>351</x>
|
||||||
|
<y>279</y>
|
||||||
|
<w>126</w>
|
||||||
|
<h>27</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Gamelogic</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>369</x>
|
||||||
|
<y>153</y>
|
||||||
|
<w>99</w>
|
||||||
|
<h>27</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Game server</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>531</x>
|
||||||
|
<y>207</y>
|
||||||
|
<w>108</w>
|
||||||
|
<h>27</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Network</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>558</x>
|
||||||
|
<y>342</y>
|
||||||
|
<w>108</w>
|
||||||
|
<h>27</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Input</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>531</x>
|
||||||
|
<y>243</y>
|
||||||
|
<w>108</w>
|
||||||
|
<h>27</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Threading</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>531</x>
|
||||||
|
<y>90</y>
|
||||||
|
<w>108</w>
|
||||||
|
<h>36</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>DanBias
|
||||||
|
bg=green</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>702</x>
|
||||||
|
<y>153</y>
|
||||||
|
<w>44</w>
|
||||||
|
<h>206</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<-</panel_attributes>
|
||||||
|
<additional_attributes>27;189;27;171;27;27</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>459</x>
|
||||||
|
<y>153</y>
|
||||||
|
<w>287</w>
|
||||||
|
<h>206</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<-</panel_attributes>
|
||||||
|
<additional_attributes>27;189;27;171;270;171;270;27</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>387</x>
|
||||||
|
<y>153</y>
|
||||||
|
<w>44</w>
|
||||||
|
<h>143</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<-</panel_attributes>
|
||||||
|
<additional_attributes>27;126;27;27</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>612</x>
|
||||||
|
<y>153</y>
|
||||||
|
<w>134</w>
|
||||||
|
<h>152</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<-</panel_attributes>
|
||||||
|
<additional_attributes>27;135;117;135;117;27</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>387</x>
|
||||||
|
<y>153</y>
|
||||||
|
<w>161</w>
|
||||||
|
<h>80</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<-</panel_attributes>
|
||||||
|
<additional_attributes>144;63;27;63;27;27</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>450</x>
|
||||||
|
<y>261</y>
|
||||||
|
<w>98</w>
|
||||||
|
<h>44</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<-</panel_attributes>
|
||||||
|
<additional_attributes>81;27;27;27</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>585</x>
|
||||||
|
<y>153</y>
|
||||||
|
<w>161</w>
|
||||||
|
<h>206</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<-</panel_attributes>
|
||||||
|
<additional_attributes>27;189;27;171;144;171;144;27</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>387</x>
|
||||||
|
<y>153</y>
|
||||||
|
<w>161</w>
|
||||||
|
<h>116</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<-</panel_attributes>
|
||||||
|
<additional_attributes>144;99;27;99;27;27</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>612</x>
|
||||||
|
<y>153</y>
|
||||||
|
<w>134</w>
|
||||||
|
<h>116</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<-</panel_attributes>
|
||||||
|
<additional_attributes>27;99;117;99;117;27</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>612</x>
|
||||||
|
<y>153</y>
|
||||||
|
<w>134</w>
|
||||||
|
<h>80</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<-</panel_attributes>
|
||||||
|
<additional_attributes>27;63;117;63;117;27</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>612</x>
|
||||||
|
<y>72</y>
|
||||||
|
<w>134</w>
|
||||||
|
<h>98</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=>-</panel_attributes>
|
||||||
|
<additional_attributes>27;27;117;27;117;81</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>387</x>
|
||||||
|
<y>72</y>
|
||||||
|
<w>161</w>
|
||||||
|
<h>98</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=>-</panel_attributes>
|
||||||
|
<additional_attributes>144;27;27;27;27;81</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Package</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>342</x>
|
||||||
|
<y>54</y>
|
||||||
|
<w>450</w>
|
||||||
|
<h>333</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Game</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>702</x>
|
||||||
|
<y>342</y>
|
||||||
|
<w>44</w>
|
||||||
|
<h>134</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<<.</panel_attributes>
|
||||||
|
<additional_attributes>27;27;27;117</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Package</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>711</x>
|
||||||
|
<y>459</y>
|
||||||
|
<w>261</w>
|
||||||
|
<h>180</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Graphics</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>720</x>
|
||||||
|
<y>486</y>
|
||||||
|
<w>243</w>
|
||||||
|
<h>144</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes><<interface>>
|
||||||
|
OysterGfx
|
||||||
|
--
|
||||||
|
Init(InitData :struct) :enum state
|
||||||
|
NewFrame(FrameConstant :struct) :void
|
||||||
|
GatherData(Model :struct) :void
|
||||||
|
Render() :void
|
||||||
|
SetOptions(Options :struct) :void
|
||||||
|
LoadModel(file :const wchar[]) :Model*
|
||||||
|
Release(resource :Model*) :void</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Package</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>441</x>
|
||||||
|
<y>459</y>
|
||||||
|
<w>252</w>
|
||||||
|
<h>198</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Input</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>513</x>
|
||||||
|
<y>342</y>
|
||||||
|
<w>116</w>
|
||||||
|
<h>143</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<<.</panel_attributes>
|
||||||
|
<additional_attributes>99;27;99;126;27;126</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>450</x>
|
||||||
|
<y>486</y>
|
||||||
|
<w>234</w>
|
||||||
|
<h>162</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes><<interface>>
|
||||||
|
RawInput
|
||||||
|
--
|
||||||
|
Self() :RawInput*
|
||||||
|
Destroy() :void
|
||||||
|
QueryInput(Key :enum state(RIK)) :void
|
||||||
|
Subscribe(Callback :function) :void
|
||||||
|
Unsubscribe(Calback :function) :void
|
||||||
|
GetError() const :const wchar*
|
||||||
|
AddDevice(Data :struct) :enum state
|
||||||
|
Enable(Enable :bool) :void</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>351</x>
|
||||||
|
<y>342</y>
|
||||||
|
<w>81</w>
|
||||||
|
<h>27</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Window API</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>360</x>
|
||||||
|
<y>153</y>
|
||||||
|
<w>386</w>
|
||||||
|
<h>206</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<-</panel_attributes>
|
||||||
|
<additional_attributes>27;189;27;171;369;171;369;27</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Package</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>126</x>
|
||||||
|
<y>459</y>
|
||||||
|
<w>306</w>
|
||||||
|
<h>198</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>Sound</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>135</x>
|
||||||
|
<y>486</y>
|
||||||
|
<w>288</w>
|
||||||
|
<h>99</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes><<interface>>
|
||||||
|
SoundWrapper
|
||||||
|
--
|
||||||
|
LoadResource(file :const char*) :ResoureHandle*
|
||||||
|
Play(PlayData :struct) :InstanceID
|
||||||
|
Stop(InstanceID :int) :void
|
||||||
|
Release(Resource :ResourceHandle*) :void</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Class</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>135</x>
|
||||||
|
<y>612</y>
|
||||||
|
<w>288</w>
|
||||||
|
<h>36</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes><<API>>
|
||||||
|
--
|
||||||
|
FMOD</panel_attributes>
|
||||||
|
<additional_attributes/>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>252</x>
|
||||||
|
<y>558</y>
|
||||||
|
<w>44</w>
|
||||||
|
<h>71</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<<.</panel_attributes>
|
||||||
|
<additional_attributes>27;54;27;27</additional_attributes>
|
||||||
|
</element>
|
||||||
|
<element>
|
||||||
|
<type>com.umlet.element.Relation</type>
|
||||||
|
<coordinates>
|
||||||
|
<x>216</x>
|
||||||
|
<y>342</y>
|
||||||
|
<w>296</w>
|
||||||
|
<h>143</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>lt=<<.</panel_attributes>
|
||||||
|
<additional_attributes>279;27;279;72;207;72;207;126;27;126</additional_attributes>
|
||||||
|
</element>
|
||||||
|
</diagram>
|
|
@ -0,0 +1,16 @@
|
||||||
|
float3 func( in float3 normalA, in float3 normalB, in float3 normalC )
|
||||||
|
{
|
||||||
|
return normalize( lerp( lerp(normalA, normalB, 0.5f), lerp(normalA, normalC, 0.5f), 0.5f ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 nearTopLeft = func( f.topPlane.normal, f.leftPlane.normal, f.nearPlane.normal );
|
||||||
|
float3 nearTopRight = func( f.topPlane.normal, f.rightPlane.normal, f.nearPlane.normal );
|
||||||
|
float3 nearBottomLeft = func( f.bottomPlane.normal, f.leftPlane.normal, f.nearPlane.normal );
|
||||||
|
float3 nearBottomRight = func( f.bottomPlane.normal, f.rightPlane.normal, f.nearPlane.normal );
|
||||||
|
|
||||||
|
|
||||||
|
float3 farTopLeft = func( f.topPlane.normal, f.leftPlane.normal, f.farPlane.normal );
|
||||||
|
float3 farTopRight = func( f.topPlane.normal, f.rightPlane.normal, f.farPlane.normal );
|
||||||
|
float3 farBottomLeft = func( f.bottomPlane.normal, f.leftPlane.normal, f.farPlane.normal );
|
||||||
|
float3 farBottomRight = func( f.bottomPlane.normal, f.rightPlane.normal, f.farPlane.normal );
|
|
@ -0,0 +1,193 @@
|
||||||
|
#include"RawInput.h"
|
||||||
|
|
||||||
|
|
||||||
|
//DefRawInputProc
|
||||||
|
//GetRawInputDeviceList
|
||||||
|
//GetRegisteredRawInputDevices
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LRESULT CALLBACK RawInput::WM_INPUT_TRANSLATE (int nCode, WPARAM wParam, LPARAM lparam)
|
||||||
|
{
|
||||||
|
if (nCode < 0) return CallNextHookEx(RawInput::Self()->_msgHook, nCode, wParam, lparam);
|
||||||
|
|
||||||
|
|
||||||
|
MSG *m = (MSG*)lparam;
|
||||||
|
|
||||||
|
if(m->message == WM_INPUT)
|
||||||
|
{
|
||||||
|
RAWINPUT* raw = RawInput::Self()->_TranslateRawInput(m->lParam);
|
||||||
|
|
||||||
|
if(!raw) goto nextHook;
|
||||||
|
if(!RawInput::Self()->Self()->_enabled)
|
||||||
|
{
|
||||||
|
if(FAILED ( DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)) ) )
|
||||||
|
RawInput::Self()->_errorMsg = L"Failed to proccess default raw input";
|
||||||
|
goto _final;
|
||||||
|
}
|
||||||
|
// if(raw->header.dwType == RIM_TYPEMOUSE) RawInput::Self()->_idleMouseData.insert(raw->data.mouse);
|
||||||
|
//else if(raw->header.dwType == RIM_TYPEKEYBOARD) RawInput::Self()->_proccessRawKeyboardData(raw->data.keyboard);
|
||||||
|
|
||||||
|
|
||||||
|
_final:
|
||||||
|
|
||||||
|
//if(FAILED ( DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)) ) )
|
||||||
|
// RawInput::Self()->_errorMsg = L"Failed to proccess default raw input";
|
||||||
|
|
||||||
|
delete raw;
|
||||||
|
}
|
||||||
|
else if (m->message == WM_QUIT)
|
||||||
|
{
|
||||||
|
if(UnhookWindowsHookEx(RawInput::Self()->_msgHook) == FALSE)
|
||||||
|
{
|
||||||
|
RawInput::Self()->_errorMsg = L"Failed to unhook message hook!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nextHook:
|
||||||
|
return CallNextHookEx(RawInput::Self()->_msgHook, nCode, wParam, lparam);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RAWINPUT* RawInput::_TranslateRawInput (LPARAM l)
|
||||||
|
{
|
||||||
|
//Get The size of the raw data buffer
|
||||||
|
UINT bufferSize;
|
||||||
|
GetRawInputData((HRAWINPUT)l, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER));
|
||||||
|
if (bufferSize < 1)
|
||||||
|
{
|
||||||
|
//Something went wrong
|
||||||
|
RawInput::Self()->_errorMsg = L"Failed to read raw buffer data in input class";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create and read the raw input data
|
||||||
|
LPBYTE rawBufferIn = new BYTE[bufferSize];
|
||||||
|
UINT readBytes = GetRawInputData((HRAWINPUT)l, RID_INPUT, rawBufferIn, &bufferSize, sizeof(RAWINPUTHEADER));
|
||||||
|
if ( readBytes != bufferSize )
|
||||||
|
{
|
||||||
|
RawInput::Self()->_errorMsg = L"Could not read raw input data";
|
||||||
|
delete [] rawBufferIn;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (RAWINPUT*)rawBufferIn;
|
||||||
|
}
|
||||||
|
void RawInput::_proccessRawKeyboardData (RAWKEYBOARD& k)
|
||||||
|
{
|
||||||
|
if(!this->_KeyboardEnabled) return;
|
||||||
|
|
||||||
|
//The key is released.
|
||||||
|
if(k.Flags == RI_KEY_BREAK || k.Flags == (RI_KEY_BREAK | RI_KEY_E0) || k.Flags == (RI_KEY_BREAK | RI_KEY_E1))
|
||||||
|
{
|
||||||
|
if(k.Message == WM_SYSKEYUP)
|
||||||
|
{
|
||||||
|
// if(k.VKey == VK_CONTROL) this->_procCollection.skd.ctrl = false;
|
||||||
|
//else if(k.VKey == VK_MENU) this->_procCollection.skd.alt = false;
|
||||||
|
//else if(k.VKey == VK_SHIFT) this->_procCollection.skd.shift = false;
|
||||||
|
}
|
||||||
|
else if(k.Message == WM_KEYUP)
|
||||||
|
{
|
||||||
|
//this->_procCollection.kd.key = (RIK)k.VKey;
|
||||||
|
//this->_procCollection.kd.released = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//The key is pressed.
|
||||||
|
else if (k.Flags == RI_KEY_MAKE || k.Flags == (RI_KEY_MAKE | RI_KEY_E0) || k.Flags == (RI_KEY_MAKE | RI_KEY_E1))
|
||||||
|
{
|
||||||
|
if(k.Message == WM_SYSKEYDOWN)
|
||||||
|
{
|
||||||
|
// if(k.VKey == VK_CONTROL) this->_procCollection.skd.ctrl = true;
|
||||||
|
//else if(k.VKey == VK_MENU) this->_procCollection.skd.alt = true;
|
||||||
|
//else if(k.VKey == VK_SHIFT) this->_procCollection.skd.shift = true;
|
||||||
|
}
|
||||||
|
else if(k.Message == WM_KEYDOWN)
|
||||||
|
{
|
||||||
|
//this->_procCollection.kd.key = (RIK)k.VKey;
|
||||||
|
//this->_procCollection.kd.released = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void RawInput::_proccessRawMouseData (RAWMOUSE& m)
|
||||||
|
{
|
||||||
|
if(!this->_mouseEnabled) return;
|
||||||
|
|
||||||
|
if(m.lLastX != 0 || m.lLastY != 0)
|
||||||
|
{
|
||||||
|
//this->_procCollection.mmd.MousePos_X += m.lLastX;
|
||||||
|
//this->_procCollection.mmd.MousePos_Y += m.lLastY;
|
||||||
|
}
|
||||||
|
if( m.usButtonFlags > 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (m.usButtonFlags)
|
||||||
|
{
|
||||||
|
//Mouse button pressed
|
||||||
|
case RI_MOUSE_LEFT_BUTTON_DOWN:
|
||||||
|
case RI_MOUSE_RIGHT_BUTTON_DOWN:
|
||||||
|
case RI_MOUSE_MIDDLE_BUTTON_DOWN:
|
||||||
|
{
|
||||||
|
if(m.usButtonFlags == RI_MOUSE_LEFT_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
//MOUSE_INPUT_btnData.key = RIK_LeftBtn;
|
||||||
|
//LBTNDOWN = true;
|
||||||
|
}
|
||||||
|
else if(m.usButtonFlags == RI_MOUSE_MIDDLE_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
//MOUSE_INPUT_btnData.key = RIK_MiddleBtn;
|
||||||
|
//MBTNDOWN = true;
|
||||||
|
}
|
||||||
|
else if(m.usButtonFlags == RI_MOUSE_RIGHT_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
//MOUSE_INPUT_btnData.key = RIK_RightBtn;
|
||||||
|
//RBTNDOWN = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Mouse button Released
|
||||||
|
case RI_MOUSE_LEFT_BUTTON_UP:
|
||||||
|
case RI_MOUSE_RIGHT_BUTTON_UP:
|
||||||
|
case RI_MOUSE_MIDDLE_BUTTON_UP:
|
||||||
|
{
|
||||||
|
if(m.usButtonFlags == RI_MOUSE_LEFT_BUTTON_UP)
|
||||||
|
{
|
||||||
|
//MOUSE_INPUT_btnData.key = RIK_LeftBtn;
|
||||||
|
//LBTNDOWN = false;
|
||||||
|
}
|
||||||
|
else if(m.usButtonFlags == RI_MOUSE_MIDDLE_BUTTON_UP)
|
||||||
|
{
|
||||||
|
//MOUSE_INPUT_btnData.key = RIK_MiddleBtn;
|
||||||
|
//MBTNDOWN = false;
|
||||||
|
}
|
||||||
|
else if(m.usButtonFlags == RI_MOUSE_RIGHT_BUTTON_UP)
|
||||||
|
{
|
||||||
|
//MOUSE_INPUT_btnData.key = RIK_RightBtn;
|
||||||
|
//RBTNDOWN = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RI_MOUSE_WHEEL:
|
||||||
|
{
|
||||||
|
int d = ((int)m.usButtonData);
|
||||||
|
|
||||||
|
if(d > 120) d = -1;
|
||||||
|
else d = 1;
|
||||||
|
|
||||||
|
//this->_procCollection.wd = d;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
#include "RawInput.h"
|
||||||
|
|
||||||
|
void RawInput::Mouse_Show()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void RawInput::Mouse_Hide()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void RawInput::Mouse_Lock()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void RawInput::Mouse_Unlock()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void RawInput::Mouse_IsBtnPressed(IN RIK)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
int RawInput::Mouse_WheelDelta()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
POINT RawInput::Mouse_Position()
|
||||||
|
{
|
||||||
|
POINT p = {0, 0};
|
||||||
|
//POINT p = { this->_activeInputData.data.MOUSE_DATA.MousePos_X, this->_activeInputData.data.MOUSE_DATA.MousePos_Y };
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawInput::Mouse_Enable()
|
||||||
|
{
|
||||||
|
this->_mouseEnabled = true;
|
||||||
|
}
|
||||||
|
void RawInput::Mouse_Disable()
|
||||||
|
{
|
||||||
|
this->_mouseEnabled = false;
|
||||||
|
}
|
||||||
|
bool RawInput::Keyboard_KeyUp(IN RIK key)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool RawInput::Keyboard_KeyDown(IN RIK key)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void RawInput::Keyboard_Enable()
|
||||||
|
{
|
||||||
|
this->_KeyboardEnabled = true;
|
||||||
|
}
|
||||||
|
void RawInput::Keyboard_Disable()
|
||||||
|
{
|
||||||
|
this->_KeyboardEnabled = false;
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
#include "RawInput.h"
|
||||||
|
|
||||||
|
|
||||||
|
template<typename FNC, typename PARAM, typename OBJECT_PARAM>
|
||||||
|
void SUBSCRIBE(SubscribeList<FNC, PARAM>* l, FNC _fnc, OBJECT_PARAM p)
|
||||||
|
{
|
||||||
|
SubscribeList<FNC, PARAM>* t = new SubscribeList<FNC, PARAM>();
|
||||||
|
|
||||||
|
t->param = p;
|
||||||
|
t->fnc = _fnc;
|
||||||
|
t->next = l;
|
||||||
|
l = t;
|
||||||
|
}
|
||||||
|
template<typename FNC, typename PARAM>
|
||||||
|
void UNSUBSCRIBE(SubscribeList<FNC, PARAM>* l, FNC fnc)
|
||||||
|
{
|
||||||
|
SubscribeList<FNC, PARAM>* w = l;
|
||||||
|
SubscribeList<FNC, PARAM>* p = 0;
|
||||||
|
while (w)
|
||||||
|
{
|
||||||
|
if(w->fnc == fnc)
|
||||||
|
{
|
||||||
|
if(p)
|
||||||
|
p->next = w->next;
|
||||||
|
|
||||||
|
delete w;
|
||||||
|
w = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p = w;
|
||||||
|
w = w->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RawInput::Input_Subscribe (IN INPUT_CALLBACK fnc)
|
||||||
|
{
|
||||||
|
//SUBSCRIBE(this->_procInput, fnc, &this->_procCollection.id);
|
||||||
|
}
|
||||||
|
void RawInput::Input_Unsubscribe (IN INPUT_CALLBACK fnc)
|
||||||
|
{
|
||||||
|
//UNSUBSCRIBE(this->_procSystemKey, fnc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
void RawInput::Subscribe (RAW_KEY_PROC fnc)
|
||||||
|
{
|
||||||
|
KeyboardProcList* t = new KeyboardProcList();
|
||||||
|
t->fnc = fnc;
|
||||||
|
t->next = 0;
|
||||||
|
|
||||||
|
KeyboardProcList* w = this->_keyProcList;
|
||||||
|
KeyboardProcList* prev = this->_keyProcList;
|
||||||
|
|
||||||
|
while (w)
|
||||||
|
{
|
||||||
|
prev = w;
|
||||||
|
w = w->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev->next = t;
|
||||||
|
}
|
||||||
|
void RawInput::Subscribe (RAW_MOUSE_PROC fnc)
|
||||||
|
{
|
||||||
|
MouseProcList* t = new MouseProcList();
|
||||||
|
t->fnc = fnc;
|
||||||
|
t->next = 0;
|
||||||
|
|
||||||
|
MouseProcList* w = this->_mouseProcList;
|
||||||
|
MouseProcList* prev = this->_mouseProcList;
|
||||||
|
|
||||||
|
while (w)
|
||||||
|
{
|
||||||
|
prev = w;
|
||||||
|
w = w->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev->next = t;
|
||||||
|
}
|
||||||
|
void RawInput::Unsubscribe (RAW_KEY_PROC fnc)
|
||||||
|
{
|
||||||
|
KeyboardProcList* w = this->_keyProcList;
|
||||||
|
KeyboardProcList* prev = 0;
|
||||||
|
|
||||||
|
while (w)
|
||||||
|
{
|
||||||
|
if(w->fnc == fnc)
|
||||||
|
{
|
||||||
|
if(prev)
|
||||||
|
prev->next = w->next;
|
||||||
|
|
||||||
|
delete w;
|
||||||
|
w = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prev = w;
|
||||||
|
w = w->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void RawInput::Unsubscribe (RAW_MOUSE_PROC fnc)
|
||||||
|
{
|
||||||
|
MouseProcList* w = this->_mouseProcList;
|
||||||
|
MouseProcList* prev = 0;
|
||||||
|
|
||||||
|
while (w)
|
||||||
|
{
|
||||||
|
if(w->fnc == fnc)
|
||||||
|
{
|
||||||
|
if(prev)
|
||||||
|
prev->next = w->next;
|
||||||
|
|
||||||
|
delete w;
|
||||||
|
w = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prev = w;
|
||||||
|
w = w->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
#include "RawInput.h"
|
||||||
|
#include <WindowsX.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
static RawInput* gInstance = 0;
|
||||||
|
|
||||||
|
template<typename FNC, typename PARAM> void DESTROY_LIST(SubscribeList<FNC, PARAM>* l)
|
||||||
|
{
|
||||||
|
SubscribeList<FNC, PARAM>* w = l;
|
||||||
|
SubscribeList<FNC, PARAM>* p = 0;
|
||||||
|
|
||||||
|
while (w)
|
||||||
|
{
|
||||||
|
p = w;
|
||||||
|
w = w->next;
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename FNC, typename PARAM> void PROCESS_SUBSCRIBERS(SubscribeList<FNC, PARAM>* l)
|
||||||
|
{
|
||||||
|
while (l)
|
||||||
|
{
|
||||||
|
l->fnc(l->param);
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RawInputWrapper* RawInputWrapper::Self ()
|
||||||
|
{
|
||||||
|
return (RawInputWrapper*)RawInput::Self();
|
||||||
|
}
|
||||||
|
void RawInputWrapper::Destroy ()
|
||||||
|
{
|
||||||
|
RawInput::Destroy();
|
||||||
|
}
|
||||||
|
RawInput* RawInput::Self ()
|
||||||
|
{
|
||||||
|
if(!gInstance)
|
||||||
|
gInstance = new RawInput();
|
||||||
|
|
||||||
|
return gInstance;
|
||||||
|
}
|
||||||
|
void RawInput::Destroy ()
|
||||||
|
{
|
||||||
|
/************************ Delete subscribers ****************************/
|
||||||
|
DESTROY_LIST(RawInput::Self()->_procInput);
|
||||||
|
|
||||||
|
/************************ Delete Other stuff ****************************/
|
||||||
|
ShowCursor(true);
|
||||||
|
RECT r;
|
||||||
|
GetWindowRect(GetDesktopWindow(), &r);
|
||||||
|
ClipCursor(&r);
|
||||||
|
|
||||||
|
/************************ Delete instance ****************************/
|
||||||
|
delete gInstance;
|
||||||
|
gInstance = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RawInput::RawInput ()
|
||||||
|
: _procInput(0)
|
||||||
|
, _enabled(1)
|
||||||
|
, _mouseEnabled(1)
|
||||||
|
, _KeyboardEnabled(1)
|
||||||
|
, _exclusive(0)
|
||||||
|
, _errorMsg(0)
|
||||||
|
, _msgHook(SetWindowsHookEx(WH_GETMESSAGE, WM_INPUT_TRANSLATE, (HINSTANCE)0, GetCurrentThreadId()))
|
||||||
|
{
|
||||||
|
if(!_msgHook) this->_errorMsg = L"Failed to initiate window message hook";
|
||||||
|
}
|
||||||
|
RawInput::~RawInput ()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
const wchar_t* RawInput::Input_GetError() const
|
||||||
|
{
|
||||||
|
return this->_errorMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RawInput::Input_AddDevice(IN const HWND& targetApplication)
|
||||||
|
{
|
||||||
|
assert(targetApplication != 0);
|
||||||
|
static const UINT c = 2;
|
||||||
|
RAWINPUTDEVICE devices[c] =
|
||||||
|
{
|
||||||
|
{ 0x01, RawInput_Usage_keyboard, RIDEV_NOLEGACY, targetApplication },
|
||||||
|
{ 0x01, RawInput_Usage_mouse, RIDEV_NOLEGACY | RIDEV_CAPTUREMOUSE, targetApplication }
|
||||||
|
};
|
||||||
|
|
||||||
|
if(! _addDevice( devices , c ) ) return false;
|
||||||
|
|
||||||
|
ShowCursor(FALSE);
|
||||||
|
//RECT r;
|
||||||
|
//GetWindow
|
||||||
|
//GetWindowRect(
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool RawInput::Input_AddDevice(IN const RAWINPUTDEVICE* d, const int& count)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
if(!d[i].hwndTarget)
|
||||||
|
{
|
||||||
|
this->_errorMsg = L"Must specify target application";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(! _addDevice( d, count ) ) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//RAWINPUTDEVICE d = { 0x01, type, RIDEV_REMOVE, NULL };
|
||||||
|
//this->_errorMsg = L"Failed to unregister device";
|
||||||
|
|
||||||
|
|
||||||
|
void RawInput::Input_Disable()
|
||||||
|
{
|
||||||
|
this->_enabled = false;
|
||||||
|
}
|
||||||
|
void RawInput::Input_Enable()
|
||||||
|
{
|
||||||
|
this->_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawInput::Input_Read()
|
||||||
|
{
|
||||||
|
//for (int i = 0; i < this->_idleKeyData.size(); i++)
|
||||||
|
// this->_proccessRawKeyboardData(this->_idleKeyData.pop());
|
||||||
|
//for (int i = 0; i < this->_idleMouseData.size(); i++)
|
||||||
|
// this->_proccessRawMouseData(this->_idleMouseData.pop());
|
||||||
|
//
|
||||||
|
//this->_idleKeyData.clear();
|
||||||
|
//this->_idleMouseData.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool RawInput::_addDevice (const RAWINPUTDEVICE* k, const int& count)
|
||||||
|
{
|
||||||
|
if(RegisterRawInputDevices(k, count, sizeof(RAWINPUTDEVICE)) == FALSE)
|
||||||
|
{
|
||||||
|
DWORD h = GetLastError();
|
||||||
|
this->_errorMsg = L"Failed to register device";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int q = 0; q < count; q++)
|
||||||
|
{
|
||||||
|
RawInputDeviceInstance i;
|
||||||
|
memcpy(&i.description, &k[q], sizeof(RAWINPUTDEVICE));
|
||||||
|
this->_deviceList.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
#include "RawInputWrapper.h"
|
||||||
|
// include the basic windows header file
|
||||||
|
#include <windows.h>
|
||||||
|
#include <windowsx.h>
|
||||||
|
#include <vld.h>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
|
||||||
|
HWND hWnd;
|
||||||
|
// this is the main message handler for the program
|
||||||
|
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
// sort through and find what code to run for the message given
|
||||||
|
switch(message)
|
||||||
|
{
|
||||||
|
// this message is read when the window is closed
|
||||||
|
case WM_DESTROY:
|
||||||
|
{
|
||||||
|
// close the application entirely
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return 0;
|
||||||
|
} break;
|
||||||
|
case WM_KEYUP:
|
||||||
|
MessageBox(0, L"WM_KEYUP", L"", 0);
|
||||||
|
break;
|
||||||
|
case WM_KEYDOWN:
|
||||||
|
MessageBox(0, L"WM_KEYDOWN", L"", 0);
|
||||||
|
break;
|
||||||
|
//case WM_INPUT:
|
||||||
|
// MessageBox(0, L"WM_INPUT_MAIN", L"", 0);
|
||||||
|
//break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle any messages the switch statement didn't
|
||||||
|
return DefWindowProc (hWnd, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
void initWindow(HINSTANCE h, int i)
|
||||||
|
{
|
||||||
|
// this struct holds information for the window class
|
||||||
|
WNDCLASSEX wc;
|
||||||
|
|
||||||
|
// clear out the window class for use
|
||||||
|
ZeroMemory(&wc, sizeof(WNDCLASSEX));
|
||||||
|
|
||||||
|
// fill in the struct with the needed information
|
||||||
|
wc.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
|
wc.lpfnWndProc = WindowProc;
|
||||||
|
wc.hInstance = h;
|
||||||
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||||
|
wc.lpszClassName = L"WindowClass1";
|
||||||
|
|
||||||
|
// register the window class
|
||||||
|
RegisterClassEx(&wc);
|
||||||
|
|
||||||
|
// create the window and use the result as the handle
|
||||||
|
hWnd = CreateWindowEx(NULL,
|
||||||
|
L"WindowClass1", // name of the window class
|
||||||
|
L"Our First Windowed Program", // title of the window
|
||||||
|
WS_OVERLAPPEDWINDOW, // window style
|
||||||
|
300, // x-position of the window
|
||||||
|
300, // y-position of the window
|
||||||
|
500, // width of the window
|
||||||
|
400, // height of the window
|
||||||
|
NULL, // we have no parent window, NULL
|
||||||
|
NULL, // we aren't using menus, NULL
|
||||||
|
h, // application handle
|
||||||
|
NULL); // used with multiple windows, NULL
|
||||||
|
|
||||||
|
// display the window on the screen
|
||||||
|
ShowWindow(hWnd, i);
|
||||||
|
}
|
||||||
|
void initRaw()
|
||||||
|
{
|
||||||
|
RawInputWrapper::Self()->Input_AddDevice(hWnd);
|
||||||
|
}
|
||||||
|
// the entry point for any Windows program
|
||||||
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||||
|
{
|
||||||
|
initWindow(hInstance, nCmdShow);
|
||||||
|
initRaw();
|
||||||
|
|
||||||
|
|
||||||
|
// this struct holds Windows event messages
|
||||||
|
MSG msg;
|
||||||
|
|
||||||
|
// wait for the next message in the queue, store the result in 'msg'
|
||||||
|
while(GetMessage(&msg, NULL, 0, 0))
|
||||||
|
{
|
||||||
|
// translate keystroke messages into the right format
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
// send the message to the WindowProc function
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
|
||||||
|
RawInputWrapper::Self()->Input_Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
RawInputWrapper::Destroy();
|
||||||
|
|
||||||
|
return msg.wParam;
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
#ifndef INCLUDE_GUARD_RAW_INPUT_H
|
||||||
|
#define INCLUDE_GUARD_RAW_INPUT_H
|
||||||
|
|
||||||
|
#include "RawInputWrapper.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO:
|
||||||
|
* 1. Origo in middle of the screen (-1 to 1)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//dx = +2*(x/w) -1
|
||||||
|
//dx = -2*(y/h) +1
|
||||||
|
|
||||||
|
template<class FNC, class PARAM>
|
||||||
|
struct SubscribeList
|
||||||
|
{
|
||||||
|
FNC fnc;
|
||||||
|
PARAM param;
|
||||||
|
SubscribeList* next;
|
||||||
|
};
|
||||||
|
struct RawInputDeviceInstance
|
||||||
|
{
|
||||||
|
RAWINPUTDEVICE description;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum RawInput_Usage
|
||||||
|
{
|
||||||
|
RawInput_Usage_pointer = 1,
|
||||||
|
RawInput_Usage_mouse = 2,
|
||||||
|
RawInput_Usage_joystick = 4,
|
||||||
|
RawInput_Usage_gamepad = 5,
|
||||||
|
RawInput_Usage_keyboard = 6,
|
||||||
|
RawInput_Usage_keypad = 7,
|
||||||
|
RawInput_Usage_multiAxisController = 8,
|
||||||
|
RawInput_Usage_TabletPCcontrols = 9,
|
||||||
|
};
|
||||||
|
|
||||||
|
class RawInput :public RawInputWrapper
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SubscribeList<INPUT_CALLBACK, const RawInputData*>* _procInput;
|
||||||
|
|
||||||
|
bool _enabled;
|
||||||
|
bool _mouseEnabled;
|
||||||
|
bool _KeyboardEnabled;
|
||||||
|
bool _exclusive;
|
||||||
|
const wchar_t* _errorMsg;
|
||||||
|
List<RawInputDeviceInstance> _deviceList;
|
||||||
|
|
||||||
|
List<RawInputData> _mouseInput;
|
||||||
|
List<RawInputData> _keyboardInput;
|
||||||
|
|
||||||
|
HHOOK _msgHook;
|
||||||
|
|
||||||
|
private:
|
||||||
|
RawInput ();
|
||||||
|
~RawInput ();
|
||||||
|
|
||||||
|
bool _addDevice (const RAWINPUTDEVICE* k, const int& count);
|
||||||
|
RAWINPUT*_TranslateRawInput (LPARAM l);
|
||||||
|
void _proccessRawMouseData (RAWMOUSE&);
|
||||||
|
void _proccessRawKeyboardData (RAWKEYBOARD&);
|
||||||
|
|
||||||
|
static LRESULT CALLBACK WM_INPUT_TRANSLATE (int nCode, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static RawInput* Self ();
|
||||||
|
static void Destroy ();
|
||||||
|
|
||||||
|
const wchar_t* Input_GetError () const;
|
||||||
|
|
||||||
|
bool Input_AddDevice (IN const HWND& targetApplication);
|
||||||
|
bool Input_AddDevice (IN const RAWINPUTDEVICE*, IN const int&);
|
||||||
|
|
||||||
|
void Input_Subscribe (IN INPUT_CALLBACK fnc);
|
||||||
|
void Input_Unsubscribe (IN INPUT_CALLBACK fnc);
|
||||||
|
|
||||||
|
void Input_Disable ();
|
||||||
|
void Input_Enable ();
|
||||||
|
|
||||||
|
void Input_Read ();
|
||||||
|
|
||||||
|
void Mouse_Show ();
|
||||||
|
void Mouse_Hide ();
|
||||||
|
void Mouse_Lock ();
|
||||||
|
void Mouse_Unlock ();
|
||||||
|
void Mouse_IsBtnPressed (IN RIK);
|
||||||
|
int Mouse_WheelDelta ();
|
||||||
|
POINT Mouse_Position ();
|
||||||
|
void Mouse_Enable ();
|
||||||
|
void Mouse_Disable ();
|
||||||
|
|
||||||
|
bool Keyboard_KeyUp (IN RIK key);
|
||||||
|
bool Keyboard_KeyDown (IN RIK key);
|
||||||
|
void Keyboard_Enable ();
|
||||||
|
void Keyboard_Disable ();
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,215 @@
|
||||||
|
#ifndef RAW_INPUT_H
|
||||||
|
#define RAW_INPUT_H
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/***************************** Keycodes ******************************/
|
||||||
|
/*********************************************************************/
|
||||||
|
//! Contains keycodes
|
||||||
|
enum RIK
|
||||||
|
{
|
||||||
|
RIK_Backspace = 0x08,
|
||||||
|
RIK_Tab = 0x09,
|
||||||
|
RIK_Enter = 0x0D,
|
||||||
|
RIK_Shift = 0x10,
|
||||||
|
RIK_Ctrl = 0x11,
|
||||||
|
RIK_Alt = 0x12,
|
||||||
|
RIK_Pause = 0x13,
|
||||||
|
RIK_CapsLock = 0x14,
|
||||||
|
RIK_Escape = 0x1B,
|
||||||
|
RIK_Space = 0x20,
|
||||||
|
RIK_PgUp = 0x21,
|
||||||
|
RIK_PgDown = 0x22,
|
||||||
|
RIK_End = 0x23,
|
||||||
|
RIK_Home = 0x24,
|
||||||
|
RIK_Left = 0x25,
|
||||||
|
RIK_Up = 0x26,
|
||||||
|
RIK_Right = 0x27,
|
||||||
|
RIK_Down = 0x28,
|
||||||
|
RIK_PrintScreen = 0x2C,
|
||||||
|
RIK_Insert = 0x2D,
|
||||||
|
RIK_Delete = 0x2E,
|
||||||
|
RIK_0 = 0x30,
|
||||||
|
RIK_1 = 0x31,
|
||||||
|
RIK_2 = 0x32,
|
||||||
|
RIK_3 = 0x33,
|
||||||
|
RIK_4 = 0x34,
|
||||||
|
RIK_5 = 0x35,
|
||||||
|
RIK_6 = 0x36,
|
||||||
|
RIK_7 = 0x37,
|
||||||
|
RIK_8 = 0x38,
|
||||||
|
RIK_9 = 0x39,
|
||||||
|
RIK_A = 0x41,
|
||||||
|
RIK_B = 0x42,
|
||||||
|
RIK_C = 0x43,
|
||||||
|
RIK_D = 0x44,
|
||||||
|
RIK_E = 0x45,
|
||||||
|
RIK_F = 0x46,
|
||||||
|
RIK_G = 0x47,
|
||||||
|
RIK_H = 0x48,
|
||||||
|
RIK_I = 0x49,
|
||||||
|
RIK_J = 0x4A,
|
||||||
|
RIK_K = 0x4B,
|
||||||
|
RIK_L = 0x4C,
|
||||||
|
RIK_M = 0x4D,
|
||||||
|
RIK_N = 0x4E,
|
||||||
|
RIK_O = 0x4F,
|
||||||
|
RIK_P = 0x50,
|
||||||
|
RIK_Q = 0x51,
|
||||||
|
RIK_R = 0x52,
|
||||||
|
RIK_S = 0x53,
|
||||||
|
RIK_T = 0x54,
|
||||||
|
RIK_U = 0x55,
|
||||||
|
RIK_V = 0x56,
|
||||||
|
RIK_W = 0x57,
|
||||||
|
RIK_X = 0x58,
|
||||||
|
RIK_Y = 0x59,
|
||||||
|
RIK_Z = 0x5A,
|
||||||
|
RIK_LeftWindows = 0x5B,
|
||||||
|
RIK_RightWindows = 0x5C,
|
||||||
|
RIK_Numpad0 = 0x60,
|
||||||
|
RIK_Numpad1 = 0x61,
|
||||||
|
RIK_Numpad2 = 0x62,
|
||||||
|
RIK_Numpad3 = 0x63,
|
||||||
|
RIK_Numpad4 = 0x64,
|
||||||
|
RIK_Numpad5 = 0x65,
|
||||||
|
RIK_Numpad6 = 0x66,
|
||||||
|
RIK_Numpad7 = 0x67,
|
||||||
|
RIK_Numpad8 = 0x68,
|
||||||
|
RIK_Numpad9 = 0x69,
|
||||||
|
RIK_Multiply = 0x6A,
|
||||||
|
RIK_Plus = 0x6B,
|
||||||
|
RIK_Subtract = 0x6D,
|
||||||
|
RIK_Decimal = 0x6E,
|
||||||
|
RIK_Divide = 0x6F,
|
||||||
|
RIK_F1 = 0x70,
|
||||||
|
RIK_F2 = 0x71,
|
||||||
|
RIK_F3 = 0x72,
|
||||||
|
RIK_F4 = 0x73,
|
||||||
|
RIK_F5 = 0x74,
|
||||||
|
RIK_F6 = 0x75,
|
||||||
|
RIK_F7 = 0x76,
|
||||||
|
RIK_F8 = 0x77,
|
||||||
|
RIK_F9 = 0x78,
|
||||||
|
RIK_F10 = 0x79,
|
||||||
|
RIK_F11 = 0x7A,
|
||||||
|
RIK_F12 = 0x7B,
|
||||||
|
RIK_F13 = 0x7C,
|
||||||
|
RIK_F14 = 0x7D,
|
||||||
|
RIK_F15 = 0x7E,
|
||||||
|
RIK_F16 = 0x7F,
|
||||||
|
RIK_F17 = 0x80,
|
||||||
|
RIK_F18 = 0x81,
|
||||||
|
RIK_F19 = 0x82,
|
||||||
|
RIK_F20 = 0x83,
|
||||||
|
RIK_F21 = 0x84,
|
||||||
|
RIK_F22 = 0x85,
|
||||||
|
RIK_F23 = 0x86,
|
||||||
|
RIK_F24 = 0x87,
|
||||||
|
RIK_Numlock = 0x90,
|
||||||
|
RIK_ScrlLock = 0x91,
|
||||||
|
RIK_LeftShift = 0xA0,
|
||||||
|
RIK_RightShift = 0xA1,
|
||||||
|
RIK_LeftCtrl = 0xA2,
|
||||||
|
RIK_RightCtrl = 0xA3,
|
||||||
|
|
||||||
|
COUNT
|
||||||
|
};
|
||||||
|
enum RIM
|
||||||
|
{
|
||||||
|
RIM_LeftBtn = 0x02,
|
||||||
|
RIM_MiddleBtn = 0x10,
|
||||||
|
RIM_RightBtn = 0x04,
|
||||||
|
RIM_Scroll = 0x0400,
|
||||||
|
};
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/***************************** Callback data ******************************/
|
||||||
|
/**************************************************************************/
|
||||||
|
enum InputType
|
||||||
|
{
|
||||||
|
InputType_Keyboard,
|
||||||
|
InputType_Mouse,
|
||||||
|
InputType_HID,
|
||||||
|
};
|
||||||
|
struct RawMouseData
|
||||||
|
{
|
||||||
|
bool shift;
|
||||||
|
bool alt;
|
||||||
|
bool ctrl;
|
||||||
|
|
||||||
|
RIM key;
|
||||||
|
bool pressed;
|
||||||
|
|
||||||
|
int MousePos_X;
|
||||||
|
int MousePos_Y;
|
||||||
|
|
||||||
|
int delta;
|
||||||
|
};
|
||||||
|
struct RawKeyData
|
||||||
|
{
|
||||||
|
bool shift;
|
||||||
|
bool alt;
|
||||||
|
bool ctrl;
|
||||||
|
|
||||||
|
RIK key;
|
||||||
|
bool released;
|
||||||
|
};
|
||||||
|
struct RawInputData
|
||||||
|
{
|
||||||
|
InputType type;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
RawMouseData MOUSE_DATA;
|
||||||
|
RawKeyData KEYBOARD_DATA;
|
||||||
|
RAWHID HID_DATA;
|
||||||
|
} data;
|
||||||
|
};
|
||||||
|
typedef void(*INPUT_CALLBACK)(const RawInputData*);
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
class RawInputWrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static RawInputWrapper* Self ();
|
||||||
|
static void Destroy ();
|
||||||
|
|
||||||
|
virtual const wchar_t* Input_GetError () const PURE;
|
||||||
|
|
||||||
|
virtual bool Input_AddDevice (IN const HWND& targetApplication) PURE;
|
||||||
|
virtual bool Input_AddDevice (IN const RAWINPUTDEVICE* d, IN const int& count) PURE;
|
||||||
|
|
||||||
|
virtual void Input_Subscribe (IN INPUT_CALLBACK fnc) PURE;
|
||||||
|
virtual void Input_Unsubscribe (IN INPUT_CALLBACK fnc) PURE;
|
||||||
|
|
||||||
|
virtual void Input_Disable () PURE;
|
||||||
|
virtual void Input_Enable () PURE;
|
||||||
|
|
||||||
|
virtual void Input_Read () PURE;
|
||||||
|
|
||||||
|
virtual void Mouse_Show () PURE;
|
||||||
|
virtual void Mouse_Hide () PURE;
|
||||||
|
virtual void Mouse_Lock () PURE;
|
||||||
|
virtual void Mouse_Unlock () PURE;
|
||||||
|
virtual void Mouse_IsBtnPressed (IN RIK key) PURE;
|
||||||
|
virtual int Mouse_WheelDelta () PURE;
|
||||||
|
virtual POINT Mouse_Position () PURE;
|
||||||
|
virtual void Mouse_Enable () PURE;
|
||||||
|
virtual void Mouse_Disable () PURE;
|
||||||
|
|
||||||
|
virtual bool Keyboard_KeyUp (IN RIK key) PURE;
|
||||||
|
virtual bool Keyboard_KeyDown (IN RIK key) PURE;
|
||||||
|
virtual void Keyboard_Enable () PURE;
|
||||||
|
virtual void Keyboard_Disable () PURE;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
#ifndef MISC_H
|
||||||
|
#define MISC_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class List
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
class Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
T value;
|
||||||
|
Node *next;
|
||||||
|
Node(T value){ this->value = value; this->next = NULL; }
|
||||||
|
~Node() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
Node *first;
|
||||||
|
int nrOfNodes;
|
||||||
|
|
||||||
|
public:
|
||||||
|
List::List()
|
||||||
|
{
|
||||||
|
this->first = NULL;
|
||||||
|
this->nrOfNodes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
List::~List()
|
||||||
|
{
|
||||||
|
Node *walker = this->first;
|
||||||
|
|
||||||
|
for(int i = 0; i<this->nrOfNodes; i++)
|
||||||
|
{
|
||||||
|
walker = walker->next;
|
||||||
|
delete this->first;
|
||||||
|
this->first = walker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List& List::operator=(const List& origObj)
|
||||||
|
{
|
||||||
|
if(this->nrOfNodes > 0)
|
||||||
|
{
|
||||||
|
Node *walker = this->first;
|
||||||
|
|
||||||
|
for(int i = 0; i<this->nrOfNodes; i++)
|
||||||
|
{
|
||||||
|
walker = walker->next;
|
||||||
|
delete this->first;
|
||||||
|
this->first = walker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->nrOfNodes = 0;
|
||||||
|
if(origObj.nrOfNodes > 0)
|
||||||
|
{
|
||||||
|
Node *walker = origObj.first;
|
||||||
|
|
||||||
|
for(int i = 0; i<origObj.nrOfNodes; i++)
|
||||||
|
{
|
||||||
|
insertLast(walker->value);
|
||||||
|
walker = walker->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void List::push(T value)
|
||||||
|
{
|
||||||
|
Node *e = new Node(value);
|
||||||
|
e->next = this->first;
|
||||||
|
this->first = e;
|
||||||
|
e = NULL;
|
||||||
|
this->nrOfNodes++;
|
||||||
|
}
|
||||||
|
|
||||||
|
T List::pop()
|
||||||
|
{
|
||||||
|
T removed;
|
||||||
|
memset(&removed, 0, sizeof(T));
|
||||||
|
|
||||||
|
if(this->nrOfNodes > 0)
|
||||||
|
{
|
||||||
|
Node *temp = first;
|
||||||
|
this->first = first->next;
|
||||||
|
memcpy(&removed, &temp->value, sizeof(T));
|
||||||
|
delete temp;
|
||||||
|
this->nrOfNodes--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
int List::size() const
|
||||||
|
{
|
||||||
|
return this->nrOfNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
Node *w = this->first;
|
||||||
|
Node *p = 0;
|
||||||
|
while (w)
|
||||||
|
{
|
||||||
|
p = w;
|
||||||
|
w = w->next;
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->first = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,284 @@
|
||||||
|
#include "InputController.h"
|
||||||
|
using namespace Oyster::Input;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
bool keys[256] = {0};
|
||||||
|
bool prevs[256]= {0};
|
||||||
|
bool mouse[5] = {0};
|
||||||
|
bool mPrev[5] = {0};
|
||||||
|
int XPos,YPos,PrevX,PrevY,DeltaX,DeltaY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::KeyPressed(const WPARAM &Key)
|
||||||
|
{
|
||||||
|
prevs[Key]=false;
|
||||||
|
keys[Key]=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::KeyReleased(const WPARAM &Key)
|
||||||
|
{
|
||||||
|
prevs[Key]=true;
|
||||||
|
keys[Key] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::isKeyDown(const WPARAM &Key)
|
||||||
|
{
|
||||||
|
return keys[Key];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::isKeyPressed(const WPARAM &Key)
|
||||||
|
{
|
||||||
|
if(keys[Key] && !prevs[Key])
|
||||||
|
{
|
||||||
|
prevs[Key] = keys[Key];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::isKeyReleased(const WPARAM &Key)
|
||||||
|
{
|
||||||
|
if(!keys[Key] && prevs[Key])
|
||||||
|
{
|
||||||
|
prevs[Key] = keys[Key];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::MouseBtnPressed(const WPARAM &btn)
|
||||||
|
{
|
||||||
|
switch(btn)
|
||||||
|
{
|
||||||
|
case MK_LBUTTON:
|
||||||
|
mouse[0] = true;
|
||||||
|
mPrev[0] = false;
|
||||||
|
break;
|
||||||
|
case MK_RBUTTON:
|
||||||
|
mouse[1] = true;
|
||||||
|
mPrev[1] = false;
|
||||||
|
break;
|
||||||
|
case MK_MBUTTON:
|
||||||
|
mouse[2] = true;
|
||||||
|
mPrev[2] = false;
|
||||||
|
break;
|
||||||
|
case MK_XBUTTON1:
|
||||||
|
mouse[3] = true;
|
||||||
|
mPrev[3] = false;
|
||||||
|
break;
|
||||||
|
case MK_XBUTTON2:
|
||||||
|
mouse[4] = true;
|
||||||
|
mPrev[4] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::MouseBtnReleased(const WPARAM &btn)
|
||||||
|
{
|
||||||
|
switch(btn)
|
||||||
|
{
|
||||||
|
case MK_LBUTTON:
|
||||||
|
mouse[0] = false;
|
||||||
|
mPrev[0] = true;
|
||||||
|
break;
|
||||||
|
case MK_RBUTTON:
|
||||||
|
mouse[1] = false;
|
||||||
|
mPrev[1] = true;
|
||||||
|
break;
|
||||||
|
case MK_MBUTTON:
|
||||||
|
mouse[2] = false;
|
||||||
|
mPrev[2] = true;
|
||||||
|
break;
|
||||||
|
case MK_XBUTTON1:
|
||||||
|
mouse[3] = false;
|
||||||
|
mPrev[3] = true;
|
||||||
|
break;
|
||||||
|
case MK_XBUTTON2:
|
||||||
|
mouse[4] = false;
|
||||||
|
mPrev[4] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Controller::isMouseBtnDown(const WPARAM &Btn)
|
||||||
|
{
|
||||||
|
switch(Btn)
|
||||||
|
{
|
||||||
|
case MK_LBUTTON:
|
||||||
|
return mouse[0];
|
||||||
|
case MK_RBUTTON:
|
||||||
|
return mouse[1];
|
||||||
|
case MK_MBUTTON:
|
||||||
|
return mouse[2];
|
||||||
|
case MK_XBUTTON1:
|
||||||
|
return mouse[3];
|
||||||
|
case MK_XBUTTON2:
|
||||||
|
return mouse[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::isMouseBtnPressed(const WPARAM &Btn)
|
||||||
|
{
|
||||||
|
switch(Btn)
|
||||||
|
{
|
||||||
|
case MK_LBUTTON:
|
||||||
|
if(mouse[0] && !mPrev[0])
|
||||||
|
{
|
||||||
|
mPrev[0] = mouse[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case MK_RBUTTON:
|
||||||
|
if(mouse[1] && !mPrev[1])
|
||||||
|
{
|
||||||
|
mPrev[1] = mouse[1];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case MK_MBUTTON:
|
||||||
|
if(mouse[2] && !mPrev[2])
|
||||||
|
{
|
||||||
|
mPrev[2] = mouse[2];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case MK_XBUTTON1:
|
||||||
|
if(mouse[3] && !mPrev[3])
|
||||||
|
{
|
||||||
|
mPrev[3] = mouse[3];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case MK_XBUTTON2:
|
||||||
|
if(mouse[4] && !mPrev[4])
|
||||||
|
{
|
||||||
|
mPrev[4] = mouse[4];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::isMouseBtnReleased(const WPARAM &Btn)
|
||||||
|
{
|
||||||
|
switch(Btn)
|
||||||
|
{
|
||||||
|
case MK_LBUTTON:
|
||||||
|
if(!mouse[0] && mPrev[0])
|
||||||
|
{
|
||||||
|
mPrev[0] = mouse[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case MK_RBUTTON:
|
||||||
|
if(!mouse[1] && mPrev[1])
|
||||||
|
{
|
||||||
|
mPrev[1] = mouse[1];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case MK_MBUTTON:
|
||||||
|
if(!mouse[2] && mPrev[2])
|
||||||
|
{
|
||||||
|
mPrev[2] = mouse[2];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case MK_XBUTTON1:
|
||||||
|
if(!mouse[3] && mPrev[3])
|
||||||
|
{
|
||||||
|
mPrev[3] = mouse[3];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case MK_XBUTTON2:
|
||||||
|
if(!mouse[4] && mPrev[4])
|
||||||
|
{
|
||||||
|
mPrev[4] = mouse[4];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::MouseMove(int x,int y)
|
||||||
|
{
|
||||||
|
PrevY = YPos;
|
||||||
|
PrevX = XPos;
|
||||||
|
XPos = x;
|
||||||
|
YPos = y;
|
||||||
|
DeltaY = YPos - PrevY;
|
||||||
|
DeltaX = XPos - PrevX;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Controller::GetY()
|
||||||
|
{
|
||||||
|
return YPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Controller::GetX()
|
||||||
|
{
|
||||||
|
return XPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Controller::GetAnalogX()
|
||||||
|
{
|
||||||
|
float f = (float)XPos;
|
||||||
|
f /=( Window::Size.left/2);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Controller::GetAnalogY()
|
||||||
|
{
|
||||||
|
float f = (float)YPos;
|
||||||
|
f /=( Window::Size.top/2);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Controller::GetDeltaY()
|
||||||
|
{
|
||||||
|
return DeltaY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Controller::GetDeltaX()
|
||||||
|
{
|
||||||
|
return DeltaX;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::ResetDeltaX()
|
||||||
|
{
|
||||||
|
DeltaX = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::ResetDeltaY()
|
||||||
|
{
|
||||||
|
DeltaY = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::RestrictMouse(bool restrict)
|
||||||
|
{
|
||||||
|
Oyster::Window::CaptureMouse(restrict);
|
||||||
|
}
|
||||||
|
|
||||||
|
//sets x=0,y=0 to be the center oc the client area
|
||||||
|
void Controller::OrigoCenter()
|
||||||
|
{
|
||||||
|
int x = Window::Size.left/2;
|
||||||
|
int y = Window::Size.top/2;
|
||||||
|
|
||||||
|
Window::SetMouseOffset(-x,-y);
|
||||||
|
}
|
||||||
|
|
||||||
|
//default
|
||||||
|
void Controller::OrigoTopLeft()
|
||||||
|
{
|
||||||
|
Oyster::Window::SetMouseOffset(0,0);
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef InputController_H
|
||||||
|
#define InputController_H
|
||||||
|
|
||||||
|
#include "../Window/Window.h"
|
||||||
|
//READ http://msdn.microsoft.com/en-us/library/windows/desktop/ms648380(v=vs.85).aspx#_win32_Confining_a_Cursor
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
class Window;
|
||||||
|
namespace Input
|
||||||
|
{
|
||||||
|
class Controller
|
||||||
|
{
|
||||||
|
friend class ::Oyster::Window;
|
||||||
|
private:
|
||||||
|
//Keybord events from Oyster::Window
|
||||||
|
static void KeyPressed(const WPARAM &Key);
|
||||||
|
//Keybord events from Oyster::Window
|
||||||
|
static void KeyReleased(const WPARAM &Key);
|
||||||
|
|
||||||
|
|
||||||
|
//Mouse events from Oyster::Window
|
||||||
|
static void MouseMove(int x,int y);
|
||||||
|
//Mouse events from Oyster::Window
|
||||||
|
static void MouseBtnPressed(const WPARAM &Btn);
|
||||||
|
static void MouseBtnReleased(const WPARAM &Btn);
|
||||||
|
public:
|
||||||
|
//Polling Functions
|
||||||
|
static bool isKeyDown(const WPARAM &Key);
|
||||||
|
static bool isKeyPressed(const WPARAM &Key);
|
||||||
|
static bool isKeyReleased(const WPARAM &Key);
|
||||||
|
|
||||||
|
static bool isMouseBtnDown(const WPARAM &Btn);
|
||||||
|
static bool isMouseBtnPressed(const WPARAM &Btn);
|
||||||
|
static bool isMouseBtnReleased(const WPARAM &Btn);
|
||||||
|
|
||||||
|
static int GetX();
|
||||||
|
static int GetY();
|
||||||
|
|
||||||
|
static float GetAnalogX();
|
||||||
|
static float GetAnalogY();
|
||||||
|
|
||||||
|
static int GetDeltaX();
|
||||||
|
static int GetDeltaY();
|
||||||
|
|
||||||
|
//Controll Functions
|
||||||
|
static void ResetDeltaX();
|
||||||
|
static void ResetDeltaY();
|
||||||
|
|
||||||
|
//off by default
|
||||||
|
static void RestrictMouse(bool b = true);
|
||||||
|
|
||||||
|
//sets x=0,y=0 to be the center oc the client area
|
||||||
|
static void OrigoCenter();
|
||||||
|
|
||||||
|
//default
|
||||||
|
static void OrigoTopLeft();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,216 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Utility Collection of Miscellanious Handy Functions
|
||||||
|
// © Dan Andersson 2013
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "Utilities.h"
|
||||||
|
#include <sstream>
|
||||||
|
#include <locale>
|
||||||
|
|
||||||
|
using ::std::vector;
|
||||||
|
using ::std::string;
|
||||||
|
|
||||||
|
namespace Utility
|
||||||
|
{
|
||||||
|
// PRIVATE STATIC ////////////////////////////////////////////////////
|
||||||
|
namespace PrivateStatic
|
||||||
|
{
|
||||||
|
const ::std::locale systemDefaultLocale = ::std::locale();
|
||||||
|
}
|
||||||
|
|
||||||
|
// STRING ////////////////////////////////////////////////////////////
|
||||||
|
namespace String
|
||||||
|
{
|
||||||
|
vector<string> & split( vector<string> &output, const string &str, char delim, string::size_type offset )
|
||||||
|
{
|
||||||
|
if( str.length() > 0 )
|
||||||
|
{
|
||||||
|
while( offset < str.length() ) // trim
|
||||||
|
{
|
||||||
|
if( str[offset] == delim )
|
||||||
|
++offset;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
string::size_type delimPos = str.find_first_of( delim, offset );
|
||||||
|
if( delimPos == string::npos )
|
||||||
|
{
|
||||||
|
if( str.length() > offset )
|
||||||
|
output.push_back( str.substr( offset, str.length() - offset ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( delimPos > offset )
|
||||||
|
output.push_back( str.substr( offset, delimPos - offset ) );
|
||||||
|
String::split( output, str, delim, delimPos + 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<string> & split( vector<string> &output, const string &str, const string &delim, string::size_type offset )
|
||||||
|
{
|
||||||
|
if( str.length() > 0 )
|
||||||
|
{
|
||||||
|
string::size_type delimPos = str.find_first_of( delim, offset );
|
||||||
|
if( delimPos == string::npos )
|
||||||
|
{
|
||||||
|
if( str.length() > offset )
|
||||||
|
output.push_back( str.substr( offset, str.length() - offset ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( delimPos > offset )
|
||||||
|
output.push_back( str.substr( offset, delimPos - offset ) );
|
||||||
|
String::split( output, str, delim, delimPos + delim.length() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<string> & split( vector<string> &output, const string &str, const vector<string> &delim, string::size_type offset )
|
||||||
|
{
|
||||||
|
if( str.length() > 0 )
|
||||||
|
{
|
||||||
|
string::size_type firstDelimPos = str.length(), delimPos;
|
||||||
|
|
||||||
|
vector<string>::size_type numDelims = delim.size(), delimRef = 0;
|
||||||
|
for( vector<string>::size_type i = 0; i < numDelims ; ++i )
|
||||||
|
{
|
||||||
|
delimPos = str.find_first_of( delim[i], offset );
|
||||||
|
if( delimPos != string::npos ) if( delimPos < firstDelimPos )
|
||||||
|
{
|
||||||
|
delimRef = i;
|
||||||
|
firstDelimPos = delimPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( firstDelimPos == str.length() )
|
||||||
|
{
|
||||||
|
if( str.length() > offset )
|
||||||
|
output.push_back( str.substr( offset, str.length() - offset ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( firstDelimPos > offset )
|
||||||
|
output.push_back( str.substr( offset, firstDelimPos - offset ) );
|
||||||
|
String::split( output, str, delim, firstDelimPos + delim[delimRef].length() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
string trim( const string &str )
|
||||||
|
{
|
||||||
|
string::size_type first = 0,
|
||||||
|
last = str.length();
|
||||||
|
|
||||||
|
if( last == 0 ) return str;
|
||||||
|
|
||||||
|
while( first < last )
|
||||||
|
{
|
||||||
|
if( str[first] == ' ' || str[first] == '\t' || str[first] == '\r' || str[first] == '\n' )
|
||||||
|
++first;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
--last;
|
||||||
|
while( last > first )
|
||||||
|
{
|
||||||
|
if( str[last] == ' ' || str[last] == '\t' || str[last] == '\r' || str[last] == '\n' )
|
||||||
|
--last;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( first == last ) if( str[first] == ' ' || str[first] == '\t' || str[first] == '\r' || str[first] == '\n' )
|
||||||
|
return "";
|
||||||
|
|
||||||
|
return str.substr( first, (++last) - first );
|
||||||
|
}
|
||||||
|
|
||||||
|
string & toLowerCase( string &output, const string &str )
|
||||||
|
{
|
||||||
|
int length = (int)str.length();
|
||||||
|
output.resize( length );
|
||||||
|
for( int i = 0; i < length; ++i )
|
||||||
|
output[i] = ::std::tolower( str[i], ::std::locale() );
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
string & toLowerCase( string &str )
|
||||||
|
{
|
||||||
|
int length = (int)str.length();
|
||||||
|
for( int i = 0; i < length; ++i )
|
||||||
|
str[i] = ::std::tolower( str[i], ::std::locale() );
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
string & toUpperCase( string &output, const string &str )
|
||||||
|
{
|
||||||
|
int length = (int)str.length();
|
||||||
|
output.resize( length );
|
||||||
|
for( int i = 0; i < length; ++i )
|
||||||
|
output[i] = ::std::toupper( str[i], ::std::locale() );
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
string & toUpperCase( string &str )
|
||||||
|
{
|
||||||
|
int length = (int)str.length();
|
||||||
|
for( int i = 0; i < length; ++i )
|
||||||
|
str[i] = ::std::toupper( str[i], ::std::locale() );
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
string & extractDirPath( string &output, const string &file, char dirDelimeter )
|
||||||
|
{
|
||||||
|
string d = " ";
|
||||||
|
d[0] = dirDelimeter;
|
||||||
|
return String::extractDirPath( output, file, d );
|
||||||
|
}
|
||||||
|
|
||||||
|
string & extractDirPath( string &output, const string &file, const string &dirDelimeter )
|
||||||
|
{
|
||||||
|
string::size_type end = file.find_last_of( dirDelimeter );
|
||||||
|
if( end == string::npos )
|
||||||
|
output = "";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++end;
|
||||||
|
output.resize( end );
|
||||||
|
for( string::size_type i = 0; i < end; ++i )
|
||||||
|
output[i] = file[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
string & replaceCharacters( string &str, char characterToReplace, char newCharacter, const string::size_type &offset, const string::size_type &end )
|
||||||
|
{
|
||||||
|
string::size_type i = offset;
|
||||||
|
while( true )
|
||||||
|
{
|
||||||
|
i = str.find_first_of( characterToReplace, i );
|
||||||
|
if( i >= end ) break;
|
||||||
|
|
||||||
|
str[i++] = newCharacter;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// STREAM ////////////////////////////////////////////////////////////
|
||||||
|
namespace Stream
|
||||||
|
{
|
||||||
|
float* readFloats( float *output, ::std::istream &input, unsigned int numFloats )
|
||||||
|
{
|
||||||
|
string str;
|
||||||
|
for( unsigned int i = 0; i < numFloats; ++i )
|
||||||
|
{
|
||||||
|
input >> str;
|
||||||
|
output[i] = (float)::std::atof( str.c_str() );
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Utility Collection of Miscellanious Handy Functions
|
||||||
|
// © Dan Andersson 2013
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef UTILITIES_H
|
||||||
|
#define UTILITIES_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <istream>
|
||||||
|
#include <vector>
|
||||||
|
#include <locale>
|
||||||
|
|
||||||
|
namespace Utility
|
||||||
|
{
|
||||||
|
namespace String
|
||||||
|
{
|
||||||
|
// note to self: add a whitespaceSplit method?
|
||||||
|
::std::vector<::std::string> & split( ::std::vector<::std::string> &output, const ::std::string &str, char delim, ::std::string::size_type offset = 0 );
|
||||||
|
::std::vector<::std::string> & split( ::std::vector<::std::string> &output, const ::std::string &str, const ::std::string &delim, ::std::string::size_type offset = 0 );
|
||||||
|
::std::vector<::std::string> & split( ::std::vector<::std::string> &output, const ::std::string &str, const ::std::vector<::std::string> &delim, ::std::string::size_type offset = 0 );
|
||||||
|
::std::string trim( const ::std::string &str );
|
||||||
|
::std::string & toLowerCase( ::std::string &output, const ::std::string &str );
|
||||||
|
::std::string & toLowerCase( ::std::string &str );
|
||||||
|
::std::string & toUpperCase( ::std::string &output, const ::std::string &str );
|
||||||
|
::std::string & toUpperCase( ::std::string &str );
|
||||||
|
::std::string & extractDirPath( ::std::string &output, const ::std::string &file, char dirDelimeter );
|
||||||
|
::std::string & extractDirPath( ::std::string &output, const ::std::string &file, const ::std::string &dirDelimeter );
|
||||||
|
::std::string & replaceCharacters( ::std::string &str, char characterToReplace, char newCharacter, const ::std::string::size_type &offset = 0, const ::std::string::size_type &end = ::std::string::npos );
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Stream
|
||||||
|
{
|
||||||
|
float* readFloats( float *output, ::std::istream &input, unsigned int numFloats );
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace StaticArray
|
||||||
|
{
|
||||||
|
template<typename ElementType, unsigned int num>
|
||||||
|
inline unsigned int numElementsOf( const ElementType(&)[num] )
|
||||||
|
{ return num; }
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Element
|
||||||
|
{
|
||||||
|
template<typename ElementType>
|
||||||
|
inline void swap( ElementType &elementA, ElementType &elementB, ElementType &swapSpace )
|
||||||
|
{ swapSpace = elementA; elementA = elementB; elementB = swapSpace; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline void swap( ElementType &elementA, ElementType &elementB )
|
||||||
|
{ ElementType swapSpace; swap( elementA, elementB, swapSpace ); }
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Value
|
||||||
|
{
|
||||||
|
template<typename ValueType>
|
||||||
|
inline ValueType abs( const ValueType &value )
|
||||||
|
{ return value < 0 ? value * -1 : value; }
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline ValueType max( const ValueType &valueA, const ValueType &valueB )
|
||||||
|
{ return valueA > valueB ? valueA : valueB; }
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline ValueType min( const ValueType &valueA, const ValueType &valueB )
|
||||||
|
{ return valueA < valueB ? valueA : valueB; }
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline ValueType radian( const ValueType °ree )
|
||||||
|
{ return degree * (3.1415926535897932384626433832795f / 180.0f); }
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline ValueType degree( const ValueType &radian )
|
||||||
|
{ return radian * (180.0f / 3.1415926535897932384626433832795f); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,75 @@
|
||||||
|
#include "WinTimer.h"
|
||||||
|
|
||||||
|
using namespace ::Utility;
|
||||||
|
|
||||||
|
namespace PrivateStatic
|
||||||
|
{
|
||||||
|
LARGE_INTEGER ticksPerSecond = { 0 };
|
||||||
|
double secondsPerTick = 0.0f;
|
||||||
|
|
||||||
|
class WatchDog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WatchDog( )
|
||||||
|
{
|
||||||
|
if( QueryPerformanceFrequency( &ticksPerSecond ) > 0 )
|
||||||
|
secondsPerTick = ((double)1.0f) / (double) ticksPerSecond.QuadPart;
|
||||||
|
}
|
||||||
|
} watchDog;
|
||||||
|
}
|
||||||
|
|
||||||
|
WinTimer::WinTimer( ) : isPaused(false)
|
||||||
|
{ this->reset(); }
|
||||||
|
|
||||||
|
void WinTimer::reset( )
|
||||||
|
{
|
||||||
|
this->isPaused = false;
|
||||||
|
this->pauseCount.QuadPart = 0;
|
||||||
|
QueryPerformanceCounter( &this->startTick );
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinTimer::pause( )
|
||||||
|
{
|
||||||
|
if( !this->isPaused )
|
||||||
|
{
|
||||||
|
this->isPaused = true;
|
||||||
|
QueryPerformanceCounter( &this->pauseStart );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinTimer::resume( )
|
||||||
|
{
|
||||||
|
if( this->isPaused )
|
||||||
|
{
|
||||||
|
this->isPaused = false;
|
||||||
|
LARGE_INTEGER currentTick;
|
||||||
|
QueryPerformanceCounter( ¤tTick );
|
||||||
|
this->pauseCount.QuadPart += currentTick.QuadPart - this->pauseStart.QuadPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double WinTimer::getElapsedSeconds( ) const
|
||||||
|
{
|
||||||
|
if( this->isPaused )
|
||||||
|
{
|
||||||
|
LARGE_INTEGER totalTick = this->pauseStart;
|
||||||
|
totalTick.QuadPart -= this->startTick.QuadPart;
|
||||||
|
totalTick.QuadPart -= this->pauseCount.QuadPart;
|
||||||
|
return PrivateStatic::secondsPerTick * (double)totalTick.QuadPart;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LARGE_INTEGER currentTick;
|
||||||
|
QueryPerformanceCounter( ¤tTick );
|
||||||
|
currentTick.QuadPart -= this->startTick.QuadPart;
|
||||||
|
currentTick.QuadPart -= this->pauseCount.QuadPart;
|
||||||
|
return PrivateStatic::secondsPerTick * (double)currentTick.QuadPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LARGE_INTEGER WinTimer::getCurrentTick( ) const
|
||||||
|
{
|
||||||
|
LARGE_INTEGER currentTick;
|
||||||
|
QueryPerformanceCounter( ¤tTick );
|
||||||
|
return currentTick;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Instanciable Timer class for windows
|
||||||
|
// © Dan Andersson 2013
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef WINTIMER_H
|
||||||
|
#define WINTIMER_H
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
namespace Utility
|
||||||
|
{
|
||||||
|
class WinTimer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WinTimer( );
|
||||||
|
|
||||||
|
void reset( );
|
||||||
|
void pause( );
|
||||||
|
void resume( );
|
||||||
|
|
||||||
|
double getElapsedSeconds( ) const;
|
||||||
|
LARGE_INTEGER getCurrentTick( ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
LARGE_INTEGER startTick, pauseStart, pauseCount;
|
||||||
|
bool isPaused;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,262 @@
|
||||||
|
#include "Event.h"
|
||||||
|
using namespace Event;
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------
|
||||||
|
// BulletCreated class definitions
|
||||||
|
BulletCreated::BulletCreated(int ownerID, Float3 position, Float3 direction)
|
||||||
|
:
|
||||||
|
GameEvent()
|
||||||
|
{
|
||||||
|
data.owner=ownerID;
|
||||||
|
data.head=direction;
|
||||||
|
}
|
||||||
|
void BulletCreated::LoadRawData(char* d)
|
||||||
|
{
|
||||||
|
memcpy(&data, d, GetSize());
|
||||||
|
/*int offset=0;
|
||||||
|
memcpy(&data.position, data, sizeof(Float3));
|
||||||
|
offset+=sizeof(Float3);
|
||||||
|
|
||||||
|
memcpy(&data.head, d+offset, sizeof(Float3));
|
||||||
|
offset+=sizeof(Float3);
|
||||||
|
memcpy(&data.owner, d+offset, sizeof(int));*/
|
||||||
|
}
|
||||||
|
void BulletCreated::SaveRawData(char* d)
|
||||||
|
{
|
||||||
|
memcpy(d, &data, GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------
|
||||||
|
// BulletHit class definitions
|
||||||
|
BulletHit::BulletHit(int attacker, int hitPlayer)
|
||||||
|
:
|
||||||
|
GameEvent()
|
||||||
|
{
|
||||||
|
data.hitTarget=hitPlayer;
|
||||||
|
data.attackingTarget=attacker;
|
||||||
|
//this->hpLeft=hl;
|
||||||
|
//this->shieldLeft=sl;
|
||||||
|
}
|
||||||
|
void BulletHit::LoadRawData(char* d)
|
||||||
|
{
|
||||||
|
memcpy(&data, d, GetSize());
|
||||||
|
}
|
||||||
|
void BulletHit::SaveRawData(char* d)
|
||||||
|
{
|
||||||
|
memcpy(d, &data, GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
ScoreUpdate::ScoreUpdate(Score* scores)
|
||||||
|
{
|
||||||
|
for (int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
data.scoreboard[i]=scores[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ScoreUpdate::LoadRawData(char* d)
|
||||||
|
{
|
||||||
|
memcpy(&data, d, GetSize());
|
||||||
|
}
|
||||||
|
void ScoreUpdate::SaveRawData(char* d)
|
||||||
|
{
|
||||||
|
memcpy(d, &data, GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------
|
||||||
|
// ShipSpawned class definitions
|
||||||
|
ShipSpawned::ShipSpawned(Float3 position, int id)
|
||||||
|
:
|
||||||
|
GameEvent()
|
||||||
|
{
|
||||||
|
data.position=position;
|
||||||
|
data.playerID=id;
|
||||||
|
}
|
||||||
|
void ShipSpawned::LoadRawData(char* d)
|
||||||
|
{
|
||||||
|
memcpy(&data, d, this->GetSize());
|
||||||
|
/*int offset=0;
|
||||||
|
memcpy(&data.position, data, sizeof(Float3));
|
||||||
|
offset+=sizeof(Float3);
|
||||||
|
|
||||||
|
memcpy(&playerID, data+offset, sizeof(int));*/
|
||||||
|
}
|
||||||
|
void ShipSpawned::SaveRawData(char* d)
|
||||||
|
{
|
||||||
|
memcpy(d, &data, GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------
|
||||||
|
// GameEnded class definitions
|
||||||
|
GameEnded::GameEnded()
|
||||||
|
:
|
||||||
|
GameEvent()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
GameEnded::GameEnded(int winner)
|
||||||
|
:
|
||||||
|
GameEvent()
|
||||||
|
{
|
||||||
|
data.winningTeam=winner;
|
||||||
|
}
|
||||||
|
void GameEnded::LoadRawData(char* d)
|
||||||
|
{
|
||||||
|
memcpy(&data, d, GetSize());
|
||||||
|
/*int offset=0;
|
||||||
|
memcpy(&eventPosition, data, sizeof(Float3));
|
||||||
|
offset+=sizeof(Float3);
|
||||||
|
|
||||||
|
memcpy(&winningTeam, data+offset, sizeof(int));
|
||||||
|
offset+=sizeof(int);
|
||||||
|
|
||||||
|
for (int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
memcpy(&data.scoreboard[i], data+offset, sizeof(Score));
|
||||||
|
offset+=sizeof(Score);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
void GameEnded::SaveRawData(char* d)
|
||||||
|
{
|
||||||
|
memcpy(d, &data, GetSize());
|
||||||
|
}
|
||||||
|
void GameEnded::setScore(int i, Score score)
|
||||||
|
{
|
||||||
|
data.scoreboard[i]=score;
|
||||||
|
}
|
||||||
|
void GameEnded::setScore(int i, int k, int d, int tk)
|
||||||
|
{
|
||||||
|
data.scoreboard[i].id=i;
|
||||||
|
data.scoreboard[i].kills=k;
|
||||||
|
data.scoreboard[i].deaths=d;
|
||||||
|
data.scoreboard[i].teamkills=tk;
|
||||||
|
}
|
||||||
|
void GameEnded::sortScore()
|
||||||
|
{
|
||||||
|
float sort[PLAYER_MAX_COUNT];
|
||||||
|
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
sort[i]=((float)(data.scoreboard[i].kills-data.scoreboard[i].teamkills))/(float)data.scoreboard[i].deaths;
|
||||||
|
}
|
||||||
|
Score tmp;
|
||||||
|
int bestID=0;
|
||||||
|
float bestScore;
|
||||||
|
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
bestScore=sort[i];
|
||||||
|
bestID=i;
|
||||||
|
for (int j=i; j<PLAYER_MAX_COUNT; j++)
|
||||||
|
{
|
||||||
|
if(bestScore<sort[j])
|
||||||
|
{
|
||||||
|
bestID=j;
|
||||||
|
bestScore=sort[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmp=data.scoreboard[i];
|
||||||
|
data.scoreboard[i]=data.scoreboard[bestID];
|
||||||
|
data.scoreboard[bestID]=tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------
|
||||||
|
// ShipDestroyed class definitions
|
||||||
|
ShipDestroyed::ShipDestroyed(int pid, int kid)
|
||||||
|
:
|
||||||
|
GameEvent()
|
||||||
|
{
|
||||||
|
data.playerID=pid;
|
||||||
|
data.killerID=kid;
|
||||||
|
}
|
||||||
|
void ShipDestroyed::setScore(int i, Score score)
|
||||||
|
{
|
||||||
|
data.scoreboard[i]=score;
|
||||||
|
}
|
||||||
|
void ShipDestroyed::setScore(int i, int k, int d, int tk)
|
||||||
|
{
|
||||||
|
data.scoreboard[i].id=i;
|
||||||
|
data.scoreboard[i].kills=k;
|
||||||
|
data.scoreboard[i].deaths=d;
|
||||||
|
data.scoreboard[i].teamkills=tk;
|
||||||
|
}
|
||||||
|
void ShipDestroyed::sortScore()
|
||||||
|
{
|
||||||
|
float sort[PLAYER_MAX_COUNT];
|
||||||
|
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
sort[i]=((float)(data.scoreboard[i].kills-data.scoreboard[i].teamkills))/data.scoreboard[i].deaths;
|
||||||
|
}
|
||||||
|
Score tmp;
|
||||||
|
int bestID=0;
|
||||||
|
float bestScore;
|
||||||
|
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
bestScore=sort[i];
|
||||||
|
bestID=i;
|
||||||
|
for (int j=i; j<PLAYER_MAX_COUNT; j++)
|
||||||
|
{
|
||||||
|
if(bestScore<sort[j])
|
||||||
|
{
|
||||||
|
bestID=j;
|
||||||
|
bestScore=sort[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmp=data.scoreboard[i];
|
||||||
|
data.scoreboard[i]=data.scoreboard[bestID];
|
||||||
|
data.scoreboard[bestID]=tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ShipDestroyed::LoadRawData(char* d)
|
||||||
|
{
|
||||||
|
memcpy(&data, d, GetSize());
|
||||||
|
/*int offset=0;
|
||||||
|
memcpy(&eventPosition, data, sizeof(Float3));
|
||||||
|
offset+=sizeof(Float3);
|
||||||
|
|
||||||
|
memcpy(&playerID, data+offset, sizeof(int));
|
||||||
|
offset+=sizeof(int);
|
||||||
|
memcpy(&killerID, data+offset, sizeof(int));
|
||||||
|
offset+=sizeof(int);
|
||||||
|
for (int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
memcpy(&data.scoreboard[i], data+offset, sizeof(Score));
|
||||||
|
offset+=sizeof(Score);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
void ShipDestroyed::SaveRawData(char* d)
|
||||||
|
{
|
||||||
|
memcpy(d, &data, GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Event::Type Event::getEventType(Event::GameEvent* evt)
|
||||||
|
{
|
||||||
|
if (typeid(*evt)==typeid(Event::BulletCreated))
|
||||||
|
{
|
||||||
|
return eBulletCreated;
|
||||||
|
}
|
||||||
|
else if(typeid(*evt)==typeid(Event::BulletHit))
|
||||||
|
{
|
||||||
|
return eBulletHit;
|
||||||
|
}
|
||||||
|
else if(typeid(*evt)==typeid(Event::ShipSpawned))
|
||||||
|
{
|
||||||
|
return eShipSpawned;
|
||||||
|
}
|
||||||
|
else if(typeid(*evt)==typeid(Event::GameEnded))
|
||||||
|
{
|
||||||
|
return eGameEnded;
|
||||||
|
}
|
||||||
|
else if(typeid(*evt)==typeid(Event::ShipDestroyed))
|
||||||
|
{
|
||||||
|
return eShipDestroyed;
|
||||||
|
}
|
||||||
|
else if(typeid(*evt)==typeid(Event::ScoreUpdate))
|
||||||
|
{
|
||||||
|
return eScoreUpdate;
|
||||||
|
}
|
||||||
|
printf("UNSUPPORTED EVENT at getEventType, Event.cpp\n");
|
||||||
|
return UNSUPPORTED_TYPE;
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
#include "NetworkIncludes.h"
|
||||||
|
#include "EventStructs.h"
|
||||||
|
#pragma once
|
||||||
|
#ifndef EVENT_H
|
||||||
|
#define EVENT_H
|
||||||
|
//There's a variable called eventList in Session.
|
||||||
|
//if you push_back any type of event, the server will pick them up in order after every update() is run.
|
||||||
|
|
||||||
|
|
||||||
|
//Try to keep events pointer-free. Trying to send a class with a pointer over a socket will result in a problem because
|
||||||
|
//it will send the pointer rather than the data in the pointer. That results in either
|
||||||
|
//A: Program crashing because it's not allowed to read that space if it's on the same computer as the server or
|
||||||
|
//B: Program crashing because the pointer most probably points to an unused space if the client is on a separate computer.
|
||||||
|
|
||||||
|
//This is the basic event class.
|
||||||
|
//a position should always be given with all events, to use as a main location for sounds, effects, or whatever. We can remove it if we decide it's not needed later on.
|
||||||
|
|
||||||
|
namespace Event
|
||||||
|
{
|
||||||
|
class GameEvent
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
public:
|
||||||
|
GameEvent(){}
|
||||||
|
virtual int GetSize()=0;
|
||||||
|
virtual void LoadRawData(char* d)=0;
|
||||||
|
virtual void SaveRawData(char* d)=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
//When a player fires a projectile, a BulletCreated event should be added.
|
||||||
|
class BulletCreated : public GameEvent
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
EventStruct::BulletCreatedStruct data;
|
||||||
|
public:
|
||||||
|
BulletCreated():GameEvent(){}
|
||||||
|
BulletCreated(int ownerID, Float3 position, Float3 Head);
|
||||||
|
int GetOwner(){return data.owner;}
|
||||||
|
int GetSize(){return sizeof(data);}
|
||||||
|
EventStruct::BulletCreatedStruct GetAsStruct(){return data;}
|
||||||
|
void LoadRawData(char* d);
|
||||||
|
void SaveRawData(char* d);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScoreUpdate : public GameEvent
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
EventStruct::ScoreUpdateStruct data;
|
||||||
|
public:
|
||||||
|
ScoreUpdate():GameEvent(){}
|
||||||
|
ScoreUpdate(Score* scoreboard);
|
||||||
|
int GetSize(){return sizeof(data);}
|
||||||
|
EventStruct::ScoreUpdateStruct GetAsStruct(){return data;}
|
||||||
|
void LoadRawData(char* d);
|
||||||
|
void SaveRawData(char* d);
|
||||||
|
};
|
||||||
|
|
||||||
|
//When some kind of player-fired projectile hits an enemy, a BulletHit even should be added.
|
||||||
|
class BulletHit : public GameEvent
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
EventStruct::BulletHitStruct data;
|
||||||
|
public:
|
||||||
|
BulletHit():GameEvent(){}
|
||||||
|
BulletHit(int attacker, int hitPlayer);
|
||||||
|
int getAttackerID(){return data.attackingTarget;}
|
||||||
|
int getHitTargetID(){return data.hitTarget;}
|
||||||
|
int GetSize(){return sizeof(data);}
|
||||||
|
EventStruct::BulletHitStruct GetAsStruct(){return data;}
|
||||||
|
void LoadRawData(char* d);
|
||||||
|
void SaveRawData(char* d);
|
||||||
|
};
|
||||||
|
|
||||||
|
//Shipspawned event, for when a ship respawns.
|
||||||
|
//In ShipSpawned, all data that the client requires should be given.
|
||||||
|
class ShipSpawned : public GameEvent
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
EventStruct::ShipSpawnedStruct data;
|
||||||
|
public:
|
||||||
|
ShipSpawned():GameEvent(){}
|
||||||
|
ShipSpawned(Float3 position, int id);
|
||||||
|
int GetSize(){return sizeof(data);}
|
||||||
|
EventStruct::ShipSpawnedStruct GetAsStruct(){return data;}
|
||||||
|
void LoadRawData(char* d);
|
||||||
|
void SaveRawData(char* d);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShipDestroyed : public GameEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EventStruct::ShipDestroyedStruct data;
|
||||||
|
public:
|
||||||
|
ShipDestroyed():GameEvent(){}
|
||||||
|
ShipDestroyed(int pid, int kid);
|
||||||
|
void setScore(int i, Score score);
|
||||||
|
void setScore(int i, int k, int d, int tk);
|
||||||
|
void sortScore();
|
||||||
|
int getDestroyedID() const {return data.playerID;}
|
||||||
|
int getAttackerID() const {return data.killerID;}
|
||||||
|
EventStruct::ShipDestroyedStruct GetAsStruct(){return data;}
|
||||||
|
|
||||||
|
int GetSize(){return sizeof(data);}
|
||||||
|
void LoadRawData(char* d);
|
||||||
|
void SaveRawData(char* d);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class GameEnded : public GameEvent
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
EventStruct::GameEndedStruct data;
|
||||||
|
//Have some variables which shows scores of player, who won, etc
|
||||||
|
//you just need the ids. Don't send names etc.
|
||||||
|
public:
|
||||||
|
GameEnded();
|
||||||
|
GameEnded(int winner);
|
||||||
|
void setScore(int i, Score score);
|
||||||
|
void setScore(int i, int k, int d, int tk);
|
||||||
|
void sortScore();
|
||||||
|
int GetSize(){return sizeof(data);}
|
||||||
|
EventStruct::GameEndedStruct GetAsStruct(){return data;}
|
||||||
|
void LoadRawData(char* d);
|
||||||
|
void SaveRawData(char* d);
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
UNSUPPORTED_TYPE,
|
||||||
|
eBulletCreated,
|
||||||
|
eBulletHit,
|
||||||
|
eShipSpawned,
|
||||||
|
eGameEnded,
|
||||||
|
eShipDestroyed,
|
||||||
|
eScoreUpdate
|
||||||
|
};
|
||||||
|
Event::Type getEventType(Event::GameEvent* evt);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,55 @@
|
||||||
|
#include "NetworkIncludes.h"
|
||||||
|
#include "NetworkConstants.h"
|
||||||
|
#ifndef NET_EVT_STRUCTS_H
|
||||||
|
#define NET_EVT_STRUCTS_H
|
||||||
|
struct Score
|
||||||
|
{
|
||||||
|
int id;//Leaderboard var
|
||||||
|
int kills;
|
||||||
|
int deaths;
|
||||||
|
int teamkills;
|
||||||
|
Score(){id=0;kills=0;deaths=0;teamkills=0;}
|
||||||
|
Score& operator+=(const Score add)
|
||||||
|
{
|
||||||
|
id+=add.id;
|
||||||
|
kills+=add.kills;
|
||||||
|
deaths+=add.deaths;
|
||||||
|
teamkills+=add.teamkills;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
namespace EventStruct
|
||||||
|
{
|
||||||
|
struct BulletCreatedStruct
|
||||||
|
{
|
||||||
|
Float3 position;
|
||||||
|
Float3 head;
|
||||||
|
int owner;
|
||||||
|
};
|
||||||
|
struct BulletHitStruct
|
||||||
|
{
|
||||||
|
int hitTarget;
|
||||||
|
int attackingTarget;
|
||||||
|
};
|
||||||
|
struct ShipSpawnedStruct
|
||||||
|
{
|
||||||
|
Float3 position;
|
||||||
|
int playerID;
|
||||||
|
};
|
||||||
|
struct ShipDestroyedStruct
|
||||||
|
{
|
||||||
|
int playerID;
|
||||||
|
int killerID;
|
||||||
|
Score scoreboard[PLAYER_MAX_COUNT];
|
||||||
|
};
|
||||||
|
struct ScoreUpdateStruct
|
||||||
|
{
|
||||||
|
Score scoreboard[PLAYER_MAX_COUNT];
|
||||||
|
};
|
||||||
|
struct GameEndedStruct
|
||||||
|
{
|
||||||
|
int winningTeam;
|
||||||
|
Score scoreboard[PLAYER_MAX_COUNT];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef NETWORK_H
|
||||||
|
#define NETWORK_H
|
||||||
|
#include "NetworkIncludes.h"
|
||||||
|
#include "EventStructs.h"
|
||||||
|
#include "NetworkUpdateStructs.h"
|
||||||
|
#include "NetworkInitStructs.h"
|
||||||
|
#include "EventStructs.h"
|
||||||
|
#include "Event.h"
|
||||||
|
#include "NetworkMiscFunctions.h"
|
||||||
|
#include "NetworkTimer.h"
|
||||||
|
#endif
|
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef NET_CONST_H
|
||||||
|
#define NET_CONST_H
|
||||||
|
//const int PLAYER_WAIT_COUNT = 1;
|
||||||
|
const int PLAYER_MAX_COUNT = 8;
|
||||||
|
const float LOBBY_WAIT_TIME = 4;
|
||||||
|
/*namespace Network
|
||||||
|
{
|
||||||
|
void LoadData(){}
|
||||||
|
}*/
|
||||||
|
#endif
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef NET_INCL_H
|
||||||
|
#define NET_INCL_H
|
||||||
|
#ifndef UNICODE
|
||||||
|
#define UNICODE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#define NOMINMAX
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <Ws2tcpip.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string>
|
||||||
|
#include <ctime>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "OysterMath.h"
|
||||||
|
using namespace Oyster::Math;
|
||||||
|
|
||||||
|
//ws2_32.lib is a lib file the linker requires for winsock compilation
|
||||||
|
#pragma comment(lib, "Ws2_32.lib")
|
||||||
|
#endif
|
|
@ -0,0 +1,70 @@
|
||||||
|
#ifndef NET_INIT_STRUCTS_H
|
||||||
|
#define NET_INIT_STRUCTS_H
|
||||||
|
#include "NetworkIncludes.h"
|
||||||
|
#include "NetworkConstants.h"
|
||||||
|
struct PlayerInitStruct
|
||||||
|
{
|
||||||
|
INT8 pid;
|
||||||
|
int teamid;
|
||||||
|
Oyster::Math::Float4x4 position;
|
||||||
|
PlayerInitStruct()
|
||||||
|
{
|
||||||
|
pid=0;
|
||||||
|
//position=Oyster::Math::Float4x4::identity;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GameInitData
|
||||||
|
{
|
||||||
|
INT8 pid;
|
||||||
|
//std::string playerNames[PLAYER_MAX_COUNT];
|
||||||
|
PlayerInitStruct player[PLAYER_MAX_COUNT];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LobbyUserStruct
|
||||||
|
{
|
||||||
|
INT8 pid;
|
||||||
|
INT8 shipID;
|
||||||
|
char usrName[15];
|
||||||
|
LobbyUserStruct()
|
||||||
|
{
|
||||||
|
pid=0;
|
||||||
|
shipID=0;
|
||||||
|
usrName[0]='\0';
|
||||||
|
}
|
||||||
|
void setName(const char* n)
|
||||||
|
{
|
||||||
|
strcpy_s(usrName, n);
|
||||||
|
}
|
||||||
|
int size()
|
||||||
|
{
|
||||||
|
int sz=sizeof(pid);
|
||||||
|
sz+=sizeof(shipID);
|
||||||
|
int tmp=(int)strlen(usrName);
|
||||||
|
sz+=(int)strlen(usrName);
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct LobbyInitData
|
||||||
|
{
|
||||||
|
INT8 pid;
|
||||||
|
INT8 playerCount;
|
||||||
|
int timer;
|
||||||
|
LobbyUserStruct players[PLAYER_MAX_COUNT];
|
||||||
|
LobbyInitData()
|
||||||
|
{
|
||||||
|
pid=0;
|
||||||
|
for (int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
players[i].pid=i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int size()
|
||||||
|
{
|
||||||
|
int sz=sizeof(pid);
|
||||||
|
for (int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
sz+=players[i].size();
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "NetworkMiscFunctions.h"
|
||||||
|
std::vector<std::string> splitString(const char* p_inStr, char p_delim)
|
||||||
|
{
|
||||||
|
std::stringstream ss(p_inStr);
|
||||||
|
std::vector<std::string> elems;
|
||||||
|
std::string item;
|
||||||
|
while(std::getline(ss, item, p_delim))
|
||||||
|
{
|
||||||
|
elems.push_back(item);
|
||||||
|
}
|
||||||
|
return elems;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef NET_MISC_FNC_H
|
||||||
|
#define NET_MISC_FNC_H
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
|
std::vector<std::string> splitString(const char* p_inStr, char p_delim);
|
||||||
|
#define SSTR( x ) dynamic_cast< std::ostringstream & >( \
|
||||||
|
( std::ostringstream() << std::dec << x ) ).str()
|
||||||
|
#endif
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include "NetworkTimer.h"
|
||||||
|
NetworkTimer::NetworkTimer()
|
||||||
|
:
|
||||||
|
c_SecondsPerCount(0.0),
|
||||||
|
c_DeltaTime(-1.0),
|
||||||
|
c_BaseTime(0),
|
||||||
|
c_PausedTime(0),
|
||||||
|
c_PrevTime(0),
|
||||||
|
c_CurrTime(0),
|
||||||
|
c_Stopped(false)
|
||||||
|
{
|
||||||
|
__int64 countsPerSec;
|
||||||
|
QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
|
||||||
|
c_SecondsPerCount =1.0 / (double)countsPerSec;
|
||||||
|
|
||||||
|
QueryPerformanceCounter((LARGE_INTEGER*)&c_PrevTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkTimer::start()
|
||||||
|
{
|
||||||
|
__int64 p_StartTime;
|
||||||
|
QueryPerformanceCounter((LARGE_INTEGER*)&p_StartTime);
|
||||||
|
if(c_Stopped)
|
||||||
|
{
|
||||||
|
c_PausedTime += (p_StartTime-c_StopTime);
|
||||||
|
c_PrevTime = p_StartTime;
|
||||||
|
c_StopTime = 0;
|
||||||
|
c_Stopped = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__int64 NetworkTimer::getTime()
|
||||||
|
{
|
||||||
|
__int64 testInt;
|
||||||
|
return QueryPerformanceCounter((LARGE_INTEGER*)&testInt);
|
||||||
|
return testInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkTimer::stop()
|
||||||
|
{
|
||||||
|
if(!c_Stopped)
|
||||||
|
{
|
||||||
|
__int64 p_CurrTime;
|
||||||
|
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
|
||||||
|
c_StopTime = p_CurrTime;
|
||||||
|
c_Stopped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void NetworkTimer::reset()
|
||||||
|
{
|
||||||
|
__int64 p_CurrTime;
|
||||||
|
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
|
||||||
|
c_BaseTime = p_CurrTime;
|
||||||
|
c_PrevTime = p_CurrTime;
|
||||||
|
c_StopTime = 0;
|
||||||
|
c_Stopped = false;
|
||||||
|
}
|
||||||
|
void NetworkTimer::tick()
|
||||||
|
{
|
||||||
|
if (c_Stopped)
|
||||||
|
{
|
||||||
|
c_DeltaTime= 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__int64 p_CurrTime;
|
||||||
|
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
|
||||||
|
c_CurrTime=p_CurrTime;
|
||||||
|
|
||||||
|
c_DeltaTime=(c_CurrTime-c_PrevTime)*c_SecondsPerCount;
|
||||||
|
c_PrevTime=c_CurrTime;
|
||||||
|
if(c_DeltaTime<0.0) c_DeltaTime=0.0;
|
||||||
|
}
|
||||||
|
float NetworkTimer::getGameTime() const
|
||||||
|
{
|
||||||
|
if(c_Stopped)
|
||||||
|
{
|
||||||
|
return (float)((c_StopTime-c_BaseTime)*c_SecondsPerCount);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return (float)(((c_CurrTime-c_PausedTime)-c_BaseTime)*c_SecondsPerCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float NetworkTimer::getDeltaTime() const
|
||||||
|
{
|
||||||
|
return (float)c_DeltaTime;
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include "NetworkIncludes.h"
|
||||||
|
#ifndef _NET_TIMER_H
|
||||||
|
#define _NET_TIMER_H
|
||||||
|
class NetworkTimer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double c_SecondsPerCount;
|
||||||
|
double c_DeltaTime;
|
||||||
|
__int64 c_BaseTime;
|
||||||
|
__int64 c_PausedTime;
|
||||||
|
__int64 c_StopTime;
|
||||||
|
__int64 c_PrevTime;
|
||||||
|
__int64 c_CurrTime;
|
||||||
|
bool c_Stopped;
|
||||||
|
public:
|
||||||
|
NetworkTimer();
|
||||||
|
__int64 getTime();
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
void reset();
|
||||||
|
void tick();
|
||||||
|
float getGameTime() const;
|
||||||
|
float getDeltaTime() const;
|
||||||
|
};
|
||||||
|
#endif
|
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef NET_UPD_STRUCTS_H
|
||||||
|
#define NET_UPD_STRUCTS_H
|
||||||
|
#include "NetworkIncludes.h"
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
struct EffectData
|
||||||
|
{
|
||||||
|
int identifier;
|
||||||
|
Float3 head;
|
||||||
|
Float3 tail;
|
||||||
|
};
|
||||||
|
struct ServerToClientUpdateData
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
Oyster::Math::Float4x4 position;
|
||||||
|
float dirVecLen;
|
||||||
|
int hp;
|
||||||
|
int shield;
|
||||||
|
long updateCount;
|
||||||
|
ServerToClientUpdateData()
|
||||||
|
{
|
||||||
|
pid=0;
|
||||||
|
updateCount=0;
|
||||||
|
hp=0;
|
||||||
|
shield=0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const int SERVER_PLAYER_DATA_SIZE = 84;
|
||||||
|
struct ClientToServerUpdateData
|
||||||
|
{
|
||||||
|
__int8 pid;
|
||||||
|
//Oyster::Math::Float4x4 position;
|
||||||
|
__int8 forward;
|
||||||
|
__int8 roll;
|
||||||
|
__int8 straferight;
|
||||||
|
__int8 strafeup;
|
||||||
|
bool firePrim;
|
||||||
|
bool fireSecond;
|
||||||
|
bool fireSpecial;
|
||||||
|
long updateCount;
|
||||||
|
bool braking;
|
||||||
|
float TurnHor;
|
||||||
|
float TurnVer;
|
||||||
|
ClientToServerUpdateData()
|
||||||
|
{
|
||||||
|
pid=0;
|
||||||
|
forward=0;
|
||||||
|
roll=0;
|
||||||
|
straferight=0;
|
||||||
|
strafeup=0;
|
||||||
|
firePrim=false;
|
||||||
|
fireSecond=false;
|
||||||
|
fireSpecial=false;
|
||||||
|
updateCount=0;
|
||||||
|
braking=false;
|
||||||
|
TurnHor= 0.0f;
|
||||||
|
TurnVer= 0.0f;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const int CLIENT_PLAYER_DATA_SIZE = sizeof(ClientToServerUpdateData);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1 @@
|
||||||
|
#include "NetworkUpdateStructs.h"
|
|
@ -0,0 +1,112 @@
|
||||||
|
#include "SocketClient.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef SOCKET_DATA_CPP
|
||||||
|
#define SOCKET_DATA_CPP
|
||||||
|
|
||||||
|
/*std::vector<std::string> splitString(char* p_inStr, char p_delim)
|
||||||
|
{
|
||||||
|
std::stringstream ss(p_inStr);
|
||||||
|
std::vector<std::string> elems;
|
||||||
|
std::string item;
|
||||||
|
while(std::getline(ss, item, p_delim))
|
||||||
|
{
|
||||||
|
elems.push_back(item);
|
||||||
|
}
|
||||||
|
return elems;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void SocketClient::parseReceivedData(/*char* data, int size*/)
|
||||||
|
{
|
||||||
|
switch (recvBuffer[0]) // TODO: runtime error occured here when shutting down client. recvBuffer invalid pointer. ~Dan 2013-05-14
|
||||||
|
{
|
||||||
|
case 1://It's data
|
||||||
|
parseData();
|
||||||
|
break;
|
||||||
|
case 2://For the moment, this is only for init data
|
||||||
|
parseGameInitData();
|
||||||
|
break;
|
||||||
|
case 3://It's a chat message
|
||||||
|
parseMessage();
|
||||||
|
break;
|
||||||
|
case 4://It's a server message
|
||||||
|
parseServermessage();
|
||||||
|
break;
|
||||||
|
case 5://Player has been connected to a game lobby
|
||||||
|
parseLobbyInitData();
|
||||||
|
break;
|
||||||
|
case 6://It's an event
|
||||||
|
parseReceivedEvent();
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
parseReceivedEffect();
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
parseRenderData();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
int a=0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SocketClient::parseRenderData()
|
||||||
|
{
|
||||||
|
receiveRenderData(recvBuffer+1, recvBufLen-1);
|
||||||
|
}
|
||||||
|
void SocketClient::parseReceivedEffect()
|
||||||
|
{
|
||||||
|
receiveEffectData(recvBuffer+1, recvBufLen-1);
|
||||||
|
}
|
||||||
|
void SocketClient::parseReceivedEvent()
|
||||||
|
{
|
||||||
|
receiveEvent(recvBuffer+1);
|
||||||
|
}
|
||||||
|
void SocketClient::parseGameInitData()
|
||||||
|
{
|
||||||
|
receiveGameInitData(recvBuffer+1);
|
||||||
|
connectStatus=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketClient::parseLobbyInitData()
|
||||||
|
{
|
||||||
|
receiveLobbyInitData(recvBuffer+1, recvBufLen-1);
|
||||||
|
connectStatus=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketClient::parseServermessage()
|
||||||
|
{
|
||||||
|
recvBuffer[recvBufLen]='\0';
|
||||||
|
if(!strcmp(recvBuffer+1, "connected"))
|
||||||
|
{
|
||||||
|
connectStatus=true;
|
||||||
|
connStatus=ONLINE_MAINMENU;
|
||||||
|
receiveConnStatus(ONLINE_MAINMENU);
|
||||||
|
}
|
||||||
|
else if(!strcmp(recvBuffer+1, "qst"))
|
||||||
|
{
|
||||||
|
connStatus=ONLINE_QUEUEING;
|
||||||
|
receiveConnStatus(ONLINE_QUEUEING);
|
||||||
|
}
|
||||||
|
else if(!strcmp(recvBuffer+1, "qed"))
|
||||||
|
{
|
||||||
|
connStatus=ONLINE_MAINMENU;
|
||||||
|
receiveConnStatus(ONLINE_MAINMENU);
|
||||||
|
}
|
||||||
|
//Server message of some sort
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketClient::parseData()
|
||||||
|
{
|
||||||
|
//memcpy(&tmpPlayer,buffer+1,playerDataSize);
|
||||||
|
//playerContPtr->setPlayerStruct(tmpPlayer);
|
||||||
|
receivePlayerUpdate(recvBuffer+1, recvBufLen-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketClient::parseMessage()
|
||||||
|
{
|
||||||
|
//std::string message;
|
||||||
|
//message="[Chat] "+users[pid].getUsername()+": "+(buffer+1);
|
||||||
|
printf("%s\n",recvBuffer+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,79 @@
|
||||||
|
#include "SocketClient.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef SOCKET_INIT_CPP
|
||||||
|
#define SOCKET_INIT_CPP
|
||||||
|
|
||||||
|
bool SocketClient::startReceiveThread()
|
||||||
|
{
|
||||||
|
threadhandle[0]=CreateThread(
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
(LPTHREAD_START_ROUTINE)&receiveDataThreadV,
|
||||||
|
(LPVOID) this,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SocketClient::startSendDataThread()
|
||||||
|
{
|
||||||
|
threadhandle[1]=CreateThread(
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
(LPTHREAD_START_ROUTINE)&receiveDataThreadV,
|
||||||
|
(LPVOID) this,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool SocketClient::init(int listenPort)
|
||||||
|
{
|
||||||
|
return initUDPSocket(listenPort);
|
||||||
|
}
|
||||||
|
bool SocketClient::connectToIP(const char* ip, int listenPort, char* initData, int initDataSize)
|
||||||
|
{
|
||||||
|
init(listenPort);
|
||||||
|
//---------------------------------------------
|
||||||
|
// Set up the port and IP of the server
|
||||||
|
//Port starts up as a different one from when connected, it changes once the server has exchanged some info with the client
|
||||||
|
|
||||||
|
UDPsendAddr.sin_family = AF_INET;
|
||||||
|
UDPsendAddr.sin_port = htons(UDPSendPort);
|
||||||
|
UDPsendAddr.sin_addr.s_addr = inet_addr(ip);
|
||||||
|
|
||||||
|
TCPsendAddr.sin_family = AF_INET;
|
||||||
|
TCPsendAddr.sin_port = htons(TCPSendPort);
|
||||||
|
TCPsendAddr.sin_addr.s_addr = inet_addr(ip);
|
||||||
|
/*iResult=connect(connTCP, (SOCKADDR *) &TCPsendAddr, addrSize);
|
||||||
|
if (iResult == SOCKET_ERROR) {
|
||||||
|
int test=WSAGetLastError();
|
||||||
|
wprintf(L"connect failed with error: %d\n", WSAGetLastError());
|
||||||
|
//closesocket(connTCP);
|
||||||
|
//WSACleanup();
|
||||||
|
return false;
|
||||||
|
}/*
|
||||||
|
iResult=send(connTCP, initData, initDataSize, 0);
|
||||||
|
if (iResult == SOCKET_ERROR) {
|
||||||
|
int test=WSAGetLastError();
|
||||||
|
wprintf(L"connect failed with error: %d\n", WSAGetLastError());
|
||||||
|
//closesocket(connTCP);
|
||||||
|
//WSACleanup();
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
iResult = sendto(connUDP,
|
||||||
|
initData, initDataSize, 0, (SOCKADDR *) & UDPsendAddr, addrSize);
|
||||||
|
if (iResult == SOCKET_ERROR) {
|
||||||
|
wprintf(L"Client UDP sendto failed with error: %d\n", WSAGetLastError());
|
||||||
|
//closesocket(connUDP);
|
||||||
|
//WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//connectStatus=true;
|
||||||
|
connectStatus=false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,79 @@
|
||||||
|
#include "SocketClient.h"
|
||||||
|
const int maxThreadCount=2;
|
||||||
|
bool validateIpAddress(const std::string ipAddress)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sa;
|
||||||
|
int result = inet_pton(AF_INET, ipAddress.c_str(), &(sa.sin_addr));
|
||||||
|
return result != 0;
|
||||||
|
}
|
||||||
|
/*int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
std::string tst;
|
||||||
|
bool test=true;
|
||||||
|
//Multithreading variables
|
||||||
|
//int nThreads = 0;
|
||||||
|
//DWORD dwThreadId[maxThreadCount];
|
||||||
|
//HANDLE threadhandle;
|
||||||
|
|
||||||
|
GameClass game;
|
||||||
|
SocketClient<GameClass> client;
|
||||||
|
//Sets up the link to the GameClass class.
|
||||||
|
client.setPlayerContPtr(&game);
|
||||||
|
//This is the loop which makes the user enter the server address.
|
||||||
|
while (!client.isReady());
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (!test)
|
||||||
|
{
|
||||||
|
printf("Could not connect to server. Try another IP.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Enter the server ip. \n");
|
||||||
|
}
|
||||||
|
getline(std::cin, tst);
|
||||||
|
if (tst.length()==0)
|
||||||
|
{
|
||||||
|
tst="127.0.0.1";
|
||||||
|
}
|
||||||
|
if (validateIpAddress(tst))
|
||||||
|
{
|
||||||
|
//Tmp init connection message: set username
|
||||||
|
char* tmp=new char[30];
|
||||||
|
printf("What is your desired username?\n");
|
||||||
|
std::cin.getline(tmp,30);
|
||||||
|
if (strlen(tmp)==0)
|
||||||
|
{
|
||||||
|
tmp="Anonymous";
|
||||||
|
}
|
||||||
|
printf("Username set to %s\n", tmp);
|
||||||
|
|
||||||
|
test=client.connectToIP(tst.c_str(), tmp, strlen(tmp));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Invalid IPaddress. Please enter a new IPaddress.\n");
|
||||||
|
test=false;
|
||||||
|
}
|
||||||
|
} while (!test);
|
||||||
|
while (!client.isConnected());
|
||||||
|
Sleep(1000);
|
||||||
|
//Starts the receive loop
|
||||||
|
//threadhandle=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&client.receiveDataThreadV,(LPVOID) &client,0,&dwThreadId[0]);
|
||||||
|
client.startReceiveThread();
|
||||||
|
//GetExitCodeThread(threadhandle, eCode);
|
||||||
|
//This is just a loop to receive user input which creates a natural delay for sendUserData.
|
||||||
|
printf("Write what you want to send\n");
|
||||||
|
tst="tmp init message";
|
||||||
|
while (tst.length()>0)
|
||||||
|
{
|
||||||
|
client.sendMessage(tst);
|
||||||
|
client.sendUserData();
|
||||||
|
getline(std::cin, tst);
|
||||||
|
}
|
||||||
|
//Kills off the thread and connection
|
||||||
|
//DWORD eCode=0;
|
||||||
|
//TerminateThread(threadhandle, eCode);
|
||||||
|
client.closeConnection();
|
||||||
|
return 0;
|
||||||
|
}*/
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include "SocketClient.h"
|
||||||
|
|
||||||
|
bool SocketClient::initTCPSocket(int listenPort)
|
||||||
|
{
|
||||||
|
TCPrecvAddr.sin_family = AF_INET;
|
||||||
|
TCPrecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
TCPrecvAddr.sin_port = htons(/*TCPRecvPort*/listenPort);
|
||||||
|
|
||||||
|
connTCP = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if (connTCP == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
iResult = bind(connTCP, (SOCKADDR *) & TCPrecvAddr, addrSize);
|
||||||
|
if (iResult == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
int tst=WSAGetLastError();
|
||||||
|
wprintf(L"bind function failed with error %d\n", WSAGetLastError());
|
||||||
|
iResult = closesocket(connTCP);
|
||||||
|
if (iResult == SOCKET_ERROR)
|
||||||
|
wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
|
||||||
|
//WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool SocketClient::sendDataTCP(const char* data, int size)
|
||||||
|
{
|
||||||
|
iResult = sendto(connTCP,
|
||||||
|
data, size, 0, (SOCKADDR *) & TCPsendAddr, addrSize);
|
||||||
|
if (iResult == SOCKET_ERROR) {
|
||||||
|
wprintf(L"TCP sendto failed with error: %d\n", WSAGetLastError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include "SocketClient.h"
|
||||||
|
bool SocketClient::initUDPSocket(int listenPort)
|
||||||
|
{
|
||||||
|
UDPrecvAddr.sin_family = AF_INET;
|
||||||
|
UDPrecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
UDPrecvAddr.sin_port = htons(listenPort);
|
||||||
|
//---------------------------------------------
|
||||||
|
// Create a socket for sending data
|
||||||
|
connUDP = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
if (connUDP == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iResult = bind(connUDP, (SOCKADDR *) & UDPrecvAddr, addrSize);
|
||||||
|
if (iResult == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
wprintf(L"bind function failed with error %d\n", WSAGetLastError());
|
||||||
|
iResult = closesocket(connUDP);
|
||||||
|
if (iResult == SOCKET_ERROR)
|
||||||
|
wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool SocketClient::sendDataUDP(const char* data, int size)
|
||||||
|
{
|
||||||
|
iResult = sendto(connUDP,
|
||||||
|
data, size, 0, (SOCKADDR *) & UDPsendAddr, addrSize);
|
||||||
|
if (iResult == SOCKET_ERROR) {
|
||||||
|
wprintf(L"sendto failed with error: %d\n", WSAGetLastError());
|
||||||
|
//closesocket(connUDP);
|
||||||
|
//WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
#include "SocketClient.h"
|
||||||
|
#pragma once
|
||||||
|
#ifndef SOCKET_CLIENT_CPP
|
||||||
|
#define SOCKET_CLIENT_CPP
|
||||||
|
|
||||||
|
SocketClient::SocketClient()
|
||||||
|
{
|
||||||
|
playerDataSize=Network::CLIENT_PLAYER_DATA_SIZE;
|
||||||
|
sendDelayMS=10;
|
||||||
|
connUDP = INVALID_SOCKET;
|
||||||
|
connTCP = INVALID_SOCKET;
|
||||||
|
//sendBuffer=new char[BUFFER_MAX_SIZE];
|
||||||
|
//sendBufLen=BUFFER_MAX_SIZE;
|
||||||
|
//ZeroMemory(sendBuffer,sendBufLen);
|
||||||
|
recvBuffer=new char[BUFFER_MAX_SIZE];
|
||||||
|
recvBufLen=BUFFER_MAX_SIZE;
|
||||||
|
ZeroMemory(recvBuffer,recvBufLen);
|
||||||
|
|
||||||
|
dataBuf=new char[playerDataSize+1];
|
||||||
|
dataBuf[0]=1;
|
||||||
|
//ZeroMemory(b,sizeof(buffer));
|
||||||
|
//----------------------
|
||||||
|
// Initialize Winsock
|
||||||
|
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||||
|
if (iResult != NO_ERROR) {
|
||||||
|
printf("WSAStartup failed with error: %d\n", iResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
addrSize=sizeof(sockaddr_in);
|
||||||
|
connectStatus=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool SocketClient::sendUserData()
|
||||||
|
{
|
||||||
|
//memcpy(dataBuf+1,&playerContPtr->getPlayerData(),playerDataSize);
|
||||||
|
//return sendData(dataBuf, playerDataSize+1);
|
||||||
|
printf("NOT YET IMPLEMENTED");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SocketClient::sendUserData(char* data, int size)
|
||||||
|
{
|
||||||
|
memcpy(dataBuf+1,data,size);
|
||||||
|
return sendDataUDP(dataBuf, size+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SocketClient::sendMessage(std::string msg)
|
||||||
|
{
|
||||||
|
if (msg[0]=='/')
|
||||||
|
{
|
||||||
|
//Server command
|
||||||
|
msg[0]=2;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Chat message
|
||||||
|
msg='1'+msg;
|
||||||
|
msg[0]=3;
|
||||||
|
}
|
||||||
|
return sendDataUDP(msg.c_str(), (int)msg.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SocketClient::closeConnection()
|
||||||
|
{
|
||||||
|
connectStatus=false;
|
||||||
|
Sleep(5);
|
||||||
|
//Give the threads 5 ms to quit themselves before terminating them
|
||||||
|
DWORD eCode=0;
|
||||||
|
TerminateThread(threadhandle[0], eCode);
|
||||||
|
TerminateThread(threadhandle[1], eCode);
|
||||||
|
//---------------------------------------------
|
||||||
|
// When the application is finished sending, close the socket.
|
||||||
|
setupStatus=false;
|
||||||
|
printf("Finished sending. Closing socket.\n");
|
||||||
|
iResult = closesocket(connUDP);
|
||||||
|
if (iResult == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
wprintf(L"closesocket failed with error: %d\n", WSAGetLastError());
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//---------------------------------------------
|
||||||
|
// Clean up and quit.
|
||||||
|
printf("Exiting.\n");
|
||||||
|
WSACleanup();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketClient::receiveDataThreadV(SocketClient* ptr)
|
||||||
|
{
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
ptr->recvBufLen=recvfrom(ptr->connUDP, ptr->recvBuffer, BUFFER_MAX_SIZE, 0, (SOCKADDR *) & ptr->UDPsendAddr, &ptr->addrSize);
|
||||||
|
if (ptr->recvBufLen == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
wprintf(L"recv failed with error %d\n", WSAGetLastError());
|
||||||
|
}
|
||||||
|
//ptr->buffer[ptr->iResult]='\0';
|
||||||
|
else
|
||||||
|
ptr->parseReceivedData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SocketClient::receiveDataWaitOnResponse()
|
||||||
|
{
|
||||||
|
recvBufLen=recvfrom(connUDP, recvBuffer, BUFFER_MAX_SIZE, 0, (SOCKADDR *) & UDPsendAddr, &addrSize);
|
||||||
|
if (recvBufLen == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
wprintf(L"recv failed with error %d\n", WSAGetLastError());
|
||||||
|
}
|
||||||
|
//buffer[iResult]='\0';
|
||||||
|
else
|
||||||
|
parseReceivedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketClient::sendDataThreadV(SocketClient* ptr)
|
||||||
|
{
|
||||||
|
printf("NOT YET IMPLEMENTED");
|
||||||
|
/*while(ptr->connectStatus)
|
||||||
|
{
|
||||||
|
memcpy(ptr->dataBuf+1,&ptr->playerContPtr->getPlayerData(),playerDataSize);
|
||||||
|
ptr->sendData(ptr->dataBuf, playerDataSize+1);
|
||||||
|
Sleep(ptr->sendDelayMS);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,147 @@
|
||||||
|
#pragma once
|
||||||
|
//Start by defining unicode
|
||||||
|
//#ifndef UNICODE
|
||||||
|
//#define UNICODE
|
||||||
|
//#endif
|
||||||
|
//defining WIN32_LEAN_AND_MEAN this early is REQUIRED if you want to avoid a certain winsock error.
|
||||||
|
//#define WIN32_LEAN_AND_MEAN
|
||||||
|
//#define NOMINMAX
|
||||||
|
//#include
|
||||||
|
//#include "GameClassExample.h"
|
||||||
|
//These includes are required for winsock
|
||||||
|
#include "Network.h"
|
||||||
|
//#include <winsock2.h>
|
||||||
|
//#include <Ws2tcpip.h>
|
||||||
|
//#include <stdio.h>
|
||||||
|
//#include <windows.h>
|
||||||
|
//#include "OysterMath.h"
|
||||||
|
//These are optional includes for various useful features
|
||||||
|
#include <time.h>
|
||||||
|
#include <string>
|
||||||
|
#include <ctime>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
//ws2_32.lib is a lib file the linker requires for winsock compilation
|
||||||
|
#pragma comment(lib, "Ws2_32.lib")
|
||||||
|
|
||||||
|
//constants used by the socket client to avoid hard coding and/or mass variable declaration
|
||||||
|
const short TCPSendPort = 11110;
|
||||||
|
const short TCPRecvPort = 11111;
|
||||||
|
const short UDPSendPort = 11000;
|
||||||
|
const short UDPRecvPort = 11001;
|
||||||
|
const int BUFFER_MAX_SIZE = 4096;
|
||||||
|
|
||||||
|
enum ConnectionStatus
|
||||||
|
{
|
||||||
|
OFFLINE,
|
||||||
|
ONLINE_MAINMENU,
|
||||||
|
ONLINE_QUEUEING,
|
||||||
|
ONLINE_INLOBBY,
|
||||||
|
ONLINE_INGAME
|
||||||
|
};
|
||||||
|
class SocketClient
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
HANDLE threadhandle[2];
|
||||||
|
int sendDelayMS;
|
||||||
|
|
||||||
|
//2 bools used to verify the activation of the client so threads can't start too early
|
||||||
|
ConnectionStatus connStatus;
|
||||||
|
bool setupStatus;
|
||||||
|
bool connectStatus;
|
||||||
|
|
||||||
|
//iResult is used to check error codes
|
||||||
|
int iResult;
|
||||||
|
//wsaData records error messages and errors which winsock might encounter
|
||||||
|
WSADATA wsaData;
|
||||||
|
|
||||||
|
//Main socket
|
||||||
|
SOCKET connUDP;
|
||||||
|
SOCKET connTCP;
|
||||||
|
|
||||||
|
//Addresses used for data transfer
|
||||||
|
sockaddr_in TCPrecvAddr;
|
||||||
|
sockaddr_in TCPsendAddr;
|
||||||
|
//UDPrecvAddr marks the port and IP adress the server is supposed to return data to.
|
||||||
|
sockaddr_in UDPrecvAddr;
|
||||||
|
//UDPsendAddr marks which IP and port the client is supposed to send data to.
|
||||||
|
sockaddr_in UDPsendAddr;
|
||||||
|
//size of a sockaddr_in. This might as well be a constant, but i'm keeping it in the class for performance reasons.
|
||||||
|
int addrSize;
|
||||||
|
|
||||||
|
//buffer which is filled when data receive happens.
|
||||||
|
char* recvBuffer;
|
||||||
|
//this variable tracks the buffer length.
|
||||||
|
int recvBufLen;
|
||||||
|
|
||||||
|
//dataBuf is a buffer solely for sending your own user data. It never changes size in order to increase performance.
|
||||||
|
//char* sendBuffer;
|
||||||
|
//int sendBufLen;
|
||||||
|
//PlayerStruct tmpPlayer;
|
||||||
|
char* dataBuf;
|
||||||
|
int playerDataSize;
|
||||||
|
public:
|
||||||
|
void setPlayerDataSize(int pds){playerDataSize=pds;}
|
||||||
|
//Constructor
|
||||||
|
SocketClient();
|
||||||
|
|
||||||
|
//Initiation for sockets.
|
||||||
|
bool init(int listenPort);
|
||||||
|
bool initTCPSocket(int listenPort);
|
||||||
|
bool initUDPSocket(int listenPort);
|
||||||
|
//Connects to a server of a user-defined IP. Can only be called after an initXSocket has gone through.
|
||||||
|
//The 2 remaining variables are init data and size of said data. Currently username.
|
||||||
|
bool connectToIP(const char* ip, int listenPort, char* initData, int initDataSize);
|
||||||
|
//sends an undefined data type of (variable#2) size to the server.
|
||||||
|
bool sendDataUDP(const char*, int);
|
||||||
|
bool sendDataTCP(const char*, int);
|
||||||
|
//sends a text string to the server.
|
||||||
|
bool sendMessage(std::string str);
|
||||||
|
bool sendServerMessage(std::string str);
|
||||||
|
//sends user data to the server
|
||||||
|
bool sendUserData();
|
||||||
|
bool sendUserData(char* data, int size);
|
||||||
|
|
||||||
|
//Closes connection, kills off the socket.
|
||||||
|
bool closeConnection();
|
||||||
|
|
||||||
|
//Simple ifBoolIsTrue checks
|
||||||
|
bool isReady() const {return setupStatus;}
|
||||||
|
bool isConnected() const {return connectStatus;}
|
||||||
|
void receiveDataWaitOnResponse();
|
||||||
|
//Sends data periodically
|
||||||
|
static void sendDataThreadV(SocketClient* ptr);
|
||||||
|
//Receive loop. This is event-based and is on its own thread.
|
||||||
|
static void receiveDataThreadV(SocketClient* ptr);
|
||||||
|
//Once data is received, it calls on the parseReceivedData function.
|
||||||
|
void parseReceivedData();
|
||||||
|
//void parseReceivedKeyframe();
|
||||||
|
//If an event is called from the server, this function will be called.
|
||||||
|
void parseReceivedEvent();
|
||||||
|
void parseReceivedEffect();
|
||||||
|
//It is then sent to one of the following functions based on the first byte of the buffer.
|
||||||
|
|
||||||
|
//Servermessage
|
||||||
|
void parseServermessage();
|
||||||
|
//single user data
|
||||||
|
void parseData();
|
||||||
|
//string (character data)
|
||||||
|
void parseMessage();
|
||||||
|
//init data which sets the start position etc of all characters.
|
||||||
|
void parseLobbyInitData();
|
||||||
|
void parseGameInitData();
|
||||||
|
void parseRenderData();
|
||||||
|
|
||||||
|
bool startReceiveThread();
|
||||||
|
bool startSendDataThread();
|
||||||
|
void setSendDelay(int ms){sendDelayMS=ms;}
|
||||||
|
|
||||||
|
//virtual functions
|
||||||
|
virtual void receiveGameInitData(char*)=0;
|
||||||
|
virtual void receiveLobbyInitData(char*, int)=0;
|
||||||
|
virtual void receivePlayerUpdate(char*, int)=0;
|
||||||
|
virtual void receiveRenderData(char*, int)=0;
|
||||||
|
virtual void receiveEffectData(char*, int)=0;
|
||||||
|
virtual void receiveConnStatus(ConnectionStatus)=0;
|
||||||
|
virtual void receiveEvent(char*)=0;
|
||||||
|
};
|
|
@ -0,0 +1,113 @@
|
||||||
|
#include "Game.h"
|
||||||
|
Game::Game()
|
||||||
|
{
|
||||||
|
playerCount=0;
|
||||||
|
started=false;
|
||||||
|
for (int i=0; i<MUTEX_COUNT; i++)
|
||||||
|
{
|
||||||
|
mutex[i] = CreateMutex(
|
||||||
|
NULL, // default security attributes
|
||||||
|
FALSE, // initially not owned
|
||||||
|
NULL); // unnamed mutex
|
||||||
|
|
||||||
|
if (mutex == NULL)
|
||||||
|
{
|
||||||
|
printf("CreateMutex error: %d\n", GetLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
ready[i]=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*bool Game::checkMoveValidity(ClientToServerUpdateData plr)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (false)
|
||||||
|
{
|
||||||
|
players[plr.pid]=plr;
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
//The package that arrived is an earlier version than the last one.
|
||||||
|
//Ignore the position data, but still check actions and such to make
|
||||||
|
//sure that you don't miss a key press.
|
||||||
|
|
||||||
|
//For example, if the fire button is true in this package but false now,
|
||||||
|
//the ship should still shoot once.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Float4x4 Game::getPlayerPos(int id)
|
||||||
|
{
|
||||||
|
WaitForSingleObject(mutex[0], INFINITE);
|
||||||
|
Float4x4 tmp=players[id].position;
|
||||||
|
ReleaseMutex(mutex[0]);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
void Game::setPlayerPos(int id, Float4x4 pos)
|
||||||
|
{
|
||||||
|
WaitForSingleObject(mutex[0], INFINITE);
|
||||||
|
players[id].position=pos;
|
||||||
|
ReleaseMutex(mutex[0]);
|
||||||
|
}
|
||||||
|
ClientToServerUpdateData Game::getPlayerData(int id)
|
||||||
|
{
|
||||||
|
WaitForSingleObject(mutex[0], INFINITE);
|
||||||
|
ClientToServerUpdateData tmp=players[id];
|
||||||
|
ReleaseMutex(mutex[0]);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
void Game::setPlayerData(int id, ClientToServerUpdateData ps)
|
||||||
|
{
|
||||||
|
WaitForSingleObject(mutex[0], INFINITE);
|
||||||
|
players[id]=ps;
|
||||||
|
ReleaseMutex(mutex[0]);
|
||||||
|
}*/
|
||||||
|
void Game::initGame(std::vector<User> usr, int nrOfPlayers)
|
||||||
|
{
|
||||||
|
/*for (int i=0; i<nrOfPlayers; i++)
|
||||||
|
{
|
||||||
|
users[i]=&usr[i];
|
||||||
|
}*/
|
||||||
|
Oyster::Math::Float4x4 initvariable=Oyster::Math::Float4x4::identity;
|
||||||
|
initvariable.v[3].x=50;
|
||||||
|
for (unsigned int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
initvariable.v[3].x=(Float)200*i;
|
||||||
|
//players[i].position=initvariable;
|
||||||
|
}
|
||||||
|
//players[1].position.m11=0.1f;
|
||||||
|
//players[1].position.m22=0.1f;
|
||||||
|
//players[1].position.m33=0.1f;
|
||||||
|
}
|
||||||
|
GameInitData Game::getInitData()
|
||||||
|
{
|
||||||
|
//Later getInitData will need to receive a user id to set it up 100%.
|
||||||
|
//That way, this is the only function that needs to be called in order to connect(or reconnect) to a game.
|
||||||
|
GameInitData init;
|
||||||
|
|
||||||
|
init.pid=0;
|
||||||
|
for (unsigned int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
init.player[i].pid=i;
|
||||||
|
init.player[i].teamid=i%2;
|
||||||
|
//init.player[i].position=getPlayerPos(i);
|
||||||
|
//users[i]->setGame(2);
|
||||||
|
//init.players[i]=players[i];
|
||||||
|
}
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
void Game::addUser(int uid)
|
||||||
|
{
|
||||||
|
userID[playerCount++]=uid;
|
||||||
|
}
|
||||||
|
bool Game::startGame()
|
||||||
|
{
|
||||||
|
started=true;
|
||||||
|
return started;
|
||||||
|
}
|
||||||
|
void Game::update(float dt)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef GAME_H
|
||||||
|
#define GAME_H
|
||||||
|
#include "User.h"
|
||||||
|
#include "ServerInclude.h"
|
||||||
|
const int MUTEX_COUNT =2;
|
||||||
|
//Mutex #0=playerPos setGet
|
||||||
|
//Mutex #1=
|
||||||
|
|
||||||
|
//#include "Session.h"
|
||||||
|
|
||||||
|
class Game
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool started;
|
||||||
|
//ClientToServerUpdateData players[PLAYER_MAX_COUNT];
|
||||||
|
User* users[PLAYER_MAX_COUNT];
|
||||||
|
int userID[PLAYER_MAX_COUNT];
|
||||||
|
bool ready[PLAYER_MAX_COUNT];
|
||||||
|
int playerCount;
|
||||||
|
|
||||||
|
//Tracks which ship each user has
|
||||||
|
int shipID[PLAYER_MAX_COUNT];
|
||||||
|
HANDLE mutex[MUTEX_COUNT];
|
||||||
|
//::Game::Session *session;
|
||||||
|
int sessionID;
|
||||||
|
public:
|
||||||
|
//Will reset all data
|
||||||
|
//playerIDs is an array of int which points toward each users connection.
|
||||||
|
void setReady(int pid, bool rdy){ready[pid]=rdy;}
|
||||||
|
bool allReady(){for (int i=0; i<playerCount; i++){if(ready[i]==false)return false;}return true;}
|
||||||
|
void initGame(std::vector<User> players, int nrOfPlayers);
|
||||||
|
GameInitData getInitData();
|
||||||
|
bool startGame();
|
||||||
|
bool isStarted(){return started;}
|
||||||
|
Game();
|
||||||
|
//Float4x4 getPlayerPos(int id);
|
||||||
|
//void setPlayerPos(int id, Float4x4 pos);
|
||||||
|
//bool checkMoveValidity(ClientToServerUpdateData plr);
|
||||||
|
//ClientToServerUpdateData getPlayerData(int id);
|
||||||
|
//void setPlayerData(int id, ClientToServerUpdateData ps);
|
||||||
|
|
||||||
|
int getPlayerCount() {return playerCount;}
|
||||||
|
int getUserID(int i) {return userID[i];}
|
||||||
|
|
||||||
|
void initLUA(char* file);
|
||||||
|
void update(float dt);
|
||||||
|
void addUser(int uid);
|
||||||
|
void removeUser(int uid){playerCount--;}
|
||||||
|
};
|
||||||
|
#endif
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include "Lobby.h"
|
||||||
|
|
||||||
|
Lobby::Lobby()
|
||||||
|
{
|
||||||
|
timerStarted=false;
|
||||||
|
nrUsers=0;
|
||||||
|
timerMutex = CreateMutex(
|
||||||
|
NULL, // default security attributes
|
||||||
|
FALSE, // initially not owned
|
||||||
|
NULL); // unnamed mutex
|
||||||
|
|
||||||
|
if (timerMutex == NULL)
|
||||||
|
{
|
||||||
|
printf("CreateMutex error: %d\n", GetLastError());
|
||||||
|
}
|
||||||
|
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
userData[i].pid=i;
|
||||||
|
userData[i].shipID=0;
|
||||||
|
userData[i].usrName[0]='\0';
|
||||||
|
//userData[i].usrName="Player";
|
||||||
|
//userData[i].usrName+=(char)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Lobby::removeUser()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void Lobby::addUser(User usr, int i)
|
||||||
|
{
|
||||||
|
userID[nrUsers]=i;
|
||||||
|
userData[nrUsers].setName(usr.getUsername().c_str());
|
||||||
|
//userData[nrUsers].shipID=1;
|
||||||
|
nrUsers++;
|
||||||
|
}
|
||||||
|
void Lobby::updateUserData(LobbyUserStruct data)
|
||||||
|
{
|
||||||
|
userData[data.pid]=data;
|
||||||
|
}
|
||||||
|
LobbyInitData Lobby::getLobbyInitData()
|
||||||
|
{
|
||||||
|
LobbyInitData data;
|
||||||
|
data.playerCount=nrUsers;
|
||||||
|
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
data.players[i]=userData[i];
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
void Lobby::startLobbyCountdown(float seconds)
|
||||||
|
{
|
||||||
|
WaitForSingleObject(timerMutex, INFINITE);
|
||||||
|
countdownLimit=seconds;
|
||||||
|
countdownTimer.reset();
|
||||||
|
countdownTimer.start();
|
||||||
|
timerStarted=true;
|
||||||
|
ReleaseMutex(timerMutex);
|
||||||
|
}
|
||||||
|
float Lobby::timeLeft()
|
||||||
|
{
|
||||||
|
WaitForSingleObject(timerMutex, INFINITE);
|
||||||
|
countdownTimer.tick();
|
||||||
|
if (!timerStarted)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float timeLeft=countdownLimit-countdownTimer.getGameTime();
|
||||||
|
if(timeLeft>0)
|
||||||
|
return timeLeft;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ReleaseMutex(timerMutex);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include "ServerInclude.h"
|
||||||
|
#include "User.h"
|
||||||
|
#ifndef LOBBY_H
|
||||||
|
#define LOBBY_H
|
||||||
|
class Lobby
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int nrUsers;
|
||||||
|
int userID[PLAYER_MAX_COUNT];
|
||||||
|
ServerTimer countdownTimer;
|
||||||
|
float countdownLimit;
|
||||||
|
LobbyUserStruct userData[PLAYER_MAX_COUNT];
|
||||||
|
bool timerStarted;
|
||||||
|
HANDLE timerMutex;
|
||||||
|
public:
|
||||||
|
Lobby();
|
||||||
|
void addUser(User usr, int i);
|
||||||
|
int getUserID(int i) const {return userID[i];}
|
||||||
|
int getNrPlayers() const {return nrUsers;}
|
||||||
|
void removeUser();
|
||||||
|
void updateUserData(LobbyUserStruct);
|
||||||
|
LobbyInitData getLobbyInitData();
|
||||||
|
void startLobbyCountdown(float seconds);
|
||||||
|
float timeLeft();
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif
|
|
@ -0,0 +1,219 @@
|
||||||
|
#include "SocketServer.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SocketServer::parseReceivedData(int threadID/*char* data, int size*/)
|
||||||
|
{
|
||||||
|
bool test=false;
|
||||||
|
for(unsigned int i=0; i<users.size(); i++)
|
||||||
|
{
|
||||||
|
if(memcmp(&connData[threadID].srcAddr, &users[i].getAddr(), sizeof(sockaddr_in)) != 0)
|
||||||
|
{
|
||||||
|
//User i has not sent the data.
|
||||||
|
test=false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Found the user which sent the data
|
||||||
|
test=true;
|
||||||
|
switch (connData[threadID].buffer[0])
|
||||||
|
{
|
||||||
|
case 1://It's data
|
||||||
|
if(users[i].isIngame()) parseData(i, users[i].getGame(), threadID);
|
||||||
|
break;
|
||||||
|
case 2://It's a user-entered command
|
||||||
|
parseServercommand(i, threadID);
|
||||||
|
break;
|
||||||
|
case 3://It's a chat message
|
||||||
|
parseMessage(i, threadID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!test)
|
||||||
|
{
|
||||||
|
//User does not exist yet
|
||||||
|
//This is temporary until i have a proper login process in place
|
||||||
|
addUser(threadID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketServer::addUser(int threadID)
|
||||||
|
{
|
||||||
|
printf("UDP adding user.\n");
|
||||||
|
User usr=User((int)users.size(),connData[threadID].srcAddr);
|
||||||
|
connData[threadID].buffer[connData[threadID].dataSize]='\0';
|
||||||
|
usr.setUsername(connData[threadID].buffer);
|
||||||
|
users.push_back(usr);
|
||||||
|
sendData(((int)users.size())-1, "\4connected",10);
|
||||||
|
std::string asd=users[users.size()-1].getUsername();
|
||||||
|
printf("Username:%s, IP:%s\n",users[users.size()-1].getUsername().c_str(), inet_ntoa(users[users.size()-1].getAddr().sin_addr));
|
||||||
|
}
|
||||||
|
void SocketServer::AddUser(ConnThreadData* data)
|
||||||
|
{
|
||||||
|
printf("TCP adding user.\n");
|
||||||
|
User usr=User((int)users.size(),data->srcAddr);
|
||||||
|
data->buffer[data->dataSize]='\0';
|
||||||
|
usr.setUsername(data->buffer);
|
||||||
|
users.push_back(usr);
|
||||||
|
sendData(((int)users.size())-1, "\4connected",10);
|
||||||
|
std::string asd=users[users.size()-1].getUsername();
|
||||||
|
printf("Username:%s, IP:%s\n",users[users.size()-1].getUsername().c_str(), inet_ntoa(users[users.size()-1].getAddr().sin_addr));
|
||||||
|
}
|
||||||
|
void SocketServer::removeUser(int id)
|
||||||
|
{
|
||||||
|
games[users[id].getGame()].removeUser(id);
|
||||||
|
users.erase(users.begin()+id);
|
||||||
|
}
|
||||||
|
void SocketServer::parseServercommand(int pid, int threadID)
|
||||||
|
{
|
||||||
|
connData[threadID].buffer[connData[threadID].dataSize]='\0';
|
||||||
|
wprintf(L"User %d sent a server command.\n", pid);
|
||||||
|
printf("The command is the following:%s.\n", connData[threadID].buffer+1);
|
||||||
|
std::vector<std::string> list=splitString(connData[threadID].buffer+1, ' ');
|
||||||
|
bool validcommand=false;
|
||||||
|
if(list.size()==0)
|
||||||
|
{
|
||||||
|
//Ignore case 1, to avoid vector subscript out of range errors
|
||||||
|
}
|
||||||
|
//First variable: Command
|
||||||
|
else if(!list[0].compare(" "))
|
||||||
|
{
|
||||||
|
//Add rest ignore cases here
|
||||||
|
}
|
||||||
|
else if(!list[0].compare("help"))
|
||||||
|
{
|
||||||
|
validcommand=true;
|
||||||
|
}
|
||||||
|
//else if(!list[0].compare("startgame"))
|
||||||
|
//{
|
||||||
|
//validcommand=true;
|
||||||
|
//Do more than just sending init data here
|
||||||
|
//sendInitData();
|
||||||
|
//}
|
||||||
|
else if (!list[0].compare("exit"))
|
||||||
|
{
|
||||||
|
validcommand=true;
|
||||||
|
//User #pid needs to be removed here, and data needs to be sorted accordingly.
|
||||||
|
}
|
||||||
|
else if (!list[0].compare("qst"))
|
||||||
|
{
|
||||||
|
validcommand=true;
|
||||||
|
if (users[pid].getState()==ONLINE)
|
||||||
|
{
|
||||||
|
sendData(pid, "\4qst",4);
|
||||||
|
users[pid].setState(ONLINE_QUEUEING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!list[0].compare("qed"))
|
||||||
|
{
|
||||||
|
validcommand=true;
|
||||||
|
if (users[pid].getState()==ONLINE_QUEUEING)
|
||||||
|
{
|
||||||
|
sendData(pid, "\4qed",4);
|
||||||
|
users[pid].setState(ONLINE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!list[0].compare("rdy"))
|
||||||
|
{
|
||||||
|
if (users[pid].getState()==ONLINE_INGAME)
|
||||||
|
{
|
||||||
|
games[users[pid].getGame()].setReady(pid, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!list[0].compare("dc"))
|
||||||
|
{
|
||||||
|
validcommand=true;
|
||||||
|
printf("User %s (ID:%d) has disconnected.",users[pid].getUsername().c_str(), pid);
|
||||||
|
users[pid].setState(OFFLINE);
|
||||||
|
removeUser(pid);
|
||||||
|
//Tell games that he might be in here taht he's down
|
||||||
|
//users.erase(users.begin()
|
||||||
|
}
|
||||||
|
else if((!list[0].compare("w")||!list[0].compare("whisper")||!list[0].compare("msg")) && list.size()>2)
|
||||||
|
{
|
||||||
|
validcommand=true;
|
||||||
|
for(unsigned int i=0; i<users.size(); i++)
|
||||||
|
{
|
||||||
|
//Second variable: Target user
|
||||||
|
if (!list[1].compare(users[i].getUsername()))
|
||||||
|
{
|
||||||
|
//Other variables: Text message.
|
||||||
|
//The +3 is for the 2 spaces and the first /. Calculating the start pos of the message.
|
||||||
|
int startloc=(int)(list[0].length()+list[1].length())+3;
|
||||||
|
//std::string msg="\3[Whisper] "+users[pid].getUsername()+":"+(connData[threadID].buffer+startloc);
|
||||||
|
//msg+=users[pid].getUsername()
|
||||||
|
//sendData(i,msg.c_str(), msg.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(!list[0].compare("setname"))
|
||||||
|
{
|
||||||
|
if(list.size()>1)
|
||||||
|
{
|
||||||
|
users[pid].setUsername(list[1]);
|
||||||
|
//list[1]="\3Your username has been changed to "+list[1];
|
||||||
|
//sendData(pid,list[1].c_str(), list[1].length());
|
||||||
|
validcommand=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!validcommand)
|
||||||
|
{
|
||||||
|
int a=0;
|
||||||
|
//sendData(pid, "\3Invalid server command.", 24);
|
||||||
|
//Tell user that the server command was invalid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SocketServer::parseData(int pid, int gid, int threadID)
|
||||||
|
{
|
||||||
|
memcpy(&connData[threadID].tmpdata,connData[threadID].buffer+1,CLIENT_PLAYER_DATA_SIZE);
|
||||||
|
//No old packets
|
||||||
|
if (users[pid].getLastUpdate()<connData[threadID].tmpdata.updateCount)
|
||||||
|
{
|
||||||
|
users[pid].setLastUpdate(connData[threadID].tmpdata.updateCount);
|
||||||
|
users[pid].setLastUpdateData(connData[threadID].tmpdata);
|
||||||
|
ControlPlayer(session->accessPlayer(pid),connData[threadID].tmpdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SocketServer::parseMessage(int pid, int threadID)
|
||||||
|
{
|
||||||
|
std::string message;
|
||||||
|
message="\3[Chat] "+users[pid].getUsername()+": "+(connData[threadID].buffer+1);
|
||||||
|
sendData(-1,message.c_str(), (int)message.length());
|
||||||
|
}
|
||||||
|
void SocketServer::sendInitData(int gid)
|
||||||
|
{
|
||||||
|
GameInitData init=games[gid].getInitData();
|
||||||
|
//int test=session->getNumPlayers(); // getNumPlayers is removed
|
||||||
|
for (int i=0; i<PLAYER_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
init.player[i].position=session->accessPlayer(i).getOrientation();
|
||||||
|
}
|
||||||
|
char* gd=new char[sizeof(init)+1];
|
||||||
|
gd[0]=2;
|
||||||
|
for (int i=0; i<games[gid].getPlayerCount(); i++)
|
||||||
|
{
|
||||||
|
int c=sizeof(init);
|
||||||
|
init.pid=i;
|
||||||
|
memcpy(gd+1,&init, sizeof(init));
|
||||||
|
sendData(games[gid].getUserID(i), gd, sizeof(init)+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SocketServer::sendLobbyInitData(int lid)
|
||||||
|
{
|
||||||
|
LobbyInitData init=lobby.getLobbyInitData();
|
||||||
|
init.timer=LOBBY_WAIT_TIME;
|
||||||
|
int c=sizeof(init);
|
||||||
|
char* gd=new char[c+1];
|
||||||
|
gd[0]=5;
|
||||||
|
for (int i=0; i<lobby.getNrPlayers(); i++)
|
||||||
|
{
|
||||||
|
init.pid=i;
|
||||||
|
memcpy(gd+1,&init, c);
|
||||||
|
sendData(lobby.getUserID(i), gd, c+1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#include "Network.h"
|
||||||
|
#pragma once
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#include <crtdbg.h>
|
||||||
|
#define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__)
|
||||||
|
#else
|
||||||
|
#define DEBUG_NEW new
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include "OysterMath.h"
|
||||||
|
#include "Session.h"
|
||||||
|
#include "ServerTimer.h"
|
||||||
|
using namespace Network;
|
||||||
|
|
||||||
|
const float GAME_UPDATEDELAY=1.0f/120.0f;
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include <ctime>
|
||||||
|
#include "SocketServer.h"
|
||||||
|
#include "ServerTimer.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <stdio.h>
|
||||||
|
//#ifdef WINDOWS
|
||||||
|
#include <direct.h>
|
||||||
|
#include "ServerInclude.h"
|
||||||
|
#define GetCurrentDir _getcwd
|
||||||
|
//#else
|
||||||
|
//For other OS than windows; can't be found on
|
||||||
|
//all windows setups so it's commented for now
|
||||||
|
//#include <unistd.h>
|
||||||
|
//#define GetCurrentDir getcwd
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
char* getCurDir()
|
||||||
|
{
|
||||||
|
char* cCurrentPath;
|
||||||
|
cCurrentPath=new char[FILENAME_MAX];
|
||||||
|
int test=sizeof(cCurrentPath);
|
||||||
|
if (!GetCurrentDir(cCurrentPath, FILENAME_MAX))
|
||||||
|
{
|
||||||
|
return "ERROR";
|
||||||
|
}
|
||||||
|
cCurrentPath[FILENAME_MAX - 1] = '\0';
|
||||||
|
return cCurrentPath;
|
||||||
|
}
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
srand((unsigned int)time(0));
|
||||||
|
::Oyster::Game::MoveAble::setDiscreteTimeSlice( GAME_UPDATEDELAY );
|
||||||
|
|
||||||
|
SocketServer server;
|
||||||
|
server.loadMapList("..\\Content\\Maplist.txt");
|
||||||
|
while (!server.isReady());
|
||||||
|
server.startThreads();
|
||||||
|
GameLogic::Object::init("NOT_IMPLEMENTED");
|
||||||
|
server.startGameCreateLoop(50);
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
server.updateServers();
|
||||||
|
}
|
||||||
|
server.closeConnection();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include "SocketServer.h"
|
||||||
|
bool SocketServer::initTCPSocket()
|
||||||
|
{
|
||||||
|
//----------------------
|
||||||
|
// Create a SOCKET for listening for incoming connection requests.
|
||||||
|
TCPSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if (TCPSocket == INVALID_SOCKET) {
|
||||||
|
wprintf(L"TCP socket function failed with error: %ld\n", WSAGetLastError());
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
iResult = bind(TCPSocket, (SOCKADDR *) & TCPRecvAddr, addrSize);
|
||||||
|
if (iResult == SOCKET_ERROR) {
|
||||||
|
wprintf(L"TCP bind function failed with error %d\n", WSAGetLastError());
|
||||||
|
iResult = closesocket(TCPSocket);
|
||||||
|
if (iResult == SOCKET_ERROR)
|
||||||
|
wprintf(L"TCP closesocket function failed with error %d\n", WSAGetLastError());
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
DWORD SocketServer::activateTCPConnectLoop(ThreadArguments* tra)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
(tra->ptr)->receiveConnection(tra->threadID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SocketServer::receiveConnection(int threadID)
|
||||||
|
{
|
||||||
|
User tmp;
|
||||||
|
//----------------------
|
||||||
|
// Listen for incoming connection requests
|
||||||
|
// on the created socket
|
||||||
|
if (listen(TCPSocket, SOMAXCONN) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
wprintf(L"listen function failed with error: %d\n", WSAGetLastError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Starting TCP connection loop.\n");
|
||||||
|
int a=0;
|
||||||
|
while(a==0)
|
||||||
|
{
|
||||||
|
a=1;
|
||||||
|
tmp.connection=accept(TCPSocket, (struct sockaddr*)&TCPRecvAddr, &addrSize);
|
||||||
|
printf("Accepted a TCP connection from IP %s.\n", inet_ntoa(TCPRecvAddr.sin_addr));
|
||||||
|
tcpData[threadID].dataSize=recv(
|
||||||
|
tmp.connection,
|
||||||
|
tcpData[threadID].buffer,
|
||||||
|
tcpData[threadID].bufLen,
|
||||||
|
0);
|
||||||
|
connData[threadID].buffer[connData[threadID].dataSize]='\0';
|
||||||
|
tmp.setUsername(tcpData[threadID].buffer);
|
||||||
|
if (tcpData[threadID].dataSize == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
wprintf(L"TCP recv failed with error %d\n", WSAGetLastError());
|
||||||
|
}
|
||||||
|
printf("TCP Thread #%d received connData from %s\n", threadID, inet_ntoa(tcpData[threadID].srcAddr.sin_addr));
|
||||||
|
//connData[threadID].buffer[connData[threadID].dataSize]='\0';
|
||||||
|
//AddUser(&tcpData[threadID]);
|
||||||
|
//parseReceivedData(threadID);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include "ServerTimer.h"
|
||||||
|
ServerTimer::ServerTimer()
|
||||||
|
:
|
||||||
|
c_SecondsPerCount(0.0),
|
||||||
|
c_DeltaTime(-1.0),
|
||||||
|
c_BaseTime(0),
|
||||||
|
c_PausedTime(0),
|
||||||
|
c_PrevTime(0),
|
||||||
|
c_CurrTime(0),
|
||||||
|
c_Stopped(false)
|
||||||
|
{
|
||||||
|
__int64 countsPerSec;
|
||||||
|
QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
|
||||||
|
c_SecondsPerCount =1.0 / (double)countsPerSec;
|
||||||
|
|
||||||
|
QueryPerformanceCounter((LARGE_INTEGER*)&c_PrevTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerTimer::start()
|
||||||
|
{
|
||||||
|
__int64 p_StartTime;
|
||||||
|
QueryPerformanceCounter((LARGE_INTEGER*)&p_StartTime);
|
||||||
|
if(c_Stopped)
|
||||||
|
{
|
||||||
|
c_PausedTime += (p_StartTime-c_StopTime);
|
||||||
|
c_PrevTime = p_StartTime;
|
||||||
|
c_StopTime = 0;
|
||||||
|
c_Stopped = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__int64 ServerTimer::getTime()
|
||||||
|
{
|
||||||
|
__int64 testInt;
|
||||||
|
return QueryPerformanceCounter((LARGE_INTEGER*)&testInt);
|
||||||
|
return testInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerTimer::stop()
|
||||||
|
{
|
||||||
|
if(!c_Stopped)
|
||||||
|
{
|
||||||
|
__int64 p_CurrTime;
|
||||||
|
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
|
||||||
|
c_StopTime = p_CurrTime;
|
||||||
|
c_Stopped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ServerTimer::reset()
|
||||||
|
{
|
||||||
|
__int64 p_CurrTime;
|
||||||
|
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
|
||||||
|
c_BaseTime = p_CurrTime;
|
||||||
|
c_PrevTime = p_CurrTime;
|
||||||
|
c_StopTime = 0;
|
||||||
|
c_Stopped = false;
|
||||||
|
}
|
||||||
|
void ServerTimer::tick()
|
||||||
|
{
|
||||||
|
if (c_Stopped)
|
||||||
|
{
|
||||||
|
c_DeltaTime= 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__int64 p_CurrTime;
|
||||||
|
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
|
||||||
|
c_CurrTime=p_CurrTime;
|
||||||
|
|
||||||
|
c_DeltaTime=(c_CurrTime-c_PrevTime)*c_SecondsPerCount;
|
||||||
|
c_PrevTime=c_CurrTime;
|
||||||
|
if(c_DeltaTime<0.0) c_DeltaTime=0.0;
|
||||||
|
}
|
||||||
|
float ServerTimer::getGameTime() const
|
||||||
|
{
|
||||||
|
if(c_Stopped)
|
||||||
|
{
|
||||||
|
return (float)((c_StopTime-c_BaseTime)*c_SecondsPerCount);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return (float)(((c_CurrTime-c_PausedTime)-c_BaseTime)*c_SecondsPerCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float ServerTimer::getDeltaTime() const
|
||||||
|
{
|
||||||
|
return (float)c_DeltaTime;
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include "ServerInclude.h"
|
||||||
|
#ifndef _GAME_TIMER_H
|
||||||
|
#define _GAME_TIMER_H
|
||||||
|
class ServerTimer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double c_SecondsPerCount;
|
||||||
|
double c_DeltaTime;
|
||||||
|
__int64 c_BaseTime;
|
||||||
|
__int64 c_PausedTime;
|
||||||
|
__int64 c_StopTime;
|
||||||
|
__int64 c_PrevTime;
|
||||||
|
__int64 c_CurrTime;
|
||||||
|
bool c_Stopped;
|
||||||
|
public:
|
||||||
|
ServerTimer();
|
||||||
|
__int64 getTime();
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
void reset();
|
||||||
|
void tick();
|
||||||
|
float getGameTime() const;
|
||||||
|
float getDeltaTime() const;
|
||||||
|
};
|
||||||
|
#endif
|
|
@ -0,0 +1,55 @@
|
||||||
|
#include "SocketServer.h"
|
||||||
|
bool SocketServer::initUDPSocket()
|
||||||
|
{
|
||||||
|
//---------------------------------------------
|
||||||
|
// Create a socket for sending data
|
||||||
|
UDPSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
if (UDPSocket == INVALID_SOCKET) {
|
||||||
|
wprintf(L"UDP socket failed with error: %ld\n", WSAGetLastError());
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//---------------------------------------------
|
||||||
|
// Bind socket to IP
|
||||||
|
iResult = bind(UDPSocket, (SOCKADDR *) & UDPRecvAddr, addrSize);
|
||||||
|
if (iResult == SOCKET_ERROR) {
|
||||||
|
wprintf(L"UDP bind failed with error: %d\n", WSAGetLastError());
|
||||||
|
closesocket(UDPSocket);
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
DWORD SocketServer::activateUDPReceiveLoop(ThreadArguments* tra)
|
||||||
|
{
|
||||||
|
(tra->ptr)->serverUDPReceiveLoopActive=true;//weird crash //PAR
|
||||||
|
(tra->ptr)->receiveDataUDP(tra->threadID);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void SocketServer::stopUDPReceiveLoops()
|
||||||
|
{
|
||||||
|
serverUDPReceiveLoopActive=false;
|
||||||
|
WaitForMultipleObjects(NR_CONNECTTHREADS, udpDataHandle, true, INFINITE);
|
||||||
|
printf("All UDP data recv threads stopped.\n");
|
||||||
|
}
|
||||||
|
void SocketServer::receiveDataUDP(int threadID)
|
||||||
|
{
|
||||||
|
while(serverUDPReceiveLoopActive)
|
||||||
|
{
|
||||||
|
connData[threadID].dataSize=recvfrom(
|
||||||
|
UDPSocket,
|
||||||
|
connData[threadID].buffer,
|
||||||
|
connData[threadID].bufLen,
|
||||||
|
0,
|
||||||
|
(SOCKADDR *)&connData[threadID].srcAddr,
|
||||||
|
&addrSize);
|
||||||
|
if (connData[threadID].dataSize == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
|
||||||
|
}
|
||||||
|
//printf("Thread #%d received data from %s\n", threadID, inet_ntoa(connData[threadID].srcAddr.sin_addr));
|
||||||
|
//connData[threadID].buffer[connData[threadID].dataSize]='\0';
|
||||||
|
else
|
||||||
|
parseReceivedData(threadID);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,420 @@
|
||||||
|
#include "SocketServer.h"
|
||||||
|
#include <fstream>
|
||||||
|
bool SocketServer::loadMapList(char* maploc)
|
||||||
|
{
|
||||||
|
::std::string workDir;
|
||||||
|
::Utility::String::extractDirPath( workDir, maploc, '\\' );
|
||||||
|
|
||||||
|
//maploc is the filename of the list which contains all maps
|
||||||
|
//load all map file names into the server, but don't load the maps themselves.
|
||||||
|
std::ifstream file;
|
||||||
|
file.open(maploc);
|
||||||
|
if (!file.is_open())
|
||||||
|
return false;
|
||||||
|
::std::string str;
|
||||||
|
while(!file.eof())
|
||||||
|
{
|
||||||
|
::std::getline( file, str );
|
||||||
|
maps.push_back( workDir + str );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
maps.push_back("map1test.map");
|
||||||
|
maps.push_back("map2 test.map");
|
||||||
|
*/
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool SocketServer::LoadInitData(char* maploc)
|
||||||
|
{
|
||||||
|
std::vector<std::string> cont;
|
||||||
|
char* in=new char[100];
|
||||||
|
std::ifstream ifs;
|
||||||
|
ifs.open(maploc);
|
||||||
|
if(!ifs.is_open())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while(!ifs.eof())
|
||||||
|
{
|
||||||
|
ifs.getline(in, 100);
|
||||||
|
cont=splitString(in, '=');
|
||||||
|
if (cont.size()==2)
|
||||||
|
{
|
||||||
|
if(!strcmp("nr_players_per_session", cont[0].c_str()))
|
||||||
|
{
|
||||||
|
playersPerSessionCount=atoi(cont[1].c_str());
|
||||||
|
}
|
||||||
|
else if(!strcmp("nr_kills_to_win", cont[0].c_str()))
|
||||||
|
{
|
||||||
|
killsRequiredPerSession=atoi(cont[1].c_str());
|
||||||
|
}
|
||||||
|
else if(!strcmp("match_type", cont[0].c_str()))
|
||||||
|
{
|
||||||
|
//Isn't used
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
ifs.close();
|
||||||
|
}
|
||||||
|
SocketServer::~SocketServer()
|
||||||
|
{
|
||||||
|
serverTCPConnectionLoopActive=false;
|
||||||
|
serverUDPReceiveLoopActive=false;
|
||||||
|
serverTCPReceiveLoopActive=false;
|
||||||
|
for (int i=0; i<NR_CONNECTTHREADS; i++)
|
||||||
|
{
|
||||||
|
delete connData[i].buffer;
|
||||||
|
}
|
||||||
|
for (int i=0; i<NR_SIMULTCPCONNECTS; i++)
|
||||||
|
{
|
||||||
|
delete tcpData[i].buffer;
|
||||||
|
}
|
||||||
|
delete sendGameDataBuffer;
|
||||||
|
delete sendEffectDataBuffer;
|
||||||
|
closeConnection();
|
||||||
|
}
|
||||||
|
void SocketServer::startGameCreateLoop(int delay)
|
||||||
|
{
|
||||||
|
lobbyActive=false;
|
||||||
|
DEBUGCTR=0;
|
||||||
|
if(!serverGameCreationActive)
|
||||||
|
{
|
||||||
|
ThreadArguments tr;
|
||||||
|
tr.ptr=this;
|
||||||
|
tr.threadID=delay;
|
||||||
|
serverGameCreationActive=true;
|
||||||
|
gameCreateHandle=CreateThread(
|
||||||
|
NULL, //Choose default security
|
||||||
|
0, //Default stack size
|
||||||
|
(LPTHREAD_START_ROUTINE)&activateServerGameLoop,
|
||||||
|
//Routine to execute
|
||||||
|
(LPVOID) &tr, //Thread parameter
|
||||||
|
0, //Immediately run the thread
|
||||||
|
0 //Thread Id
|
||||||
|
);
|
||||||
|
if (gameCreateHandle == NULL)
|
||||||
|
{
|
||||||
|
printf("Game creation thread ERROR");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Game creation thread successful\n");
|
||||||
|
Sleep(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SocketServer::stopGameCreateLoop()
|
||||||
|
{
|
||||||
|
serverGameCreationActive=false;
|
||||||
|
WaitForSingleObject(gameCreateHandle, INFINITE);
|
||||||
|
printf("Game Creation thread ended.\n");
|
||||||
|
}
|
||||||
|
DWORD SocketServer::activateServerGameLoop(ThreadArguments* tra)
|
||||||
|
{
|
||||||
|
srand((unsigned int)(time(0)));
|
||||||
|
(tra->ptr)->serverGameCreationLoop(tra->threadID);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bool SocketServer::serverGameCreationLoop(int delay)
|
||||||
|
{ // TODO: Mem access Violoation Crash 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ... delay = -858993460
|
||||||
|
//Mem access violation in a thread can also be caused by failure from something else instead of it,
|
||||||
|
//it still breaks at header even if, for example, server->load or lobby.startLobbyCountdown breaks it
|
||||||
|
//If you get an error here, make sure that isn't the problem.
|
||||||
|
int count;
|
||||||
|
while(serverGameCreationActive)
|
||||||
|
{
|
||||||
|
if (nrActiveSessions==0)
|
||||||
|
{
|
||||||
|
count=0;
|
||||||
|
for (unsigned int i=0; i<users.size(); i++)
|
||||||
|
{
|
||||||
|
if (users[i].getState()==ONLINE_QUEUEING)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count>=playersPerSessionCount)
|
||||||
|
{
|
||||||
|
games.resize(1);
|
||||||
|
//lobby.resize(games.size()+1);
|
||||||
|
session =new GameLogic::Session();
|
||||||
|
lobby = Lobby();
|
||||||
|
timer.resize(1);
|
||||||
|
timeTillUpdate.resize(1);
|
||||||
|
timeTillUpdate[0]=GAME_UPDATEDELAY;
|
||||||
|
updateCount.resize(1);
|
||||||
|
updateCount[0]=0;
|
||||||
|
int curID=(int)games.size()-1;
|
||||||
|
int mapid=rand()%maps.size();
|
||||||
|
session->setNrPlayers(playersPerSessionCount);
|
||||||
|
session->setKillsRequired(killsRequiredPerSession);
|
||||||
|
session->load(maps[mapid]);
|
||||||
|
printf("Map nr %d loaded, name %s.\n",mapid, maps[mapid].c_str());
|
||||||
|
count=0;
|
||||||
|
for (unsigned int i=0; count<playersPerSessionCount && i<users.size(); i++)
|
||||||
|
{
|
||||||
|
if (users[i].getState()==ONLINE_QUEUEING)
|
||||||
|
{
|
||||||
|
//Set to INLOBBY and send lobby data, then start a lobby
|
||||||
|
lobby.addUser(users[i], i);
|
||||||
|
users[i].setState(ONLINE_INGAME);
|
||||||
|
games[curID].addUser(i);
|
||||||
|
users[i].setGame(curID);
|
||||||
|
session->accessPlayer(i).spawn();
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lobbyActive=true;
|
||||||
|
sendLobbyInitData(curID);
|
||||||
|
lobby.startLobbyCountdown(LOBBY_WAIT_TIME);
|
||||||
|
sendRenderData(curID);
|
||||||
|
//return true;
|
||||||
|
}
|
||||||
|
if(lobbyActive)
|
||||||
|
{
|
||||||
|
for (int i=0; i<1; i++)
|
||||||
|
{
|
||||||
|
float ttimer=lobby.timeLeft();
|
||||||
|
if (ttimer==0)
|
||||||
|
{
|
||||||
|
printf("Starting game.\n");
|
||||||
|
games[i].initGame(users,playersPerSessionCount);
|
||||||
|
sendInitData(i);
|
||||||
|
nrActiveSessions++;
|
||||||
|
lobbyActive=false;
|
||||||
|
//serverGameCreationActive=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sleep(delay);
|
||||||
|
}
|
||||||
|
printf("Maximum server count reached, shutting down the sever creation thread.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SocketServer::SocketServer()
|
||||||
|
{
|
||||||
|
UDPSocket = INVALID_SOCKET;
|
||||||
|
nrActiveSessions=0;
|
||||||
|
serverGameCreationActive=false;
|
||||||
|
serverTCPConnectionLoopActive=false;
|
||||||
|
serverTCPReceiveLoopActive=false;
|
||||||
|
serverUDPReceiveLoopActive=false;
|
||||||
|
killsRequiredPerSession=10;
|
||||||
|
playersPerSessionCount=1;
|
||||||
|
LoadInitData("../ServerData.dat");
|
||||||
|
//---------------------------------------------
|
||||||
|
// Set up the port and IP of the server
|
||||||
|
//Port starts up as a different one from when UDPSocketected, it changes once the server has exchanged some info with the client
|
||||||
|
UDPRecvAddr.sin_family = AF_INET;
|
||||||
|
UDPRecvAddr.sin_port = htons(UDPRecvPort);
|
||||||
|
UDPRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
|
||||||
|
sessionEvents=std::vector<Event::GameEvent*>(0);
|
||||||
|
sessionEffects=std::vector<Network::EffectData>(0);
|
||||||
|
TCPRecvAddr.sin_family = AF_INET;
|
||||||
|
TCPRecvAddr.sin_port = htons(TCPRecvPort);
|
||||||
|
TCPRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
|
||||||
|
addrSize=sizeof(sockaddr_in);
|
||||||
|
for (int i=0; i<NR_CONNECTTHREADS; i++)
|
||||||
|
{
|
||||||
|
connData[i].buffer=new char[256];
|
||||||
|
connData[i].bufLen=256;
|
||||||
|
ZeroMemory(connData[i].buffer,sizeof(connData[i].buffer));
|
||||||
|
connData[i].dataSize=0;
|
||||||
|
//connData[i].srcAddr
|
||||||
|
memcpy(&connData[i].srcAddr, &UDPRecvAddr,addrSize);
|
||||||
|
}
|
||||||
|
for (int i=0; i<NR_SIMULTCPCONNECTS; i++)
|
||||||
|
{
|
||||||
|
tcpData[i].buffer=new char[256];
|
||||||
|
tcpData[i].bufLen=256;
|
||||||
|
ZeroMemory(tcpData[i].buffer,sizeof(tcpData[i].buffer));
|
||||||
|
tcpData[i].dataSize=0;
|
||||||
|
memcpy(&connData[i].srcAddr, &TCPRecvAddr,addrSize);
|
||||||
|
}
|
||||||
|
sendGameDataBufferSize=SERVER_PLAYER_DATA_SIZE*playersPerSessionCount+1;
|
||||||
|
sendGameDataBuffer=new char[sendGameDataBufferSize];
|
||||||
|
sendGameDataBuffer[0]=1;
|
||||||
|
sendEffectDataBuffer=new char[sizeof(Network::EffectData)+1];
|
||||||
|
sendEffectDataBuffer[0]=7;
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
// Initialize Winsock
|
||||||
|
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||||
|
if (iResult != NO_ERROR) {
|
||||||
|
wprintf(L"WSAStartup failed with error: %d\n", iResult);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Init sockets
|
||||||
|
setupStatus=initTCPSocket();
|
||||||
|
if(setupStatus)
|
||||||
|
setupStatus=initUDPSocket();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool SocketServer::startThreads()
|
||||||
|
{
|
||||||
|
//ThreadArguments tra1[NR_SIMULTCPCONNECTS];
|
||||||
|
ThreadArguments tra2[NR_CONNECTTHREADS];
|
||||||
|
//for (int i=0; i< NR_SIMULTCPCONNECTS; i++)
|
||||||
|
//{
|
||||||
|
// tra1[i].ptr=this;
|
||||||
|
// tra1[i].threadID=i;
|
||||||
|
// //printf("i - %d\n",i);
|
||||||
|
//
|
||||||
|
// tcpDataHandle[i]=CreateThread(
|
||||||
|
// NULL, //Choose default security
|
||||||
|
// 0, //Default stack size
|
||||||
|
// (LPTHREAD_START_ROUTINE)&activateTCPConnectLoop,
|
||||||
|
// //Routine to execute
|
||||||
|
// (LPVOID) &tra1[i], //Thread parameter
|
||||||
|
// 0, //Immediately run the thread
|
||||||
|
// 0 //Thread Id
|
||||||
|
// );
|
||||||
|
// if (tcpDataHandle[i] == NULL)
|
||||||
|
// {
|
||||||
|
// printf("Error Creating TCP Thread#: %d\n",i);
|
||||||
|
// return(false);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// printf("Successfully created TCP thread #: %d\n", i);
|
||||||
|
// Sleep(100);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
for (int i=0; i< NR_CONNECTTHREADS; i++)
|
||||||
|
{
|
||||||
|
tra2[i].ptr=this;
|
||||||
|
tra2[i].threadID=i;
|
||||||
|
//printf("i - %d\n",i);
|
||||||
|
udpDataHandle[i]=CreateThread(
|
||||||
|
NULL, //Choose default security
|
||||||
|
0, //Default stack size
|
||||||
|
(LPTHREAD_START_ROUTINE)&activateUDPReceiveLoop,
|
||||||
|
//Routine to execute
|
||||||
|
(LPVOID) &tra2[i], //Thread parameter
|
||||||
|
0, //Immediately run the thread
|
||||||
|
0 //Thread Id
|
||||||
|
);
|
||||||
|
if (udpDataHandle[i] == NULL)
|
||||||
|
{
|
||||||
|
printf("Error Creating UDP Thread#: %d\n",i);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Successfully created UDP thread #: %d\n", i);
|
||||||
|
Sleep(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool SocketServer::sendData(int uid, const char* data, int size)
|
||||||
|
{
|
||||||
|
//---------------------------------------------
|
||||||
|
// Send a datagram to a user
|
||||||
|
//uid -1 = broadcast message
|
||||||
|
if (uid<0)
|
||||||
|
{
|
||||||
|
for (unsigned int i=0; i<users.size(); i++)
|
||||||
|
{
|
||||||
|
iResult = sendto(UDPSocket, data, size, 0, (SOCKADDR *) & users[i].getAddr(), addrSize);
|
||||||
|
if (iResult == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
wprintf(L"UDP sendData(-1) sendto failed with error: %d\n", WSAGetLastError());
|
||||||
|
closesocket(UDPSocket);
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if((unsigned)uid>=users.size())
|
||||||
|
{
|
||||||
|
//User doesn't exist
|
||||||
|
printf("UDP sendData(%d) sendto failed because the specified user does not exist\n", uid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iResult = sendto(UDPSocket, data, size, 0, (SOCKADDR *) & users[uid].getAddr(), addrSize);
|
||||||
|
if (iResult == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
wprintf(L"UDP sendData(%d) sendto failed with error: %d\n", uid, WSAGetLastError());
|
||||||
|
closesocket(UDPSocket);
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool SocketServer::sendKeyFrameData(int size, const char* data)
|
||||||
|
{
|
||||||
|
for (int i=0; i<playersPerSessionCount; i++)
|
||||||
|
{
|
||||||
|
iResult = sendto(UDPSocket, data, size+1, 0, (SOCKADDR *) & users[games[0].getUserID(i)].getAddr(), addrSize);
|
||||||
|
if (iResult == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
wprintf(L"UDP keyFrameData sendto failed with error: %d\n", WSAGetLastError());
|
||||||
|
closesocket(UDPSocket);
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SocketServer::checkConnection(int userID)
|
||||||
|
{
|
||||||
|
char* message="\3testmessage";
|
||||||
|
int count=
|
||||||
|
sendto(
|
||||||
|
UDPSocket,
|
||||||
|
message,
|
||||||
|
(int)strlen(message),
|
||||||
|
0,
|
||||||
|
(SOCKADDR *) & users[userID].getAddr(),
|
||||||
|
addrSize);
|
||||||
|
|
||||||
|
if (count == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (count==0)
|
||||||
|
{
|
||||||
|
wprintf(L"Disconnected.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SocketServer::closeConnection()
|
||||||
|
{
|
||||||
|
//---------------------------------------------
|
||||||
|
// When the application is finished sending, close the sockets.
|
||||||
|
setupStatus=false;
|
||||||
|
wprintf(L"Finished sending. Closing socket.\n");
|
||||||
|
iResult = closesocket(UDPSocket);
|
||||||
|
if (iResult == SOCKET_ERROR) {
|
||||||
|
wprintf(L"closeUDPsocket failed with error: %d\n", WSAGetLastError());
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iResult = closesocket(TCPSocket);
|
||||||
|
if (iResult == SOCKET_ERROR) {
|
||||||
|
wprintf(L"closeTCPsocket failed with error: %d\n", WSAGetLastError());
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//---------------------------------------------
|
||||||
|
// Clean up and quit.
|
||||||
|
wprintf(L"Exiting.\n");
|
||||||
|
WSACleanup();
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,255 @@
|
||||||
|
#include "SocketServer.h"
|
||||||
|
|
||||||
|
/*// BENCHMARK BLOCK
|
||||||
|
#include "WinTimer.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
namespace Benchmark
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
double averageTime, totalTime, minTime, maxTime; unsigned int numSamples;
|
||||||
|
} timerData[10] = { 0.0f, 0.0f, ::std::numeric_limits<double>::max(), -::std::numeric_limits<double>::max(), 0 };
|
||||||
|
|
||||||
|
void sampleTime( const ::Utility::WinTimer &timer, unsigned char ref )
|
||||||
|
{
|
||||||
|
double elapsedTime = timer.getElapsedSeconds();
|
||||||
|
timerData[ref].totalTime += elapsedTime;
|
||||||
|
timerData[ref].minTime = ::Utility::Value::min( timerData[ref].minTime, elapsedTime );
|
||||||
|
timerData[ref].maxTime = ::Utility::Value::max( timerData[ref].maxTime, elapsedTime );
|
||||||
|
++timerData[ref].numSamples;
|
||||||
|
timerData[ref].averageTime = timerData[ref].totalTime / (double) timerData[ref].numSamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print( )
|
||||||
|
{
|
||||||
|
::std::ofstream file;
|
||||||
|
file.open( "BenchMarkData.txt", ::std::ios_base::app | ::std::ios_base::out );
|
||||||
|
|
||||||
|
if( file.is_open() )
|
||||||
|
{
|
||||||
|
file << "minTime\t\t: maxTime\t: averageTime\t\ttotalTime\tnumSamples\n";
|
||||||
|
for( unsigned char i = 0; i < 1; ++i )
|
||||||
|
file << timerData[i].minTime << (timerData[i].minTime == 0.0f ? "\t\t: " : "\t: ") << timerData[i].maxTime << "\t: " << timerData[i].averageTime << "\t\t" << timerData[i].totalTime << '\t' << timerData[i].numSamples <<'\n';
|
||||||
|
file << ::std::endl;
|
||||||
|
file.close();
|
||||||
|
::std::cout << "Benchmark data saved." << ::std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// END BENCHMARK BLOCK/**/
|
||||||
|
|
||||||
|
void SocketServer::updateServers()
|
||||||
|
{
|
||||||
|
for(int i=0; i<nrActiveSessions; i++)
|
||||||
|
{
|
||||||
|
if(games[i].allReady())
|
||||||
|
{
|
||||||
|
timer[i].tick();
|
||||||
|
//printf("%f seconds since last update\n", timer[i].getDeltaTime());
|
||||||
|
//printf("%f seconds since the timer started\n", timer[i].getGameTime());
|
||||||
|
|
||||||
|
//timeTillUpdate[i]-=timer[i].getDeltaTime();
|
||||||
|
|
||||||
|
DEBUGCTR++;
|
||||||
|
//Sleep(timeTillUpdate[i]*1000);
|
||||||
|
|
||||||
|
// BENCHMARK BLOCK
|
||||||
|
//::Utility::WinTimer processTimer;
|
||||||
|
// END BENCHMARK BLOCK
|
||||||
|
|
||||||
|
switch( session->update( timer[i].getDeltaTime() ) )
|
||||||
|
{
|
||||||
|
case ::GameLogic::Session::Updated:
|
||||||
|
// BENCHMARK BLOCK
|
||||||
|
//processTimer.reset();
|
||||||
|
// END BENCHMARK BLOCK
|
||||||
|
|
||||||
|
processSessionPlayerData(i);
|
||||||
|
processAllSessionEvents(i);
|
||||||
|
processAllSessionEffects(i);
|
||||||
|
|
||||||
|
// BENCHMARK BLOCK
|
||||||
|
//Benchmark::sampleTime( processTimer, 0 );
|
||||||
|
// END BENCHMARK BLOCK
|
||||||
|
|
||||||
|
DEBUGCTR=0;
|
||||||
|
updateCount[i]++;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case ::GameLogic::Session::Over:
|
||||||
|
processAllSessionEvents(i);
|
||||||
|
nrActiveSessions=0;
|
||||||
|
if(users.size()==0)
|
||||||
|
{
|
||||||
|
printf("Game with id %d done, shutting down the game.\n", 0);
|
||||||
|
Sleep(10);
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BENCHMARK BLOCK
|
||||||
|
//if( Benchmark::timerData[0].numSamples % 1000 == 1 )
|
||||||
|
// Benchmark::print();
|
||||||
|
// END BENCHMARK BLOCK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(nrActiveSessions==0)
|
||||||
|
{
|
||||||
|
Sleep(50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SocketServer::processSessionPlayerData(int serverID)
|
||||||
|
{
|
||||||
|
sendGameDataStruct.updateCount=updateCount[serverID];
|
||||||
|
int offset=1;
|
||||||
|
for (int i=0; i<playersPerSessionCount/*games[serverID].getPlayerCount()*/; i++)
|
||||||
|
{
|
||||||
|
sendGameDataStruct.position=session->accessPlayer(i).getOrientation();
|
||||||
|
sendGameDataStruct.hp=session->accessPlayer(i).getHullPoints();
|
||||||
|
sendGameDataStruct.shield=session->accessPlayer(i).getShieldPoints();
|
||||||
|
sendGameDataStruct.dirVecLen=session->accessPlayer(i).getMovement().length();
|
||||||
|
sendGameDataStruct.pid=i;
|
||||||
|
memcpy(sendGameDataBuffer+offset, &sendGameDataStruct, SERVER_PLAYER_DATA_SIZE);
|
||||||
|
offset+=SERVER_PLAYER_DATA_SIZE;
|
||||||
|
}
|
||||||
|
sendData(-1,sendGameDataBuffer, sendGameDataBufferSize);
|
||||||
|
}
|
||||||
|
void SocketServer::processAllSessionEvents(int serverID)
|
||||||
|
{
|
||||||
|
session->fetchEvents(sessionEvents);
|
||||||
|
for (int i=0; i<(int)sessionEvents.size(); i++)
|
||||||
|
{
|
||||||
|
sendEventData(serverID, i);
|
||||||
|
delete sessionEvents[i];
|
||||||
|
}
|
||||||
|
sessionEvents.resize(0);
|
||||||
|
}
|
||||||
|
bool SocketServer::sendGameData(int serverID)
|
||||||
|
{
|
||||||
|
//data[0]=1;
|
||||||
|
for (int i=0; i<games[serverID].getPlayerCount(); i++)
|
||||||
|
{
|
||||||
|
iResult = sendto(UDPSocket, sendGameDataBuffer, SERVER_PLAYER_DATA_SIZE+1, 0, (SOCKADDR *) & users[games[serverID].getUserID(i)].getAddr(), addrSize);
|
||||||
|
if (iResult == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
wprintf(L"UDP gameData sendto failed with error: %d\n", WSAGetLastError());
|
||||||
|
closesocket(UDPSocket);
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void SocketServer::sendEventData(int gid, int sid)
|
||||||
|
{
|
||||||
|
int size=sessionEvents[sid]->GetSize();
|
||||||
|
int size1=sizeof(Event::BulletCreated);
|
||||||
|
int tst=sizeof(Event::Type);
|
||||||
|
char* ed=new char[size+1+tst];
|
||||||
|
ed[0]=6;
|
||||||
|
sessionEvents[sid]->SaveRawData(ed+(1+tst));
|
||||||
|
|
||||||
|
Event::Type eTest=Event::getEventType(sessionEvents[sid]);
|
||||||
|
memcpy(ed+1, &eTest, sizeof(Event::Type));
|
||||||
|
|
||||||
|
sendData(-1, ed, size+1+tst);
|
||||||
|
delete ed;
|
||||||
|
}
|
||||||
|
void SocketServer::sendRenderData(int gid)
|
||||||
|
{
|
||||||
|
Protocol::RenderData data;
|
||||||
|
session->writeToRenderResourceData(data);
|
||||||
|
int size=data.getRequiredBufferSize()+1;
|
||||||
|
char* sendChar=new char[size];
|
||||||
|
data.fillBuffer(sendChar+1);
|
||||||
|
sendChar[0]=8;
|
||||||
|
sendData(-1, sendChar, size);
|
||||||
|
delete sendChar;
|
||||||
|
}
|
||||||
|
void SocketServer::processAllSessionEffects(int gid)
|
||||||
|
{
|
||||||
|
session->fetchEffectData(sessionEffects);
|
||||||
|
|
||||||
|
if (sessionEffects.size()>0)
|
||||||
|
{
|
||||||
|
int size=(int)sessionEffects.size()*sizeof(Network::EffectData) + 1;
|
||||||
|
delete sendEffectDataBuffer;
|
||||||
|
sendEffectDataBuffer=new char[size];
|
||||||
|
for (size_t i=0; i<sessionEffects.size(); i++)
|
||||||
|
{
|
||||||
|
memcpy(sendEffectDataBuffer+1+sizeof(Network::EffectData)*i, &sessionEffects[i], sizeof(Network::EffectData));
|
||||||
|
//sessionEffects.
|
||||||
|
}
|
||||||
|
sendEffectDataBuffer[0]=7;
|
||||||
|
sendData(-1, sendEffectDataBuffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//HACK PLAYER UPDATE
|
||||||
|
void ControlPlayer( GameLogic::Player& p,const ClientToServerUpdateData &update)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(update.braking)
|
||||||
|
p.enableMovementReduction( true );
|
||||||
|
else
|
||||||
|
p.disableMovementReduction();
|
||||||
|
p.enableRotationReduction( true );
|
||||||
|
|
||||||
|
if(update.forward>0)
|
||||||
|
p.thrustForward();
|
||||||
|
if(update.forward<0)
|
||||||
|
p.thrustBackward();
|
||||||
|
|
||||||
|
if(update.straferight>0)
|
||||||
|
p.strafeRight();
|
||||||
|
if(update.straferight<0)
|
||||||
|
p.strafeLeft();
|
||||||
|
|
||||||
|
if(update.strafeup>0)
|
||||||
|
p.climb();
|
||||||
|
if(update.strafeup<0)
|
||||||
|
p.dive();
|
||||||
|
|
||||||
|
if(update.roll>0)
|
||||||
|
{
|
||||||
|
::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.roll;
|
||||||
|
p.rotationProperty.acceleration.roll /= ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
|
||||||
|
|
||||||
|
p.rollLeft();
|
||||||
|
p.rotationProperty.acceleration.roll = baseAcceleration;
|
||||||
|
}
|
||||||
|
if(update.roll<0)
|
||||||
|
{
|
||||||
|
::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.roll;
|
||||||
|
p.rotationProperty.acceleration.roll /= ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
|
||||||
|
p.rollRight();
|
||||||
|
p.rotationProperty.acceleration.roll = baseAcceleration;
|
||||||
|
}
|
||||||
|
if(update.roll==0)
|
||||||
|
{
|
||||||
|
p.stopRotation();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(update.TurnVer!=0.0f)
|
||||||
|
{
|
||||||
|
::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.pitch;
|
||||||
|
p.rotationProperty.acceleration.pitch *= -update.TurnVer / ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
|
||||||
|
p.pitchUp( );
|
||||||
|
p.disableRotationReduction();
|
||||||
|
p.rotationProperty.acceleration.pitch = baseAcceleration;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(update.TurnHor!=0.0f)
|
||||||
|
{
|
||||||
|
::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.yaw;
|
||||||
|
p.rotationProperty.acceleration.yaw *= -update.TurnHor / ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
|
||||||
|
p.yawLeft( );
|
||||||
|
p.disableRotationReduction();
|
||||||
|
p.rotationProperty.acceleration.yaw = baseAcceleration;
|
||||||
|
}
|
||||||
|
if(update.firePrim)
|
||||||
|
p.firePrimaryWeapon();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
#include "Game.h"
|
||||||
|
#include "Lobby.h"
|
||||||
|
void ControlPlayer( GameLogic::Player& p,const ClientToServerUpdateData &update);
|
||||||
|
const int NR_CONNECTTHREADS=1;
|
||||||
|
const int NR_SIMULTCPCONNECTS=1;
|
||||||
|
//threads can only take 1 argument
|
||||||
|
struct ThreadArguments;
|
||||||
|
struct ConnThreadData
|
||||||
|
{
|
||||||
|
sockaddr_in srcAddr;
|
||||||
|
|
||||||
|
ClientToServerUpdateData tmpdata;
|
||||||
|
char* buffer;
|
||||||
|
int bufLen;
|
||||||
|
int dataSize;
|
||||||
|
};
|
||||||
|
// Link with ws2_32.lib
|
||||||
|
#pragma comment(lib, "Ws2_32.lib")
|
||||||
|
const short TCPSendPort = 11111;
|
||||||
|
const short TCPRecvPort = 11110;
|
||||||
|
const short UDPSendPort = 11001;
|
||||||
|
const short UDPRecvPort = 11000;
|
||||||
|
|
||||||
|
class SocketServer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool serverGameCreationActive;
|
||||||
|
HANDLE gameCreateHandle;
|
||||||
|
bool serverTCPConnectionLoopActive;
|
||||||
|
bool serverUDPReceiveLoopActive;
|
||||||
|
bool serverTCPReceiveLoopActive;
|
||||||
|
bool setupStatus;
|
||||||
|
int iResult;
|
||||||
|
WSADATA wsaData;
|
||||||
|
|
||||||
|
SOCKET UDPSocket;
|
||||||
|
SOCKET TCPSocket;
|
||||||
|
|
||||||
|
sockaddr_in TCPRecvAddr;
|
||||||
|
sockaddr_in UDPRecvAddr;
|
||||||
|
|
||||||
|
int addrSize;
|
||||||
|
|
||||||
|
HANDLE tcpDataHandle[NR_SIMULTCPCONNECTS];
|
||||||
|
ConnThreadData tcpData[NR_SIMULTCPCONNECTS];
|
||||||
|
|
||||||
|
HANDLE udpDataHandle[NR_CONNECTTHREADS];
|
||||||
|
ConnThreadData connData[NR_CONNECTTHREADS];
|
||||||
|
|
||||||
|
int dataSize;
|
||||||
|
|
||||||
|
|
||||||
|
char* sendEffectDataBuffer;
|
||||||
|
char* sendGameDataBuffer;
|
||||||
|
int sendGameDataBufferSize;
|
||||||
|
ServerToClientUpdateData sendGameDataStruct;
|
||||||
|
std::vector<User> users;
|
||||||
|
std::vector<Game> games;
|
||||||
|
Lobby lobby;
|
||||||
|
int nrActiveSessions;
|
||||||
|
std::vector<Event::GameEvent*> sessionEvents;
|
||||||
|
std::vector<Network::EffectData> sessionEffects;
|
||||||
|
GameLogic::Session* session;
|
||||||
|
std::vector<ServerTimer> timer;
|
||||||
|
int DEBUGCTR;
|
||||||
|
std::vector<long> updateCount;
|
||||||
|
std::vector<float> timeTillUpdate;
|
||||||
|
std::vector<::std::string> maps;
|
||||||
|
std::string text;
|
||||||
|
int playersPerSessionCount;
|
||||||
|
int killsRequiredPerSession;
|
||||||
|
bool lobbyActive;
|
||||||
|
public:
|
||||||
|
virtual ~SocketServer();
|
||||||
|
//Debug force modify functions
|
||||||
|
void processAllSessionEvents(int serverID);
|
||||||
|
void processAllSessionEffects(int gid);
|
||||||
|
void processSessionPlayerData(int serverID);
|
||||||
|
//End of debug items
|
||||||
|
void updateServers();
|
||||||
|
SocketServer();
|
||||||
|
bool checkConnection(int userID);
|
||||||
|
bool initUDPSocket();
|
||||||
|
bool initTCPSocket();
|
||||||
|
//void firstTimeConnect();
|
||||||
|
bool loadMapList(char* map);
|
||||||
|
bool serverGameCreationLoop(int delay);
|
||||||
|
bool startThreads();
|
||||||
|
static DWORD activateUDPReceiveLoop(ThreadArguments* tra);
|
||||||
|
void stopUDPReceiveLoops();
|
||||||
|
//TCP functions
|
||||||
|
static DWORD activateTCPConnectLoop(ThreadArguments* tra);
|
||||||
|
void receiveConnection(int threadID);
|
||||||
|
//End of TCP functions
|
||||||
|
bool sendData(int uid, const char*, int);
|
||||||
|
bool sendGameData(int serverID);
|
||||||
|
bool sendKeyFrameData(int size, const char* data);
|
||||||
|
void sendInitData(int gid);
|
||||||
|
void sendRenderData(int gid);
|
||||||
|
void sendEventData(int gid, int size);
|
||||||
|
void sendLobbyInitData(int lid);
|
||||||
|
bool closeConnection();
|
||||||
|
void receiveDataUDP(int threadID);
|
||||||
|
|
||||||
|
static DWORD activateServerGameLoop(ThreadArguments* tra);
|
||||||
|
void startGameCreateLoop(int delay);
|
||||||
|
void stopGameCreateLoop();
|
||||||
|
void parseReceivedData(int threadID/*char*, int*/);//char and int required if i don't want to use the class buffer
|
||||||
|
void ParseReceivedData(ConnThreadData* data);
|
||||||
|
|
||||||
|
void parseServercommand(int pid, int threadID);
|
||||||
|
void parseData(int pid, int gid, int threadID);
|
||||||
|
void parseMessage(int pid, int threadID);
|
||||||
|
|
||||||
|
void addUser(int threadID);
|
||||||
|
void AddUser(ConnThreadData* data);
|
||||||
|
void removeUser(int id);
|
||||||
|
|
||||||
|
bool isReady() const {return setupStatus;}
|
||||||
|
bool LoadInitData(char* maploc);
|
||||||
|
};
|
||||||
|
struct ThreadArguments
|
||||||
|
{
|
||||||
|
SocketServer* ptr;
|
||||||
|
int threadID;
|
||||||
|
};
|
|
@ -0,0 +1,50 @@
|
||||||
|
#include "User.h"
|
||||||
|
User::User(int i, sockaddr_in add, std::string usr)
|
||||||
|
{
|
||||||
|
addr=add;
|
||||||
|
username=usr;
|
||||||
|
curGame=-1;
|
||||||
|
connection=NULL;
|
||||||
|
state=ONLINE;
|
||||||
|
lastUpdate=-1;
|
||||||
|
updMutex = CreateMutex(
|
||||||
|
NULL, // default security attributes
|
||||||
|
FALSE, // initially not owned
|
||||||
|
NULL); // unnamed mutex
|
||||||
|
|
||||||
|
if (updMutex == NULL)
|
||||||
|
{
|
||||||
|
printf("CreateMutex error: %d\n", GetLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
User::User()
|
||||||
|
{
|
||||||
|
username="";
|
||||||
|
curGame=-1;
|
||||||
|
connection=NULL;
|
||||||
|
state=ONLINE;
|
||||||
|
lastUpdate=-1;
|
||||||
|
updMutex = CreateMutex(
|
||||||
|
NULL, // default security attributes
|
||||||
|
FALSE, // initially not owned
|
||||||
|
NULL); // unnamed mutex
|
||||||
|
|
||||||
|
if (updMutex == NULL)
|
||||||
|
{
|
||||||
|
printf("CreateMutex error: %d\n", GetLastError());
|
||||||
|
}
|
||||||
|
lastUpdateData.pid=-1;
|
||||||
|
}
|
||||||
|
void User::setLastUpdateData(Network::ClientToServerUpdateData data)
|
||||||
|
{
|
||||||
|
WaitForSingleObject(updMutex, INFINITE);
|
||||||
|
lastUpdateData=data;
|
||||||
|
ReleaseMutex(updMutex);
|
||||||
|
}
|
||||||
|
Network::ClientToServerUpdateData User::getLastUpdateData()
|
||||||
|
{
|
||||||
|
WaitForSingleObject(updMutex, INFINITE);
|
||||||
|
Network::ClientToServerUpdateData data=lastUpdateData;
|
||||||
|
ReleaseMutex(updMutex);
|
||||||
|
return data;
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
#include "ServerInclude.h"
|
||||||
|
#ifndef USER_H
|
||||||
|
#define USER_H
|
||||||
|
enum UserState
|
||||||
|
{
|
||||||
|
OFFLINE,
|
||||||
|
OFFLINE_INGAME,
|
||||||
|
ONLINE,
|
||||||
|
ONLINE_QUEUEING,
|
||||||
|
ONLINE_INLOBBY,
|
||||||
|
ONLINE_INGAME
|
||||||
|
};
|
||||||
|
class User
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string username;
|
||||||
|
int curGame;
|
||||||
|
sockaddr_in addr;
|
||||||
|
UserState state;
|
||||||
|
long lastUpdate;
|
||||||
|
HANDLE updMutex;
|
||||||
|
Network::ClientToServerUpdateData lastUpdateData;
|
||||||
|
public:
|
||||||
|
void setLastUpdateData(Network::ClientToServerUpdateData data);
|
||||||
|
Network::ClientToServerUpdateData getLastUpdateData();
|
||||||
|
void setLastUpdate(long upd){lastUpdate=upd;}
|
||||||
|
long getLastUpdate() {return lastUpdate;}
|
||||||
|
HANDLE threadHandle;
|
||||||
|
SOCKET connection;
|
||||||
|
User();
|
||||||
|
User(int id, sockaddr_in addr, std::string usr="Unknown");
|
||||||
|
//SOCKET getTCPSocket() const {return connection;}
|
||||||
|
sockaddr_in getAddr() const {return addr;}
|
||||||
|
std::string getUsername() const {return username;}
|
||||||
|
void setUsername(std::string usr){username=usr;}
|
||||||
|
void setState(UserState st){state=st;}
|
||||||
|
UserState getState(){return state;}
|
||||||
|
void setGame(int gid){curGame=gid;}
|
||||||
|
bool isIngame() {return state==ONLINE_INGAME;}
|
||||||
|
int getGame(){return curGame;}
|
||||||
|
};
|
||||||
|
#endif
|
|
@ -0,0 +1,202 @@
|
||||||
|
#include "Buffer.h"
|
||||||
|
#include "Core.h"
|
||||||
|
using namespace Oyster;
|
||||||
|
|
||||||
|
Buffer::Buffer()
|
||||||
|
{
|
||||||
|
mBuffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer::~Buffer()
|
||||||
|
{
|
||||||
|
SAFE_RELEASE(mBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT Buffer::Apply(UINT32 misc) const
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
switch(mType)
|
||||||
|
{
|
||||||
|
case VERTEX_BUFFER:
|
||||||
|
{
|
||||||
|
UINT32 vertexSize = mElementSize;
|
||||||
|
UINT32 offset = 0;
|
||||||
|
Oyster::Core::DeviceContext->IASetVertexBuffers(misc, 1, &mBuffer, &vertexSize, &offset );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case INDEX_BUFFER:
|
||||||
|
{
|
||||||
|
Oyster::Core::DeviceContext->IASetIndexBuffer(mBuffer, DXGI_FORMAT_R32_UINT, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CONSTANT_BUFFER_VS:
|
||||||
|
{
|
||||||
|
Oyster::Core::DeviceContext->VSSetConstantBuffers(misc, 1, &mBuffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CONSTANT_BUFFER_GS:
|
||||||
|
{
|
||||||
|
Oyster::Core::DeviceContext->GSSetConstantBuffers(misc, 1, &mBuffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CONSTANT_BUFFER_PS:
|
||||||
|
{
|
||||||
|
Oyster::Core::DeviceContext->PSSetConstantBuffers(misc, 1, &mBuffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CONSTANT_BUFFER_CS:
|
||||||
|
{
|
||||||
|
Oyster::Core::DeviceContext->CSSetConstantBuffers(misc,1,&mBuffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
hr = E_FAIL;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT Buffer::Init(const BUFFER_INIT_DESC& initDesc)
|
||||||
|
{
|
||||||
|
D3D11_BUFFER_DESC bufferDesc;
|
||||||
|
|
||||||
|
mType = initDesc.Type;
|
||||||
|
switch(mType)
|
||||||
|
{
|
||||||
|
case VERTEX_BUFFER:
|
||||||
|
{
|
||||||
|
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||||
|
|
||||||
|
if(initDesc.Usage == BUFFER_STREAM_OUT_TARGET)
|
||||||
|
bufferDesc.BindFlags |= D3D11_BIND_STREAM_OUTPUT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case INDEX_BUFFER:
|
||||||
|
{
|
||||||
|
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STRUCTURED_BUFFER:
|
||||||
|
{
|
||||||
|
bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CONSTANT_BUFFER_CS:
|
||||||
|
case CONSTANT_BUFFER_VS:
|
||||||
|
case CONSTANT_BUFFER_GS:
|
||||||
|
case CONSTANT_BUFFER_PS:
|
||||||
|
{
|
||||||
|
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return E_FAIL;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
mUsage = initDesc.Usage;
|
||||||
|
mElementSize = initDesc.ElementSize;
|
||||||
|
mElementCount = initDesc.NumElements;
|
||||||
|
|
||||||
|
bufferDesc.CPUAccessFlags = 0;
|
||||||
|
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
|
||||||
|
if(mUsage == BUFFER_CPU_READ)
|
||||||
|
{
|
||||||
|
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_READ;
|
||||||
|
}
|
||||||
|
else if(mUsage == BUFFER_CPU_WRITE)
|
||||||
|
{
|
||||||
|
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE;
|
||||||
|
}
|
||||||
|
else if(mUsage == BUFFER_CPU_WRITE_DISCARD)
|
||||||
|
{
|
||||||
|
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||||
|
bufferDesc.MiscFlags = 0;
|
||||||
|
bufferDesc.ByteWidth = initDesc.NumElements * initDesc.ElementSize;
|
||||||
|
bufferDesc.StructureByteStride=0;
|
||||||
|
if(mType== STRUCTURED_BUFFER)
|
||||||
|
{
|
||||||
|
bufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
|
||||||
|
bufferDesc.StructureByteStride=initDesc.ElementSize;
|
||||||
|
}
|
||||||
|
//set at least 16 bytes
|
||||||
|
if(bufferDesc.ByteWidth < 16)
|
||||||
|
bufferDesc.ByteWidth = 16;
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
if(initDesc.InitData)
|
||||||
|
{
|
||||||
|
D3D11_SUBRESOURCE_DATA data;
|
||||||
|
data.pSysMem = initDesc.InitData;
|
||||||
|
data.SysMemPitch=0;
|
||||||
|
data.SysMemSlicePitch = 0;
|
||||||
|
hr = Oyster::Core::Device->CreateBuffer(&bufferDesc, &data, &mBuffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = Oyster::Core::Device->CreateBuffer(&bufferDesc, NULL, &mBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(FAILED(hr))
|
||||||
|
{
|
||||||
|
MessageBox(NULL, "Unable to create buffer.", "Slenda Error", MB_ICONERROR | MB_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Buffer::Map()
|
||||||
|
{
|
||||||
|
void* ret = NULL;
|
||||||
|
if(mUsage == BUFFER_CPU_WRITE || mUsage == BUFFER_CPU_READ || mUsage == BUFFER_CPU_WRITE_DISCARD)
|
||||||
|
{
|
||||||
|
D3D11_MAPPED_SUBRESOURCE MappedResource;
|
||||||
|
UINT32 mapType = 0;
|
||||||
|
|
||||||
|
if(mUsage == BUFFER_CPU_READ) mapType = D3D11_MAP_READ;
|
||||||
|
else if(mUsage == BUFFER_CPU_WRITE) mapType = D3D11_MAP_WRITE;
|
||||||
|
else if(mUsage == BUFFER_CPU_WRITE_DISCARD) mapType = D3D11_MAP_WRITE_DISCARD;
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
if(FAILED(hr = Oyster::Core::DeviceContext->Map(
|
||||||
|
mBuffer,
|
||||||
|
0,
|
||||||
|
(D3D11_MAP)mapType,
|
||||||
|
0,
|
||||||
|
&MappedResource)))
|
||||||
|
{
|
||||||
|
ret = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = MappedResource.pData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::Unmap()
|
||||||
|
{
|
||||||
|
Oyster::Core::DeviceContext->Unmap( mBuffer, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer::operator ID3D11Buffer *()
|
||||||
|
{
|
||||||
|
return this->mBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer::operator const ID3D11Buffer *() const
|
||||||
|
{
|
||||||
|
return this->mBuffer;
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef CoreBuffer
|
||||||
|
#define CoreBuffer
|
||||||
|
|
||||||
|
#include "Core.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
class Buffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum BUFFER_TYPE
|
||||||
|
{
|
||||||
|
VERTEX_BUFFER,
|
||||||
|
INDEX_BUFFER,
|
||||||
|
CONSTANT_BUFFER_VS,
|
||||||
|
CONSTANT_BUFFER_GS,
|
||||||
|
CONSTANT_BUFFER_PS,
|
||||||
|
CONSTANT_BUFFER_CS,
|
||||||
|
STRUCTURED_BUFFER,
|
||||||
|
BUFFER_TYPE_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BUFFER_USAGE
|
||||||
|
{
|
||||||
|
BUFFER_DEFAULT,
|
||||||
|
BUFFER_STREAM_OUT_TARGET,
|
||||||
|
BUFFER_CPU_WRITE,
|
||||||
|
BUFFER_CPU_WRITE_DISCARD,
|
||||||
|
BUFFER_CPU_READ,
|
||||||
|
BUFFER_USAGE_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BUFFER_INIT_DESC
|
||||||
|
{
|
||||||
|
BUFFER_TYPE Type;
|
||||||
|
UINT32 NumElements;
|
||||||
|
UINT32 ElementSize;
|
||||||
|
BUFFER_USAGE Usage;
|
||||||
|
void* InitData;
|
||||||
|
|
||||||
|
BUFFER_INIT_DESC()
|
||||||
|
{
|
||||||
|
InitData = NULL;
|
||||||
|
Usage = BUFFER_DEFAULT;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
ID3D11Buffer* mBuffer;
|
||||||
|
BUFFER_TYPE mType;
|
||||||
|
BUFFER_USAGE mUsage;
|
||||||
|
|
||||||
|
UINT32 mElementSize;
|
||||||
|
UINT32 mElementCount;
|
||||||
|
public:
|
||||||
|
Buffer();
|
||||||
|
virtual ~Buffer();
|
||||||
|
|
||||||
|
HRESULT Init(const BUFFER_INIT_DESC& initDesc);
|
||||||
|
|
||||||
|
void* Map();
|
||||||
|
void Unmap();
|
||||||
|
|
||||||
|
operator ID3D11Buffer*();
|
||||||
|
operator const ID3D11Buffer*() const;
|
||||||
|
|
||||||
|
HRESULT Apply(UINT32 misc = 0) const;
|
||||||
|
|
||||||
|
ID3D11Buffer* GetBufferPointer();
|
||||||
|
UINT32 GetVertexSize();
|
||||||
|
UINT32 GetElementCount();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,164 @@
|
||||||
|
#include "Core.h"
|
||||||
|
#include "..\Window\Window.h"
|
||||||
|
|
||||||
|
using namespace Oyster;
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
//GPU
|
||||||
|
ID3D11Device *Core::Device = NULL;
|
||||||
|
|
||||||
|
//API
|
||||||
|
ID3D11DeviceContext *Core::DeviceContext = NULL;
|
||||||
|
|
||||||
|
//SwapChain
|
||||||
|
IDXGISwapChain* Core::SwapChain = NULL;
|
||||||
|
|
||||||
|
std::stringstream Log;
|
||||||
|
|
||||||
|
inline std::stringstream* AccesLog(){return &Log;}
|
||||||
|
|
||||||
|
bool Core::Init(bool SingleThreaded, bool Reference,bool ForceDX11)
|
||||||
|
{
|
||||||
|
UINT createDeviceFlags = 0;
|
||||||
|
|
||||||
|
if( SingleThreaded )
|
||||||
|
createDeviceFlags = ::D3D11_CREATE_DEVICE_SINGLETHREADED;
|
||||||
|
|
||||||
|
::D3D_DRIVER_TYPE driverType = ::D3D_DRIVER_TYPE_HARDWARE;
|
||||||
|
|
||||||
|
if(Reference)
|
||||||
|
driverType = D3D_DRIVER_TYPE_REFERENCE;
|
||||||
|
|
||||||
|
/*#if defined(DEBUG) || defined(_DEBUG)
|
||||||
|
Log << "DirectX running in debug mode.\n";
|
||||||
|
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||||
|
#endif*/
|
||||||
|
|
||||||
|
|
||||||
|
D3D_FEATURE_LEVEL featureLevelsToTry[] =
|
||||||
|
{
|
||||||
|
D3D_FEATURE_LEVEL_11_0,
|
||||||
|
D3D_FEATURE_LEVEL_10_1,
|
||||||
|
D3D_FEATURE_LEVEL_10_0
|
||||||
|
};
|
||||||
|
D3D_FEATURE_LEVEL initiatedFeatureLevel;
|
||||||
|
|
||||||
|
if( FAILED( ::D3D11CreateDevice( NULL, // default adapter
|
||||||
|
driverType,
|
||||||
|
NULL, // no software device
|
||||||
|
createDeviceFlags,
|
||||||
|
featureLevelsToTry, 3, // default feature level array. DX11 support assumed
|
||||||
|
D3D11_SDK_VERSION,
|
||||||
|
&Device, // device
|
||||||
|
&initiatedFeatureLevel,
|
||||||
|
&DeviceContext ) ) ) // context
|
||||||
|
{ // if failed
|
||||||
|
if( DeviceContext ) { DeviceContext->Release(); DeviceContext = NULL; } // safe cleanup
|
||||||
|
if( Device ) { Device->Release(); Device = NULL; } // safe cleanup
|
||||||
|
}
|
||||||
|
|
||||||
|
if( driverType == ::D3D_DRIVER_TYPE_HARDWARE )
|
||||||
|
Log << "D3D_DRIVER_TYPE_HARDWARE support discovered.\n";
|
||||||
|
else
|
||||||
|
Log << "D3D_DRIVER_TYPE_REFERENCE support discovered.\n";
|
||||||
|
|
||||||
|
if( initiatedFeatureLevel == ::D3D_FEATURE_LEVEL_11_0 )
|
||||||
|
{
|
||||||
|
Log << "DirectX Featurelevel 11.0 supported.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(ForceDX11)
|
||||||
|
return false;
|
||||||
|
if( initiatedFeatureLevel == ::D3D_FEATURE_LEVEL_10_1 )
|
||||||
|
{
|
||||||
|
Log << "DirectX Featurelevel 10.1 supported.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( initiatedFeatureLevel == ::D3D_FEATURE_LEVEL_10_0 )
|
||||||
|
{
|
||||||
|
Log << "DirectX Featurelevel 10.0 supported.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(Device)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Core::CreateSwapChain(HWND Window, int NrofBuffers,bool MSAA_Quality,bool Fullscreen)
|
||||||
|
{
|
||||||
|
//generate static Swapchain Desc
|
||||||
|
DXGI_SWAP_CHAIN_DESC desc;
|
||||||
|
desc.OutputWindow=Window;
|
||||||
|
desc.BufferCount=NrofBuffers;
|
||||||
|
desc.Windowed=!Fullscreen;
|
||||||
|
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_UNORDERED_ACCESS;
|
||||||
|
desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||||
|
desc.Flags=0;
|
||||||
|
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||||
|
desc.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;
|
||||||
|
desc.BufferDesc.RefreshRate.Denominator=1;
|
||||||
|
desc.BufferDesc.RefreshRate.Numerator=60;
|
||||||
|
desc.BufferDesc.Height = Window::Size.bottom;
|
||||||
|
desc.BufferDesc.Width = Window::Size.left;
|
||||||
|
|
||||||
|
//Check and Set multiSampling
|
||||||
|
if(MSAA_Quality)
|
||||||
|
{
|
||||||
|
if(FAILED(Device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM,4,&desc.SampleDesc.Quality)))
|
||||||
|
{
|
||||||
|
Log<< "Failed to check multisample quality levels (MSAAQuality).\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
desc.SampleDesc.Count=4;
|
||||||
|
--desc.SampleDesc.Quality;
|
||||||
|
Log << "Supported multisample quality levels (MSAAQuality): " << desc.SampleDesc.Quality+1 << "x\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
desc.SampleDesc.Count=1;
|
||||||
|
desc.SampleDesc.Quality=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get Device Factory
|
||||||
|
::IDXGIDevice *dxgiDevice = NULL;
|
||||||
|
if( FAILED( Device->QueryInterface( __uuidof( IDXGIDevice ), (void**)&dxgiDevice ) ) )
|
||||||
|
{
|
||||||
|
Log << "Failed to Query for the GPU's dxgiDevice.\nFailed to create swapChain for the GPU.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
::IDXGIAdapter *dxgiAdapter = NULL;
|
||||||
|
if( FAILED( dxgiDevice->GetParent( __uuidof( IDXGIAdapter ), (void**)&dxgiAdapter ) ) )
|
||||||
|
{
|
||||||
|
dxgiDevice->Release();
|
||||||
|
Log << "Failed to get GPU's parent dxgiAdapter.\nFailed to create swapChain for the GPU.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dxgiDevice->Release();
|
||||||
|
|
||||||
|
::IDXGIFactory *dxgiFactory = NULL;
|
||||||
|
if( FAILED( dxgiAdapter->GetParent( __uuidof( IDXGIFactory ), (void**)&dxgiFactory ) ) )
|
||||||
|
{
|
||||||
|
dxgiAdapter->Release();
|
||||||
|
Log << "Failed to get GPU's parent dxgiFactory.\nFailed to create swapChain for the GPU.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dxgiAdapter->Release();
|
||||||
|
|
||||||
|
//Create SwapChain
|
||||||
|
if( FAILED( dxgiFactory->CreateSwapChain( Device, &desc, &SwapChain ) ) )
|
||||||
|
{
|
||||||
|
dxgiFactory->Release();
|
||||||
|
Log << "Failed to create swapChain for the GPU.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dxgiFactory->Release();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef Core_h
|
||||||
|
#define Core_h
|
||||||
|
|
||||||
|
|
||||||
|
#include "CoreIncludes.h"
|
||||||
|
#include <sstream>
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
class Core
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static ID3D11Device* Device;
|
||||||
|
|
||||||
|
static ID3D11DeviceContext* DeviceContext;
|
||||||
|
|
||||||
|
static IDXGISwapChain* SwapChain;
|
||||||
|
|
||||||
|
static std::stringstream* AccesLog();
|
||||||
|
|
||||||
|
static bool Init(bool SingleThreaded,bool Reference,bool ForceDX11);
|
||||||
|
|
||||||
|
static bool CreateSwapChain(HWND Window, int NrofBuffers,bool MSAA_Quality,bool Fullscreen);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,40 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef CORE_INCLUDE
|
||||||
|
#define CORE_INCLUDE
|
||||||
|
|
||||||
|
#define NOMINMAX // Because I hate Microsoft now. ~Angry Dan.
|
||||||
|
// http://lolengine.net/blog/2011/3/4/fuck-you-microsoft-near-far-macros
|
||||||
|
#include <WinSock2.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <D3D11.h>
|
||||||
|
#include <D3DX11.h>
|
||||||
|
#include <D3DX10math.h>
|
||||||
|
#include <d3dx11effect.h>
|
||||||
|
#include <d3dCompiler.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#define SAFE_RELEASE(x) if( x ) { (x)->Release(); (x) = NULL; }
|
||||||
|
#define SAFE_DELETE(x) if( x ) { delete(x); (x) = NULL; }
|
||||||
|
#define SAFE_DELETE_ARRAY(x) if( x ) { delete[](x); (x) = NULL; }
|
||||||
|
#define PI (3.14159265358979323846f)
|
||||||
|
|
||||||
|
#pragma comment(lib, "d3d11.lib")
|
||||||
|
#pragma comment(lib, "d3dcompiler.lib")
|
||||||
|
#pragma comment (lib,"dxerr.lib")
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#pragma comment(lib, "d3dx11d.lib")
|
||||||
|
#pragma comment(lib, "Effects11D.lib")
|
||||||
|
#pragma comment(lib, "d3dx10d.lib")
|
||||||
|
#else
|
||||||
|
#pragma comment(lib, "d3dx11.lib")
|
||||||
|
#pragma comment(lib, "Effects11.lib")
|
||||||
|
#pragma comment(lib, "d3dx10.lib")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,539 @@
|
||||||
|
#include "Engine.h"
|
||||||
|
|
||||||
|
bool CreateDepthStencil(bool MSAA_Quality);
|
||||||
|
bool CreateRenderTarget();
|
||||||
|
void SetViewPort();
|
||||||
|
|
||||||
|
class oysterPrivates
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool instance,swapChained;
|
||||||
|
ID3D11DepthStencilView* depth;
|
||||||
|
ID3D11RenderTargetView *rtv;
|
||||||
|
ID3D11UnorderedAccessView *uav;
|
||||||
|
ID3D11ShaderResourceView* depthTexture;
|
||||||
|
DXGI_SAMPLE_DESC sampleDesc;
|
||||||
|
D3D11_VIEWPORT viewPort;
|
||||||
|
oysterPrivates():instance(false),swapChained(false),depth(NULL),rtv(NULL), depthTexture(NULL){};
|
||||||
|
class State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int NrOfSamples;
|
||||||
|
int SampleSpread;
|
||||||
|
int NrOfPointlights;
|
||||||
|
}States;
|
||||||
|
|
||||||
|
}instance;
|
||||||
|
|
||||||
|
Oyster::Engine::Engine()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Oyster::Engine::~Engine()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//Init
|
||||||
|
bool Oyster::Engine::Init::IsInstanced()
|
||||||
|
{
|
||||||
|
return instance.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Oyster::Engine::Init::Instance(bool SingleThreaded,bool Reference,bool ForceDX11)
|
||||||
|
{
|
||||||
|
if(!instance.instance)
|
||||||
|
if(Oyster::Core::Init(SingleThreaded,Reference,ForceDX11))
|
||||||
|
instance.instance=true;
|
||||||
|
|
||||||
|
return instance.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Oyster::Engine::Init::HasSwapChain()
|
||||||
|
{
|
||||||
|
return instance.swapChained;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Oyster::Engine::Init::CreateSwapChain(HWND Window,int NrofBuffers,bool MSAA_Quality,bool Fullscreen)
|
||||||
|
{
|
||||||
|
if(Window==0)
|
||||||
|
{
|
||||||
|
if(Oyster::Window::Handle==0)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
Window = Oyster::Window::Handle;
|
||||||
|
}
|
||||||
|
if(!instance.swapChained)
|
||||||
|
{
|
||||||
|
if(Oyster::Core::CreateSwapChain(Window,NrofBuffers,MSAA_Quality,Fullscreen))
|
||||||
|
instance.swapChained=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance.swapChained;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Oyster::Engine::Init::InitializeWindow(const LPCSTR appName, const LPCSTR className,const HINSTANCE &hInstance, const int &nCmdShow, WNDPROC wProc, bool handleLoop )
|
||||||
|
{
|
||||||
|
return Oyster::Window::init(appName,className,hInstance,nCmdShow,wProc,handleLoop);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Oyster::Engine::Init::FullInit(const Setup& setup)
|
||||||
|
{
|
||||||
|
if(!Oyster::Engine::Init::Instance(setup.Common.SingleThreaded,setup.Common.Reference,setup.Common.ForceDX11))
|
||||||
|
return false;
|
||||||
|
if(setup.Window.InitWindow)
|
||||||
|
if(!Oyster::Engine::Init::InitializeWindow(setup.Window.appname,setup.Window.classname,setup.Window.hinstance,setup.Window.nCmdShow,setup.Window.wProc, true))
|
||||||
|
return false;
|
||||||
|
if(!Oyster::Engine::Init::CreateSwapChain(NULL,setup.Common.NrOfBuffers,setup.Common.MSAA_Quality,setup.Common.Fullscreen))
|
||||||
|
return false;
|
||||||
|
if(!Oyster::Shader::InitShaders())
|
||||||
|
return false;
|
||||||
|
if(setup.Common.GenerateDepthStencil)
|
||||||
|
if(!CreateDepthStencil(setup.Common.MSAA_Quality))
|
||||||
|
return false;
|
||||||
|
if(!CreateRenderTarget())
|
||||||
|
return false;
|
||||||
|
if(!Oyster::Render::Textbox::Init())
|
||||||
|
return false;
|
||||||
|
SetViewPort();
|
||||||
|
if(setup.Common.BindDefault)
|
||||||
|
Oyster::Engine::PrepareForRendering::BindRenderTargets(&instance.rtv,1,instance.depth);
|
||||||
|
|
||||||
|
instance.States.NrOfSamples = 14;
|
||||||
|
instance.States.SampleSpread = 4;
|
||||||
|
instance.States.NrOfPointlights = 1024;
|
||||||
|
|
||||||
|
Oyster::Resources::Buffers::Init();
|
||||||
|
Oyster::Resources::ShaderEffects::Init();
|
||||||
|
Oyster::Resources::PipeLineResourses::Init();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Oyster::Buffer* Oyster::Engine::Init::Buffers::CreateBuffer(const Oyster::Buffer::BUFFER_INIT_DESC desc)
|
||||||
|
{
|
||||||
|
Oyster::Buffer *buffy = new Oyster::Buffer();
|
||||||
|
buffy->Init(desc);
|
||||||
|
return buffy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//PrepareForRendering
|
||||||
|
void Oyster::Engine::PrepareForRendering::BindRenderTargets(ID3D11RenderTargetView** RenderTargets,int NrOfTargets,ID3D11DepthStencilView* depth)
|
||||||
|
{
|
||||||
|
Oyster::Core::DeviceContext->OMSetRenderTargets(NrOfTargets,RenderTargets,depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::PrepareForRendering::BindRenderTargets(ID3D11RenderTargetView** RenderTargets,int NrOfTargets)
|
||||||
|
{
|
||||||
|
Oyster::Core::DeviceContext->OMSetRenderTargets(NrOfTargets,RenderTargets,instance.depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::PrepareForRendering::BindBackBufferAsUAV()
|
||||||
|
{
|
||||||
|
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews(0,1,&instance.uav,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::PrepareForRendering::BindUAV(ID3D11UnorderedAccessView** uav, int NrOfUavs)
|
||||||
|
{
|
||||||
|
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews(0,NrOfUavs,uav,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::PrepareForRendering::ClearBackBuffer(Math::Float4 color)
|
||||||
|
{
|
||||||
|
Oyster::Core::DeviceContext->ClearRenderTargetView(instance.rtv,(float*)color);
|
||||||
|
Oyster::Core::DeviceContext->ClearDepthStencilView(instance.depth,1,1,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::PrepareForRendering::BindBackBuffer(ID3D11DepthStencilView* depth)
|
||||||
|
{
|
||||||
|
Oyster::Core::DeviceContext->OMSetRenderTargets(1,&instance.rtv,depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::PrepareForRendering::BindBackBuffer()
|
||||||
|
{
|
||||||
|
Oyster::Core::DeviceContext->OMSetRenderTargets(1,&instance.rtv,instance.depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::PrepareForRendering::Begin2DRender()
|
||||||
|
{
|
||||||
|
Oyster::Resources::Buffers::V2DSprites.Apply();
|
||||||
|
Oyster::Resources::Buffers::CBufferGs.Apply();
|
||||||
|
Shader::SetShaderEffect(Oyster::Resources::ShaderEffects::BasicSprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::PrepareForRendering::Begin2DTextRender()
|
||||||
|
{
|
||||||
|
Oyster::Render::Textbox::TextBuffer.Apply();
|
||||||
|
Oyster::Resources::Buffers::CBufferGs.Apply();
|
||||||
|
Oyster::Shader::SetShaderEffect(Oyster::Resources::ShaderEffects::Text2DEffect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Render
|
||||||
|
void Oyster::Engine::Render::PresentScene()
|
||||||
|
{
|
||||||
|
Core::SwapChain->Present(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::Render::Geometry(const Oyster::Render::Model* models,int count,Oyster::Buffer* cBufferEveryObject, int slot)
|
||||||
|
{
|
||||||
|
if(cBufferEveryObject)
|
||||||
|
cBufferEveryObject->Apply(slot);
|
||||||
|
for(int i=0;i<count;++i)
|
||||||
|
{
|
||||||
|
if(models[i].Visible)
|
||||||
|
{
|
||||||
|
if(cBufferEveryObject)
|
||||||
|
{
|
||||||
|
void* data = cBufferEveryObject->Map();
|
||||||
|
memcpy(data,&(models[i].World->getTranspose()),64);
|
||||||
|
cBufferEveryObject->Unmap();
|
||||||
|
}
|
||||||
|
Oyster::Core::DeviceContext->PSSetShaderResources(0,models[i].info->Material.size(),&(models[i].info->Material[0]));
|
||||||
|
|
||||||
|
models[i].info->Vertices.Apply();
|
||||||
|
if(models[i].info->Indexed)
|
||||||
|
{
|
||||||
|
models[i].info->Indecies.Apply();
|
||||||
|
Oyster::Core::DeviceContext->DrawIndexed(models[i].info->VertexCount,0,0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Oyster::Core::DeviceContext->Draw(models[i].info->VertexCount,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::Render::Text(std::string text, Oyster::Math::Float2 size, Oyster::Math::Float3 Pos)
|
||||||
|
{
|
||||||
|
Pos.x -= Oyster::Window::Size.left/2;
|
||||||
|
Pos.x += size.x;
|
||||||
|
|
||||||
|
Pos.y -= Oyster::Window::Size.bottom/2;
|
||||||
|
Pos.y += size.y;
|
||||||
|
|
||||||
|
Matrix m;
|
||||||
|
Math::identityMatrix(m);
|
||||||
|
float width = (1.0f/(Window::Size.left/2.0f));
|
||||||
|
float height = (1.0f/(Window::Size.bottom/2.0f));
|
||||||
|
m.m41=Pos.x * width;
|
||||||
|
m.m42=-Pos.y * height;
|
||||||
|
m.m43=Pos.z;
|
||||||
|
m.m11=width*size.x;
|
||||||
|
m.m22=height*size.y;
|
||||||
|
void* dest = Resources::Buffers::CBufferGs.Map();
|
||||||
|
memcpy(dest,&m.getTranspose(),64);
|
||||||
|
Resources::Buffers::CBufferGs.Unmap();
|
||||||
|
Oyster::Render::Textbox::Update(text, size.x);
|
||||||
|
Oyster::Engine::PrepareForRendering::Begin2DTextRender();
|
||||||
|
Oyster::Core::DeviceContext->PSSetShaderResources(0,1,&(Oyster::Render::Textbox::Texture));
|
||||||
|
//Should be able to be outside of the for loop. Keeping it here for now though.
|
||||||
|
Oyster::Core::DeviceContext->Draw(Oyster::Render::Textbox::NumLetters, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::Render::ScreenQuad(ID3D11ShaderResourceView* srv, float ZPos)
|
||||||
|
{
|
||||||
|
|
||||||
|
Oyster::Core::DeviceContext->PSSetShaderResources(0,1,&srv);
|
||||||
|
|
||||||
|
Matrix m;
|
||||||
|
Math::identityMatrix(m);
|
||||||
|
m.m43=ZPos;
|
||||||
|
|
||||||
|
void* dest = Resources::Buffers::CBufferGs.Map();
|
||||||
|
memcpy(dest,&m.getTranspose(),64);
|
||||||
|
Resources::Buffers::CBufferGs.Unmap();
|
||||||
|
|
||||||
|
Oyster::Core::DeviceContext->Draw(1,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::Render::Sprite(ID3D11ShaderResourceView* srv, Oyster::Math::Float2 size, Oyster::Math::Float3 Pos)
|
||||||
|
{
|
||||||
|
|
||||||
|
Oyster::Core::DeviceContext->PSSetShaderResources(0,1,&srv);
|
||||||
|
|
||||||
|
Pos.x -= Oyster::Window::Size.left/2;
|
||||||
|
Pos.x += size.x/2;
|
||||||
|
|
||||||
|
Pos.y -= Oyster::Window::Size.bottom/2;
|
||||||
|
Pos.y += size.y/2;
|
||||||
|
|
||||||
|
Matrix m;
|
||||||
|
Math::identityMatrix(m);
|
||||||
|
float width = (1.0f/(Window::Size.left/2.0f));
|
||||||
|
float height = (1.0f/(Window::Size.bottom/2.0f));
|
||||||
|
m.m41=Pos.x * width;
|
||||||
|
m.m42=-Pos.y * height;
|
||||||
|
m.m43=Pos.z;
|
||||||
|
m.m11=width*size.x/2;
|
||||||
|
m.m22=height*size.y/2;
|
||||||
|
|
||||||
|
void* dest = Resources::Buffers::CBufferGs.Map();
|
||||||
|
memcpy(dest,&m.getTranspose(),64);
|
||||||
|
Resources::Buffers::CBufferGs.Unmap();
|
||||||
|
|
||||||
|
Oyster::Core::DeviceContext->Draw(1,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Misc
|
||||||
|
bool CreateDepthStencil(bool MSAA_Quality)
|
||||||
|
{
|
||||||
|
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
desc.MipLevels=1;
|
||||||
|
desc.ArraySize=1;
|
||||||
|
desc.Format = DXGI_FORMAT_D32_FLOAT;
|
||||||
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
|
||||||
|
desc.CPUAccessFlags=0;
|
||||||
|
desc.MiscFlags=0;
|
||||||
|
desc.Height = Oyster::Window::Size.bottom;
|
||||||
|
desc.Width = Oyster::Window::Size.left;
|
||||||
|
|
||||||
|
|
||||||
|
//Check and Set multiSampling
|
||||||
|
if(MSAA_Quality)
|
||||||
|
{
|
||||||
|
if(FAILED(Oyster::Core::Device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM,4,&desc.SampleDesc.Quality)))
|
||||||
|
{
|
||||||
|
//Log<< "Failed to check multisample quality levels (MSAAQuality).\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
desc.SampleDesc.Count=4;
|
||||||
|
--desc.SampleDesc.Quality;
|
||||||
|
//Log << "Supported multisample quality levels (MSAAQuality): " << desc.SampleDesc.Quality+1 << "x\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
desc.SampleDesc.Count=1;
|
||||||
|
desc.SampleDesc.Quality=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D11Texture2D* depthstencil;
|
||||||
|
|
||||||
|
if(FAILED(Oyster::Core::Device->CreateTexture2D(&desc,0,&depthstencil)))
|
||||||
|
return false;
|
||||||
|
if(FAILED(Oyster::Core::Device->CreateDepthStencilView(depthstencil,0,&instance.depth)))
|
||||||
|
{
|
||||||
|
depthstencil->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
depthstencil->Release();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CreateRenderTarget()
|
||||||
|
{
|
||||||
|
D3D11_UNORDERED_ACCESS_VIEW_DESC descView;
|
||||||
|
ZeroMemory( &descView, sizeof(descView) );
|
||||||
|
descView.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
|
||||||
|
descView.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
descView.Texture2D.MipSlice=0;
|
||||||
|
|
||||||
|
ID3D11Texture2D* backBuffer;
|
||||||
|
if(FAILED(Oyster::Core::SwapChain->GetBuffer(0,__uuidof(ID3D11Texture2D),reinterpret_cast<void**>(&backBuffer))))
|
||||||
|
return false;
|
||||||
|
if(FAILED(Oyster::Core::Device->CreateRenderTargetView(backBuffer,0,&instance.rtv)))
|
||||||
|
{
|
||||||
|
backBuffer->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(FAILED(Oyster::Core::Device->CreateUnorderedAccessView(backBuffer,0,&instance.uav)))
|
||||||
|
{
|
||||||
|
backBuffer->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
backBuffer->Release();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetViewPort()
|
||||||
|
{
|
||||||
|
instance.viewPort.TopLeftX = 0.0f;
|
||||||
|
instance.viewPort.TopLeftY = 0.0f;
|
||||||
|
instance.viewPort.Width = (float)Oyster::Window::Size.left;
|
||||||
|
instance.viewPort.Height = (float)Oyster::Window::Size.bottom;
|
||||||
|
instance.viewPort.MinDepth = 0.0f;
|
||||||
|
instance.viewPort.MaxDepth = 1.0f;
|
||||||
|
|
||||||
|
Oyster::Core::DeviceContext->RSSetViewports(1,&instance.viewPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Blur(int target)
|
||||||
|
{
|
||||||
|
//TODO: proper size calculation
|
||||||
|
|
||||||
|
//bind input
|
||||||
|
Oyster::Core::DeviceContext->CSSetShaderResources(0,1,&Oyster::Resources::PipeLineResourses::LightOut[target]);
|
||||||
|
Oyster::Engine::PrepareForRendering::BindUAV(&Oyster::Resources::PipeLineResourses::TempUav,1);
|
||||||
|
|
||||||
|
//dispatch blurr horizontal
|
||||||
|
Oyster::Shader::Set::SetCompute(Oyster::Shader::Get::GetCompute("BlurHorizontal"));
|
||||||
|
Oyster::Core::DeviceContext->Dispatch(7,Oyster::Window::Size.bottom,1);
|
||||||
|
|
||||||
|
//clean Pipeline
|
||||||
|
Oyster::Core::DeviceContext->CSSetShaderResources(0,16,&Oyster::Resources::PipeLineResourses::SrvNulls[0]);
|
||||||
|
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews(0,8,&Oyster::Resources::PipeLineResourses::uavNULL[0],0);
|
||||||
|
|
||||||
|
//bind input
|
||||||
|
Oyster::Core::DeviceContext->CSSetShaderResources(0,1,&Oyster::Resources::PipeLineResourses::TempSrv);
|
||||||
|
Oyster::Engine::PrepareForRendering::BindUAV(&Oyster::Resources::PipeLineResourses::LightTarget[target],1);
|
||||||
|
|
||||||
|
//dispatch blurr vertical
|
||||||
|
Oyster::Shader::Set::SetCompute(Oyster::Shader::Get::GetCompute("BlurVertical"));
|
||||||
|
Oyster::Core::DeviceContext->Dispatch(Oyster::Window::Size.left,5,1);
|
||||||
|
|
||||||
|
//clean Pipeline
|
||||||
|
Oyster::Core::DeviceContext->CSSetShaderResources(0,16,&Oyster::Resources::PipeLineResourses::SrvNulls[0]);
|
||||||
|
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews(0,8,&Oyster::Resources::PipeLineResourses::uavNULL[0],0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Pipeline Render
|
||||||
|
void Oyster::Engine::Pipeline::Deffered_Lightning::NewFrame(const Float4& col, const Matrix& View, const Matrix& Projection)
|
||||||
|
{
|
||||||
|
//diffuse
|
||||||
|
Oyster::Core::DeviceContext->ClearRenderTargetView( Oyster::Resources::PipeLineResourses::GeometryTarget[0], col);
|
||||||
|
|
||||||
|
//Specular
|
||||||
|
Oyster::Core::DeviceContext->ClearRenderTargetView( Oyster::Resources::PipeLineResourses::GeometryTarget[1], col);
|
||||||
|
|
||||||
|
//Glow
|
||||||
|
Oyster::Core::DeviceContext->ClearRenderTargetView( Oyster::Resources::PipeLineResourses::GeometryTarget[2], col);
|
||||||
|
|
||||||
|
//Pos
|
||||||
|
Oyster::Core::DeviceContext->ClearRenderTargetView( Oyster::Resources::PipeLineResourses::GeometryTarget[3], col);
|
||||||
|
|
||||||
|
//Normal
|
||||||
|
Oyster::Core::DeviceContext->ClearRenderTargetView( Oyster::Resources::PipeLineResourses::GeometryTarget[4], col);
|
||||||
|
|
||||||
|
Oyster::Engine::PrepareForRendering::ClearBackBuffer(col);
|
||||||
|
|
||||||
|
//Upload Camera to Resources
|
||||||
|
|
||||||
|
Matrix P = Oyster::Math::Float4x4(Projection);
|
||||||
|
Matrix V = Oyster::Math::Float4x4(View);
|
||||||
|
Matrix VP = V*P;
|
||||||
|
|
||||||
|
Oyster::Resources::PipeLineResourses::LightData.projectionMatrix = P.getTranspose();
|
||||||
|
Oyster::Resources::PipeLineResourses::LightData.viewMatrix = V;
|
||||||
|
|
||||||
|
Oyster::Collision::Frustrum( VP ).split(Oyster::Resources::PipeLineResourses::SubFrustrums, Oyster::Resources::PipeLineResourses::FrustrumDimensions.x, Oyster::Resources::PipeLineResourses::FrustrumDimensions.y, Oyster::Resources::PipeLineResourses::FrustrumDimensions.z );
|
||||||
|
|
||||||
|
void* dest = Oyster::Resources::ShaderEffects::ModelEffect.CBuffers.Vertex[0]->Map();
|
||||||
|
memcpy(dest,&VP.getTranspose(),64);
|
||||||
|
Oyster::Resources::ShaderEffects::ModelEffect.CBuffers.Vertex[0]->Unmap();
|
||||||
|
|
||||||
|
dest= Oyster::Resources::ShaderEffects::ModelEffect.CBuffers.Vertex[1]->Map();
|
||||||
|
memcpy(dest,&V.getTranspose(),64);
|
||||||
|
Oyster::Resources::ShaderEffects::ModelEffect.CBuffers.Vertex[1]->Unmap();
|
||||||
|
|
||||||
|
dest = Oyster::Resources::PipeLineResourses::Resources[0]->Map();
|
||||||
|
unsigned int bytes=0;
|
||||||
|
for(int i=0;i<Oyster::Resources::PipeLineResourses::FrustrumSize;++i)
|
||||||
|
{
|
||||||
|
Oyster::Resources::PipeLineResourses::SubFrustrums[i].writeToByte( (unsigned char*)dest,bytes);
|
||||||
|
}
|
||||||
|
Oyster::Resources::PipeLineResourses::Resources[0]->Unmap();
|
||||||
|
|
||||||
|
dest = Oyster::Resources::Buffers::CBufferPipelineCs.Map();
|
||||||
|
memcpy(dest, &Oyster::Resources::PipeLineResourses::LightData, sizeof( Oyster::Resources::BufferDefinitions::LightStructureBuffer ) );
|
||||||
|
Oyster::Resources::Buffers::CBufferPipelineCs.Unmap();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::Pipeline::Deffered_Lightning::BeginRenderGeometry()
|
||||||
|
{
|
||||||
|
Oyster::Engine::PrepareForRendering::BindRenderTargets( Oyster::Resources::PipeLineResourses::GeometryTarget, 5 );
|
||||||
|
Oyster::Shader::SetShaderEffect( Oyster::Resources::ShaderEffects::ModelEffect );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::Pipeline::Deffered_Lightning::RenderGeometry(const Oyster::Render::Model* models,int count)
|
||||||
|
{
|
||||||
|
//TODO: Add sorting to minimiza state changes
|
||||||
|
Render::Geometry( models, count, &Oyster::Resources::Buffers::CbufferVS, 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::Pipeline::Deffered_Lightning::EndRenderGeometry()
|
||||||
|
{
|
||||||
|
//TODO: Actualy Render data from previous pass
|
||||||
|
Oyster::Engine::PrepareForRendering::BindRenderTargets( Oyster::Resources::PipeLineResourses::RtvNulls, 8, NULL );
|
||||||
|
Oyster::Core::DeviceContext->PSSetShaderResources(0, 16, Oyster::Resources::PipeLineResourses::SrvNulls);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::Pipeline::Deffered_Lightning::InputPointLights(Oyster::Resources::BufferDefinitions::PointLightDescription *p, int nr)
|
||||||
|
{
|
||||||
|
void* dest = Oyster::Resources::PipeLineResourses::Resources[1]->Map();
|
||||||
|
memcpy(dest, p, sizeof(Oyster::Resources::BufferDefinitions::PointLightDescription) * nr );
|
||||||
|
Oyster::Resources::PipeLineResourses::Resources[1]->Unmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::Pipeline::Deffered_Lightning::RenderLightning()
|
||||||
|
{
|
||||||
|
Oyster::Engine::PrepareForRendering::BindUAV( Oyster::Resources::PipeLineResourses::LightTarget, 4 );
|
||||||
|
Oyster::Core::DeviceContext->CSSetShaderResources(0,5, Oyster::Resources::PipeLineResourses::GeometryOut);
|
||||||
|
Oyster::Resources::Buffers::CBufferPipelineCs.Apply();
|
||||||
|
Oyster::Core::DeviceContext->CSSetShaderResources( 6, 4, Oyster::Resources::PipeLineResourses::ComputeResources );
|
||||||
|
Oyster::Shader::Set::SetCompute( Oyster::Shader::Get::GetCompute("Pass0") );
|
||||||
|
|
||||||
|
Oyster::Core::DeviceContext->Dispatch( 49, 36, 1 );
|
||||||
|
|
||||||
|
//clean Pipeline
|
||||||
|
Oyster::Core::DeviceContext->CSSetShaderResources( 0, 16, Oyster::Resources::PipeLineResourses::SrvNulls );
|
||||||
|
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews( 0, 8, Oyster::Resources::PipeLineResourses::uavNULL, 0 );
|
||||||
|
|
||||||
|
//Blurr
|
||||||
|
//Blur( 2 );
|
||||||
|
//Blur( 3 );
|
||||||
|
|
||||||
|
//clean Pipeline
|
||||||
|
Oyster::Core::DeviceContext->CSSetShaderResources( 0, 16, Oyster::Resources::PipeLineResourses::SrvNulls );
|
||||||
|
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews( 0, 8, Oyster::Resources::PipeLineResourses::uavNULL, 0 );
|
||||||
|
|
||||||
|
//prepare and render final pass
|
||||||
|
Oyster::Engine::PrepareForRendering::BindBackBufferAsUAV();
|
||||||
|
Oyster::Shader::Set::SetCompute( Oyster::Shader::Get::GetCompute("Pass1") );
|
||||||
|
Oyster::Core::DeviceContext->CSSetShaderResources( 0, 4, Oyster::Resources::PipeLineResourses::LightOut );
|
||||||
|
|
||||||
|
Oyster::Core::DeviceContext->Dispatch( 49, 36, 1 );
|
||||||
|
|
||||||
|
//clean Pipeline
|
||||||
|
Oyster::Core::DeviceContext->CSSetShaderResources( 0, 16, Oyster::Resources::PipeLineResourses::SrvNulls );
|
||||||
|
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews( 0, 8, Oyster::Resources::PipeLineResourses::uavNULL, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//States
|
||||||
|
int Oyster::Engine::States::GetNrOfSSAOSamples()
|
||||||
|
{
|
||||||
|
return instance.States.NrOfSamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::States::SetNrOfSSAOSamples(int nr)
|
||||||
|
{
|
||||||
|
instance.States.NrOfSamples = nr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Oyster::Engine::States::GetSSAOSampleSpread()
|
||||||
|
{
|
||||||
|
return instance.States.SampleSpread;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::States::SetSSAOSampleSpread(int spread)
|
||||||
|
{
|
||||||
|
instance.States.SampleSpread = spread;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Oyster::Engine::States::GetMaxPointlights()
|
||||||
|
{
|
||||||
|
return instance.States.NrOfPointlights;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Engine::States::SetMaxPointlights(int nr)
|
||||||
|
{
|
||||||
|
instance.States.NrOfPointlights = nr;
|
||||||
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef Engine_h
|
||||||
|
#define Engine_h
|
||||||
|
|
||||||
|
#define NOMINMAX // Because I hate Microsoft now. ~Angry Dan. http://lolengine.net/blog/2011/3/4/fuck-you-microsoft-near-far-macros
|
||||||
|
|
||||||
|
#include "EngineIncludes.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
class Engine
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Engine();
|
||||||
|
~Engine();
|
||||||
|
|
||||||
|
public:
|
||||||
|
class Init
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Setup
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
bool InitWindow;
|
||||||
|
LPCSTR appname;
|
||||||
|
LPCSTR classname;
|
||||||
|
HINSTANCE hinstance;
|
||||||
|
int nCmdShow;
|
||||||
|
WNDPROC wProc;
|
||||||
|
bool ManageWindow;
|
||||||
|
}Window;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int NrOfBuffers;
|
||||||
|
bool MSAA_Quality;
|
||||||
|
bool Fullscreen;
|
||||||
|
bool SingleThreaded;
|
||||||
|
bool Reference;
|
||||||
|
bool ForceDX11;
|
||||||
|
bool GenerateDepthStencil;
|
||||||
|
bool BindDefault;
|
||||||
|
}Common;
|
||||||
|
//all but Window params have Default Values
|
||||||
|
Setup()
|
||||||
|
{
|
||||||
|
Common.NrOfBuffers=1;
|
||||||
|
Common.MSAA_Quality = false;
|
||||||
|
Common.Fullscreen = true;
|
||||||
|
Common.SingleThreaded = true;
|
||||||
|
Common.Reference = false;
|
||||||
|
Common.ForceDX11 = false;
|
||||||
|
Common.GenerateDepthStencil = true;
|
||||||
|
Common.BindDefault = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool IsInstanced();
|
||||||
|
|
||||||
|
//Creates Device and DeviceContext, if not Initialized
|
||||||
|
static bool Instance(bool SingleThreaded=true,bool Reference=false,bool ForceDX11=false);
|
||||||
|
static bool HasSwapChain();
|
||||||
|
|
||||||
|
//Creates Swapchain, if not Aready Created
|
||||||
|
static bool CreateSwapChain(HWND Window, int NrofBuffers=1,bool MSAA_Quality=false,bool Fullscreen=true);
|
||||||
|
|
||||||
|
//CreateWindow, if Not Already Created
|
||||||
|
static bool InitializeWindow(const LPCSTR appName, const LPCSTR className,const HINSTANCE &hInstance, const int &nCmdShow, WNDPROC wProc, bool HandleLoop = false );
|
||||||
|
|
||||||
|
//Performs a full initialization of a rendering pipeline, including a Window
|
||||||
|
static bool FullInit(const Setup& setup);
|
||||||
|
struct Buffers
|
||||||
|
{
|
||||||
|
static Buffer* CreateBuffer(const Buffer::BUFFER_INIT_DESC BufferDesc);
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
Init();
|
||||||
|
~Init();
|
||||||
|
};
|
||||||
|
|
||||||
|
class States
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//SSAO Quality
|
||||||
|
static void SetNrOfSSAOSamples(int);
|
||||||
|
static int GetNrOfSSAOSamples();
|
||||||
|
|
||||||
|
//SSAO Frequency
|
||||||
|
static void SetSSAOSampleSpread(int);
|
||||||
|
static int GetSSAOSampleSpread();
|
||||||
|
|
||||||
|
//PointLights
|
||||||
|
static void SetMaxPointlights(int);
|
||||||
|
static int GetMaxPointlights();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
States();
|
||||||
|
~States();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Render
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Render a number of models, setting the Per model data to the included cBuffer
|
||||||
|
/// specify NULL if no such data exists
|
||||||
|
static void Geometry(const Oyster::Render::Model* models,int count,Oyster::Buffer* cBufferEveryObject, int slot);
|
||||||
|
static void Text(std::string text, Oyster::Math::Float2 size, Oyster::Math::Float3 Pos);
|
||||||
|
//static void TextBox(const Oyster::Render::
|
||||||
|
|
||||||
|
//ensure that a compatible 2D shadereffect is applied
|
||||||
|
static void ScreenQuad(ID3D11ShaderResourceView* srv, float ZPos=1);
|
||||||
|
|
||||||
|
//ensure that a compatible 2D shadereffect is applied and that pos.z is between 0 and 1
|
||||||
|
static void Sprite(ID3D11ShaderResourceView* srv, Oyster::Math::Float2 size, Oyster::Math::Float3 Pos);
|
||||||
|
|
||||||
|
static void PresentScene();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Render();
|
||||||
|
~Render();
|
||||||
|
};
|
||||||
|
|
||||||
|
class PrepareForRendering
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//Binds several rendertargets and a depthstencil
|
||||||
|
static void BindRenderTargets(ID3D11RenderTargetView** RenderTargets,int NrOfTargets,ID3D11DepthStencilView* depth);
|
||||||
|
|
||||||
|
//Binds several Rendertargest and a default depthstencil
|
||||||
|
static void BindRenderTargets(ID3D11RenderTargetView** RenderTargets,int NrOfTargets);
|
||||||
|
|
||||||
|
//Binds the backbuffer and a depthstencil
|
||||||
|
static void BindBackBuffer(ID3D11DepthStencilView* depth);
|
||||||
|
|
||||||
|
//Binds the backbuffer and a default depthstencil
|
||||||
|
static void BindBackBuffer();
|
||||||
|
|
||||||
|
//Binds the backbuffer to the compute shader
|
||||||
|
static void BindBackBufferAsUAV();
|
||||||
|
|
||||||
|
//binds several UAV to the computeshader
|
||||||
|
static void BindUAV(ID3D11UnorderedAccessView** uav, int NrOfUavs);
|
||||||
|
|
||||||
|
//Clears the backbuffer and default depthstencil
|
||||||
|
static void ClearBackBuffer(Math::Float4 color);
|
||||||
|
|
||||||
|
static void Begin2DRender();
|
||||||
|
|
||||||
|
static void Begin2DTextRender();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Pipeline
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class Deffered_Lightning
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//Basic Setup
|
||||||
|
static void NewFrame(const Float4& Color, const Matrix& View, const Matrix& Projection);
|
||||||
|
|
||||||
|
//Geometry Pass
|
||||||
|
static void BeginRenderGeometry();
|
||||||
|
static void RenderGeometry(const Oyster::Render::Model* models,int count);
|
||||||
|
static void EndRenderGeometry();
|
||||||
|
|
||||||
|
//Lightning Pass
|
||||||
|
static void InputPointLights(Oyster::Resources::BufferDefinitions::PointLightDescription *p, int NrOfPointlights );
|
||||||
|
static void RenderLightning();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,38 @@
|
||||||
|
//Oyster
|
||||||
|
|
||||||
|
// Render
|
||||||
|
#include "Render\Model.h"
|
||||||
|
#include "Render\Camera.h"
|
||||||
|
#include "Render\TextBox.h"
|
||||||
|
|
||||||
|
// Core
|
||||||
|
#include "Core\Core.h"
|
||||||
|
#include "Core\Buffer.h"
|
||||||
|
|
||||||
|
// Shader
|
||||||
|
#include "Shader\Shader.h"
|
||||||
|
|
||||||
|
// Math
|
||||||
|
#include "Math\OysterMath.h"
|
||||||
|
|
||||||
|
// FileLoader
|
||||||
|
#include "FileLoader\ObjReader.h"
|
||||||
|
|
||||||
|
// Windows
|
||||||
|
#include "Window\Window.h"
|
||||||
|
|
||||||
|
// Input
|
||||||
|
#include "Input\InputController.h"
|
||||||
|
|
||||||
|
// Collision
|
||||||
|
#include "Collision\Collision.h"
|
||||||
|
|
||||||
|
// Game Definitions
|
||||||
|
#include "Game\OysterGame.h"
|
||||||
|
|
||||||
|
// Resources
|
||||||
|
#include "Resourses\ShaderEffects.h"
|
||||||
|
#include "Resourses\Buffers.h"
|
||||||
|
#include "Resourses\PipelineResources.h"
|
||||||
|
#include "Resourses\GraphicsDefinitions.h"
|
||||||
|
#include "Resourses\Manager.h"
|
|
@ -0,0 +1,268 @@
|
||||||
|
#include "ObjReader.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
#include "..\Core\Core.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Oyster::FileLoaders;
|
||||||
|
using namespace Oyster;
|
||||||
|
using namespace Oyster::Math;
|
||||||
|
|
||||||
|
ObjReader *ObjReader::LoadFile(std::string fileName, Oyster::Math::Float4x4 transform)
|
||||||
|
{
|
||||||
|
static std::map<std::string, ObjReader *> cache;
|
||||||
|
|
||||||
|
ObjReader *reader = NULL;
|
||||||
|
|
||||||
|
if (cache.count(fileName))
|
||||||
|
{
|
||||||
|
reader = cache[fileName];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reader = new ObjReader();
|
||||||
|
reader->ParseFile(fileName, transform);
|
||||||
|
|
||||||
|
cache[fileName] = reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjReader::ObjReader(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ObjReader::~ObjReader(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjReader::ParseFile(std::string fileName, Float4x4 transform)
|
||||||
|
{
|
||||||
|
ifstream input;
|
||||||
|
input.open(fileName.c_str());
|
||||||
|
|
||||||
|
if(!input.is_open())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string path;
|
||||||
|
Utility::String::extractDirPath(path,fileName,'\\');
|
||||||
|
|
||||||
|
std::vector<Vertex> VertexList;
|
||||||
|
std::vector<Float3> vList;
|
||||||
|
std::vector<Float3> nList;
|
||||||
|
std::vector<Float2> uvList;
|
||||||
|
Vertex vertex1, vertex2, vertex3;
|
||||||
|
Float3 face[3];
|
||||||
|
Float3 position, normal;
|
||||||
|
Float2 uv;
|
||||||
|
string s;
|
||||||
|
|
||||||
|
while(!input.eof())
|
||||||
|
{
|
||||||
|
getline(input,s);
|
||||||
|
int offset = (int)s.find(' ');
|
||||||
|
|
||||||
|
if(offset!=-1)
|
||||||
|
{
|
||||||
|
string c = s.substr(0,offset);
|
||||||
|
|
||||||
|
if(c=="v")
|
||||||
|
{
|
||||||
|
position = readVertex(offset,s);
|
||||||
|
vList.push_back(position);
|
||||||
|
}
|
||||||
|
else if(c=="vt")
|
||||||
|
{
|
||||||
|
uv = readUV(offset,s);
|
||||||
|
uvList.push_back(uv);
|
||||||
|
}
|
||||||
|
else if(c=="vn")
|
||||||
|
{
|
||||||
|
normal = readNormal(offset,s);
|
||||||
|
nList.push_back(normal);
|
||||||
|
}
|
||||||
|
else if(c=="f")
|
||||||
|
{
|
||||||
|
readFace(offset, s, face);
|
||||||
|
|
||||||
|
vertex1.Position = vList[(int)face[0].x];
|
||||||
|
vertex1.UV = uvList[(int)face[0].y];
|
||||||
|
vertex1.Normal = nList[(int)face[0].z];
|
||||||
|
|
||||||
|
vertex2.Position = vList[(int)face[1].x];
|
||||||
|
vertex2.UV = uvList[(int)face[1].y];
|
||||||
|
vertex2.Normal = nList[(int)face[1].z];
|
||||||
|
|
||||||
|
vertex3.Position = vList[(int)face[2].x];
|
||||||
|
vertex3.UV = uvList[(int)face[2].y];
|
||||||
|
vertex3.Normal = nList[(int)face[2].z];
|
||||||
|
|
||||||
|
VertexList.push_back(vertex1);
|
||||||
|
VertexList.push_back(vertex3);
|
||||||
|
VertexList.push_back(vertex2);
|
||||||
|
}
|
||||||
|
else if(c=="mtllib")
|
||||||
|
{
|
||||||
|
this->materials = GetMaterials(path+s.substr(offset+1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input.close();
|
||||||
|
|
||||||
|
this->numVertices = VertexList.size();
|
||||||
|
this->vertices = new Vertex[this->numVertices];
|
||||||
|
|
||||||
|
for(size_t i=0;i<this->numVertices;++i)
|
||||||
|
{
|
||||||
|
vertices[i].Position=Math::transformVector(Math::Float4(VertexList[i].Position,1),transform);
|
||||||
|
vertices[i].Normal=Math::transformVector(Math::Float4(VertexList[i].Normal,0),transform);
|
||||||
|
vertices[i].UV = VertexList[i].UV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjReader::GetVertexData(Vertex **vertex,int &numVertex, std::map<std::string, ID3D11ShaderResourceView *> &Textures)
|
||||||
|
{
|
||||||
|
numVertex=(int)this->numVertices;
|
||||||
|
(*vertex)=this->vertices;
|
||||||
|
Textures = this->materials;
|
||||||
|
}
|
||||||
|
|
||||||
|
Float3 ObjReader::extract(std::string d)
|
||||||
|
{
|
||||||
|
Float3 data;
|
||||||
|
int offset=(int)d.find('/');
|
||||||
|
data.x=(float)atoi(d.substr(1,offset).c_str())-1;
|
||||||
|
|
||||||
|
int newOffset = (int)d.find('/',offset+1);
|
||||||
|
string d2=d.substr(offset+1,newOffset-offset-1);
|
||||||
|
data.y=(float)atoi(d2.c_str())-1;
|
||||||
|
offset=newOffset;
|
||||||
|
|
||||||
|
newOffset = (int)d.find('/',offset+1);
|
||||||
|
string d3=d.substr(offset+1,newOffset-offset-1);
|
||||||
|
data.z=(float)atoi(d3.c_str())-1;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
Float3 ObjReader::readVertex(int offset,string s)
|
||||||
|
{
|
||||||
|
int newOffset = (int)s.find(' ',offset+1);
|
||||||
|
Float3 vertex;
|
||||||
|
string d = s.substr(offset,newOffset-offset);
|
||||||
|
vertex.x = (float)atof(d.c_str());
|
||||||
|
offset=newOffset;
|
||||||
|
|
||||||
|
newOffset = (int)s.find(' ',offset+1);
|
||||||
|
vertex.y = (float)atof(s.substr(offset,newOffset-offset).c_str());
|
||||||
|
offset=newOffset;
|
||||||
|
|
||||||
|
newOffset = (int)s.find(' ',offset+1);
|
||||||
|
vertex.z = (float)-atof(s.substr(offset,newOffset-offset).c_str());
|
||||||
|
|
||||||
|
return vertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
Float2 ObjReader::readUV(int offset,string s)
|
||||||
|
{
|
||||||
|
int newOffset = (int)s.find(' ',offset+1);
|
||||||
|
Float2 uv;
|
||||||
|
string d = s.substr(offset,newOffset-offset);
|
||||||
|
uv.x =(float)atof(d.c_str());
|
||||||
|
offset=newOffset;
|
||||||
|
|
||||||
|
newOffset = (int)s.find(' ',offset+1);
|
||||||
|
d = s.substr(offset,newOffset-offset);
|
||||||
|
uv.y =1- (float)atof(d.c_str());
|
||||||
|
offset=newOffset;
|
||||||
|
|
||||||
|
return uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
Float3 ObjReader::readNormal(int offset,string s)
|
||||||
|
{
|
||||||
|
int newOffset = (int)s.find(' ',offset+1);
|
||||||
|
Float3 vertex;
|
||||||
|
string d = s.substr(offset,newOffset-offset);
|
||||||
|
vertex.x = (float)atof(d.c_str());
|
||||||
|
offset=newOffset;
|
||||||
|
|
||||||
|
newOffset = (int)s.find(' ',offset+1);
|
||||||
|
vertex.y = (float)atof(s.substr(offset,newOffset-offset).c_str());
|
||||||
|
offset=newOffset;
|
||||||
|
|
||||||
|
newOffset = (int)s.find(' ',offset+1);
|
||||||
|
vertex.z = (float)-atof(s.substr(offset,newOffset-offset).c_str());
|
||||||
|
|
||||||
|
return vertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjReader::readFace(int offset,string s, Oyster::Math::Float3 face[3])
|
||||||
|
{
|
||||||
|
int newOffset = (int)s.find(' ',offset+1);
|
||||||
|
string point1 = s.substr(offset,newOffset-offset);
|
||||||
|
|
||||||
|
offset = newOffset;
|
||||||
|
newOffset = (int)s.find(' ',offset+1);
|
||||||
|
string point2 = s.substr(offset,newOffset-offset);
|
||||||
|
|
||||||
|
offset = newOffset;
|
||||||
|
newOffset = (int)s.find(' ',offset+1);
|
||||||
|
string point3 = s.substr(offset,newOffset-offset);
|
||||||
|
|
||||||
|
face[0] = extract(point1);
|
||||||
|
face[1] = extract(point2);
|
||||||
|
face[2] = extract(point3);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, ID3D11ShaderResourceView *> ObjReader::GetMaterials(std::string fileName)
|
||||||
|
{
|
||||||
|
ifstream input;
|
||||||
|
input.open(fileName.c_str());
|
||||||
|
|
||||||
|
std::map<std::string, ID3D11ShaderResourceView *> materials;
|
||||||
|
ID3D11ShaderResourceView *srv;
|
||||||
|
string texture;
|
||||||
|
string s;
|
||||||
|
string path;
|
||||||
|
Utility::String::extractDirPath(path,fileName,'\\');
|
||||||
|
if(!input.is_open())
|
||||||
|
return materials;
|
||||||
|
|
||||||
|
while(!input.eof())
|
||||||
|
{
|
||||||
|
getline(input,s);
|
||||||
|
int offset = (int)s.find(' ');
|
||||||
|
if(offset!=-1)
|
||||||
|
{
|
||||||
|
string c = s.substr(0,offset);
|
||||||
|
if(c=="map_Kd")
|
||||||
|
{
|
||||||
|
texture = path+s.substr(offset+1);
|
||||||
|
D3DX11CreateShaderResourceViewFromFile(Oyster::Core::Device,texture.c_str(), NULL, NULL, &srv, NULL);
|
||||||
|
materials["Diffuse"] = srv;
|
||||||
|
}
|
||||||
|
if(c=="map_G")
|
||||||
|
{
|
||||||
|
texture = path+s.substr(offset+1);
|
||||||
|
D3DX11CreateShaderResourceViewFromFile(Oyster::Core::Device,texture.c_str(), NULL, NULL, &srv, NULL);
|
||||||
|
materials["Glow"] = srv;
|
||||||
|
}
|
||||||
|
if(c=="map_Ks")
|
||||||
|
{
|
||||||
|
texture = path+s.substr(offset+1);
|
||||||
|
D3DX11CreateShaderResourceViewFromFile(Oyster::Core::Device,texture.c_str(), NULL, NULL, &srv, NULL);
|
||||||
|
materials["Specular"] = srv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input.close();
|
||||||
|
|
||||||
|
return materials;
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
#pragma once
|
||||||
|
#include "..\Core\CoreIncludes.h"
|
||||||
|
#include "..\Math\OysterMath.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace FileLoaders
|
||||||
|
{
|
||||||
|
class ObjReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Vertex
|
||||||
|
{
|
||||||
|
Oyster::Math::Float3 Position;
|
||||||
|
Oyster::Math::Float3 Normal;
|
||||||
|
Oyster::Math::Float2 UV;
|
||||||
|
};
|
||||||
|
|
||||||
|
static ObjReader *LoadFile(std::string fileName, Oyster::Math::Float4x4 transform = Oyster::Math::Float4x4::identity);
|
||||||
|
|
||||||
|
ObjReader(void);
|
||||||
|
~ObjReader(void);
|
||||||
|
|
||||||
|
void GetVertexData(Vertex **vertex,int &numVertex, std::map<std::string, ID3D11ShaderResourceView *> &textures);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vertex *vertices;
|
||||||
|
size_t numVertices;
|
||||||
|
std::map<std::string, ID3D11ShaderResourceView *> materials;
|
||||||
|
|
||||||
|
void ParseFile(std::string fileName, Oyster::Math::Float4x4 transform = Oyster::Math::Float4x4::identity);
|
||||||
|
|
||||||
|
Oyster::Math::Float3 extract(std::string d);
|
||||||
|
Oyster::Math::Float3 readVertex(int offset,std::string s);
|
||||||
|
Oyster::Math::Float2 readUV(int offset,std::string s);
|
||||||
|
Oyster::Math::Float3 readNormal(int offset,std::string s);
|
||||||
|
void readFace(int offset,std::string s, Oyster::Math::Float3 face[3]);
|
||||||
|
|
||||||
|
std::map<std::string, ID3D11ShaderResourceView *> GetMaterials(std::string fileName);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,157 @@
|
||||||
|
#include "Camera.h"
|
||||||
|
//Hack: temp include, calc proj matrix properly later
|
||||||
|
#include "..\Core\CoreIncludes.h"
|
||||||
|
|
||||||
|
using namespace Oyster;
|
||||||
|
using namespace Render;
|
||||||
|
using namespace Oyster::Math;
|
||||||
|
Camera::Camera(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Camera::~Camera(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Math::Float3 Camera::GetPosition() {return pos;}
|
||||||
|
void Camera::SetPosition(Math::Float3 p){ pos=p;}
|
||||||
|
|
||||||
|
//axis
|
||||||
|
Math::Float3 Camera::GetRight() {return right;}
|
||||||
|
Math::Float3 Camera::GetUp() {return up;}
|
||||||
|
Math::Float3 Camera::GetLook() {return look;}
|
||||||
|
|
||||||
|
//frustrum
|
||||||
|
float Camera::GetNearZ(){return nearZ;}
|
||||||
|
float Camera::GetFarZ(){return farZ;}
|
||||||
|
float Camera::GetAspect(){return aspect;}
|
||||||
|
float Camera::GetFovY(){return fovY;}
|
||||||
|
float Camera::GetFovX(){return fovX;}
|
||||||
|
|
||||||
|
//set frustrum
|
||||||
|
void Camera::SetLens(float fovY, float aspect, float zn, float zf)
|
||||||
|
{
|
||||||
|
this->fovY=fovY;
|
||||||
|
this->aspect=aspect;
|
||||||
|
nearZ=zn;
|
||||||
|
farZ=zf;
|
||||||
|
D3DXMATRIX P;
|
||||||
|
D3DXMatrixPerspectiveFovLH(&P,fovY,aspect,zn,zf);
|
||||||
|
mProj = Math::Float4x4(P);
|
||||||
|
}
|
||||||
|
|
||||||
|
//normal LookAt
|
||||||
|
void Camera::LookAt(Math::Float3 pos, Math::Float3 target, Math::Float3 worldUp)
|
||||||
|
{
|
||||||
|
look=target;
|
||||||
|
up=worldUp;
|
||||||
|
this->pos=pos;
|
||||||
|
right = up.cross(look);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get Matrices
|
||||||
|
Matrix Camera::View(){return mView;}
|
||||||
|
Matrix Camera::Proj(){return mProj;}
|
||||||
|
Matrix Camera::ViewProj()
|
||||||
|
{
|
||||||
|
return (mView * mProj).transpose(); // edited by Dan 04-19
|
||||||
|
}
|
||||||
|
|
||||||
|
//Move Camera
|
||||||
|
//FIX: Multiply Add not working
|
||||||
|
//FIX: Single Float Duplicate Creation
|
||||||
|
void Camera::Strafe(float d)
|
||||||
|
{
|
||||||
|
Math::Float3 s= Math::Float3(d,d,d);
|
||||||
|
pos= (Math::operator*(s,right)) + pos;
|
||||||
|
}
|
||||||
|
void Camera::Walk(float d)
|
||||||
|
{
|
||||||
|
Math::Float3 s= Math::Float3(d,d,d);
|
||||||
|
pos= (Math::operator*(s,look)) + pos;
|
||||||
|
}
|
||||||
|
void Camera::Fly(float d)
|
||||||
|
{
|
||||||
|
Math::Float3 s= Math::Float3(d,d,d);
|
||||||
|
pos= (Math::operator*(s,up)) + pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Rotate Camera
|
||||||
|
//FIX: Float3 * float4x4
|
||||||
|
void Camera::Pitch(float angle)
|
||||||
|
{
|
||||||
|
Matrix m;
|
||||||
|
Math::rotationMatrix(m,angle,right);
|
||||||
|
m = m.getAdjoint().getInverse();
|
||||||
|
|
||||||
|
up = (Math::Float4(up,0) * m).xyz;
|
||||||
|
look = (Math::Float4(look,0) * m).xyz;
|
||||||
|
}
|
||||||
|
void Camera::Yaw(float angle)
|
||||||
|
{
|
||||||
|
|
||||||
|
Matrix m;
|
||||||
|
Math::rotationMatrix(m,angle,up);
|
||||||
|
m = m.getAdjoint().getInverse();
|
||||||
|
|
||||||
|
right = (Math::Float4(right,0) * m).xyz;
|
||||||
|
look = (Math::Float4(look,0) * m).xyz;
|
||||||
|
}
|
||||||
|
void Camera::Roll(float angle)
|
||||||
|
{
|
||||||
|
Matrix m;
|
||||||
|
Math::rotationMatrix(m, angle,look);
|
||||||
|
m = m.getAdjoint().getInverse();
|
||||||
|
|
||||||
|
up = (Math::Float4(up,0) * m).xyz;
|
||||||
|
right = (Math::Float4(right,0) * m).xyz;
|
||||||
|
}
|
||||||
|
void Camera::RotateY(float angle)
|
||||||
|
{
|
||||||
|
Matrix m;
|
||||||
|
|
||||||
|
Math::rotationMatrix_AxisY(m, angle);
|
||||||
|
|
||||||
|
m = m.getAdjoint().getInverse();
|
||||||
|
|
||||||
|
up = (Math::Float4(up,0) * m).xyz;
|
||||||
|
look = (Math::Float4(look,0) * m).xyz;
|
||||||
|
right = (Math::Float4(right,0) * m).xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::UpdateViewMatrix()
|
||||||
|
{
|
||||||
|
look.normalize();
|
||||||
|
|
||||||
|
up = look.cross(right);
|
||||||
|
up.normalize();
|
||||||
|
|
||||||
|
right = up.cross(look);
|
||||||
|
|
||||||
|
float x = -pos.dot(right);
|
||||||
|
float y = -pos.dot(up);
|
||||||
|
float z = -pos.dot(look);
|
||||||
|
|
||||||
|
mView.m[0][0] = right.x;
|
||||||
|
mView.m[1][0] = right.y;
|
||||||
|
mView.m[2][0] = right.z;
|
||||||
|
mView.m[3][0] = x;
|
||||||
|
|
||||||
|
mView.m[0][1] = up.x;
|
||||||
|
mView.m[1][1] = up.y;
|
||||||
|
mView.m[2][1] = up.z;
|
||||||
|
mView.m[3][1] = y;
|
||||||
|
|
||||||
|
mView.m[0][2] = look.x;
|
||||||
|
mView.m[1][2] = look.y;
|
||||||
|
mView.m[2][2] = look.z;
|
||||||
|
mView.m[3][2] = z;
|
||||||
|
|
||||||
|
mView.m[0][3] = 0.0f;
|
||||||
|
mView.m[1][3] = 0.0f;
|
||||||
|
mView.m[2][3] = 0.0f;
|
||||||
|
mView.m[3][3] = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "..\Math\OysterMath.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Render
|
||||||
|
{
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Camera(void);
|
||||||
|
~Camera(void);
|
||||||
|
|
||||||
|
//position
|
||||||
|
Math::Float3 GetPosition();
|
||||||
|
void SetPosition(Math::Float3);
|
||||||
|
|
||||||
|
//axis
|
||||||
|
Math::Float3 GetRight();
|
||||||
|
Math::Float3 GetUp();
|
||||||
|
Math::Float3 GetLook();
|
||||||
|
|
||||||
|
//frustrum
|
||||||
|
float GetNearZ();
|
||||||
|
float GetFarZ();
|
||||||
|
float GetAspect();
|
||||||
|
float GetFovY();
|
||||||
|
float GetFovX();
|
||||||
|
|
||||||
|
//set frustrum
|
||||||
|
void SetLens(float fovY, float aspect, float zn, float zf);
|
||||||
|
|
||||||
|
//normal LookAt
|
||||||
|
void LookAt(Math::Float3 pos, Math::Float3 target, Math::Float3 worldUp);
|
||||||
|
|
||||||
|
//Get Matrices
|
||||||
|
Math::Matrix View();
|
||||||
|
Math::Matrix Proj();
|
||||||
|
Math::Matrix ViewProj();
|
||||||
|
|
||||||
|
//Move Camera
|
||||||
|
void Strafe(float d);
|
||||||
|
void Walk(float d);
|
||||||
|
void Fly(float d);
|
||||||
|
|
||||||
|
//Rotate Camera
|
||||||
|
void Pitch(float angle);
|
||||||
|
void Yaw(float angle);
|
||||||
|
void Roll(float angle);
|
||||||
|
void RotateY(float angle);
|
||||||
|
|
||||||
|
void UpdateViewMatrix();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Math::Vector3 pos, right, up, look;
|
||||||
|
float nearZ,farZ,aspect,fovX,fovY;
|
||||||
|
Math::Matrix mView, mProj;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Engine\Math\OysterMath.h"
|
||||||
|
|
||||||
|
struct DirectionalLight
|
||||||
|
{
|
||||||
|
Oyster::Math::Float4 Irradiance;
|
||||||
|
Oyster::Math::Float4 Direction;
|
||||||
|
};
|
|
@ -0,0 +1,32 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef Mesh_h
|
||||||
|
#define Mesh_h
|
||||||
|
|
||||||
|
//#include "../Engine.h"
|
||||||
|
|
||||||
|
|
||||||
|
//#include "..\Core\CoreIncludes.h"
|
||||||
|
//#include "..\Core\Buffer.h"
|
||||||
|
#include "OysterMath.h"
|
||||||
|
//#include "ICollideable.h"
|
||||||
|
#include "ModelInfo.h"
|
||||||
|
|
||||||
|
using namespace Oyster::Math;
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Render
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Model
|
||||||
|
{
|
||||||
|
ModelInfo* info;
|
||||||
|
Float4x4 *World;
|
||||||
|
bool Visible;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef MODELINFO_h
|
||||||
|
#define MODELINFO_h
|
||||||
|
|
||||||
|
//#include "../Engine.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "..\Core\CoreIncludes.h"
|
||||||
|
#include "..\Core\Buffer.h"
|
||||||
|
//#include "OysterMath.h"
|
||||||
|
//#include "ICollideable.h"
|
||||||
|
|
||||||
|
using namespace Oyster::Math;
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Render
|
||||||
|
{
|
||||||
|
struct ModelInfo
|
||||||
|
{
|
||||||
|
std::vector<ID3D11ShaderResourceView*> Material;
|
||||||
|
Oyster::Buffer Vertices,Indecies;
|
||||||
|
bool Indexed;
|
||||||
|
int VertexCount;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,165 @@
|
||||||
|
#include "Textbox.h"
|
||||||
|
using namespace Oyster::Render;
|
||||||
|
|
||||||
|
//int Textbox::NumTextfields=0;
|
||||||
|
Oyster::Buffer Textbox::TextBuffer;
|
||||||
|
int Textbox::NumLetters;
|
||||||
|
//std::vector<TextInstanceData> Textbox::TextInstances;
|
||||||
|
ID3D11ShaderResourceView* Textbox::Texture=NULL;
|
||||||
|
bool Textbox::Init()
|
||||||
|
{
|
||||||
|
//NumTextfields = 0;
|
||||||
|
//NumVertices = 0;
|
||||||
|
//HRESULT test=HRESULT_FAI
|
||||||
|
if(FAILED(CreateVertexBuffer()))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//update(_str, _pos);
|
||||||
|
return true;
|
||||||
|
//return true;
|
||||||
|
}
|
||||||
|
bool Textbox::SetTexture(const char* _file)
|
||||||
|
{
|
||||||
|
if(FAILED(D3DX11CreateShaderResourceViewFromFileA(Oyster::Core::Device, _file, NULL, NULL, &Texture, NULL)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool Textbox::UpdateTextField(std::string _str)
|
||||||
|
{
|
||||||
|
//DEPRECATED
|
||||||
|
//Update(_str);
|
||||||
|
return false;
|
||||||
|
/*UINT _id=TextInstances.size();
|
||||||
|
//TextInstances.resize(_id+1);
|
||||||
|
Text2D newD;
|
||||||
|
TextInstances.push_back(newD);
|
||||||
|
if(FAILED(CreateTextfield(_id)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Update(_id, _str, _pos);
|
||||||
|
TextInstances[_id].Visible=true;
|
||||||
|
TextInstances[_id].World=Float4x4::identity;
|
||||||
|
NumTextfields++;
|
||||||
|
return true;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT Textbox::CreateVertexBuffer()
|
||||||
|
{
|
||||||
|
HRESULT result;
|
||||||
|
//Create vertices
|
||||||
|
/*
|
||||||
|
std::vector<TextData> mVertices;
|
||||||
|
mVertices.resize(4);
|
||||||
|
D3DXVECTOR3 testloc=D3DXVECTOR3(0,0,0);
|
||||||
|
mVertices[0].pos = testloc+D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||||
|
mVertices[1].pos = testloc+D3DXVECTOR3(TEXT_SIZE, 0.0f, 0.0f);
|
||||||
|
mVertices[2].pos = testloc+D3DXVECTOR3(0.0f, TEXT_SIZE, 0.0f);
|
||||||
|
mVertices[3].pos = testloc+D3DXVECTOR3(TEXT_SIZE, TEXT_SIZE, 0.0f);
|
||||||
|
float normaloffset=(1.0f/TEXT_NR_LETTERS);
|
||||||
|
mVertices[0].uv=D3DXVECTOR2(normaloffset,1);
|
||||||
|
mVertices[1].uv=D3DXVECTOR2(0,1);
|
||||||
|
mVertices[2].uv=D3DXVECTOR2(normaloffset,0);
|
||||||
|
mVertices[3].uv=D3DXVECTOR2(0,0);
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Oyster::Buffer::BUFFER_INIT_DESC desc;
|
||||||
|
//desc.ElementSize=sizeof(TextData);
|
||||||
|
//desc.NumElements = mVertices.size();
|
||||||
|
//desc.Type = Oyster::Buffer::BUFFER_TYPE::VERTEX_BUFFER;
|
||||||
|
//desc.Usage = Oyster::Buffer::BUFFER_USAGE::BUFFER_DEFAULT;
|
||||||
|
//desc.InitData = &mVertices[0];
|
||||||
|
|
||||||
|
//result=TextBuffer.Init(desc);
|
||||||
|
//NumVertices=mVertices.size();
|
||||||
|
//TextInstances[_id].NumLetters=0;
|
||||||
|
/*Text2D tmp;
|
||||||
|
tmp.coff=0;
|
||||||
|
tmp.offset=0;
|
||||||
|
tmp.Pos=Float2(0,0);*/
|
||||||
|
Oyster::Buffer::BUFFER_INIT_DESC desc;
|
||||||
|
desc.ElementSize=sizeof(Text2D);
|
||||||
|
desc.NumElements = MAX_LETTER_COUNT;
|
||||||
|
desc.Type = Oyster::Buffer::BUFFER_TYPE::VERTEX_BUFFER;
|
||||||
|
desc.Usage = Oyster::Buffer::BUFFER_USAGE::BUFFER_CPU_WRITE_DISCARD;
|
||||||
|
desc.InitData = 0;
|
||||||
|
result=TextBuffer.Init(desc);
|
||||||
|
NumLetters=0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
HRESULT Textbox::CreateTextfield(int _id)
|
||||||
|
{
|
||||||
|
HRESULT result=E_FAIL;
|
||||||
|
/*if (TextInstances.size()>_id)
|
||||||
|
{
|
||||||
|
TextInstances[_id].NumLetters=0;
|
||||||
|
|
||||||
|
Oyster::Buffer::BUFFER_INIT_DESC desc;
|
||||||
|
desc.ElementSize=sizeof(Text2D);
|
||||||
|
desc.NumElements = MAX_LETTER_COUNT;
|
||||||
|
desc.Type = Oyster::Buffer::BUFFER_TYPE::VERTEX_BUFFER;
|
||||||
|
desc.Usage = Oyster::Buffer::BUFFER_USAGE::BUFFER_CPU_WRITE_DISCARD;
|
||||||
|
desc.InitData = 0;
|
||||||
|
|
||||||
|
result=TextInstances[_id].InstanceBuffer.Init(desc);
|
||||||
|
}*/
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
void Textbox::Update(std::string _str, float _xscale)
|
||||||
|
{
|
||||||
|
UINT instances=0;
|
||||||
|
Text2D tmpInst;
|
||||||
|
|
||||||
|
void* dest = TextBuffer.Map();
|
||||||
|
Text2D* dataView = reinterpret_cast<Text2D*>(dest);
|
||||||
|
//tmpInst.charOffset=_pos;
|
||||||
|
for (unsigned int i=0; i<_str.length(); i++)
|
||||||
|
{
|
||||||
|
tmpInst.coff=(1.0f/TEXT_NR_LETTERS);
|
||||||
|
tmpInst.offset=(_str[i]-32);
|
||||||
|
tmpInst.Pos=i*(0.005f*_xscale);
|
||||||
|
//float tst=getCharID(_str[i]);
|
||||||
|
//tmpInst.offset=tst;
|
||||||
|
//tmpInst.charOffset.x=_pos.x-i*TEXT_SIZE;
|
||||||
|
//tmpInst.data=tst;
|
||||||
|
dataView[instances]=tmpInst;
|
||||||
|
instances++;
|
||||||
|
}
|
||||||
|
NumLetters=instances;
|
||||||
|
//TextInstances[_id].NumLetters=instances;
|
||||||
|
TextBuffer.Unmap();
|
||||||
|
}
|
||||||
|
float Textbox::getCharID(char _in)
|
||||||
|
{
|
||||||
|
//int charid=_in;
|
||||||
|
//float charid=((_in-'0')-32);
|
||||||
|
return ((_in-32)*(1.0f/TEXT_NR_LETTERS));
|
||||||
|
//return _in-'0';
|
||||||
|
}
|
||||||
|
void Textbox::Apply(int _id)
|
||||||
|
{
|
||||||
|
//Check if the subset exists, so we don't try to pain something that isn't there resulting in a crash
|
||||||
|
//if (NumTextfields>_id)
|
||||||
|
//{
|
||||||
|
//Oyster::Core::DeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
|
//Set the size of each vertex "jump", and the start point for the shader
|
||||||
|
//unsigned int strides[2];
|
||||||
|
//offsets start at 0.
|
||||||
|
//unsigned int offsets[2]={0,0};
|
||||||
|
|
||||||
|
//Load the strides with the size of each type
|
||||||
|
//strides[0] = sizeof(TextData);
|
||||||
|
//strides[1] = sizeof(PerCharData);
|
||||||
|
|
||||||
|
//Create an array which points to the buffers needed.
|
||||||
|
//ID3D11Buffer* bufferPointers[2];
|
||||||
|
//bufferPointers[0] = TextBuffer;
|
||||||
|
//bufferPointers[1] = TextInstances[_id].InstanceBuffer;
|
||||||
|
//Load the vertex buffer into the shader
|
||||||
|
//Oyster::Core::DeviceContext->IASetVertexBuffers(0, 2, bufferPointers, strides, offsets);
|
||||||
|
//Get the basic info of the technique that's loaded
|
||||||
|
//}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "..\Engine.h"
|
||||||
|
const int MAX_LETTER_COUNT=60;
|
||||||
|
const int TEXT_NR_LETTERS=95;
|
||||||
|
const float TEXT_SIZE=2.5;
|
||||||
|
struct Text2D
|
||||||
|
{
|
||||||
|
Oyster::Math::Float Pos;
|
||||||
|
int offset;
|
||||||
|
float coff;
|
||||||
|
};
|
||||||
|
/*struct TextInstanceData
|
||||||
|
{
|
||||||
|
Oyster::Buffer InstanceBuffer;
|
||||||
|
bool Visible;
|
||||||
|
int NumLetters;
|
||||||
|
Oyster::Math::Float4x4 World;
|
||||||
|
};*/
|
||||||
|
/*struct TextData
|
||||||
|
{
|
||||||
|
Oyster::Math::Float3 pos;
|
||||||
|
Oyster::Math::Float2 uv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PerCharData
|
||||||
|
{
|
||||||
|
float data;
|
||||||
|
Oyster::Math::Float3 charOffset;
|
||||||
|
};
|
||||||
|
struct TextInstanceData
|
||||||
|
{
|
||||||
|
Oyster::Buffer InstanceBuffer;
|
||||||
|
bool Visible;
|
||||||
|
int NumLetters;
|
||||||
|
Oyster::Math::Float4x4 World;
|
||||||
|
};*/
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Render
|
||||||
|
{
|
||||||
|
class Textbox
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static float getCharID(char _in);
|
||||||
|
static HRESULT CreateVertexBuffer();
|
||||||
|
static HRESULT CreateTextfield(int _id);
|
||||||
|
public:
|
||||||
|
//static Oyster::Buffer TextBuffer;
|
||||||
|
//static int NumVertices;
|
||||||
|
//static std::vector<TextInstanceData> TextInstances;
|
||||||
|
static Oyster::Buffer TextBuffer;
|
||||||
|
static int NumLetters;
|
||||||
|
static ID3D11ShaderResourceView* Texture;
|
||||||
|
|
||||||
|
static bool Init();
|
||||||
|
static bool UpdateTextField(std::string _str);
|
||||||
|
static bool SetTexture(const char* _file);
|
||||||
|
//Updates a textbox with the certain id
|
||||||
|
static void Update(std::string _str, float _scale);
|
||||||
|
//Removes all old instances and recreates it with the input data
|
||||||
|
static HRESULT Reset(int _count, std::string* _str, Float3* _pos);
|
||||||
|
static void Apply(int _id);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include "Buffers.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Resources
|
||||||
|
{
|
||||||
|
Buffer Buffers::V2DSprites = Buffer();
|
||||||
|
Buffer Buffers::CbufferVS = Buffer();
|
||||||
|
Buffer Buffers::CBufferGs = Buffer();
|
||||||
|
Buffer Buffers::CBufferPipelineCs = Buffer();
|
||||||
|
|
||||||
|
void Buffers::Init()
|
||||||
|
{
|
||||||
|
Buffer::BUFFER_INIT_DESC desc;
|
||||||
|
|
||||||
|
desc.ElementSize=sizeof(Math::Float2);
|
||||||
|
desc.NumElements=1;
|
||||||
|
desc.Type = Buffer::BUFFER_TYPE::VERTEX_BUFFER;
|
||||||
|
desc.Usage = Buffer::BUFFER_USAGE::BUFFER_DEFAULT;
|
||||||
|
desc.InitData = &Math::Float2(0,0);
|
||||||
|
|
||||||
|
V2DSprites.Init(desc);
|
||||||
|
|
||||||
|
desc.Type=Buffer::BUFFER_TYPE::CONSTANT_BUFFER_VS;
|
||||||
|
desc.Usage = Buffer::BUFFER_USAGE::BUFFER_CPU_WRITE_DISCARD;
|
||||||
|
desc.ElementSize=sizeof(Math::Float4x4);
|
||||||
|
desc.InitData=0;
|
||||||
|
|
||||||
|
CbufferVS.Init(desc);
|
||||||
|
|
||||||
|
desc.Type = Buffer::BUFFER_TYPE::CONSTANT_BUFFER_GS;
|
||||||
|
|
||||||
|
CBufferGs.Init(desc);
|
||||||
|
|
||||||
|
desc.ElementSize=sizeof(Oyster::Resources::BufferDefinitions::LightStructureBuffer);
|
||||||
|
desc.NumElements=1;
|
||||||
|
desc.Type = Buffer::BUFFER_TYPE::CONSTANT_BUFFER_CS;
|
||||||
|
desc.Usage = Buffer::BUFFER_USAGE::BUFFER_CPU_WRITE_DISCARD;
|
||||||
|
desc.InitData = NULL;
|
||||||
|
|
||||||
|
CBufferPipelineCs.Init(desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../EngineIncludes.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Resources
|
||||||
|
{
|
||||||
|
struct Buffers
|
||||||
|
{
|
||||||
|
static Buffer V2DSprites;
|
||||||
|
|
||||||
|
static Buffer CbufferVS;
|
||||||
|
|
||||||
|
static Buffer CBufferGs;
|
||||||
|
|
||||||
|
static Buffer CBufferPipelineCs;
|
||||||
|
|
||||||
|
static void Init();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include "..\EngineIncludes.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Resources
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace BufferDefinitions
|
||||||
|
{
|
||||||
|
struct LightStructureBuffer
|
||||||
|
{
|
||||||
|
::Oyster::Math::Float4x4 viewMatrix, projectionMatrix;
|
||||||
|
::LinearAlgebra::Vector3<unsigned int> numDispatches;
|
||||||
|
unsigned int reservedPadding;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ScreenTileFrustrum
|
||||||
|
{
|
||||||
|
::Oyster::Math::Float rawElement[6 * 4];
|
||||||
|
};
|
||||||
|
|
||||||
|
class PointLightDescription
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct{ ::Oyster::Math::Float3 center; ::Oyster::Math::Float radius; } pos;
|
||||||
|
::Oyster::Math::Float3 color;
|
||||||
|
::Oyster::Math::Float intensty;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include "Manager.h"
|
||||||
|
|
||||||
|
std::unordered_map< std::string, Oyster::Render::ModelInfo*> Oyster::Resources::Manager::loadedModels = std::unordered_map< std::string, Oyster::Render::ModelInfo*>();
|
||||||
|
|
||||||
|
Oyster::Render::Model* Oyster::Resources::Manager::LoadModel(std::string Filename, Matrix Scale)
|
||||||
|
{
|
||||||
|
//TODO: Add redundncy sheck, to ensure not recreating model
|
||||||
|
|
||||||
|
//Loop to find filename
|
||||||
|
|
||||||
|
//If found Return Model
|
||||||
|
|
||||||
|
//else Create Model
|
||||||
|
|
||||||
|
Oyster::FileLoaders::ObjReader *reader = Oyster::FileLoaders::ObjReader::LoadFile(Filename, Scale);
|
||||||
|
Oyster::FileLoaders::ObjReader::Vertex** vertex = new Oyster::FileLoaders::ObjReader::Vertex*[1];
|
||||||
|
int vcount;
|
||||||
|
std::map<std::string,ID3D11ShaderResourceView *> textures;
|
||||||
|
reader->GetVertexData( vertex, vcount, textures );
|
||||||
|
|
||||||
|
Oyster::Buffer::BUFFER_INIT_DESC desc;
|
||||||
|
desc.ElementSize=sizeof(Oyster::FileLoaders::ObjReader::Vertex);
|
||||||
|
desc.NumElements = vcount;
|
||||||
|
desc.InitData = *vertex;
|
||||||
|
desc.Type = Oyster::Buffer::VERTEX_BUFFER;
|
||||||
|
desc.Usage = Oyster::Buffer::BUFFER_DEFAULT;
|
||||||
|
|
||||||
|
ID3D11ShaderResourceView *srv = textures["Diffuse"];
|
||||||
|
|
||||||
|
Oyster::Render::ModelInfo* m = new Oyster::Render::ModelInfo();
|
||||||
|
|
||||||
|
m->Vertices = *(Oyster::Engine::Init::Buffers::CreateBuffer(desc));
|
||||||
|
m->VertexCount = vcount;
|
||||||
|
m->Material.push_back(srv);
|
||||||
|
srv = textures["Specular"];
|
||||||
|
m->Material.push_back(srv);
|
||||||
|
srv = textures["Glow"];
|
||||||
|
m->Material.push_back(srv);
|
||||||
|
m->Indexed=false;
|
||||||
|
|
||||||
|
Oyster::Render::Model* model = new Oyster::Render::Model();
|
||||||
|
model->info=m;
|
||||||
|
model->Visible = true;
|
||||||
|
model->World = &Oyster::Math::Float4x4(Oyster::Math::Float4x4::identity);
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../EngineIncludes.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Resources
|
||||||
|
{
|
||||||
|
struct Manager
|
||||||
|
{
|
||||||
|
//Expects to be deleted either trough manager or after a clean
|
||||||
|
static Oyster::Render::Model* LoadModel(std::string Filename, Matrix Scale);
|
||||||
|
static void Clean();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::unordered_map< std::string, Oyster::Render::ModelInfo*> loadedModels;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,228 @@
|
||||||
|
#include "PipelineResources.h"
|
||||||
|
|
||||||
|
using namespace Oyster::Resources;
|
||||||
|
|
||||||
|
ID3D11UnorderedAccessView* PipeLineResourses::TempUav = 0;
|
||||||
|
ID3D11ShaderResourceView* PipeLineResourses::TempSrv = 0;
|
||||||
|
|
||||||
|
ID3D11ShaderResourceView* PipeLineResourses::GeometryOut[5] = {0};
|
||||||
|
ID3D11RenderTargetView* PipeLineResourses::GeometryTarget[5] = {0};
|
||||||
|
|
||||||
|
ID3D11ShaderResourceView* PipeLineResourses::ComputeResources[4] = {0};
|
||||||
|
Oyster::Buffer* PipeLineResourses::Resources[2] = {0};
|
||||||
|
|
||||||
|
ID3D11ShaderResourceView* PipeLineResourses::LightOut[4] = {0};
|
||||||
|
ID3D11UnorderedAccessView* PipeLineResourses::LightTarget[4] = {0};
|
||||||
|
|
||||||
|
ID3D11RenderTargetView* PipeLineResourses::RtvNulls[16] = {0};
|
||||||
|
ID3D11ShaderResourceView* PipeLineResourses::SrvNulls[16] = {0};
|
||||||
|
ID3D11UnorderedAccessView* PipeLineResourses::uavNULL[16] = {0};
|
||||||
|
|
||||||
|
Oyster::Collision::Frustrum* PipeLineResourses::SubFrustrums = 0;
|
||||||
|
int PipeLineResourses::FrustrumSize = 0;
|
||||||
|
LinearAlgebra::Vector3<unsigned int> PipeLineResourses::FrustrumDimensions = LinearAlgebra::Vector3<unsigned int>();
|
||||||
|
|
||||||
|
Oyster::Resources::BufferDefinitions::LightStructureBuffer PipeLineResourses::LightData = Oyster::Resources::BufferDefinitions::LightStructureBuffer();
|
||||||
|
|
||||||
|
void PipeLineResourses::Init()
|
||||||
|
{
|
||||||
|
InitGeometry();
|
||||||
|
|
||||||
|
InitSSAOData();
|
||||||
|
InitSubFrustrums();
|
||||||
|
InitPointLights();
|
||||||
|
InitLightData();
|
||||||
|
|
||||||
|
InitLighting();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipeLineResourses::InitGeometry()
|
||||||
|
{
|
||||||
|
D3D11_TEXTURE2D_DESC Tdesc;
|
||||||
|
Tdesc.Width = Oyster::Window::Size.left;
|
||||||
|
Tdesc.Height = Oyster::Window::Size.bottom;
|
||||||
|
Tdesc.MipLevels = Tdesc.ArraySize = 1;
|
||||||
|
Tdesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||||
|
Tdesc.SampleDesc.Count = 1;
|
||||||
|
Tdesc.SampleDesc.Quality=0;
|
||||||
|
Tdesc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
Tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
|
||||||
|
Tdesc.CPUAccessFlags = 0;
|
||||||
|
Tdesc.MiscFlags = 0;
|
||||||
|
|
||||||
|
ID3D11Texture2D *pTexture;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
//Geometry stage resourses
|
||||||
|
for( int i = 0; i < 5; ++i )
|
||||||
|
{
|
||||||
|
hr = Oyster::Core::Device->CreateTexture2D( &Tdesc, NULL, &pTexture );
|
||||||
|
hr = Oyster::Core::Device->CreateShaderResourceView(pTexture,0,&GeometryOut[i]);
|
||||||
|
hr = Oyster::Core::Device->CreateRenderTargetView(pTexture,0,&GeometryTarget[i]);
|
||||||
|
pTexture->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipeLineResourses::InitSSAOData()
|
||||||
|
{
|
||||||
|
//create Half Spheres and Random Data
|
||||||
|
|
||||||
|
Oyster::Buffer::BUFFER_INIT_DESC desc;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
int NrOfSamples = Oyster::Engine::States::GetNrOfSSAOSamples();
|
||||||
|
int SampleSpread = Oyster::Engine::States::GetSSAOSampleSpread();
|
||||||
|
|
||||||
|
Oyster::Math::Vector3* kernel = new Oyster::Math::Vector3[ NrOfSamples ];
|
||||||
|
Oyster::Math::Vector3* random = new Oyster::Math::Vector3[ SampleSpread ];
|
||||||
|
|
||||||
|
for(int i = 0; i < NrOfSamples; ++i)
|
||||||
|
{
|
||||||
|
kernel[i] = Oyster::Math::Vector3::null;
|
||||||
|
while( kernel[i] == Oyster::Math::Vector3::null )
|
||||||
|
{
|
||||||
|
kernel[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 - 0) + 0);
|
||||||
|
}
|
||||||
|
kernel[i].normalize();
|
||||||
|
|
||||||
|
float scale = float(i) / float(NrOfSamples);
|
||||||
|
scale = (0.1f*(1 - scale * scale) + 1.0f *( scale * scale));
|
||||||
|
kernel[i] *= scale;
|
||||||
|
|
||||||
|
if( i < SampleSpread)
|
||||||
|
{
|
||||||
|
random[i] = Oyster::Math::Vector3::null;
|
||||||
|
while( random[i] == Oyster::Math::Vector3::null )
|
||||||
|
{
|
||||||
|
random[i] = Oyster::Math::Vector3(
|
||||||
|
(float)rand() / (RAND_MAX + 1) * (1 - -1)+ -1,
|
||||||
|
(float)rand() / (RAND_MAX + 1) * (1 - -1)+ -1,
|
||||||
|
0.0f);
|
||||||
|
}
|
||||||
|
random[i].normalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
D3D11_TEXTURE1D_DESC T1desc;
|
||||||
|
T1desc.Width = NrOfSamples;
|
||||||
|
T1desc.MipLevels = T1desc.ArraySize = 1;
|
||||||
|
T1desc.Format = DXGI_FORMAT_R32G32B32_FLOAT;
|
||||||
|
T1desc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
T1desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
T1desc.CPUAccessFlags = 0;
|
||||||
|
T1desc.MiscFlags = 0;
|
||||||
|
|
||||||
|
D3D11_SUBRESOURCE_DATA sphere;
|
||||||
|
sphere.pSysMem = kernel;
|
||||||
|
|
||||||
|
D3D11_SUBRESOURCE_DATA rnd;
|
||||||
|
rnd.pSysMem = random;
|
||||||
|
|
||||||
|
|
||||||
|
ID3D11Texture1D *pTexture1[2];
|
||||||
|
|
||||||
|
hr = Oyster::Core::Device->CreateTexture1D( &T1desc, &sphere, &pTexture1[0] );
|
||||||
|
hr = Oyster::Core::Device->CreateShaderResourceView( pTexture1[0], 0, &ComputeResources[3] );
|
||||||
|
pTexture1[0]->Release();
|
||||||
|
delete[] kernel;
|
||||||
|
|
||||||
|
T1desc.Width = SampleSpread;
|
||||||
|
hr = Oyster::Core::Device->CreateTexture1D( &T1desc, &rnd, &pTexture1[1] );
|
||||||
|
hr = Oyster::Core::Device->CreateShaderResourceView( (pTexture1[1]), 0, &ComputeResources[2] );
|
||||||
|
pTexture1[1]->Release();
|
||||||
|
delete[] random;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipeLineResourses::InitSubFrustrums()
|
||||||
|
{
|
||||||
|
FrustrumDimensions.x = (::Oyster::Window::Size.left + 15U) / 16U;
|
||||||
|
FrustrumDimensions.y = (::Oyster::Window::Size.bottom + 15U) / 16U;
|
||||||
|
FrustrumDimensions.z = 1;
|
||||||
|
FrustrumSize = FrustrumDimensions.x * FrustrumDimensions.y * FrustrumDimensions.z;
|
||||||
|
if(SubFrustrums!=0)
|
||||||
|
delete[] SubFrustrums;
|
||||||
|
SubFrustrums = new Frustrum[ FrustrumSize ];
|
||||||
|
|
||||||
|
Oyster::Buffer::BUFFER_INIT_DESC desc;
|
||||||
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||||
|
|
||||||
|
//buffer description for SubFrustrums
|
||||||
|
desc.Usage = Oyster::Buffer::BUFFER_CPU_WRITE_DISCARD;
|
||||||
|
desc.Type = Oyster::Buffer::STRUCTURED_BUFFER;
|
||||||
|
desc.ElementSize = sizeof( ::Oyster::Resources::BufferDefinitions::ScreenTileFrustrum);
|
||||||
|
desc.NumElements = FrustrumSize;
|
||||||
|
desc.InitData = NULL;
|
||||||
|
|
||||||
|
//create matching srv
|
||||||
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||||
|
srvDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||||
|
srvDesc.Buffer.FirstElement = 0;
|
||||||
|
srvDesc.Buffer.NumElements = FrustrumSize;
|
||||||
|
|
||||||
|
PipeLineResourses::Resources[0] = Oyster::Engine::Init::Buffers::CreateBuffer(desc);
|
||||||
|
|
||||||
|
HRESULT hr = Oyster::Core::Device->CreateShaderResourceView( *PipeLineResourses::Resources[0], &srvDesc, &Oyster::Resources::PipeLineResourses::ComputeResources[0] );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipeLineResourses::InitPointLights()
|
||||||
|
{
|
||||||
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||||
|
Oyster::Buffer::BUFFER_INIT_DESC desc;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
//buffer description for pointlight
|
||||||
|
desc.Usage = Oyster::Buffer::BUFFER_CPU_WRITE_DISCARD;
|
||||||
|
desc.Type = Oyster::Buffer::STRUCTURED_BUFFER;
|
||||||
|
desc.ElementSize = sizeof(Oyster::Resources::BufferDefinitions::PointLightDescription);
|
||||||
|
desc.NumElements = Oyster::Engine::States::GetMaxPointlights();
|
||||||
|
desc.InitData = NULL;
|
||||||
|
|
||||||
|
PipeLineResourses::Resources[1] = Oyster::Engine::Init::Buffers::CreateBuffer(desc);
|
||||||
|
|
||||||
|
//create matching srv
|
||||||
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||||
|
srvDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||||
|
srvDesc.Buffer.FirstElement = 0;
|
||||||
|
srvDesc.Buffer.NumElements = Oyster::Engine::States::GetMaxPointlights();
|
||||||
|
|
||||||
|
hr = Oyster::Core::Device->CreateShaderResourceView( *PipeLineResourses::Resources[1], &srvDesc, &Oyster::Resources::PipeLineResourses::ComputeResources[1] );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipeLineResourses::InitLightData()
|
||||||
|
{
|
||||||
|
LightData.numDispatches = FrustrumDimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipeLineResourses::InitLighting()
|
||||||
|
{
|
||||||
|
D3D11_TEXTURE2D_DESC Tdesc;
|
||||||
|
Tdesc.Width = Oyster::Window::Size.left;
|
||||||
|
Tdesc.Height = Oyster::Window::Size.bottom;
|
||||||
|
Tdesc.MipLevels = Tdesc.ArraySize = 1;
|
||||||
|
Tdesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||||
|
Tdesc.SampleDesc.Count = 1;
|
||||||
|
Tdesc.SampleDesc.Quality=0;
|
||||||
|
Tdesc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
Tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
|
||||||
|
Tdesc.CPUAccessFlags = 0;
|
||||||
|
Tdesc.MiscFlags = 0;
|
||||||
|
|
||||||
|
ID3D11Texture2D *pTexture;
|
||||||
|
HRESULT hr;
|
||||||
|
for(int i = 0; i < 4; ++i )
|
||||||
|
{
|
||||||
|
hr = Oyster::Core::Device->CreateTexture2D( &Tdesc, NULL, &pTexture );
|
||||||
|
hr = Oyster::Core::Device->CreateShaderResourceView( pTexture, 0, &(LightOut[i]) );
|
||||||
|
hr = Oyster::Core::Device->CreateUnorderedAccessView( pTexture, 0, &(LightTarget[i]) );
|
||||||
|
pTexture->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = Oyster::Core::Device->CreateTexture2D( &Tdesc, NULL, &pTexture );
|
||||||
|
hr = Oyster::Core::Device->CreateShaderResourceView( pTexture, 0, &TempSrv );
|
||||||
|
hr = Oyster::Core::Device->CreateUnorderedAccessView( pTexture, 0, &TempUav );
|
||||||
|
pTexture->Release();
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef PipeLineResources_H
|
||||||
|
#define PipeLineResources_H
|
||||||
|
|
||||||
|
#include "..\EngineIncludes.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Resources
|
||||||
|
{
|
||||||
|
struct PipeLineResourses
|
||||||
|
{
|
||||||
|
//0 = Diffuse
|
||||||
|
//1 = Specular
|
||||||
|
//2 = Glow
|
||||||
|
//3 = Pos
|
||||||
|
//4 = Normal
|
||||||
|
static ID3D11ShaderResourceView* GeometryOut[5];
|
||||||
|
static ID3D11RenderTargetView* GeometryTarget[5];
|
||||||
|
|
||||||
|
|
||||||
|
//0 = TileBuffer
|
||||||
|
//1 = PointList
|
||||||
|
//2 = Random
|
||||||
|
//3 = Sphere
|
||||||
|
static ID3D11ShaderResourceView* ComputeResources[4];
|
||||||
|
static Oyster::Buffer* Resources[2];
|
||||||
|
|
||||||
|
|
||||||
|
//0 = Diffuse
|
||||||
|
//1 = Specular
|
||||||
|
//2 = Glow
|
||||||
|
//3 = SSAO
|
||||||
|
static ID3D11ShaderResourceView* LightOut[4];
|
||||||
|
static ID3D11UnorderedAccessView* LightTarget[4];
|
||||||
|
|
||||||
|
//0 = BlurTempStorage
|
||||||
|
static ID3D11UnorderedAccessView* TempUav;
|
||||||
|
static ID3D11ShaderResourceView* TempSrv;
|
||||||
|
|
||||||
|
static ID3D11RenderTargetView* RtvNulls[16];
|
||||||
|
static ID3D11ShaderResourceView* SrvNulls[16];
|
||||||
|
static ID3D11UnorderedAccessView* uavNULL[16];
|
||||||
|
|
||||||
|
static Oyster::Collision::Frustrum* SubFrustrums;
|
||||||
|
static int FrustrumSize;
|
||||||
|
static LinearAlgebra::Vector3<unsigned int> FrustrumDimensions;
|
||||||
|
|
||||||
|
static Oyster::Resources::BufferDefinitions::LightStructureBuffer LightData;
|
||||||
|
|
||||||
|
static void Init();
|
||||||
|
|
||||||
|
static void InitGeometry();
|
||||||
|
|
||||||
|
static void InitSSAOData();
|
||||||
|
static void InitSubFrustrums();
|
||||||
|
static void InitPointLights();
|
||||||
|
static void InitLightData();
|
||||||
|
|
||||||
|
static void InitLighting();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,100 @@
|
||||||
|
#include "ShaderEffects.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Resources
|
||||||
|
{
|
||||||
|
Shader::ShaderEffect ShaderEffects::BasicSprite = Shader::ShaderEffect();
|
||||||
|
Shader::ShaderEffect ShaderEffects::Text2DEffect = Shader::ShaderEffect();
|
||||||
|
Shader::ShaderEffect ShaderEffects::ModelEffect = Shader::ShaderEffect();
|
||||||
|
|
||||||
|
void ShaderEffects::Init()
|
||||||
|
{
|
||||||
|
BasicSprite.IAStage.Topology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
|
||||||
|
BasicSprite.Shaders.Vertex = Oyster::Shader::Get::GetVertex("2D");
|
||||||
|
BasicSprite.Shaders.Geometry = Oyster::Shader::Get::GetGeometry("2D");
|
||||||
|
BasicSprite.Shaders.Pixel = Oyster::Shader::Get::GetPixel("Texture0");
|
||||||
|
|
||||||
|
D3D11_BLEND_DESC blendDesc;
|
||||||
|
blendDesc.AlphaToCoverageEnable=false;
|
||||||
|
blendDesc.IndependentBlendEnable=false;
|
||||||
|
blendDesc.RenderTarget[0].BlendEnable=true;
|
||||||
|
|
||||||
|
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
|
||||||
|
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
|
||||||
|
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
||||||
|
|
||||||
|
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||||
|
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
|
||||||
|
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_MAX;
|
||||||
|
|
||||||
|
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||||
|
|
||||||
|
ID3D11BlendState* blender;
|
||||||
|
|
||||||
|
Oyster::Core::Device->CreateBlendState(&blendDesc,&blender);
|
||||||
|
|
||||||
|
BasicSprite.RenderStates.BlendState = blender;
|
||||||
|
|
||||||
|
ID3D11InputLayout* layout;
|
||||||
|
|
||||||
|
Oyster::Shader::CreateInputLayout(SpriteVertexDesc,1,Oyster::Shader::Get::GetVertex("2D"),layout);
|
||||||
|
|
||||||
|
BasicSprite.IAStage.Layout = layout;
|
||||||
|
|
||||||
|
Text2DEffect.IAStage.Topology=D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
|
||||||
|
Text2DEffect.Shaders.Vertex = Oyster::Shader::Get::GetVertex("Text");
|
||||||
|
Text2DEffect.Shaders.Geometry = Oyster::Shader::Get::GetGeometry("Text");
|
||||||
|
Text2DEffect.Shaders.Pixel = Oyster::Shader::Get::GetPixel("Texture0");
|
||||||
|
|
||||||
|
Oyster::Shader::CreateInputLayout(Text2DDesc,3,Oyster::Shader::Get::GetVertex("Text"),layout);
|
||||||
|
|
||||||
|
Text2DEffect.IAStage.Layout = layout;
|
||||||
|
|
||||||
|
blendDesc.AlphaToCoverageEnable = true;
|
||||||
|
Oyster::Core::Device->CreateBlendState(&blendDesc,&blender);
|
||||||
|
Text2DEffect.RenderStates.BlendState = blender;
|
||||||
|
|
||||||
|
ModelEffect.IAStage.Topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||||
|
Oyster::Shader::CreateInputLayout(ModelDesc,3,Oyster::Shader::Get::GetVertex("OBJ"),layout);
|
||||||
|
ModelEffect.IAStage.Layout = layout;
|
||||||
|
|
||||||
|
ModelEffect.Shaders.Vertex = Oyster::Shader::Get::GetVertex("OBJ");
|
||||||
|
ModelEffect.Shaders.Pixel = Oyster::Shader::Get::GetPixel("OBJDEF");
|
||||||
|
|
||||||
|
Oyster::Buffer::BUFFER_INIT_DESC desc;
|
||||||
|
|
||||||
|
desc.ElementSize=sizeof(Oyster::Math::Float4x4);
|
||||||
|
desc.NumElements = 1;
|
||||||
|
desc.Usage = Oyster::Buffer::BUFFER_CPU_WRITE_DISCARD;
|
||||||
|
desc.Type = Oyster::Buffer::CONSTANT_BUFFER_VS;
|
||||||
|
desc.InitData = NULL;
|
||||||
|
|
||||||
|
ModelEffect.CBuffers.Vertex.push_back(Oyster::Engine::Init::Buffers::CreateBuffer(desc));
|
||||||
|
ModelEffect.CBuffers.Vertex.push_back(Oyster::Engine::Init::Buffers::CreateBuffer(desc));
|
||||||
|
|
||||||
|
//use Oyster::Resources::Buffers::CbufferVS for per object data
|
||||||
|
//perObject = Oyster::Engine::Init::Buffers::CreateBuffer(desc);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11_INPUT_ELEMENT_DESC ShaderEffects::SpriteVertexDesc[1] =
|
||||||
|
{
|
||||||
|
{"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
D3D11_INPUT_ELEMENT_DESC ShaderEffects::Text2DDesc[3] =
|
||||||
|
{
|
||||||
|
{"Position",0, DXGI_FORMAT_R32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||||
|
{"Offset",0, DXGI_FORMAT_R32_SINT, 0, 4, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||||
|
{"CharOffset",0, DXGI_FORMAT_R32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
D3D11_INPUT_ELEMENT_DESC ShaderEffects::ModelDesc[3] =
|
||||||
|
{
|
||||||
|
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||||
|
{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||||
|
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Engine.h"
|
||||||
|
#include "Buffers.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Resources
|
||||||
|
{
|
||||||
|
struct ShaderEffects
|
||||||
|
{
|
||||||
|
static Oyster::Shader::ShaderEffect BasicSprite;
|
||||||
|
static Oyster::Shader::ShaderEffect Text2DEffect;
|
||||||
|
static Oyster::Shader::ShaderEffect ModelEffect;
|
||||||
|
|
||||||
|
static void Init();
|
||||||
|
|
||||||
|
static D3D11_INPUT_ELEMENT_DESC SpriteVertexDesc[1];
|
||||||
|
static D3D11_INPUT_ELEMENT_DESC Text2DDesc[3];
|
||||||
|
static D3D11_INPUT_ELEMENT_DESC ModelDesc[3];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
struct Vertex2DIn
|
||||||
|
{
|
||||||
|
float2 Pos : Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer EveryObject2D : register(c0)
|
||||||
|
{
|
||||||
|
float4x4 Translation;
|
||||||
|
};
|
||||||
|
|
||||||
|
SamplerState LinearSampler : register(s0);
|
||||||
|
|
||||||
|
struct Pixel2DIn
|
||||||
|
{
|
||||||
|
float4 Pos : SV_Position;
|
||||||
|
float2 Uv : TEXCOORD;
|
||||||
|
};
|
||||||
|
|
||||||
|
Texture2D Material : register(t0);
|
||||||
|
|
||||||
|
float4 ApplyMaterial0(Pixel2DIn input) : SV_Target0
|
||||||
|
{
|
||||||
|
return Material.Sample(LinearSampler,input.Uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vertex2DIn PassThrough(Vertex2DIn input)
|
||||||
|
{
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
[maxvertexcount(4)]
|
||||||
|
void PointToQuad(point Vertex2DIn input[1],inout TriangleStream<Pixel2DIn> Quads)
|
||||||
|
{
|
||||||
|
Pixel2DIn output;
|
||||||
|
output.Pos = mul(float4(-1,-1,0,1) ,Translation);
|
||||||
|
output.Uv = float2(0,1);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
output.Pos = mul(float4(-1,1,0,1), Translation);
|
||||||
|
output.Uv = float2(0,0);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
output.Pos = mul(float4(1,-1,0,1), Translation);
|
||||||
|
output.Uv = float2(1,1);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
output.Pos = mul(float4(1,1,0,1), Translation);
|
||||||
|
output.Uv = float2(1,0);
|
||||||
|
Quads.Append(output);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
cbuffer everyFrame : register(c0)
|
||||||
|
{
|
||||||
|
matrix VP;
|
||||||
|
}
|
||||||
|
|
||||||
|
cbuffer everyObject : register(c1)
|
||||||
|
{
|
||||||
|
matrix world;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture2D Diffuse :register(t0);
|
||||||
|
|
||||||
|
float4 VSScene(float4 input : POSITION) : SV_Position
|
||||||
|
{
|
||||||
|
//return input;
|
||||||
|
return mul(input,VP);
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 PSScene(float4 input : SV_Position) : SV_Target0
|
||||||
|
{
|
||||||
|
return float4(0,1,0,1);
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
#ifndef COLLISIONMETHODS_HLSL
|
||||||
|
#define COLLISIONMETHODS_HLSL
|
||||||
|
|
||||||
|
struct Sphere
|
||||||
|
{
|
||||||
|
float3 center;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Plane
|
||||||
|
{
|
||||||
|
float3 normal;
|
||||||
|
float phasing;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Frustrum
|
||||||
|
{
|
||||||
|
Plane leftPlane, rightPlane, bottomPlane, topPlane, nearPlane, farPlane;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool intersects( uniform Frustrum f, uniform Sphere s )
|
||||||
|
{
|
||||||
|
float connectOffset;
|
||||||
|
|
||||||
|
connectOffset = dot( f.leftPlane.normal, s.center );
|
||||||
|
connectOffset += f.leftPlane.phasing;
|
||||||
|
if( connectOffset < -s.radius ) return false;
|
||||||
|
|
||||||
|
connectOffset = dot( f.rightPlane.normal, s.center );
|
||||||
|
connectOffset += f.rightPlane.phasing;
|
||||||
|
if( connectOffset < -s.radius ) return false;
|
||||||
|
|
||||||
|
connectOffset = dot( f.bottomPlane.normal, s.center );
|
||||||
|
connectOffset += f.bottomPlane.phasing;
|
||||||
|
if( connectOffset < -s.radius ) return false;
|
||||||
|
|
||||||
|
connectOffset = dot( f.topPlane.normal, s.center );
|
||||||
|
connectOffset += f.topPlane.phasing;
|
||||||
|
if( connectOffset < -s.radius ) return false;
|
||||||
|
|
||||||
|
connectOffset = dot( f.nearPlane.normal, s.center );
|
||||||
|
connectOffset += f.nearPlane.phasing;
|
||||||
|
if( connectOffset < -s.radius ) return false;
|
||||||
|
|
||||||
|
connectOffset = dot( f.farPlane.normal, s.center );
|
||||||
|
connectOffset += f.farPlane.phasing;
|
||||||
|
if( connectOffset < -s.radius ) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,85 @@
|
||||||
|
Texture2D Diffuse : register(t0);
|
||||||
|
Texture2D Glow : register(t1);
|
||||||
|
|
||||||
|
RWTexture2D<float4> Output : register(u0);
|
||||||
|
|
||||||
|
cbuffer BlurrData : register(c0)
|
||||||
|
{
|
||||||
|
static const int blurRadius = 5;
|
||||||
|
static const float Weights[11] =
|
||||||
|
{
|
||||||
|
0.05f,0.05f,0.1f,0.1f,0.1f,0.2f,0.1f,0.1f,0.1f,0.05f,0.05f
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
[numthreads(32,32,1)]
|
||||||
|
void TryCompute(uint3 ThreadID : SV_DispatchThreadID)
|
||||||
|
{
|
||||||
|
Output[ThreadID.xy] = Diffuse[ThreadID.xy]*0.5f+Glow[ThreadID.xy]*Glow[ThreadID.xy].w;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define N 128
|
||||||
|
#define gSize (N+2*blurRadius)
|
||||||
|
groupshared float4 gCache[gSize];
|
||||||
|
|
||||||
|
[numthreads(N,1,1)]
|
||||||
|
void BlurrHor(int3 ThreadID : SV_DispatchThreadID, int3 gThreadID : SV_GroupThreadID)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(gThreadID.x < blurRadius)
|
||||||
|
{
|
||||||
|
int x = max(ThreadID.x-blurRadius,0);
|
||||||
|
gCache[gThreadID.x] = Diffuse[int2(x,ThreadID.y)];
|
||||||
|
}
|
||||||
|
if(gThreadID.x >= N-blurRadius)
|
||||||
|
{
|
||||||
|
int x = min(ThreadID.x+blurRadius,Diffuse.Length.x-1);
|
||||||
|
gCache[gThreadID.x+2*blurRadius] = Diffuse[int2(x,ThreadID.y)];
|
||||||
|
}
|
||||||
|
gCache[gThreadID.x+blurRadius] = Diffuse[min(ThreadID.xy,Diffuse.Length.xy-1)];
|
||||||
|
|
||||||
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
|
||||||
|
float4 blurCol = float4(0,0,0,0);
|
||||||
|
|
||||||
|
[unroll]
|
||||||
|
for(int i = -blurRadius; i <= blurRadius;++i)
|
||||||
|
{
|
||||||
|
int k = gThreadID.x + blurRadius + i;
|
||||||
|
blurCol +=Weights[i + blurRadius] * gCache[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
Output[ThreadID.xy] = blurCol;
|
||||||
|
//Output[ThreadID.xy] = Diffuse[((ThreadID.xy))];
|
||||||
|
}
|
||||||
|
|
||||||
|
[numthreads(1,N,1)]
|
||||||
|
void BlurrVert(int3 ThreadID : SV_DispatchThreadID, int3 gThreadID : SV_GroupThreadID)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(gThreadID.y < blurRadius)
|
||||||
|
{
|
||||||
|
int y = max(ThreadID.y-blurRadius,0);
|
||||||
|
gCache[gThreadID.y] = Diffuse[int2(ThreadID.x,y)];
|
||||||
|
}
|
||||||
|
if(gThreadID.y >= N-blurRadius)
|
||||||
|
{
|
||||||
|
int y = min(ThreadID.y+blurRadius,Diffuse.Length.y-1);
|
||||||
|
gCache[gThreadID.y+2*blurRadius] = Diffuse[int2(ThreadID.x,y)];
|
||||||
|
}
|
||||||
|
gCache[gThreadID.y+blurRadius] = Diffuse[min(ThreadID.xy,Diffuse.Length.xy-1)];
|
||||||
|
|
||||||
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
|
||||||
|
float4 blurCol = float4(0,0,0,0);
|
||||||
|
|
||||||
|
[unroll]
|
||||||
|
for(int i = -blurRadius; i <= blurRadius;++i)
|
||||||
|
{
|
||||||
|
int k = gThreadID.y + blurRadius + i;
|
||||||
|
blurCol +=Weights[i + blurRadius] * gCache[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
Output[ThreadID.xy] = blurCol;
|
||||||
|
//Output[ThreadID.xy] = Diffuse[((ThreadID.xy))];
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
struct VertexIn
|
||||||
|
{
|
||||||
|
float3 Pos : Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer EveryObject2D : register(c0)
|
||||||
|
{
|
||||||
|
float4x4 VP;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Pixel2DIn
|
||||||
|
{
|
||||||
|
float4 Pos : SV_Position;
|
||||||
|
float2 Uv : TEXCOORD;
|
||||||
|
};
|
||||||
|
|
||||||
|
const static float Width = 5.0f;
|
||||||
|
|
||||||
|
VertexIn PassThrough(VertexIn input)
|
||||||
|
{
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
[maxvertexcount(16)]
|
||||||
|
void Lazer(line VertexIn input[2],inout TriangleStream<Pixel2DIn> Quads)
|
||||||
|
{
|
||||||
|
//build coordinate system
|
||||||
|
float3 r =normalize(input[1].Pos-input[0].Pos);
|
||||||
|
float3 s = abs(r);
|
||||||
|
//set s ortogonal to r
|
||||||
|
if(s.x<s.y && s.x<s.z)
|
||||||
|
s = float3(0,-r.z,r.y);
|
||||||
|
else if(s.y<s.x && s.y<s.z)
|
||||||
|
s = float3(-r.z,0,r.x);
|
||||||
|
else
|
||||||
|
s = float3(-r.y,r.x,0);
|
||||||
|
|
||||||
|
float3 t = cross(r,s);
|
||||||
|
|
||||||
|
|
||||||
|
Pixel2DIn output;
|
||||||
|
//create the corners of the plane rxs Forward Facing
|
||||||
|
//top left
|
||||||
|
output.Pos = mul(float4( input[0].Pos + Width*s,1),VP);
|
||||||
|
output.Uv = float2(0,1);
|
||||||
|
Quads.Append(output);
|
||||||
|
//botom left
|
||||||
|
output.Pos = mul(float4( input[0].Pos - Width*s,1),VP);
|
||||||
|
output.Uv = float2(0,0);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
//top right
|
||||||
|
output.Pos = mul(float4( input[1].Pos + Width*s,1),VP);
|
||||||
|
output.Uv = float2(1,1);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
//botom right
|
||||||
|
output.Pos =mul(float4( input[1].Pos - Width*s,1),VP);
|
||||||
|
output.Uv = float2(1,0);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
Quads.RestartStrip();
|
||||||
|
|
||||||
|
//create the corners of the plane rxs BackWard Facing
|
||||||
|
//top left
|
||||||
|
output.Pos = mul(float4( input[0].Pos + Width*s,1),VP);
|
||||||
|
output.Uv = float2(0,1);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
//top right
|
||||||
|
output.Pos = mul(float4( input[1].Pos + Width*s,1),VP);
|
||||||
|
output.Uv = float2(1,1);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
//botom left
|
||||||
|
output.Pos = mul(float4( input[0].Pos - Width*s,1),VP);
|
||||||
|
output.Uv = float2(0,0);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
//botom right
|
||||||
|
output.Pos =mul(float4( input[1].Pos - Width*s,1),VP);
|
||||||
|
output.Uv = float2(1,0);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
Quads.RestartStrip();
|
||||||
|
|
||||||
|
//create the corners of the plane rxt Forward Facing
|
||||||
|
//top left
|
||||||
|
output.Pos = mul(float4( input[0].Pos + Width*t,1),VP);
|
||||||
|
output.Uv = float2(0,1);
|
||||||
|
Quads.Append(output);
|
||||||
|
//botom left
|
||||||
|
output.Pos = mul(float4( input[0].Pos - Width*t,1),VP);
|
||||||
|
output.Uv = float2(0,0);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
//top right
|
||||||
|
output.Pos = mul(float4( input[1].Pos + Width*t,1),VP);
|
||||||
|
output.Uv = float2(1,1);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
//botom right
|
||||||
|
output.Pos =mul(float4( input[1].Pos - Width*t,1),VP);
|
||||||
|
output.Uv = float2(1,0);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
Quads.RestartStrip();
|
||||||
|
|
||||||
|
//create the corners of the plane rxt Forward Facing
|
||||||
|
//top left
|
||||||
|
output.Pos = mul(float4( input[0].Pos + Width*t,1),VP);
|
||||||
|
output.Uv = float2(0,1);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
//top right
|
||||||
|
output.Pos = mul(float4( input[1].Pos + Width*t,1),VP);
|
||||||
|
output.Uv = float2(1,1);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
//botom left
|
||||||
|
output.Pos = mul(float4( input[0].Pos - Width*t,1),VP);
|
||||||
|
output.Uv = float2(0,0);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
//botom right
|
||||||
|
output.Pos =mul(float4( input[1].Pos - Width*t,1),VP);
|
||||||
|
output.Uv = float2(1,0);
|
||||||
|
Quads.Append(output);
|
||||||
|
}
|
|
@ -0,0 +1,151 @@
|
||||||
|
// Personal notes and trail of thought //////////////////////////////
|
||||||
|
/*
|
||||||
|
Light is flux ( latin fluxus ; flow )
|
||||||
|
(F1) Flux density : amount of flow through a cross section (A)
|
||||||
|
(L) Luminosity: property of light, amount of light output per time. Equivalent with the Watt unit.
|
||||||
|
(A) Area as a function of range(r).
|
||||||
|
|
||||||
|
A[r] = 4*PI*r^2
|
||||||
|
F1 = L / A[r] = L / ( 4*PI*r^2 )
|
||||||
|
|
||||||
|
_Attenuation_
|
||||||
|
Attenuation is the gradual loss in intensity of any kind of flux through a medium. ~ Wikipedia
|
||||||
|
It is also dependant of BOTH medium material and type of Flux. Attenuation( soft Tissue, Light ) != Attenuation( soft Tissue, Xray ).
|
||||||
|
Hm'Yeah .. lets not use that. And SHAME to those who use that word carelessly in computer graphics!!!
|
||||||
|
|
||||||
|
_Attenuation_coefficient_
|
||||||
|
The linear intensity loss of a narrow beam through a medium.
|
||||||
|
Hm .. This sounds CG delicious :)
|
||||||
|
F2 = L / ( AttCoeff * r )
|
||||||
|
|
||||||
|
_Total:_
|
||||||
|
F = F1 + F2 = L / ( 4*PI*r^2 ) + L / ( AttCoeff * r ) = L / ( AttCoeff*r + 4*PI*r^2 )
|
||||||
|
May vary between light spreadTypes -------^^^^
|
||||||
|
|
||||||
|
L = ( Red Luminosity, Green Luminosity, Blue Luminosity, Spread )
|
||||||
|
F = ( Red Density, Green Density, Blue Density ) = L.rgb / (AttCoeff*r + L.s^2)
|
||||||
|
|
||||||
|
AttCoeff : property of Enviroment
|
||||||
|
Ambience Light : property of Enviroment
|
||||||
|
*/
|
||||||
|
#ifndef LIGHTMATERIALMETHODS_HLSL
|
||||||
|
#define LIGHTMATERIALMETHODS_HLSL
|
||||||
|
|
||||||
|
#include "CollisionMethods.hlsl"
|
||||||
|
|
||||||
|
#define PI 3.1415926535897932384626433832795f
|
||||||
|
#define POINTLIGHT_SPREADCOEFF 12.566370614359172953850573533118f
|
||||||
|
|
||||||
|
struct PointLight
|
||||||
|
{
|
||||||
|
Sphere pos;
|
||||||
|
float3 color;
|
||||||
|
float intensity;
|
||||||
|
};
|
||||||
|
|
||||||
|
void accumulateLight( inout float3 diffusePixel, inout float3 specularPixel, uniform in PointLight lightV, uniform in float exposure, uniform in float specularGloss, uniform in float3 pixelPosV, uniform in float3 normalV )
|
||||||
|
{
|
||||||
|
float3 toLightVecV = lightV.pos.center - pixelPosV;
|
||||||
|
float range = length( toLightVecV );
|
||||||
|
|
||||||
|
if( !(range <= lightV.pos.radius ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toLightVecV /= range;
|
||||||
|
|
||||||
|
float3 illum = lightV.color;
|
||||||
|
illum *= (exposure * lightV.intensity) / ( range + (POINTLIGHT_SPREADCOEFF * pow(range, 2.0f)) ); // light density on all rgb channels
|
||||||
|
|
||||||
|
// calculating and adding the DiffuseCoefficient
|
||||||
|
float coeff = max( dot(toLightVecV, normalV), 0.0f );
|
||||||
|
diffusePixel += illum * coeff;
|
||||||
|
|
||||||
|
if( coeff > 0.0f )
|
||||||
|
{ // calculating and adding the SpecularCoefficient
|
||||||
|
coeff = max( dot( reflect(-toLightVecV, normalV), normalize(-pixelPosV) ), 0.0f );
|
||||||
|
specularPixel += illum * pow( coeff, specularGloss );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------ old below
|
||||||
|
/*
|
||||||
|
struct Medium
|
||||||
|
{
|
||||||
|
float3 ambienceLuminosity;
|
||||||
|
float attenuationCoeff;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Light
|
||||||
|
{
|
||||||
|
matrix worldToLightVolume;
|
||||||
|
float3 luminosity;
|
||||||
|
float spreadCoeff;
|
||||||
|
float4 orientation;
|
||||||
|
};
|
||||||
|
|
||||||
|
// returns light density per rgb channel
|
||||||
|
float3 calcLightDensity( uniform float rangeW, uniform Light light, uniform Medium enviroment )
|
||||||
|
{ return light.luminosity / ( (enviroment.attenuationCoeff * rangeW) + (light.spreadCoeff * pow(rangeW, 2.0f)) ); }
|
||||||
|
|
||||||
|
// returns light density per rgb channel
|
||||||
|
float3 calcLightDensity( uniform float rangeW, uniform Light light )
|
||||||
|
{ return light.luminosity / ( rangeW + (light.spreadCoeff * pow(rangeW, 2.0f)) ); }
|
||||||
|
|
||||||
|
float calcDiffuseCoeff( uniform float3 normalW, uniform float3 toLightVecW )
|
||||||
|
{ return max( dot( toLightVecW, normalW ), 0.0f ); }
|
||||||
|
|
||||||
|
float calcSpecularCoeff( uniform float3 normalW, uniform float3 toLightVecW, uniform float3 toObserverVecW )
|
||||||
|
{ return max( dot( reflect( -toLightVecW, normalW ), toObserverVecW ), 0.0f ); }
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// SHADOW SAMPLING
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
/*SamplerComparisonState shadowSampling
|
||||||
|
{
|
||||||
|
Filter = COMPARISON_MIN_MAG_MIP_POINT;
|
||||||
|
ComparisonFunc = LESS_EQUAL;
|
||||||
|
AddressU = BORDER;
|
||||||
|
AddressV = BORDER;
|
||||||
|
AddressW = BORDER;
|
||||||
|
BorderColor = float4( 0.0f, 0.0f, 0.0f, 0.0f );
|
||||||
|
};/**/
|
||||||
|
/*
|
||||||
|
SamplerState shadowSampling
|
||||||
|
{
|
||||||
|
Filter = MIN_MAG_MIP_POINT;
|
||||||
|
AddressU = BORDER;
|
||||||
|
AddressV = BORDER;
|
||||||
|
AddressW = BORDER;
|
||||||
|
BorderColor = float4( 0.0f, 0.0f, 0.0f, 0.0f );
|
||||||
|
};/**/
|
||||||
|
/*
|
||||||
|
void sampleShadowPCFx4( uniform float3 posW, uniform Light light, uniform Texture2D shadowMap, uniform float2 shadowMapResolution, out float lightExposure, out float range )
|
||||||
|
{
|
||||||
|
float4 value = mul( light.worldToLightVolume, float4(posW, 1.0f) );
|
||||||
|
value /= value.w;
|
||||||
|
float2 shadowUV = 0.5f*( float2(value.x, -value.y) + 1.0f );
|
||||||
|
float2 shadowUVDelta = 1.0f / shadowMapResolution;
|
||||||
|
range = value.z - 0.00390625f;
|
||||||
|
|
||||||
|
//lightExposure = shadowMap.SampleCmpLevelZero( shadowSampling, shadowUV, range ).r;
|
||||||
|
value.x = (float)shadowMap.Sample(shadowSampling, shadowUV ).r;
|
||||||
|
value.y = (float)shadowMap.Sample(shadowSampling, shadowUV + float2(shadowUVDelta.x, 0.0f) );
|
||||||
|
value.z = (float)shadowMap.Sample(shadowSampling, shadowUV + float2(0.0f, shadowUVDelta.y) );
|
||||||
|
value.w = (float)shadowMap.Sample(shadowSampling, shadowUV + shadowUVDelta );
|
||||||
|
|
||||||
|
value.x = range > value.x ? 0.0f : 1.0f; // 1.0f if lightRange is not lesser than range. Else 0.0f
|
||||||
|
value.y = range > value.y ? 0.0f : 1.0f;
|
||||||
|
value.z = range > value.z ? 0.0f : 1.0f;
|
||||||
|
value.w = range > value.w ? 0.0f : 1.0f;
|
||||||
|
|
||||||
|
range += 0.00390625f;
|
||||||
|
|
||||||
|
shadowUV = frac( shadowUV * shadowMapResolution );
|
||||||
|
lightExposure = lerp( lerp( value.x, value.y, shadowUV.x ), lerp( value.z, value.w, shadowUV.x ), shadowUV.y );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,74 @@
|
||||||
|
cbuffer Rarely : register(c0)
|
||||||
|
{
|
||||||
|
matrix ViewProjection;
|
||||||
|
}
|
||||||
|
|
||||||
|
cbuffer everyFrame : register(c1)
|
||||||
|
{
|
||||||
|
matrix View;
|
||||||
|
}
|
||||||
|
|
||||||
|
cbuffer everyObject : register(c2)
|
||||||
|
{
|
||||||
|
matrix World;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture2D Diffuse :register(t0);
|
||||||
|
Texture2D Specular :register(t1);
|
||||||
|
Texture2D Glow :register(t2);
|
||||||
|
|
||||||
|
SamplerState LinearSampler : register(s0);
|
||||||
|
|
||||||
|
struct VSObjIn
|
||||||
|
{
|
||||||
|
float3 Pos : POSITION;
|
||||||
|
float3 Normal : NORMAL;
|
||||||
|
float2 UV : TEXCOORD;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PSObjIn
|
||||||
|
{
|
||||||
|
float4 Pos : SV_POSITION;
|
||||||
|
float3 WorldPos : POSITION;
|
||||||
|
float3 Normal : NORMAL;
|
||||||
|
float2 UV : TEXCOORD;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PSObjOut
|
||||||
|
{
|
||||||
|
float4 Diffuse : SV_Target0;
|
||||||
|
float4 Specular : SV_Target1;
|
||||||
|
float4 Glow : SV_Target2;
|
||||||
|
float4 Pos : SV_Target3;
|
||||||
|
float4 Normal : SV_Target4;
|
||||||
|
};
|
||||||
|
|
||||||
|
PSObjIn VSObj(VSObjIn input)
|
||||||
|
{
|
||||||
|
PSObjIn output;
|
||||||
|
matrix WV = mul( World, View );
|
||||||
|
matrix WVP = mul (World, ViewProjection );
|
||||||
|
output.Pos = mul( float4(input.Pos, 1), WVP );
|
||||||
|
output.WorldPos = mul( float4(input.Pos, 1), WV ).xyz;
|
||||||
|
output.Normal = mul( float4(input.Normal, 0), WV ).xyz;
|
||||||
|
output.UV = input.UV;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 PSObj (PSObjIn errors) : SV_Target0
|
||||||
|
{
|
||||||
|
return Diffuse.Sample( LinearSampler, errors.UV );
|
||||||
|
}
|
||||||
|
|
||||||
|
PSObjOut PSDefObj(PSObjIn inp)
|
||||||
|
{
|
||||||
|
PSObjOut outp;
|
||||||
|
outp.Pos = float4( inp.WorldPos, 1 );
|
||||||
|
outp.Normal = float4( normalize(inp.Normal), 0 ); // normalize since interpolation messes them up
|
||||||
|
outp.Diffuse = Diffuse.Sample( LinearSampler, inp.UV );
|
||||||
|
outp.Specular = Specular.Sample( LinearSampler, inp.UV );
|
||||||
|
outp.Glow = Glow.Sample( LinearSampler, inp.UV );
|
||||||
|
|
||||||
|
return outp;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
//Texture2D pos : register(t3);
|
||||||
|
//Texture2D normal : register(t4);
|
||||||
|
Texture1D<float3> rand : register(t8);
|
||||||
|
Texture1D<float3> sphere : register(t9);
|
||||||
|
|
||||||
|
|
||||||
|
float SSAOperPixel( int2 pixel)
|
||||||
|
{
|
||||||
|
float3 rnd = rand[(pixel.x+pixel.y)%rand.Length.x];
|
||||||
|
|
||||||
|
float3 nvec = normal[pixel].xyz;
|
||||||
|
float3 tangent = normalize(rnd-nvec * dot(rnd, nvec));
|
||||||
|
float3 biTangent = cross(nvec,tangent);
|
||||||
|
|
||||||
|
float3x3 tbn; // = float3x3( nvec, tangent, normal);
|
||||||
|
tbn[0] =nvec;
|
||||||
|
tbn[1] =tangent;
|
||||||
|
tbn[2] =biTangent;
|
||||||
|
|
||||||
|
float occlusion = 0.0f;
|
||||||
|
for(int i=0;i<sphere.Length.x;++i)
|
||||||
|
{
|
||||||
|
float3 sampled = mul( tbn, sphere[i].xyz);
|
||||||
|
sample = sampled * SSAOSphereRadius + pos[pixel].xyz;
|
||||||
|
|
||||||
|
//test acumulate
|
||||||
|
float rangeCheck = abs(pos[pixel].z - sampled.z) < SSAOSphereRadius ? 1.0f : 0.0f;
|
||||||
|
occlusion += (sampled.z <= pos[pixel].z ? 1.0 : 0.0) * rangeCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0 - (occlusion / sphere.Length.x);
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
F ..\Shaders\BasicDemo.hlsl
|
||||||
|
V VSScene VS
|
||||||
|
P PSScene PS
|
||||||
|
|
||||||
|
F ..\Shaders\Obj.hlsl
|
||||||
|
V VSObj OBJ
|
||||||
|
P PSObj OBJ
|
||||||
|
P PSDefObj OBJDEF
|
||||||
|
|
||||||
|
F ..\Shaders\2D.hlsl
|
||||||
|
V PassThrough 2D
|
||||||
|
G PointToQuad 2D
|
||||||
|
P ApplyMaterial0 Texture0
|
||||||
|
|
||||||
|
F ..\Shaders\Text.hlsl
|
||||||
|
V PassThroughText Text
|
||||||
|
G TextToQuad Text Text
|
||||||
|
|
||||||
|
F ..\Shaders\Deffered.hlsl
|
||||||
|
C TryCompute Comp
|
||||||
|
C BlurrHor BlurHorizontal
|
||||||
|
C BlurrVert BlurVertical
|
||||||
|
|
||||||
|
F ..\Shaders\Lazer.hlsl
|
||||||
|
V PassThrough LazerV
|
||||||
|
G Lazer LazerG
|
||||||
|
|
||||||
|
F ..\Shaders\TileBasedDeffered.hlsl
|
||||||
|
C lightComputer Pass0
|
||||||
|
C composingComputer Pass1
|
|
@ -0,0 +1,77 @@
|
||||||
|
#include "2D.hlsl"
|
||||||
|
|
||||||
|
cbuffer TextPerObject : register(c0)
|
||||||
|
{
|
||||||
|
float4x4 gWorld;
|
||||||
|
};
|
||||||
|
|
||||||
|
Texture2D g_tex1 : register(t0);
|
||||||
|
|
||||||
|
struct TEXT_VS_IN
|
||||||
|
{
|
||||||
|
float3 pos : POSITION;
|
||||||
|
float2 texCoord : TEXCOORD;
|
||||||
|
float ch : CHAR;
|
||||||
|
float3 off: VOFFSET;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TEXT_VS_OUT
|
||||||
|
{
|
||||||
|
float4 pos : SV_POSITION;
|
||||||
|
float2 texCoord : TEXCOORD;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEXT_VS_OUT TEXT_VS(TEXT_VS_IN vIn)
|
||||||
|
{
|
||||||
|
TEXT_VS_OUT vOut;
|
||||||
|
vOut.pos = mul(float4(vIn.pos+vIn.off, 1.0f), gWorld);
|
||||||
|
|
||||||
|
//Adding texCoord
|
||||||
|
vOut.texCoord = vIn.texCoord;
|
||||||
|
vOut.texCoord[0]+=vIn.ch;
|
||||||
|
return vOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float4 TEXT_PS(TEXT_VS_OUT pIn) : SV_Target0
|
||||||
|
{
|
||||||
|
return g_tex1.Sample(LinearSampler, pIn.texCoord);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Text2DIn
|
||||||
|
{
|
||||||
|
float Pos : Position;
|
||||||
|
int off : Offset;
|
||||||
|
float coff : CharOffset;
|
||||||
|
};
|
||||||
|
Text2DIn PassThroughText(Text2DIn input)
|
||||||
|
{
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
[maxvertexcount(4)]
|
||||||
|
void TextToQuad(point Text2DIn input[1],inout TriangleStream<Pixel2DIn> Quads)
|
||||||
|
{
|
||||||
|
float startoff=input[0].off*input[0].coff;
|
||||||
|
float endoff=startoff+input[0].coff;
|
||||||
|
Pixel2DIn output;
|
||||||
|
|
||||||
|
output.Pos = mul(float4(-1,-1,0,1), Translation);
|
||||||
|
output.Pos.x+=input[0].Pos;
|
||||||
|
output.Uv = float2(startoff,1);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
output.Pos = mul(float4(-1,1,0,1), Translation);
|
||||||
|
output.Pos.x+=input[0].Pos;
|
||||||
|
output.Uv = float2(startoff,0);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
output.Pos = mul(float4(1,-1,0,1), Translation);
|
||||||
|
output.Pos.x+=input[0].Pos;
|
||||||
|
output.Uv = float2(endoff,1);
|
||||||
|
Quads.Append(output);
|
||||||
|
|
||||||
|
output.Pos = mul(float4(1,1,0,1), Translation);
|
||||||
|
output.Pos.x+=input[0].Pos;
|
||||||
|
output.Uv = float2(endoff,0);
|
||||||
|
Quads.Append(output);
|
||||||
|
}
|
|
@ -0,0 +1,224 @@
|
||||||
|
#include "LightMaterialMethods.hlsl"
|
||||||
|
|
||||||
|
#define BLOCKSIZE 16
|
||||||
|
#define NUMTHREADS 256
|
||||||
|
#define UINT_MAX 0xFFFFFFFF
|
||||||
|
#define FLOAT_MAX 3.402823466e+38
|
||||||
|
#define SSAOSphereRadius 10.0f
|
||||||
|
#define SPECULARITY_GLOSS_MAX 40.0f
|
||||||
|
|
||||||
|
Texture2D<float4> mapMaterialDiffuse : register( t0 );
|
||||||
|
Texture2D<float4> mapMaterialSpecular : register( t1 );
|
||||||
|
Texture2D<float4> mapGlow : register( t2 );
|
||||||
|
Texture2D<float4> mapPosV : register( t3 );
|
||||||
|
Texture2D<float4> mapNormalV : register( t4 );
|
||||||
|
Texture2D<float4> mapDepth : register( t5 );
|
||||||
|
|
||||||
|
StructuredBuffer<Frustrum> tileBuffer : register( t6 );
|
||||||
|
StructuredBuffer<PointLight> pointLightBuffer : register( t7 );
|
||||||
|
Texture1D<float3> rand : register( t8 );
|
||||||
|
Texture1D<float3> sphere : register( t9 );
|
||||||
|
|
||||||
|
RWTexture2D<float4> outputDiffuseIllum : register( u0 );
|
||||||
|
RWTexture2D<float4> outputSpecularIllum : register( u1 );
|
||||||
|
RWTexture2D<float4> outputGlowMap : register( u2 );
|
||||||
|
RWTexture2D<float4> outputSSAOMap : register( u3 );
|
||||||
|
|
||||||
|
cbuffer LightData : register( c0 )
|
||||||
|
{
|
||||||
|
float4x4 viewMatrix;
|
||||||
|
float4x4 projectionMatrix;
|
||||||
|
uint3 numDispatches;
|
||||||
|
uint reservedPadding;
|
||||||
|
};
|
||||||
|
|
||||||
|
// -- Shared Memory ------------------------------------------------- //
|
||||||
|
|
||||||
|
groupshared uint iMinDepth = UINT_MAX,
|
||||||
|
iMaxDepth = 0;
|
||||||
|
groupshared uint numVisiblePointLights = 0,
|
||||||
|
visiblePointlightIndex[1024];
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------ //
|
||||||
|
|
||||||
|
[numthreads( BLOCKSIZE, BLOCKSIZE, 1 )]
|
||||||
|
void lightComputer( uint3 groupID : SV_GroupID,
|
||||||
|
uint3 groupThreadID : SV_GroupThreadID,
|
||||||
|
uint groupIndex : SV_GroupIndex,
|
||||||
|
uint3 dispatchThreadID : SV_DispatchThreadID )
|
||||||
|
{
|
||||||
|
uint dispatchIndex = dispatchThreadID.x + numDispatches.x * ( dispatchThreadID.y + (numDispatches.y * dispatchThreadID.z) );
|
||||||
|
float3 posV = mapPosV[dispatchThreadID.xy].xyz;
|
||||||
|
|
||||||
|
// store and load shared minDepth and maxDepth
|
||||||
|
float minDepth = 0.0f, maxDepth = 0.0f,
|
||||||
|
depth = length( posV );
|
||||||
|
{
|
||||||
|
uint uidepth = (uint)( depth * 1024.0f );
|
||||||
|
InterlockedMin( iMinDepth, uidepth );
|
||||||
|
InterlockedMax( iMaxDepth, uidepth );
|
||||||
|
|
||||||
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
minDepth = (float)( iMinDepth ) * 0.0009765625f;
|
||||||
|
maxDepth = (float)( iMaxDepth ) * 0.0009765625f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Switching to LightCulling ------------------------------------- //
|
||||||
|
{
|
||||||
|
Frustrum tile = tileBuffer[dispatchIndex];
|
||||||
|
// culling the tile's near and far to minDepth & maxDepth ( with tolerance )
|
||||||
|
tile.nearPlane.phasing = -(minDepth * 0.85f);
|
||||||
|
tile.farPlane.phasing = (maxDepth * 1.15f);
|
||||||
|
|
||||||
|
uint numPointLights = pointLightBuffer.Length.x,
|
||||||
|
numPass = (numPointLights + NUMTHREADS - 1) / NUMTHREADS;
|
||||||
|
numPass = min( numPass, 1024 / NUMTHREADS );
|
||||||
|
|
||||||
|
for( uint passI = 0; passI < numPass; ++passI )
|
||||||
|
{
|
||||||
|
uint lightIndex = (passI * NUMTHREADS) + groupIndex;
|
||||||
|
lightIndex = min( lightIndex, numPointLights );
|
||||||
|
|
||||||
|
if( lightIndex < numPointLights )
|
||||||
|
if( intersects(tile, pointLightBuffer[lightIndex].pos) )
|
||||||
|
{
|
||||||
|
uint offset;
|
||||||
|
InterlockedAdd( numVisiblePointLights, 1, offset );
|
||||||
|
visiblePointlightIndex[offset] = lightIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
|
||||||
|
uint2 maxDim = mapMaterialDiffuse.Length.xy;
|
||||||
|
if( dispatchThreadID.x < maxDim.x && dispatchThreadID.y < maxDim.y )
|
||||||
|
{
|
||||||
|
// -- Switching to per Pixel Light Accumulation --------------------- //
|
||||||
|
float specularGloss = mapMaterialSpecular[dispatchThreadID.xy].w * SPECULARITY_GLOSS_MAX;
|
||||||
|
float3 normalV = mapNormalV[dispatchThreadID.xy].xyz;
|
||||||
|
|
||||||
|
float3 diffuseLight = 0,
|
||||||
|
specularLight = 0;
|
||||||
|
float4 v = float4( 0.0f, 0.0f, 0.0f, 0.0f );
|
||||||
|
|
||||||
|
for( uint lightI = 0; lightI < numVisiblePointLights; ++lightI )
|
||||||
|
{ // for each light that might touch this pixel
|
||||||
|
uint lightIndex = visiblePointlightIndex[lightI];
|
||||||
|
PointLight light = pointLightBuffer[lightIndex]; // should be preloaded into groupshared methinks
|
||||||
|
|
||||||
|
v = mul( viewMatrix, float4(light.pos.center, 1.0f) );
|
||||||
|
light.pos.center = v.xyz / v.w;
|
||||||
|
|
||||||
|
v = mul(viewMatrix, float4(light.pos.radius, 0.0f, 0.0f, 0.0f) );
|
||||||
|
light.pos.radius = length( v.xyz );
|
||||||
|
|
||||||
|
float exposure = 1.0f;
|
||||||
|
|
||||||
|
accumulateLight( diffuseLight, specularLight, light, exposure, specularGloss, posV, normalV );
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Applying SSAO ---------------------------------------- Pär H. - //
|
||||||
|
float occlusion = 0.0f;
|
||||||
|
{ //create sample coordinate system
|
||||||
|
float4 rnd = float4( rand[groupIndex % rand.Length.x].xyz, 0.0f );
|
||||||
|
|
||||||
|
|
||||||
|
float4 tangent = float4( normalize(rnd.xyz - (normalV * dot(rnd.xyz, normalV))), 0.0f );
|
||||||
|
float4 biTangent = float4( cross(tangent.xyz, normalV), 0.0f );
|
||||||
|
|
||||||
|
float4x4 tbn = float4x4( biTangent,
|
||||||
|
tangent,
|
||||||
|
float4(normalV, 0.0f),
|
||||||
|
float4(posV, 1.0f) );
|
||||||
|
|
||||||
|
for( uint i = 0; i < sphere.Length.x; ++i )
|
||||||
|
{
|
||||||
|
//take sample from localspace to viewspace
|
||||||
|
float4 sampled = mul( float4(sphere[i].xyz,1), tbn);
|
||||||
|
|
||||||
|
//project sample to get uv.xy
|
||||||
|
float4 offset = float4(sampled);
|
||||||
|
offset = mul( offset, projectionMatrix );
|
||||||
|
offset.xy /= offset.w;
|
||||||
|
offset.xy = offset.xy * 0.5 + 0.5;
|
||||||
|
offset.y = 1.0f - offset.y;
|
||||||
|
|
||||||
|
// get depth from that point in viewspace
|
||||||
|
uint2 texCoord;
|
||||||
|
texCoord.x = (uint)(offset.x * (float)(mapMaterialDiffuse.Length.x));
|
||||||
|
texCoord.y = (uint)(offset.y * (float)(mapMaterialDiffuse.Length.y));
|
||||||
|
float sampleDepth = length(mapPosV[texCoord]);
|
||||||
|
float rangeDepth = mapPosV[texCoord].z;
|
||||||
|
|
||||||
|
//compare to depth from sample
|
||||||
|
float rangeCheck = (abs(depth - sampleDepth) < SSAOSphereRadius) ? 1.0f : 0.0f;
|
||||||
|
occlusion += (sampleDepth <= length(sampled) ? 1.0f : 0.0f) * rangeCheck;
|
||||||
|
}
|
||||||
|
occlusion /= (float)(sphere.Length.x);
|
||||||
|
occlusion = 1.0f - occlusion;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Compile and write Light values to buffers --------------------- //
|
||||||
|
|
||||||
|
diffuseLight.xyz *= mapMaterialDiffuse[dispatchThreadID.xy].xyz;
|
||||||
|
specularLight.xyz *= mapMaterialSpecular[dispatchThreadID.xy].xyz;
|
||||||
|
float4 glow = mapGlow[dispatchThreadID.xy];
|
||||||
|
glow *= glow.w;
|
||||||
|
|
||||||
|
//specularLight.xyz += mapGlow[dispatchThreadID.xy].xyz;
|
||||||
|
|
||||||
|
outputDiffuseIllum[dispatchThreadID.xy] = float4( diffuseLight, 1.0f );
|
||||||
|
outputSpecularIllum[dispatchThreadID.xy] = float4( specularLight.xyz, 1 );
|
||||||
|
outputGlowMap[dispatchThreadID.xy] = float4( glow.xyz * glow.z, 1 );
|
||||||
|
outputSSAOMap[dispatchThreadID.xy] = float4( occlusion, occlusion, occlusion, 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* ------------------------------------------------------------------ //
|
||||||
|
Needs to split into two passes here. As a major Dispatch sync is
|
||||||
|
is warranted for crossDispatch datasharing.
|
||||||
|
// ------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
Texture2D<float4> mapDiffuse : register( t0 );
|
||||||
|
Texture2D<float4> mapSpecular : register( t1 );
|
||||||
|
Texture2D<float4> Glow : register( t2 );
|
||||||
|
Texture2D<float4> mapSSAO : register( t3 );
|
||||||
|
|
||||||
|
RWTexture2D<float4> outputBackBuffer : register( u0 );
|
||||||
|
|
||||||
|
[numthreads( BLOCKSIZE, BLOCKSIZE, 1 )]
|
||||||
|
void composingComputer( uint3 groupID : SV_GroupID,
|
||||||
|
uint3 groupThreadID : SV_GroupThreadID,
|
||||||
|
uint groupIndex : SV_GroupIndex,
|
||||||
|
uint3 dispatchThreadID : SV_DispatchThreadID )
|
||||||
|
{
|
||||||
|
uint2 maxDim = mapDiffuse.Length.xy;
|
||||||
|
if( dispatchThreadID.x < maxDim.x && dispatchThreadID.y < maxDim.y )
|
||||||
|
{
|
||||||
|
// -- Switching to light-material compiling ------------------------- //
|
||||||
|
float3 diffuse = mapDiffuse[dispatchThreadID.xy].xyz;
|
||||||
|
float3 specular = mapSpecular[dispatchThreadID.xy].xyz;
|
||||||
|
float3 glow = Glow[dispatchThreadID.xy].xyz;
|
||||||
|
float SSAO = mapSSAO[dispatchThreadID.xy].x;
|
||||||
|
|
||||||
|
float3 I = diffuse * SSAO + specular * SSAO + glow * 0.5f;
|
||||||
|
|
||||||
|
//outputBackBuffer[dispatchThreadID.xy] = float4( SSAO,SSAO,SSAO, 1.0f );
|
||||||
|
//return;
|
||||||
|
|
||||||
|
uint2 midScreen = mapDiffuse.Length.xy / 2;
|
||||||
|
if( dispatchThreadID.x < midScreen.x )
|
||||||
|
{
|
||||||
|
if( dispatchThreadID.y < midScreen.y )
|
||||||
|
outputBackBuffer[dispatchThreadID.xy] = float4( I, 1.0f );
|
||||||
|
else
|
||||||
|
outputBackBuffer[dispatchThreadID.xy] = float4( diffuse + specular, 1.0f );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( dispatchThreadID.y < midScreen.y )
|
||||||
|
outputBackBuffer[dispatchThreadID.xy] = float4( glow * 0.5f, 1.0f );
|
||||||
|
else
|
||||||
|
outputBackBuffer[dispatchThreadID.xy] = float4( SSAO, SSAO, SSAO, 1.0f );
|
||||||
|
}/**/
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,253 @@
|
||||||
|
#include "Shader.h"
|
||||||
|
#include "../Core/Core.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
std::vector<ID3D11PixelShader*> PS;
|
||||||
|
std::map<std::string,int> PSMap;
|
||||||
|
|
||||||
|
std::vector<ID3D11GeometryShader*> GS;
|
||||||
|
std::map<std::string,int> GSMap;
|
||||||
|
|
||||||
|
std::vector<ID3D11ComputeShader*> CS;
|
||||||
|
std::map<std::string,int> CSMap;
|
||||||
|
|
||||||
|
std::vector<ID3D11VertexShader*> VS;
|
||||||
|
std::vector<ID3D10Blob*> VBlob;
|
||||||
|
std::map<std::string,int> VSMap;
|
||||||
|
|
||||||
|
std::stringstream log;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Oyster::Shader::InitShaders(const std::string &name)
|
||||||
|
{
|
||||||
|
std::ifstream input;
|
||||||
|
input.open(name.c_str());
|
||||||
|
std::string s, file,method;
|
||||||
|
std::vector<std::string> line;
|
||||||
|
if(!input.is_open())
|
||||||
|
return false;
|
||||||
|
while(!input.eof())
|
||||||
|
{
|
||||||
|
getline(input,s);
|
||||||
|
line.clear();
|
||||||
|
Utility::String::split(line,s,' ');
|
||||||
|
if(line.size())
|
||||||
|
{
|
||||||
|
if(line[0]=="F")
|
||||||
|
{
|
||||||
|
file = line[1];
|
||||||
|
}
|
||||||
|
if(line[0]=="P")
|
||||||
|
{
|
||||||
|
ID3D10Blob *Shader,*Error;
|
||||||
|
if(!PSMap.count(line[2]))
|
||||||
|
{
|
||||||
|
PSMap[line[2]]=(int)PS.size();
|
||||||
|
ID3D11PixelShader* pixel;
|
||||||
|
if(FAILED(D3DX11CompileFromFileA(file.c_str(),NULL,NULL,line[1].c_str(),"ps_5_0",0,0,NULL,&Shader,&Error,NULL)))
|
||||||
|
{
|
||||||
|
std::string fel = (char*)Error->GetBufferPointer();
|
||||||
|
PSMap.erase(line[2]);
|
||||||
|
Error->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(FAILED(Oyster::Core::Device->CreatePixelShader(Shader->GetBufferPointer(),Shader->GetBufferSize(),NULL,&pixel)))
|
||||||
|
{
|
||||||
|
PSMap.erase(line[2]);
|
||||||
|
Error->Release();
|
||||||
|
Shader->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Shader->Release();
|
||||||
|
PS.push_back(pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(line[0]=="V")
|
||||||
|
{
|
||||||
|
ID3D10Blob *Shader,*Error;
|
||||||
|
if(!VSMap.count(line[2]))
|
||||||
|
{
|
||||||
|
int i = (int)VS.size();
|
||||||
|
VSMap[line[2]]= i;
|
||||||
|
ID3D11VertexShader* vertex;
|
||||||
|
if(FAILED(D3DX11CompileFromFileA(file.c_str(),NULL,NULL,line[1].c_str(),"vs_5_0",0,0,NULL,&Shader,&Error,NULL)))
|
||||||
|
{
|
||||||
|
log //<< "Shader Compilation Warning(s)/Error(s)\n-----------------------------\n"
|
||||||
|
<< (char*) Error->GetBufferPointer();
|
||||||
|
// << "-----------------------------\n";
|
||||||
|
s = log.str();
|
||||||
|
VSMap.erase(line[2]);
|
||||||
|
Error->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(FAILED(Oyster::Core::Device->CreateVertexShader
|
||||||
|
(Shader->GetBufferPointer(),
|
||||||
|
Shader->GetBufferSize(),
|
||||||
|
NULL,
|
||||||
|
&vertex)))
|
||||||
|
{
|
||||||
|
VSMap.erase(line[2]);
|
||||||
|
Error->Release();
|
||||||
|
Shader->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
VS.push_back(vertex);
|
||||||
|
VBlob.push_back(Shader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(line[0]=="G")
|
||||||
|
{
|
||||||
|
ID3D10Blob *Shader,*Error;
|
||||||
|
if(!GSMap.count(line[2]))
|
||||||
|
{
|
||||||
|
GSMap[line[2]]=(int)GS.size();
|
||||||
|
ID3D11GeometryShader* pixel;
|
||||||
|
if(FAILED(D3DX11CompileFromFileA(file.c_str(),NULL,NULL,line[1].c_str(),"gs_5_0",0,0,NULL,&Shader,&Error,NULL)))
|
||||||
|
{
|
||||||
|
std::string fel = (char*)Error->GetBufferPointer();
|
||||||
|
GSMap.erase(line[2]);
|
||||||
|
Error->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(FAILED(Oyster::Core::Device->CreateGeometryShader(Shader->GetBufferPointer(),Shader->GetBufferSize(),NULL,&pixel)))
|
||||||
|
{
|
||||||
|
GSMap.erase(line[2]);
|
||||||
|
Error->Release();
|
||||||
|
Shader->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Shader->Release();
|
||||||
|
GS.push_back(pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(line[0]=="C")
|
||||||
|
{
|
||||||
|
ID3D10Blob *Shader,*Error;
|
||||||
|
if(!CSMap.count(line[2]))
|
||||||
|
{
|
||||||
|
CSMap[line[2]]=(int)CS.size();
|
||||||
|
ID3D11ComputeShader* comp;
|
||||||
|
if(FAILED(D3DX11CompileFromFileA(file.c_str(),NULL,NULL,line[1].c_str(),"cs_5_0",0,0,NULL,&Shader,&Error,NULL)))
|
||||||
|
{
|
||||||
|
std::string fel = (char*)Error->GetBufferPointer();
|
||||||
|
CSMap.erase(line[2]);
|
||||||
|
Error->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(FAILED(Oyster::Core::Device->CreateComputeShader(Shader->GetBufferPointer(),Shader->GetBufferSize(),NULL,&comp)))
|
||||||
|
{
|
||||||
|
CSMap.erase(line[2]);
|
||||||
|
Error->Release();
|
||||||
|
Shader->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Shader->Release();
|
||||||
|
CS.push_back(comp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oyster::Shader::SetShaderEffect(ShaderEffect se)
|
||||||
|
{
|
||||||
|
Shader::Set::SetPixel(se.Shaders.Pixel);
|
||||||
|
Shader::Set::SetVertex(se.Shaders.Vertex);
|
||||||
|
Shader::Set::SetGeometry(se.Shaders.Geometry);
|
||||||
|
Shader::Set::SetCompute(se.Shaders.Compute);
|
||||||
|
Oyster::Core::DeviceContext->IASetInputLayout(se.IAStage.Layout);
|
||||||
|
Oyster::Core::DeviceContext->IASetPrimitiveTopology(se.IAStage.Topology);
|
||||||
|
for(unsigned int i=0;i<se.CBuffers.Vertex.size();++i)
|
||||||
|
se.CBuffers.Vertex[i]->Apply(i);
|
||||||
|
for(unsigned int i=0;i<se.CBuffers.Geometry.size();++i)
|
||||||
|
se.CBuffers.Geometry[i]->Apply(i);
|
||||||
|
for(unsigned int i=0;i<se.CBuffers.Pixel.size();++i)
|
||||||
|
se.CBuffers.Pixel[i]->Apply(i);
|
||||||
|
Oyster::Core::DeviceContext->RSSetState(se.RenderStates.Rasterizer);
|
||||||
|
Oyster::Core::DeviceContext->PSSetSamplers(0,se.RenderStates.SampleCount,se.RenderStates.SampleState);
|
||||||
|
float test[4] = {0};
|
||||||
|
Oyster::Core::DeviceContext->OMSetBlendState(se.RenderStates.BlendState,test,-1);
|
||||||
|
}
|
||||||
|
void Oyster::Shader::Set::SetPixel(int Index)
|
||||||
|
{
|
||||||
|
if(Index==-1)
|
||||||
|
Oyster::Core::DeviceContext->PSSetShader( NULL,NULL,0);
|
||||||
|
else
|
||||||
|
Oyster::Core::DeviceContext->PSSetShader( PS[Index],NULL,0);
|
||||||
|
}
|
||||||
|
void Oyster::Shader::Set::SetVertex(int Index)
|
||||||
|
{
|
||||||
|
if(Index==-1)
|
||||||
|
Oyster::Core::DeviceContext->VSSetShader(NULL,NULL,0);
|
||||||
|
else
|
||||||
|
Oyster::Core::DeviceContext->VSSetShader(VS[Index],NULL,0);
|
||||||
|
}
|
||||||
|
void Oyster::Shader::Set::SetGeometry(int Index)
|
||||||
|
{
|
||||||
|
if(Index==-1)
|
||||||
|
Oyster::Core::DeviceContext->GSSetShader(NULL,NULL,0);
|
||||||
|
else
|
||||||
|
Oyster::Core::DeviceContext->GSSetShader(GS[Index],NULL,0);
|
||||||
|
}
|
||||||
|
void Oyster::Shader::Set::SetCompute(int Index)
|
||||||
|
{
|
||||||
|
if(Index==-1)
|
||||||
|
Oyster::Core::DeviceContext->CSSetShader(NULL,NULL,0);
|
||||||
|
else
|
||||||
|
Oyster::Core::DeviceContext->CSSetShader(CS[Index],NULL,0);
|
||||||
|
}
|
||||||
|
void Oyster::Shader::Set::SetHull(int Index)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void Oyster::Shader::Set::SetDomain(int Index)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int Oyster::Shader::Get::GetPixel(std::string Name)
|
||||||
|
{
|
||||||
|
if(PSMap.count(Name))
|
||||||
|
return PSMap[Name];
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int Oyster::Shader::Get::GetVertex(std::string Name)
|
||||||
|
{
|
||||||
|
if(VSMap.count(Name))
|
||||||
|
return VSMap[Name];
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int Oyster::Shader::Get::GetGeometry(std::string Name)
|
||||||
|
{
|
||||||
|
if(GSMap.count(Name))
|
||||||
|
return GSMap[Name];
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int Oyster::Shader::Get::GetCompute(std::string Name)
|
||||||
|
{
|
||||||
|
if(CSMap.count(Name))
|
||||||
|
return CSMap[Name];
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int Oyster::Shader::Get::GetHull(std::string Name)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int Oyster::Shader::Get::GetDomain(std::string Name)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
void Oyster::Shader::CreateInputLayout(const D3D11_INPUT_ELEMENT_DESC *desc, int ElementCount,int VertexIndex,ID3D11InputLayout *&Layout)
|
||||||
|
{
|
||||||
|
if(VertexIndex==-1)
|
||||||
|
{
|
||||||
|
Layout=0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Oyster::Core::Device->CreateInputLayout(desc,ElementCount,VBlob[VertexIndex]->GetBufferPointer(),VBlob[VertexIndex]->GetBufferSize(),&Layout);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "..\Core\Buffer.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
class Shader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct ShaderEffect
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int Pixel,Vertex,Geometry,Compute,Hull,Domain;
|
||||||
|
}Shaders;
|
||||||
|
struct IAStage_
|
||||||
|
{
|
||||||
|
ID3D11InputLayout* Layout;
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY Topology;
|
||||||
|
}IAStage;
|
||||||
|
struct RenderStates_
|
||||||
|
{
|
||||||
|
ID3D11DepthStencilState *DepthStencil;
|
||||||
|
ID3D11RasterizerState *Rasterizer;
|
||||||
|
ID3D11SamplerState **SampleState;
|
||||||
|
int SampleCount;
|
||||||
|
ID3D11BlendState *BlendState;
|
||||||
|
}RenderStates;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
std::vector<Buffer*> Vertex;
|
||||||
|
std::vector<Buffer*> Geometry;
|
||||||
|
std::vector<Buffer*> Pixel;
|
||||||
|
}CBuffers;
|
||||||
|
ShaderEffect()
|
||||||
|
{
|
||||||
|
RenderStates.BlendState=NULL;
|
||||||
|
RenderStates.DepthStencil=NULL;
|
||||||
|
RenderStates.Rasterizer=NULL;
|
||||||
|
RenderStates.SampleState=NULL;
|
||||||
|
RenderStates.SampleCount=0;
|
||||||
|
Shaders.Compute=-1;
|
||||||
|
Shaders.Domain=-1;
|
||||||
|
Shaders.Geometry=-1;
|
||||||
|
Shaders.Hull=-1;
|
||||||
|
Shaders.Pixel=-1;
|
||||||
|
Shaders.Vertex=-1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static bool InitShaders(const std::string &name = "..\\Shaders\\ShaderConfig.txt");
|
||||||
|
|
||||||
|
static void SetShaderEffect(ShaderEffect);
|
||||||
|
|
||||||
|
static void CreateInputLayout(const D3D11_INPUT_ELEMENT_DESC *desc, int ElementCount,int VertexIndex,ID3D11InputLayout *&Layout);
|
||||||
|
|
||||||
|
struct Set
|
||||||
|
{
|
||||||
|
static void SetPixel(int Index);
|
||||||
|
static void SetVertex(int Index);
|
||||||
|
static void SetGeometry(int Index);
|
||||||
|
static void SetCompute(int Index);
|
||||||
|
static void SetHull(int Index);
|
||||||
|
static void SetDomain(int Index);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Get
|
||||||
|
{
|
||||||
|
static int GetPixel(std::string Name);
|
||||||
|
static int GetVertex(std::string Name);
|
||||||
|
static int GetGeometry(std::string Name);
|
||||||
|
static int GetCompute(std::string Name);
|
||||||
|
static int GetHull(std::string Name);
|
||||||
|
static int GetDomain(std::string Name);
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::stringstream* AccesLog();
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,268 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Collection of Linear Math Stuff
|
||||||
|
// © Dan Andersson 2013
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef LINEARMATH_H
|
||||||
|
#define LINEARMATH_H
|
||||||
|
|
||||||
|
#include "Vector.h"
|
||||||
|
#include "Matrix.h"
|
||||||
|
#include "Quaternion.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
namespace LinearAlgebra
|
||||||
|
{
|
||||||
|
// x2
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType> operator * ( const Matrix2x2<ElementType> &left, const Matrix2x2<ElementType> &right )
|
||||||
|
{ return Matrix2x2<ElementType>( (left.m11 * right.m11) + (left.m21 * right.m12), (left.m11 * right.m21) + (left.m21 * right.m22), (left.m12 * right.m11) + (left.m22 * right.m12), (left.m12 * right.m21) + (left.m22 * right.m22) ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType> operator * ( const Matrix2x2<ElementType> &matrix, const Vector2<ElementType> &vector )
|
||||||
|
{ return Vector2<ElementType>( (matrix.m11 * vector.x) + (matrix.m21 * vector.y), (matrix.m12 * vector.x) + (matrix.m22 * vector.y) ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType> operator * ( const Vector2<ElementType> &vector, const Matrix2x2<ElementType> &left )
|
||||||
|
{ return Vector2<ElementType>( (vector.x * matrix.m11) + (vector.y * matrix.m12), (vector.x * matrix.m21) + (vector.y * matrix.m22) ); }
|
||||||
|
|
||||||
|
// x3
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> operator * ( const Matrix3x3<ElementType> &left, const Matrix3x3<ElementType> &right )
|
||||||
|
{
|
||||||
|
Matrix3x3<ElementType> product, leftT = left.getTranspose();
|
||||||
|
for( int i = 0; i < 3; ++i ) for( int j = 0; j < 3; ++j )
|
||||||
|
product.m[i][j] = leftT.v[i].dot(right.v[j]);
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType> operator * ( const Matrix3x3<ElementType> &matrix, const Vector3<ElementType> &vector )
|
||||||
|
{ return Vector3<ElementType>( (matrix.m11 * vector.x) + (matrix.m21 * vector.y) + (matrix.m31 * vector.z), (matrix.m12 * vector.x) + (matrix.m22 * vector.y) + (matrix.m32 * vector.z), (matrix.m13 * vector.x) + (matrix.m23 * vector.y) + (matrix.m33 * vector.z) ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType> operator * ( const Vector3<ElementType> &vector, const Matrix3x3<ElementType> &left )
|
||||||
|
{ return Vector3<ElementType>( (vector.x * matrix.m11) + (vector.y * matrix.m12) + (vector.z * matrix.m13), (vector.x * matrix.m21) + (vector.y * matrix.m22) + (vector.z * matrix.m23), (vector.x * matrix.m31) + (vector.y * matrix.m32) + (vector.z * matrix.m33) ); }
|
||||||
|
|
||||||
|
// x4
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType> operator * ( const Matrix4x4<ElementType> &left, const Matrix4x4<ElementType> &right )
|
||||||
|
{
|
||||||
|
Matrix4x4<ElementType> product, rightT = right.getTranspose();
|
||||||
|
for( int i = 0; i < 4; ++i )
|
||||||
|
{
|
||||||
|
product.m[i][0] = left.v[i].dot(rightT.v[0]);
|
||||||
|
product.m[i][1] = left.v[i].dot(rightT.v[1]);
|
||||||
|
product.m[i][2] = left.v[i].dot(rightT.v[2]);
|
||||||
|
product.m[i][3] = left.v[i].dot(rightT.v[3]);
|
||||||
|
}
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType> operator * ( const Matrix4x4<ElementType> &matrix, const Vector4<ElementType> &vector )
|
||||||
|
{ return Vector4<ElementType>( (matrix.m11 * vector.x) + (matrix.m21 * vector.y) + (matrix.m31 * vector.z) + (matrix.m41 * vector.w), (matrix.m12 * vector.x) + (matrix.m22 * vector.y) + (matrix.m32 * vector.z) + (matrix.m42 * vector.w), (matrix.m13 * vector.x) + (matrix.m23 * vector.y) + (matrix.m33 * vector.z) + (matrix.m43 * vector.w), (matrix.m14 * vector.x) + (matrix.m24 * vector.y) + (matrix.m34 * vector.z) + (matrix.m44 * vector.w) ); }
|
||||||
|
|
||||||
|
template<typename ElementType> // works for column weighted matrixes
|
||||||
|
Vector4<ElementType> operator * ( const Vector4<ElementType> &vector, const Matrix4x4<ElementType> &matrix )
|
||||||
|
{ return Vector4<ElementType>( (vector.x * matrix.m11) + (vector.y * matrix.m12) + (vector.z * matrix.m13) + (vector.w * matrix.m14), (vector.x * matrix.m21) + (vector.y * matrix.m22) + (vector.z * matrix.m23) + (vector.w * matrix.m24), (vector.x * matrix.m31) + (vector.y * matrix.m32) + (vector.z * matrix.m33) + (vector.w * matrix.m34), (vector.x * matrix.m41) + (vector.y * matrix.m42) + (vector.z * matrix.m43) + (vector.w * matrix.m44) ); }
|
||||||
|
|
||||||
|
namespace _2D
|
||||||
|
{
|
||||||
|
template<typename ElementType>
|
||||||
|
inline void translationMatrix( Matrix3x3<ElementType> &output, const Vector2<ElementType> &position )
|
||||||
|
// { output = Matrix3x3<ElementType>( 1, 0, position.x, 0, 1, position.y, 0, 0, 1 ); }
|
||||||
|
{ output = Matrix3x3<ElementType>( 1, 0, 0, 0, 1, 0, position.x, position.y, 1 ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
void rotationMatrix( Matrix2x2<ElementType> &output, const ElementType &radian )
|
||||||
|
{
|
||||||
|
ElementType s = std::sin( radian ),
|
||||||
|
c = std::cos( radian );
|
||||||
|
// output = Matrix2x2<ElementType>( c, -s, s, c );
|
||||||
|
output = Matrix2x2<ElementType>( c, s, -s, c );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
void rotationMatrix( Matrix3x3<ElementType> &output, const ElementType &radian )
|
||||||
|
{
|
||||||
|
ElementType s = std::sin( radian ),
|
||||||
|
c = std::cos( radian );
|
||||||
|
// output = Matrix3x3<ElementType>( c, -s, 0, s, c, 0, 0, 0, 1 );
|
||||||
|
output = Matrix3x3<ElementType>( c, s, 0, -s, c, 0, 0, 0, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
void rigidBodyMatrix( Matrix3x3<ElementType> &output, const ElementType &radian, const Vector2<ElementType> &position )
|
||||||
|
{
|
||||||
|
ElementType s = std::sin( radian ),
|
||||||
|
c = std::cos( radian );
|
||||||
|
// output = Matrix3x3<ElementType>( c, -s, position.x, s, c, position.y, 0, 0, 1 );
|
||||||
|
output = Matrix3x3<ElementType>( c, s, 0, -s, c, 0, position.x, position.y, 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace _3D
|
||||||
|
{
|
||||||
|
template<typename ElementType>
|
||||||
|
inline void translationMatrix( Matrix4x4<ElementType> &output, const Vector3<ElementType> &position )
|
||||||
|
// { output = Matrix4x4<ElementType>( 1, 0, 0, position.x, 0, 1, 0, position.y, 0, 0, 1, position.z, 0, 0, 0, 1 ); }
|
||||||
|
{ output = Matrix4x4<ElementType>( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, position.x, position.y, position.z, 1 ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
void inverseRigidBody( Matrix4x4<ElementType> &output, const Matrix4x4<ElementType> &rigidBody )
|
||||||
|
{
|
||||||
|
output = Matrix4x4<ElementType>( rigidBody.m11, rigidBody.m21, rigidBody.m31, 0,
|
||||||
|
rigidBody.m12, rigidBody.m22, rigidBody.m32, 0,
|
||||||
|
rigidBody.m13, rigidBody.m23, rigidBody.m33, 0,
|
||||||
|
-rigidBody.v[3].xyz.dot(rigidBody.v[0].xyz),
|
||||||
|
-rigidBody.v[3].xyz.dot(rigidBody.v[1].xyz),
|
||||||
|
-rigidBody.v[3].xyz.dot(rigidBody.v[2].xyz), 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
void rotationMatrix_AxisX( Matrix3x3<ElementType> &output, const ElementType &radian )
|
||||||
|
{
|
||||||
|
ElementType s = std::sin( radian ),
|
||||||
|
c = std::cos( radian );
|
||||||
|
// output = Matrix3x3<ElementType>( 1, 0, 0, 0, c, -s, 0, s, c );
|
||||||
|
output = Matrix3x3<ElementType>( 1, 0, 0, 0, c, s, 0, -s, c );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
void rotationMatrix_AxisX( Matrix4x4<ElementType> &output, const ElementType &radian )
|
||||||
|
{
|
||||||
|
ElementType s = std::sin( radian ),
|
||||||
|
c = std::cos( radian );
|
||||||
|
// output = Matrix4x4<ElementType>( 1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1 );
|
||||||
|
output = Matrix4x4<ElementType>( 1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
void rotationMatrix_AxisY( Matrix3x3<ElementType> &output, const ElementType &radian )
|
||||||
|
{
|
||||||
|
ElementType s = std::sin( radian ),
|
||||||
|
c = std::cos( radian );
|
||||||
|
// output = Matrix3x3<ElementType>( c, 0, s, 0, 1, 0, -s, 0, c );
|
||||||
|
output = Matrix3x3<ElementType>( c, 0, -s, 0, 1, 0, s, 0, c );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
void rotationMatrix_AxisY( Matrix4x4<ElementType> &output, const ElementType &radian )
|
||||||
|
{
|
||||||
|
ElementType s = std::sin( radian ),
|
||||||
|
c = std::cos( radian );
|
||||||
|
// output = Matrix4x4<ElementType>( c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1 );
|
||||||
|
output = Matrix4x4<ElementType>( c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, 0, 0, 0, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline void rotationMatrix_AxisZ( Matrix3x3<ElementType> &output, const ElementType &radian )
|
||||||
|
{ ::LinearAlgebra::_2D::rotationMatrix( output, radian ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
void rotationMatrix_AxisZ( Matrix4x4<ElementType> &output, const ElementType &radian )
|
||||||
|
{
|
||||||
|
ElementType s = std::sin( radian ),
|
||||||
|
c = std::cos( radian );
|
||||||
|
// output = Matrix4x4<ElementType>( c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
|
||||||
|
output = Matrix4x4<ElementType>( c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
void rotationMatrix( Matrix4x4<ElementType> &output, const Vector3<ElementType> &normalizedAxis, const ElementType &radian )
|
||||||
|
{ // TODO : Optimize
|
||||||
|
ElementType r = radian * 0.5f,
|
||||||
|
s = std::sin( r ),
|
||||||
|
c = std::cos( r );
|
||||||
|
Quaternion<ElementType> q( normalizedAxis * s, c ),
|
||||||
|
qConj = q.getConjugate();
|
||||||
|
|
||||||
|
output.v[0] = Vector4<ElementType>( (q*Vector3<ElementType>(1,0,0)*qConj).imaginary, 0 );
|
||||||
|
output.v[1] = Vector4<ElementType>( (q*Vector3<ElementType>(0,1,0)*qConj).imaginary, 0 );
|
||||||
|
output.v[2] = Vector4<ElementType>( (q*Vector3<ElementType>(0,0,1)*qConj).imaginary, 0 );
|
||||||
|
output.v[3] = Vector4<ElementType>( 0, 0, 0, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
returns a deltaAngularAxis which is a vectorProduct of the movementVector and leverVector.
|
||||||
|
angular: (1/I) * L, there I is known as the "moment of inertia", L as the "angular momentum vector".
|
||||||
|
lever: Displacement vector relative to the rotation pivot.
|
||||||
|
Recommended reading: http://en.wikipedia.org/wiki/Torque
|
||||||
|
*/
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector3<ElementType> deltaAngularAxis( const Vector3<ElementType> &movement, const Vector3<ElementType> &lever )
|
||||||
|
{ return movement.cross( lever ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector3<ElementType> particleRotationMovement( const Vector3<ElementType> &deltaRadian, const Vector3<ElementType> &lever )
|
||||||
|
{ return lever.cross(deltaRadian) /= lever.dot(lever); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector3<ElementType> vectorProjection( const Vector3<ElementType> &vector, const Vector3<ElementType> &axis )
|
||||||
|
{ return axis * ( vector.dot(axis) / axis.dot(axis) ); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
output; is set to a rigibody matrix that revolve/rotate around centerOfMass and then translates.
|
||||||
|
sumDeltaAngularAxis: Sum of all ( (1/I) * ( L x D ) )-vectorproducts. There I is known as "moment of inertia", L as "angular momentum vector" and D the "lever vector".
|
||||||
|
sumTranslation: Sum of all the translation vectors.
|
||||||
|
centerOfMass: The point the particles is to revolve around, prior to translation. Default set to null vector aka origo.
|
||||||
|
Recommended reading: http://en.wikipedia.org/wiki/Torque
|
||||||
|
*/
|
||||||
|
template<typename ElementType>
|
||||||
|
void rigidBodyMatrix( Matrix4x4<ElementType> &output, const Vector3<ElementType> &sumDeltaAngularAxis, const Vector3<ElementType> &sumTranslation, const Vector3<ElementType> ¢erOfMass = Vector3<ElementType>::null )
|
||||||
|
{
|
||||||
|
ElementType deltaRadian = sumDeltaAngularAxis.length();
|
||||||
|
if( deltaRadian != 0 )
|
||||||
|
{
|
||||||
|
Vector3<ElementType> axis = sumDeltaAngularAxis / deltaRadian;
|
||||||
|
rotationMatrix( output, axis, deltaRadian );
|
||||||
|
|
||||||
|
output.v[3].xyz = centerOfMass;
|
||||||
|
output.v[3].x -= centerOfMass.dot( output.v[0].xyz );
|
||||||
|
output.v[3].y -= centerOfMass.dot( output.v[1].xyz );
|
||||||
|
output.v[3].z -= centerOfMass.dot( output.v[2].xyz );
|
||||||
|
}
|
||||||
|
else output = Matrix4x4<ElementType>::identity;
|
||||||
|
|
||||||
|
output.v[3].xyz += sumTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
output; is set to an orthographic projection matrix.
|
||||||
|
width; of the projection sample volume.
|
||||||
|
height; of the projection sample volume.
|
||||||
|
nearClip: Distance to the nearClippingPlane.
|
||||||
|
farClip: Distance to the farClippingPlane
|
||||||
|
*/
|
||||||
|
template<typename ElementType>
|
||||||
|
void projectionMatrix_Orthographic( Matrix4x4<ElementType> &output, const ElementType &width, const ElementType &height, const ElementType &nearClip, const ElementType &farClip )
|
||||||
|
{
|
||||||
|
ElementType c = 1;
|
||||||
|
c /= nearClip - farClip;
|
||||||
|
output = Matrix4x4<ElementType>( 2/width, 0, 0, 0,
|
||||||
|
0, 2/height, 0, 0,
|
||||||
|
0, 0, -c, 0, 0,
|
||||||
|
0, nearClip*c, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
output; is set to a perspective transform matrix.
|
||||||
|
vertFoV; is the vertical field of vision in radians. (se FoV Hor+ )
|
||||||
|
aspect; is the screenratio width/height (example 16/9 or 16/10 )
|
||||||
|
nearClip: Distance to the nearClippingPlane
|
||||||
|
farClip: Distance to the farClippingPlane
|
||||||
|
*/
|
||||||
|
template<typename ElementType>
|
||||||
|
void projectionMatrix_Perspective( Matrix4x4<ElementType> &output, const ElementType &vertFoV, const ElementType &aspect, const ElementType &nearClip, const ElementType &farClip )
|
||||||
|
{
|
||||||
|
ElementType fov = 1 / ::std::tan( vertFoV * 0.5f ),
|
||||||
|
dDepth = farClip;
|
||||||
|
dDepth /= farClip - nearClip;
|
||||||
|
output = Matrix4x4<ElementType>( fov / aspect, 0, 0, 0, 0, fov, 0, 0, 0, 0, dDepth, 1, 0, 0, -(dDepth * nearClip), 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,761 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Linear Math Matrixes
|
||||||
|
// Š Dan Andersson 2013
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef LINEARALGEBRA_MATRIX_H
|
||||||
|
#define LINEARALGEBRA_MATRIX_H
|
||||||
|
|
||||||
|
#include "Vector.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
namespace LinearAlgebra
|
||||||
|
{
|
||||||
|
template<typename ElementType>
|
||||||
|
class Matrix2x2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
union
|
||||||
|
{
|
||||||
|
ElementType m[2][2];
|
||||||
|
struct{ Vector2<ElementType> v[2]; };
|
||||||
|
// struct{ ElementType m11, m21, m12, m22; };
|
||||||
|
struct{ ElementType m11, m12, m21, m22; };
|
||||||
|
ElementType element[4];
|
||||||
|
char byte[sizeof(ElementType[4])];
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Matrix2x2<ElementType> identity, null;
|
||||||
|
|
||||||
|
Matrix2x2( );
|
||||||
|
Matrix2x2( const ElementType &m11, const ElementType &m12,
|
||||||
|
const ElementType &m21, const ElementType &m22 );
|
||||||
|
Matrix2x2( const Vector2<ElementType> vec[2] );
|
||||||
|
Matrix2x2( const Vector2<ElementType> &vec1, const Vector2<ElementType> &vec2 );
|
||||||
|
Matrix2x2( const ElementType element[4] );
|
||||||
|
Matrix2x2( const Matrix2x2<ElementType> &matrix );
|
||||||
|
|
||||||
|
operator ElementType* ( );
|
||||||
|
operator const ElementType* ( ) const;
|
||||||
|
|
||||||
|
Matrix2x2<ElementType> & operator = ( const Vector2<ElementType> vec[2] );
|
||||||
|
Matrix2x2<ElementType> & operator = ( const ElementType element[4] );
|
||||||
|
Matrix2x2<ElementType> & operator = ( const Matrix2x2<ElementType> &matrix );
|
||||||
|
Matrix2x2<ElementType> & operator += ( const Matrix2x2<ElementType> &matrix );
|
||||||
|
Matrix2x2<ElementType> & operator -= ( const Matrix2x2<ElementType> &matrix );
|
||||||
|
Matrix2x2<ElementType> & operator *= ( const ElementType &scalar );
|
||||||
|
Matrix2x2<ElementType> & operator /= ( const ElementType &scalar );
|
||||||
|
Matrix2x2<ElementType> operator + ( const Matrix2x2<ElementType> &matrix ) const;
|
||||||
|
Matrix2x2<ElementType> operator - ( const Matrix2x2<ElementType> &matrix ) const;
|
||||||
|
Matrix2x2<ElementType> operator * ( const ElementType &scalar ) const;
|
||||||
|
Matrix2x2<ElementType> operator / ( const ElementType &scalar ) const;
|
||||||
|
Matrix2x2<ElementType> operator - ( ) const; // unary negation
|
||||||
|
|
||||||
|
ElementType getDeterminant( ) const;
|
||||||
|
Matrix2x2<ElementType> getAdjoint( ) const;
|
||||||
|
Matrix2x2<ElementType> getTranspose( ) const;
|
||||||
|
Matrix2x2<ElementType> & transpose( );
|
||||||
|
Matrix2x2<ElementType> getInverse( ) const;
|
||||||
|
Matrix2x2<ElementType> getInverse( ElementType &determinant ) const;
|
||||||
|
Matrix2x2<ElementType> & invert( );
|
||||||
|
Matrix2x2<ElementType> & invert( ElementType &determinant );
|
||||||
|
Vector2<ElementType> getRowVector( unsigned int rowID ) const;
|
||||||
|
const Vector2<ElementType> & getColumnVector( unsigned int colID ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
class Matrix3x3
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
union
|
||||||
|
{
|
||||||
|
ElementType m[3][3];
|
||||||
|
struct{ Vector3<ElementType> v[3]; };
|
||||||
|
// struct{ ElementType m11, m21, m31, m12, m22, m32, m13, m23, m33; };
|
||||||
|
struct{ ElementType m11, m12, m13, m21, m22, m23, m31, m32, m33; };
|
||||||
|
ElementType element[9];
|
||||||
|
char byte[sizeof(ElementType[9])];
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Matrix3x3<ElementType> identity, null;
|
||||||
|
|
||||||
|
Matrix3x3( );
|
||||||
|
Matrix3x3( const ElementType &m11, const ElementType &m12, const ElementType &m13,
|
||||||
|
const ElementType &m21, const ElementType &m22, const ElementType &m23,
|
||||||
|
const ElementType &m31, const ElementType &m32, const ElementType &m33 );
|
||||||
|
Matrix3x3( const Vector3<ElementType> vec[3] );
|
||||||
|
Matrix3x3( const Vector3<ElementType> &vec1, const Vector3<ElementType> &vec2, const Vector3<ElementType> &vec3 );
|
||||||
|
Matrix3x3( const ElementType element[9] );
|
||||||
|
Matrix3x3( const Matrix3x3<ElementType> &matrix );
|
||||||
|
|
||||||
|
operator ElementType* ( );
|
||||||
|
operator const ElementType* ( ) const;
|
||||||
|
|
||||||
|
Matrix3x3<ElementType> & operator = ( const Vector3<ElementType> vec[3] );
|
||||||
|
Matrix3x3<ElementType> & operator = ( const ElementType element[9] );
|
||||||
|
Matrix3x3<ElementType> & operator = ( const Matrix3x3<ElementType> &matrix );
|
||||||
|
Matrix3x3<ElementType> & operator += ( const Matrix3x3<ElementType> &matrix );
|
||||||
|
Matrix3x3<ElementType> & operator -= ( const Matrix3x3<ElementType> &matrix );
|
||||||
|
Matrix3x3<ElementType> & operator *= ( const ElementType &scalar );
|
||||||
|
Matrix3x3<ElementType> & operator /= ( const ElementType &scalar );
|
||||||
|
Matrix3x3<ElementType> operator + ( const Matrix3x3<ElementType> &matrix ) const;
|
||||||
|
Matrix3x3<ElementType> operator - ( const Matrix3x3<ElementType> &matrix ) const;
|
||||||
|
Matrix3x3<ElementType> operator * ( const ElementType &scalar ) const;
|
||||||
|
Matrix3x3<ElementType> operator / ( const ElementType &scalar ) const;
|
||||||
|
Matrix3x3<ElementType> operator - ( ) const; // unary negation
|
||||||
|
|
||||||
|
ElementType getDeterminant( ) const;
|
||||||
|
Matrix3x3<ElementType> getAdjoint( ) const;
|
||||||
|
Matrix3x3<ElementType> getTranspose( ) const;
|
||||||
|
Matrix3x3<ElementType> & transpose( );
|
||||||
|
Matrix3x3<ElementType> getInverse( ) const;
|
||||||
|
Matrix3x3<ElementType> getInverse( ElementType &determinant ) const;
|
||||||
|
Matrix3x3<ElementType> & invert( );
|
||||||
|
Matrix3x3<ElementType> & invert( ElementType &determinant );
|
||||||
|
Vector3<ElementType> getRowVector( unsigned int rowID ) const;
|
||||||
|
const Vector3<ElementType> & getColumnVector( unsigned int colID ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
class Matrix4x4
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
union
|
||||||
|
{
|
||||||
|
ElementType m[4][4];
|
||||||
|
struct{ Vector4<ElementType> v[4]; };
|
||||||
|
// struct{ ElementType m11, m21, m31, m41, m12, m22, m32, m42, m13, m23, m33, m43, m14, m24, m34, m44; };
|
||||||
|
struct{ ElementType m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44; };
|
||||||
|
ElementType element[16];
|
||||||
|
char byte[sizeof(ElementType[16])];
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Matrix4x4<ElementType> identity, null;
|
||||||
|
|
||||||
|
Matrix4x4( );
|
||||||
|
Matrix4x4( const ElementType &m11, const ElementType &m12, const ElementType &m13, const ElementType &m14,
|
||||||
|
const ElementType &m21, const ElementType &m22, const ElementType &m23, const ElementType &m24,
|
||||||
|
const ElementType &m31, const ElementType &m32, const ElementType &m33, const ElementType &m34,
|
||||||
|
const ElementType &m41, const ElementType &m42, const ElementType &m43, const ElementType &m44 );
|
||||||
|
Matrix4x4( const Vector4<ElementType> vec[4] );
|
||||||
|
Matrix4x4( const Vector4<ElementType> &vec1, const Vector4<ElementType> &vec2, const Vector4<ElementType> &vec3, const Vector4<ElementType> &vec4 );
|
||||||
|
Matrix4x4( const ElementType element[16] );
|
||||||
|
Matrix4x4( const Matrix4x4<ElementType> &matrix );
|
||||||
|
|
||||||
|
operator ElementType* ( );
|
||||||
|
operator const ElementType* ( ) const;
|
||||||
|
|
||||||
|
Matrix4x4<ElementType> & operator = ( const Vector4<ElementType> vec[4] );
|
||||||
|
Matrix4x4<ElementType> & operator = ( const ElementType element[16] );
|
||||||
|
Matrix4x4<ElementType> & operator = ( const Matrix4x4<ElementType> &matrix );
|
||||||
|
Matrix4x4<ElementType> & operator += ( const Matrix4x4<ElementType> &matrix );
|
||||||
|
Matrix4x4<ElementType> & operator -= ( const Matrix4x4<ElementType> &matrix );
|
||||||
|
Matrix4x4<ElementType> & operator *= ( const ElementType &scalar );
|
||||||
|
Matrix4x4<ElementType> & operator /= ( const ElementType &scalar );
|
||||||
|
Matrix4x4<ElementType> operator + ( const Matrix4x4<ElementType> &matrix ) const;
|
||||||
|
Matrix4x4<ElementType> operator - ( const Matrix4x4<ElementType> &matrix ) const;
|
||||||
|
Matrix4x4<ElementType> operator * ( const ElementType &scalar ) const;
|
||||||
|
Matrix4x4<ElementType> operator / ( const ElementType &scalar ) const;
|
||||||
|
Matrix4x4<ElementType> operator - ( ) const; // unary negation
|
||||||
|
|
||||||
|
ElementType getDeterminant( ) const;
|
||||||
|
Matrix4x4<ElementType> getAdjoint( ) const;
|
||||||
|
Matrix4x4<ElementType> getTranspose( ) const;
|
||||||
|
Matrix4x4<ElementType> & transpose( );
|
||||||
|
Matrix4x4<ElementType> getInverse( ) const;
|
||||||
|
Matrix4x4<ElementType> getInverse( ElementType &determinant ) const;
|
||||||
|
Matrix4x4<ElementType> & invert( );
|
||||||
|
Matrix4x4<ElementType> & invert( ElementType &determinant );
|
||||||
|
Vector4<ElementType> getRowVector( unsigned int rowID ) const;
|
||||||
|
const Vector4<ElementType> & getColumnVector( unsigned int colID ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Body
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Matrix2x2<ElementType> ///////////////////////////////////////
|
||||||
|
template<typename ElementType>
|
||||||
|
const Matrix2x2<ElementType> Matrix2x2<ElementType>::identity = Matrix2x2<ElementType>( 1, 0, 0, 1 );
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
const Matrix2x2<ElementType> Matrix2x2<ElementType>::null = Matrix2x2<ElementType>( 0, 0, 0, 0 );
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType>::Matrix2x2( ) : m11(0), m21(0), m12(0), m22(0) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType>::Matrix2x2( const ElementType &_m11, const ElementType &_m12, const ElementType &_m21, const ElementType &_m22 )
|
||||||
|
: m11(_m11), m21(_m21), m12(_m12), m22(_m22) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType>::Matrix2x2( const Vector2<ElementType> vec[2] )
|
||||||
|
: m11(vec[0].x), m21(vec[0].y), m12(vec[1].x), m22(vec[1].y) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType>::Matrix2x2( const Vector2<ElementType> &vec1, const Vector2<ElementType> &vec2 )
|
||||||
|
: m11(vec1.x), m21(vec1.y), m12(vec2.x), m22(vec2.y) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType>::Matrix2x2( const ElementType _element[4] )
|
||||||
|
// : m11(_element[0]), m21(_element[1]), m12(_element[2]), m22(_element[3]) {}
|
||||||
|
: m11(_element[0]), m12(_element[1]), m21(_element[2]), m22(_element[3]) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType>::Matrix2x2( const Matrix2x2<ElementType> &matrix )
|
||||||
|
: m11(matrix.m11), m21(matrix.m12), m12(matrix.m21), m22(matrix.m22) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix2x2<ElementType>::operator ElementType* ( )
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix2x2<ElementType>::operator const ElementType* ( ) const
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator = ( const Vector2<ElementType> vec[2] )
|
||||||
|
{
|
||||||
|
this->v[0] = vec[0];
|
||||||
|
this->v[1] = vec[1];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator = ( const ElementType element[4] )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 4; ++i )
|
||||||
|
this->element[i] = element[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator = ( const Matrix2x2<ElementType> &matrix )
|
||||||
|
{
|
||||||
|
this->v[0] = matrix.v[0];
|
||||||
|
this->v[1] = matrix.v[1];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator += ( const Matrix2x2<ElementType> &matrix )
|
||||||
|
{
|
||||||
|
this->v[0] += matrix.v[0];
|
||||||
|
this->v[1] += matrix.v[1];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator -= ( const Matrix2x2<ElementType> &matrix )
|
||||||
|
{
|
||||||
|
this->v[0] -= matrix.v[0];
|
||||||
|
this->v[1] -= matrix.v[1];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator *= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
this->v[0] *= scalar;
|
||||||
|
this->v[1] *= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator /= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
this->v[0] /= scalar;
|
||||||
|
this->v[1] /= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::operator + ( const Matrix2x2<ElementType> &matrix ) const
|
||||||
|
{ return Matrix2x2<ElementType>(*this) += matrix; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::operator - ( const Matrix2x2<ElementType> &matrix ) const
|
||||||
|
{ return Matrix2x2<ElementType>(*this) -= matrix; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::operator * ( const ElementType &scalar ) const
|
||||||
|
{ return Matrix2x2<ElementType>(*this) *= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::operator / ( const ElementType &scalar ) const
|
||||||
|
{ return Matrix2x2<ElementType>(*this) /= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::operator - ( ) const
|
||||||
|
{ return Matrix2x2<ElementType>(-this->v[0], -this->v[1]); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
ElementType Matrix2x2<ElementType>::getDeterminant( ) const
|
||||||
|
{
|
||||||
|
ElementType determinant = (this->m11 * this->m22);
|
||||||
|
return determinant -= (this->m12 * this->m21);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType> Matrix2x2<ElementType>::getAdjoint( ) const
|
||||||
|
{ return Matrix2x2<ElementType>( this->m22, -this->m21, -this->m12, this->m11 ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::getTranspose( ) const
|
||||||
|
{ return Matrix2x2<ElementType>( this->element[0], this->element[1], this->element[2], this->element[3] ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType> & Matrix2x2<ElementType>::transpose( )
|
||||||
|
{
|
||||||
|
ElementType swapSpace;
|
||||||
|
Utility::Element::swap( this->m12, this->m21, swapSpace );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::getInverse( ) const
|
||||||
|
{ return this->getAdjoint() /= this->getDeterminant(); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType> Matrix2x2<ElementType>::getInverse( ElementType &determinant ) const
|
||||||
|
{
|
||||||
|
determinant = this->getDeterminant();
|
||||||
|
if( determinant != 0 )
|
||||||
|
return this->getAdjoint() / determinant;
|
||||||
|
return Matrix2x2<ElementType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType> & Matrix2x2<ElementType>::invert( )
|
||||||
|
{
|
||||||
|
*this /= this->getDeterminant();
|
||||||
|
this->m12 *= -1; this->m21 *= -1;
|
||||||
|
|
||||||
|
ElementType swapSpace;
|
||||||
|
Utility::Element::swap( this->m12, this->m21, swapSpace );
|
||||||
|
Utility::Element::swap( this->m11, this->m22, swapSpace );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix2x2<ElementType> & Matrix2x2<ElementType>::invert( ElementType &determinant )
|
||||||
|
{
|
||||||
|
determinant = this->getDeterminant();
|
||||||
|
|
||||||
|
if( determinant != 0 )
|
||||||
|
{
|
||||||
|
*this /= determinant;
|
||||||
|
this->m12 *= -1; this->m21 *= -1;
|
||||||
|
|
||||||
|
ElementType swapSpace;
|
||||||
|
Utility::Element::swap( this->m12, this->m21, swapSpace );
|
||||||
|
Utility::Element::swap( this->m11, this->m22, swapSpace );
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector2<ElementType> Matrix2x2<ElementType>::getRowVector( unsigned int rowID ) const
|
||||||
|
{ return Vector2<ElementType>( this->m[0][rowID], this->m[1][rowID] ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline const Vector2<ElementType> & Matrix2x2<ElementType>::getColumnVector( unsigned int colID ) const
|
||||||
|
{ return this->v[colID]; }
|
||||||
|
|
||||||
|
// Matrix3x3<ElementType> ///////////////////////////////////////
|
||||||
|
template<typename ElementType>
|
||||||
|
const Matrix3x3<ElementType> Matrix3x3<ElementType>::identity = Matrix3x3<ElementType>( 1, 0, 0, 0, 1, 0, 0, 0, 1 );
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
const Matrix3x3<ElementType> Matrix3x3<ElementType>::null = Matrix3x3<ElementType>( 0, 0, 0, 0, 0, 0, 0, 0, 0 );
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType>::Matrix3x3( ) : m11(0), m21(0), m31(0), m12(0), m22(0), m32(0), m13(0), m23(0), m33(0) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType>::Matrix3x3( const ElementType &_m11, const ElementType &_m12, const ElementType &_m13, const ElementType &_m21, const ElementType &_m22, const ElementType &_m23, const ElementType &_m31, const ElementType &_m32, const ElementType &_m33 )
|
||||||
|
: m11(_m11), m21(_m21), m31(_m31), m12(_m12), m22(_m22), m32(_m32), m13(_m13), m23(_m23), m33(_m33) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType>::Matrix3x3( const Vector3<ElementType> vec[3] )
|
||||||
|
: m11(vec[0].x), m21(vec[0].y), m31(vec[0].z), m12(vec[1].x), m22(vec[1].y), m32(vec[1].z), m13(vec[2].x), m23(vec[2].y), m33(vec[2].z) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType>::Matrix3x3( const Vector3<ElementType> &vec1, const Vector3<ElementType> &vec2, const Vector3<ElementType> &vec3 )
|
||||||
|
: m11(vec1.x), m21(vec1.y), m31(vec1.z), m12(vec2.x), m22(vec2.y), m32(vec2.z), m13(vec3.x), m23(vec3.y), m33(vec3.z) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType>::Matrix3x3( const ElementType _element[9] )
|
||||||
|
// : m11(_element[0]), m21(_element[1]), m31(_element[2]), m12(_element[3]), m22(_element[4]), m32(_element[5]), m13(_element[6]), m23(_element[7]), m33(_element[8]) {}
|
||||||
|
: m11(_element[0]), m12(_element[1]), m13(_element[2]), m21(_element[3]), m22(_element[4]), m23(_element[5]), m31(_element[6]), m32(_element[7]), m33(_element[8]) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType>::Matrix3x3( const Matrix3x3<ElementType> &matrix )
|
||||||
|
: m11(matrix.m11), m21(matrix.m21), m31(matrix.m31), m12(matrix.m12), m22(matrix.m22), m32(matrix.m32), m13(matrix.m13), m23(matrix.m23), m33(matrix.m33) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix3x3<ElementType>::operator ElementType* ( )
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix3x3<ElementType>::operator const ElementType* ( ) const
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator = ( const Vector3<ElementType> vec[3] )
|
||||||
|
{
|
||||||
|
this->v[0] = vec[0];
|
||||||
|
this->v[1] = vec[1];
|
||||||
|
this->v[2] = vec[2];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator = ( const ElementType element[9] )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 9; ++i )
|
||||||
|
this->element[i] = element[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator = ( const Matrix3x3<ElementType> &matrix )
|
||||||
|
{
|
||||||
|
this->v[0] = matrix.v[0];
|
||||||
|
this->v[1] = matrix.v[1];
|
||||||
|
this->v[2] = matrix.v[2];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator += ( const Matrix3x3<ElementType> &matrix )
|
||||||
|
{
|
||||||
|
this->v[0] += matrix.v[0];
|
||||||
|
this->v[1] += matrix.v[1];
|
||||||
|
this->v[2] += matrix.v[2];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator -= ( const Matrix3x3<ElementType> &matrix )
|
||||||
|
{
|
||||||
|
this->v[0] -= matrix.v[0];
|
||||||
|
this->v[1] -= matrix.v[1];
|
||||||
|
this->v[2] -= matrix.v[2];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator *= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
this->v[0] *= scalar;
|
||||||
|
this->v[1] *= scalar;
|
||||||
|
this->v[2] *= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator /= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
this->v[0] /= scalar;
|
||||||
|
this->v[1] /= scalar;
|
||||||
|
this->v[2] /= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix3x3<ElementType> Matrix3x3<ElementType>::operator + ( const Matrix3x3<ElementType> &matrix ) const
|
||||||
|
{ return Matrix3x3<ElementType>(*this) += matrix; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix3x3<ElementType> Matrix3x3<ElementType>::operator - ( const Matrix3x3<ElementType> &matrix ) const
|
||||||
|
{ return Matrix3x3<ElementType>(*this) -= matrix; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix3x3<ElementType> Matrix3x3<ElementType>::operator * ( const ElementType &scalar ) const
|
||||||
|
{ return Matrix3x3<ElementType>(*this) *= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix3x3<ElementType> Matrix3x3<ElementType>::operator / ( const ElementType &scalar ) const
|
||||||
|
{ return Matrix3x3<ElementType>(*this) /= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix3x3<ElementType> Matrix3x3<ElementType>::operator - ( ) const
|
||||||
|
{ return Matrix3x3<ElementType>(-this->v[0], -this->v[1], -this->v[2]); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
ElementType Matrix3x3<ElementType>::getDeterminant( ) const
|
||||||
|
{
|
||||||
|
ElementType determinant = (this->m11 * this->m22 * this->m33);
|
||||||
|
determinant += (this->m12 * this->m23 * this->m31);
|
||||||
|
determinant += (this->m13 * this->m21 * this->m32);
|
||||||
|
determinant -= (this->m11 * this->m23 * this->m32);
|
||||||
|
determinant -= (this->m12 * this->m21 * this->m33);
|
||||||
|
return determinant -= (this->m13 * this->m22 * this->m31);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> Matrix3x3<ElementType>::getAdjoint( ) const
|
||||||
|
{
|
||||||
|
return Matrix3x3<ElementType>( (this->m22*this->m33 - this->m23*this->m32), (this->m13*this->m32 - this->m12*this->m33), (this->m12*this->m23 - this->m13*this->m22),
|
||||||
|
(this->m23*this->m31 - this->m21*this->m33), (this->m11*this->m33 - this->m13*this->m31), (this->m13*this->m21 - this->m11*this->m23),
|
||||||
|
(this->m21*this->m32 - this->m22*this->m31), (this->m12*this->m31 - this->m11*this->m32), (this->m11*this->m22 - this->m12*this->m21) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix3x3<ElementType> Matrix3x3<ElementType>::getTranspose( ) const
|
||||||
|
{
|
||||||
|
return Matrix3x3<ElementType>( this->m11, this->m21, this->m31,
|
||||||
|
this->m12, this->m22, this->m32,
|
||||||
|
this->m13, this->m23, this->m33 );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> & Matrix3x3<ElementType>::transpose( )
|
||||||
|
{
|
||||||
|
ElementType swapSpace;
|
||||||
|
Utility::Element::swap( this->m12, this->m21, swapSpace );
|
||||||
|
Utility::Element::swap( this->m13, this->m31, swapSpace );
|
||||||
|
Utility::Element::swap( this->m23, this->m32, swapSpace );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> Matrix3x3<ElementType>::getInverse( ) const
|
||||||
|
{ return this->getAdjoint() /= this->getDeterminant(); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> Matrix3x3<ElementType>::getInverse( ElementType &determinant ) const
|
||||||
|
{
|
||||||
|
determinant = this->getDeterminant();
|
||||||
|
if( determinant != 0 )
|
||||||
|
return this->getAdjoint() /= determinant;
|
||||||
|
else return Matrix3x3<ElementType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> & Matrix3x3<ElementType>::invert( )
|
||||||
|
{ return *this = this->getAdjoint() /= this->getDeterminant(); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix3x3<ElementType> & Matrix3x3<ElementType>::invert( ElementType &determinant )
|
||||||
|
{
|
||||||
|
determinant = this->getDeterminant();
|
||||||
|
if( determinant != 0 )
|
||||||
|
return *this = this->getAdjoint() /= determinant;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector3<ElementType> Matrix3x3<ElementType>::getRowVector( unsigned int rowID ) const
|
||||||
|
{ return Vector3<ElementType>( this->m[0][rowID], this->m[1][rowID], this->m[2][rowID] ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline const Vector3<ElementType> & Matrix3x3<ElementType>::getColumnVector( unsigned int colID ) const
|
||||||
|
{ return this->v[colID]; }
|
||||||
|
|
||||||
|
// Matrix4x4<ElementType> ///////////////////////////////////////
|
||||||
|
template<typename ElementType>
|
||||||
|
const Matrix4x4<ElementType> Matrix4x4<ElementType>::identity = Matrix4x4<ElementType>( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
const Matrix4x4<ElementType> Matrix4x4<ElementType>::null = Matrix4x4<ElementType>( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType>::Matrix4x4( )
|
||||||
|
: m11(0), m21(0), m31(0), m41(0), m12(0), m22(0), m32(0), m42(0), m13(0), m23(0), m33(0), m43(0), m14(0), m24(0), m34(0), m44(0) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType>::Matrix4x4( const ElementType &_m11, const ElementType &_m12, const ElementType &_m13, const ElementType &_m14, const ElementType &_m21, const ElementType &_m22, const ElementType &_m23, const ElementType &_m24, const ElementType &_m31, const ElementType &_m32, const ElementType &_m33, const ElementType &_m34, const ElementType &_m41, const ElementType &_m42, const ElementType &_m43, const ElementType &_m44 )
|
||||||
|
: m11(_m11), m21(_m21), m31(_m31), m41(_m41), m12(_m12), m22(_m22), m32(_m32), m42(_m42), m13(_m13), m23(_m23), m33(_m33), m43(_m43), m14(_m14), m24(_m24), m34(_m34), m44(_m44) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType>::Matrix4x4( const Vector4<ElementType> vec[4] )
|
||||||
|
: m11(vec[0].x), m21(vec[0].y), m31(vec[0].z), m41(vec[0].w), m12(vec[1].x), m22(vec[1].y), m32(vec[1].z), m42(vec[1].w), m13(vec[2].x), m23(vec[2].y), m33(vec[2].z), m43(vec[2].w), m14(vec[3].x), m24(vec[3].y), m34(vec[3].z), m44(vec[3].w) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType>::Matrix4x4( const Vector4<ElementType> &vec1, const Vector4<ElementType> &vec2, const Vector4<ElementType> &vec3, const Vector4<ElementType> &vec4 )
|
||||||
|
: m11(vec1.x), m21(vec1.y), m31(vec1.z), m41(vec1.w), m12(vec2.x), m22(vec2.y), m32(vec2.z), m42(vec2.w), m13(vec3.x), m23(vec3.y), m33(vec3.z), m43(vec3.w), m14(vec4.x), m24(vec4.y), m34(vec4.z), m44(vec4.w) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType>::Matrix4x4( const ElementType _element[16] )
|
||||||
|
// : m11(_element[0]), m21(_element[1]), m31(_element[2]), m41(_element[3]), m12(_element[4]), m22(_element[5]), m32(_element[6]), m42(_element[7]), m13(_element[8]), m23(_element[9]), m33(_element[10]), m43(_element[11]), m14(_element[12]), m24(_element[13]), m34(_element[14]), m44(_element[15]) {}
|
||||||
|
: m11(_element[0]), m12(_element[1]), m13(_element[2]), m14(_element[3]), m21(_element[4]), m22(_element[5]), m23(_element[6]), m24(_element[7]), m31(_element[8]), m32(_element[9]), m33(_element[10]), m34(_element[11]), m41(_element[12]), m42(_element[13]), m43(_element[14]), m44(_element[15]) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType>::Matrix4x4( const Matrix4x4<ElementType> &matrix )
|
||||||
|
: m11(matrix.m11), m21(matrix.m21), m31(matrix.m31), m41(matrix.m41), m12(matrix.m12), m22(matrix.m22), m32(matrix.m32), m42(matrix.m42), m13(matrix.m13), m23(matrix.m23), m33(matrix.m33), m43(matrix.m43), m14(matrix.m14), m24(matrix.m24), m34(matrix.m34), m44(matrix.m44) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix4x4<ElementType>::operator ElementType* ( )
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix4x4<ElementType>::operator const ElementType* ( ) const
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator = ( const Vector4<ElementType> vec[4] )
|
||||||
|
{
|
||||||
|
this->v[0] = vec[0];
|
||||||
|
this->v[1] = vec[1];
|
||||||
|
this->v[2] = vec[2];
|
||||||
|
this->v[3] = vec[3];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator = ( const ElementType element[16] )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 16; ++i )
|
||||||
|
this->element[i] = element[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator = ( const Matrix4x4<ElementType> &matrix )
|
||||||
|
{
|
||||||
|
this->v[0] = matrix.v[0];
|
||||||
|
this->v[1] = matrix.v[1];
|
||||||
|
this->v[2] = matrix.v[2];
|
||||||
|
this->v[3] = matrix.v[3];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator += ( const Matrix4x4<ElementType> &matrix )
|
||||||
|
{
|
||||||
|
this->v[0] += matrix.v[0];
|
||||||
|
this->v[1] += matrix.v[1];
|
||||||
|
this->v[2] += matrix.v[2];
|
||||||
|
this->v[3] += matrix.v[3];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator -= ( const Matrix4x4<ElementType> &matrix )
|
||||||
|
{
|
||||||
|
this->v[0] -= matrix.v[0];
|
||||||
|
this->v[1] -= matrix.v[1];
|
||||||
|
this->v[2] -= matrix.v[2];
|
||||||
|
this->v[3] -= matrix.v[3];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator *= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
this->v[0] *= scalar;
|
||||||
|
this->v[1] *= scalar;
|
||||||
|
this->v[2] *= scalar;
|
||||||
|
this->v[3] *= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator /= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
this->v[0] /= scalar;
|
||||||
|
this->v[1] /= scalar;
|
||||||
|
this->v[2] /= scalar;
|
||||||
|
this->v[3] /= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::operator + ( const Matrix4x4<ElementType> &matrix ) const
|
||||||
|
{ return Matrix4x4<ElementType>(*this) += matrix; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::operator - ( const Matrix4x4<ElementType> &matrix ) const
|
||||||
|
{ return Matrix4x4<ElementType>(*this) -= matrix; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::operator * ( const ElementType &scalar ) const
|
||||||
|
{ return Matrix4x4<ElementType>(*this) *= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::operator / ( const ElementType &scalar ) const
|
||||||
|
{ return Matrix4x4<ElementType>(*this) /= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::operator - ( ) const
|
||||||
|
{ return Matrix4x4<ElementType>(-this->v[0], -this->v[1], -this->v[2], -this->v[3]); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
ElementType Matrix4x4<ElementType>::getDeterminant( ) const
|
||||||
|
{
|
||||||
|
ElementType determinant = this->m11 * Matrix3x3<ElementType>(this->m22, this->m23, this->m24, this->m32, this->m33, this->m34, this->m42, this->m43, this->m44).getDeterminant();
|
||||||
|
determinant -= this->m12 * Matrix3x3<ElementType>(this->m21, this->m23, this->m24, this->m31, this->m33, this->m34, this->m41, this->m43, this->m44).getDeterminant();
|
||||||
|
determinant += this->m13 * Matrix3x3<ElementType>(this->m21, this->m22, this->m24, this->m31, this->m32, this->m34, this->m41, this->m42, this->m44).getDeterminant();
|
||||||
|
return determinant -= this->m14 * Matrix3x3<ElementType>(this->m21, this->m22, this->m23, this->m31, this->m32, this->m33, this->m41, this->m42, this->m43).getDeterminant();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType> Matrix4x4<ElementType>::getAdjoint( ) const
|
||||||
|
{
|
||||||
|
return Matrix4x4<ElementType>( Matrix3x3<ElementType>(this->m22, this->m23, this->m24, this->m32, this->m33, this->m34, this->m42, this->m43, this->m44).getDeterminant(), -Matrix3x3<ElementType>(this->m12, this->m13, this->m14, this->m32, this->m33, this->m34, this->m42, this->m43, this->m44).getDeterminant(), Matrix3x3<ElementType>(this->m12, this->m13, this->m14, this->m22, this->m23, this->m24, this->m42, this->m43, this->m44).getDeterminant(), -Matrix3x3<ElementType>(this->m12, this->m13, this->m14, this->m22, this->m23, this->m24, this->m32, this->m33, this->m34).getDeterminant(),
|
||||||
|
-Matrix3x3<ElementType>(this->m21, this->m23, this->m24, this->m31, this->m33, this->m34, this->m41, this->m43, this->m44).getDeterminant(), Matrix3x3<ElementType>(this->m11, this->m13, this->m14, this->m31, this->m33, this->m34, this->m41, this->m43, this->m44).getDeterminant(), -Matrix3x3<ElementType>(this->m11, this->m13, this->m14, this->m21, this->m23, this->m24, this->m41, this->m43, this->m44).getDeterminant(), Matrix3x3<ElementType>(this->m11, this->m13, this->m14, this->m21, this->m23, this->m24, this->m31, this->m33, this->m34).getDeterminant(),
|
||||||
|
Matrix3x3<ElementType>(this->m21, this->m22, this->m24, this->m31, this->m32, this->m34, this->m41, this->m42, this->m44).getDeterminant(), -Matrix3x3<ElementType>(this->m11, this->m12, this->m14, this->m31, this->m32, this->m34, this->m41, this->m42, this->m44).getDeterminant(), Matrix3x3<ElementType>(this->m11, this->m12, this->m14, this->m21, this->m22, this->m24, this->m41, this->m42, this->m44).getDeterminant(), -Matrix3x3<ElementType>(this->m11, this->m12, this->m14, this->m21, this->m22, this->m24, this->m31, this->m32, this->m34).getDeterminant(),
|
||||||
|
-Matrix3x3<ElementType>(this->m21, this->m22, this->m23, this->m31, this->m32, this->m33, this->m41, this->m42, this->m43).getDeterminant(), Matrix3x3<ElementType>(this->m11, this->m12, this->m13, this->m31, this->m32, this->m33, this->m41, this->m42, this->m43).getDeterminant(), -Matrix3x3<ElementType>(this->m11, this->m12, this->m13, this->m21, this->m22, this->m23, this->m41, this->m42, this->m43).getDeterminant(), Matrix3x3<ElementType>(this->m11, this->m12, this->m13, this->m21, this->m22, this->m23, this->m31, this->m32, this->m33).getDeterminant() );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::getTranspose( ) const
|
||||||
|
{
|
||||||
|
return Matrix4x4<ElementType>( this->m11, this->m21, this->m31, this->m41,
|
||||||
|
this->m12, this->m22, this->m32, this->m42,
|
||||||
|
this->m13, this->m23, this->m33, this->m43,
|
||||||
|
this->m14, this->m24, this->m34, this->m44 );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType> & Matrix4x4<ElementType>::transpose( )
|
||||||
|
{
|
||||||
|
ElementType swapSpace;
|
||||||
|
::Utility::Element::swap( this->m12, this->m21, swapSpace );
|
||||||
|
::Utility::Element::swap( this->m13, this->m31, swapSpace );
|
||||||
|
::Utility::Element::swap( this->m14, this->m41, swapSpace );
|
||||||
|
::Utility::Element::swap( this->m23, this->m32, swapSpace );
|
||||||
|
::Utility::Element::swap( this->m24, this->m42, swapSpace );
|
||||||
|
::Utility::Element::swap( this->m34, this->m43, swapSpace );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::getInverse( ) const
|
||||||
|
{ return this->getAdjoint() /= this->getDeterminant() ; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType> Matrix4x4<ElementType>::getInverse( ElementType &determinant ) const
|
||||||
|
{
|
||||||
|
determinant = this->getDeterminant();
|
||||||
|
if( determinant != 0.0f )
|
||||||
|
return this->getAdjoint() /= determinant;
|
||||||
|
return Matrix4x4<ElementType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType> & Matrix4x4<ElementType>::invert( )
|
||||||
|
{ return *this = this->getAdjoint() /= this->getDeterminant(); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Matrix4x4<ElementType> & Matrix4x4<ElementType>::invert( ElementType &determinant )
|
||||||
|
{
|
||||||
|
determinant = this->getDeterminant();
|
||||||
|
if( determinant != 0.0f )
|
||||||
|
return *this = this->getAdjoint() /= determinant;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector4<ElementType> Matrix4x4<ElementType>::getRowVector( unsigned int rowID ) const
|
||||||
|
{ return Vector4<ElementType>( this->m[0][rowID], this->m[1][rowID], this->m[2][rowID], this->m[3][rowID] ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline const Vector4<ElementType> & Matrix4x4<ElementType>::getColumnVector( unsigned int colID ) const
|
||||||
|
{ return this->v[colID]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,32 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// by Dan Andersson 2013
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "OysterMath.h"
|
||||||
|
|
||||||
|
namespace Oyster { namespace Math
|
||||||
|
{
|
||||||
|
Float2 & operator *= ( Float2 &left, const Float2 &right )
|
||||||
|
{
|
||||||
|
left.x *= right.x;
|
||||||
|
left.y *= right.y;
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
Float3 & operator *= ( Float3 &left, const Float3 &right )
|
||||||
|
{
|
||||||
|
left.x *= right.x;
|
||||||
|
left.y *= right.y;
|
||||||
|
left.z *= right.z;
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4 & operator *= ( Float4 &left, const Float4 &right )
|
||||||
|
{
|
||||||
|
left.x *= right.x;
|
||||||
|
left.y *= right.y;
|
||||||
|
left.z *= right.z;
|
||||||
|
left.w *= right.w;
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
} }
|
|
@ -0,0 +1,220 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// by Dan Andersson 2013
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef OYSTER_MATH_H
|
||||||
|
#define OYSTER_MATH_H
|
||||||
|
|
||||||
|
#include "Utilities.h"
|
||||||
|
#include "LinearMath.h"
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace Oyster { namespace Math
|
||||||
|
{
|
||||||
|
typedef float Float;
|
||||||
|
|
||||||
|
typedef ::LinearAlgebra::Vector2<Float> Float2;
|
||||||
|
typedef ::LinearAlgebra::Vector3<Float> Float3;
|
||||||
|
typedef ::LinearAlgebra::Vector4<Float> Float4;
|
||||||
|
|
||||||
|
typedef ::LinearAlgebra::Matrix2x2<Float> Float2x2;
|
||||||
|
typedef ::LinearAlgebra::Matrix3x3<Float> Float3x3;
|
||||||
|
typedef ::LinearAlgebra::Matrix4x4<Float> Float4x4;
|
||||||
|
|
||||||
|
typedef Float4x4 Matrix;
|
||||||
|
typedef Float2 Vector2;
|
||||||
|
typedef Float3 Vector3;
|
||||||
|
typedef Float4 Vector4;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Float2 & operator *= ( Float2 &left, const Float2 &right );
|
||||||
|
|
||||||
|
inline Float2 operator * ( const Float2 &left, const Float2 &right )
|
||||||
|
{ return Float2(left) *= right; }
|
||||||
|
|
||||||
|
inline Float2 operator * ( const Float &left, const Float2 &right )
|
||||||
|
{ return Float2(right) *= left; }
|
||||||
|
|
||||||
|
Float3 & operator *= ( Float3 &left, const Float3 &right );
|
||||||
|
|
||||||
|
inline Float3 operator * ( const Float3 &left, const Float3 &right )
|
||||||
|
{ return Float3(left) *= right; }
|
||||||
|
|
||||||
|
inline Float3 operator * ( const Float &left, const Float3 &right )
|
||||||
|
{ return Float3(right) *= left; }
|
||||||
|
|
||||||
|
Float4 & operator *= ( Float4 &left, const Float4 &right );
|
||||||
|
|
||||||
|
inline Float4 operator * ( const Float4 &left, const Float4 &right )
|
||||||
|
{ return Float4(left) *= right; }
|
||||||
|
|
||||||
|
inline Float4 operator * ( const Float &left, const Float4 &right )
|
||||||
|
{ return Float4(right) *= left; }
|
||||||
|
|
||||||
|
inline Float2x2 operator * ( const Float &left, const Float2x2 &right )
|
||||||
|
{ return Float2x2(right) *= left; }
|
||||||
|
|
||||||
|
inline Float3x3 operator * ( const Float &left, const Float3x3 &right )
|
||||||
|
{ return Float3x3(right) *= left; }
|
||||||
|
|
||||||
|
inline Float4x4 operator * ( const Float &left, const Float4x4 &right )
|
||||||
|
{ return Float4x4(right) *= left; }
|
||||||
|
|
||||||
|
// Deprecated function! Use the static const member identity instead.
|
||||||
|
inline void identityMatrix( Float2x2 &output )
|
||||||
|
{ output = Float2x2::identity; }
|
||||||
|
|
||||||
|
// Deprecated function! Use the static const member identity instead.
|
||||||
|
inline void identityMatrix( Float3x3 &output )
|
||||||
|
{ output = Float3x3::identity; }
|
||||||
|
|
||||||
|
// Deprecated function! Use the static const member identity instead.
|
||||||
|
inline void identityMatrix( Float4x4 &output )
|
||||||
|
{ output = Float4x4::identity; }
|
||||||
|
|
||||||
|
// If rigidBody is assumed to be by all definitions a rigid body matrix. Then this is a faster inverse method.
|
||||||
|
inline void inverseRigidBodyMatrix( Float4x4 &output, const Float4x4 &rigidBody )
|
||||||
|
{ ::LinearAlgebra::_3D::inverseRigidBody( output, rigidBody ); }
|
||||||
|
|
||||||
|
inline void translationMatrix( Float4x4 &output, const Float3 &position )
|
||||||
|
{ ::LinearAlgebra::_3D::translationMatrix( output, position ); }
|
||||||
|
|
||||||
|
// counterclockwise rotation around X axis
|
||||||
|
inline void rotationMatrix_AxisX( Float4x4 &output, const Float &radian )
|
||||||
|
{ ::LinearAlgebra::_3D::rotationMatrix_AxisX( output, radian ); }
|
||||||
|
|
||||||
|
// counterclockwise rotation around Y axis
|
||||||
|
inline void rotationMatrix_AxisY( Float4x4 &output, const Float &radian )
|
||||||
|
{ ::LinearAlgebra::_3D::rotationMatrix_AxisY( output, radian ); }
|
||||||
|
|
||||||
|
// counterclockwise rotation around Z axis
|
||||||
|
inline void rotationMatrix_AxisZ( Float4x4 &output, const Float &radian )
|
||||||
|
{ ::LinearAlgebra::_3D::rotationMatrix_AxisZ( output, radian ); }
|
||||||
|
|
||||||
|
// counterclockwise rotation around any given Float3 vector (normalizedAxis). Please make sure it is normalized.
|
||||||
|
inline void rotationMatrix( Float4x4 &output, const Float &radian, const Float3 &normalizedAxis )
|
||||||
|
{ ::LinearAlgebra::_3D::rotationMatrix( output, normalizedAxis, radian ); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
returns a deltaAngularAxis which is a vectorProduct of the particleMovementVector and leverVector.
|
||||||
|
angular: (1/I) * L, there I is known as the "moment of inertia", L as the "angular momentum vector".
|
||||||
|
lever: Displacement vector relative to the center of mass.
|
||||||
|
Recommended reading: http://en.wikipedia.org/wiki/Torque
|
||||||
|
*/
|
||||||
|
inline Float3 deltaAngularAxis( const Float3 &movement, const Float3 &lever )
|
||||||
|
{ return ::LinearAlgebra::_3D::deltaAngularAxis( movement, lever ); }
|
||||||
|
|
||||||
|
inline Float3 particleRotationMovement( const Float3 &deltaRadian, const Float3 &lever )
|
||||||
|
{ return ::LinearAlgebra::_3D::particleRotationMovement( deltaRadian, lever ); }
|
||||||
|
|
||||||
|
inline Float3 vectorProjection( const Float3 &vector, const Float3 &axis )
|
||||||
|
{ return ::LinearAlgebra::_3D::vectorProjection( vector, axis ); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
output: is set to a rigibody matrix that revolve/rotate around centerOfMass and then translates.
|
||||||
|
sumDeltaAngularAxis: sum of all ( (1/I) * ( L x D ) )-vectorproducts. There I is known as "moment of inertia", L as "angular momentum vector" and D the "lever vector".
|
||||||
|
sumTranslation: sum of all the translation vectors.
|
||||||
|
centerOfMass: the point the particles is to revolve around, prior to translation. Default set to null vector aka origo.
|
||||||
|
Recommended reading: http://en.wikipedia.org/wiki/Torque
|
||||||
|
*/
|
||||||
|
inline void rigidBodyMatrix( Float4x4 &output, const Float3 &sumDeltaAngularAxis, const Float3 &sumTranslation, const Float3 ¢erOfMass = Float3::null )
|
||||||
|
{ ::LinearAlgebra::_3D::rigidBodyMatrix( output, sumDeltaAngularAxis, sumTranslation, centerOfMass ); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
output; is set to an orthographic projection matrix.
|
||||||
|
width; of the projection sample volume.
|
||||||
|
height; of the projection sample volume.
|
||||||
|
near: Distance to the nearPlane.
|
||||||
|
far: Distance to the farPlane
|
||||||
|
*/
|
||||||
|
inline void projectionMatrix_Orthographic( Float4x4 &output, const Float &width, const Float &height, const Float &nearClip = ::std::numeric_limits<Float>::epsilon(), const Float &farClip = ::std::numeric_limits<Float>::max() )
|
||||||
|
{ ::LinearAlgebra::_3D::projectionMatrix_Orthographic( output, width, height, nearClip, farClip ); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
output; is set to a perspective transform matrix.
|
||||||
|
vertFoV; is the vertical field of vision in radians. (se FoV Hor+ )
|
||||||
|
aspect; is the screenratio width/height (example 16/9 or 16/10 )
|
||||||
|
near: Distance to the nearPlane
|
||||||
|
far: Distance to the farPlane
|
||||||
|
*/
|
||||||
|
inline void projectionMatrix_Perspective( Float4x4 &output, const Float &verticalFoV, const Float &aspectRatio, const Float &nearClip = ::std::numeric_limits<Float>::epsilon(), const Float &farClip = ::std::numeric_limits<Float>::max() )
|
||||||
|
{ ::LinearAlgebra::_3D::projectionMatrix_Perspective( output, verticalFoV, aspectRatio, nearClip, farClip ); }
|
||||||
|
|
||||||
|
inline Float4x4 & viewProjectionMatrix( Float4x4 &output, const Float4x4 &view, const Float4x4 &projection )
|
||||||
|
{ return output = (view * projection).getTranspose(); }
|
||||||
|
|
||||||
|
inline Float4x4 & transformMatrix( Float4x4 &output, const Float4x4 &transformee, const Float4x4 &transformer )
|
||||||
|
{ return output = transformee * transformer; }
|
||||||
|
|
||||||
|
inline Float4x4 transformMatrix( const Float4x4 &transformee, const Float4x4 &transformer )
|
||||||
|
{ return transformee * transformer; }
|
||||||
|
|
||||||
|
inline Float4 & transformVector( Float4 &output, const Float4 &transformee, const Float4x4 &transformer )
|
||||||
|
{ return output = transformer * transformee; }
|
||||||
|
|
||||||
|
inline Float4 transformVector( const Float4 &transformee, const Float4x4 &transformer )
|
||||||
|
{ return transformee * transformer; }
|
||||||
|
} }
|
||||||
|
|
||||||
|
namespace Utility { namespace Value
|
||||||
|
{ // Utility Value Specializations
|
||||||
|
using namespace ::Oyster::Math;
|
||||||
|
|
||||||
|
template< > inline Float2 abs<Float2>( const Float2 &value )
|
||||||
|
{ return Float2( abs(value.x), abs(value.y) ); }
|
||||||
|
|
||||||
|
template< > inline Float2 max<Float2>( const Float2 &valueA, const Float2 &valueB )
|
||||||
|
{ return Float2( max(valueA.x, valueB.x), max(valueA.y, valueB.y) ); }
|
||||||
|
|
||||||
|
template< > inline Float2 min<Float2>( const Float2 &valueA, const Float2 &valueB )
|
||||||
|
{ return Float2( min(valueA.x, valueB.x), min(valueA.y, valueB.y) ); }
|
||||||
|
|
||||||
|
template< > inline Float3 abs<Float3>( const Float3 &value )
|
||||||
|
{ return Float3( abs(value.xy), abs(value.z) ); }
|
||||||
|
|
||||||
|
template< > inline Float3 max<Float3>( const Float3 &valueA, const Float3 &valueB )
|
||||||
|
{ return Float3( max(valueA.xy, valueB.xy), max(valueA.z, valueB.z) ); }
|
||||||
|
|
||||||
|
template< > inline Float3 min<Float3>( const Float3 &valueA, const Float3 &valueB )
|
||||||
|
{ return Float3( min(valueA.xy, valueB.xy), min(valueA.z, valueB.z) ); }
|
||||||
|
|
||||||
|
template< > inline Float4 abs<Float4>( const Float4 &value )
|
||||||
|
{ return Float4( abs(value.xyz), abs(value.w) ); }
|
||||||
|
|
||||||
|
template< > inline Float4 max<Float4>( const Float4 &valueA, const Float4 &valueB )
|
||||||
|
{ return Float4( max(valueA.xyz, valueB.xyz), max(valueA.w, valueB.w) ); }
|
||||||
|
|
||||||
|
template< > inline Float4 min<Float4>( const Float4 &valueA, const Float4 &valueB )
|
||||||
|
{ return Float4( min(valueA.xyz, valueB.xyz), min(valueA.w, valueB.w) ); }
|
||||||
|
|
||||||
|
template< > inline Float2x2 abs<Float2x2>( const Float2x2 &value )
|
||||||
|
{ return Float2x2( abs(value.v[0]), abs(value.v[1]) ); }
|
||||||
|
|
||||||
|
template< > inline Float2x2 max<Float2x2>( const Float2x2 &valueA, const Float2x2 &valueB )
|
||||||
|
{ return Float2x2( max(valueA.v[0], valueB.v[0]), max(valueA.v[1], valueB.v[1]) ); }
|
||||||
|
|
||||||
|
template< > inline Float2x2 min<Float2x2>( const Float2x2 &valueA, const Float2x2 &valueB )
|
||||||
|
{ return Float2x2( min(valueA.v[0], valueB.v[0]), min(valueA.v[1], valueB.v[1]) ); }
|
||||||
|
|
||||||
|
template< > inline Float3x3 abs<Float3x3>( const Float3x3 &value )
|
||||||
|
{ return Float3x3( abs(value.v[0]), abs(value.v[1]), abs(value[2]) ); }
|
||||||
|
|
||||||
|
template< > inline Float3x3 max<Float3x3>( const Float3x3 &valueA, const Float3x3 &valueB )
|
||||||
|
{ return Float3x3( max(valueA.v[0], valueB.v[0]), max(valueA.v[1], valueB.v[1]), max(valueA.v[2], valueB.v[2]) ); }
|
||||||
|
|
||||||
|
template< > inline Float3x3 min<Float3x3>( const Float3x3 &valueA, const Float3x3 &valueB )
|
||||||
|
{ return Float3x3( min(valueA.v[0], valueB.v[0]), min(valueA.v[1], valueB.v[1]), min(valueA.v[2], valueB.v[2]) ); }
|
||||||
|
|
||||||
|
template< > inline Float4x4 abs<Float4x4>( const Float4x4 &value )
|
||||||
|
{ return Float4x4( abs(value.v[0]), abs(value.v[1]), abs(value[2]), abs(value[3]) ); }
|
||||||
|
|
||||||
|
template< > inline Float4x4 max<Float4x4>( const Float4x4 &valueA, const Float4x4 &valueB )
|
||||||
|
{ return Float4x4( max(valueA.v[0], valueB.v[0]), max(valueA.v[1], valueB.v[1]), max(valueA.v[2], valueB.v[2]), max(valueA.v[3], valueB.v[3]) ); }
|
||||||
|
|
||||||
|
template< > inline Float4x4 min<Float4x4>( const Float4x4 &valueA, const Float4x4 &valueB )
|
||||||
|
{ return Float4x4( min(valueA.v[0], valueB.v[0]), min(valueA.v[1], valueB.v[1]), min(valueA.v[2], valueB.v[2]), min(valueA.v[3], valueB.v[3]) ); }
|
||||||
|
} }
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,183 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Linear Math Quaternions
|
||||||
|
// © Dan Andersson 2013
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef LINEARALGEBRA_QUATERNION_H
|
||||||
|
#define LINEARALGEBRA_QUATERNION_H
|
||||||
|
|
||||||
|
#include "Vector.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
namespace LinearAlgebra
|
||||||
|
{
|
||||||
|
template<typename ElementType>
|
||||||
|
class Quaternion
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct{ Vector3<ElementType> imaginary; ElementType real; };
|
||||||
|
ElementType element[4];
|
||||||
|
char byte[sizeof(ElementType[2])];
|
||||||
|
};
|
||||||
|
|
||||||
|
Quaternion( );
|
||||||
|
Quaternion( const Quaternion &quaternion );
|
||||||
|
Quaternion( const Vector3<ElementType> &imaginary, const ElementType &real );
|
||||||
|
~Quaternion( );
|
||||||
|
|
||||||
|
operator ElementType* ( );
|
||||||
|
operator const ElementType* ( ) const;
|
||||||
|
operator char* ( );
|
||||||
|
operator const char* ( ) const;
|
||||||
|
ElementType & operator [] ( int i );
|
||||||
|
const ElementType & operator [] ( int i ) const;
|
||||||
|
|
||||||
|
Quaternion<ElementType> & operator = ( const Quaternion<ElementType> &quaternion );
|
||||||
|
Quaternion<ElementType> & operator *= ( const ElementType &scalar );
|
||||||
|
Quaternion<ElementType> & operator /= ( const ElementType &scalar );
|
||||||
|
Quaternion<ElementType> & operator += ( const Quaternion<ElementType> &quaternion );
|
||||||
|
Quaternion<ElementType> & operator -= ( const Quaternion<ElementType> &quaternion );
|
||||||
|
Quaternion<ElementType> operator * ( const Quaternion<ElementType> &quaternion ) const;
|
||||||
|
Quaternion<ElementType> operator * ( const Vector3<ElementType> &vector ) const;
|
||||||
|
Quaternion<ElementType> operator * ( const ElementType &scalar ) const;
|
||||||
|
Quaternion<ElementType> operator / ( const ElementType &scalar ) const;
|
||||||
|
Quaternion<ElementType> operator + ( const Quaternion<ElementType> &quaternion ) const;
|
||||||
|
Quaternion<ElementType> operator - ( const Quaternion<ElementType> &quaternion ) const;
|
||||||
|
Quaternion<ElementType> operator - ( ) const;
|
||||||
|
|
||||||
|
Quaternion<ElementType> getConjugate( ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Body
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Quaternion<ElementType>::Quaternion( ) : imaginary(0,0,0), real(0) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Quaternion<ElementType>::Quaternion( const Quaternion &quaternion ) : imaginary(quaternion.imaginary), real(quaternion.real) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Quaternion<ElementType>::Quaternion( const Vector3<ElementType> &_imaginary, const ElementType &_real ) : imaginary(_imaginary), real(_real) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Quaternion<ElementType>::~Quaternion( ) { /* Nothing that needs to be done */ }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Quaternion<ElementType>::operator ElementType* ( )
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Quaternion<ElementType>::operator const ElementType* ( ) const
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Quaternion<ElementType>::operator char* ( )
|
||||||
|
{ return this->byte; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Quaternion<ElementType>::operator const char* ( ) const
|
||||||
|
{ return this->byte; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline ElementType & Quaternion<ElementType>::operator [] ( int i )
|
||||||
|
{ return this->element[i]; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline const ElementType & Quaternion<ElementType>::operator [] ( int i ) const
|
||||||
|
{ return this->element[i]; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Quaternion<ElementType> & Quaternion<ElementType>::operator = ( const Quaternion<ElementType> &quaternion )
|
||||||
|
{
|
||||||
|
this->imaginary = quaternion.imaginary;
|
||||||
|
this->real = quaternion.real;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Quaternion<ElementType> & Quaternion<ElementType>::operator *= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
this->imaginary *= scalar;
|
||||||
|
this->real *= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Quaternion<ElementType> & Quaternion<ElementType>::operator /= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
this->imaginary /= scalar;
|
||||||
|
this->real /= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Quaternion<ElementType> & Quaternion<ElementType>::operator += ( const Quaternion<ElementType> &quaternion )
|
||||||
|
{
|
||||||
|
this->imaginary += quaternion.imaginary;
|
||||||
|
this->real += quaternion.real;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Quaternion<ElementType> & Quaternion<ElementType>::operator -= ( const Quaternion<ElementType> &quaternion )
|
||||||
|
{
|
||||||
|
this->imaginary -= quaternion.imaginary;
|
||||||
|
this->real -= quaternion.real;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Quaternion<ElementType> Quaternion<ElementType>::operator * ( const Quaternion<ElementType> &quaternion ) const
|
||||||
|
{
|
||||||
|
Vector3<ElementType> im = this->imaginary.cross( quaternion.imaginary );
|
||||||
|
im += (quaternion.imaginary * this->real);
|
||||||
|
im += (this->imaginary * quaternion.real);
|
||||||
|
|
||||||
|
ElementType re = this->real * quaternion.real;
|
||||||
|
re -= this->imaginary.dot( quaternion.imaginary );
|
||||||
|
|
||||||
|
return Quaternion<ElementType>( im, re );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Quaternion<ElementType> Quaternion<ElementType>::operator * ( const Vector3<ElementType> &vector ) const
|
||||||
|
{
|
||||||
|
Vector3<ElementType> im = this->imaginary.cross( vector );
|
||||||
|
im += (vector * this->real);
|
||||||
|
|
||||||
|
ElementType re = this->imaginary.dot( vector ) * -1;
|
||||||
|
|
||||||
|
return Quaternion<ElementType>( im, re );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Quaternion<ElementType> Quaternion<ElementType>::operator * ( const ElementType &scalar ) const
|
||||||
|
{ return Quaternion<ElementType>(*this) *= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Quaternion<ElementType> Quaternion<ElementType>::operator / ( const ElementType &scalar ) const
|
||||||
|
{ return Quaternion<ElementType>(*this) /= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Quaternion<ElementType> Quaternion<ElementType>::operator + ( const Quaternion<ElementType> &quaternion ) const
|
||||||
|
{ return Quaternion<ElementType>(*this) += quaternion; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Quaternion<ElementType> Quaternion<ElementType>::operator - ( const Quaternion<ElementType> &quaternion ) const
|
||||||
|
{ return Quaternion<ElementType>(*this) -= quaternion; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Quaternion<ElementType> Quaternion<ElementType>::operator - ( ) const
|
||||||
|
{ return Quaternion<ElementType>(-this->imaginary, -this->real); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Quaternion<ElementType> Quaternion<ElementType>::getConjugate( ) const
|
||||||
|
{ return Quaternion<ElementType>(this->imaginary * -1, this->real ); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,659 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Linear Math Vectors
|
||||||
|
// © Dan Andersson 2013
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef LINEARALGEBRA_VECTOR_H
|
||||||
|
#define LINEARALGEBRA_VECTOR_H
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
namespace LinearAlgebra
|
||||||
|
{
|
||||||
|
template<typename ElementType>
|
||||||
|
class Vector2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct { ElementType x, y; };
|
||||||
|
ElementType element[2];
|
||||||
|
char byte[sizeof(ElementType[2])];
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Vector2<ElementType> null;
|
||||||
|
static const Vector2<ElementType> standardUnitX;
|
||||||
|
static const Vector2<ElementType> standardUnitY;
|
||||||
|
|
||||||
|
Vector2( );
|
||||||
|
Vector2( const Vector2<ElementType> &vector );
|
||||||
|
Vector2( const ElementType &element );
|
||||||
|
Vector2( const ElementType element[2] );
|
||||||
|
Vector2( const ElementType &x, const ElementType &y );
|
||||||
|
~Vector2( );
|
||||||
|
|
||||||
|
operator ElementType* ( );
|
||||||
|
operator const ElementType* ( ) const;
|
||||||
|
operator char* ( );
|
||||||
|
operator const char* ( ) const;
|
||||||
|
ElementType & operator [] ( int i );
|
||||||
|
const ElementType & operator [] ( int i ) const;
|
||||||
|
|
||||||
|
Vector2<ElementType> & operator = ( const Vector2<ElementType> &vector );
|
||||||
|
Vector2<ElementType> & operator = ( const ElementType element[2] );
|
||||||
|
Vector2<ElementType> & operator *= ( const ElementType &scalar );
|
||||||
|
Vector2<ElementType> & operator /= ( const ElementType &scalar );
|
||||||
|
Vector2<ElementType> & operator += ( const Vector2<ElementType> &vector );
|
||||||
|
Vector2<ElementType> & operator -= ( const Vector2<ElementType> &vector );
|
||||||
|
Vector2<ElementType> operator * ( const ElementType &scalar ) const;
|
||||||
|
Vector2<ElementType> operator / ( const ElementType &scalar ) const;
|
||||||
|
Vector2<ElementType> operator + ( const Vector2<ElementType> &vector ) const;
|
||||||
|
Vector2<ElementType> operator - ( const Vector2<ElementType> &vector ) const;
|
||||||
|
Vector2<ElementType> operator - ( ) const; // unary negation
|
||||||
|
|
||||||
|
bool operator == ( const Vector2<ElementType> &vector ) const;
|
||||||
|
bool operator != ( const Vector2<ElementType> &vector ) const;
|
||||||
|
|
||||||
|
ElementType length( ) const;
|
||||||
|
ElementType dot( const Vector2<ElementType> &vector ) const;
|
||||||
|
|
||||||
|
Vector2<ElementType> & normalize( );
|
||||||
|
Vector2<ElementType> getNormalized( ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
class Vector3
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct { ElementType x, y, z; };
|
||||||
|
struct { Vector2<ElementType> xy; };
|
||||||
|
ElementType element[3];
|
||||||
|
char byte[sizeof(ElementType[3])];
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Vector3<ElementType> null;
|
||||||
|
static const Vector3<ElementType> standardUnitX;
|
||||||
|
static const Vector3<ElementType> standardUnitY;
|
||||||
|
static const Vector3<ElementType> standardUnitZ;
|
||||||
|
|
||||||
|
Vector3( );
|
||||||
|
Vector3( const Vector3<ElementType> &vector );
|
||||||
|
Vector3( const Vector2<ElementType> &vector, const ElementType &z );
|
||||||
|
Vector3( const ElementType &element );
|
||||||
|
Vector3( const ElementType element[3] );
|
||||||
|
Vector3( const ElementType &x, const ElementType &y, const ElementType &z );
|
||||||
|
~Vector3( );
|
||||||
|
|
||||||
|
operator ElementType* ();
|
||||||
|
operator const ElementType* () const;
|
||||||
|
operator char* ( );
|
||||||
|
operator const char* ( ) const;
|
||||||
|
ElementType & operator [] ( int i );
|
||||||
|
const ElementType & operator [] ( int i ) const;
|
||||||
|
|
||||||
|
Vector3<ElementType> & operator = ( const Vector3<ElementType> &vector );
|
||||||
|
Vector3<ElementType> & operator = ( const ElementType element[3] );
|
||||||
|
Vector3<ElementType> & operator *= ( const ElementType &scalar );
|
||||||
|
Vector3<ElementType> & operator /= ( const ElementType &scalar );
|
||||||
|
Vector3<ElementType> & operator += ( const Vector3<ElementType> &vector );
|
||||||
|
Vector3<ElementType> & operator -= ( const Vector3<ElementType> &vector );
|
||||||
|
Vector3<ElementType> operator * ( const ElementType &scalar ) const;
|
||||||
|
Vector3<ElementType> operator / ( const ElementType &scalar ) const;
|
||||||
|
Vector3<ElementType> operator + ( const Vector3<ElementType> &vector ) const;
|
||||||
|
Vector3<ElementType> operator - ( const Vector3<ElementType> &vector ) const;
|
||||||
|
Vector3<ElementType> operator - ( ) const; // unary negation
|
||||||
|
|
||||||
|
bool operator == ( const Vector3<ElementType> &vector ) const;
|
||||||
|
bool operator != ( const Vector3<ElementType> &vector ) const;
|
||||||
|
|
||||||
|
ElementType length( ) const;
|
||||||
|
ElementType dot( const Vector3<ElementType> &vector ) const;
|
||||||
|
Vector3<ElementType> cross( const Vector3<ElementType> &vector ) const;
|
||||||
|
|
||||||
|
Vector3<ElementType> & normalize( );
|
||||||
|
Vector3<ElementType> getNormalized( ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
class Vector4
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct { ElementType x, y, z, w; };
|
||||||
|
struct { Vector2<ElementType> xy; };
|
||||||
|
struct { Vector3<ElementType> xyz; };
|
||||||
|
ElementType element[4];
|
||||||
|
char byte[sizeof(ElementType[4])];
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Vector4<ElementType> null;
|
||||||
|
static const Vector4<ElementType> standardUnitX;
|
||||||
|
static const Vector4<ElementType> standardUnitY;
|
||||||
|
static const Vector4<ElementType> standardUnitZ;
|
||||||
|
static const Vector4<ElementType> standardUnitW;
|
||||||
|
|
||||||
|
Vector4( );
|
||||||
|
Vector4( const Vector4<ElementType> &vector );
|
||||||
|
Vector4( const Vector3<ElementType> &vector, const ElementType &w );
|
||||||
|
Vector4( const Vector2<ElementType> &vector, const ElementType &z, const ElementType &w );
|
||||||
|
Vector4( const ElementType &element );
|
||||||
|
Vector4( const ElementType element[4] );
|
||||||
|
Vector4( const ElementType &x, const ElementType &y, const ElementType &z, const ElementType &w );
|
||||||
|
~Vector4( );
|
||||||
|
|
||||||
|
operator ElementType* ();
|
||||||
|
operator const ElementType* () const;
|
||||||
|
operator char* ( );
|
||||||
|
operator const char* ( ) const;
|
||||||
|
ElementType & operator [] ( int i );
|
||||||
|
const ElementType & operator [] ( int i ) const;
|
||||||
|
|
||||||
|
Vector4<ElementType> & operator = ( const Vector4<ElementType> &vector );
|
||||||
|
Vector4<ElementType> & operator = ( const ElementType element[4] );
|
||||||
|
Vector4<ElementType> & operator *= ( const ElementType &scalar );
|
||||||
|
Vector4<ElementType> & operator /= ( const ElementType &scalar );
|
||||||
|
Vector4<ElementType> & operator += ( const Vector4<ElementType> &vector );
|
||||||
|
Vector4<ElementType> & operator -= ( const Vector4<ElementType> &vector );
|
||||||
|
Vector4<ElementType> operator * ( const ElementType &scalar ) const;
|
||||||
|
Vector4<ElementType> operator / ( const ElementType &scalar ) const;
|
||||||
|
Vector4<ElementType> operator + ( const Vector4<ElementType> &vector ) const;
|
||||||
|
Vector4<ElementType> operator - ( const Vector4<ElementType> &vector ) const;
|
||||||
|
Vector4<ElementType> operator - ( ) const; // unary negation
|
||||||
|
|
||||||
|
bool operator == ( const Vector4<ElementType> &vector ) const;
|
||||||
|
bool operator != ( const Vector4<ElementType> &vector ) const;
|
||||||
|
|
||||||
|
ElementType length( ) const;
|
||||||
|
ElementType dot( const Vector4<ElementType> &vector ) const;
|
||||||
|
|
||||||
|
Vector4<ElementType> & normalize( );
|
||||||
|
Vector4<ElementType> getNormalized( ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Body
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Vector2<ElementType> ///////////////////////////////////////
|
||||||
|
template<typename ElementType> const Vector2<ElementType> Vector2<ElementType>::null = Vector2<ElementType>( );
|
||||||
|
template<typename ElementType> const Vector2<ElementType> Vector2<ElementType>::standardUnitX = Vector2<ElementType>( 1, 0 );
|
||||||
|
template<typename ElementType> const Vector2<ElementType> Vector2<ElementType>::standardUnitY = Vector2<ElementType>( 0, 1 );
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType>::Vector2( ) : x(0), y(0) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType>::Vector2( const Vector2<ElementType> &vector ) : x(vector.x), y(vector.y)
|
||||||
|
{ this->x = vector.x; this->y = vector.y; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType>::Vector2( const ElementType &_element ) : x(_element), y(_element)
|
||||||
|
{ this->x = this->y = _element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType>::Vector2( const ElementType _element[2] ) : x(_element[0]), y(_element[1]) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType>::Vector2( const ElementType &_x, const ElementType &_y ) : x(_x), y(_y) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType>::~Vector2( ) { /* Nothing that needs to be done */ }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector2<ElementType>::operator ElementType* ()
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector2<ElementType>::operator const ElementType* () const
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector2<ElementType>::operator char* ( )
|
||||||
|
{ return this->byte; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector2<ElementType>::operator const char* ( ) const
|
||||||
|
{ return this->byte; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline ElementType & Vector2<ElementType>::operator [] ( int i )
|
||||||
|
{ return this->element[i]; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline const ElementType & Vector2<ElementType>::operator [] ( int i ) const
|
||||||
|
{ return this->element[i]; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType> & Vector2<ElementType>::operator = ( const Vector2<ElementType> &vector )
|
||||||
|
{
|
||||||
|
this->element[0] = vector.element[0];
|
||||||
|
this->element[1] = vector.element[1];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType> & Vector2<ElementType>::operator = ( const ElementType _element[2] )
|
||||||
|
{
|
||||||
|
this->element[0] = _element[0];
|
||||||
|
this->element[1] = _element[1];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType> & Vector2<ElementType>::operator *= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
this->element[0] *= scalar;
|
||||||
|
this->element[1] *= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType> & Vector2<ElementType>::operator /= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
this->element[0] /= scalar;
|
||||||
|
this->element[1] /= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType> & Vector2<ElementType>::operator += ( const Vector2<ElementType> &vector )
|
||||||
|
{
|
||||||
|
this->element[0] += vector.element[0];
|
||||||
|
this->element[1] += vector.element[1];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector2<ElementType> & Vector2<ElementType>::operator -= ( const Vector2<ElementType> &vector )
|
||||||
|
{
|
||||||
|
this->element[0] -= vector.element[0];
|
||||||
|
this->element[1] -= vector.element[1];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector2<ElementType> Vector2<ElementType>::operator * ( const ElementType &scalar ) const
|
||||||
|
{ return Vector2<ElementType>(*this) *= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector2<ElementType> Vector2<ElementType>::operator / ( const ElementType &scalar ) const
|
||||||
|
{ return Vector2<ElementType>(*this) /= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector2<ElementType> Vector2<ElementType>::operator + ( const Vector2<ElementType> &vector ) const
|
||||||
|
{ return Vector2<ElementType>(*this) += vector; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector2<ElementType> Vector2<ElementType>::operator - ( const Vector2<ElementType> &vector ) const
|
||||||
|
{ return Vector2<ElementType>(*this) -= vector; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector2<ElementType> Vector2<ElementType>::operator - ( ) const
|
||||||
|
{ return Vector2<ElementType>(-this->x, -this->y); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
bool Vector2<ElementType>::operator == ( const Vector2<ElementType> &vector ) const
|
||||||
|
{
|
||||||
|
if( this->x != vector.x ) return false;
|
||||||
|
if( this->y != vector.y ) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
bool Vector2<ElementType>::operator != ( const Vector2<ElementType> &vector ) const
|
||||||
|
{
|
||||||
|
if( this->x != vector.x ) return true;
|
||||||
|
if( this->y != vector.y ) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline ElementType Vector2<ElementType>::length( ) const
|
||||||
|
{ return (ElementType) ::sqrt( this->dot(*this) ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
ElementType Vector2<ElementType>::dot( const Vector2<ElementType> &vector ) const
|
||||||
|
{
|
||||||
|
ElementType value = 0;
|
||||||
|
value += this->element[0] * vector.element[0];
|
||||||
|
value += this->element[1] * vector.element[1];
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector2<ElementType> & Vector2<ElementType>::normalize( )
|
||||||
|
{ return (*this) /= this->length(); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector2<ElementType> Vector2<ElementType>::getNormalized( ) const
|
||||||
|
{ return Vector2<ElementType>(*this).normalize(); }
|
||||||
|
|
||||||
|
// Vector3<ElementType> ///////////////////////////////////////
|
||||||
|
template<typename ElementType> const Vector3<ElementType> Vector3<ElementType>::null = Vector3<ElementType>( );
|
||||||
|
template<typename ElementType> const Vector3<ElementType> Vector3<ElementType>::standardUnitX = Vector3<ElementType>( 1, 0, 0 );
|
||||||
|
template<typename ElementType> const Vector3<ElementType> Vector3<ElementType>::standardUnitY = Vector3<ElementType>( 0, 1, 0 );
|
||||||
|
template<typename ElementType> const Vector3<ElementType> Vector3<ElementType>::standardUnitZ = Vector3<ElementType>( 0, 0, 1 );
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType>::Vector3( ) : x(0), y(0), z(0) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType>::Vector3( const Vector3<ElementType> &vector ) : x(vector.x), y(vector.y), z(vector.z)
|
||||||
|
{ this->x = vector.x; this->y = vector.y; this->z = vector.z; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType>::Vector3( const Vector2<ElementType> &vector, const ElementType &_z ) : x(vector.x), y(vector.y), z(_z)
|
||||||
|
{ this->x = vector.x; this->y = vector.y; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType>::Vector3( const ElementType &_element ) : x(_element), y(_element), z(_element)
|
||||||
|
{ this->x = this->y = this->z = _element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType>::Vector3( const ElementType _element[3] ) : x(_element[0]), y(_element[1]), z(_element[2]) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType>::Vector3( const ElementType &_x, const ElementType &_y, const ElementType &_z ) : x(_x), y(_y), z(_z)
|
||||||
|
{ this->x = _x; this->y = _y; this->z = _z; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType>::~Vector3( ) { /* Nothing that needs to be done */ }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector3<ElementType>::operator ElementType* ()
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector3<ElementType>::operator const ElementType* () const
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline ElementType & Vector3<ElementType>::operator [] ( int i )
|
||||||
|
{ return this->element[i]; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline const ElementType & Vector3<ElementType>::operator [] ( int i ) const
|
||||||
|
{ return this->element[i]; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType> & Vector3<ElementType>::operator = ( const Vector3<ElementType> &vector )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 3; ++i )
|
||||||
|
this->element[i] = vector.element[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType> & Vector3<ElementType>::operator = ( const ElementType element[3] )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 3; ++i )
|
||||||
|
this->element[i] = element[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType> & Vector3<ElementType>::operator *= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 3; ++i )
|
||||||
|
this->element[i] *= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType> & Vector3<ElementType>::operator /= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 3; ++i )
|
||||||
|
this->element[i] /= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType> & Vector3<ElementType>::operator += ( const Vector3<ElementType> &vector )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 3; ++i )
|
||||||
|
this->element[i] += vector.element[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType> & Vector3<ElementType>::operator -= ( const Vector3<ElementType> &vector )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 3; ++i )
|
||||||
|
this->element[i] -= vector.element[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector3<ElementType> Vector3<ElementType>::operator * ( const ElementType &scalar ) const
|
||||||
|
{ return Vector3<ElementType>(*this) *= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector3<ElementType> Vector3<ElementType>::operator / ( const ElementType &scalar ) const
|
||||||
|
{ return Vector3<ElementType>(*this) /= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector3<ElementType> Vector3<ElementType>::operator + ( const Vector3<ElementType> &vector ) const
|
||||||
|
{ return Vector3<ElementType>(*this) += vector; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector3<ElementType> Vector3<ElementType>::operator - ( const Vector3<ElementType> &vector ) const
|
||||||
|
{ return Vector3<ElementType>(*this) -= vector; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector3<ElementType> Vector3<ElementType>::operator - ( ) const
|
||||||
|
{ return Vector3<ElementType>(-this->x, -this->y, -this->z); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
bool Vector3<ElementType>::operator == ( const Vector3<ElementType> &vector ) const
|
||||||
|
{
|
||||||
|
if( this->x != vector.x ) return false;
|
||||||
|
if( this->y != vector.y ) return false;
|
||||||
|
if( this->z != vector.z ) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
bool Vector3<ElementType>::operator != ( const Vector3<ElementType> &vector ) const
|
||||||
|
{
|
||||||
|
if( this->x != vector.x ) return true;
|
||||||
|
if( this->y != vector.y ) return true;
|
||||||
|
if( this->z != vector.z ) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline ElementType Vector3<ElementType>::length( ) const
|
||||||
|
{ return (ElementType) ::sqrt( this->dot(*this) ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
ElementType Vector3<ElementType>::dot( const Vector3<ElementType> &vector ) const
|
||||||
|
{
|
||||||
|
ElementType value = 0;
|
||||||
|
for( int i = 0; i < 3; ++i )
|
||||||
|
value += this->element[i] * vector.element[i];
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector3<ElementType> Vector3<ElementType>::cross( const Vector3<ElementType> &vector ) const
|
||||||
|
{
|
||||||
|
return Vector3<ElementType>( (this->y*vector.z) - (this->z*vector.y),
|
||||||
|
(this->z*vector.x) - (this->x*vector.z),
|
||||||
|
(this->x*vector.y) - (this->y*vector.x) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector3<ElementType> & Vector3<ElementType>::normalize( )
|
||||||
|
{ return (*this) /= this->length(); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector3<ElementType> Vector3<ElementType>::getNormalized( ) const
|
||||||
|
{ return Vector3<ElementType>(*this).normalize(); }
|
||||||
|
|
||||||
|
// Vector4<ElementType> ///////////////////////////////////////
|
||||||
|
template<typename ElementType> const Vector4<ElementType> Vector4<ElementType>::null = Vector4<ElementType>( );
|
||||||
|
template<typename ElementType> const Vector4<ElementType> Vector4<ElementType>::standardUnitX = Vector4<ElementType>( 1, 0, 0, 0 );
|
||||||
|
template<typename ElementType> const Vector4<ElementType> Vector4<ElementType>::standardUnitY = Vector4<ElementType>( 0, 1, 0, 0 );
|
||||||
|
template<typename ElementType> const Vector4<ElementType> Vector4<ElementType>::standardUnitZ = Vector4<ElementType>( 0, 0, 1, 0 );
|
||||||
|
template<typename ElementType> const Vector4<ElementType> Vector4<ElementType>::standardUnitW = Vector4<ElementType>( 0, 0, 0, 1 );
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType>::Vector4( ) : x(0), y(0), z(0), w(0) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType>::Vector4( const Vector4<ElementType> &vector ) : x(vector.x), y(vector.y), z(vector.z), w(vector.z)
|
||||||
|
{ this->x = vector.x; this->y = vector.y; this->z = vector.z; this->w = vector.w; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType>::Vector4( const Vector3<ElementType> &vector, const ElementType &_w ) : x(vector.x), y(vector.y), z(vector.z), w(_w)
|
||||||
|
{ this->x = vector.x; this->y = vector.y; this->z = vector.z; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType>::Vector4( const Vector2<ElementType> &vector, const ElementType &_z, const ElementType &_w ) : x(vector.x), y(vector.y), z(_z), w(_w)
|
||||||
|
{ this->x = vector.x; this->y = vector.y; this->z = _z; this->w = _w; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType>::Vector4( const ElementType &_element ) : x(_element), y(_element), z(_element), w(_element)
|
||||||
|
{ this->x = this->y = this->z = this->w = _element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType>::Vector4( const ElementType _element[4] ) : x(_element[0]), y(_element[1]), z(_element[2]), w(_element[3]) {}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType>::Vector4( const ElementType &_x, const ElementType &_y, const ElementType &_z, const ElementType &_w ) : x(_x), y(_y), z(_z), w(_w)
|
||||||
|
{ this->x = _x; this->y = _y; this->z = _z; this->w = _w; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType>::~Vector4( ) { /* Nothing that needs to be done */ }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector4<ElementType>::operator ElementType* ()
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector4<ElementType>::operator const ElementType* () const
|
||||||
|
{ return this->element; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline ElementType & Vector4<ElementType>::operator [] ( int i )
|
||||||
|
{ return this->element[i]; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline const ElementType & Vector4<ElementType>::operator [] ( int i ) const
|
||||||
|
{ return this->element[i]; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType> & Vector4<ElementType>::operator = ( const Vector4<ElementType> &vector )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 4; ++i )
|
||||||
|
this->element[i] = vector.element[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType> & Vector4<ElementType>::operator = ( const ElementType element[4] )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 4; ++i )
|
||||||
|
this->element[i] = element[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType> & Vector4<ElementType>::operator *= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 4; ++i )
|
||||||
|
this->element[i] *= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType> & Vector4<ElementType>::operator /= ( const ElementType &scalar )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 4; ++i )
|
||||||
|
this->element[i] /= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType> & Vector4<ElementType>::operator += ( const Vector4<ElementType> &vector )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 4; ++i )
|
||||||
|
this->element[i] += vector.element[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
Vector4<ElementType> & Vector4<ElementType>::operator -= ( const Vector4<ElementType> &vector )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 4; ++i )
|
||||||
|
this->element[i] -= vector.element[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector4<ElementType> Vector4<ElementType>::operator * ( const ElementType &scalar ) const
|
||||||
|
{ return Vector4<ElementType>(*this) *= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector4<ElementType> Vector4<ElementType>::operator / ( const ElementType &scalar ) const
|
||||||
|
{ return Vector4<ElementType>(*this) /= scalar; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector4<ElementType> Vector4<ElementType>::operator + ( const Vector4<ElementType> &vector ) const
|
||||||
|
{ return Vector4<ElementType>(*this) += vector; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector4<ElementType> Vector4<ElementType>::operator - ( const Vector4<ElementType> &vector ) const
|
||||||
|
{ return Vector4<ElementType>(*this) -= vector; }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector4<ElementType> Vector4<ElementType>::operator - ( ) const
|
||||||
|
{ return Vector4<ElementType>(-this->x, -this->y, -this->z, -this->w); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
bool Vector4<ElementType>::operator == ( const Vector4<ElementType> &vector ) const
|
||||||
|
{
|
||||||
|
if( this->x != vector.x ) return false;
|
||||||
|
if( this->y != vector.y ) return false;
|
||||||
|
if( this->z != vector.z ) return false;
|
||||||
|
if( this->w != vector.w ) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
bool Vector4<ElementType>::operator != ( const Vector4<ElementType> &vector ) const
|
||||||
|
{
|
||||||
|
if( this->x != vector.x ) return true;
|
||||||
|
if( this->y != vector.y ) return true;
|
||||||
|
if( this->z != vector.z ) return true;
|
||||||
|
if( this->w != vector.w ) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline ElementType Vector4<ElementType>::length( ) const
|
||||||
|
{ return (ElementType) ::sqrt( this->dot(*this) ); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
ElementType Vector4<ElementType>::dot( const Vector4<ElementType> &vector ) const
|
||||||
|
{
|
||||||
|
ElementType value = 0;
|
||||||
|
for( int i = 0; i < 4; ++i )
|
||||||
|
value += this->element[i] * vector.element[i];
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector4<ElementType> & Vector4<ElementType>::normalize( )
|
||||||
|
{ return (*this) /= this->length(); }
|
||||||
|
|
||||||
|
template<typename ElementType>
|
||||||
|
inline Vector4<ElementType> Vector4<ElementType>::getNormalized( ) const
|
||||||
|
{ return Vector4<ElementType>(*this).normalize(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,65 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Created by Dan Andersson 2013
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "Box.h"
|
||||||
|
#include "Collision.h"
|
||||||
|
|
||||||
|
using namespace ::Oyster::Collision;
|
||||||
|
using namespace ::Oyster::Math;
|
||||||
|
|
||||||
|
Box::Box( ) : ICollideable(ICollideable::Box), orientation(Float4x4::identity), boundingOffset() {}
|
||||||
|
|
||||||
|
Box::Box( const Box &box ) : ICollideable(ICollideable::Box), orientation(box.orientation), boundingOffset(box.boundingOffset)
|
||||||
|
{
|
||||||
|
this->orientation = box.orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
Box::Box( const Float4x4 &o, const Float3 &s ) : ICollideable(ICollideable::Box), orientation(o), boundingOffset(s*0.5)
|
||||||
|
{
|
||||||
|
this->orientation = o;
|
||||||
|
}
|
||||||
|
Box::~Box( ) { /*Nothing needs to be done here*/ }
|
||||||
|
|
||||||
|
Box & Box::operator = ( const Box &box )
|
||||||
|
{
|
||||||
|
this->orientation = box.orientation;
|
||||||
|
this->boundingOffset = box.boundingOffset;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ICollideable* Box::clone( ) const
|
||||||
|
{ return new Box( *this ); }
|
||||||
|
|
||||||
|
bool Box::Intersects( const ICollideable *target ) const
|
||||||
|
{
|
||||||
|
switch( target->type )
|
||||||
|
{
|
||||||
|
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
|
||||||
|
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, ((Collision::Ray*)target)->collisionDistance );
|
||||||
|
case ICollideable::Sphere: return Utility::intersect( *this, *(Collision::Sphere*)target );
|
||||||
|
case ICollideable::Plane: return Utility::intersect( *this, *(Collision::Plane*)target );
|
||||||
|
case ICollideable::Triangle: return false; // TODO
|
||||||
|
case ICollideable::BoxAxisAligned: return Utility::intersect( *this, *(Collision::BoxAxisAligned*)target );
|
||||||
|
case ICollideable::Box: return Utility::intersect( *this, *(Collision::Box*)target );
|
||||||
|
case ICollideable::Frustrum: return false; // TODO
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Box::Contains( const ICollideable *target ) const
|
||||||
|
{
|
||||||
|
switch( target->type )
|
||||||
|
{
|
||||||
|
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
|
||||||
|
case ICollideable::Sphere: return false; // TODO
|
||||||
|
case ICollideable::Triangle: return false; // TODO
|
||||||
|
case ICollideable::BoxAxisAligned: return false; // TODO
|
||||||
|
case ICollideable::Box: return false; // TODO
|
||||||
|
case ICollideable::Frustrum: return false; // TODO
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ICollideable::State Box::Advanced( const ICollideable *target ) const
|
||||||
|
{ return ICollideable::Missed; } //Not supported returns 0
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue