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

游戏引擎

开发平台:

Visual C++

  1. /* Position
  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 "engine.h"
  20. #include "object.h"
  21. #include "rigidbody.h"
  22. #include "parser.h"
  23. #include "position.h"
  24. Position::Position() : spline(NULL), expression(NULL), sector(-1), radius(0.0), num_sectors(0) {
  25. sectors = new int[NUM_SECTORS];
  26. }
  27. Position::~Position() {
  28. if(spline) delete spline;
  29. if(expression) delete expression;
  30. delete sectors;
  31. }
  32. /*
  33.  */
  34. Position &Position::operator=(const Position &pos) {
  35. x = pos.x;
  36. y = pos.y;
  37. z = pos.z;
  38. spline = pos.spline ? new Spline(*pos.spline) : NULL;
  39. expression = pos.expression ? new Expression(*pos.expression) : NULL;
  40. sector = pos.sector;
  41. radius = pos.radius;
  42. num_sectors = pos.num_sectors;
  43. for(int i = 0; i < num_sectors; i++) sectors[i] = pos.sectors[i];
  44. return *this;
  45. }
  46. Position &Position::operator=(const vec3 &pos) {
  47. if(Bsp::num_sectors == 0) return *this;
  48. x = pos.x;
  49. y = pos.y;
  50. z = pos.z;
  51. num_sectors = 0;
  52. if(sector == -1) { // find in all sectors
  53. for(int i = 0; i < Bsp::num_sectors; i++) {
  54. if(Bsp::sectors[i].inside(vec3(*this))) {
  55. sector = i;
  56. find(sector,radius);
  57. return *this;
  58. }
  59. }
  60. } else {
  61. if(Bsp::sectors[sector].inside(*this) == 0) {
  62. Sector *s = &Bsp::sectors[sector];
  63. for(int i = 0; i < s->num_portals; i++) { // find in neighborning sectors
  64. Portal *p = &Bsp::portals[s->portals[i]];
  65. for(int j = 0; j < p->num_sectors; j++) {
  66. if(p->sectors[j] == sector) continue;
  67. if(Bsp::sectors[p->sectors[j]].inside(*this)) {
  68. sector = p->sectors[j];
  69. find(sector,radius);
  70. return *this;
  71. }
  72. }
  73. }
  74. for(int i = 0; i < Bsp::num_sectors; i++) { // find in all sectors
  75. if(Bsp::sectors[i].inside(*this)) {
  76. sector = i;
  77. find(sector,radius);
  78. return *this;
  79. }
  80. }
  81. sector = -1;
  82. }
  83. }
  84. if(sector != -1) find(sector,radius);
  85. return *this;
  86. }
  87. void Position::find(int sector,float r) {
  88. if(num_sectors == NUM_SECTORS) {
  89. fprintf(stderr,"Position::find(): this object presents in %d sectorsn",num_sectors);
  90. return;
  91. }
  92. sectors[num_sectors++] = sector;
  93. if(radius < 0.0) return;
  94. Sector *s = &Bsp::sectors[sector];
  95. for(int i = 0; i < s->num_portals; i++) {
  96. Portal *p = &Bsp::portals[s->portals[i]];
  97. if((*this - p->center).length() > r + p->radius) continue;
  98. for(int j = 0; j < p->num_sectors; j++) {
  99. int k = 0;
  100. for(; k < num_sectors; k++) if(sectors[k] == p->sectors[j]) break;
  101. if(k != num_sectors) continue;
  102. if(Bsp::sectors[p->sectors[j]].inside(*this,radius)) find(p->sectors[j],r - (*this - p->center).length());
  103. }
  104. }
  105. }
  106. /*
  107.  */
  108. void Position::setSpline(Spline *spline) {
  109. this->spline = spline;
  110. expression = NULL;
  111. }
  112. void Position::setExpression(Expression *expression) {
  113. spline = NULL;
  114. this->expression = expression;
  115. }
  116. /*
  117.  */
  118. void Position::setRadius(float radius) {
  119. this->radius = radius;
  120. }
  121. /*
  122.  */
  123. void Position::update(float time,mat4 &transform) {
  124. if(spline) {
  125. transform = spline->to_matrix(time);
  126. operator=(transform * vec3(0,0,0));
  127. } else if(expression) {
  128. transform = expression->to_matrix(time);
  129. operator=(transform * vec3(0,0,0));
  130. }
  131. }
  132. /*
  133.  */
  134. void Position::update(float time,Object *object) {
  135. if(spline || expression) {
  136. if(object) {
  137. object->is_identity = 0;
  138. for(int i = 0; i < num_sectors; i++) Bsp::sectors[sectors[i]].removeObject(object);
  139. radius = object->getRadius();
  140. }
  141. mat4 transform;
  142. if(spline) transform = spline->to_matrix(time);
  143. else transform = expression->to_matrix(time);
  144. operator=(transform * vec3(0,0,0));
  145. if(object) {
  146. object->transform = transform;
  147. object->itransform = transform.inverse();
  148. for(int i = 0; i < num_sectors; i++) Bsp::sectors[sectors[i]].addObject(object);
  149. }
  150. }
  151. }
  152. /*
  153.  */
  154. mat4 Position::to_matrix(float time) {
  155. if(spline) return spline->to_matrix(time);
  156. if(expression) return expression->to_matrix(time);
  157. mat4 transform;
  158. transform.translate(*this);
  159. return transform;
  160. }
  161. /*****************************************************************************/
  162. /*                                                                           */
  163. /* Spline                                                                    */
  164. /*                                                                           */
  165. /*****************************************************************************/
  166. Spline::Spline(const char *name,float speed,int close,int follow) : num(0), params(NULL), speed(speed), length(0.0), follow(follow) {
  167. FILE *file = fopen(name,"r");
  168. if(!file) {
  169. fprintf(stderr,"Spline::Spline(): error open "%s" filen",name);
  170. return;
  171. }
  172. vec3 v;
  173. while(fscanf(file,"%f %f %f",&v.x,&v.y,&v.z) == 3) num++;
  174. vec3 *val = new vec3[num];
  175. num = 0;
  176. fseek(file,0,SEEK_SET);
  177. while(fscanf(file,"%f %f %f",&v.x,&v.y,&v.z) == 3) val[num++] = v;
  178. fclose(file);
  179. float tension = 0.0;
  180. float bias = 0.0;
  181. float continuity = 0.0;
  182. params = new vec3[num * 4];
  183. for(int i = 0; i < num; i++) {
  184. vec3 prev,cur,next;
  185. if(i == 0) {
  186. if(close) prev = val[num - 1];
  187. else prev = val[i];
  188. cur = val[i];
  189. next = val[i + 1];
  190. } else if(i == num - 1) {
  191. prev = val[i - 1];
  192. cur = val[i];
  193. if(close) next = val[0];
  194. else next = val[i];
  195. } else {
  196. prev = val[i - 1];
  197. cur = val[i];
  198. next = val[i + 1];
  199. }
  200. vec3 p0 = (cur - prev) * (1.0f + bias);
  201. vec3 p1 = (next - cur) * (1.0f - bias);
  202. vec3 r0 = (p0 + (p1 - p0) * 0.5f * (1.0f + continuity)) * (1.0f - tension);
  203. vec3 r1 = (p0 + (p1 - p0) * 0.5f * (1.0f - continuity)) * (1.0f - tension);
  204. params[i * 4 + 0] = cur;
  205. params[i * 4 + 1] = next;
  206. params[i * 4 + 2] = r0;
  207. if(i) params[i * 4 - 1] = r1;
  208. else params[(num - 1) * 4 + 3] = r1;
  209. length += (next - cur).length();
  210. }
  211. for(int i = 0; i < num; i++) {
  212. vec3 p0 = params[i * 4 + 0];
  213. vec3 p1 = params[i * 4 + 1];
  214. vec3 r0 = params[i * 4 + 2];
  215. vec3 r1 = params[i * 4 + 3];
  216. params[i * 4 + 0] = p0;
  217. params[i * 4 + 1] = r0;
  218. params[i * 4 + 2] = -p0 * 3.0f + p1 * 3.0f - r0 * 2.0f - r1;
  219. params[i * 4 + 3] = p0 * 2.0f - p1 * 2.0f + r0 + r1;
  220. }
  221. delete val;
  222. }
  223. Spline::Spline(const Spline &spline) {
  224. num = spline.num;
  225. params = new vec3[num * 4];
  226. memcpy(params,spline.params,sizeof(vec3) * num * 4);
  227. speed = spline.speed;
  228. length = spline.length;
  229. follow = spline.follow;
  230. }
  231. Spline::~Spline() {
  232. if(params) delete params;
  233. }
  234. /*
  235.  */
  236. mat4 Spline::to_matrix(float time) {
  237. if(!params) return mat4();
  238. time *= speed / length * (float)num;
  239. int i = (int)time;
  240. time -= i;
  241. i = (i % num) * 4;
  242. float time2 = time * time;
  243. float time3 = time2 * time;
  244. vec3 pos = params[i + 0] + params[i + 1] * time + params[i + 2] * time2 + params[i + 3] * time3;
  245. mat4 transform;
  246. transform.translate(pos);
  247. return transform;
  248. }
  249. /*****************************************************************************/
  250. /*                                                                           */
  251. /* Expression                                                                */
  252. /*                                                                           */
  253. /*****************************************************************************/
  254. Expression::Expression(const char *str) {
  255. int length = strlen(str) + 1;
  256. for(int i = 0; i < 14; i++) {
  257. exp[i] = new char[length];
  258. exp[i][0] = '';
  259. }
  260. char *s = (char*)str;
  261. for(int i = 0; i < 14; i++) {
  262. char *d = NULL;
  263. d = exp[i];
  264. if(*s == '') {
  265. if(i == 7) return;
  266. fprintf(stderr,"Expression::Expression(): missing argument %d "%s"n",i,str);
  267. return;
  268. }
  269. while(1) {
  270. if(*s && *s != ',') {
  271. if(strchr(" tnr",*s)) s++;
  272. else *d++ = *s++;
  273. } else {
  274. if(*d == '' && *s != ',') {
  275. if(i == 6) return;
  276. fprintf(stderr,"Expression::Expression(): missing argument %d "%s"n",i,str);
  277. return;
  278. }
  279. else *d = '';
  280. if(*s) s++;
  281. break;
  282. }
  283. }
  284. }
  285. }
  286. Expression::Expression(const Expression &expression) {
  287. for(int i = 0; i < 14; i++) {
  288. exp[i] = new char[strlen(expression.exp[i]) + 1];
  289. strcpy(exp[i],expression.exp[i]);
  290. }
  291. }
  292. Expression::~Expression() {
  293. for(int i = 0; i < 14; i++) delete exp[i];
  294. }
  295. /*
  296.  */
  297. mat4 Expression::to_matrix(float time) {
  298. vec3 pos_0 = vec3(Parser::expression(exp[0],"time",time),Parser::expression(exp[1],"time",time),Parser::expression(exp[2],"time",time));
  299. quat rot_0 = quat(Parser::expression(exp[3],"time",time),Parser::expression(exp[4],"time",time),Parser::expression(exp[5],"time",time),Parser::expression(exp[6],"time",time));
  300. mat4 translate_0;
  301. translate_0.translate(pos_0);
  302. if(exp[7][0] == '') return translate_0 * rot_0.to_matrix();
  303. vec3 pos_1 = vec3(Parser::expression(exp[7],"time",time),Parser::expression(exp[8],"time",time),Parser::expression(exp[9],"time",time));
  304. quat rot_1 = quat(Parser::expression(exp[10],"time",time),Parser::expression(exp[11],"time",time),Parser::expression(exp[12],"time",time),Parser::expression(exp[13],"time",time));
  305. mat4 translate_1;
  306. translate_1.translate(pos_1);
  307. return (translate_1 * rot_1.to_matrix()) * (translate_0 * rot_0.to_matrix());
  308. }