//***************************************************************************************** // Truevision - a 3d modeler for gnome and povray // // box.cc // A simple CSG box object // // Vincent LE PRINCE // Copyright (C) 2000-2005 Vincent LE PRINCE // This file is part of the TRUEVISION Package // 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ //******************************************************************************************* #include "include/box.h" #include "include/viewmanager.h" #include "include/objectlist.h" #include "include/tvio.h" #include "include/preferences.h" //************************************** // Constructors //************************************** Box::Box( app_objs *appref ) : Object3D_with_material( appref ) { type = TV_OBJ3D_BOX; category = TV_OBJ3D_OBJECTS; set_name( _("Box") ); // Basic parameters : Geometry and transformation widgets location = new ObjParam_point( N_("Translation"), "LOC", _("Translation transformation"), app_ref, true ); location->set( 0, 0, 0 ); size = new ObjParam_scale( N_("Scale"), "SIZE", _("Scale transformation"), app_ref, true ); size->set( 0.2, 0.2, 0.2 ); rotation = new ObjParam_rotation( N_("Rotation"), "ROT", _("Rotation transformation"), app_ref, true ); rotation->set( 0, 0, 0 ); corner1 = new ObjParam_point( N_("Corner 1"), "CORN1", _("First corner of the box coordinates"), app_ref, true ); corner1->set( 0.5, 0.5, 0.5 ); corner2 = new ObjParam_point( N_("Corner 2"), "CORN2", _("Second corner of the box coordinates"), app_ref, true ); corner2->set( -0.5, -0.5, -0.5 ); } Box::Box( Box & ref ) : Object3D_with_material( ref ) { location = new ObjParam_point( *ref.location ); size = new ObjParam_scale( *ref.size ); rotation = new ObjParam_rotation( *ref.rotation ); corner1 = new ObjParam_point( *ref.corner1 ); corner2 = new ObjParam_point( *ref.corner2 ); } //************************************** // Destructor //************************************** Box::~Box() { delete location; delete size; delete rotation; delete corner1; delete corner2; } //************************************** // Display - virtual function from Object3D // // OpenGL calls to draw the box in the preview panels //************************************** void Box::display( glview *view, bool set_col ) { // If the user doesn't wanna see the box, we don't draw it if ( hidden->value() ) return; // If one parameter has changed since last call we invalidate the OpenGL display list if ( location->changed() || size->changed() || rotation->changed() || corner1->changed() || corner2->changed() ) list.invalidate(); // Set General object parameters : color etc... Object3D::display( view ); if ( set_col ) set_color(); // Call the OpenGL display list or define it if set as invalid if ( ! list.exec() ) { // Set all parameters as unchanged location->unchange(); size->unchange(); rotation->unchange(); corner1->unchange(); corner2->unchange(); // Create the display list list.begin(); glPushMatrix(); // retrieve translation, scale and rotation parameters from TvWidgets // apply them to OpenGL transformation matrix gfloat x, y, z; gfloat a, b, c; location->get( x, y, z ); glTranslatef( x, y, z ); size->get( a, b, c ); glScalef( a, b, c ); rotation->gl_rotate(); // Retrieve box geometry, define vertices and draw quads corner1->get( a, b, c ); corner2->get( x, y, z ); gfloat vertex[24][3] = { {x,y,z}, {x,y,c}, {x,b,c}, {x,b,z}, {x,b,z}, {x,b,c}, {a,b,c}, {a,b,z}, {a,b,z}, {a,b,c}, {a,y,c}, {a,y,z}, {a,y,z}, {a,y,c}, {x,y,c}, {x,y,z}, {x,y,z}, {x,b,z}, {a,b,z}, {a,y,z}, {a,b,c}, {x,b,c}, {x,y,c}, {a,y,c} }; gfloat normal[6][3] = { {-1,0,0}, {0,1,0}, {1,0,0}, {0,-1,0}, {0,0,-1}, {0,0,1} }; register int i,j; glBegin( GL_QUADS ); for ( i = 0; i < 6 ; i++ ) { glNormal3f( normal[i][0], normal[i][1], normal[i][2] ); j = i*4; glVertex3f( vertex[j][0], vertex[j][1], vertex[j][2] ); j++; glVertex3f( vertex[j][0], vertex[j][1], vertex[j][2] ); j++; glVertex3f( vertex[j][0], vertex[j][1], vertex[j][2] ); j++; glVertex3f( vertex[j][0], vertex[j][1], vertex[j][2] ); } // End of OpenGL calls and end of display list glEnd(); glPopMatrix(); list.end(); } } //*********************************************** // Edit Widget - virtual function from Object3D // // Display box parameters in the propertiy panel // when object is selected //*********************************************** void Box::edit_widget( GtkWidget *wid ) { // Check if we should display tooltips for TvWidgets PREF_DEF bool tt = pref->tooltips->value(); // General options defined in Object3D.cc Object3D::edit_widget( wid ); // Geometry options new_table( edit_cont, N_("Geometry"), 2 ); corner1->get_widget( table, tt, 1 ); corner2->get_widget( table, tt, 2 ); // Transformation new_table( edit_cont, N_("Transformation"), 3 ); location->get_widget( table, tt, 1 ); size->get_widget( table, tt, 2 ); rotation->get_widget( table, tt, 3 ); // Material & photon definitions from Object3D_with_material ( in Object3D.cc ) get_texture_widgets( edit_cont, tt ); // Show all this gtk_widget_show_all( wid ); } //*********************************************** // Destroy editor - virtual from Object3D // // Destroy the parameter editor from property panel // when object is deselected //*********************************************** void Box::destroy_editor() { Object3D::destroy_editor(); location->clear_widget(); size->clear_widget(); texture->clear_widget(); rotation->clear_widget(); corner1->clear_widget(); corner2->clear_widget(); } //*********************************************** // Mouse drag - virtual function from Object3D // // Callback for mouse interactions on preview panels //*********************************************** void Box::mouse_drag( struct drag_info *drag ) { VMAN_DEF OBJLIST_DEF switch( vmanager->get_pointer_mode() ) { case TV_PMODE_SELECT: case TV_PMODE_TRANSLATE: { location->mouse_drag( drag ); break; } case TV_PMODE_SCALE: { size->mouse_drag( drag ); break; } case TV_PMODE_ROTATE: { rotation->mouse_drag( drag ); break; } case TV_PMODE_CUSTOM: { ((ObjParam_point*)(objlist->get_current_param()))->mouse_drag( drag ); break; } default: break; } } //*********************************************** // Pref_changed - virtual function from Object3D // // Callback for Preferences change signal //*********************************************** void Box::pref_changed() { Object3D::pref_changed(); location->pref_changed(); size->pref_changed(); rotation->pref_changed(); corner1->pref_changed(); corner2->pref_changed(); } //*********************************************** // Output to povray - virtual function from Object3D // // Output code for povray // pass1 -> declare object // pass 2 -> use object //*********************************************** void Box::output_to_povray_pass1( ofstream & file ) { // Header file << "\n\n// Box : " << name->value(); file << "\n#declare "; get_underscore_name( file ); file << " ="; file << "\nbox {\n\t"; // Geometry float a, b, c, x, y, z; corner1->get( a, b, c ); corner2->get( x, y, z ); file << '<' << a << ',' << b << ',' << -c << ">,\n\t<" << x << ',' << y << ',' << -z << ">\n\t"; // Material Object3D_with_material::output_to_povray_pass1( file ); file << "\t"; // Transformation rotation->output_to_povray( file ); size->get( x, y, z ); file << "\n\tscale <" << x << ',' << y << ',' << z << ">"; location->get( x, y, z ); file << "\n\ttranslate <" << x << "," << y << "," << -z << ">"; file << "\n} "; } //*********************************************** // Save - virtual from Object3D // // Save the object to a truevision scene or truevision // object file //*********************************************** void Box::save( ofstream & file ) { file << "\nBOX{\n"; save_basics( file ); corner1->save( file ); corner2->save( file ); location->save( file ); size->save( file ); rotation->save( file ); texture->save( file ); file << "\n}"; } //*********************************************** // Load - virtual from Object3D // // Load the object from a truevision scene or truevision // object file //*********************************************** bool Box::load( ifstream & file, char *ltag ) { if ( strcmp( ltag, "BOX" ) ) return false; set_load_progress( file ); char * tag = NULL; do { tag = tvio_get_next_tag( file ); if ( tag == NULL ) break; if ( load_basics( file, tag ) ) continue; if ( location->load( file, tag ) ) continue; if ( size->load( file, tag ) ) continue; if ( rotation->load( file, tag ) ) continue; if ( corner1->load( file, tag ) ) continue; if ( corner2->load( file, tag ) ) continue; tvio_skip_section(file ); } while ( tag != NULL ); return true; }