namespace particle { ParamDesc theDragParticleForceParamDesc[] = { ParamDesc(PB_DRAG_FACTOR, "factor", PARAM_FLOAT, false), }; class DragParticleForce : public GenParticleForce { float m_factor; int m_function; public: DragParticleForce() { } void create() { GenParticleForce::create(); m_pb->addParams(theDragParticleForceParamDesc, 1); } const char* getSuperClassName() { return "gen_force"; } const char* getClassName() { return "drag"; } void preCalculate(float t) { m_pb->getValue(PB_DRAG_FACTOR, m_factor); } void calcForce(Vector& force, const Vector& pos, const Vector& vel) { float len = vel.GetLength(); Vector newVel = vel * pow(1.0f - m_factor, len); force = newVel - vel; } void parseFrom(const editor::ParserGroup& pg) { GenParticleForce::parseFrom(pg); } void parseTo(editor::ParserGroup& pg) { } }; class DragParticleForceClassDesc : public ParticleForceClassDesc { public: const char* getClassName() { return "drag"; } const char* getSuperClassName() { return "genforce"; } void* create() { return new DragParticleForce(); } }; static DragParticleForceClassDesc theDragParticleForceClassDesc; ParticleForceClassDesc* getDragParticleForceClassDesc() { return &theDragParticleForceClassDesc; } } // particle
Layer::Vocab CurveWarp::get_param_vocab()const { Layer::Vocab ret; ret.push_back(ParamDesc("origin") .set_local_name(_("Origin")) .set_description(_("Position of the destiny Spline line")) ); ret.push_back(ParamDesc("perp_width") .set_local_name(_("Width")) .set_origin("start_point") .set_description(_("How much is expanded the result perpendicular to the source line")) ); ret.push_back(ParamDesc("start_point") .set_local_name(_("Start Point")) .set_connect("end_point") .set_description(_("First point of the source line")) ); ret.push_back(ParamDesc("end_point") .set_local_name(_("End Point")) .set_description(_("Final point of the source line")) ); ret.push_back(ParamDesc("bline") .set_local_name(_("Vertices")) .set_origin("origin") .set_hint("width") .set_description(_("List of Spline Points where the source line is curved to")) ); ret.push_back(ParamDesc("fast") .set_local_name(_("Fast")) .set_description(_("When checked, renders quickly but with artifacts")) ); return ret; }
Layer::Vocab CurveGradient::get_param_vocab()const { Layer::Vocab ret(Layer_Composite::get_param_vocab()); ret.push_back(ParamDesc("origin") .set_local_name(_("Origin")) .set_description(_("Offset for the Vertices List")) ); ret.push_back(ParamDesc("width") .set_is_distance() .set_local_name(_("Width")) .set_description(_("Global width of the gradient")) ); ret.push_back(ParamDesc("bline") .set_local_name(_("Vertices")) .set_origin("origin") .set_hint("width") .set_description(_("A list of spline points")) ); ret.push_back(ParamDesc("gradient") .set_local_name(_("Gradient")) .set_description(_("Gradient to apply")) ); ret.push_back(ParamDesc("loop") .set_local_name(_("Loop")) .set_description(_("When checked the gradient is looped")) ); ret.push_back(ParamDesc("zigzag") .set_local_name(_("ZigZag")) .set_description(_("When checked the gradient is summetrical at the center")) ); ret.push_back(ParamDesc("perpendicular") .set_local_name(_("Perpendicular")) ); ret.push_back(ParamDesc("fast") .set_local_name(_("Fast")) .set_description(_("When checked, renders quickly but with artifacts")) ); return ret; }
namespace particle { static ParamDesc thePointArrayParticleSystemParamDesc[] = { ParamDesc(PB_POINT_ARRAY_MODEL_FILE, "model", PARAM_STRING, false), ParamDesc(PB_POINT_ARRAY_FIRST_VERTEX, "first_vertex", PARAM_INT, false), ParamDesc(PB_POINT_ARRAY_LAST_VERTEX, "last_vertex", PARAM_INT, false) }; struct ParticleMesh { std::vector<Vector> verts; std::vector<Vector> normals; }; class PointArrayParticleSystem : public GenParticleSystem { boost::shared_ptr<ParticleMesh> m_mesh; int m_index; int m_firstVertex; int m_lastVertex; public: PointArrayParticleSystem() { } const char* getClassName() { return "point_array"; } const char* getSuperClassName() { return "gen_system"; } ParticleSystem* launch() { PointArrayParticleSystem* ps = new PointArrayParticleSystem(); baseCopy(ps); ps->m_mesh = m_mesh; return ps; } void create() { GenParticleSystem::create(); m_pb->addParams(thePointArrayParticleSystemParamDesc, 3); m_pb->setValue(PB_POINT_ARRAY_FIRST_VERTEX, 0); m_pb->setValue(PB_POINT_ARRAY_LAST_VERTEX, 0); } void init(IStorm3D* s3d, IStorm3D_Scene* scene) { GenParticleSystem::init(s3d, scene); std::string fileName; m_pb->getValue(PB_POINT_ARRAY_MODEL_FILE, fileName); if(fileName.empty()) return; IStorm3D_Model* model = s3d->CreateNewModel(); if(model->LoadS3D(fileName.c_str())) { Iterator<IStorm3D_Model_Object*>* obj = model->ITObject->Begin(); IStorm3D_Mesh* mesh = obj->GetCurrent()->GetMesh(); if(mesh) { boost::shared_ptr<ParticleMesh> pm(new ParticleMesh()); pm->verts.resize(mesh->GetVertexCount()); pm->normals.resize(mesh->GetVertexCount()); Storm3D_Vertex* v = mesh->GetVertexBuffer(); for(int i = 0; i < mesh->GetVertexCount(); i++) { pm->verts[i] = v[i].position; pm->normals[i] = v[i].normal; } m_mesh.swap(pm); } delete obj; } delete model; } void prepareForLaunch(IStorm3D* s3d, IStorm3D_Scene* scene) { GenParticleSystem::prepareForLaunch(s3d, scene); m_pb->getValue(PB_POINT_ARRAY_FIRST_VERTEX, m_firstVertex); m_pb->getValue(PB_POINT_ARRAY_LAST_VERTEX, m_lastVertex); } void setParticlePosition(Vector& v) { if(m_mesh.get()==NULL) return; m_index = m_firstVertex + rand() % (m_lastVertex - m_firstVertex); if(m_index >= m_mesh->verts.size()) m_index = 0; v = m_mesh->verts[m_index]; } void setParticleVelocity(Vector& v, float speed) { if(m_mesh.get()==NULL) return; v = m_mesh->normals[m_index] * speed; } }; class PointArrayParticleSystemClassDesc : public ParticleSystemClassDesc { public: void* create() { return new PointArrayParticleSystem(); } const char* getClassName() { return "point_array"; } }; static PointArrayParticleSystemClassDesc thePointArrayParticleSystemClassDesc; ParticleSystemClassDesc* getPointArrayParticleSystemClassDesc() { return &thePointArrayParticleSystemClassDesc; } } // particle
namespace particle { static ParamDesc theCloudParticleSystemParamDesc[] = { ParamDesc(PB_PCLOUD_RANDOM_DIRECTION, "random_direction", PARAM_INT, false), ParamDesc(PB_PCLOUD_DIRECTION, "direction", PARAM_VECTOR, false), ParamDesc(PB_PCLOUD_SHAPE, "shape", PARAM_STRING, false), ParamDesc(PB_PCLOUD_SPHERE_INNER_RADIUS, "sphere_inner_radius", PARAM_FLOAT, false), ParamDesc(PB_PCLOUD_SPHERE_OUTER_RADIUS, "sphere_outer_radius", PARAM_FLOAT, false), ParamDesc(PB_PCLOUD_BOX_MIN, "box_min", PARAM_VECTOR, false), ParamDesc(PB_PCLOUD_BOX_MAX, "box_max", PARAM_VECTOR, false), ParamDesc(PB_PCLOUD_CYLINDER_HEIGHT, "cylinder_height", PARAM_FLOAT, false), ParamDesc(PB_PCLOUD_CYLINDER_RADIUS, "cylinder_radius", PARAM_FLOAT, false), }; class CloudParticleSystem : public GenParticleSystem { class Shape { public: virtual ~Shape() {} virtual Shape* create()=0; virtual void prepare(ParamBlock* pb)=0; virtual void gen(Vector& v)=0; }; class Sphere : public Shape { public: float innerRadius; float outerRadius; Shape* create() { return new Sphere(); } void prepare(ParamBlock* pb) { pb->getValue(PB_PCLOUD_SPHERE_INNER_RADIUS, innerRadius); pb->getValue(PB_PCLOUD_SPHERE_OUTER_RADIUS, outerRadius); } void gen(Vector& v) { v.x = (float)(-RAND_MAX) + 2.0f * (float)(rand() % RAND_MAX); v.y = (float)(-RAND_MAX) + 2.0f * (float)(rand() % RAND_MAX); v.z = (float)(-RAND_MAX) + 2.0f * (float)(rand() % RAND_MAX); v.Normalize(); v *= (innerRadius + outerRadius * (float)(rand() % RAND_MAX) / (float)RAND_MAX); } }; class Box : public Shape { public: Vector min; Vector max; Shape* create() { return new Box(); } void prepare(ParamBlock* pb) { pb->getValue(PB_PCLOUD_BOX_MIN, min); pb->getValue(PB_PCLOUD_BOX_MAX, max); } virtual void gen(Vector& v) { v.x = min.x + (max.x - min.x) * (float)(rand() % RAND_MAX) / (float)RAND_MAX; v.y = min.y + (max.y - min.y) * (float)(rand() % RAND_MAX) / (float)RAND_MAX; v.z = min.z + (max.z - min.z) * (float)(rand() % RAND_MAX) / (float)RAND_MAX; } }; class Cylinder : public Shape { public: float height; float radius; Shape* create() { return new Cylinder(); } void prepare(ParamBlock* pb) { pb->getValue(PB_PCLOUD_CYLINDER_HEIGHT, height); pb->getValue(PB_PCLOUD_CYLINDER_RADIUS, radius); } void gen(Vector& v) { float r; do { v.x = -radius + 2.0f * radius * (float)(rand() % RAND_MAX) / (float)RAND_MAX; v.z = -radius + 2.0f * radius * (float)(rand() % RAND_MAX) / (float)RAND_MAX; r = v.x * v.x + v.z + v.z; } while(r > radius); v.y = -height * 0.5f + height * (float)(rand() % RAND_MAX) / (float)RAND_MAX; } }; static Sphere sphere; static Box box; static Cylinder cylinder; static std::map<std::string, Shape*> m_shapes; Shape* m_shape; int m_randomDirection; Vector m_direction; public: const char* getClassName() { return "cloud"; } const char* getSuperClassName() { return "gen_system"; } ParticleSystem* launch() { CloudParticleSystem* ps = new CloudParticleSystem; baseCopy(ps); return ps; } void create() { GenParticleSystem::create(); m_pb->addParams(theCloudParticleSystemParamDesc, 9); m_pb->setValue(PB_PCLOUD_SHAPE, "sphere"); m_pb->setValue(PB_PCLOUD_SPHERE_INNER_RADIUS, 0.0f); m_pb->setValue(PB_PCLOUD_SPHERE_OUTER_RADIUS, 1.0f); m_pb->setValue(PB_PCLOUD_RANDOM_DIRECTION, 1); m_pb->setValue(PB_PCLOUD_DIRECTION, Vector(0.0f, 1.0f, 0.0f)); } void init(IStorm3D* s3d, IStorm3D_Scene* scene) { GenParticleSystem::init(s3d, scene); if(m_shapes.empty()) { m_shapes["sphere"] = &sphere; m_shapes["box"] = &box; m_shapes["cylinder"] = &cylinder; } } void prepareForLaunch(IStorm3D* s3d, IStorm3D_Scene* scene) { GenParticleSystem::prepareForLaunch(s3d, scene); m_pb->getValue(PB_PCLOUD_RANDOM_DIRECTION, m_randomDirection); m_pb->getValue(PB_PCLOUD_DIRECTION, m_direction); m_shape = NULL; std::string shape; m_pb->getValue(PB_PCLOUD_SHAPE, shape); m_shape = m_shapes[shape]->create(); m_shape->prepare(m_pb.get()); } void setParticleVelocity(Vector& v, float speed) { if(m_randomDirection) { float rnd1 = -1.0f + 2.0f * (float)(rand() % RAND_MAX) / (float)RAND_MAX; float rnd2 = -1.0f + 2.0f * (float)(rand() % RAND_MAX) / (float)RAND_MAX; float rnd3 = -1.0f + 2.0f * (float)(rand() % RAND_MAX) / (float)RAND_MAX; Vector d(rnd1, rnd2, rnd3); d.Normalize(); v = d * speed; } else { v = m_direction * speed; } } void setParticlePosition(Vector& v) { if(m_shape) m_shape->gen(v); } }; CloudParticleSystem::Sphere CloudParticleSystem::sphere; CloudParticleSystem::Box CloudParticleSystem::box; CloudParticleSystem::Cylinder CloudParticleSystem::cylinder; std::map<std::string, CloudParticleSystem::Shape*> CloudParticleSystem::m_shapes; class CloudParticleSystemClassDesc : public ParticleSystemClassDesc { public: void* create() { return new CloudParticleSystem(); } const char* getClassName() { return "cloud"; } }; static CloudParticleSystemClassDesc theCloudParticleSystemClassDesc; ParticleSystemClassDesc* getCloudParticleSystemClassDesc() { return &theCloudParticleSystemClassDesc; } } // frozenbyte
namespace particle { class ParticleGravity; class ParticleGravityClassDesc; static ParamDesc theParticleGravityParamDesc[] = { ParamDesc(PB_GRAVITY, "gravity", PARAM_FLOAT, false) }; class ParticleGravity : public GenParticleForce { float m_gravity; public: ParticleGravity() { } void create() { GenParticleForce::create(); m_pb->addParams(theParticleGravityParamDesc, 1); } const char* getClassName() { return "gravity"; } const char* getSuperClassName() { return "gen_force"; } void parseFrom(const editor::ParserGroup& pg) { GenParticleForce::parseFrom(pg); } void parseTo(editor::ParserGroup& pg) { } void preCalculate(float t) { m_pb->getValue(PB_GRAVITY, m_gravity); m_gravity *= PARTICLE_TIME_SCALE; } void calcForce(Vector& force, const Vector& pos, const Vector& vel) { force.x = 0; force.y = 0; force.y = -m_gravity; } }; class ParticleGravityClassDesc : public ParticleForceClassDesc { public: void* create() { return new ParticleGravity(); } const char* getClassName() { return "gravity"; } }; static ParticleGravityClassDesc theParticleGravityClassDesc; ParticleForceClassDesc* getParticleGravityClassDesc() { return &theParticleGravityClassDesc; } } // particle