Vektoren / Vertexnormal in Kugel

Übersicht BlitzBasic Blitz3D

Neue Antwort erstellen

 

Krischan

Betreff: Vektoren / Vertexnormal in Kugel

BeitragMo, Aug 10, 2009 15:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Mal eine Verständnisfrage:

Ich habe eine perfekte Kugel (keine B3D Sphere - ist zusammengesetzt aus 24 einzelnen Patches!) bei der ich alle Vertexkoordinaten in einer Schleife durchgehe. Ich möchte jetzt die UpdateNormals-Funktion umgehen (wegen der unschönen Patchränder bei der Beleuchtung) und jeden Vertexnormal direkt berechnen.

Das Zentrum der Kugel ist bei 0,0,0 und der Radius ist 1. Es ändern sich also nur die Vertexkoordinaten. Wie muss die Formel aussehen, damit ich für jeden X,Y,Z Vertexpunkt die NX/NY/NZ Werte herausfinde? Ich vermute die Lösung ist sehr einfach, komme aber nicht drauf...

ToeB

BeitragMo, Aug 10, 2009 16:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Kann man das nicht mit Winkel machen oder verstehe ich da was nicht ?

Also so :
Code: [AUSKLAPPEN]
nx# = Atan2(vy,vz)
ny# = Atan2(vx,vz)
nz# = Atan2(vy,vx)


Musste mal testen...

mfg ToeB
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!

darth

BeitragMo, Aug 10, 2009 16:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Bei einer Perfekten Kugel ist jeder Punkt gleich weit weg vom Mittelpunkt. (Ist ja klar...)

Ich verstehe nicht genau was du mit dem Patches meinst (eine Perfekte Kugel hat keine Trigs, meiner Meinung nach), aber prinzipiell lässt sich sagen:
die Normale jedes Punktes ist einfach der Vektor vom Mittelpunkt zu dem Vertex.

Wenn du die Allgemeine Normale des Trigs (=Patch?) willst, dann ist das das Kreuzprodukt zweier Vektoren auf dieser Trig-Ebene, aber das wird mit Vertex-Normals auch so berechnet, also nehme ich nicht an, dass du das willst.

Von daher würde ich bei der Behauptung stehen: nimm einfach den Vektor vom Mittelpunkt zum Vertex, der steht senkrecht auf der Tangentialebene zur Kugel an diesem Punkt.
Diese Signatur ist leer.
 

Krischan

BeitragMo, Aug 10, 2009 16:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Klappt so nicht bzw. verstehe ich bei darth nur Bahnhof. Ich geb Euch mal den Code, es handelt sich hierbei um einen etwas anderen, vertexbasierenden Planetengenerator. Es ist etwas schwer zu erklären und ich lasse das wieso und warum ich das so gemacht habe mal weg aber es macht durchaus Sinn, glaubt mir Smile

Stellt Euch einen unterteilten Würfel vor, der aus 6 Seiten besteht, jede Seite ist bei mir ein Patch mit X*X Vertices (also z.B: 32x32). Nehmt drei der Seiten weg und kopiert und ordnet diesen dreiseitigen Teilwürfel so an, dass aus 8 dieser Würfel wieder ein neuer, grosser Würfel entsteht (also nur die Aussenseiten). Dieser Würfel bzw. die einzelnen Patches werden dann mittels einer Funktion "spherized", so dass nachher aus 24 Patches ein perfekte Kugel entsteht, je nach Patchgrösse mehr oder weniger detailliert. Und dass das auch klappt könnt ihr sehen wenn Ihr den Code ausführt Shocked

Lange Rede kurze Sinn: wir haben also einen Haufen Vertices im Raum die eine Kugel bilden und ich diese blöden Nahtstellen zwischen den Patches loswerden will. Wenn man eine size von 64 oder 128 ansetzt gehen die zwar auch weg aber nur weil sie dann zu klein sind um sichtbar zu sein.

Hier der auf das wesentliche reduzierte Code, die Normalberechnung sollte in der Funktion CalcSphereNormals() stattfinden, darin befindet sich auch schon der auskommentierte Teilcode von ToeB. Mit der Maus und den Pfeiltasten könnt Ihr die Kugel drehen oder näher ran / weiter weg (und wie immer bei mir: SPACE = Wireframe)

Code: [AUSKLAPPEN]
ms=MilliSecs()

Const size=16
Global maps%=0
Local patch[2]

Dim VertexBuffer%(128,128),MeshPart%(23)

Graphics3D 800,600,32,2

; planet pivot
pivot=CreatePivot()
campivot=CreatePivot()

cam=CreateCamera(campivot)
PositionEntity cam,3,2,-5
CameraRange cam,0.1,120
CameraZoom cam,3

patch[0]=CreatePatch(size,1.0/(size)) : RotateMesh patch[0],  0,180,  0 : PositionMesh patch[0],0.5,0.5,-0.5
patch[1]=CreatePatch(size,1.0/(size)) : RotateMesh patch[1],  0,270,  0 : PositionMesh patch[1],0.5,0.5,-0.5
patch[2]=CreatePatch(size,1.0/(size)) : RotateMesh patch[2],270,  0,  0 : PositionMesh patch[2],0.5,0.5,-0.5

For i=0 To 7
   
   For j=0 To 2
      
      If counter<12 Then
         MeshPart(counter)=AddSpherePart(patch[j],pivot,  0, i*90,0)
      Else
         MeshPart(counter)=AddSpherePart(patch[j],pivot,180, i*90,0)
      EndIf
      
      counter=counter+1
      
   Next
   
Next

FreeEntity patch[0]
FreeEntity patch[1]
FreeEntity patch[2]

CalcSphereNormals()

; light source
light=CreateLight(1)
AmbientLight 16,16,16

MoveMouse 400,300

ende=MilliSecs()-ms

While Not KeyHit(1)
   
   If KeyHit(57) Then wf=1-wf : WireFrame wf
   
   ; turn planet with mouse
   mxs#=MouseXSpeed()
   mys#=MouseYSpeed()
   TurnEntity pivot,0,-0.005+mxs,0
   TurnEntity campivot,mys,0,mys
   MoveEntity cam,(KeyDown(205)-KeyDown(203))*2.0/30,0,(KeyDown(200)-KeyDown(208))*1.0/30
   PointEntity cam,pivot
   
   RenderWorld
   
   Text 0, 0,"Tris.......: "+TrisRendered()
   Text 0,15,"Calc time..: "+ende+"ms"
   
   Flip 1
   
Wend

End

Function AddSpherePart(mesh%,pivot%,rx#=0,ry#=0,rz#=0)
   
   Local m%=CopyMesh(mesh,pivot)
   Cube2Sphere(m)
   EntityFX m,2
   RotateMesh m,rx,ry,rz
   
   maps=maps+1
   
   Return m
   
End Function
   
; calculate spherical X
Function SphericalX#(x#,y#,z#)
   
   Return x*Sqr(1.0-y*y*0.5-z*z*0.5+y*y*z*z*1.0/3)
   
End Function

; calculate spherical Y
Function SphericalY#(x#,y#,z#)
   
   Return y*Sqr(1.0-z*z*0.5-x*x*0.5+z*z*x*x*1.0/3)
   
End Function

; calculate spherical Z
Function SphericalZ#(x#,y#,z#)
   
   Return z*Sqr(1.0-x*x*0.5-y*y*0.5+x*x*y*y*1.0/3)
   
End Function

; transform a cube patch to sphere patch
Function Cube2Sphere(mesh%)
   
   Local s%,surf%,v%
   Local vx#,vy#,vz#
   
   For s=1 To CountSurfaces(mesh)
      
      surf=GetSurface(mesh,s)
      
      For v=0 To CountVertices(surf)-1
         
         vx=VertexX(surf,v)
         vy=VertexY(surf,v)
         vz=VertexZ(surf,v)
         
         VertexCoords surf,v,SphericalX(vx,vy,vz),SphericalY(vx,vy,vz),SphericalZ(vx,vy,vz)
         
      Next
      
   Next
   
End Function


Function CalcSphereNormals()
   
   For i=0 To maps-1
      
      surf=GetSurface(MeshPart(i),1)
      
      For v=0 To CountVertices(surf)-1
         
         VertexColor surf,v,255,255,255
         
         vx#=VertexX(surf,v)
         vy#=VertexY(surf,v)
         vz#=VertexZ(surf,v)
         
         ;nx# = ATan2(vy,vz)
         ;ny# = ATan2(vx,vz)
         ;nz# = ATan2(vy,vx)
         ;VertexNormal surf,v,nx,ny,nz
         
      Next
      
      UpdateNormals MeshPart(i)
      
   Next
      
End Function

Function CreatePatch(size%,scale#)
   
   Local x%,z%,v#,u#,v0%,v1%,v2%,v3%
   
   ; create mesh and surface
   Local mesh%=CreateMesh()
   Local surf%=CreateSurface(mesh)
   
   For z=0 To size
      
      For x=0 To size
         
         ; calculate uv coordinates that the texture fits to the tile
         u=x*1.0/size
         v=z*1.0/size*-1
         
         ; set vertexposition
         VertexBuffer(x,z)=AddVertex (surf,-((size)/2.0)+x,-((size)/2.0)+z,size/2,u,v)
         VertexColor surf,VertexBuffer(x,z),255,255,255,1.0
         
      Next
      
   Next
   
   ; set triangles
   For z=0 To size-1
      
      For x=0 To size-1
         
         v0=VertexBuffer(x,z)
         v1=VertexBuffer(x+1,z)
         v2=VertexBuffer(x+1,z+1)
         v3=VertexBuffer(x,z+1)
         
         AddTriangle (surf,v0,v2,v1)
         AddTriangle (surf,v0,v3,v2)
         
      Next
      
   Next
   
   ; position, scale and fx
   ScaleMesh mesh,scale,scale,scale
   
   FlipMesh mesh
   
   Return mesh
   
End Function

Noobody

BeitragMo, Aug 10, 2009 17:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie Darth bereits erklärte, ist bei einer Kugel die Normale eines Vertex einfach der Vektor vom Mittelpunkt zum Vertex Razz

Deine Funktion sähe also folgendermassen aus Code: [AUSKLAPPEN]
Function CalcSphereNormals()
   For i=0 To maps-1
      surf=GetSurface(MeshPart(i),1)
      
      For v=0 To CountVertices(surf)-1
         VertexColor surf,v,255,255,255
         
         VX#=VertexX(surf,v)
         VY#=VertexY(surf,v)
         VZ#=VertexZ(surf,v)
         
         TFormNormal VX#, VY#, VZ#, 0, 0
         VertexNormal surf,v, TFormedX(), TFormedY(), TFormedZ()
      Next
   Next
End Function


Das TFormNormal habe ich da reingeschrieben, damit der Richtungsvektor von Mittelpunkt zu Vertex sicher die Länge 1 hat, da du ansonsten unter Umständen Grafikfehler bekommst.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun
 

Krischan

BeitragMo, Aug 10, 2009 17:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja super, genau das ist es! Ich wusste es hat was mit Tformdingsbums zu tun, stehe aber mit Vektoren immer ein wenig auf Kriegsfuss Rolling Eyes Zum Glück sind Planeten rund (wobei ich mir, seit ich dieses Programm geschrieben habe, sicher bin dass wir auf einem Würfel leben, der bloss zu einer Kugel verzerrt wurde) Very Happy

Neue Antwort erstellen


Übersicht BlitzBasic Blitz3D

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group