Code archives/3D Graphics - Mesh/CreateTree()
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| First attempt to allow creating trees within BlitzBasic3D. Note: This function requires CreateTorus() and CreateCylinderTaper(), also in this archive. | |||||
; BB3D Tree, V1.1 by Martin A. Parrott (parrottm@hotmail.com)
; Oct. 28, 2001 - 1. Added ability to texture the tree components
; 2. Added another leaf type, type 6
;
; This is a piece of code to create a 3D tree with a few predefined
; leaf types. Feel free to add your own leaf routines to the select/case area
; This code is based on code written in Lscript for Lightwave 3D by Newtek
; which was in turn based on an earlier BML script for Lightwave 3D
; and that was based on code ported from a POVRay macro, whew!
; Note: This code is not warranted in any way so use at your own risk
; And test it For usability in your own program
;
; This code is free to use, but if you modify it, please send the
; changes to the above email address so I can continue to release
; updates so others can benefit.
;
; This routine can make many different types of trees, bushes, etc.
; Just change the variables! There are a lot to allow flexibility, so go for it!
;
; Parameters are:
; Wiggle_Flag 1="on", 2="off". Specifies whether to 'wiggle' the branches as they are rotated.
; Branches_On_End_Flag 1="on", 2="off". specifies growth on just the ends or evenly spaced along branch.
; LEAF TYPE is: 0=Realistic, 1=Sphere Blobs
; 2=Strange, 3=Torus
; 4=Triangles, 5=Ultra-Triangles
; 6=Texture mapped (Maps a graphics on a flattened cube, supply your own graphic)
; -1=Default, just a sphere!
; Leaf_Mesh sets the maximum # of trianges for type 4/5 leaves
; Number_Of_Large_Branches NUMBER OF Large/Medium/Small BRANCHES is in relation to each 'parent' branch.
; Number_Of_Medium_Branches
; Number_Of_Small_Branches
; Large_Branch_Minimum_Angle# Large/Medium/Small BRANCH MIN/MAX TILT ANGLE sets limits of random branch tilt.
; Medium_Branch_Minimum_Angle#
; Small_Branch_Minimum_Angle#
; Large_Branch_Maximum_Angle#
; Medium_Branch_Maximum_Angle#
; Small_Branch_Maximum_Angle#
; Tree_Trunk_Size# sets the height of the tree trunk.
; Large_Branch_Size_Min# Large/Medium/Small BRANCH MIN/MAX SIZE sets length limits of the branches.
; Medium_Branch_Size_Min#
; Small_Branch_Size_Min#
; Large_Branch_Size_Max#
; Medium_Branch_Size_Max#
; Small_Branch_Size_Max#
; Trunk_seg This sets the number of faces in each trunk and branch cylinder
; LBranch_seg
; MBranch_seg
; SBranch_seg
; Trunk_Big_Dia# These set the bottom diameter of the trunk/branches
; Trunk_Small_Dia# These set the top diameter of the trunk/branches
; LBranch_Big_Dia#
; LBranch_Small_Dia#
; MBranch_Big_Dia#
; MBranch_Small_Dia#
; SBranch_Big_Dia#
; SBranch_Small_Dia#
; Texture section
; Uncomment the following and replace the image files with your own if you want
; textures on your trunk, branches and/or leaves
; Note: If you don't want these to be global variables, move them inside the
; function below
;Global Trunk_texture$="trunk.bmp"
;Global LargeBranch_texture$="largebranch.bmp"
;Global MediumBranch_texture$="medbranch.bmp"
;Global SmallBranch_texture$="smallbranch.bmp"
;Global Leaf_texture$="leaf.bmp"
Include "../lib/cylindertaper.bb" ; Needed to create the trunk and limbs of our tree
Include "../lib/torus.bb" ; Needed for one of our strange leaf types!
Function CreateTree(Wiggle_Flag=2,Branches_On_End_Flag=2,Leaf_Type=-1,Leaf_Mesh=100,Number_Of_Large_Branches=5,Number_Of_Medium_Branches=3,Number_Of_Small_Branches=7,Large_Branch_Minimum_Angle#=20,Medium_Branch_Minimum_Angle#=20,Small_Branch_Minimum_Angle#=20,Large_Branch_Maximum_Angle#=40,Medium_Branch_Maximum_Angle#=40,Small_Branch_Maximum_Angle#=40,Tree_Trunk_Size#=9,Large_Branch_Size_Min#=2,Medium_Branch_Size_Min#=2,Small_Branch_Size_Min#=2,Large_Branch_Size_Max#=4,Medium_Branch_Size_Max#=3,Small_Branch_Size_Max#=4,Trunk_seg=15,LBranch_seg=4,MBranch_seg=4,SBranch_seg=4,Trunk_Big_Dia#=1,Trunk_Small_Dia#=.8,LBranch_Big_Dia#=.6,LBranch_Small_Dia#=.4,MBranch_Big_Dia#=.3,MBranch_Small_Dia#=.2,SBranch_Big_Dia#=.1,SBranch_Small_Dia#=.05)
; System calculated variables. Takes from defaults above or passed function parameters
L_Bmin#=Large_Branch_Minimum_Angle#
L_Bmax#=Large_Branch_Maximum_Angle# - Large_Branch_Minimum_Angle#
M_Bmin#=Medium_Branch_Minimum_Angle#
M_Bmax#=Medium_Branch_Maximum_Angle# - Medium_Branch_Minimum_Angle#
S_Bmin#=Small_Branch_Minimum_Angle#
S_Bmax#=Small_Branch_Maximum_Angle# - Small_Branch_Minimum_Angle#
Large_Branch_Size_Range#=Large_Branch_Size_Max# - Large_Branch_Size_Min#
Medium_Branch_Size_Range#=Medium_Branch_Size_Max# - Medium_Branch_Size_Min#
Small_Branch_Size_Range#=Small_Branch_Size_Max# - Small_Branch_Size_Min#
If Trunk_texture$<>"" ; Get our Trunk texture if defined
trunktex=LoadTexture(Trunk_texture$)
Else
trunktex=0
EndIf
If LargeBranch_texture$<>"" ; Get our Large branch texture if defined
lbranchtex=LoadTexture(LargeBranch_texture$)
Else
lbranchtex=0
EndIf
If MediumBranch_texture$<>"" ; Get our Medium branch texture if defined
mbranchtex=LoadTexture(MediumBranch_texture$)
Else
mbranchtex=0
EndIf
If SmallBranch_texture$<>"" ; Get our Small branch texture if defined
sbranchtex=LoadTexture(SmallBranch_texture$)
Else
sbranchtex=0
EndIf
If Leaf_texture$<>"" ; Get our Leaf texture if defined
leaftex=LoadTexture(Leaf_texture$,54)
Else
leaftex=0
EndIf
; Make the Tree Trunk
; Note: the Make_Branch function puts a sphere on the end of the branch to 'smooth'
; up the construction. If you want to save polys, change all calls of Make_Branch
; below to Make_Branch_Nosphere
Trunk=Make_Branch(Tree_Trunk_Size#,Trunk_Big_Dia#,Trunk_Small_Dia#,Trunk_seg,trunktex)
A=0
While A < Number_Of_Large_Branches
; Make one large branch.
This_Large_Branch_Size#=( Rnd(0,1) * Large_Branch_Size_Range# ) + Large_Branch_Size_Min#
LBranch=Make_Branch(This_Large_Branch_Size#,LBranch_Big_Dia#,LBranch_Small_Dia#,LBranch_seg,lbranchtex)
If LargeBranch_texture$<>"" ; If the texture is defined, apply it
EntityTexture LBranch,lbranchtex
EndIf
; Loop To put medium branches on that large branch.
B=0
While B < Number_Of_Medium_Branches
This_Medium_Branch_Size#=( Rnd(0,1) * Medium_Branch_Size_Range# ) + Medium_Branch_Size_Min#
MBranch=Make_Branch(This_Medium_Branch_Size#,MBranch_Big_Dia#,MBranch_Small_Dia#,MBranch_seg,mbranchtex)
EntityParent MBranch,LBranch
If MediumBranch_texture$<>"" ; If the texture is defined, apply it
EntityTexture MBranch,mbranchtex
EndIf
; Loop To put small branches on that medium branch.
C=0
While C < Number_Of_Small_Branches
This_Small_Branch_Size#=( Rnd(0,1) * Small_Branch_Size_Range# ) + Small_Branch_Size_Min#
SBranch=Make_Branch_Nosphere(This_Small_Branch_Size#,SBranch_Big_Dia#,SBranch_Small_Dia#,SBranch_seg,sbranchtex)
EntityParent SBranch,MBranch
If SmallBranch_texture$<>"" ; If the texture is defined, apply it
EntityTexture SBranch,sbranchtex
EndIf
; The leaf at the End of the small branch.
Temp_leaf=Make_Leaf(Leaf_Type,Leaf_Mesh,leaftex)
PositionEntity Temp_leaf,0,This_Small_Branch_Size#,0
; First, spin the vertical branch To a random angle.
; The branch doesn't really change - this actually
; just spins the leaf around!
SpinAngle=(Rnd(0,1)*360)
EntityParent Temp_leaf,SBranch
TurnEntity SBranch,0,spinangle,0,True
If Leaf_texture$<>"" ; If the texture is defined, apply it
EntityTexture Temp_leaf,leaftex
EndIf
; Now, tilt it over a little.
BranchAngle=(Rnd(0,1)*S_Bmax)+S_Bmin
TurnEntity SBranch,0,0,BranchAngle,True
; Rotate it into place, with a little random wiggle.
Wiggle=(Rnd(0,1)*20) - 10
If Wiggle_Flag=2
Wiggle=0
EndIf
C2=( 360 / Number_Of_Small_Branches ) * C
C2=C2 + Wiggle
TurnEntity SBranch,0,C2,0,True
; Move it up To the top of the Medium_Branch.
; If flag is "off", Then move To the Next spot on branch.
TEMP_HEIGHT#=This_Medium_Branch_Size#;
If ( Branches_On_End_Flag=2 )
TEMP_HEIGHT#=This_Medium_Branch_Size# - ((This_Medium_Branch_Size# / Number_Of_Small_Branches) * C)
EndIf
PositionEntity SBranch,0,TEMP_HEIGHT#,0
C=C + 1
Wend
BranchAngle=(Rnd(0,1)*M_Bmax)+M_Bmin
TurnEntity MBranch,0,0,BranchAngle,True
Wiggle=(Rnd(0,1)*20) - 10
If ( Wiggle_Flag=2 )
Wiggle=0
EndIf
B2=( 360 / Number_Of_Medium_Branches ) * B
B2=B2 + Wiggle
TurnEntity MBranch,0,B2,0,True
; Move the Medium_Branch up To the top of the Large_Branch.
; If flag is "off", Then move To the Next spot on branch.
TEMP_HEIGHT#=This_Large_Branch_Size#
If ( Branches_On_End_Flag=2 )
TEMP_HEIGHT#=This_Large_Branch_Size# - ((This_Large_Branch_Size# / Number_Of_Medium_Branches)*B)
EndIf
PositionEntity MBranch,0,TEMP_HEIGHT#,0
B=B + 1
Wend
BranchAngle=(Rnd(0,1)*L_Bmax)+L_Bmin
TurnEntity LBranch,0,0,BranchAngle,True
Wiggle=(Rnd(0,1)*20) - 10
If Wiggle_Flag=2
Wiggle=0
EndIf
A2=( 360 / Number_Of_Large_Branches ) * A
A2=A2 + Wiggle
TurnEntity LBranch,0,A2,0,True
; Move the Large_Branch up To the top of the Tree_Trunk.
; If flag is "off", Then move To the Next spot on trunk.
; These are spaced differently than the other branches - they
; start about 3/4 of the way up the trunk.
TEMP_HEIGHT#=Tree_Trunk_Size#
If Branches_On_End_Flag=2
TEMP_HEIGHT#=Tree_Trunk_Size# - ((Tree_Trunk_Size# / Number_Of_Large_Branches) * A/4);
EndIf
PositionEntity LBranch,0,TEMP_HEIGHT#,0
A=A + 1
EntityParent LBranch,Trunk
Wend
Return Trunk
End Function
Function Make_Leaf(Leaf_Type,Leaf_Mesh,texture)
Select Leaf_Type
; Let's do the quasi-REALISTIC leaf.
Case 0
piv0=CreatePivot()
piv1=CreatePivot(piv0)
leaf1=CreateSphere(8,piv1)
EntityColor leaf1,0,150,0
PositionEntity leaf1,0,-2.5,-5
TurnEntity leaf1,-30,0,0,True
ScaleEntity leaf1,2.4,.6,6
piv2=CopyEntity(piv1,piv0)
TurnEntity piv2,0,120,0
piv3=CopyEntity(piv2,piv0)
TurnEntity piv2,0,120,0
ScaleEntity piv0,.1,.1,.1 ; Change this scale to size the overall cluster
Return piv0
; Now create the actual Sphere Blob leaf.
Case 1
ball=CreateSphere(8)
ScaleEntity ball,2,2,2 ; Change this to size the 'blobs' up and down
EntityAlpha ball,.1
EntityColor ball,0,150,0
leafmesh=CreateMesh(ball)
leafsurf=CreateSurface(leafmesh)
A=1
While A<=Leaf_Mesh
; Calculate random location For First point.
X1#=( Rnd(0,1) * 2 ) - 1
Y1#=( Rnd(0,1) * 2 ) - 1
Z1#=( Rnd(0,1) * 2 ) - 1
pnt0=AddVertex(leafsurf,x1#,y1#,z1#)
pnt1=AddVertex(leafsurf,0,0,0)
pnt2=AddVertex(leafsurf,0,0,.1)
AddTriangle(leafsurf,pnt0,pnt1,pnt2)
pnt1=AddVertex(leafsurf,0,0,0)
pnt2=AddVertex(leafsurf,.1,0,0)
AddTriangle(leafsurf,pnt0,pnt1,pnt2)
A=A + 1
Wend
EntityColor leafmesh,0,150,0
Return ball
; Now create the actual STRANGE leaf. Change this To anything!
Case 2
box=CreateCube()
EntityColor box,0,150,0
ScaleEntity box,2,2,2
sph=CreateSphere(8,box)
EntityColor sph,150,0,0
ScaleEntity sph,1.2,1.2,1.2
ScaleEntity box,.3,.3,.3
Return box
; Now create the actual TORUS leaf.
Case 3
torus=createtorus(5,12,0,0,0,0,.25,1)
EntityColor torus,150,0,0
torcyl1=CreateCylinder(3,False,torus)
EntityColor torcyl1,0,150,0
ScaleEntity torcyl1,.1,1,.1
TurnEntity torcyl1,90,0,0
torcyl2=CreateCylinder(3,False,torus)
EntityColor torcyl2,0,150,0
ScaleEntity torcyl2,.1,1,.1
TurnEntity torcyl2,0,0,90
Return torus
; Create the Tri leaf Object - with lots of little triangles!!!
Case 4
leafmesh=CreateMesh()
leafsurf=CreateSurface(leafmesh)
A=1
While A<=Leaf_Mesh
; Calculate random location For First point.
X1#=( Rnd(0,1) * 2 ) - 1
Y1#=( Rnd(0,1) * 2 ) - 1
Z1#=( Rnd(0,1) * 2 ) - 1
;Move a little way from *First* point.
X2#=X1# + ( Rnd(0,1) * 0.6 ) - 0.3
Y2#=Y1# + ( Rnd(0,1) * 0.6 ) - 0.3
Z2#=Z1# + ( Rnd(0,1) * 0.6 ) - 0.3
; Move a little way from *First* point.
X3#=X1# + ( Rnd(0,1) * 0.6 ) - 0.3
Y3#=Y1# + ( Rnd(0,1) * 0.6 ) - 0.3
Z3#=Z1# + ( Rnd(0,1) * 0.6 ) - 0.3
pnt0=AddVertex(leafsurf,X1#,Y1#,Z1#)
pnt1=AddVertex(leafsurf,X2#,Y2#,Z2#)
pnt2=AddVertex(leafsurf,X3#,Y3#,Z3#)
AddTriangle(leafsurf,pnt0,pnt1,pnt2)
A=A + 1
Wend
EntityColor leafmesh,0,150,0
Return leafmesh
; Create the ULTRA-Tri leaf Object - with lots of little triangles,
; And Each "leaf" has a connector "branch" back To <0,0,0>.
Case 5
leafmesh=CreateMesh(parent)
leafsurf=CreateSurface(leafmesh)
A=1
While A<=Leaf_Mesh
; Calculate random location For First point.
X1=( Rnd(0,1) * 2 ) - 1
Y1=( Rnd(0,1) * 2 ) - 1
Z1=( Rnd(0,1) * 2 ) - 1
; Move a little way from *First* point.
X2=X1 + ( Rnd(0,1) * 0.6 ) - 0.3
Y2=Y1 + ( Rnd(0,1) * 0.6 ) - 0.3
Z2=Z1 + ( Rnd(0,1) * 0.6 ) - 0.3
; Move a little way from *First* point.
X3=X1 + ( Rnd(0,1) * 0.6 ) - 0.3
Y3=Y1 + ( Rnd(0,1) * 0.6 ) - 0.3
Z3=Z1 + ( Rnd(0,1) * 0.6 ) - 0.3
pnt0=AddVertex(leafsurf,x1#,y1#,z1#)
pnt1=AddVertex(leafsurf,x2#,y2#,z2#)
pnt2=AddVertex(leafsurf,x3#,y3#,z3#)
AddTriangle(leafsurf,pnt0,pnt1,pnt2)
pnt1=AddVertex(leafsurf,0,0,0)
pnt2=AddVertex(leafsurf,0,0,.1)
AddTriangle(leafsurf,pnt0,pnt1,pnt2)
pnt1=AddVertex(leafsurf,0,0,0)
pnt2=AddVertex(leafsurf,.1,0,0)
AddTriangle(leafsurf,pnt0,pnt1,pnt2)
A=A + 1
Wend
EntityColor leafmesh,0,150,0
Return leafmesh
; Map a user specified graphic on a flattened cube
Case 6
cube=CreateCube() ; Alternate to 'fast' leaf below. We map an image of a leaf on a flattened cube
ScaleEntity cube,1,1,.001 ; Flatten our cube
tex=LoadTexture("leaf.bmp",54) ; Change the image name to one of your own
EntityTexture cube,tex
Return cube
; Use FAST leaf as the Default.
Default
ball=CreateSphere(4)
ScaleEntity ball,.3,.3,.3
EntityColor ball,0,150,0
Return ball
End Select
End Function
Function Make_Branch(branch_size#,Big_Dia#,Small_Dia#,branch_seg,texture) ; Now create some branches.
branch=createcylindertaper(branch_seg,0,0,0,0,0,Big_Dia#,Small_Dia#,branch_size#)
ball=CreateSphere(branch_seg/2,branch)
ScaleEntity ball,Small_Dia#,Small_Dia#,Small_Dia#
PositionEntity ball,0,branch_size,0
If texture>0 ; If we have a texture, put it on
EntityTexture branch,texture
EntityTexture ball,texture
Else ; If we don't have a texture, color it
EntityColor branch,90,45,0 ; Give us a dark brown color, change to whatever color your want!
EntityColor ball,90,45,0 ; Give us a dark brown color, change to whatever color your want!
EndIf
Return branch
End Function
Function Make_Branch_Nosphere(branch_size#,Big_Dia#,Small_Dia#,SBranch_seg,texture)
branch=createcylindertaper(SBranch_seg,0,0,0,0,0,Big_Dia#,Small_Dia#,branch_size#)
If texture>0 ; If we have a texture, put it on
EntityTexture branch,texture
Else ; If we don't have a texture, color it
EntityColor branch,90,45,0 ; Give us a dark brown color, change to whatever color your want!
EndIf
Return branch
End Function |
Comments
| ||
| I changed the above a little, so it's easy to make a randomized tree. It is returned as a single mesh, just the trunk(no leafs yet). Example. Engine. |
Code Archives Forum