[B3D] FreeTreeLib - schneller Einbau von Bäumen

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

Diedel

Betreff: [B3D] FreeTreeLib - schneller Einbau von Bäumen

BeitragSo, Mai 10, 2009 16:10
Antworten mit Zitat
Benutzer-Profile anzeigen
FreeTreeLibuser posted image

Hab mal etwas mit Blitz3D herumgespielt und mir dabei gedacht ein paar Bäumchen könnten nicht fehlen, herausgekommen ist eine Art Baumgenerator für 3D welcher nach ein paar ausgewählten Parametern schnell einen Baum erstellt und nach Wunsch auch gleich noch ein paar Sprites an die Äste hängt.

Hier mal ein Screenshot:
user posted image

Die Funktionen sind in der Datei FreeTree.bb enthalten, in der Sample.bb ist ein kommentiertes Beispiel mit welchem ich die Verwendung der Lib (kann hier überhaupt schon von einer Libary die Rede sein?) erkläre, ein Großteil der Codes kommt dabei aus Schnipseln der B3D-Samples.
Hier (das ist der aktuellste Link Wink) kann das Ganze nun gedownloadet werden, soweit ich das sehe werden bei einfacher Verwendung der Grafiken keine Kopierrechte verletzt. Die Hauptfunktion besteht aus der CreateTree() welche im Samplecode eigentlich ausreichend erklärt wird aber dennoch nocheinmal hier:

FreeTree hat Folgendes geschrieben:
CreateTree%(X#, Y#, Z#, Startlänge#, Änderungsfaktor#, Durchgänge%, Verzweigungen%[,Sprite%=0 , Parent%=0, Wind%=True])
Erstellt einen Baum und gibt ihn als Mesh zurück.

Parameter:
X# - Die X-Position an der der Baum platziert werden soll
Y# - Die Y-Position an der der Baum platziert werden soll
Z# - Die Z-Position an der der Baum platziert werden soll
Startlänge# - Die Länge mit der die Äste am Anfang beginnen sollen, sie variieren jedoch auch hier bereits+-
Änderungsfaktor# - Der Faktor um den die Länge der Äste nach Start von Ast zu Ast abnehmen soll
Durchgänge% - Die Zahl der Stufen die gemacht werden sollen, vorsicht vor hohen Zahlen!
Verzweigungen% - Die Anzahl der Äste die pro Verzweigung generiert werden sollen
Sprite% - Wenn ein Sprite angebenen wird wird dieses an Alle Verzweigungen (außer der Ersten) drankopiert
Parent% - Hiermit kann ein Parent für den zu generierenden Baum angegeben werden
Wind% - Wenn hier True bzw. 1 angegeben wird, kann der Baum für Windoperationen genutzt werden

Rückgabewert:
Zurückgegeben wird ein Mesh das den Baum beinhaltet sowie als Childs die ganzen (wenn angeben) zugefügten Sprites enthält.


UpdateWind([Speed#=1, Force#=10, Independent%=True, Trees%])
Bewegt die Blätter der Bäume, geplant ist auchnoch eine Bewegung der Bäume selbst.

Parameter:
Speed# - Gibt die Geschwindikeit an, mit der die Blätter hin und her schaukeln sollen
Force# - Ausschlag der Blätterbewegung
Independent% - Wenn True bzw. 1 schwingen die Blätter eines Baumes anderst als die der anderen Bäume
Trees% - Falls Ture bzw. 1 bewegen sich auch die Bäume

Rückgabewert:
-Nicht vorhanden-


FreeTree(Entity%)
Löscht einen mit CreateTree erstellten Baum vollständig aus dem Speicher.

Parameter:
Entity% - Die Identität eines Baumes der mit CreateTree%(...) erstellt wurde, wird zum Löschen von Bämen empfohlen bei denen der Parameter Wind aktiviert war

Rückgabewert:
-Nicht vorhanden-
*Grüner Text heißt neu hinzugekommen (seit 11. Mai 22:59)

Aufgrund der Regeln noch den aktuellen Code der Lib (braucht keine externen Ressourcen):
BlitzBasic: [AUSKLAPPEN]
;FreeTreeLib von Diedel, zu finden unter https://www.blitzforum.de/forum/viewtopic.php?t=31680
;Ich übernehme keine Haftung für den Code bzw. aus ihm resultierenden Wirkungen, des Weiteren
;gilt er vollständig als Public-Domain was zur Folge hat, dass Ihr auf einen Creditseintrag
;verzichten dürft und die Lib kostenfrei verwenden dürft, aber dennoch würde ich mich über
;einen Eintrag in euer Projekt freuen wenn Ihr sie benutzt, in diesem Sinne: Los gehts! ;P

Global windpr#


Function CreateTree%(x#,y#,z#,height#,fac#,nodes%,taps%,sprite%=0,parent%=0,wind%=True)
mesh=CreateMesh(parent)
PositionEntity mesh,x,y,z
CreateTreeNode(0,0,0,0,0,height,fac,nodes%,taps%,Null,mesh,sprite,wind)
For Node.TNode=Each TNode
Delete Node
Next
Return mesh
End Function

Function UpdateWind(speed#=1,force#=10,independent%=True,trees%=True)
Local val#
For VLeaves.TLeaves=Each TLeaves
val=windpr
If independent Then
SeedRnd(VLeaves\par)
val=val+Rnd(0,360)
EndIf
RotateSprite VLeaves\sprite,Sin(val)*force
RotateEntity VLeaves\par,Sin(val)*force,0,Cos(val)*force
Next
windpr=(windpr+speed) Mod 360
End Function

Function FreeTree(entity%)
If entity<>0 Then
For VLeaves.TLeaves=Each TLeaves
If VLeaves\par=entity Then
FreeEntity VLeaves\sprite
Delete VLeaves
EndIf
Next
FreeEntity entity
EndIf
End Function



Function CreateTreeNode(x#,y#,z#,pitch#,yaw#,height#,fac#,nodes%,i%,pre.TNode,mesh,sprite,wind)
If nodes<=0 Or i<=0 Then Return
If pre=Null Then
pre.TNode=New TNode
pre\x=x
pre\y=y
pre\z=z
pre\pre=Null
CreateTreeNode(pre\x,pre\y,pre\z,pitch,yaw,height*fac,fac*Rnd(0.9,1.1),nodes-1,i,pre,mesh,sprite,wind)
Else
pivot=CreatePivot()
For ii%=1 To i
Node.TNode=New TNode
Node\pre=pre
r#=Rnd(0.25,1)
PositionEntity pivot,x,y,z
RotateEntity pivot,r*60*fac+pitch,((ii-1)/Float(i))*360*Rnd(0.9,1.1)+yaw,0,1
MoveEntity pivot,0,height*r,0
Node\x=EntityX(pivot)
Node\y=EntityY(pivot)
Node\z=EntityZ(pivot)
If sprite Then
sprite=CopyEntity(sprite,mesh)
ScaleSprite sprite,1*fac,1*fac
PositionEntity sprite,Node\x,Node\y,Node\z
EntityColor sprite,Rand(155,255),Rand(155,255),Rand(155,255)
If wind Then
VLeaves.TLeaves=New TLeaves
VLeaves\sprite=sprite
VLeaves\par=mesh
EndIf
EndIf
CreateTreeNode(Node\x,Node\y,Node\z,VectorPitch(Node\x-pre\x,Node\y-pre\y,Node\z-pre\z),VectorYaw(Node\x-pre\x,Node\y-pre\y,Node\z-pre\z),height*fac,fac*Rnd(0.9,1.1),nodes-1,i,Node,mesh,sprite,wind)
cc=CLine3D(Node\x,Node\y,Node\z,pre\x,pre\y,pre\z,height*0.01,3)
AddMesh cc,mesh
FreeEntity cc
Next
FreeEntity pivot
EndIf
End Function

Function CLine3D(x1#,y1#,z1#,x2#,y2#,z2#,r#=1,segments=32)
cc=CreateCylinder(segments)
p=CreatePivot()
pp=CreatePivot()
PositionEntity p,x2,y2,z2
PositionEntity pp,x1,y1,z1
PointEntity pp,p
TurnEntity pp,90,0,0
MoveEntity pp,0,CSeglen3D#(x1,y1,z1,x2,y2,z2)/2,0
ScaleMesh cc,r#,CSeglen3D#(x1,y1,z1,x2,y2,z2)/2,r#
RotateMesh cc,EntityPitch(pp,1)+180,EntityYaw(pp,1),EntityRoll(pp,1)
PositionMesh cc,EntityX(pp,1),EntityY(pp,1),EntityZ(pp,1)
FreeEntity p
FreeEntity pp
Return cc
End Function

Function CSeglen3D#(x#,y#,z#,x2#,y2#,z2#)
Return Sqr((x#-x2#)*(x#-x2#)+(y#-y2#)*(y#-y2#)+(z#-z2#)*(z#-z2#))
End Function

Type TLeaves
Field sprite%
Field par%
End Type

Type TNode
Field x#,y#,z#
Field pre.TNode
End Type


Und auchnoch der Beispielcode (Die benötigten Dateien liegen dem Download bei):
BlitzBasic: [AUSKLAPPEN]
;Grafik initiieren
Graphics3D 800,600,32,2
SetBuffer BackBuffer()

;Die FreeTree-Funktionen einbinden
Include "FreeTreeLib.bb"

;Kamera erstellen und ausrichten/anpassen
pcam%=CreatePivot()
cam%=CreateCamera(pcam)
CameraRange cam,0.5,200
CameraFogRange cam,0,150
CameraClsColor cam,200,240,255
CameraFogColor cam,200,240,255
CameraFogMode cam,1
MoveEntity pcam,0,4,0
MoveEntity cam,0,0,-20

;Licht reinbauen
light%=CreateLight(1)
MoveEntity light,0,10,0

;Zufall sicherstellen, Timer erstellen und FPS-Variable definieren
SeedRnd MilliSecs()
timer=CreateTimer(60)
fps#=60

;Variblen die das Gras (aus den Samples)
Global length%=20,ystep#=0.01,an#
Dim plane%(length-1)

;Skybox und Gras erstellen (aus den Samples)
mesh_skybox%=MakeSkyBox("data\sky")
ScaleEntity mesh_skybox,0.75,0.75,0.75
tex%=LoadTexture("data\Ground.bmp",1+8+256)
ScaleTexture tex,50,50
tex1%=LoadTexture("data\GrassClip.bmp",1+2+8)
ScaleTexture tex1,4,4
ground%=CreatePlane(1)
EntityTexture ground,tex
EntityFX ground,1
For a#=0 To length-1
plane(a)=CreatePlane()
EntityTexture plane(a),tex1
PositionEntity plane(a),0,+(a*ystep),0
EntityColor plane(a),100,120+((a/(length-1))*135),80
EntityAlpha plane(a),0.9
Next




;FreeTreeLib wird ausschließlich hier verwendet!-------

;Sprites die die Blätter darstellen laden
Dim leaves(10)
For i=0 To 9
leaves(i)=LoadSprite("data\leaves"+i+".png",1+2+8+256)
Next

;Die Textur für den Baumstamm laden
tree_tex=LoadTexture("data\trunk.jpg",1+8+256)

;In einer kleinen Schleife die Bäume erstellen
For i=1 To 100

;Zufälliger Winkel aud Radius für die Baumposition bestimmen
w#=Rnd(0,360)
l#=Rnd(0,40)

;Baum erstellen. Es wird der Baum als Mesh zurückgegeben, wenn ein Sprite für Blätter
;angegeben wurde wird dieses an alle Verzweigungen kopiert (außer an der Untersten)
;CreateTree%(X#, Y#, Z#, Startlänge#, Änderungsfaktor#, Durchgänge%, Verzweigungen%[,Sprite%=0 ,Parent%=0, Wind%=True])
tree=CreateTree(Cos(w)*l,0,Sin(w)*l,4,0.8,Rand(2,4),3,leaves(Rand(0,9)))

;Die Baumtextur auf den Baum bringen und zufällig etwas einfärben
EntityTexture tree,tree_tex
EntityColor tree,Rand(200,255),Rand(200,255),255
Next

;So, die Bäume wären erstellt und die Blätter schon alle dazukopiert, nun können die Blätter-
;Sprites gelöscht werden
For i=0 To 9
FreeEntity leaves(i)
Next

;Ende der FreeTreeLib-Bnutzung!----------------------




;Hautpschleife
While(Not KeyHit(1))
;Cls und Zeitmesser für FPS
Cls
ms=MilliSecs()

;Das Gras updaten (aus den Samples)
an=an+4:If an>359 Then an=0
s#=Cos(an)/15000
For b=0 To length-1
MoveEntity plane(b),s*(b^1.5),0,s*(b^1.5)*0.5
Next

;Eine kleine Maussteuerung
mx=MouseX():my=MouseY():mz=MouseZ()
msx=MouseXSpeed():msy=MouseYSpeed():msz=MouseZSpeed()
If MouseDown(2) Then
sx#=msx*0.05+sx*0.95
sy#=msy*0.05+sy*0.95
EndIf
sz#=sz+msz*0.5
sx#=sx/1.08
sy#=sy/1.08
sz#=sz/1.08
TurnEntity pcam,sy/4.0,0,0
TurnEntity pcam,0,-sx/4.0,0,1
MoveEntity cam,0,0,sz
If EntityY(cam,1)<-45 Then
sy=Abs(sy)+0.1
TurnEntity pcam,sy/4.0,0,0
EndIf

;Den Wind von FreeTree winden lassen
;UpdateWind([speed#=1, force#=10, independet%=True, trees%=True])
UpdateWind(1,5)

;3D-Welt updaten und zeichnen
UpdateWorld()
RenderWorld()

;Die Texte ausgeben
Color 40,40,40
Text 0,0,TrisRendered()+" Tris"
Text 0,14,fps+" FPS"

;Flip, fps berechnen und auf Timer warten
Flip()
fps=1000.0/(MilliSecs()-ms)*0.1+fps*0.9
WaitTimer(timer)
Wend

End





Function MakeSkyBox(file$) ;Standartfunktion (aus den Samples)
m=CreateMesh()
;front face
b=LoadBrush( file$+"_FR.bmp",49 )
s=CreateSurface( m,b )
AddVertex s,-1,+1,-1,0,0:AddVertex s,+1,+1,-1,1,0
AddVertex s,+1,-1,-1,1,1:AddVertex s,-1,-1,-1,0,1
AddTriangle s,0,1,2:AddTriangle s,0,2,3
FreeBrush b
;right face
b=LoadBrush( file$+"_LF.bmp",49 )
s=CreateSurface( m,b )
AddVertex s,+1,+1,-1,0,0:AddVertex s,+1,+1,+1,1,0
AddVertex s,+1,-1,+1,1,1:AddVertex s,+1,-1,-1,0,1
AddTriangle s,0,1,2:AddTriangle s,0,2,3
FreeBrush b
;back face
b=LoadBrush( file$+"_BK.bmp",49 )
s=CreateSurface( m,b )
AddVertex s,+1,+1,+1,0,0:AddVertex s,-1,+1,+1,1,0
AddVertex s,-1,-1,+1,1,1:AddVertex s,+1,-1,+1,0,1
AddTriangle s,0,1,2:AddTriangle s,0,2,3
FreeBrush b
;left face
b=LoadBrush( file$+"_RT.bmp",49 )
s=CreateSurface( m,b )
AddVertex s,-1,+1,+1,0,0:AddVertex s,-1,+1,-1,1,0
AddVertex s,-1,-1,-1,1,1:AddVertex s,-1,-1,+1,0,1
AddTriangle s,0,1,2:AddTriangle s,0,2,3
FreeBrush b
;top face
b=LoadBrush( file$+"_UP.bmp",49 )
s=CreateSurface( m,b )
AddVertex s,-1,+1,+1,0,1:AddVertex s,+1,+1,+1,0,0
AddVertex s,+1,+1,-1,1,0:AddVertex s,-1,+1,-1,1,1
AddTriangle s,0,1,2:AddTriangle s,0,2,3
FreeBrush b
ScaleMesh m,100,100,100
FlipMesh m
EntityFX m,9
EntityOrder m,10
Return m
End Function


Viel Spaß wünsche ich euch damit in der Hoffnung, dass Ihr damit Etwas anfangen könnt Wink .

lg Diedel
  • Zuletzt bearbeitet von Diedel am Sa, Nov 06, 2010 15:18, insgesamt 6-mal bearbeitet
 

vanjolo

BeitragSo, Mai 10, 2009 18:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Find ich, kurz und knapp, sowas von Genial!!


Ich habe oft das Problem das ich mal schnell eine neues Modell in eine Landschaft setzen möchte um zu sehen wie das Model wirkt. Für mich ist das wirklich hilfreich!

Danke Diedel
***************************
in Entwicklung:
Tank Battles - Panzeraction
Pacific Battles - Rundenstrategie
abgeschlossenes Projekt: Harrier Assault
 

aletes

BeitragSo, Mai 10, 2009 18:50
Antworten mit Zitat
Benutzer-Profile anzeigen
hmm, das sieht echtmal wirklich gut aus Very Happy
kann ich noch gut gebrauchen

Diedel

BeitragSo, Mai 10, 2009 19:42
Antworten mit Zitat
Benutzer-Profile anzeigen
So, neue Version wäre hochgeladen. Nun mit erster Windunterstützung, mal sehen ob ich meine ganzen Ideen diesbezüglich noch so umsetzen kann ich ich es mir vorstelle. Den ersten Beitrag habe ich dementsprechend editiert, also ab nach oben Wink .

Ich vergaß noch die Steuerung im Sample zu erklären auch wenn sie schnell gefunden sein dürfte:
Mit dem Mausrad kann man schön zoomen, mit Hilfe der rechten Maustaste kann man wenn sie gedrückt wird durch Bewegungen der Maus die kamera um den Mittelpunkt des Ganzen drehen Smile.

So, der erste Beitrag wäre nun auchnoch den Regeln des Codearchivs angepasst Rolling Eyes.
Achja, die einzelnen Bäume/das, was bei CreateTree%(...) als Mesh zurückgegeben wird, ist SingleSurface, nur damit Ihr euch da möglicherweise nicht umsonst um etwas bemüht was bereits drinn ist Idea.

lg Diedel
Owned.

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group