summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/Decals.cpp26
-rw-r--r--src/Game.h1
-rw-r--r--src/GameInitDispose.cpp8
-rw-r--r--src/GameLoop.cpp2
-rw-r--r--src/GameTick.cpp237
-rw-r--r--src/Models.cpp70
-rw-r--r--src/Models.h2
-rw-r--r--src/Person.cpp42
-rw-r--r--src/Quaternions.cpp83
-rw-r--r--src/Quaternions.h92
-rw-r--r--src/Skeleton.cpp2
-rw-r--r--src/Sprites.cpp9
12 files changed, 174 insertions, 400 deletions
diff --git a/src/Decals.cpp b/src/Decals.cpp
index 92888ec..1522053 100644
--- a/src/Decals.cpp
+++ b/src/Decals.cpp
@@ -31,7 +31,7 @@ int Decals::MakeDecal(int atype, XYZ location, float size, XYZ normal, int poly,
 	XYZ axis[3];
 	XYZ temp;
 
-	nothing=0;
+	nothing = {};
 
 	axis[0].x=1;
 	axis[1].y=1;
@@ -44,20 +44,16 @@ int Decals::MakeDecal(int atype, XYZ location, float size, XYZ normal, int poly,
 	if(normalv[1]>normalv[major])major=1;
 	if(normalv[2]>normalv[major])major=2;
 
-	if (normalv[0] == 1 || normalv[1] == 1 || normalv[2] == 1)
-	{
-	if ((major == 0 && normal.x > 0) || major == 1){
-		right=0;
-		right.z=-1;}
-	else if (major == 0){
-		right=0;
-		right.z=1;}
-    else {
-        right=0;
-		right.x=normal.z;}
-   	}
-   	else
-    	CrossProduct(axis[major], normal, &right);
+	if (normalv[0] == 1 || normalv[1] == 1 || normalv[2] == 1) {
+		if (major == 0 && normal.x > 0 || major == 1)
+			right = {0.0f, 0.0f, -1.0f};
+		else if (major == 0)
+			right = {0.0f, 0.0f, 1.0f};
+		else if (major == 0)
+			right = {normal.z, 0.0f, 0.0f};
+	} else {
+		CrossProduct(axis[major], normal, &right);
+	}
 
     CrossProduct(normal, right, &up);
     Normalise(&up);
diff --git a/src/Game.h b/src/Game.h
index 05bb4d6..4835f42 100644
--- a/src/Game.h
+++ b/src/Game.h
@@ -113,7 +113,6 @@ public:
 	bool paused;
 	bool menu;
 
-	XYZ vipgoal;
 	XYZ aimer[2];
 
 	double eqn[4];
diff --git a/src/GameInitDispose.cpp b/src/GameInitDispose.cpp
index b95768e..6d99c4c 100644
--- a/src/GameInitDispose.cpp
+++ b/src/GameInitDispose.cpp
@@ -238,9 +238,8 @@ void initGame(Game* game)
 
 	if (!game->initialized) {
 		auto& point0 = game->boundingpoints[0];
-		point0 = 0;
+		point0.x = point0.y = 0;
 		point0.z = boundingscale;
-		point0.y = 0;
 
 		for (int i = 1; i < 8; ++i)
 			game->boundingpoints[i] = DoRotation(point0,
@@ -353,9 +352,6 @@ void initGame(Game* game)
 	game->numpeople++;
 	game->spawndelay = 0.1f;
 
-	game->vipgoal = vip.playercoords
-		+ DoRotation({10000000.0f, 0.0f, 0.0f}, 0, randUint(360), 0);
-
 	// Init city block rotations
 	for (int i = 0; i < num_blocks; ++i)
 		for (int j = 0; j < num_blocks; ++j) {
@@ -973,7 +969,7 @@ void initGame(Game* game)
 		person.health = 100;
 		person.skeleton.free = 0;
 		person.ammo = 0;
-		person.velocity = 0;
+		person.velocity = {};
 
 		// Load skeleton structure
 		person.skeleton.reload();
diff --git a/src/GameLoop.cpp b/src/GameLoop.cpp
index caa3c1b..f174e70 100644
--- a/src/GameLoop.cpp
+++ b/src/GameLoop.cpp
@@ -154,7 +154,7 @@ void handleKey(Game* game, int key, int action, int mods)
 
 			player.playercoords = game->bodycoords;
 			player.oldplayercoords = game->bodycoords;
-			player.velocity = 0;
+			player.velocity = {};
 		}
 	}
 
diff --git a/src/GameTick.cpp b/src/GameTick.cpp
index a848289..8adbbfe 100644
--- a/src/GameTick.cpp
+++ b/src/GameTick.cpp
@@ -565,12 +565,7 @@ void Game::Tick()
 				inblock=0;
 
 				//Ground collision
-
-				move=0;
-
-				move.x=i*block_spacing;
-
-				move.z=j*block_spacing;
+				move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing};
 
 				whichtri=sidewalkcollide.LineCheck2(overpoint,underpoint,&collpoint,move,cityrotation[i][j]*90);
 
@@ -601,13 +596,7 @@ void Game::Tick()
 					if(inblock){
 
 						for(int l=0;l<8;l++){
-
-							move=0;
-
-							move.x=i*block_spacing;
-
-							move.z=j*block_spacing;
-
+							move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing};
 							whichtri=blockwalls[citytype[i][j]].LineCheck3(person[k].oldplayercoords+boundingpoints[l],person[k].playercoords+boundingpoints[l],&collpoint,move,cityrotation[i][j]*90,&depth);
 
 							if(whichtri!=-1){
@@ -625,13 +614,7 @@ void Game::Tick()
 							pointnum=k+1;
 
 							if(pointnum>3)pointnum=0;
-
-							move=0;
-
-							move.x=i*block_spacing;
-
-							move.z=j*block_spacing;
-
+							move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing};
 							whichtri=blockwalls[citytype[i][j]].LineCheck3(person[k].playercoords+boundingpoints[l],person[k].playercoords+boundingpoints[pointnum],&collpoint,move,cityrotation[i][j]*90,&depth);
 
 							if(whichtri!=-1){
@@ -651,13 +634,7 @@ void Game::Tick()
 					if(inblock&&person[k].playercoords.y>30){
 
 						if(!person[k].onground){
-
-							move=0;
-
-							move.x=i*block_spacing;
-
-							move.z=j*block_spacing;
-
+							move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing};
 							whichtri=blockroofs[citytype[i][j]].LineCheck2(overpoint,underpoint,&collpoint,move,cityrotation[i][j]*90);
 
 							if(whichtri!=-1&&person[k].playercoords.y<=collpoint.y&&person[k].velocity.y<=0){
@@ -702,10 +679,9 @@ void Game::Tick()
 
 	}
 
-	//Camera
-	camera.oldposition=camera.position;
-	camera.targetoffset=0;
-	camera.targetoffset.z=-5;
+	// Camera
+	camera.oldposition = camera.position;
+	camera.targetoffset = {0.0f, 0.0f, -5.0f};
 
 	// Spawn people
 	int cyclenum = 0;
@@ -935,24 +911,23 @@ void Game::Tick()
 				underpoint=person[i].skeleton.joints[abdomen].position;
 				underpoint.y-=3000;
 
-				move=0;
-				move.x=person[i].whichblockx*block_spacing;
-				move.z=person[i].whichblocky*block_spacing;
+				move = {
+					(float) person[i].whichblockx * block_spacing,
+					0.0f,
+					(float) person[i].whichblocky * block_spacing,
+				};
 
 				XYZ temp;
 				whichtri=sidewalkcollide.LineCheck2(overpoint,underpoint,&temp,move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90);
 
-				XYZ normish;
-				normish=0;
-				normish.y=1;
-
+				XYZ normish {0.0f, 1.0f, 0.0f};
 				if(whichtri>=0){
 					decals.MakeDecal(bloodpool,temp,12,normish, whichtri, &sidewalkcollide, move, cityrotation[person[i].whichblockx][person[i].whichblocky]*90);
 				}
 				if(whichtri==-1){
 					temp=person[i].skeleton.joints[abdomen].position;
 					temp.y=-.5;
-					move=0;
+					move = {};
 					decals.MakeDecal(bloodpool,temp,12,normish, 0, &sidewalkcollide, move, 0);
 				}
 
@@ -1008,7 +983,7 @@ void Game::Tick()
 				if(person[i].skeleton.free>0){
 					bleedloc=(person[i].bjoint1->position+person[i].bjoint2->position)/2;
 				}
-				vel=0;
+				vel = {};
 				sprites.MakeSprite(bloodspritedown, .6, 1, .2, .2,bleedloc, vel, 3*person[i].bleeding);
 			}
 
@@ -1064,9 +1039,9 @@ void Game::Tick()
 
 				for(int k=0;k<2;k++){
 					person[person[i].killtarget].skeleton.joints[head].position=DoRotation(person[i].skeleton.joints[righthand].position,0,person[i].playerrotation,0)+person[i].playercoords;
-					person[person[i].killtarget].skeleton.joints[head].velocity=0;
+					person[person[i].killtarget].skeleton.joints[head].velocity = {};
 					person[person[i].killtarget].skeleton.joints[rightshoulder].position=DoRotation(person[i].skeleton.joints[lefthand].position,0,person[i].playerrotation,0)+person[i].playercoords;
-					person[person[i].killtarget].skeleton.joints[rightshoulder].velocity=0;
+					person[person[i].killtarget].skeleton.joints[rightshoulder].velocity = {};
 					person[person[i].killtarget].skeleton.DoConstraints();
 					person[person[i].killtarget].skeleton.DoConstraints(&blocksimplecollide[citytype[person[i].whichblockx][person[i].whichblocky]],&move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90);
 				}
@@ -1524,16 +1499,18 @@ void Game::Tick()
 			person[i].whichblockx=((person[i].skeleton.joints[0].position.x+block_spacing/2)/block_spacing);
 			person[i].whichblocky=((person[i].skeleton.joints[0].position.z+block_spacing/2)/block_spacing);
 
-			move=0;
-			move.x=person[i].whichblockx*block_spacing;
-			move.z=person[i].whichblocky*block_spacing;
+			move = {
+				(float) person[i].whichblockx * block_spacing,
+				0.0f,
+				(float) person[i].whichblocky * block_spacing,
+			};
 			person[i].skeleton.DoGravity();
 
 			if(person[i].averageloc.y<=50)person[i].skeleton.DoConstraints(&blocksimplecollide[citytype[person[i].whichblockx][person[i].whichblocky]],&move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90);
 			if(person[i].averageloc.y>50)person[i].skeleton.DoConstraints(&blockcollide[citytype[person[i].whichblockx][person[i].whichblocky]],&move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90);
 
 			person[i].oldaverageloc=person[i].averageloc;
-			person[i].averageloc=0;
+			person[i].averageloc = {};
 
 			for (auto& joint : person[i].skeleton.joints)
 				person[i].averageloc += joint.position;
@@ -1570,7 +1547,7 @@ void Game::Tick()
 			person[i].playerrotation*=360/6.28;
 			if(0>firsttop.x)person[i].playerrotation=360-person[i].playerrotation;
 			person[i].playerrotation*=-1;
-			person[i].playervelocity=0;
+			person[i].playervelocity = {};
 			if(person[i].targetanimation==getupfrontanim)person[i].playerrotation+=180;
 
 			for (int j = 0; j < max_joints; ++j) {
@@ -1917,10 +1894,8 @@ void Game::Tick()
 
 				}
 
-				//Blocks
-
-				wallhit=0;
-
+				// Blocks
+				wallhit = {};
 				beginx=(person[j].playercoords.x+block_spacing/2)/block_spacing-3;
 
 				if(beginx<0)beginx=0;
@@ -1939,18 +1914,10 @@ void Game::Tick()
 
 				if(beginx<endx&&beginz<endz)
 
-				finalwallhit=0;
-
+				finalwallhit = {};
 				for(int i=beginx;i<=endx;i++)
-
 					for(int j=beginz;j<=endz;j++){
-
-						move=0;
-
-						move.x=i*block_spacing;
-
-						move.z=j*block_spacing;
-
+						move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing};
 						whichtri=blocks[citytype[i][j]].LineCheck2(start,end,&wallhit,move,cityrotation[i][j]*90);
 
 						if(whichtri!=-1){
@@ -1972,37 +1939,20 @@ void Game::Tick()
 							model=&blocks[citytype[i][j]];
 
 							if(j==0&&blocks[citytype[i][j]].normals[whichtri].y>.9)bulletstrength=2;
-
 						}
-
 					}
-
-				wallhit=0;
-
-				wallhit.x=camera.position.x;
-
-				wallhit.z=camera.position.z;
+				wallhit = {camera.position.x, 0.0f, camera.position.z};
 
 				whichtri=Bigstreet.LineCheck2(start,end,&wallhit,wallhit,0);
 
 				if(whichtri!=-1){
-
 					end.y-=.5;
-
 					end=wallhit;
-
 					finalwallhit=wallhit;
-
 					bulletstrength=2;
-
-					hitnorm=0;
-
-					hitnorm.y=1;
-
-					hitmove=0;
-
+					hitnorm = {0.0f, 1.0f, 0.0f};
+					hitmove = {};
 					hitrotation=0;
-
 				}
 
 				if(m==0){
@@ -2349,25 +2299,18 @@ void Game::Tick()
 
 				if(j!=0||zoom==0)sprites.MakeSprite(bullet, .07, 1, 1, .7, lastshot[0]+aim*1, lastshot[1], .2);
 
-				//Nearby bullet whoosh
-
-				long dot_ta,dot_tb;
-
-				XYZ *a,*b,*c,nearest;
-
-				a=&lastshot[0];
-
-				*a+=aim*1;
-
-				b=&lastshot[1];
-
-				c=&camera.position;
-
-				nearest=0;
-
-				dot_ta = (c->x - a->x)*(b->x - a->x) + (c->y - a->y)*(b->y - a->y) + (c->z - a->z)*(b->z - a->z);
-
-				dot_tb = (c->x - b->x)*(a->x - b->x) + (c->y - b->y)*(a->y - b->y) + (c->z - b->z)*(a->z - b->z);
+				// Nearby bullet whoosh
+				XYZ* a = &lastshot[0];
+				*a += aim;
+				XYZ* b = &lastshot[1];
+				XYZ* c = &camera.position;
+				XYZ nearest {};
+				long dot_ta = (c->x - a->x) * (b->x - a->x)
+					+ (c->y - a->y) * (b->y - a->y)
+					+ (c->z - a->z) * (b->z - a->z);
+				long dot_tb = (c->x - b->x) * (a->x - b->x)
+					+ (c->y - b->y) * (a->y - b->y)
+					+ (c->z - b->z) * (a->z - b->z);
 
 				if (dot_ta > 0 && dot_tb > 0) {
 					nearest.x = a->x + ((b->x - a->x) * dot_ta) / (dot_ta + dot_tb);
@@ -2475,10 +2418,8 @@ void Game::Tick()
 
 				end=start+aim*1000;
 
-				//Blocks
-
-				wallhit=0;
-
+				// Blocks
+				wallhit = {};
 				beginx=(person[j].playercoords.x+block_spacing/2)/block_spacing-2;
 
 				if(beginx<0)beginx=0;
@@ -2497,18 +2438,10 @@ void Game::Tick()
 
 				if(beginx<endx&&beginz<endz)
 
-				finalwallhit=0;
-
+				finalwallhit = {};
 				for(int i=beginx;i<=endx;i++)
-
 					for(int j=beginz;j<=endz;j++){
-
-						move=0;
-
-						move.x=i*block_spacing;
-
-						move.z=j*block_spacing;
-
+						move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing};
 						whichtri=blocks[citytype[i][j]].LineCheck2(start,end,&wallhit,move,cityrotation[i][j]*90);
 
 						if(whichtri!=-1){
@@ -2520,13 +2453,7 @@ void Game::Tick()
 						}
 
 					}
-
-				wallhit=0;
-
-				wallhit.x=camera.position.x;
-
-				wallhit.z=camera.position.z;
-
+				wallhit = {camera.position.x, 0.0f, camera.position.z};
 				whichtri=Bigstreet.LineCheck2(start,end,&wallhit,wallhit,0);
 
 				if(whichtri!=-1){
@@ -2587,8 +2514,7 @@ void Game::Tick()
 	snowdelay-=multiplier;
 	while(snowdelay<0&&environment==snowy_environment){
 		snowdelay+=1/precipitationdensity*2;
-		velocity=0;
-		velocity.y=-5;
+		velocity = {0.0f, -5.0f, 0.0f};
 		start=camera.position;
 		start.y+=precipitationvert;
 		start.x += randUint(precipitationhorz);
@@ -2598,8 +2524,7 @@ void Game::Tick()
 
 	while(snowdelay<0&&environment==rainy_environment){
 		snowdelay+=1/precipitationdensity/4;
-		velocity=0;
-		velocity.y=-100;
+		velocity = {0.0f, -100.0f, 0.0f};
 		start=camera.position;
 		start.y+=precipitationvert;
 		start.x += randUint(precipitationhorz) * 0.5f;
@@ -2631,11 +2556,7 @@ void Game::Tick()
 
 				wherey=(sprites.location[i].z+block_spacing/2)/block_spacing;
 
-				move=0;
-
-				move.x=wherex*block_spacing;
-
-				move.z=wherey*block_spacing;
+				move = {(float) wherex * block_spacing, 0.0f, (float) wherey * block_spacing};
 
 				whichtri=blocks[citytype[wherex][wherey]].LineCheck2(sprites.oldlocation[i],sprites.location[i],&wallhit,move,cityrotation[wherex][wherey]*90);
 
@@ -2667,36 +2588,23 @@ void Game::Tick()
 						alSourcePlay(gSourceID[whichsound]);
 					}
 
-					if(findLengthfast(sprites.velocity[i])<=10)sprites.velocity[i]=0;
+					if (findLengthfast(sprites.velocity[i]) <= 10)
+						sprites.velocity[i] = {};
 
 				}
 
 				if(sprites.location[i].y<0){
-
 					impact=1;
-
-					sprites.velocity[i].y*=-1;
-
-					sprites.velocity[i]*=.3;
-
-					sprites.location[i].y=0;
+					sprites.velocity[i].y *= -1.0f;
+					sprites.velocity[i] *= 0.3f;
+					sprites.location[i].y = 0.0f;
 
 					if(sprites.type[i]==grenadesprite){
-
 						if(sprites.size[i]>1){
-
-							move=0;
-
+							move = {};
 							sprites.location[i].y=-.5;
-
-							XYZ normish;
-
-							normish=0;
-
-							normish.y=1;
-
+							XYZ normish = {0.0f, 1.0f, 0.0f};
 							decals.MakeDecal(crater, sprites.location[i],9,normish, 0, &blocks[citytype[wherex][wherey]], move, 0);
-
 						}
 
 						auto soundpos = sprites.location[i] - camera.position;
@@ -2713,7 +2621,8 @@ void Game::Tick()
 
 					}
 
-					if(findLengthfast(sprites.velocity[i])<=10)sprites.velocity[i]=0;
+					if (findLengthfast(sprites.velocity[i]) <= 10)
+						sprites.velocity[i] = {};
 
 				}
 
@@ -2828,33 +2737,19 @@ void Game::Tick()
 					//if(!sprites.size[i]>1){
 
 						overpoint=sprites.location[i];
-
 						overpoint.y+=3000;
-
 						underpoint=sprites.location[i];
-
 						underpoint.y-=3000;
-
-						move=0;
-
 						wherex=(sprites.location[i].x+block_spacing/2)/block_spacing;
-
 						wherey=(sprites.location[i].z+block_spacing/2)/block_spacing;
+						move = {(float) wherex * block_spacing, 0.0f, (float) wherey * block_spacing};
 
-						move.x=wherex*block_spacing;
-
-						move.z=wherey*block_spacing;
 
 						XYZ temp;
 
 						whichtri=sidewalkcollide.LineCheck2(overpoint,underpoint,&temp,move,cityrotation[wherex][wherey]*90);
 
-						XYZ normish;
-
-						normish=0;
-
-						normish.y=1;
-
+						XYZ normish = {0.0f, 1.0f, 0.0f};
 						if(whichtri>=0){
 
 							decals.MakeDecal(crater, sprites.location[i],9,normish, 0, &sidewalkcollide, move, cityrotation[wherex][wherey]*90);
@@ -2862,17 +2757,11 @@ void Game::Tick()
 						}
 
 						if(whichtri==-1){
-
 							temp=sprites.location[i];
-
 							temp.y=-.5;
-
-							move=0;
-
+							move = {};
 							decals.MakeDecal(crater, sprites.location[i],9,normish, 0, &sidewalkcollide, move, 0);
-
 						}
-
 					//}
 
 					for(int k=0;k<numpeople;k++){
diff --git a/src/Models.cpp b/src/Models.cpp
index 4c92f93..6632562 100644
--- a/src/Models.cpp
+++ b/src/Models.cpp
@@ -4,10 +4,18 @@
 #include "Models.h"
 #include "misc.h"
 
-//Functions
-void Model::UpdateVertexArray(){
-	int i;
-	for(i=0;i<TriangleNum;i++){
+void Model::CalculateNormals()
+{
+	for (int i = 0; i < TriangleNum; ++i) {
+		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);
+	}
+
+	for (int i = 0; i < TriangleNum; ++i) {
 		vArray[i*27+0]=vertex[Triangles[i].vertex[0]].x;
 		vArray[i*27+1]=vertex[Triangles[i].vertex[0]].y;
 		vArray[i*27+2]=vertex[Triangles[i].vertex[0]].z;
@@ -39,29 +47,16 @@ void Model::UpdateVertexArray(){
 		vArray[i*27+26]=Triangles[i].b;
 	}
 
-	XYZ average;
-	int howmany;
-	average=0;
-	howmany=0;
-	boundingboxmin=20000;
-	boundingboxmax=-20000;
-	for(int i=0;i<vertexNum;i++){
-		howmany++;
-		average=average+vertex[i];
-		if(vertex[i].x<boundingboxmin.x)boundingboxmin.x=vertex[i].x;
-		if(vertex[i].y<boundingboxmin.y)boundingboxmin.y=vertex[i].y;
-		if(vertex[i].z<boundingboxmin.z)boundingboxmin.z=vertex[i].z;
-		if(vertex[i].x>boundingboxmax.x)boundingboxmax.x=vertex[i].x;
-		if(vertex[i].y>boundingboxmax.y)boundingboxmax.y=vertex[i].y;
-		if(vertex[i].z>boundingboxmax.z)boundingboxmax.z=vertex[i].z;
-	}
-	average=average/howmany;
-	boundingspherecenter=average;
-	boundingsphereradius=0;
-	for(int i=0;i<vertexNum;i++){
-		if(findDistancefast(average,vertex[i])>boundingsphereradius)boundingsphereradius=findDistancefast(average,vertex[i]);
-	}
-	boundingsphereradius=sqrt(boundingsphereradius);
+	boundingspherecenter = {};
+	for (int i = 0; i < vertexNum; ++i)
+		boundingspherecenter += vertex[i];
+	boundingspherecenter /= vertexNum;
+
+	boundingsphereradius = 0;
+	for (int i = 0; i < vertexNum; ++i)
+		boundingsphereradius = max(boundingsphereradius,
+			findDistancefast(boundingspherecenter, vertex[i]));
+	boundingsphereradius = sqrt(boundingsphereradius);
 }
 
 void Model::load(const char* path)
@@ -85,30 +80,9 @@ void Model::load(const char* path)
 		Triangles[i].b = model.faces.ptr[i].b;
 	}
 	free(model.faces.ptr);
-
-	XYZ average {};
-	for (auto&& v : vertex)
-		boundingspherecenter += v;
-	boundingspherecenter /= vertexNum;
-
-	boundingsphereradius = 0;
-	for (auto&& v : vertex)
-		boundingsphereradius = std::max(boundingsphereradius,
-			findDistancefast(average, v));
-	boundingsphereradius = sqrt(boundingsphereradius);
 	CalculateNormals();
 }
 
-void Model::CalculateNormals()
-{
-	int i;
-	for(i=0;i<TriangleNum;i++){
-		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]);
-	}
-	UpdateVertexArray();
-}
-
 extern int nocolors;
 void Model::draw()
 {
diff --git a/src/Models.h b/src/Models.h
index f20602c..5c68997 100644
--- a/src/Models.h
+++ b/src/Models.h
@@ -45,8 +45,6 @@ public:
 	void CalculateNormals();
 	void draw();
 	void draw(float r,float g,float b);
-
-	XYZ boundingboxmin, boundingboxmax;
 };
 
 #endif
diff --git a/src/Person.cpp b/src/Person.cpp
index dca3bbb..4097aa5 100644
--- a/src/Person.cpp
+++ b/src/Person.cpp
@@ -313,33 +313,14 @@ void Person::DoAnimations(int who)
 
 	//Look up+down
 	if(!skeleton.free&&(whichgun!=nogun||who==0)&&health==100&&currentanimation!=lyinganim&&currentanimation!=getupfrontanim&&currentanimation!=getupbackanim&&currentanimation!=diveanim&&targetanimation!=diveanim&&targetanimation!=throwanim&&targetanimation!=thrownanim){
-		XYZ facing;
-		XYZ facingdown;
-		XYZ facinghalf;
-		XYZ facingright;
-		if(who==0){
-			playerrotation2=camera.rotation2;
-			//Facing
-			facing=0;
-			facing.z=1;
-
-			facinghalf=DoRotation(facing,playerrotation2/2,0,0);
-			facinghalf=DoRotation(facinghalf,0,-7,0);
-			facing=DoRotation(facing,playerrotation2,0,0);
-			facingright=DoRotation(facing,0,-90,0);
-			facingdown=DoRotation(facing,90,0,0);
-		}
-		if(who!=0){
-			//Facing
-			facing=0;
-			facing.z=1;
-
-			facinghalf=DoRotation(facing,playerrotation2/2,0,0);
-			facinghalf=DoRotation(facinghalf,0,-7,0);
-			facing=DoRotation(facing,playerrotation2,0,0);
-			facingright=DoRotation(facing,0,-90,0);
-			facingdown=DoRotation(facing,90,0,0);
-		}
+		if (who == 0)
+			playerrotation2 = camera.rotation2;
+		XYZ facing {0.0f, 0.0f, 1.0f};
+		XYZ facinghalf = DoRotation(DoRotation(facing,
+			playerrotation2 / 2, 0, 0), 0, -7, 0);
+		facing = DoRotation(facing, playerrotation2, 0, 0);
+		XYZ facingright = DoRotation(facing, 0, -90, 0);
+		XYZ facingdown = DoRotation(facing, 90, 0, 0);
 		XYZ rotatearound;
 		XYZ oldpos;
 		switch (whichgun) {
@@ -714,9 +695,8 @@ void Person::DoStuff(int who)
 	if (backwardsanim)
 		facing *= -1;
 
-	if(onground){
-		velocity=0;
-	}
+	if(onground)
+		velocity = {};
 	if(((currentanimation==joganim||currentanimation==zombiejoganim||currentanimation==diveanim)&&onground)||(who==0&&visions==1&&((currentanimation==joganim||currentanimation==walkanim||currentanimation==diveanim)||(currentanimation==zombiejoganim||currentanimation==zombiewalkanim)))){
 		playercoords+=facing*multiplier*15*speed;
 		velocity.x=facing.x*15*speed;
@@ -961,7 +941,7 @@ int Person::DrawSkeleton(int who)
 						skeleton.offset = 1;
 						joint.offset -= normal * multiplier * 5;
 					} else {
-						joint.offset=0;
+						joint.offset = {};
 					}
 				}
 				skeleton.DoConstraints();
diff --git a/src/Quaternions.cpp b/src/Quaternions.cpp
index fc38c44..0bd0442 100644
--- a/src/Quaternions.cpp
+++ b/src/Quaternions.cpp
@@ -2,89 +2,6 @@
 
 #include "Quaternions.h"
 
-XYZ XYZ::operator+(XYZ add){
-	XYZ ne;
-	ne=add;
-	ne.x+=x;
-	ne.y+=y;
-	ne.z+=z;
-	return ne;
-}
-
-XYZ XYZ::operator-(XYZ add){
-	XYZ ne;
-	ne=add;
-	ne.x=x-ne.x;
-	ne.y=y-ne.y;
-	ne.z=z-ne.z;
-	return ne;
-}
-
-XYZ XYZ::operator*(float add){
-	XYZ ne;
-	ne.x=x*add;
-	ne.y=y*add;
-	ne.z=z*add;
-	return ne;
-}
-
-XYZ XYZ::operator*(XYZ add){
-	XYZ ne;
-	ne.x=x*add.x;
-	ne.y=y*add.y;
-	ne.z=z*add.z;
-	return ne;
-}
-
-XYZ XYZ::operator/(float add){
-	XYZ ne;
-	ne.x=x/add;
-	ne.y=y/add;
-	ne.z=z/add;
-	return ne;
-}
-
-void XYZ::operator+=(XYZ add){
-	x+=add.x;
-	y+=add.y;
-	z+=add.z;
-}
-
-void XYZ::operator-=(XYZ add){
-	x=x-add.x;
-	y=y-add.y;
-	z=z-add.z;
-}
-
-void XYZ::operator*=(float add){
-	x=x*add;
-	y=y*add;
-	z=z*add;
-}
-
-void XYZ::operator*=(XYZ add){
-	x=x*add.x;
-	y=y*add.y;
-	z=z*add.z;
-}
-
-void XYZ::operator/=(float add){
-	x=x/add;
-	y=y/add;
-	z=z/add;
-}
-
-void XYZ::operator=(float add){
-	x=add;
-	y=add;
-	z=add;
-}
-
-bool XYZ::operator==(XYZ add){
-	if(x==add.x&&y==add.y&&z==add.z)return 1;
-	return 0;
-}
-
 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;
diff --git a/src/Quaternions.h b/src/Quaternions.h
index c41dfe8..8cf1eff 100644
--- a/src/Quaternions.h
+++ b/src/Quaternions.h
@@ -1,39 +1,65 @@
-#ifndef _QUATERNIONS_H_
-#define _QUATERNIONS_H_
+#ifndef BLACKSHADES_QUATERNIONS_H
+#define BLACKSHADES_QUATERNIONS_H
 
 using namespace std;
 
-class XYZ{
-	public:
-		float x;
-		float y;
-		float z;
-		XYZ operator+(XYZ add);
-		XYZ operator-(XYZ add);
-		XYZ operator*(float add);
-		XYZ operator*(XYZ add);
-		XYZ operator/(float add);
-		void operator+=(XYZ add);
-		void operator-=(XYZ add);
-		void operator*=(float add);
-		void operator*=(XYZ add);
-		void operator/=(float add);
-		void operator=(float add);
-		bool operator==(XYZ add);
+struct XYZ {
+	float x, y, z;
 };
 
-void CrossProduct(XYZ P, XYZ Q, XYZ *V);
-void Normalise(XYZ *vectory);
-bool PointInTriangle(XYZ *p, XYZ normal, XYZ *p1, XYZ *p2, XYZ *p3);
-float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ n, XYZ *p);
-float LineFacetd(XYZ *p1,XYZ *p2,XYZ *pa,XYZ *pb,XYZ *pc,XYZ *n, XYZ *p);
-void ReflectVector(XYZ *vel, XYZ *n);
-XYZ DoRotation(XYZ thePoint, float xang, float yang, float zang);
-float findDistance(XYZ point1, XYZ point2);
-float findLengthfast(XYZ point1);
-float findDistancefast(XYZ point1, XYZ point2);
-float dotproduct(XYZ point1, 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);
+#ifdef __cplusplus
+constexpr bool operator==(const XYZ& u, const XYZ& v)
+{
+	return u.x == v.x && u.y == v.y && u.z == v.z;
+}
+constexpr XYZ operator+(XYZ u, const XYZ& v)
+{
+	return {u.x + v.x, u.y + v.y, u.z + v.z};
+}
+constexpr XYZ operator-(XYZ u, const XYZ& v)
+{
+	return {u.x - v.x, u.y - v.y, u.z - v.z};
+}
+constexpr XYZ operator*(XYZ u, const XYZ& v)
+{
+	return {u.x * v.x, u.y * v.y, u.z * v.z};
+}
+constexpr XYZ operator*(XYZ u, float k)
+{
+	return {u.x * k, u.y * k, u.z * k};
+}
+constexpr XYZ operator/(XYZ u, float k)
+{
+	return {u.x / k, u.y / k, u.z / k};
+}
 
-#endif
+constexpr XYZ& operator+=(XYZ& u, const XYZ& v) { return u = u + v; }
+constexpr XYZ& operator-=(XYZ& u, const XYZ& v) { return u = u - v; }
+constexpr XYZ& operator*=(XYZ& u, const XYZ& v) { return u = u * v; }
+constexpr XYZ& operator*=(XYZ& u, float k) { return u = u * k; }
+constexpr XYZ& operator/=(XYZ& u, float k) { return u = u / k; }
+
+float LineFacetd(XYZ p1, XYZ p2, XYZ pa, XYZ pb, XYZ pc, XYZ n, XYZ* p);
+float LineFacetd(XYZ* p1, XYZ* p2, XYZ* pa, XYZ* pb, XYZ* pc, XYZ* n, XYZ* p);
+#endif // __cplusplus
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+	void CrossProduct(XYZ P, XYZ Q, XYZ *V);
+	void Normalise(XYZ *vectory);
+	bool PointInTriangle(XYZ *p, XYZ normal, XYZ *p1, XYZ *p2, XYZ *p3);
+	void ReflectVector(XYZ *vel, XYZ *n);
+	XYZ DoRotation(XYZ thePoint, float xang, float yang, float zang);
+	float findDistance(XYZ point1, XYZ point2);
+	float findLengthfast(XYZ point1);
+	float findDistancefast(XYZ point1, XYZ point2);
+	float dotproduct(XYZ point1, 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);
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+#endif // BLACKSHADES_QUATERNIONS_H
diff --git a/src/Skeleton.cpp b/src/Skeleton.cpp
index e5cdd7a..dc5cdf8 100644
--- a/src/Skeleton.cpp
+++ b/src/Skeleton.cpp
@@ -465,7 +465,7 @@ void Skeleton::reload()
 
 		joints[i].existing = true;
 		joints[i].locked = false;
-		joints[i].velocity = 0;
+		joints[i].velocity = {};
 		joints[i].oldposition = joints[i].position;
 	}
 
diff --git a/src/Sprites.cpp b/src/Sprites.cpp
index e3ffc75..239c0a8 100644
--- a/src/Sprites.cpp
+++ b/src/Sprites.cpp
@@ -254,11 +254,10 @@ void Sprites::draw()
 				glPopMatrix();
 				avgProj=(endProj+begProj)/2;
 
-				dx	= endProj.x - begProj.x;
-				dy	= endProj.y - begProj.y;
-				oolen= 1/sqrt(dx*dx+dy*dy)*0.5;
-				persp=0;
-				persp.x=-dy*oolen; persp.y=dx*oolen;
+				dx = endProj.x - begProj.x;
+				dy = endProj.y - begProj.y;
+				oolen = 0.5f / sqrt(dx * dx + dy * dy);
+				persp = {-dy * oolen, dx * oolen, 0.0f};
 
 				glColor4f(color1[i]*fogcolorr*1.6,color2[i]*fogcolorg*1.6,color3[i]*fogcolorb*1.6,brightness[i]);