51 using std::make_unique;
53 using std::unique_ptr;
100 ParticleSystemEditorTabView::ParticleSystemEditorTabView(
EditorView* editorView,
const string& tabId,
Prototype* prototype):
Gizmo(nullptr,
"spsv")
105 this->prototype = unique_ptr<Prototype>(
prototype);
106 this->
audio = Audio::getInstance();
107 this->
engine = unique_ptr<Engine>(Engine::createOffScreenInstance(512, 512,
true,
true,
true));
108 this->
engine->setShadowMapLightEyeDistanceScale(0.1f);
109 this->
engine->setSceneColor(
Color4(39.0f / 255.0f, 39.0f / 255.0f, 39.0f / 255.0f, 1.0f));
113 Gizmo::setEngine(
engine.get());
124 for (
auto& event:
engine->getGUI()->getKeyboardEvents()) {
125 if (event.isProcessed() ==
true)
continue;
126 auto isKeyDown =
event.getType() == GUIKeyboardEvent::KEYBOARDEVENT_KEY_PRESSED;
132 for (
auto& event:
engine->getGUI()->getMouseEvents()) {
133 if (event.isProcessed() ==
true)
continue;
136 if (event.getType() == GUIMouseEvent::MOUSEEVENT_RELEASED) {
137 auto selectedEntity =
engine->getEntity(
"model");
146 event.setProcessed(
true);
148 if (event.getType() == GUIMouseEvent::MOUSEEVENT_PRESSED) {
149 Node* selectedEntityNode =
nullptr;
151 Entity* selectedEntity =
nullptr;
152 if (
getGizmoMode() ==
GIZMOMODE_NONE) selectedEntity =
engine->getEntityByMousePosition(event.getXUnscaled(), event.getYUnscaled(),
nullptr, &selectedEntityNode, &selectedSubParticleSystem);
155 event.setProcessed(
true);
158 event.setProcessed(
true);
160 if (selectedEntity !=
nullptr) {
162 if (psg !=
nullptr && selectedSubParticleSystem !=
nullptr) {
164 for (
auto pse: psg->getParticleSystems()) {
165 if (pse == selectedSubParticleSystem) {
174 event.setProcessed(
true);
177 if (event.getType() == GUIMouseEvent::MOUSEEVENT_DRAGGED) {
185 auto selectedEntity =
engine->getEntity(
"model");
188 if (gizmoEntity !=
nullptr && selectedEntity !=
nullptr) {
189 selectedEntity->setTranslation(selectedEntity->getTranslation().clone().add(deltaTranslation));
190 selectedEntity->update();
191 auto localTransformations =
dynamic_cast<ParticleSystem*
>(selectedEntity)->getLocalTransform();
192 localTransformations.
setScale(localTransformations.getScale().clone().scale(deltaScale));
194 if (localTransformations.getRotationCount() == 0) {
195 localTransformations.addRotation(Rotation::Z_AXIS, 0.0f);
196 localTransformations.addRotation(Rotation::Y_AXIS, 0.0f);
197 localTransformations.addRotation(Rotation::X_AXIS, 0.0f);
199 localTransformations.setRotationAngle(0, localTransformations.getRotationAngle(0) + deltaRotation[2]);
200 localTransformations.setRotationAngle(1, localTransformations.getRotationAngle(1) + deltaRotation[1]);
201 localTransformations.setRotationAngle(2, localTransformations.getRotationAngle(2) + deltaRotation[0]);
203 localTransformations.update();
204 dynamic_cast<ParticleSystem*
>(selectedEntity)->setLocalTransform(localTransformations);
208 if (Math::abs(deltaTranslation.
getX()) > Math::EPSILON ||
209 Math::abs(deltaTranslation.
getY()) > Math::EPSILON ||
210 Math::abs(deltaTranslation.
getZ()) > Math::EPSILON) {
214 event.setProcessed(
true);
230 if (sound !=
nullptr) sound->
play();
252 Console::println(
"ParticleSystemEditorTabView::initialize(): An error occurred: " +
string(exception.what()));
298 auto soundDefinition =
prototype->getSound(soundId);
299 if (soundDefinition !=
nullptr && soundDefinition->getFileName().length() > 0) {
300 auto pathName = PrototypeReader::getResourcePathName(
301 Tools::getPathName(
prototype->getFileName()),
302 soundDefinition->getFileName()
304 auto fileName = Tools::getFileName(soundDefinition->getFileName());
305 auto sound =
new Sound(
310 sound->setGain(soundDefinition->getGain());
311 sound->setPitch(soundDefinition->getPitch());
312 sound->setLooping(soundDefinition->isLooping());
313 sound->setFixed(
true);
317 if (soundDefinition->getOffset() <= 0) {
335 engine->removeEntity(
"model");
348 if (changeOutlinerSelection ==
true) {
354 if (changeOutlinerSelection ==
true) {
363 auto selectedEntity =
engine->getEntity(
"model");
365 if (psg !=
nullptr) {
371 if (selectedEntity !=
nullptr) {
372 if (pse !=
nullptr) {
373 Gizmo::updateGizmo(pse->getEmitter()->getCenter().clone().scale(
objectScale).add(selectedEntity->getTranslation()), selectedEntity->getTransform());
375 Gizmo::updateGizmo(selectedEntity->getWorldBoundingBox()->getCenter(), selectedEntity->getTransform());
383 Gizmo::setGizmoRotation(transform);
390 auto objectScaleInverted =
Vector3(
395 transform.setScale(objectScaleInverted);
398 auto emitterType = particleSystem->getEmitter();
399 if (emitterType == PrototypeParticleSystem_Emitter::NONE) {
402 if (emitterType == PrototypeParticleSystem_Emitter::POINT_PARTICLE_EMITTER) {
403 auto emitter = particleSystem->getPointParticleEmitter();
404 auto position = transform.getTranslation().clone().scale(objectScaleInverted).add(emitter->getPosition());
405 if (guiOnly ==
false) {
406 emitter->setPosition(position);
411 if (emitterType == PrototypeParticleSystem_Emitter::BOUNDINGBOX_PARTICLE_EMITTER) {
412 auto emitter = particleSystem->getBoundingBoxParticleEmitters();
413 auto center = transform.getTranslation().clone().scale(objectScaleInverted).add(emitter->getObbCenter());
414 auto axis0 = emitter->getObbAxis0().clone().scale(emitter->getObbHalfextension().getX() * 2.0f);
415 auto axis1 = emitter->getObbAxis1().clone().scale(emitter->getObbHalfextension().getY() * 2.0f);
416 auto axis2 = emitter->getObbAxis2().clone().scale(emitter->getObbHalfextension().getZ() * 2.0f);
417 auto halfExtension = emitter->getObbHalfextension();
418 axis0 = localTransform.getTransformMatrix().multiplyNoTranslation(axis0);
419 axis1 = localTransform.getTransformMatrix().multiplyNoTranslation(axis1);
420 axis2 = localTransform.getTransformMatrix().multiplyNoTranslation(axis2);
423 Math::clamp(axis0.computeLength() / 2.0f, 0.01f, 1000.0f),
424 Math::clamp(axis1.computeLength() / 2.0f, 0.01f, 1000.0f),
425 Math::clamp(axis2.computeLength() / 2.0f, 0.01f, 1000.0f)
431 if (guiOnly ==
false) {
432 emitter->setObbCenter(center);
433 emitter->setObbAxis0(axis0);
434 emitter->setObbAxis1(axis1);
435 emitter->setObbAxis2(axis2);
436 emitter->setObbHalfextension(halfExtension);
441 if (emitterType == PrototypeParticleSystem_Emitter::CIRCLE_PARTICLE_EMITTER) {
442 auto emitter = particleSystem->getCircleParticleEmitter();
443 auto center = transform.getTranslation().clone().scale(objectScaleInverted).add(emitter->getCenter());
444 auto axis0 = emitter->getAxis0();
445 auto axis1 = emitter->getAxis1();
446 axis0 = localTransform.getTransformMatrix().multiplyNoTranslation(axis0).normalize();
447 axis1 = localTransform.getTransformMatrix().multiplyNoTranslation(axis1).normalize();
461 auto radius = Math::clamp(emitter->getRadius() * Math::abs(scale), 0.01f, 1000.0f);
462 if (guiOnly ==
false) {
463 emitter->setCenter(center);
464 emitter->setAxis0(axis0);
465 emitter->setAxis1(axis1);
466 emitter->setRadius(radius);
471 if (emitterType == PrototypeParticleSystem_Emitter::CIRCLE_PARTICLE_EMITTER_PLANE_VELOCITY) {
472 auto emitter = particleSystem->getCircleParticleEmitterPlaneVelocity();
473 auto center = transform.getTranslation().clone().scale(objectScaleInverted).add(emitter->getCenter());
474 auto axis0 = emitter->getAxis0();
475 auto axis1 = emitter->getAxis1();
476 axis0 = localTransform.getTransformMatrix().multiplyNoTranslation(axis0).normalize();
477 axis1 = localTransform.getTransformMatrix().multiplyNoTranslation(axis1).normalize();
491 auto radius = Math::clamp(emitter->getRadius() * Math::abs(scale), 0.01f, 1000.0f);
492 if (guiOnly ==
false) {
493 emitter->setCenter(center);
494 emitter->setAxis0(axis0);
495 emitter->setAxis1(axis1);
496 emitter->setRadius(radius);
501 if (emitterType == PrototypeParticleSystem_Emitter::SPHERE_PARTICLE_EMITTER) {
502 auto emitter = particleSystem->getSphereParticleEmitter();
503 auto center = transform.getTranslation().clone().scale(objectScaleInverted).add(emitter->getCenter());
517 auto radius = Math::clamp(emitter->getRadius() * Math::abs(scale), 0.01f, 1000.0f);
518 if (guiOnly ==
false) {
519 emitter->setCenter(center);
520 emitter->setRadius(radius);
525 Console::println(
"SharedParticleSystemView::applyParticleSystemTransform(): unknown particle system emitter '" + particleSystem->getEmitter()->getName() +
"'");
528 if (guiOnly ==
false) {
530 auto modelEntity =
engine->getEntity(
"model");
531 if (modelEntity !=
nullptr)
engine->removeEntity(
"model");
535 modelEntity = SceneConnector::createEntity(
prototype.get(),
"model", transform);
536 if (modelEntity !=
nullptr) {
537 modelEntity->setPickable(
true);
538 engine->addEntity(modelEntity);
544 PrototypeWriter::write(pathName, fileName,
prototype.get());
virtual void play()=0
Plays this audio entity.
Interface to audio module.
AudioEntity * getEntity(const string &id)
Returns an audio entity identified by given id.
void addEntity(AudioEntity *entity)
Adds a audio entity.
void removeEntity(const string &id)
Removes an audio entity.
Sound audio entity implementation.
Color 4 definition class.
virtual void setScale(const Vector3 &scale)=0
Set scale.
virtual const Transform & getTransform() const =0
Particle system group, which combines several particle systems into a group, to be used with engine c...
const vector< ParticleSystem * > & getParticleSystems()
Scene engine/physics connector.
Prototype audio definition.
Prototype bounding box particle emitter definition.
Prototype circle particle emitter plane velocity definition.
Prototype circle particle emitter definition.
Prototype particle system emitter type enum.
Prototype point particle emitter definition.
Prototype sphere particle emitter definition.
GUI screen node that represents a screen that can be rendered via GUI system.
void forwardChange(GUIElementNode *node)
Forward change event.
GUINode * getNodeById(const string &nodeId)
Get GUI node by id.
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Vector3 & add(float scalar)
Adds a scalar.
float computeLengthSquared() const
Vector3 clone() const
Clones this vector3.
Vector3 & sub(float scalar)
Subtracts a scalar.
Vector3 & set(float x, float y, float z)
Sets this vector3 by its components.
Particle system editor tab controller.
Particle system editor tab view.
void saveFile(const string &pathName, const string &fileName)
Saving prototype as tempty prototype.
void setGizmoRotation(const Transform &transform)
Set GIZMO rotation.
void playSound(const string &soundId) override
Play sound.
void dispose() override
Disposes the view.
void display() override
Renders the view.
void reloadOutliner() override
Reload outliner.
void onCameraRotation() override
On rotation event to be overloaded.
unique_ptr< Engine > engine
void initialize() override
Initiates the view.
void deactivate() override
Deactivate.
PrototypeSoundsSubView * prototypeSoundsView
Engine * getEngine() override
unique_ptr< ParticleSystemEditorTabController > particleSystemEditorTabController
void handleInputEvents() override
Handle input events that have not yet been processed.
void applyParticleSystemTransform(ParticleSystem *particleSystemEntity, bool guiOnly)
Apply particle system transform.
TabView::OutlinerState outlinerState
void activate() override
Activate.
unique_ptr< CameraRotationInputHandler > cameraRotationInputHandler
void updateGizmo()
Update GIZMO.
PrototypePhysicsSubView * prototypePhysicsView
~ParticleSystemEditorTabView()
Destructor.
void stopSound() override
Stop sound.
void setParticleSystemIndex(int idx, bool changeOutlinerSelection=true)
Set particle system index, the particle system to edit.
void updateRendering() override
Update rendering.
void initParticleSystem()
Init particle system.
unique_ptr< Prototype > prototype
int getParticleSystemIndex()
PrototypeDisplaySubView * prototypeDisplayView
void onCameraScale() override
On scale event to be overloaded.
void uninitParticleSystem()
Uninit particle system.
Mutable utf8 aware string class.
MutableString & append(char c)
Append character.
std::exception Exception
Exception base class.
Particle system entity interface.
virtual const Transform & getLocalTransform()=0