Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/WolfireGames/overgrowth.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Math/enginemath.cpp')
-rw-r--r--Source/Math/enginemath.cpp161
1 files changed, 161 insertions, 0 deletions
diff --git a/Source/Math/enginemath.cpp b/Source/Math/enginemath.cpp
new file mode 100644
index 00000000..84d7eae0
--- /dev/null
+++ b/Source/Math/enginemath.cpp
@@ -0,0 +1,161 @@
+//-----------------------------------------------------------------------------
+// Name: enginemath.cpp
+// Developer: Wolfire Games LLC
+// Author: David Rosen
+// Description: This contains most 3d math functions and classes
+// License: Read below
+//-----------------------------------------------------------------------------
+//
+// Copyright 2022 Wolfire Games LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-----------------------------------------------------------------------------
+#include "enginemath.h"
+
+#include <Math/vec3math.h>
+
+#define _USE_MATH_DEFINES
+#include <cmath>
+#include <cstdlib>
+#include <cstdio>
+#include <algorithm>
+
+void PlaneSpace(const vec3 &n, vec3 &p, vec3 &q) {
+ if (fabs(n[2]) > 0.7071067f) {
+ // choose p in y-z plane
+ float a = n[1]*n[1] + n[2]*n[2];
+ float k = 1.0f/sqrtf(a);
+ p[0] = 0;
+ p[1] = -n[2]*k;
+ p[2] = n[1]*k;
+ // set q = n x p
+ q[0] = a*k;
+ q[1] = -n[0]*p[2];
+ q[2] = n[0]*p[1];
+ }
+ else {
+ // choose p in x-y plane
+ float a = n[0]*n[0] + n[1]*n[1];
+ float k = 1.0f/sqrtf(a);
+ p[0] = -n[1]*k;
+ p[1] = n[0]*k;
+ p[2] = 0;
+ // set q = n x p
+ q[0] = -n[2]*p[1];
+ q[1] = n[2]*p[0];
+ q[2] = a*k;
+ }
+}
+float RangedRandomFloat(float min, float max) {
+ if(min == max){
+ return min;
+ }
+ return (((float)abs(rand()))/RAND_MAX*((float)(max)-(float)(min))+(float)(min));
+}
+
+int RangedRandomInt(int min, int max) { // Inclusive
+ return abs(rand())%(max-min+1)+min;
+}
+
+float Range(float val, float min_val, float max_val) {
+ float temp_val = val;
+ temp_val -= min_val;
+ temp_val /= (max_val-min_val);
+ return min(1.0f,max(0.0f,temp_val));
+}
+
+float YAxisRotationFromVector(const vec3 &theVector)
+{
+ vec3 vector(theVector.x(),0,theVector.z());
+ vector = normalize(vector);
+ float new_rotation = acos(vector.z())/3.1415f*180.0f;
+ if(vector.x()<0)new_rotation*=-1;
+ new_rotation+=180;
+ return new_rotation;
+}
+
+vec3 AngleAxisRotation(const vec3 &thePoint, const vec3 &theAxis, const float howmuch){
+ return AngleAxisRotationRadian(thePoint, theAxis, howmuch * deg2radf);
+}
+
+vec3 AngleAxisRotationRadian(const vec3 &thePoint, const vec3 &theAxis, const float howmuch){
+ float costheta=cosf(howmuch);
+ return thePoint*costheta+theAxis*(dot(thePoint,theAxis))*(1-costheta)+cross(thePoint,theAxis)*sinf(howmuch);
+}
+
+vec3 doRotation(const vec3 &thePoint, const float xang, const float yang, const float zang){
+ return doRotationRadian(thePoint, xang*deg2radf, yang*deg2radf, zang*deg2radf);
+}
+
+vec3 doRotationRadian(const vec3 &thePoint, const float xang, const float yang, const float zang){
+ vec3 newpoint;
+ vec3 oldpoint;
+
+ oldpoint=thePoint;
+
+ if(yang!=0){
+ newpoint.z()=oldpoint.z()*cosf(yang)-oldpoint.x()*sinf(yang);
+ newpoint.x()=oldpoint.z()*sinf(yang)+oldpoint.x()*cosf(yang);
+ oldpoint.z()=newpoint.z();
+ oldpoint.x()=newpoint.x();
+ }
+
+ if(zang!=0){
+ newpoint.x()=oldpoint.x()*cosf(zang)-oldpoint.y()*sinf(zang);
+ newpoint.y()=oldpoint.y()*cosf(zang)+oldpoint.x()*sinf(zang);
+ oldpoint.x()=newpoint.x();
+ oldpoint.y()=newpoint.y();
+ }
+
+ if(xang!=0){
+ newpoint.y()=oldpoint.y()*cosf(xang)-oldpoint.z()*sinf(xang);
+ newpoint.z()=oldpoint.y()*sinf(xang)+oldpoint.z()*cosf(xang);
+ oldpoint.z()=newpoint.z();
+ oldpoint.y()=newpoint.y();
+ }
+
+ return oldpoint;
+}
+
+int log2(unsigned int x)
+{
+ int log = -1; // special case for log2(0)
+ while (x != 0) { x >>= 1; log++; }
+ return log;
+}
+
+void GetRotationBetweenVectors( const vec3 &a, const vec3 &b, quaternion &rotate ) {
+ vec3 rotate_axis = normalize(cross(a, b));
+ vec3 up = normalize(a);
+ vec3 right_vec = cross(up, rotate_axis);
+ vec3 ik_dir = normalize(b);
+ float rotate_angle = atan2f(-dot(ik_dir, right_vec), dot(ik_dir, up));
+ rotate = quaternion(vec4(rotate_axis, rotate_angle));
+}
+
+const uint64_t m1 = 0x5555555555555555; //binary: 0101...
+const uint64_t m2 = 0x3333333333333333; //binary: 00110011..
+const uint64_t m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ...
+const uint64_t m8 = 0x00ff00ff00ff00ff; //binary: 8 zeros, 8 ones ...
+const uint64_t m16 = 0x0000ffff0000ffff; //binary: 16 zeros, 16 ones ...
+const uint64_t m32 = 0x00000000ffffffff; //binary: 32 zeros, 32 ones
+const uint64_t hff = 0xffffffffffffffff; //binary: all ones
+const uint64_t h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
+
+int popcount(uint64_t x) {
+ x -= (x >> 1) & m1; //put count of each 2 bits into those 2 bits
+ x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
+ x = (x + (x >> 4)) & m4; //put count of each 8 bits into those 8 bits
+ return (x * h01)>>56; //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
+}