X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Fnbodycuda%2Fnbody.C;fp=cinelerra-5.1%2Fplugins%2Fnbodycuda%2Fnbody.C;h=ae15e643f6b3cd36b3a7ae1fad5f0a1f8525f0a0;hb=b1649fe7b38cfb4bbec58b19fb8dda2daa0ce520;hp=0000000000000000000000000000000000000000;hpb=abf5c6bb4dec2c2d03df2872e1d337e3905b3619;p=goodguy%2Fcinelerra.git diff --git a/cinelerra-5.1/plugins/nbodycuda/nbody.C b/cinelerra-5.1/plugins/nbodycuda/nbody.C new file mode 100644 index 00000000..ae15e643 --- /dev/null +++ b/cinelerra-5.1/plugins/nbodycuda/nbody.C @@ -0,0 +1,392 @@ +/* + * CINELERRA + * Copyright (C) 1997-2014 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define GL_GLEXT_PROTOTYPES +#include +#include +#include + +#include "clip.h" +#include "filexml.h" +#include "language.h" +#include "mutex.h" + +#include "cwindow.h" +#include "cwindowgui.h" +#include "mwindow.h" +#include "pluginserver.h" +#include "playback3d.h" + +#include "nbody.h" +#include "nbodycuda.h" +#include "nbodywindow.h" + + +static struct N_BodyParams demoParams[] = { + { 0.016f, 1.54f, 8.0f, 0.1f, 1.0f, 1.0f, 0, -2, -100}, + { 0.016f, 0.68f, 20.0f, 0.1f, 1.0f, 0.8f, 0, -2, -30}, + { 0.0006f, 0.16f, 1000.0f, 1.0f, 1.0f, 0.07f, 0, 0, -1.5f}, + { 0.0006f, 0.16f, 1000.0f, 1.0f, 1.0f, 0.07f, 0, 0, -1.5f}, + { 0.0019f, 0.32f, 276.0f, 1.0f, 1.0f, 0.07f, 0, 0, -5}, + { 0.0016f, 0.32f, 272.0f, 0.145f, 1.0f, 0.08f, 0, 0, -5}, + { 0.0160f, 6.04f, 0.0f, 1.0f, 1.0f, 0.76f, 0, 0, -50}, +}; +const int N_BodyParams::num_demos = sizeof(demoParams)/sizeof(*demoParams); + + +REGISTER_PLUGIN(N_BodyMain) + +void N_BodyConfig::reset(int i) +{ + *(N_BodyParams*)this = demoParams[i]; + trans[0] = trans_lag[0] = m_x; + trans[1] = trans_lag[1] = m_y; + trans[2] = trans_lag[2] = m_z; + rot[0] = rot_lag[0] = 0; + rot[1] = rot_lag[1] = 0; + rot[2] = rot_lag[2] = 0; + mode = ParticleRenderer::PARTICLE_SPRITES_COLOR; + numBodies = 4096; + inertia = 0.1; +} + +N_BodyConfig::N_BodyConfig() +{ + reset(); +} + +int N_BodyConfig::equivalent(N_BodyConfig &that) +{ + return m_timestep == that.m_timestep && + m_clusterScale == that.m_clusterScale && + m_velocityScale == that.m_velocityScale && + m_softening == that. m_softening && + m_damping == that.m_damping && + m_pointSize == that.m_pointSize && + m_x == that.m_x && + m_y == that.m_y && + m_z == that.m_z && + trans[0] == that.trans[0] && + trans[1] == that.trans[1] && + trans[2] == that.trans[2] && + trans_lag[0] == that.trans_lag[0] && + trans_lag[1] == that.trans_lag[1] && + trans_lag[2] == that.trans_lag[2] && + rot[0] == that.rot[0] && + rot[1] == that.rot[1] && + rot[2] == that.rot[2] && + rot_lag[0] == that.rot_lag[0] && + rot_lag[1] == that.rot_lag[1] && + rot_lag[2] == that.rot_lag[2] && + inertia == that.inertia && + numBodies == that.numBodies; + return 1; +} + +void N_BodyConfig::copy_from(N_BodyConfig &that) +{ + m_timestep = that.m_timestep; + m_clusterScale = that.m_clusterScale; + m_velocityScale = that.m_velocityScale; + m_softening = that. m_softening; + m_damping = that.m_damping; + m_pointSize = that.m_pointSize; + m_x = that.m_x; + m_y = that.m_y; + m_z = that.m_z; + trans[0] = that.trans[0]; + trans[1] = that.trans[1]; + trans[2] = that.trans[2]; + trans_lag[0] = that.trans_lag[0]; + trans_lag[1] = that.trans_lag[1]; + trans_lag[2] = that.trans_lag[2]; + rot[0] = that.rot[0]; + rot[1] = that.rot[1]; + rot[2] = that.rot[2]; + rot_lag[0] = that.rot_lag[0]; + rot_lag[1] = that.rot_lag[1]; + rot_lag[2] = that.rot_lag[2]; + inertia = that.inertia; + numBodies = that.numBodies; +} + +void N_BodyConfig::interpolate( N_BodyConfig &prev, N_BodyConfig &next, + long prev_frame, long next_frame, long current_frame) +{ + copy_from(next); +} + +void N_BodyConfig::limits() +{ + if( m_damping < 0.001 ) m_damping = 0.001; + if( trans[2] < 0.005 ) trans[2] = 0.005; + int n = 1; + while( n < numBodies ) n <<= 1; + bclamp(n, 0x0010, 0x4000); + numBodies = n; + bclamp(inertia, 0.f,1.f); + bclamp(mode, 0, (int)ParticleRenderer::PARTICLE_NUM_MODES-1); +} + + +N_BodyMain::N_BodyMain(PluginServer *server) + : PluginVClient(server) +{ + cuda = 0; + blockSize = 256; + + m_nbody = 0; + m_renderer = 0; + m_hPos = 0; + m_hVel = 0; + m_hColor = 0; + + curr_position = -1; + new_position = -1; +} + +N_BodyMain::~N_BodyMain() +{ + delete cuda; +} + +void N_BodyMain::init(int numBodies) +{ + selectDemo(0); + delete m_nbody; m_nbody = new N_BodySystem(numBodies, 1, blockSize); + int sz = numBodies*4; + delete [] m_hPos; m_hPos = new float[sz]; + delete [] m_hVel; m_hVel = new float[sz]; + delete [] m_hColor; m_hColor = new float[sz]; + delete m_renderer; m_renderer = new ParticleRenderer; +// config here + m_nbody->setSoftening(config.m_softening); + m_nbody->setDamping(config.m_damping); + reset(numBodies, NBODY_CONFIG_RANDOM); + resetRenderer(); +} + +void N_BodyMain::reset(int numBodies, NBodyConfig cfg) +{ + randomizeBodies(cfg, m_hPos, m_hVel, m_hColor, + config.m_clusterScale, config.m_velocityScale, + numBodies, true); + setArrays(m_hPos, m_hVel); +} + +void N_BodyMain::resetRenderer() +{ + float color[4] = { 1.0f, 0.6f, 0.3f, 1.0f}; + m_renderer->setBaseColor(color); + m_renderer->setColors(m_hColor, m_nbody->getNumBodies()); + m_renderer->setSpriteSize(config.m_pointSize); +} + +void N_BodyMain::selectDemo(int index) +{ + config.reset(index); +} + +void N_BodyMain::finalize() +{ + delete [] m_hPos; m_hPos = 0; + delete [] m_hVel; m_hVel = 0; + delete [] m_hColor; m_hColor = 0; + delete m_nbody; m_nbody = 0; + delete m_renderer; m_renderer = 0; +} + +void N_BodyMain::draw() +{ + cuda->draw_event(); + glClearColor(0.,0.,0.,1.); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glColor4f(1.,1.,1.,1.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + float inertia = config.inertia; + for( int c=0; c<3; ++c ) { + config.trans_lag[c] += (config.trans[c] - config.trans_lag[c]) * inertia; + config.rot_lag[c] += (config.rot[c] - config.rot_lag[c]) * inertia; + } + + glTranslatef(config.trans_lag[0], config.trans_lag[1], config.trans_lag[2]); + glRotatef(config.rot_lag[0], 1.0, 0.0, 0.0); + glRotatef(config.rot_lag[1], 0.0, 1.0, 0.0); + glDisable(GL_TEXTURE_2D); + display(); +} + + +const char* N_BodyMain::plugin_title() { return N_("N_Body"); } +int N_BodyMain::is_realtime() { return 1; } +int N_BodyMain::is_synthesis() { return 1; } + +NEW_WINDOW_MACRO(N_BodyMain, N_BodyWindow); +LOAD_CONFIGURATION_MACRO(N_BodyMain, N_BodyConfig) + +void N_BodyMain::save_data(KeyFrame *keyframe) +{ + FileXML output; + +// cause data to be stored directly in text + output.set_shared_output(keyframe->xbuf); + output.tag.set_title("NBODYCUDA"); + output.tag.set_property("TIMESTEP", config.m_timestep); + output.tag.set_property("CLUSTER_SCALE", config.m_clusterScale); + output.tag.set_property("VELOCITY_SCALE", config.m_velocityScale); + output.tag.set_property("SOFTENING", config.m_softening); + output.tag.set_property("DAMPING", config.m_damping); + output.tag.set_property("POINT_SIZE", config.m_pointSize); + output.tag.set_property("X", config.m_x); + output.tag.set_property("Y", config.m_y); + output.tag.set_property("Z", config.m_z); + output.tag.set_property("TRANS_X",config.trans[0]); + output.tag.set_property("TRANS_Y",config.trans[1]); + output.tag.set_property("TRANS_Z",config.trans[2]); + output.tag.set_property("TRANS_LAG_X",config.trans_lag[0]); + output.tag.set_property("TRANS_LAG_Y",config.trans_lag[1]); + output.tag.set_property("TRANS_LAG_Z",config.trans_lag[2]); + output.tag.set_property("ROT_X",config.rot[0]); + output.tag.set_property("ROT_Y",config.rot[1]); + output.tag.set_property("ROT_Z",config.rot[2]); + output.tag.set_property("ROT_LAG_X",config.rot_lag[0]); + output.tag.set_property("ROT_LAG_Y",config.rot_lag[1]); + output.tag.set_property("ROT_LAG_Z",config.rot_lag[2]); + output.tag.set_property("INERTIA", config.inertia); + output.tag.set_property("MODE", config.mode); + output.tag.set_property("NUM_BODIES", config.numBodies); + output.append_tag(); + output.append_newline(); + output.tag.set_title("/NBODYCUDA"); + output.append_tag(); + output.append_newline(); + output.terminate_string(); +} + +void N_BodyMain::read_data(KeyFrame *keyframe) +{ + FileXML input; + input.set_shared_input(keyframe->xbuf); + + int result = 0; + while( !(result = input.read_tag()) ) { + if( input.tag.title_is("NBODYCUDA") ) { + config.m_timestep = input.tag.get_property("TIMESTEP", config.m_timestep); + config.m_clusterScale = input.tag.get_property("CLUSTER_SCALE", config.m_clusterScale); + config.m_velocityScale = input.tag.get_property("VELOCITY_SCALE", config.m_velocityScale); + config.m_softening = input.tag.get_property("SOFTENING", config.m_softening); + config.m_damping = input.tag.get_property("DAMPING", config.m_damping); + config.m_pointSize = input.tag.get_property("POINT_SIZE", config.m_pointSize); + config.m_x = input.tag.get_property("X", config.m_x); + config.m_y = input.tag.get_property("Y", config.m_y); + config.m_z = input.tag.get_property("Z", config.m_z); + config.trans[0] = input.tag.get_property("TRANS_X", config.trans[0]); + config.trans[1] = input.tag.get_property("TRANS_Y", config.trans[1]); + config.trans[2] = input.tag.get_property("TRANS_Z", config.trans[2]); + config.trans_lag[0] = input.tag.get_property("TRANS_LAG_X", config.trans_lag[0]); + config.trans_lag[1] = input.tag.get_property("TRANS_LAG_Y", config.trans_lag[1]); + config.trans_lag[2] = input.tag.get_property("TRANS_LAG_Z", config.trans_lag[2]); + config.rot[0] = input.tag.get_property("ROT_X", config.rot[0]); + config.rot[1] = input.tag.get_property("ROT_Y", config.rot[1]); + config.rot[2] = input.tag.get_property("ROT_Z", config.rot[2]); + config.rot_lag[0] = input.tag.get_property("ROT_LAG_X", config.rot_lag[0]); + config.rot_lag[1] = input.tag.get_property("ROT_LAG_Y", config.rot_lag[1]); + config.rot_lag[2] = input.tag.get_property("ROT_LAG_Z", config.rot_lag[2]); + config.inertia = input.tag.get_property("INERTIA", config.inertia); + config.mode = input.tag.get_property("MODE", config.mode); + config.numBodies = input.tag.get_property("NUM_BODIES", config.numBodies); + } + } + config.limits(); +} + +void N_BodyMain::update_gui() +{ + if( !thread ) return; + if( !load_configuration() ) return; + thread->window->lock_window("N_BodyMain::update_gui"); + N_BodyWindow *window = (N_BodyWindow*)thread->window; + window->update_gui(); + window->flush(); + window->unlock_window(); +} + +int N_BodyMain::process_buffer(VFrame *frame, int64_t start_position, double frame_rate) +{ + + //int need_reconfigure = + load_configuration(); + new_position = start_position; + output = get_output(0); + color_model = output->get_color_model(); + if( get_use_opengl() ) + return run_opengl(); +// always use_opengl + Canvas *canvas = server->mwindow->cwindow->gui->canvas; + return server->mwindow->playback_3d->run_plugin(canvas, this); +} + +// cuda + +N_BodyCuda::N_BodyCuda() +{ + version = 0; + numSMs = 0; +} +N_BodyCuda::~N_BodyCuda() +{ +} + +// opengl from here down + +void N_BodyMain::init_cuda() +{ + if( !cuda ) { + cuda = new N_BodyCuda(); + cuda->init_dev(); + } + cuda->init(); +} +void N_BodyMain::finish_cuda() +{ + cuda->finish(); +} + +int N_BodyMain::handle_opengl() +{ + output->enable_opengl(); + output->init_screen(); + if( !m_nbody || get_source_position() == 0 || + (int)m_nbody->getNumBodies() != config.numBodies ) + init(config.numBodies); + init_cuda(); + if( curr_position != new_position ) { + updateSimulation(); + curr_position = new_position; + } + draw(); + finish_cuda(); + output->set_opengl_state(VFrame::SCREEN); + if( !get_use_opengl() ) // rendering + output->screen_to_ram(); + return 0; +} +