physic.cpp
上传用户:qccn516
上传日期:2013-05-02
资源大小:3382k
文件大小:4k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /* Physic
  2.  *
  3.  * Copyright (C) 2003-2004, Alexander Zaprjagaev <frustum@frustum.org>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include "rigidbody.h"
  22. #include "collide.h"
  23. #include "joint.h"
  24. #include "physic.h"
  25. float Physic::time = 0.0;
  26. float Physic::time_step = 1.0f / 50.0f;
  27. float Physic::gravitation = -9.8f * 0.5f;
  28. float Physic::velocity_max = 20.0f;
  29. float Physic::velocity_threshold = 0.1f * 0.1f;
  30. float Physic::angularVelocity_threshold = (2.0f * DEG2RAD) * (2.0f * DEG2RAD);
  31. float Physic::time_to_frost = 1.0f / 10.f;
  32. float Physic::penetration_speed = 1.0f / 5.0f;
  33. int Physic::num_first_iterations = 5;
  34. int Physic::num_second_iterations = 15;
  35. int Physic::all_joints = 0;
  36. int Physic::num_joints = 0;
  37. Joint **Physic::joints = NULL;
  38. int Physic::all_rigidbodies = 0;
  39. int Physic::num_rigidbodies = 0;
  40. RigidBody **Physic::rigidbodies = NULL;
  41. /*
  42.  */
  43. int rigidbody_cmp(const void *a,const void *b) {
  44. RigidBody *r0 = *(RigidBody**)a;
  45. RigidBody *r1 = *(RigidBody**)b;
  46. if(r0->pos.z > r1->pos.z) return 1;
  47. if(r0->pos.z < r1->pos.z) return -1;
  48. return 0;
  49. }
  50. /*
  51.  */
  52. void Physic::update(float ifps) {
  53. qsort(rigidbodies,num_rigidbodies,sizeof(RigidBody*),rigidbody_cmp);
  54. time += ifps;
  55. while(time > time_step) {
  56. time -= time_step;
  57. for(int i = 0; i < num_rigidbodies; i++) {
  58. RigidBody *rb = rigidbodies[i];
  59. rb->force = vec3(0,0,0);
  60. rb->torque = vec3(0,0,0);
  61. if(rb->frozen == 0) rb->findContacts(time_step);
  62. rb->frozen = 0;
  63. }
  64. for(int i = 0; i < num_first_iterations; i++) {
  65. int done = 1;
  66. for(int j = 0; j < num_rigidbodies; j++) {
  67. if(rigidbodies[j]->contactsResponse(time_step) == 0) done = 0;
  68. }
  69. for(int j = 0; j < num_joints; j++) {
  70. joints[j]->response(time_step);
  71. }
  72. if(done) break;
  73. }
  74. for(int i = 0; i < num_rigidbodies; i++) {
  75. RigidBody *rb = rigidbodies[i];
  76. if(rb->collide->num_contacts > 0 && rb->num_joints == 0 &&
  77. rb->velocity * rb->velocity < velocity_threshold &&
  78. rb->angularVelocity * rb->angularVelocity < angularVelocity_threshold) {
  79. rb->frozen_time += time_step;
  80. if(rb->frozen_time > time_to_frost) {
  81. if(rb->frozen_num_objects == rb->collide->num_objects) {
  82. rb->frozen = 1;
  83. rb->velocity = vec3(0,0,0);
  84. rb->angularVelocity = vec3(0,0,0);
  85. } else {
  86. rb->frozen = 0;
  87. rb->frozen_time = 0.0;
  88. rb->findContacts(time_step);
  89. }
  90. }
  91. rb->frozen_num_objects = rb->collide->num_objects;
  92. } else {
  93. rb->frozen = 0;
  94. rb->frozen_time = 0.0;
  95. rb->findContacts(time_step);
  96. }
  97. rb->calcForce(time_step);
  98. rb->integrateVelocity(time_step);
  99. }
  100. for(int i = 0; i < num_second_iterations; i++) {
  101. int done = 1;
  102. for(int j = 0; j < num_rigidbodies; j++) {
  103. if(rigidbodies[j]->contactsResponse(time_step,true) == 0) done = 0;
  104. }
  105. for(int j = 0; j < num_joints; j++) {
  106. joints[j]->response(time_step);
  107. }
  108. if(done) break;
  109. }
  110. for(int i = 0; i < num_rigidbodies; i++) {
  111. if(rigidbodies[i]->frozen == 0) rigidbodies[i]->integratePos(time_step);
  112. }
  113. }
  114. // new simulate - new objects
  115. for(int i = 0; i < num_rigidbodies; i++) {
  116. rigidbodies[i]->simulated = 0;
  117. rigidbodies[i]->immovable = 0;
  118. }
  119. num_rigidbodies = 0;
  120. num_joints = 0;
  121. }