/* COPYRIGHT: (c) since 2009 Kene Meniru (GNU GPL V2.0) Free Software and OSI certified Open Source Software You may view the full copyright text at: http://opensource.org/licenses/gpl-license.php This file contains the collection of POV-Ray Macros called KoBl DT. KoBl DT 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. KoBl DT 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 KoBl DT; if not, write to the Free Software Foundation, inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # File last modified on *date_ */ /*||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -------------------------- Inclusions ----------------------------- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| These general included files are for tests only. The plan is to make most if not all of the needed definitions available inline to reduce the use of resources. As a result, inclusions have been disabled.*/ //#include "colors.inc" //#include "textures.inc" //#include "stones.inc" //#include "glass.inc" //#include "metals.inc" // /* --- We need the location of the floor surface. This is the surface of the floor on which the walls will rest on. This does not describe the surface of the stairs. The default is 0 if the user does not provide a value --- Default color for all objects if there is no color declaration. The value is from the colors.inc file */ /*+++++++++++++++ Fundamental declarations ++++++++++++++*/ #ifndef( Floor_Surface ) #declare Floor_Surface = 0; #end // #default{ pigment { color red 0.196078 green 0.8 blue 0.196078 }} // /*||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ------------------------ Sun and lighting --------------------------- |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/ /*- Creation of a basic sun and good lighting for scene production --- Creation of a realistic sun for final render --- Creation for different types of lighting (area light, etc) --- Creation of lighting for interior rendering especially for radiosty */ /*||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ------------------------------ Cameras ---------------------------- |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/ /*It should be possible to do the following with a camera and lightsource - Normal creation with regular lens (with adjustments to location look at, etc) - Addition of a different type of lens (wide angle for example) - Creation with an object as the focus. Then with adjustments to camera to view parts of that object */ /*||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -------------------------- landscape -------------------------------- |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/ // ability to accurately create the building site and ability to place the finished model on it /*||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ------------------ General Object Variables ------------------------- |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/ /*Component_ArraySize is the total number of arrays for each object that can be created in KoBlDT. Changing this increases the capacity to save save objects that are manipulated in KoBlDT --- Component_Index initiates the indeces for the items saved in the arrays. This number is incremented by KoBlDT in order to add more objects as they are saved --- Each of the following arrays provide containers for objects and thier properties. Each stored item can be accessed by identifying their assigned Component_index. Each array can hold a number of objects or properties that is equal to Component_ArraySize --- Component_Objects: holds all the different objects created such as walls, doors, etc --- Component_Objects_Loc: holds the vector values that designate the location of an object. KoBlDT stores 4 of these vector sets A. Original location (position at which the object was created, typically at 0,0,0) 1. Point1 (or start point) 2. Point2 (or end point) B. Final location 3. Point1 (or start point) 4. Point2 (or end point) --- Component_Objects_Rad: holds the radius of curved objects --- Component_Objects_Id: holds the unique id information for each object 1. Name of the object. This is a unique string that can be used to identify the object in the scene file 2. Name of the any reference for this object --- Component_Object_Type: holds the type of object being saved. KoBlDT can support the following type of objects Primitive Components: Box, Cylinder, Sphere, (Torus and Text) Architectural Components: Space, Level, Floor, Wall, (Door, Window, Stair, (Roof)) --- Component_Object_Rot: holds the rotations that should be applied to the object 1. Rotation angle for the object 2. Rotation angle of the reference for this object (not sure why this is designated */ /*+++++++++++++++ Setting variables for capturing objects +++++++++++++++*/ #declare Component_ArraySize = 2000; #declare Component_Index = -1; #declare Component_Objects = array[ Component_ArraySize ]; // KoBlDT objects #declare Component_Objects_Loc = array[ Component_ArraySize ][4]; // Initial Locations. point1,point2 #declare Component_Objects_Rad = array[ Component_ArraySize ]; // Radii #declare Component_Objects_Id = array[ Component_ArraySize ][2]; // Id. Need to add ref, and level #declare Component_Objects_Type = array[ Component_ArraySize ]; // Type #declare Component_Objects_Rot = array[ Component_ArraySize ][2]; // Rotation angle // /*This macro saves the object sent to it. It requires the following parameters in sequence 1. Name: This is the Component_object_Id 2. Type: This is the Component_Object_Type 3. Obj: This is the Component_Object 4. Start: This is the x, y, z of the start point for the Component_Object_Loc 5. End: This is the x, y, z of the end point for the Component_Object_Loc 6. Radius: This is the length of the radius for curved Component_objects 7. Rotation: This is a rotation angle for the object. The default is 0 degrees on Z axis To save an object: --- Increase Component_Index value. The index for the arrays --- Save the object in the Component_Object array --- Save the starting point in the Component_Object_Loc array --- Save the ending point in the Component_Object_Loc array --- Save the rotation angle for the object --- If this is a cylinder or a cone, save the radius in the Component_Object_Radius array --- Save the object identity name in the Component_Objects_Id array --- Save the object type in the Component_Objects_Type array */ /*++++++++++++++++++++ Capturing Objects +++++++++++++++++++*/ #macro Save_Object( Name, Type, Obj, Start, End, Radius, Rotation ) #declare Component_Index = Component_Index+1; #declare Component_Objects[ Component_Index ] = Obj; #declare Component_Objects_Loc[ Component_Index ][0] = Start; #declare Component_Objects_Loc[ Component_Index ][1] = End; #declare Component_Objects_Rot[ Component_Index ][0] = Rotation; #if( strcmp( Type,"Cylinder" )=0 | strcmp( Type,"Cone" )=0 ) #declare Component_Objects_Rad[ Component_Index ] = Radius; #end #declare Component_Objects_Id[ Component_Index ][0] = Name; #declare Component_Objects_Type[ Component_Index ] = Type; #end // /*This macro recalls a saved cylinder and puts it in the scene at the correct location provided. It requires the following parameters in sequence 1. Name: Unique identifier for the cylinder 2. XPos: New x vector position to move the cylinder 3. YPos: New y vector position to move the cylinder 4. ZPos: New z vector position to move the cylinder To position an object in the scene: --- Set up a counter and increment it by one until we get the type and index for the object to put --- Using the object type, determine which object we are dealing with --- Get the current location and add the provided values to move them to the desired location --- Save these new values as final locations in Component_Objects_Loc */ /*+++++++++++++++ Putting an object ++++++++++++++++*/ #macro Put( Name, XPos, YPos, ZPos ) #local Count = 0; #while( Count <= Component_Index ) #if( strcmp( Component_Objects_Id[ Count ][0], Name )=0 ) //#debug concat( "In If: ", Component_Objects_Id[ Count ][0],"\n" ) // DEBUG MSG #local Obj_Type = Component_Objects_Type[ Count ]; #local Obj_Index = Count; #local Count = Component_Index; // end loop immediately #end #local Count = Count + 1; #end #if( strcmp( "Cylinder", Obj_Type )=0 ) #local Old_Start = Component_Objects_Loc[ Obj_Index ][0]; #local Old_EndY = Component_Objects_Loc[ Obj_Index ][1].y; /*+++ Start computing put position +++*/ #local New_Start = < Old_Start.x + XPos, Old_Start.y + YPos, Old_Start.z + ZPos >; #local New_End = < Old_Start.x + XPos, Old_EndY, Old_Start.z + ZPos >; #declare Component_Objects_Loc[ Obj_Index ][2] = New_Start; // save new start coordinates #declare Component_Objects_Loc[ Obj_Index ][3] = New_End; // save new end coordinates #end #if( strcmp( "Box", Obj_Type )=0 ) #local Old_LL = Component_Objects_Loc[ Obj_Index ][0]; #local Old_UR = Component_Objects_Loc[ Obj_Index ][1]; /*+++ Start computing put position +++*/ #local New_LL = < Old_LL.x + XPos, Old_LL.y + YPos, Old_LL.z + ZPos >; #local New_UR = < New_LL.x + Old_UR.x, New_LL.y + Old_UR.y, New_LL.z + Old_UR.z >; #declare Component_Objects_Loc[ Obj_Index ][2] = New_LL; // save new start coordinates #declare Component_Objects_Loc[ Obj_Index ][3] = New_UR; // save new end coordinates #end //#else //#debug concat( "In Else: ", Component_Objects_Id[ Obj_Index ][0],"\n" ) // DEBUG MSG #end // /*This macro places a cylinder at a position relative to another object. It requires the following parameters in sequence 1. Name: Unique identifier for the cylinder to be moved 2. Ref: Unique identifier for the relative object 3. XPos, YPos, ZPos: x,y,z distance from the relative object To offset an object relative to another: --- Get indices for the object and the relative object --- Also get the relative object's type (so we can know how to access the location information) --- Get current position of the relative object and the height of the cylinder to be moved --- Get the rotation angle --- Add the provided values to the location of the relative object to get the new position for object --- Move the object by adding the distance(s) to be moved to the current position of the reference object --- Save the new location, the string id and rotation angle of the relative object. Not sure why am saving the rotation angle */ /*+++++++++++++++ Putting a Cylinder with reference ++++++++++++++++*/ #macro Offset( Name, Ref, XPos, YPos, ZPos ) #local Count = 0; // loop to find the object and relative object indices #while ( Count <= Component_Index ) #if( strcmp( Component_Objects_Id[ Count ][0], Name )=0 ) //get index for object #local Obj_Index = Count; //#debug concat( "In Name If: ", Component_Objects_Id[ Count ][0],"\n" ) // DEBUG MSG #end #if( strcmp( Component_Objects_Id[ Count ][0], Ref )=0 ) //get index for reference #local Ref_Index = Count; #local Ref_Type = Component_Objects_Type[ Ref_Index ]; // get relative object type #local Obj_Type = Component_Objects_Type[ Ref_Index ]; // get object type #end #local Count = Count + 1; #end // determine the type of relative object and get its current location #if( strcmp( "Box", Ref_Type )=0 ) #ifdef( Component_Objects_Loc[ Ref_Index ][2] ) // if cylinder has been moved #local Ref_Pos = Component_Objects_Loc[ Ref_Index ][2]; #else // otherwise use original position #local Ref_Pos = Component_Objects_Loc[ Ref_Index ][0]; #end #end #if( strcmp( "Cylinder", Ref_Type )=0 ) #ifdef( Component_Objects_Loc[ Ref_Index ][2] ) // if cylinder has been moved #local Ref_Pos = Component_Objects_Loc[ Ref_Index ][2]; #else // otherwise use original position #local Ref_Pos = Component_Objects_Loc[ Ref_Index ][0]; #end #end // get the rotation for the relative object #local Ref_Rotation = Component_Objects_Rot[ Ref_Index ][0]; // Get relavant information for a cylinder #if( strcmp( "Cylinder", Obj_Type )=0 ) #ifdef( Component_Objects_Loc[ Obj_Index ][2] ) // if cylinder has been moved #local Obj_Height = Component_Objects_Loc[ Obj_Index ][3].y; #else // otherwise use original position #local Obj_Height = Component_Objects_Loc[ Obj_Index ][1].y; #end //Move the object relative the reference #local New_Pos = < Ref_Pos.x, Ref_Pos.y, Ref_Pos.z > + < XPos, YPos, ZPos >; //#local New_Start = Obj_Pos; #local New_End = < New_Pos.x, Obj_Height, New_Pos.z >; #declare Component_Objects_Loc[ Obj_Index ][2] = New_Pos; // save new start coordinates #declare Component_Objects_Loc[ Obj_Index ][3] = New_End; // save new end coordinates #declare Component_Objects_Id[ Obj_Index ][1] = Ref; // save reference #declare Component_Objects_Rot[ Obj_Index ][1] = Ref_Rotation; #end // Get relavant information for a box #if( strcmp( "Box", Obj_Type )=0 ) #ifdef( Component_Objects_Loc[ Obj_Index ][2] ) // if box has been moved #local Old_UR = Component_Objects_Loc[ Obj_Index ][3]; #else #local Old_UR = Component_Objects_Loc[ Obj_Index ][1]; // otherwise use original position #end #local New_LL = < Ref_Pos.x, Ref_Pos.y, Ref_Pos.z > + < XPos, YPos, ZPos >; #local New_UR = < New_LL.x + Old_UR.x, New_LL.y + Old_UR.y, New_LL.z + Old_UR.z, >; #declare Component_Objects_Loc[ Obj_Index ][2] = New_LL; // save new start coordinates #declare Component_Objects_Loc[ Obj_Index ][3] = New_UR; // save new end coordinates #declare Component_Objects_Id[ Obj_Index ][1] = Ref; // save reference #declare Component_Objects_Rot[ Obj_Index ][1] = Ref_Rotation; #end #end // /*This macro rotates an object. It requires the following parameters in sequence 1. Name of object to be rotated 2. Rotation angle To rotate an object: --- Get index for the object --- Save the supplied rotation angle and axis */ /*+++++++++++++++ Rotating an object ++++++++++++++++*/ #macro Rotate( Name, Rotation ) #local Count = 0; #while( Count <= Component_Index ) #if( strcmp( Component_Objects_Id[ Count ][0], Name )=0 ) //get index for object #declare Component_Objects_Rot[ Count ][0] = transform{ rotate Rotation }; #local Count = Component_Index; // end the loop immediately // #end #local Count = Count + 1; #end #end // /*This macro provides the POV-Ray code of an object to be rendered. It requires the name of the object from Component_Objects_Id To show an object: --- Use a counter to determine the index of the object --- use the index obtained to get the following information a. Object definition b. Original location of the object. Objects should be created in a position where they can be rotated predictably c. Rotation angle and axis for the object d. If the object has been moved, get its final location. --- Return the code for the object */ /*++++++++++++++++++ Show an object ++++++++++++++++++++*/ #macro Show( Name ) #local Count = 0; #while( Count <= Component_Index ) #if( strcmp( Component_Objects_Id[ Count ][0], Name )=0 ) //get index for object #local Object_To_Show = Component_Objects[ Count ]; #local Original_Pos = Component_Objects_Loc[ Count ][0]; #local Obj_Rotation = Component_Objects_Rot[ Count ][0]; // get rotation #ifdef( Component_Objects_Loc[ Count ][2] ) // if cylinder has been moved #local Final_Pos = Component_Objects_Loc[ Count ][2]; #else #local Final_Pos = Component_Objects_Loc[ Count ][0]; #end object { Object_To_Show translate Original_Pos // Go to original position transform{ Obj_Rotation } // apply any rotations translate Final_Pos // Got to final location } #local Count = Component_Index; // end the loop immediately #end #local Count = Count + 1; // increment to the next item in the array #end #end /*This macro creates a cylinder with its center at 0,0,0 and the base end resting on the Floor_Surface, the default of which is 0 but can be changed in the scene file. It requires the following parameters in sequence 1. Name: Unique identifier for the cylinder 2. Radius: Distance from the center of the cylinder to its cureved edge 3. Height: Distance from the flat base of the cylinder to the flat top --- The x vector for the base is placed on 0 --- The y vector is matched with the value of Floor_Surface. Which means that the base of the cylinder is placed on the floor surface when created --- The z vector is placed on 0 --- The x vector for the top is matched with the x for the base --- The y vector for the top is the y value plus the height of the cylinder. This means that the top of the cylinder is located above the base along the y axis --- The z vector for the top is matched with the z for the base --- The x,y,z of the base is combined in Base_Point --- The x,y,z of the top is combined in Cap_Point --- the cylinder is created and passed to Save_Object to be saved */ /*+++++++++++++++ Making a Cylinder ++++++++++++++++*/ #macro Make_Cylinder( Name, Radius, Height ) #local Base_PointX = 0; // x value at base of cylinder #local Base_PointY = Floor_Surface; // y value at base of cylinder #local Base_PointZ = 0; // z value at base of cylinder #local Cap_PointX = Base_PointX; // x value at top of cylinder #local Cap_PointY = Base_PointY + Height; // y value at top of cylinder #local Cap_PointZ = Base_PointZ; // z value at top of cylinder #local Component_Radius = Radius; // radius of cylinder #local Component_Rot = transform{ rotate 0*z }; // default rotation #local Base_Point = < Base_PointX, Base_PointY, Base_PointZ >; #local Cap_Point = < Cap_PointX, Cap_PointY, Cap_PointZ >; #local Component_Obj = cylinder{ Base_Point, Cap_Point, Component_Radius } Save_Object( Name, "Cylinder", Component_Obj, Base_Point, Cap_Point, Radius, Component_Rot ) #end // /*This macro creates a box with its lower left corner at <0,Floor_Surface,0> and the upper right corner at . It requires the following parameters in sequence 1. Name: Unique identifier 2. Length: Distance along the +Z axis 3. Width: Thickness of the box along +X axis 3. Height: Distance along the +Y axis starting from the floor surface To create a box (Note: the Lower Left and the Upper Right will be refered to as LL and UR) --- The LL x float for the base is placed on 0 --- The LL y float is matched with the value of Floor_Surface. Which means that the base of the box is placed on the floor surface when created --- The LL z float is placed on 0 --- The UR x float is the addition of the width and the LL x --- The UR y float is the addition of the LL y and the height of the box --- The UR z float is the addition of the LL z and the length of the box --- A zero rotation is added. This is the default for all objects --- The x,y,z of the LL and UR is defined --- The box is created with a dummy value for radius and passed to Save_Object to be saved. Saved_Objects expects a radius which does not apply here */ /*+++++++++++++++ Making a box ++++++++++++++++*/ #macro Make_Box( Name, Length, Width, Height ) #local Lower_LeftX = 0; #local Lower_LeftY = Floor_Surface; #local Lower_LeftZ = 0; #local Upper_RightX = Lower_LeftX + Width; #local Upper_RightY = Lower_LeftY + Height; #local Upper_RightZ = Lower_LeftZ + Length; #local Component_Rot = transform{ rotate 0*z }; #local Lower_Left = < Lower_LeftX, Lower_LeftY, Lower_LeftZ >; #local Upper_Right = < Upper_RightX, Upper_RightY, Upper_RightZ >; #local Component_Obj = box{ Lower_Left, Upper_Right } #local DUMMY_RADIUS = 0; Save_Object( Name, "Box", Component_Obj, Lower_Left, Upper_Right, DUMMY_RADIUS, Component_Rot ) #end /*++++++++++++++++++++Start user interface testing +++++++++++++++++++*/ light_source{ <5000, 10000, -6000> color red 1.0 green 1.0 blue 1.0 } camera { location <4500, 20300, -3350> //right -x*image_width/image_height // right handedness //sky <0, 0, 1> // right handedness look_at <6000, 1800, 6000> angle 60 } plane { y, Floor_Surface material{ texture{ pigment{ color red 0.80 green 0.80 blue 0.80 }}} } #declare fCyl = "FirstCyl"; #declare sCyl = "SecondCyl"; #declare tCyl = "ThirdCyl"; #declare fBox = "FirstBox"; #declare sBox = "SecondBox"; #declare box1 = "Box01"; #declare box2 = "Box02"; #declare box3 = "Box03"; #declare box4 = "Box04"; #declare box5 = "Box05"; #declare box6 = "Box06"; #declare cyl1 = "Cylinder01"; /* Make_Cylinder( fCyl, 1000, 3000 ) // create first cylinder Make_Cylinder( sCyl, 2000, 1000 ) // create second cylinder... testing Make_Cylinder( tCyl, 500, 1000 ) // create second cylinder... testing Put( fCyl, -1000, 0, -3000 ) //put cylinder in scene without reference //Rotate( sCyl, 45*z ) //Offset( sCyl, fCyl, 0, 3000, 0 ) //put sCyl with reference to tCyl Show( fCyl ) Rotate( fCyl, -45*z ) Show( fCyl ) //Show( sCyl ) Offset( tCyl, fCyl, 0, 3000, 0 ) //put cylinder in scene without reference Show( tCyl ) Make_Box( fBox, 6000, 230, 3000 ) //Put( fBox, -2000, 0, 0 ) Rotate( fBox, 90*y ) Offset( fBox, sCyl, 2000, 1000, 0 ) //Show( fBox ) */ // Make vertical walls Make_Box( box1, 5230, 230, 3000 ) Make_Box( box2, 6000, 230, 3000 ) Make_Box( box3, 6000, 230, 3000 ) // Put vertical walls in position Put( box1, 4000, 0, 0 ) Offset( box2, box1, 6000, 0, 0 ) Offset( box3, box1, -4000, 0, 5000 ) // Render vertical walls Show( box1 ) Show( box2 ) Show( box3 ) // make horizontal walls Make_Box( box4, 3770, 230, 3000 ) Make_Box( box5, 5770, 230, 3000 ) Make_Box( box6, 11770, 230, 3000 ) // Put horizontal walls Offset( box4, box1, -3770, 0, 5230 ) Rotate( box4, 90*y ) Offset( box5, box1, 230, 0, 230 ) Rotate( box5, 90*y ) Offset( box6, box1, -3770, 0, 11000 ) Rotate( box6, 90*y ) // show horizontal walls Show( box4 ) Show( box5 ) Show( box6 ) // Make cylinderical space Make_Cylinder( cyl1, 2500, 3000 ) // put circular space Offset( cyl1, box6, 12000, 0, -2500 ) // show cirlinderical space Show( cyl1 )