Initial commit
This commit is contained in:
68
.gitignore
vendored
Normal file
68
.gitignore
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
# ---> C
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# ---> CMake
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
CMakeUserPresets.json
|
||||
|
||||
56
Box2f.c
Normal file
56
Box2f.c
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "CgeMath.h"
|
||||
#include <string.h>
|
||||
|
||||
#define EPSILON 0.00001f
|
||||
#define PI 3.14159265358979323846f
|
||||
|
||||
void CgeBox2fUnion(const float aMin[2], const float aMax[2],
|
||||
const float bMin[2], const float bMax[2],
|
||||
float outMin[2], float outMax[2]) {
|
||||
CgeVec2fMin(aMin, bMin, outMin);
|
||||
CgeVec2fMax(aMax, bMax, outMax);
|
||||
}
|
||||
|
||||
int CgeBox2fIntersect(const float aMin[2], const float aMax[2],
|
||||
const float bMin[2], const float bMax[2],
|
||||
float outMin[2], float outMax[2]) {
|
||||
CgeVec2fMax(aMin, bMin, outMin);
|
||||
CgeVec2fMin(aMax, bMax, outMax);
|
||||
|
||||
if (outMin[0] >= outMax[0] || outMin[1] >= outMax[1])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeBox2fContains(const float aMin[2], const float aMax[2],
|
||||
const float point[2]) {
|
||||
if (point[0] < aMin[0] || point[1] < aMin[1])
|
||||
return 0;
|
||||
|
||||
if (point[0] > aMax[0] || point[1] > aMax[1])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeBox2fEnclose(const float *points, size_t size, float outMin[2],
|
||||
float outMax[2]) {
|
||||
float tmp1[2], tmp2[2];
|
||||
size_t i;
|
||||
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
memcpy(tmp1, points, sizeof(tmp1));
|
||||
memcpy(tmp2, points, sizeof(tmp2));
|
||||
|
||||
for (i = 1; i < size; i++) {
|
||||
CgeVec2fMin(tmp1, points + i * 2, tmp1);
|
||||
CgeVec2fMax(tmp2, points + i * 2, tmp2);
|
||||
}
|
||||
|
||||
memcpy(outMin, tmp1, sizeof(tmp1));
|
||||
memcpy(outMax, tmp2, sizeof(tmp2));
|
||||
return 1;
|
||||
}
|
||||
56
Box3f.c
Normal file
56
Box3f.c
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "CgeMath.h"
|
||||
#include <string.h>
|
||||
|
||||
#define EPSILON 0.00001f
|
||||
#define PI 3.14159265358979323846f
|
||||
|
||||
void CgeBox3fUnion(const float aMin[3], const float aMax[3],
|
||||
const float bMin[3], const float bMax[3],
|
||||
float outMin[3], float outMax[3]) {
|
||||
CgeVec3fMin(aMin, bMin, outMin);
|
||||
CgeVec3fMax(aMax, bMax, outMax);
|
||||
}
|
||||
|
||||
int CgeBox3fIntersect(const float aMin[3], const float aMax[3],
|
||||
const float bMin[3], const float bMax[3],
|
||||
float outMin[3], float outMax[3]) {
|
||||
CgeVec3fMax(aMin, bMin, outMin);
|
||||
CgeVec3fMin(aMax, bMax, outMax);
|
||||
|
||||
if (outMin[0] >= outMax[0] || outMin[1] >= outMax[1] || outMin[2] >= outMax[2])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeBox3fContains(const float aMin[3], const float aMax[3],
|
||||
const float point[3]) {
|
||||
if (point[0] < aMin[0] || point[1] < aMin[1] || point[2] < aMin[2])
|
||||
return 0;
|
||||
|
||||
if (point[0] > aMax[0] || point[1] > aMax[1] || point[2] > aMax[2])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeBox3fEnclose(const float *points, size_t size, float outMin[3],
|
||||
float outMax[3]) {
|
||||
float tmp1[3], tmp2[3];
|
||||
size_t i;
|
||||
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
memcpy(tmp1, points, sizeof(tmp1));
|
||||
memcpy(tmp2, points, sizeof(tmp2));
|
||||
|
||||
for (i = 1; i < size; i++) {
|
||||
CgeVec3fMin(tmp1, points + i * 3, tmp1);
|
||||
CgeVec3fMax(tmp2, points + i * 3, tmp2);
|
||||
}
|
||||
|
||||
memcpy(outMin, tmp1, sizeof(tmp1));
|
||||
memcpy(outMax, tmp2, sizeof(tmp2));
|
||||
return 1;
|
||||
}
|
||||
40
CMakeLists.txt
Normal file
40
CMakeLists.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(CgeMath LANGUAGES C)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
set(SOURCES
|
||||
Box2f.c
|
||||
Box3f.c
|
||||
Line.c
|
||||
Mat3f.c
|
||||
Mat4f.c
|
||||
Misc.c
|
||||
Plane.c
|
||||
Quat4f.c
|
||||
Ray2f.c
|
||||
Ray3f.c
|
||||
Vec2f.c
|
||||
Vec2i.c
|
||||
Vec3f.c
|
||||
Vec3i.c
|
||||
Vec4f.c
|
||||
Vec4i.c
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
CgeMath.h
|
||||
)
|
||||
|
||||
add_library(CgeMath STATIC ${SOURCES} ${HEADERS})
|
||||
|
||||
target_include_directories(CgeMath PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
install(TARGETS CgeMath
|
||||
ARCHIVE DESTINATION lib
|
||||
LIBRARY DESTINATION lib
|
||||
RUNTIME DESTINATION bin
|
||||
)
|
||||
|
||||
install(FILES ${HEADERS} DESTINATION include)
|
||||
230
CgeMath.h
Normal file
230
CgeMath.h
Normal file
@@ -0,0 +1,230 @@
|
||||
#ifndef CGE_MATH_H
|
||||
#define CGE_MATH_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void CgeBox2fUnion(const float aMin[2], const float aMax[2],
|
||||
const float bMin[2], const float bMax[2],
|
||||
float outMin[2], float outMax[2]);
|
||||
int CgeBox2fIntersect(const float aMin[2], const float aMax[2],
|
||||
const float bMin[2], const float bMax[2],
|
||||
float outMin[2], float outMax[2]);
|
||||
int CgeBox2fContains(const float aMin[2], const float aMax[2],
|
||||
const float point[2]);
|
||||
int CgeBox2fEnclose(const float *points, size_t size, float outMin[2],
|
||||
float outMax[2]);
|
||||
|
||||
void CgeBox3fUnion(const float aMin[3], const float aMax[3],
|
||||
const float bMin[3], const float bMax[3],
|
||||
float outMin[3], float outMax[3]);
|
||||
int CgeBox3fIntersect(const float aMin[3], const float aMax[3],
|
||||
const float bMin[3], const float bMax[3],
|
||||
float outMin[3], float outMax[3]);
|
||||
int CgeBox3fContains(const float aMin[3], const float aMax[3],
|
||||
const float point[3]);
|
||||
int CgeBox3fEnclose(const float *points, size_t size, float outMin[3],
|
||||
float outMax[3]);
|
||||
|
||||
int CgeLineFromPoints(const float a[2], const float b[2], float out[3]);
|
||||
float CgeLineDistance(const float line[3], const float point[2]);
|
||||
void CgeLineClosestPoint(const float line[3], const float point[2],
|
||||
float out[2]);
|
||||
|
||||
void CgeMat3fIdentity(float out[9]);
|
||||
void CgeMat3fAdd(const float a[9], const float b[9], float out[9]);
|
||||
void CgeMat3fSub(const float a[9], const float b[9], float out[9]);
|
||||
void CgeMat3fMul(const float a[9], const float b[9], float out[9]);
|
||||
void CgeMat3fScale(const float a[9], float b, float out[9]);
|
||||
void CgeMat3fTranspose(const float in[9], float out[9]);
|
||||
float CgeMat3fTrace(const float in[9]);
|
||||
float CgeMat3fDet(const float in[9]);
|
||||
int CgeMat3fInverse(const float in[9], float out[9]);
|
||||
void CgeMat3fFromScale(float x, float y, float out[9]);
|
||||
void CgeMat3fFromTranslation(float x, float y, float out[9]);
|
||||
void CgeMat3fFromRotation(float angle, float out[9]);
|
||||
void CgeMat3fApplyVec3f(float a[9], float b[3], float out[3]);
|
||||
void CgeMat3fApplyVec2f(float a[9], float b[2], float out[2]);
|
||||
|
||||
void CgeMat4fIdentity(float out[16]);
|
||||
void CgeMat4fAdd(const float a[16], const float b[16], float out[16]);
|
||||
void CgeMat4fSub(const float a[16], const float b[16], float out[16]);
|
||||
void CgeMat4fMul(const float a[16], const float b[16], float out[16]);
|
||||
void CgeMat4fScale(const float a[16], float b, float out[16]);
|
||||
void CgeMat4fTranspose(const float in[16], float out[16]);
|
||||
float CgeMat4fTrace(const float in[16]);
|
||||
float CgeMat4fDet(const float in[16]);
|
||||
int CgeMat4fInverse(const float in[16], float out[16]);
|
||||
void CgeMat4fFromScale(float x, float y, float z, float out[16]);
|
||||
void CgeMat4fFromTranslation(float x, float y, float z, float out[16]);
|
||||
void CgeMat4fFromRotationX(float angle, float out[16]);
|
||||
void CgeMat4fFromRotationY(float angle, float out[16]);
|
||||
void CgeMat4fFromRotationZ(float angle, float out[16]);
|
||||
void CgeMat4fFromAxis(const float axis[3], float angle, float out[16]);
|
||||
void CgeMat4fFromEuler(float roll, float pitch, float yaw, float out[16]);
|
||||
void CgeMat4fFromQuat4f(const float in[4], float out[16]);
|
||||
void CgeMat4fFromOrtho(float xMin, float xMax, float yMin, float yMax,
|
||||
float zMin, float zMax, float out[16]);
|
||||
void CgeMat4fFromFrustum(float fov, float aspect, float zMin, float zMax,
|
||||
float out[16]);
|
||||
void CgeMat4fFromLookAt(const float position[3], const float at[3],
|
||||
const float up[3], float out[16]);
|
||||
void CgeMat4fApplyVec4f(const float a[16], const float b[4], float out[4]);
|
||||
void CgeMat4fApplyVec3f(const float a[16], const float b[3], float out[3]);
|
||||
|
||||
float CgeLerpf(float a, float b, float t);
|
||||
|
||||
void CgeTriangle3fBarycentric(const float a[3], const float b[3],
|
||||
const float c[3], const float point[3],
|
||||
float out[3]);
|
||||
|
||||
int CgePlaneFromPoints(const float a[3], const float b[3], const float c[3],
|
||||
float out[4]);
|
||||
float CgePlaneDistance(const float plane[4], const float point[3]);
|
||||
|
||||
void CgePlaneClosestPoint(const float plane[4], const float point[3],
|
||||
float out[3]);
|
||||
|
||||
#define CgeQuat4fAdd(a, b, out) CgeVec4fAdd(a, b, out)
|
||||
#define CgeQuat4fSub(a, b, out) CgeVec4fSub(a, b, out)
|
||||
#define CgeQuat4fScale(a, b, out) CgeVec4fScale(a, b, out)
|
||||
#define CgeQuat4fNegate(in, out) CgeVec4fNegate(in, out)
|
||||
#define CgeQuat4fDot(a, b) CgeVec4fDot(a, b)
|
||||
#define CgeQuat4fLength(in) CgeVec4fLength(in)
|
||||
#define CgeQuat4fNormal(in, out) CgeVec4fNormal(in, out)
|
||||
#define CgeQuat4fLerp(a, b, t, out) CgeVec4fLerp(a, b, t, out)
|
||||
|
||||
void CgeQuat4fIdentity(float out[4]);
|
||||
void CgeQuat4fConjugate(const float in[4],float out[4]);
|
||||
void CgeQuat4fInverse(const float in[4], float out[4]);
|
||||
void CgeQuat4fMul(const float a[4], const float b[4], float out[4]);
|
||||
void CgeQuat4fSlerp(const float a[4], const float b[4], float t, float out[4]);
|
||||
void CgeQuat4fFromEuler(float roll, float pitch, float yaw, float out[4]);
|
||||
void CgeQuat4fFromAxis(const float axis[3], float angle, float out[4]);
|
||||
void CgeQuat4fToEuler(const float in[4], float *roll, float *pitch, float *yaw);
|
||||
void CgeQuat4fToAxis(const float in[4], float axis[3], float *angle);
|
||||
void CgeQuat4fToMat4f(const float in[4], float out[16]);
|
||||
|
||||
int CgeRay2fIntersectLine(const float start[2], const float direction[2],
|
||||
const float line[3], float *t, float out[2]);
|
||||
int CgeRay2fIntersectTime(const float aStart[2], const float aDirection[2],
|
||||
const float bStart[2], const float bDirection[2],
|
||||
float *time1, float *time2);
|
||||
int CgeRay2fIntersectRay(const float aStart[2], const float aDirection[2],
|
||||
const float bStart[2], const float bDirection[2],
|
||||
float *t, float out[2]);
|
||||
int CgeRay2fIntersectSegment(const float aStart[2], const float aDirection[2],
|
||||
const float bStart[2], const float bEnd[2],
|
||||
float *t, float out[2]);
|
||||
int CgeSegment2fIntersectLine(const float start[2], const float end[2],
|
||||
const float line[3], float *t, float out[2]);
|
||||
int CgeSegment2fIntersectSegment(const float aStart[2], const float aEnd[2],
|
||||
const float bStart[2], const float bEnd[2],
|
||||
float *t, float out[2]);
|
||||
int CgeRay2fIntersectBox2f(const float aStart[2], const float aDirection[2],
|
||||
const float bMin[2], const float bMax[2],
|
||||
float *t, float out[2]);
|
||||
int CgeSegment2fIntersectBox2f(const float aStart[2], const float aEnd[2],
|
||||
const float bMin[2], const float bMax[2],
|
||||
float *t, float out[2]);
|
||||
|
||||
int CgeRay3fIntersectPlane(const float start[3], const float direction[3],
|
||||
const float plane[4], float *t, float out[3]);
|
||||
int CgeRay3fIntersectTriangle(const float start[3], const float direction[3],
|
||||
const float a[3], const float b[3],
|
||||
const float c[3], float *t, float out[3]);
|
||||
int CgeSegment3fIntersectPlane(const float start[3], const float end[3],
|
||||
const float plane[4], float *t, float out[3]);
|
||||
int CgeSegment3fIntersectTriangle(const float start[3], const float end[3],
|
||||
const float a[3], const float b[3],
|
||||
const float c[3], float *t, float out[3]);
|
||||
int CgeRay3fIntersectBox3f(const float aStart[3], const float aDirection[3],
|
||||
const float bMin[3], const float bMax[3],
|
||||
float *t, float out[3]);
|
||||
int CgeSegment3fIntersectBox3f(const float aStart[3], const float aEnd[3],
|
||||
const float bMin[3], const float bMax[3],
|
||||
float *t, float out[3]);
|
||||
|
||||
void CgeVec2fAdd(const float a[2], const float b[2], float out[2]);
|
||||
void CgeVec2fSub(const float a[2], const float b[2], float out[2]);
|
||||
void CgeVec2fMul(const float a[2], const float b[2], float out[2]);
|
||||
void CgeVec2fScale(const float a[2], float b, float out[2]);
|
||||
void CgeVec2fMulAdd(const float a[2], const float b[2], const float c[2],
|
||||
float out[2]);
|
||||
void CgeVec2fNegate(const float in[2], float out[2]);
|
||||
float CgeVec2fDot(const float a[2], const float b[2]);
|
||||
float CgeVec2fCross(const float a[2], const float b[2]);
|
||||
float CgeVec2fLength(const float in[2]);
|
||||
void CgeVec2fNormal(const float in[2], float out[2]);
|
||||
float CgeVec2fNormalEx(const float in[2], float out[2]);
|
||||
void CgeVec2fMin(const float a[2], const float b[2], float out[2]);
|
||||
void CgeVec2fMax(const float a[2], const float b[2], float out[2]);
|
||||
void CgeVec2fLerp(const float a[2], const float b[2], float t, float out[2]);
|
||||
void CgeVec2fProject(const float a[2], const float b[2], float out[2]);
|
||||
void CgeVec2fBarycentric(const float a[2], const float b[2], const float c[2],
|
||||
float v, float w, float out[2]);
|
||||
|
||||
void CgeVec2iAdd(const int a[2], const int b[2], int out[2]);
|
||||
void CgeVec2iSub(const int a[2], const int b[2], int out[2]);
|
||||
void CgeVec2iMul(const int a[2], const int b[2], int out[2]);
|
||||
void CgeVec2iScale(const int a[2], int b, int out[2]);
|
||||
void CgeVec2iMulAdd(const int a[2], const int b[2], const int c[2], int out[2]);
|
||||
void CgeVec2iNegate(const int in[2], int out[2]);
|
||||
void CgeVec2iMin(const int a[2], const int b[2], int out[2]);
|
||||
void CgeVec2iMax(const int a[2], const int b[2], int out[2]);
|
||||
|
||||
void CgeVec3fAdd(const float a[3], const float b[3], float out[3]);
|
||||
void CgeVec3fSub(const float a[3], const float b[3], float out[3]);
|
||||
void CgeVec3fMul(const float a[3], const float b[3], float out[3]);
|
||||
void CgeVec3fScale(const float a[3], float b, float out[3]);
|
||||
void CgeVec3fMulAdd(const float a[3], const float b[3], const float c[3],
|
||||
float out[3]);
|
||||
void CgeVec3fNegate(const float in[3], float out[3]);
|
||||
float CgeVec3fDot(const float a[3], const float b[3]);
|
||||
void CgeVec3fCross(const float a[3], const float b[3], float out[3]);
|
||||
float CgeVec3fLength(const float in[3]);
|
||||
void CgeVec3fNormal(const float in[3], float out[3]);
|
||||
float CgeVec3fNormalEx(const float in[3], float out[3]);
|
||||
void CgeVec3fMin(const float a[3], const float b[3], float out[3]);
|
||||
void CgeVec3fMax(const float a[3], const float b[3], float out[3]);
|
||||
void CgeVec3fLerp(const float a[3], const float b[3], float t, float out[3]);
|
||||
void CgeVec3fProject(const float a[3], const float b[3], float out[3]);
|
||||
void CgeVec3fBarycentric(const float a[3], const float b[3], const float c[3],
|
||||
float v, float w, float out[3]);
|
||||
|
||||
void CgeVec3iAdd(const int a[3], const int b[3], int out[3]);
|
||||
void CgeVec3iSub(const int a[3], const int b[3], int out[3]);
|
||||
void CgeVec3iMul(const int a[3], const int b[3], int out[3]);
|
||||
void CgeVec3iScale(const int a[3], int b, int out[3]);
|
||||
void CgeVec3iMulAdd(const int a[3], const int b[3], const int c[3], int out[3]);
|
||||
void CgeVec3iNegate(const int in[3], int out[3]);
|
||||
void CgeVec3iMin(const int a[3], const int b[3], int out[3]);
|
||||
void CgeVec3iMax(const int a[3], const int b[3], int out[3]);
|
||||
|
||||
void CgeVec4fAdd(const float a[4], const float b[4], float out[4]);
|
||||
void CgeVec4fSub(const float a[4], const float b[4], float out[4]);
|
||||
void CgeVec4fMul(const float a[4], const float b[4], float out[4]);
|
||||
void CgeVec4fScale(const float a[4], float b, float out[4]);
|
||||
void CgeVec4fMulAdd(const float a[4], const float b[4], const float c[4],
|
||||
float out[4]);
|
||||
void CgeVec4fNegate(const float in[4], float out[4]);
|
||||
float CgeVec4fDot(const float a[4], const float b[4]);
|
||||
float CgeVec4fLength(const float in[4]);
|
||||
void CgeVec4fNormal(const float in[4], float out[4]);
|
||||
float CgeVec4fNormalEx(const float in[4], float out[4]);
|
||||
void CgeVec4fMin(const float a[4], const float b[4], float out[4]);
|
||||
void CgeVec4fMax(const float a[4], const float b[4], float out[4]);
|
||||
void CgeVec4fLerp(const float a[4], const float b[4], float t, float out[4]);
|
||||
void CgeVec4fProject(const float a[4], const float b[4], float out[4]);
|
||||
void CgeVec4fBarycentric(const float a[4], const float b[4], const float c[4],
|
||||
float v, float w, float out[4]);
|
||||
|
||||
void CgeVec4iAdd(const int a[4], const int b[4], int out[4]);
|
||||
void CgeVec4iSub(const int a[4], const int b[4], int out[4]);
|
||||
void CgeVec4iMul(const int a[4], const int b[4], int out[4]);
|
||||
void CgeVec4iScale(const int a[4], int b, int out[4]);
|
||||
void CgeVec4iMulAdd(const int a[4], const int b[4], const int c[4], int out[4]);
|
||||
void CgeVec4iNegate(const int in[4], int out[4]);
|
||||
void CgeVec4iMin(const int a[4], const int b[4], int out[4]);
|
||||
void CgeVec4iMax(const int a[4], const int b[4], int out[4]);
|
||||
|
||||
#endif /* CGE_MATH_H */
|
||||
12
LICENSE
Normal file
12
LICENSE
Normal file
@@ -0,0 +1,12 @@
|
||||
Copyright (C) 2026 by blankhex me@blankhex.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
30
Line.c
Normal file
30
Line.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "CgeMath.h"
|
||||
#include <string.h>
|
||||
|
||||
#define EPSILON 0.00001f
|
||||
#define PI 3.14159265358979323846f
|
||||
|
||||
int CgeLineFromPoints(const float a[2], const float b[2], float out[3]) {
|
||||
float tmp[2];
|
||||
|
||||
tmp[0] = a[1] - b[1];
|
||||
tmp[1] = b[0] - a[0];
|
||||
if (CgeVec2fNormalEx(tmp, tmp) < EPSILON)
|
||||
return 0;
|
||||
|
||||
out[2] = CgeVec2fDot(tmp, a);
|
||||
memcpy(out, tmp, sizeof(tmp));
|
||||
return 1;
|
||||
}
|
||||
|
||||
float CgeLineDistance(const float line[3], const float point[2]) {
|
||||
return CgeVec2fDot(line, point) - line[2];
|
||||
}
|
||||
|
||||
void CgeLineClosestPoint(const float line[3], const float point[2],
|
||||
float out[2]) {
|
||||
float tmp[2];
|
||||
|
||||
CgeVec2fScale(line, CgeLineDistance(line, point), tmp);
|
||||
CgeVec2fSub(point, tmp, out);
|
||||
}
|
||||
24
Makefile.mingw
Normal file
24
Makefile.mingw
Normal file
@@ -0,0 +1,24 @@
|
||||
# MinGW Makefile for CgeMath
|
||||
|
||||
CC = gcc
|
||||
AR = ar
|
||||
CFLAGS = -std=c99 -O2 -Wall -Wextra
|
||||
ARFLAGS = rcs
|
||||
TARGET = libCgeMath.a
|
||||
|
||||
SOURCES = Box2f.c Box3f.c Line.c Mat3f.c Mat4f.c Misc.c Plane.c Quat4f.c \
|
||||
Ray2f.c Ray3f.c Vec2f.c Vec2i.c Vec3f.c Vec3i.c Vec4f.c Vec4i.c
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
%.o: %.c CgeMath.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
del $(OBJECTS) $(TARGET) 2>nul || exit 0
|
||||
34
Makefile.posix
Normal file
34
Makefile.posix
Normal file
@@ -0,0 +1,34 @@
|
||||
# POSIX Makefile for CgeMath
|
||||
|
||||
CC = gcc
|
||||
AR = ar
|
||||
CFLAGS = -std=c99 -O2 -Wall -Wextra -fPIC
|
||||
ARFLAGS = rcs
|
||||
TARGET = libCgeMath.a
|
||||
|
||||
SOURCES = Box2f.c Box3f.c Line.c Mat3f.c Mat4f.c Misc.c Plane.c Quat4f.c \
|
||||
Ray2f.c Ray3f.c Vec2f.c Vec2i.c Vec3f.c Vec3i.c Vec4f.c Vec4i.c
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
|
||||
.PHONY: all clean install
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
%.o: %.c CgeMath.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) $(TARGET)
|
||||
|
||||
install: $(TARGET)
|
||||
cp $(TARGET) /usr/local/lib/
|
||||
cp CgeMath.h /usr/local/include/
|
||||
ldconfig || echo "Run ldconfig manually if needed"
|
||||
|
||||
uninstall:
|
||||
rm -f /usr/local/lib/libCgeMath.a
|
||||
rm -f /usr/local/include/CgeMath.h
|
||||
ldconfig || true
|
||||
24
Makefile.win32
Normal file
24
Makefile.win32
Normal file
@@ -0,0 +1,24 @@
|
||||
# Makefile.win32 for MSVC (NMake)
|
||||
# Usage: Open "x86 Native Tools Command Prompt", then:
|
||||
# nmake -f Makefile.win32
|
||||
|
||||
CC = cl
|
||||
LIB = lib
|
||||
CFLAGS = /c /nologo /W3 /O2
|
||||
LIBFLAGS = /nologo
|
||||
TARGET = CgeMath.lib
|
||||
|
||||
SOURCES = Box2f.c Box3f.c Line.c Mat3f.c Mat4f.c Misc.c Plane.c Quat4f.c \
|
||||
Ray2f.c Ray3f.c Vec2f.c Vec2i.c Vec3f.c Vec3i.c Vec4f.c Vec4i.c
|
||||
OBJECTS = $(SOURCES:.c=.obj)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(LIB) $(LIBFLAGS) /OUT:$(TARGET) $(OBJECTS)
|
||||
|
||||
{.}.c{}.obj:
|
||||
$(CC) $(CFLAGS) /Fo$@ $<
|
||||
|
||||
clean:
|
||||
del $(OBJECTS) $(TARGET) 2>nul
|
||||
|
||||
.PHONY: clean
|
||||
167
Mat3f.c
Normal file
167
Mat3f.c
Normal file
@@ -0,0 +1,167 @@
|
||||
#include "CgeMath.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define EPSILON 0.00001f
|
||||
#define PI 3.14159265358979323846f
|
||||
#define SET_ROW(row, val) row[0] = row[1] = row[2] = val
|
||||
|
||||
void CgeMat3fIdentity(float out[9]) {
|
||||
static const float ident[9] = {
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
memcpy(out, ident, sizeof(ident));
|
||||
}
|
||||
|
||||
void CgeMat3fAdd(const float a[9], const float b[9], float out[9]) {
|
||||
CgeVec3fAdd(&a[0], &b[0], &out[0]);
|
||||
CgeVec3fAdd(&a[3], &b[3], &out[3]);
|
||||
CgeVec3fAdd(&a[6], &b[6], &out[6]);
|
||||
}
|
||||
|
||||
void CgeMat3fSub(const float a[9], const float b[9], float out[9]) {
|
||||
CgeVec3fSub(&a[0], &b[0], &out[0]);
|
||||
CgeVec3fSub(&a[3], &b[3], &out[3]);
|
||||
CgeVec3fSub(&a[6], &b[6], &out[6]);
|
||||
}
|
||||
|
||||
void CgeMat3fMul(const float a[9], const float b[9], float out[9]) {
|
||||
float tmp[9], row[3];
|
||||
|
||||
SET_ROW(row, b[0]); CgeVec3fMul(&a[0], row, &tmp[0]);
|
||||
SET_ROW(row, b[1]); CgeVec3fMulAdd(&a[3], row, &tmp[0], &tmp[0]);
|
||||
SET_ROW(row, b[2]); CgeVec3fMulAdd(&a[6], row, &tmp[0], &tmp[0]);
|
||||
|
||||
SET_ROW(row, b[3]); CgeVec3fMul(&a[0], row, &tmp[3]);
|
||||
SET_ROW(row, b[4]); CgeVec3fMulAdd(&a[3], row, &tmp[3], &tmp[3]);
|
||||
SET_ROW(row, b[5]); CgeVec3fMulAdd(&a[6], row, &tmp[3], &tmp[3]);
|
||||
|
||||
SET_ROW(row, b[6]); CgeVec3fMul(&a[0], row, &tmp[6]);
|
||||
SET_ROW(row, b[7]); CgeVec3fMulAdd(&a[3], row, &tmp[6], &tmp[6]);
|
||||
SET_ROW(row, b[8]); CgeVec3fMulAdd(&a[6], row, &tmp[6], &tmp[6]);
|
||||
|
||||
memcpy(out, tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
void CgeMat3fScale(const float a[9], float b, float out[9]) {
|
||||
CgeVec3fScale(&a[0], b, &out[0]);
|
||||
CgeVec3fScale(&a[3], b, &out[3]);
|
||||
CgeVec3fScale(&a[6], b, &out[6]);
|
||||
}
|
||||
|
||||
void CgeMat3fTranspose(const float in[9], float out[9]) {
|
||||
float tmp[9];
|
||||
|
||||
tmp[0] = in[0]; tmp[3] = in[1]; tmp[6] = in[2];
|
||||
tmp[1] = in[3]; tmp[4] = in[4]; tmp[7] = in[5];
|
||||
tmp[2] = in[6]; tmp[5] = in[7]; tmp[8] = in[8];
|
||||
|
||||
memcpy(out, tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
float CgeMat3fTrace(const float in[9]) {
|
||||
return in[0] + in[4] + in[8];
|
||||
}
|
||||
|
||||
float CgeMat3fDet(const float in[9]) {
|
||||
float a, b, c, result;
|
||||
|
||||
a = in[4] * in[8] - in[7] * in[5];
|
||||
b = in[1] * in[8] - in[7] * in[2];
|
||||
c = in[1] * in[5] - in[4] * in[2];
|
||||
|
||||
result = 0.0f;
|
||||
result += in[0] * a;
|
||||
result -= in[3] * b;
|
||||
result += in[6] * c;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int CgeMat3fInverse(const float in[9], float out[9]) {
|
||||
float a, b, c, det;
|
||||
float tmp[16];
|
||||
|
||||
a = in[4] * in[8] - in[7] * in[5];
|
||||
b = in[1] * in[8] - in[7] * in[2];
|
||||
c = in[1] * in[5] - in[4] * in[2];
|
||||
|
||||
tmp[0] = a;
|
||||
tmp[1] = -b;
|
||||
tmp[2] = c;
|
||||
|
||||
det = 0.0f;
|
||||
det += in[0] * tmp[0];
|
||||
det += in[3] * tmp[1];
|
||||
det += in[6] * tmp[2];
|
||||
|
||||
if (fabsf(det) < EPSILON)
|
||||
return 0;
|
||||
|
||||
a = in[3] * in[8] - in[6] * in[5];
|
||||
b = in[0] * in[8] - in[6] * in[2];
|
||||
c = in[0] * in[5] - in[3] * in[2];
|
||||
|
||||
tmp[3] = -a;
|
||||
tmp[4] = b;
|
||||
tmp[5] = -c;
|
||||
|
||||
a = in[3] * in[7] - in[6] * in[4];
|
||||
b = in[0] * in[7] - in[6] * in[1];
|
||||
c = in[0] * in[4] - in[3] * in[1];
|
||||
|
||||
tmp[6] = a;
|
||||
tmp[7] = -b;
|
||||
tmp[8] = c;
|
||||
|
||||
CgeMat3fScale(tmp, 1.0f / det, out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CgeMat3fFromScale(float x, float y, float out[9]) {
|
||||
CgeMat3fIdentity(out);
|
||||
out[0] = x;
|
||||
out[4] = y;
|
||||
}
|
||||
|
||||
void CgeMat3fFromTranslation(float x, float y, float out[9]) {
|
||||
CgeMat3fIdentity(out);
|
||||
out[6] = x;
|
||||
out[7] = y;
|
||||
}
|
||||
|
||||
void CgeMat3fFromRotation(float angle, float out[9]) {
|
||||
float c, s;
|
||||
|
||||
c = cosf(angle);
|
||||
s = sinf(angle);
|
||||
|
||||
CgeMat3fIdentity(out);
|
||||
out[0] = c;
|
||||
out[1] = s;
|
||||
out[3] = -s;
|
||||
out[4] = c;
|
||||
}
|
||||
|
||||
void CgeMat3fApplyVec3f(float a[9], float b[3], float out[3]) {
|
||||
float tmp[3], row[3];
|
||||
|
||||
SET_ROW(row, b[0]); CgeVec3fMul(&a[0], row, tmp);
|
||||
SET_ROW(row, b[1]); CgeVec3fMulAdd(&a[3], row, tmp, tmp);
|
||||
SET_ROW(row, b[2]); CgeVec3fMulAdd(&a[6], row, tmp, tmp);
|
||||
|
||||
memcpy(out, tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
void CgeMat3fApplyVec2f(float a[9], float b[2], float out[2]) {
|
||||
float tmp[3], row[3];
|
||||
|
||||
SET_ROW(row, b[0]); CgeVec3fMul(&a[0], row, tmp);
|
||||
SET_ROW(row, b[1]); CgeVec3fMulAdd(&a[3], row, tmp, tmp);
|
||||
SET_ROW(row, 1.0f); CgeVec3fMulAdd(&a[6], row, tmp, tmp);
|
||||
|
||||
memcpy(out, tmp, sizeof(float) * 2);
|
||||
}
|
||||
362
Mat4f.c
Normal file
362
Mat4f.c
Normal file
@@ -0,0 +1,362 @@
|
||||
#include "CgeMath.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define EPSILON 0.00001f
|
||||
#define PI 3.14159265358979323846f
|
||||
#define SET_ROW(row, val) row[0] = row[1] = row[2] = row[3] = val
|
||||
|
||||
void CgeMat4fIdentity(float out[16]) {
|
||||
const float ident[16] = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
memcpy(out, ident, sizeof(ident));
|
||||
}
|
||||
|
||||
void CgeMat4fAdd(const float a[16], const float b[16], float out[16]) {
|
||||
CgeVec4fAdd(&a[0], &b[0], &out[0]);
|
||||
CgeVec4fAdd(&a[4], &b[4], &out[4]);
|
||||
CgeVec4fAdd(&a[8], &b[8], &out[8]);
|
||||
CgeVec4fAdd(&a[12], &b[12], &out[12]);
|
||||
}
|
||||
|
||||
void CgeMat4fSub(const float a[16], const float b[16], float out[16]) {
|
||||
CgeVec4fSub(&a[0], &b[0], &out[0]);
|
||||
CgeVec4fSub(&a[4], &b[4], &out[4]);
|
||||
CgeVec4fSub(&a[8], &b[8], &out[8]);
|
||||
CgeVec4fSub(&a[12], &b[12], &out[12]);
|
||||
}
|
||||
|
||||
void CgeMat4fMul(const float a[16], const float b[16], float out[16]) {
|
||||
float tmp[16], row[4];
|
||||
|
||||
SET_ROW(row, b[0]); CgeVec4fMul(&a[0], row, &tmp[0]);
|
||||
SET_ROW(row, b[1]); CgeVec4fMulAdd(&a[4], row, &tmp[0], &tmp[0]);
|
||||
SET_ROW(row, b[2]); CgeVec4fMulAdd(&a[8], row, &tmp[0], &tmp[0]);
|
||||
SET_ROW(row, b[3]); CgeVec4fMulAdd(&a[12], row, &tmp[0], &tmp[0]);
|
||||
|
||||
SET_ROW(row, b[4]); CgeVec4fMul(&a[0], row, &tmp[4]);
|
||||
SET_ROW(row, b[5]); CgeVec4fMulAdd(&a[4], row, &tmp[4], &tmp[4]);
|
||||
SET_ROW(row, b[6]); CgeVec4fMulAdd(&a[8], row, &tmp[4], &tmp[4]);
|
||||
SET_ROW(row, b[7]); CgeVec4fMulAdd(&a[12], row, &tmp[4], &tmp[4]);
|
||||
|
||||
SET_ROW(row, b[8]); CgeVec4fMul(&a[0], row, &tmp[8]);
|
||||
SET_ROW(row, b[9]); CgeVec4fMulAdd(&a[4], row, &tmp[8], &tmp[8]);
|
||||
SET_ROW(row, b[10]); CgeVec4fMulAdd(&a[8], row, &tmp[8], &tmp[8]);
|
||||
SET_ROW(row, b[11]); CgeVec4fMulAdd(&a[12], row, &tmp[8], &tmp[8]);
|
||||
|
||||
SET_ROW(row, b[12]); CgeVec4fMul(&a[0], row, &tmp[12]);
|
||||
SET_ROW(row, b[13]); CgeVec4fMulAdd(&a[4], row, &tmp[12], &tmp[12]);
|
||||
SET_ROW(row, b[14]); CgeVec4fMulAdd(&a[8], row, &tmp[12], &tmp[12]);
|
||||
SET_ROW(row, b[15]); CgeVec4fMulAdd(&a[12], row, &tmp[12], &tmp[12]);
|
||||
|
||||
memcpy(out, tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
void CgeMat4fScale(const float a[16], float b, float out[16]) {
|
||||
CgeVec4fScale(&a[0], b, &out[0]);
|
||||
CgeVec4fScale(&a[4], b, &out[4]);
|
||||
CgeVec4fScale(&a[8], b, &out[8]);
|
||||
CgeVec4fScale(&a[12], b, &out[12]);
|
||||
}
|
||||
|
||||
void CgeMat4fTranspose(const float in[16], float out[16]) {
|
||||
float tmp[16];
|
||||
|
||||
tmp[0] = in[0]; tmp[4] = in[1]; tmp[8] = in[2]; tmp[12] = in[3];
|
||||
tmp[1] = in[4]; tmp[5] = in[5]; tmp[9] = in[6]; tmp[13] = in[7];
|
||||
tmp[2] = in[8]; tmp[6] = in[9]; tmp[10] = in[10]; tmp[14] = in[11];
|
||||
tmp[3] = in[12]; tmp[7] = in[13]; tmp[11] = in[14]; tmp[15] = in[15];
|
||||
|
||||
memcpy(out, tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
float CgeMat4fTrace(const float in[16]) {
|
||||
return in[0] + in[5] + in[10] + in[15];
|
||||
}
|
||||
|
||||
float CgeMat4fDet(const float in[16]) {
|
||||
float a, b, c, d, e, f, result;
|
||||
|
||||
a = in[2] * in[7] - in[3] * in[6];
|
||||
b = in[2] * in[11] - in[3] * in[10];
|
||||
c = in[2] * in[15] - in[3] * in[14];
|
||||
d = in[6] * in[11] - in[7] * in[10];
|
||||
e = in[6] * in[15] - in[7] * in[14];
|
||||
f = in[10] * in[15] - in[11] * in[14];
|
||||
|
||||
result = 0.0f;
|
||||
result += in[0] * (in[5] * f - in[9] * e + in[13] * d);
|
||||
result -= in[4] * (in[1] * f - in[9] * c + in[13] * b);
|
||||
result += in[8] * (in[1] * e - in[5] * c + in[13] * a);
|
||||
result -= in[12] * (in[1] * d - in[5] * b + in[9] * a);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int CgeMat4fInverse(const float in[16], float out[16]) {
|
||||
float a, b, c, d, e, f, det;
|
||||
float tmp[16];
|
||||
|
||||
a = in[2] * in[7] - in[3] * in[6];
|
||||
b = in[2] * in[11] - in[3] * in[10];
|
||||
c = in[2] * in[15] - in[3] * in[14];
|
||||
d = in[6] * in[11] - in[7] * in[10];
|
||||
e = in[6] * in[15] - in[7] * in[14];
|
||||
f = in[10] * in[15] - in[11] * in[14];
|
||||
|
||||
tmp[0] = (in[5] * f - in[9] * e + in[13] * d);
|
||||
tmp[1] = -(in[1] * f - in[9] * c + in[13] * b);
|
||||
tmp[2] = (in[1] * e - in[5] * c + in[13] * a);
|
||||
tmp[3] = -(in[1] * d - in[5] * b + in[9] * a);
|
||||
|
||||
det = 0.0f;
|
||||
det += in[0] * tmp[0];
|
||||
det += in[4] * tmp[1];
|
||||
det += in[8] * tmp[2];
|
||||
det += in[12] * tmp[3];
|
||||
|
||||
if (fabsf(det) < EPSILON)
|
||||
return 0;
|
||||
|
||||
tmp[4] = -(in[4] * f - in[8] * e + in[12] * d);
|
||||
tmp[5] = (in[0] * f - in[8] * c + in[12] * b);
|
||||
tmp[6] = -(in[0] * e - in[4] * c + in[12] * a);
|
||||
tmp[7] = (in[0] * d - in[4] * b + in[8] * a);
|
||||
|
||||
a = in[1] * in[7] - in[3] * in[5];
|
||||
b = in[1] * in[11] - in[3] * in[9];
|
||||
c = in[1] * in[15] - in[3] * in[13];
|
||||
d = in[5] * in[11] - in[7] * in[9];
|
||||
e = in[5] * in[15] - in[7] * in[13];
|
||||
f = in[9] * in[15] - in[11] * in[13];
|
||||
|
||||
tmp[8] = (in[4] * f - in[8] * e + in[12] * d);
|
||||
tmp[9] = -(in[0] * f - in[8] * c + in[12] * b);
|
||||
tmp[10] = (in[0] * e - in[4] * c + in[12] * a);
|
||||
tmp[11] = -(in[0] * d - in[4] * b + in[8] * a);
|
||||
|
||||
a = in[1] * in[6] - in[2] * in[5];
|
||||
b = in[1] * in[10] - in[2] * in[9];
|
||||
c = in[1] * in[14] - in[2] * in[13];
|
||||
d = in[5] * in[10] - in[6] * in[9];
|
||||
e = in[5] * in[14] - in[6] * in[13];
|
||||
f = in[9] * in[14] - in[10] * in[13];
|
||||
|
||||
tmp[12] = -(in[4] * f - in[8] * e + in[12] * d);
|
||||
tmp[13] = (in[0] * f - in[8] * c + in[12] * b);
|
||||
tmp[14] = -(in[0] * e - in[4] * c + in[12] * a);
|
||||
tmp[15] = (in[0] * d - in[4] * b + in[8] * a);
|
||||
|
||||
CgeMat4fScale(tmp, 1.0f / det, out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CgeMat4fFromScale(float x, float y, float z, float out[16]) {
|
||||
CgeMat4fIdentity(out);
|
||||
out[0] = x;
|
||||
out[5] = y;
|
||||
out[10] = z;
|
||||
}
|
||||
|
||||
void CgeMat4fFromTranslation(float x, float y, float z, float out[16]) {
|
||||
CgeMat4fIdentity(out);
|
||||
out[12] = x;
|
||||
out[13] = y;
|
||||
out[14] = z;
|
||||
}
|
||||
|
||||
void CgeMat4fFromRotationX(float angle, float out[16]) {
|
||||
float c, s;
|
||||
|
||||
c = cosf(angle);
|
||||
s = sinf(angle);
|
||||
|
||||
CgeMat4fIdentity(out);
|
||||
out[5] = c;
|
||||
out[6] = s;
|
||||
out[9] = -s;
|
||||
out[10] = c;
|
||||
}
|
||||
|
||||
void CgeMat4fFromRotationY(float angle, float out[16]) {
|
||||
float c, s;
|
||||
|
||||
c = cosf(angle);
|
||||
s = sinf(angle);
|
||||
|
||||
CgeMat4fIdentity(out);
|
||||
out[0] = c;
|
||||
out[2] = -s;
|
||||
out[8] = s;
|
||||
out[10] = c;
|
||||
}
|
||||
|
||||
void CgeMat4fFromRotationZ(float angle, float out[16]) {
|
||||
float c, s;
|
||||
|
||||
c = cosf(angle);
|
||||
s = sinf(angle);
|
||||
|
||||
CgeMat4fIdentity(out);
|
||||
out[0] = c;
|
||||
out[1] = s;
|
||||
out[4] = -s;
|
||||
out[5] = c;
|
||||
}
|
||||
|
||||
void CgeMat4fFromAxis(const float axis[3], float angle, float out[16]) {
|
||||
float x, y, z, length;
|
||||
float c, s, moc, xx, xy, xz, yy, yz, zz;
|
||||
|
||||
length = CgeVec3fLength(axis);
|
||||
CgeMat4fIdentity(out);
|
||||
|
||||
if (fabsf(length) < EPSILON)
|
||||
return;
|
||||
|
||||
x = axis[0] / length;
|
||||
y = axis[1] / length;
|
||||
z = axis[2] / length;
|
||||
|
||||
c = cosf(angle);
|
||||
s = sinf(angle);
|
||||
moc = 1.0f - c;
|
||||
|
||||
xx = x * x;
|
||||
xy = x * y;
|
||||
xz = x * z;
|
||||
yy = y * y;
|
||||
yz = y * z;
|
||||
zz = z * z;
|
||||
|
||||
out[0] = c + xx * moc;
|
||||
out[1] = xy * moc + z * s;
|
||||
out[2] = xz * moc - y * s;
|
||||
|
||||
out[4] = xy * moc - z * s;
|
||||
out[5] = c + yy * moc;
|
||||
out[6] = yz * moc + x * s;
|
||||
|
||||
out[8] = xz * moc + y * s;
|
||||
out[9] = yz * moc - x * s;
|
||||
out[10] = c + zz * moc;
|
||||
}
|
||||
|
||||
void CgeMat4fFromEuler(float roll, float pitch, float yaw, float out[16]) {
|
||||
float rs, rc, ys, yc, ps, pc;
|
||||
|
||||
rs = sinf(roll);
|
||||
rc = cosf(roll);
|
||||
ps = sinf(pitch);
|
||||
pc = cosf(pitch);
|
||||
ys = sinf(yaw);
|
||||
yc = cosf(yaw);
|
||||
|
||||
CgeMat4fIdentity(out);
|
||||
out[0] = pc * yc;
|
||||
out[1] = pc * ys;
|
||||
out[2] = -ps;
|
||||
out[4] = ps * rs * yc - rc * ys;
|
||||
out[5] = ps * rs * ys + rc * yc;
|
||||
out[6] = pc * rs;
|
||||
out[8] = rs * ys + ps * rc * yc;
|
||||
out[9] = ps * rc * ys - rs * yc;
|
||||
out[10] = pc * rc;
|
||||
}
|
||||
|
||||
void CgeMat4fFromQuat4f(const float in[4], float out[16]) {
|
||||
CgeQuat4fToMat4f(in, out);
|
||||
}
|
||||
|
||||
void CgeMat4fFromOrtho(float xMin, float xMax, float yMin, float yMax,
|
||||
float zMin, float zMax, float out[16]) {
|
||||
float dx, dy, dz;
|
||||
|
||||
dx = xMax - xMin;
|
||||
dy = yMax - yMin;
|
||||
dz = zMax - zMin;
|
||||
|
||||
CgeMat4fIdentity(out);
|
||||
|
||||
out[0] = 2.0f / dx;
|
||||
out[5] = 2.0f / dy;
|
||||
out[10] = -2.0f / dz;
|
||||
out[12] = -(xMax + xMin) / dx;
|
||||
out[13] = -(yMax + yMin) / dy;
|
||||
out[14] = -(zMax + zMin) / dz;
|
||||
}
|
||||
|
||||
void CgeMat4fFromFrustum(float fov, float aspect, float zMin, float zMax,
|
||||
float out[16]) {
|
||||
float t, dz;
|
||||
|
||||
dz = zMax - zMin;
|
||||
t = tanf(fov / 2.0f);
|
||||
|
||||
CgeMat4fIdentity(out);
|
||||
|
||||
out[0] = 1.0f / (aspect * t);
|
||||
out[5] = 1.0f / t;
|
||||
out[10] = -(zMax + zMin) / dz;
|
||||
out[11] = -1.0f;
|
||||
out[14] = -(2.0f * zMax * zMin) / dz;
|
||||
out[15] = 0.0f;
|
||||
}
|
||||
|
||||
void CgeMat4fFromLookAt(const float position[3], const float at[3],
|
||||
const float up[3], float out[16]) {
|
||||
float cameraDir[3], cameraRight[3], cameraUp[3];
|
||||
|
||||
CgeVec3fSub(position, at, cameraDir);
|
||||
CgeVec3fNormal(cameraDir, cameraDir);
|
||||
CgeVec3fCross(up, cameraDir, cameraRight);
|
||||
CgeVec3fNormal(cameraRight, cameraRight);
|
||||
CgeVec3fCross(cameraDir, cameraRight, cameraUp);
|
||||
|
||||
out[0] = cameraRight[0];
|
||||
out[1] = cameraUp[0];
|
||||
out[2] = cameraDir[0];
|
||||
out[3] = 0.0f;
|
||||
|
||||
out[4] = cameraRight[1];
|
||||
out[5] = cameraUp[1];
|
||||
out[6] = cameraDir[1];
|
||||
out[7] = 0.0f;
|
||||
|
||||
out[8] = cameraRight[2];
|
||||
out[9] = cameraUp[2];
|
||||
out[10] = cameraDir[2];
|
||||
out[11] = 0.0f;
|
||||
|
||||
out[12] = -CgeVec3fDot(cameraRight, position);
|
||||
out[13] = -CgeVec3fDot(cameraUp, position);
|
||||
out[14] = -CgeVec3fDot(cameraDir, position);
|
||||
out[15] = 1.0f;
|
||||
}
|
||||
|
||||
void CgeMat4fApplyVec4f(const float a[16], const float b[4], float out[4]) {
|
||||
float tmp[4], row[4];
|
||||
|
||||
SET_ROW(row, b[0]); CgeVec4fMul(&a[0], row, tmp);
|
||||
SET_ROW(row, b[1]); CgeVec4fMulAdd(&a[4], row, tmp, tmp);
|
||||
SET_ROW(row, b[2]); CgeVec4fMulAdd(&a[8], row, tmp, tmp);
|
||||
SET_ROW(row, b[3]); CgeVec4fMulAdd(&a[12], row, tmp, tmp);
|
||||
|
||||
memcpy(out, tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
void CgeMat4fApplyVec3f(const float a[16], const float b[3], float out[3]) {
|
||||
float tmp[4], row[4];
|
||||
|
||||
SET_ROW(row, b[0]); CgeVec4fMul(&a[0], row, tmp);
|
||||
SET_ROW(row, b[1]); CgeVec4fMulAdd(&a[4], row, tmp, tmp);
|
||||
SET_ROW(row, b[2]); CgeVec4fMulAdd(&a[8], row, tmp, tmp);
|
||||
SET_ROW(row, 1.0f); CgeVec4fMulAdd(&a[12], row, tmp, tmp);
|
||||
|
||||
memcpy(out, tmp, sizeof(float) * 3);
|
||||
}
|
||||
27
Misc.c
Normal file
27
Misc.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "CgeMath.h"
|
||||
|
||||
float CgeLerpf(float a, float b, float t) {
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
void CgeTriangle3fBarycentric(const float a[3], const float b[3],
|
||||
const float c[3], const float point[3],
|
||||
float out[3]) {
|
||||
float tmp1[3], tmp2[3], tmp3[3];
|
||||
float t11, t12, t22, t31, t32, denom;
|
||||
|
||||
CgeVec3fSub(b, a, tmp1);
|
||||
CgeVec3fSub(c, a, tmp2);
|
||||
CgeVec3fSub(point, a, tmp3);
|
||||
|
||||
t11 = CgeVec3fDot(tmp1, tmp1);
|
||||
t12 = CgeVec3fDot(tmp1, tmp2);
|
||||
t22 = CgeVec3fDot(tmp2, tmp2);
|
||||
t31 = CgeVec3fDot(tmp3, tmp1);
|
||||
t32 = CgeVec3fDot(tmp3, tmp2);
|
||||
denom = 1.0f / (t11 * t22 - t12 * t12);
|
||||
|
||||
out[1] = (t22 * t31 - t12 * t32) * denom;
|
||||
out[2] = (t11 * t32 - t12 * t31) * denom;
|
||||
out[0] = 1.0f - out[1] - out[2];
|
||||
}
|
||||
32
Plane.c
Normal file
32
Plane.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "CgeMath.h"
|
||||
#include <string.h>
|
||||
|
||||
#define EPSILON 0.00001f
|
||||
#define PI 3.14159265358979323846f
|
||||
|
||||
int CgePlaneFromPoints(const float a[3], const float b[3], const float c[3],
|
||||
float out[4]) {
|
||||
float tmp1[3], tmp2[3];
|
||||
|
||||
CgeVec3fSub(b, a, tmp1);
|
||||
CgeVec3fSub(c, a, tmp2);
|
||||
CgeVec3fCross(tmp2, tmp1, tmp1);
|
||||
if (CgeVec3fNormalEx(tmp1, tmp1) < EPSILON)
|
||||
return 0;
|
||||
|
||||
out[3] = CgeVec3fDot(a, tmp1);
|
||||
memcpy(out, tmp1, sizeof(tmp1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
float CgePlaneDistance(const float plane[4], const float point[3]) {
|
||||
return CgeVec3fDot(plane, point) - plane[3];
|
||||
}
|
||||
|
||||
void CgePlaneClosestPoint(const float plane[4], const float point[3],
|
||||
float out[3]) {
|
||||
float tmp[3];
|
||||
|
||||
CgeVec3fScale(plane, CgePlaneDistance(plane, point), tmp);
|
||||
CgeVec3fSub(point, tmp, out);
|
||||
}
|
||||
160
Quat4f.c
Normal file
160
Quat4f.c
Normal file
@@ -0,0 +1,160 @@
|
||||
#include "CgeMath.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define EPSILON 0.00001f
|
||||
#define PI 3.14159265358979323846f
|
||||
|
||||
void CgeQuat4fIdentity(float out[4]) {
|
||||
static const float ident[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
memcpy(out, ident, sizeof(ident));
|
||||
}
|
||||
|
||||
void CgeQuat4fConjugate(const float in[4], float out[4]) {
|
||||
out[0] = -in[0];
|
||||
out[1] = -in[1];
|
||||
out[2] = -in[2];
|
||||
out[3] = in[3];
|
||||
}
|
||||
|
||||
void CgeQuat4fInverse(const float in[4], float out[4]) {
|
||||
float dot;
|
||||
|
||||
dot = CgeVec4fDot(in, in);
|
||||
CgeQuat4fConjugate(in, out);
|
||||
CgeQuat4fScale(out, 1.0f / dot, out);
|
||||
}
|
||||
|
||||
void CgeQuat4fMul(const float a[4], const float b[4], float out[4]) {
|
||||
float tmp1[4], tmp2[4], tmp3[4];
|
||||
float w;
|
||||
|
||||
w = a[3] * b[3] - CgeVec3fDot(a, b);
|
||||
CgeVec4fScale(a, b[3], tmp1);
|
||||
CgeVec4fScale(b, a[3], tmp2);
|
||||
CgeVec3fCross(a, b, tmp3);
|
||||
CgeVec4fAdd(tmp1, tmp2, out);
|
||||
CgeVec4fAdd(tmp3, out, out);
|
||||
out[3] = w;
|
||||
}
|
||||
|
||||
void CgeQuat4fSlerp(const float a[4], const float b[4], float t, float out[4]) {
|
||||
float angle, denom;
|
||||
float from[4], to[4];
|
||||
|
||||
angle = acosf(CgeVec4fDot(a, b));
|
||||
if (fabsf(angle) < EPSILON) {
|
||||
CgeVec4fLerp(a, b, t, out);
|
||||
return;
|
||||
}
|
||||
|
||||
denom = 1.0f / sinf(angle);
|
||||
CgeVec4fScale(a, sinf((1 - t) * angle) * denom, from);
|
||||
CgeVec4fScale(b, sinf(t * angle) * denom, to);
|
||||
CgeVec4fAdd(from, to, out);
|
||||
}
|
||||
|
||||
void CgeQuat4fFromEuler(float roll, float pitch, float yaw, float out[4]) {
|
||||
float cr, cp, cy, sr, sp, sy;
|
||||
|
||||
cr = cosf(roll / 2.0f);
|
||||
cp = cosf(pitch / 2.0f);
|
||||
cy = cosf(yaw / 2.0f);
|
||||
sr = sinf(roll / 2.0f);
|
||||
sp = sinf(pitch / 2.0f);
|
||||
sy = sinf(yaw / 2.0f);
|
||||
|
||||
out[0] = sr * cp * cy - cr * sp * sy;
|
||||
out[1] = cr * sp * cy + sr * cp * sy;
|
||||
out[2] = cr * cp * sy - sr * sp * cy;
|
||||
out[3] = cr * cp * cy + sr * sp * sy;
|
||||
}
|
||||
|
||||
void CgeQuat4fFromAxis(const float axis[3], float angle, float out[4]) {
|
||||
float c, s;
|
||||
|
||||
c = cosf(angle / 2.0f);
|
||||
s = sinf(angle / 2.0f);
|
||||
|
||||
out[0] = axis[0] * s;
|
||||
out[1] = axis[1] * s;
|
||||
out[2] = axis[2] * s;
|
||||
out[3] = c;
|
||||
}
|
||||
|
||||
void CgeQuat4fToEuler(const float in[4], float *roll, float *pitch,
|
||||
float *yaw) {
|
||||
float ww, xw, yw, zw, xx, xy, xz, yy, yz, zz, angle;
|
||||
|
||||
xx = in[0] * in[0];
|
||||
xy = in[0] * in[1];
|
||||
xz = in[0] * in[2];
|
||||
xw = in[0] * in[3];
|
||||
yy = in[1] * in[1];
|
||||
yz = in[1] * in[2];
|
||||
yw = in[1] * in[3];
|
||||
zz = in[2] * in[2];
|
||||
zw = in[2] * in[3];
|
||||
ww = in[3] * in[3];
|
||||
|
||||
angle = 2.0f * (yw - xz);
|
||||
if (angle > 1.0f)
|
||||
angle = 1.0f;
|
||||
if (angle < -1.0f)
|
||||
angle = -1.0f;
|
||||
|
||||
*pitch = asinf(angle);
|
||||
|
||||
if (fabsf(*pitch - (PI / 2.0f)) < EPSILON) {
|
||||
*roll = 0.0f;
|
||||
*yaw = -2.0f * atan2f(in[0], in[3]);
|
||||
} else if (fabsf(*pitch - (PI / -2.0f)) < EPSILON) {
|
||||
*roll = 0.0f;
|
||||
*yaw = 2.0f * atan2f(in[0], in[3]);
|
||||
} else {
|
||||
*roll = atan2f(2.0f * (xw + yz), ww - xx - yy + zz);
|
||||
*yaw = atan2f(2.0f * (zw + xy), ww + xx - yy - zz);
|
||||
}
|
||||
}
|
||||
|
||||
void CgeQuat4fToAxis(const float in[4], float axis[3], float *angle) {
|
||||
*angle = 2.0f * acosf(in[3]);
|
||||
|
||||
if (fabsf(*angle) < EPSILON) {
|
||||
axis[0] = 1.0f;
|
||||
axis[1] = 0.0f;
|
||||
axis[2] = 0.0f;
|
||||
} else {
|
||||
float tmp;
|
||||
|
||||
tmp = sqrtf(1.0f - in[3] * in[3]);
|
||||
axis[0] = in[0] / tmp;
|
||||
axis[1] = in[1] / tmp;
|
||||
axis[2] = in[2] / tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void CgeQuat4fToMat4f(const float in[4], float out[16]) {
|
||||
float xx, xy, xz, xw, yy, yz, yw, zz, zw;
|
||||
|
||||
xx = in[0] * in[0];
|
||||
xy = in[0] * in[1];
|
||||
xz = in[0] * in[2];
|
||||
xw = in[0] * in[3];
|
||||
yy = in[1] * in[1];
|
||||
yz = in[1] * in[2];
|
||||
yw = in[1] * in[3];
|
||||
zz = in[2] * in[2];
|
||||
zw = in[2] * in[3];
|
||||
|
||||
CgeMat4fIdentity(out);
|
||||
out[0] = 1.0f - 2.0f * (yy + zz);
|
||||
out[1] = 2.0f * (xy + zw);
|
||||
out[2] = 2.0f * (xz - yw);
|
||||
out[4] = 2.0f * (xy - zw);
|
||||
out[5] = 1.0f - 2.0f * (xx + zz);
|
||||
out[6] = 2.0f * (yz + xw);
|
||||
out[8] = 2.0f * (xz + yw);
|
||||
out[9] = 2.0f * (yz - xw);
|
||||
out[10] = 1.0f - 2.0f * (xx + yy);
|
||||
}
|
||||
62
README.md
Normal file
62
README.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# CgeMath - Lightweight Math Library for C
|
||||
|
||||
A compact, dependency-free C library for 2D/3D math, linear algebra, and
|
||||
computational geometry operations.
|
||||
|
||||
## Features
|
||||
|
||||
- 2D/3D vector operations: addition, subtraction, scaling, dot product, cross product
|
||||
- Vector normalization, length computation, linear interpolation (lerp)
|
||||
- 3x3 and 4x4 matrix operations: multiplication, addition, transpose, inverse, determinant
|
||||
- Matrix utilities: identity, scaling, translation, rotation (axis and Euler)
|
||||
- Projection matrices: orthographic, frustum, perspective from FOV
|
||||
- View matrix from position, target, and up vector
|
||||
- Quaternion operations: multiplication, conjugate, inverse, slerp, lerp
|
||||
- Quaternion to/from rotation matrix and Euler angles
|
||||
- Axis-aligned bounding box (AABB) operations in 2D and 3D: union, intersection, containment
|
||||
- Point enclosure: compute bounding box from point set
|
||||
- Line and plane geometry: construction from points, distance to point, closest point
|
||||
- Ray, segment, and line intersection tests in 2D and 3D
|
||||
- Ray-triangle and segment-triangle intersection
|
||||
- Barycentric coordinate computation for 2D and 3D triangles
|
||||
- Integer vector operations for 2D, 3D, 4D: add, subtract, min, max
|
||||
|
||||
## Build Systems
|
||||
|
||||
- CMake - supports Linux, macOS, Windows (MSVC, MinGW)
|
||||
- Makefile.posix - for GCC/Clang on POSIX systems
|
||||
- Makefile.mingw - for MinGW on Windows
|
||||
- Makefile.win32 - for MSVC with NMake
|
||||
|
||||
Builds a static library. No shared library or external dependencies.
|
||||
|
||||
## Usage Example
|
||||
|
||||
```c
|
||||
#include "CgeMath.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
float pos[] = {1.0f, 0.0f, 0.0f};
|
||||
float scale[] = {2.0f, 2.0f, 2.0f};
|
||||
float mat[16], result[3];
|
||||
|
||||
CgeMat4fIdentity(mat);
|
||||
CgeMat4fFromScale(scale[0], scale[1], scale[2], mat);
|
||||
CgeMat4fApplyVec3f(mat, pos, result);
|
||||
|
||||
printf("Transformed: (%f, %f, %f)\n",
|
||||
result[0], result[1], result[2]);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## Portability
|
||||
|
||||
- Written in C89 + stdint.h
|
||||
- No dynamic memory allocation
|
||||
- No external dependencies
|
||||
|
||||
## License
|
||||
|
||||
0BSD - a permissive license with no attribution required.
|
||||
193
Ray2f.c
Normal file
193
Ray2f.c
Normal file
@@ -0,0 +1,193 @@
|
||||
#include "CgeMath.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define EPSILON 0.00001f
|
||||
#define PI 3.14159265358979323846f
|
||||
|
||||
int CgeRay2fIntersectLine(const float start[2], const float direction[2],
|
||||
const float line[3], float *t, float out[2]) {
|
||||
float tmp1[2];
|
||||
float denom, time;
|
||||
|
||||
/* Calculate intersection time */
|
||||
denom = CgeVec2fDot(direction, line);
|
||||
time = (line[2] - CgeVec2fDot(line, start)) / denom;
|
||||
|
||||
/* Check for ray/plane parallel to each other or point is behing the ray. */
|
||||
if (fabsf(denom) < EPSILON || time < 0.0f)
|
||||
return 0;
|
||||
|
||||
/* Compute intersection point */
|
||||
CgeVec2fScale(direction, time, tmp1);
|
||||
CgeVec2fAdd(start, tmp1, out);
|
||||
*t = time;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeRay2fIntersectTime(const float aStart[2], const float aDirection[2],
|
||||
const float bStart[2], const float bDirection[2],
|
||||
float *time1, float *time2) {
|
||||
float tmp1[2], tmp2[2], tmp3[2];
|
||||
float denom;
|
||||
|
||||
/* Rotate directions by 90 degrees and caluclate denom */
|
||||
tmp1[0] = -aDirection[1]; tmp1[1] = aDirection[0];
|
||||
tmp2[0] = -bDirection[1]; tmp2[1] = bDirection[0];
|
||||
denom = CgeVec2fDot(tmp1, bDirection);
|
||||
|
||||
if (fabsf(denom) < EPSILON)
|
||||
return 0;
|
||||
|
||||
/* Calculate segments offset and intersection times */
|
||||
CgeVec2fSub(aStart, bStart, tmp3);
|
||||
*time1 = CgeVec2fDot(tmp3, tmp2) / denom;
|
||||
*time2 = CgeVec2fDot(tmp3, tmp1) / denom;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeRay2fIntersectRay(const float aStart[2], const float aDirection[2],
|
||||
const float bStart[2], const float bDirection[2],
|
||||
float *t, float out[2]) {
|
||||
float tmp[2];
|
||||
float time1, time2;
|
||||
|
||||
if (CgeRay2fIntersectTime(aStart, aDirection, bStart, bDirection, &time1, &time2))
|
||||
return 0;
|
||||
|
||||
if (time1 < 0.0f || time2 < 0.0f)
|
||||
return 0;
|
||||
|
||||
CgeVec2fScale(aDirection, time1, tmp);
|
||||
CgeVec2fAdd(aStart, tmp, out);
|
||||
*t = time1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeRay2fIntersectSegment(const float aStart[2], const float aDirection[2],
|
||||
const float bStart[2], const float bEnd[2],
|
||||
float *t, float out[2]) {
|
||||
float tmp[2];
|
||||
float time1, time2;
|
||||
|
||||
CgeVec2fSub(bEnd, bStart, tmp);
|
||||
if (CgeRay2fIntersectTime(aStart, aDirection, bStart, tmp, &time1, &time2))
|
||||
return 0;
|
||||
|
||||
if (time1 < 0.0f || time2 < 0.0f || time2 > 1.0f)
|
||||
return 0;
|
||||
|
||||
CgeVec2fScale(aDirection, time1, tmp);
|
||||
CgeVec2fAdd(aStart, tmp, out);
|
||||
*t = time1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeSegment2fIntersectLine(const float start[2], const float end[2],
|
||||
const float line[3], float *t, float out[2]) {
|
||||
float tmp[2];
|
||||
float denom, time;
|
||||
|
||||
/* Calculate intersection time */
|
||||
CgeVec2fSub(end, start, tmp);
|
||||
denom = CgeVec2fDot(tmp, line);
|
||||
time = (line[2] - CgeVec2fDot(line, start)) / denom;
|
||||
|
||||
/* Check for ray/plane parallel to each other or point is behing the ray. */
|
||||
if (fabsf(denom) < EPSILON || time < 0.0f || time > 1.0f)
|
||||
return 0;
|
||||
|
||||
/* Compute intersection point */
|
||||
CgeVec2fScale(tmp, time, tmp);
|
||||
CgeVec2fAdd(start, tmp, out);
|
||||
*t = time;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeSegment2fIntersectSegment(const float aStart[2], const float aEnd[2],
|
||||
const float bStart[2], const float bEnd[2],
|
||||
float *t, float out[2]) {
|
||||
float tmp1[2], tmp2[2];
|
||||
float time1, time2;
|
||||
|
||||
CgeVec2fSub(aEnd, aStart, tmp1);
|
||||
CgeVec2fSub(bEnd, bStart, tmp2);
|
||||
if (CgeRay2fIntersectTime(aStart, tmp1, bStart, tmp2, &time1, &time2))
|
||||
return 0;
|
||||
|
||||
if (time1 < 0.0f || time1 > 1.0f || time2 < 0.0f || time2 > 1.0f)
|
||||
return 0;
|
||||
|
||||
CgeVec2fLerp(aStart, aEnd, time1, out);
|
||||
*t = time1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeRay2fIntersectBox2f(const float aStart[2], const float aDirection[2],
|
||||
const float bMin[2], const float bMax[2],
|
||||
float *t, float out[2]) {
|
||||
float timeNear, timeFar, hitNear, hitFar, denom, tmp;
|
||||
int i;
|
||||
|
||||
timeNear = -1.0f / 0.0f;
|
||||
timeFar = 1.0f / 0.0f;
|
||||
|
||||
/* Check if origin inside box */
|
||||
if (!CgeBox2fContains(bMin, bMax, aStart)) {
|
||||
memcpy(out, aStart, sizeof(float) * 2);
|
||||
*t = 0.0f;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check each axis for the minimal and maximum intersection time */
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (fabsf(aDirection[i]) < EPSILON) {
|
||||
if (aStart[i] < bMin[i] || aStart[i] > bMax[i])
|
||||
return 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
denom = 1.0f / aDirection[i];
|
||||
hitNear = (bMin[i] - aStart[i]) * denom;
|
||||
hitFar = (bMax[i] - aStart[i]) * denom;
|
||||
|
||||
if (hitNear > hitFar) {
|
||||
tmp = hitNear;
|
||||
hitNear = hitFar;
|
||||
hitFar = tmp;
|
||||
}
|
||||
|
||||
if (hitNear > timeNear)
|
||||
timeNear = hitNear;
|
||||
if (hitFar < timeFar)
|
||||
timeFar = hitFar;
|
||||
|
||||
if (timeNear > timeFar || timeFar < 0.0f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
out[0] = aStart[0] + aDirection[0] * timeNear;
|
||||
out[1] = aStart[1] + aDirection[1] * timeNear;
|
||||
*t = timeNear;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeSegment2fIntersectBox2f(const float aStart[2], const float aEnd[2],
|
||||
const float bMin[2], const float bMax[2],
|
||||
float *t, float out[2]) {
|
||||
float tmp[3];
|
||||
float time;
|
||||
|
||||
CgeVec2fSub(aEnd, aStart, tmp);
|
||||
if (CgeRay2fIntersectBox2f(aStart, tmp, bMin, bMax, &time, out))
|
||||
return 0;
|
||||
|
||||
if (time > 1.0f)
|
||||
return 0;
|
||||
|
||||
*t = time;
|
||||
return 1;
|
||||
}
|
||||
195
Ray3f.c
Normal file
195
Ray3f.c
Normal file
@@ -0,0 +1,195 @@
|
||||
#include "CgeMath.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define EPSILON 0.00001f
|
||||
#define PI 3.14159265358979323846f
|
||||
|
||||
int CgeRay3fIntersectPlane(const float start[3], const float direction[3],
|
||||
const float plane[4], float *t, float out[3]) {
|
||||
float tmp1[3];
|
||||
float denom, time;
|
||||
|
||||
/* Calculate intersection time */
|
||||
denom = CgeVec3fDot(direction, plane);
|
||||
time = (plane[3] - CgeVec3fDot(plane, start)) / denom;
|
||||
|
||||
/* Check for ray/plane parallel to each other or point is behing the ray. */
|
||||
if (fabsf(denom) < EPSILON || time < 0.0f)
|
||||
return 0;
|
||||
|
||||
/* Compute intersection point */
|
||||
CgeVec3fScale(direction, time, tmp1);
|
||||
CgeVec3fAdd(start, tmp1, out);
|
||||
*t = time;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeRay3fIntersectTriangle(const float start[3], const float direction[3],
|
||||
const float a[3], const float b[3],
|
||||
const float c[3], float *t, float out[3]) {
|
||||
float plane[4];
|
||||
float tmp1[3], tmp2[3], tmp3[3];
|
||||
float time;
|
||||
|
||||
/* Compute plane */
|
||||
if (CgePlaneFromPoints(a, b, c, plane))
|
||||
return 0;
|
||||
|
||||
/* Compute intersection point in ray against plane */
|
||||
if (CgeRay3fIntersectPlane(start, direction, plane, &time, tmp3))
|
||||
return 0;
|
||||
|
||||
/* Check if point inside rectangle */
|
||||
CgeVec3fSub(b, a, tmp1);
|
||||
CgeVec3fSub(tmp3, a, tmp2);
|
||||
CgeVec3fCross(tmp2, tmp1, tmp1);
|
||||
if (CgeVec3fDot(tmp1, plane) < 0.0f)
|
||||
return 0;
|
||||
|
||||
CgeVec3fSub(c, b, tmp1);
|
||||
CgeVec3fSub(tmp3, b, tmp2);
|
||||
CgeVec3fCross(tmp2, tmp1, tmp1);
|
||||
if (CgeVec3fDot(tmp1, plane) < 0.0f)
|
||||
return 0;
|
||||
|
||||
CgeVec3fSub(a, c, tmp1);
|
||||
CgeVec3fSub(tmp3, c, tmp2);
|
||||
CgeVec3fCross(tmp2, tmp1, tmp1);
|
||||
if (CgeVec3fDot(tmp1, plane) < 0.0f)
|
||||
return 0;
|
||||
|
||||
/* Copy intersection point */
|
||||
memcpy(out, tmp3, sizeof(tmp3));
|
||||
*t = time;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeSegment3fIntersectPlane(const float start[3], const float end[3],
|
||||
const float plane[4], float *t, float out[3]) {
|
||||
float tmp[3];
|
||||
float denom, time;
|
||||
|
||||
/* Calculate intersection time */
|
||||
CgeVec3fSub(end, start, tmp);
|
||||
denom = CgeVec3fDot(tmp, plane);
|
||||
time = (plane[3] - CgeVec3fDot(plane, start)) / denom;
|
||||
|
||||
/* Check for ray/plane parallel to each other or point is behing the ray. */
|
||||
if (fabsf(denom) < EPSILON || time < 0.0f || time > 1.0f)
|
||||
return 0;
|
||||
|
||||
/* Compute intersection point */
|
||||
CgeVec3fScale(tmp, time, tmp);
|
||||
CgeVec3fAdd(start, tmp, out);
|
||||
*t = time;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeSegment3fIntersectTriangle(const float start[3], const float end[3],
|
||||
const float a[3], const float b[3],
|
||||
const float c[3], float *t, float out[3]) {
|
||||
float plane[4];
|
||||
float tmp1[3], tmp2[3], tmp3[3];
|
||||
float time;
|
||||
|
||||
/* Compute plane */
|
||||
if (CgePlaneFromPoints(a, b, c, plane))
|
||||
return 0;
|
||||
|
||||
/* Compute intersection point in ray against plane */
|
||||
if (CgeSegment3fIntersectPlane(start, end, plane, &time, tmp3))
|
||||
return 0;
|
||||
|
||||
/* Check if point inside rectangle */
|
||||
CgeVec3fSub(b, a, tmp1);
|
||||
CgeVec3fSub(tmp3, a, tmp2);
|
||||
CgeVec3fCross(tmp2, tmp1, tmp1);
|
||||
if (CgeVec3fDot(tmp1, plane) < 0.0f)
|
||||
return 0;
|
||||
|
||||
CgeVec3fSub(c, b, tmp1);
|
||||
CgeVec3fSub(tmp3, b, tmp2);
|
||||
CgeVec3fCross(tmp2, tmp1, tmp1);
|
||||
if (CgeVec3fDot(tmp1, plane) < 0.0f)
|
||||
return 0;
|
||||
|
||||
CgeVec3fSub(a, c, tmp1);
|
||||
CgeVec3fSub(tmp3, c, tmp2);
|
||||
CgeVec3fCross(tmp2, tmp1, tmp1);
|
||||
if (CgeVec3fDot(tmp1, plane) < 0.0f)
|
||||
return 0;
|
||||
|
||||
/* Copy intersection point */
|
||||
memcpy(out, tmp3, sizeof(tmp3));
|
||||
*t = time;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeRay3fIntersectBox3f(const float aStart[3], const float aDirection[3],
|
||||
const float bMin[3], const float bMax[3], float *t,
|
||||
float out[3]) {
|
||||
float timeNear, timeFar, hitNear, hitFar, denom, tmp;
|
||||
int i;
|
||||
|
||||
timeNear = -1.0f / 0.0f;
|
||||
timeFar = 1.0f / 0.0f;
|
||||
|
||||
/* Check if origin inside box */
|
||||
if (!CgeBox3fContains(bMin, bMax, aStart)) {
|
||||
memcpy(out, aStart, sizeof(float) * 3);
|
||||
*t = 0.0f;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check each axis for the minimal and maximum intersection time */
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (fabsf(aDirection[i]) < EPSILON) {
|
||||
if (aStart[i] < bMin[i] || aStart[i] > bMax[i])
|
||||
return 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
denom = 1.0f / aDirection[i];
|
||||
hitNear = (bMin[i] - aStart[i]) * denom;
|
||||
hitFar = (bMax[i] - aStart[i]) * denom;
|
||||
|
||||
if (hitNear > hitFar) {
|
||||
tmp = hitNear;
|
||||
hitNear = hitFar;
|
||||
hitFar = tmp;
|
||||
}
|
||||
|
||||
if (hitNear > timeNear)
|
||||
timeNear = hitNear;
|
||||
if (hitFar < timeFar)
|
||||
timeFar = hitFar;
|
||||
|
||||
if (timeNear > timeFar || timeFar < 0.0f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
out[0] = aStart[0] + aDirection[0] * timeNear;
|
||||
out[1] = aStart[1] + aDirection[1] * timeNear;
|
||||
out[2] = aStart[2] + aDirection[2] * timeNear;
|
||||
*t = timeNear;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CgeSegment3fIntersectBox3f(const float aStart[3], const float aEnd[3],
|
||||
const float bMin[3], const float bMax[3],
|
||||
float *t, float out[3]) {
|
||||
float tmp[3];
|
||||
float time;
|
||||
|
||||
CgeVec3fSub(aEnd, aStart, tmp);
|
||||
if (CgeRay3fIntersectBox3f(aStart, tmp, bMin, bMax, &time, out))
|
||||
return 0;
|
||||
|
||||
if (time > 1.0f)
|
||||
return 0;
|
||||
|
||||
*t = time;
|
||||
return 1;
|
||||
}
|
||||
95
Vec2f.c
Normal file
95
Vec2f.c
Normal file
@@ -0,0 +1,95 @@
|
||||
#include "CgeMath.h"
|
||||
#include <math.h>
|
||||
|
||||
#define SET_ROW(row, val) row[0] = row[1] = val
|
||||
|
||||
void CgeVec2fAdd(const float a[2], const float b[2], float out[2]) {
|
||||
out[0] = a[0] + b[0];
|
||||
out[1] = a[1] + b[1];
|
||||
}
|
||||
|
||||
void CgeVec2fSub(const float a[2], const float b[2], float out[2]) {
|
||||
out[0] = a[0] - b[0];
|
||||
out[1] = a[1] - b[1];
|
||||
}
|
||||
|
||||
void CgeVec2fMul(const float a[2], const float b[2], float out[2]) {
|
||||
out[0] = a[0] * b[0];
|
||||
out[1] = a[1] * b[1];
|
||||
}
|
||||
|
||||
void CgeVec2fScale(const float a[2], float b, float out[2]) {
|
||||
out[0] = a[0] * b;
|
||||
out[1] = a[1] * b;
|
||||
}
|
||||
|
||||
void CgeVec2fMulAdd(const float a[2], const float b[2], const float c[2],
|
||||
float out[2]) {
|
||||
out[0] = a[0] * b[0] + c[0];
|
||||
out[1] = a[1] * b[1] + c[1];
|
||||
}
|
||||
|
||||
void CgeVec2fNegate(const float in[2], float out[2]) {
|
||||
out[0] = -in[0];
|
||||
out[1] = -in[1];
|
||||
}
|
||||
|
||||
float CgeVec2fDot(const float a[2], const float b[2]) {
|
||||
return a[0] * b[0] + a[1] * b[1];
|
||||
}
|
||||
|
||||
float CgeVec2fCross(const float a[2], const float b[2]) {
|
||||
return a[0] * b[1] - a[1] * b[0];
|
||||
}
|
||||
|
||||
float CgeVec2fLength(const float in[2]) {
|
||||
return sqrtf(CgeVec2fDot(in, in));
|
||||
}
|
||||
|
||||
void CgeVec2fNormal(const float in[2], float out[2]) {
|
||||
CgeVec2fScale(in, 1.0f / CgeVec2fLength(in), out);
|
||||
}
|
||||
|
||||
float CgeVec2fNormalEx(const float in[2], float out[2]) {
|
||||
float length;
|
||||
|
||||
length = CgeVec2fLength(in);
|
||||
CgeVec2fScale(in, 1.0f / length, out);
|
||||
return length;
|
||||
}
|
||||
|
||||
void CgeVec2fMin(const float a[2], const float b[2], float out[2]) {
|
||||
if (a[0] < b[0]) out[0] = a[0]; else out[0] = b[0];
|
||||
if (a[1] < b[1]) out[1] = a[1]; else out[1] = b[1];
|
||||
}
|
||||
|
||||
void CgeVec2fMax(const float a[2], const float b[2], float out[2]) {
|
||||
if (a[0] > b[0]) out[0] = a[0]; else out[0] = b[0];
|
||||
if (a[1] > b[1]) out[1] = a[1]; else out[1] = b[1];
|
||||
}
|
||||
|
||||
void CgeVec2fLerp(const float a[2], const float b[2], float t, float out[2]) {
|
||||
float tmp[2];
|
||||
|
||||
CgeVec2fSub(b, a, tmp);
|
||||
CgeVec2fScale(tmp, t, tmp);
|
||||
CgeVec2fAdd(a, tmp, out);
|
||||
}
|
||||
|
||||
void CgeVec2fProject(const float a[2], const float b[2], float out[2]) {
|
||||
float amount;
|
||||
|
||||
amount = CgeVec2fDot(a, b) / CgeVec2fDot(b, b);
|
||||
CgeVec2fScale(b, amount, out);
|
||||
}
|
||||
|
||||
void CgeVec2fBarycentric(const float a[2], const float b[2], const float c[2],
|
||||
float v, float w, float out[2]) {
|
||||
float tmp1[2], tmp2[2];
|
||||
float u;
|
||||
|
||||
u = 1.0f - v - w;
|
||||
SET_ROW(tmp1, u); CgeVec2fMul(a, tmp1, tmp2);
|
||||
SET_ROW(tmp1, v); CgeVec2fMulAdd(b, tmp1, tmp2, tmp2);
|
||||
SET_ROW(tmp1, w); CgeVec2fMulAdd(c, tmp1, tmp2, out);
|
||||
}
|
||||
42
Vec2i.c
Normal file
42
Vec2i.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "CgeMath.h"
|
||||
|
||||
void CgeVec2iAdd(const int a[2], const int b[2], int out[2]) {
|
||||
out[0] = a[0] + b[0];
|
||||
out[1] = a[1] + b[1];
|
||||
}
|
||||
|
||||
void CgeVec2iSub(const int a[2], const int b[2], int out[2]) {
|
||||
out[0] = a[0] - b[0];
|
||||
out[1] = a[1] - b[1];
|
||||
}
|
||||
|
||||
void CgeVec2iMul(const int a[2], const int b[2], int out[2]) {
|
||||
out[0] = a[0] * b[0];
|
||||
out[1] = a[1] * b[1];
|
||||
}
|
||||
|
||||
void CgeVec2iScale(const int a[2], int b, int out[2]) {
|
||||
out[0] = a[0] * b;
|
||||
out[1] = a[1] * b;
|
||||
}
|
||||
|
||||
void CgeVec2iMulAdd(const int a[2], const int b[2], const int c[2],
|
||||
int out[2]) {
|
||||
out[0] = a[0] * b[0] + c[0];
|
||||
out[1] = a[1] * b[1] + c[1];
|
||||
}
|
||||
|
||||
void CgeVec2iNegate(const int in[2], int out[2]) {
|
||||
out[0] = -in[0];
|
||||
out[1] = -in[1];
|
||||
}
|
||||
|
||||
void CgeVec2iMin(const int a[2], const int b[2], int out[2]) {
|
||||
if (a[0] < b[0]) out[0] = a[0]; else out[0] = b[0];
|
||||
if (a[1] < b[1]) out[1] = a[1]; else out[1] = b[1];
|
||||
}
|
||||
|
||||
void CgeVec2iMax(const int a[2], const int b[2], int out[2]) {
|
||||
if (a[0] > b[0]) out[0] = a[0]; else out[0] = b[0];
|
||||
if (a[1] > b[1]) out[1] = a[1]; else out[1] = b[1];
|
||||
}
|
||||
109
Vec3f.c
Normal file
109
Vec3f.c
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "CgeMath.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define SET_ROW(row, val) row[0] = row[1] = row[2] = val
|
||||
|
||||
void CgeVec3fAdd(const float a[3], const float b[3], float out[3]) {
|
||||
out[0] = a[0] + b[0];
|
||||
out[1] = a[1] + b[1];
|
||||
out[2] = a[2] + b[2];
|
||||
}
|
||||
|
||||
void CgeVec3fSub(const float a[3], const float b[3], float out[3]) {
|
||||
out[0] = a[0] - b[0];
|
||||
out[1] = a[1] - b[1];
|
||||
out[2] = a[2] - b[2];
|
||||
}
|
||||
|
||||
void CgeVec3fMul(const float a[3], const float b[3], float out[3]) {
|
||||
out[0] = a[0] * b[0];
|
||||
out[1] = a[1] * b[1];
|
||||
out[2] = a[2] * b[2];
|
||||
}
|
||||
|
||||
void CgeVec3fScale(const float a[3], float b, float out[3]) {
|
||||
out[0] = a[0] * b;
|
||||
out[1] = a[1] * b;
|
||||
out[2] = a[2] * b;
|
||||
}
|
||||
|
||||
void CgeVec3fMulAdd(const float a[3], const float b[3], const float c[3],
|
||||
float out[3]) {
|
||||
out[0] = a[0] * b[0] + c[0];
|
||||
out[1] = a[1] * b[1] + c[1];
|
||||
out[2] = a[2] * b[2] + c[2];
|
||||
}
|
||||
|
||||
void CgeVec3fNegate(const float in[3], float out[3]) {
|
||||
out[0] = -in[0];
|
||||
out[1] = -in[1];
|
||||
out[2] = -in[2];
|
||||
}
|
||||
|
||||
float CgeVec3fDot(const float a[3], const float b[3]) {
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
}
|
||||
|
||||
void CgeVec3fCross(const float a[3], const float b[3], float out[3]) {
|
||||
float tmp[3];
|
||||
|
||||
tmp[0] = a[1] * b[2] - a[2] * b[1];
|
||||
tmp[1] = a[2] * b[0] - a[0] * b[2];
|
||||
tmp[2] = a[0] * b[1] - a[1] * b[0];
|
||||
memcpy(out, tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
float CgeVec3fLength(const float in[3]) {
|
||||
return sqrtf(CgeVec3fDot(in, in));
|
||||
}
|
||||
|
||||
void CgeVec3fNormal(const float in[3], float out[3]) {
|
||||
CgeVec3fScale(in, 1.0f / CgeVec3fLength(in), out);
|
||||
}
|
||||
|
||||
float CgeVec3fNormalEx(const float in[3], float out[3]) {
|
||||
float length;
|
||||
|
||||
length = CgeVec3fLength(in);
|
||||
CgeVec3fScale(in, 1.0f / length, out);
|
||||
return length;
|
||||
}
|
||||
|
||||
void CgeVec3fMin(const float a[3], const float b[3], float out[3]) {
|
||||
if (a[0] < b[0]) out[0] = a[0]; else out[0] = b[0];
|
||||
if (a[1] < b[1]) out[1] = a[1]; else out[1] = b[1];
|
||||
if (a[2] < b[2]) out[2] = a[2]; else out[2] = b[2];
|
||||
}
|
||||
|
||||
void CgeVec3fMax(const float a[3], const float b[3], float out[3]) {
|
||||
if (a[0] > b[0]) out[0] = a[0]; else out[0] = b[0];
|
||||
if (a[1] > b[1]) out[1] = a[1]; else out[1] = b[1];
|
||||
if (a[2] > b[2]) out[2] = a[2]; else out[2] = b[2];
|
||||
}
|
||||
|
||||
void CgeVec3fLerp(const float a[3], const float b[3], float t, float out[3]) {
|
||||
float tmp[3];
|
||||
|
||||
CgeVec3fSub(b, a, tmp);
|
||||
CgeVec3fScale(tmp, t, tmp);
|
||||
CgeVec3fAdd(a, tmp, out);
|
||||
}
|
||||
|
||||
void CgeVec3fProject(const float a[3], const float b[3], float out[3]) {
|
||||
float amount;
|
||||
|
||||
amount = CgeVec3fDot(a, b) / CgeVec3fDot(b, b);
|
||||
CgeVec3fScale(b, amount, out);
|
||||
}
|
||||
|
||||
void CgeVec3fBarycentric(const float a[3], const float b[3], const float c[3],
|
||||
float v, float w, float out[3]) {
|
||||
float tmp1[3], tmp2[3];
|
||||
float u;
|
||||
|
||||
u = 1.0f - v - w;
|
||||
SET_ROW(tmp1, u); CgeVec3fMul(a, tmp1, tmp2);
|
||||
SET_ROW(tmp1, v); CgeVec3fMulAdd(b, tmp1, tmp2, tmp2);
|
||||
SET_ROW(tmp1, w); CgeVec3fMulAdd(c, tmp1, tmp2, out);
|
||||
}
|
||||
50
Vec3i.c
Normal file
50
Vec3i.c
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "CgeMath.h"
|
||||
|
||||
void CgeVec3iAdd(const int a[3], const int b[3], int out[3]) {
|
||||
out[0] = a[0] + b[0];
|
||||
out[1] = a[1] + b[1];
|
||||
out[2] = a[2] + b[2];
|
||||
}
|
||||
|
||||
void CgeVec3iSub(const int a[3], const int b[3], int out[3]) {
|
||||
out[0] = a[0] - b[0];
|
||||
out[1] = a[1] - b[1];
|
||||
out[2] = a[2] - b[2];
|
||||
}
|
||||
|
||||
void CgeVec3iMul(const int a[3], const int b[3], int out[3]) {
|
||||
out[0] = a[0] * b[0];
|
||||
out[1] = a[1] * b[1];
|
||||
out[2] = a[2] * b[2];
|
||||
}
|
||||
|
||||
void CgeVec3iScale(const int a[3], int b, int out[3]) {
|
||||
out[0] = a[0] * b;
|
||||
out[1] = a[1] * b;
|
||||
out[2] = a[2] * b;
|
||||
}
|
||||
|
||||
void CgeVec3iMulAdd(const int a[3], const int b[3], const int c[3],
|
||||
int out[3]) {
|
||||
out[0] = a[0] * b[0] + c[0];
|
||||
out[1] = a[1] * b[1] + c[1];
|
||||
out[2] = a[2] * b[2] + c[2];
|
||||
}
|
||||
|
||||
void CgeVec3iNegate(const int in[3], int out[3]) {
|
||||
out[0] = -in[0];
|
||||
out[1] = -in[1];
|
||||
out[2] = -in[2];
|
||||
}
|
||||
|
||||
void CgeVec3iMin(const int a[3], const int b[3], int out[3]) {
|
||||
if (a[0] < b[0]) out[0] = a[0]; else out[0] = b[0];
|
||||
if (a[1] < b[1]) out[1] = a[1]; else out[1] = b[1];
|
||||
if (a[2] < b[2]) out[2] = a[2]; else out[2] = b[2];
|
||||
}
|
||||
|
||||
void CgeVec3iMax(const int a[3], const int b[3], int out[3]) {
|
||||
if (a[0] > b[0]) out[0] = a[0]; else out[0] = b[0];
|
||||
if (a[1] > b[1]) out[1] = a[1]; else out[1] = b[1];
|
||||
if (a[2] > b[2]) out[2] = a[2]; else out[2] = b[2];
|
||||
}
|
||||
108
Vec4f.c
Normal file
108
Vec4f.c
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "CgeMath.h"
|
||||
#include <math.h>
|
||||
|
||||
#define SET_ROW(row, val) row[0] = row[1] = row[2] = row[3] = val
|
||||
|
||||
void CgeVec4fAdd(const float a[4], const float b[4], float out[4]) {
|
||||
out[0] = a[0] + b[0];
|
||||
out[1] = a[1] + b[1];
|
||||
out[2] = a[2] + b[2];
|
||||
out[3] = a[3] + b[3];
|
||||
}
|
||||
|
||||
void CgeVec4fSub(const float a[4], const float b[4], float out[4]) {
|
||||
out[0] = a[0] - b[0];
|
||||
out[1] = a[1] - b[1];
|
||||
out[2] = a[2] - b[2];
|
||||
out[3] = a[3] - b[3];
|
||||
}
|
||||
|
||||
void CgeVec4fMul(const float a[4], const float b[4], float out[4]) {
|
||||
out[0] = a[0] * b[0];
|
||||
out[1] = a[1] * b[1];
|
||||
out[2] = a[2] * b[2];
|
||||
out[3] = a[3] * b[3];
|
||||
}
|
||||
|
||||
void CgeVec4fScale(const float a[4], float b, float out[4]) {
|
||||
out[0] = a[0] * b;
|
||||
out[1] = a[1] * b;
|
||||
out[2] = a[2] * b;
|
||||
out[3] = a[3] * b;
|
||||
}
|
||||
|
||||
void CgeVec4fMulAdd(const float a[4], const float b[4], const float c[4],
|
||||
float out[4]) {
|
||||
out[0] = a[0] * b[0] + c[0];
|
||||
out[1] = a[1] * b[1] + c[1];
|
||||
out[2] = a[2] * b[2] + c[2];
|
||||
out[3] = a[3] * b[3] + c[3];
|
||||
}
|
||||
|
||||
void CgeVec4fNegate(const float in[4], float out[4]) {
|
||||
out[0] = -in[0];
|
||||
out[1] = -in[1];
|
||||
out[2] = -in[2];
|
||||
out[3] = -in[3];
|
||||
}
|
||||
|
||||
float CgeVec4fDot(const float a[4], const float b[4]) {
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
|
||||
}
|
||||
|
||||
float CgeVec4fLength(const float in[4]) {
|
||||
return sqrtf(CgeVec4fDot(in, in));
|
||||
}
|
||||
|
||||
void CgeVec4fNormal(const float in[4],
|
||||
float out[4]) {
|
||||
CgeVec4fScale(in, 1.0f / CgeVec4fLength(in), out);
|
||||
}
|
||||
|
||||
float CgeVec4fNormalEx(const float in[4], float out[4]) {
|
||||
float length;
|
||||
|
||||
length = CgeVec4fLength(in);
|
||||
CgeVec4fScale(in, 1.0f / length, out);
|
||||
return length;
|
||||
}
|
||||
|
||||
void CgeVec4fMin(const float a[4], const float b[4], float out[4]) {
|
||||
if (a[0] < b[0]) out[0] = a[0]; else out[0] = b[0];
|
||||
if (a[1] < b[1]) out[1] = a[1]; else out[1] = b[1];
|
||||
if (a[2] < b[2]) out[2] = a[2]; else out[2] = b[2];
|
||||
if (a[3] < b[3]) out[3] = a[3]; else out[3] = b[3];
|
||||
}
|
||||
|
||||
void CgeVec4fMax(const float a[4], const float b[4], float out[4]) {
|
||||
if (a[0] > b[0]) out[0] = a[0]; else out[0] = b[0];
|
||||
if (a[1] > b[1]) out[1] = a[1]; else out[1] = b[1];
|
||||
if (a[2] > b[2]) out[2] = a[2]; else out[2] = b[2];
|
||||
if (a[3] > b[3]) out[3] = a[3]; else out[3] = b[3];
|
||||
}
|
||||
|
||||
void CgeVec4fLerp(const float a[4], const float b[4], float t, float out[4]) {
|
||||
float tmp[4];
|
||||
|
||||
CgeVec4fSub(b, a, tmp);
|
||||
CgeVec4fScale(tmp, t, tmp);
|
||||
CgeVec4fAdd(a, tmp, out);
|
||||
}
|
||||
|
||||
void CgeVec4fProject(const float a[4], const float b[4], float out[4]) {
|
||||
float amount;
|
||||
|
||||
amount = CgeVec4fDot(a, b) / CgeVec4fDot(b, b);
|
||||
CgeVec4fScale(b, amount, out);
|
||||
}
|
||||
|
||||
void CgeVec4fBarycentric(const float a[4], const float b[4], const float c[4],
|
||||
float v, float w, float out[4]) {
|
||||
float tmp1[4], tmp2[4];
|
||||
float u;
|
||||
|
||||
u = 1.0f - v - w;
|
||||
SET_ROW(tmp1, u); CgeVec4fMul(a, tmp1, tmp2);
|
||||
SET_ROW(tmp1, v); CgeVec4fMulAdd(b, tmp1, tmp2, tmp2);
|
||||
SET_ROW(tmp1, w); CgeVec4fMulAdd(c, tmp1, tmp2, out);
|
||||
}
|
||||
58
Vec4i.c
Normal file
58
Vec4i.c
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "CgeMath.h"
|
||||
|
||||
void CgeVec4iAdd(const int a[4], const int b[4], int out[4]) {
|
||||
out[0] = a[0] + b[0];
|
||||
out[1] = a[1] + b[1];
|
||||
out[2] = a[2] + b[2];
|
||||
out[3] = a[3] + b[3];
|
||||
}
|
||||
|
||||
void CgeVec4iSub(const int a[4], const int b[4], int out[4]) {
|
||||
out[0] = a[0] - b[0];
|
||||
out[1] = a[1] - b[1];
|
||||
out[2] = a[2] - b[2];
|
||||
out[3] = a[3] - b[3];
|
||||
}
|
||||
|
||||
void CgeVec4iMul(const int a[4], const int b[4], int out[4]) {
|
||||
out[0] = a[0] * b[0];
|
||||
out[1] = a[1] * b[1];
|
||||
out[2] = a[2] * b[2];
|
||||
out[3] = a[3] * b[3];
|
||||
}
|
||||
|
||||
void CgeVec4iScale(const int a[4], int b, int out[4]) {
|
||||
out[0] = a[0] * b;
|
||||
out[1] = a[1] * b;
|
||||
out[2] = a[2] * b;
|
||||
out[3] = a[3] * b;
|
||||
}
|
||||
|
||||
void CgeVec4iMulAdd(const int a[4], const int b[4], const int c[4],
|
||||
int out[4]) {
|
||||
out[0] = a[0] * b[0] + c[0];
|
||||
out[1] = a[1] * b[1] + c[1];
|
||||
out[2] = a[2] * b[2] + c[2];
|
||||
out[3] = a[3] * b[3] + c[3];
|
||||
}
|
||||
|
||||
void CgeVec4iNegate(const int in[4], int out[4]) {
|
||||
out[0] = -in[0];
|
||||
out[1] = -in[1];
|
||||
out[2] = -in[2];
|
||||
out[3] = -in[3];
|
||||
}
|
||||
|
||||
void CgeVec4iMin(const int a[4], const int b[4], int out[4]) {
|
||||
if (a[0] < b[0]) out[0] = a[0]; else out[0] = b[0];
|
||||
if (a[1] < b[1]) out[1] = a[1]; else out[1] = b[1];
|
||||
if (a[2] < b[2]) out[2] = a[2]; else out[2] = b[2];
|
||||
if (a[3] < b[3]) out[3] = a[3]; else out[3] = b[3];
|
||||
}
|
||||
|
||||
void CgeVec4iMax(const int a[4], const int b[4], int out[4]) {
|
||||
if (a[0] > b[0]) out[0] = a[0]; else out[0] = b[0];
|
||||
if (a[1] > b[1]) out[1] = a[1]; else out[1] = b[1];
|
||||
if (a[2] > b[2]) out[2] = a[2]; else out[2] = b[2];
|
||||
if (a[3] > b[3]) out[3] = a[3]; else out[3] = b[3];
|
||||
}
|
||||
Reference in New Issue
Block a user