Welt2D.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. #include "Welt2D.h"
  2. #include "Bild.h"
  3. using namespace Framework;
  4. Object2D::Object2D()
  5. {
  6. rSpeed = 0;
  7. rotation = 0;
  8. size = 1;
  9. ref = 1;
  10. }
  11. Object2D::~Object2D()
  12. {}
  13. void Object2D::explosion( Vertex worldPos, float intensity )
  14. {
  15. intensity /= ( position - worldPos ).getLengthSq();
  16. speed += ( position - worldPos ) * intensity;
  17. }
  18. void Object2D::impuls( Vertex start, Vertex speed )
  19. {}
  20. void Object2D::setSpeed( Vertex speed )
  21. {
  22. this->speed = speed;
  23. }
  24. void Object2D::setSpeed( float x, float y )
  25. {
  26. speed.x = x, speed.y = y;
  27. }
  28. void Object2D::setPosition( Vertex pos )
  29. {
  30. position = pos;
  31. }
  32. void Object2D::setPosition( float x, float y )
  33. {
  34. position = Vertex( x, y );
  35. }
  36. void Object2D::setDrehungSpeed( float ds )
  37. {
  38. rSpeed = ds;
  39. }
  40. void Object2D::setDrehung( float drehung )
  41. {
  42. rotation = drehung;
  43. while( rotation > PI * 2 )
  44. rotation -= (float)PI * 2;
  45. while( rotation < 0 )
  46. rotation += (float)PI * 2;
  47. }
  48. void Object2D::addDrehung( float drehung )
  49. {
  50. rotation += drehung;
  51. while( rotation > PI * 2 )
  52. rotation -= (float)PI * 2;
  53. while( rotation < 0 )
  54. rotation += (float)PI * 2;
  55. }
  56. void Object2D::setSize( float size )
  57. {
  58. this->size = size;
  59. }
  60. void Object2D::addSize( float size )
  61. {
  62. this->size += size;
  63. }
  64. bool Object2D::handleCollision( Object2D *obj )
  65. {
  66. Vertex hp;
  67. if( istModelInnen( obj, &hp ) )
  68. {
  69. Vertex v1 = getSpeed() + getWorldDir( getObjectPos( hp ).rotation( rSpeed ) - getObjectPos( hp ) );
  70. Vertex v2 = obj->getSpeed() + getWorldDir( obj->getObjectPos( hp ).rotation( obj->getDrehungSpeed() ) - obj->getObjectPos( hp ) );
  71. float m1 = getMasse();
  72. float m2 = obj->getMasse();
  73. if( m1 == 0 || m2 == 0 )
  74. return 0;
  75. rSpeed = 0;
  76. speed = Vertex( 0, 0 );
  77. obj->setDrehungSpeed( 0 );
  78. obj->setSpeed( 0, 0 );
  79. if( v2.x || v2.y )
  80. impuls( hp - v2, v2 * ( m2 / ( m1 + m2 ) ) );
  81. if( v1.x || v1.y )
  82. obj->impuls( hp - v1, v1 * ( m1 / ( m1 + m2 ) ) );
  83. return 1;
  84. }
  85. return 0;
  86. }
  87. bool Object2D::tick( const WeltInfo &info, double zeit )
  88. {
  89. rotation += rSpeed * (float)zeit;
  90. while( rotation > PI * 2 )
  91. rotation -= (float)PI * 2;
  92. while( rotation < 0 )
  93. rotation += (float)PI * 2;
  94. position += speed * (float)zeit;
  95. while( zeit > 1 )
  96. {
  97. rSpeed -= rSpeed - ( rSpeed / ( 1 + info.airResistance * getLuftWiederstand() ) );
  98. speed -= speed - ( speed / ( 1 + info.airResistance * getLuftWiederstand() ) );
  99. zeit -= 1;
  100. }
  101. rSpeed -= ( rSpeed - ( rSpeed / ( 1 + info.airResistance * getLuftWiederstand() ) ) ) * (float)zeit;
  102. speed -= ( speed - ( speed / ( 1 + info.airResistance * getLuftWiederstand() ) ) ) * (float)zeit;
  103. return rSpeed != 0 || speed != Vertex( 0, 0 );
  104. }
  105. bool Object2D::istPunktInnen( Vertex p ) const
  106. {
  107. return 0;
  108. }
  109. bool Object2D::istLinieInnen( Vertex a, Vertex b ) const
  110. {
  111. return 0;
  112. }
  113. bool Object2D::istModelInnen( const Object2D *zObj, Vertex *sp, bool end ) const
  114. {
  115. return 0;
  116. }
  117. Mat3< float > Object2D::getObjectMatrix() const
  118. {
  119. return Mat3<float>::translation( position ) * Mat3<float>::rotation( rotation ) * Mat3<float>::scaling( size );
  120. }
  121. Mat3< float > Object2D::getInverseObjectMatrix() const
  122. {
  123. return Mat3<float>::scaling( 1 / size ) * Mat3<float>::rotation( -rotation ) * Mat3<float>::translation( -position );
  124. }
  125. Vertex Object2D::getObjectPos( Vertex worldPos ) const
  126. {
  127. return ( worldPos - position ).rotation( -rotation ) * ( 1 / size );
  128. }
  129. Vertex Object2D::getObjectDir( Vertex worldDir ) const
  130. {
  131. return Vertex( worldDir.x, worldDir.y ).rotation( -rotation ) * ( 1 / size );
  132. }
  133. Vertex Object2D::getWorldPos( Vertex objectPos ) const
  134. {
  135. return ( Vertex( objectPos ) * size ).rotation( rotation ) + position;
  136. }
  137. Vertex Object2D::getWorldDir( Vertex objectDir ) const
  138. {
  139. return ( Vertex( objectDir ) * size ).rotation( rotation );
  140. }
  141. Vertex Object2D::getSpeed() const
  142. {
  143. return speed;
  144. }
  145. Vertex Object2D::getPosition() const
  146. {
  147. return position;
  148. }
  149. float Object2D::getDrehungSpeed() const
  150. {
  151. return rSpeed;
  152. }
  153. float Object2D::getDrehung() const
  154. {
  155. return rotation;
  156. }
  157. float Object2D::getSize() const
  158. {
  159. return size;
  160. }
  161. bool Object2D::calcHitPoint( Vertex pos, Vertex dir, Vertex &hitpoint ) const
  162. {
  163. return 0;
  164. }
  165. float Object2D::getLuftWiederstand() const
  166. {
  167. return 0;
  168. }
  169. float Object2D::getMasse() const
  170. {
  171. return 0;
  172. }
  173. Object2D *Object2D::getThis()
  174. {
  175. ref++;
  176. return this;
  177. }
  178. Object2D *Object2D::release()
  179. {
  180. if( !--ref )
  181. delete this;
  182. return 0;
  183. }
  184. Welt2D::Welt2D()
  185. {
  186. objects = new RCArray< Object2D >();
  187. memset( &info, 0, sizeof( WeltInfo ) );
  188. ref = 1;
  189. }
  190. Welt2D::~Welt2D()
  191. {
  192. objects->release();
  193. }
  194. void Welt2D::setAirResistance( float resistance )
  195. {
  196. info.airResistance = resistance;
  197. }
  198. void Welt2D::addObject( Object2D *obj )
  199. {
  200. objects->add( obj );
  201. }
  202. void Welt2D::explosion( Vertex worldPos, float intensity, float maxRad )
  203. {
  204. maxRad = maxRad * maxRad;
  205. for( auto obj = objects->getArray(); obj.set; obj++ )
  206. {
  207. if( ( obj.var->getPosition() - worldPos ).getLengthSq() < maxRad )
  208. obj.var->explosion( worldPos, intensity );
  209. }
  210. }
  211. void Welt2D::impuls( Vertex worldPos, Vertex worldDir )
  212. {
  213. Vertex hitPoint;
  214. float dist = INFINITY;
  215. Object2D *o = 0;
  216. for( auto obj = objects->getArray(); obj.set; obj++ )
  217. {
  218. if( obj.var->calcHitPoint( worldPos, worldDir, hitPoint ) )
  219. {
  220. if( ( hitPoint - worldPos ).getLengthSq() < dist )
  221. {
  222. dist = ( hitPoint - worldPos ).getLengthSq();
  223. o = obj.var;
  224. }
  225. }
  226. }
  227. if( o )
  228. o->impuls( worldPos, worldDir );
  229. }
  230. bool Welt2D::tick( double zeit )
  231. {
  232. bool ret = 0;
  233. for( auto obj = objects->getArray(); obj.set; obj++ )
  234. {
  235. if( obj.next )
  236. {
  237. for( auto obj2 = *obj.next; obj2.set; obj2++ )
  238. {
  239. if( obj.var->handleCollision( obj2 ) )
  240. {
  241. while( obj.var->istModelInnen( obj2 ) )
  242. {
  243. ret |= obj.var->tick( info, 0.03 );
  244. ret |= obj2.var->tick( info, 0.03 );
  245. }
  246. }
  247. }
  248. }
  249. ret |= obj.var->tick( info, zeit );
  250. }
  251. return ret;
  252. }
  253. void Welt2D::render( Mat3< float > &kamMat, Punkt size, Bild &zRObj )
  254. {
  255. for( auto obj = objects->getArray(); obj.set; obj++ )
  256. {
  257. Rect2< float > bnd = obj.var->getBoundingBox();
  258. Vertex topRight = Vertex( bnd.topLeft.y, bnd.bottomRight.x );
  259. Vertex bottomLeft = Vertex( bnd.topLeft.x, bnd.bottomRight.y );
  260. bnd.bottomRight = kamMat * bnd.bottomRight;
  261. bnd.topLeft = kamMat * bnd.topLeft;
  262. topRight = kamMat * topRight;
  263. bottomLeft = kamMat * bottomLeft;
  264. if( ( bnd.bottomRight.x >= 0 && bnd.bottomRight.x < size.x ) ||
  265. ( bnd.bottomRight.y >= 0 && bnd.bottomRight.y < size.y ) ||
  266. ( bnd.topLeft.x >= 0 && bnd.topLeft.x < size.x ) ||
  267. ( bnd.topLeft.y >= 0 && bnd.topLeft.y < size.y ) ||
  268. ( topRight.x >= 0 && topRight.x < size.x ) ||
  269. ( topRight.y >= 0 && topRight.y < size.y ) ||
  270. ( bottomLeft.x >= 0 && bottomLeft.x < size.x ) ||
  271. ( bottomLeft.y >= 0 && bottomLeft.y < size.y ) )
  272. obj.var->render( kamMat, zRObj );
  273. }
  274. }
  275. Welt2D *Welt2D::getThis()
  276. {
  277. ref++;
  278. return this;
  279. }
  280. Welt2D *Welt2D::release()
  281. {
  282. if( !--ref )
  283. delete this;
  284. return 0;
  285. }