#constant C_basicLengthFactor 75.0 #constant C_basicSizeFactor 15.0 #constant C_BranchRadiusDecline 0.55 #constant C_BranchLengthDecline 0.70 #constant C_maxDownAngle 135 #constant C_branchMinAngle 30.0 #constant C_branchRndAngle 10.0 #constant C_trunkMinAngle 5.0 #constant C_trunkRndAngle 5.5 #constant C_textureDeScale 5.0 #constant C_BranchesPerLayer 3 #constant C_NumberOfLayers 5 #constant C_NumberOfLeaves 2 #constant C_XuprightOffset 270 #constant C_BarkTextureStart 1 #constant C_BarkTextureEnd 5 #constant C_LeafTextureStart 6 #constant C_LeafTextureEnd 10 #constant C_GroundTexture 100 #constant C_RainTexture 200 type XYZfloat x as float y as float z as float endtype gosub setupEnvironment do text 10,10,"Screen FPS: " + str$(screen FPS()) text 10,30,"Polygons on Screen: " + str$(Statistic(1)) text 10,50,"Hold [Shift] and move mouse to turn, RMB goes forward, LMB goes backward" text 10,70,"Press [Space] to generate a new tree..." MouseControl(2) `update rain updateRain() if spacekey() = 1 repeat text 10,10,"Screen FPS: " + str$(screen FPS()) text 10,30,"Polygons on Screen: " + str$(Statistic(1)) text 10,50,"Hold [Shift] and move mouse to turn, RMB goes forward, LMB goes backward" center text screen width()/2,70,"...Release [Space] to generate a new tree..." MouseControl(2) syn il spacekey() = 0 if limbedTreeObj <> 0 if object exist(limbedTreeObj) = 1 then delete object limbedTreeObj endif text screen width()-text width("...Constructing New Tree "),70, "...Constructing New Tree " sync limbedTreeObj = CreateLimbedTree(XYZstartPos, XYZstartDir, C_BranchesPerLayer, C_NumberOfLayers, C_basicLengthFactor, C_basicSizeFactor) pause("...New Tree Created, Press [space] to resume...") endif sync loop setupEnvironment: sync on sync rate 0 autocam off set display mode 800,600,32 position camera 200,200,200 point camera 0,100,0 randomize timer() `randomize 1 text 0,0,"Generating Bark Texture..." sync sync for n = C_BarkTextureStart to C_BarkTextureEnd BarkTexture(n) next n cls rgb(0,0,0) ink rgb(255,255,255),0 text 0,0,"Generating Leaf Textures..." sync sync for n = C_LeafTextureStart to C_LeafTextureEnd LeafTexture(n) next n GroundTexture(C_GroundTexture) global XYZfReturn as XYZfloat global XYZstartDir as XYZfloat global XYZstartPos as XYZfloat global rainObj as integer global limbedTreeObj as integer XYZstartDir.x = 0 XYZstartDir.y = 0 XYZstartDir.z = 0 XYZstartPos.x = 0 XYZstartPos.y = 0 XYZstartPos.z = 0 make matrix 1, 5000, 5000, 35, 35 position matrix 1,-2500,0,-2500 set matrix wireframe on 1 prepare matrix texture 1, C_GroundTexture, 1, 1 fill matrix 1, 0, 1 randomize matrix 1,30 update matrix 1 ink rgb(255,255,255),0 fog on fog color RGB(189,193,196) fog distance 1000 color backdrop RGB(189,193,196) limbedTreeObj = CreateLimbedTree(XYZstartPos, XYZstartDir, C_BranchesPerLayer, C_NumberOfLayers, C_basicLengthFactor, C_basicSizeFactor) make light 1 set point light 1, -100, 100, -100 rainSpout() ink rgb(150,150,150),0 return function rainSpout() RainTexture(C_RainTexture) rainObj = FreeObject() `MemblockTCone(rainObj, 20, 50, 30, 800) `MemblockTCone(rainObj+1,20,75, 45, 800) make object cylinder rainObj, 100 : scale object rainObj,200,800,200 make object cylinder rainObj+1, 100 : scale object rainObj+1,400,800,400 texture object rainObj, C_RainTexture texture object rainObj+1, C_RainTexture set object transparency rainObj, 0 set object transparency rainObj+1, 0 ghost object on rainObj ghost object on rainObj+1 set object cull rainObj, 0 set object cull rainObj+1, 0 disable object zwrite rainObj disable object zwrite rainObj+1 set object light rainObj, 0 set object light rainObj+1, 0 endfunction function updateRain() position object rainObj, camera position x(), 0, camera position z() position object rainObj+1, camera position x(), 0, camera position z() `position object rainObj, 0, 400, 0 `position object rainObj+1, 0, 400, 0 scroll object texture rainObj,0.0001,-0.005 scroll object texture rainObj+1,-0.0001,-0.005 endfunction function CreateLimbedTree(pos as XYZfloat, direction as XYZfloat, BPL as integer, numLayers as integer, length as float, width as float) local treeobj as integer treeobj = FreeObject() make object box treeobj, 0, 0, 0 DrawLimbedTree(numLayers, BPL, treeobj, 0, direction, pos, length, width) `DrawLimbedTree(6, BPL, treeobj, 0, direction, pos, length, width) set object transparency treeobj,1 endfunction treeobj function DrawLimbedTree(n as integer,BPL as integer, obj as integer, limb as integer, direction as XYZfloat, pos as XYZfloat, length as float, width as float) local RndBchDir as XYZfloat local RndBchPos as XYZfloat if n > 0 limb = DrawLimbedTrunk(n, obj, limb, pos, direction, length, width) `sync `pause("Created a Trunk") if n > 1 rem trunk stem RandomLimbedBranchDirection(C_trunkRndAngle, C_trunkMinAngle) : RndBchDir = XYZfReturn NewLimbedTrunkPos(length) : RndBchPos = XYZfReturn `pause("Stem") DrawLimbedTree(n-1,BPL,obj,limb,RndBchDir,RndBchPos,LengthDeScale(n,length), SizeDeScale(n,width)) rem branches ahoy!!! for i = 1 to BPL RandomLimbedBranchDirection(C_branchRndAngle, C_branchMinAngle) : RndBchDir = XYZfReturn RandomLimbedBranchPosition(length) : RndBchPos = XYZfReturn `pause("Branches") DrawLimbedTree(n-1,BPL,obj,limb,RndBchDir,RndBchPos,LengthDeScale(n,length), SizeDeScale(n,width)) next i endif endif rem draw leaves... if n <= 1 and C_NumberOfLeaves > 0 for i = 1 to C_NumberOfLeaves RndBchPos.x = 0 RndBchPos.y = (i-1.0)*1.0*(length*0.666666 / (C_NumberOfLeaves*1.0)) + (length*0.3) RndBchpos.z = 0 RndBchDir.x = -10 + rnd(20) RndBchDir.y = -20 + rnd(40) RndBchDir.z = 0 DrawLimbedLeaf(obj, limb, RndBchPos, RndBchDir, 6, 3) RndBchDir.x = -10 + rnd(20) RndBchDir.y = 160 + rnd(40) DrawLimbedLeaf(obj, limb, RndBchPos, RndBchDir, 6, 3) next i RndBchDir.x = rnd(360) RndBchDir.y = 0 RndBchDir.z = 90 RndBchPos.y = length - length * 0.125 DrawLimbedLeaf(obj, limb, RndBchPos, RndBchDir, 6, 3) endif endfunction function DrawLimbedTrunk(n, obj, limb, pos as XYZfloat, direction as XYZfloat, length as float, width as float) local meshNum as integer local newLimb as integer meshNum = FreeMesh() newLimb = FreeLimb(obj) `clone object objnum, baseTrunkObj if n <= 1 MemblockMeshCone(meshNum, n+4, width, length) `MemblockMeshTCone(meshNum, n+4, C_BranchRadiusDecline * width, width, length) else MemblockMeshTCone(meshNum, n+4, C_BranchRadiusDecline * width, width, length) endif add limb obj, newLimb, meshNum link limb obj, limb, newLimb rotate limb obj, newLimb, direction.x, direction.y, direction.z offset limb obj, newLimb, pos.x, pos.y, pos.z texture limb obj, newLimb, C_BarkTextureStart + rnd(C_BarkTextureEnd-C_BarkTextureStart) `scale limb texture obj, newLimb, width/C_textureDeScale, width/C_textureDeScale endfunction newLimb function DrawLimbedLeaf(obj, limb, pos as XYZfloat, direction as XYZfloat, length as float, width as float) local meshNum as integer local newLimb as integer meshNum = FreeMesh() newLimb = FreeLimb(obj) `clone object objnum, baseTrunkObj MemblockMeshPlain(meshNum, width, length) add limb obj, newLimb, meshNum link limb obj, limb, newLimb rotate limb obj, newLimb, direction.x, direction.y, direction.z offset limb obj, newLimb, pos.x, pos.y, pos.z texture limb obj, newLimb, C_LeafTextureStart+rnd(C_LeafTextureEnd - C_LeafTextureStart) endfunction function RandomLimbedBranchDirection(randomAngle as float, minAngle as float) XYZfReturn.x = minAngle + rnd(randomAngle) XYZfReturn.y = rnd(360) XYZfReturn.z = 0 endfunction function NewLimbedTrunkPos(length as float) XYZfReturn.x = 0 XYZfReturn.y = length - length/40.0 XYZfReturn.z = 0 endfunction function RandomLimbedBranchPosition(length as float) XYZfReturn.x = 0 XYZfReturn.y = length/2.0 + rnd(length/3.0) XYZfReturn.z = 0 endfunction function SizeDeScale(n as integer, size as float) rem more work, for n anyways... local rtrn as float rtrn = size*C_BranchRadiusDecline endfunction rtrn function LengthDeScale(n as integer, size as float) local rtrn as float rtrn = size*C_BranchLengthDecline endfunction rtrn function BarkTexture(imgNum as integer) local xSize as integer local ySize as integer local tmpXa as integer local tmpYa as integer local tmpXb as integer local tmpYb as integer local extream as integer xSize = 255 ySize = 255 cls rgb(120,90,70) for n = 1 to (xSize+ySize)*50 extream = -60 + rnd(100) ink rgb(110+rnd(20)+extream,80+rnd(20)+extream,60+rnd(20)+extream),0 circle rnd(xSize), rnd(ySize),3 next n for n = 1 to (xSize+ySize)*3 extream = -60 + rnd(100) ink rgb(110+rnd(20)+extream,80+rnd(20)+extream,60+rnd(20)+extream),0 tmpXa = rnd(xSize) tmpYa = rnd(ySize - ySize/3) tmpXb = tmpXa-3+rnd(6) if tmpXb < 0 then tmpXb = 0 if tmpXb > xSize then tmpXb = xSize tmpYb = tmpYa + rnd(ySize/2) if tmpYb > ySize then tmpYb = ySize line tmpXa, tmpYa, tmpXb, tmpYb extream = -60 + rnd(100) ink rgb(110+rnd(20)+extream,80+rnd(20)+extream,60+rnd(20)+extream),0 tmpXa = rnd(10) for x = 1 to 5 circle rnd(xSize), rnd(ySize),5+tmpXa+x next x next n blur bitmap 0,2 get image imgNum,xSize/4,ySize/4,(xSize*3)/4,(ySize*3)/4,0 endfunction function LeafTexture(imgNum as integer) cls rgb(0,0,0) local xSize as integer local ySize as integer local fractQty as integer local tmpXa as integer local tmpYa as integer local tmpXb as integer local tmpYb as integer local color as dword local extream as integer xSize = 100 ySize = 200 fractQty = 100 ink rgb(rnd(40),150+rnd(40)+extream,rnd(40)),0 for n = 0 to ySize*2 tmpXb = (sin(180.0*n*1.0/ySize*2.0)+1.0)*xSize/2.0 tmpXa = (sin(180.0*n*1.0/ySize*2.0+180)+1.0)*xSize/2.0 tmpYa = (cos(180.0*n*1.0/ySize*2.0)+1.0)*(ySize)/2.0 tmpYb = (cos(180.0*(n+1)*1.0/ySize*2.0)+1.0)*(ySize)/2.0 box tmpXb, tmpYa, tmpXa, tmpYb next n for n = 1 to fractQty tmpXa = xSize/2 tmpYa = ySize-(abs(n-fractQty/2)/(fractQty/2.0))*ySize*0.7 tmpXb = (sin(360.0*n*1.0/fractQty*1.0 + 180)+1.0)*xSize/2.0 tmpYb = (cos(360.0*n*1.0/fractQty*1.0 + 180)+1.0)*(ySize)/2.0 extream = -50 + rnd(100) color = rgb(rnd(40),100+rnd(40)+extream,rnd(40)) fracture(tmpXa,tmpYa,tmpXb,tmpYb, 50, 7, color) next n get image imgNum,0,0,xSize,ySize,0 endfunction function GroundTexture(imgNum as integer) local xSize as integer local ySize as integer local tmpXa as integer local tmpYa as integer local tmpXb as integer local tmpYb as integer local extream as integer xSize = 255 ySize = 255 cls rgb(120,90,70) for n = 1 to (xSize+ySize)*50 extream = -60 + rnd(100) ink rgb(110+rnd(20)+extream,80+rnd(20)+extream,60+rnd(20)+extream),0 circle rnd(xSize), rnd(ySize),3 next n for n = 1 to (xSize+ySize)*3 extream = -60 + rnd(100) ink rgb(110+rnd(20)+extream,80+rnd(20)+extream,60+rnd(20)+extream),0 tmpXa = rnd(xSize) tmpYa = rnd(ySize) tmpXb = rnd(xSize) tmpYb = rnd(ySize) line tmpXa, tmpYa, tmpXb, tmpYb extream = -60 + rnd(100) ink rgb(110+rnd(20)+extream,80+rnd(20)+extream,60+rnd(20)+extream),0 tmpXa = rnd(10) for x = 1 to 5 circle rnd(xSize), rnd(ySize),5+tmpXa+x next x next n blur bitmap 0,2 get image imgNum,xSize/4,ySize/4,(xSize*3)/4,(ySize*3)/4,0 endfunction function RainTexture(imgNum as integer) local xSize as integer local ySize as integer local tmpXa as integer local tmpYa as integer local tmpXb as integer local tmpYb as integer local extream as integer cls rgb(0,0,0) xSize = 1200 ySize = 1200 create bitmap 1, xSize, ySize set current bitmap 1 cls rgb(0,0,0) for n = 1 to (xSize)*4 extream = -120 + rnd(40) ink rgb(200+rnd(10)+extream,200+rnd(10)+extream,210+rnd(10)+extream),0 tmpXa = rnd(xSize) tmpYa = rnd(ySize - 20) tmpXb = tmpXa-3+rnd(6) if tmpXb < 0 then tmpXb = 0 if tmpXb > xSize then tmpXb = xSize tmpYb = tmpYa + rnd(10) + 10 if tmpYb > ySize then tmpYb = ySize line tmpXa, tmpYa, tmpXb, tmpYb next n get image imgNum,0,0,xSize,ySize,0 delete bitmap 1 set current bitmap 0 endfunction function MemblockTCone(object as integer, density as integer, topSize as float, btmSize as float, height as float) local tmpmesh as integer tmpmesh = FreeMesh() MemblockMeshTCone(tmpmesh, density, topSize, btmSize, height) make object object, tmpmesh, 1 delete mesh tmpmesh endfunction function MemblockCone(object as integer, density as integer, size as float, height as float) local tmpmesh as integer tmpmesh = FreeMesh() MemblockMeshCone(tmpmesh, density, size, height) make object object, tmpmesh, 1 delete mesh tmpmesh endfunction function MemblockMeshTCone(mesh as integer, density as integer, topSize as float, btmSize as float, height as float) local memblock as integer local vertexCount as integer local offset as integer memblock = FreeMemblock() make memblock memblock, 12 + (32 * density * 6) write memblock dword memblock, 0, 275 write memblock dword memblock, 4, 32 write memblock dword memblock, 8, density * 6 offset = 12 for i = 1 to density `write poly one and two------------------------------------- writeVertex275(memblock, offset , sin((i-1.0)*360.0/density)*topSize/2.0, height, cos((i-1.0)*360.0/density)*topSize/2.0, cos((i-1.0)*360.0/density*1.0), 0, sin((i-1.0)*360.0/density), (i-1.0)/density, 0.0) writeVertex275(memblock, offset+32 , sin((i-1.0)*360.0/density)*btmSize/2.0, 0, cos((i-1.0)*360.0/density)*btmSize/2.0, cos((i-1.0)*360.0/density*1.0), 0, sin((i-1.0)*360.0/density), (i-1.0)/density, 1.0) writeVertex275(memblock, offset+64 , sin((i*1.0)*360.0/density)*topSize/2.0, height, cos((i*1.0)*360.0/density)*topSize/2.0, cos((i*1.0)*360.0/density*1.0), 0, sin((i*1.0)*360.0/density), (i*1.0)/density, 0.0) writeVertex275(memblock, offset+96 , sin((i-1.0)*360.0/density)*btmSize/2.0, 0, cos((i-1.0)*360.0/density)*btmSize/2.0, cos((i-1.0)*360.0/density*1.0), 0, sin((i-1.0)*360.0/density), (i-1.0)/density, 1.0) writeVertex275(memblock, offset+128, sin((i*1.0)*360.0/density)*btmSize/2.0, 0, cos((i*1.0)*360.0/density)*btmSize/2.0, cos((i*1.0)*360.0/density*1.0), 0, sin((i*1.0)*360.0/density), (i*1.0)/density, 1.0) writeVertex275(memblock, offset+160, sin((i*1.0)*360.0/density)*topSize/2.0, height, cos((i*1.0)*360.0/density)*topSize/2.0, cos((i*1.0)*360.0/density*1.0), 0, sin((i*1.0)*360.0/density), (i*1.0)/density, 0.0) inc offset, 192 next i make mesh from memblock mesh, memblock delete memblock memblock endfunction function MemblockMeshCone(mesh as integer, density as integer, size as float, height as float) local memblock as integer local vertexCount as integer local offset as integer memblock = FreeMemblock() make memblock memblock, 12 + (32 * density * 3) write memblock dword memblock, 0, 275 write memblock dword memblock, 4, 32 write memblock dword memblock, 8, density * 3 offset = 12 for i = 1 to density `write poly one------------------------------------- writeVertex275(memblock, offset , sin((i-1.0)*360.0/density)*size/2.0, 0, cos((i-1.0)*360.0/density)*size/2.0, cos((i-1.0)*360.0/density*1.0), 0, sin((i-1.0)*360.0/density), (i-1.0)/density , 1.0) writeVertex275(memblock, offset+32, sin((i*1.0)*360.0/density)*size/2.0, 0, cos((i*1.0)*360.0/density)*size/2.0, cos((i*1.0)*360.0/density*1.0), 0, sin((i*1.0)*360.0/density), (i*1.0)/density , 1.0) writeVertex275(memblock, offset+64, 0 , height, 0 , cos((i*1.0)*360.0/density*1.0), 0, sin((i*1.0)*360.0/density), (i-1.0)/(density-1), 0.0) inc offset, 96 next i make mesh from memblock mesh, memblock delete memblock memblock endfunction function MemblockMeshPlain(mesh as integer, width as float, height as float) local memblock as integer local vertexCount as integer local offset as integer memblock = FreeMemblock() make memblock memblock, 12 + (32 * 4 * 3) write memblock dword memblock, 0, 275 write memblock dword memblock, 4, 32 write memblock dword memblock, 8, 12 offset = 12 `write poly one and two and invert------------------------------------- writeVertex275(memblock, offset , 0 , 0, width/-2.0, 0, 1, 0, 0.0, 1.0) writeVertex275(memblock, offset+32 , 0 , 0, width/2.0 , 0, 1, 0, 1.0, 1.0) writeVertex275(memblock, offset+64 , height, 0, width/-2.0, 0, 1, 0, 0.0, 0.0) inc offset, 96 writeVertex275(memblock, offset , 0 , 0, width/2.0 , 0, 1, 0, 1.0, 1.0) writeVertex275(memblock, offset+32 , height, 0, width/2.0, 0, 1, 0, 1.0, 0.0) writeVertex275(memblock, offset+64 , height, 0, width/-2.0, 0, 1, 0, 0.0, 0.0) inc offset, 96 writeVertex275(memblock, offset , 0 , 0, width/2.0 , 0, -1, 0, 1.0, 1.0) writeVertex275(memblock, offset+32 , 0 , 0, width/-2.0, 0, -1, 0, 0.0, 1.0) writeVertex275(memblock, offset+64 , height, 0, width/-2.0, 0, -1, 0, 0.0, 0.0) inc offset, 96 writeVertex275(memblock, offset , height, 0, width/2.0, 0, -1, 0, 1.0, 0.0) writeVertex275(memblock, offset+32 , 0 , 0, width/2.0 , 0, -1, 0, 1.0, 1.0) writeVertex275(memblock, offset+64 , height, 0, width/-2.0, 0, -1, 0, 0.0, 0.0) make mesh from memblock mesh, memblock delete memblock memblock endfunction function writeVertex275(memblock, offset, x#, y#, z#, nx#, ny#, nz#, u#, v#) write memblock float memblock, offset + 0, x# write memblock float memblock, offset + 4, y# write memblock float memblock, offset + 8, z# `write normal data write memblock float memblock, offset + 12, nx# write memblock float memblock, offset + 16, ny# write memblock float memblock, offset + 20, nz# `write UV information write memblock float memblock, offset + 24, u# write memblock float memblock, offset + 28, v# endfunction `an electric function pulled from one of my 20 liners that never went... function fracture(startx, starty, endx, endy, devdegree, points, color) rem this scales the number of points acording to the distance traversed `test# = (2D_Distance(startx, starty, endx, endy)*density) / 2D_Distance(0, 0, screen width(), screen height()) dim lines(points,1) #constant xposition=0 #constant yposition=1 lines(0,xposition) = startx lines(0,yposition) = starty alpha = 0 distance = 0 angle = 0 for n = 1 to points angle = rnd(devdegree) - int(devdegree/2) if n = points - 1 angle = 0 endif distance = sqrt((startx - endx)*(startx - endx) + (starty - endy)*(starty - endy)) / (points - n) alpha = atanfull((endy - starty),(endx - startx)) lines(n,xposition) = distance * cos(alpha + angle) + startx lines(n,yposition) = distance * sin(alpha + angle) + starty startx = lines(n,xposition) starty = lines(n,yposition) next n ink color,0 for n = 1 to points line lines(n-1,xposition),lines(n-1,yposition),lines(n,xposition),lines(n,yposition) next n endfunction `pauses untill the space key is pressed function pause(prompt as string) repeat center text screen width()/2, 15, prompt MouseControl(0.5) syn il spacekey() = 1 repeat center text screen width()/2, 15, prompt MouseControl(0.5) syn il spacekey() = 0 endfunction function MouseControl(Speed as float) if shiftkey() = 1 xrotate camera camera angle x()+mousemovey()/3.0 yrotate camera camera angle y()+mousemovex()/6.0 if mouseclick()=1 then move camera Speed if mouseclick()=2 then move camera (0-Speed) endif r=mousemovex() r=mousemovey() endfunction `hides and or deletes objects function ClearObjects(maxSearch as integer) for i = 1 to maxSearch `if object exist(i) = 1 then delete object i if object exist(i) = 1 then hide object i next i endfunction function FreeObject() repeat inc i if object exist(i)=0 then found=1 until found endfunction i function FreeImage() repeat inc i if image exist(i)=0 then found=1 until found endfunction i function FreeLimb(objNum) repeat inc i if limb exist(objNum,i)=0 then found=1 until found endfunction i function FreeMemblock() repeat inc i if memblock exist(i)=0 then found=1 until found endfunction i function FreeMesh() repeat inc i if mesh exist(i)=0 then found=1 until found endfunction i