├── .gitignore ├── Makefile ├── ModelSpecification.txt ├── README.md ├── pmmodel ├── 3DTest │ ├── _DTest.1 │ └── main.cpp └── pmmodel.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── julian.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ └── julian.xcuserdatad │ └── xcschemes │ ├── 3DTest.xcscheme │ └── xcschememanagement.plist └── src ├── AppState.h ├── Color.h ├── GLView.h ├── Image.h ├── PMModel.h ├── PMModelGL.h ├── PMWorld.h ├── PMWorldGL.h ├── TPL.h ├── TexCodec.h ├── common.h ├── main.cpp ├── renderer ├── Bound.h ├── BoundAABB.h ├── Camera.h ├── CameraController.h ├── Geometry.h ├── Mesh.h ├── RenderGL.h ├── Scenegraph.h ├── Storage.h ├── Texture.h └── TextureData.h ├── system ├── Input.h ├── InputController.h ├── MappedController.h ├── MappedInput.h └── WindowController.h └── vecmath ├── Matrix3.h ├── Matrix4.h ├── MatrixG3.h ├── MatrixG4.h ├── Tuple2.h ├── Tuple3.h ├── Tuple4.h ├── Vecmath.h ├── Vector2.h ├── Vector3.h └── Vector4.h /.gitignore: -------------------------------------------------------------------------------- 1 | 3DTest-cmd 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | EXENAME=3DTest-cmd 3 | CXXFLAGS=-g -Wall -DSFML_DYNAMIC -I. 4 | 5 | .PHONY: clean 6 | 7 | all: $(EXENAME) 8 | 9 | $(EXENAME): src/* 10 | g++ $(CXXFLAGS) src/main.cpp -o $@ $(LDFLAGS) -lsfml-graphics -lsfml-window -lsfml-system -framework OpenGL 11 | rm -rf $(EXENAME).dSYM 12 | 13 | clean: 14 | rm -rf $(EXENAME) 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Paper Mario Model Viewer 2 | ======================== 3 | 4 | View models from: 5 | - Paper Mario: The Thousand Year Door 6 | - Super Paper Mario 7 | 8 | Building 9 | ======== 10 | 11 | You need SFML 2.1 installed, after that run make in this directory. 12 | 13 | Running 14 | ======= 15 | 16 | Example: 17 | ./3DTest-cmd /path/to/model/file 18 | 19 | Make sure that the model's corresponding texture file (if it exists) is in the same directory. 20 | Texture files end in a dash (-). 21 | 22 | Using 23 | ===== 24 | 25 | Arrow Keys: Move around 26 | T/R/Z: Translate/Rotate/Zoom mode 27 | C: World/Camera mode 28 | 29 | This project is released under the BSD license. 30 | 31 | 32 | -------------------------------------------------------------------------------- /pmmodel/3DTest/_DTest.1: -------------------------------------------------------------------------------- 1 | .\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples. 2 | .\"See Also: 3 | .\"man mdoc.samples for a complete listing of options 4 | .\"man mdoc for the short list of editing options 5 | .\"/usr/share/misc/mdoc.template 6 | .Dd 7/27/14 \" DATE 7 | .Dt 3DTest 1 \" Program name and manual section number 8 | .Os Darwin 9 | .Sh NAME \" Section Header - required - don't modify 10 | .Nm 3DTest, 11 | .\" The following lines are read in generating the apropos(man -k) database. Use only key 12 | .\" words here as the database is built based on the words here and in the .ND line. 13 | .Nm Other_name_for_same_program(), 14 | .Nm Yet another name for the same program. 15 | .\" Use .Nm macro to designate other names for the documented program. 16 | .Nd This line parsed for whatis database. 17 | .Sh SYNOPSIS \" Section Header - required - don't modify 18 | .Nm 19 | .Op Fl abcd \" [-abcd] 20 | .Op Fl a Ar path \" [-a path] 21 | .Op Ar file \" [file] 22 | .Op Ar \" [file ...] 23 | .Ar arg0 \" Underlined argument - use .Ar anywhere to underline 24 | arg2 ... \" Arguments 25 | .Sh DESCRIPTION \" Section Header - required - don't modify 26 | Use the .Nm macro to refer to your program throughout the man page like such: 27 | .Nm 28 | Underlining is accomplished with the .Ar macro like this: 29 | .Ar underlined text . 30 | .Pp \" Inserts a space 31 | A list of items with descriptions: 32 | .Bl -tag -width -indent \" Begins a tagged list 33 | .It item a \" Each item preceded by .It macro 34 | Description of item a 35 | .It item b 36 | Description of item b 37 | .El \" Ends the list 38 | .Pp 39 | A list of flags and their descriptions: 40 | .Bl -tag -width -indent \" Differs from above in tag removed 41 | .It Fl a \"-a flag as a list item 42 | Description of -a flag 43 | .It Fl b 44 | Description of -b flag 45 | .El \" Ends the list 46 | .Pp 47 | .\" .Sh ENVIRONMENT \" May not be needed 48 | .\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1 49 | .\" .It Ev ENV_VAR_1 50 | .\" Description of ENV_VAR_1 51 | .\" .It Ev ENV_VAR_2 52 | .\" Description of ENV_VAR_2 53 | .\" .El 54 | .Sh FILES \" File used or created by the topic of the man page 55 | .Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact 56 | .It Pa /usr/share/file_name 57 | FILE_1 description 58 | .It Pa /Users/joeuser/Library/really_long_file_name 59 | FILE_2 description 60 | .El \" Ends the list 61 | .\" .Sh DIAGNOSTICS \" May not be needed 62 | .\" .Bl -diag 63 | .\" .It Diagnostic Tag 64 | .\" Diagnostic informtion here. 65 | .\" .It Diagnostic Tag 66 | .\" Diagnostic informtion here. 67 | .\" .El 68 | .Sh SEE ALSO 69 | .\" List links in ascending order by section, alphabetically within a section. 70 | .\" Please do not reference files that do not exist without filing a bug report 71 | .Xr a 1 , 72 | .Xr b 1 , 73 | .Xr c 1 , 74 | .Xr a 2 , 75 | .Xr b 2 , 76 | .Xr a 3 , 77 | .Xr b 3 78 | .\" .Sh BUGS \" Document known, unremedied bugs 79 | .\" .Sh HISTORY \" Document history if command behaves in a unique manner -------------------------------------------------------------------------------- /pmmodel/3DTest/main.cpp: -------------------------------------------------------------------------------- 1 | ../../src/main.cpp -------------------------------------------------------------------------------- /pmmodel/pmmodel.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B9EEE5C7198590CD00C64E71 /* _DTest.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = B9EEE5C6198590CD00C64E71 /* _DTest.1 */; }; 11 | B9EEE5CD198591C600C64E71 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B9EEE5CC198591C600C64E71 /* main.cpp */; }; 12 | B9EEE5CF1985921A00C64E71 /* libsfml-system.2.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EEE5CE1985921A00C64E71 /* libsfml-system.2.1.dylib */; }; 13 | B9EEE5D11985921C00C64E71 /* libsfml-window.2.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EEE5D01985921C00C64E71 /* libsfml-window.2.1.dylib */; }; 14 | B9EEE5D31985922200C64E71 /* libsfml-graphics.2.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EEE5D21985922200C64E71 /* libsfml-graphics.2.1.dylib */; }; 15 | B9EEE5D51985924F00C64E71 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EEE5D41985924F00C64E71 /* OpenGL.framework */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | B9EEE5BF198590CD00C64E71 /* CopyFiles */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = /usr/share/man/man1/; 23 | dstSubfolderSpec = 0; 24 | files = ( 25 | B9EEE5C7198590CD00C64E71 /* _DTest.1 in CopyFiles */, 26 | ); 27 | runOnlyForDeploymentPostprocessing = 1; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | B9EEE5C1198590CD00C64E71 /* 3DTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = 3DTest; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | B9EEE5C6198590CD00C64E71 /* _DTest.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = _DTest.1; sourceTree = ""; }; 34 | B9EEE5CB1985912A00C64E71 /* src */ = {isa = PBXFileReference; lastKnownFileType = folder; name = src; path = ../src; sourceTree = ""; }; 35 | B9EEE5CC198591C600C64E71 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../../src/main.cpp; sourceTree = ""; }; 36 | B9EEE5CE1985921A00C64E71 /* libsfml-system.2.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libsfml-system.2.1.dylib"; path = "../../../../../usr/local/Cellar/sfml/2.1/lib/libsfml-system.2.1.dylib"; sourceTree = ""; }; 37 | B9EEE5D01985921C00C64E71 /* libsfml-window.2.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libsfml-window.2.1.dylib"; path = "../../../../../usr/local/Cellar/sfml/2.1/lib/libsfml-window.2.1.dylib"; sourceTree = ""; }; 38 | B9EEE5D21985922200C64E71 /* libsfml-graphics.2.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libsfml-graphics.2.1.dylib"; path = "../../../../../usr/local/Cellar/sfml/2.1/lib/libsfml-graphics.2.1.dylib"; sourceTree = ""; }; 39 | B9EEE5D41985924F00C64E71 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = ../../../../../System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; 40 | /* End PBXFileReference section */ 41 | 42 | /* Begin PBXFrameworksBuildPhase section */ 43 | B9EEE5BE198590CD00C64E71 /* Frameworks */ = { 44 | isa = PBXFrameworksBuildPhase; 45 | buildActionMask = 2147483647; 46 | files = ( 47 | B9EEE5CF1985921A00C64E71 /* libsfml-system.2.1.dylib in Frameworks */, 48 | B9EEE5D51985924F00C64E71 /* OpenGL.framework in Frameworks */, 49 | B9EEE5D11985921C00C64E71 /* libsfml-window.2.1.dylib in Frameworks */, 50 | B9EEE5D31985922200C64E71 /* libsfml-graphics.2.1.dylib in Frameworks */, 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | /* End PBXFrameworksBuildPhase section */ 55 | 56 | /* Begin PBXGroup section */ 57 | B9EEE5B61985908300C64E71 = { 58 | isa = PBXGroup; 59 | children = ( 60 | B9EEE5D41985924F00C64E71 /* OpenGL.framework */, 61 | B9EEE5D21985922200C64E71 /* libsfml-graphics.2.1.dylib */, 62 | B9EEE5D01985921C00C64E71 /* libsfml-window.2.1.dylib */, 63 | B9EEE5CE1985921A00C64E71 /* libsfml-system.2.1.dylib */, 64 | B9EEE5CB1985912A00C64E71 /* src */, 65 | B9EEE5C3198590CD00C64E71 /* 3DTest */, 66 | B9EEE5C2198590CD00C64E71 /* Products */, 67 | ); 68 | sourceTree = ""; 69 | }; 70 | B9EEE5C2198590CD00C64E71 /* Products */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | B9EEE5C1198590CD00C64E71 /* 3DTest */, 74 | ); 75 | name = Products; 76 | sourceTree = ""; 77 | }; 78 | B9EEE5C3198590CD00C64E71 /* 3DTest */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | B9EEE5CC198591C600C64E71 /* main.cpp */, 82 | B9EEE5C6198590CD00C64E71 /* _DTest.1 */, 83 | ); 84 | path = 3DTest; 85 | sourceTree = ""; 86 | }; 87 | /* End PBXGroup section */ 88 | 89 | /* Begin PBXNativeTarget section */ 90 | B9EEE5C0198590CD00C64E71 /* 3DTest */ = { 91 | isa = PBXNativeTarget; 92 | buildConfigurationList = B9EEE5C8198590CD00C64E71 /* Build configuration list for PBXNativeTarget "3DTest" */; 93 | buildPhases = ( 94 | B9EEE5BD198590CD00C64E71 /* Sources */, 95 | B9EEE5BE198590CD00C64E71 /* Frameworks */, 96 | B9EEE5BF198590CD00C64E71 /* CopyFiles */, 97 | ); 98 | buildRules = ( 99 | ); 100 | dependencies = ( 101 | ); 102 | name = 3DTest; 103 | productName = 3DTest; 104 | productReference = B9EEE5C1198590CD00C64E71 /* 3DTest */; 105 | productType = "com.apple.product-type.tool"; 106 | }; 107 | /* End PBXNativeTarget section */ 108 | 109 | /* Begin PBXProject section */ 110 | B9EEE5B71985908300C64E71 /* Project object */ = { 111 | isa = PBXProject; 112 | attributes = { 113 | LastUpgradeCheck = 0510; 114 | }; 115 | buildConfigurationList = B9EEE5BA1985908300C64E71 /* Build configuration list for PBXProject "pmmodel" */; 116 | compatibilityVersion = "Xcode 3.2"; 117 | developmentRegion = English; 118 | hasScannedForEncodings = 0; 119 | knownRegions = ( 120 | en, 121 | ); 122 | mainGroup = B9EEE5B61985908300C64E71; 123 | productRefGroup = B9EEE5C2198590CD00C64E71 /* Products */; 124 | projectDirPath = ""; 125 | projectRoot = ""; 126 | targets = ( 127 | B9EEE5C0198590CD00C64E71 /* 3DTest */, 128 | ); 129 | }; 130 | /* End PBXProject section */ 131 | 132 | /* Begin PBXSourcesBuildPhase section */ 133 | B9EEE5BD198590CD00C64E71 /* Sources */ = { 134 | isa = PBXSourcesBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | B9EEE5CD198591C600C64E71 /* main.cpp in Sources */, 138 | ); 139 | runOnlyForDeploymentPostprocessing = 0; 140 | }; 141 | /* End PBXSourcesBuildPhase section */ 142 | 143 | /* Begin XCBuildConfiguration section */ 144 | B9EEE5BB1985908300C64E71 /* Debug */ = { 145 | isa = XCBuildConfiguration; 146 | buildSettings = { 147 | }; 148 | name = Debug; 149 | }; 150 | B9EEE5BC1985908300C64E71 /* Release */ = { 151 | isa = XCBuildConfiguration; 152 | buildSettings = { 153 | }; 154 | name = Release; 155 | }; 156 | B9EEE5C9198590CD00C64E71 /* Debug */ = { 157 | isa = XCBuildConfiguration; 158 | buildSettings = { 159 | ALWAYS_SEARCH_USER_PATHS = NO; 160 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 161 | CLANG_CXX_LIBRARY = "libc++"; 162 | CLANG_ENABLE_MODULES = YES; 163 | CLANG_ENABLE_OBJC_ARC = YES; 164 | CLANG_WARN_BOOL_CONVERSION = YES; 165 | CLANG_WARN_CONSTANT_CONVERSION = YES; 166 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 167 | CLANG_WARN_EMPTY_BODY = YES; 168 | CLANG_WARN_ENUM_CONVERSION = YES; 169 | CLANG_WARN_INT_CONVERSION = YES; 170 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 171 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 172 | COPY_PHASE_STRIP = NO; 173 | GCC_C_LANGUAGE_STANDARD = gnu99; 174 | GCC_DYNAMIC_NO_PIC = NO; 175 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 176 | GCC_OPTIMIZATION_LEVEL = 0; 177 | GCC_PREPROCESSOR_DEFINITIONS = ( 178 | "DEBUG=1", 179 | "$(inherited)", 180 | ); 181 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 182 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 183 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 184 | GCC_WARN_UNDECLARED_SELECTOR = YES; 185 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 186 | GCC_WARN_UNUSED_FUNCTION = YES; 187 | GCC_WARN_UNUSED_VARIABLE = YES; 188 | HEADER_SEARCH_PATHS = ( 189 | "$(inherited)", 190 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 191 | ../src, 192 | /usr/local/include, 193 | ); 194 | LIBRARY_SEARCH_PATHS = ( 195 | /usr/local/lib, 196 | /usr/local/Cellar/sfml/2.1/lib, 197 | ); 198 | MACOSX_DEPLOYMENT_TARGET = 10.9; 199 | ONLY_ACTIVE_ARCH = YES; 200 | PRODUCT_NAME = "$(TARGET_NAME)"; 201 | SDKROOT = macosx; 202 | }; 203 | name = Debug; 204 | }; 205 | B9EEE5CA198590CD00C64E71 /* Release */ = { 206 | isa = XCBuildConfiguration; 207 | buildSettings = { 208 | ALWAYS_SEARCH_USER_PATHS = NO; 209 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 210 | CLANG_CXX_LIBRARY = "libc++"; 211 | CLANG_ENABLE_MODULES = YES; 212 | CLANG_ENABLE_OBJC_ARC = YES; 213 | CLANG_WARN_BOOL_CONVERSION = YES; 214 | CLANG_WARN_CONSTANT_CONVERSION = YES; 215 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 216 | CLANG_WARN_EMPTY_BODY = YES; 217 | CLANG_WARN_ENUM_CONVERSION = YES; 218 | CLANG_WARN_INT_CONVERSION = YES; 219 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 220 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 221 | COPY_PHASE_STRIP = YES; 222 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 223 | ENABLE_NS_ASSERTIONS = NO; 224 | GCC_C_LANGUAGE_STANDARD = gnu99; 225 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 226 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 227 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 228 | GCC_WARN_UNDECLARED_SELECTOR = YES; 229 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 230 | GCC_WARN_UNUSED_FUNCTION = YES; 231 | GCC_WARN_UNUSED_VARIABLE = YES; 232 | HEADER_SEARCH_PATHS = ( 233 | "$(inherited)", 234 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 235 | ../src, 236 | /usr/local/include, 237 | ); 238 | LIBRARY_SEARCH_PATHS = ( 239 | /usr/local/lib, 240 | /usr/local/Cellar/sfml/2.1/lib, 241 | ); 242 | MACOSX_DEPLOYMENT_TARGET = 10.9; 243 | PRODUCT_NAME = "$(TARGET_NAME)"; 244 | SDKROOT = macosx; 245 | }; 246 | name = Release; 247 | }; 248 | /* End XCBuildConfiguration section */ 249 | 250 | /* Begin XCConfigurationList section */ 251 | B9EEE5BA1985908300C64E71 /* Build configuration list for PBXProject "pmmodel" */ = { 252 | isa = XCConfigurationList; 253 | buildConfigurations = ( 254 | B9EEE5BB1985908300C64E71 /* Debug */, 255 | B9EEE5BC1985908300C64E71 /* Release */, 256 | ); 257 | defaultConfigurationIsVisible = 0; 258 | defaultConfigurationName = Release; 259 | }; 260 | B9EEE5C8198590CD00C64E71 /* Build configuration list for PBXNativeTarget "3DTest" */ = { 261 | isa = XCConfigurationList; 262 | buildConfigurations = ( 263 | B9EEE5C9198590CD00C64E71 /* Debug */, 264 | B9EEE5CA198590CD00C64E71 /* Release */, 265 | ); 266 | defaultConfigurationIsVisible = 0; 267 | }; 268 | /* End XCConfigurationList section */ 269 | }; 270 | rootObject = B9EEE5B71985908300C64E71 /* Project object */; 271 | } 272 | -------------------------------------------------------------------------------- /pmmodel/pmmodel.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /pmmodel/pmmodel.xcodeproj/project.xcworkspace/xcuserdata/julian.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uyjulian/PaperMarioModelViewer/de1fb31344b7b82629a931c03e5f68ea5afc60e5/pmmodel/pmmodel.xcodeproj/project.xcworkspace/xcuserdata/julian.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /pmmodel/pmmodel.xcodeproj/xcuserdata/julian.xcuserdatad/xcschemes/3DTest.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 64 | 65 | 66 | 67 | 71 | 72 | 76 | 77 | 81 | 82 | 86 | 87 | 91 | 92 | 96 | 97 | 101 | 102 | 103 | 104 | 110 | 111 | 117 | 118 | 119 | 120 | 122 | 123 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /pmmodel/pmmodel.xcodeproj/xcuserdata/julian.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | 3DTest.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | B9EEE5C0198590CD00C64E71 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/AppState.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef APPSTATE_H_ 27 | #define APPSTATE_H_ 28 | 29 | #include "system/InputController.h" 30 | #include "renderer/Camera.h" 31 | 32 | class AppState { 33 | public: 34 | 35 | struct Vars { 36 | enum TransformState { 37 | TRANSLATE, ROTATE, ZOOM, 38 | }; 39 | 40 | enum CameraModel { 41 | MANIPULATE_WORLD, MANIPULATE_CAMERA, 42 | }; 43 | 44 | enum SelectState { 45 | SELECT_SGNODE, SELECT_MESH, SELECT_POLY, 46 | }; 47 | 48 | bool showMeshBBox; 49 | bool showPolyFrame; 50 | bool showSGObjectBBox; 51 | TransformState transformState; 52 | CameraModel cameraModel; 53 | SelectState selectState; 54 | int selectIndex; 55 | 56 | Vars () { 57 | resetDefault(); 58 | } 59 | 60 | void resetDefault () { 61 | showMeshBBox = false; 62 | showPolyFrame = false; 63 | showSGObjectBBox = false; 64 | transformState = ROTATE; 65 | cameraModel = MANIPULATE_WORLD; 66 | selectState = SELECT_SGNODE; 67 | selectIndex = -1; 68 | } 69 | }; 70 | 71 | InputController& ic; 72 | gfx::Camera camera; 73 | Vars vars; 74 | 75 | unsigned frameCounter; 76 | 77 | public: 78 | 79 | static AppState& getState () { 80 | static AppState as; 81 | return as; 82 | } 83 | 84 | void resetDefault () { 85 | frameCounter = 0; 86 | camera.setEye(0.f, 0.f, 30.f); 87 | camera.setFocus(0.f, 0.f, 0.f); 88 | vars.resetDefault(); 89 | } 90 | 91 | protected: 92 | 93 | AppState () 94 | : ic(InputController::getController()) { 95 | resetDefault(); 96 | } 97 | 98 | AppState (const AppState&) 99 | : ic(InputController::getController()) { 100 | resetDefault(); 101 | } 102 | 103 | AppState& operator= (const AppState&) { 104 | return *this; 105 | } 106 | }; 107 | 108 | #endif /* APPSTATE_H_ */ 109 | -------------------------------------------------------------------------------- /src/Color.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef COLOR_H_ 27 | #define COLOR_H_ 28 | 29 | #include "common.h" 30 | 31 | const float CI_RED = 0.212; 32 | const float CI_GREEN = 0.701; 33 | const float CI_BLUE = 0.087; 34 | 35 | class Color8 { 36 | protected: 37 | 38 | u8 r; 39 | u8 g; 40 | u8 b; 41 | u8 a; 42 | u8 lum; 43 | 44 | public: 45 | 46 | Color8 () 47 | : r(0), g(0), b(0), a(0), lum(0) { 48 | } 49 | 50 | Color8 (u8 red, u8 green, u8 blue, u8 alpha) 51 | : r(red), g(green), b(blue), a(alpha), lum((u8)(r * CI_RED + g * CI_GREEN + b * CI_BLUE)) { 52 | } 53 | 54 | Color8 (u8 luminance) 55 | : r(luminance), g(luminance), b(luminance), a(255), lum(luminance) { 56 | } 57 | 58 | Color8 (u8 luminance, u8 alpha) 59 | : r(luminance), g(luminance), b(luminance), a(alpha), lum(luminance) { 60 | } 61 | 62 | Color8 (const Color8& c) 63 | : r(c.red()), g(c.green()), b(c.blue()), a(c.alpha()), lum(c.luminance()) { 64 | } 65 | 66 | void blend (const Color8& c0, const Color8& c1, u8 alpha) { 67 | r = ((255 - alpha) * c0.red() + alpha * c1.red()) >> 8; 68 | g = ((255 - alpha) * c0.green() + alpha * c1.green()) >> 8; 69 | b = ((255 - alpha) * c0.blue() + alpha * c1.blue()) >> 8; 70 | a = ((255 - alpha) * c0.alpha() + alpha * c1.alpha()) >> 8; 71 | lum = ((255 - alpha) * c0.luminance() + alpha * c1.luminance()) >> 8; 72 | } 73 | 74 | void set (u8 red, u8 green, u8 blue, u8 alpha) { 75 | r = red; 76 | g = green; 77 | b = blue; 78 | a = alpha; 79 | lum = (u8)(r * CI_RED + g * CI_GREEN + b * CI_BLUE); 80 | } 81 | 82 | u8 red () const { return r; } 83 | u8 green () const { return g; } 84 | u8 blue () const { return b; } 85 | u8 alpha () const { return a; } 86 | u8 luminance () const { return lum; } 87 | }; 88 | 89 | #endif /* COLOR_H_ */ 90 | -------------------------------------------------------------------------------- /src/GLView.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef GLVIEW_H_ 27 | #define GLVIEW_H_ 28 | 29 | #include 30 | #include 31 | #include "AppState.h" 32 | #include "PMModelGL.h" 33 | //#include "PMWorldGL.h" 34 | #include "system/Input.h" 35 | #include "vecmath/MatrixG4.h" 36 | #include "renderer/Scenegraph.h" 37 | 38 | class GLView { 39 | protected: 40 | 41 | std::string modelFile; 42 | PMModelGL pmm; 43 | 44 | unsigned _width; 45 | unsigned _height; 46 | 47 | public: 48 | 49 | GLView () { 50 | _width = 800; 51 | _height = 600; 52 | } 53 | 54 | GLView (int width, int height) { 55 | _width = width; 56 | _height = height; 57 | } 58 | 59 | virtual ~GLView () { } 60 | 61 | void setModelFile (const std::string& str) { 62 | modelFile = str; 63 | } 64 | 65 | void init () { 66 | glClearDepth(1.f); 67 | glClearColor(.2f, .2f, .2f, 0.f); 68 | 69 | glEnable(GL_DEPTH_TEST); 70 | glDepthMask(GL_TRUE); 71 | 72 | glDisable(GL_CULL_FACE); 73 | glDisable(GL_ALPHA_TEST); 74 | glDisable(GL_BLEND); 75 | 76 | if (!pmm.LoadFile(modelFile)) { 77 | std::cout << "Error encountered: " << pmm.errorMessage << std::endl; 78 | exit(1); 79 | } 80 | 81 | pmm.Init(); 82 | 83 | AppState::getState(); 84 | resize(_width, _height); 85 | } 86 | 87 | void resize (int width, int height) { 88 | _width = width; 89 | _height = height; 90 | 91 | glMatrixMode(GL_PROJECTION); 92 | glLoadIdentity(); 93 | gluPerspective(40.f, (float)width / (float)height, .1f, 2000.f); 94 | glViewport(0, 0, width, height); 95 | glMatrixMode(GL_MODELVIEW); 96 | } 97 | 98 | void display () { 99 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 100 | 101 | glMatrixMode(GL_MODELVIEW); 102 | glLoadIdentity(); 103 | 104 | // Camera transformation 105 | 106 | AppState& state = AppState::getState(); 107 | state.camera.viewTransform(); 108 | 109 | // Draw Model 110 | 111 | pmm.Draw(); 112 | 113 | // Draw state informational text 114 | 115 | WindowController& wc = WindowController::getController(); 116 | 117 | std::stringstream str(""); 118 | str << "Paper Mario Model Viewer | "; 119 | str << "Camera: "; 120 | str << cameraStateString(); 121 | str << " | Model: "; 122 | str << pmm.GetInfoString(); 123 | 124 | wc.window.setTitle(str.str()); 125 | } 126 | 127 | void eventLoop () { 128 | AppState& state = AppState::getState(); 129 | // Switch modelview transformation 130 | if (state.ic.input.keyPressed(sf::Keyboard::T)) { 131 | state.vars.transformState = AppState::Vars::TRANSLATE; 132 | } 133 | if (state.ic.input.keyPressed(sf::Keyboard::R)) { 134 | state.vars.transformState = AppState::Vars::ROTATE; 135 | } 136 | if (state.ic.input.keyPressed(sf::Keyboard::Z)) { 137 | state.vars.transformState = AppState::Vars::ZOOM; 138 | } 139 | 140 | // Switch cmarea model 141 | if (state.ic.input.keyPressed(sf::Keyboard::C)) { 142 | if (state.vars.cameraModel == AppState::Vars::MANIPULATE_WORLD) { 143 | state.vars.cameraModel = AppState::Vars::MANIPULATE_CAMERA; 144 | } 145 | else { 146 | state.vars.cameraModel = AppState::Vars::MANIPULATE_WORLD; 147 | } 148 | } 149 | 150 | float speedMult = 1.f; 151 | if (state.ic.input.keyHeld(sf::Keyboard::RShift)) { 152 | speedMult = 2.f; 153 | } 154 | 155 | if (state.vars.transformState == AppState::Vars::ZOOM) { 156 | if (state.ic.input.keyHeld(sf::Keyboard::Up)) { 157 | modelviewZoom(state, -.5f * speedMult); 158 | } 159 | if (state.ic.input.keyHeld(sf::Keyboard::Down)) { 160 | modelviewZoom(state, .5f * speedMult); 161 | } 162 | } 163 | if (state.vars.transformState == AppState::Vars::TRANSLATE) { 164 | if (state.ic.input.keyHeld(sf::Keyboard::Up)) { 165 | modelviewTranslate(state, 0.f, .5f * speedMult); 166 | } 167 | if (state.ic.input.keyHeld(sf::Keyboard::Down)) { 168 | modelviewTranslate(state, 0.f, -.5f * speedMult); 169 | } 170 | if (state.ic.input.keyHeld(sf::Keyboard::Left)) { 171 | modelviewTranslate(state, -.5f * speedMult, 0.f); 172 | } 173 | if (state.ic.input.keyHeld(sf::Keyboard::Right)) { 174 | modelviewTranslate(state, .5f * speedMult, 0.f); 175 | } 176 | } 177 | if (state.vars.transformState == AppState::Vars::ROTATE) { 178 | if (state.ic.input.keyHeld(sf::Keyboard::Up)) { 179 | modelviewRotate(state, -1.f * speedMult, 0.f); 180 | } 181 | if (state.ic.input.keyHeld(sf::Keyboard::Down)) { 182 | modelviewRotate(state, 1.f * speedMult, 0.f); 183 | } 184 | if (state.ic.input.keyHeld(sf::Keyboard::Left)) { 185 | modelviewRotate(state, 0.f, -1.f * speedMult); 186 | } 187 | if (state.ic.input.keyHeld(sf::Keyboard::Right)) { 188 | modelviewRotate(state, 0.f, 1.f * speedMult); 189 | } 190 | } 191 | 192 | if (state.ic.input.keyPressed(sf::Keyboard::Num1)) { 193 | state.vars.showSGObjectBBox = (state.vars.showSGObjectBBox) ? 0 : 1; 194 | } 195 | 196 | // Display Restrictions 197 | if (state.ic.input.keyPressed(sf::Keyboard::D)) { 198 | switch (state.vars.selectState) { 199 | case AppState::Vars::SELECT_SGNODE: 200 | state.vars.selectState = AppState::Vars::SELECT_MESH; break; 201 | case AppState::Vars::SELECT_MESH: 202 | state.vars.selectState = AppState::Vars::SELECT_POLY; break; 203 | case AppState::Vars::SELECT_POLY: 204 | state.vars.selectState = AppState::Vars::SELECT_SGNODE; break; 205 | } 206 | } 207 | 208 | if (state.ic.input.keyPressed(sf::Keyboard::Add)) { 209 | state.vars.selectIndex++; 210 | } 211 | if (state.ic.input.keyPressed(sf::Keyboard::Subtract)) { 212 | if (state.vars.selectIndex > -1) { 213 | state.vars.selectIndex--; 214 | } 215 | } 216 | } 217 | 218 | protected: 219 | 220 | void modelviewTranslate (AppState& state, f32 x, f32 y) { 221 | switch (state.vars.cameraModel) { 222 | case AppState::Vars::MANIPULATE_WORLD: 223 | state.camera.translateWorld(x, y, 0.f); 224 | break; 225 | case AppState::Vars::MANIPULATE_CAMERA: 226 | break; 227 | } 228 | } 229 | 230 | void modelviewZoom (AppState& state, f32 z) { 231 | switch (state.vars.cameraModel) { 232 | case AppState::Vars::MANIPULATE_WORLD: 233 | state.camera.translateWorld(0.f, 0.f, z); 234 | break; 235 | case AppState::Vars::MANIPULATE_CAMERA: 236 | state.camera.moveEyeAndFocus(-z); 237 | break; 238 | } 239 | } 240 | 241 | void modelviewRotate (AppState& state, f32 x, f32 y) { 242 | switch (state.vars.cameraModel) { 243 | case AppState::Vars::MANIPULATE_WORLD: 244 | state.camera.rotateWorld(x, y, 0.f); 245 | break; 246 | case AppState::Vars::MANIPULATE_CAMERA: 247 | state.camera.moveFocusRelativeEye(y, -x); 248 | break; 249 | } 250 | } 251 | 252 | std::string cameraStateString () const { 253 | AppState& state = AppState::getState(); 254 | std::stringstream str; 255 | 256 | switch (state.vars.cameraModel) { 257 | case AppState::Vars::MANIPULATE_WORLD: 258 | str << "WORLD | "; 259 | break; 260 | case AppState::Vars::MANIPULATE_CAMERA: 261 | str << "CAMERA | "; 262 | break; 263 | } 264 | 265 | switch (state.vars.transformState) { 266 | case AppState::Vars::TRANSLATE: 267 | str << "Translate"; 268 | break; 269 | case AppState::Vars::ROTATE: 270 | str << "Rotate"; 271 | break; 272 | case AppState::Vars::ZOOM: 273 | str << "Zoom"; 274 | break; 275 | } 276 | 277 | return str.str(); 278 | } 279 | 280 | }; 281 | 282 | #endif /* GLVIEW_H_ */ 283 | -------------------------------------------------------------------------------- /src/Image.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef IMAGE_H_ 27 | #define IMAGE_H_ 28 | 29 | #include 30 | #include 31 | #include "Color.h" 32 | 33 | class Image { 34 | public: 35 | 36 | enum ImageType { 37 | LUM4, LUM8, 38 | LUM4_A4, LUM8_A8, 39 | RGB8, RGBA8, 40 | }; 41 | 42 | std::vector _data; 43 | 44 | protected: 45 | 46 | ImageType _type; 47 | int _width; 48 | int _height; 49 | 50 | public: 51 | 52 | Image () 53 | : _type(RGBA8), _width(0), _height(0) { 54 | } 55 | 56 | Image (int width, int height, ImageType imageType) { 57 | setup(width, height, imageType); 58 | } 59 | 60 | ~Image () { 61 | 62 | } 63 | 64 | int getHeight () const { 65 | return _height; 66 | } 67 | 68 | int getWidth () const { 69 | return _width; 70 | } 71 | 72 | void setup (int width, int height, ImageType imageType) { 73 | _width = width; 74 | _height = height; 75 | _type = imageType; 76 | 77 | int bpp = typeBPP(_type); 78 | _data.resize(((_width * _height) >> 1) * ((bpp << 1) / 8)); 79 | } 80 | 81 | void setPixel (int x, int y, const Color8& c) { 82 | switch (_type) { 83 | case LUM4: setPixel_LUM4(x, y, c); break; 84 | case LUM8: setPixel_LUM8(x, y, c); break; 85 | case LUM4_A4: setPixel_LUM4_A4(x, y, c); break; 86 | case LUM8_A8: setPixel_LUM8_A8(x, y, c); break; 87 | case RGB8: setPixel_RGB8(x, y, c); break; 88 | case RGBA8: setPixel_RGBA8(x, y, c); break; 89 | } 90 | } 91 | 92 | void setPixelBlock (int x, int y, int w, int h, const std::vector& data, int offset, int scansize) { 93 | unsigned int vecsz = offset + (h * scansize); 94 | if (data.capacity() < vecsz) { 95 | return; 96 | } 97 | 98 | // Clip dimentions 99 | if (x + w > _width) { 100 | w = _width - x; 101 | } 102 | if (y + h > _height) { 103 | h = _height - y; 104 | } 105 | 106 | // Set data 107 | for (int j = y; j < y + h; j++) { 108 | for (int i = x; i < x + w; i++) { 109 | int srcIndex = offset + ((j - y) * scansize) + (i - x); 110 | setPixel(i, j, data[srcIndex]); 111 | } 112 | } 113 | } 114 | 115 | protected: 116 | 117 | int typeBPP (ImageType type) const { 118 | switch (type) { 119 | case LUM4: return 4; 120 | case LUM8: return 8; 121 | case LUM4_A4: return 8; 122 | case LUM8_A8: return 16; 123 | case RGB8: return 24; 124 | case RGBA8: return 32; 125 | default: return 0; 126 | } 127 | } 128 | 129 | void setPixel_LUM4 (int x, int y, const Color8& c) { 130 | int pixelsIn = (y * _width) + x; 131 | int addr = pixelsIn >> 1; 132 | if (pixelsIn % 2 == 0) { 133 | _data[addr] = (_data[addr] & 0x0F) | (c.luminance() & 0xF0); 134 | } 135 | else { 136 | _data[addr] = (_data[addr] & 0xF0) | (c.luminance() >> 4); 137 | } 138 | } 139 | 140 | void setPixel_LUM8 (int x, int y, const Color8& c) { 141 | int addr = (y * _width) + x; 142 | _data[addr] = c.luminance(); 143 | } 144 | 145 | void setPixel_LUM4_A4 (int x, int y, const Color8& c) { 146 | int addr = (y * _width) + x; 147 | _data[addr] = (c.luminance() & 0xF0) | (c.alpha() >> 4); 148 | } 149 | 150 | void setPixel_LUM8_A8 (int x, int y, const Color8& c) { 151 | int addr = 2 * ((y * _width) + x); 152 | _data[addr] = c.luminance(); 153 | _data[addr+1] = c.alpha(); 154 | } 155 | 156 | void setPixel_RGB8 (int x, int y, const Color8& c) { 157 | int addr = 3 * ((y * _width) + x); 158 | _data[addr] = c.red(); 159 | _data[addr+1] = c.green(); 160 | _data[addr+2] = c.blue(); 161 | } 162 | 163 | void setPixel_RGBA8 (int x, int y, const Color8& c) { 164 | int addr = 4 * ((y * _width) + x); 165 | _data[addr] = (c.red()); 166 | _data[addr+1] = (c.green()); 167 | _data[addr+2] = (c.blue()); 168 | _data[addr+3] = c.alpha(); 169 | } 170 | }; 171 | 172 | #endif /* IMAGE_H_ */ 173 | -------------------------------------------------------------------------------- /src/PMModelGL.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef PMMODELGL_H_ 27 | #define PMMODELGL_H_ 28 | 29 | #include 30 | #include 31 | #include 32 | #include "renderer/Scenegraph.h" 33 | #include "renderer/RenderGL.h" 34 | #include "system/WindowController.h" 35 | #include "vecmath/Vecmath.h" 36 | #include "PMModel.h" 37 | #include "TPL.h" 38 | #include "common.h" 39 | 40 | class PMModelGL : public PMModel { 41 | public: 42 | 43 | TPL tpl; 44 | 45 | gfx::Scenegraph scenegraph; 46 | gfx::RenderGL renderer; 47 | 48 | std::string errorMessage; 49 | 50 | public: 51 | 52 | /* 53 | * Parses the PMModel Scene Graph and transformation data into a renderable 54 | * Scenegraph object. 55 | */ 56 | 57 | void parseSceneNode (gfx::Scenegraph::Node* node, unsigned sgRecordIndex) { 58 | const Scenegraph& sgr = sgRecords[sgRecordIndex]; 59 | 60 | vmath::Vector3f v1(sgObjectTransforms[sgr.sgObjectTransIndex + 0].transform, 61 | sgObjectTransforms[sgr.sgObjectTransIndex + 1].transform, 62 | sgObjectTransforms[sgr.sgObjectTransIndex + 2].transform); 63 | 64 | vmath::Vector3f v2(sgObjectTransforms[sgr.sgObjectTransIndex + 3].transform, 65 | sgObjectTransforms[sgr.sgObjectTransIndex + 4].transform, 66 | sgObjectTransforms[sgr.sgObjectTransIndex + 5].transform); 67 | 68 | vmath::Vector3f v3(sgObjectTransforms[sgr.sgObjectTransIndex + 6].transform, 69 | sgObjectTransforms[sgr.sgObjectTransIndex + 7].transform, 70 | sgObjectTransforms[sgr.sgObjectTransIndex + 8].transform); 71 | 72 | vmath::Vector3f v4(sgObjectTransforms[sgr.sgObjectTransIndex + 9].transform, 73 | sgObjectTransforms[sgr.sgObjectTransIndex + 10].transform, 74 | sgObjectTransforms[sgr.sgObjectTransIndex + 11].transform); 75 | 76 | vmath::Vector3f v5(sgObjectTransforms[sgr.sgObjectTransIndex + 12].transform, 77 | sgObjectTransforms[sgr.sgObjectTransIndex + 13].transform, 78 | sgObjectTransforms[sgr.sgObjectTransIndex + 14].transform); 79 | 80 | vmath::Vector3f v6(sgObjectTransforms[sgr.sgObjectTransIndex + 15].transform, 81 | sgObjectTransforms[sgr.sgObjectTransIndex + 16].transform, 82 | sgObjectTransforms[sgr.sgObjectTransIndex + 17].transform); 83 | 84 | vmath::Vector3f v7(sgObjectTransforms[sgr.sgObjectTransIndex + 18].transform, 85 | sgObjectTransforms[sgr.sgObjectTransIndex + 19].transform, 86 | sgObjectTransforms[sgr.sgObjectTransIndex + 20].transform); 87 | 88 | vmath::Vector3f v8(sgObjectTransforms[sgr.sgObjectTransIndex + 21].transform, 89 | sgObjectTransforms[sgr.sgObjectTransIndex + 22].transform, 90 | sgObjectTransforms[sgr.sgObjectTransIndex + 23].transform); 91 | 92 | node->addTransform(gfx::Scenegraph::Node::TRANSFORM_TRANSLATE, v1); 93 | node->addTransform(gfx::Scenegraph::Node::TRANSFORM_TRANSLATE, v7); 94 | node->addTransform(gfx::Scenegraph::Node::TRANSFORM_SCALE, v2); 95 | node->addTransform(gfx::Scenegraph::Node::TRANSFORM_TRANSLATE, 0.f - v8); 96 | node->addTransform(gfx::Scenegraph::Node::TRANSFORM_ROTATE_ZYX, v4); 97 | node->addTransform(gfx::Scenegraph::Node::TRANSFORM_TRANSLATE, v5); 98 | node->addTransform(gfx::Scenegraph::Node::TRANSFORM_ROTATE_ZYX, 2.f * v3); 99 | node->addTransform(gfx::Scenegraph::Node::TRANSFORM_TRANSLATE, 0.f - v6); 100 | 101 | parseGeometry(node, sgRecordIndex); 102 | 103 | if (sgr.childRecord != -1) { 104 | gfx::Scenegraph::Node* child = scenegraph.newChild(node); 105 | parseSceneNode(child, sgr.childRecord); 106 | } 107 | 108 | if (sgr.nextRecord != -1 && node->hasParent()) { 109 | gfx::Scenegraph::Node* sibling = scenegraph.newChild(node->getParent()); 110 | parseSceneNode(sibling, sgr.nextRecord); 111 | } 112 | } 113 | 114 | void parseGeometry (gfx::Scenegraph::Node* node, unsigned sgRecordIndex) { 115 | const Scenegraph& sgr = sgRecords[sgRecordIndex]; 116 | 117 | // Skip node if it has no geometry attached 118 | if (sgr.sgObjectIndex == -1) { 119 | return; 120 | } 121 | 122 | const SGObject& object = sgObjects[sgr.sgObjectIndex]; 123 | const SGObjectVis& visibility = sgObjectVisibility[sgr.sgObjectVisIndex]; 124 | 125 | for (int meshId = 0; meshId < object.meshCount; meshId++) { 126 | const Mesh& mesh = meshes[object.meshIndex + meshId]; 127 | gfx::Geometry geo; 128 | 129 | geo.mesh(parseMesh(object, meshId)); 130 | geo.spacialNode = node; 131 | 132 | if (mesh.texMapIndex != -1) { 133 | unsigned textureId = textures[texMaps[mesh.texMapIndex].textureIndex].tplIndex; 134 | geo.texture = renderer.getTexture(textureId); 135 | } 136 | 137 | if (visibility.visibility == 0) { 138 | geo.visible = false; 139 | } 140 | 141 | parseGeometryBlending(object, geo); 142 | parseGeometryCulling(object, geo); 143 | 144 | node->addGeometry(renderer.addGeometry(geo)); 145 | } 146 | } 147 | 148 | void parseGeometryBlending (const SGObject& object, gfx::Geometry& geo) { 149 | switch (object.blending) { 150 | case 0x00: 151 | geo.alphaTest = true; 152 | geo.alphaThresh = 0.995f; 153 | break; 154 | case 0x01: 155 | break; 156 | case 0x02: 157 | geo.alphaTest = true; 158 | geo.alphaThresh = 0.5f; 159 | break; 160 | case 0x03: 161 | geo.blend = true; 162 | geo.blendSrc = GL_SRC_ALPHA; 163 | geo.blendDst = GL_ONE_MINUS_SRC_ALPHA; 164 | break; 165 | default: 166 | std::cout << "(!!) Unknown blending mode: " << object.blending << std::endl; 167 | } 168 | } 169 | 170 | void parseGeometryCulling (const SGObject& object, gfx::Geometry& geo) { 171 | switch (object.culling) { 172 | case 0x01: 173 | geo.cull = true; 174 | geo.cullFunc = GL_BACK; 175 | break; 176 | case 0x03: 177 | geo.cull = false; 178 | break; 179 | default: 180 | std::cout << "(!!) Unknown culling mode: " << object.culling << std::endl; 181 | } 182 | } 183 | 184 | gfx::Mesh* parseMesh (const SGObject& object, int meshId) { 185 | const Mesh& mesh = meshes[object.meshIndex + meshId]; 186 | 187 | gfx::TriMesh renderMesh; 188 | if (mesh.texMapIndex == -1) { 189 | renderMesh.useTexCoords(false); 190 | } 191 | 192 | for (int polyId = 0; polyId < mesh.polygonCount; polyId++) { 193 | const Polygon& poly = polygons[mesh.polygonIndex + polyId]; 194 | std::vector polyIndex; 195 | 196 | // Draw each vertex suite in polygon 197 | for (unsigned int v = 0; v < poly.vertexCount; v++) { 198 | unsigned vertexId = object.vertexIndex + polyVertices[mesh.polyVertexIndex + poly.polyVertexIndex + v].vertexIndex; 199 | unsigned normalId = object.u0x48 + polyNormals[mesh.polyNormalIndex + poly.polyVertexIndex + v].normalIndex; 200 | unsigned colorId = object.u0x50 + polyColors[mesh.polyColorIndex + poly.polyVertexIndex + v].colorIndex; 201 | unsigned texCoordId = object.texCoordIndex + polyTexCoords[mesh.polyTexCoordIndex + poly.polyVertexIndex + v].texCoordIndex; 202 | 203 | gfx::vertexDef vdef; 204 | vdef.vertex = gfx::vertex3f(vertices[vertexId].x, vertices[vertexId].y, vertices[vertexId].z); 205 | vdef.normal = gfx::normal3f(normals[normalId].nx, normals[normalId].ny, normals[normalId].nz); 206 | vdef.color = gfx::color4ub(colors[colorId].r, colors[colorId].g, colors[colorId].b, colors[colorId].a); 207 | if (mesh.texMapIndex != -1) { 208 | vdef.texCoord = gfx::texCoord2f(texCoords[texCoordId].s, texCoords[texCoordId].t); 209 | } 210 | 211 | renderMesh.addVertex(vdef); 212 | polyIndex.push_back(renderMesh.getVertexCount() - 1); 213 | } 214 | 215 | renderMesh.addIndexPolygon(polyIndex); 216 | } 217 | 218 | return renderer.addMesh(renderMesh); 219 | } 220 | 221 | void parseTextures () { 222 | for (unsigned i = 0; i < textures.size(); i++) { 223 | gfx::TextureData texData(GL_RGBA, tpl._textures[i].texHeader.width, 224 | tpl._textures[i].texHeader.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 225 | 0, tpl._textures[i].tex); 226 | gfx::Texture tex(GL_TEXTURE_2D, texData); 227 | 228 | renderer.addTexture(tex); 229 | } 230 | 231 | for (unsigned i = 0; i < texMaps.size(); i++) { 232 | //gfx::Texture* texPtr = renderer.getTexture(texMaps[i].textureIndex); 233 | 234 | switch (texMaps[i].u0x04) { 235 | case 0x00: 236 | //tex.setTexEnvMode(GL_REPLACE); 237 | //tex.setTexParameteri(GL_TEXTURE_MAG_FILTER, GL_NEAREST); 238 | //tex.setTexParameteri(GL_TEXTURE_MIN_FILTER, GL_NEAREST); 239 | break; 240 | case 0x03: 241 | //tex.setTexEnvMode(GL_MODULATE); 242 | //tex.setTexParameteri(GL_TEXTURE_MAG_FILTER, GL_LINEAR); 243 | //tex.setTexParameteri(GL_TEXTURE_MIN_FILTER, GL_LINEAR); 244 | break; 245 | default: 246 | std::cout << "(!!) Unknown tex env mode: " << texMaps[i].u0x04 << std::endl; 247 | } 248 | } 249 | } 250 | 251 | void Init () { 252 | AppState& state = AppState::getState(); 253 | renderer.camera(&state.camera); 254 | 255 | parseTextures(); 256 | 257 | parseSceneNode (scenegraph.root(), sgRecords.size() - 1); 258 | scenegraph.update(); 259 | } 260 | 261 | void Draw () { 262 | renderer.drawGeometry(); 263 | } 264 | 265 | std::string GetInfoString () { 266 | AppState& state = AppState::getState(); 267 | 268 | std::stringstream str("Select: "); 269 | 270 | switch (state.vars.selectState) { 271 | case AppState::Vars::SELECT_SGNODE: 272 | str << "Node"; 273 | break; 274 | case AppState::Vars::SELECT_MESH: 275 | str << "Mesh"; 276 | break; 277 | case AppState::Vars::SELECT_POLY: 278 | str << "Poly"; 279 | break; 280 | } 281 | 282 | if (state.vars.selectIndex == -1) { 283 | str << " = ALL"; 284 | } 285 | else { 286 | str << " = " << state.vars.selectIndex; 287 | } 288 | 289 | return str.str(); 290 | } 291 | 292 | bool LoadFile (const std::string& file) { 293 | if (!PMModel::LoadFile(file)) { 294 | errorMessage.append("could not open model file '" + filename + "';"); 295 | return false; 296 | } 297 | 298 | std::string tplPath = pathname(file) + "/" + header.textureFile + "-"; 299 | 300 | if (!tpl.LoadFile(tplPath)) { 301 | errorMessage.append("could not open texture file '" + tplPath + "';"); 302 | return false; 303 | } 304 | 305 | std::string infoPath = filename + ".info.txt"; 306 | 307 | // Write info file 308 | if (!PMModel::WriteInfoFile(infoPath, tpl)) { 309 | errorMessage.append("could not open info file '" + infoPath + "';"); 310 | return false; 311 | } 312 | 313 | return true; 314 | } 315 | 316 | void drawWireBox (const vmath::Vector3f& vmin, const vmath::Vector3f& vmax) const { 317 | glBegin(GL_LINE_LOOP); 318 | glVertex3f(vmin.x, vmin.y, vmin.z); 319 | glVertex3f(vmin.x, vmin.y, vmax.z); 320 | glVertex3f(vmax.x, vmin.y, vmax.z); 321 | glVertex3f(vmax.x, vmin.y, vmin.z); 322 | glEnd(); 323 | glBegin(GL_LINE_LOOP); 324 | glVertex3f(vmin.x, vmax.y, vmin.z); 325 | glVertex3f(vmin.x, vmax.y, vmax.z); 326 | glVertex3f(vmax.x, vmax.y, vmax.z); 327 | glVertex3f(vmax.x, vmax.y, vmin.z); 328 | glEnd(); 329 | glBegin(GL_LINES); 330 | glVertex3f(vmin.x, vmin.y, vmin.z); 331 | glVertex3f(vmin.x, vmax.y, vmin.z); 332 | glVertex3f(vmin.x, vmin.y, vmax.z); 333 | glVertex3f(vmin.x, vmax.y, vmax.z); 334 | glVertex3f(vmax.x, vmin.y, vmax.z); 335 | glVertex3f(vmax.x, vmax.y, vmax.z); 336 | glVertex3f(vmax.x, vmin.y, vmin.z); 337 | glVertex3f(vmax.x, vmax.y, vmin.z); 338 | glEnd(); 339 | } 340 | }; 341 | 342 | #endif /* PMMODELGL_H_ */ 343 | -------------------------------------------------------------------------------- /src/PMWorldGL.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef PMWORLDGL_H_ 27 | #define PMWORLDGL_H_ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "vecmath/Vecmath.h" 34 | #include "renderer/RenderGL.h" 35 | #include "PMWorld.h" 36 | #include "TPL.h" 37 | #include "common.h" 38 | 39 | class PMWorldGL : public PMWorld { 40 | public: 41 | 42 | TPL tpl; 43 | std::vector glTextures; 44 | 45 | std::string errorMessage; 46 | 47 | public: 48 | 49 | void Init() { 50 | 51 | } 52 | 53 | void Draw () { 54 | //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 55 | drawSceneGraph(sgRecords[0]); 56 | 57 | /*glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 58 | for (u32 i = 0; i < meshes.size(); i++) { 59 | const Mesh& mesh = meshes[i]; 60 | 61 | for (u32 j = 0; j < mesh.polyCount; j++) { 62 | const Polygon& polygon = mesh.polygons[j]; 63 | glBegin(GL_TRIANGLE_STRIP); 64 | 65 | for (u32 k = 0; k < polygon.vertexCount; k++) { 66 | const PolyVertex& pvertex = polygon.vertices[k]; 67 | const Vertex& vertex = vertices[pvertex.vertexID]; 68 | 69 | glVertex3f(vertex.x, vertex.y, vertex.z); 70 | } 71 | glEnd(); 72 | } 73 | }*/ 74 | /*glBegin(GL_POINTS); 75 | for (unsigned int i = 0; i < vertices.size(); i++) { 76 | glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z); 77 | } 78 | glEnd();*/ 79 | } 80 | 81 | void drawSceneGraph (const Scenegraph& sgr) { 82 | glPushMatrix(); 83 | 84 | 85 | 86 | glTranslatef(sgr.u0x30, sgr.u0x34, sgr.u0x38); 87 | 88 | glScalef(sgr.u0x18, sgr.u0x1C, sgr.u0x20); 89 | 90 | 91 | glTranslatef(sgr.u0x48, sgr.u0x4C, sgr.u0x50); 92 | //glRotatef(sgr.u0x2C, 0.f, 0.f, 1.f); 93 | //glRotatef(sgr.u0x28, 0.f, 1.f, 0.f); 94 | //glRotatef(sgr.u0x24, 1.f, 0.f, 0.f); 95 | glTranslatef(sgr.u0x3C, sgr.u0x40, sgr.u0x44); 96 | 97 | 98 | if (sgr.u0x5C != 0) { 99 | const Material& material = materials[sgr.u0x60]; 100 | 101 | drawMesh(sgr.meshes[0], material); 102 | } 103 | 104 | glPopMatrix(); 105 | 106 | if (sgr.addrChild != 0) { 107 | drawSceneGraph(sgRecords[sgr.childID]); 108 | } 109 | 110 | //glPopMatrix(); 111 | 112 | if (sgr.addrNext != 0) { 113 | drawSceneGraph(sgRecords[sgr.nextID]); 114 | } 115 | } 116 | 117 | void drawMesh (const Mesh& mesh, const Material& material) { 118 | 119 | if (material.textureID >= 0) { 120 | glEnable(GL_TEXTURE_2D); 121 | glBindTexture(GL_TEXTURE_2D, glTextures[material.textureID]); 122 | } 123 | 124 | for (u32 j = 0; j < mesh.polyCount; j++) { 125 | const Polygon& polygon = mesh.polygons[j]; 126 | glBegin(GL_TRIANGLE_STRIP); 127 | 128 | for (u32 k = 0; k < polygon.vertexCount; k++) { 129 | const PolyVertex& pvertex = polygon.vertices[k]; 130 | const Vertex& vertex = vertices[pvertex.vertexID]; 131 | 132 | glVertex3f(vertex.x, vertex.y, vertex.z); 133 | glTexCoord2f(vertex.x, vertex.y); 134 | } 135 | glEnd(); 136 | } 137 | 138 | glDisable(GL_TEXTURE_2D); 139 | } 140 | 141 | bool LoadFile (const std::string& file) { 142 | if (!PMWorld::LoadFile(file)) { 143 | errorMessage.append("could not open world file '" + filename + "';"); 144 | return false; 145 | } 146 | 147 | std::string tplPath = pathname(file) + "/t"; 148 | 149 | if (!tpl.LoadFile(tplPath)) { 150 | errorMessage.append("could not open texture file '" + tplPath + "';"); 151 | return false; 152 | } 153 | 154 | std::string infoPath = filename + ".info.txt"; 155 | 156 | // Write info file 157 | if (!PMWorld::WriteInfoFile(infoPath)) { 158 | errorMessage.append("could not open info file '" + infoPath + "';"); 159 | return false; 160 | } 161 | 162 | LoadTextures(); 163 | return true; 164 | } 165 | 166 | void LoadTextures () { 167 | glTextures.resize(tpl._header.nTextures); 168 | glGenTextures(tpl._header.nTextures, &glTextures[0]); 169 | 170 | //for (unsigned int i = 0; i < tpl._header.nTextures; i++) { 171 | for (unsigned int i = 0; i < texTable.textureCount; i++) { 172 | int ti = i; 173 | glBindTexture(GL_TEXTURE_2D, glTextures[ti]); 174 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 175 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 176 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 177 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 178 | 179 | //switch (texMaps[i].u0x04) { 180 | // case 0x00: 181 | // glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 182 | // break; 183 | // case 0x03: 184 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 185 | // break; 186 | // default: 187 | // std::cout << "(!!) Unknown tex env mode: " << texMaps[i].u0x04 << std::endl; 188 | //} 189 | 190 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 191 | tpl._textures[ti].texHeader.width, tpl._textures[ti].texHeader.height, 192 | 0, GL_RGBA, GL_UNSIGNED_BYTE, &tpl._textures[ti].tex._data[0]); 193 | } 194 | } 195 | 196 | void drawWireBox (const vmath::Vector3f& vmin, const vmath::Vector3f& vmax) const { 197 | glBegin(GL_LINE_LOOP); 198 | glVertex3f(vmin.x, vmin.y, vmin.z); 199 | glVertex3f(vmin.x, vmin.y, vmax.z); 200 | glVertex3f(vmax.x, vmin.y, vmax.z); 201 | glVertex3f(vmax.x, vmin.y, vmin.z); 202 | glEnd(); 203 | glBegin(GL_LINE_LOOP); 204 | glVertex3f(vmin.x, vmax.y, vmin.z); 205 | glVertex3f(vmin.x, vmax.y, vmax.z); 206 | glVertex3f(vmax.x, vmax.y, vmax.z); 207 | glVertex3f(vmax.x, vmax.y, vmin.z); 208 | glEnd(); 209 | glBegin(GL_LINES); 210 | glVertex3f(vmin.x, vmin.y, vmin.z); 211 | glVertex3f(vmin.x, vmax.y, vmin.z); 212 | glVertex3f(vmin.x, vmin.y, vmax.z); 213 | glVertex3f(vmin.x, vmax.y, vmax.z); 214 | glVertex3f(vmax.x, vmin.y, vmax.z); 215 | glVertex3f(vmax.x, vmax.y, vmax.z); 216 | glVertex3f(vmax.x, vmin.y, vmin.z); 217 | glVertex3f(vmax.x, vmax.y, vmin.z); 218 | glEnd(); 219 | } 220 | }; 221 | 222 | #endif /* PMWORLDGL_H_ */ 223 | -------------------------------------------------------------------------------- /src/TPL.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef TPL_H_ 27 | #define TPL_H_ 28 | 29 | #include 30 | #include 31 | #include 32 | #include "common.h" 33 | #include "TexCodec.h" 34 | 35 | class TPL { 36 | public: 37 | 38 | struct TPLHeader { 39 | u32 magic; 40 | u32 nTextures; 41 | u32 szHeader; 42 | }; 43 | 44 | struct TPLTexDef { 45 | u32 headerOffset; 46 | u32 paletteOffset; 47 | }; 48 | 49 | struct TPLTexHeader { 50 | u16 height; 51 | u16 width; 52 | u32 format; 53 | u32 dataOffset; 54 | u32 wrap_s; 55 | u32 wrap_t; 56 | u32 minFilter; 57 | u32 magFilter; 58 | f32 lodBias; 59 | u8 edgeLod; 60 | u8 minLod; 61 | u8 maxLod; 62 | u8 unpacked; 63 | }; 64 | 65 | struct TPLPalHeader { 66 | u16 nItems; 67 | u8 unpacked; 68 | u8 pad; 69 | u32 format; 70 | u32 dataOffset; 71 | }; 72 | 73 | struct TPLTexture { 74 | TPLTexHeader texHeader; 75 | TPLPalHeader palHeader; 76 | Image tex; 77 | 78 | TPLTexture () { } 79 | }; 80 | 81 | public: 82 | 83 | std::string _filename; 84 | TPLHeader _header; 85 | std::vector _textures; 86 | 87 | public: 88 | 89 | bool LoadFile (const std::string& filename) { 90 | _filename = filename; 91 | std::fstream filestr; 92 | 93 | filestr.open(filename.c_str(), std::fstream::in | std::fstream::binary); 94 | if (filestr.fail()) { 95 | return false; 96 | } 97 | 98 | // Get file size; 99 | filestr.seekg(0, std::fstream::end); 100 | int filesize = filestr.tellg(); 101 | filestr.seekg(0, std::fstream::beg); 102 | 103 | // Read entire file 104 | std::vector buffer(filesize); 105 | filestr.read((char*)&buffer[0], filesize); 106 | 107 | filestr.close(); 108 | 109 | // Read header 110 | //filestr.read((char*)&_header, sizeof(TPLHeader)); 111 | _header.magic = getU32(buffer, 0); 112 | _header.nTextures = getU32(buffer, 4); 113 | _header.szHeader = getU32(buffer, 8); 114 | 115 | if (_header.magic != 0x0020AF30) { 116 | return false; 117 | } 118 | 119 | _textures.resize(_header.nTextures); 120 | 121 | // Get list of defined textures 122 | std::vector defs(_header.nTextures); 123 | for (unsigned int i = 0; i < _header.nTextures; i++) { 124 | int dataIndex = _header.szHeader + (i * 8); 125 | defs[i].headerOffset = getU32(buffer, dataIndex); 126 | defs[i].paletteOffset = getU32(buffer, dataIndex + 4); 127 | } 128 | 129 | // Get textures 130 | for (unsigned int i = 0; i < _header.nTextures; i++) { 131 | _textures[i].texHeader.height = getU16(buffer, defs[i].headerOffset + 0); 132 | _textures[i].texHeader.width = getU16(buffer, defs[i].headerOffset + 2); 133 | _textures[i].texHeader.format = getU32(buffer, defs[i].headerOffset + 4); 134 | _textures[i].texHeader.dataOffset = getU32(buffer, defs[i].headerOffset + 8); 135 | _textures[i].texHeader.wrap_s = getU32(buffer, defs[i].headerOffset + 12); 136 | _textures[i].texHeader.wrap_t = getU32(buffer, defs[i].headerOffset + 16); 137 | _textures[i].texHeader.minFilter = getU32(buffer, defs[i].headerOffset + 20); 138 | _textures[i].texHeader.magFilter = getU32(buffer, defs[i].headerOffset + 24); 139 | _textures[i].texHeader.lodBias = getF32(buffer, defs[i].headerOffset + 28); 140 | _textures[i].texHeader.edgeLod = buffer[defs[i].headerOffset + 32]; 141 | _textures[i].texHeader.minLod = buffer[defs[i].headerOffset + 33]; 142 | _textures[i].texHeader.maxLod = buffer[defs[i].headerOffset + 34]; 143 | _textures[i].texHeader.unpacked = buffer[defs[i].headerOffset + 35]; 144 | 145 | if (defs[i].paletteOffset != 0) { 146 | _textures[i].palHeader.nItems = getU16(buffer, defs[i].paletteOffset + 0); 147 | _textures[i].palHeader.unpacked = buffer[defs[i].paletteOffset + 4]; 148 | _textures[i].palHeader.pad = buffer[defs[i].paletteOffset + 5]; 149 | _textures[i].palHeader.format = getU32(buffer, defs[i].paletteOffset + 6); 150 | _textures[i].palHeader.dataOffset = getU32(buffer, defs[i].paletteOffset + 10); 151 | } 152 | 153 | TexCodec codec; 154 | codec.texWidth = _textures[i].texHeader.width; 155 | codec.texHeight = _textures[i].texHeader.height; 156 | codec.dataOffset = _textures[i].palHeader.dataOffset; 157 | codec.cacheLineSize = 32; 158 | codec.cacheLinesPerTile = 1; 159 | 160 | switch (_textures[i].texHeader.format) { 161 | case 0: codec.type = TexCodec::I4; break; 162 | case 1: codec.type = TexCodec::I8; break; 163 | case 2: codec.type = TexCodec::IA4; break; 164 | case 3: codec.type = TexCodec::IA8; break; 165 | case 4: codec.type = TexCodec::RGB565; break; 166 | case 5: codec.type = TexCodec::RGB5A3; break; 167 | case 6: codec.type = TexCodec::RGBA8; 168 | codec.cacheLinesPerTile = 2; break; 169 | case 14: codec.type = TexCodec::CMPR; break; 170 | default: std::cout << "Unsupported TPL format: " << codec.type << std::endl; 171 | return false; 172 | } 173 | 174 | if (_textures[i].texHeader.format == 14) { 175 | _textures[i].tex = codec.DecodeCMPR(buffer, _textures[i].texHeader.dataOffset); 176 | } 177 | else { 178 | _textures[i].tex = codec.DecodeTiled(buffer, _textures[i].texHeader.dataOffset); 179 | } 180 | 181 | } 182 | 183 | return true; 184 | } 185 | }; 186 | 187 | #endif /* TPL_H_ */ 188 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef COMMON_H_ 27 | #define COMMON_H_ 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | typedef unsigned char u8; 34 | typedef unsigned short u16; 35 | typedef unsigned long u32; 36 | typedef unsigned long long u64; 37 | typedef signed char s8; 38 | typedef signed short s16; 39 | typedef signed long s32; 40 | typedef signed long long s64; 41 | typedef float f32; 42 | typedef double f64; 43 | 44 | inline float halfFloat (u16 hf) { 45 | u32 f = (hf & 0x8000) << 16; 46 | u16 e = (hf >> 10) & 0x001F; 47 | 48 | f |= (e + 112) << 23; 49 | f |= (hf & 0x03FF) << 13; 50 | 51 | if (e == 0x00) f &= 0x807FFFFF; 52 | if (e == 0x1F) f |= 0x7F800000; 53 | 54 | return (*(f32*) &f); 55 | } 56 | 57 | /*inline void byteSwap (u16 &s) 58 | { 59 | u8 v1 = s & 0xFF; 60 | u8 v2 = s >> 8; 61 | s = (v1 << 8) | v2; 62 | }*/ 63 | 64 | inline u16 byteSwap (u16 s) 65 | { 66 | u8 v1 = s & 0xFF; 67 | u8 v2 = s >> 8; 68 | return (v1 << 8) | v2; 69 | } 70 | 71 | inline void byteSwap (u32 &s) 72 | { 73 | u8 v1 = s & 0xFF; 74 | u8 v2 = (s >> 8) & 0xFF; 75 | u8 v3 = (s >> 16) & 0xFF; 76 | u8 v4 = (s >> 24) & 0xFF; 77 | s = (v1 << 24) | (v2 << 16) | (v3 << 8) | v4; 78 | } 79 | 80 | inline void byteSwap (s16 &s) 81 | { 82 | //byteSwap(*(u16*) &s); 83 | } 84 | 85 | inline void byteSwap (s32 &s) 86 | { 87 | byteSwap(*(u32*) &s); 88 | } 89 | 90 | inline void byteSwap (f32 &f) 91 | { 92 | byteSwap(*(u32*) &f); 93 | } 94 | 95 | inline u8 getComponent (u32 src, int idx) { 96 | int mask = (0xFF << (idx * 8)); 97 | return (u8) ((src & mask) >> (idx * 8)); 98 | } 99 | 100 | inline s8 getSComponent (u32 src, int idx) { 101 | return (s8) getComponent(src, idx); 102 | } 103 | 104 | inline u16 getU16 (const std::vector& v, int index) { 105 | return v[index] << 8 | v[index+1]; 106 | } 107 | 108 | inline u32 getU32 (const std::vector& v, int index) { 109 | return v[index] << 24 | v[index+1] << 16 | v[index+2] << 8 | v[index+3]; 110 | } 111 | 112 | inline s16 getS16 (const std::vector& v, int index) { 113 | return (s16) getU16(v, index); 114 | } 115 | 116 | inline s32 getS32 (const std::vector& v, int index) { 117 | return (s32) getU32(v, index); 118 | } 119 | 120 | inline f32 getF16 (const std::vector& v, int index) { 121 | u16 raw = getU16(v, index); 122 | return halfFloat(raw); 123 | } 124 | 125 | inline f32 getF32 (const std::vector& v, int index) { 126 | u32 raw = getU32(v, index); 127 | return (*(f32*) &raw); 128 | } 129 | 130 | inline std::string getString (const std::vector& v, int index, int maxLen) { 131 | std::string str = ""; 132 | for (int i = 0; i < maxLen; i++) { 133 | if (v[index + i] == 0) break; 134 | str.append(1, v[index + i]); 135 | } 136 | return str; 137 | } 138 | 139 | inline float PI () { 140 | return 3.14159265f; 141 | } 142 | 143 | inline float radians (float degrees) { 144 | return (degrees * PI()) / 180.f; 145 | } 146 | 147 | inline std::string pathname (const std::string& str) { 148 | unsigned lastsep = str.find_last_of("/\\"); 149 | return str.substr(0, lastsep); 150 | } 151 | 152 | inline void toggle (int &v) { 153 | (v) ? v = 0 : v = 1; 154 | } 155 | 156 | inline bool fileExists (const std::string &filename) { 157 | FILE *fh = fopen(filename.c_str(), "rb"); 158 | if (fh != NULL) { 159 | fclose(fh); 160 | return true; 161 | } 162 | return false; 163 | } 164 | 165 | #endif /* COMMON_H_ */ 166 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "system/InputController.h" 32 | #include "system/WindowController.h" 33 | #include "GLView.h" 34 | 35 | int main (int argc, char** argv) 36 | { 37 | if (argc <= 1) { 38 | std::cout << "No model file specified" << std::endl; 39 | return 1; 40 | } 41 | 42 | AppState& state = AppState::getState(); 43 | WindowController& wc = WindowController::getController(); 44 | InputController& ic = InputController::getController(); 45 | 46 | int appInitWidth = 800; 47 | int appInitHeight = 600; 48 | 49 | sf::FloatRect windowRect(0.f, 0.f, 800.f, 600.f); 50 | sf::View windowView(windowRect); 51 | 52 | sf::ContextSettings settings; 53 | settings.depthBits = 24; 54 | settings.stencilBits = 8; 55 | settings.antialiasingLevel = 2; 56 | settings.majorVersion = 2; 57 | settings.minorVersion = 1; 58 | 59 | wc.window.create(sf::VideoMode(appInitWidth, appInitHeight, 32), "", sf::Style::Resize | sf::Style::Close, settings); 60 | wc.window.setView(windowView); 61 | wc.window.setVerticalSyncEnabled(true); 62 | wc.window.setFramerateLimit(60); 63 | wc.window.setTitle("Paper Mario Model Viewer"); 64 | 65 | //wc.window.preserveOpenGLStates(true); 66 | 67 | GLView view = GLView(appInitWidth, appInitHeight); 68 | 69 | std::cout << "File: " << argv[1] << std::endl; 70 | 71 | try { 72 | view.setModelFile(std::string(argv[1])); 73 | view.init(); 74 | 75 | std::string programDir = pathname(std::string(argv[0])); 76 | 77 | } 78 | catch (std::exception e) { 79 | std::cout << std::endl; 80 | std::cout << "Uncaught Initialization Exception:" << std::endl; 81 | std::cout << e.what() << std::endl; 82 | std::cout << "Press any key to continue..." << std::flush; 83 | 84 | std::cin.ignore( std::numeric_limits ::max(), '\n' ); 85 | exit(1); 86 | } 87 | 88 | try { 89 | while (wc.window.isOpen()) { 90 | wc.window.setActive(); 91 | ic.input.resetState(); 92 | 93 | wc.window.clear(sf::Color(96, 96, 96)); 94 | 95 | sf::Event event; 96 | while (wc.window.pollEvent(event)) 97 | { 98 | ic.input.processEvent(event); 99 | 100 | if (event.type == sf::Event::Closed) { 101 | wc.window.close(); 102 | } 103 | 104 | if (event.type == sf::Event::Resized) { 105 | view.resize(event.size.width, event.size.height); 106 | } 107 | } 108 | 109 | view.eventLoop(); 110 | view.display(); 111 | 112 | 113 | wc.window.display(); 114 | 115 | 116 | state.frameCounter++; 117 | } 118 | } 119 | catch (std::exception e) { 120 | std::cout << std::endl; 121 | std::cout << "Uncaught Runtime Exception:" << std::endl; 122 | std::cout << e.what() << std::endl << std::endl; 123 | std::cout << "Press any key to continue..." << std::flush; 124 | 125 | std::cin.ignore( std::numeric_limits ::max(), '\n' ); 126 | exit(1); 127 | } 128 | 129 | return 0; 130 | } 131 | -------------------------------------------------------------------------------- /src/renderer/Bound.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef GFX_BOUND_H_ 27 | #define GFX_BOUND_H_ 28 | 29 | #include 30 | #include 31 | 32 | #include "../vecmath/Vecmath.h" 33 | #include "Storage.h" 34 | 35 | namespace gfx { 36 | 37 | class Bound { 38 | protected: 39 | 40 | vmath::Vector3f _center; 41 | vmath::Vector3f _extants; 42 | bool _singular; 43 | 44 | public: 45 | 46 | Bound () 47 | : _center(0.f), _extants(0.f), _singular(true) { 48 | } 49 | 50 | virtual ~Bound () { } 51 | 52 | void addPoints (const std::vector& verts) { 53 | if (verts.size() == 0) { 54 | return; 55 | } 56 | 57 | vmath::Vector3f min(FLT_MAX); 58 | vmath::Vector3f max(FLT_MIN); 59 | 60 | if (!_singular) { 61 | min = _center - _extants; 62 | max = _center + _extants; 63 | } 64 | 65 | for (unsigned i = 0; i < verts.size(); i++) { 66 | if (verts[i].x < min.x) min.x = verts[i].x; 67 | else if (verts[i].x > max.x) max.x = verts[i].x; 68 | 69 | if (verts[i].y < min.y) min.y = verts[i].y; 70 | else if (verts[i].y > max.y) max.y = verts[i].y; 71 | 72 | if (verts[i].z < min.z) min.z = verts[i].z; 73 | else if (verts[i].z > max.z) max.z = verts[i].z; 74 | } 75 | 76 | recalcBound(min, max); 77 | } 78 | 79 | void addPoints (const std::vector& verts) { 80 | if (verts.size() == 0) { 81 | return; 82 | } 83 | 84 | vmath::Vector3f min(FLT_MAX); 85 | vmath::Vector3f max(FLT_MIN); 86 | 87 | if (!_singular) { 88 | min = _center - _extants; 89 | max = _center + _extants; 90 | } 91 | 92 | for (unsigned i = 0; i < verts.size(); i++) { 93 | if (verts[i].x < min.x) min.x = verts[i].x; 94 | else if (verts[i].x > max.x) max.x = verts[i].x; 95 | 96 | if (verts[i].y < min.y) min.y = verts[i].y; 97 | else if (verts[i].y > max.y) max.y = verts[i].y; 98 | 99 | if (verts[i].z < min.z) min.z = verts[i].z; 100 | else if (verts[i].z > max.z) max.z = verts[i].z; 101 | } 102 | 103 | recalcBound(min, max); 104 | } 105 | 106 | const vmath::Vector3f& center () const { 107 | return _center; 108 | } 109 | 110 | void center (const vmath::Vector3f& vec) { 111 | _center = vec; 112 | } 113 | 114 | const vmath::Vector3f& extants () const { 115 | return _extants; 116 | } 117 | 118 | void extants (const vmath::Vector3f& vec) { 119 | _extants = vec; 120 | } 121 | 122 | void reset () { 123 | _center.set(0.f); 124 | _extants.set(0.f); 125 | _singular = true; 126 | } 127 | 128 | virtual void transform (const vmath::Matrix4f& mat) = 0; 129 | 130 | protected: 131 | 132 | virtual void recalcBound (const vmath::Vector3f& min, const vmath::Vector3f& max) = 0; 133 | }; 134 | 135 | } 136 | 137 | #endif /* GFX_BOUND_H_ */ 138 | -------------------------------------------------------------------------------- /src/renderer/BoundAABB.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef GFX_BOUNDAABB_H_ 27 | #define GFX_BOUNDAABB_H_ 28 | 29 | #include "Bound.h" 30 | 31 | namespace gfx { 32 | 33 | class BoundAABB : public Bound { 34 | public: 35 | 36 | BoundAABB () 37 | : Bound() { 38 | } 39 | 40 | virtual ~BoundAABB () { } 41 | 42 | void transform (const vmath::Matrix4f& mat) { 43 | vmath::Vector3f min = _center - _extants; 44 | vmath::Vector3f max = _center + _extants; 45 | 46 | vmath::Vector3f newMin(mat.getElement(12), mat.getElement(13), mat.getElement(14)); 47 | vmath::Vector3f newMax(newMin); 48 | 49 | for (int i = 0; i < 3; i++) { 50 | for (int j = 0; j < 3; j++) { 51 | float av = mat(i, j) * min(j); 52 | float bv = mat(i, j) * max(j); 53 | 54 | if (av < bv) { 55 | newMin(i) += av; 56 | newMax(i) += bv; 57 | } 58 | else { 59 | newMin(i) += bv; 60 | newMax(i) += av; 61 | } 62 | } 63 | } 64 | 65 | recalcBound(newMin, newMax); 66 | } 67 | 68 | protected: 69 | 70 | void recalcBound (const vmath::Vector3f& min, const vmath::Vector3f& max) { 71 | _center = (min + max) / 2.f; 72 | _extants = max - _center; 73 | _singular = false; 74 | } 75 | 76 | }; 77 | 78 | } 79 | 80 | 81 | #endif /* GFX_BOUNDAABB_H_ */ 82 | -------------------------------------------------------------------------------- /src/renderer/Camera.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef GFX_CAMERA_H_ 27 | #define GFX_CAMERA_H_ 28 | 29 | #include 30 | 31 | #include "../vecmath/Vecmath.h" 32 | #include "../vecmath/MatrixG3.h" 33 | #include "../vecmath/MatrixG4.h" 34 | 35 | namespace gfx { 36 | 37 | class Camera { 38 | protected: 39 | 40 | vmath::Vector3f eyePoint; 41 | vmath::Vector3f focusPoint; 42 | vmath::Vector3f focusAnchor; 43 | vmath::Vector3f up; 44 | 45 | vmath::Vector3f worldTranslate; 46 | vmath::Vector3f worldRotate; 47 | 48 | vmath::MatrixG4f cameraTransform; 49 | 50 | public: 51 | 52 | Camera () 53 | : eyePoint(0.f, 0.f, 1.f), 54 | focusPoint(0.f, 0.f, 0.f), 55 | focusAnchor(0.f, 0.f, 0.f), 56 | up(0.f, 1.f, 0.f), 57 | worldTranslate(0.f, 0.f, 0.f), 58 | worldRotate(0.f, 0.f, 0.f) { 59 | } 60 | 61 | const vmath::Vector3f& getEye () const { 62 | return eyePoint; 63 | } 64 | 65 | const vmath::Vector3f& getFocus () const { 66 | return focusPoint; 67 | } 68 | 69 | const vmath::Vector3f& getAnchor () const { 70 | return focusAnchor; 71 | } 72 | 73 | const vmath::Vector3f& getUp () const { 74 | return up; 75 | } 76 | 77 | const vmath::MatrixG4f& getCameraTransform () const { 78 | return cameraTransform; 79 | } 80 | 81 | void setEye (const vmath::Vector3f& v) { 82 | eyePoint.set(v); 83 | } 84 | 85 | void setEye (float x, float y, float z) { 86 | eyePoint.set(x, y, z); 87 | } 88 | 89 | void setFocus (const vmath::Vector3f& v) { 90 | focusPoint.set(v); 91 | } 92 | 93 | void setFocus (float x, float y, float z) { 94 | focusPoint.set(x, y, z); 95 | } 96 | 97 | void setAnchor (const vmath::Vector3f& v) { 98 | focusAnchor.set(v); 99 | } 100 | 101 | void setAnchor (float x, float y, float z) { 102 | focusAnchor.set(x, y, z); 103 | } 104 | 105 | void setUp (const vmath::Vector3f& v) { 106 | up.set(v); 107 | } 108 | 109 | void setUp (float x, float y, float z) { 110 | up.set(x, y, z); 111 | } 112 | 113 | /** 114 | * Move the eye point by differential coordinates relative to itself 115 | */ 116 | 117 | void moveEye (const vmath::Vector3f& v) { 118 | eyePoint += v; 119 | } 120 | 121 | void moveEye (float x, float y, float z) { 122 | eyePoint.x += x; 123 | eyePoint.y += y; 124 | eyePoint.z += z; 125 | } 126 | 127 | /** 128 | * Move the eye point in a straight line towards to focus point 129 | */ 130 | 131 | void moveEye (float dist) { 132 | vmath::Vector3f rayDir = focusPoint - eyePoint; 133 | rayDir.normalize(); 134 | rayDir.scale(dist); 135 | 136 | eyePoint += rayDir; 137 | 138 | if (eyePoint == focusPoint) { 139 | eyePoint -= rayDir; 140 | } 141 | } 142 | 143 | /** 144 | * Move the focus point by differential coordinates relative to itself 145 | */ 146 | 147 | void moveFocus (const vmath::Vector3f& v) { 148 | focusPoint += v; 149 | } 150 | 151 | void moveFocus (float x, float y, float z) { 152 | focusPoint.x += x; 153 | focusPoint.y += y; 154 | focusPoint.z += z; 155 | } 156 | 157 | /** 158 | * Move the focus anchor point by differential coordinates relative to itself 159 | */ 160 | 161 | void moveAnchor (const vmath::Vector3f& v) { 162 | focusAnchor += v; 163 | } 164 | 165 | void moveAnchor (float x, float y, float z) { 166 | focusAnchor.x += x; 167 | focusAnchor.y += y; 168 | focusAnchor.z += z; 169 | } 170 | 171 | /** 172 | * Move the eye and focus points together on the eye-focus line 173 | */ 174 | 175 | void moveEyeAndFocus (float dist) { 176 | vmath::Vector3f rayDir = focusPoint - eyePoint; 177 | rayDir.normalize(); 178 | rayDir.scale(dist); 179 | 180 | eyePoint += rayDir; 181 | focusPoint += rayDir; 182 | } 183 | 184 | /** 185 | * Rotate the eye point around the focus point by a differential azimuth and elevation 186 | */ 187 | 188 | void moveEyeRelativeFocus (float azimuth, float elevation) { 189 | vmath::Vector3f rot = eyePoint - focusPoint; 190 | 191 | vmath::MatrixG3f mat = vmath::Matrix3f::IDENTITY; 192 | mat.rotateY(azimuth); 193 | 194 | vmath::Vector3f axis = orthoAxisY(focusPoint, eyePoint); 195 | mat.rotate(elevation, axis.x, axis.y, axis.z); 196 | 197 | mat.transform(rot); 198 | rot += focusPoint; 199 | eyePoint = rot; 200 | } 201 | 202 | /** 203 | * Rotate the focus point around the eye point by a differential azimuth and elevation 204 | */ 205 | 206 | void moveFocusRelativeEye (float azimuth, float elevation) { 207 | vmath::Vector3f rot = focusPoint - eyePoint; 208 | 209 | vmath::MatrixG3f mat = vmath::Matrix3f::IDENTITY; 210 | mat.rotateY(azimuth); 211 | 212 | vmath::Vector3f axis = orthoAxisY(eyePoint, focusPoint); 213 | mat.rotate(elevation, axis.x, axis.y, axis.z); 214 | 215 | mat.transform(rot); 216 | rot += eyePoint; 217 | focusPoint = rot; 218 | } 219 | 220 | /** 221 | * Rotate the focus point around the eye point by an azimuth and elevation relative 222 | * to a set anchor point 223 | */ 224 | 225 | void moveFocusRelativeAnchor (float azimuth, float elevation) { 226 | vmath::Vector3f rot = focusAnchor - eyePoint; 227 | 228 | vmath::MatrixG3f mat = vmath::Matrix3f::IDENTITY; 229 | vmath::Vector3f axis = orthoAxisY(eyePoint, focusAnchor); 230 | mat.rotate(elevation, axis.x, axis.y, axis.z); 231 | 232 | mat.rotateY(azimuth); 233 | 234 | mat.transform(rot); 235 | rot += eyePoint; 236 | focusPoint = rot; 237 | } 238 | 239 | void rotateWorld (const vmath::Vector3f& v) { 240 | worldRotate += v; 241 | } 242 | 243 | void rotateWorld (float x, float y, float z) { 244 | worldRotate.x += x; 245 | worldRotate.y += y; 246 | worldRotate.z += z; 247 | } 248 | 249 | void translateWorld (const vmath::Vector3f& v) { 250 | worldTranslate += v; 251 | } 252 | 253 | void translateWorld (float x, float y, float z) { 254 | worldTranslate.x += x; 255 | worldTranslate.y += y; 256 | worldTranslate.z += z; 257 | } 258 | 259 | void viewTransform () { 260 | 261 | cameraTransform = viewLookAt(); 262 | 263 | if (worldTranslate != 0) { 264 | cameraTransform.translate(worldTranslate.x, worldTranslate.y, worldTranslate.z); 265 | } 266 | 267 | if (worldRotate.x) cameraTransform.rotateX(worldRotate.x); 268 | if (worldRotate.y) cameraTransform.rotateY(worldRotate.y); 269 | if (worldRotate.z) cameraTransform.rotateZ(worldRotate.z); 270 | 271 | vmath::Matrix4f cameraTranspose = cameraTransform; 272 | cameraTranspose.transpose(); 273 | 274 | glMultMatrixf(cameraTranspose.asArray()); 275 | } 276 | 277 | protected: 278 | 279 | vmath::Matrix4f viewLookAt () const { 280 | vmath::Vector3f f = focusPoint - eyePoint; 281 | f.normalize(); 282 | 283 | vmath::Vector3f UP = up; 284 | UP.normalize(); 285 | 286 | vmath::Vector3f s = f.cross(UP); 287 | vmath::Vector3f u = s.cross(f); 288 | 289 | vmath::MatrixG4f ctrans(s.x, s.y, s.z, 0, 290 | u.x, u.y, u.z, 0, 291 | -f.x, -f.y, -f.z, 0, 292 | 0, 0, 0, 1); 293 | 294 | ctrans.translate(-eyePoint.x, -eyePoint.y, -eyePoint.z); 295 | 296 | return ctrans; 297 | } 298 | 299 | static vmath::Vector3f orthoAxisY (const vmath::Vector3f& p0, const vmath::Vector3f& p1) { 300 | vmath::Vector3f v0 = p1 - p0; 301 | vmath::Vector3f v1 = p1; 302 | v1.y += 5.f; 303 | v1 -= p0; 304 | 305 | vmath::Vector3f v2 = v0.cross(v1); 306 | v2.normalize(); 307 | return v2; 308 | } 309 | 310 | }; 311 | 312 | } 313 | 314 | #endif /* GFX_CAMERA_H_ */ 315 | -------------------------------------------------------------------------------- /src/renderer/CameraController.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef GFX_CAMERACONTROLLER_H_ 27 | #define GFX_CAMERACONTROLLER_H_ 28 | 29 | #include "Camera.h" 30 | 31 | namespace gfx { 32 | 33 | class CameraController { 34 | public: 35 | 36 | static CameraController& getController () { 37 | static CameraController cc; 38 | return cc; 39 | } 40 | 41 | Camera* camera; 42 | 43 | protected: 44 | 45 | CameraController () { } 46 | 47 | CameraController (const CameraController&) { } 48 | 49 | CameraController& operator= (const CameraController&) { 50 | return *this; 51 | } 52 | 53 | }; 54 | 55 | } 56 | 57 | #endif /* GFX_CAMERACONTROLLER_H_ */ 58 | -------------------------------------------------------------------------------- /src/renderer/Geometry.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef GFX_GEOMETRY_H_ 27 | #define GFX_GEOMETRY_H_ 28 | 29 | #include "Scenegraph.h" 30 | #include "Mesh.h" 31 | #include "Texture.h" 32 | 33 | namespace gfx { 34 | 35 | /** 36 | * Geometry reflects an instance of geometric data; more than one Geometry node 37 | * may point to the same data set, but each object reflects a separate spacial 38 | * instance. 39 | */ 40 | 41 | class Geometry { 42 | public: 43 | 44 | Texture* texture; 45 | 46 | Scenegraph::Node* spacialNode; 47 | 48 | bool visible; 49 | bool alphaTest; 50 | bool blend; 51 | bool cull; 52 | 53 | float alphaThresh; 54 | unsigned blendSrc; 55 | unsigned blendDst; 56 | unsigned cullFunc; 57 | 58 | protected: 59 | 60 | Mesh* _mesh; 61 | BoundAABB _aabb; 62 | 63 | public: 64 | 65 | Geometry () 66 | : texture(NULL), spacialNode(NULL), visible(true), alphaTest(false), 67 | blend(false), cull(false), _mesh(NULL) { 68 | } 69 | 70 | Geometry (Mesh* meshPtr) 71 | : texture(NULL), spacialNode(NULL), visible(true), alphaTest(false), 72 | blend(false), cull(false), _mesh(meshPtr) { 73 | } 74 | 75 | Geometry (Mesh* meshPtr, Texture* texPtr) 76 | : texture(texPtr), spacialNode(NULL), visible(true), alphaTest(false), 77 | blend(false), cull(false), _mesh(meshPtr) { 78 | } 79 | 80 | const BoundAABB& getAABB () const { 81 | return _aabb; 82 | } 83 | 84 | bool hasMesh () const { 85 | return _mesh != NULL; 86 | } 87 | 88 | bool hasSpacialNode () const { 89 | return spacialNode != NULL; 90 | } 91 | 92 | bool hasTexture () const { 93 | return texture != NULL; 94 | } 95 | 96 | Mesh* mesh () { 97 | return _mesh; 98 | } 99 | 100 | const Mesh* mesh () const { 101 | return _mesh; 102 | } 103 | 104 | void mesh (Mesh* meshPtr) { 105 | _mesh = meshPtr; 106 | 107 | _aabb.reset(); 108 | _aabb.addPoints(_mesh->getVertexList()); 109 | } 110 | 111 | }; 112 | 113 | } 114 | 115 | #endif /* GFX_GEOMETRY_H_ */ 116 | -------------------------------------------------------------------------------- /src/renderer/Mesh.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef GFX_MESH_H_ 27 | #define GFX_MESH_H_ 28 | 29 | #include 30 | #include 31 | 32 | #include "../vecmath/Vecmath.h" 33 | #include "Storage.h" 34 | 35 | namespace gfx { 36 | 37 | class Mesh { 38 | protected: 39 | 40 | std::vector vertexList; 41 | std::vector normalList; 42 | std::vector colorList; 43 | std::vector texCoordList; 44 | unsigned int vertexCount; 45 | 46 | std::vector indexList; 47 | unsigned int indexCount; 48 | 49 | unsigned int vtxBitmask; 50 | 51 | public: 52 | 53 | enum { 54 | VTX_VERTEX = 1, 55 | VTX_NORMAL = 2, 56 | VTX_COLOR = 4, 57 | VTX_TEXCOORD = 8, 58 | }; 59 | 60 | Mesh () 61 | : vertexList(0), normalList(0), colorList(0), texCoordList(0), vertexCount(0), 62 | indexList(0), indexCount(0), vtxBitmask(0xFFFF) { 63 | } 64 | 65 | Mesh (unsigned int bitmask) 66 | : vertexList(0), normalList(0), colorList(0), texCoordList(0), vertexCount(0), 67 | indexList(0), indexCount(0), vtxBitmask(bitmask) { 68 | } 69 | 70 | void addIndex (unsigned int idx) { 71 | if (idx >= vertexCount) { 72 | throw std::out_of_range("Vertex ID out of range."); 73 | } 74 | 75 | indexList.push_back(idx); 76 | indexCount++; 77 | } 78 | 79 | void addVertex (const vertexDef& vdef) { 80 | if (vtxBitmask & VTX_VERTEX) { 81 | vertexList.push_back(vdef.vertex); 82 | } 83 | if (vtxBitmask & VTX_NORMAL) { 84 | normalList.push_back(vdef.normal); 85 | } 86 | if (vtxBitmask & VTX_COLOR) { 87 | colorList.push_back(vdef.color); 88 | } 89 | if (vtxBitmask & VTX_TEXCOORD) { 90 | texCoordList.push_back(vdef.texCoord); 91 | } 92 | 93 | vertexCount++; 94 | } 95 | 96 | void clear () { 97 | vertexList.clear(); 98 | normalList.clear(); 99 | colorList.clear(); 100 | texCoordList.clear(); 101 | indexList.clear(); 102 | } 103 | 104 | const std::vector& getColorList () const { 105 | return colorList; 106 | } 107 | 108 | unsigned int getIndexCount () const { 109 | return indexCount; 110 | } 111 | 112 | const std::vector& getIndexList () const { 113 | return indexList; 114 | } 115 | 116 | const std::vector& getNormalList () const { 117 | return normalList; 118 | } 119 | 120 | const std::vector& getTexCoordList () const { 121 | return texCoordList; 122 | } 123 | 124 | unsigned int getVertexCount () const { 125 | return vertexCount; 126 | } 127 | 128 | const std::vector& getVertexList () const { 129 | return vertexList; 130 | } 131 | 132 | bool useColors () const { 133 | return (vtxBitmask & VTX_COLOR); 134 | } 135 | 136 | void useColors (bool state) { 137 | if (state != (vtxBitmask & VTX_COLOR)) { 138 | clear(); 139 | } 140 | setState(VTX_COLOR, state); 141 | } 142 | 143 | bool useNormals () const { 144 | return (vtxBitmask & VTX_NORMAL); 145 | } 146 | 147 | void useNormals (bool state) { 148 | if (state != (vtxBitmask & VTX_NORMAL)) { 149 | clear(); 150 | } 151 | setState(VTX_NORMAL, state); 152 | } 153 | 154 | bool useTexCoords () const { 155 | return (vtxBitmask & VTX_TEXCOORD); 156 | } 157 | 158 | void useTexCoords (bool state) { 159 | if (state != (vtxBitmask & VTX_TEXCOORD)) { 160 | clear(); 161 | } 162 | setState(VTX_TEXCOORD, state); 163 | } 164 | 165 | bool useVertices () const { 166 | return (vtxBitmask & VTX_VERTEX); 167 | } 168 | 169 | void useVertices (bool state) { 170 | if (state != (vtxBitmask & VTX_VERTEX)) { 171 | clear(); 172 | } 173 | setState(VTX_VERTEX, state); 174 | } 175 | 176 | protected: 177 | 178 | void disableState (unsigned int mask) { 179 | vtxBitmask &= (0xFFFFFFFF ^ mask); 180 | } 181 | 182 | void enableState (unsigned int mask) { 183 | vtxBitmask |= mask; 184 | } 185 | 186 | void setState (unsigned int mask, bool state) { 187 | if (state) { 188 | enableState(mask); 189 | } 190 | else { 191 | disableState(mask); 192 | } 193 | } 194 | 195 | }; 196 | 197 | 198 | class TriMesh : public Mesh { 199 | public: 200 | 201 | TriMesh () 202 | : Mesh() { 203 | } 204 | 205 | TriMesh (unsigned int bitmask) 206 | : Mesh(bitmask) { 207 | } 208 | 209 | void addIndexPolygon (const std::vector& points) { 210 | if (points.size() <= 3) { 211 | for (unsigned int i = 0; i < points.size(); i++) { 212 | addIndex(points[i]); 213 | } 214 | return; 215 | } 216 | 217 | // If we're dealing with quads or higher, split them 218 | 219 | unsigned int p0 = points[0]; 220 | for (unsigned int i = 2; i < points.size(); i++) { 221 | addIndex(p0); 222 | addIndex(points[i - 1]); 223 | addIndex(points[i]); 224 | } 225 | } 226 | 227 | void addIndexTriangle (unsigned int i0, unsigned int i1, unsigned int i2) { 228 | addIndex(i0); 229 | addIndex(i1); 230 | addIndex(i2); 231 | } 232 | 233 | }; 234 | 235 | } 236 | 237 | #endif /* GFX_MESH_H_ */ 238 | -------------------------------------------------------------------------------- /src/renderer/RenderGL.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef GFX_RENDERGL_H_ 27 | #define GFX_RENDERGL_H_ 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include "../vecmath/Vecmath.h" 34 | #include "../vecmath/MatrixG4.h" 35 | #include "Mesh.h" 36 | #include "Texture.h" 37 | #include "CameraController.h" 38 | #include "../AppState.h" 39 | 40 | namespace gfx { 41 | 42 | /** 43 | * Sorting function for rendering transparent meshes back-to-font. 44 | * Right now this is a hack and very inefficient. Sorting by mesh 45 | * is also not sufficient sometimes. 46 | */ 47 | 48 | bool blendSort (const Geometry* a, const Geometry* b) { 49 | CameraController& cc = CameraController::getController(); 50 | 51 | vmath::Vector3f transEye = cc.camera->getEye(); 52 | //cc.camera->getCameraTransform().transform(transEye); 53 | 54 | vmath::Vector3f transA = a->getAABB().center(); 55 | vmath::Vector3f transB = b->getAABB().center(); 56 | cc.camera->getCameraTransform().transform(transA); 57 | cc.camera->getCameraTransform().transform(transB); 58 | 59 | vmath::Vector3f dista = transA - transEye; 60 | vmath::Vector3f distb = transB - transEye; 61 | 62 | return dista.length() > distb.length(); 63 | } 64 | 65 | /** 66 | * Main rendering class. This class owns most of its resources, so 67 | * the client need not worry about cleaning up returned pointers. 68 | */ 69 | 70 | class RenderGL { 71 | protected: 72 | 73 | std::list meshList; 74 | std::vector textures; 75 | 76 | std::vector geoList; 77 | 78 | Camera* _camera; 79 | 80 | public: 81 | 82 | Geometry* addGeometry (const Geometry& geo) { 83 | geoList.push_back(geo); 84 | return &geoList.back(); 85 | } 86 | 87 | Mesh* addMesh (const Mesh& mesh) { 88 | meshList.push_back(mesh); 89 | return &meshList.back(); 90 | } 91 | 92 | Texture* addTexture (const Texture& tex) { 93 | textures.push_back(tex); 94 | return &textures.back(); 95 | } 96 | 97 | void camera (Camera* cam) { 98 | _camera = cam; 99 | } 100 | 101 | /** 102 | * Draw all geometry added to the renderer. First solid objects are 103 | * drawn, then any transparent meshes are sorted and drawn. 104 | */ 105 | 106 | void drawGeometry () { 107 | AppState& state = AppState::getState(); 108 | std::vector blended; 109 | 110 | for (unsigned i = 0; i < geoList.size(); i++) { 111 | const Geometry* citer = &geoList[i]; 112 | if (state.vars.selectState == AppState::Vars::SELECT_SGNODE && state.vars.selectIndex != -1) { 113 | if (state.vars.selectIndex != (int)i) { 114 | continue; 115 | } 116 | } 117 | 118 | if (!citer->visible) { 119 | continue; 120 | } 121 | 122 | if (citer->blend) { 123 | blended.push_back(&*citer); 124 | continue; 125 | } 126 | 127 | drawGeometry(&*citer); 128 | } 129 | 130 | CameraController& cc = CameraController::getController(); 131 | cc.camera = _camera; 132 | 133 | sort(blended.begin(), blended.end(), blendSort); 134 | 135 | std::vector::const_iterator cpiter; 136 | for (cpiter = blended.begin(); cpiter != blended.end(); cpiter++) { 137 | const Geometry* geoPtr = *cpiter; 138 | drawGeometry(geoPtr); 139 | } 140 | } 141 | 142 | void drawGeometry (const Geometry* geo) { 143 | const vmath::MatrixG4f& worldMat = geo->spacialNode->getWorldMatrix(); 144 | 145 | glPushMatrix(); 146 | glPushAttrib(GL_ENABLE_BIT); 147 | 148 | glMultMatrixf(worldMat.asArray()); 149 | 150 | if (geo->hasTexture()) { 151 | geo->texture->enable(); 152 | geo->texture->bind(); 153 | } 154 | 155 | if (geo->alphaTest) { 156 | glEnable(GL_ALPHA_TEST); 157 | glAlphaFunc(GL_GEQUAL, geo->alphaThresh); 158 | } 159 | if (geo->blend) { 160 | glEnable(GL_BLEND); 161 | glBlendFunc(geo->blendSrc, geo->blendDst); 162 | } 163 | if (geo->cull) { 164 | glEnable(GL_CULL_FACE); 165 | glCullFace(geo->cullFunc); 166 | } 167 | 168 | drawMesh(geo->mesh(), GL_TRIANGLES); 169 | 170 | glPopAttrib(); 171 | glPopMatrix(); 172 | } 173 | 174 | void drawMesh (const Mesh* mesh, GLuint renderType) { 175 | drawMeshImmediate(mesh, renderType); 176 | } 177 | 178 | void drawMeshImmediate (const Mesh* mesh, GLuint renderType) { 179 | const std::vector& vertexList = mesh->getVertexList(); 180 | const std::vector& normalList = mesh->getNormalList(); 181 | const std::vector& colorList = mesh->getColorList(); 182 | const std::vector& texCoordList = mesh->getTexCoordList(); 183 | const std::vector& indexList = mesh->getIndexList(); 184 | 185 | typedef std::vector::const_iterator uintCIter; 186 | 187 | glBegin(renderType); 188 | 189 | for (uintCIter iter = indexList.begin(); iter < indexList.end(); iter++) { 190 | if (mesh->useColors()) { 191 | const color4ub& color = colorList[*iter]; 192 | glColor4ub(color.r, color.g, color.b, color.a); 193 | } 194 | 195 | if (mesh->useNormals()) { 196 | const normal3f& normal = normalList[*iter]; 197 | glNormal3f(normal.nx, normal.ny, normal.nz); 198 | } 199 | 200 | if (mesh->useTexCoords()) { 201 | const texCoord2f& texCoord = texCoordList[*iter]; 202 | glTexCoord2f(texCoord.s, texCoord.t); 203 | } 204 | 205 | if (mesh->useVertices()) { 206 | const vertex3f& vertex = vertexList[*iter]; 207 | glVertex3f(vertex.x, vertex.y, vertex.z); 208 | } 209 | } 210 | 211 | glEnd(); 212 | } 213 | 214 | const std::vector& getGeometry () const { 215 | return geoList; 216 | } 217 | 218 | Texture* getTexture (unsigned id) { 219 | return &textures.at(id); 220 | } 221 | 222 | unsigned getTextureCount () const { 223 | return textures.size(); 224 | } 225 | }; 226 | 227 | 228 | 229 | } 230 | 231 | #endif /* GFX_RENDERGL_H_ */ 232 | -------------------------------------------------------------------------------- /src/renderer/Scenegraph.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef GFX_SCENEGRAPH_H_ 27 | #define GFX_SCENEGRAPH_H_ 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include "../vecmath/MatrixG4.h" 34 | #include "BoundAABB.h" 35 | 36 | namespace gfx { 37 | 38 | class Geometry; 39 | 40 | /** 41 | * The Scene Graph represents the logical, and by extension, spacial relationship 42 | * of objects in the scene. 43 | * 44 | * Each node caries local transformation data relative to the world position of 45 | * its parent. The world transformation is precomputed for each object to allow 46 | * for independent draw order. 47 | */ 48 | 49 | class Scenegraph { 50 | public: 51 | 52 | class Node { 53 | public: 54 | 55 | enum TransformType { 56 | TRANSFORM_TRANSLATE, 57 | TRANSFORM_SCALE, 58 | TRANSFORM_ROTATE_XYZ, 59 | TRANSFORM_ROTATE_ZYX, 60 | }; 61 | 62 | typedef std::pair Transform; 63 | 64 | protected: 65 | 66 | typedef std::list::iterator NodeIter; 67 | 68 | friend class Scenegraph; 69 | 70 | protected: 71 | 72 | Node* parent; 73 | std::list children; 74 | 75 | std::vector geoNodes; 76 | 77 | vmath::MatrixG4f worldMatrix; 78 | bool dirtyMatrix; 79 | bool visible; 80 | 81 | std::vector transformSet; 82 | 83 | public: 84 | 85 | Node () 86 | : parent(NULL), children(0), geoNodes(0), worldMatrix(vmath::Matrix4f::IDENTITY), 87 | dirtyMatrix(true), visible(true), transformSet(0) { 88 | } 89 | 90 | void addGeometry (Geometry* geo) { 91 | geoNodes.push_back(geo); 92 | } 93 | 94 | unsigned addTransform (TransformType type, const vmath::Vector3f& v) { 95 | transformSet.push_back(std::make_pair(type, v)); 96 | dirtyMatrix = true; 97 | return transformSet.size() - 1; 98 | } 99 | 100 | const std::list& getChildren () const { 101 | return children; 102 | } 103 | 104 | Node* getParent () const { 105 | return parent; 106 | } 107 | 108 | const vmath::Vector3f& getTransform (unsigned index) const { 109 | return transformSet.at(index).second; 110 | } 111 | 112 | TransformType getTransformType (unsigned index) const { 113 | return transformSet.at(index).first; 114 | } 115 | 116 | const vmath::MatrixG4f& getWorldMatrix () const { 117 | return worldMatrix; 118 | } 119 | 120 | bool hasChildren () const { 121 | return children.size() > 0; 122 | } 123 | 124 | bool hasParent () const { 125 | return parent != NULL; 126 | } 127 | 128 | void setTransform (unsigned index, const vmath::Vector3f& v) { 129 | transformSet.at(index).second = v; 130 | dirtyMatrix = true; 131 | } 132 | 133 | void setVisibility (bool vis) { 134 | visible = vis; 135 | } 136 | 137 | void updateTransform (unsigned index, const vmath::Vector3f& v) { 138 | transformSet.at(index).second += v; 139 | dirtyMatrix = true; 140 | } 141 | 142 | protected: 143 | 144 | void checkWorldMatrix () { 145 | if (parent == NULL && dirtyMatrix) { 146 | worldMatrix.setIdentity(); 147 | updateWorldMatrix(); 148 | return; 149 | } 150 | 151 | for (NodeIter iter = children.begin(); iter != children.end(); iter++) { 152 | Node* child = *iter; 153 | if (child->dirtyMatrix) { 154 | child->updateWorldMatrix(worldMatrix); 155 | } 156 | else { 157 | child->checkWorldMatrix(); 158 | } 159 | } 160 | } 161 | 162 | void updateWorldMatrix (const vmath::MatrixG4f& parentWorld) { 163 | worldMatrix.set(parentWorld); 164 | updateWorldMatrix(); 165 | } 166 | 167 | void updateWorldMatrix () { 168 | 169 | // Recalculate world matrix 170 | for (unsigned i = 0; i < transformSet.size(); i++) { 171 | const vmath::Vector3f& v = transformSet[i].second; 172 | 173 | switch (transformSet[i].first) { 174 | case TRANSFORM_TRANSLATE: 175 | worldMatrix.translate(v.x, v.y, v.z); 176 | break; 177 | case TRANSFORM_SCALE: 178 | worldMatrix.scale(v.x, v.y, v.z); 179 | break; 180 | case TRANSFORM_ROTATE_XYZ: 181 | worldMatrix.rotateX(v.x); 182 | worldMatrix.rotateY(v.y); 183 | worldMatrix.rotateZ(v.z); 184 | break; 185 | case TRANSFORM_ROTATE_ZYX: 186 | worldMatrix.rotateZ(v.z); 187 | worldMatrix.rotateY(v.y); 188 | worldMatrix.rotateX(v.x); 189 | break; 190 | } 191 | } 192 | 193 | for (NodeIter iter = children.begin(); iter != children.end(); iter++) { 194 | Node* child = *iter; 195 | child->updateWorldMatrix(worldMatrix); 196 | } 197 | 198 | worldMatrix.transpose(); 199 | 200 | dirtyMatrix = false; 201 | } 202 | }; 203 | 204 | protected: 205 | 206 | Node* rootNode; 207 | 208 | std::list nodeSet; 209 | 210 | public: 211 | 212 | Scenegraph () { 213 | nodeSet.push_back(Node()); 214 | rootNode = &nodeSet.front(); 215 | } 216 | 217 | virtual ~Scenegraph () { } 218 | 219 | Node* newChild (Node* parent) { 220 | nodeSet.push_back(Node()); 221 | Node* node = &nodeSet.back(); 222 | 223 | node->parent = parent; 224 | parent->children.push_back(node); 225 | 226 | return node; 227 | } 228 | 229 | Node* root () const { 230 | return rootNode; 231 | } 232 | 233 | void update () { 234 | rootNode->checkWorldMatrix(); 235 | } 236 | 237 | }; 238 | 239 | } 240 | 241 | #include "Geometry.h" 242 | 243 | #endif /* GFX_SCENEGRAPH_H_ */ 244 | -------------------------------------------------------------------------------- /src/renderer/Storage.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef GFX_STORAGE_H_ 27 | #define GFX_STORAGE_H_ 28 | 29 | namespace gfx { 30 | 31 | struct vertex3f { 32 | float x; 33 | float y; 34 | float z; 35 | 36 | vertex3f () { } 37 | 38 | vertex3f (float a, float b, float c) 39 | : x(a), y(b), z(c) { 40 | } 41 | }; 42 | 43 | struct normal3f { 44 | float nx; 45 | float ny; 46 | float nz; 47 | 48 | normal3f () { } 49 | 50 | normal3f (float a, float b, float c) 51 | : nx(a), ny(b), nz(c) { 52 | } 53 | }; 54 | 55 | struct color4ub { 56 | unsigned char r; 57 | unsigned char g; 58 | unsigned char b; 59 | unsigned char a; 60 | 61 | color4ub () { } 62 | 63 | color4ub (unsigned char cr, unsigned char cg, unsigned char cb, unsigned char ca) 64 | : r(cr), g(cg), b(cb), a(ca) { 65 | } 66 | }; 67 | 68 | struct texCoord2f { 69 | float s; 70 | float t; 71 | 72 | texCoord2f () 73 | : s(0), t(0) { 74 | } 75 | 76 | texCoord2f (float ts, float tt) 77 | : s(ts), t(tt) { 78 | } 79 | }; 80 | 81 | struct vertexDef { 82 | vertex3f vertex; 83 | normal3f normal; 84 | color4ub color; 85 | texCoord2f texCoord; 86 | }; 87 | 88 | } 89 | 90 | #endif /* GFX_STORAGE_H_ */ 91 | -------------------------------------------------------------------------------- /src/renderer/Texture.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef GFX_TEXTURE_H_ 27 | #define GFX_TEXTURE_H_ 28 | 29 | #include 30 | 31 | #include "TextureData.h" 32 | 33 | namespace gfx { 34 | 35 | class Texture { 36 | protected: 37 | 38 | TextureData _texData; 39 | 40 | GLuint _texName; 41 | GLuint _target; 42 | GLuint _env_mode; 43 | 44 | static GLuint _global_env_mode; 45 | 46 | public: 47 | 48 | Texture (GLuint target, const TextureData& texdata) 49 | : _texData(texdata), _texName(0), _target(target), _env_mode(GL_MODULATE) { 50 | 51 | glGenTextures(1, &_texName); 52 | glBindTexture(target, _texName); 53 | 54 | glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT); 55 | glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT); 56 | glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 57 | glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 58 | 59 | glTexImage2D(target, _texData._mipmapLevel, _texData._internalFormat, 60 | _texData._width, _texData._height, _texData._border, 61 | _texData._pixelFormat, _texData._pixelType, &_texData._texels->_data[0]); 62 | } 63 | 64 | void bind () { 65 | glBindTexture(_target, _texName); 66 | 67 | if (_env_mode != _global_env_mode) { 68 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, _env_mode); 69 | _global_env_mode = _env_mode; 70 | } 71 | } 72 | 73 | void disable () { 74 | glDisable(_target); 75 | } 76 | 77 | void enable () { 78 | glEnable(_target); 79 | } 80 | 81 | GLuint getTarget () { 82 | return _target; 83 | } 84 | 85 | GLuint getTextureObject () { 86 | return _texName; 87 | } 88 | 89 | void setTexEnvMode (GLint value) { 90 | _env_mode = value; 91 | } 92 | 93 | void setTexParameterf (GLenum param, GLfloat value) { 94 | glTexParameterf(_target, param, value); 95 | } 96 | 97 | void setTexParameteri (GLenum param, GLint value) { 98 | glTexParameteri(_target, param, value); 99 | } 100 | 101 | void updateImage (const TextureData& texData) { 102 | _texData = texData; 103 | } 104 | 105 | }; 106 | 107 | GLuint Texture::_global_env_mode = GL_MODULATE; 108 | 109 | } 110 | 111 | #endif /* GFX_TEXTURE_H_ */ 112 | -------------------------------------------------------------------------------- /src/renderer/TextureData.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef GFX_TEXTUREDATA_H_ 27 | #define GFX_TEXTUREDATA_H_ 28 | 29 | #include 30 | 31 | #include "../Image.h" 32 | 33 | namespace gfx { 34 | 35 | class Texture; 36 | 37 | class TextureData { 38 | protected: 39 | 40 | friend class Texture; 41 | 42 | int _internalFormat; 43 | int _width; 44 | int _height; 45 | int _border; 46 | int _pixelFormat; 47 | int _pixelType; 48 | int _mipmapLevel; 49 | 50 | const Image* _texels; 51 | 52 | public: 53 | 54 | TextureData (int internalFormat, int width, int height, int border, int pixelFormat, int pixelType, int mipmap, const Image& texels) 55 | : _internalFormat(internalFormat), _width(width), _height(height), _border(border), 56 | _pixelFormat(pixelFormat), _pixelType(pixelType), _mipmapLevel(mipmap), _texels(&texels) { 57 | } 58 | 59 | TextureData (int internalFormat, int pixelFormat, int mipmap, const Image& texels) 60 | : _internalFormat(internalFormat), _width(texels.getWidth()), _height(texels.getHeight()), 61 | _border(0), _pixelFormat(pixelFormat), _pixelType(GL_UNSIGNED_BYTE), _mipmapLevel(mipmap), 62 | _texels(&texels) { 63 | } 64 | 65 | }; 66 | 67 | } 68 | 69 | #endif /* GFX_TEXTUREDATA_H_ */ 70 | -------------------------------------------------------------------------------- /src/system/Input.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef INPUT_H_JRAQ_ 27 | #define INPUT_H_JRAQ_ 28 | 29 | #include 30 | #include 31 | 32 | class Input { 33 | protected: 34 | 35 | std::vector _mouseHoldState; 36 | std::vector _mouseClickState; 37 | std::vector _keyHoldState; 38 | std::vector _keyClickState; 39 | 40 | int _mouseWheelState; 41 | int _mouseX; 42 | int _mouseY; 43 | int _mouseDragX; 44 | int _mouseDragY; 45 | 46 | public: 47 | 48 | Input () 49 | : _mouseHoldState(5), _mouseClickState(5), _keyHoldState(384), _keyClickState(384) { 50 | initState(); 51 | } 52 | 53 | virtual ~Input () { } 54 | 55 | void initState () { 56 | _mouseWheelState = 0; 57 | _mouseX = 0; 58 | _mouseY = 0; 59 | _mouseDragX = 0; 60 | _mouseDragY = 0; 61 | 62 | for (int i = 0; i < 384; i++) { 63 | _keyClickState[i] = false; 64 | _keyHoldState[i] = false; 65 | } 66 | for (int i = 0; i < 5; i++) { 67 | _mouseClickState[i] = false; 68 | _mouseHoldState[i] = false; 69 | } 70 | } 71 | 72 | void resetState () { 73 | for (int i = 0; i < 384; i++) { 74 | _keyClickState[i] = false; 75 | } 76 | for (int i = 0; i < 5; i++) { 77 | _mouseClickState[i] = false; 78 | } 79 | } 80 | 81 | void processEvent (sf::Event event) { 82 | switch (event.type) { 83 | case sf::Event::KeyPressed: 84 | keyPressedEvent(event); break; 85 | case sf::Event::KeyReleased: 86 | keyReleasedEvent(event); break; 87 | case sf::Event::MouseButtonPressed: 88 | mousePressedEvent(event); break; 89 | case sf::Event::MouseButtonReleased: 90 | mouseReleasedEvent(event); break; 91 | case sf::Event::MouseMoved: 92 | mouseMovedEvent(event); break; 93 | case sf::Event::MouseWheelMoved: 94 | mouseWheelMovedEvent(event); break; 95 | default: break; 96 | } 97 | } 98 | 99 | bool keyPressed (sf::Keyboard::Key key) const { 100 | return _keyClickState[key]; 101 | } 102 | 103 | bool keyHeld (sf::Keyboard::Key key) const { 104 | return _keyHoldState[key]; 105 | } 106 | 107 | bool mouseClicked (sf::Mouse::Button button) const { 108 | return _mouseClickState[button]; 109 | } 110 | 111 | bool mouseHeld (sf::Mouse::Button button) const { 112 | return _mouseHoldState[button]; 113 | } 114 | 115 | bool mouseWheelMoved () const { 116 | return (_mouseWheelState != 0); 117 | } 118 | 119 | int mouseWheelDistance () const { 120 | return _mouseWheelState; 121 | } 122 | 123 | int mouseX () const { 124 | return _mouseX; 125 | } 126 | 127 | int mouseY () const { 128 | return _mouseY; 129 | } 130 | 131 | bool mouseDragged () const; 132 | int mouseDraggedX () const; 133 | int mouseDraggedY () const; 134 | 135 | protected: 136 | 137 | void keyPressedEvent (sf::Event event) { 138 | _keyHoldState[event.key.code] = true; 139 | } 140 | 141 | void keyReleasedEvent (sf::Event event) { 142 | _keyHoldState[event.key.code] = false; 143 | _keyClickState[event.key.code] = true; 144 | } 145 | 146 | void mousePressedEvent (sf::Event event) { 147 | _mouseHoldState[event.mouseButton.button] = true; 148 | } 149 | 150 | void mouseReleasedEvent (sf::Event event) { 151 | _mouseHoldState[event.mouseButton.button] = false; 152 | _mouseClickState[event.mouseButton.button] = true; 153 | } 154 | 155 | void mouseMovedEvent (sf::Event event) { 156 | _mouseX = event.mouseMove.x; 157 | _mouseY = event.mouseMove.y; 158 | } 159 | 160 | void mouseWheelMovedEvent (sf::Event event) { 161 | _mouseWheelState = event.mouseWheel.delta; 162 | } 163 | }; 164 | 165 | #endif /* INPUT_H_JRAQ_*/ 166 | -------------------------------------------------------------------------------- /src/system/InputController.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef INPUTCONTROLLER_H_ 27 | #define INPUTCONTROLLER_H_ 28 | 29 | #include "Input.h" 30 | 31 | class InputController { 32 | public: 33 | 34 | static InputController& getController () { 35 | static InputController ic; 36 | return ic; 37 | } 38 | 39 | Input input; 40 | 41 | protected: 42 | 43 | InputController () { } 44 | 45 | InputController (const InputController&) { } 46 | 47 | InputController& operator= (const InputController&) { 48 | return *this; 49 | } 50 | 51 | }; 52 | 53 | #endif /* INPUTCONTROLLER_H_ */ 54 | -------------------------------------------------------------------------------- /src/system/MappedController.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef MAPPEDCONTROLLER_H_ 27 | #define MAPPEDCONTROLLER_H_ 28 | 29 | #include "MappedInput.h" 30 | 31 | class MappedInputController { 32 | public: 33 | 34 | static MappedInputController& getController () { 35 | static MappedInputController ic; 36 | return ic; 37 | } 38 | 39 | MappedInput input; 40 | 41 | protected: 42 | 43 | MappedInputController () { } 44 | 45 | MappedInputController (const MappedInputController&) { } 46 | 47 | MappedInputController& operator= (const MappedInputController&) { 48 | return *this; 49 | } 50 | 51 | }; 52 | 53 | #endif /* MAPPEDCONTROLLER_H_ */ 54 | -------------------------------------------------------------------------------- /src/system/MappedInput.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef MAPPEDINPUT_H_ 27 | #define MAPPEDINPUT_H_ 28 | 29 | #include "Input.h" 30 | 31 | namespace Keymap { 32 | enum Code { 33 | Left, 34 | Right, 35 | Up, 36 | Down, 37 | Action1, 38 | Action2, 39 | Action3, 40 | Action4, 41 | Start, 42 | }; 43 | } 44 | 45 | namespace Mousemap { 46 | enum Button { 47 | Left, 48 | Middle, 49 | Right, 50 | XButton1, 51 | XButton2, 52 | }; 53 | } 54 | 55 | class MappedInput: public Input { 56 | protected: 57 | 58 | std::vector _keyMap; 59 | std::vector _mouseMap; 60 | 61 | public: 62 | 63 | MappedInput () 64 | : _keyMap(9), _mouseMap(5), Input() { 65 | loadDefaultMap(); 66 | } 67 | 68 | virtual ~MappedInput () { } 69 | 70 | void loadDefaultMap () { 71 | _keyMap[Keymap::Left] = sf::Key::Left; 72 | _keyMap[Keymap::Right] = sf::Key::Right; 73 | _keyMap[Keymap::Up] = sf::Key::Up; 74 | _keyMap[Keymap::Down] = sf::Key::Down; 75 | _keyMap[Keymap::Action1] = sf::Key::RShift; 76 | _keyMap[Keymap::Action2] = sf::Key::RControl; 77 | _keyMap[Keymap::Action3] = sf::Key::A; 78 | _keyMap[Keymap::Action4] = sf::Key::LShift; 79 | _keyMap[Keymap::Start] = sf::Key::Return; 80 | 81 | _mouseMap[Mousemap::Left] = sf::Mouse::Left; 82 | _mouseMap[Mousemap::Middle] = sf::Mouse::Middle; 83 | _mouseMap[Mousemap::Right] = sf::Mouse::Right; 84 | _mouseMap[Mousemap::XButton1] = sf::Mouse::XButton1; 85 | _mouseMap[Mousemap::XButton2] = sf::Mouse::XButton2; 86 | } 87 | 88 | void setMapping (Keymap::Code code, sf::Key::Code sfcode) { 89 | _keyMap[code] = sfcode; 90 | } 91 | 92 | void setMapping (Mousemap::Button button, sf::Mouse::Button sfbutton) { 93 | _mouseMap[button] = sfbutton; 94 | } 95 | 96 | bool keyPressed (Keymap::Code key) const { 97 | return Input::keyHeld(_keyMap[key]); 98 | } 99 | 100 | bool keyHeld (Keymap::Code key) const { 101 | return Input::keyPressed(_keyMap[key]); 102 | } 103 | 104 | bool mouseClicked (Mousemap::Button button) const { 105 | return Input::mouseClicked(_mouseMap[button]); 106 | } 107 | 108 | bool mouseHeld (Mousemap::Button button) const { 109 | return Input::mouseHeld(_mouseMap[button]); 110 | } 111 | }; 112 | 113 | #endif /* MAPPEDINPUT_H_ */ 114 | -------------------------------------------------------------------------------- /src/system/WindowController.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef WINDOWCONTROLLER_H_ 27 | #define WINDOWCONTROLLER_H_ 28 | 29 | #include 30 | 31 | class WindowController { 32 | public: 33 | 34 | static WindowController& getController () { 35 | static WindowController wc; 36 | return wc; 37 | } 38 | 39 | sf::RenderWindow window; 40 | 41 | protected: 42 | 43 | WindowController () { } 44 | 45 | WindowController (const WindowController&) { } 46 | 47 | WindowController& operator= (const WindowController&) { 48 | return *this; 49 | } 50 | 51 | }; 52 | 53 | #endif /* WINDOWCONTROLLER_H_ */ 54 | -------------------------------------------------------------------------------- /src/vecmath/Matrix3.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef VMATH_MATRIX3_H_ 27 | #define VMATH_MATRIX3_H_ 28 | 29 | #include 30 | 31 | #include "Vecmath.h" 32 | 33 | namespace vmath { 34 | 35 | template 36 | class Matrix3 { 37 | public: 38 | 39 | class SingularException : public std::runtime_error { 40 | public: 41 | 42 | SingularException() 43 | : std::runtime_error("Singular Matrix Exception") { 44 | } 45 | }; 46 | 47 | static const Matrix3 IDENTITY; 48 | 49 | protected: 50 | 51 | static const unsigned _nElements = 9; 52 | static const unsigned _nCols = 3; 53 | static const unsigned _nRows = 3; 54 | 55 | T _m[_nElements]; 56 | 57 | public: 58 | 59 | Matrix3 () { 60 | for (unsigned int i = 0; i < _nElements; i++) { 61 | _m[i] = 0; 62 | } 63 | } 64 | 65 | Matrix3 (T a00, T a01, T a02, T a10, T a11, T a12, T a20, T a21, T a22) { 66 | _m[0] = a00; _m[1] = a01; _m[2] = a02; 67 | _m[3] = a10; _m[4] = a11; _m[5] = a12; 68 | _m[6] = a20; _m[7] = a21; _m[8] = a22; 69 | } 70 | 71 | Matrix3 (const T* p) { 72 | for (unsigned int i = 0; i < _nElements; i++) { 73 | _m[i] = p[i]; 74 | } 75 | } 76 | 77 | Matrix3 (const Matrix3& m) { 78 | for (unsigned int i = 0; i < _nElements; i++) { 79 | _m[i] = m._m[i]; 80 | } 81 | } 82 | 83 | Matrix3& operator= (const Matrix3& m) { 84 | set(m); 85 | return *this; 86 | } 87 | 88 | friend Matrix3 operator+<> (const Matrix3& m1, const Matrix3& m2); 89 | friend Matrix3 operator+<> (const Matrix3& m, T s); 90 | 91 | Matrix3& operator+= (const Matrix3& m) { 92 | add(m); 93 | return *this; 94 | } 95 | 96 | Matrix3& operator+= (T s) { 97 | add(s); 98 | return *this; 99 | } 100 | 101 | friend Matrix3 operator-<> (const Matrix3& m1, const Matrix3& m2); 102 | friend Matrix3 operator-<> (const Matrix3& m, T s); 103 | 104 | Matrix3& operator-= (const Matrix3& m) { 105 | sub(m); 106 | return *this; 107 | } 108 | 109 | Matrix3& operator-= (T s) { 110 | sub(s); 111 | return *this; 112 | } 113 | 114 | friend Matrix3 operator*<> (const Matrix3& m1, const Matrix3& m2); 115 | friend Matrix3 operator*<> (const Matrix3& m, T s); 116 | friend Matrix3 operator*<> (T s, const Matrix3& m); 117 | friend Vector3 operator*<> (const Matrix3& m, const Vector3& v); 118 | friend Vector3_T operator*<> (const Vector3_T& vt, const Matrix3& m); 119 | 120 | Matrix3& operator*= (const Matrix3& m) { 121 | mul(m); 122 | return *this; 123 | } 124 | 125 | Matrix3& operator*= (T s) { 126 | mul(s); 127 | return *this; 128 | } 129 | 130 | friend Matrix3 operator/<> (const Matrix3& m, T s); 131 | 132 | Matrix3& operator/= (T s) { 133 | mul(1.0 / s); 134 | return *this; 135 | } 136 | 137 | Matrix3 operator== (const Matrix3& m) const { 138 | return std::equal(_m.begin(), _m.end(), m); 139 | } 140 | 141 | Matrix3 operator!= (const Matrix3& m) const { 142 | return !(*this == m); 143 | } 144 | 145 | T& operator() (unsigned row, unsigned col) { 146 | if (row >= _nRows || col >= _nCols) { 147 | throw std::out_of_range("Subscript index out of range"); 148 | } 149 | 150 | return _m[_nRows * row + col]; 151 | } 152 | 153 | T operator() (unsigned row, unsigned col) const { 154 | if (row >= _nRows || col > _nCols) { 155 | throw std::out_of_range("Subscript index out of range"); 156 | } 157 | 158 | return _m[_nRows * row + col]; 159 | } 160 | 161 | friend std::ostream& operator<< (std::ostream &os, const Matrix3& m) { 162 | os << m.toString(); 163 | return os; 164 | } 165 | 166 | void add (T s) { 167 | for (unsigned int i = 0; i < _nElements; i++) { 168 | _m[i] += s; 169 | } 170 | } 171 | 172 | void add (const Matrix3& m) { 173 | for (unsigned int i = 0; i < _nElements; i++) { 174 | _m[i] += m._m[i]; 175 | } 176 | } 177 | 178 | const T* asArray () const { 179 | return _m; 180 | } 181 | 182 | T determinant () const { 183 | T sub0 = _m[0] * det2x2(_m[4], _m[5], _m[7], _m[8]); 184 | T sub1 = _m[1] * det2x2(_m[3], _m[5], _m[6], _m[8]); 185 | T sub2 = _m[2] * det2x2(_m[3], _m[4], _m[6], _m[7]); 186 | 187 | return sub0 - sub1 + sub2; 188 | } 189 | 190 | void getColumn (unsigned col, Vector3& v) const { 191 | if (col >= _nCols) { 192 | throw std::out_of_range("Column out of range"); 193 | } 194 | 195 | v.x = _m[_nRows * 0 + col]; 196 | v.y = _m[_nRows * 1 + col]; 197 | v.z = _m[_nRows * 2 + col]; 198 | } 199 | 200 | Vector3 getColumn (unsigned col) const { 201 | Vector3 v; 202 | getColumn(col, v); 203 | return v; 204 | } 205 | 206 | T getElement (unsigned index) const { 207 | if (index >= _nElements) { 208 | throw std::out_of_range("Element index out of range"); 209 | } 210 | 211 | return _m[index]; 212 | } 213 | 214 | T getElement (unsigned row, unsigned col) const { 215 | if (row >= _nRows || col >= _nCols) { 216 | throw std::out_of_range("Element index out of range"); 217 | } 218 | 219 | return _m[_nRows * row + col]; 220 | } 221 | 222 | void getRow (unsigned row, Vector3& v) const { 223 | if (row >= _nRows) { 224 | throw std::out_of_range("Row out of range"); 225 | } 226 | 227 | v.x = _m[_nRows * row + 0]; 228 | v.y = _m[_nRows * row + 1]; 229 | v.z = _m[_nRows * row + 2]; 230 | } 231 | 232 | Vector3 getRow (unsigned row) const { 233 | Vector3 v; 234 | getRow(row, v); 235 | return v; 236 | } 237 | 238 | void invert () { 239 | T d00 = det2x2(_m[4], _m[5], _m[7], _m[8]); 240 | T d01 = det2x2(_m[3], _m[5], _m[6], _m[8]); 241 | T d02 = det2x2(_m[3], _m[4], _m[6], _m[7]); 242 | 243 | T det = d00 - d01 + d02; 244 | if (det == 0) { 245 | throw SingularException(); 246 | } 247 | 248 | T d10 = det2x2(_m[1], _m[2], _m[7], _m[8]); 249 | T d11 = det2x2(_m[0], _m[2], _m[6], _m[8]); 250 | T d12 = det2x2(_m[0], _m[1], _m[6], _m[7]); 251 | 252 | T d20 = det2x2(_m[1], _m[2], _m[4], _m[5]); 253 | T d21 = det2x2(_m[0], _m[2], _m[3], _m[5]); 254 | T d22 = det2x2(_m[0], _m[1], _m[3], _m[4]); 255 | 256 | setRow(0, d00, -d01, d02); 257 | setRow(1, -d10, d11, -d12); 258 | setRow(2, d20, -d21, d22); 259 | 260 | mul(1.0 / det); 261 | transpose(); 262 | } 263 | 264 | void mul (T s) { 265 | for (unsigned int i = 0; i < _nElements; i++) { 266 | _m[i] *= s; 267 | } 268 | } 269 | 270 | void mul (const Matrix3& m) { 271 | T n00 = _m[0] * m._m[0] + _m[1] * m._m[3] + _m[2] * m._m[6]; 272 | T n01 = _m[0] * m._m[1] + _m[1] * m._m[4] + _m[2] * m._m[7]; 273 | T n02 = _m[0] * m._m[2] + _m[1] * m._m[5] + _m[2] * m._m[8]; 274 | T n10 = _m[3] * m._m[0] + _m[4] * m._m[3] + _m[5] * m._m[6]; 275 | T n11 = _m[3] * m._m[1] + _m[4] * m._m[4] + _m[5] * m._m[7]; 276 | T n12 = _m[3] * m._m[2] + _m[4] * m._m[5] + _m[5] * m._m[8]; 277 | T n20 = _m[6] * m._m[0] + _m[7] * m._m[3] + _m[8] * m._m[6]; 278 | T n21 = _m[6] * m._m[1] + _m[7] * m._m[4] + _m[8] * m._m[7]; 279 | T n22 = _m[6] * m._m[2] + _m[7] * m._m[5] + _m[8] * m._m[8]; 280 | 281 | setRow(0, n00, n01, n02); 282 | setRow(1, n10, n11, n12); 283 | setRow(2, n20, n21, n22); 284 | } 285 | 286 | Vector3 mul (const Vector3& v) { 287 | Vector3 out(v); 288 | transform(out); 289 | return out; 290 | } 291 | 292 | void negate () { 293 | mul(-1.f); 294 | } 295 | 296 | void set (T s) { 297 | _m[0] = s; _m[1] = 0; _m[2] = 0; 298 | _m[3] = 0; _m[4] = s; _m[5] = 0; 299 | _m[6] = 0; _m[7] = 0; _m[8] = s; 300 | } 301 | 302 | void set (T a00, T a01, T a02, T a10, T a11, T a12, T a20, T a21, T a22) { 303 | _m[0] = a00; _m[1] = a01; _m[2] = a02; 304 | _m[3] = a10; _m[4] = a11; _m[5] = a12; 305 | _m[6] = a20; _m[7] = a21; _m[8] = a22; 306 | } 307 | 308 | void set (const T* p) { 309 | for (unsigned int i = 0; i < _nElements; i++) { 310 | _m[i] += p[i]; 311 | } 312 | } 313 | 314 | void set (const Matrix3& m) { 315 | for (unsigned int i = 0; i < _nElements; i++) { 316 | _m[i] = m._m[i]; 317 | } 318 | } 319 | 320 | void setColumn (unsigned col, T x, T y, T z) { 321 | if (col >= _nCols) { 322 | throw std::out_of_range("Column out of range"); 323 | } 324 | 325 | _m[_nRows * 0 + col] = x; 326 | _m[_nRows * 1 + col] = y; 327 | _m[_nRows * 2 + col] = z; 328 | } 329 | 330 | void setColumn (unsigned col, const Vector3& v) { 331 | setColumn(col, v.x, v.y, v.z); 332 | } 333 | 334 | void setElement (unsigned index, T s) { 335 | if (index >= _nElements) { 336 | throw std::out_of_range("Element index out of range"); 337 | } 338 | 339 | _m[index] = s; 340 | } 341 | 342 | void setElement (unsigned row, unsigned col, T s) { 343 | if (row >= _nRows || col >= _nCols) { 344 | throw std::out_of_range("Element index out of range"); 345 | } 346 | 347 | _m[_nRows * row + col] = s; 348 | } 349 | 350 | void setIdentity () { 351 | set(1.f); 352 | } 353 | 354 | void setRow (unsigned row, T x, T y, T z) { 355 | if (row >= _nRows) { 356 | throw std::out_of_range("Row out of range"); 357 | } 358 | 359 | _m[_nRows * row + 0] = x; 360 | _m[_nRows * row + 1] = y; 361 | _m[_nRows * row + 2] = z; 362 | } 363 | 364 | void setRow (unsigned row, const Vector3& v) { 365 | setRow(row, v.x, v.y, v.z); 366 | } 367 | 368 | void setZero () { 369 | set(0.f); 370 | } 371 | 372 | void sub (T s) { 373 | add(-s); 374 | } 375 | 376 | void sub(const Matrix3& m) { 377 | for (unsigned int i = 0; i < _nElements; i++) { 378 | _m[i] -= m._m[i]; 379 | } 380 | } 381 | 382 | std::string toString () const { 383 | std::stringstream str; 384 | str.precision(3); 385 | 386 | str << "("; 387 | for (unsigned i = 0; i < _nElements - 1; i++) { 388 | str << std::setw(8) << std::fixed << _m[i] << ","; 389 | } 390 | str << std::setw(8) << std::fixed << _m[_nElements - 1]; 391 | str << ")"; 392 | 393 | return str.str(); 394 | } 395 | 396 | void transform (Vector3& t) const { 397 | T tx = _m[0] * t.x + _m[1] * t.y + _m[2] * t.z; 398 | T ty = _m[3] * t.x + _m[4] * t.y + _m[5] * t.z; 399 | T tz = _m[6] * t.x + _m[7] * t.y + _m[8] * t.z; 400 | 401 | t.set(tx, ty, tz); 402 | } 403 | 404 | void transpose () { 405 | swap(_m[1], _m[3]); 406 | swap(_m[2], _m[6]); 407 | swap(_m[5], _m[7]); 408 | } 409 | 410 | protected: 411 | 412 | T det2x2 (T a, T b, T c, T d) const { 413 | return (a * d) - (b * c); 414 | } 415 | 416 | 417 | void swap (T& s0, T& s1) { 418 | T s2 = s0; 419 | s0 = s1; 420 | s1 = s2; 421 | } 422 | }; 423 | 424 | template 425 | const Matrix3 Matrix3::IDENTITY(1, 0, 0, 0, 1, 0, 0, 0, 1); 426 | 427 | typedef Matrix3 Matrix3d; 428 | typedef Matrix3 Matrix3f; 429 | 430 | } 431 | 432 | #endif /* VMATH_MATRIX3_H_ */ 433 | -------------------------------------------------------------------------------- /src/vecmath/MatrixG3.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef VMATH_MATRIXG3_H_ 27 | #define VMATH_MATRIXG3_H_ 28 | 29 | #include 30 | 31 | #include "Vecmath.h" 32 | 33 | namespace vmath { 34 | 35 | template 36 | class MatrixG3 : public Matrix3 { 37 | protected: 38 | 39 | using Matrix3::_m; 40 | 41 | public: 42 | 43 | MatrixG3 () 44 | : Matrix3() { 45 | } 46 | 47 | MatrixG3 (T a00, T a01, T a02, T a10, T a11, T a12, T a20, T a21, T a22) 48 | : Matrix3(a00, a01, a02, a10, a11, a12, a20, a21, a22) { 49 | } 50 | 51 | MatrixG3 (const T* p) 52 | : Matrix3(p) { 53 | } 54 | 55 | MatrixG3 (const Matrix3& m) 56 | : Matrix3(m) { 57 | } 58 | 59 | void rotate (T a, T x, T y, T z) { 60 | T rada = radians(a); 61 | T sina = std::sin(rada); 62 | T cosa = std::cos(rada); 63 | 64 | Vector3 u(x, y, z); 65 | u.normalize(); 66 | 67 | Matrix3 uuT = u * u.transpose(); 68 | 69 | Matrix3 S(0, -u.z, u.y, u.z, 0, -u.x, -u.y, u.x, 0); 70 | 71 | Matrix3 M = uuT + cosa * (Matrix3::IDENTITY - uuT) + sina * S; 72 | 73 | this->mul(M); 74 | } 75 | 76 | void rotateX (T a) { 77 | T rada = radians(a); 78 | T sina = std::sin(rada); 79 | T cosa = std::cos(rada); 80 | T tmp1, tmp2; 81 | 82 | tmp1 = _m[1] * cosa + _m[2] * sina; 83 | tmp2 = _m[1] * -sina + _m[2] * cosa; 84 | _m[1] = tmp1; _m[2] = tmp2; 85 | 86 | tmp1 = _m[4] * cosa + _m[5] * sina; 87 | tmp2 = _m[4] * -sina + _m[5] * cosa; 88 | _m[4] = tmp1; _m[5] = tmp2; 89 | 90 | tmp1 = _m[7] * cosa + _m[8] * sina; 91 | tmp2 = _m[7] * -sina + _m[8] * cosa; 92 | _m[7] = tmp1; _m[8] = tmp2; 93 | } 94 | 95 | void rotateY (T a) { 96 | T rada = radians(a); 97 | T sina = std::sin(rada); 98 | T cosa = std::cos(rada); 99 | T tmp1, tmp2; 100 | 101 | tmp1 = _m[0] * cosa + _m[2] * -sina; 102 | tmp2 = _m[0] * sina + _m[2] * cosa; 103 | _m[0] = tmp1; _m[2] = tmp2; 104 | 105 | tmp1 = _m[3] * cosa + _m[5] * -sina; 106 | tmp2 = _m[3] * sina + _m[5] * cosa; 107 | _m[3] = tmp1; _m[5] = tmp2; 108 | 109 | tmp1 = _m[6] * cosa + _m[8] * -sina; 110 | tmp2 = _m[6] * sina + _m[8] * cosa; 111 | _m[6] = tmp1; _m[8] = tmp2; 112 | } 113 | 114 | void rotateZ (T a) { 115 | T rada = radians(a); 116 | T sina = std::sin(rada); 117 | T cosa = std::cos(rada); 118 | T tmp1, tmp2; 119 | 120 | tmp1 = _m[0] * cosa + _m[1] * sina; 121 | tmp2 = _m[0] * -sina + _m[1] * cosa; 122 | _m[0] = tmp1; _m[1] = tmp2; 123 | 124 | tmp1 = _m[3] * cosa + _m[4] * sina; 125 | tmp2 = _m[3] * -sina + _m[4] * cosa; 126 | _m[3] = tmp1; _m[4] = tmp2; 127 | 128 | tmp1 = _m[6] * cosa + _m[7] * sina; 129 | tmp2 = _m[6] * -sina + _m[7] * cosa; 130 | _m[6] = tmp1; _m[7] = tmp2; 131 | } 132 | 133 | void scale (T x, T y, T z) { 134 | _m[0] *= x; 135 | _m[3] *= x; 136 | _m[6] *= x; 137 | 138 | _m[1] *= y; 139 | _m[4] *= y; 140 | _m[7] *= y; 141 | 142 | _m[2] *= z; 143 | _m[5] *= z; 144 | _m[8] *= z; 145 | } 146 | 147 | protected: 148 | 149 | static T radians (T degrees) { 150 | //const double PI = 3.14159265; 151 | return (degrees * PI / 180.0); 152 | } 153 | }; 154 | 155 | typedef MatrixG3 MatrixG3f; 156 | typedef MatrixG3 MatrixG3d; 157 | 158 | } 159 | 160 | #endif /* VMATH_MATRIXG3_H_ */ 161 | -------------------------------------------------------------------------------- /src/vecmath/MatrixG4.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef VMATH_MATRIXG4_H_ 27 | #define VMATH_MATRIXG4_H_ 28 | 29 | #include 30 | 31 | #include "Vecmath.h" 32 | 33 | namespace vmath { 34 | 35 | template 36 | class MatrixG4 : public Matrix4 { 37 | protected: 38 | 39 | using Matrix4::_m; 40 | 41 | public: 42 | 43 | MatrixG4 () 44 | : Matrix4() { 45 | } 46 | 47 | MatrixG4 (T a00, T a01, T a02, T a03, T a10, T a11, T a12, T a13, T a20, T a21, T a22, T a23, T a30, T a31, T a32, T a33) 48 | : Matrix4(a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, a30, a31, a32, a33) { 49 | } 50 | 51 | MatrixG4 (const T* p) 52 | : Matrix4(p) { 53 | } 54 | 55 | MatrixG4 (const Matrix4& m) 56 | : Matrix4(m) { 57 | } 58 | 59 | void rotate (T a, T x, T y, T z) { 60 | T rada = radians(a); 61 | T sina = std::sin(rada); 62 | T cosa = std::cos(rada); 63 | 64 | Vector3 u(x, y, z); 65 | u.normalize(); 66 | 67 | Matrix3 uuT = u * u.transpose(); 68 | 69 | Matrix3 S(0, -u.z, u.y, u.z, 0, -u.x, -u.y, u.x, 0); 70 | 71 | Matrix3 M = uuT + cosa * (Matrix3::IDENTITY - uuT) + sina * S; 72 | 73 | Vector3 r0 = M.getRow(0); 74 | Vector3 r1 = M.getRow(1); 75 | Vector3 r2 = M.getRow(2); 76 | 77 | T tmp1, tmp2, tmp3; 78 | 79 | tmp1 = _m[0] * r0.x + _m[1] * r1.x + _m[2] * r2.x; 80 | tmp2 = _m[0] * r0.y + _m[1] * r1.y + _m[2] * r2.y; 81 | tmp3 = _m[0] * r0.z + _m[1] * r1.z + _m[2] * r2.z; 82 | _m[0] = tmp1; _m[1] = tmp2; _m[2] = tmp3; 83 | 84 | tmp1 = _m[4] * r0.x + _m[5] * r1.x + _m[6] * r2.x; 85 | tmp2 = _m[4] * r0.y + _m[5] * r1.y + _m[6] * r2.y; 86 | tmp3 = _m[4] * r0.z + _m[5] * r1.z + _m[6] * r2.z; 87 | _m[4] = tmp1; _m[5] = tmp2; _m[6] = tmp3; 88 | 89 | tmp1 = _m[8] * r0.x + _m[9] * r1.x + _m[10] * r2.x; 90 | tmp2 = _m[8] * r0.y + _m[9] * r1.y + _m[10] * r2.y; 91 | tmp3 = _m[8] * r0.z + _m[9] * r1.z + _m[10] * r2.z; 92 | _m[8] = tmp1; _m[9] = tmp2; _m[10] = tmp3; 93 | 94 | tmp1 = _m[12] * r0.x + _m[13] * r1.x + _m[14] * r2.x; 95 | tmp2 = _m[12] * r0.y + _m[13] * r1.y + _m[14] * r2.y; 96 | tmp3 = _m[12] * r0.z + _m[13] * r1.z + _m[14] * r2.z; 97 | _m[12] = tmp1; _m[13] = tmp2; _m[14] = tmp3; 98 | } 99 | 100 | void rotateX (T a) { 101 | T rada = radians(a); 102 | T sina = std::sin(rada); 103 | T cosa = std::cos(rada); 104 | T tmp1, tmp2; 105 | 106 | tmp1 = _m[1] * cosa + _m[2] * sina; 107 | tmp2 = _m[1] * -sina + _m[2] * cosa; 108 | _m[1] = tmp1; _m[2] = tmp2; 109 | 110 | tmp1 = _m[5] * cosa + _m[6] * sina; 111 | tmp2 = _m[5] * -sina + _m[6] * cosa; 112 | _m[5] = tmp1; _m[6] = tmp2; 113 | 114 | tmp1 = _m[9] * cosa + _m[10] * sina; 115 | tmp2 = _m[9] * -sina + _m[10] * cosa; 116 | _m[9] = tmp1; _m[10] = tmp2; 117 | 118 | tmp1 = _m[13] * cosa + _m[14] * sina; 119 | tmp2 = _m[13] * -sina + _m[14] * cosa; 120 | _m[13] = tmp1; _m[14] = tmp2; 121 | } 122 | 123 | void rotateY (T a) { 124 | T rada = radians(a); 125 | T sina = std::sin(rada); 126 | T cosa = std::cos(rada); 127 | T tmp1, tmp2; 128 | 129 | tmp1 = _m[0] * cosa + _m[2] * -sina; 130 | tmp2 = _m[0] * sina + _m[2] * cosa; 131 | _m[0] = tmp1; _m[2] = tmp2; 132 | 133 | tmp1 = _m[4] * cosa + _m[6] * -sina; 134 | tmp2 = _m[4] * sina + _m[6] * cosa; 135 | _m[4] = tmp1; _m[6] = tmp2; 136 | 137 | tmp1 = _m[8] * cosa + _m[10] * -sina; 138 | tmp2 = _m[8] * sina + _m[10] * cosa; 139 | _m[8] = tmp1; _m[10] = tmp2; 140 | 141 | tmp1 = _m[12] * cosa + _m[14] * -sina; 142 | tmp2 = _m[12] * sina + _m[14] * cosa; 143 | _m[12] = tmp1; _m[14] = tmp2; 144 | } 145 | 146 | void rotateZ (T a) { 147 | T rada = radians(a); 148 | T sina = std::sin(rada); 149 | T cosa = std::cos(rada); 150 | T tmp1, tmp2; 151 | 152 | tmp1 = _m[0] * cosa + _m[1] * sina; 153 | tmp2 = _m[0] * -sina + _m[1] * cosa; 154 | _m[0] = tmp1; _m[1] = tmp2; 155 | 156 | tmp1 = _m[4] * cosa + _m[5] * sina; 157 | tmp2 = _m[4] * -sina + _m[5] * cosa; 158 | _m[4] = tmp1; _m[5] = tmp2; 159 | 160 | tmp1 = _m[8] * cosa + _m[9] * sina; 161 | tmp2 = _m[8] * -sina + _m[9] * cosa; 162 | _m[8] = tmp1; _m[9] = tmp2; 163 | 164 | tmp1 = _m[12] * cosa + _m[13] * sina; 165 | tmp2 = _m[12] * -sina + _m[13] * cosa; 166 | _m[12] = tmp1; _m[13] = tmp2; 167 | } 168 | 169 | void scale (T x, T y, T z) { 170 | _m[0] *= x; 171 | _m[4] *= x; 172 | _m[8] *= x; 173 | _m[12] *= x; 174 | 175 | _m[1] *= y; 176 | _m[5] *= y; 177 | _m[9] *= y; 178 | _m[13] *= y; 179 | 180 | _m[2] *= z; 181 | _m[6] *= z; 182 | _m[10] *= z; 183 | _m[14] *= z; 184 | } 185 | 186 | void transform (Tuple3& t) const { 187 | T tx = _m[0] * t.x + _m[1] * t.y + _m[2] * t.z + _m[3]; 188 | T ty = _m[4] * t.x + _m[5] * t.y + _m[6] * t.z + _m[7]; 189 | T tz = _m[8] * t.x + _m[9] * t.y + _m[10] * t.z + _m[11]; 190 | 191 | t.set(tx, ty, tz); 192 | } 193 | 194 | void translate (T x, T y, T z) { 195 | _m[3] += _m[0] * x + _m[1] * y + _m[2] * z; 196 | _m[7] += _m[4] * x + _m[5] * y + _m[6] * z; 197 | _m[11] += _m[8] * x + _m[9] * y + _m[10] * z; 198 | _m[15] += _m[12] * x + _m[13] * y + _m[14] * z; 199 | } 200 | 201 | protected: 202 | 203 | static T radians (T degrees) { 204 | //const double PI = 3.14159265; 205 | return (degrees * PI / 180.0); 206 | } 207 | }; 208 | 209 | typedef MatrixG4 MatrixG4f; 210 | typedef MatrixG4 MatrixG4d; 211 | 212 | } 213 | 214 | #endif /* VMATH_MATRIXG4_H_ */ 215 | -------------------------------------------------------------------------------- /src/vecmath/Tuple2.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef VMATH_TUPLE2_H_ 27 | #define VMATH_TUPLE2_H_ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "Vecmath.h" 37 | 38 | namespace vmath { 39 | 40 | template 41 | class Tuple2 { 42 | 43 | protected: 44 | 45 | static const unsigned _nElements = 2; 46 | 47 | typedef T Tuple2::* const TRef[2]; 48 | static const TRef _t; 49 | 50 | public: 51 | 52 | T x; 53 | T y; 54 | 55 | public: 56 | 57 | Tuple2 () 58 | : x(0), y(0) { 59 | } 60 | 61 | Tuple2 (T s) 62 | : x(s), y(s) { 63 | } 64 | 65 | Tuple2 (T fx, T fy) 66 | : x(fx), y(fy) { 67 | } 68 | 69 | Tuple2 (const Tuple2& t) 70 | : x(t.x), y(t.y) { 71 | } 72 | 73 | Tuple2 (const Tuple2* t) 74 | : x(t->x), y(t->y) { 75 | } 76 | 77 | Tuple2 (const T* p) 78 | : x(p[0]), y(p[1]) { 79 | } 80 | 81 | //virtual ~Tuple2 () { } 82 | 83 | Tuple2& operator= (const Tuple2& t) { 84 | x = t.x; 85 | y = t.y; 86 | return *this; 87 | } 88 | 89 | friend Tuple2 operator+<> (const Tuple2& t1, const Tuple2& t2); 90 | friend Tuple2 operator+<> (const Tuple2& t, T s); 91 | friend Tuple2 operator+<> (T s, const Tuple2& t); 92 | 93 | void operator+= (const Tuple2& t) { 94 | add(t); 95 | } 96 | 97 | void operator+= (T s) { 98 | add(s); 99 | } 100 | 101 | friend Tuple2 operator-<> (const Tuple2& t1, const Tuple2& t2); 102 | friend Tuple2 operator-<> (const Tuple2& t, T s); 103 | friend Tuple2 operator-<> (T s, const Tuple2& t); 104 | 105 | friend Tuple2 operator-<> (const Tuple2& t); 106 | 107 | void operator-= (const Tuple2& t) { 108 | sub(t); 109 | } 110 | 111 | void operator-= (T s) { 112 | sub(s); 113 | } 114 | 115 | friend Tuple2 operator*<> (const Tuple2& t, T s); 116 | friend Tuple2 operator*<> (T s, const Tuple2& t); 117 | 118 | void operator*= (T s) { 119 | scale(s); 120 | } 121 | 122 | friend Tuple2 operator/<> (const Tuple2& t, T s); 123 | 124 | void operator/= (T s) { 125 | scale(1.0 / s); 126 | } 127 | 128 | bool operator== (const Tuple2& t) const { 129 | return (x == t.x && y == t.y); 130 | } 131 | 132 | bool operator== (T s) const { 133 | return ((x * x + y * y) == s); 134 | } 135 | 136 | bool operator!= (const Tuple2& t) const { 137 | return !(*this == t); 138 | } 139 | 140 | bool operator!= (T s) const { 141 | return !(*this == s); 142 | } 143 | 144 | T& operator[] (unsigned index) { 145 | return this->*_t[index]; 146 | } 147 | 148 | const T& operator[] (unsigned index) const { 149 | return this->*_t[index]; 150 | } 151 | 152 | T& operator() (unsigned index) { 153 | if (index >= _nElements) { 154 | throw std::out_of_range("Subscript index out of range"); 155 | } 156 | 157 | return this->*_t[index]; 158 | } 159 | 160 | const T& operator() (unsigned index) const { 161 | if (index >= _nElements) { 162 | throw std::out_of_range("Subscript index out of range"); 163 | } 164 | 165 | return this->*_t[index]; 166 | } 167 | 168 | friend std::ostream& operator<< (std::ostream &os, const Tuple2& t) { 169 | os << t.toString(); 170 | return os; 171 | } 172 | 173 | void absolute () { 174 | if (x < 0) x = 0 - x; 175 | if (y < 0) y = 0 - y; 176 | } 177 | 178 | void add (T s) { 179 | x += s; 180 | y += s; 181 | } 182 | 183 | void add (const Tuple2& t) { 184 | x += t.x; 185 | y += t.y; 186 | } 187 | 188 | void clamp (T min, T max) { 189 | clampMin(min); 190 | clampMax(max); 191 | } 192 | 193 | void clampMax (T max) { 194 | if (x > max) x = max; 195 | if (y > max) y = max; 196 | } 197 | 198 | void clampMin (T min) { 199 | if (x < min) x = min; 200 | if (y < min) y = min; 201 | } 202 | 203 | bool equals (const Tuple2& t) const { 204 | return (x == t.x && y == t.y); 205 | } 206 | 207 | bool epsilonEquals (const Tuple2& t, T epsilon) const { 208 | return (x * x + y * y) <= (epsilon * epsilon); 209 | } 210 | 211 | void get (T* p) const { 212 | p[0] = x; 213 | p[1] = y; 214 | } 215 | 216 | T getElement (unsigned index) const { 217 | if (index >= _nElements) { 218 | throw std::out_of_range("Subscript index out of range"); 219 | } 220 | 221 | return this->*_t[index]; 222 | } 223 | 224 | void interpolate (const Tuple2& t, float alpha) { 225 | x = (1.f - alpha) * x + alpha * t.x; 226 | y = (1.f - alpha) * y + alpha * t.y; 227 | } 228 | 229 | void negate () { 230 | scale(-1.f); 231 | } 232 | 233 | void scale (T s) { 234 | x *= s; 235 | y *= s; 236 | } 237 | 238 | void scaleAdd (T s, T a) { 239 | x = x * s + a; 240 | y = y * s + a; 241 | } 242 | 243 | void scaleAdd (T s, const Tuple2& t) { 244 | x = x * s + t.x; 245 | y = y * s + t.y; 246 | } 247 | 248 | void set (T s) { 249 | x = s; 250 | y = s; 251 | } 252 | 253 | void set (T fx, T fy) { 254 | x = fx; 255 | y = fy; 256 | } 257 | 258 | void set (const Tuple2& t) { 259 | x = t.x; 260 | y = t.y; 261 | } 262 | 263 | void set (const T* p) { 264 | x = p[0]; 265 | y = p[1]; 266 | } 267 | 268 | void setElement (unsigned index, T s) { 269 | if (index >= _nElements) { 270 | throw std::out_of_range("Subscript index out of range"); 271 | } 272 | 273 | this->*_t[index] = s; 274 | } 275 | 276 | void sub (T s) { 277 | x -= s; 278 | y -= s; 279 | } 280 | 281 | void sub (const Tuple2& t) { 282 | x -= t.x; 283 | y -= t.y; 284 | } 285 | 286 | std::string toString () const { 287 | std::stringstream str; 288 | str.precision(3); 289 | 290 | str << "("; 291 | str << std::setw(8) << std::fixed << x << ","; 292 | str << std::setw(8) << std::fixed << y; 293 | str << ")"; 294 | 295 | return str.str(); 296 | } 297 | }; 298 | 299 | template 300 | const typename Tuple2::TRef Tuple2::_t = { 301 | &Tuple2::x, 302 | &Tuple2::y 303 | }; 304 | 305 | typedef Tuple2 Tuple2b; 306 | typedef Tuple2 Tuple2d; 307 | typedef Tuple2 Tuple2f; 308 | typedef Tuple2 Tuple2i; 309 | 310 | } 311 | 312 | #endif /* VMATH_TUPLE2_H_ */ 313 | -------------------------------------------------------------------------------- /src/vecmath/Tuple3.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef VMATH_TUPLE3_H_ 27 | #define VMATH_TUPLE3_H_ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "Vecmath.h" 37 | 38 | namespace vmath { 39 | 40 | template 41 | class Tuple3 { 42 | protected: 43 | 44 | static const unsigned _nElements = 3; 45 | 46 | typedef T Tuple3::* const TRef[3]; 47 | static const TRef _t; 48 | 49 | public: 50 | 51 | T x; 52 | T y; 53 | T z; 54 | 55 | public: 56 | 57 | Tuple3 () 58 | : x(0), y(0), z(0) { 59 | } 60 | 61 | Tuple3 (T s) 62 | : x(s), y(s), z(s) { 63 | } 64 | 65 | Tuple3 (T fx, T fy, T fz) 66 | : x(fx), y(fy), z(fz) { 67 | } 68 | 69 | Tuple3 (const Tuple3& t) 70 | : x(t.x), y(t.y), z(t.z) { 71 | } 72 | 73 | Tuple3 (const Tuple3* t) 74 | : x(t->x), y(t->y), z(t->z) { 75 | } 76 | 77 | Tuple3 (const T* p) 78 | : x(p[0]), y(p[1]), z(p[2]) { 79 | } 80 | 81 | //virtual ~Tuple3 () { } 82 | 83 | Tuple3& operator= (const Tuple3& t) { 84 | x = t.x; 85 | y = t.y; 86 | z = t.z; 87 | return *this; 88 | } 89 | 90 | friend Tuple3 operator+<> (const Tuple3& t1, const Tuple3& t2); 91 | friend Tuple3 operator+<> (const Tuple3& t, T s); 92 | friend Tuple3 operator+<> (T s, const Tuple3& t); 93 | 94 | void operator+= (const Tuple3& t) { 95 | add(t); 96 | } 97 | 98 | void operator+= (T s) { 99 | add(s); 100 | } 101 | 102 | friend Tuple3 operator-<> (const Tuple3& t1, const Tuple3& t2); 103 | friend Tuple3 operator-<> (const Tuple3& t, T s); 104 | friend Tuple3 operator-<> (T s, const Tuple3& t); 105 | 106 | friend Tuple3 operator-<> (const Tuple3& t); 107 | 108 | void operator-= (const Tuple3& t) { 109 | sub(t); 110 | } 111 | 112 | void operator-= (T s) { 113 | sub(s); 114 | } 115 | 116 | friend Tuple3 operator*<> (const Tuple3& t, T s); 117 | friend Tuple3 operator*<> (T s, const Tuple3& t); 118 | 119 | void operator*= (T s) { 120 | scale(s); 121 | } 122 | 123 | friend Tuple3 operator/<> (const Tuple3& t, T s); 124 | 125 | void operator/= (T s) { 126 | scale(1.0 / s); 127 | } 128 | 129 | bool operator== (const Tuple3& t) const { 130 | return (x == t.x && y == t.y && z == t.z); 131 | } 132 | 133 | bool operator== (T s) const { 134 | return ((x * x + y * y + z * z) == s); 135 | } 136 | 137 | bool operator!= (const Tuple3& t) const { 138 | return !(*this == t); 139 | } 140 | 141 | bool operator!= (T s) const { 142 | return !(*this == s); 143 | } 144 | 145 | T& operator[] (unsigned index) { 146 | return this->*_t[index]; 147 | } 148 | 149 | const T& operator[] (unsigned index) const { 150 | return this->*_t[index]; 151 | } 152 | 153 | T& operator() (unsigned index) { 154 | if (index >= _nElements) { 155 | throw std::out_of_range("Subscript index out of range"); 156 | } 157 | 158 | return this->*_t[index]; 159 | } 160 | 161 | const T& operator() (unsigned index) const { 162 | if (index >= _nElements) { 163 | throw std::out_of_range("Subscript index out of range"); 164 | } 165 | 166 | return this->*_t[index]; 167 | } 168 | 169 | friend std::ostream& operator<< (std::ostream &os, const Tuple3& t) { 170 | os << t.toString(); 171 | return os; 172 | } 173 | 174 | void absolute () { 175 | if (x < 0) x = 0 - x; 176 | if (y < 0) y = 0 - y; 177 | if (z < 0) z = 0 - z; 178 | } 179 | 180 | void add (T s) { 181 | x += s; 182 | y += s; 183 | z += s; 184 | } 185 | 186 | void add (const Tuple3& t) { 187 | x += t.x; 188 | y += t.y; 189 | z += t.z; 190 | } 191 | 192 | void clamp (T min, T max) { 193 | clampMin(min); 194 | clampMax(max); 195 | } 196 | 197 | void clampMax (T max) { 198 | if (x > max) x = max; 199 | if (y > max) y = max; 200 | if (z > max) z = max; 201 | } 202 | 203 | void clampMin (T min) { 204 | if (x < min) x = min; 205 | if (y < min) y = min; 206 | if (z < min) z = min; 207 | } 208 | 209 | bool equals (const Tuple3& t) const { 210 | return (x == t.x && y == t.y && z == t.z); 211 | } 212 | 213 | bool epsilonEquals (const Tuple3& t, T epsilon) const { 214 | return (x * x + y * y + z * z) <= (epsilon * epsilon); 215 | } 216 | 217 | void get (T* p) const { 218 | p[0] = x; 219 | p[1] = y; 220 | p[2] = z; 221 | } 222 | 223 | T getElement (unsigned index) const { 224 | if (index >= _nElements) { 225 | throw std::out_of_range("Subscript index out of range"); 226 | } 227 | 228 | return this->*_t[index]; 229 | } 230 | 231 | void interpolate (const Tuple3& t, float alpha) { 232 | x = (1.f - alpha) * x + alpha * t.x; 233 | y = (1.f - alpha) * y + alpha * t.y; 234 | z = (1.f - alpha) * z + alpha * t.z; 235 | } 236 | 237 | void negate () { 238 | scale(-1.f); 239 | } 240 | 241 | void scale (T s) { 242 | x *= s; 243 | y *= s; 244 | z *= s; 245 | } 246 | 247 | void scaleAdd (T s, T a) { 248 | x = x * s + a; 249 | y = y * s + a; 250 | z = z * s + a; 251 | } 252 | 253 | void scaleAdd (T s, const Tuple3& t) { 254 | x = x * s + t.x; 255 | y = y * s + t.y; 256 | z = z * s + t.z; 257 | } 258 | 259 | void set (T s) { 260 | x = s; 261 | y = s; 262 | z = s; 263 | } 264 | 265 | void set (T fx, T fy, T fz) { 266 | x = fx; 267 | y = fy; 268 | z = fz; 269 | } 270 | 271 | void set (const Tuple3& t) { 272 | x = t.x; 273 | y = t.y; 274 | z = t.z; 275 | } 276 | 277 | void set (const T* p) { 278 | x = p[0]; 279 | y = p[1]; 280 | z = p[2]; 281 | } 282 | 283 | void setElement (unsigned index, T s) { 284 | if (index >= _nElements) { 285 | throw std::out_of_range("Subscript index out of range"); 286 | } 287 | 288 | this->*_t[index] = s; 289 | } 290 | 291 | void sub (T s) { 292 | x -= s; 293 | y -= s; 294 | z -= s; 295 | } 296 | 297 | void sub (const Tuple3& t) { 298 | x -= t.x; 299 | y -= t.y; 300 | z -= t.z; 301 | } 302 | 303 | std::string toString () const { 304 | std::stringstream str; 305 | str.precision(3); 306 | 307 | str << "("; 308 | str << std::setw(8) << std::fixed << x << ","; 309 | str << std::setw(8) << std::fixed << y << ","; 310 | str << std::setw(8) << std::fixed << z; 311 | str << ")"; 312 | 313 | return str.str(); 314 | } 315 | }; 316 | 317 | template 318 | const typename Tuple3::TRef Tuple3::_t = { 319 | &Tuple3::x, 320 | &Tuple3::y, 321 | &Tuple3::z 322 | }; 323 | 324 | typedef Tuple3 Tuple3b; 325 | typedef Tuple3 Tuple3d; 326 | typedef Tuple3 Tuple3f; 327 | typedef Tuple3 Tuple3i; 328 | 329 | } 330 | 331 | #endif /* VMATH_TUPLE3_H_ */ 332 | -------------------------------------------------------------------------------- /src/vecmath/Tuple4.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef VMATH_TUPLE4_H_ 27 | #define VMATH_TUPLE4_H_ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "Vecmath.h" 37 | 38 | namespace vmath { 39 | 40 | template 41 | class Tuple4 { 42 | protected: 43 | 44 | static const unsigned _nElements = 4; 45 | 46 | typedef T Tuple4::* const TRef[4]; 47 | static const TRef _t; 48 | 49 | public: 50 | 51 | T x; 52 | T y; 53 | T z; 54 | T w; 55 | 56 | public: 57 | 58 | Tuple4 () 59 | : x(0), y(0), z(0), w(0) { 60 | } 61 | 62 | Tuple4 (T s) 63 | : x(s), y(s), z(s), w(s) { 64 | } 65 | 66 | Tuple4 (T fx, T fy, T fz, T fw) 67 | : x(fx), y(fy), z(fz), w(fw) { 68 | } 69 | 70 | Tuple4 (const Tuple3& t, T fw) 71 | : x(t.x), y(t.y), z(t.z), w(fw) { 72 | } 73 | 74 | Tuple4 (const Tuple4& t) 75 | : x(t.x), y(t.y), z(t.z), w(t.w) { 76 | } 77 | 78 | Tuple4 (const Tuple4* t) 79 | : x(t->x), y(t->y), z(t->z), w(t->w) { 80 | } 81 | 82 | Tuple4 (const T* p) 83 | : x(p[0]), y(p[1]), z(p[2]), w(p[3]) { 84 | } 85 | 86 | //virtual ~Tuple4 () { } 87 | 88 | Tuple4& operator= (const Tuple4& t) { 89 | x = t.x; 90 | y = t.y; 91 | z = t.z; 92 | w = t.w; 93 | return *this; 94 | } 95 | 96 | friend Tuple4 operator+<> (const Tuple4& t1, const Tuple4& t2); 97 | friend Tuple4 operator+<> (const Tuple4& t, T s); 98 | friend Tuple4 operator+<> (T s, const Tuple4& t); 99 | 100 | void operator+= (const Tuple4& t) { 101 | add(t); 102 | } 103 | 104 | void operator+= (T s) { 105 | add(s); 106 | } 107 | 108 | friend Tuple4 operator-<> (const Tuple4& t1, const Tuple4& t2); 109 | friend Tuple4 operator-<> (const Tuple4& t, T s); 110 | friend Tuple4 operator-<> (T s, const Tuple4& t); 111 | 112 | friend Tuple4 operator-<> (const Tuple4& t); 113 | 114 | void operator-= (const Tuple4& t) { 115 | sub(t); 116 | } 117 | 118 | void operator-= (T s) { 119 | sub(s); 120 | } 121 | 122 | friend Tuple4 operator*<> (const Tuple4& t, T s); 123 | friend Tuple4 operator*<> (T s, const Tuple4& t); 124 | 125 | void operator*= (T s) { 126 | scale(s); 127 | } 128 | 129 | friend Tuple4 operator/<> (const Tuple4& t, T s); 130 | 131 | void operator/= (T s) { 132 | scale(1.0 / s); 133 | } 134 | 135 | bool operator== (const Tuple4& t) const { 136 | return (x == t.x && y == t.y && z == t.z && w = t.w); 137 | } 138 | 139 | bool operator== (T s) const { 140 | return ((x * x + y * y + z * z + w * w) == s); 141 | } 142 | 143 | bool operator!= (const Tuple4& t) const { 144 | return !(*this == t); 145 | } 146 | 147 | bool operator!= (T s) const { 148 | return !(*this == s); 149 | } 150 | 151 | T& operator[] (unsigned index) { 152 | return this->*_t[index]; 153 | } 154 | 155 | const T& operator[] (unsigned index) const { 156 | return this->*_t[index]; 157 | } 158 | 159 | T& operator() (unsigned index) { 160 | if (index >= _nElements) { 161 | throw std::out_of_range("Subscript index out of range"); 162 | } 163 | 164 | return this->*_t[index]; 165 | } 166 | 167 | const T& operator() (unsigned index) const { 168 | if (index >= _nElements) { 169 | throw std::out_of_range("Subscript index out of range"); 170 | } 171 | 172 | return this->*_t[index]; 173 | } 174 | 175 | friend std::ostream& operator<< (std::ostream &os, const Tuple4& t) { 176 | os << t.toString(); 177 | return os; 178 | } 179 | 180 | void absolute () { 181 | if (x < 0) x = 0 - x; 182 | if (y < 0) y = 0 - y; 183 | if (z < 0) z = 0 - z; 184 | if (w < 0) w = 0 - w; 185 | } 186 | 187 | void add (T s) { 188 | x += s; 189 | y += s; 190 | z += s; 191 | w += s; 192 | } 193 | 194 | void add (const Tuple4& t) { 195 | x += t.x; 196 | y += t.y; 197 | z += t.z; 198 | w += t.w; 199 | } 200 | 201 | void clamp (T min, T max) { 202 | clampMin(min); 203 | clampMax(max); 204 | } 205 | 206 | void clampMax (T max) { 207 | if (x > max) x = max; 208 | if (y > max) y = max; 209 | if (z > max) z = max; 210 | if (w > max) w = max; 211 | } 212 | 213 | void clampMin (T min) { 214 | if (x < min) x = min; 215 | if (y < min) y = min; 216 | if (z < min) z = min; 217 | if (w < min) w = min; 218 | } 219 | 220 | bool equals (const Tuple4& t) const { 221 | return (x == t.x && y == t.y && z == t.z && w = t.w); 222 | } 223 | 224 | bool epsilonEquals (const Tuple4& t, T epsilon) const { 225 | return (x * x + y * y + z * z + w * w) <= (epsilon * epsilon); 226 | } 227 | 228 | void get (T* p) const { 229 | p[0] = x; 230 | p[1] = y; 231 | p[2] = z; 232 | p[3] = w; 233 | } 234 | 235 | T getElement (unsigned index) const { 236 | if (index >= _nElements) { 237 | throw std::out_of_range("Subscript index out of range"); 238 | } 239 | 240 | return this->*_t[index]; 241 | } 242 | 243 | void interpolate (const Tuple4& t, float alpha) { 244 | x = (1.f - alpha) * x + alpha * t.x; 245 | y = (1.f - alpha) * y + alpha * t.y; 246 | z = (1.f - alpha) * z + alpha * t.z; 247 | w = (1.f - alpha) * w + alpha * t.w; 248 | } 249 | 250 | void negate () { 251 | scale(-1.f); 252 | } 253 | 254 | void scale (T s) { 255 | x *= s; 256 | y *= s; 257 | z *= s; 258 | w *= s; 259 | } 260 | 261 | void scaleAdd (T s, T a) { 262 | x = x * s + a; 263 | y = y * s + a; 264 | z = z * s + a; 265 | w = w * s + a; 266 | } 267 | 268 | void scaleAdd (T s, const Tuple4& t) { 269 | x = x * s + t.x; 270 | y = y * s + t.y; 271 | z = z * s + t.z; 272 | w = w * s + t.w; 273 | } 274 | 275 | void set (T s) { 276 | x = s; 277 | y = s; 278 | z = s; 279 | w = s; 280 | } 281 | 282 | void set (T fx, T fy, T fz, T fw) { 283 | x = fx; 284 | y = fy; 285 | z = fz; 286 | w = fw; 287 | } 288 | 289 | void set (const Tuple4& t) { 290 | x = t.x; 291 | y = t.y; 292 | z = t.z; 293 | w = t.w; 294 | } 295 | 296 | void set (const T* p) { 297 | x = p[0]; 298 | y = p[1]; 299 | z = p[2]; 300 | w = p[3]; 301 | } 302 | 303 | void setElement (unsigned index, T s){ 304 | if (index >= _nElements) { 305 | throw std::out_of_range("Subscript index out of range"); 306 | } 307 | 308 | this->*_t[index] = s; 309 | } 310 | 311 | void sub (T s) { 312 | x -= s; 313 | y -= s; 314 | z -= s; 315 | w -= s; 316 | } 317 | 318 | void sub (const Tuple4& t) { 319 | x -= t.x; 320 | y -= t.y; 321 | z -= t.z; 322 | w -= t.w; 323 | } 324 | 325 | std::string toString () const { 326 | std::stringstream str; 327 | str.precision(3); 328 | 329 | str << "("; 330 | str << std::setw(8) << std::fixed << x << ","; 331 | str << std::setw(8) << std::fixed << y << ","; 332 | str << std::setw(8) << std::fixed << z << ","; 333 | str << std::setw(8) << std::fixed << w; 334 | str << ")"; 335 | 336 | return str.str(); 337 | } 338 | }; 339 | 340 | template 341 | const typename Tuple4::TRef Tuple4::_t = { 342 | &Tuple4::x, 343 | &Tuple4::y, 344 | &Tuple4::z, 345 | &Tuple4::w 346 | }; 347 | 348 | typedef Tuple4 Tuple4b; 349 | typedef Tuple4 Tuple4d; 350 | typedef Tuple4 Tuple4f; 351 | typedef Tuple4 Tuple4i; 352 | 353 | } 354 | 355 | #endif /* VMATH_TUPLE4_H_ */ 356 | -------------------------------------------------------------------------------- /src/vecmath/Vecmath.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef VMATH_VECMATH_H_ 27 | #define VMATH_VECMATH_H_ 28 | 29 | namespace vmath { 30 | 31 | const double PI = 3.14159265; 32 | 33 | template 34 | class Matrix3; 35 | 36 | template 37 | class Matrix4; 38 | 39 | template 40 | class Tuple2; 41 | 42 | template 43 | class Tuple3; 44 | 45 | template 46 | class Tuple4; 47 | 48 | template 49 | class Vector2; 50 | 51 | template 52 | class Vector2_T; 53 | 54 | template 55 | class Vector3; 56 | 57 | template 58 | class Vector3_T; 59 | 60 | template 61 | class Vector4; 62 | 63 | template 64 | class Vector4_T; 65 | 66 | /* Addition */ 67 | 68 | template 69 | inline Tuple2 operator+ (const Tuple2& t1, const Tuple2& t2) { 70 | Tuple2 op(t1); 71 | op.add(t2); 72 | return op; 73 | } 74 | 75 | template 76 | inline Tuple3 operator+ (const Tuple3& t1, const Tuple3& t2) { 77 | Tuple3 op(t1); 78 | op.add(t2); 79 | return op; 80 | } 81 | 82 | template 83 | inline Tuple4 operator+ (const Tuple4& t1, const Tuple4& t2) { 84 | Tuple4 op(t1); 85 | op.add(t2); 86 | return op; 87 | } 88 | 89 | template 90 | inline Matrix3 operator+ (const Matrix3& m1, const Matrix3& m2) { 91 | Matrix3 op(m1); 92 | op.add(m2); 93 | return op; 94 | } 95 | 96 | template 97 | inline Matrix4 operator+ (const Matrix4& m1, const Matrix4& m2) { 98 | Matrix4 op(m1); 99 | op.add(m2); 100 | return op; 101 | } 102 | 103 | template 104 | inline Tuple2 operator+ (const Tuple2& t, T s) { 105 | Tuple2 op(t); 106 | op.add(s); 107 | return op; 108 | } 109 | 110 | template 111 | inline Tuple3 operator+ (const Tuple3& t, T s) { 112 | Tuple3 op(t); 113 | op.add(s); 114 | return op; 115 | } 116 | 117 | template 118 | inline Tuple4 operator+ (const Tuple4& t, T s) { 119 | Tuple4 op(t); 120 | op.add(s); 121 | return op; 122 | } 123 | 124 | template 125 | inline Matrix3 operator+ (const Matrix3& m, T s) { 126 | Matrix3 op(m); 127 | op.add(s); 128 | return op; 129 | } 130 | 131 | template 132 | inline Matrix4 operator+ (const Matrix4& m, T s) { 133 | Matrix4 op(m); 134 | op.add(s); 135 | return op; 136 | } 137 | 138 | template 139 | inline Tuple2 operator+ (T s, const Tuple2& t) { 140 | Tuple2 op(s); 141 | op.add(t); 142 | return op; 143 | } 144 | 145 | template 146 | inline Tuple3 operator+ (T s, const Tuple3& t) { 147 | Tuple3 op(s); 148 | op.add(t); 149 | return op; 150 | } 151 | 152 | template 153 | inline Tuple4 operator+ (T s, const Tuple4& t) { 154 | Tuple4 op(s); 155 | op.add(t); 156 | return op; 157 | } 158 | 159 | /* Subtraction */ 160 | 161 | template 162 | inline Tuple2 operator- (const Tuple2& t1, const Tuple2& t2) { 163 | Tuple2 op(t1); 164 | op.sub(t2); 165 | return op; 166 | } 167 | 168 | template 169 | inline Tuple3 operator- (const Tuple3& t1, const Tuple3& t2) { 170 | Tuple3 op(t1); 171 | op.sub(t2); 172 | return op; 173 | } 174 | 175 | template 176 | inline Tuple4 operator- (const Tuple4& t1, const Tuple4& t2) { 177 | Tuple4 op(t1); 178 | op.sub(t2); 179 | return op; 180 | } 181 | 182 | template 183 | inline Matrix3 operator- (const Matrix3& m1, const Matrix3& m2) { 184 | Matrix3 op(m1); 185 | op.sub(m2); 186 | return op; 187 | } 188 | 189 | template 190 | inline Matrix4 operator- (const Matrix4& m1, const Matrix4& m2) { 191 | Matrix4 op(m1); 192 | op.sub(m2); 193 | return op; 194 | } 195 | 196 | template 197 | inline Tuple2 operator- (const Tuple2& t, T s) { 198 | Tuple2 op(t); 199 | op.sub(s); 200 | return op; 201 | } 202 | 203 | template 204 | inline Tuple3 operator- (const Tuple3& t, T s) { 205 | Tuple3 op(t); 206 | op.sub(s); 207 | return op; 208 | } 209 | 210 | template 211 | inline Tuple4 operator- (const Tuple4& t, T s) { 212 | Tuple4 op(t); 213 | op.sub(s); 214 | return op; 215 | } 216 | 217 | template 218 | inline Matrix3 operator- (const Matrix3& m, T s) { 219 | Matrix3 op(m); 220 | op.sub(s); 221 | return op; 222 | } 223 | 224 | template 225 | inline Matrix4 operator- (const Matrix4& m, T s) { 226 | Matrix4 op(m); 227 | op.sub(s); 228 | return op; 229 | } 230 | 231 | template 232 | inline Tuple2 operator- (T s, const Tuple2& t) { 233 | Tuple2 op(s); 234 | op.sub(t); 235 | return op; 236 | } 237 | 238 | template 239 | inline Tuple3 operator- (T s, const Tuple3& t) { 240 | Tuple3 op(s); 241 | op.sub(t); 242 | return op; 243 | } 244 | 245 | template 246 | inline Tuple4 operator- (T s, const Tuple4& t) { 247 | Tuple4 op(s); 248 | op.sub(t); 249 | return op; 250 | } 251 | 252 | /* Negation */ 253 | 254 | template 255 | inline Tuple2 operator- (const Tuple2& t) { 256 | Tuple2 op(t); 257 | op.neg(); 258 | return op; 259 | } 260 | 261 | template 262 | inline Tuple3 operator- (const Tuple3& t) { 263 | Tuple3 op(t); 264 | op.neg(); 265 | return op; 266 | } 267 | 268 | template 269 | inline Tuple4 operator- (const Tuple4& t) { 270 | Tuple4 op(t); 271 | op.neg(); 272 | return op; 273 | } 274 | 275 | /* Multiplication */ 276 | 277 | template 278 | inline Matrix3 operator* (const Matrix3& m1, const Matrix3& m2) { 279 | Matrix3 op(m1); 280 | op.mul(m2); 281 | return op; 282 | } 283 | 284 | template 285 | inline Matrix4 operator* (const Matrix4& m1, const Matrix4& m2) { 286 | Matrix4 op(m1); 287 | op.mul(m2); 288 | return op; 289 | } 290 | 291 | template 292 | inline Tuple2 operator* (const Tuple2& t, T s) { 293 | Tuple2 op(t); 294 | op.scale(s); 295 | return op; 296 | } 297 | 298 | template 299 | inline Tuple3 operator* (const Tuple3& t, T s) { 300 | Tuple3 op(t); 301 | op.scale(s); 302 | return op; 303 | } 304 | 305 | template 306 | inline Tuple4 operator* (const Tuple4& t, T s) { 307 | Tuple4 op(t); 308 | op.scale(s); 309 | return op; 310 | } 311 | 312 | template 313 | inline Matrix3 operator* (const Matrix3& m, T s) { 314 | Matrix3 op(m); 315 | op.mul(s); 316 | return op; 317 | } 318 | 319 | template 320 | inline Matrix4 operator* (const Matrix4& m, T s) { 321 | Matrix4 op(m); 322 | op.mul(s); 323 | return op; 324 | } 325 | 326 | template 327 | inline Tuple2 operator* (T s, const Tuple2& t) { 328 | Tuple2 op(t); 329 | op.scale(s); 330 | return op; 331 | } 332 | 333 | template 334 | inline Tuple3 operator* (T s, const Tuple3& t) { 335 | Tuple3 op(t); 336 | op.scale(s); 337 | return op; 338 | } 339 | 340 | template 341 | inline Tuple4 operator* (T s, const Tuple4& t) { 342 | Tuple4 op(t); 343 | op.scale(s); 344 | return op; 345 | } 346 | 347 | template 348 | inline Matrix3 operator* (T s, const Matrix3& m) { 349 | Matrix3 op(m); 350 | op.mul(s); 351 | return op; 352 | } 353 | 354 | template 355 | inline Matrix4 operator* (T s, const Matrix4& m) { 356 | Matrix4 op(m); 357 | op.mul(s); 358 | return op; 359 | } 360 | 361 | template 362 | inline Vector3 operator* (const Matrix3& m, const Vector3& v) { 363 | return m.mul(v); 364 | } 365 | 366 | template 367 | inline Vector4 operator* (const Matrix4& m, const Vector4& v) { 368 | return m.mul(v); 369 | } 370 | 371 | template 372 | inline Vector3_T operator* (const Vector3_T& vt, const Matrix3& m) { 373 | Vector3_T out; 374 | out.x = m._m[0] * vt.x + m._m[3] * vt.y + m._m[6] * vt.z; 375 | out.y = m._m[1] * vt.x + m._m[4] * vt.y + m._m[7] * vt.z; 376 | out.z = m._m[2] * vt.x + m._m[5] * vt.y + m._m[8] * vt.z; 377 | return out; 378 | } 379 | 380 | template 381 | inline Vector4_T operator* (const Vector4_T& vt, const Matrix4& m) { 382 | Vector4_T out; 383 | out.x = m._m[0] * vt.x + m._m[4] * vt.y + m._m[8] * vt.z + m._m[12] * vt.w; 384 | out.y = m._m[1] * vt.x + m._m[5] * vt.y + m._m[9] * vt.z + m._m[13] * vt.w; 385 | out.z = m._m[2] * vt.x + m._m[6] * vt.y + m._m[10] * vt.z + m._m[14] * vt.w; 386 | out.w = m._m[3] * vt.x + m._m[7] * vt.y + m._m[11] * vt.z + m._m[15] * vt.w; 387 | return out; 388 | } 389 | 390 | template 391 | inline T operator* (const Vector2_T& vt, const Vector2& v) { 392 | return vt.x * v.x + vt.y * v.y; 393 | } 394 | 395 | template 396 | inline T operator* (const Vector3_T& vt, const Vector3& v) { 397 | return vt.x * v.x + vt.y * v.y + vt.z * v.z; 398 | } 399 | 400 | template 401 | inline T operator* (const Vector4_T& vt, const Vector4& v) { 402 | return vt.x * v.x + vt.y * v.y + vt.z * v.z + vt.w * v.w; 403 | } 404 | 405 | template 406 | inline Matrix3 operator* (const Vector3& v, const Vector3_T& vt) { 407 | Matrix3 out(v.x * vt.x, v.x * vt.y, v.x * vt.z, 408 | v.y * vt.x, v.y * vt.y, v.y * vt.z, 409 | v.z * vt.x, v.z * vt.y, v.z * vt.z); 410 | return out; 411 | } 412 | 413 | template 414 | inline Matrix4 operator* (const Vector4& v, const Vector4_T& vt) { 415 | Matrix4 out(v.x * vt.x, v.x * vt.y, v.x * vt.z, v.x * vt.w, 416 | v.y * vt.x, v.y * vt.y, v.y * vt.z, v.y * vt.w, 417 | v.z * vt.x, v.z * vt.y, v.z * vt.z, v.z * vt.w, 418 | v.w * vt.x, v.w * vt.y, v.w * vt.z, v.w * vt.w); 419 | return out; 420 | } 421 | 422 | /* Division */ 423 | 424 | template 425 | inline Tuple2 operator/ (const Tuple2& m, T s) { 426 | Tuple2 op(m); 427 | op.scale(1.0 / s); 428 | return op; 429 | } 430 | 431 | template 432 | inline Tuple3 operator/ (const Tuple3& m, T s) { 433 | Tuple3 op(m); 434 | op.scale(1.0 / s); 435 | return op; 436 | } 437 | 438 | template 439 | inline Tuple4 operator/ (const Tuple4& m, T s) { 440 | Tuple4 op(m); 441 | op.scale(1.0 / s); 442 | return op; 443 | } 444 | 445 | template 446 | inline Matrix3 operator/ (const Matrix3& m, T s) { 447 | Matrix3 op(m); 448 | op.mul(1.0 / s); 449 | return op; 450 | } 451 | 452 | template 453 | inline Matrix4 operator/ (const Matrix4& m, T s) { 454 | Matrix4 op(m); 455 | op.mul(1.0 / s); 456 | return op; 457 | } 458 | 459 | } 460 | 461 | #include "Tuple2.h" 462 | #include "Tuple3.h" 463 | #include "Tuple4.h" 464 | #include "Vector2.h" 465 | #include "Vector3.h" 466 | #include "Vector4.h" 467 | #include "Matrix3.h" 468 | #include "Matrix4.h" 469 | 470 | #endif /* VMATH_VECMATH_H_ */ 471 | -------------------------------------------------------------------------------- /src/vecmath/Vector2.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef VMATH_VECTOR2_H_ 27 | #define VMATH_VECTOR2_H_ 28 | 29 | #include 30 | #include "Vecmath.h" 31 | 32 | namespace vmath { 33 | 34 | template 35 | class Vector2 : public Tuple2 { 36 | public: 37 | 38 | using Tuple2::x; 39 | using Tuple2::y; 40 | 41 | static const Vector2 UNIT_X; 42 | static const Vector2 UNIT_Y; 43 | 44 | public: 45 | 46 | Vector2 () 47 | : Tuple2() { 48 | } 49 | 50 | Vector2 (T s) 51 | : Tuple2(s) { 52 | } 53 | 54 | Vector2 (T fx, T fy) 55 | : Tuple2(fx, fy) { 56 | } 57 | 58 | Vector2 (const Tuple2& t2f) 59 | : Tuple2(t2f) { 60 | } 61 | 62 | Vector2 (const T* p) 63 | : Tuple2(p) { 64 | } 65 | 66 | //virtual ~Vector2 () { } 67 | 68 | T angle (const Vector2& v2f) const { 69 | Vector2 a(*this); 70 | Vector2 b(v2f); 71 | a.normalize(); 72 | b.normalize(); 73 | return acos(a.dot(b)); 74 | } 75 | 76 | T dot (const Vector2& v2f) const { 77 | return x * v2f.x + y * v2f.y; 78 | } 79 | 80 | T length () const { 81 | return sqrt (lengthSquared()); 82 | } 83 | 84 | T lengthSquared () const { 85 | return x * x + y * y; 86 | } 87 | 88 | void normalize () { 89 | T mag = length(); 90 | if (mag != 0) { 91 | x /= mag; 92 | y /= mag; 93 | } 94 | } 95 | 96 | Vector2 normalized () const { 97 | Vector2 op(*this); 98 | op.normalize(); 99 | return op; 100 | } 101 | 102 | Vector2_T transpose () const { 103 | Vector2_T op(*this); 104 | return op; 105 | } 106 | }; 107 | 108 | template 109 | const Vector2 Vector2::UNIT_X(1, 0); 110 | 111 | template 112 | const Vector2 Vector2::UNIT_Y(0, 1); 113 | 114 | 115 | typedef Vector2 Vector2d; 116 | typedef Vector2 Vector2f; 117 | 118 | /** 119 | * Transpose vector, useful for some matrix arithmetic. 120 | */ 121 | 122 | template 123 | class Vector2_T : public Tuple2 { 124 | public: 125 | 126 | Vector2_T () 127 | : Tuple2() { 128 | } 129 | 130 | Vector2_T (T s) 131 | : Tuple2(s) { 132 | } 133 | 134 | Vector2_T (T fx, T fy) 135 | : Tuple2(fx, fy) { 136 | } 137 | 138 | Vector2_T (const Tuple2& t2f) 139 | : Tuple2(t2f) { 140 | } 141 | 142 | Vector2_T (const Tuple2* t2f) 143 | : Tuple2(t2f) { 144 | } 145 | 146 | Vector2_T (const T* p) 147 | : Tuple2(p) { 148 | } 149 | 150 | //virtual ~Vector2_T () { } 151 | 152 | Vector2 transpose () const { 153 | Vector2 op(*this); 154 | return op; 155 | } 156 | 157 | }; 158 | 159 | typedef Vector2_T Vector2d_T; 160 | typedef Vector2_T Vector2f_T; 161 | } 162 | 163 | #endif /* VMATH_VECTOR2_H_ */ 164 | -------------------------------------------------------------------------------- /src/vecmath/Vector3.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef VMATH_VECTOR3_H_ 27 | #define VMATH_VECTOR3_H_ 28 | 29 | #include 30 | #include "Vecmath.h" 31 | 32 | namespace vmath { 33 | 34 | template 35 | class Vector3 : public Tuple3 { 36 | public: 37 | 38 | using Tuple3::x; 39 | using Tuple3::y; 40 | using Tuple3::z; 41 | 42 | static const Vector3 UNIT_X; 43 | static const Vector3 UNIT_Y; 44 | static const Vector3 UNIT_Z; 45 | 46 | public: 47 | 48 | Vector3 () 49 | : Tuple3() { 50 | } 51 | 52 | Vector3 (T s) 53 | : Tuple3(s) { 54 | } 55 | 56 | Vector3 (T fx, T fy, T fz) 57 | : Tuple3(fx, fy, fz) { 58 | } 59 | 60 | Vector3 (const Tuple3& t3f) 61 | : Tuple3(t3f) { 62 | } 63 | 64 | Vector3 (const Tuple3* t3f) 65 | : Tuple3(t3f) { 66 | } 67 | 68 | Vector3 (const T* p) 69 | : Tuple3(p) { 70 | } 71 | 72 | //virtual ~Vector3 () { } 73 | 74 | T angle (const Vector3& v3f) const { 75 | Vector3 a(*this); 76 | Vector3 b(v3f); 77 | a.normalize(); 78 | b.normalize(); 79 | return acos(a.dot(b)); 80 | } 81 | 82 | Vector3 cross (const Vector3& v3f) const { 83 | T i = y * v3f.z - z * v3f.y; 84 | T j = z * v3f.x - x * v3f.z; 85 | T k = x * v3f.y - y * v3f.x; 86 | return Vector3(i, j, k); 87 | } 88 | 89 | T dot (const Vector3& v3f) const { 90 | return x * v3f.x + y * v3f.y + z * v3f.z; 91 | } 92 | 93 | T length () const { 94 | return sqrt (lengthSquared()); 95 | } 96 | 97 | T lengthSquared () const { 98 | return x * x + y * y + z * z; 99 | } 100 | 101 | void normalize () { 102 | T mag = length(); 103 | if (mag != 0) { 104 | x /= mag; 105 | y /= mag; 106 | z /= mag; 107 | } 108 | } 109 | 110 | Vector3 normalized () const { 111 | Vector3 op(*this); 112 | op.normalize(); 113 | return op; 114 | } 115 | 116 | Vector3_T transpose () const { 117 | Vector3_T op(*this); 118 | return op; 119 | } 120 | }; 121 | 122 | template 123 | const Vector3 Vector3::UNIT_X(1, 0, 0); 124 | 125 | template 126 | const Vector3 Vector3::UNIT_Y(0, 1, 0); 127 | 128 | template 129 | const Vector3 Vector3::UNIT_Z(0, 0, 1); 130 | 131 | 132 | typedef Vector3 Vector3d; 133 | typedef Vector3 Vector3f; 134 | 135 | /** 136 | * Transpose vector, useful for some matrix arithmetic. 137 | */ 138 | 139 | template 140 | class Vector3_T : public Tuple3 { 141 | public: 142 | 143 | Vector3_T () 144 | : Tuple3() { 145 | } 146 | 147 | Vector3_T (T s) 148 | : Tuple3(s) { 149 | } 150 | 151 | Vector3_T (T fx, T fy, T fz) 152 | : Tuple3(fx, fy, fz) { 153 | } 154 | 155 | Vector3_T (const Tuple3& t3f) 156 | : Tuple3(t3f) { 157 | } 158 | 159 | Vector3_T (const T* p) 160 | : Tuple3(p) { 161 | } 162 | 163 | //virtual ~Vector3_T () { } 164 | 165 | Vector3 transpose () const { 166 | Vector3 op(*this); 167 | return op; 168 | } 169 | 170 | }; 171 | 172 | typedef Vector3_T Vector3d_T; 173 | typedef Vector3_T Vector3f_T; 174 | } 175 | 176 | #endif /* VMATH_VECTOR3_H_ */ 177 | -------------------------------------------------------------------------------- /src/vecmath/Vector4.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2009 Justin Aquadro 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef VMATH_VECTOR4_H_ 27 | #define VMATH_VECTOR4_H_ 28 | 29 | #include 30 | #include "Vecmath.h" 31 | 32 | namespace vmath { 33 | 34 | template 35 | class Vector4 : public Tuple4 { 36 | public: 37 | 38 | using Tuple4::x; 39 | using Tuple4::y; 40 | using Tuple4::z; 41 | using Tuple4::w; 42 | 43 | static const Vector4 UNIT_X; 44 | static const Vector4 UNIT_Y; 45 | static const Vector4 UNIT_Z; 46 | static const Vector4 UNIT_W; 47 | 48 | public: 49 | 50 | Vector4 () 51 | : Tuple4() { 52 | } 53 | 54 | Vector4 (T s) 55 | : Tuple4(s) { 56 | } 57 | 58 | Vector4 (T fx, T fy, T fz, T wz) 59 | : Tuple4(fx, fy, fz, wz) { 60 | } 61 | 62 | Vector4 (const Tuple3& t3f, T s) 63 | : Tuple4(t3f, s) { 64 | } 65 | 66 | Vector4 (const Tuple4& t4f) 67 | : Tuple4(t4f) { 68 | } 69 | 70 | Vector4 (const Tuple4* t4f) 71 | : Tuple4(t4f) { 72 | } 73 | 74 | Vector4 (const T* p) 75 | : Tuple4(p) { 76 | } 77 | 78 | //virtual ~Vector4 () { } 79 | 80 | T angle (const Vector4& v4f) const { 81 | Vector4 a(*this); 82 | Vector4 b(v4f); 83 | a.normalize(); 84 | b.normalize(); 85 | return acos(a.dot(b)); 86 | } 87 | 88 | T dot (const Vector4& v4f) const { 89 | return x * v4f.x + y * v4f.y + z * v4f.z + w * v4f.w; 90 | } 91 | 92 | T length () const { 93 | return sqrt (lengthSquared()); 94 | } 95 | 96 | T lengthSquared () const { 97 | return x * x + y * y + z * z + w * w; 98 | } 99 | 100 | void normalize () { 101 | T mag = length(); 102 | if (mag != 0) { 103 | x /= mag; 104 | y /= mag; 105 | z /= mag; 106 | w /= mag; 107 | } 108 | } 109 | 110 | Vector4 normalized () const { 111 | Vector4 op(*this); 112 | op.normalize(); 113 | return op; 114 | } 115 | 116 | Vector4_T transpose () const { 117 | Vector4_T op(*this); 118 | return op; 119 | } 120 | }; 121 | 122 | template 123 | const Vector4 Vector4::UNIT_X(1, 0, 0, 0); 124 | 125 | template 126 | const Vector4 Vector4::UNIT_Y(0, 1, 0, 0); 127 | 128 | template 129 | const Vector4 Vector4::UNIT_Z(0, 0, 1, 0); 130 | 131 | template 132 | const Vector4 Vector4::UNIT_W(0, 0, 0, 1); 133 | 134 | typedef Vector4 Vector4d; 135 | typedef Vector4 Vector4f; 136 | 137 | /** 138 | * Transpose vector, useful for some matrix arithmetic. 139 | */ 140 | 141 | template 142 | class Vector4_T : public Tuple4 { 143 | public: 144 | 145 | Vector4_T () 146 | : Tuple4() { 147 | } 148 | 149 | Vector4_T (T s) 150 | : Tuple4(s) { 151 | } 152 | 153 | Vector4_T (T fx, T fy, T fz) 154 | : Tuple4(fx, fy, fz) { 155 | } 156 | 157 | Vector4_T (const Tuple4& t3f) 158 | : Tuple4(t3f) { 159 | } 160 | 161 | Vector4_T (const T* p) 162 | : Tuple4(p) { 163 | } 164 | 165 | //virtual ~Vector4_T () { } 166 | 167 | Vector4 transpose () const { 168 | Vector4 op(*this); 169 | return op; 170 | } 171 | 172 | }; 173 | 174 | typedef Vector4_T Vector4d_T; 175 | typedef Vector4_T Vector4f_T; 176 | 177 | } 178 | 179 | #endif /* VMATH_VECTOR4_H_ */ 180 | --------------------------------------------------------------------------------