From 1fefea03ada9881337a6819c3ba8e9f11fc00af9 Mon Sep 17 00:00:00 2001 From: Reuben Chao Date: Thu, 5 Feb 2015 01:57:50 +0800 Subject: [PATCH] new file: build/proj_mac/AppDelegate.h new file: build/proj_mac/AppDelegate.mm new file: build/proj_mac/Contents.json new file: build/proj_mac/Info.plist new file: build/proj_mac/MainMenu.xib new file: build/proj_mac/OpenGLView.h new file: build/proj_mac/OpenGLView.mm new file: build/proj_mac/main.m new file: build/proj_mac/proj_mac.xcodeproj/project.pbxproj new file: build/proj_mac/proj_mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file: build/proj_mac/proj_mac.xcodeproj/project.xcworkspace/xcuserdata/reuben.xcuserdatad/UserInterfaceState.xcuserstate new file: build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file: build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcschemes/proj_mac.xcscheme new file: build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcschemes/xcschememanagement.plist new file: external/kazmath/GL/mat4stack.c new file: external/kazmath/GL/mat4stack.h new file: external/kazmath/GL/matrix.c new file: external/kazmath/GL/matrix.h new file: external/kazmath/aabb.c new file: external/kazmath/aabb.h new file: external/kazmath/kazmath.h new file: external/kazmath/mat3.c new file: external/kazmath/mat3.h new file: external/kazmath/mat4.c new file: external/kazmath/mat4.h new file: external/kazmath/plane.c new file: external/kazmath/plane.h new file: external/kazmath/quaternion.c new file: external/kazmath/quaternion.h new file: external/kazmath/ray2.c new file: external/kazmath/ray2.h new file: external/kazmath/utility.c new file: external/kazmath/utility.h new file: external/kazmath/vec2.c new file: external/kazmath/vec2.h new file: external/kazmath/vec3.c new file: external/kazmath/vec3.h new file: external/kazmath/vec4.c new file: external/kazmath/vec4.h new file: sample/sample_ocean/OceanDelegate.h new file: tiny3d_main/RenderQueueGroup.cpp new file: tiny3d_main/RenderQueueGroup.h new file: tiny3d_main/RenderSystem.cpp new file: tiny3d_main/RenderSystem.h new file: tiny3d_main/TinyCamera.cpp new file: tiny3d_main/TinyCamera.h new file: tiny3d_main/TinyDelegate.cpp new file: tiny3d_main/TinyDelegate.h new file: tiny3d_main/TinyEntity.cpp new file: tiny3d_main/TinyEntity.h new file: tiny3d_main/TinyGPUProgram.cpp new file: tiny3d_main/TinyGPUProgram.h new file: tiny3d_main/TinyGPUProgramManager.cpp new file: tiny3d_main/TinyGPUProgramManager.h new file: tiny3d_main/TinyInputManager.cpp new file: tiny3d_main/TinyInputManager.h new file: tiny3d_main/TinyInputObject.cpp new file: tiny3d_main/TinyInputObject.h new file: tiny3d_main/TinyKeyboard.cpp new file: tiny3d_main/TinyKeyboard.h new file: tiny3d_main/TinyLight.cpp new file: tiny3d_main/TinyLight.h new file: tiny3d_main/TinyMaterial.cpp new file: tiny3d_main/TinyMaterial.h new file: tiny3d_main/TinyMath.cpp new file: tiny3d_main/TinyMath.h new file: tiny3d_main/TinyMesh.cpp new file: tiny3d_main/TinyMesh.h new file: tiny3d_main/TinyMouse.cpp new file: tiny3d_main/TinyMouse.h new file: tiny3d_main/TinyMovableObject.cpp new file: tiny3d_main/TinyMovableObject.h new file: tiny3d_main/TinyObject.cpp new file: tiny3d_main/TinyObject.h new file: tiny3d_main/TinyRenderQueue.cpp new file: tiny3d_main/TinyRenderQueue.h new file: tiny3d_main/TinyRenderQueueSortingQrouping.cpp new file: tiny3d_main/TinyRenderQueueSortingQrouping.h new file: tiny3d_main/TinyRenderSystem.cpp new file: tiny3d_main/TinyRenderSystem.h new file: tiny3d_main/TinyRenderTarget.cpp new file: tiny3d_main/TinyRenderTarget.h new file: tiny3d_main/TinyRenderTexture.cpp new file: tiny3d_main/TinyRenderTexture.h new file: tiny3d_main/TinyRenderWindow.cpp new file: tiny3d_main/TinyRenderWindow.h new file: tiny3d_main/TinyRenderable.cpp new file: tiny3d_main/TinyRenderable.h new file: tiny3d_main/TinyResourceManager.cpp new file: tiny3d_main/TinyResourceManager.h new file: tiny3d_main/TinyRoot.cpp new file: tiny3d_main/TinyRoot.h new file: tiny3d_main/TinySceneManager.cpp new file: tiny3d_main/TinySceneManager.h new file: tiny3d_main/TinySceneNode.cpp new file: tiny3d_main/TinySceneNode.h new file: tiny3d_main/TinySchedulerManager.cpp new file: tiny3d_main/TinySchedulerManager.h new file: tiny3d_main/TinyTexture.cpp new file: tiny3d_main/TinyTexture.h new file: tiny3d_main/TinyTextureManager.cpp new file: tiny3d_main/TinyTextureManager.h new file: tiny3d_main/TinyViewPort.cpp new file: tiny3d_main/TinyViewPort.h --- build/proj_mac/AppDelegate.h | 15 + build/proj_mac/AppDelegate.mm | 42 + build/proj_mac/Contents.json | 58 ++ build/proj_mac/Info.plist | 34 + build/proj_mac/MainMenu.xib | 680 +++++++++++++++ build/proj_mac/OpenGLView.h | 30 + build/proj_mac/OpenGLView.mm | 229 +++++ build/proj_mac/main.m | 13 + .../proj_mac.xcodeproj/project.pbxproj | 597 +++++++++++++ .../contents.xcworkspacedata | 7 + .../UserInterfaceState.xcuserstate | Bin 0 -> 50604 bytes .../xcdebugger/Breakpoints_v2.xcbkptlist | 71 ++ .../xcschemes/proj_mac.xcscheme | 110 +++ .../xcschemes/xcschememanagement.plist | 27 + external/kazmath/GL/mat4stack.c | 74 ++ external/kazmath/GL/mat4stack.h | 51 ++ external/kazmath/GL/matrix.c | 323 +++++++ external/kazmath/GL/matrix.h | 63 ++ external/kazmath/aabb.c | 140 +++ external/kazmath/aabb.h | 61 ++ external/kazmath/kazmath.h | 39 + external/kazmath/mat3.c | 427 +++++++++ external/kazmath/mat3.h | 84 ++ external/kazmath/mat4.c | 810 ++++++++++++++++++ external/kazmath/mat4.h | 95 ++ external/kazmath/plane.c | 237 +++++ external/kazmath/plane.h | 73 ++ external/kazmath/quaternion.c | 533 ++++++++++++ external/kazmath/quaternion.h | 113 +++ external/kazmath/ray2.c | 199 +++++ external/kazmath/ray2.h | 54 ++ external/kazmath/utility.c | 59 ++ external/kazmath/utility.h | 93 ++ external/kazmath/vec2.c | 213 +++++ external/kazmath/vec2.h | 69 ++ external/kazmath/vec3.c | 399 +++++++++ external/kazmath/vec3.h | 73 ++ external/kazmath/vec4.c | 158 ++++ external/kazmath/vec4.h | 70 ++ sample/sample_ocean/OceanDelegate.h | 13 + tiny3d_main/RenderQueueGroup.cpp | 9 + tiny3d_main/RenderQueueGroup.h | 14 + tiny3d_main/RenderSystem.cpp | 9 + tiny3d_main/RenderSystem.h | 14 + tiny3d_main/TinyCamera.cpp | 120 +++ tiny3d_main/TinyCamera.h | 32 + tiny3d_main/TinyDelegate.cpp | 41 + tiny3d_main/TinyDelegate.h | 30 + tiny3d_main/TinyEntity.cpp | 9 + tiny3d_main/TinyEntity.h | 13 + tiny3d_main/TinyGPUProgram.cpp | 9 + tiny3d_main/TinyGPUProgram.h | 28 + tiny3d_main/TinyGPUProgramManager.cpp | 111 +++ tiny3d_main/TinyGPUProgramManager.h | 20 + tiny3d_main/TinyInputManager.cpp | 95 ++ tiny3d_main/TinyInputManager.h | 44 + tiny3d_main/TinyInputObject.cpp | 9 + tiny3d_main/TinyInputObject.h | 23 + tiny3d_main/TinyKeyboard.cpp | 64 ++ tiny3d_main/TinyKeyboard.h | 55 ++ tiny3d_main/TinyLight.cpp | 9 + tiny3d_main/TinyLight.h | 14 + tiny3d_main/TinyMaterial.cpp | 9 + tiny3d_main/TinyMaterial.h | 14 + tiny3d_main/TinyMath.cpp | 29 + tiny3d_main/TinyMath.h | 22 + tiny3d_main/TinyMesh.cpp | 9 + tiny3d_main/TinyMesh.h | 13 + tiny3d_main/TinyMouse.cpp | 86 ++ tiny3d_main/TinyMouse.h | 73 ++ tiny3d_main/TinyMovableObject.cpp | 9 + tiny3d_main/TinyMovableObject.h | 22 + tiny3d_main/TinyObject.cpp | 9 + tiny3d_main/TinyObject.h | 21 + tiny3d_main/TinyRenderQueue.cpp | 9 + tiny3d_main/TinyRenderQueue.h | 13 + .../TinyRenderQueueSortingQrouping.cpp | 9 + tiny3d_main/TinyRenderQueueSortingQrouping.h | 14 + tiny3d_main/TinyRenderSystem.cpp | 26 + tiny3d_main/TinyRenderSystem.h | 41 + tiny3d_main/TinyRenderTarget.cpp | 9 + tiny3d_main/TinyRenderTarget.h | 23 + tiny3d_main/TinyRenderTexture.cpp | 9 + tiny3d_main/TinyRenderTexture.h | 14 + tiny3d_main/TinyRenderWindow.cpp | 9 + tiny3d_main/TinyRenderWindow.h | 14 + tiny3d_main/TinyRenderable.cpp | 9 + tiny3d_main/TinyRenderable.h | 13 + tiny3d_main/TinyResourceManager.cpp | 9 + tiny3d_main/TinyResourceManager.h | 14 + tiny3d_main/TinyRoot.cpp | 60 ++ tiny3d_main/TinyRoot.h | 28 + tiny3d_main/TinySceneManager.cpp | 9 + tiny3d_main/TinySceneManager.h | 13 + tiny3d_main/TinySceneNode.cpp | 9 + tiny3d_main/TinySceneNode.h | 13 + tiny3d_main/TinySchedulerManager.cpp | 44 + tiny3d_main/TinySchedulerManager.h | 30 + tiny3d_main/TinyTexture.cpp | 9 + tiny3d_main/TinyTexture.h | 13 + tiny3d_main/TinyTextureManager.cpp | 220 +++++ tiny3d_main/TinyTextureManager.h | 25 + tiny3d_main/TinyViewPort.cpp | 11 + tiny3d_main/TinyViewPort.h | 13 + 104 files changed, 8256 insertions(+) create mode 100644 build/proj_mac/AppDelegate.h create mode 100644 build/proj_mac/AppDelegate.mm create mode 100644 build/proj_mac/Contents.json create mode 100644 build/proj_mac/Info.plist create mode 100644 build/proj_mac/MainMenu.xib create mode 100644 build/proj_mac/OpenGLView.h create mode 100644 build/proj_mac/OpenGLView.mm create mode 100644 build/proj_mac/main.m create mode 100644 build/proj_mac/proj_mac.xcodeproj/project.pbxproj create mode 100644 build/proj_mac/proj_mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 build/proj_mac/proj_mac.xcodeproj/project.xcworkspace/xcuserdata/reuben.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist create mode 100644 build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcschemes/proj_mac.xcscheme create mode 100644 build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100755 external/kazmath/GL/mat4stack.c create mode 100755 external/kazmath/GL/mat4stack.h create mode 100755 external/kazmath/GL/matrix.c create mode 100755 external/kazmath/GL/matrix.h create mode 100755 external/kazmath/aabb.c create mode 100755 external/kazmath/aabb.h create mode 100755 external/kazmath/kazmath.h create mode 100755 external/kazmath/mat3.c create mode 100755 external/kazmath/mat3.h create mode 100755 external/kazmath/mat4.c create mode 100755 external/kazmath/mat4.h create mode 100755 external/kazmath/plane.c create mode 100755 external/kazmath/plane.h create mode 100755 external/kazmath/quaternion.c create mode 100755 external/kazmath/quaternion.h create mode 100755 external/kazmath/ray2.c create mode 100755 external/kazmath/ray2.h create mode 100755 external/kazmath/utility.c create mode 100755 external/kazmath/utility.h create mode 100755 external/kazmath/vec2.c create mode 100755 external/kazmath/vec2.h create mode 100755 external/kazmath/vec3.c create mode 100755 external/kazmath/vec3.h create mode 100755 external/kazmath/vec4.c create mode 100755 external/kazmath/vec4.h create mode 100644 sample/sample_ocean/OceanDelegate.h create mode 100644 tiny3d_main/RenderQueueGroup.cpp create mode 100644 tiny3d_main/RenderQueueGroup.h create mode 100644 tiny3d_main/RenderSystem.cpp create mode 100644 tiny3d_main/RenderSystem.h create mode 100755 tiny3d_main/TinyCamera.cpp create mode 100755 tiny3d_main/TinyCamera.h create mode 100644 tiny3d_main/TinyDelegate.cpp create mode 100644 tiny3d_main/TinyDelegate.h create mode 100644 tiny3d_main/TinyEntity.cpp create mode 100644 tiny3d_main/TinyEntity.h create mode 100644 tiny3d_main/TinyGPUProgram.cpp create mode 100644 tiny3d_main/TinyGPUProgram.h create mode 100755 tiny3d_main/TinyGPUProgramManager.cpp create mode 100755 tiny3d_main/TinyGPUProgramManager.h create mode 100755 tiny3d_main/TinyInputManager.cpp create mode 100755 tiny3d_main/TinyInputManager.h create mode 100644 tiny3d_main/TinyInputObject.cpp create mode 100644 tiny3d_main/TinyInputObject.h create mode 100644 tiny3d_main/TinyKeyboard.cpp create mode 100644 tiny3d_main/TinyKeyboard.h create mode 100644 tiny3d_main/TinyLight.cpp create mode 100644 tiny3d_main/TinyLight.h create mode 100644 tiny3d_main/TinyMaterial.cpp create mode 100644 tiny3d_main/TinyMaterial.h create mode 100644 tiny3d_main/TinyMath.cpp create mode 100644 tiny3d_main/TinyMath.h create mode 100644 tiny3d_main/TinyMesh.cpp create mode 100644 tiny3d_main/TinyMesh.h create mode 100644 tiny3d_main/TinyMouse.cpp create mode 100644 tiny3d_main/TinyMouse.h create mode 100644 tiny3d_main/TinyMovableObject.cpp create mode 100644 tiny3d_main/TinyMovableObject.h create mode 100644 tiny3d_main/TinyObject.cpp create mode 100644 tiny3d_main/TinyObject.h create mode 100644 tiny3d_main/TinyRenderQueue.cpp create mode 100644 tiny3d_main/TinyRenderQueue.h create mode 100644 tiny3d_main/TinyRenderQueueSortingQrouping.cpp create mode 100644 tiny3d_main/TinyRenderQueueSortingQrouping.h create mode 100644 tiny3d_main/TinyRenderSystem.cpp create mode 100644 tiny3d_main/TinyRenderSystem.h create mode 100644 tiny3d_main/TinyRenderTarget.cpp create mode 100644 tiny3d_main/TinyRenderTarget.h create mode 100644 tiny3d_main/TinyRenderTexture.cpp create mode 100644 tiny3d_main/TinyRenderTexture.h create mode 100644 tiny3d_main/TinyRenderWindow.cpp create mode 100644 tiny3d_main/TinyRenderWindow.h create mode 100644 tiny3d_main/TinyRenderable.cpp create mode 100644 tiny3d_main/TinyRenderable.h create mode 100644 tiny3d_main/TinyResourceManager.cpp create mode 100644 tiny3d_main/TinyResourceManager.h create mode 100644 tiny3d_main/TinyRoot.cpp create mode 100644 tiny3d_main/TinyRoot.h create mode 100644 tiny3d_main/TinySceneManager.cpp create mode 100644 tiny3d_main/TinySceneManager.h create mode 100644 tiny3d_main/TinySceneNode.cpp create mode 100644 tiny3d_main/TinySceneNode.h create mode 100644 tiny3d_main/TinySchedulerManager.cpp create mode 100644 tiny3d_main/TinySchedulerManager.h create mode 100644 tiny3d_main/TinyTexture.cpp create mode 100644 tiny3d_main/TinyTexture.h create mode 100755 tiny3d_main/TinyTextureManager.cpp create mode 100755 tiny3d_main/TinyTextureManager.h create mode 100644 tiny3d_main/TinyViewPort.cpp create mode 100644 tiny3d_main/TinyViewPort.h diff --git a/build/proj_mac/AppDelegate.h b/build/proj_mac/AppDelegate.h new file mode 100644 index 0000000..5dc5815 --- /dev/null +++ b/build/proj_mac/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + +@property (weak) IBOutlet NSWindow *window; + +@end \ No newline at end of file diff --git a/build/proj_mac/AppDelegate.mm b/build/proj_mac/AppDelegate.mm new file mode 100644 index 0000000..be9bac8 --- /dev/null +++ b/build/proj_mac/AppDelegate.mm @@ -0,0 +1,42 @@ +// +// AppDelegate.m +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#import "AppDelegate.h" +#import "OpenGLView.h" + + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application + NSOpenGLPixelFormatAttribute attributes[] = { + NSOpenGLPFAColorSize, 32, + NSOpenGLPFADepthSize, 16, + NSOpenGLPFAStencilSize, 8, + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAAccelerated, + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, + 0 + }; + + NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; + if (pixelFormat == nil) { + NSLog(@"Faild create pixel format"); + return; + } + + NSOpenGLView *view = [[OpenGLView alloc] initWithFrame:self.window.frame pixelFormat:pixelFormat]; + + [self.window setContentView:view]; +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/build/proj_mac/Contents.json b/build/proj_mac/Contents.json new file mode 100644 index 0000000..2db2b1c --- /dev/null +++ b/build/proj_mac/Contents.json @@ -0,0 +1,58 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/build/proj_mac/Info.plist b/build/proj_mac/Info.plist new file mode 100644 index 0000000..c0a6678 --- /dev/null +++ b/build/proj_mac/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + com.reuben.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2015 reuben chao. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/build/proj_mac/MainMenu.xib b/build/proj_mac/MainMenu.xib new file mode 100644 index 0000000..103906c --- /dev/null +++ b/build/proj_mac/MainMenu.xib @@ -0,0 +1,680 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/proj_mac/OpenGLView.h b/build/proj_mac/OpenGLView.h new file mode 100644 index 0000000..db2eeed --- /dev/null +++ b/build/proj_mac/OpenGLView.h @@ -0,0 +1,30 @@ +// +// TinyOpenGLView.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef proj_mac_TinyOpenGLView_h +#define proj_mac_TinyOpenGLView_h + +#import +#import +#import "TinyDelegate.h" +#include "TinyMouse.h" +#include "TinyKeyboard.h" + +@interface OpenGLView : NSOpenGLView { + NSTimer *mTimer; + Tiny::TinyMouse *mMouse; + Tiny::TinyKeyboard *mKeyBoard; +}; + +- (void)visit:(NSTimer*)timer; + +@end + + + +#endif \ No newline at end of file diff --git a/build/proj_mac/OpenGLView.mm b/build/proj_mac/OpenGLView.mm new file mode 100644 index 0000000..82ddb0b --- /dev/null +++ b/build/proj_mac/OpenGLView.mm @@ -0,0 +1,229 @@ +// +// OpenGLView.m +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#import + +#import +#import "OpenGLView.h" +#import "TinyInputManager.h" +#include "TinyMouse.h" +#include "TinyKeyboard.h" +#include "TinyRoot.h" +#include +#include +#include "kazmath/kazmath.h" +#include "TinyMath.h" +#include "TinyDelegate.h" + + +@implementation OpenGLView + +- (id)initWithFrame:(NSRect)frameRect pixelFormat:(NSOpenGLPixelFormat*)format +{ + self = [super initWithFrame:frameRect pixelFormat:format]; + if (self) + { + NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] + options: (NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveInKeyWindow ) + owner:self + userInfo:nil]; + [self addTrackingArea:trackingArea]; + } + + //create mouse and keyboard delegate + Tiny::TinyInputObject *inputObject_mouse = Tiny::TinyInputManager::getSingleton()->getInputObject(Tiny::InputDevice::Mouse); + mMouse = (Tiny::TinyMouse *)inputObject_mouse; + Tiny::TinyInputObject *inputObject_keyboard = Tiny::TinyInputManager::getSingleton()->getInputObject(Tiny::InputDevice::Keyboard); + mKeyBoard = (Tiny::TinyKeyboard *)inputObject_keyboard; + + //init TinyDelegate, which is the entry of custom application. + Tiny::TinyDelegate::getSingleton(); + + //schedule main loop + mTimer = [NSTimer timerWithTimeInterval:(1.0 / 60.0) target:self selector:@selector(visit:) userInfo:nil repeats:YES]; + [[NSRunLoop currentRunLoop]addTimer:mTimer forMode:NSDefaultRunLoopMode]; + + return self; +} + +- (void)visit:(NSTimer*)timer +{ + if ([timer isEqual:mTimer] == YES) + { + [self drawRect:[self bounds]]; + } +} + +- (void)drawRect:(NSRect)dirtyRect +{ + [[self openGLContext] makeCurrentContext]; + + Tiny::TinyRoot::getSingleton()->renderOneFrame([mTimer timeInterval]); + + [[self openGLContext] flushBuffer]; +} + +- (void)update // moved or resized +{ + [super update]; + + [[self openGLContext] makeCurrentContext]; + [[self openGLContext] update]; + + NSRect rect = [self bounds]; + Tiny::TinyRoot::getSingleton()->onWindowUpdate(rect.size.width, rect.size.height); +} + +- (void)reshape +{ + [super reshape]; + + [[self openGLContext] makeCurrentContext]; + [[self openGLContext] update]; + + NSRect rect = [self bounds]; + Tiny::TinyRoot::getSingleton()->onWindowUpdate(rect.size.width, rect.size.height); +} + +- (BOOL)acceptsFirstResponder +{ + return YES; +} + +#pragma mark - keyboard and mouse event + +- (void)keyDown:(NSEvent *)theEvent +{ + //[super keyDown:theEvent]; + NSString *characters = [theEvent characters]; + std::string keys; + for (NSUInteger i = 0; i < [characters length]; ++i) + { + unichar character = [characters characterAtIndex:i]; + Tiny::TinyKeyEvent event; + event.mKeyCode = character; + mKeyBoard->keyPressed(&event); + } + //NSLog(@"keyDown: %@", characters); +} + +- (void)keyUp:(NSEvent *)theEvent +{ + //[super keyUp:theEvent]; + NSString *characters = [theEvent characters]; + std::string keys; + for (NSUInteger i = 0; i < [characters length]; ++i) + { + unichar character = [characters characterAtIndex:i]; + Tiny::TinyKeyEvent event; + event.mKeyCode = character; + mKeyBoard->keyReleased(&event); + } + //NSLog(@"keyUp: %@", characters); +} + +- (void)mouseMoved:(NSEvent *)theEvent +{ + //[super mouseMoved:theEvent]; + + Tiny::TinyMouseEvent event; + event.state.deltaX = [theEvent deltaX]; + event.state.deltaY = [theEvent deltaY]; + + NSPoint location = [theEvent locationInWindow];; + kmVec2 vec2 = Tiny::kmVec2Make(location.x, location.y); + + mMouse->setLocation(&vec2); + mMouse->mouseMoved(&event); + //NSLog(@"mouseMoved: x:%f y:%f", x, y); +} + +- (void)mouseDown:(NSEvent *)theEvent +{ + //[super mouseDown:theEvent]; + NSPoint location = [theEvent locationInWindow]; + Tiny::TinyMouseEvent event; + kmVec2 vec2 = Tiny::kmVec2Make(location.x, location.y); + mMouse->setLocation(&vec2); + mMouse->mousePressed(&event, Tiny::TinyMouseButtonID::MB_Left); + //NSLog(@"mouseDown: location:%f %f", location.x, location.y); +} + +- (void)mouseUp:(NSEvent *)theEvent +{ + //[super mouseUp:theEvent]; + NSPoint location = [theEvent locationInWindow]; + Tiny::TinyMouseEvent event; + kmVec2 vec2 = Tiny::kmVec2Make(location.x, location.y); + mMouse->setLocation(&vec2); + mMouse->mouseReleased(&event, Tiny::TinyMouseButtonID::MB_Left); + //NSLog(@"mouseUp: location:%f %f", location.x, location.y); +} + +- (void)rightMouseDown:(NSEvent *)theEvent +{ + //[super rightMouseDown:theEvent]; +// NSPoint location = [theEvent locationInWindow]; +// [[TinyInputManager sharedInputController] mouseRightDown:location]; + //NSLog(@"rightMouseDown: location:%f %f", location.x, location.y); +} + +- (void)rightMouseUp:(NSEvent *)theEvent +{ + //[super rightMouseUp:theEvent]; +// NSPoint location = [theEvent locationInWindow]; +// [[TinyInputManager sharedInputController] mouseRightUp:location]; + //NSLog(@"rightMouseUp: location:%f %f", location.x, location.y); +} + +- (void)mouseDragged:(NSEvent *)theEvent +{ + //[super mouseDragged:theEvent]; +// CGFloat x = [theEvent deltaX]; +// CGFloat y = [theEvent deltaY]; +// [[TinyInputManager sharedInputController] mouseLeftDragWithX:x andY:y]; + //NSLog(@"mouseDragged: x:%f y:%f", x, y); +} + +- (void)rightMouseDragged:(NSEvent *)theEvent +{ + //[super rightMouseDragged:theEvent]; +// CGFloat x = [theEvent deltaX]; +// CGFloat y = [theEvent deltaY]; +// [[TinyInputManager sharedInputController] mouseRightDragWithX:x andY:y]; + //NSLog(@"rightMouseDragged: x:%f y:%f", x, y); +} + +- (void)scrollWheel:(NSEvent *)theEvent +{ + //[super scrollWheel:theEvent]; +// CGFloat x = [theEvent scrollingDeltaX]; +// CGFloat y = [theEvent scrollingDeltaY]; +// [[TinyInputManager sharedInputController] mouseScrollWithX:x andY:y]; + //NSLog(@"scrollWheel: x:%f y:%f", x, y); +} + +- (void)mouseEntered:(NSEvent *)theEvent +{ + //[super mouseEntered:theEvent]; + //NSLog(@"mouseEntered"); +} + +- (void)mouseExited:(NSEvent *)theEvent +{ + //[super mouseExited:theEvent]; + //NSLog(@"mouseExited"); +} + +- (void)cursorUpdate:(NSEvent *)theEvent +{ + //[super cursorUpdate:theEvent]; + //NSLog(@"cursorUpdate"); +} + +@end diff --git a/build/proj_mac/main.m b/build/proj_mac/main.m new file mode 100644 index 0000000..5a113db --- /dev/null +++ b/build/proj_mac/main.m @@ -0,0 +1,13 @@ +// +// main.m +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/build/proj_mac/proj_mac.xcodeproj/project.pbxproj b/build/proj_mac/proj_mac.xcodeproj/project.pbxproj new file mode 100644 index 0000000..5b38dac --- /dev/null +++ b/build/proj_mac/proj_mac.xcodeproj/project.pbxproj @@ -0,0 +1,597 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1B0760C51A7F66E4007103F3 /* aabb.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B0760AB1A7F66E4007103F3 /* aabb.c */; }; + 1B0760C61A7F66E4007103F3 /* mat4stack.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B0760AE1A7F66E4007103F3 /* mat4stack.c */; }; + 1B0760C71A7F66E4007103F3 /* matrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B0760B01A7F66E4007103F3 /* matrix.c */; }; + 1B0760C81A7F66E4007103F3 /* mat3.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B0760B31A7F66E4007103F3 /* mat3.c */; }; + 1B0760C91A7F66E4007103F3 /* mat4.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B0760B51A7F66E4007103F3 /* mat4.c */; }; + 1B0760CA1A7F66E4007103F3 /* plane.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B0760B71A7F66E4007103F3 /* plane.c */; }; + 1B0760CB1A7F66E4007103F3 /* quaternion.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B0760B91A7F66E4007103F3 /* quaternion.c */; }; + 1B0760CC1A7F66E4007103F3 /* ray2.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B0760BB1A7F66E4007103F3 /* ray2.c */; }; + 1B0760CD1A7F66E4007103F3 /* utility.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B0760BD1A7F66E4007103F3 /* utility.c */; }; + 1B0760CE1A7F66E4007103F3 /* vec2.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B0760BF1A7F66E4007103F3 /* vec2.c */; }; + 1B0760CF1A7F66E4007103F3 /* vec3.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B0760C11A7F66E4007103F3 /* vec3.c */; }; + 1B0760D01A7F66E4007103F3 /* vec4.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B0760C31A7F66E4007103F3 /* vec4.c */; }; + 1B4BB8571A81C3C300E97FB4 /* TinyCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4BB8561A81C3C300E97FB4 /* TinyCamera.cpp */; }; + 1B4BB87E1A81C52500E97FB4 /* TinyDelegate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4BB85A1A81C52500E97FB4 /* TinyDelegate.cpp */; }; + 1B4BB87F1A81C52500E97FB4 /* TinyGPUProgram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4BB85E1A81C52500E97FB4 /* TinyGPUProgram.cpp */; }; + 1B4BB8801A81C52500E97FB4 /* TinyGPUProgramManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4BB8601A81C52500E97FB4 /* TinyGPUProgramManager.cpp */; }; + 1B4BB8811A81C52500E97FB4 /* TinyInputManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4BB8621A81C52500E97FB4 /* TinyInputManager.cpp */; }; + 1B4BB8821A81C52500E97FB4 /* TinyLight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4BB8641A81C52500E97FB4 /* TinyLight.cpp */; }; + 1B4BB8831A81C52500E97FB4 /* TinyMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4BB8661A81C52500E97FB4 /* TinyMath.cpp */; }; + 1B4BB8841A81C52500E97FB4 /* TinyMovableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4BB86A1A81C52500E97FB4 /* TinyMovableObject.cpp */; }; + 1B4BB8851A81C52500E97FB4 /* TinyObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4BB86C1A81C52500E97FB4 /* TinyObject.cpp */; }; + 1B4BB8861A81C52500E97FB4 /* TinyResourceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4BB8711A81C52500E97FB4 /* TinyResourceManager.cpp */; }; + 1B4BB8871A81C52500E97FB4 /* TinyRoot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4BB8731A81C52500E97FB4 /* TinyRoot.cpp */; }; + 1B4BB8881A81C52500E97FB4 /* TinyTextureManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4BB8791A81C52500E97FB4 /* TinyTextureManager.cpp */; }; + 1B4BB8891A81C52500E97FB4 /* TinyViewPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4BB87B1A81C52500E97FB4 /* TinyViewPort.cpp */; }; + 1B4F26111A7FEAD200DABC42 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1B4F26091A7FEAD200DABC42 /* AppDelegate.mm */; }; + 1B4F26121A7FEAD200DABC42 /* Contents.json in Resources */ = {isa = PBXBuildFile; fileRef = 1B4F260A1A7FEAD200DABC42 /* Contents.json */; }; + 1B4F26131A7FEAD200DABC42 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1B4F260B1A7FEAD200DABC42 /* Info.plist */; }; + 1B4F26141A7FEAD200DABC42 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B4F260C1A7FEAD200DABC42 /* main.m */; }; + 1B4F26151A7FEAD200DABC42 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1B4F260D1A7FEAD200DABC42 /* MainMenu.xib */; }; + 1B4F26161A7FEAD200DABC42 /* OpenGLView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1B4F260F1A7FEAD200DABC42 /* OpenGLView.mm */; }; + 1BA22F0F1A82154A0060733E /* TinyInputObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F0D1A82154A0060733E /* TinyInputObject.cpp */; }; + 1BA22F121A8215E50060733E /* TinyMouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F101A8215E50060733E /* TinyMouse.cpp */; }; + 1BA22F151A8216180060733E /* TinyKeyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F131A8216180060733E /* TinyKeyboard.cpp */; }; + 1BA22F171A8216900060733E /* TinyEntity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F161A8216900060733E /* TinyEntity.cpp */; }; + 1BA22F1A1A8217540060733E /* TinyMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F181A8217540060733E /* TinyMaterial.cpp */; }; + 1BA22F1C1A8217760060733E /* TinyMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F1B1A8217760060733E /* TinyMesh.cpp */; }; + 1BA22F1E1A82179C0060733E /* TinyRenderable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F1D1A82179C0060733E /* TinyRenderable.cpp */; }; + 1BA22F201A8217B70060733E /* TinyRenderQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F1F1A8217B70060733E /* TinyRenderQueue.cpp */; }; + 1BA22F221A8217D10060733E /* TinyRenderTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F211A8217D10060733E /* TinyRenderTarget.cpp */; }; + 1BA22F251A8217EA0060733E /* TinyRenderWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F231A8217EA0060733E /* TinyRenderWindow.cpp */; }; + 1BA22F281A8218040060733E /* TinyRenderTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F261A8218040060733E /* TinyRenderTexture.cpp */; }; + 1BA22F2A1A8218210060733E /* TinySceneManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F291A8218210060733E /* TinySceneManager.cpp */; }; + 1BA22F2C1A8218350060733E /* TinySceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F2B1A8218350060733E /* TinySceneNode.cpp */; }; + 1BA22F2E1A8218490060733E /* TinySchedulerManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F2D1A8218490060733E /* TinySchedulerManager.cpp */; }; + 1BA22F301A82185D0060733E /* TinyTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F2F1A82185D0060733E /* TinyTexture.cpp */; }; + 1BA22F391A8268440060733E /* TinyRenderQueueSortingQrouping.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F371A8268440060733E /* TinyRenderQueueSortingQrouping.cpp */; }; + 1BA22F3C1A82685B0060733E /* TinyRenderSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1BA22F3A1A82685B0060733E /* TinyRenderSystem.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1B0760701A7F2626007103F3 /* proj_mac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = proj_mac.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1B0760AB1A7F66E4007103F3 /* aabb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = aabb.c; path = ../../external/kazmath/aabb.c; sourceTree = ""; }; + 1B0760AC1A7F66E4007103F3 /* aabb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = aabb.h; path = ../../external/kazmath/aabb.h; sourceTree = ""; }; + 1B0760AE1A7F66E4007103F3 /* mat4stack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mat4stack.c; sourceTree = ""; }; + 1B0760AF1A7F66E4007103F3 /* mat4stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mat4stack.h; sourceTree = ""; }; + 1B0760B01A7F66E4007103F3 /* matrix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = matrix.c; sourceTree = ""; }; + 1B0760B11A7F66E4007103F3 /* matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = matrix.h; sourceTree = ""; }; + 1B0760B21A7F66E4007103F3 /* kazmath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = kazmath.h; path = ../../external/kazmath/kazmath.h; sourceTree = ""; }; + 1B0760B31A7F66E4007103F3 /* mat3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mat3.c; path = ../../external/kazmath/mat3.c; sourceTree = ""; }; + 1B0760B41A7F66E4007103F3 /* mat3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mat3.h; path = ../../external/kazmath/mat3.h; sourceTree = ""; }; + 1B0760B51A7F66E4007103F3 /* mat4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mat4.c; path = ../../external/kazmath/mat4.c; sourceTree = ""; }; + 1B0760B61A7F66E4007103F3 /* mat4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mat4.h; path = ../../external/kazmath/mat4.h; sourceTree = ""; }; + 1B0760B71A7F66E4007103F3 /* plane.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = plane.c; path = ../../external/kazmath/plane.c; sourceTree = ""; }; + 1B0760B81A7F66E4007103F3 /* plane.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = plane.h; path = ../../external/kazmath/plane.h; sourceTree = ""; }; + 1B0760B91A7F66E4007103F3 /* quaternion.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = quaternion.c; path = ../../external/kazmath/quaternion.c; sourceTree = ""; }; + 1B0760BA1A7F66E4007103F3 /* quaternion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = quaternion.h; path = ../../external/kazmath/quaternion.h; sourceTree = ""; }; + 1B0760BB1A7F66E4007103F3 /* ray2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ray2.c; path = ../../external/kazmath/ray2.c; sourceTree = ""; }; + 1B0760BC1A7F66E4007103F3 /* ray2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ray2.h; path = ../../external/kazmath/ray2.h; sourceTree = ""; }; + 1B0760BD1A7F66E4007103F3 /* utility.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = utility.c; path = ../../external/kazmath/utility.c; sourceTree = ""; }; + 1B0760BE1A7F66E4007103F3 /* utility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = utility.h; path = ../../external/kazmath/utility.h; sourceTree = ""; }; + 1B0760BF1A7F66E4007103F3 /* vec2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vec2.c; path = ../../external/kazmath/vec2.c; sourceTree = ""; }; + 1B0760C01A7F66E4007103F3 /* vec2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vec2.h; path = ../../external/kazmath/vec2.h; sourceTree = ""; }; + 1B0760C11A7F66E4007103F3 /* vec3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vec3.c; path = ../../external/kazmath/vec3.c; sourceTree = ""; }; + 1B0760C21A7F66E4007103F3 /* vec3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vec3.h; path = ../../external/kazmath/vec3.h; sourceTree = ""; }; + 1B0760C31A7F66E4007103F3 /* vec4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vec4.c; path = ../../external/kazmath/vec4.c; sourceTree = ""; }; + 1B0760C41A7F66E4007103F3 /* vec4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vec4.h; path = ../../external/kazmath/vec4.h; sourceTree = ""; }; + 1B4BB8561A81C3C300E97FB4 /* TinyCamera.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyCamera.cpp; path = ../../tiny3d_main/TinyCamera.cpp; sourceTree = ""; }; + 1B4BB8591A81C52500E97FB4 /* TinyCamera.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyCamera.h; path = ../../tiny3d_main/TinyCamera.h; sourceTree = ""; }; + 1B4BB85A1A81C52500E97FB4 /* TinyDelegate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyDelegate.cpp; path = ../../tiny3d_main/TinyDelegate.cpp; sourceTree = ""; }; + 1B4BB85B1A81C52500E97FB4 /* TinyDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyDelegate.h; path = ../../tiny3d_main/TinyDelegate.h; sourceTree = ""; }; + 1B4BB85C1A81C52500E97FB4 /* TinyEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyEntity.h; path = ../../tiny3d_main/TinyEntity.h; sourceTree = ""; }; + 1B4BB85E1A81C52500E97FB4 /* TinyGPUProgram.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyGPUProgram.cpp; path = ../../tiny3d_main/TinyGPUProgram.cpp; sourceTree = ""; }; + 1B4BB85F1A81C52500E97FB4 /* TinyGPUProgram.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyGPUProgram.h; path = ../../tiny3d_main/TinyGPUProgram.h; sourceTree = ""; }; + 1B4BB8601A81C52500E97FB4 /* TinyGPUProgramManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyGPUProgramManager.cpp; path = ../../tiny3d_main/TinyGPUProgramManager.cpp; sourceTree = ""; }; + 1B4BB8611A81C52500E97FB4 /* TinyGPUProgramManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyGPUProgramManager.h; path = ../../tiny3d_main/TinyGPUProgramManager.h; sourceTree = ""; }; + 1B4BB8621A81C52500E97FB4 /* TinyInputManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyInputManager.cpp; path = ../../tiny3d_main/TinyInputManager.cpp; sourceTree = ""; }; + 1B4BB8631A81C52500E97FB4 /* TinyInputManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyInputManager.h; path = ../../tiny3d_main/TinyInputManager.h; sourceTree = ""; }; + 1B4BB8641A81C52500E97FB4 /* TinyLight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyLight.cpp; path = ../../tiny3d_main/TinyLight.cpp; sourceTree = ""; }; + 1B4BB8651A81C52500E97FB4 /* TinyLight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyLight.h; path = ../../tiny3d_main/TinyLight.h; sourceTree = ""; }; + 1B4BB8661A81C52500E97FB4 /* TinyMath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyMath.cpp; path = ../../tiny3d_main/TinyMath.cpp; sourceTree = ""; }; + 1B4BB8671A81C52500E97FB4 /* TinyMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyMath.h; path = ../../tiny3d_main/TinyMath.h; sourceTree = ""; }; + 1B4BB8691A81C52500E97FB4 /* TinyMesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyMesh.h; path = ../../tiny3d_main/TinyMesh.h; sourceTree = ""; }; + 1B4BB86A1A81C52500E97FB4 /* TinyMovableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyMovableObject.cpp; path = ../../tiny3d_main/TinyMovableObject.cpp; sourceTree = ""; }; + 1B4BB86B1A81C52500E97FB4 /* TinyMovableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyMovableObject.h; path = ../../tiny3d_main/TinyMovableObject.h; sourceTree = ""; }; + 1B4BB86C1A81C52500E97FB4 /* TinyObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyObject.cpp; path = ../../tiny3d_main/TinyObject.cpp; sourceTree = ""; }; + 1B4BB86D1A81C52500E97FB4 /* TinyObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyObject.h; path = ../../tiny3d_main/TinyObject.h; sourceTree = ""; }; + 1B4BB86E1A81C52500E97FB4 /* TinyRenderable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyRenderable.h; path = ../../tiny3d_main/TinyRenderable.h; sourceTree = ""; }; + 1B4BB86F1A81C52500E97FB4 /* TinyRenderQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyRenderQueue.h; path = ../../tiny3d_main/TinyRenderQueue.h; sourceTree = ""; }; + 1B4BB8701A81C52500E97FB4 /* TinyRenderTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyRenderTarget.h; path = ../../tiny3d_main/TinyRenderTarget.h; sourceTree = ""; }; + 1B4BB8711A81C52500E97FB4 /* TinyResourceManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyResourceManager.cpp; path = ../../tiny3d_main/TinyResourceManager.cpp; sourceTree = ""; }; + 1B4BB8721A81C52500E97FB4 /* TinyResourceManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyResourceManager.h; path = ../../tiny3d_main/TinyResourceManager.h; sourceTree = ""; }; + 1B4BB8731A81C52500E97FB4 /* TinyRoot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyRoot.cpp; path = ../../tiny3d_main/TinyRoot.cpp; sourceTree = ""; }; + 1B4BB8741A81C52500E97FB4 /* TinyRoot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyRoot.h; path = ../../tiny3d_main/TinyRoot.h; sourceTree = ""; }; + 1B4BB8751A81C52500E97FB4 /* TinySceneManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinySceneManager.h; path = ../../tiny3d_main/TinySceneManager.h; sourceTree = ""; }; + 1B4BB8761A81C52500E97FB4 /* TinySceneNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinySceneNode.h; path = ../../tiny3d_main/TinySceneNode.h; sourceTree = ""; }; + 1B4BB8771A81C52500E97FB4 /* TinySchedulerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinySchedulerManager.h; path = ../../tiny3d_main/TinySchedulerManager.h; sourceTree = ""; }; + 1B4BB8781A81C52500E97FB4 /* TinyTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyTexture.h; path = ../../tiny3d_main/TinyTexture.h; sourceTree = ""; }; + 1B4BB8791A81C52500E97FB4 /* TinyTextureManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyTextureManager.cpp; path = ../../tiny3d_main/TinyTextureManager.cpp; sourceTree = ""; }; + 1B4BB87A1A81C52500E97FB4 /* TinyTextureManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyTextureManager.h; path = ../../tiny3d_main/TinyTextureManager.h; sourceTree = ""; }; + 1B4BB87B1A81C52500E97FB4 /* TinyViewPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyViewPort.cpp; path = ../../tiny3d_main/TinyViewPort.cpp; sourceTree = ""; }; + 1B4BB87C1A81C52500E97FB4 /* TinyViewPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyViewPort.h; path = ../../tiny3d_main/TinyViewPort.h; sourceTree = ""; }; + 1B4F26081A7FEAD200DABC42 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; }; + 1B4F26091A7FEAD200DABC42 /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AppDelegate.mm; sourceTree = SOURCE_ROOT; }; + 1B4F260A1A7FEAD200DABC42 /* Contents.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Contents.json; sourceTree = SOURCE_ROOT; }; + 1B4F260B1A7FEAD200DABC42 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; }; + 1B4F260C1A7FEAD200DABC42 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; }; + 1B4F260D1A7FEAD200DABC42 /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = SOURCE_ROOT; }; + 1B4F260E1A7FEAD200DABC42 /* OpenGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenGLView.h; sourceTree = SOURCE_ROOT; }; + 1B4F260F1A7FEAD200DABC42 /* OpenGLView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenGLView.mm; sourceTree = SOURCE_ROOT; }; + 1B4F263B1A7FEB2300DABC42 /* OceanDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OceanDelegate.h; path = ../../sample/sample_ocean/OceanDelegate.h; sourceTree = ""; }; + 1BA22F0D1A82154A0060733E /* TinyInputObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyInputObject.cpp; path = ../../tiny3d_main/TinyInputObject.cpp; sourceTree = ""; }; + 1BA22F0E1A82154A0060733E /* TinyInputObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyInputObject.h; path = ../../tiny3d_main/TinyInputObject.h; sourceTree = ""; }; + 1BA22F101A8215E50060733E /* TinyMouse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyMouse.cpp; path = ../../tiny3d_main/TinyMouse.cpp; sourceTree = ""; }; + 1BA22F111A8215E50060733E /* TinyMouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyMouse.h; path = ../../tiny3d_main/TinyMouse.h; sourceTree = ""; }; + 1BA22F131A8216180060733E /* TinyKeyboard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyKeyboard.cpp; path = ../../tiny3d_main/TinyKeyboard.cpp; sourceTree = ""; }; + 1BA22F141A8216180060733E /* TinyKeyboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyKeyboard.h; path = ../../tiny3d_main/TinyKeyboard.h; sourceTree = ""; }; + 1BA22F161A8216900060733E /* TinyEntity.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyEntity.cpp; path = ../../tiny3d_main/TinyEntity.cpp; sourceTree = ""; }; + 1BA22F181A8217540060733E /* TinyMaterial.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyMaterial.cpp; path = ../../tiny3d_main/TinyMaterial.cpp; sourceTree = ""; }; + 1BA22F191A8217540060733E /* TinyMaterial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyMaterial.h; path = ../../tiny3d_main/TinyMaterial.h; sourceTree = ""; }; + 1BA22F1B1A8217760060733E /* TinyMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyMesh.cpp; path = ../../tiny3d_main/TinyMesh.cpp; sourceTree = ""; }; + 1BA22F1D1A82179C0060733E /* TinyRenderable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyRenderable.cpp; path = ../../tiny3d_main/TinyRenderable.cpp; sourceTree = ""; }; + 1BA22F1F1A8217B70060733E /* TinyRenderQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyRenderQueue.cpp; path = ../../tiny3d_main/TinyRenderQueue.cpp; sourceTree = ""; }; + 1BA22F211A8217D10060733E /* TinyRenderTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyRenderTarget.cpp; path = ../../tiny3d_main/TinyRenderTarget.cpp; sourceTree = ""; }; + 1BA22F231A8217EA0060733E /* TinyRenderWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyRenderWindow.cpp; path = ../../tiny3d_main/TinyRenderWindow.cpp; sourceTree = ""; }; + 1BA22F241A8217EA0060733E /* TinyRenderWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyRenderWindow.h; path = ../../tiny3d_main/TinyRenderWindow.h; sourceTree = ""; }; + 1BA22F261A8218040060733E /* TinyRenderTexture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyRenderTexture.cpp; path = ../../tiny3d_main/TinyRenderTexture.cpp; sourceTree = ""; }; + 1BA22F271A8218040060733E /* TinyRenderTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyRenderTexture.h; path = ../../tiny3d_main/TinyRenderTexture.h; sourceTree = ""; }; + 1BA22F291A8218210060733E /* TinySceneManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinySceneManager.cpp; path = ../../tiny3d_main/TinySceneManager.cpp; sourceTree = ""; }; + 1BA22F2B1A8218350060733E /* TinySceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinySceneNode.cpp; path = ../../tiny3d_main/TinySceneNode.cpp; sourceTree = ""; }; + 1BA22F2D1A8218490060733E /* TinySchedulerManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinySchedulerManager.cpp; path = ../../tiny3d_main/TinySchedulerManager.cpp; sourceTree = ""; }; + 1BA22F2F1A82185D0060733E /* TinyTexture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyTexture.cpp; path = ../../tiny3d_main/TinyTexture.cpp; sourceTree = ""; }; + 1BA22F371A8268440060733E /* TinyRenderQueueSortingQrouping.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyRenderQueueSortingQrouping.cpp; path = ../../tiny3d_main/TinyRenderQueueSortingQrouping.cpp; sourceTree = ""; }; + 1BA22F381A8268440060733E /* TinyRenderQueueSortingQrouping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyRenderQueueSortingQrouping.h; path = ../../tiny3d_main/TinyRenderQueueSortingQrouping.h; sourceTree = ""; }; + 1BA22F3A1A82685B0060733E /* TinyRenderSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TinyRenderSystem.cpp; path = ../../tiny3d_main/TinyRenderSystem.cpp; sourceTree = ""; }; + 1BA22F3B1A82685B0060733E /* TinyRenderSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TinyRenderSystem.h; path = ../../tiny3d_main/TinyRenderSystem.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1B07606D1A7F2626007103F3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1B0760671A7F2626007103F3 = { + isa = PBXGroup; + children = ( + 1B0760721A7F2626007103F3 /* proj_mac */, + 1B0760961A7F6641007103F3 /* tiny3d_main */, + 1B0760A91A7F669F007103F3 /* external */, + 1B0760E21A7F6F37007103F3 /* samples */, + 1B0760711A7F2626007103F3 /* Products */, + ); + sourceTree = ""; + }; + 1B0760711A7F2626007103F3 /* Products */ = { + isa = PBXGroup; + children = ( + 1B0760701A7F2626007103F3 /* proj_mac.app */, + ); + name = Products; + sourceTree = ""; + }; + 1B0760721A7F2626007103F3 /* proj_mac */ = { + isa = PBXGroup; + children = ( + 1B4F26081A7FEAD200DABC42 /* AppDelegate.h */, + 1B4F26091A7FEAD200DABC42 /* AppDelegate.mm */, + 1B4F260A1A7FEAD200DABC42 /* Contents.json */, + 1B4F260B1A7FEAD200DABC42 /* Info.plist */, + 1B4F260C1A7FEAD200DABC42 /* main.m */, + 1B4F260D1A7FEAD200DABC42 /* MainMenu.xib */, + 1B4F260E1A7FEAD200DABC42 /* OpenGLView.h */, + 1B4F260F1A7FEAD200DABC42 /* OpenGLView.mm */, + ); + path = proj_mac; + sourceTree = ""; + }; + 1B0760961A7F6641007103F3 /* tiny3d_main */ = { + isa = PBXGroup; + children = ( + 1B4BB8561A81C3C300E97FB4 /* TinyCamera.cpp */, + 1B4BB8591A81C52500E97FB4 /* TinyCamera.h */, + 1B4BB85A1A81C52500E97FB4 /* TinyDelegate.cpp */, + 1B4BB85B1A81C52500E97FB4 /* TinyDelegate.h */, + 1BA22F161A8216900060733E /* TinyEntity.cpp */, + 1B4BB85C1A81C52500E97FB4 /* TinyEntity.h */, + 1B4BB85E1A81C52500E97FB4 /* TinyGPUProgram.cpp */, + 1B4BB85F1A81C52500E97FB4 /* TinyGPUProgram.h */, + 1B4BB8601A81C52500E97FB4 /* TinyGPUProgramManager.cpp */, + 1B4BB8611A81C52500E97FB4 /* TinyGPUProgramManager.h */, + 1B4BB8621A81C52500E97FB4 /* TinyInputManager.cpp */, + 1B4BB8631A81C52500E97FB4 /* TinyInputManager.h */, + 1BA22F0D1A82154A0060733E /* TinyInputObject.cpp */, + 1BA22F0E1A82154A0060733E /* TinyInputObject.h */, + 1BA22F131A8216180060733E /* TinyKeyboard.cpp */, + 1BA22F141A8216180060733E /* TinyKeyboard.h */, + 1B4BB8641A81C52500E97FB4 /* TinyLight.cpp */, + 1B4BB8651A81C52500E97FB4 /* TinyLight.h */, + 1BA22F181A8217540060733E /* TinyMaterial.cpp */, + 1BA22F191A8217540060733E /* TinyMaterial.h */, + 1B4BB8661A81C52500E97FB4 /* TinyMath.cpp */, + 1B4BB8671A81C52500E97FB4 /* TinyMath.h */, + 1BA22F1B1A8217760060733E /* TinyMesh.cpp */, + 1B4BB8691A81C52500E97FB4 /* TinyMesh.h */, + 1BA22F101A8215E50060733E /* TinyMouse.cpp */, + 1BA22F111A8215E50060733E /* TinyMouse.h */, + 1B4BB86A1A81C52500E97FB4 /* TinyMovableObject.cpp */, + 1B4BB86B1A81C52500E97FB4 /* TinyMovableObject.h */, + 1B4BB86C1A81C52500E97FB4 /* TinyObject.cpp */, + 1B4BB86D1A81C52500E97FB4 /* TinyObject.h */, + 1BA22F1D1A82179C0060733E /* TinyRenderable.cpp */, + 1B4BB86E1A81C52500E97FB4 /* TinyRenderable.h */, + 1BA22F1F1A8217B70060733E /* TinyRenderQueue.cpp */, + 1B4BB86F1A81C52500E97FB4 /* TinyRenderQueue.h */, + 1BA22F371A8268440060733E /* TinyRenderQueueSortingQrouping.cpp */, + 1BA22F381A8268440060733E /* TinyRenderQueueSortingQrouping.h */, + 1BA22F3A1A82685B0060733E /* TinyRenderSystem.cpp */, + 1BA22F3B1A82685B0060733E /* TinyRenderSystem.h */, + 1BA22F211A8217D10060733E /* TinyRenderTarget.cpp */, + 1B4BB8701A81C52500E97FB4 /* TinyRenderTarget.h */, + 1BA22F261A8218040060733E /* TinyRenderTexture.cpp */, + 1BA22F271A8218040060733E /* TinyRenderTexture.h */, + 1BA22F231A8217EA0060733E /* TinyRenderWindow.cpp */, + 1BA22F241A8217EA0060733E /* TinyRenderWindow.h */, + 1B4BB8711A81C52500E97FB4 /* TinyResourceManager.cpp */, + 1B4BB8721A81C52500E97FB4 /* TinyResourceManager.h */, + 1B4BB8731A81C52500E97FB4 /* TinyRoot.cpp */, + 1B4BB8741A81C52500E97FB4 /* TinyRoot.h */, + 1BA22F291A8218210060733E /* TinySceneManager.cpp */, + 1B4BB8751A81C52500E97FB4 /* TinySceneManager.h */, + 1BA22F2B1A8218350060733E /* TinySceneNode.cpp */, + 1B4BB8761A81C52500E97FB4 /* TinySceneNode.h */, + 1BA22F2D1A8218490060733E /* TinySchedulerManager.cpp */, + 1B4BB8771A81C52500E97FB4 /* TinySchedulerManager.h */, + 1BA22F2F1A82185D0060733E /* TinyTexture.cpp */, + 1B4BB8781A81C52500E97FB4 /* TinyTexture.h */, + 1B4BB8791A81C52500E97FB4 /* TinyTextureManager.cpp */, + 1B4BB87A1A81C52500E97FB4 /* TinyTextureManager.h */, + 1B4BB87B1A81C52500E97FB4 /* TinyViewPort.cpp */, + 1B4BB87C1A81C52500E97FB4 /* TinyViewPort.h */, + ); + name = tiny3d_main; + path = proj_mac; + sourceTree = ""; + }; + 1B0760A91A7F669F007103F3 /* external */ = { + isa = PBXGroup; + children = ( + 1B0760AA1A7F66C7007103F3 /* kazmath */, + ); + name = external; + path = proj_mac; + sourceTree = ""; + }; + 1B0760AA1A7F66C7007103F3 /* kazmath */ = { + isa = PBXGroup; + children = ( + 1B0760AB1A7F66E4007103F3 /* aabb.c */, + 1B0760AC1A7F66E4007103F3 /* aabb.h */, + 1B0760AD1A7F66E4007103F3 /* GL */, + 1B0760B21A7F66E4007103F3 /* kazmath.h */, + 1B0760B31A7F66E4007103F3 /* mat3.c */, + 1B0760B41A7F66E4007103F3 /* mat3.h */, + 1B0760B51A7F66E4007103F3 /* mat4.c */, + 1B0760B61A7F66E4007103F3 /* mat4.h */, + 1B0760B71A7F66E4007103F3 /* plane.c */, + 1B0760B81A7F66E4007103F3 /* plane.h */, + 1B0760B91A7F66E4007103F3 /* quaternion.c */, + 1B0760BA1A7F66E4007103F3 /* quaternion.h */, + 1B0760BB1A7F66E4007103F3 /* ray2.c */, + 1B0760BC1A7F66E4007103F3 /* ray2.h */, + 1B0760BD1A7F66E4007103F3 /* utility.c */, + 1B0760BE1A7F66E4007103F3 /* utility.h */, + 1B0760BF1A7F66E4007103F3 /* vec2.c */, + 1B0760C01A7F66E4007103F3 /* vec2.h */, + 1B0760C11A7F66E4007103F3 /* vec3.c */, + 1B0760C21A7F66E4007103F3 /* vec3.h */, + 1B0760C31A7F66E4007103F3 /* vec4.c */, + 1B0760C41A7F66E4007103F3 /* vec4.h */, + ); + name = kazmath; + sourceTree = ""; + }; + 1B0760AD1A7F66E4007103F3 /* GL */ = { + isa = PBXGroup; + children = ( + 1B0760AE1A7F66E4007103F3 /* mat4stack.c */, + 1B0760AF1A7F66E4007103F3 /* mat4stack.h */, + 1B0760B01A7F66E4007103F3 /* matrix.c */, + 1B0760B11A7F66E4007103F3 /* matrix.h */, + ); + name = GL; + path = ../../external/kazmath/GL; + sourceTree = ""; + }; + 1B0760E21A7F6F37007103F3 /* samples */ = { + isa = PBXGroup; + children = ( + 1B0760E41A7F719E007103F3 /* sample_ocean */, + ); + name = samples; + path = proj_mac; + sourceTree = ""; + }; + 1B0760E41A7F719E007103F3 /* sample_ocean */ = { + isa = PBXGroup; + children = ( + 1B4F263B1A7FEB2300DABC42 /* OceanDelegate.h */, + ); + name = sample_ocean; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1B07606F1A7F2626007103F3 /* proj_mac */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1B07608D1A7F2626007103F3 /* Build configuration list for PBXNativeTarget "proj_mac" */; + buildPhases = ( + 1B07606C1A7F2626007103F3 /* Sources */, + 1B07606D1A7F2626007103F3 /* Frameworks */, + 1B07606E1A7F2626007103F3 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = proj_mac; + productName = proj_mac; + productReference = 1B0760701A7F2626007103F3 /* proj_mac.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 1B0760681A7F2626007103F3 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0610; + ORGANIZATIONNAME = "reuben chao"; + TargetAttributes = { + 1B07606F1A7F2626007103F3 = { + CreatedOnToolsVersion = 6.1.1; + }; + }; + }; + buildConfigurationList = 1B07606B1A7F2626007103F3 /* Build configuration list for PBXProject "proj_mac" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 1B0760671A7F2626007103F3; + productRefGroup = 1B0760711A7F2626007103F3 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1B07606F1A7F2626007103F3 /* proj_mac */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1B07606E1A7F2626007103F3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1B4F26131A7FEAD200DABC42 /* Info.plist in Resources */, + 1B4F26121A7FEAD200DABC42 /* Contents.json in Resources */, + 1B4F26151A7FEAD200DABC42 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1B07606C1A7F2626007103F3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1BA22F281A8218040060733E /* TinyRenderTexture.cpp in Sources */, + 1BA22F1C1A8217760060733E /* TinyMesh.cpp in Sources */, + 1BA22F301A82185D0060733E /* TinyTexture.cpp in Sources */, + 1BA22F391A8268440060733E /* TinyRenderQueueSortingQrouping.cpp in Sources */, + 1BA22F171A8216900060733E /* TinyEntity.cpp in Sources */, + 1B4BB87E1A81C52500E97FB4 /* TinyDelegate.cpp in Sources */, + 1BA22F0F1A82154A0060733E /* TinyInputObject.cpp in Sources */, + 1B0760CA1A7F66E4007103F3 /* plane.c in Sources */, + 1B0760CE1A7F66E4007103F3 /* vec2.c in Sources */, + 1B0760C91A7F66E4007103F3 /* mat4.c in Sources */, + 1B0760CF1A7F66E4007103F3 /* vec3.c in Sources */, + 1B4BB8831A81C52500E97FB4 /* TinyMath.cpp in Sources */, + 1B4BB8881A81C52500E97FB4 /* TinyTextureManager.cpp in Sources */, + 1B4BB8821A81C52500E97FB4 /* TinyLight.cpp in Sources */, + 1BA22F121A8215E50060733E /* TinyMouse.cpp in Sources */, + 1B4F26161A7FEAD200DABC42 /* OpenGLView.mm in Sources */, + 1BA22F221A8217D10060733E /* TinyRenderTarget.cpp in Sources */, + 1BA22F201A8217B70060733E /* TinyRenderQueue.cpp in Sources */, + 1B0760C81A7F66E4007103F3 /* mat3.c in Sources */, + 1B0760D01A7F66E4007103F3 /* vec4.c in Sources */, + 1B4BB8801A81C52500E97FB4 /* TinyGPUProgramManager.cpp in Sources */, + 1B4BB8871A81C52500E97FB4 /* TinyRoot.cpp in Sources */, + 1B0760C51A7F66E4007103F3 /* aabb.c in Sources */, + 1B4BB87F1A81C52500E97FB4 /* TinyGPUProgram.cpp in Sources */, + 1B4BB8851A81C52500E97FB4 /* TinyObject.cpp in Sources */, + 1B4BB8891A81C52500E97FB4 /* TinyViewPort.cpp in Sources */, + 1BA22F1E1A82179C0060733E /* TinyRenderable.cpp in Sources */, + 1BA22F2C1A8218350060733E /* TinySceneNode.cpp in Sources */, + 1B4F26111A7FEAD200DABC42 /* AppDelegate.mm in Sources */, + 1BA22F2A1A8218210060733E /* TinySceneManager.cpp in Sources */, + 1BA22F3C1A82685B0060733E /* TinyRenderSystem.cpp in Sources */, + 1BA22F1A1A8217540060733E /* TinyMaterial.cpp in Sources */, + 1B4BB8841A81C52500E97FB4 /* TinyMovableObject.cpp in Sources */, + 1BA22F251A8217EA0060733E /* TinyRenderWindow.cpp in Sources */, + 1BA22F151A8216180060733E /* TinyKeyboard.cpp in Sources */, + 1B0760CC1A7F66E4007103F3 /* ray2.c in Sources */, + 1B0760C61A7F66E4007103F3 /* mat4stack.c in Sources */, + 1B0760C71A7F66E4007103F3 /* matrix.c in Sources */, + 1BA22F2E1A8218490060733E /* TinySchedulerManager.cpp in Sources */, + 1B4BB8571A81C3C300E97FB4 /* TinyCamera.cpp in Sources */, + 1B0760CD1A7F66E4007103F3 /* utility.c in Sources */, + 1B4F26141A7FEAD200DABC42 /* main.m in Sources */, + 1B4BB8861A81C52500E97FB4 /* TinyResourceManager.cpp in Sources */, + 1B0760CB1A7F66E4007103F3 /* quaternion.c in Sources */, + 1B4BB8811A81C52500E97FB4 /* TinyInputManager.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1B07608B1A7F2626007103F3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.10; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 1B07608C1A7F2626007103F3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.10; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + 1B07608E1A7F2626007103F3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + "$(PROJECT_DIR)/../../tiny3d_main", + "$(PROJECT_DIR)/../../external", + "$(PROJECT_DIR)/../../sample", + "$(PROJECT_DIR)", + ); + INFOPLIST_FILE = proj_mac/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 1B07608F1A7F2626007103F3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + "$(PROJECT_DIR)/../../tiny3d_main", + "$(PROJECT_DIR)/../../external", + "$(PROJECT_DIR)/../../sample", + "$(PROJECT_DIR)", + ); + INFOPLIST_FILE = proj_mac/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1B07606B1A7F2626007103F3 /* Build configuration list for PBXProject "proj_mac" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1B07608B1A7F2626007103F3 /* Debug */, + 1B07608C1A7F2626007103F3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1B07608D1A7F2626007103F3 /* Build configuration list for PBXNativeTarget "proj_mac" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1B07608E1A7F2626007103F3 /* Debug */, + 1B07608F1A7F2626007103F3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 1B0760681A7F2626007103F3 /* Project object */; +} diff --git a/build/proj_mac/proj_mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/build/proj_mac/proj_mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..be1de7c --- /dev/null +++ b/build/proj_mac/proj_mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/build/proj_mac/proj_mac.xcodeproj/project.xcworkspace/xcuserdata/reuben.xcuserdatad/UserInterfaceState.xcuserstate b/build/proj_mac/proj_mac.xcodeproj/project.xcworkspace/xcuserdata/reuben.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..2d741ec74040e3cc7eaa97d1e68ebde99d78e305 GIT binary patch literal 50604 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 + + + + + + + + + + + + + + + + + + + + diff --git a/build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcschemes/proj_mac.xcscheme b/build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcschemes/proj_mac.xcscheme new file mode 100644 index 0000000..6fb8acb --- /dev/null +++ b/build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcschemes/proj_mac.xcscheme @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcschemes/xcschememanagement.plist b/build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..57d42a7 --- /dev/null +++ b/build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,27 @@ + + + + + SchemeUserState + + proj_mac.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + 1B07606F1A7F2626007103F3 + + primary + + + 1B0760821A7F2626007103F3 + + primary + + + + + diff --git a/external/kazmath/GL/mat4stack.c b/external/kazmath/GL/mat4stack.c new file mode 100755 index 0000000..1cbcdae --- /dev/null +++ b/external/kazmath/GL/mat4stack.c @@ -0,0 +1,74 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include + +#define INITIAL_SIZE 30 +#define INCREMENT 50 + +#include "mat4stack.h" + +void km_mat4_stack_initialize(km_mat4_stack* stack) { + stack->stack = (kmMat4*) malloc(sizeof(kmMat4) * INITIAL_SIZE); //allocate the memory + stack->capacity = INITIAL_SIZE; //Set the capacity to 10 + stack->top = NULL; //Set the top to NULL + stack->item_count = 0; +}; + +void km_mat4_stack_push(km_mat4_stack* stack, const kmMat4* item) +{ + stack->top = &stack->stack[stack->item_count]; + kmMat4Assign(stack->top, item); + stack->item_count++; + + if(stack->item_count >= stack->capacity) + { + kmMat4* temp = NULL; + stack->capacity += INCREMENT; + temp = stack->stack; + stack->stack = (kmMat4*) malloc(stack->capacity*sizeof(kmMat4)); + memcpy(stack->stack, temp, sizeof(kmMat4)*(stack->capacity - INCREMENT)); + free(temp); + stack->top = &stack->stack[stack->item_count - 1]; + } +} + +void km_mat4_stack_pop(km_mat4_stack* stack, kmMat4* pOut) +{ + assert(stack->item_count && "Cannot pop an empty stack"); + + stack->item_count--; + stack->top = &stack->stack[stack->item_count - 1]; +} + +void km_mat4_stack_release(km_mat4_stack* stack) { + free(stack->stack); + stack->top = NULL; + stack->item_count = 0; + stack->capacity = 0; +} diff --git a/external/kazmath/GL/mat4stack.h b/external/kazmath/GL/mat4stack.h new file mode 100755 index 0000000..7de12aa --- /dev/null +++ b/external/kazmath/GL/mat4stack.h @@ -0,0 +1,51 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef C_STACK_H_INCLUDED +#define C_STACK_H_INCLUDED + +#include "../mat4.h" + +typedef struct km_mat4_stack { + int capacity; //The total item capacity + int item_count; //The number of items + kmMat4* top; + kmMat4* stack; +} km_mat4_stack; + +#ifdef __cplusplus +extern "C" { +#endif + +void km_mat4_stack_initialize(km_mat4_stack* stack); +void km_mat4_stack_push(km_mat4_stack* stack, const kmMat4* item); +void km_mat4_stack_pop(km_mat4_stack* stack, kmMat4* pOut); +void km_mat4_stack_release(km_mat4_stack* stack); + +#ifdef __cplusplus +} +#endif + +#endif // C_STACK_H_INCLUDED diff --git a/external/kazmath/GL/matrix.c b/external/kazmath/GL/matrix.c new file mode 100755 index 0000000..0564ae1 --- /dev/null +++ b/external/kazmath/GL/matrix.c @@ -0,0 +1,323 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include + +#include "matrix.h" +#include "mat4stack.h" + +// --- +// Begin additions by Tobias Lensing for icedcoffee-framework.org + +typedef struct km_mat4_stack_context { + km_mat4_stack modelview_matrix_stack; + km_mat4_stack projection_matrix_stack; + km_mat4_stack texture_matrix_stack; + km_mat4_stack* current_stack; + unsigned char initialized; + void *contextRef; + struct km_mat4_stack_context_list *entry; +} km_mat4_stack_context; + +typedef struct km_mat4_stack_context_list { + km_mat4_stack_context context; + struct km_mat4_stack_context_list *prev; + struct km_mat4_stack_context_list *next; +} km_mat4_stack_context_list; + +static pthread_key_t current_context_key; +static km_mat4_stack_context_list *contexts; +static unsigned char initialized = 0; +static pthread_mutex_t contexts_mutex = PTHREAD_MUTEX_INITIALIZER; + +void lazyInitialize() +{ + if (!initialized) { + pthread_key_create(¤t_context_key, NULL); + initialized = 1; + } +} + +km_mat4_stack_context *lookUpContext(void *contextRef) +{ + lazyInitialize(); + + if (contexts) { + km_mat4_stack_context_list *entry = contexts; + pthread_mutex_lock(&contexts_mutex); + do { + if (entry->context.contextRef == contextRef) { + pthread_mutex_unlock(&contexts_mutex); + return &entry->context; + } + } while ((entry = entry->next)); + pthread_mutex_unlock(&contexts_mutex); + } + + return NULL; +} + +km_mat4_stack_context *registerContext(void *contextRef) +{ + lazyInitialize(); + + km_mat4_stack_context *existingContext = lookUpContext(contextRef); + if (!existingContext) { + km_mat4_stack_context_list *entry = contexts; + km_mat4_stack_context_list *last = NULL; + + pthread_mutex_lock(&contexts_mutex); + if (entry) { + do { + last = entry; + } while((entry = entry->next)); + } + pthread_mutex_unlock(&contexts_mutex); + + km_mat4_stack_context_list *newEntry = (km_mat4_stack_context_list *)malloc(sizeof(km_mat4_stack_context_list)); + memset(newEntry, 0, sizeof(km_mat4_stack_context_list)); + newEntry->context.contextRef = contextRef; + newEntry->context.entry = newEntry; + newEntry->prev = last; + + pthread_mutex_lock(&contexts_mutex); + if (last) { + last->next = newEntry; + } + if (!contexts) { + contexts = newEntry; + } + pthread_mutex_unlock(&contexts_mutex); + + return &newEntry->context; + } + + return existingContext; +} + +void kmGLSetCurrentContext(void *contextRef) +{ + km_mat4_stack_context *current_context = registerContext(contextRef); + pthread_setspecific(current_context_key, current_context); +} + +void *kmGLGetCurrentContext() +{ + return ((km_mat4_stack_context *)pthread_getspecific(current_context_key))->contextRef; +} + +void kmGLClearContext(km_mat4_stack_context *context) +{ + // Unlink current context from linked list + if (context->entry->prev) + context->entry->prev->next = context->entry->next; + + //Clear the matrix stacks + km_mat4_stack_release(&context->modelview_matrix_stack); + km_mat4_stack_release(&context->projection_matrix_stack); + km_mat4_stack_release(&context->texture_matrix_stack); + + //Delete the matrices + context->initialized = 0; + + //Set the current stack to point nowhere + context->current_stack = NULL; + + // Free the list entry, including its stacks + free(context->entry); +} + +void kmGLClearCurrentContext() +{ + kmGLClearContext(pthread_getspecific(current_context_key)); + pthread_setspecific(current_context_key, NULL); +} + +void kmGLClearAllContexts() +{ + km_mat4_stack_context_list *entry = contexts; + do { + kmGLClearContext(&entry->context); + } while ((entry = entry->next)); + + pthread_setspecific(current_context_key, NULL); +} + +// End additions by Tobias Lensing for icedcoffee-framework.org +// --- + +km_mat4_stack_context *lazyInitializeCurrentContext() +{ + km_mat4_stack_context *current_context = pthread_getspecific(current_context_key); + + assert(current_context != NULL && "No context set"); + + if (current_context && !current_context->initialized) { + kmMat4 identity; //Temporary identity matrix + + //Initialize all 3 stacks + //modelview_matrix_stack = (km_mat4_stack*) malloc(sizeof(km_mat4_stack)); + km_mat4_stack_initialize(¤t_context->modelview_matrix_stack); + + //projection_matrix_stack = (km_mat4_stack*) malloc(sizeof(km_mat4_stack)); + km_mat4_stack_initialize(¤t_context->projection_matrix_stack); + + //texture_matrix_stack = (km_mat4_stack*) malloc(sizeof(km_mat4_stack)); + km_mat4_stack_initialize(¤t_context->texture_matrix_stack); + + current_context->current_stack = ¤t_context->modelview_matrix_stack; + current_context->initialized = 1; + + kmMat4Identity(&identity); + + //Make sure that each stack has the identity matrix + km_mat4_stack_push(¤t_context->modelview_matrix_stack, &identity); + km_mat4_stack_push(¤t_context->projection_matrix_stack, &identity); + km_mat4_stack_push(¤t_context->texture_matrix_stack, &identity); + } + + return current_context; +} + +void kmGLMatrixMode(kmGLEnum mode) +{ + km_mat4_stack_context *current_context = lazyInitializeCurrentContext(); + + switch(mode) + { + case KM_GL_MODELVIEW: + current_context->current_stack = ¤t_context->modelview_matrix_stack; + break; + case KM_GL_PROJECTION: + current_context->current_stack = ¤t_context->projection_matrix_stack; + break; + case KM_GL_TEXTURE: + current_context->current_stack = ¤t_context->texture_matrix_stack; + break; + default: + assert(0 && "Invalid matrix mode specified"); //TODO: Proper error handling + break; + } +} + +void kmGLPushMatrix(void) +{ + kmMat4 top; + + km_mat4_stack_context *current_context = lazyInitializeCurrentContext(); + + //Duplicate the top of the stack (i.e the current matrix) + kmMat4Assign(&top, current_context->current_stack->top); + km_mat4_stack_push(current_context->current_stack, &top); +} + +void kmGLPopMatrix(void) +{ + km_mat4_stack_context *current_context = pthread_getspecific(current_context_key); + assert(current_context->initialized && "Cannot Pop empty matrix stack"); + //No need to lazy initialize, you shouldnt be popping first anyway! + km_mat4_stack_pop(current_context->current_stack, NULL); +} + +void kmGLLoadIdentity() +{ + km_mat4_stack_context *current_context = lazyInitializeCurrentContext(); + kmMat4Identity(current_context->current_stack->top); //Replace the top matrix with the identity matrix +} + +void kmGLMultMatrix(const kmMat4* pIn) +{ + km_mat4_stack_context *current_context = lazyInitializeCurrentContext(); + kmMat4Multiply(current_context->current_stack->top, current_context->current_stack->top, pIn); +} + +void kmGLLoadMatrix(const kmMat4* pIn) +{ + km_mat4_stack_context *current_context = lazyInitializeCurrentContext(); + kmMat4Assign(current_context->current_stack->top, pIn); +} + +void kmGLGetMatrix(kmGLEnum mode, kmMat4* pOut) +{ + km_mat4_stack_context *current_context = lazyInitializeCurrentContext(); + + switch(mode) + { + case KM_GL_MODELVIEW: + kmMat4Assign(pOut, current_context->modelview_matrix_stack.top); + break; + case KM_GL_PROJECTION: + kmMat4Assign(pOut, current_context->projection_matrix_stack.top); + break; + case KM_GL_TEXTURE: + kmMat4Assign(pOut, current_context->texture_matrix_stack.top); + break; + default: + assert(1 && "Invalid matrix mode specified"); //TODO: Proper error handling + break; + } +} + +void kmGLTranslatef(float x, float y, float z) +{ + km_mat4_stack_context *current_context = pthread_getspecific(current_context_key); + + kmMat4 translation; + + //Create a rotation matrix using the axis and the angle + kmMat4Translation(&translation,x,y,z); + + //Multiply the rotation matrix by the current matrix + kmMat4Multiply(current_context->current_stack->top, current_context->current_stack->top, &translation); +} + +void kmGLRotatef(float angle, float x, float y, float z) +{ + km_mat4_stack_context *current_context = pthread_getspecific(current_context_key); + + kmVec3 axis; + kmMat4 rotation; + + //Create an axis vector + kmVec3Fill(&axis, x, y, z); + + //Create a rotation matrix using the axis and the angle + kmMat4RotationAxisAngle(&rotation, &axis, kmDegreesToRadians(angle)); + + //Multiply the rotation matrix by the current matrix + kmMat4Multiply(current_context->current_stack->top, current_context->current_stack->top, &rotation); +} + +void kmGLScalef(float x, float y, float z) +{ + km_mat4_stack_context *current_context = pthread_getspecific(current_context_key); + + kmMat4 scaling; + kmMat4Scaling(&scaling, x, y, z); + kmMat4Multiply(current_context->current_stack->top, current_context->current_stack->top, &scaling); +} diff --git a/external/kazmath/GL/matrix.h b/external/kazmath/GL/matrix.h new file mode 100755 index 0000000..ab698a0 --- /dev/null +++ b/external/kazmath/GL/matrix.h @@ -0,0 +1,63 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef KM_GL_MATRIX_H_INCLUDED +#define KM_GL_MATRIX_H_INCLUDED + +#define KM_GL_MODELVIEW 0x1700 +#define KM_GL_PROJECTION 0x1701 +#define KM_GL_TEXTURE 0x1702 + +typedef unsigned int kmGLEnum; + +#include "../mat4.h" +#include "../vec3.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Added by Tobias Lensing for icedcoffee-framework.org +void kmGLSetCurrentContext(void *contextRef); +void *kmGLGetCurrentContext(); +void kmGLClearCurrentContext(); +void kmGLClearAllContexts(); + +void kmGLPushMatrix(void); +void kmGLPopMatrix(void); +void kmGLMatrixMode(kmGLEnum mode); +void kmGLLoadIdentity(void); +void kmGLLoadMatrix(const kmMat4* pIn); +void kmGLMultMatrix(const kmMat4* pIn); +void kmGLTranslatef(float x, float y, float z); +void kmGLRotatef(float angle, float x, float y, float z); +void kmGLScalef(float x, float y, float z); +void kmGLGetMatrix(kmGLEnum mode, kmMat4* pOut); + +#ifdef __cplusplus +} +#endif + +#endif // MATRIX_H_INCLUDED diff --git a/external/kazmath/aabb.c b/external/kazmath/aabb.c new file mode 100755 index 0000000..4cdf0e6 --- /dev/null +++ b/external/kazmath/aabb.c @@ -0,0 +1,140 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "aabb.h" + + +/** + Initializes the AABB around a central point. If centre is NULL then the origin + is used. Returns pBox. +*/ +kmAABB* kmAABBInitialize(kmAABB* pBox, const kmVec3* centre, const kmScalar width, const kmScalar height, const kmScalar depth) { + if(!pBox) return 0; + + kmVec3 origin; + kmVec3* point = centre ? (kmVec3*) centre : &origin; + kmVec3Zero(&origin); + + pBox->min.x = point->x - (width / 2); + pBox->min.y = point->y - (height / 2); + pBox->min.z = point->z - (depth / 2); + + pBox->max.x = point->x + (width / 2); + pBox->max.y = point->y + (height / 2); + pBox->max.z = point->z + (depth / 2); + + return pBox; +} + +/** + * Returns KM_TRUE if point is in the specified AABB, returns + * KM_FALSE otherwise. + */ +const int kmAABBContainsPoint(const kmAABB* pBox, const kmVec3* pPoint) +{ + if(pPoint->x >= pBox->min.x && pPoint->x <= pBox->max.x && + pPoint->y >= pBox->min.y && pPoint->y <= pBox->max.y && + pPoint->z >= pBox->min.z && pPoint->z <= pBox->max.z) { + return KM_TRUE; + } + + return KM_FALSE; +} + +/** + * Assigns pIn to pOut, returns pOut. + */ +kmAABB* const kmAABBAssign(kmAABB* pOut, const kmAABB* pIn) +{ + kmVec3Assign(&pOut->min, &pIn->min); + kmVec3Assign(&pOut->max, &pIn->max); + return pOut; +} + +/** + * Scales pIn by s, stores the resulting AABB in pOut. Returns pOut + */ +kmAABB* const kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s) +{ + assert(0 && "Not implemented"); +} + +kmBool kmAABBIntersectsTriangle(kmAABB* box, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3) { + assert(0 && "Not implemented"); + return KM_TRUE; +} + +kmEnum kmAABBContainsAABB(const kmAABB* container, const kmAABB* to_check) { + kmVec3 corners[8]; + kmEnum result = KM_CONTAINS_ALL; + kmBool found = KM_FALSE; + + kmVec3Fill(&corners[0], to_check->min.x, to_check->min.y, to_check->min.z); + kmVec3Fill(&corners[1], to_check->max.x, to_check->min.y, to_check->min.z); + kmVec3Fill(&corners[2], to_check->max.x, to_check->max.y, to_check->min.z); + kmVec3Fill(&corners[3], to_check->min.x, to_check->max.y, to_check->min.z); + kmVec3Fill(&corners[4], to_check->min.x, to_check->min.y, to_check->max.z); + kmVec3Fill(&corners[5], to_check->max.x, to_check->min.y, to_check->max.z); + kmVec3Fill(&corners[6], to_check->max.x, to_check->max.y, to_check->max.z); + kmVec3Fill(&corners[7], to_check->min.x, to_check->max.y, to_check->max.z); + + for(kmUchar i = 0; i < 8; ++i) { + if(!kmAABBContainsPoint(container, &corners[i])) { + result = KM_CONTAINS_PARTIAL; + if(found) { + //If we previously found a corner that was within the container + //We know that partial is the final result + return result; + } + } else { + found = KM_TRUE; + } + } + + if(!found) { + result = KM_CONTAINS_NONE; + } + + return result; +} + +kmScalar kmAABBDiameterX(const kmAABB* aabb) { + return fabs(aabb->max.x - aabb->min.x); +} + +kmScalar kmAABBDiameterY(const kmAABB* aabb) { + return fabs(aabb->max.y - aabb->min.y); +} + +kmScalar kmAABBDiameterZ(const kmAABB* aabb) { + return fabs(aabb->max.z - aabb->min.z); +} + +kmVec3* kmAABBCentre(const kmAABB* aabb, kmVec3* pOut) { + kmVec3Add(pOut, &aabb->min, &aabb->max); + kmVec3Scale(pOut, pOut, 0.5); + return pOut; +} + diff --git a/external/kazmath/aabb.h b/external/kazmath/aabb.h new file mode 100755 index 0000000..3017955 --- /dev/null +++ b/external/kazmath/aabb.h @@ -0,0 +1,61 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef KAZMATH_AABB_H_INCLUDED +#define KAZMATH_AABB_H_INCLUDED + +#include "vec3.h" +#include "utility.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A struture that represents an axis-aligned + * bounding box. + */ +typedef struct kmAABB { + kmVec3 min; /** The max corner of the box */ + kmVec3 max; /** The min corner of the box */ +} kmAABB; + + +kmAABB* kmAABBInitialize(kmAABB* pBox, const kmVec3* centre, const kmScalar width, const kmScalar height, const kmScalar depth); +const int kmAABBContainsPoint(const kmAABB* pBox, const kmVec3* pPoint); +kmAABB* const kmAABBAssign(kmAABB* pOut, const kmAABB* pIn); +kmAABB* const kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s); +kmBool kmAABBIntersectsTriangle(kmAABB* box, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3); +kmEnum kmAABBContainsAABB(const kmAABB* container, const kmAABB* to_check); +kmScalar kmAABBDiameterX(const kmAABB* aabb); +kmScalar kmAABBDiameterY(const kmAABB* aabb); +kmScalar kmAABBDiameterZ(const kmAABB* aabb); +kmVec3* kmAABBCentre(const kmAABB* aabb, kmVec3* pOut); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/kazmath/kazmath.h b/external/kazmath/kazmath.h new file mode 100755 index 0000000..ef09870 --- /dev/null +++ b/external/kazmath/kazmath.h @@ -0,0 +1,39 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef KAZMATH_H_INCLUDED +#define KAZMATH_H_INCLUDED + +#include "vec2.h" +#include "vec3.h" +#include "mat3.h" +#include "mat4.h" +#include "utility.h" +#include "quaternion.h" +#include "plane.h" +#include "aabb.h" +#include "ray2.h" + +#endif // KAZMATH_H_INCLUDED diff --git a/external/kazmath/mat3.c b/external/kazmath/mat3.c new file mode 100755 index 0000000..a533814 --- /dev/null +++ b/external/kazmath/mat3.c @@ -0,0 +1,427 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +#include "utility.h" +#include "vec3.h" +#include "mat3.h" +#include "mat4.h" +#include "quaternion.h" + +kmMat3* const kmMat3Fill(kmMat3* pOut, const kmScalar* pMat) +{ + memcpy(pOut->mat, pMat, sizeof(kmScalar) * 9); + return pOut; +} + +/** Sets pOut to an identity matrix returns pOut*/ +kmMat3* const kmMat3Identity(kmMat3* pOut) +{ + memset(pOut->mat, 0, sizeof(kmScalar) * 9); + pOut->mat[0] = pOut->mat[4] = pOut->mat[8] = 1.0f; + return pOut; +} + +const kmScalar kmMat3Determinant(const kmMat3* pIn) +{ + kmScalar output; + /* + calculating the determinant following the rule of sarus, + | 0 3 6 | 0 3 | + m = | 1 4 7 | 1 4 | + | 2 5 8 | 2 5 | + now sum up the products of the diagonals going to the right (i.e. 0,4,8) + and substract the products of the other diagonals (i.e. 2,4,6) + */ + + output = pIn->mat[0] * pIn->mat[4] * pIn->mat[8] + pIn->mat[1] * pIn->mat[5] * pIn->mat[6] + pIn->mat[2] * pIn->mat[3] * pIn->mat[7]; + output -= pIn->mat[2] * pIn->mat[4] * pIn->mat[6] + pIn->mat[0] * pIn->mat[5] * pIn->mat[7] + pIn->mat[1] * pIn->mat[3] * pIn->mat[8]; + + return output; +} + + +kmMat3* const kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn) +{ + pOut->mat[0] = pIn->mat[4] * pIn->mat[8] - pIn->mat[5] * pIn->mat[7]; + pOut->mat[1] = pIn->mat[2] * pIn->mat[7] - pIn->mat[1] * pIn->mat[8]; + pOut->mat[2] = pIn->mat[1] * pIn->mat[5] - pIn->mat[2] * pIn->mat[4]; + pOut->mat[3] = pIn->mat[5] * pIn->mat[6] - pIn->mat[3] * pIn->mat[8]; + pOut->mat[4] = pIn->mat[0] * pIn->mat[8] - pIn->mat[2] * pIn->mat[6]; + pOut->mat[5] = pIn->mat[2] * pIn->mat[3] - pIn->mat[0] * pIn->mat[5]; + pOut->mat[6] = pIn->mat[3] * pIn->mat[7] - pIn->mat[4] * pIn->mat[6]; + pOut->mat[7] = pIn->mat[1] * pIn->mat[6] - pIn->mat[0] * pIn->mat[7]; + pOut->mat[8] = pIn->mat[0] * pIn->mat[4] - pIn->mat[1] * pIn->mat[3]; + + return pOut; +} + +kmMat3* const kmMat3Inverse(kmMat3* pOut, const kmMat3* pM) +{ + kmScalar determinate = kmMat3Determinant(pM); + kmScalar detInv; + kmMat3 adjugate; + + if(determinate == 0.0) + { + return NULL; + } + + detInv = 1.0 / determinate; + + kmMat3Adjugate(&adjugate, pM); + kmMat3ScalarMultiply(pOut, &adjugate, detInv); + + return pOut; +} + +/** Returns true if pIn is an identity matrix */ +const int kmMat3IsIdentity(const kmMat3* pIn) +{ + static const kmScalar identity [] = { 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f}; + + return (memcmp(identity, pIn->mat, sizeof(kmScalar) * 9) == 0); +} + +/** Sets pOut to the transpose of pIn, returns pOut */ +kmMat3* const kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn) +{ + kmScalar temp[9]; + + temp[0] = pIn->mat[0]; + temp[1] = pIn->mat[3]; + temp[2] = pIn->mat[6]; + + temp[3] = pIn->mat[1]; + temp[4] = pIn->mat[4]; + temp[5] = pIn->mat[7]; + + temp[6] = pIn->mat[2]; + temp[7] = pIn->mat[5]; + temp[8] = pIn->mat[8]; + + memcpy(&pOut->mat, temp, sizeof(kmScalar)*9); + + return pOut; +} + +/* Multiplies pM1 with pM2, stores the result in pOut, returns pOut */ +kmMat3* const kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2) +{ + kmScalar mat[9]; + + const kmScalar *m1 = pM1->mat, *m2 = pM2->mat; + + mat[0] = m1[0] * m2[0] + m1[3] * m2[1] + m1[6] * m2[2]; + mat[1] = m1[1] * m2[0] + m1[4] * m2[1] + m1[7] * m2[2]; + mat[2] = m1[2] * m2[0] + m1[5] * m2[1] + m1[8] * m2[2]; + + mat[3] = m1[0] * m2[3] + m1[3] * m2[4] + m1[6] * m2[5]; + mat[4] = m1[1] * m2[3] + m1[4] * m2[4] + m1[7] * m2[5]; + mat[5] = m1[2] * m2[3] + m1[5] * m2[4] + m1[8] * m2[5]; + + mat[6] = m1[0] * m2[6] + m1[3] * m2[7] + m1[6] * m2[8]; + mat[7] = m1[1] * m2[6] + m1[4] * m2[7] + m1[7] * m2[8]; + mat[8] = m1[2] * m2[6] + m1[5] * m2[7] + m1[8] * m2[8]; + + memcpy(pOut->mat, mat, sizeof(kmScalar)*9); + + return pOut; +} + +kmMat3* const kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor) +{ + kmScalar mat[9]; + int i; + + for(i = 0; i < 9; i++) + { + mat[i] = pM->mat[i] * pFactor; + } + + memcpy(pOut->mat, mat, sizeof(kmScalar)*9); + + return pOut; +} + +/** Assigns the value of pIn to pOut */ +kmMat3* const kmMat3Assign(kmMat3* pOut, const kmMat3* pIn) +{ + assert(pOut != pIn); //You have tried to self-assign!! + + memcpy(pOut->mat, pIn->mat, sizeof(kmScalar)*9); + + return pOut; +} + +kmMat3* const kmMat3AssignMat4(kmMat3* pOut, const kmMat4* pIn) { + pOut->mat[0] = pIn->mat[0]; + pOut->mat[1] = pIn->mat[1]; + pOut->mat[2] = pIn->mat[2]; + + pOut->mat[3] = pIn->mat[4]; + pOut->mat[4] = pIn->mat[5]; + pOut->mat[5] = pIn->mat[6]; + + pOut->mat[6] = pIn->mat[8]; + pOut->mat[7] = pIn->mat[9]; + pOut->mat[8] = pIn->mat[10]; + return pOut; +} + +/** Returns true if the 2 matrices are equal (approximately) */ +const int kmMat3AreEqual(const kmMat3* pMat1, const kmMat3* pMat2) +{ + int i; + if (pMat1 == pMat2) { + return KM_TRUE; + } + + for (i = 0; i < 9; ++i) { + if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] && + pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) { + return KM_FALSE; + } + } + + return KM_TRUE; +} + +/* Rotation around the z axis so everything stays planar in XY */ +kmMat3* const kmMat3Rotation(kmMat3* pOut, const kmScalar radians) +{ + /* + | cos(A) -sin(A) 0 | + M = | sin(A) cos(A) 0 | + | 0 0 1 | + */ + + pOut->mat[0] = cosf(radians); + pOut->mat[1] = sinf(radians); + pOut->mat[2] = 0.0f; + + pOut->mat[3] = -sinf(radians);; + pOut->mat[4] = cosf(radians); + pOut->mat[5] = 0.0f; + + pOut->mat[6] = 0.0f; + pOut->mat[7] = 0.0f; + pOut->mat[8] = 1.0f; + + return pOut; +} + +/** Builds a scaling matrix */ +kmMat3* const kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y) +{ +// memset(pOut->mat, 0, sizeof(kmScalar) * 9); + kmMat3Identity(pOut); + pOut->mat[0] = x; + pOut->mat[4] = y; + + return pOut; +} + +kmMat3* const kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y) +{ +// memset(pOut->mat, 0, sizeof(kmScalar) * 9); + kmMat3Identity(pOut); + pOut->mat[6] = x; + pOut->mat[7] = y; +// pOut->mat[8] = 1.0; + + return pOut; +} + + +kmMat3* const kmMat3RotationQuaternion(kmMat3* pOut, const kmQuaternion* pIn) +{ + if (!pIn || !pOut) { + return NULL; + } + + // First row + pOut->mat[0] = 1.0f - 2.0f * (pIn->y * pIn->y + pIn->z * pIn->z); + pOut->mat[1] = 2.0f * (pIn->x * pIn->y - pIn->w * pIn->z); + pOut->mat[2] = 2.0f * (pIn->x * pIn->z + pIn->w * pIn->y); + + // Second row + pOut->mat[3] = 2.0f * (pIn->x * pIn->y + pIn->w * pIn->z); + pOut->mat[4] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->z * pIn->z); + pOut->mat[5] = 2.0f * (pIn->y * pIn->z - pIn->w * pIn->x); + + // Third row + pOut->mat[6] = 2.0f * (pIn->x * pIn->z - pIn->w * pIn->y); + pOut->mat[7] = 2.0f * (pIn->y * pIn->z + pIn->w * pIn->x); + pOut->mat[8] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->y * pIn->y); + + return pOut; +} + +kmMat3* const kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians) +{ + kmScalar rcos = cosf(radians); + kmScalar rsin = sinf(radians); + + pOut->mat[0] = rcos + axis->x * axis->x * (1 - rcos); + pOut->mat[1] = axis->z * rsin + axis->y * axis->x * (1 - rcos); + pOut->mat[2] = -axis->y * rsin + axis->z * axis->x * (1 - rcos); + + pOut->mat[3] = -axis->z * rsin + axis->x * axis->y * (1 - rcos); + pOut->mat[4] = rcos + axis->y * axis->y * (1 - rcos); + pOut->mat[5] = axis->x * rsin + axis->z * axis->y * (1 - rcos); + + pOut->mat[6] = axis->y * rsin + axis->x * axis->z * (1 - rcos); + pOut->mat[7] = -axis->x * rsin + axis->y * axis->z * (1 - rcos); + pOut->mat[8] = rcos + axis->z * axis->z * (1 - rcos); + + return pOut; +} + +kmVec3* const kmMat3RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn) +{ + /*Surely not this easy?*/ + kmQuaternion temp; + kmQuaternionRotationMatrix(&temp, pIn); + kmQuaternionToAxisAngle(&temp, pAxis, radians); + return pAxis; +} + +/** + * Builds an X-axis rotation matrix and stores it in pOut, returns pOut + */ +kmMat3* const kmMat3RotationX(kmMat3* pOut, const kmScalar radians) +{ + /* + | 1 0 0 | + M = | 0 cos(A) -sin(A) | + | 0 sin(A) cos(A) | + + */ + + pOut->mat[0] = 1.0f; + pOut->mat[1] = 0.0f; + pOut->mat[2] = 0.0f; + + pOut->mat[3] = 0.0f; + pOut->mat[4] = cosf(radians); + pOut->mat[5] = sinf(radians); + + pOut->mat[6] = 0.0f; + pOut->mat[7] = -sinf(radians); + pOut->mat[8] = cosf(radians); + + return pOut; +} + +/** + * Builds a rotation matrix using the rotation around the Y-axis + * The result is stored in pOut, pOut is returned. + */ +kmMat3* const kmMat3RotationY(kmMat3* pOut, const kmScalar radians) +{ + /* + | cos(A) 0 sin(A) | + M = | 0 1 0 | + | -sin(A) 0 cos(A) | + */ + + pOut->mat[0] = cosf(radians); + pOut->mat[1] = 0.0f; + pOut->mat[2] = -sinf(radians); + + pOut->mat[3] = 0.0f; + pOut->mat[4] = 1.0f; + pOut->mat[5] = 0.0f; + + pOut->mat[6] = sinf(radians); + pOut->mat[7] = 0.0f; + pOut->mat[8] = cosf(radians); + + return pOut; +} + +/** + * Builds a rotation matrix around the Z-axis. The resulting + * matrix is stored in pOut. pOut is returned. + */ +kmMat3* const kmMat3RotationZ(kmMat3* pOut, const kmScalar radians) +{ + /* + | cos(A) -sin(A) 0 | + M = | sin(A) cos(A) 0 | + | 0 0 1 | + */ + + pOut->mat[0] = cosf(radians); + pOut->mat[1] =-sinf(radians); + pOut->mat[2] = 0.0f; + + pOut->mat[3] = sinf(radians);; + pOut->mat[4] = cosf(radians); + pOut->mat[5] = 0.0f; + + pOut->mat[6] = 0.0f; + pOut->mat[7] = 0.0f; + pOut->mat[8] = 1.0f; + + return pOut; +} + +kmVec3* const kmMat3GetUpVec3(kmVec3* pOut, const kmMat3* pIn) { + pOut->x = pIn->mat[3]; + pOut->y = pIn->mat[4]; + pOut->z = pIn->mat[5]; + + kmVec3Normalize(pOut, pOut); + + return pOut; +} + +kmVec3* const kmMat3GetRightVec3(kmVec3* pOut, const kmMat3* pIn) { + pOut->x = pIn->mat[0]; + pOut->y = pIn->mat[1]; + pOut->z = pIn->mat[2]; + + kmVec3Normalize(pOut, pOut); + + return pOut; +} + +kmVec3* const kmMat3GetForwardVec3(kmVec3* pOut, const kmMat3* pIn) { + pOut->x = pIn->mat[6]; + pOut->y = pIn->mat[7]; + pOut->z = pIn->mat[8]; + + kmVec3Normalize(pOut, pOut); + + return pOut; +} + diff --git a/external/kazmath/mat3.h b/external/kazmath/mat3.h new file mode 100755 index 0000000..0e4c227 --- /dev/null +++ b/external/kazmath/mat3.h @@ -0,0 +1,84 @@ +#ifndef HEADER_8E9D0ABA3C76B989 +#define HEADER_8E9D0ABA3C76B989 + +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef MAT3_H_INCLUDED +#define MAT3_H_INCLUDED + +#include "utility.h" + +struct kmVec3; +struct kmQuaternion; +struct kmMat4; + +typedef struct kmMat3{ + kmScalar mat[9]; +} kmMat3; + +#ifdef __cplusplus +extern "C" { +#endif + +kmMat3* const kmMat3Fill(kmMat3* pOut, const kmScalar* pMat); +kmMat3* const kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn); +kmMat3* const kmMat3Identity(kmMat3* pOut); +kmMat3* const kmMat3Inverse(kmMat3* pOut, const kmMat3* pM); +const int kmMat3IsIdentity(const kmMat3* pIn); +kmMat3* const kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn); +const kmScalar kmMat3Determinant(const kmMat3* pIn); +kmMat3* const kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2); +kmMat3* const kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor); + +kmMat3* const kmMat3Assign(kmMat3* pOut, const kmMat3* pIn); +kmMat3* const kmMat3AssignMat4(kmMat3* pOut, const struct kmMat4* pIn); +const int kmMat3AreEqual(const kmMat3* pM1, const kmMat3* pM2); + +struct kmVec3* const kmMat3GetUpVec3(struct kmVec3* pOut, const kmMat3* pIn); +struct kmVec3* const kmMat3GetRightVec3(struct kmVec3* pOut, const kmMat3* pIn); +struct kmVec3* const kmMat3GetForwardVec3(struct kmVec3* pOut, const kmMat3* pIn); + +kmMat3* const kmMat3RotationX(kmMat3* pOut, const kmScalar radians); +kmMat3* const kmMat3RotationY(kmMat3* pOut, const kmScalar radians); +kmMat3* const kmMat3RotationZ(kmMat3* pOut, const kmScalar radians); + +kmMat3* const kmMat3Rotation(kmMat3* pOut, const kmScalar radians); +kmMat3* const kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y); +kmMat3* const kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y); + +kmMat3* const kmMat3RotationQuaternion(kmMat3* pOut, const struct kmQuaternion* pIn); + +kmMat3* const kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians); +struct kmVec3* const kmMat3RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn); + +#ifdef __cplusplus +} +#endif +#endif // MAT3_H_INCLUDED + + +#endif // header guard diff --git a/external/kazmath/mat4.c b/external/kazmath/mat4.c new file mode 100755 index 0000000..cf2b5ee --- /dev/null +++ b/external/kazmath/mat4.c @@ -0,0 +1,810 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + * @file mat4.c + */ +#include +#include +#include + +#include "utility.h" +#include "vec3.h" +#include "mat4.h" +#include "mat3.h" +#include "quaternion.h" +#include "plane.h" + +/** + * Fills a kmMat4 structure with the values from a 16 + * element array of kmScalars + * @Params pOut - A pointer to the destination matrix + * pMat - A 16 element array of kmScalars + * @Return Returns pOut so that the call can be nested + */ +kmMat4* const kmMat4Fill(kmMat4* pOut, const kmScalar* pMat) +{ + memcpy(pOut->mat, pMat, sizeof(kmScalar) * 16); + return pOut; +} + +/** + * Sets pOut to an identity matrix returns pOut + * @Params pOut - A pointer to the matrix to set to identity + * @Return Returns pOut so that the call can be nested + */ +kmMat4* const kmMat4Identity(kmMat4* pOut) +{ + memset(pOut->mat, 0, sizeof(kmScalar) * 16); + pOut->mat[0] = pOut->mat[5] = pOut->mat[10] = pOut->mat[15] = 1.0f; + return pOut; +} + + +kmScalar get(const kmMat4 * pIn, int row, int col) +{ + return pIn->mat[row + 4*col]; +} + +void set(kmMat4 * pIn, int row, int col, kmScalar value) +{ + pIn->mat[row + 4*col] = value; +} + +void swap(kmMat4 * pIn, int r1, int c1, int r2, int c2) +{ + kmScalar tmp = get(pIn,r1,c1); + set(pIn,r1,c1,get(pIn,r2,c2)); + set(pIn,r2,c2, tmp); +} + +//Returns an upper and a lower triangular matrix which are L and R in the Gauss algorithm +int gaussj(kmMat4 *a, kmMat4 *b) +{ + int i, icol = 0, irow = 0, j, k, l, ll, n = 4, m = 4; + kmScalar big, dum, pivinv; + int indxc[n]; + int indxr[n]; + int ipiv[n]; + + for (j = 0; j < n; j++) { + ipiv[j] = 0; + } + + for (i = 0; i < n; i++) { + big = 0.0f; + for (j = 0; j < n; j++) { + if (ipiv[j] != 1) { + for (k = 0; k < n; k++) { + if (ipiv[k] == 0) { + if (abs(get(a,j, k)) >= big) { + big = abs(get(a,j, k)); + irow = j; + icol = k; + } + } + } + } + } + ++(ipiv[icol]); + if (irow != icol) { + for (l = 0; l < n; l++) { + swap(a,irow, l, icol, l); + } + for (l = 0; l < m; l++) { + swap(b,irow, l, icol, l); + } + } + indxr[i] = irow; + indxc[i] = icol; + if (get(a,icol, icol) == 0.0) { + return KM_FALSE; + } + pivinv = 1.0f / get(a,icol, icol); + set(a,icol, icol, 1.0f); + for (l = 0; l < n; l++) { + set(a,icol, l, get(a,icol, l) * pivinv); + } + for (l = 0; l < m; l++) { + set(b,icol, l, get(b,icol, l) * pivinv); + } + + for (ll = 0; ll < n; ll++) { + if (ll != icol) { + dum = get(a,ll, icol); + set(a,ll, icol, 0.0f); + for (l = 0; l < n; l++) { + set(a,ll, l, get(a,ll, l) - get(a,icol, l) * dum); + } + for (l = 0; l < m; l++) { + set(b,ll, l, get(a,ll, l) - get(b,icol, l) * dum); + } + } + } + } +// This is the end of the main loop over columns of the reduction. It only remains to unscram- +// ble the solution in view of the column interchanges. We do this by interchanging pairs of +// columns in the reverse order that the permutation was built up. + for (l = n - 1; l >= 0; l--) { + if (indxr[l] != indxc[l]) { + for (k = 0; k < n; k++) { + swap(a,k, indxr[l], k, indxc[l]); + } + } + } + return KM_TRUE; +} + +/** + * Calculates the inverse of pM and stores the result in + * pOut. + * @Return Returns NULL if there is no inverse, else pOut + */ +kmMat4* const kmMat4Inverse(kmMat4* pOut, const kmMat4* pM) +{ + kmMat4 inv; + kmMat4Assign(&inv, pM); + + kmMat4 tmp; + kmMat4Identity(&tmp); + + if(gaussj(&inv, &tmp) == KM_FALSE) { + return NULL; + } + + kmMat4Assign(pOut, &inv); + return pOut; +} +/** + * Returns KM_TRUE if pIn is an identity matrix + * KM_FALSE otherwise + */ +const int kmMat4IsIdentity(const kmMat4* pIn) +{ + static const kmScalar identity [] = { 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + + return (memcmp(identity, pIn->mat, sizeof(kmScalar) * 16) == 0); +} + +/** + * Sets pOut to the transpose of pIn, returns pOut + */ +kmMat4* const kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn) +{ + int x, z; + + for (z = 0; z < 4; ++z) { + for (x = 0; x < 4; ++x) { + pOut->mat[(z * 4) + x] = pIn->mat[(x * 4) + z]; + } + } + + return pOut; +} + +/** + * Multiplies pM1 with pM2, stores the result in pOut, returns pOut + */ +kmMat4* const kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2) +{ + kmScalar mat[16]; + + const kmScalar *m1 = pM1->mat, *m2 = pM2->mat; + + mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3]; + mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3]; + mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3]; + mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3]; + + mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7]; + mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7]; + mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7]; + mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7]; + + mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11]; + mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11]; + mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11]; + mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11]; + + mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15]; + mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15]; + mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15]; + mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]; + + + memcpy(pOut->mat, mat, sizeof(kmScalar)*16); + + return pOut; +} + +/** + * Assigns the value of pIn to pOut + */ +kmMat4* const kmMat4Assign(kmMat4* pOut, const kmMat4* pIn) +{ + assert(pOut != pIn && "You have tried to self-assign!!"); + + memcpy(pOut->mat, pIn->mat, sizeof(kmScalar)*16); + + return pOut; +} + +kmMat4* const kmMat4AssignMat3(kmMat4* pOut, const kmMat3* pIn) { + kmMat4Identity(pOut); + + pOut->mat[0] = pIn->mat[0]; + pOut->mat[1] = pIn->mat[1]; + pOut->mat[2] = pIn->mat[2]; + pOut->mat[3] = 0.0; + + pOut->mat[4] = pIn->mat[3]; + pOut->mat[5] = pIn->mat[4]; + pOut->mat[6] = pIn->mat[5]; + pOut->mat[7] = 0.0; + + pOut->mat[8] = pIn->mat[6]; + pOut->mat[9] = pIn->mat[7]; + pOut->mat[10] = pIn->mat[8]; + pOut->mat[11] = 0.0; + + return pOut; +} + + +/** + * Returns KM_TRUE if the 2 matrices are equal (approximately) + */ +const int kmMat4AreEqual(const kmMat4* pMat1, const kmMat4* pMat2) +{ + int i = 0; + + assert(pMat1 != pMat2 && "You are comparing the same thing!"); + + for (i = 0; i < 16; ++i) + { + if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] && + pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) { + return KM_FALSE; + } + } + + return KM_TRUE; +} + +/** + * Build a rotation matrix from an axis and an angle. Result is stored in pOut. + * pOut is returned. + */ +kmMat4* const kmMat4RotationAxisAngle(kmMat4* pOut, const kmVec3* axis, kmScalar radians) +{ + kmScalar rcos = cosf(radians); + kmScalar rsin = sinf(radians); + + kmVec3 normalizedAxis; + kmVec3Normalize(&normalizedAxis, axis); + + pOut->mat[0] = rcos + normalizedAxis.x * normalizedAxis.x * (1 - rcos); + pOut->mat[1] = normalizedAxis.z * rsin + normalizedAxis.y * normalizedAxis.x * (1 - rcos); + pOut->mat[2] = -normalizedAxis.y * rsin + normalizedAxis.z * normalizedAxis.x * (1 - rcos); + pOut->mat[3] = 0.0f; + + pOut->mat[4] = -normalizedAxis.z * rsin + normalizedAxis.x * normalizedAxis.y * (1 - rcos); + pOut->mat[5] = rcos + normalizedAxis.y * normalizedAxis.y * (1 - rcos); + pOut->mat[6] = normalizedAxis.x * rsin + normalizedAxis.z * normalizedAxis.y * (1 - rcos); + pOut->mat[7] = 0.0f; + + pOut->mat[8] = normalizedAxis.y * rsin + normalizedAxis.x * normalizedAxis.z * (1 - rcos); + pOut->mat[9] = -normalizedAxis.x * rsin + normalizedAxis.y * normalizedAxis.z * (1 - rcos); + pOut->mat[10] = rcos + normalizedAxis.z * normalizedAxis.z * (1 - rcos); + pOut->mat[11] = 0.0f; + + pOut->mat[12] = 0.0f; + pOut->mat[13] = 0.0f; + pOut->mat[14] = 0.0f; + pOut->mat[15] = 1.0f; + + return pOut; +} + +/** + * Builds an X-axis rotation matrix and stores it in pOut, returns pOut + */ +kmMat4* const kmMat4RotationX(kmMat4* pOut, const kmScalar radians) +{ + /* + | 1 0 0 0 | + M = | 0 cos(A) -sin(A) 0 | + | 0 sin(A) cos(A) 0 | + | 0 0 0 1 | + + */ + + pOut->mat[0] = 1.0f; + pOut->mat[1] = 0.0f; + pOut->mat[2] = 0.0f; + pOut->mat[3] = 0.0f; + + pOut->mat[4] = 0.0f; + pOut->mat[5] = cosf(radians); + pOut->mat[6] = sinf(radians); + pOut->mat[7] = 0.0f; + + pOut->mat[8] = 0.0f; + pOut->mat[9] = -sinf(radians); + pOut->mat[10] = cosf(radians); + pOut->mat[11] = 0.0f; + + pOut->mat[12] = 0.0f; + pOut->mat[13] = 0.0f; + pOut->mat[14] = 0.0f; + pOut->mat[15] = 1.0f; + + return pOut; +} + +/** + * Builds a rotation matrix using the rotation around the Y-axis + * The result is stored in pOut, pOut is returned. + */ +kmMat4* const kmMat4RotationY(kmMat4* pOut, const kmScalar radians) +{ + /* + | cos(A) 0 sin(A) 0 | + M = | 0 1 0 0 | + | -sin(A) 0 cos(A) 0 | + | 0 0 0 1 | + */ + + pOut->mat[0] = cosf(radians); + pOut->mat[1] = 0.0f; + pOut->mat[2] = -sinf(radians); + pOut->mat[3] = 0.0f; + + pOut->mat[4] = 0.0f; + pOut->mat[5] = 1.0f; + pOut->mat[6] = 0.0f; + pOut->mat[7] = 0.0f; + + pOut->mat[8] = sinf(radians); + pOut->mat[9] = 0.0f; + pOut->mat[10] = cosf(radians); + pOut->mat[11] = 0.0f; + + pOut->mat[12] = 0.0f; + pOut->mat[13] = 0.0f; + pOut->mat[14] = 0.0f; + pOut->mat[15] = 1.0f; + + return pOut; +} + +/** + * Builds a rotation matrix around the Z-axis. The resulting + * matrix is stored in pOut. pOut is returned. + */ +kmMat4* const kmMat4RotationZ(kmMat4* pOut, const kmScalar radians) +{ + /* + | cos(A) -sin(A) 0 0 | + M = | sin(A) cos(A) 0 0 | + | 0 0 1 0 | + | 0 0 0 1 | + */ + + pOut->mat[0] = cosf(radians); + pOut->mat[1] = sinf(radians); + pOut->mat[2] = 0.0f; + pOut->mat[3] = 0.0f; + + pOut->mat[4] = -sinf(radians);; + pOut->mat[5] = cosf(radians); + pOut->mat[6] = 0.0f; + pOut->mat[7] = 0.0f; + + pOut->mat[8] = 0.0f; + pOut->mat[9] = 0.0f; + pOut->mat[10] = 1.0f; + pOut->mat[11] = 0.0f; + + pOut->mat[12] = 0.0f; + pOut->mat[13] = 0.0f; + pOut->mat[14] = 0.0f; + pOut->mat[15] = 1.0f; + + return pOut; +} + +/** + * Builds a rotation matrix from pitch, yaw and roll. The resulting + * matrix is stored in pOut and pOut is returned + */ +kmMat4* const kmMat4RotationPitchYawRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll) +{ + double cr = cos(pitch); + double sr = sin(pitch); + double cp = cos(yaw); + double sp = sin(yaw); + double cy = cos(roll); + double sy = sin(roll); + double srsp = sr * sp; + double crsp = cr * sp; + + pOut->mat[0] = (kmScalar) cp * cy; + pOut->mat[4] = (kmScalar) cp * sy; + pOut->mat[8] = (kmScalar) - sp; + + pOut->mat[1] = (kmScalar) srsp * cy - cr * sy; + pOut->mat[5] = (kmScalar) srsp * sy + cr * cy; + pOut->mat[9] = (kmScalar) sr * cp; + + pOut->mat[2] = (kmScalar) crsp * cy + sr * sy; + pOut->mat[6] = (kmScalar) crsp * sy - sr * cy; + pOut->mat[10] = (kmScalar) cr * cp; + + pOut->mat[3] = pOut->mat[7] = pOut->mat[11] = 0.0; + pOut->mat[15] = 1.0; + + return pOut; +} + +/** Converts a quaternion to a rotation matrix, + * the result is stored in pOut, returns pOut + */ +kmMat4* const kmMat4RotationQuaternion(kmMat4* pOut, const kmQuaternion* pQ) +{ + kmScalar x2 = pQ->x * pQ->x; + kmScalar y2 = pQ->y * pQ->y; + kmScalar z2 = pQ->z * pQ->z; + kmScalar xy = pQ->x * pQ->y; + kmScalar xz = pQ->x * pQ->z; + kmScalar yz = pQ->y * pQ->z; + kmScalar wx = pQ->w * pQ->x; + kmScalar wy = pQ->w * pQ->y; + kmScalar wz = pQ->w * pQ->z; + + pOut->mat[0] = 1.0 - 2.0 * (y2 + z2); + pOut->mat[1] = 2.0 * (xy - wz); + pOut->mat[2] = 2.0 * (xz + wy); + pOut->mat[3] = 0.0; + + // Second row + pOut->mat[4] = 2.0 * (xy + wz); + pOut->mat[5] = 1.0 - 2.0 * (x2 + z2); + pOut->mat[6] = 2.0 * (yz - wx); + pOut->mat[7] = 0.0; + + // Third row + pOut->mat[8] = 2.0 * (xz - wy); + pOut->mat[9] = 2.0 * (yz + wx); + pOut->mat[10] = 1.0 - 2.0 * (x2 + y2); + pOut->mat[11] = 0.0; + + // Fourth row + pOut->mat[12] = 0; + pOut->mat[13] = 0; + pOut->mat[14] = 0; + pOut->mat[15] = 1.0; + + return pOut; +} + +/** Builds a scaling matrix */ +kmMat4* const kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y, + const kmScalar z) +{ + memset(pOut->mat, 0, sizeof(kmScalar) * 16); + pOut->mat[0] = x; + pOut->mat[5] = y; + pOut->mat[10] = z; + pOut->mat[15] = 1.0f; + + return pOut; +} + +/** + * Builds a translation matrix. All other elements in the matrix + * will be set to zero except for the diagonal which is set to 1.0 + */ +kmMat4* const kmMat4Translation(kmMat4* pOut, const kmScalar x, + const kmScalar y, const kmScalar z) +{ + //FIXME: Write a test for this + memset(pOut->mat, 0, sizeof(kmScalar) * 16); + + pOut->mat[0] = 1.0f; + pOut->mat[5] = 1.0f; + pOut->mat[10] = 1.0f; + + pOut->mat[12] = x; + pOut->mat[13] = y; + pOut->mat[14] = z; + pOut->mat[15] = 1.0f; + + return pOut; +} + +/** + * Get the up vector from a matrix. pIn is the matrix you + * wish to extract the vector from. pOut is a pointer to the + * kmVec3 structure that should hold the resulting vector + */ +kmVec3* const kmMat4GetUpVec3(kmVec3* pOut, const kmMat4* pIn) +{ + pOut->x = pIn->mat[4]; + pOut->y = pIn->mat[5]; + pOut->z = pIn->mat[6]; + + kmVec3Normalize(pOut, pOut); + + return pOut; +} + +/** Extract the right vector from a 4x4 matrix. The result is + * stored in pOut. Returns pOut. + */ +kmVec3* const kmMat4GetRightVec3(kmVec3* pOut, const kmMat4* pIn) +{ + pOut->x = pIn->mat[0]; + pOut->y = pIn->mat[1]; + pOut->z = pIn->mat[2]; + + kmVec3Normalize(pOut, pOut); + + return pOut; +} + +/** + * Extract the forward vector from a 4x4 matrix. The result is + * stored in pOut. Returns pOut. + */ +kmVec3* const kmMat4GetForwardVec3(kmVec3* pOut, const kmMat4* pIn) +{ + pOut->x = pIn->mat[8]; + pOut->y = pIn->mat[9]; + pOut->z = pIn->mat[10]; + + kmVec3Normalize(pOut, pOut); + + return pOut; +} + +/** + * Creates a perspective projection matrix in the + * same way as gluPerspective + */ +kmMat4* const kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY, + kmScalar aspect, kmScalar zNear, + kmScalar zFar) +{ + kmScalar r = kmDegreesToRadians(fovY / 2); + kmScalar deltaZ = zFar - zNear; + kmScalar s = sin(r); + kmScalar cotangent = 0; + + if (deltaZ == 0 || s == 0 || aspect == 0) { + return NULL; + } + + //cos(r) / sin(r) = cot(r) + cotangent = cos(r) / s; + + kmMat4Identity(pOut); + pOut->mat[0] = cotangent / aspect; + pOut->mat[5] = cotangent; + pOut->mat[10] = -(zFar + zNear) / deltaZ; + pOut->mat[11] = -1; + pOut->mat[14] = -2 * zNear * zFar / deltaZ; + pOut->mat[15] = 0; + + return pOut; +} + +/** Creates an orthographic projection matrix like glOrtho */ +kmMat4* const kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left, + kmScalar right, kmScalar bottom, + kmScalar top, kmScalar nearVal, + kmScalar farVal) +{ + kmScalar tx = -((right + left) / (right - left)); + kmScalar ty = -((top + bottom) / (top - bottom)); + kmScalar tz = -((farVal + nearVal) / (farVal - nearVal)); + + kmMat4Identity(pOut); + pOut->mat[0] = 2 / (right - left); + pOut->mat[5] = 2 / (top - bottom); + pOut->mat[10] = -2 / (farVal - nearVal); + pOut->mat[12] = tx; + pOut->mat[13] = ty; + pOut->mat[14] = tz; + + return pOut; +} + +/** + * Builds a translation matrix in the same way as gluLookAt() + * the resulting matrix is stored in pOut. pOut is returned. + */ +kmMat4* const kmMat4LookAt(kmMat4* pOut, const kmVec3* pEye, + const kmVec3* pCenter, const kmVec3* pUp) +{ + kmVec3 f, up, s, u; + kmMat4 translate; + + kmVec3Subtract(&f, pCenter, pEye); + kmVec3Normalize(&f, &f); + + kmVec3Assign(&up, pUp); + kmVec3Normalize(&up, &up); + + kmVec3Cross(&s, &f, &up); + kmVec3Normalize(&s, &s); + + kmVec3Cross(&u, &s, &f); + kmVec3Normalize(&s, &s); + + kmMat4Identity(pOut); + + pOut->mat[0] = s.x; + pOut->mat[4] = s.y; + pOut->mat[8] = s.z; + + pOut->mat[1] = u.x; + pOut->mat[5] = u.y; + pOut->mat[9] = u.z; + + pOut->mat[2] = -f.x; + pOut->mat[6] = -f.y; + pOut->mat[10] = -f.z; + + kmMat4Translation(&translate, -pEye->x, -pEye->y, -pEye->z); + kmMat4Multiply(pOut, pOut, &translate); + + return pOut; +} + +/** + * Extract a 3x3 rotation matrix from the input 4x4 transformation. + * Stores the result in pOut, returns pOut + */ +kmMat3* const kmMat4ExtractRotation(kmMat3* pOut, const kmMat4* pIn) +{ + pOut->mat[0] = pIn->mat[0]; + pOut->mat[1] = pIn->mat[1]; + pOut->mat[2] = pIn->mat[2]; + + pOut->mat[3] = pIn->mat[4]; + pOut->mat[4] = pIn->mat[5]; + pOut->mat[5] = pIn->mat[6]; + + pOut->mat[6] = pIn->mat[8]; + pOut->mat[7] = pIn->mat[9]; + pOut->mat[8] = pIn->mat[10]; + + return pOut; +} + +/** + * Take the rotation from a 4x4 transformation matrix, and return it as an axis and an angle (in radians) + * returns the output axis. + */ +kmVec3* const kmMat4RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn) +{ + /*Surely not this easy?*/ + kmQuaternion temp; + kmMat3 rotation; + kmMat4ExtractRotation(&rotation, pIn); + kmQuaternionRotationMatrix(&temp, &rotation); + kmQuaternionToAxisAngle(&temp, pAxis, radians); + return pAxis; +} + +/** Build a 4x4 OpenGL transformation matrix using a 3x3 rotation matrix, + * and a 3d vector representing a translation. Assign the result to pOut, + * pOut is also returned. + */ +kmMat4* const kmMat4RotationTranslation(kmMat4* pOut, const kmMat3* rotation, const kmVec3* translation) +{ + pOut->mat[0] = rotation->mat[0]; + pOut->mat[1] = rotation->mat[1]; + pOut->mat[2] = rotation->mat[2]; + pOut->mat[3] = 0.0f; + + pOut->mat[4] = rotation->mat[3]; + pOut->mat[5] = rotation->mat[4]; + pOut->mat[6] = rotation->mat[5]; + pOut->mat[7] = 0.0f; + + pOut->mat[8] = rotation->mat[6]; + pOut->mat[9] = rotation->mat[7]; + pOut->mat[10] = rotation->mat[8]; + pOut->mat[11] = 0.0f; + + pOut->mat[12] = translation->x; + pOut->mat[13] = translation->y; + pOut->mat[14] = translation->z; + pOut->mat[15] = 1.0f; + + return pOut; +} + +kmPlane* const kmMat4ExtractPlane(kmPlane* pOut, const kmMat4* pIn, const kmEnum plane) +{ + kmScalar t = 1.0f; + + switch(plane) { + case KM_PLANE_RIGHT: + pOut->a = pIn->mat[3] - pIn->mat[0]; + pOut->b = pIn->mat[7] - pIn->mat[4]; + pOut->c = pIn->mat[11] - pIn->mat[8]; + pOut->d = pIn->mat[15] - pIn->mat[12]; + break; + case KM_PLANE_LEFT: + pOut->a = pIn->mat[3] + pIn->mat[0]; + pOut->b = pIn->mat[7] + pIn->mat[4]; + pOut->c = pIn->mat[11] + pIn->mat[8]; + pOut->d = pIn->mat[15] + pIn->mat[12]; + break; + case KM_PLANE_BOTTOM: + pOut->a = pIn->mat[3] + pIn->mat[1]; + pOut->b = pIn->mat[7] + pIn->mat[5]; + pOut->c = pIn->mat[11] + pIn->mat[9]; + pOut->d = pIn->mat[15] + pIn->mat[13]; + break; + case KM_PLANE_TOP: + pOut->a = pIn->mat[3] - pIn->mat[1]; + pOut->b = pIn->mat[7] - pIn->mat[5]; + pOut->c = pIn->mat[11] - pIn->mat[9]; + pOut->d = pIn->mat[15] - pIn->mat[13]; + break; + case KM_PLANE_FAR: + pOut->a = pIn->mat[3] - pIn->mat[2]; + pOut->b = pIn->mat[7] - pIn->mat[6]; + pOut->c = pIn->mat[11] - pIn->mat[10]; + pOut->d = pIn->mat[15] - pIn->mat[14]; + break; + case KM_PLANE_NEAR: + pOut->a = pIn->mat[3] + pIn->mat[2]; + pOut->b = pIn->mat[7] + pIn->mat[6]; + pOut->c = pIn->mat[11] + pIn->mat[10]; + pOut->d = pIn->mat[15] + pIn->mat[14]; + break; + default: + assert(0 && "Invalid plane index"); + } + + t = sqrtf(pOut->a * pOut->a + + pOut->b * pOut->b + + pOut->c * pOut->c); + pOut->a /= t; + pOut->b /= t; + pOut->c /= t; + pOut->d /= t; + + return pOut; +} diff --git a/external/kazmath/mat4.h b/external/kazmath/mat4.h new file mode 100755 index 0000000..177c74d --- /dev/null +++ b/external/kazmath/mat4.h @@ -0,0 +1,95 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef MAT4_H_INCLUDED +#define MAT4_H_INCLUDED + +#include "utility.h" + +struct kmVec3; +struct kmMat3; +struct kmQuaternion; +struct kmPlane; + +/* +A 4x4 matrix + + | 0 4 8 12 | + mat = | 1 5 9 13 | + | 2 6 10 14 | + | 3 7 11 15 | +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct kmMat4 { + kmScalar mat[16]; +} kmMat4; + +kmMat4* const kmMat4Fill(kmMat4* pOut, const kmScalar* pMat); + + +kmMat4* const kmMat4Identity(kmMat4* pOut); + +kmMat4* const kmMat4Inverse(kmMat4* pOut, const kmMat4* pM); + + +const int kmMat4IsIdentity(const kmMat4* pIn); + +kmMat4* const kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn); +kmMat4* const kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2); + +kmMat4* const kmMat4Assign(kmMat4* pOut, const kmMat4* pIn); +kmMat4* const kmMat4AssignMat3(kmMat4* pOut, const struct kmMat3* pIn); + +const int kmMat4AreEqual(const kmMat4* pM1, const kmMat4* pM2); + +kmMat4* const kmMat4RotationX(kmMat4* pOut, const kmScalar radians); +kmMat4* const kmMat4RotationY(kmMat4* pOut, const kmScalar radians); +kmMat4* const kmMat4RotationZ(kmMat4* pOut, const kmScalar radians); +kmMat4* const kmMat4RotationPitchYawRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll); +kmMat4* const kmMat4RotationQuaternion(kmMat4* pOut, const struct kmQuaternion* pQ); +kmMat4* const kmMat4RotationTranslation(kmMat4* pOut, const struct kmMat3* rotation, const struct kmVec3* translation); +kmMat4* const kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z); +kmMat4* const kmMat4Translation(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z); + +struct kmVec3* const kmMat4GetUpVec3(struct kmVec3* pOut, const kmMat4* pIn); +struct kmVec3* const kmMat4GetRightVec3(struct kmVec3* pOut, const kmMat4* pIn); +struct kmVec3* const kmMat4GetForwardVec3(struct kmVec3* pOut, const kmMat4* pIn); + +kmMat4* const kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY, kmScalar aspect, kmScalar zNear, kmScalar zFar); +kmMat4* const kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left, kmScalar right, kmScalar bottom, kmScalar top, kmScalar nearVal, kmScalar farVal); +kmMat4* const kmMat4LookAt(kmMat4* pOut, const struct kmVec3* pEye, const struct kmVec3* pCenter, const struct kmVec3* pUp); + +kmMat4* const kmMat4RotationAxisAngle(kmMat4* pOut, const struct kmVec3* axis, kmScalar radians); +struct kmMat3* const kmMat4ExtractRotation(struct kmMat3* pOut, const kmMat4* pIn); +struct kmPlane* const kmMat4ExtractPlane(struct kmPlane* pOut, const kmMat4* pIn, const kmEnum plane); +struct kmVec3* const kmMat4RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn); +#ifdef __cplusplus +} +#endif +#endif /* MAT4_H_INCLUDED */ diff --git a/external/kazmath/plane.c b/external/kazmath/plane.c new file mode 100755 index 0000000..caa520a --- /dev/null +++ b/external/kazmath/plane.c @@ -0,0 +1,237 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include + +#include "vec3.h" +#include "vec4.h" +#include "plane.h" +#include "mat4.h" + +const kmScalar kmPlaneDot(const kmPlane* pP, const kmVec4* pV) +{ + //a*x + b*y + c*z + d*w + + return (pP->a * pV->x + + pP->b * pV->y + + pP->c * pV->z + + pP->d * pV->w); +} + +const kmScalar kmPlaneDotCoord(const kmPlane* pP, const kmVec3* pV) +{ + return (pP->a * pV->x + + pP->b * pV->y + + pP->c * pV->z + pP->d); +} + +const kmScalar kmPlaneDotNormal(const kmPlane* pP, const kmVec3* pV) +{ + return (pP->a * pV->x + + pP->b * pV->y + + pP->c * pV->z); +} + +kmPlane* const kmPlaneFromPointNormal(kmPlane* pOut, const kmVec3* pPoint, const kmVec3* pNormal) +{ + /* + Planea = Nx + Planeb = Ny + Planec = Nz + Planed = −N⋅P + */ + + + pOut->a = pNormal->x; + pOut->b = pNormal->y; + pOut->c = pNormal->z; + pOut->d = -kmVec3Dot(pNormal, pPoint); + + return pOut; +} + +/** + * Creates a plane from 3 points. The result is stored in pOut. + * pOut is returned. + */ +kmPlane* const kmPlaneFromPoints(kmPlane* pOut, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3) +{ + /* + v = (B − A) × (C − A) + n = 1⁄|v| v + Outa = nx + Outb = ny + Outc = nz + Outd = −n⋅A + */ + + kmVec3 n, v1, v2; + kmVec3Subtract(&v1, p2, p1); //Create the vectors for the 2 sides of the triangle + kmVec3Subtract(&v2, p3, p1); + kmVec3Cross(&n, &v1, &v2); //Use the cross product to get the normal + + kmVec3Normalize(&n, &n); //Normalize it and assign to pOut->m_N + + pOut->a = n.x; + pOut->b = n.y; + pOut->c = n.z; + pOut->d = kmVec3Dot(kmVec3Scale(&n, &n, -1.0), p1); + + return pOut; +} + +// Added by tlensing (http://icedcoffee-framework.org) +kmVec3* const kmPlaneIntersectLine(kmVec3* pOut, const kmPlane* pP, const kmVec3* pV1, const kmVec3* pV2) +{ + /* + n = (Planea, Planeb, Planec) + d = V − U + Out = U − d⋅(Pd + n⋅U)⁄(d⋅n) [iff d⋅n ≠ 0] + */ + kmVec3 d; // direction from V1 to V2 + kmVec3Subtract(&d, pV2, pV1); // Get the direction vector + + kmVec3 n; // plane normal + n.x = pP->a; + n.y = pP->b; + n.z = pP->c; + kmVec3Normalize(&n, &n); + + kmScalar nt = -(n.x * pV1->x + n.y * pV1->y + n.z * pV1->z + pP->d); + kmScalar dt = (n.x * d.x + n.y * d.y + n.z * d.z); + + if (fabs(dt) < kmEpsilon) { + pOut = NULL; + return pOut; // line parallel or contained + } + + kmScalar t = nt/dt; + pOut->x = pV1->x + d.x * t; + pOut->y = pV1->y + d.y * t; + pOut->z = pV1->z + d.z * t; + + return pOut; +} + +kmPlane* const kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP) +{ + kmVec3 n; + kmScalar l = 0; + + if (!pP->a && !pP->b && !pP->c) { + pOut->a = pP->a; + pOut->b = pP->b; + pOut->c = pP->c; + pOut->d = pP->d; + return pOut; + } + + n.x = pP->a; + n.y = pP->b; + n.z = pP->c; + + l = 1.0f / kmVec3Length(&n); //Get 1/length + kmVec3Normalize(&n, &n); //Normalize the vector and assign to pOut + + pOut->a = n.x; + pOut->b = n.y; + pOut->c = n.z; + + pOut->d = pP->d * l; //Scale the D value and assign to pOut + + return pOut; +} + +kmPlane* const kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s) +{ + assert(0 && "Not implemented"); + return NULL; +} + +/** + * Returns POINT_INFRONT_OF_PLANE if pP is infront of pIn. Returns + * POINT_BEHIND_PLANE if it is behind. Returns POINT_ON_PLANE otherwise + */ +const POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const kmVec3* pP) +{ + // This function will determine if a point is on, in front of, or behind + // the plane. First we store the dot product of the plane and the point. + kmScalar distance = pIn->a * pP->x + pIn->b * pP->y + pIn->c * pP->z + pIn->d; + + // Simply put if the dot product is greater than 0 then it is infront of it. + // If it is less than 0 then it is behind it. And if it is 0 then it is on it. + if(distance > 0.001) return POINT_INFRONT_OF_PLANE; + if(distance < -0.001) return POINT_BEHIND_PLANE; + + return POINT_ON_PLANE; +} + +kmPlane* kmPlaneExtractFromMat4(kmPlane* pOut, const struct kmMat4* pIn, kmInt row) { + int scale = (row < 0) ? -1 : 1; + row = abs(row) - 1; + + pOut->a = pIn->mat[3] + scale * pIn->mat[row]; + pOut->b = pIn->mat[7] + scale * pIn->mat[row + 4]; + pOut->c = pIn->mat[11] + scale * pIn->mat[row + 8]; + pOut->d = pIn->mat[15] + scale * pIn->mat[row + 12]; + + return kmPlaneNormalize(pOut, pOut); +} + +kmVec3* kmPlaneGetIntersection(kmVec3* pOut, const kmPlane* p1, const kmPlane* p2, const kmPlane* p3) { + kmVec3 n1, n2, n3, cross; + kmVec3 r1, r2, r3; + double denom = 0; + + kmVec3Fill(&n1, p1->a, p1->b, p1->c); + kmVec3Fill(&n2, p2->a, p2->b, p2->c); + kmVec3Fill(&n3, p3->a, p3->b, p3->c); + + kmVec3Cross(&cross, &n2, &n3); + + denom = kmVec3Dot(&n1, &cross); + + if (kmAlmostEqual(denom, 0.0)) { + return NULL; + } + + kmVec3Cross(&r1, &n2, &n3); + kmVec3Cross(&r2, &n3, &n1); + kmVec3Cross(&r3, &n1, &n2); + + kmVec3Scale(&r1, &r1, -p1->d); + kmVec3Scale(&r2, &r2, p2->d); + kmVec3Scale(&r3, &r3, p3->d); + + kmVec3Subtract(pOut, &r1, &r2); + kmVec3Subtract(pOut, pOut, &r3); + kmVec3Scale(pOut, pOut, 1.0 / denom); + + //p = -d1 * ( n2.Cross ( n3 ) ) – d2 * ( n3.Cross ( n1 ) ) – d3 * ( n1.Cross ( n2 ) ) / denom; + + return pOut; +} + diff --git a/external/kazmath/plane.h b/external/kazmath/plane.h new file mode 100755 index 0000000..d69a3c2 --- /dev/null +++ b/external/kazmath/plane.h @@ -0,0 +1,73 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef PLANE_H_INCLUDED +#define PLANE_H_INCLUDED + +#define KM_PLANE_LEFT 0 +#define KM_PLANE_RIGHT 1 +#define KM_PLANE_BOTTOM 2 +#define KM_PLANE_TOP 3 +#define KM_PLANE_NEAR 4 +#define KM_PLANE_FAR 5 + +#include "utility.h" + +struct kmVec3; +struct kmVec4; +struct kmMat4; + +typedef struct kmPlane { + kmScalar a, b, c, d; +} kmPlane; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum POINT_CLASSIFICATION { + POINT_INFRONT_OF_PLANE = 0, + POINT_BEHIND_PLANE, + POINT_ON_PLANE, +} POINT_CLASSIFICATION; + +const kmScalar kmPlaneDot(const kmPlane* pP, const struct kmVec4* pV); +const kmScalar kmPlaneDotCoord(const kmPlane* pP, const struct kmVec3* pV); +const kmScalar kmPlaneDotNormal(const kmPlane* pP, const struct kmVec3* pV); +kmPlane* const kmPlaneFromPointNormal(kmPlane* pOut, const struct kmVec3* pPoint, const struct kmVec3* pNormal); +kmPlane* const kmPlaneFromPoints(kmPlane* pOut, const struct kmVec3* p1, const struct kmVec3* p2, const struct kmVec3* p3); +kmVec3* const kmPlaneIntersectLine(struct kmVec3* pOut, const kmPlane* pP, const struct kmVec3* pV1, const struct kmVec3* pV2); +kmPlane* const kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP); +kmPlane* const kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s); +const POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const kmVec3* pP); /** Classifys a point against a plane */ + +kmPlane* kmPlaneExtractFromMat4(kmPlane* pOut, const struct kmMat4* pIn, kmInt row); +kmVec3* kmPlaneGetIntersection(kmVec3* pOut, const kmPlane* p1, const kmPlane* p2, const kmPlane* p3); + +#ifdef __cplusplus +} +#endif + +#endif // PLANE_H_INCLUDED diff --git a/external/kazmath/quaternion.c b/external/kazmath/quaternion.c new file mode 100755 index 0000000..1c5af5a --- /dev/null +++ b/external/kazmath/quaternion.c @@ -0,0 +1,533 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include +#include + +#include "utility.h" +#include "mat3.h" +#include "vec3.h" +#include "quaternion.h" + +///< Returns pOut, sets pOut to the conjugate of pIn +kmQuaternion* const kmQuaternionConjugate(kmQuaternion* pOut, const kmQuaternion* pIn) +{ + pOut->x = -pIn->x; + pOut->y = -pIn->y; + pOut->z = -pIn->z; + pOut->w = pIn->w; + + return pOut; +} + +///< Returns the dot product of the 2 quaternions +const kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2) +{ + /* A dot B = B dot A = AtBt + AxBx + AyBy + AzBz */ + + return (q1->w * q2->w + + q1->x * q2->x + + q1->y * q2->y + + q1->z * q2->z); +} + +///< Returns the exponential of the quaternion +kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn) +{ + assert(0); + + return pOut; +} + +///< Makes the passed quaternion an identity quaternion +kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut) +{ + pOut->x = 0.0; + pOut->y = 0.0; + pOut->z = 0.0; + pOut->w = 1.0; + + return pOut; +} + +///< Returns the inverse of the passed Quaternion +kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut, + const kmQuaternion* pIn) +{ + kmScalar l = kmQuaternionLength(pIn); + kmQuaternion tmp; + + if (fabs(l) < kmEpsilon) + { + pOut->x = 0.0; + pOut->y = 0.0; + pOut->z = 0.0; + pOut->w = 0.0; + + return pOut; + } + + + + ///Get the conjugute and divide by the length + kmQuaternionScale(pOut, + kmQuaternionConjugate(&tmp, pIn), 1.0f / l); + + return pOut; +} + +///< Returns true if the quaternion is an identity quaternion +int kmQuaternionIsIdentity(const kmQuaternion* pIn) +{ + return (pIn->x == 0.0 && pIn->y == 0.0 && pIn->z == 0.0 && + pIn->w == 1.0); +} + +///< Returns the length of the quaternion +kmScalar kmQuaternionLength(const kmQuaternion* pIn) +{ + return sqrtf(kmQuaternionLengthSq(pIn)); +} + +///< Returns the length of the quaternion squared (prevents a sqrt) +kmScalar kmQuaternionLengthSq(const kmQuaternion* pIn) +{ + return pIn->x * pIn->x + pIn->y * pIn->y + + pIn->z * pIn->z + pIn->w * pIn->w; +} + +///< Returns the natural logarithm +kmQuaternion* kmQuaternionLn(kmQuaternion* pOut, + const kmQuaternion* pIn) +{ + /* + A unit quaternion, is defined by: + Q == (cos(theta), sin(theta) * v) where |v| = 1 + The natural logarithm of Q is, ln(Q) = (0, theta * v) + */ + + assert(0); + + return pOut; +} + +///< Multiplies 2 quaternions together +extern +kmQuaternion* kmQuaternionMultiply(kmQuaternion* pOut, + const kmQuaternion* q1, + const kmQuaternion* q2) +{ + pOut->x = q1->w * q2->x + q1->x * q2->w + q1->y * q2->z - q1->z * q2->y; + pOut->y = q1->w * q2->y + q1->y * q2->w + q1->z * q2->x - q1->x * q2->z; + pOut->z = q1->w * q2->z + q1->z * q2->w + q1->x * q2->y - q1->y * q2->x; + pOut->w = q1->w * q2->w - q1->x * q2->x - q1->y * q2->y - q1->z * q2->z; + + return pOut; +} + +///< Normalizes a quaternion +kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut, + const kmQuaternion* pIn) +{ + kmScalar length = kmQuaternionLength(pIn); + assert(fabs(length) > kmEpsilon); + kmQuaternionScale(pOut, pIn, 1.0f / length); + + return pOut; +} + +///< Rotates a quaternion around an axis +kmQuaternion* kmQuaternionRotationAxis(kmQuaternion* pOut, + const kmVec3* pV, + kmScalar angle) +{ + kmScalar rad = angle * 0.5f; + kmScalar scale = sinf(rad); + + pOut->w = cosf(rad); + pOut->x = pV->x * scale; + pOut->y = pV->y * scale; + pOut->z = pV->z * scale; + + return pOut; +} + +///< Creates a quaternion from a rotation matrix +kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut, + const kmMat3* pIn) +{ +/* +Note: The OpenGL matrices are transposed from the description below +taken from the Matrix and Quaternion FAQ + + if ( mat[0] > mat[5] && mat[0] > mat[10] ) { // Column 0: + S = sqrt( 1.0 + mat[0] - mat[5] - mat[10] ) * 2; + X = 0.25 * S; + Y = (mat[4] + mat[1] ) / S; + Z = (mat[2] + mat[8] ) / S; + W = (mat[9] - mat[6] ) / S; + } else if ( mat[5] > mat[10] ) { // Column 1: + S = sqrt( 1.0 + mat[5] - mat[0] - mat[10] ) * 2; + X = (mat[4] + mat[1] ) / S; + Y = 0.25 * S; + Z = (mat[9] + mat[6] ) / S; + W = (mat[2] - mat[8] ) / S; + } else { // Column 2: + S = sqrt( 1.0 + mat[10] - mat[0] - mat[5] ) * 2; + X = (mat[2] + mat[8] ) / S; + Y = (mat[9] + mat[6] ) / S; + Z = 0.25 * S; + W = (mat[4] - mat[1] ) / S; + } +*/ + + kmScalar x, y, z, w; + kmScalar *pMatrix = NULL; + kmScalar m4x4[16] = {0}; + kmScalar scale = 0.0f; + kmScalar diagonal = 0.0f; + + if(!pIn) { + return NULL; + } + +/* 0 3 6 + 1 4 7 + 2 5 8 + + 0 1 2 3 + 4 5 6 7 + 8 9 10 11 + 12 13 14 15*/ + + m4x4[0] = pIn->mat[0]; + m4x4[1] = pIn->mat[3]; + m4x4[2] = pIn->mat[6]; + m4x4[4] = pIn->mat[1]; + m4x4[5] = pIn->mat[4]; + m4x4[6] = pIn->mat[7]; + m4x4[8] = pIn->mat[2]; + m4x4[9] = pIn->mat[5]; + m4x4[10] = pIn->mat[8]; + m4x4[15] = 1; + pMatrix = &m4x4[0]; + + diagonal = pMatrix[0] + pMatrix[5] + pMatrix[10] + 1; + + if(diagonal > kmEpsilon) { + // Calculate the scale of the diagonal + scale = (kmScalar)sqrt(diagonal ) * 2; + + // Calculate the x, y, x and w of the quaternion through the respective equation + x = ( pMatrix[9] - pMatrix[6] ) / scale; + y = ( pMatrix[2] - pMatrix[8] ) / scale; + z = ( pMatrix[4] - pMatrix[1] ) / scale; + w = 0.25f * scale; + } + else + { + // If the first element of the diagonal is the greatest value + if ( pMatrix[0] > pMatrix[5] && pMatrix[0] > pMatrix[10] ) + { + // Find the scale according to the first element, and double that value + scale = (kmScalar)sqrt( 1.0f + pMatrix[0] - pMatrix[5] - pMatrix[10] ) * 2.0f; + + // Calculate the x, y, x and w of the quaternion through the respective equation + x = 0.25f * scale; + y = (pMatrix[4] + pMatrix[1] ) / scale; + z = (pMatrix[2] + pMatrix[8] ) / scale; + w = (pMatrix[9] - pMatrix[6] ) / scale; + } + // Else if the second element of the diagonal is the greatest value + else if (pMatrix[5] > pMatrix[10]) + { + // Find the scale according to the second element, and double that value + scale = (kmScalar)sqrt( 1.0f + pMatrix[5] - pMatrix[0] - pMatrix[10] ) * 2.0f; + + // Calculate the x, y, x and w of the quaternion through the respective equation + x = (pMatrix[4] + pMatrix[1] ) / scale; + y = 0.25f * scale; + z = (pMatrix[9] + pMatrix[6] ) / scale; + w = (pMatrix[2] - pMatrix[8] ) / scale; + } + // Else the third element of the diagonal is the greatest value + else + { + // Find the scale according to the third element, and double that value + scale = (kmScalar)sqrt( 1.0f + pMatrix[10] - pMatrix[0] - pMatrix[5] ) * 2.0f; + + // Calculate the x, y, x and w of the quaternion through the respective equation + x = (pMatrix[2] + pMatrix[8] ) / scale; + y = (pMatrix[9] + pMatrix[6] ) / scale; + z = 0.25f * scale; + w = (pMatrix[4] - pMatrix[1] ) / scale; + } + } + + pOut->x = x; + pOut->y = y; + pOut->z = z; + pOut->w = w; + + return pOut; +} + +///< Create a quaternion from yaw, pitch and roll +kmQuaternion* kmQuaternionRotationYawPitchRoll(kmQuaternion* pOut, + kmScalar yaw, + kmScalar pitch, + kmScalar roll) +{ + kmScalar ex, ey, ez; // temp half euler angles + kmScalar cr, cp, cy, sr, sp, sy, cpcy, spsy; // temp vars in roll,pitch yaw + + ex = kmDegreesToRadians(pitch) / 2.0f; // convert to rads and half them + ey = kmDegreesToRadians(yaw) / 2.0f; + ez = kmDegreesToRadians(roll) / 2.0f; + + cr = cosf(ex); + cp = cosf(ey); + cy = cosf(ez); + + sr = sinf(ex); + sp = sinf(ey); + sy = sinf(ez); + + cpcy = cp * cy; + spsy = sp * sy; + + pOut->w = cr * cpcy + sr * spsy; + + pOut->x = sr * cpcy - cr * spsy; + pOut->y = cr * sp * cy + sr * cp * sy; + pOut->z = cr * cp * sy - sr * sp * cy; + + kmQuaternionNormalize(pOut, pOut); + + return pOut; +} + +///< Interpolate between 2 quaternions +kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut, + const kmQuaternion* q1, + const kmQuaternion* q2, + kmScalar t) +{ + + /*kmScalar CosTheta = Q0.DotProd(Q1); + kmScalar Theta = acosf(CosTheta); + kmScalar SinTheta = sqrtf(1.0f-CosTheta*CosTheta); + + kmScalar Sin_T_Theta = sinf(T*Theta)/SinTheta; + kmScalar Sin_OneMinusT_Theta = sinf((1.0f-T)*Theta)/SinTheta; + + Quaternion Result = Q0*Sin_OneMinusT_Theta; + Result += (Q1*Sin_T_Theta); + + return Result;*/ + + if (q1->x == q2->x && + q1->y == q2->y && + q1->z == q2->z && + q1->w == q2->w) { + + pOut->x = q1->x; + pOut->y = q1->y; + pOut->z = q1->z; + pOut->w = q1->w; + + return pOut; + } + + kmScalar ct = kmQuaternionDot(q1, q2); + kmScalar theta = acosf(ct); + kmScalar st = sqrtf(1.0 - kmSQR(ct)); + + kmScalar stt = sinf(t * theta) / st; + kmScalar somt = sinf((1.0 - t) * theta) / st; + + kmQuaternion temp, temp2; + kmQuaternionScale(&temp, q1, somt); + kmQuaternionScale(&temp2, q2, stt); + kmQuaternionAdd(pOut, &temp, &temp2); + + return pOut; +} + +///< Get the axis and angle of rotation from a quaternion +void kmQuaternionToAxisAngle(const kmQuaternion* pIn, + kmVec3* pAxis, + kmScalar* pAngle) +{ + kmScalar tempAngle; // temp angle + kmScalar scale; // temp vars + + tempAngle = acosf(pIn->w); + scale = sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z)); + + if (((scale > -kmEpsilon) && scale < kmEpsilon) + || (scale < 2*kmPI + kmEpsilon && scale > 2*kmPI - kmEpsilon)) // angle is 0 or 360 so just simply set axis to 0,0,1 with angle 0 + { + *pAngle = 0.0f; + + pAxis->x = 0.0f; + pAxis->y = 0.0f; + pAxis->z = 1.0f; + } + else + { + *pAngle = tempAngle * 2.0f; // angle in radians + + pAxis->x = pIn->x / scale; + pAxis->y = pIn->y / scale; + pAxis->z = pIn->z / scale; + kmVec3Normalize(pAxis, pAxis); + } +} + +kmQuaternion* kmQuaternionScale(kmQuaternion* pOut, + const kmQuaternion* pIn, + kmScalar s) +{ + pOut->x = pIn->x * s; + pOut->y = pIn->y * s; + pOut->z = pIn->z * s; + pOut->w = pIn->w * s; + + return pOut; +} + +kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn) +{ + memcpy(pOut, pIn, sizeof(kmScalar) * 4); + + return pOut; +} + +kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2) +{ + pOut->x = pQ1->x + pQ2->x; + pOut->y = pQ1->y + pQ2->y; + pOut->z = pQ1->z + pQ2->z; + pOut->w = pQ1->w + pQ2->w; + + return pOut; +} + +/** Adapted from the OGRE engine! + + Gets the shortest arc quaternion to rotate this vector to the destination + vector. +@remarks + If you call this with a dest vector that is close to the inverse + of this vector, we will rotate 180 degrees around the 'fallbackAxis' + (if specified, or a generated axis if not) since in this case + ANY axis of rotation is valid. +*/ + +kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const kmVec3* vec1, const kmVec3* vec2, const kmVec3* fallback) { + + kmVec3 v1, v2; + kmScalar a; + + kmVec3Assign(&v1, vec1); + kmVec3Assign(&v2, vec2); + + kmVec3Normalize(&v1, &v1); + kmVec3Normalize(&v2, &v2); + + a = kmVec3Dot(&v1, &v2); + + if (a >= 1.0) { + kmQuaternionIdentity(pOut); + return pOut; + } + + if (a < (1e-6f - 1.0f)) { + if (fabs(kmVec3LengthSq(fallback)) < kmEpsilon) { + kmQuaternionRotationAxis(pOut, fallback, kmPI); + } else { + kmVec3 axis; + kmVec3 X; + X.x = 1.0; + X.y = 0.0; + X.z = 0.0; + + + kmVec3Cross(&axis, &X, vec1); + + //If axis is zero + if (fabs(kmVec3LengthSq(&axis)) < kmEpsilon) { + kmVec3 Y; + Y.x = 0.0; + Y.y = 1.0; + Y.z = 0.0; + + kmVec3Cross(&axis, &Y, vec1); + } + + kmVec3Normalize(&axis, &axis); + + kmQuaternionRotationAxis(pOut, &axis, kmPI); + } + } else { + kmScalar s = sqrtf((1+a) * 2); + kmScalar invs = 1 / s; + + kmVec3 c; + kmVec3Cross(&c, &v1, &v2); + + pOut->x = c.x * invs; + pOut->y = c.y * invs; + pOut->z = c.z * invs; + pOut->w = s * 0.5f; + + kmQuaternionNormalize(pOut, pOut); + } + + return pOut; + +} + +kmVec3* kmQuaternionMultiplyVec3(kmVec3* pOut, const kmQuaternion* q, const kmVec3* v) { + kmVec3 uv, uuv, qvec; + + qvec.x = q->x; + qvec.y = q->y; + qvec.z = q->z; + + kmVec3Cross(&uv, &qvec, v); + kmVec3Cross(&uuv, &qvec, &uv); + + kmVec3Scale(&uv, &uv, (2.0f * q->w)); + kmVec3Scale(&uuv, &uuv, 2.0f); + + kmVec3Add(pOut, v, &uv); + kmVec3Add(pOut, pOut, &uuv); + + return pOut; +} + diff --git a/external/kazmath/quaternion.h b/external/kazmath/quaternion.h new file mode 100755 index 0000000..81ff547 --- /dev/null +++ b/external/kazmath/quaternion.h @@ -0,0 +1,113 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef QUATERNION_H_INCLUDED +#define QUATERNION_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utility.h" + +struct kmMat4; +struct kmMat3; +struct kmVec3; + +typedef struct kmQuaternion { + kmScalar x; + kmScalar y; + kmScalar z; + kmScalar w; +} kmQuaternion; + +kmQuaternion* const kmQuaternionConjugate(kmQuaternion* pOut, const kmQuaternion* pIn); ///< Returns pOut, sets pOut to the conjugate of pIn + +const kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2); ///< Returns the dot product of the 2 quaternions + +kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn); ///< Returns the exponential of the quaternion + +///< Makes the passed quaternion an identity quaternion + +kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut); + +///< Returns the inverse of the passed Quaternion + +kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut, + const kmQuaternion* pIn); + +///< Returns true if the quaternion is an identity quaternion + +int kmQuaternionIsIdentity(const kmQuaternion* pIn); + +///< Returns the length of the quaternion + +kmScalar kmQuaternionLength(const kmQuaternion* pIn); + +///< Returns the length of the quaternion squared (prevents a sqrt) + +kmScalar kmQuaternionLengthSq(const kmQuaternion* pIn); + +///< Returns the natural logarithm + +kmQuaternion* kmQuaternionLn(kmQuaternion* pOut, const kmQuaternion* pIn); + +///< Multiplies 2 quaternions together + +kmQuaternion* kmQuaternionMultiply(kmQuaternion* pOut, const kmQuaternion* q1, const kmQuaternion* q2); + +///< Normalizes a quaternion + +kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut, const kmQuaternion* pIn); + +///< Rotates a quaternion around an axis + +kmQuaternion* kmQuaternionRotationAxis(kmQuaternion* pOut, const struct kmVec3* pV, kmScalar angle); + +///< Creates a quaternion from a rotation matrix + +kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut, const struct kmMat3* pIn); + +///< Create a quaternion from yaw, pitch and roll + +kmQuaternion* kmQuaternionRotationYawPitchRoll(kmQuaternion* pOut, kmScalar yaw, kmScalar pitch, kmScalar roll); +///< Interpolate between 2 quaternions +kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut, const kmQuaternion* q1, const kmQuaternion* q2, kmScalar t); + +///< Get the axis and angle of rotation from a quaternion +void kmQuaternionToAxisAngle(const kmQuaternion* pIn, struct kmVec3* pVector, kmScalar* pAngle); + +///< Scale a quaternion +kmQuaternion* kmQuaternionScale(kmQuaternion* pOut, const kmQuaternion* pIn, kmScalar s); +kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn); +kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2); +kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const struct kmVec3* vec1, const struct kmVec3* vec2, const struct kmVec3* fallback); +struct kmVec3* kmQuaternionMultiplyVec3(struct kmVec3* pOut, const kmQuaternion* q, const struct kmVec3* v); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/kazmath/ray2.c b/external/kazmath/ray2.c new file mode 100755 index 0000000..cdcdf8a --- /dev/null +++ b/external/kazmath/ray2.c @@ -0,0 +1,199 @@ +#include +#include +#include "ray2.h" + +void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy) { + ray->start.x = px; + ray->start.y = py; + ray->dir.x = vx; + ray->dir.y = vy; +} + +kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection) { + + kmScalar x1 = ray->start.x; + kmScalar y1 = ray->start.y; + kmScalar x2 = ray->start.x + ray->dir.x; + kmScalar y2 = ray->start.y + ray->dir.y; + kmScalar x3 = p1->x; + kmScalar y3 = p1->y; + kmScalar x4 = p2->x; + kmScalar y4 = p2->y; + + kmScalar denom = (y4 -y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); + + //If denom is zero, the lines are parallel + if(denom > -kmEpsilon && denom < kmEpsilon) { + return KM_FALSE; + } + + kmScalar ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom; + kmScalar ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom; + + kmScalar x = x1 + ua * (x2 - x1); + kmScalar y = y1 + ua * (y2 - y1); + + if((0.0 < ua) && (ua < 1.0) && (0.0 < ub) && (ub < 1.0)) { + intersection->x = x; + intersection->y = y; + + return KM_TRUE; + } + + return KM_FALSE; +} + +void calculate_line_normal(kmVec2 p1, kmVec2 p2, kmVec2 other_point, kmVec2* normal_out) { + /* + A = (3,4) + B = (2,1) + C = (1,3) + + AB = (2,1) - (3,4) = (-1,-3) + AC = (1,3) - (3,4) = (-2,-1) + N = n(AB) = (-3,1) + D = dot(N,AC) = 6 + -1 = 5 + + since D > 0: + N = -N = (3,-1) + */ + + kmVec2 edge, other_edge; + kmVec2Subtract(&edge, &p2, &p1); + kmVec2Subtract(&other_edge, &other_point, &p1); + kmVec2Normalize(&edge, &edge); + kmVec2Normalize(&other_edge, &other_edge); + + kmVec2 n; + n.x = edge.y; + n.y = -edge.x; + + kmScalar d = kmVec2Dot(&n, &other_edge); + if(d > 0.0f) { + n.x = -n.x; + n.y = -n.y; + } + + normal_out->x = n.x; + normal_out->y = n.y; + kmVec2Normalize(normal_out, normal_out); +} + +kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out, kmScalar* distance_out) { + kmVec2 intersect; + kmVec2 final_intersect; + kmVec2 normal; + kmScalar distance = 10000.0f; + kmBool intersected = KM_FALSE; + + if(kmRay2IntersectLineSegment(ray, p1, p2, &intersect)) { + kmVec2 tmp; + kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start)); + kmVec2 this_normal; + calculate_line_normal(*p1, *p2, *p3, &this_normal); + if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) { + final_intersect.x = intersect.x; + final_intersect.y = intersect.y; + distance = this_distance; + kmVec2Assign(&normal, &this_normal); + intersected = KM_TRUE; + } + } + + if(kmRay2IntersectLineSegment(ray, p2, p3, &intersect)) { + kmVec2 tmp; + kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start)); + + kmVec2 this_normal; + calculate_line_normal(*p2, *p3, *p1, &this_normal); + + if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) { + final_intersect.x = intersect.x; + final_intersect.y = intersect.y; + distance = this_distance; + kmVec2Assign(&normal, &this_normal); + intersected = KM_TRUE; + } + } + + if(kmRay2IntersectLineSegment(ray, p3, p1, &intersect)) { + + kmVec2 tmp; + kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start)); + + kmVec2 this_normal; + calculate_line_normal(*p3, *p1, *p2, &this_normal); + if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) { + final_intersect.x = intersect.x; + final_intersect.y = intersect.y; + distance = this_distance; + kmVec2Assign(&normal, &this_normal); + intersected = KM_TRUE; + } + } + + if(intersected) { + intersection->x = final_intersect.x; + intersection->y = final_intersect.y; + if(normal_out) { + normal_out->x = normal.x; + normal_out->y = normal.y; + } + if(distance) { + *distance_out = distance; + } + } + + return intersected; +} + +kmBool kmRay2IntersectBox(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, const kmVec2* p4, +kmVec2* intersection, kmVec2* normal_out) { + kmBool intersected = KM_FALSE; + kmVec2 intersect, final_intersect, normal; + kmScalar distance = 10000.0f; + + const kmVec2* points[4]; + points[0] = p1; + points[1] = p2; + points[2] = p3; + points[3] = p4; + + unsigned int i = 0; + for(; i < 4; ++i) { + const kmVec2* this_point = points[i]; + const kmVec2* next_point = (i == 3) ? points[0] : points[i+1]; + const kmVec2* other_point = (i == 3 || i == 0) ? points[1] : points[0]; + + if(kmRay2IntersectLineSegment(ray, this_point, next_point, &intersect)) { + + kmVec2 tmp; + kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start)); + + kmVec2 this_normal; + + calculate_line_normal(*this_point, *next_point, *other_point, &this_normal); + if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) { + kmVec2Assign(&final_intersect, &intersect); + distance = this_distance; + intersected = KM_TRUE; + kmVec2Assign(&normal, &this_normal); + } + } + } + + if(intersected) { + intersection->x = final_intersect.x; + intersection->y = final_intersect.y; + if(normal_out) { + normal_out->x = normal.x; + normal_out->y = normal.y; + } + } + + return intersected; +} + +kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection) { + assert(0 && "Not implemented"); +} diff --git a/external/kazmath/ray2.h b/external/kazmath/ray2.h new file mode 100755 index 0000000..5465cf2 --- /dev/null +++ b/external/kazmath/ray2.h @@ -0,0 +1,54 @@ +/* +Copyright (c) 2011, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef RAY_2_H +#define RAY_2_H + +#include "utility.h" +#include "vec2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct kmRay2 { + kmVec2 start; + kmVec2 dir; +} kmRay2; + +void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy); +kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection); +kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out, kmScalar* distance); + +kmBool kmRay2IntersectBox(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, const kmVec2* p4, +kmVec2* intersection, kmVec2* normal_out); + +kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/kazmath/utility.c b/external/kazmath/utility.c new file mode 100755 index 0000000..13c7cc9 --- /dev/null +++ b/external/kazmath/utility.c @@ -0,0 +1,59 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "utility.h" + +/** + * Returns the square of s (e.g. s*s) + */ +kmScalar kmSQR(kmScalar s) { + return s*s; +} + +/** + * Returns degrees as radians. + */ +kmScalar kmDegreesToRadians(kmScalar degrees) { + return degrees * kmPIOver180; +} + +/** + * Returns radians as degrees + */ +kmScalar kmRadiansToDegrees(kmScalar radians) { + return radians * kmPIUnder180; +} + +kmScalar min(kmScalar lhs, kmScalar rhs) { + return (lhs < rhs)? lhs : rhs; +} + +kmScalar max(kmScalar lhs, kmScalar rhs) { + return (lhs > rhs)? lhs : rhs; +} + +kmBool kmAlmostEqual(kmScalar lhs, kmScalar rhs) { + return (lhs + kmEpsilon > rhs && lhs - kmEpsilon < rhs); +} diff --git a/external/kazmath/utility.h b/external/kazmath/utility.h new file mode 100755 index 0000000..d73adff --- /dev/null +++ b/external/kazmath/utility.h @@ -0,0 +1,93 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTILITY_H_INCLUDED +#define UTILITY_H_INCLUDED + +#include + +#ifndef kmScalar +#ifdef USE_DOUBLE_PRECISION +#define kmScalar double +#else +#define kmScalar float +#endif + +#endif + +#ifndef kmBool +#define kmBool unsigned char +#endif + +#ifndef kmUchar +#define kmUchar unsigned char +#endif + +#ifndef kmEnum +#define kmEnum unsigned int +#endif + +#ifndef kmUint +#define kmUint unsigned int +#endif + +#ifndef kmInt +#define kmInt int +#endif + +#ifndef KM_FALSE +#define KM_FALSE 0 +#endif + +#ifndef KM_TRUE +#define KM_TRUE 1 +#endif + +#define kmPI 3.141592f +#define kmPIOver180 0.017453f // PI / 180 +#define kmPIUnder180 57.295779f // 180 / PI +#define kmEpsilon 0.0001 + +#define KM_CONTAINS_NONE 0 +#define KM_CONTAINS_PARTIAL 1 +#define KM_CONTAINS_ALL 2 + +#ifdef __cplusplus +extern "C" { +#endif + +extern kmScalar kmSQR(kmScalar s); +extern kmScalar kmDegreesToRadians(kmScalar degrees); +extern kmScalar kmRadiansToDegrees(kmScalar radians); + +extern kmScalar min(kmScalar lhs, kmScalar rhs); +extern kmScalar max(kmScalar lhs, kmScalar rhs); +extern kmBool kmAlmostEqual(kmScalar lhs, kmScalar rhs); + +#ifdef __cplusplus +} +#endif + +#endif /* UTILITY_H_INCLUDED */ diff --git a/external/kazmath/vec2.c b/external/kazmath/vec2.c new file mode 100755 index 0000000..5916ac0 --- /dev/null +++ b/external/kazmath/vec2.c @@ -0,0 +1,213 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include + +#include "mat3.h" +#include "vec2.h" +#include "utility.h" + +kmVec2* kmVec2Fill(kmVec2* pOut, kmScalar x, kmScalar y) +{ + pOut->x = x; + pOut->y = y; + return pOut; +} + +kmScalar kmVec2Length(const kmVec2* pIn) +{ + return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y)); +} + +kmScalar kmVec2LengthSq(const kmVec2* pIn) +{ + return kmSQR(pIn->x) + kmSQR(pIn->y); +} + +kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn) +{ + if (!pIn->x && !pIn->y) + return kmVec2Assign(pOut, pIn); + + kmScalar l = 1.0f / kmVec2Length(pIn); + + kmVec2 v; + v.x = pIn->x * l; + v.y = pIn->y * l; + + pOut->x = v.x; + pOut->y = v.y; + + return pOut; +} + +kmVec2* kmVec2Add(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2) +{ + pOut->x = pV1->x + pV2->x; + pOut->y = pV1->y + pV2->y; + + return pOut; +} + +kmScalar kmVec2Dot(const kmVec2* pV1, const kmVec2* pV2) +{ + return pV1->x * pV2->x + pV1->y * pV2->y; +} + +kmScalar kmVec2Cross(const kmVec2* pV1, const kmVec2* pV2) +{ + return pV1->x * pV2->y - pV1->y * pV2->x; +} + +kmVec2* kmVec2Subtract(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2) +{ + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + + return pOut; +} + +kmVec2* kmVec2Transform(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM) +{ + kmVec2 v; + + v.x = pV->x * pM->mat[0] + pV->y * pM->mat[3] + pM->mat[6]; + v.y = pV->x * pM->mat[1] + pV->y * pM->mat[4] + pM->mat[7]; + + pOut->x = v.x; + pOut->y = v.y; + + return pOut; +} + +kmVec2* kmVec2TransformCoord(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM) +{ + assert(0); + return NULL; +} + +kmVec2* kmVec2Scale(kmVec2* pOut, const kmVec2* pIn, const kmScalar s) +{ + pOut->x = pIn->x * s; + pOut->y = pIn->y * s; + + return pOut; +} + +int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2) +{ + return ( + (p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) && + (p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon) + ); +} + +/** + * Assigns pIn to pOut. Returns pOut. If pIn and pOut are the same + * then nothing happens but pOut is still returned + */ +kmVec2* kmVec2Assign(kmVec2* pOut, const kmVec2* pIn) { + if (pOut == pIn) { + return pOut; + } + + pOut->x = pIn->x; + pOut->y = pIn->y; + + return pOut; +} + +/** + * Rotates the point anticlockwise around a center + * by an amount of degrees. + * + * Code ported from Irrlicht: http://irrlicht.sourceforge.net/ + */ +kmVec2* kmVec2RotateBy(kmVec2* pOut, const kmVec2* pIn, + const kmScalar degrees, const kmVec2* center) +{ + kmScalar x, y; + const kmScalar radians = kmDegreesToRadians(degrees); + const kmScalar cs = cos(radians), sn = sin(radians); + + pOut->x = pIn->x - center->x; + pOut->y = pIn->y - center->y; + + x = pOut->x * cs - pOut->y * sn; + y = pOut->x * sn + pOut->y * cs; + + pOut->x = x + center->x; + pOut->y = y + center->y; + + return pOut; +} + +/** + * Returns the angle in degrees between the two vectors + */ +kmScalar kmVec2DegreesBetween(const kmVec2* v1, const kmVec2* v2) { + if(kmVec2AreEqual(v1, v2)) { + return 0.0; + } + + kmVec2 t1, t2; + kmVec2Normalize(&t1, v1); + kmVec2Normalize(&t2, v2); + + kmScalar cross = kmVec2Cross(&t1, &t2); + kmScalar dot = kmVec2Dot(&t1, &t2); + + /* + * acos is only defined for -1 to 1. Outside the range we + * get NaN even if that's just because of a floating point error + * so we clamp to the -1 - 1 range + */ + + if(dot > 1.0) dot = 1.0; + if(dot < -1.0) dot = -1.0; + + return kmRadiansToDegrees(atan2(cross, dot)); +} + +/** + * Returns the distance between the two points + */ +kmScalar kmVec2DistanceBetween(const kmVec2* v1, const kmVec2* v2) { + kmVec2 diff; + kmVec2Subtract(&diff, v2, v1); + return fabs(kmVec2Length(&diff)); +} +/** + * Returns the point mid-way between two others + */ +kmVec2* kmVec2MidPointBetween(kmVec2* pOut, const kmVec2* v1, const kmVec2* v2) { + kmVec2 diff; + kmVec2Subtract(&diff, v2, v1); + kmVec2Normalize(&diff, &diff); + kmVec2Scale(&diff, &diff, kmVec2DistanceBetween(v1, v2) * 0.5); + kmVec2Add(pOut, v1, &diff); + return pOut; +} diff --git a/external/kazmath/vec2.h b/external/kazmath/vec2.h new file mode 100755 index 0000000..916bdba --- /dev/null +++ b/external/kazmath/vec2.h @@ -0,0 +1,69 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef VEC2_H_INCLUDED +#define VEC2_H_INCLUDED + +#include "utility.h" + +struct kmMat3; + +#pragma pack(push) /* push current alignment to stack */ +#pragma pack(1) /* set alignment to 1 byte boundary */ +typedef struct kmVec2 { + kmScalar x; + kmScalar y; +} kmVec2; + +#pragma pack(pop) + +#ifdef __cplusplus +extern "C" { +#endif + +kmVec2* kmVec2Fill(kmVec2* pOut, kmScalar x, kmScalar y); +kmScalar kmVec2Length(const kmVec2* pIn); ///< Returns the length of the vector +kmScalar kmVec2LengthSq(const kmVec2* pIn); ///< Returns the square of the length of the vector +kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn); ///< Returns the vector passed in set to unit length +kmVec2* kmVec2Add(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2); ///< Adds 2 vectors and returns the result +kmScalar kmVec2Dot(const kmVec2* pV1, const kmVec2* pV2); /** Returns the Dot product which is the cosine of the angle between the two vectors multiplied by their lengths */ +kmScalar kmVec2Cross(const kmVec2* pV1, const kmVec2* pV2); +kmVec2* kmVec2Subtract(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2); ///< Subtracts 2 vectors and returns the result +kmVec2* kmVec2Transform(kmVec2* pOut, const kmVec2* pV1, const struct kmMat3* pM); /** Transform the Vector */ +kmVec2* kmVec2TransformCoord(kmVec2* pOut, const kmVec2* pV, const struct kmMat3* pM); /// +#include + +#include "utility.h" +#include "vec4.h" +#include "mat4.h" +#include "mat3.h" +#include "vec3.h" + +/** + * Fill a kmVec3 structure using 3 floating point values + * The result is store in pOut, returns pOut + */ +kmVec3* kmVec3Fill(kmVec3* pOut, kmScalar x, kmScalar y, kmScalar z) +{ + pOut->x = x; + pOut->y = y; + pOut->z = z; + return pOut; +} + + +/** + * Returns the length of the vector + */ +kmScalar kmVec3Length(const kmVec3* pIn) +{ + return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z)); +} + +/** + * Returns the square of the length of the vector + */ +kmScalar kmVec3LengthSq(const kmVec3* pIn) +{ + return kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z); +} + + /** + * Returns the vector passed in set to unit length + * the result is stored in pOut. + */ +kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn) +{ + if (!pIn->x && !pIn->y && !pIn->z) + return kmVec3Assign(pOut, pIn); + + kmScalar l = 1.0f / kmVec3Length(pIn); + + kmVec3 v; + v.x = pIn->x * l; + v.y = pIn->y * l; + v.z = pIn->z * l; + + pOut->x = v.x; + pOut->y = v.y; + pOut->z = v.z; + + return pOut; +} + +/** + * Returns a vector perpendicular to 2 other vectors. + * The result is stored in pOut. + */ +kmVec3* kmVec3Cross(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2) +{ + + kmVec3 v; + + v.x = (pV1->y * pV2->z) - (pV1->z * pV2->y); + v.y = (pV1->z * pV2->x) - (pV1->x * pV2->z); + v.z = (pV1->x * pV2->y) - (pV1->y * pV2->x); + + pOut->x = v.x; + pOut->y = v.y; + pOut->z = v.z; + + return pOut; +} + +/** + * Returns the cosine of the angle between 2 vectors + */ +kmScalar kmVec3Dot(const kmVec3* pV1, const kmVec3* pV2) +{ + return ( pV1->x * pV2->x + + pV1->y * pV2->y + + pV1->z * pV2->z ); +} + +/** + * Adds 2 vectors and returns the result. The resulting + * vector is stored in pOut. + */ +kmVec3* kmVec3Add(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2) +{ + kmVec3 v; + + v.x = pV1->x + pV2->x; + v.y = pV1->y + pV2->y; + v.z = pV1->z + pV2->z; + + pOut->x = v.x; + pOut->y = v.y; + pOut->z = v.z; + + return pOut; +} + + /** + * Subtracts 2 vectors and returns the result. The result is stored in + * pOut. + */ +kmVec3* kmVec3Subtract(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2) +{ + kmVec3 v; + + v.x = pV1->x - pV2->x; + v.y = pV1->y - pV2->y; + v.z = pV1->z - pV2->z; + + pOut->x = v.x; + pOut->y = v.y; + pOut->z = v.z; + + return pOut; +} + +kmVec3* kmVec3MultiplyMat3(kmVec3* pOut, const kmVec3* pV, const kmMat3* pM) { + kmVec3 v; + + v.x = pV->x * pM->mat[0] + pV->y * pM->mat[3] + pV->z * pM->mat[6]; + v.y = pV->x * pM->mat[1] + pV->y * pM->mat[4] + pV->z * pM->mat[7]; + v.z = pV->x * pM->mat[2] + pV->y * pM->mat[5] + pV->z * pM->mat[8]; + + pOut->x = v.x; + pOut->y = v.y; + pOut->z = v.z; + + return pOut; +} + +/** + * Multiplies vector (x, y, z, 1) by a given matrix. The result + * is stored in pOut. pOut is returned. + */ + +kmVec3* kmVec3MultiplyMat4(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM) { + kmVec3 v; + + v.x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8] + pM->mat[12]; + v.y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9] + pM->mat[13]; + v.z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10] + pM->mat[14]; + + pOut->x = v.x; + pOut->y = v.y; + pOut->z = v.z; + + return pOut; +} + + +kmVec3* kmVec3Transform(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM) +{ + /* + @deprecated Should intead use kmVec3MultiplyMat4 + */ + return kmVec3MultiplyMat4(pOut, pV, pM); +} + +kmVec3* kmVec3InverseTransform(kmVec3* pOut, const kmVec3* pVect, const kmMat4* pM) +{ + kmVec3 v1, v2; + + v1.x = pVect->x - pM->mat[12]; + v1.y = pVect->y - pM->mat[13]; + v1.z = pVect->z - pM->mat[14]; + + v2.x = v1.x * pM->mat[0] + v1.y * pM->mat[1] + v1.z * pM->mat[2]; + v2.y = v1.x * pM->mat[4] + v1.y * pM->mat[5] + v1.z * pM->mat[6]; + v2.z = v1.x * pM->mat[8] + v1.y * pM->mat[9] + v1.z * pM->mat[10]; + + pOut->x = v2.x; + pOut->y = v2.y; + pOut->z = v2.z; + + return pOut; +} + +kmVec3* kmVec3InverseTransformNormal(kmVec3* pOut, const kmVec3* pVect, const kmMat4* pM) +{ + kmVec3 v; + + v.x = pVect->x * pM->mat[0] + pVect->y * pM->mat[1] + pVect->z * pM->mat[2]; + v.y = pVect->x * pM->mat[4] + pVect->y * pM->mat[5] + pVect->z * pM->mat[6]; + v.z = pVect->x * pM->mat[8] + pVect->y * pM->mat[9] + pVect->z * pM->mat[10]; + + pOut->x = v.x; + pOut->y = v.y; + pOut->z = v.z; + + return pOut; +} + + +kmVec3* kmVec3TransformCoord(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM) +{ + /* + a = (Vx, Vy, Vz, 1) + b = (a×M)T + Out = 1⁄bw(bx, by, bz) + */ + + kmVec4 v; + kmVec4 inV; + kmVec4Fill(&inV, pV->x, pV->y, pV->z, 1.0); + + kmVec4Transform(&v, &inV,pM); + + pOut->x = v.x / v.w; + pOut->y = v.y / v.w; + pOut->z = v.z / v.w; + + return pOut; +} + +kmVec3* kmVec3TransformNormal(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM) +{ +/* + a = (Vx, Vy, Vz, 0) + b = (a×M)T + Out = (bx, by, bz) +*/ + //Omits the translation, only scaling + rotating + kmVec3 v; + + v.x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8]; + v.y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9]; + v.z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10]; + + pOut->x = v.x; + pOut->y = v.y; + pOut->z = v.z; + + return pOut; + +} + +/** + * Scales a vector to length s. Does not normalize first, + * you should do that! + */ +kmVec3* kmVec3Scale(kmVec3* pOut, const kmVec3* pIn, const kmScalar s) +{ + pOut->x = pIn->x * s; + pOut->y = pIn->y * s; + pOut->z = pIn->z * s; + + return pOut; +} + +/** + * Returns KM_TRUE if the 2 vectors are approximately equal + */ +int kmVec3AreEqual(const kmVec3* p1, const kmVec3* p2) +{ + if ((p1->x < (p2->x + kmEpsilon) && p1->x > (p2->x - kmEpsilon)) && + (p1->y < (p2->y + kmEpsilon) && p1->y > (p2->y - kmEpsilon)) && + (p1->z < (p2->z + kmEpsilon) && p1->z > (p2->z - kmEpsilon))) { + return 1; + } + + return 0; +} + +/** + * Assigns pIn to pOut. Returns pOut. If pIn and pOut are the same + * then nothing happens but pOut is still returned + */ +kmVec3* kmVec3Assign(kmVec3* pOut, const kmVec3* pIn) { + if (pOut == pIn) { + return pOut; + } + + pOut->x = pIn->x; + pOut->y = pIn->y; + pOut->z = pIn->z; + + return pOut; +} + +/** + * Sets all the elements of pOut to zero. Returns pOut. + */ +kmVec3* kmVec3Zero(kmVec3* pOut) { + pOut->x = 0.0f; + pOut->y = 0.0f; + pOut->z = 0.0f; + + return pOut; +} + +/** + * Get the rotations that would make a (0,0,1) direction vector point in the same direction as this direction vector. + * Useful for orienting vector towards a point. + * + * Returns a rotation vector containing the X (pitch) and Y (raw) rotations (in degrees) that when applied to a + * +Z (e.g. 0, 0, 1) direction vector would make it point in the same direction as this vector. The Z (roll) rotation + * is always 0, since two Euler rotations are sufficient to point in any given direction. + * + * Code ported from Irrlicht: http://irrlicht.sourceforge.net/ + */ +kmVec3* kmVec3GetHorizontalAngle(kmVec3* pOut, const kmVec3 *pIn) { + const kmScalar z1 = sqrt(pIn->x * pIn->x + pIn->z * pIn->z); + + pOut->y = kmRadiansToDegrees(atan2(pIn->x, pIn->z)); + if (pOut->y < 0) + pOut->y += 360; + if (pOut->y >= 360) + pOut->y -= 360; + + pOut->x = kmRadiansToDegrees(atan2(z1, pIn->y)) - 90.0; + if (pOut->x < 0) + pOut->x += 360; + if (pOut->x >= 360) + pOut->x -= 360; + + return pOut; +} + +/** + * Builds a direction vector from input vector. + * Input vector is assumed to be rotation vector composed from 3 Euler angle rotations, in degrees. + * The forwards vector will be rotated by the input vector + * + * Code ported from Irrlicht: http://irrlicht.sourceforge.net/ + */ +kmVec3* kmVec3RotationToDirection(kmVec3* pOut, const kmVec3* pIn, const kmVec3* forwards) +{ + const kmScalar xr = kmDegreesToRadians(pIn->x); + const kmScalar yr = kmDegreesToRadians(pIn->y); + const kmScalar zr = kmDegreesToRadians(pIn->z); + const kmScalar cr = cos(xr), sr = sin(xr); + const kmScalar cp = cos(yr), sp = sin(yr); + const kmScalar cy = cos(zr), sy = sin(zr); + + const kmScalar srsp = sr*sp; + const kmScalar crsp = cr*sp; + + const kmScalar pseudoMatrix[] = { + (cp*cy), (cp*sy), (-sp), + (srsp*cy-cr*sy), (srsp*sy+cr*cy), (sr*cp), + (crsp*cy+sr*sy), (crsp*sy-sr*cy), (cr*cp) + }; + + pOut->x = forwards->x * pseudoMatrix[0] + + forwards->y * pseudoMatrix[3] + + forwards->z * pseudoMatrix[6]; + + pOut->y = forwards->x * pseudoMatrix[1] + + forwards->y * pseudoMatrix[4] + + forwards->z * pseudoMatrix[7]; + + pOut->z = forwards->x * pseudoMatrix[2] + + forwards->y * pseudoMatrix[5] + + forwards->z * pseudoMatrix[8]; + + return pOut; +} diff --git a/external/kazmath/vec3.h b/external/kazmath/vec3.h new file mode 100755 index 0000000..4f2c5b0 --- /dev/null +++ b/external/kazmath/vec3.h @@ -0,0 +1,73 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef VEC3_H_INCLUDED +#define VEC3_H_INCLUDED + +#include +#include "utility.h" + +struct kmMat4; +struct kmMat3; + +typedef struct kmVec3 { + kmScalar x; + kmScalar y; + kmScalar z; +} kmVec3; + +#ifdef __cplusplus +extern "C" { +#endif + +kmVec3* kmVec3Fill(kmVec3* pOut, kmScalar x, kmScalar y, kmScalar z); +kmScalar kmVec3Length(const kmVec3* pIn); /** Returns the length of the vector */ +kmScalar kmVec3LengthSq(const kmVec3* pIn); /** Returns the square of the length of the vector */ +kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn); /** Returns the vector passed in set to unit length */ +kmVec3* kmVec3Cross(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Returns a vector perpendicular to 2 other vectors */ +kmScalar kmVec3Dot(const kmVec3* pV1, const kmVec3* pV2); /** Returns the cosine of the angle between 2 vectors */ +kmVec3* kmVec3Add(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Adds 2 vectors and returns the result */ +kmVec3* kmVec3Subtract(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Subtracts 2 vectors and returns the result */ + +kmVec3* kmVec3MultiplyMat3(kmVec3 *pOut, const kmVec3 *pV, const struct kmMat3* pM); +kmVec3* kmVec3MultiplyMat4(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM); + +kmVec3* kmVec3Transform(kmVec3* pOut, const kmVec3* pV1, const struct kmMat4* pM); /** Transforms a vector (assuming w=1) by a given matrix */ +kmVec3* kmVec3TransformNormal(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM);/**Transforms a 3D normal by a given matrix */ +kmVec3* kmVec3TransformCoord(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM); /**Transforms a 3D vector by a given matrix, projecting the result back into w = 1. */ + +kmVec3* kmVec3Scale(kmVec3* pOut, const kmVec3* pIn, const kmScalar s); /** Scales a vector to length s */ +int kmVec3AreEqual(const kmVec3* p1, const kmVec3* p2); +kmVec3* kmVec3InverseTransform(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM); +kmVec3* kmVec3InverseTransformNormal(kmVec3* pOut, const kmVec3* pVect, const struct kmMat4* pM); +kmVec3* kmVec3Assign(kmVec3* pOut, const kmVec3* pIn); +kmVec3* kmVec3Zero(kmVec3* pOut); +kmVec3* kmVec3GetHorizontalAngle(kmVec3* pOut, const kmVec3 *pIn); /** Get the rotations that would make a (0,0,1) direction vector point in the same direction as this direction vector. */ +kmVec3* kmVec3RotationToDirection(kmVec3* pOut, const kmVec3* pIn, const kmVec3* forwards); /** Builds a direction vector from input vector. */ + +#ifdef __cplusplus +} +#endif +#endif /* VEC3_H_INCLUDED */ diff --git a/external/kazmath/vec4.c b/external/kazmath/vec4.c new file mode 100755 index 0000000..2b23b91 --- /dev/null +++ b/external/kazmath/vec4.c @@ -0,0 +1,158 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include +#include + +#include "utility.h" +#include "vec4.h" +#include "mat4.h" + + +kmVec4* kmVec4Fill(kmVec4* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w) +{ + pOut->x = x; + pOut->y = y; + pOut->z = z; + pOut->w = w; + return pOut; +} + + +/// Adds 2 4D vectors together. The result is store in pOut, the function returns +/// pOut so that it can be nested in another function. +kmVec4* kmVec4Add(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2) { + pOut->x = pV1->x + pV2->x; + pOut->y = pV1->y + pV2->y; + pOut->z = pV1->z + pV2->z; + pOut->w = pV1->w + pV2->w; + + return pOut; +} + +/// Returns the dot product of 2 4D vectors +kmScalar kmVec4Dot(const kmVec4* pV1, const kmVec4* pV2) { + return ( pV1->x * pV2->x + + pV1->y * pV2->y + + pV1->z * pV2->z + + pV1->w * pV2->w ); +} + +/// Returns the length of a 4D vector, this uses a sqrt so if the squared length will do use +/// kmVec4LengthSq +kmScalar kmVec4Length(const kmVec4* pIn) { + return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w)); +} + +/// Returns the length of the 4D vector squared. +kmScalar kmVec4LengthSq(const kmVec4* pIn) { + return kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w); +} + +/// Returns the interpolation of 2 4D vectors based on t. Currently not implemented! +kmVec4* kmVec4Lerp(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2, kmScalar t) { + assert(0); + return pOut; +} + +/// Normalizes a 4D vector. The result is stored in pOut. pOut is returned +kmVec4* kmVec4Normalize(kmVec4* pOut, const kmVec4* pIn) { + kmScalar l = 1.0f / kmVec4Length(pIn); + + pOut->x *= l; + pOut->y *= l; + pOut->z *= l; + pOut->w *= l; + + return pOut; +} + +/// Scales a vector to the required length. This performs a Normalize before multiplying by S. +kmVec4* kmVec4Scale(kmVec4* pOut, const kmVec4* pIn, const kmScalar s) { + kmVec4Normalize(pOut, pIn); + + pOut->x *= s; + pOut->y *= s; + pOut->z *= s; + pOut->w *= s; + return pOut; +} + +/// Subtracts one 4D pV2 from pV1. The result is stored in pOut. pOut is returned +kmVec4* kmVec4Subtract(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2) { + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + pOut->z = pV1->z - pV2->z; + pOut->w = pV1->w - pV2->w; + + return pOut; +} + +/// Multiplies a 4D vector by a matrix, the result is stored in pOut, and pOut is returned. +kmVec4* kmVec4MultiplyMat4(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM) { + pOut->x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8] + pV->w * pM->mat[12]; + pOut->y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9] + pV->w * pM->mat[13]; + pOut->z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10] + pV->w * pM->mat[14]; + pOut->w = pV->x * pM->mat[3] + pV->y * pM->mat[7] + pV->z * pM->mat[11] + pV->w * pM->mat[15]; + return pOut; +} + +kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const kmMat4* pM) { + return kmVec4MultiplyMat4(pOut, pV, pM); +} + +/// Loops through an input array transforming each vec4 by the matrix. +kmVec4* kmVec4TransformArray(kmVec4* pOut, unsigned int outStride, + const kmVec4* pV, unsigned int vStride, const kmMat4* pM, unsigned int count) { + unsigned int i = 0; + //Go through all of the vectors + while (i < count) { + const kmVec4* in = pV + (i * vStride); //Get a pointer to the current input + kmVec4* out = pOut + (i * outStride); //and the current output + kmVec4Transform(out, in, pM); //Perform transform on it + ++i; + } + + return pOut; +} + +int kmVec4AreEqual(const kmVec4* p1, const kmVec4* p2) { + return ( + (p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) && + (p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon) && + (p1->z < p2->z + kmEpsilon && p1->z > p2->z - kmEpsilon) && + (p1->w < p2->w + kmEpsilon && p1->w > p2->w - kmEpsilon) + ); +} + +kmVec4* kmVec4Assign(kmVec4* pOut, const kmVec4* pIn) { + assert(pOut != pIn); + + memcpy(pOut, pIn, sizeof(kmScalar) * 4); + + return pOut; +} + diff --git a/external/kazmath/vec4.h b/external/kazmath/vec4.h new file mode 100755 index 0000000..ac7d838 --- /dev/null +++ b/external/kazmath/vec4.h @@ -0,0 +1,70 @@ +/* +Copyright (c) 2008, Luke Benstead. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef VEC4_H_INCLUDED +#define VEC4_H_INCLUDED + +#include "utility.h" + +struct kmMat4; + +#pragma pack(push) /* push current alignment to stack */ +#pragma pack(1) /* set alignment to 1 byte boundary */ + +typedef struct kmVec4 { + kmScalar x; + kmScalar y; + kmScalar z; + kmScalar w; +} kmVec4; + +#pragma pack(pop) + +#ifdef __cplusplus +extern "C" { +#endif + +kmVec4* kmVec4Fill(kmVec4* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w); +kmVec4* kmVec4Add(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2); +kmScalar kmVec4Dot(const kmVec4* pV1, const kmVec4* pV2); +kmScalar kmVec4Length(const kmVec4* pIn); +kmScalar kmVec4LengthSq(const kmVec4* pIn); +kmVec4* kmVec4Lerp(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2, kmScalar t); +kmVec4* kmVec4Normalize(kmVec4* pOut, const kmVec4* pIn); +kmVec4* kmVec4Scale(kmVec4* pOut, const kmVec4* pIn, const kmScalar s); ///< Scales a vector to length s +kmVec4* kmVec4Subtract(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2); + +kmVec4* kmVec4MultiplyMat4(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM); +kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM); +kmVec4* kmVec4TransformArray(kmVec4* pOut, unsigned int outStride, + const kmVec4* pV, unsigned int vStride, const struct kmMat4* pM, unsigned int count); +int kmVec4AreEqual(const kmVec4* p1, const kmVec4* p2); +kmVec4* kmVec4Assign(kmVec4* pOut, const kmVec4* pIn); + +#ifdef __cplusplus +} +#endif + +#endif // VEC4_H_INCLUDED diff --git a/sample/sample_ocean/OceanDelegate.h b/sample/sample_ocean/OceanDelegate.h new file mode 100644 index 0000000..26451b3 --- /dev/null +++ b/sample/sample_ocean/OceanDelegate.h @@ -0,0 +1,13 @@ +// +// OceanDelegate.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef proj_mac_OceanDelegate_h +#define proj_mac_OceanDelegate_h + + +#endif diff --git a/tiny3d_main/RenderQueueGroup.cpp b/tiny3d_main/RenderQueueGroup.cpp new file mode 100644 index 0000000..6bc8b0e --- /dev/null +++ b/tiny3d_main/RenderQueueGroup.cpp @@ -0,0 +1,9 @@ +// +// RenderQueueGroup.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "RenderQueueGroup.h" diff --git a/tiny3d_main/RenderQueueGroup.h b/tiny3d_main/RenderQueueGroup.h new file mode 100644 index 0000000..be3b116 --- /dev/null +++ b/tiny3d_main/RenderQueueGroup.h @@ -0,0 +1,14 @@ +// +// RenderQueueGroup.h +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__RenderQueueGroup__ +#define __proj_mac__RenderQueueGroup__ + +#include + +#endif /* defined(__proj_mac__RenderQueueGroup__) */ diff --git a/tiny3d_main/RenderSystem.cpp b/tiny3d_main/RenderSystem.cpp new file mode 100644 index 0000000..1e180ac --- /dev/null +++ b/tiny3d_main/RenderSystem.cpp @@ -0,0 +1,9 @@ +// +// RenderSystem.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "RenderSystem.h" diff --git a/tiny3d_main/RenderSystem.h b/tiny3d_main/RenderSystem.h new file mode 100644 index 0000000..3caf651 --- /dev/null +++ b/tiny3d_main/RenderSystem.h @@ -0,0 +1,14 @@ +// +// RenderSystem.h +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__RenderSystem__ +#define __proj_mac__RenderSystem__ + +#include + +#endif /* defined(__proj_mac__RenderSystem__) */ diff --git a/tiny3d_main/TinyCamera.cpp b/tiny3d_main/TinyCamera.cpp new file mode 100755 index 0000000..3ba9de9 --- /dev/null +++ b/tiny3d_main/TinyCamera.cpp @@ -0,0 +1,120 @@ +// +// TinyCamera.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#import "TinyCamera.h" + +@implementation TinyCameraController + +- (id)initWithEye:(kmVec3)eye Center:(kmVec3)center Up:(kmVec3)up +{ + self = [super init]; + if (self) { + kmVec3Fill(&_eye, eye.x, eye.y, eye.z); + kmVec3Fill(&_center, center.x, center.y, center.z); + kmVec3Fill(&_up, up.x, up.y, up.z); + _moveSpeed = 3.0; + _rotateSpeed = 0.01; + _fov = 45.0; + _aspect = 4.0/3.0; + _near = 0.1; + _far = 1000.0; + + [[GSInputController sharedInputController] addEventDelegate:self]; + } + + return self; +} + +- (kmMat4)viewMatrix +{ + kmMat4 view; + kmMat4LookAt(&view, &_eye, &_center, &_up); + return view; +} + +- (kmMat4)perspectiveMatrix +{ + kmMat4 projection; + kmMat4PerspectiveProjection(&projection, _fov, _aspect, _near, _far); + return projection; +} +- (void)updateInput:(NSTimeInterval)timeInterval +{ + kmVec3 f, s, u; + + kmVec3Subtract(&f, &_center, &_eye); + kmVec3Normalize(&f, &f); + + kmVec3Normalize(&_up, &_up); + + kmVec3Cross(&s, &f, &_up); + kmVec3Normalize(&s, &s); + + kmVec3Cross(&u, &s, &f); + kmVec3Normalize(&s, &s); + + GSInputController *inputController = [GSInputController sharedInputController]; + float delta = _moveSpeed * timeInterval; + if ([inputController keyIsPressed:NSLeftArrowFunctionKey] + || [inputController keyIsPressed:'a'] + || [inputController keyIsPressed:'A']) { + kmVec3Scale(&s, &s, -delta); + kmVec3Add(&_eye, &_eye, &s); + kmVec3Add(&_center, &_center, &s); + } else if ([inputController keyIsPressed:NSRightArrowFunctionKey] + || [inputController keyIsPressed:'d'] + || [inputController keyIsPressed:'D']) { + kmVec3Scale(&s, &s, delta); + kmVec3Add(&_eye, &_eye, &s); + kmVec3Add(&_center, &_center, &s); + } else if ([inputController keyIsPressed:NSUpArrowFunctionKey] + || [inputController keyIsPressed:'w'] + || [inputController keyIsPressed:'W']) { + kmVec3Scale(&f, &f, delta); + kmVec3Add(&_eye, &_eye, &f); + kmVec3Add(&_center, &_center, &f); + } else if ([inputController keyIsPressed:NSDownArrowFunctionKey] + || [inputController keyIsPressed:'s'] + || [inputController keyIsPressed:'S']) { + kmVec3Scale(&f, &f, -delta); + kmVec3Add(&_eye, &_eye, &f); + kmVec3Add(&_center, &_center, &f); + } +} + +- (void)mouseLeftDragWithX:(CGFloat)x andY:(CGFloat)y +{ + float thetaX = -x * _rotateSpeed; + float thetaY = -y * _rotateSpeed; + + kmVec3 f, s, yawAxis, frontDir; + + kmVec3Subtract(&f, &_center, &_eye); + kmVec3Normalize(&f, &f); + kmVec3Normalize(&_up, &_up); + kmVec3Cross(&s, &f, &_up); + kmVec3Normalize(&s, &s); + + yawAxis.x = 0; + yawAxis.y =1; + yawAxis.z = 0; + + kmVec3Subtract(&frontDir, &_center, &_eye); + + kmQuaternion yaw, pitch; + kmQuaternionRotationAxis(&yaw, &yawAxis, thetaX); + kmQuaternionRotationAxis(&pitch, &s, thetaY); + kmQuaternionMultiplyVec3(&frontDir, &pitch, &frontDir); + kmQuaternionMultiplyVec3(&frontDir, &yaw, &frontDir); + kmQuaternionMultiplyVec3(&_up, &pitch, &_up); + kmQuaternionMultiplyVec3(&_up, &yaw, &_up); + + kmVec3Add(&_center, &_eye, &frontDir); +} + +@end diff --git a/tiny3d_main/TinyCamera.h b/tiny3d_main/TinyCamera.h new file mode 100755 index 0000000..0e60518 --- /dev/null +++ b/tiny3d_main/TinyCamera.h @@ -0,0 +1,32 @@ +// +// TinyCamera.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#import +#import "kazmath/kazmath.h" +#import "GSInputController.h" +#import +#import + +@interface GSCameraController : NSObject + +@property (nonatomic, readonly) kmVec3 eye; +@property (nonatomic, readonly) kmVec3 center; +@property (nonatomic, readonly) kmVec3 up; +@property (nonatomic, readwrite) float moveSpeed; +@property (nonatomic, readwrite) float rotateSpeed; +@property (nonatomic, readwrite) float fov; +@property (nonatomic, readwrite) float aspect; +@property (nonatomic, readwrite) float near; +@property (nonatomic, readwrite) float far; + +- (id)initWithEye:(kmVec3)eye Center:(kmVec3)center Up:(kmVec3)up; + +- (kmMat4)viewMatrix; +- (kmMat4)perspectiveMatrix; + +@end diff --git a/tiny3d_main/TinyDelegate.cpp b/tiny3d_main/TinyDelegate.cpp new file mode 100644 index 0000000..a40f428 --- /dev/null +++ b/tiny3d_main/TinyDelegate.cpp @@ -0,0 +1,41 @@ +// +// TinyDelegate.cpp +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyDelegate.h" +#include "TinyInputManager.h" +#include "TinyRoot.h" + +namespace Tiny +{ + TinyDelegate *TinyDelegate::sSingleTon = NULL; + + TinyDelegate::TinyDelegate() + { + + } + + TinyDelegate::~TinyDelegate() + { + + } + + void TinyDelegate::initialize() + { + + } + + TinyDelegate *TinyDelegate::getSingleton() + { + if (sSingleTon == NULL) + { + sSingleTon = new TinyDelegate(); + sSingleTon->initialize(); + } + return sSingleTon; + } +} \ No newline at end of file diff --git a/tiny3d_main/TinyDelegate.h b/tiny3d_main/TinyDelegate.h new file mode 100644 index 0000000..bb2cdfe --- /dev/null +++ b/tiny3d_main/TinyDelegate.h @@ -0,0 +1,30 @@ +// +// TinyDelegate.h +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyDelegate__ +#define __proj_mac__TinyDelegate__ + +#include "TinyObject.h" + +namespace Tiny +{ + class TinyDelegate : public TinyObject + { + public: + TinyDelegate(); + virtual ~TinyDelegate(); + static TinyDelegate *getSingleton(); + virtual void initialize(); + private: + bool mIsSchedule; + static TinyDelegate *sSingleTon; + }; +} + + +#endif /* defined(__proj_mac__TinyDelegate__) */ diff --git a/tiny3d_main/TinyEntity.cpp b/tiny3d_main/TinyEntity.cpp new file mode 100644 index 0000000..2873d69 --- /dev/null +++ b/tiny3d_main/TinyEntity.cpp @@ -0,0 +1,9 @@ +// +// TinyEntity.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include diff --git a/tiny3d_main/TinyEntity.h b/tiny3d_main/TinyEntity.h new file mode 100644 index 0000000..d4fa7ea --- /dev/null +++ b/tiny3d_main/TinyEntity.h @@ -0,0 +1,13 @@ +// +// TinyEntity.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef proj_mac_TinyEntity_h +#define proj_mac_TinyEntity_h + + +#endif diff --git a/tiny3d_main/TinyGPUProgram.cpp b/tiny3d_main/TinyGPUProgram.cpp new file mode 100644 index 0000000..fa41453 --- /dev/null +++ b/tiny3d_main/TinyGPUProgram.cpp @@ -0,0 +1,9 @@ +// +// TinyGPUProgram.cpp +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyGPUProgram.h" diff --git a/tiny3d_main/TinyGPUProgram.h b/tiny3d_main/TinyGPUProgram.h new file mode 100644 index 0000000..491f0ae --- /dev/null +++ b/tiny3d_main/TinyGPUProgram.h @@ -0,0 +1,28 @@ +// +// TinyGPUProgram.h +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyGPUProgram__ +#define __proj_mac__TinyGPUProgram__ + +#include +#include "TinyObject.h" + +namespace Tiny +{ + class GPUProgramParameters : public TinyObject + { + + }; + + class TinyGPUProgram : public TinyObject + { + + }; +} + +#endif /* defined(__proj_mac__TinyGPUProgram__) */ diff --git a/tiny3d_main/TinyGPUProgramManager.cpp b/tiny3d_main/TinyGPUProgramManager.cpp new file mode 100755 index 0000000..bf75f38 --- /dev/null +++ b/tiny3d_main/TinyGPUProgramManager.cpp @@ -0,0 +1,111 @@ +// +// TinyShaderManager +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#import "GSShaderController.h" +#import +#import + +@implementation GSShaderController + ++ (GSShaderController *)sharedShaderController +{ + static GSShaderController *instance = nil; + + if (instance == nil) { + instance = [[GSShaderController alloc] init]; + } + + return instance; +} + +- (GLuint)programWithVertexShaderFile:(NSString *)vsfilePath FragmentShaderFile:(NSString *)fsFilePath +{ + NSString *vsfileFullPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:vsfilePath]; + NSString *fsFileFullPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fsFilePath]; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + if ([fileManager fileExistsAtPath:vsfileFullPath] == NO) { + NSLog(@"%@ not exist", vsfileFullPath); + return 0; + } + if ([fileManager fileExistsAtPath:fsFileFullPath] == NO) { + NSLog(@"%@ not exist", fsFileFullPath); + return 0; + } + + // read shader code from file + NSString *vsContent = [NSString stringWithContentsOfFile:vsfileFullPath encoding:NSUTF8StringEncoding error:nil]; + NSString *fsContent = [NSString stringWithContentsOfFile:fsFileFullPath encoding:NSUTF8StringEncoding error:nil]; + + return [self programWithVertexShader:vsContent FragmentShader:fsContent]; +} + +- (GLuint)programWithVertexShader:(NSString *)vsContent FragmentShader:(NSString *)fsContent +{ + // Create the shaders + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + + GLint result = GL_FALSE; + int infoLogLength; + char *shaderInfoMessage = NULL; + char *programInfoMessage = NULL; + + // Compile Vertex Shader + const char *vsString = [vsContent UTF8String]; + glShaderSource(vertexShader, 1, &vsString , NULL); + glCompileShader(vertexShader); + + // Check Vertex Shader + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &result); + glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &infoLogLength); + if (infoLogLength > 0) { + shaderInfoMessage = (char *)malloc(infoLogLength + 1); + glGetShaderInfoLog(vertexShader, infoLogLength, NULL, shaderInfoMessage); + NSLog(@"vertex shder info: %s", shaderInfoMessage); + free(shaderInfoMessage); + } + + // Compile Fragment Shader + const char *fsString = [fsContent UTF8String]; + glShaderSource(fragmentShader, 1, &fsString , NULL); + glCompileShader(fragmentShader); + + // Check Fragment Shader + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &result); + glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &infoLogLength); + if (infoLogLength > 0) { + shaderInfoMessage = (char *)malloc(infoLogLength + 1); + glGetShaderInfoLog(fragmentShader, infoLogLength, NULL, shaderInfoMessage); + NSLog(@"fragment shder info: %s", shaderInfoMessage); + free(shaderInfoMessage); + } + + // Link the program + GLuint program = glCreateProgram(); + glAttachShader(program, vertexShader); + glAttachShader(program, fragmentShader); + glLinkProgram(program); + + // Check the program + glGetProgramiv(program, GL_LINK_STATUS, &result); + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength); + if (infoLogLength > 0) { + programInfoMessage = (char *)malloc(infoLogLength + 1); + glGetProgramInfoLog(program, infoLogLength, NULL, programInfoMessage); + NSLog(@"program info: %s", programInfoMessage); + free(programInfoMessage); + } + + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + return program; +} + +@end diff --git a/tiny3d_main/TinyGPUProgramManager.h b/tiny3d_main/TinyGPUProgramManager.h new file mode 100755 index 0000000..d21915d --- /dev/null +++ b/tiny3d_main/TinyGPUProgramManager.h @@ -0,0 +1,20 @@ +// +// TinyShaderManager.h +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#import +#import +#import + +@interface GSShaderController : NSObject + ++ (GSShaderController *)sharedShaderController; + +- (GLuint)programWithVertexShader:(NSString *)vsContent FragmentShader:(NSString *)fsContent; +- (GLuint)programWithVertexShaderFile:(NSString *)vsfilePath FragmentShaderFile:(NSString *)fsFilePath; + +@end diff --git a/tiny3d_main/TinyInputManager.cpp b/tiny3d_main/TinyInputManager.cpp new file mode 100755 index 0000000..77f7e77 --- /dev/null +++ b/tiny3d_main/TinyInputManager.cpp @@ -0,0 +1,95 @@ +// +// TinyInputManager.cpp +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyInputManager.h" +#include "TinyMouse.h" +#include "TinyKeyboard.h" + +namespace Tiny +{ + TinyInputManager *TinyInputManager::sSingleTon = nullptr; + + TinyInputManager::TinyInputManager() + { + } + + TinyInputManager::~TinyInputManager() + { + } + + TinyInputManager *TinyInputManager::getSingleton() + { + if (sSingleTon == nullptr) + { + sSingleTon = new TinyInputManager(); + sSingleTon->initialize(); + } + return sSingleTon; + } + + void TinyInputManager::initialize() + { + } + + std::vector * TinyInputManager::checkInputObjectList(InputDevice inputDevice) + { + auto deviceIter = mInputDevices.find(inputDevice); + std::vector *inputObjList; + if (deviceIter == mInputDevices.end()) + { + inputObjList = new std::vector(); + mInputDevices[inputDevice] = inputObjList; + } + else + { + inputObjList = deviceIter->second; + } + return inputObjList; + } + + void TinyInputManager::createInputObject(InputDevice inputDevice) + { + TinyInputObject* inputObject = nullptr; + switch (inputDevice) { + case InputDevice::Mouse: + { + inputObject = Tiny::TinyMouse::create(); + break; + } + case InputDevice::Keyboard: + { + inputObject = Tiny::TinyKeyboard::create(); + break; + } + default: + { + break; + } + } + if (inputObject != nullptr) + { + auto inputObjList = checkInputObjectList(inputDevice); + inputObjList->push_back(inputObject); + } + } + + TinyInputObject* TinyInputManager::getInputObject(InputDevice inputDevice, int index) + { + auto deviceIter = mInputDevices.find(inputDevice); + TinyInputObject* ret = nullptr; + if (deviceIter != mInputDevices.end()) + { + std::vector *inputObjects = deviceIter->second; + if (inputObjects->size() > index) + { + ret = (*inputObjects)[index]; + } + } + return ret; + } +} \ No newline at end of file diff --git a/tiny3d_main/TinyInputManager.h b/tiny3d_main/TinyInputManager.h new file mode 100755 index 0000000..c27dbd6 --- /dev/null +++ b/tiny3d_main/TinyInputManager.h @@ -0,0 +1,44 @@ +// +// TinyInputManager.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyInputDelegate__ +#define __proj_mac__TinyInputDelegate__ + +#include +#include +#include +#include +#include "TinyObject.h" +#include "TinyInputObject.h" +#include "kazmath/kazmath.h" + +namespace Tiny +{ + enum InputDevice + { + Mouse = 0, + Keyboard + }; + + class TinyInputManager : public TinyObject + { + public: + static TinyInputManager *getSingleton(); + TinyInputManager(); + virtual ~TinyInputManager(); + TinyInputObject* getInputObject(InputDevice inputDevice, int index = 0); + void createInputObject(InputDevice inputDevice); + void initialize(); + private: + std::vector * checkInputObjectList(InputDevice inputDevice); + std::map *> mInputDevices; + static TinyInputManager *sSingleTon; + }; +} + +#endif diff --git a/tiny3d_main/TinyInputObject.cpp b/tiny3d_main/TinyInputObject.cpp new file mode 100644 index 0000000..7b49dcd --- /dev/null +++ b/tiny3d_main/TinyInputObject.cpp @@ -0,0 +1,9 @@ +// +// TinyInputObject.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyInputObject.h" diff --git a/tiny3d_main/TinyInputObject.h b/tiny3d_main/TinyInputObject.h new file mode 100644 index 0000000..e9754b9 --- /dev/null +++ b/tiny3d_main/TinyInputObject.h @@ -0,0 +1,23 @@ +// +// TinyInputObject.h +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyInputObject__ +#define __proj_mac__TinyInputObject__ + +#include +#include "TinyObject.h" + +namespace Tiny +{ + class TinyInputObject : public TinyObject + { + + }; +} + +#endif /* defined(__proj_mac__TinyInputObject__) */ diff --git a/tiny3d_main/TinyKeyboard.cpp b/tiny3d_main/TinyKeyboard.cpp new file mode 100644 index 0000000..8d6b1b2 --- /dev/null +++ b/tiny3d_main/TinyKeyboard.cpp @@ -0,0 +1,64 @@ +// +// TinyKeyboard.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyKeyboard.h" + +namespace Tiny +{ + TinyKeyListener::TinyKeyListener() : mIsMarkForRemove(false) {} + TinyKeyListener::~TinyKeyListener() {} + + void TinyKeyListener::markForRemove(bool isRemove) + { + mIsMarkForRemove = isRemove; + } + + TinyKeyboard::TinyKeyboard() {} + + TinyKeyboard::~TinyKeyboard() {} + + TinyKeyboard *TinyKeyboard::create() + { + auto ret = new TinyKeyboard(); + ret->initialize(); + return ret; + } + + void TinyKeyboard::addEventCallBack(TinyKeyListener* listener) + { + auto listenerIter = mListeners.find(listener); + listener->markForRemove(false); + if (listenerIter == mListeners.end()) + { + mListeners.insert(listener); + } + } + + void TinyKeyboard::removeEventCallBack(TinyKeyListener* listener) + { + listener->markForRemove(true); + } + + void TinyKeyboard::keyPressed(Tiny::TinyKeyEvent *event) + { + std::set::iterator listenerIter; + for (listenerIter = mListeners.begin(); listenerIter != mListeners.end(); listenerIter ++) + { + (*listenerIter)->keyPressed(event); + } + } + + void TinyKeyboard::keyReleased(Tiny::TinyKeyEvent *event) + { + std::set::iterator listenerIter; + for (listenerIter = mListeners.begin(); listenerIter != mListeners.end(); listenerIter ++) + { + (*listenerIter)->keyReleased(event); + } + } +} \ No newline at end of file diff --git a/tiny3d_main/TinyKeyboard.h b/tiny3d_main/TinyKeyboard.h new file mode 100644 index 0000000..3a67742 --- /dev/null +++ b/tiny3d_main/TinyKeyboard.h @@ -0,0 +1,55 @@ +// +// TinyKeyboard.h +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyKeyboard__ +#define __proj_mac__TinyKeyboard__ + +#include +#include "TinyObject.h" +#include "TinyInputObject.h" +#include + +namespace Tiny +{ + + class TinyKeyEvent : public TinyObject + { + public: + unsigned short mKeyCode; + }; + + class TinyKeyListener : public TinyObject + { + public: + TinyKeyListener(); + virtual ~TinyKeyListener(); + virtual void keyPressed(TinyKeyEvent* event) = 0; + virtual void keyReleased(TinyKeyEvent* event) = 0; + void markForRemove(bool isRemove); + private: + bool mIsMarkForRemove; + }; + + class TinyKeyboard : public TinyInputObject + { + public: + TinyKeyboard(); + virtual ~TinyKeyboard(); + static TinyKeyboard *create(); + void initialize(); + void addEventCallBack(TinyKeyListener* listener); + void removeEventCallBack(TinyKeyListener* listener); + void keyPressed(TinyKeyEvent* event); + void keyReleased(TinyKeyEvent* event); + void isKeyDown(unsigned short keyCode); + private: + std::set mListeners; + }; +} + +#endif /* defined(__proj_mac__TinyKeyboard__) */ diff --git a/tiny3d_main/TinyLight.cpp b/tiny3d_main/TinyLight.cpp new file mode 100644 index 0000000..3abf86f --- /dev/null +++ b/tiny3d_main/TinyLight.cpp @@ -0,0 +1,9 @@ +// +// TinyLight.cpp +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyLight.h" diff --git a/tiny3d_main/TinyLight.h b/tiny3d_main/TinyLight.h new file mode 100644 index 0000000..670d80e --- /dev/null +++ b/tiny3d_main/TinyLight.h @@ -0,0 +1,14 @@ +// +// TinyLight.h +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyLight__ +#define __proj_mac__TinyLight__ + +#include + +#endif /* defined(__proj_mac__TinyLight__) */ diff --git a/tiny3d_main/TinyMaterial.cpp b/tiny3d_main/TinyMaterial.cpp new file mode 100644 index 0000000..5ece538 --- /dev/null +++ b/tiny3d_main/TinyMaterial.cpp @@ -0,0 +1,9 @@ +// +// TinyMaterial.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyMaterial.h" diff --git a/tiny3d_main/TinyMaterial.h b/tiny3d_main/TinyMaterial.h new file mode 100644 index 0000000..d8643b5 --- /dev/null +++ b/tiny3d_main/TinyMaterial.h @@ -0,0 +1,14 @@ +// +// TinyMaterial.h +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyMaterial__ +#define __proj_mac__TinyMaterial__ + +#include + +#endif /* defined(__proj_mac__TinyMaterial__) */ diff --git a/tiny3d_main/TinyMath.cpp b/tiny3d_main/TinyMath.cpp new file mode 100644 index 0000000..79f6de7 --- /dev/null +++ b/tiny3d_main/TinyMath.cpp @@ -0,0 +1,29 @@ +// +// TinyMath.cpp +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyMath.h" + +namespace Tiny +{ + kmVec3 kmVec3Make(float x, float y, float z) + { + kmVec3 ret; + ret.x = x; + ret.y = y; + ret.z = z; + return ret; + } + + kmVec2 kmVec2Make(float x, float y) + { + kmVec2 ret; + ret.x = x; + ret.y = y; + return ret; + } +} \ No newline at end of file diff --git a/tiny3d_main/TinyMath.h b/tiny3d_main/TinyMath.h new file mode 100644 index 0000000..d196e2d --- /dev/null +++ b/tiny3d_main/TinyMath.h @@ -0,0 +1,22 @@ +// +// TinyMath.h +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyMath__ +#define __proj_mac__TinyMath__ + +#include + +#include "kazmath/kazmath.h" + +namespace Tiny +{ + kmVec3 kmVec3Make(float x, float y, float z); + kmVec2 kmVec2Make(float x, float y); +} + +#endif /* defined(__proj_mac__TinyMath__) */ diff --git a/tiny3d_main/TinyMesh.cpp b/tiny3d_main/TinyMesh.cpp new file mode 100644 index 0000000..ad851ad --- /dev/null +++ b/tiny3d_main/TinyMesh.cpp @@ -0,0 +1,9 @@ +// +// TinyMesh.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyMesh.h" diff --git a/tiny3d_main/TinyMesh.h b/tiny3d_main/TinyMesh.h new file mode 100644 index 0000000..ab524d2 --- /dev/null +++ b/tiny3d_main/TinyMesh.h @@ -0,0 +1,13 @@ +// +// TinyMesh.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef proj_mac_TinyMesh_h +#define proj_mac_TinyMesh_h + + +#endif diff --git a/tiny3d_main/TinyMouse.cpp b/tiny3d_main/TinyMouse.cpp new file mode 100644 index 0000000..28fa8c8 --- /dev/null +++ b/tiny3d_main/TinyMouse.cpp @@ -0,0 +1,86 @@ +// +// TinyMouse.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyMouse.h" + +namespace Tiny +{ + TinyMouseListener::TinyMouseListener() : mIsMarkForRemove(false) + { + } + + TinyMouseListener::~TinyMouseListener() {} + + void TinyMouseListener::markForRemove(bool isRemove) + { + mIsMarkForRemove = isRemove; + } + + TinyMouse::TinyMouse() + { + mLocation.x = 0; + mLocation.y = 0; + } + + TinyMouse::~TinyMouse() {} + + TinyMouse *TinyMouse::create() + { + auto ret = new TinyMouse(); + ret->initialize(); + return ret; + } + + void TinyMouse::setLocation(kmVec2 *location) + { + mLocation.x = location->x; + mLocation.y = location->y; + } + + void TinyMouse::addEventCallBack(TinyMouseListener* listener) + { + auto listenerIter = mListeners.find(listener); + listener->markForRemove(false); + if (listenerIter == mListeners.end()) + { + mListeners.insert(listener); + } + } + + void TinyMouse::removeEventCallBack(TinyMouseListener* listener) + { + listener->markForRemove(true); + } + + void TinyMouse::mouseMoved(TinyMouseEvent* event) + { + std::set::iterator listenerIter; + for (listenerIter = mListeners.begin(); listenerIter != mListeners.end(); listenerIter ++) + { + (*listenerIter)->mouseMoved(event); + } + } + + void TinyMouse::mousePressed(TinyMouseEvent* event, TinyMouseButtonID id) + { + std::set::iterator listenerIter; + for (listenerIter = mListeners.begin(); listenerIter != mListeners.end(); listenerIter ++) + { + (*listenerIter)->mousePressed(event, id); + } + } + + void TinyMouse::mouseReleased(TinyMouseEvent* event, TinyMouseButtonID id) + { + std::set::iterator listenerIter; + for (listenerIter = mListeners.begin(); listenerIter != mListeners.end(); listenerIter ++) + { + (*listenerIter)->mouseReleased(event, id); + } + } +} \ No newline at end of file diff --git a/tiny3d_main/TinyMouse.h b/tiny3d_main/TinyMouse.h new file mode 100644 index 0000000..a3ca1c3 --- /dev/null +++ b/tiny3d_main/TinyMouse.h @@ -0,0 +1,73 @@ +// +// TinyMouse.h +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyMouse__ +#define __proj_mac__TinyMouse__ + +#include +#include "TinyObject.h" +#include "TinyInputObject.h" +#include +#include "kazmath/kazmath.h" + +namespace Tiny +{ + enum TinyMouseButtonID + { + MB_Left = 0, + MB_Right, + MB_Middle + }; + + class TinyMouseState : public TinyObject + { + public: + //position diff + int deltaX; + int deltaY; + }; + + class TinyMouseEvent : public TinyObject + { + public: + TinyMouseState state; + }; + + class TinyMouseListener : public TinyObject + { + public: + TinyMouseListener(); + virtual ~TinyMouseListener(); + virtual void mouseMoved(TinyMouseEvent* event) = 0; + virtual void mousePressed(TinyMouseEvent* event, TinyMouseButtonID id) = 0; + virtual void mouseReleased(TinyMouseEvent* event, TinyMouseButtonID id) = 0; + void markForRemove(bool isRemove); + private: + bool mIsMarkForRemove; + }; + + class TinyMouse : public TinyInputObject + { + public: + TinyMouse(); + virtual ~TinyMouse(); + static TinyMouse *create(); + void initialize(); + void addEventCallBack(TinyMouseListener* listener); + void removeEventCallBack(TinyMouseListener* listener); + void mouseMoved(TinyMouseEvent* event); + void mousePressed(TinyMouseEvent* event, TinyMouseButtonID id); + void mouseReleased(TinyMouseEvent* event, TinyMouseButtonID id); + void setLocation(kmVec2 *location); + private: + std::set mListeners; + kmVec2 mLocation; + }; +} + +#endif /* defined(__proj_mac__TinyMouse__) */ diff --git a/tiny3d_main/TinyMovableObject.cpp b/tiny3d_main/TinyMovableObject.cpp new file mode 100644 index 0000000..a82aacd --- /dev/null +++ b/tiny3d_main/TinyMovableObject.cpp @@ -0,0 +1,9 @@ +// +// TinyMovableObject.cpp +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyMovableObject.h" diff --git a/tiny3d_main/TinyMovableObject.h b/tiny3d_main/TinyMovableObject.h new file mode 100644 index 0000000..101b2b3 --- /dev/null +++ b/tiny3d_main/TinyMovableObject.h @@ -0,0 +1,22 @@ +// +// TinyMovableObject.h +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyMovableObject__ +#define __proj_mac__TinyMovableObject__ + +#include +#include "TinyObject.h" + +namespace Tiny { + class TinyMovableObject : public TinyObject + { + + }; +} + +#endif /* defined(__proj_mac__TinyMovableObject__) */ diff --git a/tiny3d_main/TinyObject.cpp b/tiny3d_main/TinyObject.cpp new file mode 100644 index 0000000..adef6ec --- /dev/null +++ b/tiny3d_main/TinyObject.cpp @@ -0,0 +1,9 @@ +// +// TinyObject.cpp +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyObject.h" diff --git a/tiny3d_main/TinyObject.h b/tiny3d_main/TinyObject.h new file mode 100644 index 0000000..9192b80 --- /dev/null +++ b/tiny3d_main/TinyObject.h @@ -0,0 +1,21 @@ +// +// TinyObject.h +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyObject__ +#define __proj_mac__TinyObject__ + +#include + +namespace Tiny { + class TinyObject + { + + }; +} + +#endif /* defined(__proj_mac__TinyObject__) */ diff --git a/tiny3d_main/TinyRenderQueue.cpp b/tiny3d_main/TinyRenderQueue.cpp new file mode 100644 index 0000000..32d1fad --- /dev/null +++ b/tiny3d_main/TinyRenderQueue.cpp @@ -0,0 +1,9 @@ +// +// TinyRenderQueue.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyRenderQueue.h" diff --git a/tiny3d_main/TinyRenderQueue.h b/tiny3d_main/TinyRenderQueue.h new file mode 100644 index 0000000..a3fe7cd --- /dev/null +++ b/tiny3d_main/TinyRenderQueue.h @@ -0,0 +1,13 @@ +// +// TinyRenderQueue.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef proj_mac_TinyRenderQueue_h +#define proj_mac_TinyRenderQueue_h + + +#endif diff --git a/tiny3d_main/TinyRenderQueueSortingQrouping.cpp b/tiny3d_main/TinyRenderQueueSortingQrouping.cpp new file mode 100644 index 0000000..d310780 --- /dev/null +++ b/tiny3d_main/TinyRenderQueueSortingQrouping.cpp @@ -0,0 +1,9 @@ +// +// TinyRenderQueueSortingQrouping.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyRenderQueueSortingQrouping.h" diff --git a/tiny3d_main/TinyRenderQueueSortingQrouping.h b/tiny3d_main/TinyRenderQueueSortingQrouping.h new file mode 100644 index 0000000..047bb42 --- /dev/null +++ b/tiny3d_main/TinyRenderQueueSortingQrouping.h @@ -0,0 +1,14 @@ +// +// TinyRenderQueueSortingQrouping.h +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyRenderQueueSortingQrouping__ +#define __proj_mac__TinyRenderQueueSortingQrouping__ + +#include + +#endif /* defined(__proj_mac__TinyRenderQueueSortingQrouping__) */ diff --git a/tiny3d_main/TinyRenderSystem.cpp b/tiny3d_main/TinyRenderSystem.cpp new file mode 100644 index 0000000..011bcc1 --- /dev/null +++ b/tiny3d_main/TinyRenderSystem.cpp @@ -0,0 +1,26 @@ +// +// TinyRenderSystem.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyRenderSystem.h" + +namespace Tiny +{ + TinyRenderSystem *TinyRenderSystem::sSingleton = nullptr; + + TinyRenderSystem *TinyRenderSystem::getSingleton() + { + if (nullptr == sSingleton) + { + sSingleton = new TinyRenderSystem(); + sSingleton->initialize(); + } + return sSingleton; + } + + +} diff --git a/tiny3d_main/TinyRenderSystem.h b/tiny3d_main/TinyRenderSystem.h new file mode 100644 index 0000000..0acb965 --- /dev/null +++ b/tiny3d_main/TinyRenderSystem.h @@ -0,0 +1,41 @@ +// +// TinyRenderSystem.h +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyRenderSystem__ +#define __proj_mac__TinyRenderSystem__ + +#include + +#include "TinyObject.h" +#include +#include +#include "TinyRenderTarget.h" +#include "TinyGPUProgram.h" + +namespace Tiny +{ + class TinyRenderSystem : public TinyObject + { + public: + TinyRenderSystem(); + virtual ~TinyRenderSystem(); + static TinyRenderSystem *getSingleton(); + void initialize(); + void updateAllRenderTargets(); + void swapAllRenderTargetBuffers(); + void render(); + void bindGPUProgram(TinyGPUProgram *program); + void bindGPUProgramParameters(GPUProgramParameters *params); + void setRenderTarget(TinyRenderTarget *target); + private: + std::map mRenderTargets; + static TinyRenderSystem *sSingleton; + }; +} + +#endif /* defined(__proj_mac__TinyRenderSystem__) */ diff --git a/tiny3d_main/TinyRenderTarget.cpp b/tiny3d_main/TinyRenderTarget.cpp new file mode 100644 index 0000000..b1b019b --- /dev/null +++ b/tiny3d_main/TinyRenderTarget.cpp @@ -0,0 +1,9 @@ +// +// TinyRenderTarget.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyRenderTarget.h" diff --git a/tiny3d_main/TinyRenderTarget.h b/tiny3d_main/TinyRenderTarget.h new file mode 100644 index 0000000..8c8a28b --- /dev/null +++ b/tiny3d_main/TinyRenderTarget.h @@ -0,0 +1,23 @@ +// +// TinyRenderTarget.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef proj_mac_TinyRenderTarget_h +#define proj_mac_TinyRenderTarget_h + +#include "TinyObject.h" + +namespace Tiny +{ + class TinyRenderTarget : public TinyObject + { + public: + + }; +} + +#endif diff --git a/tiny3d_main/TinyRenderTexture.cpp b/tiny3d_main/TinyRenderTexture.cpp new file mode 100644 index 0000000..3f4eda0 --- /dev/null +++ b/tiny3d_main/TinyRenderTexture.cpp @@ -0,0 +1,9 @@ +// +// TinyRenderTexture.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyRenderTexture.h" diff --git a/tiny3d_main/TinyRenderTexture.h b/tiny3d_main/TinyRenderTexture.h new file mode 100644 index 0000000..ac7c4d8 --- /dev/null +++ b/tiny3d_main/TinyRenderTexture.h @@ -0,0 +1,14 @@ +// +// TinyRenderTexture.h +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyRenderTexture__ +#define __proj_mac__TinyRenderTexture__ + +#include + +#endif /* defined(__proj_mac__TinyRenderTexture__) */ diff --git a/tiny3d_main/TinyRenderWindow.cpp b/tiny3d_main/TinyRenderWindow.cpp new file mode 100644 index 0000000..8a3d8f8 --- /dev/null +++ b/tiny3d_main/TinyRenderWindow.cpp @@ -0,0 +1,9 @@ +// +// TinyRenderWindow.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyRenderWindow.h" diff --git a/tiny3d_main/TinyRenderWindow.h b/tiny3d_main/TinyRenderWindow.h new file mode 100644 index 0000000..2f2f6a8 --- /dev/null +++ b/tiny3d_main/TinyRenderWindow.h @@ -0,0 +1,14 @@ +// +// TinyRenderWindow.h +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyRenderWindow__ +#define __proj_mac__TinyRenderWindow__ + +#include + +#endif /* defined(__proj_mac__TinyRenderWindow__) */ diff --git a/tiny3d_main/TinyRenderable.cpp b/tiny3d_main/TinyRenderable.cpp new file mode 100644 index 0000000..6aaa3cc --- /dev/null +++ b/tiny3d_main/TinyRenderable.cpp @@ -0,0 +1,9 @@ +// +// TinyRenderable.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyRenderable.h" diff --git a/tiny3d_main/TinyRenderable.h b/tiny3d_main/TinyRenderable.h new file mode 100644 index 0000000..6ee54db --- /dev/null +++ b/tiny3d_main/TinyRenderable.h @@ -0,0 +1,13 @@ +// +// TinyRenderable.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef proj_mac_TinyRenderable_h +#define proj_mac_TinyRenderable_h + + +#endif diff --git a/tiny3d_main/TinyResourceManager.cpp b/tiny3d_main/TinyResourceManager.cpp new file mode 100644 index 0000000..52c81b2 --- /dev/null +++ b/tiny3d_main/TinyResourceManager.cpp @@ -0,0 +1,9 @@ +// +// TinyResourceManager.cpp +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyResourceManager.h" diff --git a/tiny3d_main/TinyResourceManager.h b/tiny3d_main/TinyResourceManager.h new file mode 100644 index 0000000..9d4d987 --- /dev/null +++ b/tiny3d_main/TinyResourceManager.h @@ -0,0 +1,14 @@ +// +// TinyResourceManager.h +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef __proj_mac__TinyResourceManager__ +#define __proj_mac__TinyResourceManager__ + +#include + +#endif /* defined(__proj_mac__TinyResourceManager__) */ diff --git a/tiny3d_main/TinyRoot.cpp b/tiny3d_main/TinyRoot.cpp new file mode 100644 index 0000000..51d71ef --- /dev/null +++ b/tiny3d_main/TinyRoot.cpp @@ -0,0 +1,60 @@ +// +// TinyRoot.cpp +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include +#include "TinySchedulerManager.h" +#include "TinyRoot.h" +#include "TinyRenderSystem.h" + +namespace Tiny +{ + TinyRoot *TinyRoot::sSingleton = nullptr; + + TinyRoot *TinyRoot::getSingleton() + { + if (nullptr == sSingleton) + { + sSingleton = new TinyRoot(); + } + return sSingleton; + } + + TinyRoot::TinyRoot() + { + } + + TinyRoot::~TinyRoot() + { + } + + void TinyRoot::renderOneFrame(float timeInterval) + { + //add Time to scheduler. + Tiny::TinyScheduleManager::getSingleton()->timeStep(timeInterval); + + //update all render targets, include render window, render texture, etc. + updateAllRenderTargets(); + + } + + void TinyRoot::updateAllRenderTargets() + { + //render all render target. + Tiny::TinyRenderSystem::getSingleton()->updateAllRenderTargets(); + Tiny::TinyRenderSystem::getSingleton()->swapAllRenderTargetBuffers(); + } + + void TinyRoot::onWindowUpdate(float width, float height) + { + //set all render target dirty. + } +} + + + + diff --git a/tiny3d_main/TinyRoot.h b/tiny3d_main/TinyRoot.h new file mode 100644 index 0000000..640c213 --- /dev/null +++ b/tiny3d_main/TinyRoot.h @@ -0,0 +1,28 @@ +// +// TinyRoot.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef proj_mac_TinyRoot_h +#define proj_mac_TinyRoot_h + +namespace Tiny { + class TinyRoot + { + public: + static TinyRoot *getSingleton(); + TinyRoot(); + ~TinyRoot(); + void renderOneFrame(float timeInterval); + void updateAllRenderTargets(); + void onWindowUpdate(float width, float height); + private: + static TinyRoot *sSingleton; + + }; +} + +#endif diff --git a/tiny3d_main/TinySceneManager.cpp b/tiny3d_main/TinySceneManager.cpp new file mode 100644 index 0000000..9ff8e7b --- /dev/null +++ b/tiny3d_main/TinySceneManager.cpp @@ -0,0 +1,9 @@ +// +// TinySceneManager.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinySceneManager.h" diff --git a/tiny3d_main/TinySceneManager.h b/tiny3d_main/TinySceneManager.h new file mode 100644 index 0000000..55bf5b1 --- /dev/null +++ b/tiny3d_main/TinySceneManager.h @@ -0,0 +1,13 @@ +// +// TinySceneManager.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef proj_mac_TinySceneManager_h +#define proj_mac_TinySceneManager_h + + +#endif diff --git a/tiny3d_main/TinySceneNode.cpp b/tiny3d_main/TinySceneNode.cpp new file mode 100644 index 0000000..989e3d5 --- /dev/null +++ b/tiny3d_main/TinySceneNode.cpp @@ -0,0 +1,9 @@ +// +// TinySceneNode.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinySceneNode.h" diff --git a/tiny3d_main/TinySceneNode.h b/tiny3d_main/TinySceneNode.h new file mode 100644 index 0000000..993cabd --- /dev/null +++ b/tiny3d_main/TinySceneNode.h @@ -0,0 +1,13 @@ +// +// TinySceneNode.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef proj_mac_TinySceneNode_h +#define proj_mac_TinySceneNode_h + + +#endif diff --git a/tiny3d_main/TinySchedulerManager.cpp b/tiny3d_main/TinySchedulerManager.cpp new file mode 100644 index 0000000..3a0ca7a --- /dev/null +++ b/tiny3d_main/TinySchedulerManager.cpp @@ -0,0 +1,44 @@ +// +// TinySchedulerManager.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinySchedulerManager.h" + +namespace Tiny +{ + TinyScheduleManager *TinyScheduleManager::sSingleton = nullptr; + + TinyScheduleManager::TinyScheduleManager() + { + + } + + TinyScheduleManager::~TinyScheduleManager() + { + + } + + TinyScheduleManager *TinyScheduleManager::getSingleton() + { + if (sSingleton == nullptr) + { + sSingleton = new TinyScheduleManager(); + sSingleton->initialize(); + } + return sSingleton; + } + + void TinyScheduleManager::initialize() + { + + } + + void TinyScheduleManager::timeStep(float timeInterval) + { + + } +} \ No newline at end of file diff --git a/tiny3d_main/TinySchedulerManager.h b/tiny3d_main/TinySchedulerManager.h new file mode 100644 index 0000000..f6aa148 --- /dev/null +++ b/tiny3d_main/TinySchedulerManager.h @@ -0,0 +1,30 @@ +// +// TinySchedulerManager.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef proj_mac_TinySchedulerManager_h +#define proj_mac_TinySchedulerManager_h + +#include "TinyObject.h" + +namespace Tiny +{ + class TinyScheduleManager : public TinyObject + { + public: + TinyScheduleManager(); + virtual ~TinyScheduleManager(); + static TinyScheduleManager *getSingleton(); + void initialize(); + void timeStep(float timeInterval); + private: + static TinyScheduleManager *sSingleton; + + }; +} + +#endif diff --git a/tiny3d_main/TinyTexture.cpp b/tiny3d_main/TinyTexture.cpp new file mode 100644 index 0000000..fb42204 --- /dev/null +++ b/tiny3d_main/TinyTexture.cpp @@ -0,0 +1,9 @@ +// +// TinyTexture.cpp +// proj_mac +// +// Created by reuben chao on 2/4/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include "TinyTexture.h" diff --git a/tiny3d_main/TinyTexture.h b/tiny3d_main/TinyTexture.h new file mode 100644 index 0000000..167ad9d --- /dev/null +++ b/tiny3d_main/TinyTexture.h @@ -0,0 +1,13 @@ +// +// TinyTexture.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef proj_mac_TinyTexture_h +#define proj_mac_TinyTexture_h + + +#endif diff --git a/tiny3d_main/TinyTextureManager.cpp b/tiny3d_main/TinyTextureManager.cpp new file mode 100755 index 0000000..cf452c9 --- /dev/null +++ b/tiny3d_main/TinyTextureManager.cpp @@ -0,0 +1,220 @@ +// +// TinyTextureController.cpp +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#import "GSTextureController.h" +#import "GSOpenGLInfoHelper.h" +#import +#import + +unsigned long getNextPOT(unsigned long x) +{ + x = x - 1; + x = x | (x >> 1); + x = x | (x >> 2); + x = x | (x >> 4); + x = x | (x >> 8); + x = x | (x >>16); + return x + 1; +} + +@implementation GSTextureController + ++ (GSTextureController *)sharedTextureController +{ + static GSTextureController *instance = nil; + + if (instance == nil) { + instance = [[GSTextureController alloc] init]; + } + + return instance; +} + +- (id)init +{ + self = [super init]; + if (self) { + GSOpenGLInfoHelper *openGLInfoHelp = [GSOpenGLInfoHelper sharedOpenGLInfoHelper]; + + if (openGLInfoHelp.openglVersion < 2.0) { + _supportsNPOT = NO; + } else { + _supportsNPOT = YES; + } + } + + return self; +} + +- (GLuint)cubeTextureWithFileNameArr:(NSMutableArray*)fileNameArr useMipmap:(BOOL)isMapmap +{ + //glPixelStorei(GL_UNPACK_ALIGNMENT,4); + GLuint texObj; + + glActiveTexture(GL_TEXTURE0); + glEnable(GL_TEXTURE_CUBE_MAP); + glGenTextures(1, &texObj); + glBindTexture(GL_TEXTURE_CUBE_MAP, texObj); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + if (isMapmap == NO) { + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } else { + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + } + + for (int cubeIdx = 0; cubeIdx < 6; cubeIdx ++) + { + NSMutableArray* dataArr = [NSMutableArray arrayWithCapacity:16]; + NSMutableArray* sizeArr = [NSMutableArray arrayWithCapacity:16]; + NSString* fileName = (NSString *)fileNameArr[cubeIdx]; + [self getFileData:fileName useMipmap:isMapmap dataArr:dataArr sizeArr:sizeArr]; + int mipMapCount = (int)dataArr.count; + for (int i = 0; i < mipMapCount; i ++) + { + CGSize size; + void* data; + [sizeArr[i] getValue:&size]; + [dataArr[i] getValue:&data]; + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeIdx, i, GL_RGBA, (GLsizei)size.width, (GLsizei)size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + free(data); + } + } + glDisable(GL_TEXTURE_CUBE_MAP); + + return texObj; +} + +- (GLuint)textureWithFileName:(NSString *)fileName useMipmap:(BOOL)isMapmap +{ + //glPixelStorei(GL_UNPACK_ALIGNMENT,4); + GLuint texObj; + glGenTextures(1, &texObj); + + glActiveTexture(GL_TEXTURE0); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texObj); + + NSMutableArray* dataArr = [NSMutableArray arrayWithCapacity:16]; + NSMutableArray* sizeArr = [NSMutableArray arrayWithCapacity:16]; + [self getFileData:fileName useMipmap:isMapmap dataArr:dataArr sizeArr:sizeArr]; + int mipMapCount = (int)dataArr.count; + for (int i = 0; i < mipMapCount; i ++) + { + CGSize size; + void* data; + [sizeArr[i] getValue:&size]; + [dataArr[i] getValue:&data]; + glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, (GLsizei)size.width, (GLsizei)size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + free(data); + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (isMapmap == NO) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); + } + + glDisable(GL_TEXTURE_2D); + + return texObj; +} + +- (void)getFileData:(NSString *)fileName useMipmap:(BOOL)isMapmap dataArr:(NSMutableArray*)dataArr sizeArr:(NSMutableArray*)sizeArr +{ + NSString *fullPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName]; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + if ([fileManager fileExistsAtPath:fullPath] == NO) { + NSLog(@"%@ not exist", fullPath); + return; + } + + NSData *fileData = [[NSData alloc] initWithContentsOfFile:fullPath]; + NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithData:fileData]; + CGImageRef cgImage = [image CGImage]; + + CGImageAlphaInfo info = CGImageGetAlphaInfo(cgImage); + //support NPOT + NSUInteger textureWidth, textureHeight; + if( self.supportsNPOT == NO ) + { + textureWidth = getNextPOT(CGImageGetWidth(cgImage)); + textureHeight = getNextPOT(CGImageGetHeight(cgImage)); + } + else + { + textureWidth = CGImageGetWidth(cgImage); + textureHeight = CGImageGetHeight(cgImage); + } + CGSize imageSize = CGSizeMake(CGImageGetWidth(cgImage), CGImageGetHeight(cgImage)); + CGColorSpaceRef colorSpace = CGImageGetColorSpace(cgImage); + BOOL hasAlpha = ((info == kCGImageAlphaPremultipliedLast) || (info == kCGImageAlphaPremultipliedFirst) || (info == kCGImageAlphaLast) || (info == kCGImageAlphaFirst) ? YES : NO); + + if(colorSpace) { + if( hasAlpha ) { + info = kCGImageAlphaPremultipliedLast; + } else { + info = kCGImageAlphaNoneSkipLast; + } + } else { + return; + } + + GLint level = 0; + NSUInteger width = textureWidth; + NSUInteger height = textureHeight; + NSUInteger widthImage = imageSize.width; + NSUInteger heightImage = imageSize.height; + do { + if (level > 0) { + width /= 2; + height /= 2; + + widthImage /= 2; + if (widthImage == 0) { + widthImage = 1; + } + + heightImage /= 2; + if (heightImage == 0) { + heightImage = 1; + } + } + + void *data = malloc(height * width * 4); + colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = CGBitmapContextCreate(data, width, height, 8, 4 * width, colorSpace, info | kCGBitmapByteOrder32Big); + CGColorSpaceRelease(colorSpace); + + CGContextClearRect(context, CGRectMake(0, 0, width, height)); + CGContextTranslateCTM(context, 0, height - heightImage); + CGContextDrawImage(context, CGRectMake(0, 0, widthImage, heightImage), cgImage); + + [dataArr addObject:[NSValue valueWithPointer:data]]; + [sizeArr addObject:[NSValue valueWithSize:CGSizeMake(width, height)]]; + + CGContextRelease(context); + + if (width == 1 && height == 1) { + break; + } + level++; + + } while (isMapmap); +} + +@end diff --git a/tiny3d_main/TinyTextureManager.h b/tiny3d_main/TinyTextureManager.h new file mode 100755 index 0000000..225fbe4 --- /dev/null +++ b/tiny3d_main/TinyTextureManager.h @@ -0,0 +1,25 @@ +// +// TinyTextureController.h +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#import +#import +#import + +@interface GSTextureController : NSObject + +@property (nonatomic, readonly) BOOL supportsNPOT; + ++ (GSTextureController *)sharedTextureController; + +- (GLuint)textureWithFileName:(NSString *)fileName useMipmap:(BOOL)isMapmap; + +- (GLuint)cubeTextureWithFileNameArr:(NSMutableArray *)fileNameArr useMipmap:(BOOL)isMapmap; + +- (void)getFileData:(NSString *)fileName useMipmap:(BOOL)isMapmap dataArr:(NSMutableArray*)dataArr sizeArr:(NSMutableArray*)sizeArr; + +@end diff --git a/tiny3d_main/TinyViewPort.cpp b/tiny3d_main/TinyViewPort.cpp new file mode 100644 index 0000000..1b56239 --- /dev/null +++ b/tiny3d_main/TinyViewPort.cpp @@ -0,0 +1,11 @@ +// +// TinyViewPort.cpp +// proj_mac +// +// Created by reuben chao on 2/3/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#include + +//glViewport(0, 0, (GLint) rect.size.width, (GLint) rect.size.height); \ No newline at end of file diff --git a/tiny3d_main/TinyViewPort.h b/tiny3d_main/TinyViewPort.h new file mode 100644 index 0000000..f9e70ee --- /dev/null +++ b/tiny3d_main/TinyViewPort.h @@ -0,0 +1,13 @@ +// +// TinyViewPort.h +// proj_mac +// +// Created by reuben chao on 2/2/15. +// Copyright (c) 2015 reuben chao. All rights reserved. +// + +#ifndef proj_mac_TinyViewPort_h +#define proj_mac_TinyViewPort_h + + +#endif