Add new mat4 functions and some external testing
This commit is contained in:
		
							parent
							
								
									fceac54ecb
								
							
						
					
					
						commit
						65ee7bab4b
					
				
							
								
								
									
										275
									
								
								dqn.h
									
									
									
									
									
								
							
							
						
						
									
										275
									
								
								dqn.h
									
									
									
									
									
								
							| @ -96,24 +96,18 @@ DQN_FILE_SCOPE void  DqnMem_Free   (void *memory); | |||||||
| //      BeginTempRegion and EndTempRegion functions. Specifically freeing
 | //      BeginTempRegion and EndTempRegion functions. Specifically freeing
 | ||||||
| //      individual items is typically not generalisable in this scheme.
 | //      individual items is typically not generalisable in this scheme.
 | ||||||
| 
 | 
 | ||||||
| typedef struct DqnMemStackBlock |  | ||||||
| { |  | ||||||
| 	u8     *memory; |  | ||||||
| 	size_t  used; |  | ||||||
| 	size_t  size; |  | ||||||
| 
 |  | ||||||
| 	DqnMemStackBlock *prevBlock; |  | ||||||
| } DqnMemStackBlock; |  | ||||||
| 
 |  | ||||||
| enum DqnMemStackFlag | enum DqnMemStackFlag | ||||||
| { | { | ||||||
| 	DqnMemStackFlag_IsNotExpandable       = (1 << 0), | 	DqnMemStackFlag_IsNotExpandable       = (1 << 0), | ||||||
| 	DqnMemStackFlag_IsFixedMemoryFromUser = (1 << 1), // NOTE(doyle): Required to indicate we CAN'T free this memory when free is called.
 | 	DqnMemStackFlag_IsFixedMemoryFromUser = (1 << 1), // NOTE(doyle): Required to indicate we CAN'T free this memory when free is called.
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
|  | // Advanced API Structs
 | ||||||
|  | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
| typedef struct DqnMemStack | typedef struct DqnMemStack | ||||||
| { | { | ||||||
| 	DqnMemStackBlock *block; | 	struct DqnMemStackBlock *block; | ||||||
| 
 | 
 | ||||||
| 	u32 flags; | 	u32 flags; | ||||||
| 	i32 tempStackCount; | 	i32 tempStackCount; | ||||||
| @ -122,8 +116,8 @@ typedef struct DqnMemStack | |||||||
| 
 | 
 | ||||||
| typedef struct DqnTempMemStack | typedef struct DqnTempMemStack | ||||||
| { | { | ||||||
| 	DqnMemStack      *stack; | 	DqnMemStack             *stack; | ||||||
| 	DqnMemStackBlock *startingBlock; | 	struct DqnMemStackBlock *startingBlock; | ||||||
| 	size_t used; | 	size_t used; | ||||||
| 
 | 
 | ||||||
| } DqnTempMemStack; | } DqnTempMemStack; | ||||||
| @ -132,12 +126,12 @@ DQN_FILE_SCOPE bool DqnMemStack_InitWithFixedMem (DqnMemStack *const stack, u8 * | |||||||
| DQN_FILE_SCOPE bool DqnMemStack_InitWithFixedSize(DqnMemStack *const stack, size_t size, const bool zeroClear, const u32 byteAlign = 4); // Single allocation from platform, no further allocations, returns NULL of allocate if out of space
 | DQN_FILE_SCOPE bool DqnMemStack_InitWithFixedSize(DqnMemStack *const stack, size_t size, const bool zeroClear, const u32 byteAlign = 4); // Single allocation from platform, no further allocations, returns NULL of allocate if out of space
 | ||||||
| DQN_FILE_SCOPE bool DqnMemStack_Init             (DqnMemStack *const stack, size_t size, const bool zeroClear, const u32 byteAlign = 4); // Allocates from platform dynamically as space runs out
 | DQN_FILE_SCOPE bool DqnMemStack_Init             (DqnMemStack *const stack, size_t size, const bool zeroClear, const u32 byteAlign = 4); // Allocates from platform dynamically as space runs out
 | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE void *DqnMemStack_Push          (DqnMemStack *const stack, size_t size);             // Returns NULL if out of space and stack is using fixed memory/size, or platform allocation fails
 | DQN_FILE_SCOPE void *DqnMemStack_Push          (DqnMemStack *const stack, size_t size);             // Returns NULL if out of space and stack is using fixed memory/size, or platform allocation fails.
 | ||||||
| DQN_FILE_SCOPE bool  DqnMemStack_Pop           (DqnMemStack *const stack, void *ptr, size_t size);  // Frees the given ptr. It MUST be the last allocated item in the stack
 | DQN_FILE_SCOPE bool  DqnMemStack_Pop           (DqnMemStack *const stack, void *ptr, size_t size);  // Frees the given ptr. It MUST be the last allocated item in the stack.
 | ||||||
| DQN_FILE_SCOPE void  DqnMemStack_Free          (DqnMemStack *const stack);                          // Frees all blocks belonging to this stack
 | DQN_FILE_SCOPE void  DqnMemStack_Free          (DqnMemStack *const stack);                          // Frees all blocks belonging to this stack.
 | ||||||
| DQN_FILE_SCOPE bool  DqnMemStack_FreeStackBlock(DqnMemStack *const stack, DqnMemStackBlock *block); // Frees the specified block, returns false if block doesn't belong
 | DQN_FILE_SCOPE bool  DqnMemStack_FreeStackBlock(DqnMemStack *const stack, DqnMemStackBlock *block); // Frees the specified block, returns false if block doesn't belong, calls DqnMem_Free().
 | ||||||
| DQN_FILE_SCOPE bool  DqnMemStack_FreeLastBlock (DqnMemStack *const stack);                          // Frees the last-most memory block. If last block, free that block, next allocate will attach a block.
 | DQN_FILE_SCOPE bool  DqnMemStack_FreeLastBlock (DqnMemStack *const stack);                          // Frees the last-most memory block. If last block, free that block, next allocate will attach a block.
 | ||||||
| DQN_FILE_SCOPE void  DqnMemStack_ClearCurrBlock(DqnMemStack *const stack, const bool zeroClear);    // Reset the current memory block usage to 0
 | DQN_FILE_SCOPE void  DqnMemStack_ClearCurrBlock(DqnMemStack *const stack, const bool zeroClear);    // Reset the current memory block usage to 0.
 | ||||||
| 
 | 
 | ||||||
| // TempMemStack is only required for the function. Once BeginTempRegion() is called, subsequent allocation calls can be made using the original stack.
 | // TempMemStack is only required for the function. Once BeginTempRegion() is called, subsequent allocation calls can be made using the original stack.
 | ||||||
| // Upon EndTempRegion() the original stack will free any additional blocks it allocated during the temp region and revert to the original
 | // Upon EndTempRegion() the original stack will free any additional blocks it allocated during the temp region and revert to the original
 | ||||||
| @ -147,12 +141,26 @@ DQN_FILE_SCOPE void  DqnMemStack_ClearCurrBlock(DqnMemStack *const stack, const | |||||||
| DQN_FILE_SCOPE DqnTempMemStack DqnMemStack_BeginTempRegion(DqnMemStack *const stack); | DQN_FILE_SCOPE DqnTempMemStack DqnMemStack_BeginTempRegion(DqnMemStack *const stack); | ||||||
| DQN_FILE_SCOPE void            DqnMemStack_EndTempRegion  (DqnTempMemStack tempstack); | DQN_FILE_SCOPE void            DqnMemStack_EndTempRegion  (DqnTempMemStack tempstack); | ||||||
| 
 | 
 | ||||||
|  | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
| // (OPTIONAL) DqnMemStack Advanced API
 | // (OPTIONAL) DqnMemStack Advanced API
 | ||||||
|  | // Blocks are freely modifiable if you want fine grained control. Size value and
 | ||||||
|  | // memory ptr should _NOT_ be modified directly, only indirectly through the
 | ||||||
|  | // regular API.
 | ||||||
|  | typedef struct DqnMemStackBlock | ||||||
|  | { | ||||||
|  | 	u8     *memory; | ||||||
|  | 	size_t  size; | ||||||
|  | 	size_t  used; | ||||||
|  | 
 | ||||||
|  | 	DqnMemStackBlock *prevBlock; | ||||||
|  | } DqnMemStackBlock; | ||||||
|  | 
 | ||||||
| // This is useful for forcing a new block to be used. AllocateCompatibleBlock
 | // This is useful for forcing a new block to be used. AllocateCompatibleBlock
 | ||||||
| // will fail if the supplied stack has flags set such that the stack is not
 | // will fail if the supplied stack has flags set such that the stack is not
 | ||||||
| // allowed to have new blocks.
 | // allowed to have new blocks.
 | ||||||
| DQN_FILE_SCOPE DqnMemStackBlock *DqnMemStack_AllocateCompatibleBlock(const DqnMemStack *const stack, size_t size); | DQN_FILE_SCOPE DqnMemStackBlock *DqnMemStack_AllocateCompatibleBlock(const DqnMemStack *const stack, size_t size); | ||||||
| DQN_FILE_SCOPE bool              DqnMemStack_AttachBlock            (DqnMemStack *const stack, DqnMemStackBlock *const newBlock); | DQN_FILE_SCOPE bool              DqnMemStack_AttachBlock            (DqnMemStack *const stack, DqnMemStackBlock *const newBlock); | ||||||
|  | DQN_FILE_SCOPE bool              DqnMemStack_DetachBlock            (DqnMemStack *const stack, DqnMemStackBlock *const detachBlock); | ||||||
| 
 | 
 | ||||||
| // (IMPORTANT) Should only be used to free blocks that haven't been attached!
 | // (IMPORTANT) Should only be used to free blocks that haven't been attached!
 | ||||||
| // Attached blocks should be freed using FreeStackBlock().
 | // Attached blocks should be freed using FreeStackBlock().
 | ||||||
| @ -521,8 +529,9 @@ typedef union DqnV3i | |||||||
| } DqnV3i; | } DqnV3i; | ||||||
| 
 | 
 | ||||||
| // DqnV3
 | // DqnV3
 | ||||||
| DQN_FILE_SCOPE DqnV3 DqnV3_3i(i32 x, i32 y, i32 z); // Create a vector using ints and typecast to floats
 | DQN_FILE_SCOPE DqnV3 DqnV3_1f(f32 xyz); | ||||||
| DQN_FILE_SCOPE DqnV3 DqnV3_3f(f32 x, f32 y, f32 z); | DQN_FILE_SCOPE DqnV3 DqnV3_3f(f32 x, f32 y, f32 z); | ||||||
|  | DQN_FILE_SCOPE DqnV3 DqnV3_3i(i32 x, i32 y, i32 z); // Create a vector using ints and typecast to floats
 | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE DqnV3 DqnV3_Add     (DqnV3 a, DqnV3 b); | DQN_FILE_SCOPE DqnV3 DqnV3_Add     (DqnV3 a, DqnV3 b); | ||||||
| DQN_FILE_SCOPE DqnV3 DqnV3_Sub     (DqnV3 a, DqnV3 b); | DQN_FILE_SCOPE DqnV3 DqnV3_Sub     (DqnV3 a, DqnV3 b); | ||||||
| @ -533,19 +542,23 @@ DQN_FILE_SCOPE f32   DqnV3_Dot     (DqnV3 a, DqnV3 b); | |||||||
| DQN_FILE_SCOPE bool  DqnV3_Equals  (DqnV3 a, DqnV3 b); | DQN_FILE_SCOPE bool  DqnV3_Equals  (DqnV3 a, DqnV3 b); | ||||||
| DQN_FILE_SCOPE DqnV3 DqnV3_Cross   (DqnV3 a, DqnV3 b); | DQN_FILE_SCOPE DqnV3 DqnV3_Cross   (DqnV3 a, DqnV3 b); | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE DqnV3 DqnV3_Normalise(DqnV3 a); | DQN_FILE_SCOPE DqnV3 DqnV3_Normalise    (DqnV3 a); | ||||||
|  | DQN_FILE_SCOPE f32   DqnV3_Length       (DqnV3 a, DqnV3 b); | ||||||
|  | DQN_FILE_SCOPE f32   DqnV3_LengthSquared(DqnV3 a, DqnV3 b); | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE inline DqnV3  operator- (DqnV3  a, DqnV3 b) { return      DqnV3_Sub     (a, b);  } | DQN_FILE_SCOPE inline DqnV3  operator- (DqnV3  a, DqnV3 b) { return      DqnV3_Sub     (a, b);           } | ||||||
| DQN_FILE_SCOPE inline DqnV3  operator+ (DqnV3  a, DqnV3 b) { return      DqnV3_Add     (a, b);  } | DQN_FILE_SCOPE inline DqnV3  operator+ (DqnV3  a, DqnV3 b) { return      DqnV3_Add     (a, b);           } | ||||||
| DQN_FILE_SCOPE inline DqnV3  operator* (DqnV3  a, DqnV3 b) { return      DqnV3_Hadamard(a, b);  } | DQN_FILE_SCOPE inline DqnV3  operator+ (DqnV3  a, f32   b) { return      DqnV3_Add     (a, DqnV3_1f(b)); } | ||||||
| DQN_FILE_SCOPE inline DqnV3  operator* (DqnV3  a, f32   b) { return      DqnV3_Scalef  (a, b);  } | DQN_FILE_SCOPE inline DqnV3  operator* (DqnV3  a, DqnV3 b) { return      DqnV3_Hadamard(a, b);           } | ||||||
| DQN_FILE_SCOPE inline DqnV3  operator* (DqnV3  a, i32   b) { return      DqnV3_Scalei  (a, b);  } | DQN_FILE_SCOPE inline DqnV3  operator* (DqnV3  a, f32   b) { return      DqnV3_Scalef  (a, b);           } | ||||||
| DQN_FILE_SCOPE inline DqnV3 &operator*=(DqnV3 &a, DqnV3 b) { return (a = DqnV3_Hadamard(a, b)); } | DQN_FILE_SCOPE inline DqnV3  operator* (DqnV3  a, i32   b) { return      DqnV3_Scalei  (a, b);           } | ||||||
| DQN_FILE_SCOPE inline DqnV3 &operator*=(DqnV3 &a, f32   b) { return (a = DqnV3_Scalef  (a, b)); } | DQN_FILE_SCOPE inline DqnV3  operator/ (DqnV3  a, f32   b) { return      DqnV3_Scalef  (a, (1.0f/b));    } | ||||||
| DQN_FILE_SCOPE inline DqnV3 &operator*=(DqnV3 &a, i32   b) { return (a = DqnV3_Scalei  (a, b)); } | DQN_FILE_SCOPE inline DqnV3 &operator*=(DqnV3 &a, DqnV3 b) { return (a = DqnV3_Hadamard(a, b));          } | ||||||
| DQN_FILE_SCOPE inline DqnV3 &operator-=(DqnV3 &a, DqnV3 b) { return (a = DqnV3_Sub     (a, b)); } | DQN_FILE_SCOPE inline DqnV3 &operator*=(DqnV3 &a, f32   b) { return (a = DqnV3_Scalef  (a, b));          } | ||||||
| DQN_FILE_SCOPE inline DqnV3 &operator+=(DqnV3 &a, DqnV3 b) { return (a = DqnV3_Add     (a, b)); } | DQN_FILE_SCOPE inline DqnV3 &operator*=(DqnV3 &a, i32   b) { return (a = DqnV3_Scalei  (a, b));          } | ||||||
| DQN_FILE_SCOPE inline bool   operator==(DqnV3  a, DqnV3 b) { return      DqnV3_Equals  (a, b);  } | DQN_FILE_SCOPE inline DqnV3 &operator-=(DqnV3 &a, DqnV3 b) { return (a = DqnV3_Sub     (a, b));          } | ||||||
|  | DQN_FILE_SCOPE inline DqnV3 &operator+=(DqnV3 &a, DqnV3 b) { return (a = DqnV3_Add     (a, b));          } | ||||||
|  | DQN_FILE_SCOPE inline bool   operator==(DqnV3  a, DqnV3 b) { return      DqnV3_Equals  (a, b);           } | ||||||
| 
 | 
 | ||||||
| // DqnV3i
 | // DqnV3i
 | ||||||
| DQN_FILE_SCOPE DqnV3i DqnV3i_3i(i32 x, i32 y, i32 z); | DQN_FILE_SCOPE DqnV3i DqnV3i_3i(i32 x, i32 y, i32 z); | ||||||
| @ -572,6 +585,7 @@ typedef union DqnV4 { | |||||||
| // Create a vector using ints and typecast to floats
 | // Create a vector using ints and typecast to floats
 | ||||||
| DQN_FILE_SCOPE DqnV4 DqnV4_4i(i32 x, i32 y, i32 z, f32 w); | DQN_FILE_SCOPE DqnV4 DqnV4_4i(i32 x, i32 y, i32 z, f32 w); | ||||||
| DQN_FILE_SCOPE DqnV4 DqnV4_4f(f32 x, f32 y, f32 z, f32 w); | DQN_FILE_SCOPE DqnV4 DqnV4_4f(f32 x, f32 y, f32 z, f32 w); | ||||||
|  | DQN_FILE_SCOPE DqnV4 DqnV4_V3(DqnV3 a, f32 w); | ||||||
| DQN_FILE_SCOPE DqnV4 DqnV4_1f(f32 xyzw); | DQN_FILE_SCOPE DqnV4 DqnV4_1f(f32 xyzw); | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE DqnV4 DqnV4_Add     (DqnV4 a, DqnV4 b); | DQN_FILE_SCOPE DqnV4 DqnV4_Add     (DqnV4 a, DqnV4 b); | ||||||
| @ -600,18 +614,23 @@ DQN_FILE_SCOPE inline bool   operator==(DqnV4  a, DqnV4 b) { return      DqnV4_E | |||||||
| ////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
| typedef union DqnMat4 | typedef union DqnMat4 | ||||||
| { | { | ||||||
|  | 	// TODO(doyle): Row/column instead? More cache friendly since multiplication
 | ||||||
|  | 	// prefers rows.
 | ||||||
| 	DqnV4 col[4]; | 	DqnV4 col[4]; | ||||||
| 	// Column/row
 | 	f32   e[4][4]; // Column/row
 | ||||||
| 	f32 e[4][4]; |  | ||||||
| } DqnMat4; | } DqnMat4; | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE DqnMat4 DqnMat4_Identity (); | DQN_FILE_SCOPE DqnMat4 DqnMat4_Identity    (); | ||||||
| DQN_FILE_SCOPE DqnMat4 DqnMat4_Ortho    (f32 left, f32 right, f32 bottom, f32 top, f32 zNear, f32 zFar); | 
 | ||||||
| DQN_FILE_SCOPE DqnMat4 DqnMat4_Translate(f32 x, f32 y, f32 z); | DQN_FILE_SCOPE DqnMat4 DqnMat4_Orthographic(f32 left, f32 right, f32 bottom, f32 top, f32 zNear, f32 zFar); | ||||||
| DQN_FILE_SCOPE DqnMat4 DqnMat4_Rotate   (f32 radians, f32 x, f32 y, f32 z); | DQN_FILE_SCOPE DqnMat4 DqnMat4_Perspective (f32 fovYDegrees, f32 aspectRatio, f32 zNear, f32 zFar); | ||||||
| DQN_FILE_SCOPE DqnMat4 DqnMat4_Scale    (f32 x, f32 y, f32 z); | DQN_FILE_SCOPE DqnMat4 DqnMat4_LookAt      (DqnV3 eye, DqnV3 center, DqnV3 up); | ||||||
| DQN_FILE_SCOPE DqnMat4 DqnMat4_Mul      (DqnMat4 a, DqnMat4 b); | 
 | ||||||
| DQN_FILE_SCOPE DqnV4   DqnMat4_MulV4    (DqnMat4 a, DqnV4 b); | DQN_FILE_SCOPE DqnMat4 DqnMat4_Translate   (f32 x, f32 y, f32 z); | ||||||
|  | DQN_FILE_SCOPE DqnMat4 DqnMat4_Rotate      (f32 radians, f32 x, f32 y, f32 z); | ||||||
|  | DQN_FILE_SCOPE DqnMat4 DqnMat4_Scale       (f32 x, f32 y, f32 z); | ||||||
|  | DQN_FILE_SCOPE DqnMat4 DqnMat4_Mul         (DqnMat4 a, DqnMat4 b); | ||||||
|  | DQN_FILE_SCOPE DqnV4   DqnMat4_MulV4       (DqnMat4 a, DqnV4 b); | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
| // Other Math
 | // Other Math
 | ||||||
| @ -1383,7 +1402,7 @@ DqnMemStack_AllocateCompatibleBlock(const DqnMemStack *const stack, size_t size) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE bool DqnMemStack_AttachBlock(DqnMemStack *const stack, | DQN_FILE_SCOPE bool DqnMemStack_AttachBlock(DqnMemStack *const stack, | ||||||
|                                              DqnMemStackBlock *const newBlock) |                                             DqnMemStackBlock *const newBlock) | ||||||
| { | { | ||||||
| 	if (!stack || !newBlock) return false; | 	if (!stack || !newBlock) return false; | ||||||
| 	if (stack->flags & DqnMemStackFlag_IsFixedMemoryFromUser) return false; | 	if (stack->flags & DqnMemStackFlag_IsFixedMemoryFromUser) return false; | ||||||
| @ -1394,6 +1413,31 @@ DQN_FILE_SCOPE bool DqnMemStack_AttachBlock(DqnMemStack *const stack, | |||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | DQN_FILE_SCOPE bool DqnMemStack_DetachBlock(DqnMemStack *const stack, | ||||||
|  |                                             DqnMemStackBlock *const detachBlock) | ||||||
|  | { | ||||||
|  | 	if (!stack || !detachBlock) return false; | ||||||
|  | 	if (stack->flags & DqnMemStackFlag_IsFixedMemoryFromUser) return false; | ||||||
|  | 	if (stack->flags & DqnMemStackFlag_IsNotExpandable)       return false; | ||||||
|  | 
 | ||||||
|  | 	DqnMemStackBlock **blockPtr = &stack->block; | ||||||
|  | 	while (*blockPtr && *blockPtr != detachBlock) | ||||||
|  | 		blockPtr = &((*blockPtr)->prevBlock); | ||||||
|  | 
 | ||||||
|  | 	if (*blockPtr) | ||||||
|  | 	{ | ||||||
|  | 		*blockPtr = detachBlock->prevBlock; | ||||||
|  | 		detachBlock->prevBlock = NULL; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| DQN_FILE_SCOPE void DqnMemStack_FreeBlock(DqnMemStackBlock *block) | DQN_FILE_SCOPE void DqnMemStack_FreeBlock(DqnMemStackBlock *block) | ||||||
| { | { | ||||||
| 	if (!block) return; | 	if (!block) return; | ||||||
| @ -1406,17 +1450,17 @@ DQN_FILE_SCOPE bool DqnMemStack_InitWithFixedMem(DqnMemStack *const stack, | |||||||
|                                                   const u32 byteAlign) |                                                   const u32 byteAlign) | ||||||
| { | { | ||||||
| 	if (!stack || !mem) return false; | 	if (!stack || !mem) return false; | ||||||
| 	DQN_ASSERT(!stack->block); |  | ||||||
| 
 | 
 | ||||||
| 	// TODO(doyle): Better logging
 | 	// TODO(doyle): Better logging
 | ||||||
| 	if (memSize < sizeof(DqnMemStackBlock)) | 	if (memSize < sizeof(DqnMemStackBlock)) | ||||||
| 		DQN_ASSERT(DQN_INVALID_CODE_PATH); | 		DQN_ASSERT(DQN_INVALID_CODE_PATH); | ||||||
| 
 | 
 | ||||||
| 	stack->block         = (DqnMemStackBlock *)mem; | 	stack->block            = (DqnMemStackBlock *)mem; | ||||||
| 	stack->block->memory = mem + sizeof(DqnMemStackBlock); | 	stack->block->memory    = mem + sizeof(DqnMemStackBlock); | ||||||
| 	stack->block->used   = 0; | 	stack->block->used      = 0; | ||||||
| 	stack->block->size   = memSize - sizeof(DqnMemStackBlock); | 	stack->block->size      = memSize - sizeof(DqnMemStackBlock); | ||||||
| 	stack->flags         = (DqnMemStackFlag_IsFixedMemoryFromUser | DqnMemStackFlag_IsNotExpandable); | 	stack->block->prevBlock = NULL; | ||||||
|  | 	stack->flags = (DqnMemStackFlag_IsFixedMemoryFromUser | DqnMemStackFlag_IsNotExpandable); | ||||||
| 
 | 
 | ||||||
| 	const u32 DEFAULT_ALIGNMENT = 4; | 	const u32 DEFAULT_ALIGNMENT = 4; | ||||||
| 	stack->tempStackCount     = 0; | 	stack->tempStackCount     = 0; | ||||||
| @ -2032,18 +2076,21 @@ DQN_FILE_SCOPE bool DqnV2i_Equals(DqnV2i a, DqnV2i b) | |||||||
| ////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
| // Vec3
 | // Vec3
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
|  | DQN_FILE_SCOPE DqnV3 DqnV3_1f(f32 xyz) | ||||||
|  | { | ||||||
|  | 	DqnV3 result = {xyz, xyz, xyz}; | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| DQN_FILE_SCOPE DqnV3 DqnV3_3f(f32 x, f32 y, f32 z) | DQN_FILE_SCOPE DqnV3 DqnV3_3f(f32 x, f32 y, f32 z) | ||||||
| { | { | ||||||
| 	DqnV3 result = {}; | 	DqnV3 result = {x, y, z}; | ||||||
| 	result.x       = x; |  | ||||||
| 	result.y       = y; |  | ||||||
| 	result.z       = z; |  | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE DqnV3 DqnV3_3i(i32 x, i32 y, i32 z) | DQN_FILE_SCOPE DqnV3 DqnV3_3i(i32 x, i32 y, i32 z) | ||||||
| { | { | ||||||
| 	DqnV3 result = DqnV3_3f((f32)x, (f32)y, (f32)z); | 	DqnV3 result = {(f32)x, (f32)y, (f32)z}; | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -2141,6 +2188,24 @@ DQN_FILE_SCOPE DqnV3 DqnV3_Normalise(DqnV3 a) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | DQN_FILE_SCOPE f32 DqnV3_LengthSquared(DqnV3 a, DqnV3 b) | ||||||
|  | { | ||||||
|  | 	f32 x      = b.x - a.x; | ||||||
|  | 	f32 y      = b.y - a.y; | ||||||
|  | 	f32 z      = b.z - a.z; | ||||||
|  | 	f32 result = (DQN_SQUARED(x) + DQN_SQUARED(y) + DQN_SQUARED(z)); | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | DQN_FILE_SCOPE f32 DqnV3_Length(DqnV3 a, DqnV3 b) | ||||||
|  | { | ||||||
|  | 	f32 lengthSq = DqnV3_LengthSquared(a, b); | ||||||
|  | 	if (lengthSq == 0) return 0; | ||||||
|  | 
 | ||||||
|  | 	f32 result = DqnMath_Sqrtf(lengthSq); | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| DQN_FILE_SCOPE DqnV3i DqnV3i_3i(i32 x, i32 y, i32 z) | DQN_FILE_SCOPE DqnV3i DqnV3i_3i(i32 x, i32 y, i32 z) | ||||||
| { | { | ||||||
| 	DqnV3i result = {x, y, z}; | 	DqnV3i result = {x, y, z}; | ||||||
| @ -2168,6 +2233,14 @@ DQN_FILE_SCOPE DqnV4 DqnV4_4i(i32 x, i32 y, i32 z, i32 w) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | DQN_FILE_SCOPE DqnV4 DqnV4_V3(DqnV3 a, f32 w) | ||||||
|  | { | ||||||
|  | 	DqnV4 result; | ||||||
|  | 	result.xyz = a; | ||||||
|  | 	result.w   = w; | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| DQN_FILE_SCOPE DqnV4 DqnV4_1f(f32 xyzw) | DQN_FILE_SCOPE DqnV4 DqnV4_1f(f32 xyzw) | ||||||
| { | { | ||||||
| 	DqnV4 result = {xyzw, xyzw, xyzw, xyzw}; | 	DqnV4 result = {xyzw, xyzw, xyzw, xyzw}; | ||||||
| @ -2248,7 +2321,7 @@ DQN_FILE_SCOPE bool DqnV4_Equals(DqnV4 a, DqnV4 b) | |||||||
| ////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
| DQN_FILE_SCOPE DqnMat4 DqnMat4_Identity() | DQN_FILE_SCOPE DqnMat4 DqnMat4_Identity() | ||||||
| { | { | ||||||
| 	DqnMat4 result    = {0}; | 	DqnMat4 result = {0}; | ||||||
| 	result.e[0][0] = 1; | 	result.e[0][0] = 1; | ||||||
| 	result.e[1][1] = 1; | 	result.e[1][1] = 1; | ||||||
| 	result.e[2][2] = 1; | 	result.e[2][2] = 1; | ||||||
| @ -2256,13 +2329,13 @@ DQN_FILE_SCOPE DqnMat4 DqnMat4_Identity() | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE DqnMat4 | DQN_FILE_SCOPE DqnMat4 DqnMat4_Orthographic(f32 left, f32 right, f32 bottom, f32 top, f32 zNear, | ||||||
| DqnMat4_Ortho(f32 left, f32 right, f32 bottom, f32 top, f32 zNear, f32 zFar) |                                             f32 zFar) | ||||||
| { | { | ||||||
| 	DqnMat4 result = DqnMat4_Identity(); | 	DqnMat4 result = DqnMat4_Identity(); | ||||||
| 	result.e[0][0] = +2.0f   / (right - left); | 	result.e[0][0] = +2.0f / (right - left); | ||||||
| 	result.e[1][1] = +2.0f   / (top   - bottom); | 	result.e[1][1] = +2.0f / (top   - bottom); | ||||||
| 	result.e[2][2] = -2.0f   / (zFar  - zNear); | 	result.e[2][2] = -2.0f / (zFar  - zNear); | ||||||
| 
 | 
 | ||||||
| 	result.e[3][0] = -(right + left)   / (right - left); | 	result.e[3][0] = -(right + left)   / (right - left); | ||||||
| 	result.e[3][1] = -(top   + bottom) / (top   - bottom); | 	result.e[3][1] = -(top   + bottom) / (top   - bottom); | ||||||
| @ -2271,6 +2344,51 @@ DqnMat4_Ortho(f32 left, f32 right, f32 bottom, f32 top, f32 zNear, f32 zFar) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | DQN_FILE_SCOPE DqnMat4 DqnMat4_Perspective(f32 fovYDegrees, f32 aspectRatio, f32 zNear, f32 zFar) | ||||||
|  | { | ||||||
|  | 	f32 fovYRadians         = DQN_DEGREES_TO_RADIANS(fovYDegrees); | ||||||
|  | 	f32 fovYRadiansOver2    = fovYRadians * 0.5f; | ||||||
|  | 	f32 tanFovYRadiansOver2 = tanf(fovYRadiansOver2); | ||||||
|  | 	f32 zNearSubZFar        = zNear - zFar; | ||||||
|  | 
 | ||||||
|  | 	DqnMat4 result = DqnMat4_Identity(); | ||||||
|  | 	result.e[0][0] = 1.0f / (tanFovYRadiansOver2 * aspectRatio); | ||||||
|  | 	result.e[1][1] = 1.0f / tanFovYRadiansOver2; | ||||||
|  | 	result.e[2][2] = (zNear + zFar) / zNearSubZFar; | ||||||
|  | 	result.e[2][3] = -1.0f; | ||||||
|  | 	result.e[3][2] = (2.0f * zNear * zFar) / zNearSubZFar; | ||||||
|  | 	result.e[3][3] = 0.0f; | ||||||
|  | 
 | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | DQN_FILE_SCOPE DqnMat4 DqnMat4_LookAt(DqnV3 eye, DqnV3 center, DqnV3 up) | ||||||
|  | { | ||||||
|  | 	DqnMat4 result = {0}; | ||||||
|  | 
 | ||||||
|  | 	DqnV3 f = DqnV3_Normalise(DqnV3_Sub(eye, center)); | ||||||
|  | 	DqnV3 s = DqnV3_Normalise(DqnV3_Cross(up, f)); | ||||||
|  | 	DqnV3 u = DqnV3_Cross(f, s); | ||||||
|  | 
 | ||||||
|  | 	result.e[0][0] = s.x; | ||||||
|  | 	result.e[0][1] = u.x; | ||||||
|  | 	result.e[0][2] = f.x; | ||||||
|  | 
 | ||||||
|  | 	result.e[1][0] = s.y; | ||||||
|  | 	result.e[1][1] = u.y; | ||||||
|  | 	result.e[1][2] = f.y; | ||||||
|  | 
 | ||||||
|  | 	result.e[2][0] = s.z; | ||||||
|  | 	result.e[2][1] = u.z; | ||||||
|  | 	result.e[2][2] = f.z; | ||||||
|  | 
 | ||||||
|  | 	result.e[3][0] = DqnV3_Dot(s, eye); | ||||||
|  | 	result.e[3][1] = DqnV3_Dot(u, eye); | ||||||
|  | 	result.e[3][2] = -DqnV3_Dot(f, eye); | ||||||
|  | 	result.e[3][3] = 1.0f; | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| DQN_FILE_SCOPE DqnMat4 DqnMat4_Translate(f32 x, f32 y, f32 z) | DQN_FILE_SCOPE DqnMat4 DqnMat4_Translate(f32 x, f32 y, f32 z) | ||||||
| { | { | ||||||
| 	DqnMat4 result = DqnMat4_Identity(); | 	DqnMat4 result = DqnMat4_Identity(); | ||||||
| @ -2282,23 +2400,22 @@ DQN_FILE_SCOPE DqnMat4 DqnMat4_Translate(f32 x, f32 y, f32 z) | |||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE DqnMat4 DqnMat4_Rotate(f32 radians, f32 x, f32 y, f32 z) | DQN_FILE_SCOPE DqnMat4 DqnMat4_Rotate(f32 radians, f32 x, f32 y, f32 z) | ||||||
| { | { | ||||||
| 	DqnMat4 result = DqnMat4_Identity(); | 	DqnMat4 result     = DqnMat4_Identity(); | ||||||
| 	f32 sinVal = sinf(radians); | 	f32 sinVal         = sinf(radians); | ||||||
| 	f32 cosVal = cosf(radians); | 	f32 cosVal         = cosf(radians); | ||||||
|  | 	f32 oneMinusCosVal = 1 - cosVal; | ||||||
| 
 | 
 | ||||||
| 	result.e[0][0] = (cosVal + (DQN_SQUARED(x) * (1.0f - cosVal))); | 	result.e[0][0] = (DQN_SQUARED(x) * oneMinusCosVal) + cosVal; | ||||||
| 	result.e[0][1] = ((y * z * (1.0f - cosVal)) + (z * sinVal)); | 	result.e[0][1] = (x * y          * oneMinusCosVal) + (z * sinVal); | ||||||
| 	result.e[0][2] = ((z * x * (1.0f - cosVal)) - (y * sinVal)); | 	result.e[0][2] = (x * z          * oneMinusCosVal) - (y * sinVal); | ||||||
| 
 | 
 | ||||||
| 	result.e[1][0] = ((x * y * (1.0f - cosVal)) - (z * sinVal)); | 	result.e[1][0] = (y * x          * oneMinusCosVal) - (z * sinVal); | ||||||
| 	result.e[1][1] = (cosVal + (DQN_SQUARED(y) * (1.0f - cosVal))); | 	result.e[1][1] = (DQN_SQUARED(y) * oneMinusCosVal) + cosVal; | ||||||
| 	result.e[1][2] = ((z * y * (1.0f - cosVal)) + (x * sinVal)); | 	result.e[1][2] = (y * z          * oneMinusCosVal) + (x * sinVal); | ||||||
| 
 | 
 | ||||||
| 	result.e[2][0] = ((x * z * (1.0f - cosVal)) + (y * sinVal)); | 	result.e[2][0] = (z * x          * oneMinusCosVal) + (y * sinVal); | ||||||
| 	result.e[2][1] = ((y * z * (1.0f - cosVal)) - (x * sinVal)); | 	result.e[2][1] = (z * y          * oneMinusCosVal) - (x * sinVal); | ||||||
| 	result.e[2][2] = (cosVal + (DQN_SQUARED(z) * (1.0f - cosVal))); | 	result.e[2][2] = (DQN_SQUARED(z) * oneMinusCosVal) + cosVal; | ||||||
| 
 |  | ||||||
| 	result.e[3][3] = 1; |  | ||||||
| 
 | 
 | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| @ -2317,7 +2434,8 @@ DQN_FILE_SCOPE DqnMat4 DqnMat4_Mul(DqnMat4 a, DqnMat4 b) | |||||||
| { | { | ||||||
| 	DqnMat4 result = {0}; | 	DqnMat4 result = {0}; | ||||||
| 	for (i32 j = 0; j < 4; j++) { | 	for (i32 j = 0; j < 4; j++) { | ||||||
| 		for (i32 i = 0; i < 4; i++) { | 		for (i32 i = 0; i < 4; i++) | ||||||
|  | 		{ | ||||||
| 			result.e[j][i] = a.e[0][i] * b.e[j][0] | 			result.e[j][i] = a.e[0][i] * b.e[j][0] | ||||||
| 			               + a.e[1][i] * b.e[j][1] | 			               + a.e[1][i] * b.e[j][1] | ||||||
| 			               + a.e[2][i] * b.e[j][2] | 			               + a.e[2][i] * b.e[j][2] | ||||||
| @ -2331,15 +2449,10 @@ DQN_FILE_SCOPE DqnMat4 DqnMat4_Mul(DqnMat4 a, DqnMat4 b) | |||||||
| DQN_FILE_SCOPE DqnV4 DqnMat4_MulV4(DqnMat4 a, DqnV4 b) | DQN_FILE_SCOPE DqnV4 DqnMat4_MulV4(DqnMat4 a, DqnV4 b) | ||||||
| { | { | ||||||
| 	DqnV4 result = {0}; | 	DqnV4 result = {0}; | ||||||
| 
 | 	result.x = (a.e[0][0] * b.x) + (a.e[1][0] * b.y) + (a.e[2][0] * b.z) + (a.e[3][0] * b.w); | ||||||
| 	result.x = (a.e[0][0] * b.x) + (a.e[1][0] * b.y) + (a.e[2][0] * b.z) + | 	result.y = (a.e[0][1] * b.x) + (a.e[1][1] * b.y) + (a.e[2][1] * b.z) + (a.e[3][1] * b.w); | ||||||
| 	           (a.e[3][0] * b.w); | 	result.z = (a.e[0][2] * b.x) + (a.e[1][2] * b.y) + (a.e[2][2] * b.z) + (a.e[3][2] * b.w); | ||||||
| 	result.y = (a.e[0][1] * b.x) + (a.e[1][1] * b.y) + (a.e[2][1] * b.z) + | 	result.w = (a.e[0][3] * b.x) + (a.e[1][3] * b.y) + (a.e[2][3] * b.z) + (a.e[3][3] * b.w); | ||||||
| 	           (a.e[3][1] * b.w); |  | ||||||
| 	result.z = (a.e[0][2] * b.x) + (a.e[1][2] * b.y) + (a.e[2][2] * b.z) + |  | ||||||
| 	           (a.e[3][2] * b.w); |  | ||||||
| 	result.w = (a.e[0][3] * b.x) + (a.e[1][3] * b.y) + (a.e[2][3] * b.z) + |  | ||||||
| 	           (a.e[3][3] * b.w); |  | ||||||
| 
 | 
 | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,7 +2,97 @@ | |||||||
| #define DQN_IMPLEMENTATION | #define DQN_IMPLEMENTATION | ||||||
| #include "dqn.h" | #include "dqn.h" | ||||||
| 
 | 
 | ||||||
|  | #define HANDMADE_MATH_IMPLEMENTATION | ||||||
|  | #define HANDMADE_MATH_CPP_MODE | ||||||
|  | #include "tests/HandmadeMath.h" | ||||||
|  | 
 | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  | 
 | ||||||
|  | void HandmadeMathVerifyMat4(DqnMat4 dqnMat, hmm_mat4 hmmMat) | ||||||
|  | { | ||||||
|  | 	f32 *hmmMatf = (f32 *)&hmmMat; | ||||||
|  | 	f32 *dqnMatf = (f32 *)&dqnMat; | ||||||
|  | 
 | ||||||
|  | 	const u32 EXPECTED_SIZE = 16; | ||||||
|  | 	u32 totalSize = DQN_ARRAY_COUNT(dqnMat.e) * DQN_ARRAY_COUNT(dqnMat.e[0]); | ||||||
|  | 	DQN_ASSERT(totalSize == EXPECTED_SIZE); | ||||||
|  | 	DQN_ASSERT(totalSize == (DQN_ARRAY_COUNT(hmmMat.Elements) * DQN_ARRAY_COUNT(hmmMat.Elements[0]))); | ||||||
|  | 
 | ||||||
|  | 	for (i32 i = 0; i < EXPECTED_SIZE; i++) | ||||||
|  | 		DQN_ASSERT(hmmMatf[i] == dqnMatf[i]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HandmadeMathTest() | ||||||
|  | { | ||||||
|  | 	// Test Perspective/Projection matrix values
 | ||||||
|  | 	{ | ||||||
|  | 		f32 aspectRatio = 1; | ||||||
|  | 		DqnMat4 dqnPerspective = DqnMat4_Perspective(90, aspectRatio, 100, 1000); | ||||||
|  | 		hmm_mat4 hmmPerspective = HMM_Perspective(90, aspectRatio, 100, 1000); | ||||||
|  | 		HandmadeMathVerifyMat4(dqnPerspective, hmmPerspective); | ||||||
|  | 
 | ||||||
|  | 		printf("HandmadeMathTest(): Perspective: Completed successfully\n"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Test Mat4 translate * scale
 | ||||||
|  | 	{ | ||||||
|  | 		hmm_vec3 hmmVec       = HMM_Vec3i(1, 2, 3); | ||||||
|  | 		DqnV3 dqnVec          = DqnV3_3i(1, 2, 3); | ||||||
|  | 		DqnMat4 dqnTranslate  = DqnMat4_Translate(dqnVec.x, dqnVec.y, dqnVec.z); | ||||||
|  | 		hmm_mat4 hmmTranslate = HMM_Translate(hmmVec); | ||||||
|  | 		HandmadeMathVerifyMat4(dqnTranslate, hmmTranslate); | ||||||
|  | 
 | ||||||
|  | 		hmm_vec3 hmmAxis      = HMM_Vec3(0.5f, 0.2f, 0.7f); | ||||||
|  | 		DqnV3 dqnAxis         = DqnV3_3f(0.5f, 0.2f, 0.7f); | ||||||
|  | 		f32 rotationInDegrees = 80.0f; | ||||||
|  | 
 | ||||||
|  | 		// TODO(doyle): ?? Handmade Math does it a rotations in a different way
 | ||||||
|  | 		// way, they normalise the given axis producing different results.
 | ||||||
|  | 		// HandmadeMathVerifyMat4(dqnRotate, hmmRotate);
 | ||||||
|  | 
 | ||||||
|  | 		dqnVec *= 2; | ||||||
|  | 		hmmVec *= 2; | ||||||
|  | 		DqnMat4 dqnScale  = DqnMat4_Scale(dqnVec.x, dqnVec.y, dqnVec.z); | ||||||
|  | 		hmm_mat4 hmmScale = HMM_Scale(hmmVec); | ||||||
|  | 		HandmadeMathVerifyMat4(dqnScale, hmmScale); | ||||||
|  | 
 | ||||||
|  | 		DqnMat4 dqnTSMatrix  = DqnMat4_Mul(dqnTranslate, dqnScale); | ||||||
|  | 		hmm_mat4 hmmTSMatrix = HMM_MultiplyMat4(hmmTranslate, hmmScale); | ||||||
|  | 		HandmadeMathVerifyMat4(dqnTSMatrix, hmmTSMatrix); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 		// Test Mat4 * MulV4
 | ||||||
|  | 		{ | ||||||
|  | 			DqnV4 dqnV4    = DqnV4_4f(1, 2, 3, 4); | ||||||
|  | 			hmm_vec4 hmmV4 = HMM_Vec4(1, 2, 3, 4); | ||||||
|  | 
 | ||||||
|  | 			DqnV4 dqnResult    = DqnMat4_MulV4(dqnTSMatrix, dqnV4); | ||||||
|  | 			hmm_vec4 hmmResult = HMM_MultiplyMat4ByVec4(hmmTSMatrix, hmmV4); | ||||||
|  | 
 | ||||||
|  | 			DQN_ASSERT(dqnResult.x == hmmResult.X); | ||||||
|  | 			DQN_ASSERT(dqnResult.y == hmmResult.Y); | ||||||
|  | 			DQN_ASSERT(dqnResult.z == hmmResult.Z); | ||||||
|  | 			DQN_ASSERT(dqnResult.w == hmmResult.W); | ||||||
|  | 
 | ||||||
|  | 			printf( | ||||||
|  | 			    "HandmadeMathTest(): Mat4 * MulV4: Completed successfully\n"); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		printf("HandmadeMathTest(): Translate/Scale/Rotate Mat4_Mul: Completed successfully\n"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Test LookAt/Camera/View matrix returns same results
 | ||||||
|  | 	{ | ||||||
|  | 		DqnMat4 dqnViewMatrix = DqnMat4_LookAt(DqnV3_3f(4, 3, 3), DqnV3_1f(0), DqnV3_3f(0, 1, 0)); | ||||||
|  | 		hmm_mat4 hmmViewMatrix = | ||||||
|  | 		    HMM_LookAt(HMM_Vec3(4, 3, 3), HMM_Vec3(0, 0, 0), HMM_Vec3(0, 1, 0)); | ||||||
|  | 
 | ||||||
|  | 		HandmadeMathVerifyMat4(dqnViewMatrix, hmmViewMatrix); | ||||||
|  | 		printf("HandmadeMathTest(): LookAt: Completed successfully\n"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void StringsTest() | void StringsTest() | ||||||
| { | { | ||||||
| 	{ // Char Checks
 | 	{ // Char Checks
 | ||||||
| @ -1404,6 +1494,7 @@ int main(void) | |||||||
| 	StringsTest(); | 	StringsTest(); | ||||||
| 	RandomTest(); | 	RandomTest(); | ||||||
| 	MathTest(); | 	MathTest(); | ||||||
|  | 	HandmadeMathTest(); | ||||||
| 	VecTest(); | 	VecTest(); | ||||||
| 	OtherTest(); | 	OtherTest(); | ||||||
| 	ArrayTest(); | 	ArrayTest(); | ||||||
|  | |||||||
							
								
								
									
										2659
									
								
								tests/HandmadeMath.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2659
									
								
								tests/HandmadeMath.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user