Seite 1 von 1

SphereMapping für 3D Objekte mit fehlenden UV Werten

Verfasst: 16.04.2009 22:08
von mpz
Hallo Leute,

ich habe mich gerade mit "SphereMapping" beschäftigt. D.h. wie kann ich auf ein kugelförmiges Mesh welches nur aus Vertices mit x,y,z Koordinaten besteht eine Textur richtig raufmappen. Eine einfache Prozedur habe ich gefunden und eine weitere Prozedure entwickelt die aus den x,y Werten eines X,Y Systems eine Winkelangabe in Grad erzeugt. Diese wird dann durch 360 Grad geteilt und ich habe ein Wertesystem von 0 bis 1 = UV Mapping.

Die meisten fragen sich wozu benötige ich dieses Zeug? Nun mit der MP_AngleCalculation(x,y) kann man den Winkel von zwei Punkten errechnen und bei runden Meshs auch die UV Koodinaten ermitteln. Damit ist es möglich verschiedene Objekte die nach mathematischen Algorhytmen erzeugt wurden oder aber auch fertige Mesh zu laden und nachträglich eine Texturrierung durchzuführen. Ein PB Ogre Mesh Beispiel kann ich nicht beiliegen, da ich nicht an die Vertices von geladenen Meshs in PB Ogre rankomme.

Eine kleine "Studie" als Beispiel mit meiner Engine als Windows Exe liegt bei.

Hier die 2D Anwendung, Winkelberechnung von zwei Punkten im xy System

Code: Alles auswählen

; Einfache Winkelberechnung von Punkten

Procedure MP_AngleCalculation (x1.f,y1.f) ; Winkelangabe von 0,0 Koodinaten aus gesehen

If x1 = 0 
   	If y1 > 0  
   	  AktTan.f = 350
   	Else
   	  AktTan.f = -350
   	EndIf
Else
    AktTan.f = y1 / x1
EndIf

  Winkel=Round((180.0/#PI)*(ATan(AktTan)),#PB_Round_Nearest);

  If x1 < 0 
     Winkel + 180
  Else
    If y1 < 0
       Winkel + 360
    EndIf   
  EndIf

  ProcedureReturn Winkel

EndProcedure


; Definiere Zwei Punkte

x1 = 3
y1 = 5

x2 = 12
y2 = -4

;Zur Berechnung x1,y1 auf Nullpunkt schieben 

Rx1 = x2 - x1
Ry1 = y2 - y1

Debug "Winkelangabe von x1,y1 nach x2,y2 = " + Str(MP_AngleCalculation (Rx1,Ry1)) + " Grad"
Hier die 3D Anwendung, Texturrierung von Objekten

Den erste Algorythmus findet man hier
http://www.mvps.org/directx/articles/spheremap.htm

Code: Alles auswählen

For n = 0 To MP_CountVertices(Sphere1)-1 ; Anzahl der Vertices ermitteln
        x.f = MP_VertexX (Sphere1,n) ; ließt x Wert eines Vertices
        y.f = MP_VertexY (Sphere1,n) ; ließt y Wert eines Vertices
        MP_SetVertexU (Sphere1,n, ASin(x)/#PI+0.5)  ; Alternate fast methodic = x*0.5+0.5 
        ;schreibt U Wert eines Vertices
        MP_SetVertexV (Sphere1,n, ASin(-y)/#PI+0.5) ; Alternate fast methodic = -y*0.5+0.5
        ;schreibt V Wert eines Vertices
Next
Der zweite Algorythmus

Code: Alles auswählen

For n = 0 To MP_CountVertices(Sphere2)-1

        x.f = MP_VertexX (Sphere2,n) ; ließt x Wert eines Vertices
        y.f = MP_VertexY (Sphere2,n) ; ließt y Wert eines Vertices
        z.f = MP_VertexZ (Sphere2,n) ; ließt z Wert eines Vertices
 
        MP_SetVertexU (Sphere2,n, MP_AngleCalculation(x,z)/360) ; Schreibt U Wert, Winkel /360 = Wert 0 bis 1
        MP_SetVertexV (Sphere2,n, ASin(-y)/#PI+0.5)             ; Schreibt V Wert
        
Next
Beispielcode mit MP3D Library
http://rapidshare.de/files/46765015/Mapping.exe.html

Code: Alles auswählen


;////////////////////////////////////////////////////////////////
;//
;// Project Title: MP 3D Engine
;// File Title: Bewegende Objekte2.pb
;// Created On: 16.4.2008
;// Updated On: 
;// Author: Michael Paulwitz
;// OS:Windows
;// 
;// Objekte mit UV Koordinaten versehen
;//
;// http://www.mvps.org/directx/articles/spheremap.htm
;//
;////////////////////////////////////////////////////////////////

;-
;- ProgrammStart

Procedure MP_AngleCalculation (x1.f,y1.f) ; Winkelangabe von 0,0 Koodinaten aus gesehen

If x1 = 0 
   	If y1 > 0  
   	  AktTan.f = 350
   	Else
   	  AktTan.f = -350
   	EndIf
Else
    AktTan.f = y1 / x1
EndIf

  Winkel=Round((180.0/#PI)*(ATan(AktTan)),#PB_Round_Nearest);

  If x1 < 0 
     Winkel + 180
  Else
    If y1 < 0
       Winkel + 360
    EndIf   
  EndIf

  ProcedureReturn Winkel

EndProcedure

MP_Graphics3D (640,480,0,3) ; Erstelle ein WindowsFenster #Window = 0
SetWindowTitle(0, "2 Methodics for Spherical Mapping with x,y,z Coords") ; So soll es heissen

camera=MP_CreateCamera() ; Kamera erstellen
light=MP_CreateLight(1) ; Es werde Licht

If CreateImage(0, 255, 255)

    Font = LoadFont(#PB_Any, "Arial"  , 138) 
    StartDrawing(ImageOutput(0))

    Box(0, 0, 128, 128,RGB(255,0,0))
    Box(128, 0, 128, 128,RGB(0,255,0))
    Box(0, 128, 128, 128,RGB(0,0,255))
    Box(128, 128, 128, 128,RGB(255,255,0))

    DrawingFont(FontID(Font))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(73,35,"5")
  
    StopDrawing() ; This is absolutely needed when the drawing operations are finished !!! Never forget it !
    
EndIf

;Create Sphere
Sphere1 = MP_CreateSphere(12)
Sphere2 = MP_CreateSphere(12)
Teapot1 = MP_CreateTeapot()
Teapot2 = MP_CreateTeapot() ; Yes teapot not Sphere

MP_PositionEntity (Sphere1,-1.5,1.3,6 )
MP_PositionEntity (Sphere2,1.5,1.3,6 )
MP_PositionEntity (Teapot1,-1.5,-1.3,6 )
MP_PositionEntity (Teapot2,1.5,-1.3,6 )

;- Create Sphere1 Methodic 1, UV coordinate is calculated from the XY coordinate, with ASin   
For n = 0 To MP_CountVertices(Sphere1)-1
        x.f = MP_VertexX (Sphere1,n)
        y.f = MP_VertexY (Sphere1,n)
        MP_SetVertexU (Sphere1,n, ASin(x)/#PI+0.5)  ; Alternate fast methodic = x*0.5+0.5 
        MP_SetVertexV (Sphere1,n, ASin(-y)/#PI+0.5) ; Alternate fast methodic = -y*0.5+0.5
Next

;- Sphere2 with Methodic 2, UV coordinate is calculated with from the XY coordinate  
For n = 0 To MP_CountVertices(Sphere2)-1

        x.f = MP_VertexX (Sphere2,n)
        y.f = MP_VertexY (Sphere2,n)
        z.f = MP_VertexZ (Sphere2,n)
 
        MP_SetVertexU (Sphere2,n, MP_AngleCalculation(x,z)/360)
        MP_SetVertexV (Sphere2,n, ASin(-y)/#PI+0.5)
        
Next

;- Create Teapot and make you own uv Mapping
For n = 0 To MP_CountVertices(Teapot1)-1

        x.f = MP_VertexX (Teapot1,n)
        y.f = MP_VertexY (Teapot1,n)
        z.f = MP_VertexZ (Teapot1,n)
 
        MP_SetVertexU (Teapot1,n, ASin(x)/#PI+0.5) 
        MP_SetVertexV (Teapot1,n, ASin(-y)/#PI+0.5)
        
Next

;- Create Teapot and make you own uv Mapping
For n = 0 To MP_CountVertices(Teapot2)-1

        x.f = MP_VertexX (Teapot2,n)
        y.f = MP_VertexY (Teapot2,n)
        z.f = MP_VertexZ (Teapot2,n)
 
        MP_SetVertexU (Teapot2,n, MP_AngleCalculation(x,z)/360) 
        MP_SetVertexV (Teapot2,n, ASin(-y)/#PI+0.5)

Next

Texture = MP_ImageToTexture(0,0) ; Create Texture from image 

MP_EntityTexture (Sphere1, Texture ) ; textur to mesh
MP_EntityTexture (Sphere2, Texture ) ; textur to mesh
MP_EntityTexture (Teapot1, Texture ) ; textur to mesh
MP_EntityTexture (Teapot2, Texture ) ; textur to mesh

While Not MP_KeyDown(#PB_Key_Escape) And Not MP_WindowEvent() = #PB_Event_CloseWindow; Esc abfrage oder schliessen
  
    MP_TurnEntity (Sphere1,1,0,0.1) ; Moving Sphere
    MP_DrawText (10,10,MP_ARGB(255,255,255,255),"method 1"+Chr(10)+"Sphere") 

    MP_TurnEntity (Sphere2,1,0,0.1) ; Moving Sphere
    MP_DrawText (320,10,MP_ARGB(255,255,255,255),"method 2"+Chr(10)+"Sphere") 

    MP_TurnEntity (Teapot1,1,0,0.1) ; Moving Sphere
    MP_DrawText (10,240,MP_ARGB(255,255,255,255),"method 1 used on not Sphere Objekt") 

    MP_TurnEntity (Teapot2,1,0,0.1) ; Moving Sphere
    MP_DrawText (320,240,MP_ARGB(255,255,255,255),"method 2 used on not Sphere Objekt") 
    
    MP_RenderWorld () ; Hier gehts los
    MP_Flip () ; 

Wend

End