Mausbewegungen umrechnen

Übersicht BlitzBasic Blitz3D

Neue Antwort erstellen

derAtomkeks

ehemals "Sethus"

Betreff: Mausbewegungen umrechnen

BeitragDo, Okt 20, 2011 12:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo zusammen,

ich würde meinen Worldeditor gerne etwas benutzerfreundlicher gestalten:
Dafür sollen Verschiebungen sowohl von Texturen als auch von Meshes per Maus präzise gesteuert werden können.
Dafür soll natürlich die Perspektive der Kamera berücksichtigt werden.

Wenn ein von der Kamera sehr weit entferntes Objekt zur Seite bewegt werden soll, muss es natürlich stärker bewegt werden, als ein sich direkt vor der Kamera befindliches Objekt.

Bei Texturen und Rotation von Objekten wirds noch schwieriger: Hier muss ja nicht nur die Distanz, sondern auch die Neigung der gepickten Oberfläche zur Kamera, sowie deren Rotation berücksichtigt werden.

Ich will also quasi den einen Punkt, den ich mit der Maus greife, festhalten und (auf einer vorher im Editor festgelegten Achse) verschieben / drehen können.

Ich habe schon einiges ausprobiert mit den blitzinternen Koordinatentransformations-Funktionen, bin dabei aber noch nicht auf den grünen Zweig gekommen.

Ich hoffe ich habe das Problem verständlich genug formuliert und ihr könnt mir helfen! Smile

Jan_

Ehemaliger Admin

BeitragDo, Okt 20, 2011 12:34
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzBasic: [AUSKLAPPEN]
CameraPick()
PickedX()
PickedY()
PickedZ()


Daraus bekommst du die 3D Verschiebung der Maus, wenn du das über 2Sachen machst.
Rotation sollte ja egal sein, weil die ja entfernungsunabhängig ist.

kleiner Tip noch: 3D Pytagoras:
Code: [AUSKLAPPEN]
entfernung#=sqr((xneu-xalt)^2+(yneu-yalt)^2+(zneu-zalt)^2)


Lg. Jan_
between angels and insects

Midimaster

BeitragDo, Okt 20, 2011 13:41
Antworten mit Zitat
Benutzer-Profile anzeigen
naja....
Wenn du mit dem CameraPick() arbeitest, erhältst du ja drei wichtige Angaben:

PickedEntity()

damit weißt du welches Objekt du anvisierst hast. Da du dich ja entschieden hast, die gültige Achse vorher festzulegen, musst Du das Entity jetzt nur nur im Bezug der World-Koordinaten() bewegen. Dazu wirst Du auswerten müssen wie sich seit dem Pick die Maus bewegt hat.

Willst Du drehen, dann wäre es vielleicht klug, statt der World()-Lage des Objektes, in der Fortsetzung gleich mit dem lokalen Koordinatensystem zu arbeiten. So dreht sich das Objekt bei einer y-Drehung um "seine" y-Achse.

PickedSurface()

liefert dir gleich mal die Oberfläche, die auf dem Entity vom Pick getroffen wurde. Um nun die Texturen zu verschieben, würde ich gar nicht die World() umrechnen, sondern in der Fortsetzung gleich nur mit dem lokalen Koordinatensystem der Surface arbeiten. Da gibt es dann nur U und V (wie X und Y). So würde ich das auch als User erwarten
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

derAtomkeks

ehemals "Sethus"

BeitragDo, Okt 20, 2011 20:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke ihr beiden, aber leider ist das alles nichts neues für mich. Das Problem ist, dass ich die Linie der Differenz der 3D-Koordinaten der Maus-Picks in eine 2D-Linie auf der gepickten Surface umwandeln muss, damit die Verschiebung auch bei Rotation des Objektes bzw. anderer Perspektive der Kamera auch passt.
Mittlerweile habe ich durch ausprobieren das Ganze für einen 1x1x1 großen Cube hinbekommen.
Hier mal mein Code soweit dazu (Pfeiltasten - Objekt drehen, Mausklick - Surface auswählen, Maus bewegen - Textur auf Surface verschieben ; Textur müsstet ihr noch ersetzen):

Code: [AUSKLAPPEN]
Graphics3D 640,480,0,2
SetBuffer BackBuffer()
camera=CreateCamera()
light=CreateLight(1)
RotateEntity light,90,0,0

Local brushWhite = CreateBrush(255, 255, 255)
Local brushRed   = CreateBrush()
Local tex = LoadTexture("D:\gras.jpg")
BrushTexture brushRed, tex
;cube = CreateCone(12)
cube=CSGAddMyMeshCubeX(0, -.5, -.5, -.5, .5, .5, .5, 0, 0, 0, brushWhite, brushWhite, brushWhite, brushWhite, brushWhite, brushWhite) ;CreateCube() ;cube()
EntityPickMode cube,2
EntityColor cube,200,200,250
PositionEntity cube,0,0,3
RotateEntity cube,0,0,0

Local iSelectedSurf
Local fMovU#
Local fMovV#

Local fLastX#, fLastY#, fLastZ#
Local fCurrX#, fCurrY#, fCurrZ#
Local fNormX#, fNormY#, fNormZ#
Local fFacX#, fFacY#, fFacZ#

While Not KeyDown(1)
   
   If KeyDown(200) Then TurnEntity cube,  0.5, 0,   0
   If KeyDown(208) Then TurnEntity cube, -0.5, 0,   0
   If KeyDown(203) Then TurnEntity cube,  0,   0.5, 0
   If KeyDown(205) Then TurnEntity cube,  0,  -0.5, 0
   
   RenderWorld
   
   If MouseHit(1) Then
      CameraPick camera, MouseX(), MouseY()
      iSelectedSurf = PickedSurface()
      For i=1 To CountSurfaces(cube)
         If GetSurface(cube,i) <> iSelectedSurf Then
            PaintSurface GetSurface(cube,i), brushWhite
         Else
            PaintSurface iSelectedSurf, brushRed
         End If
      Next
   End If
   
   ent = CameraPick(camera, MouseX(), MouseY())
   
   If ent <> 0 Then
      
      TFormPoint PickedX#(), PickedY#(), PickedZ#(), 0, cube
      fCurrX# = TFormedX#()
      fCurrY# = TFormedY#()
      fCurrZ# = TFormedZ#()
      Text 0, 0, "Local dX: " + (fCurrX# - fLastX#)
      Text 0,15, "Local dY: " + (fCurrY# - fLastY#)
      Text 0,30, "Local dZ: " + (fCurrZ# - fLastZ#)
      
      TFormNormal PickedNX#(), PickedNY#(), PickedNZ#(), 0, ent
      fNormX# = TFormedX#()
      fNormY# = TFormedY#()
      fNormZ# = TFormedZ#()
      If (fNormX# < 0.01) And (fNormX# > -0.01) Then fNormX# = 0.0
      If (fNormY# < 0.01) And (fNormY# > -0.01) Then fNormY# = 0.0
      If (fNormZ# < 0.01) And (fNormZ# > -0.01) Then fNormZ# = 0.0
      Text 400, 0, "Local picked NX: " + fNormX#
      Text 400,15, "Local picked NY: " + fNormY#
      Text 400,30, "Local picked NZ: " + fNormZ#
      
      fMovU# = fNormZ# * (fCurrX# - fLastX#) - fNormX# * (fCurrZ# - fLastZ#) + Abs(fNormY#) * (fCurrZ# - fLastZ#)
      fMovV# = fNormY# * (fCurrX# - fLastX#) + (1-Abs(fNormY#)) * (fCurrY# - fLastY#)
      
      fLastX# = fCurrX#
      fLastY# = fCurrY#
      fLastZ# = fCurrZ#
      
   End If
   
   If iSelectedSurf <> 0 Then
      For i = 0 To CountVertices(iSelectedSurf) - 1
         VertexTexCoords iSelectedSurf, i, VertexU#(iSelectedSurf, i) + fMovU#, VertexV#(iSelectedSurf, i) + fMovV#
      Next
   End If
      
   Flip
Wend
End


Function CSGAddMyMeshCubeX(m,x1#,y1#,z1#,x2#,y2#,z2#,cx,cy,cz,br_top,br_bottom,br_left, br_right,br_front,br_back,o_top=1,o_bottom=1,o_left=1,o_right=1,o_front=1,o_back=1)
   
 ;MR 31.10.2002
   
 ;Create a Cube centered
   
 ;m       =Entity Handle 0=Create a new one :-)
 ;x1,x2   =From X1 To X2
 ;cx,cy,cy=Center 
 ;br_     =Brush  Handle
 ;o_      =Optional 1=Create 0=No Create 
   
   Local w#,h#,d#
   
 ;w#=witdh  (X)
 ;h#=height (Y)
 ;d#=depth  (Z)
   
   w#=x2#-x1#
   h#=y2#-y1#
   d#=z2#-z1#
   
  ;--------------------- Center ?
   
   If cx=1 Then
      x1=x1-w/2.0
      x2=x2-w/2.0
   EndIf
   
   If cy=1 Then
      y1=y1-h/2.0
      y2=y2-h/2.0
   EndIf
   
   If cz=1 Then
      z1=z1-d/2.0
      z2=z2-d/2.0
   EndIf
   
  ;-----------------------------
   
   If m=0 Then
      m=CreateMesh()
   EndIf
   
  ;-----------------------------
   
   ;top face
   If o_top=1 Then
      s=CreateSurface( m , br_top)
      AddVertex s,x1,y2,z2,0,1:AddVertex s,x2,y2,z2,0,0
      AddVertex s,x2,y2,z1,1,0:AddVertex s,x1,y2,z1,1,1
      AddTriangle s,0,1,2:AddTriangle s,0,2,3
   EndIf
   
   ;bottom face   
   If o_bottom=1 Then
      s=CreateSurface( m , br_bottom)
      AddVertex s,x1,y1,z1,1,0:AddVertex s,x2,y1,z1,1,1
      AddVertex s,x2,y1,z2,0,1:AddVertex s,x1,y1,z2,0,0
      AddTriangle s,0,1,2:AddTriangle s,0,2,3
   EndIf
   
   ;left face
   If o_left=1 Then
      s=CreateSurface( m , br_left)
      AddVertex s,x1,y2,z2,0,0:AddVertex s,x1,y2,z1,1,0
      AddVertex s,x1,y1,z1,1,1:AddVertex s,x1,y1,z2,0,1
      AddTriangle s,0,1,2:AddTriangle s,0,2,3
   EndIf
   
   ;right face
   If o_right=1 Then
      s=CreateSurface( m , br_right)
      AddVertex s,x2,y2,z1,0,0:AddVertex s,x2,y2,z2,1,0
      AddVertex s,x2,y1,z2,1,1:AddVertex s,x2,y1,z1,0,1
      AddTriangle s,0,1,2:AddTriangle s,0,2,3
   EndIf
   
   ;front face
   If o_front=1 Then
      s=CreateSurface( m , br_front)
      AddVertex s,x1,y2,z1,0,0:AddVertex s,x2,y2,z1,1,0
      AddVertex s,x2,y1,z1,1,1:AddVertex s,x1,y1,z1,0,1
      AddTriangle s,0,1,2:AddTriangle s,0,2,3
   EndIf
   
   ;back face
   If o_back=1 Then
      s=CreateSurface( m , br_back)
      AddVertex s,x2,y2,z2,0,0:AddVertex s,x1,y2,z2,1,0
      AddVertex s,x1,y1,z2,1,1:AddVertex s,x2,y1,z2,0,1
      AddTriangle s,0,1,2:AddTriangle s,0,2,3
   EndIf
   
   UpdateNormals m
   
  ;EntityPickMode m,2 ;Poly
   
   Return m 
   
End Function


Das Problem dabei ist, dass das Ganze nur für1x1x1 große Cubes funktioniert. Auf einer Kugel gehts auch noch... Aber auf einem Kegel funktioniert die Unterseite beispielsweise nicht wirklich.
Und sobald ich das Ganze auf Oberflächen von durch CSG entstandene Objekte anwende, funktioniert schon mal garnichts mehr. Das muss doch irgendwie möglich sein, aus den Normalen-Koordinaten und den lokalen gepickten Koordinaten irgendwie 2D-Surface-Koordinaten zu basteln..??

Edit: Und die Größe der Surface muss ich auch noch irgendwie einfließen lassen, sonst passt die Bewegungsgeschwindigkeit wieder nicht mit der der Maus überein Evil or Very Mad

Mr.Keks

BeitragFr, Okt 21, 2011 1:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi Sethus, die Normalen von Vertices/Triangles haben im allgemeinen nicht zwingend etwas mit den UV-Koordinaten zu tun, um die es dir hier ja eigentlich geht. Die UV-Verzerrung richtig umzusetzen, ist vermutlich seehr unangenehm - bin da allerdings auch planlos.

Ich würde dir folgendes Verfahren mit einer linearen Abbildung vorschlagen, das für gewöhnlich eine gute Näherung darstellen sollte: Schau, welches Dreieck gepickt wurde. Hol dir die Vertexkoordinaten und wandle sie in Weltkoordinaten um, hol dir die entsprechenden Bildschirmkoordinaten mit CameraProject. Dann suche den untersten, linksten, rechtesten, obersten der Vertices bzgl des Bildschirms raus. Dann dividierste jeweils den 2d-Vektor zwischen den UV-Koordinaten des obersten und untersten sowie des linkesten und rechtesten einmal durch die x- und einmal durch die y-Differenz zwischen den Bildschirmkoordinaten der entsprechenden Vertices. (Also so Werte von wegen, wie viel U sich verändert pro X..) Sollte pro Vektor so eine Art 2x2-Matrix rauskommen. Dann einfach die beiden Matrizen addieren. Die resultierende Matrix kannste dann mit deiner X/Y-Maus-Bewegung multiplizieren, um den 2d-Vektor zu erhalten, um den du die UV-Koordinaten pro Bewegung ändern müsstest. Wie gesagt, das ist nur eine Näherung, die die perspektivische Verzerrung ignoriert und für sehr krude Dreiecke möglicherweise wirklich negativ auffällig wird -- die meisten Probleme sollten aber durch die geschickte Vertex-Wahl behoben werden, hoffe ich.
MrKeks.net

Midimaster

BeitragFr, Okt 21, 2011 9:02
Antworten mit Zitat
Benutzer-Profile anzeigen
also ich bin noch nicht ganz davon überzeugt, dass mein weg nicht vielleicht doch eine Lösung für dich wäre...

hier mal ein Ansatz. die Surface wird mit der Maus bewegt. eine Bewegung in MouseX-Achse bewegt auch die Surface in "ihrer" X-Achse. Es kommt völlig ohne die Berechnungen aus:

BlitzBasic: [AUSKLAPPEN]
While Not KeyDown(1)

If KeyDown(200) Then TurnEntity cube, 0.5, 0, 0
If KeyDown(208) Then TurnEntity cube, -0.5, 0, 0
If KeyDown(203) Then TurnEntity cube, 0, 0.5, 0
If KeyDown(205) Then TurnEntity cube, 0, -0.5, 0

RenderWorld

If MouseHit(1) Then
CameraPick camera, MouseX(), MouseY()
iSelectedSurf = PickedSurface()
For i=1 To CountSurfaces(cube)
If GetSurface(cube,i) <> iSelectedSurf Then
PaintSurface GetSurface(cube,i), brushWhite
Else
PaintSurface iSelectedSurf, brushRed
End If
Next
End If

ent = CameraPick(camera, MouseX(), MouseY())

If MouseDown(1)
diffx#=Sgn(MouseX()-Vx)
diffx=diffx/100
diffy#=Sgn(MouseY()-VY)
diffY=diffY/100
vx=MouseX()
vy=MouseY()



If iSelectedSurf <> 0 Then
For i = 0 To CountVertices(iSelectedSurf) - 1
; VertexTexCoords iSelectedSurf, i, VertexU#(iSelectedSurf, i) + fMovU#, VertexV#(iSelectedSurf, i) + fMovV#
VertexTexCoords iSelectedSurf, i, VertexU#(iSelectedSurf, i) - diffX, VertexV#(iSelectedSurf, i) -DiffY
Next
End If
EndIf
Flip
Wend
End




Hier wäre nur noch die Frage zu klären, wie man herausfindet, ob die Surface-Achsen der Surface einigermaßen mit der Maus übereinstimmen.

Dann noch eine Anregung: wird die Maus auf dem Mesh bewegt ergeben sich doch sofort andere PickedX(),... Koordinaten. Man könnte doch durch Subtrahieren aus den vorherigen PickedX() und dem neuen eine Art Vektor errechnen, der dann zeigt, wie die Bewegung auf dem Mesh ausgesehen hat?
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

derAtomkeks

ehemals "Sethus"

BeitragFr, Okt 21, 2011 13:52
Antworten mit Zitat
Benutzer-Profile anzeigen
@Midimaster: Die Differenz der gepickten Koordinaten bilden ist das, was ich getan habe Wink Deine Lösung funktioniert leider schon bei einem einfachen Cube nicht mehr richtig und Skalierung wird auch nicht beachtet. Trotzdem danke Smile

@Mr. Keks: Damit sollte ich das Problem mit der Skalierung in den Griff bekommen. Die Normale muss ich doch aber irgendwie einbinden, um auf die Neigung der Fläche (also nicht durch Rotation, sondern beispielsweise die Schrägen Seiten eines Kegels) einzugehen. Wenn ich flach vor eine zur Kamera parallele Fläche gucke, dann entspricht die V-Bewegung der Y-Bewegung der Maus. Wenn die Fläche nach hinten geneigt ist (die Normale also nicht 0, 0, -1; sondern zB. 0, 0.5, -1), dann muss sich die Textur in V-Richtung schneller bewegen. (-> Pythagoras und so.). Oder habe ich das bei dir jetzt nur überlesen?`

Das wird aber doch alles irgendwie komplexer (und bei gewölbten Flächen u.a. auch ungenauer), als ich mir das gedacht hatte. Wahrscheinlich ist es besser, wenn ich einfach ein Fenster zum Editor hinzufüge, in dem die auf der Surface befindliche Textur angezeigt wird und dort per Maus verschoben werden kann.
Ist ja jetzt auch nicht so schlimm, wäre halt ein nettes Feature gewesen Wink Zumal es mich doch echt interessiert, wie die Jungs vom Croteam das im Leveleditor für ihr Serious Sam First Encounter umgesetzt haben, da geht das nämlich alles ganz einfach, und so wie man sich das wünscht. Vielleicht bekomme ich ja den SOurce wenn ich ganz lieb frage *hust*.

Edit: Nachdem ich die UV-Koordinaten bei der Cube-Erstellung angepasst habe, funktioniert das Ganze jetzt auch ohne komische Umrechnungen. Brauche ich also nur noch Algos zur Erstellung von Kugeln, Zylindern, Kegeln, ... Rolling Eyes Sowas hat nicht zufälligerweise jemand in der Hinterhand?

Noobody

BeitragFr, Okt 21, 2011 17:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Problemlösung sieht eigentlich so aus: Man macht einen CameraPick an der Mausposition, berechnet die UV-Koordinaten am Schnittpunkt, macht im nächsten Frame wieder einen CameraPick an der Mausposition und berechnet die UV-Koordinaten ein zweites Mal. Dann nimmt man einfach die Differenz dieser zwei UV-Koordinaten und verschiebt die Texturkoordinaten aller Vertices der Surface um diese Differenz. Somit landet der Pixel der Textur, der sich im letzten Frame unter der Maus befand, wieder unter der Maus - man zieht die Textur also mit der Maus mit.

Das Problem ist aber, dass das Berechnen der Texturkoordinaten am Schnittpunkt wirklich keine leichte Sache ist. Blitz stellt entsprechende PickedU/V leider nicht zur Verfügung, daher muss man es von Hand machen.

Meine Lösung funktioniert wie folgt: Da man die UVs der Vertizes ja gegeben hat, muss man diese innerhalb des gegebenen (aber beliebigen) Dreicks interpolieren. Dazu verwendet man das Baryzentrische Koordinatensystem, welches einem nach Berechnung dreier Koordinaten diese Interpolation relativ leicht macht. Auf dem Wiki ist sogar eine Formel dazu. Problem ist aber, dass diese natürlich nur für 2D gilt; in unserem Fall hat man aber das Dreieck in 3D-Koordinaten gegeben - die Formel funktioniert also nicht.
Nun hat man zwei Möglichkeiten: Erstens, das Dreieck mittels CameraProject auf den Bildschirm projizieren und da weiterarbeiten. Hier läuft man allerdings in das Problem, dass die Interpolation dann nicht mehr linear ist, sondern auch noch perspektivisch verzerrt ist (man müsste also noch die interpolierte Z-Koordinate mit einbeziehen); ausserdem bekommt man Riesenprobleme, wenn die drei Eckpunkte des Dreiecks nicht auf dem Bildschirm liegen.
Darum wählte ich die zweite Möglichkeit. Die vier Punkte (drei Eckpunkte und ein Schnittpunkt) liegen ja alle auf einer Ebene, darum ist es uns möglich, aus diesen 4 Punkten eine Ebene zu bauen und daraus dann ein lokales, orthonormales 2D Koordinatensystem zu basteln, in welches wir die 4 Punkte transformieren können. Dann haben wir wieder 2D-Koordinaten, können die Formel anwenden und haben zum Schluss unsere baryzentrischen Koordinaten, mit welchen wir dann die UV-Koordinaten berechnen können.

Mein Code sieht so aus: BlitzBasic: [AUSKLAPPEN]
Graphics3D 800, 600, 0, 2
SetBuffer BackBuffer()

Global PickedU#, PickedV#


Local Cam = CreateCamera()
Local Texture = CreateFunkyTexture()
Local Mesh = CreateCone(64)
EntityPickMode Mesh, 2
EntityTexture Mesh, Texture

MoveEntity Cam, 0.0, 0.0, -3.0

Local Timer = CreateTimer(60)

Local OldPickedU#, OldPickedV#, OldPickedSurface

While Not KeyHit(1)
TurnEntity Mesh, KeyDown(200) - KeyDown(208), KeyDown(205) - KeyDown(203), 0.0, True

If MouseDown(1) Then
CameraPick(Cam, MouseX(), MouseY())

If PickedEntity() <> 0 And PickedSurface() <> 0 Then
CalculatePickedUV()

If PickedSurface() = OldPickedSurface Then
DU# = PickedU# - OldPickedU#
DV# = PickedV# - OldPickedV#

Local Surface = PickedSurface()
For Vertex = 0 To CountVertices(Surface) - 1
Local U# = VertexU(Surface, Vertex)
Local V# = VertexV(Surface, Vertex)

VertexTexCoords Surface, Vertex, U# - DU#, V# - DV#
Next

PickedU# = PickedU# - DU#
PickedV# = PickedV# - DV#
Else
OldPickedSurface = PickedSurface()
EndIf

OldPickedU# = PickedU#
OldPickedV# = PickedV#
Else
OldPickedSurface = 0
EndIf
Else
OldPickedSurface = 0
EndIf

RenderWorld

Flip 0
WaitTimer Timer
Wend
End

Function CreateFunkyTexture()
Local Texture = CreateTexture(256, 256, 1)

SetBuffer TextureBuffer(Texture)
LockBuffer()

For X = 0 To 255
For Y = 0 To 255
WritePixelFast X, Y, (X*$010001) Xor (Y*$010101)
Next
Next

UnlockBuffer()
SetBuffer BackBuffer()

Return Texture
End Function

Function CalculatePickedUV()
Local Surface = PickedSurface()
If Surface Then
Local Mesh = PickedEntity()

TFormPoint PickedX(), PickedY(), PickedZ(), 0, Mesh

Local Triangle = PickedTriangle()

Local V1 = TriangleVertex(Surface, Triangle, 0)
Local V2 = TriangleVertex(Surface, Triangle, 1)
Local V3 = TriangleVertex(Surface, Triangle, 2)

Local DX1# = VertexX(Surface, V2) - VertexX(Surface, V1)
Local DY1# = VertexY(Surface, V2) - VertexY(Surface, V1)
Local DZ1# = VertexZ(Surface, V2) - VertexZ(Surface, V1)
Local DX2# = VertexX(Surface, V3) - VertexX(Surface, V1)
Local DY2# = VertexY(Surface, V3) - VertexY(Surface, V1)
Local DZ2# = VertexZ(Surface, V3) - VertexZ(Surface, V1)

Local NX# = DY1#*DZ2# - DY2#*DZ1#
Local NY# = DX2#*DZ1# - DX1#*DZ2#
Local NZ# = DX1#*DY2# - DY1#*DX2#
Local UX# = NY #*DZ2# - DY2#*NZ #
Local UY# = DX2#*NZ # - NX #*DZ2#
Local UZ# = NX #*DY2# - NY #*DX2#

Local InvLength1# = 1.0/Sqr(UX#*UX# + UY#*UY# + UZ#*UZ#)
Local Length2# = Sqr(DX2#*DX2# + DY2#*DY2# + DZ2#*DZ2#)
Local InvLength2# = 1.0/Length2#

UX# = UX#*InvLength1#
UY# = UY#*InvLength1#
UZ# = UZ#*InvLength1#
DX2# = DX2#*InvLength2#
DY2# = DY2#*InvLength2#
DZ2# = DZ2#*InvLength2#

Local T1# = 0.0
Local S1# = 0.0
Local T2# = DX1#*UX # + DY1#*UY # + DZ1#*UZ #
Local S2# = DX1#*DX2# + DY1#*DY2# + DZ1#*DZ2#
Local T3# = 0.0
Local S3# = Length2#
Local T4# = (TFormedX() - VertexX(Surface, V1))*UX # + (TFormedY() - VertexY(Surface, V1))*UY # + (TFormedZ() - VertexZ(Surface, V1))*UZ #
Local S4# = (TFormedX() - VertexX(Surface, V1))*DX2# + (TFormedY() - VertexY(Surface, V1))*DY2# + (TFormedZ() - VertexZ(Surface, V1))*DZ2#


Local Denominator# = 1.0/((S2# - S3#)*(T1# - T3#) + (T3# - T2#)*(S1# - S3#))
Local Lambda1# = ((S2# - S3#)*(T4# - T3#) + (T3# - T2#)*(S4# - S3#))*Denominator#
Local Lambda2# = ((S3# - S1#)*(T4# - T3#) + (T1# - T3#)*(S4# - S3#))*Denominator#
Local Lambda3# = 1.0 - Lambda1# - Lambda2#

PickedU# = VertexU(Surface, V1)*Lambda1# + VertexU(Surface, V2)*Lambda2# + VertexU(Surface, V3)*Lambda3#
PickedV# = VertexV(Surface, V1)*Lambda1# + VertexV(Surface, V2)*Lambda2# + VertexV(Surface, V3)*Lambda3#
EndIf
End Function


Das Herumziehen der Textur funktioniert erstaunlich gut; nur dort, wo zwei angrenzende Dreiecke keine kontinuierlichen Texturkoordinaten haben, kommt es zu "Rucklern" - falls diese störend werden, kannst du sie unterbinden, indem du zusätzlich prüfst, ob in diesem Frame das gleiche Dreieck gepickt wurde wie im letzten.
Was auch ganz cool ist, wenn man die Texture festhält und das Objekt mit den Pfeiltasten rotieren lässt. Der festgehaltene Pixel bleibt dann wirklich am selben Ort.

Ich hoffe, das hilft dir weiter.
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

derAtomkeks

ehemals "Sethus"

BeitragFr, Okt 21, 2011 17:58
Antworten mit Zitat
Benutzer-Profile anzeigen
WooooooW Shocked
Das ist die Lösung, die ich gesucht habe!
Habe sie zwar noch nicht ganz verstanden, werde mich jetzt aber mal intensiv mit deinem Code und den geposteten Wiki-Artikeln beschäftigen, dann wird das schon. Smile

Vielen Dank!!

Studierst du bzw. hast du etwas mathematisches studiert, oder woher weiß man sowas? Very Happy

Noobody

BeitragFr, Okt 21, 2011 18:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich studiere im Moment Informatik im 3. Semester.

Den Teil mit den baryzentrischen Koordinaten wusste ich schon vorher (brauchte ich damals für einen kleinen Software-Rasterizer), und der Rest ging nach einem Semester Lineare Algebra eigentlich relativ fix von der Hand Razz
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

derAtomkeks

ehemals "Sethus"

BeitragFr, Okt 21, 2011 23:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, autodidaktisch lernen ftw!! Very Happy

Kannst du mir vielleicht auch noch genau so schlau mit der Rotation von Texturen auf einer Surface helfen? Das muss auch nicht per Maus geschehen, das muss eingetippt werden. Ich lese da immer von Rotationsmatrizen... aber wie helfen mir die bei einem womöglich noch unregelmäßígen Netz aus Vertices? Question
 

n-Halbleiter

BeitragFr, Okt 21, 2011 23:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Öhm, Rotationsmatrizen haben die Eigenschaft, dass man mit ihnen beliebige Punkte um den Punkt (0,0) drehen kann. Die neuen Koordinaten des Punktes sind n = R * a (n = Matrix * alt). Wenn du nun eine Menge Punkte hast, multiplizierst du halt die Koordinaten jedes Punktes mit der Matrix, um die neuen Koordinaten zu erhalten. Mache das bei allen Punkten, und alle Punkte sind gedreht. (:
mfg, Calvin
Maschine: Intel Core2 Duo E6750, 4GB DDR2-Ram, ATI Radeon HD4850, Win 7 x64 und Ubuntu 12.04 64-Bit
Ploing!
Blog

"Die Seele einer jeden Ordnung ist ein großer Papierkorb." - Kurt Tucholsky (09.01.1890 - 21.12.1935)

derAtomkeks

ehemals "Sethus"

BeitragSa, Okt 22, 2011 0:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Okay, habs, vielen Dank nochmal an alle Smile Vielleicht kommt ja noch mal ein Nachtrag irgendwann. Very Happy

Neue Antwort erstellen


Übersicht BlitzBasic Blitz3D

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group