diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Decals.cpp | 7 | ||||
-rw-r--r-- | src/GameLoop.cpp | 2 | ||||
-rw-r--r-- | src/GameTick.cpp | 29 | ||||
-rw-r--r-- | src/Models.cpp | 29 | ||||
-rw-r--r-- | src/Person.cpp | 45 | ||||
-rw-r--r-- | src/Quaternions.cpp | 79 | ||||
-rw-r--r-- | src/Quaternions.h | 19 | ||||
-rw-r--r-- | src/Skeleton.cpp | 38 | ||||
-rw-r--r-- | src/misc.h | 3 | ||||
-rw-r--r-- | src/misc.zig | 50 |
10 files changed, 121 insertions, 180 deletions
diff --git a/src/Decals.cpp b/src/Decals.cpp index 8a6ab5e..e5971e4 100644 --- a/src/Decals.cpp +++ b/src/Decals.cpp @@ -52,12 +52,11 @@ int Decals::MakeDecal(int atype, XYZ location, float size, XYZ normal, int poly, else if (major == 0) right = {normal.z, 0.0f, 0.0f}; } else { - CrossProduct(axis[major], normal, &right); + right = crossProduct(axis[major], normal); } - CrossProduct(normal, right, &up); - Normalise(&up); - Normalise(&right); + up = normalize(crossProduct(normal, right)); + right = normalize(right); float count; float count2; diff --git a/src/GameLoop.cpp b/src/GameLoop.cpp index 0cfe3ef..f9eefcc 100644 --- a/src/GameLoop.cpp +++ b/src/GameLoop.cpp @@ -141,7 +141,7 @@ void handleKey(Game* game, int key, int action, int mods) XYZ towards = player.playercoords - game->bodycoords; if (towards.x || towards.z) { - Normalise(&towards); + towards = normalize(towards); camera.rotation = asin(towards.x) * 180.0f / M_PI; if (towards.z > 0) camera.rotation = 180 - camera.rotation; diff --git a/src/GameTick.cpp b/src/GameTick.cpp index 1193c3c..fc5305b 100644 --- a/src/GameTick.cpp +++ b/src/GameTick.cpp @@ -186,7 +186,7 @@ void click(Game* game, int button, int action, int mods) XYZ flatfacing = facing; flatfacing.y = 0; - Normalise(&flatfacing); + flatfacing = normalize(flatfacing); // Gun whacking or knife slashing if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS @@ -932,7 +932,7 @@ void renderLaser(Game* game) return; } - Normalise(&aim); + aim = normalize(aim); auto& coords = player.playercoords; auto start = coords + DoRotation(joints[lefthand].position, 0.0f, rotation, 0.0f) @@ -1015,7 +1015,7 @@ void Game::Tick() XYZ flatfacing = facing; flatfacing.y = 0; - Normalise(&flatfacing); + flatfacing = normalize(flatfacing); // Check collision with buildings int beginx,endx; @@ -1449,8 +1449,7 @@ void Game::Tick() } if(person[i].targetanimation!=zombieeatanim||person[i].type!=zombietype){ - towards=person[i].playercoords-person[i].pathtarget; - Normalise(&towards); + towards = normalize(person[i].playercoords - person[i].pathtarget); person[i].playerrotation=asin(0-towards.x)*360/6.28; if(towards.z>0)person[i].playerrotation=180-person[i].playerrotation; } @@ -1527,8 +1526,8 @@ void Game::Tick() person[i].playercoords.y = joint.position.y; //Find orientation - XYZ firsttop=person[i].skeleton.joints[neck].position-person[i].skeleton.joints[groin].position; - Normalise(&firsttop); + XYZ firsttop = normalize(person[i].skeleton.joints[neck].position + - person[i].skeleton.joints[groin].position); person[i].playerrotation=acos(0-firsttop.z); person[i].playerrotation*=360/6.28; if(0>firsttop.x)person[i].playerrotation=360-person[i].playerrotation; @@ -1626,7 +1625,7 @@ void Game::Tick() aim = aimPlayer(this); else aim = facing; - Normalise(&aim); + aim = normalize(aim); int aimjoint; switch (person[j].whichgun) { @@ -2000,10 +1999,8 @@ void Game::Tick() joint.offset += DoRotation(aim * 200 / distance / totalarea * 10, 0, -person[whichhit].playerrotation, 0); } - if (findLengthfast(joint.offset) > 36) { - Normalise(&joint.offset); - joint.offset *= 6; - } + if (findLengthfast(joint.offset) > 36) + joint.offset = normalize(joint.offset) * 6; } } @@ -2232,7 +2229,7 @@ void Game::Tick() if (sprites.size[i] > 1) decals.MakeDecal(crater, wallhit, 9, normalrotated, whichtri, &blocks[citytype[wherex][wherey]], move, cityrotation[wherex][wherey] * 90); sprites.location[i] = wallhit + normalrotated * 0.02f; - ReflectVector(&sprites.velocity[i], &normalrotated); + reflect(&sprites.velocity[i], normalrotated); sprites.velocity[i] *= 0.3f; if (sprites.type[i] == grenadesprite && sprites.size[i] <= 1) { @@ -2341,8 +2338,7 @@ void Game::Tick() joint.offset += DoRotation(sprites.velocity[i] * 0.1 * 200 / distance / totalarea * 10, 0, -person[j].playerrotation, 0); } if (findLengthfast(joint.offset) > 9) { - Normalise(&joint.offset); - joint.offset *= 3; + joint.offset = normalize(joint.offset) * 3; } } } @@ -2432,8 +2428,7 @@ void Game::Tick() person[k].longdead=1; for (auto& joint : person[k].skeleton.joints) { - relation = joint.position - sprites.location[i]; - Normalise(&relation); + relation = normalize(joint.position - sprites.location[i]); auto distance = findDistance(joint.position, sprites.location[i]); if (distance > 1) joint.velocity += relation / distance * 300; diff --git a/src/Models.cpp b/src/Models.cpp index ad0f357..e706ebf 100644 --- a/src/Models.cpp +++ b/src/Models.cpp @@ -6,14 +6,11 @@ void Model::CalculateNormals() { - for (int i = 0; i < TriangleNum; ++i) { - CrossProduct(vertex[Triangles[i].vertex[1]] + for (int i = 0; i < TriangleNum; ++i) + normals[i] = normalize(crossProduct(vertex[Triangles[i].vertex[1]] - vertex[Triangles[i].vertex[0]], vertex[Triangles[i].vertex[2]] - - vertex[Triangles[i].vertex[0]], - normals + i); - Normalise(normals + i); - } + - vertex[Triangles[i].vertex[0]])); for (int i = 0; i < TriangleNum; ++i) { vArray[i*27+0]=vertex[Triangles[i].vertex[0]].x; @@ -128,10 +125,7 @@ int Model::LineCheck(XYZ p1,XYZ p2, XYZ *p) int intersecting=0; int firstintersecting=-1; XYZ point; - if(sphere_line_intersection(p1.x,p1.y,p1.z, - p2.x,p2.y,p2.z, - boundingspherecenter.x,boundingspherecenter.y,boundingspherecenter.z, - boundingsphereradius)) + if (segmentIntersectsSphere(p1, p2, boundingspherecenter, boundingsphereradius)) for (j=0;j<TriangleNum;j++){ intersecting=LineFacetd(p1,p2,vertex[Triangles[j].vertex[0]],vertex[Triangles[j].vertex[1]],vertex[Triangles[j].vertex[2]],normals[j],&point); if (intersecting == 0) continue; @@ -153,10 +147,7 @@ int Model::LineCheck2(XYZ p1,XYZ p2, XYZ *p, XYZ move, float rotate) p2=p2-move; if(rotate)p1=DoRotation(p1,0,-rotate,0); if(rotate)p2=DoRotation(p2,0,-rotate,0); - if(sphere_line_intersection(p1.x,p1.y,p1.z, - p2.x,p2.y,p2.z, - boundingspherecenter.x,boundingspherecenter.y,boundingspherecenter.z, - boundingsphereradius)) + if (segmentIntersectsSphere(p1, p2, boundingspherecenter, boundingsphereradius)) for (j=0;j<TriangleNum;j++){ intersecting=LineFacetd(p1,p2,vertex[Triangles[j].vertex[0]],vertex[Triangles[j].vertex[1]],vertex[Triangles[j].vertex[2]],normals[j],&point); if (intersecting == 0) continue; @@ -181,10 +172,7 @@ int Model::LineCheck2(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate) *p2=*p2-*move; if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0); if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0); - if(sphere_line_intersection(p1->x,p1->y,p1->z, - p2->x,p2->y,p2->z, - boundingspherecenter.x,boundingspherecenter.y,boundingspherecenter.z, - boundingsphereradius)) + if (segmentIntersectsSphere(*p1, *p2, boundingspherecenter, boundingsphereradius)) for (j=0;j<TriangleNum;j++){ intersecting = LineFacetd(*p1, *p2, vertex[Triangles[j].vertex[0]], @@ -213,10 +201,7 @@ int Model::LineCheck3(XYZ p1,XYZ p2, XYZ *p, XYZ move, float rotate, float *d) p2=p2-move; p1=DoRotation(p1,0,-rotate,0); p2=DoRotation(p2,0,-rotate,0); - if(sphere_line_intersection(p1.x,p1.y,p1.z, - p2.x,p2.y,p2.z, - boundingspherecenter.x,boundingspherecenter.y,boundingspherecenter.z, - boundingsphereradius)) + if (segmentIntersectsSphere(p1, p2, boundingspherecenter, boundingsphereradius)) for (j=0;j<TriangleNum;j++){ intersecting=LineFacetd(p1,p2,vertex[Triangles[j].vertex[0]],vertex[Triangles[j].vertex[1]],vertex[Triangles[j].vertex[2]],normals[j],&point); if (intersecting == 0) continue; diff --git a/src/Person.cpp b/src/Person.cpp index 2007857..452a8bd 100644 --- a/src/Person.cpp +++ b/src/Person.cpp @@ -72,9 +72,7 @@ HitStruct Person::BulletCollideWithPlayer(int who, XYZ start, XYZ end){ } tempbulletloc[0]=start; tempbulletloc[1]=end; - if(sphere_line_intersection(tempbulletloc[0].x,tempbulletloc[0].y,tempbulletloc[0].z, - tempbulletloc[1].x,tempbulletloc[1].y,tempbulletloc[1].z, - average.x, average.y, average.z, distancemax)){ + if (segmentIntersectsSphere(start, end, average, distancemax)) { for (auto& joint : skeleton.joints) { if (joint.hasparent && joint.visible) { tempbulletloc[0] = start; @@ -726,7 +724,7 @@ void Person::FindRotationGun(XYZ start, XYZ target) tempforward=DoRotation(tempforward,0,gunrotate1-90,0); tempforward=DoRotation(tempforward,0,0,gunrotate2-90); tempforward.y=0; - Normalise(&tempforward); + tempforward = normalize(tempforward); gunrotate3=acos(0-tempforward.z)*rad2deg; if(0>tempforward.x)gunrotate3=360-gunrotate3; } @@ -935,8 +933,7 @@ int Person::DrawSkeleton(int who) joint.oldposition = joint.position; joint.position += joint.offset; if (findLengthfast(joint.offset) >= multiplier * multiplier * 25) { - normal = joint.offset; - Normalise(&normal); + normal = normalize(joint.offset); skeleton.offset = 1; joint.offset -= normal * multiplier * 5; } else { @@ -947,34 +944,30 @@ int Person::DrawSkeleton(int who) } auto& fwdjoints = skeleton.forwardjoints; - CrossProduct(skeleton.joints[fwdjoints[1]].position + skeleton.forward = normalize(crossProduct(skeleton.joints[fwdjoints[1]].position - skeleton.joints[fwdjoints[0]].position, skeleton.joints[fwdjoints[2]].position - - skeleton.joints[fwdjoints[0]].position, - &skeleton.forward); - Normalise(&skeleton.forward); + - skeleton.joints[fwdjoints[0]].position)); auto& lowfwd = skeleton.lowforwardjoints; - CrossProduct(skeleton.joints[lowfwd[1]].position + skeleton.lowforward = normalize(crossProduct(skeleton.joints[lowfwd[1]].position - skeleton.joints[lowfwd[0]].position, skeleton.joints[lowfwd[2]].position - - skeleton.joints[lowfwd[0]].position, - &skeleton.lowforward); - Normalise(&skeleton.lowforward); + - skeleton.joints[lowfwd[0]].position)); // Special forwards auto specialfwd = skeleton.specialforward; *specialfwd++ = skeleton.forward; - *specialfwd = skeleton.joints[rightelbow].position + *specialfwd = normalize(skeleton.joints[rightelbow].position - skeleton.joints[rightshoulder].position / 2 - - right_wrist / 2 + skeleton.forward * 0.2; - Normalise(specialfwd++); + - right_wrist / 2 + skeleton.forward * 0.2); + specialfwd++; - *specialfwd = skeleton.joints[leftelbow].position + *specialfwd = normalize(skeleton.joints[leftelbow].position - skeleton.joints[leftshoulder].position / 2 - - left_wrist / 2 + skeleton.forward * 0.2; - Normalise(specialfwd++); + - left_wrist / 2 + skeleton.forward * 0.2); + specialfwd++; if(!who && aimamount > 0 && health == 100 && whichgun != nogun) { @@ -990,17 +983,17 @@ int Person::DrawSkeleton(int who) skeleton.specialforward[2] += facingdown * aimamount; } - *specialfwd = skeleton.joints[righthip].position / 2 + *specialfwd = normalize(skeleton.joints[righthip].position / 2 + skeleton.joints[rightankle].position / 2 - skeleton.joints[rightknee].position - + skeleton.lowforward * 0.2; - Normalise(specialfwd++); + + skeleton.lowforward * 0.2); + specialfwd++; - *specialfwd = skeleton.joints[lefthip].position / 2 + *specialfwd = normalize(skeleton.joints[lefthip].position / 2 + skeleton.joints[leftankle].position / 2 - skeleton.joints[leftknee].position - + skeleton.lowforward * 0.2; - Normalise(specialfwd++); + + skeleton.lowforward * 0.2); + specialfwd++; for (int i = 0; i < max_joints; i++) if (skeleton.joints[i].hasparent diff --git a/src/Quaternions.cpp b/src/Quaternions.cpp index 6fe85bf..9142da0 100644 --- a/src/Quaternions.cpp +++ b/src/Quaternions.cpp @@ -2,20 +2,6 @@ #include "Quaternions.h" -void CrossProduct(XYZ P, XYZ Q, XYZ *V){ - V->x = P.y * Q.z - P.z * Q.y; - V->y = P.z * Q.x - P.x * Q.z; - V->z = P.x * Q.y - P.y * Q.x; -} - -void Normalise(XYZ *vectory) { - float d = sqrt(vectory->x*vectory->x+vectory->y*vectory->y+vectory->z*vectory->z); - if(d==0){return;} - vectory->x /= d; - vectory->y /= d; - vectory->z /= d; -} - extern float u0, u1, u2; extern float v0, v1, v2; extern float a, b; @@ -117,30 +103,6 @@ float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc, XYZ n, XYZ *p) return 1; } -void ReflectVector(XYZ *vel, XYZ *n) -{ - XYZ vn; - XYZ vt; - float dotprod; - - dotprod=dotproduct(*n,*vel); - vn.x=n->x*dotprod; - vn.y=n->y*dotprod; - vn.z=n->z*dotprod; - - vt.x=vel->x-vn.x; - vt.y=vel->y-vn.y; - vt.z=vel->z-vn.z; - - vel->x = vt.x - vn.x; - vel->y = vt.y - vn.y; - vel->z = vt.z - vn.z; -} - -float dotproduct(XYZ point1, XYZ point2){ - return point1.x * point2.x + point1.y * point2.y + point1.z * point2.z; -} - float findDistance(XYZ point1, XYZ point2){ return sqrt((point1.x-point2.x)*(point1.x-point2.x)+(point1.y-point2.y)*(point1.y-point2.y)+(point1.z-point2.z)*(point1.z-point2.z)); } @@ -191,44 +153,3 @@ XYZ DoRotation(XYZ thePoint, float xang, float yang, float zang){ return thePoint; } - -float square( float f ) { return (f*f) ;} - -bool sphere_line_intersection(float x1, float y1, float z1, - float x2, float y2, float z2, float x3, float y3, float z3, float r) -{ - - // x1,y1,z1 P1 coordinates (point of line) - // x2,y2,z2 P2 coordinates (point of line) - // x3,y3,z3, r P3 coordinates and radius (sphere) - // x,y,z intersection coordinates - // - // This function returns a pointer array which first index indicates - // the number of intersection point, followed by coordinate pairs. - - float a, b, c, i; - - if(x1>x3+r&&x2>x3+r)return(0); - if(x1<x3-r&&x2<x3-r)return(0); - if(y1>y3+r&&y2>y3+r)return(0); - if(y1<y3-r&&y2<y3-r)return(0); - if(z1>z3+r&&z2>z3+r)return(0); - if(z1<z3-r&&z2<z3-r)return(0); - a = square(x2 - x1) + square(y2 - y1) + square(z2 - z1); - b = 2* ( (x2 - x1)*(x1 - x3) - + (y2 - y1)*(y1 - y3) - + (z2 - z1)*(z1 - z3) ) ; - c = square(x3) + square(y3) + - square(z3) + square(x1) + - square(y1) + square(z1) - - 2* ( x3*x1 + y3*y1 + z3*z1 ) - square(r) ; - i = b * b - 4 * a * c ; - - if ( i < 0.0 ) - { - // no intersection - return(0); - } - - return(1); -} diff --git a/src/Quaternions.h b/src/Quaternions.h index ee3e876..16ff2d9 100644 --- a/src/Quaternions.h +++ b/src/Quaternions.h @@ -41,23 +41,24 @@ constexpr XYZ& operator/=(XYZ& u, float k) { return u = u / k; } #ifdef __cplusplus extern "C" { #endif // __cplusplus - void CrossProduct(struct XYZ P, struct XYZ Q, struct XYZ *V); - void Normalise(struct XYZ *vectory); - bool PointInTriangle(struct XYZ *p, struct XYZ normal, - struct XYZ *p1, struct XYZ *p2, struct XYZ *p3); + float dotProduct(struct XYZ, struct XYZ); + struct XYZ crossProduct(struct XYZ, struct XYZ); + struct XYZ normalize(struct XYZ); + void reflect(struct XYZ*, struct XYZ); + bool segmentIntersectsSphere(struct XYZ, struct XYZ, struct XYZ, float); + float LineFacetd(struct XYZ p1, struct XYZ p2, struct XYZ pa, struct XYZ pb, struct XYZ pc, struct XYZ n, struct XYZ *p); - void ReflectVector(struct XYZ *vel, struct XYZ *n); struct XYZ DoRotation(struct XYZ thePoint, float xang, float yang, float zang); float findDistance(struct XYZ point1, struct XYZ point2); float findLengthfast(struct XYZ point1); float findDistancefast(struct XYZ point1, struct XYZ point2); - float dotproduct(struct XYZ point1, struct XYZ point2); - bool sphere_line_intersection(float x1, float y1, float z1, - float x2, float y2, float z2, - float x3, float y3, float z3, float r); + + void getFrustum(float (*)[4]); + int cubeInFrustum(float (*)[4], float, float, float, float); + int sphereInFrustum(float (*)[4], float, float, float, float); #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/src/Skeleton.cpp b/src/Skeleton.cpp index dc5cdf8..6925fb6 100644 --- a/src/Skeleton.cpp +++ b/src/Skeleton.cpp @@ -34,10 +34,8 @@ void Joint::DoConstraint() if(hasparent){ //Find midpoint midp=(position+parent->position)/2; - //Find vector from midpoint to second vector - vel=parent->position-midp; - //Change to unit vector - Normalise(&vel); + // Find vector from midpoint to second vector + vel = normalize(parent->position - midp); //Apply velocity change velocity+=((midp-vel*length/2)-position); parent->velocity+=((midp+vel*length/2)-parent->position); @@ -69,10 +67,8 @@ void Muscle::DoConstraint(int broken) //Find midpoint midp=(parent1->position+parent2->position)/2; - //Find vector from midpoint to second vector - vel=parent2->position-midp; - //Change to unit vector - Normalise(&vel); + // Find vector from midpoint to second vector + vel = normalize(parent2->position - midp); //Apply velocity change newpoint1=midp-vel*length/2; newpoint2=midp+vel*length/2; @@ -137,7 +133,7 @@ void Skeleton::DoConstraints(Model *collide, XYZ *move, float rotation) && collide->normals[whichtri].y <= 0.8) { normalrotated = DoRotation(collide->normals[whichtri], 0, rotation, 0); pos = impact + normalrotated * offset; - ReflectVector(&joints[i].velocity, &normalrotated); + reflect(&joints[i].velocity, normalrotated); joints[i].velocity *= 0.3; } @@ -284,7 +280,7 @@ void Skeleton::FindRotationJoint(int which) tempforward=DoRotation(tempforward,0,joints[which].rotate1-90,0); tempforward=DoRotation(tempforward,0,0,joints[which].rotate2-90); tempforward.y=0; - Normalise(&tempforward); + tempforward = normalize(tempforward); joints[which].rotate3=acos(0-tempforward.z)*rad2deg; if(0>tempforward.x)joints[which].rotate3=360-joints[which].rotate3; } @@ -313,7 +309,7 @@ void Skeleton::FindRotationMuscle(int which) tempforward=DoRotation(tempforward,0,muscles[which].rotate1-90,0); tempforward=DoRotation(tempforward,0,0,muscles[which].rotate2-90); tempforward.y=0; - Normalise(&tempforward); + tempforward = normalize(tempforward); muscles[which].rotate3=acos(0-tempforward.z)*rad2deg; for (auto& joint : joints) if (&joint == muscles[which].parent1) { @@ -344,11 +340,15 @@ void Animation::load(const char* name) for (int i = 0; i < max_joints; ++i) testskeleton.joints[i].position = position[i][j]; //Find forward vectors - CrossProduct(testskeleton.joints[testskeleton.forwardjoints[1]].position-testskeleton.joints[testskeleton.forwardjoints[0]].position,testskeleton.joints[testskeleton.forwardjoints[2]].position-testskeleton.joints[testskeleton.forwardjoints[0]].position,&testskeleton.forward); - Normalise(&testskeleton.forward); + testskeleton.forward = normalize(crossProduct(testskeleton.joints[testskeleton.forwardjoints[1]].position + - testskeleton.joints[testskeleton.forwardjoints[0]].position, + testskeleton.joints[testskeleton.forwardjoints[2]].position + - testskeleton.joints[testskeleton.forwardjoints[0]].position)); - CrossProduct(testskeleton.joints[testskeleton.lowforwardjoints[1]].position-testskeleton.joints[testskeleton.lowforwardjoints[0]].position,testskeleton.joints[testskeleton.lowforwardjoints[2]].position-testskeleton.joints[testskeleton.lowforwardjoints[0]].position,&testskeleton.lowforward); - Normalise(&testskeleton.lowforward); + testskeleton.lowforward = normalize(crossProduct(testskeleton.joints[testskeleton.lowforwardjoints[1]].position + - testskeleton.joints[testskeleton.lowforwardjoints[0]].position, + testskeleton.joints[testskeleton.lowforwardjoints[2]].position + - testskeleton.joints[testskeleton.lowforwardjoints[0]].position)); //Special forwards testskeleton.specialforward[0]=testskeleton.forward; @@ -356,20 +356,20 @@ void Animation::load(const char* name) testskeleton.specialforward[1]=testskeleton.joints[rightshoulder].position+testskeleton.joints[rightwrist].position; testskeleton.specialforward[1]=testskeleton.joints[rightelbow].position-testskeleton.specialforward[1]/2; testskeleton.specialforward[1]+=testskeleton.forward*.2; - Normalise(&testskeleton.specialforward[1]); + testskeleton.specialforward[1] = normalize(testskeleton.specialforward[1]); testskeleton.specialforward[2]=testskeleton.joints[leftshoulder].position+testskeleton.joints[leftwrist].position; testskeleton.specialforward[2]=testskeleton.joints[leftelbow].position-testskeleton.specialforward[2]/2; testskeleton.specialforward[2]+=testskeleton.forward*.2; - Normalise(&testskeleton.specialforward[2]); + testskeleton.specialforward[2] = normalize(testskeleton.specialforward[2]); testskeleton.specialforward[3]=testskeleton.joints[righthip].position+testskeleton.joints[rightankle].position; testskeleton.specialforward[3]=testskeleton.specialforward[3]/2-testskeleton.joints[rightknee].position; testskeleton.specialforward[3]+=testskeleton.lowforward*.2; - Normalise(&testskeleton.specialforward[3]); + testskeleton.specialforward[3] = normalize(testskeleton.specialforward[3]); testskeleton.specialforward[4]=testskeleton.joints[lefthip].position+testskeleton.joints[leftankle].position; testskeleton.specialforward[4]=testskeleton.specialforward[4]/2-testskeleton.joints[leftknee].position; testskeleton.specialforward[4]+=testskeleton.lowforward*.2; - Normalise(&testskeleton.specialforward[4]); + testskeleton.specialforward[4] = normalize(testskeleton.specialforward[4]); //Find joint rotations for (int i = 0; i < max_joints; ++i) diff --git a/src/misc.h b/src/misc.h index a51e2f3..148917f 100644 --- a/src/misc.h +++ b/src/misc.h @@ -74,9 +74,6 @@ extern "C" { int32_t randInt(int32_t at_least, int32_t at_most); uint32_t randUint(uint32_t less_than); - void getFrustum(float (*)[4]); - int cubeInFrustum(float (*)[4], float, float, float, float); - int sphereInFrustum(float (*)[4], float, float, float, float); void setFog(struct Fog*, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); void tempFog(struct Fog*, GLfloat, GLfloat, GLfloat); diff --git a/src/misc.zig b/src/misc.zig index d523827..0b1ad54 100644 --- a/src/misc.zig +++ b/src/misc.zig @@ -17,6 +17,7 @@ // You should have received a copy of the GNU General Public License // along with Black Shades. If not, see <https://www.gnu.org/licenses/>. +const Child = std.meta.Child; const Dir = std.fs.Dir; const TokenIterator = std.mem.TokenIterator(u8); const allocPrint = std.fmt.allocPrint; @@ -377,6 +378,55 @@ pub fn saveScores(base_dir: []const u8, current: Scores) !void { try dir.writeFile("scores.ini", data); } +// TODO: move graphics functions to a seperate file +fn sqr(x: anytype) @TypeOf(x) { + return x * x; +} + +fn dot(u: anytype, v: @TypeOf(u)) Child(@TypeOf(u)) { + return @reduce(.Add, u * v); +} + +fn norm(v: anytype) Child(@TypeOf(v)) { + return @sqrt(dot(v, v)); +} + +const XYZ = extern struct { x: f32, y: f32, z: f32 }; + +export fn crossProduct(u: XYZ, v: XYZ) XYZ { + return .{ + .x = u.y * v.z - u.z * v.y, + .y = u.z * v.x - u.x * v.z, + .z = u.x * v.y - u.y * v.x, + }; +} + +export fn normalize(v: XYZ) XYZ { + const u = @bitCast(@Vector(3, f32), v); + const d = norm(u); + return if (d == 0) v else @bitCast(XYZ, u / @splat(3, d)); +} + +export fn reflect(v: XYZ, n: XYZ) XYZ { + const u = @bitCast(@Vector(3, f32), v); + const m = @bitCast(@Vector(3, f32), n); + return @bitCast(XYZ, u - m * @splat(3, dot(u, m) * 2)); +} + +export fn segmentIntersectsSphere(a: XYZ, b: XYZ, j: XYZ, r: f32) bool { + // FIXME: call directly with vectors + const p = @bitCast(@Vector(3, f32), a); + const q = @bitCast(@Vector(3, f32), b); + const i = @bitCast(@Vector(3, f32), j); + + if (@reduce(.Or, @max(p, q) < i - @splat(3, r))) return false; + if (@reduce(.Or, @min(p, q) > i + @splat(3, r))) return false; + // https://en.wikipedia.org/wiki/Line–sphere_intersection + const d = q - p; // line's direction + const u = d / @splat(3, norm(d)); // unit vector + return sqr(dot(u, (p - i))) >= @reduce(.Add, sqr(p - i)) - sqr(r); +} + export fn getFrustum(frustum: [*][4]f32) void { var proj: [16]f32 = undefined; c.glGetFloatv(c.GL_PROJECTION_MATRIX, &proj); |