Advertisement
Guest User

Code Snippets

a guest
May 24th, 2019
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.33 KB | None | 0 0
  1. ## Here's the main game loop (just the relevant parts anyway):
  2.  
  3. ```
  4. //Update camera
  5. //BUGFIX: Stage tilt doesn't seem to take camera rotation into account, figure out why and fix
  6. //BUGFIX: Shadows rotate in the opposite direction as expected, figure out why and fix
  7. if(glm::length2(glm::vec2(p->Velocity.x,p->Velocity.z))>0.000001f) {
  8. float vang = atan2f(-p->Velocity.x,-p->Velocity.z);
  9. if(GameSubmode!=2) {
  10. vang = -vang;
  11. }
  12. if(vang<0) {vang+=6.283185f;}
  13. float delta = fmodf(vang-PrevCamAngle,6.283185f);
  14. vang = fmodf(2*delta,6.283185f)-delta;
  15. PrevCamAngle = PrevCamAngle+(vang*0.25f);
  16. if(PrevCamAngle<0) {PrevCamAngle+=6.283185f;}
  17. }
  18. glm::quat PrevCamRotation = glm::angleAxis(PrevCamAngle,glm::vec3(0,1,0));
  19.  
  20. //Initialize gravity vector
  21. glm::vec3 gravity(0,-0.098f,0);
  22. //Set target to no rotation (so that goal/perfect end sequences slow down ball gradually)
  23. glm::quat target = glm::quat(1,0,0,0);
  24. glm::quat target2 = glm::quat(1,0,0,0);
  25. //If gameplay is active, set target according to input
  26. if(GameSubmode==2) {
  27. target = PrevCamRotation*
  28. glm::angleAxis(-AnalogX/2,glm::vec3(0,0,1))*
  29. glm::angleAxis(-AnalogY/2,glm::vec3(1,0,0));
  30. target2 = PrevCamRotation*
  31. glm::angleAxis(AnalogX/2,glm::vec3(0,0,1))*
  32. glm::angleAxis(AnalogY/2,glm::vec3(1,0,0));
  33. } else if(GameSubmode==4) {
  34. }
  35. //Update stage rotation, and rotate gravity vector accordingly
  36. PrevStageRotation = glm::slerp(PrevStageRotation,target,0.05f);
  37. PrevGravRotation = glm::slerp(PrevGravRotation,target2,0.05f);
  38. gravity = PrevGravRotation*gravity;
  39.  
  40. //Clear previous collisions
  41. bool isColi = false;
  42. float minDist = 2;
  43. glm::vec3 coliNrm = glm::vec3(0);
  44. glm::vec3 coliPt;
  45.  
  46. //Check for stage collisions
  47. CollisionResult * cr = new CollisionResult();
  48. //For each stage object
  49. for(int i=OBJID_STAGE; i<OBJID_GOALS; i++) {
  50. //If the stage object exists and has collision
  51. if(objBuffer[i].IsActive && objBuffer[i].HasCollision) {
  52. //TODO: Pre-transform player
  53. //Calculate collision
  54. objBuffer[i].ObjCollision->CollideSphere(cr,p->Position,p->Velocity);
  55. //If player is colliding
  56. if(cr->IsCollision) {
  57. isColi = true;
  58. minDist = cr->CollisionDistance;
  59. coliPt = cr->CollisionPoint;
  60. coliNrm = cr->CollisionNormal;
  61. }
  62. //TODO: Post-transform player
  63. }
  64. }
  65. //Check for object collisions
  66. //OMITTED FOR CLARITY
  67. //Handle rolling and friction
  68. //If there was a collision
  69. //BUGFIX: The ball is all jittery, figure out how best to fix
  70. if(isColi) {
  71. float dp = glm::dot(coliNrm,p->Velocity);
  72. if(dp<0) {
  73. p->Velocity += -1.7f*dp*coliNrm;
  74. //p->Position += -0.2f*(0.5f-minDist)*dp*coliNrm;
  75. }
  76. //Rotate ball against surface normal
  77. glm::quat rot = glm::angleAxis(glm::length(p->Velocity)*2,glm::cross(coliNrm,p->Velocity));
  78. p->Rotation = glm::normalize(rot*p->Rotation);
  79. //Adjust velocity for friction
  80. float d = glm::dot(coliNrm,glm::normalize(gravity));
  81. float fric = 0.9f*sqrtf(1.001f-(d*d));
  82. float d2 = glm::dot(coliNrm,p->Velocity);
  83. glm::vec3 proj = d2*coliNrm;
  84. glm::vec3 rej = p->Velocity-proj;
  85. p->Velocity = proj + fric*rej;
  86. }
  87. PrevColiNrm = coliNrm;
  88. //Update ball position
  89. p->Position += p->Velocity;
  90. //Update ball velocity
  91. p->Velocity += gravity;
  92. //Check for terminal velocity (to avoid clipping)
  93. if(glm::length2(p->Velocity)>1) {
  94. p->Velocity = glm::normalize(p->Velocity);
  95. }
  96. //TODO: animate player
  97.  
  98. //Update object specific properties
  99. //OMITTED FOR CLARITY
  100.  
  101. //Display ball
  102. u_CameraPos = PrevStageRotation*(p->Position+(PrevCamRotation*glm::vec3(0,2,5)));
  103. u_View = glm::lookAt(u_CameraPos,PrevStageRotation*p->Position,glm::vec3(0,1,0));
  104. objBuffer[OBJID_BALL_INNER].Position = objBuffer[OBJID_BALL_OUTER].Position = PrevStageRotation*p->Position;
  105. objBuffer[OBJID_MONKEY].Position = PrevStageRotation*(p->Position + glm::vec3(0,-0.5f,0));
  106. objBuffer[OBJID_BALL_INNER].Rotation = objBuffer[OBJID_BALL_OUTER].Rotation = glm::normalize(PrevStageRotation*p->Rotation);
  107. objBuffer[OBJID_MONKEY].Rotation = glm::normalize(PrevStageRotation);
  108. //Rotate and animate stage and objects
  109. for(int i=OBJID_STAGE; i<OBJID_BUTTONS; i++) {
  110. if(objBuffer[i].IsActive) {
  111. //TODO: animate objects
  112.  
  113. //Update object position and rotation to reflect stage tilt
  114. objBuffer[i].Position = PrevStageRotation*objBuffer[i].TruePosition;
  115. objBuffer[i].Rotation = glm::normalize(PrevStageRotation*objBuffer[i].TrueRotation);
  116. }
  117. }
  118. ```
  119.  
  120. ## Here are the collision routines (pretty sure these are correct, like 99%):
  121.  
  122. ```
  123. void FCOL::CollideSphere(CollisionResult * result, glm::vec3 position, glm::vec3 velocity) {
  124. result->IsCollision = false;
  125.  
  126. CollisionResult * cr = new CollisionResult();
  127.  
  128. result->CollisionDistance = 2;
  129.  
  130. for(int i=0; i<TriCount; i++) {
  131. if(glm::dot(velocity,Entries[i].Normal)<0) {
  132. Entries[i].CollideSphere(cr,position);
  133. if(cr->IsCollision) {
  134. if(result->CollisionDistance>cr->CollisionDistance) {
  135. result->IsCollision = true;
  136. result->CollisionDistance = cr->CollisionDistance;
  137. result->CollisionPoint = cr->CollisionPoint;
  138. result->CollisionNormal = Entries[i].Normal;
  139. }
  140. }
  141. }
  142. }
  143.  
  144. return;
  145. }
  146. void FCOLTriangle::CollideSphere(CollisionResult * result, glm::vec3 position) {
  147. result->IsCollision = false;
  148.  
  149. glm::vec3 ap = Points[0]-position;
  150. glm::vec3 bp = Points[1]-position;
  151. glm::vec3 cp = Points[2]-position;
  152. float rr = 0.25f;
  153. glm::vec3 v = glm::cross(bp-ap,cp-ap);
  154. float d = glm::dot(ap,v);
  155. float e = glm::dot(v,v);
  156. if((d*d)>(rr*e)) {return;}
  157.  
  158. float aa = glm::dot(ap,ap);
  159. float ab = glm::dot(ap,bp);
  160. float ac = glm::dot(ap,cp);
  161. float bb = glm::dot(bp,bp);
  162. float bc = glm::dot(bp,cp);
  163. float cc = glm::dot(cp,cp);
  164. if(aa>rr && ab>aa && ac>aa) {return;}
  165. if(bb>rr && ab>bb && bc>bb) {return;}
  166. if(cc>rr && ac>cc && bc>cc) {return;}
  167.  
  168. glm::vec3 a2b = bp-ap;
  169. glm::vec3 b2c = cp-bp;
  170. glm::vec3 c2a = ap-cp;
  171. float d1 = ab-aa;
  172. float d2 = bc-bb;
  173. float d3 = ac-cc;
  174. float e1 = glm::dot(a2b,a2b);
  175. float e2 = glm::dot(b2c,b2c);
  176. float e3 = glm::dot(c2a,c2a);
  177. glm::vec3 q1 = ap*e1 - d1*a2b;
  178. glm::vec3 q2 = bp*e2 - d2*b2c;
  179. glm::vec3 q3 = cp*e3 - d3*c2a;
  180. glm::vec3 qc = cp*e1 - q1;
  181. glm::vec3 qa = ap*e2 - q2;
  182. glm::vec3 qb = bp*e3 - q3;
  183. if(glm::dot(q1,q1)>(rr*e1*e1) && glm::dot(q1,qc)>0) {return;}
  184. if(glm::dot(q2,q2)>(rr*e2*e2) && glm::dot(q2,qa)>0) {return;}
  185. if(glm::dot(q3,q3)>(rr*e3*e3) && glm::dot(q3,qb)>0) {return;}
  186.  
  187. result->IsCollision = true;
  188.  
  189.  
  190.  
  191. float dist = glm::dot(ap,Normal);
  192. glm::vec3 pnt = position+dist*Normal;
  193. float dist2 = sqrtf(glm::dot(ap,ap));
  194. if(fabsf(dist2)<fabsf(dist)) {
  195. dist = dist2;
  196. pnt = Points[0];
  197. }
  198. dist2 = sqrtf(glm::dot(bp,bp));
  199. if(fabsf(dist2)<fabsf(dist)) {
  200. dist = dist2;
  201. pnt = Points[1];
  202. }
  203. dist2 = sqrtf(glm::dot(cp,cp));
  204. if(fabsf(dist2)<fabsf(dist)) {
  205. dist = dist2;
  206. pnt = Points[2];
  207. }
  208. dist2 = glm::length(ap-glm::dot(ap,glm::normalize(a2b))*glm::normalize(a2b));
  209. if(fabsf(dist2)<fabsf(dist)) {
  210. dist = dist2;
  211. pnt = position+dist*glm::normalize(a2b);
  212. }
  213. dist2 = glm::length(bp-glm::dot(bp,glm::normalize(b2c))*glm::normalize(b2c));
  214. if(fabsf(dist2)<fabsf(dist)) {
  215. dist = dist2;
  216. pnt = position+dist*glm::normalize(b2c);
  217. }
  218. dist2 = glm::length(cp-glm::dot(cp,glm::normalize(c2a))*glm::normalize(c2a));
  219. if(fabsf(dist2)<fabsf(dist)) {
  220. dist = dist2;
  221. pnt = position+dist*glm::normalize(c2a);
  222. }
  223.  
  224. result->CollisionPoint = pnt;
  225. result->CollisionDistance = fabsf(dist);
  226. }
  227. ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement