ParticlesGame.cpp 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196
  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 ZOOM_DEFAULT = 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, ZOOM_DEFAULT);
  106. _scene->setActiveCamera(camera);
  107. SAFE_RELEASE(camera);
  108. addGrid(61);
  109. // Create a font for drawing the framerate.
  110. _font = Font::create("res/ui/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", "res");
  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 == _started)
  602. {
  603. if (_started->isChecked())
  604. {
  605. emitter->start();
  606. }
  607. else
  608. {
  609. emitter->stop();
  610. }
  611. }
  612. else if (control == _vsync)
  613. {
  614. Game::getInstance()->setVsync(_vsync->isChecked());
  615. }
  616. else if (id == "additive")
  617. {
  618. if (((RadioButton*)control)->isSelected())
  619. emitter->setTextureBlending(ParticleEmitter::BLEND_ADDITIVE);
  620. }
  621. else if (id == "transparent")
  622. {
  623. if (((RadioButton*)control)->isSelected())
  624. emitter->setTextureBlending(ParticleEmitter::BLEND_TRANSPARENT);
  625. }
  626. else if (id == "multiply")
  627. {
  628. if (((RadioButton*)control)->isSelected())
  629. emitter->setTextureBlending(ParticleEmitter::BLEND_MULTIPLIED);
  630. }
  631. else if (id == "opaque")
  632. {
  633. if (((RadioButton*)control)->isSelected())
  634. emitter->setTextureBlending(ParticleEmitter::BLEND_OPAQUE);
  635. }
  636. break;
  637. case Listener::CLICK:
  638. if (control == _reset)
  639. {
  640. // Re-load the current emitter and reset the view
  641. _particleEmitter = ParticleEmitter::create(_url.c_str());
  642. emitterChanged();
  643. }
  644. else if (control == _emit)
  645. {
  646. // Emit a burst of particles.
  647. unsigned int burstSize = (unsigned int)_burstSize->getValue();
  648. emitter->emitOnce(burstSize);
  649. }
  650. else if (id == "sprite")
  651. {
  652. updateTexture();
  653. }
  654. else if (id == "updateFrames")
  655. {
  656. updateFrames();
  657. }
  658. break;
  659. case Listener::PRESS:
  660. if (control == _zoomIn)
  661. {
  662. _wDown = true;
  663. }
  664. else if (control == _zoomOut)
  665. {
  666. _sDown = true;
  667. }
  668. break;
  669. case Listener::RELEASE:
  670. if (control == _zoomIn)
  671. {
  672. _wDown = false;
  673. }
  674. else if (control == _zoomOut)
  675. {
  676. _sDown = false;
  677. }
  678. else if (control == _save)
  679. {
  680. Game::getInstance()->pause();
  681. saveFile();
  682. Game::getInstance()->resume();
  683. }
  684. else if (control == _load)
  685. {
  686. Game::getInstance()->pause();
  687. std::string filename = FileSystem::displayFileDialog(FileSystem::OPEN, "Select Particle File", "Particle Files", "particle", "res");
  688. if (filename.length() > 0)
  689. {
  690. _url = filename;
  691. _particleEmitter = ParticleEmitter::create(_url.c_str());
  692. emitterChanged();
  693. }
  694. Game::getInstance()->resume();
  695. }
  696. break;
  697. }
  698. }
  699. void ParticlesGame::updateFrames()
  700. {
  701. Texture* texture = _particleEmitter->getTexture();
  702. TextBox* cBox = (TextBox*)_form->getControl("frameCount");
  703. TextBox* wBox = (TextBox*)_form->getControl("frameWidth");
  704. TextBox* hBox = (TextBox*)_form->getControl("frameHeight");
  705. unsigned int fc = (unsigned int)atoi(cBox->getText());
  706. unsigned int w = (unsigned int)atoi(wBox->getText());
  707. unsigned int h = (unsigned int)atoi(hBox->getText());
  708. if (fc > 0 && fc < 256 && fc < 1000 && w > 0 && h > 0 && w < 4096 && h < 4096)
  709. {
  710. if (w > _particleEmitter->getTexture()->getWidth())
  711. {
  712. wBox->setText(toString(texture->getWidth()).c_str());
  713. }
  714. if (h > texture->getHeight())
  715. {
  716. hBox->setText(toString(texture->getHeight()).c_str());
  717. }
  718. _particleEmitter->setSpriteFrameCoords(fc, w, h);
  719. }
  720. }
  721. void ParticlesGame::finalize()
  722. {
  723. SAFE_RELEASE(_scene);
  724. SAFE_RELEASE(_form);
  725. SAFE_RELEASE(_font);
  726. SAFE_RELEASE(_particleEmitter);
  727. }
  728. void ParticlesGame::update(float elapsedTime)
  729. {
  730. // Update camera movement
  731. if (_wDown)
  732. {
  733. Vector3 v = _scene->getActiveCamera()->getNode()->getForwardVector();
  734. v.normalize();
  735. v.scale(INPUT_SENSITIVITY * elapsedTime);
  736. _scene->getActiveCamera()->getNode()->translate(v);
  737. }
  738. if (_aDown)
  739. {
  740. Vector3 v = _scene->getActiveCamera()->getNode()->getLeftVector();
  741. v.normalize();
  742. v.scale(INPUT_SENSITIVITY * elapsedTime);
  743. _scene->getActiveCamera()->getNode()->translate(v);
  744. }
  745. if (_sDown)
  746. {
  747. Vector3 v = _scene->getActiveCamera()->getNode()->getBackVector();
  748. v.normalize();
  749. v.scale(INPUT_SENSITIVITY * elapsedTime);
  750. _scene->getActiveCamera()->getNode()->translate(v);
  751. }
  752. if (_dDown)
  753. {
  754. Vector3 v = _scene->getActiveCamera()->getNode()->getRightVector();
  755. v.normalize();
  756. v.scale(INPUT_SENSITIVITY * elapsedTime);
  757. _scene->getActiveCamera()->getNode()->translate(v);
  758. }
  759. // Update particles.
  760. _particleEmitterNode->getParticleEmitter()->update(elapsedTime);
  761. }
  762. void ParticlesGame::render(float elapsedTime)
  763. {
  764. // Clear the color and depth buffers.
  765. clear(CLEAR_COLOR_DEPTH, BACKGROUND_COLOR, 1.0f, 0);
  766. // Visit all the nodes in the scene for drawing.
  767. _scene->visit(this, &ParticlesGame::drawScene, (void*)0);
  768. // Draw the UI.
  769. _form->draw();
  770. // Draw the framerate and number of live particles.
  771. drawFrameRate(_font, Vector4(1, 1, 1, 1), 205, 40, getFrameRate());
  772. }
  773. bool ParticlesGame::drawScene(Node* node, void* cookie)
  774. {
  775. if (node->getModel())
  776. node->getModel()->draw();
  777. if (node->getParticleEmitter())
  778. node->getParticleEmitter()->draw();
  779. return true;
  780. }
  781. bool ParticlesGame::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
  782. {
  783. switch (evt)
  784. {
  785. case Mouse::MOUSE_PRESS_MIDDLE_BUTTON:
  786. Game::getInstance()->setMouseCaptured(true);
  787. _panning = true;
  788. return true;
  789. case Mouse::MOUSE_RELEASE_MIDDLE_BUTTON:
  790. Game::getInstance()->setMouseCaptured(false);
  791. _panning = false;
  792. return true;
  793. case Mouse::MOUSE_PRESS_LEFT_BUTTON:
  794. Game::getInstance()->setMouseCaptured(true);
  795. _rotating = true;
  796. return true;
  797. case Mouse::MOUSE_RELEASE_LEFT_BUTTON:
  798. Game::getInstance()->setMouseCaptured(false);
  799. _rotating = false;
  800. return true;
  801. case Mouse::MOUSE_PRESS_RIGHT_BUTTON:
  802. Game::getInstance()->setMouseCaptured(true);
  803. _zooming = true;
  804. return true;
  805. case Mouse::MOUSE_RELEASE_RIGHT_BUTTON:
  806. Game::getInstance()->setMouseCaptured(false);
  807. _zooming = false;
  808. return true;
  809. case Mouse::MOUSE_MOVE:
  810. if (_panning)
  811. {
  812. Vector3 n(-(float)x * PANNING_SENSITIVITY, (float)y * PANNING_SENSITIVITY, 0);
  813. _cameraParent->getMatrix().transformVector(&n);
  814. _cameraParent->translate(n);
  815. return true;
  816. }
  817. else if (_rotating)
  818. {
  819. _cameraParent->rotateY(-MATH_DEG_TO_RAD((float)x * ROTATE_SENSITIVITY));
  820. _cameraParent->rotateX(-MATH_DEG_TO_RAD((float)y * ROTATE_SENSITIVITY));
  821. return true;
  822. }
  823. else if (_zooming)
  824. {
  825. Vector3 v = _scene->getActiveCamera()->getNode()->getForwardVector();
  826. v.normalize();
  827. v.scale((float)(x-y) * INPUT_SENSITIVITY);
  828. _scene->getActiveCamera()->getNode()->translate(v);
  829. return true;
  830. }
  831. break;
  832. case Mouse::MOUSE_WHEEL:
  833. if (wheelDelta != 0)
  834. {
  835. Vector3 v = _scene->getActiveCamera()->getNode()->getForwardVector();
  836. v.normalize();
  837. v.scale((float)(wheelDelta));
  838. _scene->getActiveCamera()->getNode()->translate(v);
  839. return true;
  840. }
  841. break;
  842. }
  843. return true;
  844. }
  845. void ParticlesGame::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  846. {
  847. // Touch events that don't hit the UI
  848. // allow the camera to rotate around the particle emitter.
  849. switch (evt)
  850. {
  851. case Touch::TOUCH_PRESS:
  852. _touched = true;
  853. _prevX = x;
  854. _prevY = y;
  855. break;
  856. case Touch::TOUCH_RELEASE:
  857. _touched = false;
  858. break;
  859. case Touch::TOUCH_MOVE:
  860. {
  861. if (_touched)
  862. {
  863. int deltaX = x - _prevX;
  864. int deltaY = y - _prevY;
  865. _prevX = x;
  866. _prevY = y;
  867. _cameraParent->rotateY(MATH_DEG_TO_RAD(deltaX * -0.5f));
  868. _cameraParent->rotateX(MATH_DEG_TO_RAD(deltaY * -0.5f));
  869. }
  870. }
  871. break;
  872. default:
  873. break;
  874. };
  875. }
  876. void ParticlesGame::keyEvent(Keyboard::KeyEvent evt, int key)
  877. {
  878. switch(evt)
  879. {
  880. case Keyboard::KEY_PRESS:
  881. switch (key)
  882. {
  883. case Keyboard::KEY_ESCAPE:
  884. exit();
  885. break;
  886. case Keyboard::KEY_B:
  887. // Disable blending.
  888. _particleEmitterNode->getParticleEmitter()->setTextureBlending(ParticleEmitter::BLEND_OPAQUE);
  889. break;
  890. case Keyboard::KEY_W:
  891. _wDown = true;
  892. break;
  893. case Keyboard::KEY_A:
  894. _aDown = true;
  895. break;
  896. case Keyboard::KEY_S:
  897. _sDown = true;
  898. break;
  899. case Keyboard::KEY_D:
  900. _dDown = true;
  901. break;
  902. }
  903. break;
  904. case Keyboard::KEY_RELEASE:
  905. switch (key)
  906. {
  907. case Keyboard::KEY_W:
  908. _wDown = false;
  909. break;
  910. case Keyboard::KEY_A:
  911. _aDown = false;
  912. break;
  913. case Keyboard::KEY_S:
  914. _sDown = false;
  915. break;
  916. case Keyboard::KEY_D:
  917. _dDown = false;
  918. break;
  919. }
  920. break;
  921. }
  922. }
  923. void ParticlesGame::loadEmitters()
  924. {
  925. // Load the default particle emitter
  926. _url = DEFAULT_PARTICLE_EMITTER;
  927. _particleEmitter = ParticleEmitter::create(_url.c_str());
  928. _particleEmitterNode = _scene->addNode("Particle Emitter");
  929. _particleEmitterNode->setTranslation(0.0f, 0.0f, 0.0f);
  930. emitterChanged();
  931. }
  932. void ParticlesGame::emitterChanged()
  933. {
  934. ParticleEmitter* emitter = _particleEmitter;
  935. // Set the new emitter on the node.
  936. _particleEmitterNode->setParticleEmitter(_particleEmitter);
  937. _particleEmitter->release();
  938. // Reset camera view and zoom.
  939. _scene->getActiveCamera()->getNode()->setTranslation(0.0f, 0.0f, 40.0f);
  940. _cameraParent->setIdentity();
  941. _particleEmitterNode->setIdentity();
  942. // Parse editor section of particle properties
  943. Properties* p = Properties::create(_url.c_str());
  944. Properties* ns = p->getNamespace("editor", true);
  945. if (ns)
  946. {
  947. Vector3 v3;
  948. if (ns->getVector3("cameraTranslation", &v3))
  949. {
  950. _cameraParent->setTranslation(v3);
  951. }
  952. if (ns->getVector3("cameraZoom", &v3))
  953. {
  954. _scene->getActiveCamera()->getNode()->setTranslation(v3);
  955. }
  956. Quaternion q;
  957. if (ns->getQuaternionFromAxisAngle("cameraRotation", &q))
  958. {
  959. _cameraParent->setRotation(q);
  960. }
  961. float f;
  962. if ((f = ns->getFloat("sizeMax")) != 0.0f)
  963. {
  964. _startMin->setMax(f);
  965. _startMax->setMax(f);
  966. _endMin->setMax(f);
  967. _endMax->setMax(f);
  968. }
  969. if ((f = ns->getFloat("energyMax")) != 0.0f)
  970. {
  971. _energyMin->setMax(f);
  972. _energyMax->setMax(f);
  973. }
  974. }
  975. SAFE_DELETE(p);
  976. // Set the values of UI controls to display the new emitter's settings.
  977. _startRed->setValue(emitter->getColorStart().x);
  978. _startGreen->setValue(emitter->getColorStart().y);
  979. _startBlue->setValue(emitter->getColorStart().z);
  980. _startAlpha->setValue(emitter->getColorStart().w);
  981. _endRed->setValue(emitter->getColorEnd().x);
  982. _endGreen->setValue(emitter->getColorEnd().y);
  983. _endBlue->setValue(emitter->getColorEnd().z);
  984. _endAlpha->setValue(emitter->getColorEnd().w);
  985. _startMin->setValue(emitter->getSizeStartMin());
  986. _startMax->setValue(emitter->getSizeStartMax());
  987. _endMin->setValue(emitter->getSizeEndMin());
  988. _endMax->setValue(emitter->getSizeEndMax());
  989. _energyMin->setValue(emitter->getEnergyMin());
  990. _energyMax->setValue(emitter->getEnergyMax());
  991. _emissionRate->setValue(emitter->getEmissionRate());
  992. const Vector3& posVar = emitter->getPositionVariance();
  993. _posVarX->setValue(posVar.x);
  994. _posVarY->setValue(posVar.y);
  995. _posVarZ->setValue(posVar.z);
  996. const Vector3& vel = emitter->getVelocity();
  997. _velX->setValue(vel.x);
  998. _velY->setValue(vel.y);
  999. _velZ->setValue(vel.z);
  1000. const Vector3& velVar = emitter->getVelocityVariance();
  1001. _velVarX->setValue(velVar.x);
  1002. _velVarY->setValue(velVar.y);
  1003. _velVarZ->setValue(velVar.z);
  1004. const Vector3& accel = emitter->getAcceleration();
  1005. _accelX->setValue(accel.x);
  1006. _accelY->setValue(accel.y);
  1007. _accelZ->setValue(accel.z);
  1008. const Vector3& accelVar = emitter->getAccelerationVariance();
  1009. _accelVarX->setValue(accelVar.x);
  1010. _accelVarY->setValue(accelVar.y);
  1011. _accelVarZ->setValue(accelVar.z);
  1012. _spinSpeedMin->setValue(emitter->getRotationPerParticleSpeedMin());
  1013. _spinSpeedMax->setValue(emitter->getRotationPerParticleSpeedMax());
  1014. const Vector3& axis = emitter->getRotationAxis();
  1015. _axisX->setValue(axis.x);
  1016. _axisY->setValue(axis.y);
  1017. _axisZ->setValue(axis.z);
  1018. const Vector3& axisVar = emitter->getRotationAxisVariance();
  1019. _axisVarX->setValue(axisVar.x);
  1020. _axisVarY->setValue(axisVar.y);
  1021. _axisVarZ->setValue(axisVar.z);
  1022. _rotationSpeedMin->setValue(emitter->getRotationSpeedMin());
  1023. _rotationSpeedMax->setValue(emitter->getRotationSpeedMax());
  1024. // Update our image control
  1025. updateImageControl();
  1026. // Start the emitter
  1027. emitter->start();
  1028. }
  1029. void ParticlesGame::drawSplash(void* param)
  1030. {
  1031. clear(CLEAR_COLOR_DEPTH, Vector4(0, 0, 0, 1), 1.0f, 0);
  1032. SpriteBatch* batch = SpriteBatch::create("res/logo_powered_white.png");
  1033. batch->start();
  1034. 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);
  1035. batch->finish();
  1036. SAFE_DELETE(batch);
  1037. }
  1038. void ParticlesGame::drawFrameRate(Font* font, const Vector4& color, unsigned int x, unsigned int y, unsigned int fps)
  1039. {
  1040. char buffer[30];
  1041. sprintf(buffer, "FPS: %u\nParticles: %u", fps, _particleEmitterNode->getParticleEmitter()->getParticlesCount());
  1042. font->start();
  1043. font->drawText(buffer, x, y, color, 22);
  1044. font->finish();
  1045. }
  1046. void ParticlesGame::resizeEvent(unsigned int width, unsigned int height)
  1047. {
  1048. setViewport(gameplay::Rectangle(width, height));
  1049. _form->setSize(width, height);
  1050. _scene->getActiveCamera()->setAspectRatio((float)getWidth() / (float)getHeight());
  1051. }
  1052. void ParticlesGame::updateTexture()
  1053. {
  1054. std::string file = FileSystem::displayFileDialog(FileSystem::OPEN, "Select Texture", "Texture Files", "png", "res");
  1055. if (file.length() > 0)
  1056. {
  1057. // Set new sprite on our emitter
  1058. _particleEmitter->setTexture(file.c_str(), _particleEmitter->getTextureBlending());
  1059. // Update the UI to display the new sprite
  1060. updateImageControl();
  1061. }
  1062. }
  1063. void ParticlesGame::updateImageControl()
  1064. {
  1065. ImageControl* img = (ImageControl*)_form->getControl("sprite");
  1066. img->setImage(_particleEmitter->getTexture()->getPath());
  1067. // Resize the image control so keep it to scale
  1068. int w = _particleEmitter->getTexture()->getWidth();
  1069. int h = _particleEmitter->getTexture()->getHeight();
  1070. int max = w > h ? w : h;
  1071. if (max > 120)
  1072. {
  1073. float ratio = 120.0f / max;
  1074. w *= ratio;
  1075. h *= ratio;
  1076. }
  1077. img->setSize(w, h);
  1078. _form->getControl("image")->setHeight(h + _form->getControl("imageSettings")->getHeight() + 50);
  1079. ((TextBox*)_form->getControl("frameCount"))->setText(toString(_particleEmitter->getSpriteFrameCount()).c_str());
  1080. ((TextBox*)_form->getControl("frameWidth"))->setText(toString(_particleEmitter->getSpriteWidth()).c_str());
  1081. ((TextBox*)_form->getControl("frameHeight"))->setText(toString(_particleEmitter->getSpriteHeight()).c_str());
  1082. switch (_particleEmitter->getTextureBlending())
  1083. {
  1084. case ParticleEmitter::BLEND_ADDITIVE:
  1085. ((RadioButton*)_form->getControl("additive"))->setSelected(true);
  1086. break;
  1087. case ParticleEmitter::BLEND_MULTIPLIED:
  1088. ((RadioButton*)_form->getControl("multiply"))->setSelected(true);
  1089. break;
  1090. case ParticleEmitter::BLEND_OPAQUE:
  1091. ((RadioButton*)_form->getControl("opaque"))->setSelected(true);
  1092. break;
  1093. case ParticleEmitter::BLEND_TRANSPARENT:
  1094. ((RadioButton*)_form->getControl("transparent"))->setSelected(true);
  1095. break;
  1096. }
  1097. }