ParticlesGame.cpp 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194
  1. #include "ParticlesGame.h"
  2. // Declare our game instance.
  3. ParticlesGame game;
  4. #define DEFAULT_PARTICLE_EMITTER "res/fire.particle"
  5. const float INPUT_SENSITIVITY = 0.05f;
  6. const float PANNING_SENSITIVITY = 0.01f;
  7. const float ROTATE_SENSITIVITY = 0.25f;
  8. const Vector4 BACKGROUND_COLOR = Vector4::zero();
  9. const float INITIAL_ZOOM = 6.0f;
  10. ParticlesGame::ParticlesGame() : _scene(NULL), _panning(false), _rotating(false), _zooming(false)
  11. {
  12. }
  13. void ParticlesGame::addGrid(unsigned int lineCount)
  14. {
  15. float z = -1;
  16. // There needs to be an odd number of lines
  17. lineCount |= 1;
  18. const unsigned int pointCount = lineCount * 4;
  19. const unsigned int verticesSize = pointCount * (3 + 3); // (3 (position(xyz) + 3 color(rgb))
  20. std::vector<float> vertices;
  21. vertices.resize(verticesSize);
  22. const float gridLength = (float)(lineCount / 2);
  23. float value = -gridLength;
  24. for (unsigned int i = 0; i < verticesSize; ++i)
  25. {
  26. // Default line color is dark grey
  27. Vector4 color(0.3f, 0.3f, 0.3f, 1.0f);
  28. // Every 10th line is brighter grey
  29. if (((int)value) % 10 == 0)
  30. {
  31. color.set(0.45f, 0.45f, 0.45f, 1.0f);
  32. }
  33. // The Z axis is blue
  34. if (value == 0.0f)
  35. {
  36. color.set(0.15f, 0.15f, 0.7f, 1.0f);
  37. }
  38. // Build the lines
  39. vertices[i] = value;
  40. vertices[++i] = -gridLength;
  41. vertices[++i] = z;
  42. vertices[++i] = color.x;
  43. vertices[++i] = color.y;
  44. vertices[++i] = color.z;
  45. vertices[++i] = value;
  46. vertices[++i] = gridLength;
  47. vertices[++i] = z;
  48. vertices[++i] = color.x;
  49. vertices[++i] = color.y;
  50. vertices[++i] = color.z;
  51. // The X axis is red
  52. if (value == 0.0f)
  53. {
  54. color.set(0.7f, 0.15f, 0.15f, 1.0f);
  55. }
  56. vertices[++i] = -gridLength;
  57. vertices[++i] = value;
  58. vertices[++i] = z;
  59. vertices[++i] = color.x;
  60. vertices[++i] = color.y;
  61. vertices[++i] = color.z;
  62. vertices[++i] = gridLength;
  63. vertices[++i] = value;
  64. vertices[++i] = z;
  65. vertices[++i] = color.x;
  66. vertices[++i] = color.y;
  67. vertices[++i] = color.z;
  68. value += 1.0f;
  69. }
  70. VertexFormat::Element elements[] =
  71. {
  72. VertexFormat::Element(VertexFormat::POSITION, 3),
  73. VertexFormat::Element(VertexFormat::COLOR, 3)
  74. };
  75. Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 2), pointCount, false);
  76. if (mesh == NULL)
  77. return;
  78. mesh->setPrimitiveType(Mesh::LINES);
  79. mesh->setVertexData(&vertices[0], 0, pointCount);
  80. Model* model = Model::create(mesh);
  81. model->setMaterial("res/grid.material");
  82. SAFE_RELEASE(mesh);
  83. _scene->addNode("grid")->setModel(model);
  84. model->release();
  85. }
  86. void ParticlesGame::initialize()
  87. {
  88. // Display the gameplay splash screen
  89. displayScreen(this, &ParticlesGame::drawSplash, NULL, 250L);
  90. setMultiTouch(true);
  91. // Set keyboard state.
  92. _wDown = _aDown = _sDown = _dDown = false;
  93. _touched = false;
  94. _prevX = _prevY = 0;
  95. // Create a scene with a camera node.
  96. // The camera node is a child of a node at the same location as the particle emitter.
  97. // The camera node is offset from its parent, looking straight at it.
  98. // That way, when we rotate the parent node, the camera stays aimed at the particle emitter.
  99. _scene = Scene::create();
  100. Node* cameraNode = _scene->addNode("Camera");
  101. _cameraParent = _scene->addNode("CameraParent");
  102. _cameraParent->addChild(cameraNode);
  103. Camera* camera = Camera::createPerspective(45.0f, (float)getWidth() / (float)getHeight(), 0.25f, 1000.0f);
  104. cameraNode->setCamera(camera);
  105. cameraNode->setTranslation(0.0f, 0.0f, INITIAL_ZOOM);
  106. _scene->setActiveCamera(camera);
  107. SAFE_RELEASE(camera);
  108. addGrid(61);
  109. // Create a font for drawing the framerate.
  110. _font = Font::create("res/arial.gpb");
  111. // Load the form for editing ParticleEmitters.
  112. _form = Form::create("res/editor.form");
  113. _form->setConsumeInputEvents(false);
  114. //_form->setState(Control::FOCUS);
  115. // Store pointers to UI controls we care about.
  116. _startRed = (Slider*)_form->getControl("startRed");
  117. _startGreen = (Slider*)_form->getControl("startGreen");
  118. _startBlue = (Slider*)_form->getControl("startBlue");
  119. _startAlpha = (Slider*)_form->getControl("startAlpha");
  120. _endRed = (Slider*)_form->getControl("endRed");
  121. _endGreen = (Slider*)_form->getControl("endGreen");
  122. _endBlue = (Slider*)_form->getControl("endBlue");
  123. _endAlpha = (Slider*)_form->getControl("endAlpha");
  124. _particleProperties = (Container*)_form->getControl("particleProperties");
  125. _startMin = (Slider*)_form->getControl("startMin");
  126. _startMax = (Slider*)_form->getControl("startMax");
  127. _endMin = (Slider*)_form->getControl("endMin");
  128. _endMax = (Slider*)_form->getControl("endMax");
  129. _energyMin = (Slider*)_form->getControl("energyMin");
  130. _energyMax = (Slider*)_form->getControl("energyMax");
  131. _emissionRate = (Slider*)_form->getControl("emissionRate");
  132. _started = (CheckBox*)_form->getControl("started");
  133. _reset = (Button*)_form->getControl("reset");
  134. _emit = (Button*)_form->getControl("emit");
  135. _zoomIn = (Button*)_form->getControl("zoomIn");
  136. _zoomOut = (Button*)_form->getControl("zoomOut");
  137. _save = (Button*)_form->getControl("save");
  138. _load = (Button*)_form->getControl("load");
  139. _burstSize = (Slider*)_form->getControl("burstSize");
  140. _posVarX = (Slider*)_form->getControl("posVarX");
  141. _posVarY = (Slider*)_form->getControl("posVarY");
  142. _posVarZ = (Slider*)_form->getControl("posVarZ");
  143. _velX = (Slider*)_form->getControl("velocityX");
  144. _velY = (Slider*)_form->getControl("velocityY");
  145. _velZ = (Slider*)_form->getControl("velocityZ");
  146. _velVarX = (Slider*)_form->getControl("velocityVarX");
  147. _velVarY = (Slider*)_form->getControl("velocityVarY");
  148. _velVarZ = (Slider*)_form->getControl("velocityVarZ");
  149. _accelX = (Slider*)_form->getControl("accelX");
  150. _accelY = (Slider*)_form->getControl("accelY");
  151. _accelZ = (Slider*)_form->getControl("accelZ");
  152. _accelVarX = (Slider*)_form->getControl("accelVarX");
  153. _accelVarY = (Slider*)_form->getControl("accelVarY");
  154. _accelVarZ = (Slider*)_form->getControl("accelVarZ");
  155. _spinSpeedMin = (Slider*)_form->getControl("spinSpeedMin");
  156. _spinSpeedMax = (Slider*)_form->getControl("spinSpeedMax");
  157. _axisX = (Slider*)_form->getControl("axisX");
  158. _axisY = (Slider*)_form->getControl("axisY");
  159. _axisZ = (Slider*)_form->getControl("axisZ");
  160. _axisVarX = (Slider*)_form->getControl("axisVarX");
  161. _axisVarY = (Slider*)_form->getControl("axisVarY");
  162. _axisVarZ = (Slider*)_form->getControl("axisVarZ");
  163. _rotationSpeedMin = (Slider*)_form->getControl("rotationSpeedMin");
  164. _rotationSpeedMax = (Slider*)_form->getControl("rotationSpeedMax");
  165. _vsync = (CheckBox*)_form->getControl("vsync");
  166. // Listen for UI events.
  167. _startRed->addListener(this, Listener::VALUE_CHANGED);
  168. _startGreen->addListener(this, Listener::VALUE_CHANGED);
  169. _startBlue->addListener(this, Listener::VALUE_CHANGED);
  170. _startAlpha->addListener(this, Listener::VALUE_CHANGED);
  171. _endRed->addListener(this, Listener::VALUE_CHANGED);
  172. _endGreen->addListener(this, Listener::VALUE_CHANGED);
  173. _endBlue->addListener(this, Listener::VALUE_CHANGED);
  174. _endAlpha->addListener(this, Listener::VALUE_CHANGED);
  175. _startMin->addListener(this, Listener::VALUE_CHANGED);
  176. _startMax->addListener(this, Listener::VALUE_CHANGED);
  177. _endMin->addListener(this, Listener::VALUE_CHANGED);
  178. _endMax->addListener(this, Listener::VALUE_CHANGED);
  179. _energyMin->addListener(this, Listener::VALUE_CHANGED);
  180. _energyMax->addListener(this, Listener::VALUE_CHANGED);
  181. _emissionRate->addListener(this, Listener::VALUE_CHANGED);
  182. _started->addListener(this, Listener::VALUE_CHANGED);
  183. _reset->addListener(this, Listener::CLICK);
  184. _emit->addListener(this, Listener::CLICK);
  185. _zoomIn->addListener(this, Listener::PRESS);
  186. _zoomIn->addListener(this, Listener::RELEASE);
  187. _zoomOut->addListener(this, Listener::PRESS);
  188. _zoomOut->addListener(this, Listener::RELEASE);
  189. _save->addListener(this, Listener::RELEASE);
  190. _load->addListener(this, Listener::RELEASE);
  191. _burstSize->addListener(this, Listener::VALUE_CHANGED);
  192. _form->getControl("posX")->addListener(this, Listener::VALUE_CHANGED);
  193. _form->getControl("posY")->addListener(this, Listener::VALUE_CHANGED);
  194. _form->getControl("posZ")->addListener(this, Listener::VALUE_CHANGED);
  195. _posVarX->addListener(this, Listener::VALUE_CHANGED);
  196. _posVarY->addListener(this, Listener::VALUE_CHANGED);
  197. _posVarZ->addListener(this, Listener::VALUE_CHANGED);
  198. _velX->addListener(this, Listener::VALUE_CHANGED);
  199. _velY->addListener(this, Listener::VALUE_CHANGED);
  200. _velZ->addListener(this, Listener::VALUE_CHANGED);
  201. _velVarX->addListener(this, Listener::VALUE_CHANGED);
  202. _velVarY->addListener(this, Listener::VALUE_CHANGED);
  203. _velVarZ->addListener(this, Listener::VALUE_CHANGED);
  204. _accelX->addListener(this, Listener::VALUE_CHANGED);
  205. _accelY->addListener(this, Listener::VALUE_CHANGED);
  206. _accelZ->addListener(this, Listener::VALUE_CHANGED);
  207. _accelVarX->addListener(this, Listener::VALUE_CHANGED);
  208. _accelVarY->addListener(this, Listener::VALUE_CHANGED);
  209. _accelVarZ->addListener(this, Listener::VALUE_CHANGED);
  210. _spinSpeedMin->addListener(this, Listener::VALUE_CHANGED);
  211. _spinSpeedMax->addListener(this, Listener::VALUE_CHANGED);
  212. _axisX->addListener(this, Listener::VALUE_CHANGED);
  213. _axisY->addListener(this, Listener::VALUE_CHANGED);
  214. _axisZ->addListener(this, Listener::VALUE_CHANGED);
  215. _axisVarX->addListener(this, Listener::VALUE_CHANGED);
  216. _axisVarY->addListener(this, Listener::VALUE_CHANGED);
  217. _axisVarZ->addListener(this, Listener::VALUE_CHANGED);
  218. _rotationSpeedMin->addListener(this, Listener::VALUE_CHANGED);
  219. _rotationSpeedMax->addListener(this, Listener::VALUE_CHANGED);
  220. _vsync->addListener(this, Listener::VALUE_CHANGED);
  221. _form->getControl("sprite")->addListener(this, Listener::CLICK);
  222. _form->getControl("additive")->addListener(this, Listener::VALUE_CHANGED);
  223. _form->getControl("transparent")->addListener(this, Listener::VALUE_CHANGED);
  224. _form->getControl("multiply")->addListener(this, Listener::VALUE_CHANGED);
  225. _form->getControl("opaque")->addListener(this, Listener::VALUE_CHANGED);
  226. _form->getControl("updateFrames")->addListener(this, Listener::CLICK);
  227. // Load preset emitters.
  228. loadEmitters();
  229. updateImageControl();
  230. }
  231. std::string ParticlesGame::toString(bool b)
  232. {
  233. return b ? "true" : "false";
  234. }
  235. std::string ParticlesGame::toString(int i)
  236. {
  237. char buf[1024];
  238. sprintf(buf, "%d", i);
  239. return buf;
  240. }
  241. std::string ParticlesGame::toString(unsigned int i)
  242. {
  243. char buf[1024];
  244. sprintf(buf, "%d", i);
  245. return buf;
  246. }
  247. std::string ParticlesGame::toString(const Vector3& v)
  248. {
  249. std::ostringstream s;
  250. s << v.x << ", " << v.y << ", " << v.z;
  251. return s.str();
  252. }
  253. std::string ParticlesGame::toString(const Vector4& v)
  254. {
  255. std::ostringstream s;
  256. s << v.x << ", " << v.y << ", " << v.z << ", " << v.w;
  257. return s.str();
  258. }
  259. std::string ParticlesGame::toString(const Quaternion& q)
  260. {
  261. std::ostringstream s;
  262. s << q.x << ", " << q.y << ", " << q.z << ", " << q.w;
  263. return s.str();
  264. }
  265. std::string ParticlesGame::toString(ParticleEmitter::TextureBlending blending)
  266. {
  267. switch (blending)
  268. {
  269. case ParticleEmitter::BLEND_OPAQUE:
  270. return "OPAQUE";
  271. case ParticleEmitter::BLEND_TRANSPARENT:
  272. return "TRANSPARENT";
  273. case ParticleEmitter::BLEND_ADDITIVE:
  274. return "ADDITIVE";
  275. case ParticleEmitter::BLEND_MULTIPLIED:
  276. return "MULTIPLIED";
  277. default:
  278. return "TRANSPARENT";
  279. }
  280. }
  281. void ParticlesGame::saveFile()
  282. {
  283. std::string filename;
  284. filename = FileSystem::displayFileDialog(FileSystem::SAVE, "Save Particle File", "Particle Files", "particle");
  285. if (filename.length() == 0)
  286. return;
  287. ParticleEmitter* e = _particleEmitter;
  288. // Extract just the particle name from the filename
  289. std::string dir = FileSystem::getDirectoryName(filename.c_str());
  290. std::string ext = FileSystem::getExtension(filename.c_str());
  291. std::string name = filename.substr(dir.length(), filename.length() - dir.length() - ext.length());
  292. Texture* texture = e->getTexture();
  293. std::string texturePath = texture->getPath();
  294. std::string textureDir = FileSystem::getDirectoryName(texturePath.c_str());
  295. texturePath = texturePath.substr(textureDir.length());
  296. // Get camera rotation as axis-angle
  297. Vector3 cameraAxis;
  298. float cameraAngle = MATH_RAD_TO_DEG(_cameraParent->getRotation().toAxisAngle(&cameraAxis));
  299. // Write out a properties file
  300. std::ostringstream s;
  301. s <<
  302. "particle " << name << "\n" <<
  303. "{\n" <<
  304. " sprite\n" <<
  305. " {\n" <<
  306. " path = " << texturePath << "\n" <<
  307. " width = " << e->getSpriteWidth() << "\n" <<
  308. " height = " << e->getSpriteHeight() << "\n" <<
  309. " blending = " << toString(e->getTextureBlending()) << "\n" <<
  310. " animated = " << toString(e->isSpriteAnimated()) << "\n" <<
  311. " looped = " << toString(e->isSpriteLooped()) << "\n" <<
  312. " frameCount = " << e->getSpriteFrameCount() << "\n" <<
  313. " frameRandomOffset = " << e->getSpriteFrameRandomOffset() << "\n" <<
  314. " frameDuration = " << e->getSpriteFrameDuration() << "\n" <<
  315. " }\n" <<
  316. "\n" <<
  317. " particleCountMax = " << e->getParticleCountMax() << "\n" <<
  318. " emissionRate = " << e->getEmissionRate() << "\n" <<
  319. " ellipsoid = " << toString(e->isEllipsoid()) << "\n" <<
  320. " orbitPosition = " << toString(e->getOrbitPosition()) << "\n" <<
  321. " orbitVelocity = " << toString(e->getOrbitVelocity()) << "\n" <<
  322. " orbitAcceleration = " << toString(e->getOrbitAcceleration()) << "\n" <<
  323. " sizeStartMin = " << e->getSizeStartMin() << "\n" <<
  324. " sizeStartMax = " << e->getSizeStartMax() << "\n" <<
  325. " sizeEndMin = " << e->getSizeEndMin() << "\n" <<
  326. " sizeEndMax = " << e->getSizeEndMax() << "\n" <<
  327. " energyMin = " << e->getEnergyMin() << "\n" <<
  328. " energyMax = " << e->getEnergyMax() << "\n" <<
  329. " colorStart = " << toString(e->getColorStart()) << "\n" <<
  330. " colorStartVar = " << toString(e->getColorStartVariance()) << "\n" <<
  331. " colorEnd = " << toString(e->getColorEnd()) << "\n" <<
  332. " colorEndVar = " << toString(e->getColorEndVariance()) << "\n" <<
  333. " position = " << toString(e->getPosition()) << "\n" <<
  334. " positionVar = " << toString(e->getPositionVariance()) << "\n" <<
  335. " velocity = " << toString(e->getVelocity()) << "\n" <<
  336. " velocityVar = " << toString(e->getVelocityVariance()) << "\n" <<
  337. " acceleration = " << toString(e->getAcceleration()) << "\n" <<
  338. " accelerationVar = " << toString(e->getAccelerationVariance()) << "\n" <<
  339. " rotationPerParticleSpeedMin = " << e->getRotationPerParticleSpeedMin() << "\n" <<
  340. " rotationPerParticleSpeedMax = " << e->getRotationPerParticleSpeedMax() << "\n" <<
  341. "\n" <<
  342. " editor\n" <<
  343. " {\n" <<
  344. " cameraTranslation = " << toString(_cameraParent->getTranslation()) << "\n" <<
  345. " cameraZoom = " << toString(_scene->getActiveCamera()->getNode()->getTranslation()) << "\n" <<
  346. " cameraRotation = " << toString(cameraAxis) << ", " << cameraAngle << "\n" <<
  347. " sizeMax = " << _startMax->getMax() << "\n" <<
  348. " energyMax = " << _energyMax->getMax() << "\n" <<
  349. " }\n"
  350. "}\n";
  351. std::string text = s.str();
  352. Stream* stream = FileSystem::open(filename.c_str(), FileSystem::WRITE);
  353. stream->write(text.c_str(), 1, text.length());
  354. stream->close();
  355. SAFE_DELETE(stream);
  356. }
  357. void ParticlesGame::controlEvent(Control* control, EventType evt)
  358. {
  359. std::string id = control->getId();
  360. // Handle UI events.
  361. ParticleEmitter* emitter = _particleEmitterNode->getParticleEmitter();
  362. switch(evt)
  363. {
  364. case Listener::VALUE_CHANGED:
  365. if (control == _startRed)
  366. {
  367. Vector4 startColor = emitter->getColorStart();
  368. startColor.x = _startRed->getValue();
  369. emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
  370. }
  371. else if (control == _startGreen)
  372. {
  373. Vector4 startColor = emitter->getColorStart();
  374. startColor.y = _startGreen->getValue();
  375. emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
  376. }
  377. else if (control == _startBlue)
  378. {
  379. Vector4 startColor = emitter->getColorStart();
  380. startColor.z = _startBlue->getValue();
  381. emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
  382. }
  383. else if (control == _startAlpha)
  384. {
  385. Vector4 startColor = emitter->getColorStart();
  386. startColor.w = _startAlpha->getValue();
  387. emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
  388. }
  389. else if (control == _endRed)
  390. {
  391. Vector4 endColor = emitter->getColorEnd();
  392. endColor.x = _endRed->getValue();
  393. emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
  394. }
  395. else if (control == _endGreen)
  396. {
  397. Vector4 endColor = emitter->getColorEnd();
  398. endColor.y = _endGreen->getValue();
  399. emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
  400. }
  401. else if (control == _endBlue)
  402. {
  403. Vector4 endColor = emitter->getColorEnd();
  404. endColor.z = _endBlue->getValue();
  405. emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
  406. }
  407. else if (control == _endAlpha)
  408. {
  409. Vector4 endColor = emitter->getColorEnd();
  410. endColor.w = _endAlpha->getValue();
  411. emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
  412. }
  413. else if (control == _startMin)
  414. {
  415. emitter->setSize(_startMin->getValue(), emitter->getSizeStartMax(), emitter->getSizeEndMin(), emitter->getSizeEndMax());
  416. }
  417. else if (control == _startMax)
  418. {
  419. emitter->setSize(emitter->getSizeStartMin(), _startMax->getValue(), emitter->getSizeEndMin(), emitter->getSizeEndMax());
  420. }
  421. else if (control == _endMin)
  422. {
  423. emitter->setSize(emitter->getSizeStartMin(), emitter->getSizeStartMax(), _endMin->getValue(), emitter->getSizeEndMax());
  424. }
  425. else if (control == _endMax)
  426. {
  427. emitter->setSize(emitter->getSizeStartMin(), emitter->getSizeStartMax(), emitter->getSizeEndMin(), _endMax->getValue());
  428. }
  429. else if (control == _energyMin)
  430. {
  431. emitter->setEnergy(_energyMin->getValue(), emitter->getEnergyMax());
  432. }
  433. else if (control == _energyMax)
  434. {
  435. emitter->setEnergy(emitter->getEnergyMin(), _energyMax->getValue());
  436. }
  437. else if (control == _emissionRate)
  438. {
  439. emitter->setEmissionRate(_emissionRate->getValue());
  440. }
  441. else if (id == "posX")
  442. {
  443. Vector3 pos(emitter->getPosition());
  444. pos.x = ((Slider*)control)->getValue();
  445. emitter->setPosition(pos, emitter->getPositionVariance());
  446. }
  447. else if (id == "posY")
  448. {
  449. Vector3 pos(emitter->getPosition());
  450. pos.y = ((Slider*)control)->getValue();
  451. emitter->setPosition(pos, emitter->getPositionVariance());
  452. }
  453. else if (id == "posZ")
  454. {
  455. Vector3 pos(emitter->getPosition());
  456. pos.z = ((Slider*)control)->getValue();
  457. emitter->setPosition(pos, emitter->getPositionVariance());
  458. }
  459. else if (control == _posVarX)
  460. {
  461. Vector3 posVar = emitter->getPositionVariance();
  462. posVar.x = _posVarX->getValue();
  463. emitter->setPosition(emitter->getPosition(), posVar);
  464. }
  465. else if (control == _posVarY)
  466. {
  467. Vector3 posVar = emitter->getPositionVariance();
  468. posVar.y = _posVarY->getValue();
  469. emitter->setPosition(emitter->getPosition(), posVar);
  470. }
  471. else if (control == _posVarZ)
  472. {
  473. Vector3 posVar = emitter->getPositionVariance();
  474. posVar.z = _posVarZ->getValue();
  475. emitter->setPosition(emitter->getPosition(), posVar);
  476. }
  477. else if (control == _velX)
  478. {
  479. Vector3 vel = emitter->getVelocity();
  480. vel.x = _velX->getValue();
  481. emitter->setVelocity(vel, emitter->getVelocityVariance());
  482. }
  483. else if (control == _velY)
  484. {
  485. Vector3 vel = emitter->getVelocity();
  486. vel.y = _velY->getValue();
  487. emitter->setVelocity(vel, emitter->getVelocityVariance());
  488. }
  489. else if (control == _velZ)
  490. {
  491. Vector3 vel = emitter->getVelocity();
  492. vel.z = _velZ->getValue();
  493. emitter->setVelocity(vel, emitter->getVelocityVariance());
  494. }
  495. else if (control == _velVarX)
  496. {
  497. Vector3 velVar = emitter->getVelocityVariance();
  498. velVar.x = _velVarX->getValue();
  499. emitter->setVelocity(emitter->getVelocity(), velVar);
  500. }
  501. else if (control == _velVarY)
  502. {
  503. Vector3 velVar = emitter->getVelocityVariance();
  504. velVar.y = _velVarY->getValue();
  505. emitter->setVelocity(emitter->getVelocity(), velVar);
  506. }
  507. else if (control == _velVarZ)
  508. {
  509. Vector3 velVar = emitter->getVelocityVariance();
  510. velVar.z = _velVarZ->getValue();
  511. emitter->setVelocity(emitter->getVelocity(), velVar);
  512. }
  513. else if (control == _accelX)
  514. {
  515. Vector3 accel = emitter->getAcceleration();
  516. accel.x = _accelX->getValue();
  517. emitter->setAcceleration(accel, emitter->getAccelerationVariance());
  518. }
  519. else if (control == _accelY)
  520. {
  521. Vector3 accel = emitter->getAcceleration();
  522. accel.y = _accelY->getValue();
  523. emitter->setAcceleration(accel, emitter->getAccelerationVariance());
  524. }
  525. else if (control == _accelZ)
  526. {
  527. Vector3 accel = emitter->getAcceleration();
  528. accel.z = _accelZ->getValue();
  529. emitter->setAcceleration(accel, emitter->getAccelerationVariance());
  530. }
  531. else if (control == _accelVarX)
  532. {
  533. Vector3 accelVar = emitter->getAccelerationVariance();
  534. accelVar.x = _accelVarX->getValue();
  535. emitter->setAcceleration(emitter->getAcceleration(), accelVar);
  536. }
  537. else if (control == _accelVarY)
  538. {
  539. Vector3 accelVar = emitter->getAccelerationVariance();
  540. accelVar.y = _accelVarY->getValue();
  541. emitter->setAcceleration(emitter->getAcceleration(), accelVar);
  542. }
  543. else if (control == _accelVarZ)
  544. {
  545. Vector3 accelVar = emitter->getAccelerationVariance();
  546. accelVar.z = _accelVarZ->getValue();
  547. emitter->setAcceleration(emitter->getAcceleration(), accelVar);
  548. }
  549. else if (control == _spinSpeedMin)
  550. {
  551. emitter->setRotationPerParticle(_spinSpeedMin->getValue(), emitter->getRotationPerParticleSpeedMax());
  552. }
  553. else if (control == _spinSpeedMax)
  554. {
  555. emitter->setRotationPerParticle(emitter->getRotationPerParticleSpeedMin(), _spinSpeedMax->getValue());
  556. }
  557. else if (control == _axisX)
  558. {
  559. Vector3 axis = emitter->getRotationAxis();
  560. axis.x = _axisX->getValue();
  561. emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
  562. }
  563. else if (control == _axisY)
  564. {
  565. Vector3 axis = emitter->getRotationAxis();
  566. axis.y = _axisY->getValue();
  567. emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
  568. }
  569. else if (control == _axisZ)
  570. {
  571. Vector3 axis = emitter->getRotationAxis();
  572. axis.z = _axisZ->getValue();
  573. emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
  574. }
  575. else if (control == _axisVarX)
  576. {
  577. Vector3 axisVar = emitter->getRotationAxisVariance();
  578. axisVar.x = _axisVarX->getValue();
  579. emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
  580. }
  581. else if (control == _axisVarY)
  582. {
  583. Vector3 axisVar = emitter->getRotationAxisVariance();
  584. axisVar.y = _axisVarY->getValue();
  585. emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
  586. }
  587. else if (control == _axisVarZ)
  588. {
  589. Vector3 axisVar = emitter->getRotationAxisVariance();
  590. axisVar.z = _axisVarZ->getValue();
  591. emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
  592. }
  593. else if (control == _rotationSpeedMin)
  594. {
  595. emitter->setRotation(_rotationSpeedMin->getValue(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), emitter->getRotationAxisVariance());
  596. }
  597. else if (control == _rotationSpeedMax)
  598. {
  599. emitter->setRotation(emitter->getRotationSpeedMin(), _rotationSpeedMax->getValue(), emitter->getRotationAxis(), emitter->getRotationAxisVariance());
  600. }
  601. else if (control == _burstSize)
  602. {
  603. char txt[25];
  604. sprintf(txt, "Burst Size\n\n%.0f", _burstSize->getValue());
  605. _burstSize->setText(txt);
  606. }
  607. else if (control == _started)
  608. {
  609. if (_started->isChecked())
  610. {
  611. emitter->start();
  612. }
  613. else
  614. {
  615. emitter->stop();
  616. }
  617. }
  618. else if (control == _vsync)
  619. {
  620. Game::getInstance()->setVsync(_vsync->isChecked());
  621. }
  622. else if (id == "additive")
  623. {
  624. if (((RadioButton*)control)->isSelected())
  625. emitter->setTextureBlending(ParticleEmitter::BLEND_ADDITIVE);
  626. }
  627. else if (id == "transparent")
  628. {
  629. if (((RadioButton*)control)->isSelected())
  630. emitter->setTextureBlending(ParticleEmitter::BLEND_TRANSPARENT);
  631. }
  632. else if (id == "multiply")
  633. {
  634. if (((RadioButton*)control)->isSelected())
  635. emitter->setTextureBlending(ParticleEmitter::BLEND_MULTIPLIED);
  636. }
  637. else if (id == "opaque")
  638. {
  639. if (((RadioButton*)control)->isSelected())
  640. emitter->setTextureBlending(ParticleEmitter::BLEND_OPAQUE);
  641. }
  642. break;
  643. case Listener::CLICK:
  644. if (control == _reset)
  645. {
  646. // Re-load the current emitter and reset the view
  647. _particleEmitter = ParticleEmitter::create(_url.c_str());
  648. emitterChanged();
  649. }
  650. else if (control == _emit)
  651. {
  652. // Emit a burst of particles.
  653. unsigned int burstSize = (unsigned int)_burstSize->getValue();
  654. emitter->emitOnce(burstSize);
  655. }
  656. else if (id == "sprite")
  657. {
  658. updateTexture();
  659. }
  660. else if (id == "updateFrames")
  661. {
  662. updateFrames();
  663. }
  664. break;
  665. case Listener::PRESS:
  666. if (control == _zoomIn)
  667. {
  668. _wDown = true;
  669. }
  670. else if (control == _zoomOut)
  671. {
  672. _sDown = true;
  673. }
  674. break;
  675. case Listener::RELEASE:
  676. if (control == _zoomIn)
  677. {
  678. _wDown = false;
  679. }
  680. else if (control == _zoomOut)
  681. {
  682. _sDown = false;
  683. }
  684. else if (control == _save)
  685. {
  686. Game::getInstance()->pause();
  687. saveFile();
  688. Game::getInstance()->resume();
  689. }
  690. else if (control == _load)
  691. {
  692. Game::getInstance()->pause();
  693. std::string filename = FileSystem::displayFileDialog(FileSystem::OPEN, "Select Particle File", "Particle Files", "particle");
  694. if (filename.length() > 0)
  695. {
  696. _url = filename;
  697. _particleEmitter = ParticleEmitter::create(_url.c_str());
  698. emitterChanged();
  699. }
  700. Game::getInstance()->resume();
  701. }
  702. break;
  703. }
  704. }
  705. void ParticlesGame::updateFrames()
  706. {
  707. Texture* texture = _particleEmitter->getTexture();
  708. TextBox* cBox = (TextBox*)_form->getControl("frameCount");
  709. TextBox* wBox = (TextBox*)_form->getControl("frameWidth");
  710. TextBox* hBox = (TextBox*)_form->getControl("frameHeight");
  711. unsigned int fc = (unsigned int)atoi(cBox->getText());
  712. unsigned int w = (unsigned int)atoi(wBox->getText());
  713. unsigned int h = (unsigned int)atoi(hBox->getText());
  714. if (fc > 0 && fc < 256 && fc < 1000 && w > 0 && h > 0 && w < 4096 && h < 4096)
  715. {
  716. if (w > _particleEmitter->getTexture()->getWidth())
  717. {
  718. wBox->setText(toString(texture->getWidth()).c_str());
  719. }
  720. if (h > texture->getHeight())
  721. {
  722. hBox->setText(toString(texture->getHeight()).c_str());
  723. }
  724. _particleEmitter->setSpriteFrameCoords(fc, w, h);
  725. }
  726. }
  727. void ParticlesGame::finalize()
  728. {
  729. SAFE_RELEASE(_scene);
  730. SAFE_RELEASE(_form);
  731. SAFE_RELEASE(_font);
  732. SAFE_RELEASE(_particleEmitter);
  733. }
  734. void ParticlesGame::update(float elapsedTime)
  735. {
  736. // Update camera movement
  737. if (_wDown)
  738. {
  739. Vector3 v = _scene->getActiveCamera()->getNode()->getForwardVector();
  740. v.normalize();
  741. v.scale(INPUT_SENSITIVITY * elapsedTime);
  742. _scene->getActiveCamera()->getNode()->translate(v);
  743. }
  744. if (_aDown)
  745. {
  746. Vector3 v = _scene->getActiveCamera()->getNode()->getLeftVector();
  747. v.normalize();
  748. v.scale(INPUT_SENSITIVITY * elapsedTime);
  749. _scene->getActiveCamera()->getNode()->translate(v);
  750. }
  751. if (_sDown)
  752. {
  753. Vector3 v = _scene->getActiveCamera()->getNode()->getBackVector();
  754. v.normalize();
  755. v.scale(INPUT_SENSITIVITY * elapsedTime);
  756. _scene->getActiveCamera()->getNode()->translate(v);
  757. }
  758. if (_dDown)
  759. {
  760. Vector3 v = _scene->getActiveCamera()->getNode()->getRightVector();
  761. v.normalize();
  762. v.scale(INPUT_SENSITIVITY * elapsedTime);
  763. _scene->getActiveCamera()->getNode()->translate(v);
  764. }
  765. // Update particles.
  766. _particleEmitterNode->getParticleEmitter()->update(elapsedTime);
  767. }
  768. void ParticlesGame::render(float elapsedTime)
  769. {
  770. // Clear the color and depth buffers.
  771. clear(CLEAR_COLOR_DEPTH, BACKGROUND_COLOR, 1.0f, 0);
  772. // Visit all the nodes in the scene for drawing.
  773. _scene->visit(this, &ParticlesGame::drawScene, (void*)0);
  774. // Draw the UI.
  775. _form->draw();
  776. // Draw the framerate and number of live particles.
  777. drawFrameRate(_font, Vector4(1, 1, 1, 1), 170, 40, getFrameRate());
  778. }
  779. bool ParticlesGame::drawScene(Node* node, void* cookie)
  780. {
  781. if (node->getModel())
  782. node->getModel()->draw();
  783. if (node->getParticleEmitter())
  784. node->getParticleEmitter()->draw();
  785. return true;
  786. }
  787. bool ParticlesGame::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
  788. {
  789. switch (evt)
  790. {
  791. case Mouse::MOUSE_PRESS_MIDDLE_BUTTON:
  792. Game::getInstance()->setMouseCaptured(true);
  793. _panning = true;
  794. return true;
  795. case Mouse::MOUSE_RELEASE_MIDDLE_BUTTON:
  796. Game::getInstance()->setMouseCaptured(false);
  797. _panning = false;
  798. return true;
  799. case Mouse::MOUSE_PRESS_LEFT_BUTTON:
  800. Game::getInstance()->setMouseCaptured(true);
  801. _rotating = true;
  802. return true;
  803. case Mouse::MOUSE_RELEASE_LEFT_BUTTON:
  804. Game::getInstance()->setMouseCaptured(false);
  805. _rotating = false;
  806. return true;
  807. case Mouse::MOUSE_PRESS_RIGHT_BUTTON:
  808. Game::getInstance()->setMouseCaptured(true);
  809. _zooming = true;
  810. return true;
  811. case Mouse::MOUSE_RELEASE_RIGHT_BUTTON:
  812. Game::getInstance()->setMouseCaptured(false);
  813. _zooming = false;
  814. return true;
  815. case Mouse::MOUSE_MOVE:
  816. if (_panning)
  817. {
  818. Vector3 n(-(float)x * PANNING_SENSITIVITY, (float)y * PANNING_SENSITIVITY, 0);
  819. _cameraParent->getMatrix().transformVector(&n);
  820. _cameraParent->translate(n);
  821. return true;
  822. }
  823. else if (_rotating)
  824. {
  825. _cameraParent->rotateY(-MATH_DEG_TO_RAD((float)x * ROTATE_SENSITIVITY));
  826. _cameraParent->rotateX(-MATH_DEG_TO_RAD((float)y * ROTATE_SENSITIVITY));
  827. return true;
  828. }
  829. else if (_zooming)
  830. {
  831. Vector3 v = _scene->getActiveCamera()->getNode()->getForwardVector();
  832. v.normalize();
  833. v.scale((float)(x-y) * INPUT_SENSITIVITY);
  834. _scene->getActiveCamera()->getNode()->translate(v);
  835. return true;
  836. }
  837. break;
  838. }
  839. return true;
  840. }
  841. void ParticlesGame::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  842. {
  843. // Touch events that don't hit the UI
  844. // allow the camera to rotate around the particle emitter.
  845. switch (evt)
  846. {
  847. case Touch::TOUCH_PRESS:
  848. _touched = true;
  849. _prevX = x;
  850. _prevY = y;
  851. break;
  852. case Touch::TOUCH_RELEASE:
  853. _touched = false;
  854. break;
  855. case Touch::TOUCH_MOVE:
  856. {
  857. if (_touched)
  858. {
  859. int deltaX = x - _prevX;
  860. int deltaY = y - _prevY;
  861. _prevX = x;
  862. _prevY = y;
  863. _cameraParent->rotateY(MATH_DEG_TO_RAD(deltaX * -0.5f));
  864. _cameraParent->rotateX(MATH_DEG_TO_RAD(deltaY * -0.5f));
  865. }
  866. }
  867. break;
  868. default:
  869. break;
  870. };
  871. }
  872. void ParticlesGame::keyEvent(Keyboard::KeyEvent evt, int key)
  873. {
  874. switch(evt)
  875. {
  876. case Keyboard::KEY_PRESS:
  877. switch (key)
  878. {
  879. case Keyboard::KEY_ESCAPE:
  880. exit();
  881. break;
  882. case Keyboard::KEY_B:
  883. // Disable blending.
  884. _particleEmitterNode->getParticleEmitter()->setTextureBlending(ParticleEmitter::BLEND_OPAQUE);
  885. break;
  886. case Keyboard::KEY_W:
  887. _wDown = true;
  888. break;
  889. case Keyboard::KEY_A:
  890. _aDown = true;
  891. break;
  892. case Keyboard::KEY_S:
  893. _sDown = true;
  894. break;
  895. case Keyboard::KEY_D:
  896. _dDown = true;
  897. break;
  898. }
  899. break;
  900. case Keyboard::KEY_RELEASE:
  901. switch (key)
  902. {
  903. case Keyboard::KEY_W:
  904. _wDown = false;
  905. break;
  906. case Keyboard::KEY_A:
  907. _aDown = false;
  908. break;
  909. case Keyboard::KEY_S:
  910. _sDown = false;
  911. break;
  912. case Keyboard::KEY_D:
  913. _dDown = false;
  914. break;
  915. }
  916. break;
  917. }
  918. }
  919. void ParticlesGame::loadEmitters()
  920. {
  921. // Load the default particle emitter
  922. _url = DEFAULT_PARTICLE_EMITTER;
  923. _particleEmitter = ParticleEmitter::create(_url.c_str());
  924. _particleEmitterNode = _scene->addNode("Particle Emitter");
  925. _particleEmitterNode->setTranslation(0.0f, 0.0f, 0.0f);
  926. emitterChanged();
  927. }
  928. void ParticlesGame::emitterChanged()
  929. {
  930. ParticleEmitter* emitter = _particleEmitter;
  931. // Set the new emitter on the node.
  932. _particleEmitterNode->setParticleEmitter(_particleEmitter);
  933. _particleEmitter->release();
  934. // Reset camera view and zoom.
  935. _scene->getActiveCamera()->getNode()->setTranslation(0.0f, 0.0f, 40.0f);
  936. _cameraParent->setIdentity();
  937. _particleEmitterNode->setIdentity();
  938. // Set the values of UI controls to display the new emitter's settings.
  939. _startRed->setValue(emitter->getColorStart().x);
  940. _startGreen->setValue(emitter->getColorStart().y);
  941. _startBlue->setValue(emitter->getColorStart().z);
  942. _startAlpha->setValue(emitter->getColorStart().w);
  943. _endRed->setValue(emitter->getColorEnd().x);
  944. _endGreen->setValue(emitter->getColorEnd().y);
  945. _endBlue->setValue(emitter->getColorEnd().z);
  946. _endAlpha->setValue(emitter->getColorEnd().w);
  947. _startMin->setValue(emitter->getSizeStartMin());
  948. _startMax->setValue(emitter->getSizeStartMax());
  949. _endMin->setValue(emitter->getSizeEndMin());
  950. _endMax->setValue(emitter->getSizeEndMax());
  951. _energyMin->setValue(emitter->getEnergyMin());
  952. _energyMax->setValue(emitter->getEnergyMax());
  953. _emissionRate->setValue(emitter->getEmissionRate());
  954. char txt[25];
  955. sprintf(txt, "Burst Size\n\n%.0f", _burstSize->getValue());
  956. _burstSize->setText(txt);
  957. const Vector3& posVar = emitter->getPositionVariance();
  958. _posVarX->setValue(posVar.x);
  959. _posVarY->setValue(posVar.y);
  960. _posVarZ->setValue(posVar.z);
  961. const Vector3& vel = emitter->getVelocity();
  962. _velX->setValue(vel.x);
  963. _velY->setValue(vel.y);
  964. _velZ->setValue(vel.z);
  965. const Vector3& velVar = emitter->getVelocityVariance();
  966. _velVarX->setValue(velVar.x);
  967. _velVarY->setValue(velVar.y);
  968. _velVarZ->setValue(velVar.z);
  969. const Vector3& accel = emitter->getAcceleration();
  970. _accelX->setValue(accel.x);
  971. _accelY->setValue(accel.y);
  972. _accelZ->setValue(accel.z);
  973. const Vector3& accelVar = emitter->getAccelerationVariance();
  974. _accelVarX->setValue(accelVar.x);
  975. _accelVarY->setValue(accelVar.y);
  976. _accelVarZ->setValue(accelVar.z);
  977. _spinSpeedMin->setValue(emitter->getRotationPerParticleSpeedMin());
  978. _spinSpeedMax->setValue(emitter->getRotationPerParticleSpeedMax());
  979. const Vector3& axis = emitter->getRotationAxis();
  980. _axisX->setValue(axis.x);
  981. _axisY->setValue(axis.y);
  982. _axisZ->setValue(axis.z);
  983. const Vector3& axisVar = emitter->getRotationAxisVariance();
  984. _axisVarX->setValue(axisVar.x);
  985. _axisVarY->setValue(axisVar.y);
  986. _axisVarZ->setValue(axisVar.z);
  987. _rotationSpeedMin->setValue(emitter->getRotationSpeedMin());
  988. _rotationSpeedMax->setValue(emitter->getRotationSpeedMax());
  989. // Update our image control
  990. updateImageControl();
  991. // Parse editor section of particle properties
  992. Properties* p = Properties::create(_url.c_str());
  993. Properties* ns = p->getNamespace("editor", true);
  994. if (ns)
  995. {
  996. Vector3 v3;
  997. if (ns->getVector3("cameraTranslation", &v3))
  998. {
  999. _cameraParent->setTranslation(v3);
  1000. }
  1001. if (ns->getVector3("cameraZoom", &v3))
  1002. {
  1003. _scene->getActiveCamera()->getNode()->setTranslation(v3);
  1004. }
  1005. Quaternion q;
  1006. if (ns->getQuaternionFromAxisAngle("cameraRotation", &q))
  1007. {
  1008. _cameraParent->setRotation(q);
  1009. }
  1010. float f;
  1011. if ((f = ns->getFloat("sizeMax")) != 0.0f)
  1012. {
  1013. _startMin->setMax(f);
  1014. _startMax->setMax(f);
  1015. _endMin->setMax(f);
  1016. _endMax->setMax(f);
  1017. }
  1018. if ((f = ns->getFloat("energyMax")) != 0.0f)
  1019. {
  1020. _energyMin->setMax(f);
  1021. _energyMax->setMax(f);
  1022. }
  1023. }
  1024. SAFE_DELETE(p);
  1025. // Start the emitter
  1026. emitter->start();
  1027. }
  1028. void ParticlesGame::drawSplash(void* param)
  1029. {
  1030. clear(CLEAR_COLOR_DEPTH, Vector4(0, 0, 0, 1), 1.0f, 0);
  1031. SpriteBatch* batch = SpriteBatch::create("res/logo_powered_white.png");
  1032. batch->start();
  1033. batch->draw(this->getWidth() * 0.5f, this->getHeight() * 0.5f, 0.0f, 512.0f, 512.0f, 0.0f, 1.0f, 1.0f, 0.0f, Vector4::one(), true);
  1034. batch->finish();
  1035. SAFE_DELETE(batch);
  1036. }
  1037. void ParticlesGame::drawFrameRate(Font* font, const Vector4& color, unsigned int x, unsigned int y, unsigned int fps)
  1038. {
  1039. char buffer[30];
  1040. sprintf(buffer, "FPS: %u\nParticles: %u", fps, _particleEmitterNode->getParticleEmitter()->getParticlesCount());
  1041. font->start();
  1042. font->drawText(buffer, x, y, color, 22);
  1043. font->finish();
  1044. }
  1045. void ParticlesGame::resizeEvent(unsigned int width, unsigned int height)
  1046. {
  1047. setViewport(gameplay::Rectangle(width, height));
  1048. _form->setSize(width, height);
  1049. _scene->getActiveCamera()->setAspectRatio((float)getWidth() / (float)getHeight());
  1050. }
  1051. void ParticlesGame::updateTexture()
  1052. {
  1053. std::string file = FileSystem::displayFileDialog(FileSystem::OPEN, "Select Texture", "PNG Files", "png");
  1054. if (file.length() > 0)
  1055. {
  1056. // Set new sprite on our emitter
  1057. _particleEmitter->setTexture(file.c_str(), _particleEmitter->getTextureBlending());
  1058. // Update the UI to display the new sprite
  1059. updateImageControl();
  1060. }
  1061. }
  1062. void ParticlesGame::updateImageControl()
  1063. {
  1064. ((ImageControl*)_form->getControl("sprite"))->setImage(_particleEmitter->getTexture()->getPath());
  1065. // Resize the image control so keep it to scale
  1066. int w = _particleEmitter->getTexture()->getWidth();
  1067. int h = _particleEmitter->getTexture()->getHeight();
  1068. int max = w > h ? w : h;
  1069. if (max > 140)
  1070. {
  1071. float ratio = 140.0f / max;
  1072. w *= ratio;
  1073. h *= ratio;
  1074. }
  1075. ((ImageControl*)_form->getControl("sprite"))->setSize(w, h);
  1076. _form->getControl("image")->setHeight(h + _form->getControl("imageSettings")->getHeight() + 50);
  1077. ((TextBox*)_form->getControl("frameCount"))->setText(toString(_particleEmitter->getSpriteFrameCount()).c_str());
  1078. ((TextBox*)_form->getControl("frameWidth"))->setText(toString(_particleEmitter->getSpriteWidth()).c_str());
  1079. ((TextBox*)_form->getControl("frameHeight"))->setText(toString(_particleEmitter->getSpriteHeight()).c_str());
  1080. switch (_particleEmitter->getTextureBlending())
  1081. {
  1082. case ParticleEmitter::BLEND_ADDITIVE:
  1083. ((RadioButton*)_form->getControl("additive"))->setSelected(true);
  1084. break;
  1085. case ParticleEmitter::BLEND_MULTIPLIED:
  1086. ((RadioButton*)_form->getControl("multiply"))->setSelected(true);
  1087. break;
  1088. case ParticleEmitter::BLEND_OPAQUE:
  1089. ((RadioButton*)_form->getControl("opaque"))->setSelected(true);
  1090. break;
  1091. case ParticleEmitter::BLEND_TRANSPARENT:
  1092. ((RadioButton*)_form->getControl("transparent"))->setSelected(true);
  1093. break;
  1094. }
  1095. }