00001 00002 /* 00003 TEDDY - General graphics application library 00004 Copyright (C) 1999-2002 Timo Suoranta 00005 tksuoran@cc.helsinki.fi 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Lesser General Public 00009 License as published by the Free Software Foundation; either 00010 version 2.1 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public 00018 License along with this library; if not, write to the Free Software 00019 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 00021 $Id: LWSceneObject.cpp,v 1.1 2002/02/16 12:41:39 tksuoran Exp $ 00022 */ 00023 00024 00025 #include "Teddy/TeddyConfig.h" 00026 #if defined( TEDDY_INCLUDE_LW_SCENE ) 00027 00028 00029 #include "Teddy/Imports/LWBone.h" 00030 #include "Teddy/Imports/LWCamera.h" 00031 #include "Teddy/Imports/LWChannelEnvelope.h" 00032 #include "Teddy/Imports/LWChannelKey.h" 00033 #include "Teddy/Imports/LWInstance.h" 00034 #include "Teddy/Imports/LWLight.h" 00035 #include "Teddy/Imports/LWModel.h" 00036 #include "Teddy/Imports/LWMotion.h" 00037 #include "Teddy/Imports/LWSceneFile.h" 00038 #include "Teddy/Imports/LWSceneParser.h" 00039 #include "Teddy/SysSupport/Messages.h" 00040 using namespace Teddy::SysSupport; 00041 00042 00043 namespace Teddy { 00044 namespace Imports { 00045 00046 00047 /* 00048 LoadObject <object path + filename> (Alternative: AddNullObject) 00049 00050 example: LoadObject Objects/Tutorial/LightBeam.lwo 00051 00052 The LoadObject function is the first listing in all 00053 Object Segments. It provides LightWave with the path 00054 and filename for the object to be loaded. The object's 00055 path is generated by adding the current content directory 00056 to the beginning of the given path and filename. 00057 00058 In this example if the current content directory were 00059 <c:/NewTek>, LightWave would attempt to load the file 00060 <c:/NewTek/Objects/Tutorial/LightBeam.lwo>. 00061 00062 It is possible to have duplicate objects in a scene 00063 file. When the LoadObject function is called, and 00064 the object name already exists, a numbered suffix is 00065 added to the duplicate object's name. This number is 00066 enclosed in parenthesis and follows the object name. 00067 00068 For example: LightBeam.lwo (2) is the second instance 00069 of the LightBeam.lwo object in the current scene file. 00070 00071 The added suffix is not saved in the scene file, and 00072 is used only as a user reference. 00073 00074 User Interface: 00075 00076 The LoadObject/AddNullObject listing is produced from 00077 the following functions on the Objects Panel; LoadObject, 00078 Load from Scene, and Add Null Object. 00079 00080 The LoadObject/AddNullObject function is listed with all objects. 00081 */ 00082 void LWSceneParser::LoadObjectLayer(){ 00083 int layer = file->read_int (); 00084 std::string model_name = file->read_string(); 00085 dmsg( M_LWS, "LoadObjectLayer %d %s", layer, model_name.c_str() ); 00086 00087 current_object = new LWInstance(); 00088 current_object->setModelName( model_name ); 00089 dmsg( M_LWS, "objects.insert( make_pair(%d,%s) ) ...", next_object, model_name.c_str() ); 00090 objects.insert( make_pair(next_object,current_object) ); 00091 dmsg( M_LWS, "objects.insert( make_pair(%d,%s) ) done", next_object, model_name.c_str() ); 00092 next_object++; 00093 } 00094 00095 00096 /* 00097 Alternative: AddNullObject NullObject 00098 00099 Alternative example: AddNullObject NullObject 00100 00101 The AddNullObject function will create a null object 00102 named "NullObject" in the current scene. NullObjects 00103 are treated as a normal object in the scene file. 00104 00105 User Interface: 00106 00107 The LoadObject/AddNullObject listing is produced from the 00108 following functions on the Objects Panel; LoadObject, 00109 Load from Scene, and Add Null Object. 00110 00111 The LoadObject/AddNullObject function is listed with all objects. 00112 */ 00113 void LWSceneParser::AddNullObject(){ 00114 char *null_object_name = file->read_string(); 00115 current_object = new LWInstance(); 00116 objects.insert( make_pair(next_object,current_object) ); 00117 next_object++; 00118 } 00119 00120 00121 void LWSceneParser::LoadObject(){} 00122 00123 00124 /* 00125 ShowObject nvisibility ncolor 00126 00127 Determines how the object is displayed in the interface. 00128 The visibility codes are 00129 00130 0 - hidden 00131 1 - bounding box 00132 2 - vertices only 00133 3 - wireframe 00134 4 - front face wireframe 00135 5 - shaded solid 00136 6 - textured shaded solid 00137 00138 The color used to draw bounding boxes, vertices and wireframes 00139 can be one of the following. 00140 00141 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 00142 00143 The default visibility and color are stored in the config file. 00144 If they haven't been altered by the user, they are textured 00145 shaded solid (6) and cyan (3) in LightWave 6.5. 00146 */ 00147 void LWSceneParser::ShowObject(){ 00148 current_object->setVisibility( file->read_int() ); 00149 current_object->setColor ( file->read_int() ); 00150 } 00151 00152 00153 /* 00154 ObjDissolve <percentage> ¦ (envelope) 00155 00156 example: ObjDissolve 0.500000 00157 00158 The ObjDissolve function determines the object's 00159 dissolve level during the rendering process. The 00160 example would produce an object that is 50% dissolved 00161 throughout the animation. The value is listed as a 00162 percentage out to six decimal places. If the value is 00163 left at the default of 0% dissolved, the function does 00164 not provide a listing in the scene file. The value of 00165 this function can be changed over time with an envelope. 00166 If an envelope is selected, the functions value is 00167 replaced with an envelope identifier. For more information 00168 on envelopes, see the Envelopes Section 1.4. 00169 00170 User Interface: 00171 00172 The ObjDissolve function is set from the Objects Panel. 00173 */ 00174 void LWSceneParser::ObjectDissolve(){ 00175 double object_dissolve = file->read_double(); 00176 } 00177 00178 00179 void LWSceneParser::SubdivisionOrder(){ 00180 int subdivision_order = file->read_int(); 00181 } 00182 00183 00184 void LWSceneParser::SubPatchLevel(){ 00185 int a = file->read_int(); 00186 int b = file->read_int(); 00187 } 00188 00189 00190 /* 00191 ShadowOptions <bit-field value> 00192 00193 example: ShadowOptions 7 00194 00195 The ShadowOptions function provides the shadowing 00196 characteristics for the current object. 00197 00198 The bit-field value is produced by calculating the 00199 decimal value of a 3 position bit-field whose bits 00200 represent logical on/off switches that are number 00201 left to right from 0 to 2. The least-significant bit 00202 for this field is the rightmost bit. Each shadow option 00203 has a corresponding bit in the bit-field. When a 00204 shadow option is turned on, its bit (or switch) 00205 is turned on. 00206 00207 <bit position>: 00208 0 - Self Shadow 00209 1 - Cast Shadow 00210 2 - Receive Shadow 00211 00212 The ShadowOptions function produces a listing for all objects. 00213 00214 User Interface: 00215 00216 The shadow options function is set from 00217 the bottom of the Objects Panel. 00218 */ 00219 void LWSceneParser::ShadowOptions(){ 00220 int shadow_options = file->read_int(); 00221 } 00222 00223 00224 /* 00225 DistanceDissolve <flag> 00226 00227 example: DistanceDissolve 1 00228 00229 The DistanceDissolve flag turns the distance dissolve 00230 function on and off. This function produces a 00231 DistanceDissolve listing with a value of 1 and 00232 adds the MaxDissolveDistance listing (see below) 00233 when turned on. When turned off, this function does 00234 not provide a listing in the scene file. 00235 00236 <flag>: 00237 0 - Off (No Listing) 00238 1 - On (Function listing plus additional MaxDissolveDistance listing) 00239 */ 00240 void LWSceneParser::DistanceDissolve(){ 00241 int distance_dissolve = file->read_int(); 00242 } 00243 00244 00245 /* 00246 Additional: MaxDissolveDistance <distance> 00247 00248 example: MaxDissolveDistance 25.000000 00249 00250 The MaxDissolveDistance function provides the distance 00251 from the camera that the object will be %100 dissolved. 00252 In the example shown, the object will be completely 00253 dissolved at 25 meters. 00254 00255 User Interface: 00256 00257 The DistanceDissolve functions are set from the 00258 Objects Panel. 00259 */ 00260 void LWSceneParser::MaxDissolveDistance(){ 00261 double max_distance_dissolve = file->read_double(); 00262 } 00263 00264 00265 /* 00266 PolygonSize <percentage> ¦ (envelope) 00267 00268 example: PolygonSize 0.350000 00269 00270 The PolygonSize function provides a value that adjusts 00271 the polygon size of all polygons in the current object. 00272 The example would produce an object with all polygons 00273 35% of their original size. If the value is left at the 00274 default 100%, this function does not provide a listing in 00275 the scene file. The value of this function can be changed 00276 over time with an envelope. If an envelope is selected, 00277 the functions value is replaced with an envelope identifier. 00278 For more information on envelopes, see the Envelopes 00279 Section 1.4. 00280 00281 User Interface: 00282 00283 The PolygonSize function is set from the Objects Panel. 00284 */ 00285 void LWSceneParser::PolygonSize(){ 00286 double polygon_size = file->read_double(); 00287 } 00288 00289 00290 /* 00291 Particle/LineSize <value> 00292 00293 example: Particle/LineSize 1 00294 00295 The Particle/LineSize function determines the size 00296 of a one and two point polygons when rendered. 00297 00298 If the value is left at the default of Automatic, no 00299 function listing is produced in the scene file. 00300 00301 <value>: 00302 0 - Automatic (No function listing) 00303 1- Small 00304 2 - Medium 00305 3 - Large 00306 00307 User Interface: 00308 00309 The Particle/LineSize function is set from the 00310 Particle/Line Size pop-up panel on the Objects Panel. 00311 */ 00312 void LWSceneParser::ParticleSize(){ 00313 double size = file->read_double(); 00314 } 00315 void LWSceneParser::LineSize(){ 00316 double size = file->read_double(); 00317 } 00318 00319 00320 void LWSceneParser::UnseenByRays(){ 00321 int unseen_by_rays = file->read_int(); 00322 } 00323 00324 00325 void LWSceneParser::UnseenByCamera(){ 00326 int unseen_by_camera = file->read_int(); 00327 } 00328 00329 00330 /* 00331 UnaffectedByFog <flag> 00332 00333 example: UnaffectedByFog 1 00334 00335 The UnaffectedByFog flag activates the Unaffected by 00336 Fog function that will allow the current object to 00337 render normally when fog is turned on. This function 00338 produces a UnaffectedByFog listing with a value of 1 00339 when turned on. When turned off, this function does 00340 not produce a listing in the scene file. 00341 00342 <flag>: 00343 0 - Off (No function listing) 00344 1 - On 00345 00346 User Interface: 00347 00348 The UnaffectedByFog function is set from the Objects Panel. 00349 */ 00350 void LWSceneParser::UnaffectedByFog(){ 00351 int unaffected_by_fog = file->read_int(); 00352 } 00353 00354 00355 void LWSceneParser::AffectedByFog(){ 00356 int affected_by_fog = file->read_int(); 00357 } 00358 00359 00360 void LWSceneParser::ExcludeLight(){ 00361 int exclude_light = file->read_int(); 00362 } 00363 00364 00365 /* 00366 ObjPolygonEdges <flag> 00367 00368 example: ObjPolygonEdges 1 00369 00370 The ObjPolygonEdges flag activates the Polygon Edges 00371 function that renders all polygons with a visible 00372 outline. This function produces a ObjPolygonEdges 00373 listing with a value of 1 and adds an ObjEdgeColor 00374 listing (see below) when turned on. When turned off, 00375 this function does not produce a listing in the scene file. 00376 00377 <flag>: 00378 0 - Off (No function listing) 00379 1 - On (Function listing plus additional listing) 00380 */ 00381 void LWSceneParser::ObjPolygonEdges(){ 00382 int obj_polygon_edges = file->read_int(); 00383 } 00384 00385 00386 /* 00387 Additional: ObjEdgeColor <red value> <green value> <blue value> 00388 00389 example: ObjEdgeColor 0 0 255 00390 00391 The ObjEgdeColor function provides the RGB color 00392 values for the object's polygon edges. 00393 00394 <color value range>: 00395 red value - 0 - 255 00396 green value - 0 - 255 00397 blue value - 0 - 255 00398 00399 User Interface: 00400 00401 The ObjPolygonEdges functions are set from the 00402 Objects Panel. 00403 */ 00404 void LWSceneParser::ObjEdgeColor(){ 00405 double red = file->read_double(); 00406 double green = file->read_double(); 00407 double blue = file->read_double(); 00408 } 00409 00410 00411 void LWSceneParser::PolygonEdgeFlags(){ 00412 int polygon_edge_flags = file->read_int(); 00413 } 00414 00415 00416 void LWSceneParser::PolygonEdgeThickness(){ 00417 double polygon_edge_thickness = file->read_double(); 00418 } 00419 00420 00421 void LWSceneParser::PolygonEdgesZScale(){ 00422 double polygon_edges_z_scale = file->read_double(); 00423 } 00424 00425 00426 void LWSceneParser::EdgeNominalDistance(){ 00427 double edge_nominal_distance = file->read_double(); 00428 } 00429 00430 00431 // for lights and cameras too 00432 00433 00434 /* 00435 PivotPoint <x position> <y position> <z position> 00436 00437 example: PivotPoint 0 16.9 -11.6 00438 00439 The PivotPoint function provides the x, y, and z 00440 positions for the pivot point of the object. This 00441 determines the center of rotation for the current 00442 object. The position values are given as a distance 00443 (meters) of offset from the original object center. 00444 00445 User Interface: 00446 00447 The PivotPoint values are set from the Move Pivot Point 00448 mouse function in Layout. 00449 */ 00450 void LWSceneParser::PivotPosition(){ 00451 double x = file->read_double(); 00452 double y = file->read_double(); 00453 double z = file->read_double(); 00454 00455 //z = -z; 00456 00457 if( current_object != NULL ){ 00458 current_object->setPivotPosition( Vector(x,y,z) ); 00459 }else{ 00460 emsg( M_LWS, "No current object for pivot point" ); 00461 } 00462 } 00463 00464 00465 /* 00466 When a scene file needs to refer to specific items to establish item 00467 relationships (parenting, for example), it uses item numbers. Items 00468 are numbered in the order in which they appear in the file, starting 00469 with 0. 00470 00471 Item numbers can be written in one of two ways, depending on which 00472 keyword they're used with. In general, if the type of the item 00473 (object, bone, light, camera) can be determined from the keyword 00474 alone, the item number will simply be the ordinal, written as a 00475 decimal integer. When the keyword can be used with items of more 00476 than one type, the item number is an unsigned integer written as 00477 an 8-digit hexadecimal string, the format produced by the C-language 00478 "%8X" print format specifier, and the high bits identify the item type. 00479 00480 The first hex digit (most significant 4 bits) of the hex item number 00481 string identifies the item type. 00482 00483 1 - Object 00484 2 - Light 00485 3 - Camera 00486 4 - Bone 00487 00488 The other digits make up the item number, except in the case of 00489 bones. For bones, the next 3 digits (bits 16-27) are the bone 00490 number and the last 4 digits (bits 0-15) are the object number 00491 for the object the bone belongs to. Some examples: 00492 00493 10000000 - the first object 00494 20000000 - the first light 00495 4024000A - the 37th bone (24 hex) in the 11th object (0A hex) 00496 */ 00497 void LWSceneParser::ParentItem(){ 00498 unsigned long all_bits = file->read_hex_int(); 00499 00500 if( current_object != NULL ){ 00501 current_object->setParentObjectId( all_bits ); 00502 }else{ 00503 emsg( M_LWS, "Current object for ParentItem not found" ); 00504 } 00505 } 00506 00507 00508 /* 00509 ObjectMotion 00510 NumChannels nchannels 00511 Channel nindex 00512 { Envelope ... 00513 00514 The ObjectMotion keyword signals the start of the motion 00515 information for the object. Motions are stored in envelopes, 00516 one for each motion channel. There are 9 standard channels, 00517 numbered from 0 to 8. 00518 00519 0, 1, 2 - (x, y, z) position 00520 3, 4, 5 - (heading, pitch, bank) rotation 00521 6, 7, 8 - (sx, sy, sz) scale factors along each axis 00522 00523 The values of all of these are relative to the object's parent, 00524 if it has one. 00525 */ 00526 void LWSceneParser::ObjectMotion(){ 00527 current_motion = new LWMotion(); 00528 current_object->setMotion( current_motion ); 00529 } 00530 void LWSceneParser::NumChannels(){ 00531 num_channels = file->read_int(); 00532 } 00533 void LWSceneParser::Channel(){ 00534 int channel_id = file->read_int(); 00535 current_channel_envelope = new LWChannelEnvelope( channel_id ); 00536 current_motion->insert( current_channel_envelope ); 00537 file->read_begin_scope(); 00538 } 00539 void LWSceneParser::Envelope(){ 00540 num_channel_keys = file->read_int(); 00541 } 00542 void LWSceneParser::Key(){ 00543 double value = file->read_double(); 00544 double time = file->read_double(); 00545 int spantype = file->read_int(); 00546 double p1 = file->read_double(); 00547 double p2 = file->read_double(); 00548 double p3 = file->read_double(); 00549 double p4 = file->read_double(); 00550 double p5 = file->read_double(); 00551 double p6 = file->read_double(); 00552 00553 /*if( current_channel_envelope->getChannelId() == LW_CHANNEL_Z ){ 00554 value = -value; 00555 }*/ 00556 00557 LWChannelKey *channel_key = new LWChannelKey( 00558 value, 00559 time, 00560 spantype, 00561 p1, 00562 p2, 00563 p3, 00564 p4, 00565 p5, 00566 p6 00567 ); 00568 current_channel_envelope->insert( channel_key ); 00569 } 00570 void LWSceneParser::Behaviors(){ 00571 int pre = file->read_int(); 00572 int post = file->read_int(); 00573 current_channel_envelope->setBehaviors( pre, post ); 00574 file->read_end_scope(); 00575 } 00576 00577 00578 /* 00579 LockedChannels <bit-field value> 00580 00581 example: LockedChannels 4093 00582 00583 The LockedChannels function determines the extent of the mouse control 00584 from LightWave's Layout. Separate independent channels of motion, 00585 rotation, etc. can be locked off to restrict the mouse's control on 00586 the current object. The mouse functions that it can effect are: 00587 Move (X,Y,Z), Rotate(H,P,B), Scale/Stretch(X,Y,Z), and MovePivotPoint(X,Y,Z). 00588 00589 The bit-field value is produced by calculating the decimal value of a 00590 12 position bit-field whose bits represent logical on/off switches that 00591 are number left to right from 0 - 11. The least-significant bit for 00592 this field is the rightmost bit. Each channel has a corresponding bit 00593 in the bit-field. When a channel is locked, its bit (or switch) is 00594 turned on. 00595 00596 <bit positions>: 0 - Move X 00597 1 - Move Y 00598 2 - Move Z 00599 3 - Rotate Heading 00600 4 - Rotate Pitch 00601 5 - Rotate Bank 00602 6 - Scale X / Size X (channels are connected) 00603 7 - Scale Y / Size Y (channels are connected) 00604 8 - Scale Z / Size Z (channels are connected) 00605 9 - MovePivotPoint X 00606 10 - Move Pivot Point Y 00607 11 - Move Pivot Point Z 00608 00609 User Interface: 00610 00611 The LockedChannels function is set from the Layout mouse 00612 control area. 00613 */ 00614 void LWSceneParser::LockedChannels(){ 00615 int locked_channels = file->read_int(); 00616 } 00617 00618 00619 /* 00620 ParentObject <object instance> 00621 00622 example: ParentObject 4 00623 00624 The ParentObject function provides LightWave with the 00625 current object's parent object in the hierarchical chain. 00626 The value is equal to the parent objects position in the 00627 loading sequence. The example function would parent the 00628 current object to the fourth object instance in the scen 00629 file. When the ParentObject function is active, all keyframe 00630 information for the object becomes an offset from the 00631 parents information. 00632 00633 User Interface: 00634 00635 Objects hierarchies are created by selecting the parent 00636 function from layout. The parent object is then selected 00637 from the pop-up listing provided. 00638 */ 00639 void LWSceneParser::ParentObject(){ 00640 LWInstance *parent_object = NULL; 00641 int parent_object_id = file->read_int(); 00642 00643 int_to_LWInstance::iterator i_it = objects.find( parent_object_id ); 00644 if( i_it != objects.end() ){ 00645 parent_object = (*i_it).second; 00646 } 00647 if( current_object != NULL ){ 00648 current_object->setParentObject( parent_object ); 00649 } 00650 } 00651 00652 00653 void LWSceneParser::TargetObject(){ 00654 int target_object = file->read_int(); 00655 } 00656 00657 00658 /* 00659 GoalObject <object instance> 00660 00661 example: GoalObject 5 00662 00663 The GoalObject function provides LightWave with the current 00664 bone's goal object for an inverse kinematics chain. The 00665 value is equal to the goal object position in the loading 00666 sequence. The example function would goal the current bone 00667 to the fifth object instance in the scene file. 00668 00669 User Interface: 00670 00671 The GoalObject function is set from the IK options from 00672 Layout. 00673 */ 00674 void LWSceneParser::GoalObject(){ 00675 int goal_object = file->read_int(); 00676 } 00677 00678 00679 void LWSceneParser::SchematicPosition(){} 00680 00681 00682 }; // namespace Imports 00683 }; // namespace Teddy 00684 00685 00686 #endif // TEDDY_INCLUDE_LW_SCENE 00687