From d6b59469718eb27d1d79cd5e9549cc2a2d4abd6a Mon Sep 17 00:00:00 2001 From: chsieh Date: Fri, 17 Dec 2010 14:55:04 -0800 Subject: [PATCH] Initial commit. More or less the default XCode project (deleted a strange setContext function call from the default code, though) plus ported code. Still need to make sure it compiles and whatnot on OSX, and also add the proper proprocessor defines. --- .gitignore | 2 + Classes/EAGLView.h | 37 + Classes/EAGLView.m | 163 +++ Classes/Foundation/Common/Assert.h | 17 + Classes/Foundation/Common/Base.h | 11 + Classes/Foundation/Common/GlobalDefines.h | 120 ++ Classes/Foundation/Common/GlobalInclude.h | 5 + Classes/Foundation/Common/GlobalTypes.h | 40 + Classes/Foundation/Common/Print.h | 5 + Classes/Foundation/Common/Singleton.h | 50 + Classes/Foundation/Containers/BitEncoder.h | 10 + .../Foundation/Containers/LocklessRingBuffer.cpp | 161 +++ Classes/Foundation/Containers/LocklessRingBuffer.h | 23 + Classes/Foundation/Hash/DJB2.h | 25 + Classes/Foundation/Math/MathDefines.h | 14 + Classes/Foundation/Math/MathInclude.h | 8 + Classes/Foundation/Math/MathOperations.h | 75 + Classes/Foundation/Math/MathTypes.h | 363 +++++ Classes/Foundation/Math/Matrix.h | 660 +++++++++ Classes/Foundation/Math/Quaternion.h | 100 ++ Classes/Foundation/Math/Vector.h | 1176 ++++++++++++++++ Classes/Foundation/Memory/MemoryBitset.cpp | 318 +++++ Classes/Foundation/Memory/MemoryBitset.h | 49 + Classes/Foundation/Memory/MemoryHeap.cpp | 32 + Classes/Foundation/Memory/MemoryHeap.h | 37 + Classes/Foundation/Memory/MemoryLinear.h | 110 ++ Classes/Foundation/Synchronization/Atomic32Bit.h | 99 ++ Classes/Foundation/Synchronization/MemorySync.h | 21 + Classes/GraphicsServices/OpenGLServices.h | 23 + Classes/LittlestAppDelegate.h | 22 + Classes/LittlestAppDelegate.m | 56 + Classes/LittlestViewController.h | 34 + Classes/LittlestViewController.m | 412 ++++++ Littlest-Info.plist | 32 + Littlest.xcodeproj/dorischen.mode1v3 | 1420 ++++++++++++++++++++ Littlest.xcodeproj/dorischen.pbxuser | 375 ++++++ Littlest.xcodeproj/project.pbxproj | 431 ++++++ LittlestViewController.xib | 389 ++++++ Littlest_Prefix.pch | 14 + MainWindow.xib | 485 +++++++ Shaders/Shader.fsh | 14 + Shaders/Shader.vsh | 22 + Shaders/Standard/Standard.fsh | 7 + Shaders/Standard/Standard.vsh | 18 + main.m | 17 + 45 files changed, 7502 insertions(+), 0 deletions(-) create mode 100644 .gitignore create mode 100644 Classes/EAGLView.h create mode 100644 Classes/EAGLView.m create mode 100755 Classes/Foundation/Common/Assert.h create mode 100755 Classes/Foundation/Common/Base.h create mode 100755 Classes/Foundation/Common/GlobalDefines.h create mode 100755 Classes/Foundation/Common/GlobalInclude.h create mode 100755 Classes/Foundation/Common/GlobalTypes.h create mode 100755 Classes/Foundation/Common/Print.h create mode 100755 Classes/Foundation/Common/Singleton.h create mode 100755 Classes/Foundation/Containers/BitEncoder.h create mode 100755 Classes/Foundation/Containers/LocklessRingBuffer.cpp create mode 100755 Classes/Foundation/Containers/LocklessRingBuffer.h create mode 100755 Classes/Foundation/Hash/DJB2.h create mode 100755 Classes/Foundation/Math/MathDefines.h create mode 100755 Classes/Foundation/Math/MathInclude.h create mode 100755 Classes/Foundation/Math/MathOperations.h create mode 100755 Classes/Foundation/Math/MathTypes.h create mode 100755 Classes/Foundation/Math/Matrix.h create mode 100755 Classes/Foundation/Math/Quaternion.h create mode 100755 Classes/Foundation/Math/Vector.h create mode 100755 Classes/Foundation/Memory/MemoryBitset.cpp create mode 100755 Classes/Foundation/Memory/MemoryBitset.h create mode 100755 Classes/Foundation/Memory/MemoryHeap.cpp create mode 100755 Classes/Foundation/Memory/MemoryHeap.h create mode 100755 Classes/Foundation/Memory/MemoryLinear.h create mode 100755 Classes/Foundation/Synchronization/Atomic32Bit.h create mode 100755 Classes/Foundation/Synchronization/MemorySync.h create mode 100644 Classes/GraphicsServices/OpenGLServices.h create mode 100644 Classes/LittlestAppDelegate.h create mode 100644 Classes/LittlestAppDelegate.m create mode 100644 Classes/LittlestViewController.h create mode 100644 Classes/LittlestViewController.m create mode 100644 Littlest-Info.plist create mode 100644 Littlest.xcodeproj/dorischen.mode1v3 create mode 100644 Littlest.xcodeproj/dorischen.pbxuser create mode 100755 Littlest.xcodeproj/project.pbxproj create mode 100644 LittlestViewController.xib create mode 100644 Littlest_Prefix.pch create mode 100644 MainWindow.xib create mode 100644 Shaders/Shader.fsh create mode 100644 Shaders/Shader.vsh create mode 100644 Shaders/Standard/Standard.fsh create mode 100644 Shaders/Standard/Standard.vsh create mode 100644 main.m diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5430402 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# ignore built files +build/* diff --git a/Classes/EAGLView.h b/Classes/EAGLView.h new file mode 100644 index 0000000..277392d --- /dev/null +++ b/Classes/EAGLView.h @@ -0,0 +1,37 @@ +// +// EAGLView.h +// Littlest +// +// Created by Doris Chen on 12/4/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import + +#import +#import +#import +#import + +// This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. +// The view content is basically an EAGL surface you render your OpenGL scene into. +// Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel. +@interface EAGLView : UIView +{ +@private + EAGLContext *context; + + // The pixel dimensions of the CAEAGLLayer. + GLint framebufferWidth; + GLint framebufferHeight; + + // The OpenGL ES names for the framebuffer and renderbuffer used to render to this view. + GLuint defaultFramebuffer, colorRenderbuffer; +} + +@property (nonatomic, retain) EAGLContext *context; + +- (void)setFramebuffer; +- (BOOL)presentFramebuffer; + +@end diff --git a/Classes/EAGLView.m b/Classes/EAGLView.m new file mode 100644 index 0000000..4fb0237 --- /dev/null +++ b/Classes/EAGLView.m @@ -0,0 +1,163 @@ +// +// EAGLView.m +// Littlest +// +// Created by Doris Chen on 12/4/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import + +#import "EAGLView.h" + +//----------------------------------------------------------------------------------------------------------- +@interface EAGLView (PrivateMethods) +- (void)createFrameBuffer; +- (void)deleteFramebuffer; +@end + +//----------------------------------------------------------------------------------------------------------- +@implementation EAGLView + +@dynamic context; + +//----------------------------------------------------------------------------------------------------------- +// You must implement this method ++ (Class)layerClass +{ + return [CAEAGLLayer class]; +} + +//----------------------------------------------------------------------------------------------------------- +//The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:. +- (id)initWithCoder:(NSCoder*)coder +{ + self = [super initWithCoder:coder]; + if (self) + { + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + + eaglLayer.opaque = TRUE; + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, + kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, + nil]; + } + + return self; +} + +//----------------------------------------------------------------------------------------------------------- +- (void)dealloc +{ + [self deleteFramebuffer]; + [context release]; + + [super dealloc]; +} + +//----------------------------------------------------------------------------------------------------------- +- (EAGLContext *)context +{ + return context; +} + +//----------------------------------------------------------------------------------------------------------- +- (void)setContext:(EAGLContext *)newContext +{ + if (context != newContext) + { + [self deleteFramebuffer]; + [context release]; + + context = [newContext retain]; + } +} + +//----------------------------------------------------------------------------------------------------------- +- (void)createFrameBuffer +{ + if (context && !defaultFramebuffer) + { + [EAGLContext setCurrentContext:context]; + + // Create default framebuffer object. + glGenFramebuffers(1, &defaultFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); + + // Create color render buffer and allocate backing store. + glGenRenderbuffers(1, &colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); + [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + } +} + +//----------------------------------------------------------------------------------------------------------- +- (void)deleteFramebuffer +{ + if (context) + { + [EAGLContext setCurrentContext:context]; + + if (defaultFramebuffer) + { + glDeleteFramebuffers(1, &defaultFramebuffer); + defaultFramebuffer = 0; + } + + if (colorRenderbuffer) + { + glDeleteRenderbuffers(1, &colorRenderbuffer); + colorRenderbuffer = 0; + } + } +} + +//----------------------------------------------------------------------------------------------------------- +- (void)setFramebuffer +{ + if (context) + { + [EAGLContext setCurrentContext:context]; + + if (!defaultFramebuffer) + [self createFrameBuffer]; + + glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); + + glViewport(0, 0, framebufferWidth, framebufferHeight); + } +} + +//----------------------------------------------------------------------------------------------------------- +- (BOOL)presentFramebuffer +{ + BOOL success = FALSE; + + if (context) + { + [EAGLContext setCurrentContext:context]; + + glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); + + success = [context presentRenderbuffer:GL_RENDERBUFFER]; + } + + return success; +} + +//----------------------------------------------------------------------------------------------------------- +- (void)layoutSubviews +{ + // The framebuffer will be re-created at the beginning of the next setFramebuffer method call. + [self deleteFramebuffer]; +} + +@end diff --git a/Classes/Foundation/Common/Assert.h b/Classes/Foundation/Common/Assert.h new file mode 100755 index 0000000..123e36a --- /dev/null +++ b/Classes/Foundation/Common/Assert.h @@ -0,0 +1,17 @@ +#pragma once + +#ifdef DEBUG + +#include + +#define Assert(expression) if (!(expression)) __debugbreak(); + +#define AssertMessage(expression, message, ...) \ + if (!(expression)) Printf(message, ##__VA_ARGS__) + +#else + +slInline void Assert(bool expression) {} +slInline void AssertMsg(bool expression, char* msg, ...) {} + +#endif \ No newline at end of file diff --git a/Classes/Foundation/Common/Base.h b/Classes/Foundation/Common/Base.h new file mode 100755 index 0000000..4cf66ae --- /dev/null +++ b/Classes/Foundation/Common/Base.h @@ -0,0 +1,11 @@ +#pragma once + +namespace Foundation +{ + class CBase + { + public: + CBase() {} + ~CBase() {} + }; +} diff --git a/Classes/Foundation/Common/GlobalDefines.h b/Classes/Foundation/Common/GlobalDefines.h new file mode 100755 index 0000000..58323d7 --- /dev/null +++ b/Classes/Foundation/Common/GlobalDefines.h @@ -0,0 +1,120 @@ +#pragma once + +#include "Foundation/Common/GlobalTypes.h" + +#ifdef _WINDOWS +#define __WINDOWS__ +#endif + +#ifdef _DEBUG +#define DEBUG +#endif + +#ifdef _NDEBUG +#define RELEASE +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +//---------------------------------------------------------------------------------------- +// cache information +#ifndef CACHE_LINE_SIZE +#define CACHE_LINE_SIZE 128 //equal to 2 line for intel normally +#endif + +//---------------------------------------------------------------------------------------- +//force inline on non-debug, might make code explode +#ifdef _DEBUG + #define slInline inline +#else + #define slInline __forceinline +#endif + +//compiler determined inline +#define clInline inline + +#define slRestrict __restrict + +//---------------------------------------------------------------------------------------- +// alignment macros +#if defined(__WINDOWS__) +#define ALIGN(N) __declspec(align(N)) +#endif + +#define IS_POWER_OF_TWO(x) ( ((x) & -(x)) == (x) ) + +#pragma warning(disable:4146) // =( +#define ALIGN_UP(x, ALIGNMENT) ( ((x) + (ALIGNMENT) - 1) & -(ALIGNMENT) ) +#define ALIGN_DOWN(x, ALIGNMENT) ( (x) & -(ALIGNMENT) ) + +#define POWER_OF_TWO_MOD(x, N) ( (x) & ((N) - 1) ) + +#define ALIGN_CACHE ( ALIGN( CACHE_LINE_SIZE ) ) + +//---------------------------------------------------------------------------------------- +// cache macros +#if defined(__WINDOWS__) +// uhh, nothing? +#elif defined(__ARM__) +#define DCBT(x) __asm__("pld" #(x)) +#else +#error Not implemented yet! +#endif + +//---------------------------------------------------------------------------------------- +// string and memory functions +#if defined(__WINDOWS__) + #include + + #pragma intrinsic(memcpy) + #pragma intrinsic(memset) + #pragma intrinsic(strcmp) + #pragma intrinsic(strcpy) + #pragma intrinsic(strlen) + #pragma intrinsic(strcat) +#endif + +//---------------------------------------------------------------------------------------- +// color constants +#define NULL_COLOR 0x00000000 +#define BLACK_COLOR 0x000000ff +#define RED_COLOR 0xff0000ff +#define GREEN_COLOR 0x00ff00ff +#define BLUE_COLOR 0x0000ffff +#define WHITE_COLOR 0xffffffff + +//---------------------------------------------------------------------------------------- +#if defined(__WINDOWS__) +slInline uint8_t LZCount(uint64_t x) +{ + uint8_t leading_zero_count = 0; + uint8_t next_shift = 32; + uint64_t copy = x; + while (next_shift != 0) + { + bool non_zero = copy >= (0x1ULL << next_shift); + uint8_t actual_shift = (uint8_t)non_zero * next_shift; + leading_zero_count += actual_shift; + copy >>= actual_shift; + next_shift >>= 1; + } + leading_zero_count += (copy == 0x1ULL); + + return leading_zero_count; +} +#else +#error // use lzcnt! +#endif + +//---------------------------------------------------------------------------------------- +#define RightMostEnabledBit(x) ((x) & -(x)) \ No newline at end of file diff --git a/Classes/Foundation/Common/GlobalInclude.h b/Classes/Foundation/Common/GlobalInclude.h new file mode 100755 index 0000000..5ffd39f --- /dev/null +++ b/Classes/Foundation/Common/GlobalInclude.h @@ -0,0 +1,5 @@ +#pragma once + +#include "GlobalDefines.h" +#include "GlobalTypes.h" +#include "Assert.h" diff --git a/Classes/Foundation/Common/GlobalTypes.h b/Classes/Foundation/Common/GlobalTypes.h new file mode 100755 index 0000000..5e1d3d5 --- /dev/null +++ b/Classes/Foundation/Common/GlobalTypes.h @@ -0,0 +1,40 @@ +#pragma once + +#ifdef uint32_t +#undef uint32_t +#endif + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned int uint32_t; +typedef long long int64_t; +typedef unsigned long long uint64_t; +typedef uint32_t color32_t; + +union IntFloat +{ + int8_t m_Int8[4]; + uint8_t m_UInt8[4]; + int16_t m_Int16[2]; + uint16_t m_UInt16[2]; + int32_t m_Int32; + uint32_t m_UInt32; + float m_Float; +}; + +union LongDouble +{ + int8_t m_Int8[8]; + uint8_t m_UInt8[8]; + int16_t m_Int16[4]; + uint16_t m_UInt16[4]; + int32_t m_Int32[2]; + uint32_t m_UInt32[2]; + int64_t m_Int64; + uint64_t m_UInt64; + float m_Float[2]; + double m_Double; +}; diff --git a/Classes/Foundation/Common/Print.h b/Classes/Foundation/Common/Print.h new file mode 100755 index 0000000..c86bdb9 --- /dev/null +++ b/Classes/Foundation/Common/Print.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +#define Printf(message, ...) printf(message, ##__VA_ARGS__) diff --git a/Classes/Foundation/Common/Singleton.h b/Classes/Foundation/Common/Singleton.h new file mode 100755 index 0000000..cdbead7 --- /dev/null +++ b/Classes/Foundation/Common/Singleton.h @@ -0,0 +1,50 @@ +#pragma once + +#include "Foundation/Common/GlobalInclude.h" + +/* +Statically allocates for faster access +*/ + +namespace Foundation +{ + +template +class Singleton +{ +private: + static T* m_Instance; + +protected: + Singleton(){m_Instance = 0;} + +public: + static T* Create() + { + Assert( m_Instance == 0); + if(m_Instance) + { + return m_Instance; + } + m_Instance = new(16) T(); + return m_Instance; + } + + slInline static T* GetInstance() + { + //Assert( m_Instance == 0); + return m_Instance; + } + + static void DestroyInstance() + { + if(m_Instance) + { + delete m_Instance; + } + } +}; + +template T* Singleton::m_Instance = 0; + +} diff --git a/Classes/Foundation/Containers/BitEncoder.h b/Classes/Foundation/Containers/BitEncoder.h new file mode 100755 index 0000000..102e7fc --- /dev/null +++ b/Classes/Foundation/Containers/BitEncoder.h @@ -0,0 +1,10 @@ +#pragma once + +#include "Foundation/Common/GlobalInclude.h" + +#define SET_BITS(x, new_val, shift, mask) ((x) = (((x) & ~(mask)) | (((new_val) << (shift)) & (mask)))) +#define ZERO_BITS(x, mask) ((x) &= ~(mask)) +#define OR_BITS (x, new_val, shift, mask) ((x) |= (((new_val) << (shift)) & (mask))) +#define AND_BITS(x, new_val, shift, mask) ((x) &= (((new_val) << (shift)) & (mask))) +#define GET_BITS(x, mask) ((x) & (mask)) +#define GET_BITS_RIGHT(x, shift, mask) (((x) & (mask)) >> (shift)) diff --git a/Classes/Foundation/Containers/LocklessRingBuffer.cpp b/Classes/Foundation/Containers/LocklessRingBuffer.cpp new file mode 100755 index 0000000..48d7ed7 --- /dev/null +++ b/Classes/Foundation/Containers/LocklessRingBuffer.cpp @@ -0,0 +1,161 @@ +#pragma once + +#include "LocklessRingBuffer.h" +#include "Foundation/Synchronization/MemorySync.h" + +//---------------------------------------------------------------------------------------- +void LocklessRingBuffer::Init(void* buffer, uint32_t buffer_size) +{ + m_Base = (uint8_t*)buffer; + m_BufferSize = buffer_size; + m_WriteOffset = 0; + m_ReadOffset = 0; +} + +//---------------------------------------------------------------------------------------- +void LocklessRingBuffer::Destroy() +{ + m_Base = NULL; + m_BufferSize = 0; + m_WriteOffset = 0; + m_ReadOffset = 0; +} + +//---------------------------------------------------------------------------------------- +bool LocklessRingBuffer::Write(void* entry, uint32_t entry_size) +{ + Assert(entry_size < m_BufferSize); + + uint32_t new_write_offset = m_WriteOffset; + uint32_t remaining_space = m_WriteOffset < m_ReadOffset ? m_ReadOffset - m_WriteOffset - 1 : m_ReadOffset + m_BufferSize - m_WriteOffset; + if (remaining_space < entry_size) + { + return false; + } + + bool write_will_end_lower = new_write_offset + entry_size >= m_BufferSize; + + uint32_t distance_to_top = (entry_size > m_BufferSize - new_write_offset) ? (m_BufferSize - new_write_offset) : entry_size; + memcpy(m_Base + new_write_offset, entry, distance_to_top); + new_write_offset += distance_to_top; + + if (write_will_end_lower) + { + uint32_t remainder = entry_size - distance_to_top; + memcpy(m_Base, (uint8_t*)entry + distance_to_top, remainder); + new_write_offset = remainder; + } + + ReadWriteSync(); + + m_WriteOffset = new_write_offset; + return true; +} + +//---------------------------------------------------------------------------------------- +bool LocklessRingBuffer::Write(void* entries[], uint32_t entry_sizes[], uint32_t entry_count) +{ + uint32_t total_size = 0; + for (uint32_t i = 0; i < entry_count; i++) + { + total_size += entry_sizes[i]; + } + + Assert(total_size < m_BufferSize); + + uint32_t new_write_offset = m_WriteOffset; + uint32_t remaining_space = m_WriteOffset < m_ReadOffset ? m_ReadOffset - m_WriteOffset - 1 : m_ReadOffset + m_BufferSize - m_WriteOffset; + if (remaining_space < total_size) + { + return false; + } + + for (uint32_t i = 0; i < entry_count; i++) + { + bool write_will_end_lower = new_write_offset + entry_sizes[i] >= m_BufferSize; + uint32_t distance_to_top = (entry_sizes[i] > m_BufferSize - new_write_offset) ? (m_BufferSize - new_write_offset) : entry_sizes[i]; + memcpy(m_Base + new_write_offset, entries[i], distance_to_top); + new_write_offset += distance_to_top; + + if (write_will_end_lower) + { + uint32_t remainder = entry_sizes[i] - distance_to_top; + memcpy(m_Base, (uint8_t*)entries[i] + distance_to_top, remainder); + new_write_offset = remainder; + } + } + + ReadWriteSync(); + + m_WriteOffset = new_write_offset; + return true; +} + +//---------------------------------------------------------------------------------------- +bool LocklessRingBuffer::Peek(void* read_buffer, uint32_t read_size) +{ + uint32_t read_remaining = m_WriteOffset < m_ReadOffset ? m_BufferSize - m_ReadOffset + m_WriteOffset : m_WriteOffset - m_ReadOffset; + if (read_remaining < read_size) + { + return false; + } + + uint32_t read_to_top = m_BufferSize - m_ReadOffset <= read_size ? m_BufferSize - m_ReadOffset : read_size; + memcpy(read_buffer, m_Base + m_ReadOffset, read_to_top); + if (m_BufferSize - m_ReadOffset <= read_size) + { + memcpy((uint8_t*)read_buffer + read_to_top, m_Base, read_remaining - read_to_top); + } + + return true; +} + +//---------------------------------------------------------------------------------------- +bool LocklessRingBuffer::Read(void* read_buffer, uint32_t read_size) +{ + uint32_t read_remaining = m_WriteOffset < m_ReadOffset ? m_BufferSize - m_ReadOffset + m_WriteOffset : m_WriteOffset - m_ReadOffset; + if (read_remaining < read_size) + { + return false; + } + + uint32_t read_to_top = m_BufferSize - m_ReadOffset <= read_size ? m_BufferSize - m_ReadOffset : read_size; + memcpy(read_buffer, m_Base + m_ReadOffset, read_to_top); + uint32_t new_read_offset = m_ReadOffset + read_to_top; + + if (m_BufferSize - m_ReadOffset <= read_size) + { + memcpy((uint8_t*)read_buffer + read_to_top, m_Base, read_remaining - read_to_top); + new_read_offset = read_remaining - read_to_top; + } + + ReadWriteSync(); + + m_ReadOffset = new_read_offset; + + return true; +} + +//---------------------------------------------------------------------------------------- +bool LocklessRingBuffer::ReadDiscard(uint32_t read_size) +{ + uint32_t read_remaining = m_WriteOffset < m_ReadOffset ? m_BufferSize - m_ReadOffset + m_WriteOffset : m_WriteOffset - m_ReadOffset; + if (read_remaining < read_size) + { + return false; + } + + uint32_t read_to_top = m_BufferSize - m_ReadOffset <= read_size ? m_BufferSize - m_ReadOffset : read_size; + uint32_t new_read_offset = m_ReadOffset + read_to_top; + + if (m_BufferSize - m_ReadOffset <= read_size) + { + new_read_offset = read_remaining - read_to_top; + } + + ReadWriteSync(); + + m_ReadOffset = new_read_offset; + + return true; +} diff --git a/Classes/Foundation/Containers/LocklessRingBuffer.h b/Classes/Foundation/Containers/LocklessRingBuffer.h new file mode 100755 index 0000000..e098a36 --- /dev/null +++ b/Classes/Foundation/Containers/LocklessRingBuffer.h @@ -0,0 +1,23 @@ +#pragma once + +#include "Foundation/Common/GlobalInclude.h" + +class LocklessRingBuffer +{ +private: + uint8_t* m_Base; + uint32_t m_BufferSize; + uint32_t m_WriteOffset; + uint32_t m_ReadOffset; + +public: + void Init(void* buffer, uint32_t buffer_size); + void Destroy(); + + bool Write(void* entry, uint32_t entry_size); + bool Write(void* entries[], uint32_t entry_sizes[], uint32_t entry_count); + + bool Peek(void* read_buffer, uint32_t read_size); + bool Read(void* read_buffer, uint32_t read_size); + bool ReadDiscard(uint32_t read_size); +}; diff --git a/Classes/Foundation/Hash/DJB2.h b/Classes/Foundation/Hash/DJB2.h new file mode 100755 index 0000000..30fa608 --- /dev/null +++ b/Classes/Foundation/Hash/DJB2.h @@ -0,0 +1,25 @@ +#pragma once + +#include "Foundation/Common/GlobalInclude.h" + +//========================== +// djb2 string hash function +//-------------------------- +static slInline uint32 StrHash(const char *str) +{ + uint32 hash = 5381; + int32 c = *str; + + if(!str) + { + Assert(false); + return 0; + } + + while ( (*str != 0) ){ + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + c = (*str++); + } + + return hash; +} \ No newline at end of file diff --git a/Classes/Foundation/Math/MathDefines.h b/Classes/Foundation/Math/MathDefines.h new file mode 100755 index 0000000..1aedb6b --- /dev/null +++ b/Classes/Foundation/Math/MathDefines.h @@ -0,0 +1,14 @@ +#pragma once + +#define kEpsilon 1e-6 +#define kSqrtEpsilon 1e-3 + +#define kPi 3.1415926535897932384626433832795 +#define kPi_2 1.5707963267948966192313216916398 +#define kPi_3 1.0471975511965977461542144610932 +#define kPi_4 0.78539816339744830961566084581988 +#define k2Pi_3 2.0943951023931954923084289221863 +#define k3Pi_4 2.3561944901923449288469825374596 +#define k2Pi 6.283185307179586476925286766559 + +#define kE 2.7182818284590452353602874713527 \ No newline at end of file diff --git a/Classes/Foundation/Math/MathInclude.h b/Classes/Foundation/Math/MathInclude.h new file mode 100755 index 0000000..718190a --- /dev/null +++ b/Classes/Foundation/Math/MathInclude.h @@ -0,0 +1,8 @@ +#pragma once + +#include "Foundation/Math/MathDefines.h" +#include "Foundation/Math/MathOperations.h" +#include "Foundation/Math/MathTypes.h" +#include "Foundation/Math/Vector.h" +#include "Foundation/Math/Quaternion.h" +#include "Foundation/Math/Matrix.h" diff --git a/Classes/Foundation/Math/MathOperations.h b/Classes/Foundation/Math/MathOperations.h new file mode 100755 index 0000000..af49e6f --- /dev/null +++ b/Classes/Foundation/Math/MathOperations.h @@ -0,0 +1,75 @@ +#pragma once + +#include +#include "Foundation/Common/GlobalInclude.h" + +#if defined(__WINDOWS__) + +#pragma intrinsic(sin) +#pragma intrinsic(cos) +#pragma intrinsic(tan) +#pragma intrinsic(abs) +#pragma intrinsic(fabs) +#pragma intrinsic(asin) +#pragma intrinsic(acos) +#pragma intrinsic(atan) +#pragma intrinsic(atan2) +#pragma intrinsic(exp) +#pragma intrinsic(sqrt) +#pragma intrinsic(log) +#pragma intrinsic(log10) + +#endif + +#define Sinf(x) sin(x) +#define Cosf(x) cos(x) +#define Tanf(x) tan(x) +#define Sqrtf(x) sqrt(x) + +//---------------------------------------------------------------------------------------- +#define Min2(x, y) ( (x) <= (y) ? (x) : (y) ) +#define Max2(x, y) ( (x) >= (y) ? (x) : (y) ) +#define Min3(x, y, z) ( (x) <= (y) ? ((x) <= (z) ? (x) : (z)) : ((y) <= (z) ? (y) : (z)) ) +#define Max3(x, y, z) ( (x) >= (y) ? ((x) >= (z) ? (x) : (z)) : ((y) >= (z) ? (y) : (z)) ) + +//---------------------------------------------------------------------------------------- +slInline float Absf(const float& f) +{ + IntFloat int_float; + int_float.m_Float = f; + int_float.m_Int32 &= 0x7fffffff; + return int_float.m_Float; +} + +//---------------------------------------------------------------------------------------- +slInline bool EpsilonEquals(const float& a, const float& b, const float& epsilon) +{ + return Absf(a - b) <= epsilon; +} + +//---------------------------------------------------------------------------------------- +slInline uint16_t ConvertFloatToHalf( unsigned int f ) +{ + unsigned int s = f & 0x80000000; + signed int e = ((f & 0x7f800000) >> 23) - (127 - 15); + if (e < 0) return 0; + else if (e > 31) + { + e = 31; + } + unsigned int fo = f & 0x7fffff; + return (uint16_t)((s >> 16) | ((e << 10) & 0x7c00) | (fo >> 13)); +} + +//---------------------------------------------------------------------------------------- +slInline float ConvertHalfToFloat( unsigned short h ) +{ + unsigned int s = h & 0x8000; + unsigned int e = ((h & 0x7c00) >> 10) - 15 + 127; + unsigned int f = h & 0x3ff; + + IntFloat int_float; + int_float.m_UInt32 = ((s << 16) | ((e << 23) & 0x7f800000) | (f << 13)); + + return int_float.m_Float; +} diff --git a/Classes/Foundation/Math/MathTypes.h b/Classes/Foundation/Math/MathTypes.h new file mode 100755 index 0000000..c16a44e --- /dev/null +++ b/Classes/Foundation/Math/MathTypes.h @@ -0,0 +1,363 @@ +#pragma once + +#include "Foundation/Common/GlobalInclude.h" +#include "Foundation/Math/MathOperations.h" + +//---------------------------------------------------------------------------------------- +struct Vector2 +{ + float x; + float y; + + slInline explicit Vector2() {} + slInline explicit Vector2(const float xy) {x = xy; y = xy;} + slInline explicit Vector2(const float ix, const float iy) {x = ix; y = iy;} + + slInline Vector2(const Vector2& v) {x = v.x; y = v.y;} // copy constructor + + slInline float* AsFloatArray() {return &x;} + slInline const float* AsFloatArray() const {return &x;} + + slInline float GetComponent(int index) const {return AsFloatArray()[index];} +}; + + +//---------------------------------------------------------------------------------------- +struct Vector3 +{ + float x; + float y; + float z; + + slInline explicit Vector3() {} + slInline explicit Vector3(const float xyz) {x = xyz; y = xyz; z = xyz;} + slInline explicit Vector3(const float ix, const float iy, const float iz) {x = ix; y = iy; z = iz;} + + slInline explicit Vector3(const Vector2& v, const float iz) {x = v.x; y = v.y; z = iz;} + + slInline Vector3(const Vector3& v) {x = v.x; y = v.y; z = v.z;} // copy constructor + + slInline Vector2 AsVector2() const {return Vector2(x, y);} + + slInline float* AsFloatArray() {return &x;} + slInline const float* AsFloatArray() const {return &x;} + + slInline float GetComponent(int index) const {return AsFloatArray()[index];} +}; + + +//---------------------------------------------------------------------------------------- +struct Vector4 +{ + float x; + float y; + float z; + float w; + + slInline explicit Vector4() {} + slInline explicit Vector4(const float xyzw) {x = xyzw; y = xyzw; z = xyzw; w = xyzw;} + slInline explicit Vector4(const float xyz, const float iw) {x = xyz; y = xyz; z = xyz; w = iw;} + slInline explicit Vector4(const float ix, const float iy, const float iz, const float iw) {x = ix; y = iy; z = iz; w = iw;} + + slInline explicit Vector4(const Vector2& u, const Vector2& v) {x = u.x; y = u.y; z = v.x; w = v.y;} + slInline explicit Vector4(const Vector2& v, const float iz, const float iw) {x = v.x; y = v.y; z = iz; w = iw;} + + slInline explicit Vector4(const Vector3& v, const float iw) {x = v.x; y = v.y; z = v.z; w = iw;} + + slInline Vector4(const Vector4& v) {x = v.x; y = v.y; z = v.z; w = v.w;} // copy constructor + + slInline Vector2 AsVector2() const {return Vector2(x, y);} + slInline Vector3 AsVector3() const {return Vector3(x, y, z);} + + slInline float* AsFloatArray() {return &x;} + slInline const float* AsFloatArray() const {return &x;} + + slInline float GetComponent(int index) const {return AsFloatArray()[index];} +}; + + +//---------------------------------------------------------------------------------------- +struct Quaternion +{ + float i; + float j; + float k; + float s; + + slInline explicit Quaternion() {} + explicit Quaternion(const float angle, const Vector3& normalized_axis); + explicit Quaternion(const float angle, const float x, const float y, const float z); + + slInline Quaternion(const Quaternion& q) {i = q.i; j = q.j; k = q.k; s = q.s;} + + Vector4 AsVector4(); + slInline float* AsFloatArray() {return &i;} + + Vector3 GetImaginary(); + slInline float GetReal() {return s;} +}; + +slInline Quaternion::Quaternion(const float angle, const Vector3& normalized_axis) +{ + Assert( EpsilonEquals(LengthVector3(normalized_axis), 1.0f, kEpsilon) ); + float half_angle = angle * 0.5f; + float sin_half_angle = Sinf(half_angle); + i = normalized_axis.x * sin_half_angle; + j = normalized_axis.y * sin_half_angle; + k = normalized_axis.z * sin_half_angle; + s = Cosf(half_angle); +} + +slInline Quaternion::Quaternion(const float angle, const float x, const float y, const float z) +{ + Assert( EpsilonEquals(x * x + y * y + z * z, 1.0f, kSqrtEpsilon) ); + float half_angle = angle * 0.5f; + float sin_half_angle = Sinf(half_angle); + i = x * sin_half_angle; + j = y * sin_half_angle; + k = z * sin_half_angle; + s = Cosf(half_angle); +} + +Vector4 Quaternion::AsVector4() +{ + Vector4 r; + r.x = i; + r.y = j; + r.z = k; + r.w = s; + return r; +} + +Vector3 Quaternion::GetImaginary() +{ + Vector3 r; + r.x = i; + r.y = j; + r.z = k; + return r; +} + + +//---------------------------------------------------------------------------------------- +struct Matrix3 +{ + Vector3 v[3]; + + slInline explicit Matrix3() {} + explicit Matrix3(const Vector3& v0, const Vector3& v1, const Vector3& v2); + explicit Matrix3(const float v00, const float v01, const float v02, + const float v10, const float v11, const float v12, + const float v20, const float v21, const float v22); + Matrix3(Matrix3& m); // copy constructor + + float* AsFloatArray() {return &v[0].x;} +}; + +slInline Matrix3::Matrix3(const Vector3& v0, const Vector3& v1, const Vector3& v2) +{ + v[0] = v0; + v[1] = v1; + v[2] = v2; +} + +slInline Matrix3::Matrix3(const float v00, const float v01, const float v02, const float v10, const float v11, const float v12, const float v20, const float v21, const float v22) +{ + v[0].x = v00; v[0].y = v01; v[0].z = v02; + v[1].x = v10; v[1].y = v11; v[1].z = v12; + v[2].x = v20; v[2].y = v21; v[2].z = v22; +} + +slInline Matrix3::Matrix3(Matrix3& m) +{ + v[0] = m.v[0]; + v[1] = m.v[1]; + v[2] = m.v[2]; +} + + +//---------------------------------------------------------------------------------------- +struct Matrix4 +{ + Vector4 v[4]; + + slInline explicit Matrix4() {} + explicit Matrix4(const Vector4& v0, const Vector4& v1, const Vector4& v2, const Vector4& v3); + explicit Matrix4(const float v00, const float v01, const float v02, const float v03, + const float v10, const float v11, const float v12, const float v13, + const float v20, const float v21, const float v22, const float v23, + const float v30, const float v31, const float v32, const float v33); + explicit Matrix4(const Matrix3& m); + Matrix4(const Matrix4& m); // copy constructor + + float* AsFloatArray() {return &v[0].x;} +}; + +slInline Matrix4::Matrix4(const Vector4& v0, const Vector4& v1, const Vector4& v2, const Vector4& v3) +{ + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; +} + +slInline Matrix4::Matrix4(const float v00, const float v01, const float v02, const float v03, const float v10, const float v11, const float v12, const float v13, const float v20, const float v21, const float v22, const float v23, const float v30, const float v31, const float v32, const float v33) +{ + v[0].x = v00; v[0].y = v01; v[0].z = v02; v[0].w = v03; + v[1].x = v10; v[1].y = v11; v[1].z = v12; v[1].w = v13; + v[2].x = v20; v[2].y = v21; v[2].z = v22; v[2].w = v23; + v[3].x = v30; v[3].y = v31; v[3].z = v32; v[3].w = v33; +} + +slInline Matrix4::Matrix4(const Matrix3& m) +{ + v[0].x = m.v[0].x; v[0].y = m.v[0].y; v[0].z = m.v[0].z; v[0].w = 0.0f; + v[1].x = m.v[1].x; v[1].y = m.v[1].y; v[1].z = m.v[1].z; v[1].w = 0.0f; + v[2].x = m.v[2].x; v[2].y = m.v[2].y; v[2].z = m.v[2].z; v[2].w = 0.0f; + v[3].x = 0.0f; v[3].y = 0.0f; v[3].z = 0.0f; v[3].w = 1.0f; +} + +slInline Matrix4::Matrix4(const Matrix4& m) +{ + v[0] = m.v[0]; + v[1] = m.v[1]; + v[2] = m.v[2]; + v[3] = m.v[3]; +} + + +//---------------------------------------------------------------------------------------- +typedef ALIGN(8) Vector2 AlignedVector2; +typedef ALIGN(16) Vector3 AlignedVector3; +typedef ALIGN(16) Vector4 AlignedVector4; + +typedef ALIGN(64) Matrix3 AlignedMatrix3; +typedef ALIGN(64) Matrix4 AlignedMatrix4; + + +//---------------------------------------------------------------------------------------- +// SIMD Structures +//---------------------------------------------------------------------------------------- +struct Vector2SOA +{ + uint32_t m_Count; + uint32_t m_MaxCount; + + float* m_X; + float* m_Y; + + slInline explicit Vector2SOA() {m_Count = 0; m_MaxCount = 0; m_X = NULL; m_Y = NULL;} + bool InitVector2SOA(float* buffer, uint32_t buffer_size); + + void GetVector2AtIndex(Vector2& v, uint32_t index) {Assert(index < m_Count); v.x = m_X[index]; v.y = m_Y[index];} +}; + +slInline bool Vector2SOA::InitVector2SOA(float* buffer, uint32_t max_count) +{ + m_Count = 0; + + uint64_t buffer_addr = (uint64_t)buffer; + uint64_t buffer_addr_aligned = ALIGN_UP(buffer_addr, 16); + uint64_t buffer_end = (uint64_t)(buffer + max_count); + + if (buffer_end - buffer_addr_aligned < 20) + { + m_MaxCount = 0; + m_X = NULL; + m_Y = NULL; + + return false; + } + + uint32_t remainder = (uint32_t)POWER_OF_TWO_MOD(buffer_end, 16) / 4; + uint32_t slot_count = (uint32_t)(buffer_end - buffer_addr_aligned) / 32; + + m_MaxCount = slot_count * 4 + (uint32_t)(remainder * (slot_count & 0x1)); + + m_X = (float*)buffer_addr_aligned; + m_Y = m_X + ALIGN_UP(m_MaxCount, 4); +} + + +//---------------------------------------------------------------------------------------- +struct Vector3SOA : public Vector2SOA +{ + float* m_Z; + + slInline explicit Vector3SOA() {m_Count = 0; m_MaxCount = 0; m_X = NULL; m_Y = NULL; m_Z = NULL;} + bool InitVector3SOA(float* buffer, uint32_t buffer_size); + + void GetVector3AtIndex(Vector3& v, uint32_t index) {Assert(index < m_Count); v.x = m_X[index]; v.y = m_Y[index]; v.z = m_Z[index];} +}; + +slInline bool Vector3SOA::InitVector3SOA(float* buffer, uint32_t max_count) +{ + m_Count = 0; + + uint64_t buffer_addr = (uint64_t)buffer; + uint64_t buffer_addr_aligned = ALIGN_UP(buffer_addr, 16); + uint64_t buffer_end = (uint64_t)(buffer + max_count); + + if (buffer_end - buffer_addr_aligned < 36) + { + m_MaxCount = 0; + m_X = NULL; + m_Y = NULL; + m_Z = NULL; + + return false; + } + + uint32_t remainder = (uint32_t)POWER_OF_TWO_MOD(buffer_end, 16) / 4; + uint32_t slot_count = (uint32_t)(buffer_end - buffer_addr_aligned) / 48; + + m_MaxCount = slot_count * 4 + (uint32_t)(remainder * (slot_count % 3 == 2)); + + m_X = (float*)buffer_addr_aligned; + uint32_t aligned_count = ALIGN_UP(m_MaxCount, 4); + m_Y = m_X + aligned_count; + m_Z = m_Y + aligned_count; +} + + +//---------------------------------------------------------------------------------------- +struct Vector4SOA : public Vector3SOA +{ + float* m_W; + + slInline explicit Vector4SOA() {m_Count = 0; m_MaxCount = 0; m_X = NULL; m_Y = NULL; m_Z = NULL; m_W = NULL;} + bool InitVector4SOA(float* buffer, uint32_t buffer_size); + + void GetVector4AtIndex(Vector4& v, uint32_t index) {Assert(index < m_Count); v.x = m_X[index]; v.y = m_Y[index]; v.z = m_Z[index]; v.w = m_W[index];} +}; + +slInline bool Vector4SOA::InitVector4SOA(float* buffer, uint32_t max_count) +{ + m_Count = 0; + + uint64_t buffer_addr = (uint64_t)buffer; + uint64_t buffer_addr_aligned = ALIGN_UP(buffer_addr, 16); + uint64_t buffer_end = (uint64_t)(buffer + max_count); + + if (buffer_end - buffer_addr_aligned < 52) + { + m_MaxCount = 0; + m_X = NULL; + m_Y = NULL; + m_Z = NULL; + m_W = NULL; + + return false; + } + + uint32_t remainder = (uint32_t)POWER_OF_TWO_MOD(buffer_end, 16) / 4; + uint32_t slot_count = (uint32_t)(buffer_end - buffer_addr_aligned) / 64; + + m_MaxCount = slot_count * 4 + (uint32_t)(remainder * ((slot_count & 0x3) == 4)); + + m_X = (float*)buffer_addr_aligned; + uint32_t aligned_count = ALIGN_UP(m_MaxCount, 4); + m_Y = m_X + aligned_count; + m_Z = m_Y + aligned_count; + m_W = m_Z + aligned_count; +} diff --git a/Classes/Foundation/Math/Matrix.h b/Classes/Foundation/Math/Matrix.h new file mode 100755 index 0000000..37e5362 --- /dev/null +++ b/Classes/Foundation/Math/Matrix.h @@ -0,0 +1,660 @@ +#pragma once + +#include "Foundation/Common/GlobalInclude.h" +#include "Foundation/Math/MathOperations.h" +#include "Foundation/Math/MathTypes.h" +#include "Foundation/Math/Vector.h" + +//---------------------------------------------------------------------------------------- +// Matrix are expressed in post-multiply row-major format. +// That is, matrix multiplication follows the form v = x * A. +// A local-to-world transform with basis a, b, c, expressed in world space, will result +// in a matrix that looks like: +// _ _ +// | a | +// | b | +// | c | +// - - +// +// Therefore, translate t will naturally follow below c, in the illustration above. +// With this, we can stuff the matrix directly into OpenGL and not have to do swizzling. +//---------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------------------- +// Matrix3 +//---------------------------------------------------------------------------------------- +void SetMatrix3(Matrix3& r, const Matrix3& a); +void SetMatrix3(Matrix3& r, const Vector3& v0, const Vector3& v1, const Vector3& v2); + +void ScaleMatrix3(Matrix3& r, const float s, const Matrix3& a); +Matrix3 ScaleMatrix3(const float s, const Matrix3& a); + +float DeterminantOfMatrix3(const Matrix3& a); + +void TransposeMatrix3(Matrix3& r, const Matrix3& a); +Matrix3 TransposeMatrix3(const Matrix3& a); + +void InvertAffineMatrix3(Matrix3& r, const Matrix3& a); +Matrix3 InvertAffineMatrix3(const Matrix3& a); + +void InvertGeneralMatrix3(Matrix3& r, const Matrix3& a); +Matrix3 InvertGeneralMatrix3(const Matrix3& a); + +void MulMatrix3(Matrix3& r, const Matrix3& a, const Matrix3& b); +Matrix3 MulMatrix3(const Matrix3& a, const Matrix3& b); + +void MulMatrix3ByTransposedMatrix3(Matrix3& r, const Matrix3& a, const Matrix3& b); +Matrix3 MulMatrix3ByTransposedMatrix3(const Matrix3& a, const Matrix3& b); + +void MulVector3ByMatrix3(Vector3& r, const Vector3& v, const Matrix3& a); +Vector3 MulVector3ByMatrix3(const Vector3& v, const Matrix3& a); + +//---------------------------------------------------------------------------------------- +slInline void SetMatrix3(Matrix3& r, const Matrix3& a) +{ + r.v[0] = a.v[0]; + r.v[1] = a.v[1]; + r.v[2] = a.v[2]; +} + +//---------------------------------------------------------------------------------------- +slInline void SetMatrix3(Matrix3& r, const Vector3& v0, const Vector3& v1, const Vector3& v2) +{ + r.v[0] = v0; + r.v[1] = v1; + r.v[2] = v2; +} + +//---------------------------------------------------------------------------------------- +slInline void ScaleMatrix3(Matrix3& r, const float s, const Matrix3& a) +{ + ScaleVector3(r.v[0], s, a.v[0]); + ScaleVector3(r.v[1], s, a.v[1]); + ScaleVector3(r.v[2], s, a.v[2]); +} + +//---------------------------------------------------------------------------------------- +slInline Matrix3 ScaleMatrix3(const float s, const Matrix3& a) +{ + Matrix3 r; + ScaleVector3(r.v[0], s, a.v[0]); + ScaleVector3(r.v[1], s, a.v[1]); + ScaleVector3(r.v[2], s, a.v[2]); + return r; +} + +//---------------------------------------------------------------------------------------- +slInline float DeterminantOfMatrix3(const Matrix3& a) +{ + return a.v[0].x * (a.v[1].y * a.v[2].z - a.v[1].z * a.v[2].y) + + a.v[0].y * (a.v[1].z * a.v[2].x - a.v[1].x * a.v[2].z) + + a.v[0].z * (a.v[1].x * a.v[2].y - a.v[1].y * a.v[2].x); +} + +//---------------------------------------------------------------------------------------- +slInline void TransposeMatrix3(Matrix3& r, const Matrix3& a) +{ + // a might be the same as r + r.v[0].x = a.v[0].x; + r.v[1].y = a.v[1].y; + r.v[2].z = a.v[2].z; + + float temp; + temp = r.v[0].y; + r.v[0].y = r.v[1].x; + r.v[1].x = temp; + + temp = r.v[0].z; + r.v[0].z = r.v[2].x; + r.v[2].x = temp; + + temp = r.v[1].z; + r.v[1].z = r.v[2].y; + r.v[2].y = temp; +} + +//---------------------------------------------------------------------------------------- +slInline Matrix3 TransposeMatrix3(const Matrix3& a) +{ + Matrix3 r; + r.v[0].x = a.v[0].x; r.v[0].y = a.v[1].x; r.v[0].z = a.v[2].x; + r.v[1].x = a.v[0].y; r.v[1].y = a.v[1].y; r.v[1].z = a.v[2].y; + r.v[2].x = a.v[0].z; r.v[2].y = a.v[1].z; r.v[2].z = a.v[2].z; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void InvertAffineMatrix3(Matrix3& r, const Matrix3& a) +{ + TransposeMatrix3(r, a); +} + +//---------------------------------------------------------------------------------------- +slInline Matrix3 InvertAffineMatrix3(const Matrix3& a) +{ + return TransposeMatrix3(a); +} + +//---------------------------------------------------------------------------------------- +slInline void InvertGeneralMatrix3(Matrix3& r, const Matrix3& a) +{ + float inv_determinant = 1.0f / DeterminantOfMatrix3(a); + + Matrix3 a_T; + TransposeMatrix3(a_T, a); + CrossVector3(r.v[0], a_T.v[1], a_T.v[2]); + CrossVector3(r.v[1], a_T.v[2], a_T.v[0]); + CrossVector3(r.v[2], a_T.v[0], a_T.v[1]); + + ScaleMatrix3(r, inv_determinant, r); +} + +//---------------------------------------------------------------------------------------- +slInline Matrix3 InvertGeneralMatrix3(const Matrix3& a) +{ + float inv_determinant = 1.0f / DeterminantOfMatrix3(a); + + Matrix3 r; + Matrix3 a_T = TransposeMatrix3(a); + CrossVector3(r.v[0], a_T.v[1], a_T.v[2]); + CrossVector3(r.v[1], a_T.v[2], a_T.v[0]); + CrossVector3(r.v[2], a_T.v[0], a_T.v[1]); + + return ScaleMatrix3(inv_determinant, r); +} + +//---------------------------------------------------------------------------------------- +slInline void MulMatrix3(Matrix3& r, const Matrix3& a, const Matrix3& b) +{ + Matrix3 temp; + + temp.v[0].x = DotVector3(a.v[0], b.v[0].x, b.v[1].x, b.v[2].x); + temp.v[0].y = DotVector3(a.v[0], b.v[0].y, b.v[1].y, b.v[2].y); + temp.v[0].z = DotVector3(a.v[0], b.v[0].z, b.v[1].z, b.v[2].z); + + temp.v[1].x = DotVector3(a.v[1], b.v[0].x, b.v[1].x, b.v[2].x); + temp.v[1].y = DotVector3(a.v[1], b.v[0].y, b.v[1].y, b.v[2].y); + temp.v[1].z = DotVector3(a.v[1], b.v[0].z, b.v[1].z, b.v[2].z); + + temp.v[2].x = DotVector3(a.v[2], b.v[0].x, b.v[1].x, b.v[2].x); + temp.v[2].y = DotVector3(a.v[2], b.v[0].y, b.v[1].y, b.v[2].y); + temp.v[2].z = DotVector3(a.v[2], b.v[0].z, b.v[1].z, b.v[2].z); + + SetMatrix3(r, temp); +} + +//---------------------------------------------------------------------------------------- +slInline Matrix3 MulMatrix3(const Matrix3& a, const Matrix3& b) +{ + Matrix3 r; + + r.v[0].x = DotVector3(a.v[0], b.v[0].x, b.v[1].x, b.v[2].x); + r.v[0].y = DotVector3(a.v[0], b.v[0].y, b.v[1].y, b.v[2].y); + r.v[0].z = DotVector3(a.v[0], b.v[0].z, b.v[1].z, b.v[2].z); + + r.v[1].x = DotVector3(a.v[1], b.v[0].x, b.v[1].x, b.v[2].x); + r.v[1].y = DotVector3(a.v[1], b.v[0].y, b.v[1].y, b.v[2].y); + r.v[1].z = DotVector3(a.v[1], b.v[0].z, b.v[1].z, b.v[2].z); + + r.v[2].x = DotVector3(a.v[2], b.v[0].x, b.v[1].x, b.v[2].x); + r.v[2].y = DotVector3(a.v[2], b.v[0].y, b.v[1].y, b.v[2].y); + r.v[2].z = DotVector3(a.v[2], b.v[0].z, b.v[1].z, b.v[2].z); + + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void MulMatrix3ByTransposedMatrix3(Matrix3& r, const Matrix3& a, const Matrix3& b) +{ + Matrix3 temp; + + temp.v[0].x = DotVector3(a.v[0], b.v[0]); + temp.v[0].y = DotVector3(a.v[0], b.v[1]); + temp.v[0].z = DotVector3(a.v[0], b.v[2]); + + temp.v[1].x = DotVector3(a.v[1], b.v[0]); + temp.v[1].y = DotVector3(a.v[1], b.v[1]); + temp.v[1].z = DotVector3(a.v[1], b.v[2]); + + temp.v[2].x = DotVector3(a.v[2], b.v[0]); + temp.v[2].y = DotVector3(a.v[2], b.v[1]); + temp.v[2].z = DotVector3(a.v[2], b.v[2]); + + SetMatrix3(r, temp); +} + +//---------------------------------------------------------------------------------------- +slInline Matrix3 MulMatrix3ByTransposedMatrix3(const Matrix3& a, const Matrix3& b) +{ + Matrix3 r; + + r.v[0].x = DotVector3(a.v[0], b.v[0]); + r.v[0].y = DotVector3(a.v[0], b.v[1]); + r.v[0].z = DotVector3(a.v[0], b.v[2]); + + r.v[1].x = DotVector3(a.v[1], b.v[0]); + r.v[1].y = DotVector3(a.v[1], b.v[1]); + r.v[1].z = DotVector3(a.v[1], b.v[2]); + + r.v[2].x = DotVector3(a.v[2], b.v[0]); + r.v[2].y = DotVector3(a.v[2], b.v[1]); + r.v[2].z = DotVector3(a.v[2], b.v[2]); + + return r; +} + +//---------------------------------------------------------------------------------------- +// do NOT pass in components of a as the r vector +slInline void MulVector3ByMatrix3(Vector3& r, const Vector3& v, const Matrix3& a) +{ + float x = v.x * a.v[0].x + v.y * a.v[1].x + v.z * a.v[2].x; + float y = v.x * a.v[0].y + v.y * a.v[1].y + v.z * a.v[2].y; + float z = v.x * a.v[0].z + v.y * a.v[1].z + v.z * a.v[2].z; + SetVector3(r, x, y, z); +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 MulVector3ByMatrix3(const Vector3& v, const Matrix3& a) +{ + Vector3 r; + r.x = v.x * a.v[0].x + v.y * a.v[1].x + v.z * a.v[2].x; + r.y = v.x * a.v[0].y + v.y * a.v[1].y + v.z * a.v[2].y; + r.z = v.x * a.v[0].z + v.y * a.v[1].z + v.z * a.v[2].z; + return r; +} + + + +//---------------------------------------------------------------------------------------- +// Matrix4 +//---------------------------------------------------------------------------------------- +void SetMatrix4(Matrix4& r, const Matrix4& a); +void SetMatrix4(Matrix4& r, const Matrix3& a); +void SetMatrix4(Matrix4& r, const Matrix3& a, const Vector3& position); + +void ScaleMatrix4(Matrix4& r, const float s, const Matrix4& a); +Matrix4 ScaleMatrix4(const float s, const Matrix4& a); + +float DeterminantOfMatrix4(const Matrix4& a); + +void TransposeMatrix4(Matrix4& r, const Matrix4& a); +Matrix4 TransposeMatrix4(const Matrix4& a); + +void InvertAffineMatrix4(Matrix4& r, const Matrix4& a); +Matrix4 InvertAffineMatrix4(const Matrix4& a); + +void InvertGeneralMatrix4(Matrix4& r, const Matrix4& a); +Matrix4 InvertGeneralMatrix4(const Matrix4& a); + +void MulMatrix4(Matrix4& r, const Matrix4& a, const Matrix4& b); +Matrix4 MulMatrix4(const Matrix4& a, const Matrix4& b); + +void MulMatrix4ByTransposedMatrix4(Matrix4& r, const Matrix4& a, const Matrix4& t); +Matrix4 MulMatrix4ByTransposedMatrix4(const Matrix4& a, Matrix4& t); + +void MulVector4ByMatrix4(Vector4& r, const Vector4& v, const Matrix4& a); +Vector4 MulVector4ByMatrix4(const Vector4& v, const Matrix4& a); + +void MulVector3ByMatrix4(Vector4& r, const Vector3& v, const float w, const Matrix4& a); +Vector4 MulVector3ByMatrix4(const Vector3& v, const float w, const Matrix4& a); + +void MulVector4ByTransposedMatrix4(Vector4& r, const Vector4& v, const Matrix4& t); +Vector4 MulVector4ByTransposedMatrix4(const Vector4& v, const Matrix4& t); + +void MulVector3ByTransposedMatrix4(Vector4& r, const Vector3& v, const float w, const Matrix4& t); +Vector4 MulVector3ByTransposedMatrix4(const Vector3& v, const float w, const Matrix4& t); + +//---------------------------------------------------------------------------------------- +slInline void SetMatrix4(Matrix4& r, const Matrix4& a) +{ + r.v[0] = a.v[0]; + r.v[1] = a.v[1]; + r.v[2] = a.v[2]; + r.v[3] = a.v[3]; +} + +//---------------------------------------------------------------------------------------- +slInline void SetMatrix4(Matrix4& r, const Matrix3& a) +{ + SetVector4(r.v[0], a.v[0], 0.0f); + SetVector4(r.v[1], a.v[1], 0.0f); + SetVector4(r.v[2], a.v[2], 0.0f); + SetVector4(r.v[3], 0.0f, 0.0f, 0.0f, 1.0f); +} + +//---------------------------------------------------------------------------------------- +slInline void SetMatrix4(Matrix4& r, const Matrix3& a, const Vector3& position) +{ + SetVector4(r.v[0], a.v[0], 0.0f); + SetVector4(r.v[1], a.v[1], 0.0f); + SetVector4(r.v[2], a.v[2], 0.0f); + SetVector4(r.v[3], position, 1.0f); +} + +//---------------------------------------------------------------------------------------- +slInline void ScaleMatrix4(Matrix4& r, const float s, const Matrix4& a) +{ + ScaleVector4(r.v[0], s, a.v[0]); + ScaleVector4(r.v[1], s, a.v[1]); + ScaleVector4(r.v[2], s, a.v[2]); + ScaleVector4(r.v[3], s, a.v[3]); +} + +//---------------------------------------------------------------------------------------- +slInline Matrix4 ScaleMatrix4(const float s, const Matrix4& a) +{ + Matrix4 r; + ScaleVector4(r.v[0], s, a.v[0]); + ScaleVector4(r.v[1], s, a.v[1]); + ScaleVector4(r.v[2], s, a.v[2]); + ScaleVector4(r.v[3], s, a.v[3]); + return r; +} + +//---------------------------------------------------------------------------------------- +slInline float DeterminantOfMatrix4(const Matrix4& a) +{ + // is this correct? + Vector4 cross_product; + CrossVector4(cross_product, a.v[1], a.v[2], a.v[3]); + return DotVector4(a.v[0], cross_product); +} + +//---------------------------------------------------------------------------------------- +slInline void TransposeMatrix4(Matrix4& r, const Matrix4& a) +{ + // a might be the same as r + r.v[0].x = a.v[0].x; + r.v[1].y = a.v[1].y; + r.v[2].z = a.v[2].z; + r.v[3].w = a.v[3].w; + + float temp; + temp = r.v[0].y; + r.v[0].y = r.v[1].x; + r.v[1].x = temp; + + temp = r.v[0].z; + r.v[0].z = r.v[2].x; + r.v[2].x = temp; + + temp = r.v[0].w; + r.v[0].w = r.v[3].x; + r.v[3].x = temp; + + temp = r.v[1].z; + r.v[1].z = r.v[2].y; + r.v[2].y = temp; + + temp = r.v[1].w; + r.v[1].w = r.v[3].y; + r.v[3].y = temp; + + temp = r.v[2].w; + r.v[2].w = r.v[3].z; + r.v[3].z = temp; +} + +//---------------------------------------------------------------------------------------- +slInline Matrix4 TransposeMatrix4(const Matrix4& a) +{ + Matrix4 r; + r.v[0].x = a.v[0].x; r.v[0].y = a.v[1].x; r.v[0].z = a.v[2].x; r.v[0].w = a.v[3].x; + r.v[1].x = a.v[0].y; r.v[1].y = a.v[1].y; r.v[1].z = a.v[2].y; r.v[1].w = a.v[3].y; + r.v[2].x = a.v[0].z; r.v[2].y = a.v[1].z; r.v[2].z = a.v[2].z; r.v[2].w = a.v[3].z; + r.v[3].x = a.v[0].w; r.v[3].y = a.v[1].w; r.v[3].z = a.v[2].w; r.v[3].w = a.v[3].w; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void InvertAffineMatrix4(Matrix4& r, const Matrix4& a) +{ + // this may not be correct... + Matrix3 a3_T(a.v[0].AsVector3(), a.v[1].AsVector3(), a.v[2].AsVector3()); + InvertAffineMatrix3(a3_T, a3_T); + + Vector3 transpose; + MulVector3ByMatrix3(transpose, a.v[3].AsVector3(), a3_T); + + SetMatrix4(r, a3_T, transpose); +} + +//---------------------------------------------------------------------------------------- +slInline Matrix4 InvertAffineMatrix4(const Matrix4& a) +{ + Matrix4 r; + + // this may not be correct... + Matrix3 a3_T(a.v[0].AsVector3(), a.v[1].AsVector3(), a.v[2].AsVector3()); + InvertAffineMatrix3(a3_T, a3_T); + + Vector3 transpose; + MulVector3ByMatrix3(transpose, a.v[3].AsVector3(), a3_T); + + SetMatrix4(r, a3_T, transpose); + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void InvertGeneralMatrix4(Matrix4& r, const Matrix4& a) +{ + // does this work? + float inv_determinant = 1.0f / DeterminantOfMatrix4(a); + + Matrix4 a_T; + TransposeMatrix4(a_T, a); + CrossVector4(r.v[0], a_T.v[1], a_T.v[2], a_T.v[3]); + CrossVector4(r.v[1], a_T.v[2], a_T.v[3], a_T.v[0]); + CrossVector4(r.v[2], a_T.v[3], a_T.v[0], a_T.v[1]); + CrossVector4(r.v[3], a_T.v[0], a_T.v[1], a_T.v[2]); + + ScaleMatrix4(r, inv_determinant, r); +} + +//---------------------------------------------------------------------------------------- +slInline Matrix4 InvertGeneralMatrix4(const Matrix4& a) +{ + // does this work? + Matrix4 r; + float inv_determinant = 1.0f / DeterminantOfMatrix4(a); + + Matrix4 a_T; + TransposeMatrix4(a_T, a); + r.v[0] = CrossVector4(a_T.v[1], a_T.v[2], a_T.v[3]); + r.v[1] = CrossVector4(a_T.v[2], a_T.v[3], a_T.v[0]); + r.v[2] = CrossVector4(a_T.v[3], a_T.v[0], a_T.v[1]); + r.v[3] = CrossVector4(a_T.v[0], a_T.v[1], a_T.v[2]); + + return ScaleMatrix4(inv_determinant, r); +} + +//---------------------------------------------------------------------------------------- +slInline void MulMatrix4(Matrix4& r, const Matrix4& a, const Matrix4& b) +{ + Matrix4 temp; + + temp.v[0].x = DotVector4(a.v[0], b.v[0].x, b.v[1].x, b.v[2].x, b.v[3].x); + temp.v[0].y = DotVector4(a.v[0], b.v[0].y, b.v[1].y, b.v[2].y, b.v[3].y); + temp.v[0].z = DotVector4(a.v[0], b.v[0].z, b.v[1].z, b.v[2].z, b.v[3].z); + temp.v[0].w = DotVector4(a.v[0], b.v[0].w, b.v[1].w, b.v[2].w, b.v[3].w); + + temp.v[1].x = DotVector4(a.v[1], b.v[0].x, b.v[1].x, b.v[2].x, b.v[3].x); + temp.v[1].y = DotVector4(a.v[1], b.v[0].y, b.v[1].y, b.v[2].y, b.v[3].y); + temp.v[1].z = DotVector4(a.v[1], b.v[0].z, b.v[1].z, b.v[2].z, b.v[3].z); + temp.v[1].w = DotVector4(a.v[1], b.v[0].w, b.v[1].w, b.v[2].w, b.v[3].w); + + temp.v[2].x = DotVector4(a.v[2], b.v[0].x, b.v[1].x, b.v[2].x, b.v[3].x); + temp.v[2].y = DotVector4(a.v[2], b.v[0].y, b.v[1].y, b.v[2].y, b.v[3].y); + temp.v[2].z = DotVector4(a.v[2], b.v[0].z, b.v[1].z, b.v[2].z, b.v[3].z); + temp.v[2].w = DotVector4(a.v[2], b.v[0].w, b.v[1].w, b.v[2].w, b.v[3].w); + + temp.v[3].x = DotVector4(a.v[3], b.v[0].x, b.v[1].x, b.v[2].x, b.v[3].x); + temp.v[3].y = DotVector4(a.v[3], b.v[0].y, b.v[1].y, b.v[2].y, b.v[3].y); + temp.v[3].z = DotVector4(a.v[3], b.v[0].z, b.v[1].z, b.v[2].z, b.v[3].z); + temp.v[3].w = DotVector4(a.v[3], b.v[0].w, b.v[1].w, b.v[2].w, b.v[3].w); + + SetMatrix4(r, temp); +} + +//---------------------------------------------------------------------------------------- +slInline Matrix4 MulMatrix4(const Matrix4& a, const Matrix4& b) +{ + Matrix4 r; + + r.v[0].x = DotVector4(a.v[0], b.v[0].x, b.v[1].x, b.v[2].x, b.v[3].x); + r.v[0].y = DotVector4(a.v[0], b.v[0].y, b.v[1].y, b.v[2].y, b.v[3].y); + r.v[0].z = DotVector4(a.v[0], b.v[0].z, b.v[1].z, b.v[2].z, b.v[3].z); + r.v[0].w = DotVector4(a.v[0], b.v[0].w, b.v[1].w, b.v[2].w, b.v[3].w); + + r.v[1].x = DotVector4(a.v[1], b.v[0].x, b.v[1].x, b.v[2].x, b.v[3].x); + r.v[1].y = DotVector4(a.v[1], b.v[0].y, b.v[1].y, b.v[2].y, b.v[3].y); + r.v[1].z = DotVector4(a.v[1], b.v[0].z, b.v[1].z, b.v[2].z, b.v[3].z); + r.v[1].w = DotVector4(a.v[1], b.v[0].w, b.v[1].w, b.v[2].w, b.v[3].w); + + r.v[2].x = DotVector4(a.v[2], b.v[0].x, b.v[1].x, b.v[2].x, b.v[3].x); + r.v[2].y = DotVector4(a.v[2], b.v[0].y, b.v[1].y, b.v[2].y, b.v[3].y); + r.v[2].z = DotVector4(a.v[2], b.v[0].z, b.v[1].z, b.v[2].z, b.v[3].z); + r.v[2].w = DotVector4(a.v[2], b.v[0].w, b.v[1].w, b.v[2].w, b.v[3].w); + + r.v[3].x = DotVector4(a.v[3], b.v[0].x, b.v[1].x, b.v[2].x, b.v[3].x); + r.v[3].y = DotVector4(a.v[3], b.v[0].y, b.v[1].y, b.v[2].y, b.v[3].y); + r.v[3].z = DotVector4(a.v[3], b.v[0].z, b.v[1].z, b.v[2].z, b.v[3].z); + r.v[3].w = DotVector4(a.v[3], b.v[0].w, b.v[1].w, b.v[2].w, b.v[3].w); + + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void MulMatrix4ByTransposedMatrix4(Matrix4& r, const Matrix4& a, const Matrix4& t) +{ + Matrix4 temp; + + temp.v[0].x = DotVector4(a.v[0], b.v[0]); + temp.v[0].y = DotVector4(a.v[0], b.v[1]); + temp.v[0].z = DotVector4(a.v[0], b.v[2]); + temp.v[0].w = DotVector4(a.v[0], b.v[3]); + + temp.v[1].x = DotVector4(a.v[1], b.v[0]); + temp.v[1].y = DotVector4(a.v[1], b.v[1]); + temp.v[1].z = DotVector4(a.v[1], b.v[2]); + temp.v[1].w = DotVector4(a.v[1], b.v[3]); + + temp.v[2].x = DotVector4(a.v[2], b.v[0]); + temp.v[2].y = DotVector4(a.v[2], b.v[1]); + temp.v[2].z = DotVector4(a.v[2], b.v[2]); + temp.v[2].w = DotVector4(a.v[2], b.v[3]); + + temp.v[3].x = DotVector4(a.v[3], b.v[0]); + temp.v[3].y = DotVector4(a.v[3], b.v[1]); + temp.v[3].z = DotVector4(a.v[3], b.v[2]); + temp.v[3].w = DotVector4(a.v[3], b.v[3]); + + SetMatrix4(r, temp); +} + +//---------------------------------------------------------------------------------------- +slInline Matrix4 MulMatrix4ByTransposedMatrix4(const Matrix4& a, const Matrix4& t) +{ + Matrix4 r; + + r.v[0].x = DotVector4(a.v[0], b.v[0]); + r.v[0].y = DotVector4(a.v[0], b.v[1]); + r.v[0].z = DotVector4(a.v[0], b.v[2]); + r.v[0].w = DotVector4(a.v[0], b.v[3]); + + r.v[1].x = DotVector4(a.v[1], b.v[0]); + r.v[1].y = DotVector4(a.v[1], b.v[1]); + r.v[1].z = DotVector4(a.v[1], b.v[2]); + r.v[1].w = DotVector4(a.v[1], b.v[3]); + + r.v[2].x = DotVector4(a.v[2], b.v[0]); + r.v[2].y = DotVector4(a.v[2], b.v[1]); + r.v[2].z = DotVector4(a.v[2], b.v[2]); + r.v[2].w = DotVector4(a.v[2], b.v[3]); + + r.v[3].x = DotVector4(a.v[3], b.v[0]); + r.v[3].y = DotVector4(a.v[3], b.v[1]); + r.v[3].z = DotVector4(a.v[3], b.v[2]); + r.v[3].w = DotVector4(a.v[3], b.v[3]); + + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void MulVector4ByMatrix4(Vector4& r, const Vector4& v, const Matrix4& a) +{ + Vector4 result; + ScaleVector4(result, v.x, a.v[0]); + ScaleAddVector4(result, v.y, a.v[1], result); + ScaleAddVector4(result, v.z, a.v[2], result); + ScaleAddVector4(result, v.w, a.v[3], result); + SetVector4(r, result); +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 MulVector4ByMatrix4(const Vector4& v, const Matrix4& a) +{ + Vector4 r; + ScaleVector4(r, v.x, a.v[0]); + ScaleAddVector4(r, v.y, a.v[1], r); + ScaleAddVector4(r, v.z, a.v[2], r); + ScaleAddVector4(r, v.w, a.v[3], r); + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void MulVector3ByMatrix4(Vector4& r, const Vector3& v, const float iw, const Matrix4& a) +{ + Vector4 result; + ScaleVector4(result, v.x, a.v[0]); + ScaleAddVector4(result, v.y, a.v[1], result); + ScaleAddVector4(result, v.z, a.v[2], result); + ScaleAddVector4(result, iw, a.v[3], result); + SetVector4(r, result); +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 MulVector3ByMatrix4(const Vector3& v, const float iw, const Matrix4& a) +{ + Vector4 r; + ScaleVector4(r, v.x, a.v[0]); + ScaleAddVector4(r, v.y, a.v[1], r); + ScaleAddVector4(r, v.z, a.v[2], r); + ScaleAddVector4(r, iw, a.v[3], r); + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void MulVector4ByTransposedMatrix4(Vector4& r, const Vector4& v, const Matrix4& t) +{ + float x = DotVector4(v, t.v[0]); + float y = DotVector4(v, t.v[1]); + float z = DotVector4(v, t.v[2]); + float w = DotVector4(v, t.v[3]); + SetVector4(r, x, y, z, w); +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 MulVector4ByTransposedMatrix4(const Vector4& v, const Matrix4& t) +{ + Vector4 r; + r.x = DotVector4(v, t.v[0]); + r.y = DotVector4(v, t.v[1]); + r.z = DotVector4(v, t.v[2]); + r.w = DotVector4(v, t.v[3]); + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void MulVector3ByTransposedMatrix4(Vector4& r, const Vector3& v, const float w, const Matrix4& t) +{ + Vector4 v_new(v, w); + MulVector4ByTransposedMatrix4(r, v_new, a); +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 MulVector3ByTransposedMatrix4(const Vector3& v, const float w, const Matrix4& t) +{ + Vector4 v_as_v4(v, w); + return MulVector4ByTransposedMatrix4(v_as_v4, t); +} diff --git a/Classes/Foundation/Math/Quaternion.h b/Classes/Foundation/Math/Quaternion.h new file mode 100755 index 0000000..8a303db --- /dev/null +++ b/Classes/Foundation/Math/Quaternion.h @@ -0,0 +1,100 @@ +#pragma once + +#include "Foundation/Common/GlobalInclude.h" +#include "Foundation/Common/MathTypes.h" +#include "Foundation/Math/Vector.h" + +//---------------------------------------------------------------------------------------- +// Quaternion +//---------------------------------------------------------------------------------------- +void SetQuaternion(Quaternion& r, const float angle, const float x, const float y, const float z); +void SetQuaternion(Quaternion& r, const float angle, const Vector3& rotation_axis); +void ScaleQuaternion(Quaternion& r, const float s, const Quaternion& q); +void MulQuaternion(Quaternion& r, const Quaternion& p, const Quaternion& q); +void ConjugateOfQuaternion(Quaternion& r, const Quaternion& q); +float NormOfQuaternion(const Quaternion& q); +float NormSquaredOfQuaternion(const Quaternion& q); +void NormalizeQuaternion(Quaternion& r, Quaternion& q); +void InverseQuaterion(Quaternion& r, const Quaternion& q); + +//---------------------------------------------------------------------------------------- +void SetQuaternion(Quaternion& r, const float angle, const float x, const float y, const float z) +{ + Assert( EpsilonEquals(LengthVector3(rotation_axis), 0.0f, kEpsilon) ); + + float half_angle = angle * 0.5f; + float sin_half_angle = Sinf(half_angle); + + r.i = x * sin_half_angle; + r.j = y * sin_half_angle; + r.k = z * sin_half_angle; + r.s = Cosf(half_angle); +} + +//---------------------------------------------------------------------------------------- +void SetQuaternion(Quaternion& r, const float angle, const Vector3& rotation_axis) +{ + Assert( EpsilonEquals(LengthVector3(rotation_axis), 0.0f, kEpsilon) ); + + float half_angle = angle * 0.5f; + float sin_half_angle = Sinf(half_angle); + + r.i = rotation_axis.x * sin_half_angle; + r.j = rotation_axis.y * sin_half_angle; + r.k = rotation_axis.z * sin_half_angle; + r.s = Cosf(half_angle); +} + +//---------------------------------------------------------------------------------------- +void ScaleQuaternion(Quaternion& r, const float s, const Quaternion& q) +{ + r.i = q.i * s; + r.j = q.j * s; + r.k = q.k * s; + r.s = q.s * s; +} + +//---------------------------------------------------------------------------------------- +void MulQuaternion(Quaternion& r, const Quaternion& p, const Quaternion& q) +{ + r.i = p.s * q.i + p.i * q.s + p.j * q.k - p.k * q.j; + r.j = p.s * q.j + p.j * q.s + p.k * q.i - p.i * q.k; + r.k = p.s * q.k + p.k * q.s + p.i * q.j - p.j * q.i; + r.s = p.s * q.s - p.i * q.i - p.j * q.j - p.k * q.k; +} + +//---------------------------------------------------------------------------------------- +void ConjugateOfQuaternion(Quaternion& r, const Quaternion& q) +{ + r.i = -q.i; + r.j = -q.j; + r.k = -q.k; + r.s = q.s; +} + +//---------------------------------------------------------------------------------------- +float NormOfQuaternion(const Quaternion& q) +{ + return Sqrtf( q.i * q.i + q.j * q.j + q.k * q.k + q.s * q.s); +} + +//---------------------------------------------------------------------------------------- +float NormSquaredOfQuaternion(const Quaternion& q) +{ + return q.i * q.i + q.j * q.j + q.k * q.k + q.s * q.s; +} + +//---------------------------------------------------------------------------------------- +void NormalizeQuaternion(Quaternion& r, Quaternion& q) +{ + float norm_scale = 1.0f / NormQuaternion( q ); + ScaleQuaternion( r, norm_scale, q ); +} + +//---------------------------------------------------------------------------------------- +void InverseQuaterion(Quaternion& r, const Quaternion& q) +{ + ConjugateOfQuaternion( r, q ); + float inv_norm_squared = 1.0f / NormSquaredOfQuaternion( q ); + ScaleQuaternion( r, inv_norm_squared, q ); +} diff --git a/Classes/Foundation/Math/Vector.h b/Classes/Foundation/Math/Vector.h new file mode 100755 index 0000000..3e5e524 --- /dev/null +++ b/Classes/Foundation/Math/Vector.h @@ -0,0 +1,1176 @@ +#pragma once + +#include "Foundation/Common/GlobalInclude.h" +#include "Foundation/Math/MathTypes.h" +#include "Foundation/Math/MathOperations.h" + +//---------------------------------------------------------------------------------------- +// Vector2 +//---------------------------------------------------------------------------------------- +void SetVector2(Vector2& r, const Vector2& v); +void SetVector2(Vector2& r, const float x, const float y); +void SetVector2(Vector2& r, const float xy); +void AbsVector2(Vector2& r, const Vector2& v); +float MinComponentVector2(const Vector2& v); +float MaxComponentVector2(const Vector2& v); +uint32_t MinIndexVector2(const Vector2& v); +uint32_t MaxIndexVector2(const Vector2& v); +float DotVector2(const Vector2& a, const Vector2& b); +float DotVector2(const Vector2& a, const float x, const float y); + +void PerpendicularVector2(Vector2& r, const Vector2& v); +Vector2 PerpendicularVector2(const Vector2& v); + +void AddVector2ByScalar(Vector2& r, const float s, const Vector2& v); +Vector2 AddVector2ByScalar(const float s, const Vector2& v); + +void AddVector2(Vector2& r, const Vector2& a, const Vector2& b); +Vector2 AddVector2(const Vector2& a, const Vector2& b); + +void AddVector2(Vector2& r, const Vector2& a, const float x, const float y); +Vector2 AddVector2(const Vector2& a, const float x, const float y); + +void SubVector2(Vector2& r, const Vector2& a, const Vector2& b); +Vector2 SubVector2(const Vector2& a, const Vector2& b); + +void SubVector2(Vector2& r, const Vector2& a, const float x, const float y); +Vector2 SubVector2(const Vector2& a, const float x, const float y); + +void ScaleVector2(Vector2& r, const float s, const Vector2& v); +Vector2 ScaleVector2(const float s, const Vector2& v); + +void MulVector2(Vector2& r, const Vector2& a, const Vector2& b); +Vector2 MulVector2(const Vector2& a, const Vector2& b); + +void MulVector2(Vector2& r, const Vector2& a, const float x, const float y); +Vector2 MulVector2(const Vector2& a, const float x, const float y); + +void DivVector2(Vector2& r, const Vector2& a, const Vector2& b); +Vector2 DivVector2(const Vector2& a, const Vector2& b); + +void DivVector2(Vector2& r, const Vector2& a, const float x, const float y); +Vector2 DivVector2(const Vector2& a, const float x, const float y); + +void ScaleAddVector2(Vector2& r, const float s, const Vector2& v_scale, const Vector2& v_add); +Vector2 ScaleAddVector2(const float s, const Vector2& v_scale, const Vector2& v_add); + +void NormalizeVector2(Vector2& r, const Vector2& a); +Vector2 NormalizeVector2(const Vector2& a); + +float LengthOfVector2(const Vector2& a); +float LengthSquaredOfVector2(const Vector2& a); + +//---------------------------------------------------------------------------------------- +slInline void SetVector2(Vector2& r, const Vector2& v) +{ + r.x = v.x; + r.y = v.y; +} + +//---------------------------------------------------------------------------------------- +slInline void SetVector2(Vector2& r, const float x, const float y) +{ + r.x = x; + r.y = y; +} + +//---------------------------------------------------------------------------------------- +slInline void SetVector2(Vector2& r, const float xy) +{ + r.x = xy; + r.y = xy; +} + +//---------------------------------------------------------------------------------------- +void AbsVector2(Vector2& r, const Vector2& v) +{ + r.x = Absf(v.x); + r.y = Absf(v.y); +} + +//---------------------------------------------------------------------------------------- +float MinComponentVector2(const Vector2& v) +{ + return v.x <= v.y ? v.x : v.y; +} + +//---------------------------------------------------------------------------------------- +float MaxComponentVector2(const Vector2& v) +{ + return v.x >= v.y ? v.x : v.y; +} + +//---------------------------------------------------------------------------------------- +uint32_t MinIndexVector2(const Vector2& v) +{ + return v.x <= v.y ? 0 : 1; +} + +//---------------------------------------------------------------------------------------- +uint32_t MaxIndexVector2(const Vector2& v) +{ + return v.x >= v.y ? 0 : 1; +} + +//---------------------------------------------------------------------------------------- +slInline float DotVector2(const Vector2& a, const Vector2& b) +{ + return a.x * b.x + a.y * b.y; +} + +//---------------------------------------------------------------------------------------- +slInline float DotVector2(const Vector2& a, const float x, const float y) +{ + return a.x * x + a.y * y; +} + +//---------------------------------------------------------------------------------------- +slInline void PerpendicularVector2(Vector2& r, const Vector2& v) +{ + r.x = -v.y; + r.y = v.x; +} + +//---------------------------------------------------------------------------------------- +slInline Vector2 PerpendicularVector2(const Vector2& v) +{ + Vector2 r; + r.x = -v.y; + r.y = v.x; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void AddVector2ByScalar(Vector2& r, const float s, Vector2& v) +{ + r.x = s + v.x; + r.y = s + v.y; +} + +//---------------------------------------------------------------------------------------- +slInline Vector2 AddVector2ByScalar(const float s, const Vector2& v) +{ + Vector2 r; + r.x = s + v.x; + r.y = s + v.y; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void AddVector2(Vector2& r, const Vector2& a, const Vector2& b) +{ + r.x = a.x + b.x; + r.y = a.y + b.y; +} + +//---------------------------------------------------------------------------------------- +slInline Vector2 AddVector2(const Vector2& a, const Vector2& b) +{ + Vector2 r; + r.x = a.x + b.x; + r.y = a.y + b.y; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void AddVector2(Vector2& r, const Vector2& a, const float x, const float y) +{ + r.x = a.x + x; + r.y = a.y + y; +} + +//---------------------------------------------------------------------------------------- +slInline Vector2 AddVector2(const Vector2& a, const float x, const float y) +{ + Vector2 r; + r.x = a.x + x; + r.y = a.y + y; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void SubVector2(Vector2& r, const Vector2& a, const Vector2& b) +{ + r.x = a.x - b.x; + r.y = a.y - b.y; +} + +//---------------------------------------------------------------------------------------- +slInline Vector2 SubVector2(const Vector2& a, const Vector2& b) +{ + Vector2 r; + r.x = a.x - b.x; + r.y = a.y - b.y; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void SubVector2(Vector2& r, const Vector2& a, const float x, const float y) +{ + r.x = a.x - x; + r.y = a.y - y; +} + +//---------------------------------------------------------------------------------------- +slInline Vector2 SubVector2(const Vector2& a, const float x, const float y) +{ + Vector2 r; + r.x = a.x - x; + r.y = a.y - y; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void ScaleVector2(Vector2& r, const float s, const Vector2& v) +{ + r.x = s * v.x; + r.y = s * v.y; +} + +//---------------------------------------------------------------------------------------- +slInline Vector2 ScaleVector2(const float s, const Vector2& v) +{ + Vector2 r; + r.x = s * v.x; + r.y = s * v.y; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void MulVector2(Vector2& r, const Vector2& a, const Vector2& b) +{ + r.x = a.x * b.x; + r.y = a.y * b.y; +} + +//---------------------------------------------------------------------------------------- +slInline Vector2 MulVector2(const Vector2& a, const Vector2& b) +{ + Vector2 r; + r.x = a.x * b.x; + r.y = a.y * b.y; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void MulVector2(Vector2& r, const Vector2& a, const float x, const float y) +{ + r.x = a.x * x; + r.y = a.y * y; +} + +//---------------------------------------------------------------------------------------- +slInline Vector2 MulVector2(const Vector2& a, const float x, const float y) +{ + Vector2 r; + r.x = a.x * x; + r.y = a.y * y; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void DivVector2(Vector2& r, const Vector2& a, const Vector2& b) +{ + r.x = a.x / b.x; + r.y = a.y / b.y; +} + +//---------------------------------------------------------------------------------------- +slInline Vector2 DivVector2(const Vector2& a, const Vector2& b) +{ + Vector2 r; + r.x