scale sprite 3d
-
superadnim
- Enthusiast

- Posts: 480
- Joined: Thu Jul 27, 2006 4:06 am
scale sprite 3d
how can i scale a sprite3d down in width so it's not square anymore? i tried using TransformSprite3D but the help document isnt very helpful
worth noting: i have to rotate the sprite and they are of course textured
i dont want to use external libraries if possible
thanks
worth noting: i have to rotate the sprite and they are of course textured
i dont want to use external libraries if possible
thanks
Re: scale sprite 3d
ZoomSprite3D(#Sprite, NewWidth, NewHeight)superadnim wrote:how can i scale a sprite3d down in width so it's not square anymore?
Code: Select all
If InitSprite() = 0 Or InitSprite3D() = 0
MessageRequester("Error", "Can't open screen & sprite enviroment!", 0)
End
EndIf
If OpenWindow(0, 0, 0, 800, 600, "Sprite3D", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 0, 0, 0)
CreateSprite(0, 64, 64, #PB_Sprite_Texture)
If StartDrawing(SpriteOutput(0))
Box(0,0,64,64,RGB($FF,$FF,$00))
DrawingMode(#PB_2DDrawing_Outlined)
Box(0,0,64,64,RGB($00,$00,$FF))
LineXY( 0,0,64,64,RGB($00,$00,$FF))
LineXY(64,0, 0,64,RGB($00,$00,$FF))
StopDrawing()
EndIf
CreateSprite3D(0,0)
Else
MessageRequester("Error", "Can't open windowed screen!", 0)
End
EndIf
EndIf
direction = 2
zoomX = 64
zoomY = 64
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
End
EndSelect
Until Event = 0
FlipBuffers()
ClearScreen(RGB($40, $40, $40))
If Start3D()
ZoomSprite3D(0,zoomX,zoomY)
;RotateSprite3D(0,3,#PB_Relative)
DisplaySprite3D(0, 400-zoomX*0.5, 300-zoomY*0.5)
Stop3D()
EndIf
zoomX + direction
If zoomX > 300 : direction = -2 : EndIf
If zoomX < 20 : direction = 2 : EndIf
Delay(1)
ForEver-
superadnim
- Enthusiast

- Posts: 480
- Joined: Thu Jul 27, 2006 4:06 am
Re: scale sprite 3d
hi thanks!
the problem is that the transformation matrix seems to be pushed or something because i cant get the effect im after by calling ZoomSprite3D and then RotateSprite3D
i have square images that need to be sized down in one axis so i can get a iso effect when i rotate it (so i would scale it down by height not width but i need to perform both actions anyway)
thats the reason why i think the only way of doing it is through TransformSprite3D but i dont know how
in legacy opengl you would push or pop the matrix off the stack to achieve what im after
the problem is that the transformation matrix seems to be pushed or something because i cant get the effect im after by calling ZoomSprite3D and then RotateSprite3D
i have square images that need to be sized down in one axis so i can get a iso effect when i rotate it (so i would scale it down by height not width but i need to perform both actions anyway)
thats the reason why i think the only way of doing it is through TransformSprite3D but i dont know how
in legacy opengl you would push or pop the matrix off the stack to achieve what im after
Re: scale sprite 3d
I think I know what you want:
TransformSprite3D() + DisplaySprite3D(#Sprite,0,0) display the sprite exactly at the co-ordinates pairs (x,y)
of TransformSprite3D().
Unfortunately I don't know more about TransformSprite3D() and I don't understand the 'z' parameter myself, as it is not documented
and I think the PB developers can't explain it themselves.
Zoom and Rotate don't seem to work together with TransformSprite3D(). So I am sorry, can't help.
Code: Select all
If InitSprite() = 0 Or InitSprite3D() = 0
MessageRequester("Error", "Can't open screen & sprite enviroment!", 0)
End
EndIf
If OpenWindow(0, 0, 0, 800, 600, "Sprite3D", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 0, 0, 0)
CreateSprite(0, 64, 64, #PB_Sprite_Texture)
If StartDrawing(SpriteOutput(0))
Box(0,0,64,64,RGB($FF,$FF,$00))
DrawingMode(#PB_2DDrawing_Outlined)
Box(0,0,64,64,RGB($00,$00,$FF))
For y = 0 To 64 Step 4
LineXY(0,y,64,y,RGB($00,$FF,$FF))
Next y
LineXY( 0,0,64,64,RGB($00,$00,$FF))
;LineXY(63,0, 0,63,RGB($00,$00,$FF))
LineXY(64,0, 0,64,RGB($00,$00,$FF))
;LineXY(65,0, 0,65,RGB($00,$00,$FF))
StopDrawing()
EndIf
CreateSprite3D(0,0)
Else
MessageRequester("Error", "Can't open windowed screen!", 0)
End
EndIf
EndIf
direction = 2
zoomX = 64
zoomY = 64
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
End
EndSelect
Until Event = 0
FlipBuffers()
ClearScreen(RGB($40, $40, $40))
If Start3D()
TransformSprite3D(0, 0,0, 64,0, 64,64, 0,64)
DisplaySprite3D(0,0,0)
TransformSprite3D(0, 200,175, 300,175, 200,200, 100,200)
DisplaySprite3D(0,0,0)
TransformSprite3D(0, 400,175, 800,175, 500,275, 100,275)
DisplaySprite3D(0,0,0)
Stop3D()
EndIf
Delay(1)
ForEverof TransformSprite3D().
Unfortunately I don't know more about TransformSprite3D() and I don't understand the 'z' parameter myself, as it is not documented
and I think the PB developers can't explain it themselves.
Zoom and Rotate don't seem to work together with TransformSprite3D(). So I am sorry, can't help.
Re: scale sprite 3d
the best i can do
only work with directx, look like opengl has zbuffer not activated.
Code: Select all
Procedure RotateSprY(spriteId.i, width.i, height.i, angle.f )
Define sine.f
Define cosine.f
Define x.f
Define z.f
angle = Radian(angle)
sine = Sin( angle )
cosine = Cos( angle )
; Y rotation:
; _______________________________ _
;|cos(angle) 0 -sin(angle) | * |x|
;|0 1 0 | |y|
;|sin(angle) 0 cos(angle) | |z|
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯
x = (1 * cosine) - (width * sine )
z = (1 * sine) + (width * cosine)
If (x>0.0)
TransformSprite3D(spriteId, 0, 0, 100, x, 0, 100+z, x, height, 100+z, 0, height, 100)
Else
TransformSprite3D(spriteId, x, 0, 100+z, 0, 0, 100, 0, height, 100, x, height, 100+z)
EndIf
EndProcedure
-
superadnim
- Enthusiast

- Posts: 480
- Joined: Thu Jul 27, 2006 4:06 am
Re: scale sprite 3d
thanks for your help guys
xorc1zt: im not sure how your code works
but what im trying to do is rotate a sprite 45 degrees and then squish it pretty much by half so it looks like an isometric sprite the trick is that when you rotate this sprite it has to rotate around this plane but because pb rotation and scale functions do the transformation separately it doesnt work hence why i think the only way to do it natively is by using TransformSprite3D
if i do it with the native functions the scaling is performed separately and what i get is a rotating rectangle instead of what should look like an isometric sprite
otherwise is it possible to change the view matrix or some other transformation to 'abuse' the native engine?
xorc1zt: im not sure how your code works
if i do it with the native functions the scaling is performed separately and what i get is a rotating rectangle instead of what should look like an isometric sprite
otherwise is it possible to change the view matrix or some other transformation to 'abuse' the native engine?
Re: scale sprite 3d
this ?
Code: Select all
Macro MakeSpriteIso(spriteID, width, height)
TransformSprite3D(spriteId, 0, height/2, 1, width/2, 0, 1, width, height/2, 1, width/2, height, 1)
EndMacro
;alternative
Macro MakeSpriteIso2(spriteID, width, height)
TransformSprite3D(spriteId, width/2, 0, 1, width, height/2, 1, width/2, height, 1, 0, height/2, 1)
EndMacro
-
superadnim
- Enthusiast

- Posts: 480
- Joined: Thu Jul 27, 2006 4:06 am
Re: scale sprite 3d
this has no effect if we use the rotation function it must all be integrated otherwise each function cancels each other out
Re: scale sprite 3d
I think one of these two are what you are after:
Code: Select all
;iso rotated left 45 degrees
Macro MakeSpriteIso(spriteID, width, height)
TransformSprite3D(spriteID, 0, height/4, width/2, 0, width, height/4, width/2, height/2)
EndMacro
;iso rotated right degrees
Macro MakeSpriteIso2(spriteID, width, height)
TransformSprite3D(spriteID, width/2, 0, width, height/4, width/2, height/2, 0, height/4)
EndMacro-
superadnim
- Enthusiast

- Posts: 480
- Joined: Thu Jul 27, 2006 4:06 am
Re: scale sprite 3d
thanks but no i want to perform arbitrary rotation on objects not just fixed
Re: scale sprite 3d
Try this:superadnim wrote:thanks but no i want to perform arbitrary rotation on objects not just fixed
Code: Select all
Structure Point_f
x.f
y.f
EndStructure
;iso rotated right degrees
Procedure MakeSpriteIsoRight(spriteID, width, height, cx, cy, degree, newWidth, newHeight)
Protected.Point_f p1, p2, p3, p4
Protected.f wf = width / newWidth, hf = height / newHeight
If degree = 0
p1\x = (( -cx) / wf) - 0.5: p1\y = (( -cy) / hf) - 0.5
p2\x = ((width - cx) / wf) - 0.5: p2\y = (( -cy) / hf) - 0.5
p3\x = ((width - cx) / wf) - 0.5: p3\y = ((height - cy) / hf) - 0.5
p4\x = (( -cx) / wf) - 0.5: p4\y = ((height - cy) / hf) - 0.5
Else
Protected.f angCos = Cos(Radian(degree)), angSin = Sin(Radian(degree))
v1 = -cx * angCos: v3 = -cy * angSin
v2 = -cx * angSin: v4 = -cy * angCos
v6 = (width - cx) * angCos: v7 = (height - cy) * angSin
v5 = (width - cx) * angSin: v8 = (height - cy) * angCos
p1\x = ((v1 - v3) / wf) - 0.5: p1\y = ((v4 + v2) / hf) - 0.5
p2\x = ((v6 - v3) / wf) - 0.5: p2\y = ((v4 + v5) / hf) - 0.5
p3\x = ((v6 - v7) / wf) - 0.5: p3\y = ((v8 + v5) / hf) - 0.5
p4\x = ((v1 - v7) / wf) - 0.5: p4\y = ((v8 + v2) / hf) - 0.5
EndIf
TransformSprite3D(spriteID, p1\x, p1\y, p2\x, p2\y, p3\x, p3\y, p4\x, p4\y)
EndProcedure
;iso rotated left 45 degrees
Procedure MakeSpriteIsoLeft(spriteID, width, height, cx, cy, degree, newWidth, newHeight)
MakeSpriteIsoRight(spriteID, width, height, cx, cy, 360 - degree, newWidth, newHeight)
EndProcedure
If InitSprite() = 0 Or InitSprite3D() = 0
MessageRequester("Error", "Can't open screen & sprite enviroment!", 0)
End
EndIf
If OpenWindow(0, 0, 0, 800, 600, "Sprite3D", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 0, 0, 0)
CreateSprite(0, 64, 64, #PB_Sprite_Texture)
LoadFont(0, "Arial", 36)
If StartDrawing(SpriteOutput(0))
Box(0,0,64,64,RGB($FF,$FF,$00))
; DrawingMode(#PB_2DDrawing_Outlined)
; Box(0,0,64,64,RGB($00,$00,$FF))
; LineXY( 0,0,64,64,RGB($00,$00,$FF))
; LineXY(64,0, 0,64,RGB($00,$00,$FF))
DrawingMode(#PB_2DDrawing_Outlined)
DrawingFont(FontID(0))
DrawText(0,0,"PB",RGB($FF,$00,$00))
Box(0,0,64,64,RGB($00,$00,$FF))
LineXY( 0,0,64,64,RGB($00,$00,$FF))
LineXY(64,0, 0,64,RGB($00,$00,$FF))
StopDrawing()
EndIf
CreateSprite3D(0,0)
Else
MessageRequester("Error", "Can't open windowed screen!", 0)
End
EndIf
EndIf
direction = 2
zoomX = 64
zoomY = 64
Repeat
Repeat
event = WindowEvent()
Select event
Case #PB_Event_CloseWindow
End
EndSelect
Until event = 0
FlipBuffers()
ClearScreen(RGB($40, $40, $40))
If Start3D()
MakeSpriteIsoLeft(0, 64, 64, 32, 32, 0, 64, 64) ;normal
DisplaySprite3D(0, 100, 100)
MakeSpriteIsoLeft(0, 64, 64, 32, 32, angle, 64, 32) ;squished vertically
DisplaySprite3D(0, 200-zoomX*0.5, 300-zoomY*0.5)
MakeSpriteIsoLeft(0, 64, 64, 32, 32, angle, 32, 64) ;squished horizontally
DisplaySprite3D(0, 300-zoomX*0.5, 300-zoomY*0.5)
MakeSpriteIsoRight(0, 64, 64, 32, 32, angle, 2 * zoomX, 1 * zoomX) ;squished vertically and zoomed
DisplaySprite3D(0, 700-zoomX*0.5, 300-zoomY*0.5)
MakeSpriteIsoRight(0, 64, 64, 32, 32, angle, 1 * zoomX, 2 * zoomX) ;squished horizontally and zoomed
DisplaySprite3D(0, 500-zoomX*0.5, 300-zoomY*0.5)
MakeSpriteIsoLeft(0, 64, 64, 32, 32, angle, 64, 20 + zoomX / 2) ;squishiness varying vertically
DisplaySprite3D(0, 200, 500)
MakeSpriteIsoLeft(0, 64, 64, 32, 32, angle, 20 + zoomX / 2, 64) ;squishiness varying horizontally
DisplaySprite3D(0, 300, 500)
Stop3D()
EndIf
angle + 1: If angle > 360: angle = 0: EndIf
zoomX + direction
If zoomX > 100 : direction = -2 : EndIf
If zoomX < 20 : direction = 2 : EndIf
Delay(1)
ForEverI worked out the transformation but ran into some slight calculation errors. I looked up some old code written by Kelebrindae that solved the problems I had. You will probably find some other functions he wrote helpful for sprite3D. Here is the thread that had similar code to what I posted above.
I wrote it as a procedure but you may need or prefer to use it as a macro.
Here is an update of the previous code for PureBasic v5.20LTS:
Code: Select all
Structure Point_f
x.f
y.f
EndStructure
;iso rotated right degrees
Procedure MakeSpriteIsoRight(spriteID, width, height, cx, cy, degree, newWidth, newHeight)
Protected.Point_f p1, p2, p3, p4
Protected.f wf = width / newWidth, hf = height / newHeight
If degree = 0
p1\x = (( -cx) / wf) - 0.5: p1\y = (( -cy) / hf) - 0.5
p2\x = ((width - cx) / wf) - 0.5: p2\y = (( -cy) / hf) - 0.5
p3\x = ((width - cx) / wf) - 0.5: p3\y = ((height - cy) / hf) - 0.5
p4\x = (( -cx) / wf) - 0.5: p4\y = ((height - cy) / hf) - 0.5
Else
Protected.f angCos = Cos(Radian(degree)), angSin = Sin(Radian(degree))
v1 = -cx * angCos: v3 = -cy * angSin
v2 = -cx * angSin: v4 = -cy * angCos
v6 = (width - cx) * angCos: v7 = (height - cy) * angSin
v5 = (width - cx) * angSin: v8 = (height - cy) * angCos
p1\x = ((v1 - v3) / wf) - 0.5: p1\y = ((v4 + v2) / hf) - 0.5
p2\x = ((v6 - v3) / wf) - 0.5: p2\y = ((v4 + v5) / hf) - 0.5
p3\x = ((v6 - v7) / wf) - 0.5: p3\y = ((v8 + v5) / hf) - 0.5
p4\x = ((v1 - v7) / wf) - 0.5: p4\y = ((v8 + v2) / hf) - 0.5
EndIf
TransformSprite(spriteID, p1\x, p1\y, p2\x, p2\y, p3\x, p3\y, p4\x, p4\y)
EndProcedure
;iso rotated left 45 degrees
Procedure MakeSpriteIsoLeft(spriteID, width, height, cx, cy, degree, newWidth, newHeight)
MakeSpriteIsoRight(spriteID, width, height, cx, cy, 360 - degree, newWidth, newHeight)
EndProcedure
If InitSprite() = 0
MessageRequester("Error", "Can't open screen & sprite enviroment!", 0)
End
EndIf
If OpenWindow(0, 0, 0, 800, 600, "Sprite3D", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 0, 0, 0)
CreateSprite(0, 64, 64)
LoadFont(0, "Arial", 36)
If StartDrawing(SpriteOutput(0))
Box(0,0,64,64,RGB($FF,$FF,$00))
; DrawingMode(#PB_2DDrawing_Outlined)
; Box(0,0,64,64,RGB($00,$00,$FF))
; LineXY( 0,0,64,64,RGB($00,$00,$FF))
; LineXY(64,0, 0,64,RGB($00,$00,$FF))
DrawingMode(#PB_2DDrawing_Outlined)
DrawingFont(FontID(0))
DrawText(0,0,"PB",RGB($FF,$00,$00))
Box(0,0,64,64,RGB($00,$00,$FF))
LineXY( 0,0,64,64,RGB($00,$00,$FF))
LineXY(64,0, 0,64,RGB($00,$00,$FF))
StopDrawing()
EndIf
Else
MessageRequester("Error", "Can't open windowed screen!", 0)
End
EndIf
EndIf
direction = 2
zoomX = 64
zoomY = 64
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
End
EndSelect
Until Event = 0
FlipBuffers()
ClearScreen(RGB($40, $40, $40))
MakeSpriteIsoLeft(0, 64, 64, 32, 32, 0, 64, 64) ;normal
DisplaySprite(0, 100, 100)
MakeSpriteIsoLeft(0, 64, 64, 32, 32, angle, 64, 32) ;squished vertically
DisplaySprite(0, 200-zoomX*0.5, 300-zoomY*0.5)
MakeSpriteIsoLeft(0, 64, 64, 32, 32, angle, 32, 64) ;squished horizontally
DisplaySprite(0, 300-zoomX*0.5, 300-zoomY*0.5)
MakeSpriteIsoRight(0, 64, 64, 32, 32, angle, 2 * zoomX, 1 * zoomX) ;squished vertically and zoomed
DisplaySprite(0, 700-zoomX*0.5, 300-zoomY*0.5)
MakeSpriteIsoRight(0, 64, 64, 32, 32, angle, 1 * zoomX, 2 * zoomX) ;squished horizontally and zoomed
DisplaySprite(0, 500-zoomX*0.5, 300-zoomY*0.5)
MakeSpriteIsoLeft(0, 64, 64, 32, 32, angle, 64, 20 + zoomX / 2) ;squishiness varying vertically
DisplaySprite(0, 200, 500)
MakeSpriteIsoLeft(0, 64, 64, 32, 32, angle, 20 + zoomX / 2, 64) ;squishiness varying horizontally
DisplaySprite(0, 300, 500)
angle + 1: If angle > 360: angle = 0: EndIf
zoomX + direction
If zoomX > 100 : direction = -2 : EndIf
If zoomX < 20 : direction = 2 : EndIf
Delay(1)
ForEver@Edit: Added an updated version for v5.20 LTS
Last edited by Demivec on Fri Oct 04, 2013 11:29 pm, edited 1 time in total.
-
superadnim
- Enthusiast

- Posts: 480
- Joined: Thu Jul 27, 2006 4:06 am
Re: scale sprite 3d
ohh this works! thanks!
although if we use opengl then it doesnt work properly
but it does in dx
strange thing it looks like theres an issue with the vertices not just the UV coords in fact those are fine in OGL but the vertices arent
although if we use opengl then it doesnt work properly
strange thing it looks like theres an issue with the vertices not just the UV coords in fact those are fine in OGL but the vertices arent
