From: chsieh Date: Fri, 17 Dec 2010 22:55:04 +0000 (-0800) Subject: Initial commit. More or less the default XCode project (deleted a strange setContext... X-Git-Tag: box2d-testbed~43 X-Git-Url: http://git.less.ly:3516/?a=commitdiff_plain;h=d6b59469718eb27d1d79cd5e9549cc2a2d4abd6a;p=tanks-ios.git 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. --- 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 = a.x / b.x; + r.y = a.y / b.y; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void DivVector2(Vector2& r, const Vector2& a, const float x, const float y) +{ + r.x = a.x / x; + r.y = a.y / y; +} + +//---------------------------------------------------------------------------------------- +slInline Vector2 DivVector2(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 ScaleAddVector2(Vector2& r, const float s, const Vector2& v_scale, const Vector2& v_add) +{ + r.x = v_scale.x * s + v_add.x; + r.y = v_scale.y * s + v_add.y; +} + +//---------------------------------------------------------------------------------------- +slInline Vector2 ScaleAddVector2(const float s, const Vector2& v_scale, const Vector2& v_add) +{ + Vector2 r; + r.x = v_scale.x * s + v_add.x; + r.y = v_scale.y * s + v_add.y; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void NormalizeVector2(Vector2& r, const Vector2& a) +{ + float scale = 1.0f / LengthOfVector2(a); + ScaleVector2( r, scale, a ); +} + +//---------------------------------------------------------------------------------------- +slInline Vector2 NormalizeVector2(const Vector2& a) +{ + float scale = 1.0f / LengthOfVector2(a); + return ScaleVector2( scale, a ); +} + +//---------------------------------------------------------------------------------------- +slInline float LengthOfVector2(const Vector2& a) +{ + return Sqrtf( DotVector2(a, a) ); +} + +//---------------------------------------------------------------------------------------- +slInline float LengthSquaredOfVector2(const Vector2& a) +{ + return DotVector2(a, a); +} + + + +//---------------------------------------------------------------------------------------- +// Vector3 +//---------------------------------------------------------------------------------------- +void SetVector3(Vector3& r, const Vector3& v); +void SetVector3(Vector3& r, const Vector2& v, const float z); +void SetVector3(Vector3& r, const float xyz); +void SetVector3(Vector3& r, const float x, const float y, const float z); + +void AbsVector3(Vector3& r, const Vector3& v); +Vector3 AbsVector3(const Vector3& v); + +float MinComponentVector3(const Vector3& v); +float MaxComponentVector3(const Vector3& v); +uint32_t MinIndexVector3(const Vector3& v); +uint32_t MaxIndexVector3(const Vector3& v); +float DotVector3(const Vector3& a, const Vector3& b); +float DotVector3(const Vector3& a, const float x, const float y, const float z); + +void CrossVector3(Vector3& r, const Vector3& a, const Vector3& b); +Vector3 CrossVector3(const Vector3& a, const Vector3& b); + +void AddVector3ByScalar(Vector3& r, const float s, Vector3& v); +Vector3 AddVector3ByScalar(const float s, Vector3& v); + +void AddVector3(Vector3& r, const Vector3& a, const Vector3& b); +Vector3 AddVector3(const Vector3& a, const Vector3& b); + +void AddVector3(Vector3& r, const Vector3& a, const float x, const float y, const float z); +Vector3 AddVector3(const Vector3& a, const float x, const float y, const float z); + +void SubVector3(Vector3& r, const Vector3& a, const Vector3& b); +Vector3 SubVector3(const Vector3& a, const Vector3& b); + +void SubVector3(Vector3& r, const Vector3& a, const float x, const float y, const float z); +Vector3 SubVector3(const Vector3& a, const float x, const float y, const float z); + +void ScaleVector3(Vector3& r, const float s, const Vector3& v); +Vector3 ScaleVector3(const float s, const Vector3& v); + +void MulVector3(Vector3& r, const Vector3& a, const Vector3& b); +Vector3 MulVector3(const Vector3& a, const Vector3& b); + +void MulVector3(Vector3& r, const Vector3& a, const float x, const float y, const float z); +Vector3 MulVector3(const Vector3& a, const float x, const float y, const float z); + +void DivVector3(Vector3& r, const Vector3& a, const Vector3& b); +Vector3 DivVector3(const Vector3& a, const Vector3& b); + +void DivVector3(Vector3& r, const Vector3& a, const float x, const float y, const float z); +Vector3 DivVector3(const Vector3& a, const float x, const float y, const float z); + +void ScaleAddVector3(Vector3& r, const float s, const Vector3& v_scale, const Vector3& v_add); +Vector3 ScaleAddVector3(const float s, const Vector3& v_scale, const Vector3& v_add); + +void NormalizeVector3(Vector3& r, const Vector3& a); +Vector3 NormalizeVector3(const Vector3& a); + +float LengthVector3(const Vector3& a); +float LengthSquaredVector3(const Vector3& a); + +//---------------------------------------------------------------------------------------- +slInline void SetVector3(Vector3& r, const Vector3& v) +{ + r.x = v.x; + r.y = v.y; + r.z = v.z; +} + +//---------------------------------------------------------------------------------------- +slInline void SetVector3(Vector3& r, const Vector2& v, const float z) +{ + r.x = v.x; + r.y = v.y; + r.z = z; +} + +//---------------------------------------------------------------------------------------- +slInline void SetVector3(Vector3& r, const float xyz) +{ + r.x = xyz; + r.y = xyz; + r.z = xyz; +} + +//---------------------------------------------------------------------------------------- +slInline void SetVector3(Vector3& r, const float x, const float y, const float z) +{ + r.x = x; + r.y = y; + r.z = z; +} + +//---------------------------------------------------------------------------------------- +slInline void AbsVector3(Vector3& r, const Vector3& v) +{ + r.x = Absf(v.x); + r.y = Absf(v.y); + r.z = Absf(v.z); +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 AbsVector3(const Vector3& v) +{ + Vector3 r; + r.x = Absf(v.x); + r.y = Absf(v.y); + r.z = Absf(v.z); + return r; +} + +//---------------------------------------------------------------------------------------- +slInline float MinComponentVector3(const Vector3& v) +{ + float xy = v.x <= v.y ? v.x : v.y; + return xy <= v.z ? xy : v.z; +} + +//---------------------------------------------------------------------------------------- +slInline float MaxComponentVector3(const Vector3& v) +{ + float xy = v.x >= v.y ? v.x : v.y; + return xy >= v.z ? xy : v.z; +} + +//---------------------------------------------------------------------------------------- +slInline uint32_t MinIndexVector3(const Vector3& v) +{ + const float* v_array = &v.x; + uint32_t xy = v.x <= v.y ? 0 : 1; + return v_array[xy] <= v.z ? xy : 2; +} + +//---------------------------------------------------------------------------------------- +slInline uint32_t MaxIndexVector3(const Vector3& v) +{ + const float* v_array = &v.x; + uint32_t xy = v.x >= v.y ? 0 : 1; + return v_array[xy] >= v.z ? xy : 2; +} + +//---------------------------------------------------------------------------------------- +slInline float DotVector3(const Vector3& a, const Vector3& b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +//---------------------------------------------------------------------------------------- +slInline float DotVector3(const Vector3& a, const float x, const float y, const float z) +{ + return a.x * x + a.y * y + a.z * z; +} + +//---------------------------------------------------------------------------------------- +slInline void CrossVector3(Vector3& r, const Vector3& a, const Vector3& b) +{ + float x = a.y * b.z - b.y * a.z; + float y = a.z * b.x - b.z * a.x; + float z = a.x * b.y - b.x * a.y; + r.x = x; + r.y = y; + r.z = z; +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 CrossVector3(const Vector3& a, const Vector3& b) +{ + Vector3 r; + r.x = a.y * b.z - b.y * a.z; + r.y = a.z * b.x - b.z * a.x; + r.z = a.x * b.y - b.x * a.y; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void AddVector3ByScalar(Vector3& r, const float s, Vector3& v) +{ + r.x = s + v.x; + r.y = s + v.y; + r.z = s + v.z; +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 AddVector3ByScalar(const float s, Vector3& v) +{ + Vector3 r; + r.x = s + v.x; + r.y = s + v.y; + r.z = s + v.z; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void AddVector3(Vector3& r, const Vector3& a, const Vector3& b) +{ + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 AddVector3(const Vector3& a, const Vector3& b) +{ + Vector3 r; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void AddVector3(Vector3& r, const Vector3& a, const float x, const float y, const float z) +{ + r.x = a.x + x; + r.y = a.y + y; + r.z = a.z + z; +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 AddVector3(const Vector3& a, const float x, const float y, const float z) +{ + Vector3 r; + r.x = a.x + x; + r.y = a.y + y; + r.z = a.z + z; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void SubVector3(Vector3& r, const Vector3& a, const Vector3& b) +{ + r.x = a.x - b.x; + r.y = a.y - b.y; + r.z = a.z - b.z; +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 SubVector3(const Vector3& a, const Vector3& b) +{ + Vector3 r; + r.x = a.x - b.x; + r.y = a.y - b.y; + r.z = a.z - b.z; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 SubVector3(const Vector3& a, const float x, const float y, const float z) +{ + Vector3 r; + r.x = a.x - x; + r.y = a.y - y; + r.z = a.z - z; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void ScaleVector3(Vector3& r, const float s, const Vector3& v) +{ + r.x = s * v.x; + r.y = s * v.y; + r.z = s * v.z; +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 ScaleVector3(const float s, const Vector3& v) +{ + Vector3 r; + r.x = s * v.x; + r.y = s * v.y; + r.z = s * v.z; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void MulVector3(Vector3& r, const Vector3& a, const Vector3& b) +{ + r.x = a.x * b.x; + r.y = a.y * b.y; + r.z = a.z * b.z; +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 MulVector3(const Vector3& a, const Vector3& b) +{ + Vector3 r; + r.x = a.x * b.x; + r.y = a.y * b.y; + r.z = a.z * b.z; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void MulVector3(Vector3& r, const Vector3& a, const float x, const float y, const float z) +{ + r.x = a.x * x; + r.y = a.y * y; + r.z = a.z * z; +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 MulVector3(const Vector3& a, const float x, const float y, const float z) +{ + Vector3 r; + r.x = a.x * x; + r.y = a.y * y; + r.z = a.z * z; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void DivVector3(Vector3& r, const Vector3& a, const Vector3& b) +{ + r.x = a.x / b.x; + r.y = a.y / b.y; + r.z = a.z / b.z; +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 DivVector3(const Vector3& a, const Vector3& b) +{ + Vector3 r; + r.x = a.x / b.x; + r.y = a.y / b.y; + r.z = a.z / b.z; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void DivVector3(Vector3& r, const Vector3& a, const float x, const float y, const float z) +{ + r.x = a.x / x; + r.y = a.y / y; + r.z = a.z / z; +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 DivVector3(const Vector3& a, const float x, const float y, const float z) +{ + Vector3 r; + r.x = a.x / x; + r.y = a.y / y; + r.z = a.z / z; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void ScaleAddVector3(Vector3& r, const float s, const Vector3& v_scale, const Vector3& v_add) +{ + r.x = s * v_scale.x + v_add.x; + r.y = s * v_scale.y + v_add.y; + r.z = s * v_scale.z + v_add.z; +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 ScaleAddVector3(const float s, const Vector3& v_scale, const Vector3& v_add) +{ + Vector3 r; + r.x = s * v_scale.x + v_add.x; + r.y = s * v_scale.y + v_add.y; + r.z = s * v_scale.z + v_add.z; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void NormalizeVector3(Vector3& r, const Vector3& a) +{ + float scale = 1.0f / LengthOfVector3( a ); + ScaleVector3( r, scale, a ); +} + +//---------------------------------------------------------------------------------------- +slInline Vector3 NormalizeVector3(const Vector3& a) +{ + float scale = 1.0f / LengthOfVector3( a ); + return ScaleVector3( scale, a ); +} + +//---------------------------------------------------------------------------------------- +slInline float LengthOfVector3(const Vector3& a) +{ + return Sqrtf( DotVector3(a, a) ); +} + +//---------------------------------------------------------------------------------------- +slInline float LengthSquaredOfVector3(const Vector3& a) +{ + return DotVector3( a, a ); +} + + + +//---------------------------------------------------------------------------------------- +// Vector4 +//---------------------------------------------------------------------------------------- +void SetVector4(Vector4& r, const Vector4& v); +void SetVector4(Vector4& r, const Vector2& a, const Vector2& b); +void SetVector4(Vector4& r, const Vector3& v, const float w); +void SetVector4(Vector4& r, const float xyzw); +void SetVector4(Vector4& r, const float x, const float y, const float z, const float w); + +void AbsVector4(Vector4& r, const Vector4& v); +Vector4 AbsVector4(const Vector4& v); + +float MinComponentVector4(const Vector4& v); +float MaxComponentVector4(const Vector4& v); +uint32_t MinIndexVector4(const Vector4& v); +uint32_t MaxIndexVector4(const Vector4& v); +float DotVector4(const Vector4& a, const Vector4& b); +float DotVector4(const Vector4& a, const float x, const float y, const float z, const float w); + +void CrossVector4(Vector4& r, const Vector4& a, const Vector4& b, const Vector4& c); +Vector4 CrossVector4(const Vector4& a, const Vector4& b, const Vector4& c); + +void AddVector4ByScalar(Vector4& r, const float s, Vector4& v); +Vector4 AddVector4ByScalar(const float s, Vector4& v); + +void AddVector4(Vector4& r, const Vector4& a, const Vector4& b); +Vector4 AddVector4(const Vector4& a, const Vector4& b); + +void AddVector4(Vector4& r, const Vector4& a, const float x, const float y, const float z, const float w); +Vector4 AddVector4(const Vector4& a, const float x, const float y, const float z, const float w); + +void SubVector4(Vector4& r, const Vector4& a, const Vector4& b); +Vector4 SubVector4(const Vector4& a, const Vector4& b); + +void SubVector4(Vector4& r, const Vector4& a, const float x, const float y, const float z, const float w); +Vector4 SubVector4(const Vector4& a, const float x, const float y, const float z, const float w); + +void ScaleVector4(Vector4& r, const float s, const Vector4& v); +Vector4 ScaleVector4(const float s, const Vector4& v); + +void MulVector4(Vector4& r, const Vector4& a, const Vector4& b); +Vector4 MulVector4(const Vector4& a, const Vector4& b); + +void MulVector4(Vector4& r, const Vector4& a, const float x, const float y, const float z, const float w); +Vector4 MulVector4(const Vector4& a, const float x, const float y, const float z, const float w); + +void DivVector4(Vector4& r, const Vector4& a, const Vector4& b); +Vector4 DivVector4(const Vector4& a, const Vector4& b); + +void DivVector4(Vector4& r, const Vector4& a, const float x, const float y, const float z, const float w); +Vector4 DivVector4(const Vector4& a, const float x, const float y, const float z, const float w); + +void ScaleAddVector4(Vector4& r, const float s, const Vector4& v_scale, const Vector4& v_add); +Vector4 ScaleAddVector4(const float s, const Vector4& v_scale, const Vector4& v_add); + +void NormalizeVector4(Vector4& r, const Vector4& a); +Vector4 NormalizeVector4(const Vector4& a); + +float LengthVector4(const Vector4& a); +float LengthSquaredVector4(const Vector4& a); + +//---------------------------------------------------------------------------------------- +slInline void SetVector4(Vector4& r, const Vector4& v) +{ + r.x = v.x; + r.y = v.y; + r.z = v.z; + r.w = v.w; +} + +//---------------------------------------------------------------------------------------- +slInline void SetVector4(Vector4& r, const Vector2& a, const Vector2& b) +{ + r.x = a.x; + r.y = a.y; + r.z = b.x; + r.w = b.y; +} + +//---------------------------------------------------------------------------------------- +slInline void SetVector4(Vector4& r, const Vector3& v, const float w) +{ + r.x = v.x; + r.y = v.y; + r.z = v.z; + r.w = w; +} + +//---------------------------------------------------------------------------------------- +slInline void SetVector4(Vector4& r, const float xyzw) +{ + r.x = xyzw; + r.y = xyzw; + r.z = xyzw; + r.w = xyzw; +} + +//---------------------------------------------------------------------------------------- +slInline void SetVector4(Vector4& r, const float x, const float y, const float z, const float w) +{ + r.x = x; + r.y = y; + r.z = z; + r.w = w; +} + +//---------------------------------------------------------------------------------------- +slInline void AbsVector4(Vector4& r, const Vector4& v) +{ + r.x = Absf(v.x); + r.y = Absf(v.y); + r.z = Absf(v.z); + r.w = Absf(v.w); +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 AbsVector4(const Vector4& v) +{ + Vector4 r; + r.x = Absf(v.x); + r.y = Absf(v.y); + r.z = Absf(v.z); + r.w = Absf(v.w); + return r; +} + +//---------------------------------------------------------------------------------------- +slInline float MinComponentVector4(const Vector4& v) +{ + float xy = v.x <= v.y ? v.x : v.y; + float zw = v.z <= v.w ? v.z : v.w; + return xy <= zw ? xy : zw; +} + +//---------------------------------------------------------------------------------------- +slInline float MaxComponentVector4(const Vector4& v) +{ + float xy = v.x >= v.y ? v.x : v.y; + float zw = v.z >= v.w ? v.z : v.w; + return xy >= zw ? xy : zw; +} + +//---------------------------------------------------------------------------------------- +slInline uint32_t MinIndexVector4(const Vector4& v) +{ + const float* v_array = &v.x; + uint32_t xy = v.x <= v.y ? 0 : 1; + uint32_t zw = v.x <= v.y ? 2 : 3; + return v_array[xy] <= v_array[zw] ? xy : zw; +} + +//---------------------------------------------------------------------------------------- +slInline uint32_t MaxIndexVector4(const Vector4& v) +{ + const float* v_array = &v.x; + uint32_t xy = v.x >= v.y ? 0 : 1; + uint32_t zw = v.x >= v.y ? 2 : 3; + return v_array[xy] >= v_array[zw] ? xy : zw; +} + +//---------------------------------------------------------------------------------------- +slInline float DotVector4(const Vector4& a, const Vector4& b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +} + +//---------------------------------------------------------------------------------------- +slInline float DotVector4(const Vector4& a, const float x, const float y, const float z, const float w) +{ + return a.x * x + a.y * y + a.z * z + a.w * w; +} + +//---------------------------------------------------------------------------------------- +slInline void CrossVector4(Vector4& r, const Vector4& a, const Vector4& b, const Vector4& c) +{ + // is this right? + r.x = a.y * (b.z * c.w - b.w * c.z) - a.z * (b.y * c.w - c.y * b.w) + a.w * (b.y * c.z - b.z * c.y); + r.y = -a.x * (b.z * c.w - b.w * c.z) + a.z * (b.x * c.w - c.x * b.w) - a.w * (b.x * c.z - b.z * c.x); + r.z = a.x * (b.y * c.w - b.w * c.y) - a.y * (b.x * c.w - c.x * b.w) + a.w * (b.x * c.y - b.y * c.x); + r.w = -a.x * (b.y * c.z - b.z * c.y) + a.y * (b.x * c.z - b.z * c.x) - a.z * (b.x * c.y - b.y * c.x); +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 CrossVector4(const Vector4& a, const Vector4& b, const Vector4& c) +{ + Vector4 r; + // is this right? + r.x = a.y * (b.z * c.w - b.w * c.z) - a.z * (b.y * c.w - c.y * b.w) + a.w * (b.y * c.z - b.z * c.y); + r.y = -a.x * (b.z * c.w - b.w * c.z) + a.z * (b.x * c.w - c.x * b.w) - a.w * (b.x * c.z - b.z * c.x); + r.z = a.x * (b.y * c.w - b.w * c.y) - a.y * (b.x * c.w - c.x * b.w) + a.w * (b.x * c.y - b.y * c.x); + r.w = -a.x * (b.y * c.z - b.z * c.y) + a.y * (b.x * c.z - b.z * c.x) - a.z * (b.x * c.y - b.y * c.x); + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void AddVector4ByScalar(Vector4& r, const float s, Vector4& v) +{ + r.x = s * v.x; + r.y = s * v.y; + r.z = s * v.z; + r.w = s * v.w; +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 AddVector4ByScalar(const float s, Vector4& v) +{ + Vector4 r; + r.x = s * v.x; + r.y = s * v.y; + r.z = s * v.z; + r.w = s * v.w; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void AddVector4(Vector4& r, const Vector4& a, const Vector4& b) +{ + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + r.w = a.w + b.w; +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 AddVector4(const Vector4& a, const Vector4& b) +{ + Vector4 r; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + r.w = a.w + b.w; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void AddVector4(Vector4& r, const Vector4& a, const float x, const float y, const float z, const float w) +{ + r.x = a.x + x; + r.y = a.y + y; + r.z = a.z + z; + r.w = a.w + w; +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 AddVector4(const Vector4& a, const float x, const float y, const float z, const float w) +{ + Vector4 r; + r.x = a.x + x; + r.y = a.y + y; + r.z = a.z + z; + r.w = a.w + w; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void SubVector4(Vector4& r, const Vector4& a, const Vector4& b) +{ + r.x = a.x - b.x; + r.y = a.y - b.y; + r.z = a.z - b.z; + r.w = a.w - b.w; +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 SubVector4(const Vector4& a, const Vector4& b) +{ + Vector4 r; + r.x = a.x - b.x; + r.y = a.y - b.y; + r.z = a.z - b.z; + r.w = a.w - b.w; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void SubVector4(Vector4& r, const Vector4& a, const float x, const float y, const float z, const float w) +{ + r.x = a.x - x; + r.y = a.y - y; + r.z = a.z - z; + r.w = a.w - w; +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 SubVector4(const Vector4& a, const float x, const float y, const float z, const float w) +{ + Vector4 r; + r.x = a.x - x; + r.y = a.y - y; + r.z = a.z - z; + r.w = a.w - w; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void ScaleVector4(Vector4& r, const float s, const Vector4& v) +{ + r.x = s * v.x; + r.y = s * v.y; + r.z = s * v.z; + r.w = s * v.w; +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 ScaleVector4(const float s, const Vector4& v) +{ + Vector4 r; + r.x = s * v.x; + r.y = s * v.y; + r.z = s * v.z; + r.w = s * v.w; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void MulVector4(Vector4& r, const Vector4& a, const Vector4& b) +{ + r.x = a.x * b.x; + r.y = a.y * b.y; + r.z = a.z * b.z; + r.w = a.w * b.w; +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 MulVector4(const Vector4& a, const Vector4& b) +{ + Vector4 r; + r.x = a.x * b.x; + r.y = a.y * b.y; + r.z = a.z * b.z; + r.w = a.w * b.w; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void MulVector4(Vector4& r, const Vector4& a, const float x, const float y, const float z, const float w) +{ + r.x = a.x * x; + r.y = a.y * y; + r.z = a.z * z; + r.w = a.w * w; +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 MulVector4(const Vector4& a, const float x, const float y, const float z, const float w) +{ + Vector4 r; + r.x = a.x * x; + r.y = a.y * y; + r.z = a.z * z; + r.w = a.w * w; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void DivVector4(Vector4& r, const Vector4& a, const Vector4& b) +{ + r.x = a.x / b.x; + r.y = a.y / b.y; + r.z = a.z / b.z; + r.w = a.w / b.w; +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 DivVector4(const Vector4& a, const Vector4& b) +{ + Vector4 r; + r.x = a.x / b.x; + r.y = a.y / b.y; + r.z = a.z / b.z; + r.w = a.w / b.w; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void DivVector4(Vector4& r, const Vector4& a, const float x, const float y, const float z, const float w) +{ + r.x = a.x / x; + r.y = a.y / y; + r.z = a.z / z; + r.w = a.w / w; +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 DivVector4(const Vector4& a, const float x, const float y, const float z, const float w) +{ + Vector4 r; + r.x = a.x / x; + r.y = a.y / y; + r.z = a.z / z; + r.w = a.w / w; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void ScaleAddVector4(Vector4& r, const float s, const Vector4& v_scale, const Vector4& v_add) +{ + r.x = s * v_scale.x + v_add.x; + r.y = s * v_scale.y + v_add.y; + r.z = s * v_scale.z + v_add.z; + r.w = s * v_scale.w + v_add.w; +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 ScaleAddVector4(const float s, const Vector4& v_scale, const Vector4& v_add) +{ + Vector4 r; + r.x = s * v_scale.x + v_add.x; + r.y = s * v_scale.y + v_add.y; + r.z = s * v_scale.z + v_add.z; + r.w = s * v_scale.w + v_add.w; + return r; +} + +//---------------------------------------------------------------------------------------- +slInline void NormalizeVector4(Vector4& r, const Vector4& a) +{ + float scale = 1.0f / LengthOfVector4( a ); + ScaleVector4( r, scale, a ); +} + +//---------------------------------------------------------------------------------------- +slInline Vector4 NormalizeVector4(const Vector4& a) +{ + float scale = 1.0f / LengthOfVector4( a ); + return ScaleVector4( scale, a ); +} + +//---------------------------------------------------------------------------------------- +slInline float LengthOfVector4(const Vector4& a) +{ + return Sqrtf( DotVector4(a, a) ); +} + +//---------------------------------------------------------------------------------------- +slInline float LengthSquaredOfVector4(const Vector4& a) +{ + return DotVector4( a, a ); +} diff --git a/Classes/Foundation/Memory/MemoryBitset.cpp b/Classes/Foundation/Memory/MemoryBitset.cpp new file mode 100755 index 0000000..a9d4e19 --- /dev/null +++ b/Classes/Foundation/Memory/MemoryBitset.cpp @@ -0,0 +1,318 @@ +#include "MemoryBitset.h" + +//---------------------------------------------------------------------------------------- +int32_t MemoryBitset::FindLowestUnused(int32_t start_search_index) +{ + int32_t top_index = start_search_index / 4096; + uint64_t* top_pointer = m_TopBits + top_index; + int32_t top_offset = (start_search_index - top_index * 4096) / 64; + uint64_t first_top_mask = ~(0xffffffffffffffffULL << top_offset); + + // handling the starting case + if ((*top_pointer | first_top_mask) != 0xffffffffffffffffULL) + { + uint64_t valid_top_bits = (*top_pointer | first_top_mask); + uint64_t top_unused_bits = ~valid_top_bits; + uint64_t right_most_top_bit = RightMostEnabledBit(top_unused_bits); + int32_t bottom_index = top_index * 64 + 64 - LZCount(right_most_top_bit); + uint64_t bottom_bits = m_BottomBits[bottom_index]; + + if (start_search_index > bottom_index * 64) + { + // construct the mask for the valid bits + int32_t bottom_offset = start_search_index - bottom_index * 64; + uint64_t first_bottom_mask = ~(0xffffffffffffffffULL << bottom_offset); + bottom_bits |= first_bottom_mask; + } + + uint64_t bottom_unused_bits = ~bottom_bits; + uint64_t right_most_bottom_unused_bit = RightMostEnabledBit(bottom_unused_bits); + int32_t final_index = bottom_index * 64 + 64 - LZCount(right_most_bottom_unused_bit); + return final_index < m_MaxCount ? final_index : INVALID_INDEX; + } + + // guess the first dereference didn't get us anything + top_pointer++; + top_index++; + + // skip over all top bits that're fully allocated + while (*top_pointer == 0xffffffffffffffffULL && top_pointer <= m_MaxTopPointer) + { + top_pointer++; + top_index++; + } + + if (top_pointer > m_MaxTopPointer) + { + return INVALID_INDEX; + } + + uint64_t right_most_top_unused_bit = RightMostEnabledBit(~*top_pointer); + int32_t bottom_index = top_index * 64 + 64 - LZCount(right_most_top_unused_bit); + uint64_t* bottom_pointer = m_BottomBits + bottom_index; + int32_t bottom_offset = start_search_index - top_index * 4096; + uint64_t first_bottom_mask = ~(0xffffffffffffffffULL << bottom_offset); + + // skip over all bottom bits that're fully allocated + while (*bottom_pointer == 0xffffffffffffffffULL && bottom_pointer <= m_MaxBottomPointer) + { + bottom_pointer++; + bottom_index++; + } + + // make sure we didn't overflow + if (bottom_pointer > m_MaxBottomPointer) + { + return INVALID_INDEX; + } + + uint64_t right_most_bottom_unused_bit = RightMostEnabledBit(~*bottom_pointer); + int32_t final_index = bottom_index * 64 + 64 - LZCount(right_most_bottom_unused_bit); + + // make sure we didn't overflow + if (final_index >= m_MaxCount) + { + return INVALID_INDEX; + } + + return final_index; +} + +//---------------------------------------------------------------------------------------- +int32_t MemoryBitset::FindLowestUnused() +{ + int32_t top_index = 0; + uint64_t* top_pointer = m_TopBits; + + // skip over all top bits that're fully allocated + while (*top_pointer == 0xffffffffffffffffULL && top_pointer <= m_MaxTopPointer) + { + top_pointer++; + top_index++; + } + + uint64_t right_most_top_unused_bit = RightMostEnabledBit(~*top_pointer); + int32_t bottom_index = top_index * 64 + 64 - LZCount(right_most_top_unused_bit); + uint64_t* bottom_pointer = m_BottomBits + bottom_index; + + // skip over all bottom bits that're fully allocated + while (*bottom_pointer == 0xffffffffffffffffULL && bottom_pointer <= m_MaxBottomPointer) + { + bottom_pointer++; + bottom_index++; + } + + uint64_t right_most_bottom_unused_bit = RightMostEnabledBit(~*bottom_pointer); + int32_t final_index = bottom_index * 64 + 64 - LZCount(right_most_bottom_unused_bit); + + return final_index; +} + +//---------------------------------------------------------------------------------------- +int32_t MemoryBitset::FindHighestInUse(int32_t start_search_index) +{ + if (start_search_index < 0 || start_search_index >= m_MaxCount) + { + return INVALID_INDEX; + } + + int32_t bottom_index = start_search_index / 64; + uint64_t* bottom_pointer = m_BottomBits + bottom_index; + int32_t bottom_offset = start_search_index - bottom_index * 64; + uint64_t bottom_used_bits = *bottom_pointer & (0x1ULL << bottom_offset); + + while (bottom_used_bits == 0ULL && bottom_pointer >= m_BottomBits) + { + bottom_index--; + bottom_pointer--; + bottom_used_bits = *bottom_pointer; + } + + if (bottom_pointer < m_BottomBits) + { + return INVALID_INDEX; + } + + return bottom_index * 64 + 63 - LZCount(RightMostEnabledBit(*bottom_pointer)); +} + +//---------------------------------------------------------------------------------------- +int32_t MemoryBitset::FindHighestInUse() +{ + int32_t bottom_index = m_MaxCount / 64; + uint64_t* bottom_pointer = m_BottomBits + bottom_index; + int32_t bottom_offset = m_MaxCount - bottom_index * 64; + uint64_t bottom_used_bits = *bottom_pointer & (0x1ULL << bottom_offset); + + while (bottom_used_bits == 0ULL && bottom_pointer >= m_BottomBits) + { + bottom_index--; + bottom_pointer--; + bottom_used_bits = *bottom_pointer; + } + + if (bottom_pointer < m_BottomBits) + { + return INVALID_INDEX; + } + + return bottom_index * 64 + 63 - LZCount(RightMostEnabledBit(*bottom_pointer)); +} + +//---------------------------------------------------------------------------------------- +void MemoryBitset::GetSizesNeeded(uint32_t& top_size, uint32_t& bottom_size, int32_t entry_count) +{ + Assert(entry_count > 0); + + uint32_t aligned_4096_count = ALIGN_UP(entry_count, 4096); + top_size = aligned_4096_count / 512; + + uint32_t aligned_64_count = ALIGN_UP(entry_count, 64); + bottom_size = aligned_64_count / 8; +} + +//---------------------------------------------------------------------------------------- +bool MemoryBitset::Init(uint64_t* top_bits, uint64_t* bottom_bits, int32_t entry_count) +{ + Assert(entry_count > 0); + + m_TopBits = top_bits; + m_BottomBits = bottom_bits; + m_MaxCount = entry_count; + m_MaxTopPointer = m_TopBits + ALIGN_UP(m_MaxCount, 4096) / 4096; + m_MaxBottomPointer = m_BottomBits + ALIGN_UP(m_MaxCount, 64) / 64; + m_IndicesInUse = 0; + m_LowestUnused = 0; + m_HighestInUse = INVALID_INDEX; + + memset(m_BottomBits, 0, ALIGN_UP(m_MaxCount, 64) / 8); + memset(m_TopBits, 0, ALIGN_UP(m_MaxCount, 4096) / 512); + + return true; +} + +//---------------------------------------------------------------------------------------- +void MemoryBitset::Reset() +{ + m_IndicesInUse = 0; + m_LowestUnused = 0; + m_HighestInUse = -1; + + memset(m_BottomBits, 0, ALIGN_UP(m_MaxCount, 64) / 8); + memset(m_TopBits, 0, ALIGN_UP(m_MaxCount, 4096) / 512); +} + +//---------------------------------------------------------------------------------------- +void MemoryBitset::Destroy() +{ + m_TopBits = NULL; + m_BottomBits = NULL; + m_MaxTopPointer = NULL; + m_MaxBottomPointer = NULL; + m_MaxCount = 0; + m_IndicesInUse = 0; + m_LowestUnused = 0; + m_HighestInUse = -1; +} + +//---------------------------------------------------------------------------------------- +int32_t MemoryBitset::AllocateIndex() +{ + if (m_IndicesInUse == m_MaxCount) + { + return -1; + } + + int32_t return_index = m_LowestUnused; + + int32_t bottom_index = m_LowestUnused / 64; + int32_t bottom_offset = m_LowestUnused - bottom_index; + m_BottomBits[bottom_index] |= (0x1ULL << bottom_offset); + + if (m_BottomBits[bottom_index] = 0xffffffffffffffffULL) + { + int32_t top_index = m_LowestUnused / 4096; + int32_t top_offset = m_LowestUnused - top_index; + m_TopBits[top_index] |= (0x1ULL << top_offset); + } + + if ((uint32_t)(m_HighestInUse + 1) == m_IndicesInUse) + { + m_HighestInUse++; + m_LowestUnused++; + m_IndicesInUse++; + } + else + { + m_IndicesInUse++; + m_LowestUnused = m_IndicesInUse == m_MaxCount ? m_MaxCount : FindLowestUnused(m_LowestUnused); + } + + return return_index; +} + +//---------------------------------------------------------------------------------------- +bool MemoryBitset::AllocateSpecificIndex(int32_t index) +{ + uint32_t bottom_index = index / 64; + uint32_t bottom_offset = index - bottom_index; + uint64_t bottom_mask = (0x1ULL << bottom_offset); + + if (m_IndicesInUse == m_MaxCount || index >= m_MaxCount || (m_BottomBits[bottom_index] & bottom_mask)) + { + return false; + } + + m_BottomBits[bottom_index] |= bottom_mask; + + if (m_BottomBits[bottom_index] == 0xffffffffffffffffULL) + { + uint32_t top_index = index / 4096; + uint32_t top_offset = index - top_index; + uint64_t top_mask = (0x1ULL << top_offset); + m_TopBits[top_index] |= top_mask; + } + + m_IndicesInUse++; + + if (index > m_HighestInUse) + { + m_HighestInUse = index; + } + + if (index == m_LowestUnused) + { + m_LowestUnused = (m_IndicesInUse == m_MaxCount) ? m_MaxCount : FindLowestUnused(m_LowestUnused + 1); + } + + return true; +} + +//---------------------------------------------------------------------------------------- +void MemoryBitset::FreeIndex(int32_t index) +{ + uint32_t bottom_index = index / 64; + uint32_t bottom_offset = index - bottom_index; + uint64_t bottom_mask = (0x1ULL << bottom_offset); + + if (m_IndicesInUse == 0 || index >= m_MaxCount || !(m_BottomBits[bottom_index] & bottom_mask)) + { + return; + } + + if (m_BottomBits[bottom_index] == 0xffffffffffffffffULL) + { + uint32_t top_index = index / 4096; + uint32_t top_offset = index - top_index; + uint64_t top_mask = (0x1ULL << top_offset); + m_TopBits[top_index] &= ~top_mask; + } + + m_BottomBits[bottom_index] &= ~bottom_mask; + m_IndicesInUse--; + m_LowestUnused = index < m_LowestUnused ? index : m_LowestUnused; + if (m_HighestInUse == index) + { + m_HighestInUse = FindHighestInUse(index - 1); + } +} diff --git a/Classes/Foundation/Memory/MemoryBitset.h b/Classes/Foundation/Memory/MemoryBitset.h new file mode 100755 index 0000000..1e929f7 --- /dev/null +++ b/Classes/Foundation/Memory/MemoryBitset.h @@ -0,0 +1,49 @@ +#pragma once + +#include "Foundation/Common/GlobalInclude.h" + +//---------------------------------------------------------------------------------------- +class MemoryBitset +{ +private: + uint64_t* m_TopBits; + uint64_t* m_BottomBits; + + uint64_t* m_MaxTopPointer; + uint64_t* m_MaxBottomPointer; + + int32_t m_MaxCount; + int32_t m_IndicesInUse; + int32_t m_LowestUnused; + int32_t m_HighestInUse; + + int32_t FindLowestUnused(int32_t start_search_index); // finds upwards to m_MaxCount + int32_t FindLowestUnused(); // finds upwards to m_MaxCount + int32_t FindHighestInUse(int32_t start_search_index); // finds downwards to 0 + int32_t FindHighestInUse(); // finds downwards to 0 + +public: + static const int32_t INVALID_INDEX = -1; + + static void GetSizesNeeded(uint32_t& top_size, uint32_t& bottom_size, int32_t entry_count); + + bool Init(uint64_t* top_bits, uint64_t* bottom_bits, int32_t entry_count); + void Reset(); + void Destroy(); + + int32_t AllocateIndex(); + bool AllocateSpecificIndex(int32_t index); + void FreeIndex(int32_t index); + + bool IsIndexAllocated(int32_t index); + int32_t GetAllocatedCount() {return m_IndicesInUse;} + int32_t GetHighestIndexInUse() {return m_HighestInUse;} +}; + +//---------------------------------------------------------------------------------------- +inline bool MemoryBitset::IsIndexAllocated(int32_t index) +{ + uint32_t bottom_index = index / 64; + uint32_t bottom_offset = index - bottom_index; + return (m_BottomBits[bottom_index] & (0x1ULL << bottom_offset)) > 0; +} diff --git a/Classes/Foundation/Memory/MemoryHeap.cpp b/Classes/Foundation/Memory/MemoryHeap.cpp new file mode 100755 index 0000000..8a8d2fd --- /dev/null +++ b/Classes/Foundation/Memory/MemoryHeap.cpp @@ -0,0 +1,32 @@ +#include "MemoryHeap.h" + +//---------------------------------------------------------------------------------------- +bool MemoryHeap::Init(void* base, size_t size) +{ + if (size <= sizeof(FreeRecordInPage)) + { + return false; + } + + uint64_t base_address = ALIGN_UP( (uint64_t)base, sizeof(FreeRecordInPage) ); + m_Base = (uint8_t*)base_address; + m_Size = size; + + return true; +} + +//---------------------------------------------------------------------------------------- +void MemoryHeap::Destroy() +{ +} + +//---------------------------------------------------------------------------------------- +void* MemoryHeap::Allocate(uint32_t size, uint32_t alignment) +{ + return NULL; +} + +//---------------------------------------------------------------------------------------- +void MemoryHeap::Free(void* address) +{ +} diff --git a/Classes/Foundation/Memory/MemoryHeap.h b/Classes/Foundation/Memory/MemoryHeap.h new file mode 100755 index 0000000..12ad656 --- /dev/null +++ b/Classes/Foundation/Memory/MemoryHeap.h @@ -0,0 +1,37 @@ +#pragma once + +#include "Foundation/Common/GlobalInclude.h" + +class MemoryHeap +{ +private: + class MemoryBlock + { + static const uint32_t s_Sentinel = 0xdeadbeef; + + uint32_t m_BlockSize; + }; + +#if defined(__WINDOWS__) + static const uint32_t s_PageSize = 4096; +#else +#error NEED TO SPECIFY THIS! +#endif + + struct FreeRecordInPage + { + uint32_t m_FreeBlockSize; + uint32_t m_NextFreeOffset; + }; + + size_t m_Size; + uint8_t* m_Base; + + uint32_t m_PageCount; + + bool Init(void* base, size_t size); + void Destroy(); + + void* Allocate(uint32_t size, uint32_t alignment); + void Free(void* address); +}; diff --git a/Classes/Foundation/Memory/MemoryLinear.h b/Classes/Foundation/Memory/MemoryLinear.h new file mode 100755 index 0000000..5b6cc09 --- /dev/null +++ b/Classes/Foundation/Memory/MemoryLinear.h @@ -0,0 +1,110 @@ +#pragma once + +#include "Foundation/Common/GlobalInclude.h" +#include "MemoryHeap.h" + +//---------------------------------------------------------------------------------------- +class MemoryLinear +{ +private: + MemoryHeap* m_Heap; + uint8_t* m_Base; + uint32_t m_Size; + uint32_t m_Offset; + uint32_t m_OffsetTop; + +public: + bool Init(MemoryHeap* heap, uint32_t size, uint32_t alignment = 1); + void Destroy(); + + void* Allocate(uint32_t size, uint32_t alignment = 1); + void* AllocateTop(uint32_t size, uint32_t alignment = 1); + + uint32_t GetCurrentOffset(); + void RollBackOffset(uint32_t offset); + + uint32_t GetCurrentOffsetTop(); + void RollBackOffsetTop(uint32_t offset); + + void Reset(); +}; + +//---------------------------------------------------------------------------------------- +slInline bool MemoryLinear::Init(MemoryHeap* heap, uint32_t size, uint32_t alignment = 1) +{ + m_Heap = heap; + m_Base = (uint8_t*)m_Heap->Allocate(size, "MemoryLinear", alignment); + m_Size = size; + m_Offset = 0; + m_OffsetTop = 0; +} + +//---------------------------------------------------------------------------------------- +slInline void MemoryLinear::Destroy() +{ + m_Heap->Free(m_Base); + m_Heap = NULL; + m_Base = NULL; + m_Size = 0; + m_Offset = 0; + m_OffsetTop = 0; +} + +//---------------------------------------------------------------------------------------- +slInline void* MemoryLinear::Allocate(uint32_t size, uint32_t alignment) +{ + int64_t aligned_address = ALIGN_UP((int64_t)m_Base + m_Offset, alignment); + if (aligned_address + size > (int64_t)m_Base + m_Size - m_OffsetTop) + { + return NULL; + } + + m_Offset = aligned_address - (int64_t)m_Base; + return (void*)aligned_address; +} + +//---------------------------------------------------------------------------------------- +slInline void* MemoryLinear::AllocateTop(uint32_t size, uint32_t alignment) +{ + int64_t aligned_address = ALIGN_DOWN((int64_t)m_Base + m_Size - m_OffsetTop - size, alignment); + if (aligned_address < (int64_t)m_Base + m_Offset) + { + return NULL; + } + + m_OffsetTop = (int64_t)m_Base + m_Size - aligned_address); + return (void*)aligned_address; +} + +//---------------------------------------------------------------------------------------- +slInline uint32_t MemoryLinear::GetCurrentOffset() +{ + return m_Offset; +} + +//---------------------------------------------------------------------------------------- +slInline void MemoryLinear::RollBackOffset(uint32_t offset) +{ + Assert(offset <= m_Offset); + m_Offset = offset; +} + +//---------------------------------------------------------------------------------------- +slInline uint32_t MemoryLinear::GetCurrentOffsetTop() +{ + return m_OffsetTop; +} + +//---------------------------------------------------------------------------------------- +slInline void MemoryLinear::RollBackOffsetTop(uint32_t offset_top) +{ + Assert(offset_top >= m_OffsetTop); + m_OffsetTop = offset_top; +} + +//---------------------------------------------------------------------------------------- +slInline void MemoryLinear::Reset() +{ + m_Offset = 0; + m_OffsetTop = 0; +} diff --git a/Classes/Foundation/Synchronization/Atomic32Bit.h b/Classes/Foundation/Synchronization/Atomic32Bit.h new file mode 100755 index 0000000..2290a2c --- /dev/null +++ b/Classes/Foundation/Synchronization/Atomic32Bit.h @@ -0,0 +1,99 @@ +#pragma once + +#include "Foundation/Common/GlobalInclude.h" + +#if defined(__WINDOWS__) + +#include + +#pragma intrinsic(InterlockedIncrement) +#pragma intrinsic(InterlockedDecrement) +#pragma intrinsic(InterlockedExchange) +#pragma intrinsic(InterlockedExchangeAdd) +#pragma intrinsic(InterlockedExchangeSubtract) +#pragma intrinsic(InterlockedCompareExchange) +#pragma intrinsic(InterlockedAnd) +#pragma intrinsic(InterlockedOr) +#pragma intrinsic(InterlockedXor) + +class Atomic32Bit +{ +private: + __declspec(align(16)) uint32_t m_LockValue; + +public: + Atomic32Bit() + { + m_LockValue = 0; + } + + ~Atomic32Bit() + { + m_LockValue = 0; + } + + // use intrinsics instead since they r automatically defined for x64 and x86 structs + uint32_t Increment(const uint32_t lock_value) //returns current value + { + return InterlockedIncrement(&m_LockValue); + + /* + volatile unsigned int* p_temp = &m_Locker; + __asm + { + mov eax, 1 + mov edx, [p_temp] + lock xadd [edx],eax + } + */ + } + + uint32_t SetValue(const uint32_t value) + { + return InterlockedExchange(&m_LockValue, value); + + /* + volatile unsigned int* p_temp = &m_Locker; + __asm + { + mov eax, Value + mov edx, [p_temp] + lock xchg [edx],eax + } + */ + } + + uint32_t Decrement(const uint32_t lock_value) //returns current value + { + return InterlockedDecrement(&m_LockValue); + + /* + volatile unsigned int* p_temp = &m_Locker; + __asm + { + mov eax, -1 + mov edx, [p_temp] + lock xadd [edx],eax + } + */ + } + + void And(uint32_t& lock_value) + { + InterlockedAnd(&m_LockValue, lock_value); + lock_value = m_LockValue; + } + + // this function can be inlined as long as the volatile is here + slInline uint32_t GetValue() + { + volatile uint32_t* p_temp = &m_LockValue; + return (unsigned int)*p_temp; + } +}; + +#else + +#error Not yet implemented! + +#endif diff --git a/Classes/Foundation/Synchronization/MemorySync.h b/Classes/Foundation/Synchr