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 0000000..2d741ec Binary files /dev/null and b/build/proj_mac/proj_mac.xcodeproj/project.xcworkspace/xcuserdata/reuben.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..7012aa5 --- /dev/null +++ b/build/proj_mac/proj_mac.xcodeproj/xcuserdata/reuben.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + 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