diff --git a/src/fgt/filter_physics/GravitySubFilter.cpp b/src/fgt/filter_physics/GravitySubFilter.cpp index 50c6b9a81..fa3d56c1c 100644 --- a/src/fgt/filter_physics/GravitySubFilter.cpp +++ b/src/fgt/filter_physics/GravitySubFilter.cpp @@ -31,6 +31,8 @@ bool GravitySubFilter::configurationHasChanged(RichParameterSet& par){ } void GravitySubFilter::initialize(MeshDocument& md, RichParameterSet& par){ + MeshSubFilter::initialize(md, par); + static float gravity[3] = {0.0f, -9.8f, 0.0f}; m_engine.clear(); m_engine.setGlobalForce(gravity); @@ -42,7 +44,6 @@ void GravitySubFilter::initialize(MeshDocument& md, RichParameterSet& par){ for(unsigned int i = 0; i < md.size(); i++) m_layersTrans.push_back(LayerTransformations()); - m_steps = m_seconds / m_stepSize; for(int i = 0; i <= m_steps; i++){ for(unsigned int j = 0; j < md.size(); j++){ m_layersTrans[j].push_back(m_engine.getTransformationMatrix(*md.getMesh(j))); diff --git a/src/fgt/filter_physics/MeshSubFilter.cpp b/src/fgt/filter_physics/MeshSubFilter.cpp index bd768159d..1821ebfd0 100644 --- a/src/fgt/filter_physics/MeshSubFilter.cpp +++ b/src/fgt/filter_physics/MeshSubFilter.cpp @@ -20,3 +20,7 @@ bool MeshSubFilter::configurationHasChanged(RichParameterSet& par){ m_seconds = par.getInt("seconds"); return changed; } + +void MeshSubFilter::initialize(MeshDocument&, RichParameterSet&){ + m_steps = m_seconds / m_stepSize; +} diff --git a/src/fgt/filter_physics/MeshSubFilter.h b/src/fgt/filter_physics/MeshSubFilter.h index c207b1d00..d094907c2 100644 --- a/src/fgt/filter_physics/MeshSubFilter.h +++ b/src/fgt/filter_physics/MeshSubFilter.h @@ -22,7 +22,7 @@ protected: typedef std::vector LayerTransformations; typedef std::vector LayersTransformations; - virtual void initialize(MeshDocument&, RichParameterSet&) = 0; + virtual void initialize(MeshDocument&, RichParameterSet&); virtual bool configurationHasChanged(RichParameterSet& par); int m_steps; diff --git a/src/fgt/filter_physics/RandomDropFilter.cpp b/src/fgt/filter_physics/RandomDropFilter.cpp index 8b0aab4d5..eb9f6b3f8 100644 --- a/src/fgt/filter_physics/RandomDropFilter.cpp +++ b/src/fgt/filter_physics/RandomDropFilter.cpp @@ -17,67 +17,93 @@ void RandomDropFilter::initParameterSet(QAction* action,MeshDocument& md, RichPa for(int i = 1; i <= md.size(); i++){ layers.push_back(QString::number(i)); } - par.addParam(new RichEnum("randomLayer", 0, layers, "Random object layer", "Select the layer that contains the object that will spawn randomly")); + par.addParam(new RichEnum("randomLayer", 1, layers, "Random object layer", "Select the layer that contains the object that will spawn randomly")); par.addParam(new RichFloat("distance", 1.0f, "Random radius interval", "The object will spawn in a random position contained in the specified radius")); - par.addParam(new RichFloat("dropRate", 0.005f, "Drop rate", "The drop rate")); + par.addParam(new RichInt("dropRate", 2, "Drop rate", "The drop rate")); } bool RandomDropFilter::applyFilter(QAction* filter, MeshDocument &md, RichParameterSet& par, vcg::CallBackPos* cb){ MeshSubFilter::applyFilter(filter, md, par, cb); int currentStep = (par.getDynamicFloat("timeline") * m_steps) / 100; + unsigned int rndObjects = m_seconds/m_dropRate; + unsigned int currentRndObject = md.size() - rndObjects + currentStep/(100*m_dropRate); - for(int i = 0; i < md.size(); i++) + for(int i = 0; i < md.size(); i++){ md.getMesh(i)->cm.Tr = m_layersTrans[i][currentStep]; + if(i < currentRndObject) + md.getMesh(i)->visible = true; + else + md.getMesh(i)->visible = false; + } + return true; } void RandomDropFilter::initialize(MeshDocument& md, RichParameterSet& par){ + MeshSubFilter::initialize(md, par); + static float gravity[3] = {0.0f, -9.8f, 0.0f}; m_engine.clear(); m_engine.setGlobalForce(gravity); srand((unsigned)time(0)); - for(unsigned int i = 0; i < m_steps*m_seconds*m_dropRate; i++) + unsigned int rndObjects = m_seconds/m_dropRate; + for(unsigned int i = 0; i < rndObjects; i++) addRandomObject(md); - for(unsigned int i = 0; i < md.size(); i++) - m_engine.registerTriMesh(*md.getMesh(i), m_randomLayer == i ? true : false); + for(unsigned int i = 0; i < md.size() - rndObjects; i++) + m_engine.registerTriMesh(*md.getMesh(i), m_randomLayer == i ? false : true); m_layersTrans.clear(); for(unsigned int i = 0; i < md.size(); i++) m_layersTrans.push_back(LayerTransformations()); - m_steps = m_seconds / m_stepSize; + m_steps = m_seconds/m_stepSize; for(int i = 0; i <= m_steps; i++){ - for(unsigned int j = 0; j < md.size(); j++){ + int currentRndObject = md.size() - rndObjects + i/(100*m_dropRate); + + if(i != 0 && i % (100*m_dropRate) == 0) + m_engine.registerTriMesh(*md.getMesh(currentRndObject - 1), false); + + for(unsigned int j = 0; j < currentRndObject; j++){ m_layersTrans[j].push_back(m_engine.getTransformationMatrix(*md.getMesh(j))); } + + for(unsigned int j = currentRndObject; j < md.size(); j++){ + m_layersTrans[j].push_back(vcg::Matrix44::Identity()); + } + m_engine.integrate(m_stepSize); } } void RandomDropFilter::addRandomObject(MeshDocument& md){ - float x = (float) rand()/RAND_MAX * m_distance; - float y = (float) rand()/RAND_MAX * m_distance; - float z = (float) rand()/RAND_MAX * m_distance; + MeshModel* meshCopy = md.addNewMesh("rndMesh"); + vcg::tri::Append::Mesh(meshCopy->cm, md.getMesh(m_randomLayer)->cm, false, true); + meshCopy->cm.Tr = md.getMesh(m_randomLayer)->cm.Tr; - /*MeshModel* meshCopy = md.addNewMesh("rndMesh"); - vcg::tri::Append::Mesh(md.getMesh(m_randomLayer)->cm, meshCopy->cm, false, true);*/ + float x = (float) meshCopy->cm.Tr.GetColumn3(3).X() + m_distance/2.0f - rand()/(RAND_MAX*m_distance); + float y = (float) meshCopy->cm.Tr.GetColumn3(3).Y() + m_distance/2.0f - rand()/(RAND_MAX*m_distance); + float z = (float) meshCopy->cm.Tr.GetColumn3(3).Z() + m_distance/2.0f - rand()/(RAND_MAX*m_distance); + + meshCopy->cm.Tr.SetRotateRad(rand(), vcg::Point3(x, y, z)); + meshCopy->cm.Tr.SetTranslate(x, y, z); + meshCopy->visible = false; } bool RandomDropFilter::configurationHasChanged(RichParameterSet& par){ bool changed = MeshSubFilter::configurationHasChanged(par) || m_randomLayer != par.getEnum("randomLayer") || m_distance != par.getFloat("distance") || - m_dropRate != par.getFloat("dropRate"); + m_dropRate != par.getInt("dropRate"); m_randomLayer = par.getEnum("randomLayer"); m_distance = par.getFloat("distance"); - m_dropRate = par.getFloat("dropRate"); + m_dropRate = par.getInt("dropRate"); return changed; } diff --git a/src/fgt/filter_physics/RandomDropFilter.h b/src/fgt/filter_physics/RandomDropFilter.h index ad15c04b6..0655437e3 100644 --- a/src/fgt/filter_physics/RandomDropFilter.h +++ b/src/fgt/filter_physics/RandomDropFilter.h @@ -22,8 +22,8 @@ protected: private: int m_randomLayer; - int m_distance; - float m_dropRate; + int m_dropRate; + float m_distance; ODEFacade m_engine; };