Sprite3D - HotSpot and float coordiantes

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
zxtunes.com
Enthusiast
Enthusiast
Posts: 375
Joined: Wed Apr 23, 2008 7:51 am
Location: Saint-Petersburg, Russia
Contact:

Sprite3D - HotSpot and float coordiantes

Post by zxtunes.com »

Haaf Game Engine (HGE) have very useful function: SetHotSpot(x.f, y.f)

"Anchor point is the center for scaling, rotation and position operations."

And all 3d engines have float x,y cordinates for display 3D sprites, but no PB, why?

When sprite moves very slowly (less than 1 pixel for a frame) in PB it looks jerks, and in HGE/Flash and other engines fantastic smoothly.

To do this Features please.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Re: Sprite3D - HotSpot and float coordiantes

Post by Kaeru Gaman »

because sprite3D functions of PB are special functions for a 2D surface,
no orthogonal camera for a 3D world like it later days is done.
oh... and have a nice day.
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Sprite3D - HotSpot and float coordiantes

Post by djes »

It would be nice to have this, and it could be easy as sprites are now 3d based.
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Sprite3D - HotSpot and float coordiantes

Post by djes »

Here's a kelebrindae macro that does the job nicely (warning zoom and sprite are resetting transformations)

Code: Select all

; These variables are used in the myTransformSprite3D macro (they're defined here because it can't be done in the macro)
Global TRF3D_angCos.f,TRF3D_angSin.f,TRF3D_x1.f,TRF3D_y1.f,TRF3D_x2.f,TRF3D_y2.f,TRF3D_x3.f,TRF3D_y3.f,TRF3D_x4.f,TRF3D_y4.f

; Define the size for a sprite3D, its origin (in pixels), and its rotation angle (absolute)
; Replace the following BlitzMax commands: "SetScale", "SetImageHandle", and "SetRotation"
Macro myTransformSprite3D(numSprite,sizeX,sizeY,pivotX = 0,pivotY = 0,angle = 0)
  ; In PureBasic, a Sprite3D is used to display 2D sprite with 3D hardware ; it's just a textured plane, actually.
  ; Thus, it's possible to zoom, rotate or deform a 3D sprite simply by moving its 4 vertex.
  ; This is done through the "TransformSprite3D" command.

  If angle = 0
    TransformSprite3D(numSprite,-(pivotX),-(pivotY),(sizeX) - (pivotX),-(pivotY),(sizeX) - (pivotX),(sizeY) - (pivotY),-(pivotX),(sizeY) - (pivotY))
  Else
    TRF3D_angCos = Cos(angle)
    TRF3D_angSin = Sin(angle)   
   
    TRF3D_x1 = -(pivotX) * TRF3D_angCos - (-(pivotY) * TRF3D_angSin)
    TRF3D_y1 = -(pivotY) * TRF3D_angCos + (-(pivotX) * TRF3D_angSin)
   
    TRF3D_x2 = ((sizeX) - (pivotX)) * TRF3D_angCos - (-(pivotY) * TRF3D_angSin)
    TRF3D_y2 = -(pivotY) * TRF3D_angCos + ((sizeX) - (pivotX)) * TRF3D_angSin
   
    TRF3D_x3 = ((sizeX) - (pivotX)) * TRF3D_angCos - ((sizeY) - (pivotY)) * TRF3D_angSin
    TRF3D_y3 = ((sizeY) - (pivotY)) * TRF3D_angCos + ((sizeX) - (pivotX)) * TRF3D_angSin
   
    TRF3D_x4 = -(pivotX) * TRF3D_angCos - ((sizeY) - (pivotY)) * TRF3D_angSin
    TRF3D_y4 = ((sizeY) - (pivotY)) * TRF3D_angCos + (-(pivotX) * TRF3D_angSin)

    TransformSprite3D(numSprite,TRF3D_x1,TRF3D_y1,TRF3D_x2,TRF3D_y2,TRF3D_x3,TRF3D_y3,TRF3D_x4,TRF3D_y4)
  EndIf   

EndMacro
User avatar
idle
Always Here
Always Here
Posts: 5844
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Sprite3D - HotSpot and float coordiantes

Post by idle »

add this for linux

Code: Select all

CompilerIf #PB_OS_Linux   ;order for linux is x1,y1,x3,y2,x2,y3,x4,y4
      TransformSprite3D(numsprite,TRF3D_x1,TRF3D_y1,TRF3D_x3,TRF3D_y2,TRF3D_x2,TRF3D_y3,TRF3D_x4,TRF3D_y4)
CompilerElse       
      TransformSprite3D(numSprite,TRF3D_x1,TRF3D_y1,TRF3D_x2,TRF3D_y2,TRF3D_x3,TRF3D_y3,TRF3D_x4,TRF3D_y4)
CompilerEndIf

Windows 11, Manjaro, Raspberry Pi OS
Image
Kelebrindae
Enthusiast
Enthusiast
Posts: 151
Joined: Tue Apr 01, 2008 3:23 pm

Re: Sprite3D - HotSpot and float coordiantes

Post by Kelebrindae »

Thanks for this fix, Idle. :)
Does it work with the openGL subsystem for Windows, too ?

Also: "x1,y1,x3,y2,x2,y3,x4,y4" ?
By Golly, that's pretty counter-intuitive! :?
How did you manage to find it ?
User avatar
idle
Always Here
Always Here
Posts: 5844
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Sprite3D - HotSpot and float coordiantes

Post by idle »

Don't know haven't tried it on windows with opengl subsystem

Yes it is a bit odd, I just swapped them round until it worked.
Windows 11, Manjaro, Raspberry Pi OS
Image
Kelebrindae
Enthusiast
Enthusiast
Posts: 151
Joined: Tue Apr 01, 2008 3:23 pm

Re: Sprite3D - HotSpot and float coordiantes

Post by Kelebrindae »

As it's some sort of frequently asked question, I've compiled in a little include all the needed functions to :
- Define a hotspot for a Sprite3D;
- Color a Sprite3D or its vertices individually;
- Flip a Sprite3D;
- Perform a "clipSprite" to animate a Sprite3D;
- And a few other things...

Warning: DirectX9 only.

Here's a little demo:
http://keleb.free.fr/codecorner/downloa ... rite3D.zip

And here is the include (save it as "EXT_sprite3D.pbi") :

Code: Select all

; Author: Kelebrindae
; Date: April, 4, 2011
; PB version: v4.51
; ---------------------------------------------------------------------------------------------------------------
; Description:
; ---------------------------------------------------------------------------------------------------------------
; "Extension" for sprites 3D. It adds:
;   - Handle (= "hotspot", = "pivot") definition
;   - Flipping, horizontally and/or vertically
;   - Clipping
;   - Coloring
;   - a few other things...
; ---------------------------------------------------------------------------------------------------------------
; Known bugs and limitations:
; ---------------------------------------------------------------------------------------------------------------
; - Only for DirectX9...
; ---------------------------------------------------------------------------------------------------------------


;********************************************************
;- Structure and Variables
;********************************************************

; DirectX9 vertex
Structure D3DTLVERTEX
  x.f
  y.f
  z.f
  rhw.f
  Color.l
  tu.f
  tv.f
EndStructure

; DirectX9 sprite3D
Structure PB_DX9Sprite3D
  TexRes.i
  Vertice.D3DTLVERTEX[4]      ; position of the 4 vertices, relative to the sprite origin
  TmpVertice.D3DTLVERTEX[4]   ; position of the 4 vertices, relative to the screen origin
  Width.l                     ; width set with ZoomSprite3D()
  Height.l                    ; height set with ZoomSprite3D()
  RealWidth.l                 ; width before rescaling
  RealHeight.l                ; height before rescaling
  Angle.f                     ; angle
  Transformed.l
EndStructure

; The EXT_Sprite3D_struct stores the pointer to the real sprite3D, plus its pivot, flipmode, and alpha
Structure EXT_Sprite3D_struct
  numSprite3D.i               ; PB's sprite3D linked to the current EXT_sprite3D
  *ptrSprite3D.PB_DX9Sprite3D ; pointer to the DirectX9 sprite3D
  pivotX.i                    ; Hotspot - coord X
  pivotY.i                    ; Hotspot - coord X
  flipmode.b                  ; 0 = not flipped; 1 = H. flip; 2 = V. Flip; 3 = both
  alpha.i                     ; opacity level, from 0 to 255
EndStructure
Global Dim EXT_Sprite3D.EXT_Sprite3D_struct(1)

; Vertices number
Enumeration
  #TOPLEFT
  #TOPRIGHT
  #BOTTOMLEFT
  #BOTTOMRIGHT
EndEnumeration

; These variables are used in the EXT_TransformSprite3D macro (they're defined here because it can't be done in the macro)
Global *TRF3D_DX9sprite3D.PB_DX9Sprite3D,TRF3D_angCos.f,TRF3D_angSin.f,TRF3D_v1.f,TRF3D_v2.f,TRF3D_v3.f,TRF3D_v4.f,TRF3D_v5.f,TRF3D_v6.f,TRF3D_v7.f,TRF3D_v8.f

;-
;********************************************************
;- Create & Destroy
;********************************************************
; Initializes the sprite3D and adds it to the "EXT_Sprite3D" array, or redefines an already existing one.
; Then, returns the indice of the new item in this array.
Procedure.i EXT_CreateSprite3D(numSprite3D.i,numSprite.i)
  Static lastSprite3D.i
  
  ; If numSprite3D is equal to "#PB_Any", then add an item in the "EXT_Sprite3D" array and initialize it.
  If numSprite3D = #PB_Any
    lastSprite3D + 1
    ReDim EXT_Sprite3D(lastSprite3D  + 1)
    
    EXT_Sprite3D(lastSprite3D)\numSprite3D = CreateSprite3D(#PB_Any, numSprite)
    EXT_Sprite3D(lastSprite3D)\ptrSprite3D = IsSprite3D(EXT_Sprite3D(lastSprite3D)\numSprite3D)
    EXT_Sprite3D(lastSprite3D)\pivotX = 0
    EXT_Sprite3D(lastSprite3D)\pivotY = 0
    EXT_Sprite3D(lastSprite3D)\flipmode = %00
    EXT_Sprite3D(lastSprite3D)\alpha = 255
    
    ProcedureReturn lastSprite3D
  Else
    ; If numSprite3D is not equal to "#PB_Any", we want to redefine an already existing EXT_sprite3D.
    If numSprite3D > ArraySize(EXT_Sprite3D())
      MessageRequester("Error","ERROR: EXT_sprite3D #"+Str(numsprite3D)+" is not initialized.")
      ProcedureReturn 0
    EndIf
    If EXT_Sprite3D(numSprite3D)\numSprite3D > 0
      FreeSprite3D(EXT_Sprite3D(numSprite3D)\numSprite3D)
    EndIf
    
    EXT_Sprite3D(numSprite3D)\numSprite3D = CreateSprite3D(#PB_Any, numSprite)
    EXT_Sprite3D(numSprite3D)\ptrSprite3D = IsSprite3D(EXT_Sprite3D(numSprite3D)\numSprite3D)
    EXT_Sprite3D(numSprite3D)\pivotX = 0
    EXT_Sprite3D(numSprite3D)\pivotY = 0
    EXT_Sprite3D(numSprite3D)\flipmode = %00
    EXT_Sprite3D(numSprite3D)\alpha = 255
    
    ProcedureReturn numSprite3D
  EndIf  
    
EndProcedure

; Deletes a EXT_sprite3D
Procedure EXT_FreeSprite3D(numEXT_Spr3d.i)
  If numSprite3D > ArraySize(EXT_Sprite3D())
      MessageRequester("Error","ERROR: EXT_sprite3D #"+Str(numsprite3D)+" is not initialized.")
      ProcedureReturn 0
  EndIf
  If EXT_Sprite3D(numSprite3D)\numSprite3D > 0
    FreeSprite3D(EXT_Sprite3D(numSprite3D)\numSprite3D)
  EndIf
  
  EXT_Sprite3D(numSprite3D)\numSprite3D = 0
  EXT_Sprite3D(numSprite3D)\ptrSprite3D = 0
EndProcedure


;-
;********************************************************
;- Deformations
;********************************************************

; This macro is used by the "SetHandle", "Zoom", and "Rotate" macros.
; It aggregates theses 3 infos (handle, size and angle) to compute the position of the 4 vertices.
Macro EXT_TransformSprite3D(sizeX,sizeY,pivotX = 0,pivotY = 0,angle = 0)
  ; In PureBasic, a Sprite3D is used to display a 2D sprite with 3D hardware ; it's just a textured plane, actually.
  ; Thus, it's possible to zoom, rotate or deform a 3D sprite simply by moving its 4 vertices.
  
  ; NB: Don't ask me about the "-0.5". PB's "TransformSprite3D" do it, so I do it too, but I don't know why...
  If angle = 0
    *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\x = -(pivotX) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\y = -(pivotY) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\x = (sizeX) - (pivotX) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\y = -(pivotY) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\x = (sizeX) - (pivotX) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\y = (sizeY) - (pivotY) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\x = -(pivotX) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\y = (sizeY) - (pivotY) - 0.5

  Else
    TRF3D_angCos = Cos(angle)
    TRF3D_angSin = Sin(angle)    
    
    TRF3D_v1 = -(pivotX) * TRF3D_angCos
    TRF3D_v2 = -(pivotX) * TRF3D_angSin
    
    TRF3D_v3 = -(pivotY) * TRF3D_angSin
    TRF3D_v4 = -(pivotY) * TRF3D_angCos
    
    TRF3D_v5 = ((sizeX) - (pivotX)) * TRF3D_angSin
    TRF3D_v6 = ((sizeX) - (pivotX)) * TRF3D_angCos
    
    TRF3D_v7 = ((sizeY) - (pivotY)) * TRF3D_angSin
    TRF3D_v8 = ((sizeY) - (pivotY)) * TRF3D_angCos    

    *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\x = TRF3D_v1 - TRF3D_v3 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\y = TRF3D_v4 + TRF3D_v2 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\x = TRF3D_v6 - TRF3D_v3 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\y = TRF3D_v4 + TRF3D_v5 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\x = TRF3D_v6 - TRF3D_v7 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\y = TRF3D_v8 + TRF3D_v5 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\x = TRF3D_v1 - TRF3D_v7 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\y = TRF3D_v8 + TRF3D_v2 - 0.5
  EndIf    
  *TRF3D_DX9sprite3D\Transformed = 1  

EndMacro  


; Sets the position of the "handle" (= "hotspot", or "pivot") of an EXT_sprite3D
; NB: When you resize a sprite, the position of its handle isn't recalculed.
;     If you have a 32x32 sprite with its handle centered (at cords 16,16) and you resize it to 64x64,
;     the handle stays at 16,16 and thus is off-center...
Macro EXT_SetHandleSprite3D(numEXT_Spr3d,newPivotX,newPivotY)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  EXT_Sprite3D(numEXT_Spr3d)\pivotX = (newPivotX)
  EXT_Sprite3D(numEXT_Spr3d)\pivotY  = (newPivotY)
  
  EXT_TransformSprite3D(*TRF3D_DX9sprite3D\Width,*TRF3D_DX9sprite3D\Height,EXT_Sprite3D(numEXT_Spr3d)\pivotX,EXT_Sprite3D(numEXT_Spr3d)\pivotY,*TRF3D_DX9sprite3D\Angle)
EndMacro

; Rescales an EXT_sprite3D
Macro EXT_ZoomSprite3D(numEXT_Spr3d,newSizeX,newSizeY)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  *TRF3D_DX9sprite3D\Width = (newSizeX)
  *TRF3D_DX9sprite3D\Height = (newSizeY)
  
  EXT_TransformSprite3D(*TRF3D_DX9sprite3D\Width,*TRF3D_DX9sprite3D\Height,EXT_Sprite3D(numEXT_Spr3d)\pivotX,EXT_Sprite3D(numEXT_Spr3d)\pivotY,*TRF3D_DX9sprite3D\Angle)
EndMacro

; Rotates an EXT_sprite3D
Macro EXT_RotateSprite3D(numEXT_Spr3d,newAngle)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  *TRF3D_DX9sprite3D\Angle = (newAngle)
  
  EXT_TransformSprite3D(*TRF3D_DX9sprite3D\Width,*TRF3D_DX9sprite3D\Height,EXT_Sprite3D(numEXT_Spr3d)\pivotX,EXT_Sprite3D(numEXT_Spr3d)\pivotY,*TRF3D_DX9sprite3D\Angle)
EndMacro


;-
;********************************************************
;- Flipping, Clipping, Coloring
;********************************************************

; Mirrors an EXT_sprite3D by manipulating its UV mapping (inverts left and right vertices' UV coords)
Macro EXT_FlipHoriSprite3D(numEXT_Spr3d)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  Swap *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tu,*TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tu
  Swap *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tv,*TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tv
  Swap *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tu,*TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tu
  Swap *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tv,*TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tv
  
  EXT_Sprite3D(numEXT_Spr3d)\flipmode = EXT_Sprite3D(numEXT_Spr3d)\flipmode ! %01
EndMacro

; Flips an EXT_sprite3D upside down by manipulating its UV mapping (inverts top and bottom vertices' UV coords)
Macro EXT_FlipVertSprite3D(numEXT_Spr3d)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  Swap *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tu,*TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tu
  Swap *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tv,*TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tv
  Swap *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tu,*TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tu
  Swap *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tv,*TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tv
  
  EXT_Sprite3D(numEXT_Spr3d)\flipmode = EXT_Sprite3D(numEXT_Spr3d)\flipmode ! %10
EndMacro


; Clips (= "crop") the image displayed by an EXT_sprite3D (very useful for animated sprites).
; NB: This doesn't change the actual size of the sprite3D, so you must ensure that each frame
;     of the animation is of the same size (or they will by stretched to the size of the sprite).
Macro EXT_ClipSprite3D(numEXT_Spr3d,x,y,x2,y2)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  ; The flip mode (left-right, up-down, or both) affects the computation of the UV coords
  Select EXT_Sprite3D(numEXT_Spr3d)\flipmode
    Case %00 ; no flip
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
    Case %01 ; horizontal flip
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
    Case %10 ; vertical flip
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
    Case %11 ; both
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
  EndSelect
  
EndMacro


; Applies a color filter to an EXT_sprite3D
Macro EXT_SetColorSprite3D(numEXT_Spr3d, newColor)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\Color = newColor
  *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\Color = newColor
  *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\Color = newColor
  *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\Color = newColor
EndMacro

; Same, but for just one vertex of the EXT_sprite3D
Macro EXT_SetVertexColorSprite3D(numEXT_Spr3d,numVertex,newColor)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\Color = newColor
EndMacro

; Sets the alpha level ( = transparency) of an EXT_sprite3D. 0 = invisible, 255 = opaque
Macro EXT_SetAlphaSprite3D(numEXT_Spr3d, newAlpha)
  EXT_Sprite3D(numEXT_Spr3d)\alpha = newAlpha
EndMacro


;-
;********************************************************
;- Utilitary
;********************************************************

; Gets the current width of an EXT_sprite3D
Macro EXT_GetWidthSprite3D(numEXT_Spr3d)
  EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D\Width
EndMacro
; Gets the current height of an EXT_sprite3D
Macro EXT_GetHeightSprite3D(numEXT_Spr3d)
  EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D\Height
EndMacro

; Gets the "real" width of an EXT_sprite3D (that is to say, before any rescaling)
Macro EXT_GetRealWidthSprite3D(numEXT_Spr3d)
  EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D\Width
EndMacro

; Gets the "real" height of an EXT_sprite3D (that is to say, before any rescaling)
Macro EXT_GetRealHeightSprite3D(numEXT_Spr3d)
  EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D\Height
EndMacro

; Gets the current angle in radians of an EXT_sprite3D
Macro EXT_GetAngleSprite3D(numEXT_Spr3d)
  EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D\Height  
EndMacro  

; Gives True if the EXT_sprite3D is horizontally flipped
Macro EXT_isFlipHoriSprite3D(numEXT_Spr3d)
  (EXT_Sprite3D(numEXT_Spr3d)\flipmode & %01)
EndMacro  

; Gives True if the EXT_sprite3D is vertically flipped
Macro EXT_isFlipVertSprite3D(numEXT_Spr3d)
  ((EXT_Sprite3D(numEXT_Spr3d)\flipmode & %10) >> 1)
EndMacro  


;-
;********************************************************
;- Display
;********************************************************

; Display the EXT_sprite3D with its current alpha level
Macro EXT_DisplaySprite3D(numEXT_Spr3d,x,y)
  DisplaySprite3D(EXT_Sprite3D(numEXT_Spr3D)\numSprite3D,x,y,EXT_Sprite3D(numEXT_Spr3d)\alpha)
EndMacro


; Display various informations about a sprite3D in the debugger
Macro EXT_DebugInfosSprite3D(numEXT_Spr3d)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  Debug "TexRes = " + Str(*TRF3D_DX9sprite3D\texRes)
  Debug "Vertices: "
  For i=0 To 3
    Debug "    " + Str(i) + " -> x,y   = " + StrF(*TRF3D_DX9sprite3D\Vertice[i]\x,2) + "," + StrF(*TRF3D_DX9sprite3D\Vertice[i]\y,2)
    Debug "         rhw   = " + StrF(*TRF3D_DX9sprite3D\Vertice[i]\rhw,2)
    Debug "         color = " + Str(Red(*TRF3D_DX9sprite3D\Vertice[i]\color)) + "," + Str(Green(*TRF3D_DX9sprite3D\Vertice[i]\color)) + Str(Blue(*TRF3D_DX9sprite3D\Vertice[i]\color))
  Next i
  Debug "Temp Vertices: "
  For i=0 To 3
    Debug "    " + Str(i) + " -> x,y   = " + StrF(*TRF3D_DX9sprite3D\TmpVertice[i]\x,2) + "," + StrF(*TRF3D_DX9sprite3D\TmpVertice[i]\y,2)
    Debug "         rhw   = " + StrF(*TRF3D_DX9sprite3D\TmpVertice[i]\rhw,2)
    Debug "         color = " + Str(Red(*TRF3D_DX9sprite3D\TmpVertice[i]\color)) + "," + Str(Green(*TRF3D_DX9sprite3D\TmpVertice[i]\color)) + Str(Blue(*TRF3D_DX9sprite3D\TmpVertice[i]\color))
  Next i
  Debug "Width, Height      = " + Str(*TRF3D_DX9sprite3D\Width) + "," + Str(*TRF3D_DX9sprite3D\Height)
  Debug "Real Width, Height = " + Str(*TRF3D_DX9sprite3D\RealWidth) + "," + Str(*TRF3D_DX9sprite3D\RealHeight)
  Debug "Angle = " + StrF(*TRF3D_DX9sprite3D\Angle)
  Debug "Transformed = " + Str(*TRF3D_DX9sprite3D\Transformed)
  
EndMacro
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Sprite3D - HotSpot and float coordiantes

Post by Demivec »

Thanks Kelebrindae! :)
AndyMK
Enthusiast
Enthusiast
Posts: 582
Joined: Wed Jul 12, 2006 4:38 pm
Location: UK

Re: Sprite3D - HotSpot and float coordiantes

Post by AndyMK »

Kelebrindae wrote:As it's some sort of frequently asked question, I've compiled in a little include all the needed functions to :
- Define a hotspot for a Sprite3D;
- Color a Sprite3D or its vertices individually;
- Flip a Sprite3D;
- Perform a "clipSprite" to animate a Sprite3D;
- And a few other things...

Warning: DirectX9 only.

Here's a little demo:
http://keleb.free.fr/codecorner/downloa ... rite3D.zip

And here is the include (save it as "EXT_sprite3D.pbi") :

Code: Select all

; Author: Kelebrindae
; Date: April, 4, 2011
; PB version: v4.51
; ---------------------------------------------------------------------------------------------------------------
; Description:
; ---------------------------------------------------------------------------------------------------------------
; "Extension" for sprites 3D. It adds:
;   - Handle (= "hotspot", = "pivot") definition
;   - Flipping, horizontally and/or vertically
;   - Clipping
;   - Coloring
;   - a few other things...
; ---------------------------------------------------------------------------------------------------------------
; Known bugs and limitations:
; ---------------------------------------------------------------------------------------------------------------
; - Only for DirectX9...
; ---------------------------------------------------------------------------------------------------------------


;********************************************************
;- Structure and Variables
;********************************************************

; DirectX9 vertex
Structure D3DTLVERTEX
  x.f
  y.f
  z.f
  rhw.f
  Color.l
  tu.f
  tv.f
EndStructure

; DirectX9 sprite3D
Structure PB_DX9Sprite3D
  TexRes.i
  Vertice.D3DTLVERTEX[4]      ; position of the 4 vertices, relative to the sprite origin
  TmpVertice.D3DTLVERTEX[4]   ; position of the 4 vertices, relative to the screen origin
  Width.l                     ; width set with ZoomSprite3D()
  Height.l                    ; height set with ZoomSprite3D()
  RealWidth.l                 ; width before rescaling
  RealHeight.l                ; height before rescaling
  Angle.f                     ; angle
  Transformed.l
EndStructure

; The EXT_Sprite3D_struct stores the pointer to the real sprite3D, plus its pivot, flipmode, and alpha
Structure EXT_Sprite3D_struct
  numSprite3D.i               ; PB's sprite3D linked to the current EXT_sprite3D
  *ptrSprite3D.PB_DX9Sprite3D ; pointer to the DirectX9 sprite3D
  pivotX.i                    ; Hotspot - coord X
  pivotY.i                    ; Hotspot - coord X
  flipmode.b                  ; 0 = not flipped; 1 = H. flip; 2 = V. Flip; 3 = both
  alpha.i                     ; opacity level, from 0 to 255
EndStructure
Global Dim EXT_Sprite3D.EXT_Sprite3D_struct(1)

; Vertices number
Enumeration
  #TOPLEFT
  #TOPRIGHT
  #BOTTOMLEFT
  #BOTTOMRIGHT
EndEnumeration

; These variables are used in the EXT_TransformSprite3D macro (they're defined here because it can't be done in the macro)
Global *TRF3D_DX9sprite3D.PB_DX9Sprite3D,TRF3D_angCos.f,TRF3D_angSin.f,TRF3D_v1.f,TRF3D_v2.f,TRF3D_v3.f,TRF3D_v4.f,TRF3D_v5.f,TRF3D_v6.f,TRF3D_v7.f,TRF3D_v8.f

;-
;********************************************************
;- Create & Destroy
;********************************************************
; Initializes the sprite3D and adds it to the "EXT_Sprite3D" array, or redefines an already existing one.
; Then, returns the indice of the new item in this array.
Procedure.i EXT_CreateSprite3D(numSprite3D.i,numSprite.i)
  Static lastSprite3D.i
  
  ; If numSprite3D is equal to "#PB_Any", then add an item in the "EXT_Sprite3D" array and initialize it.
  If numSprite3D = #PB_Any
    lastSprite3D + 1
    ReDim EXT_Sprite3D(lastSprite3D  + 1)
    
    EXT_Sprite3D(lastSprite3D)\numSprite3D = CreateSprite3D(#PB_Any, numSprite)
    EXT_Sprite3D(lastSprite3D)\ptrSprite3D = IsSprite3D(EXT_Sprite3D(lastSprite3D)\numSprite3D)
    EXT_Sprite3D(lastSprite3D)\pivotX = 0
    EXT_Sprite3D(lastSprite3D)\pivotY = 0
    EXT_Sprite3D(lastSprite3D)\flipmode = %00
    EXT_Sprite3D(lastSprite3D)\alpha = 255
    
    ProcedureReturn lastSprite3D
  Else
    ; If numSprite3D is not equal to "#PB_Any", we want to redefine an already existing EXT_sprite3D.
    If numSprite3D > ArraySize(EXT_Sprite3D())
      MessageRequester("Error","ERROR: EXT_sprite3D #"+Str(numsprite3D)+" is not initialized.")
      ProcedureReturn 0
    EndIf
    If EXT_Sprite3D(numSprite3D)\numSprite3D > 0
      FreeSprite3D(EXT_Sprite3D(numSprite3D)\numSprite3D)
    EndIf
    
    EXT_Sprite3D(numSprite3D)\numSprite3D = CreateSprite3D(#PB_Any, numSprite)
    EXT_Sprite3D(numSprite3D)\ptrSprite3D = IsSprite3D(EXT_Sprite3D(numSprite3D)\numSprite3D)
    EXT_Sprite3D(numSprite3D)\pivotX = 0
    EXT_Sprite3D(numSprite3D)\pivotY = 0
    EXT_Sprite3D(numSprite3D)\flipmode = %00
    EXT_Sprite3D(numSprite3D)\alpha = 255
    
    ProcedureReturn numSprite3D
  EndIf  
    
EndProcedure

; Deletes a EXT_sprite3D
Procedure EXT_FreeSprite3D(numEXT_Spr3d.i)
  If numSprite3D > ArraySize(EXT_Sprite3D())
      MessageRequester("Error","ERROR: EXT_sprite3D #"+Str(numsprite3D)+" is not initialized.")
      ProcedureReturn 0
  EndIf
  If EXT_Sprite3D(numSprite3D)\numSprite3D > 0
    FreeSprite3D(EXT_Sprite3D(numSprite3D)\numSprite3D)
  EndIf
  
  EXT_Sprite3D(numSprite3D)\numSprite3D = 0
  EXT_Sprite3D(numSprite3D)\ptrSprite3D = 0
EndProcedure


;-
;********************************************************
;- Deformations
;********************************************************

; This macro is used by the "SetHandle", "Zoom", and "Rotate" macros.
; It aggregates theses 3 infos (handle, size and angle) to compute the position of the 4 vertices.
Macro EXT_TransformSprite3D(sizeX,sizeY,pivotX = 0,pivotY = 0,angle = 0)
  ; In PureBasic, a Sprite3D is used to display a 2D sprite with 3D hardware ; it's just a textured plane, actually.
  ; Thus, it's possible to zoom, rotate or deform a 3D sprite simply by moving its 4 vertices.
  
  ; NB: Don't ask me about the "-0.5". PB's "TransformSprite3D" do it, so I do it too, but I don't know why...
  If angle = 0
    *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\x = -(pivotX) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\y = -(pivotY) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\x = (sizeX) - (pivotX) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\y = -(pivotY) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\x = (sizeX) - (pivotX) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\y = (sizeY) - (pivotY) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\x = -(pivotX) - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\y = (sizeY) - (pivotY) - 0.5

  Else
    TRF3D_angCos = Cos(angle)
    TRF3D_angSin = Sin(angle)    
    
    TRF3D_v1 = -(pivotX) * TRF3D_angCos
    TRF3D_v2 = -(pivotX) * TRF3D_angSin
    
    TRF3D_v3 = -(pivotY) * TRF3D_angSin
    TRF3D_v4 = -(pivotY) * TRF3D_angCos
    
    TRF3D_v5 = ((sizeX) - (pivotX)) * TRF3D_angSin
    TRF3D_v6 = ((sizeX) - (pivotX)) * TRF3D_angCos
    
    TRF3D_v7 = ((sizeY) - (pivotY)) * TRF3D_angSin
    TRF3D_v8 = ((sizeY) - (pivotY)) * TRF3D_angCos    

    *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\x = TRF3D_v1 - TRF3D_v3 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\y = TRF3D_v4 + TRF3D_v2 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\x = TRF3D_v6 - TRF3D_v3 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\y = TRF3D_v4 + TRF3D_v5 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\x = TRF3D_v6 - TRF3D_v7 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\y = TRF3D_v8 + TRF3D_v5 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\x = TRF3D_v1 - TRF3D_v7 - 0.5
    *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\y = TRF3D_v8 + TRF3D_v2 - 0.5
  EndIf    
  *TRF3D_DX9sprite3D\Transformed = 1  

EndMacro  


; Sets the position of the "handle" (= "hotspot", or "pivot") of an EXT_sprite3D
; NB: When you resize a sprite, the position of its handle isn't recalculed.
;     If you have a 32x32 sprite with its handle centered (at cords 16,16) and you resize it to 64x64,
;     the handle stays at 16,16 and thus is off-center...
Macro EXT_SetHandleSprite3D(numEXT_Spr3d,newPivotX,newPivotY)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  EXT_Sprite3D(numEXT_Spr3d)\pivotX = (newPivotX)
  EXT_Sprite3D(numEXT_Spr3d)\pivotY  = (newPivotY)
  
  EXT_TransformSprite3D(*TRF3D_DX9sprite3D\Width,*TRF3D_DX9sprite3D\Height,EXT_Sprite3D(numEXT_Spr3d)\pivotX,EXT_Sprite3D(numEXT_Spr3d)\pivotY,*TRF3D_DX9sprite3D\Angle)
EndMacro

; Rescales an EXT_sprite3D
Macro EXT_ZoomSprite3D(numEXT_Spr3d,newSizeX,newSizeY)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  *TRF3D_DX9sprite3D\Width = (newSizeX)
  *TRF3D_DX9sprite3D\Height = (newSizeY)
  
  EXT_TransformSprite3D(*TRF3D_DX9sprite3D\Width,*TRF3D_DX9sprite3D\Height,EXT_Sprite3D(numEXT_Spr3d)\pivotX,EXT_Sprite3D(numEXT_Spr3d)\pivotY,*TRF3D_DX9sprite3D\Angle)
EndMacro

; Rotates an EXT_sprite3D
Macro EXT_RotateSprite3D(numEXT_Spr3d,newAngle)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  *TRF3D_DX9sprite3D\Angle = (newAngle)
  
  EXT_TransformSprite3D(*TRF3D_DX9sprite3D\Width,*TRF3D_DX9sprite3D\Height,EXT_Sprite3D(numEXT_Spr3d)\pivotX,EXT_Sprite3D(numEXT_Spr3d)\pivotY,*TRF3D_DX9sprite3D\Angle)
EndMacro


;-
;********************************************************
;- Flipping, Clipping, Coloring
;********************************************************

; Mirrors an EXT_sprite3D by manipulating its UV mapping (inverts left and right vertices' UV coords)
Macro EXT_FlipHoriSprite3D(numEXT_Spr3d)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  Swap *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tu,*TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tu
  Swap *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tv,*TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tv
  Swap *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tu,*TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tu
  Swap *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tv,*TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tv
  
  EXT_Sprite3D(numEXT_Spr3d)\flipmode = EXT_Sprite3D(numEXT_Spr3d)\flipmode ! %01
EndMacro

; Flips an EXT_sprite3D upside down by manipulating its UV mapping (inverts top and bottom vertices' UV coords)
Macro EXT_FlipVertSprite3D(numEXT_Spr3d)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  Swap *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tu,*TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tu
  Swap *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tv,*TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tv
  Swap *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tu,*TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tu
  Swap *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tv,*TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tv
  
  EXT_Sprite3D(numEXT_Spr3d)\flipmode = EXT_Sprite3D(numEXT_Spr3d)\flipmode ! %10
EndMacro


; Clips (= "crop") the image displayed by an EXT_sprite3D (very useful for animated sprites).
; NB: This doesn't change the actual size of the sprite3D, so you must ensure that each frame
;     of the animation is of the same size (or they will by stretched to the size of the sprite).
Macro EXT_ClipSprite3D(numEXT_Spr3d,x,y,x2,y2)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  ; The flip mode (left-right, up-down, or both) affects the computation of the UV coords
  Select EXT_Sprite3D(numEXT_Spr3d)\flipmode
    Case %00 ; no flip
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
    Case %01 ; horizontal flip
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
    Case %10 ; vertical flip
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
    Case %11 ; both
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\tv = (y) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tu = (x) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
      
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tu = (x2) / *TRF3D_DX9sprite3D\RealWidth
      *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\tv = (y2) / *TRF3D_DX9sprite3D\RealHeight
  EndSelect
  
EndMacro


; Applies a color filter to an EXT_sprite3D
Macro EXT_SetColorSprite3D(numEXT_Spr3d, newColor)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\Color = newColor
  *TRF3D_DX9sprite3D\Vertice[#TOPRIGHT]\Color = newColor
  *TRF3D_DX9sprite3D\Vertice[#BOTTOMLEFT]\Color = newColor
  *TRF3D_DX9sprite3D\Vertice[#BOTTOMRIGHT]\Color = newColor
EndMacro

; Same, but for just one vertex of the EXT_sprite3D
Macro EXT_SetVertexColorSprite3D(numEXT_Spr3d,numVertex,newColor)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  *TRF3D_DX9sprite3D\Vertice[#TOPLEFT]\Color = newColor
EndMacro

; Sets the alpha level ( = transparency) of an EXT_sprite3D. 0 = invisible, 255 = opaque
Macro EXT_SetAlphaSprite3D(numEXT_Spr3d, newAlpha)
  EXT_Sprite3D(numEXT_Spr3d)\alpha = newAlpha
EndMacro


;-
;********************************************************
;- Utilitary
;********************************************************

; Gets the current width of an EXT_sprite3D
Macro EXT_GetWidthSprite3D(numEXT_Spr3d)
  EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D\Width
EndMacro
; Gets the current height of an EXT_sprite3D
Macro EXT_GetHeightSprite3D(numEXT_Spr3d)
  EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D\Height
EndMacro

; Gets the "real" width of an EXT_sprite3D (that is to say, before any rescaling)
Macro EXT_GetRealWidthSprite3D(numEXT_Spr3d)
  EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D\Width
EndMacro

; Gets the "real" height of an EXT_sprite3D (that is to say, before any rescaling)
Macro EXT_GetRealHeightSprite3D(numEXT_Spr3d)
  EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D\Height
EndMacro

; Gets the current angle in radians of an EXT_sprite3D
Macro EXT_GetAngleSprite3D(numEXT_Spr3d)
  EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D\Height  
EndMacro  

; Gives True if the EXT_sprite3D is horizontally flipped
Macro EXT_isFlipHoriSprite3D(numEXT_Spr3d)
  (EXT_Sprite3D(numEXT_Spr3d)\flipmode & %01)
EndMacro  

; Gives True if the EXT_sprite3D is vertically flipped
Macro EXT_isFlipVertSprite3D(numEXT_Spr3d)
  ((EXT_Sprite3D(numEXT_Spr3d)\flipmode & %10) >> 1)
EndMacro  


;-
;********************************************************
;- Display
;********************************************************

; Display the EXT_sprite3D with its current alpha level
Macro EXT_DisplaySprite3D(numEXT_Spr3d,x,y)
  DisplaySprite3D(EXT_Sprite3D(numEXT_Spr3D)\numSprite3D,x,y,EXT_Sprite3D(numEXT_Spr3d)\alpha)
EndMacro


; Display various informations about a sprite3D in the debugger
Macro EXT_DebugInfosSprite3D(numEXT_Spr3d)
  *TRF3D_DX9sprite3D = EXT_Sprite3D(numEXT_Spr3d)\ptrSprite3D
  
  Debug "TexRes = " + Str(*TRF3D_DX9sprite3D\texRes)
  Debug "Vertices: "
  For i=0 To 3
    Debug "    " + Str(i) + " -> x,y   = " + StrF(*TRF3D_DX9sprite3D\Vertice[i]\x,2) + "," + StrF(*TRF3D_DX9sprite3D\Vertice[i]\y,2)
    Debug "         rhw   = " + StrF(*TRF3D_DX9sprite3D\Vertice[i]\rhw,2)
    Debug "         color = " + Str(Red(*TRF3D_DX9sprite3D\Vertice[i]\color)) + "," + Str(Green(*TRF3D_DX9sprite3D\Vertice[i]\color)) + Str(Blue(*TRF3D_DX9sprite3D\Vertice[i]\color))
  Next i
  Debug "Temp Vertices: "
  For i=0 To 3
    Debug "    " + Str(i) + " -> x,y   = " + StrF(*TRF3D_DX9sprite3D\TmpVertice[i]\x,2) + "," + StrF(*TRF3D_DX9sprite3D\TmpVertice[i]\y,2)
    Debug "         rhw   = " + StrF(*TRF3D_DX9sprite3D\TmpVertice[i]\rhw,2)
    Debug "         color = " + Str(Red(*TRF3D_DX9sprite3D\TmpVertice[i]\color)) + "," + Str(Green(*TRF3D_DX9sprite3D\TmpVertice[i]\color)) + Str(Blue(*TRF3D_DX9sprite3D\TmpVertice[i]\color))
  Next i
  Debug "Width, Height      = " + Str(*TRF3D_DX9sprite3D\Width) + "," + Str(*TRF3D_DX9sprite3D\Height)
  Debug "Real Width, Height = " + Str(*TRF3D_DX9sprite3D\RealWidth) + "," + Str(*TRF3D_DX9sprite3D\RealHeight)
  Debug "Angle = " + StrF(*TRF3D_DX9sprite3D\Angle)
  Debug "Transformed = " + Str(*TRF3D_DX9sprite3D\Transformed)
  
EndMacro

Excellent addition to 3D Sprites but can you explain how to use the EXT_SetHandleSprite3D command? What kind of units do i need to use? I tried pixels to set a point outside of an image but it does not rotate how i want it to. One of the examples shows a -0.5,0.5.. is it float percentages or something?
AndyMK
Enthusiast
Enthusiast
Posts: 582
Joined: Wed Jul 12, 2006 4:38 pm
Location: UK

Re: Sprite3D - HotSpot and float coordiantes

Post by AndyMK »

Ignore my last post. It was late and i didn't all the commands available.
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Re: Sprite3D - HotSpot and float coordiantes

Post by DoubleDutch »

Kelebrindae: Thanks for the code...

Fred/Freak: imho these things need to be 'built-in' and cross platform.
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
Post Reply