[bb] SpriteMesh instead of Blitz3d Sprite by RemiD [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:43

Previous topic - Next topic

BlitzBot

Title : SpriteMesh instead of Blitz3d Sprite
Author : RemiD
Posted : 1+ years ago

Description : Shows how to use a sprite mesh instead of a Blitz3d sprite

Code :
Code (blitzbasic) Select
Global GWidth% = 800
Global GHeight% = 600
Global GColors% = 32
Global GMode% = 2
Graphics3D(GWidth,GHeight,GColors,GMode)

SeedRnd(MilliSecs())
 
Global Camera = CreateCamera()
CameraRange(Camera,0.1,10000)

Origine = CreateCube()
ScaleMesh(Origine,0.01/2,0.01/2,0.01/2)
EntityColor(Origine,255,000,000)
EntityFX(Origine,1)
 
Global DebugFeet = CreatePivot()  
 
Global DebugEyes = CreatePivot()
PositionEntity(DebugEyes,EntityX(DebugFeet,True),EntityY(DebugFeet,True),EntityZ(DebugFeet,True))
RotateEntity(DebugEyes,EntityPitch(DebugFeet,True),EntityYaw(DebugFeet,True),EntityRoll(DebugFeet,True))
MoveEntity(DebugEyes,0,1.7,0.25)
EntityParent(DebugEyes,DebugFeet,True)

DebugMesh = CreateCube()
ScaleMesh(DebugMesh,0.5/2,1.8/2,0.25/2)
PositionMesh(DebugMesh,0,1.8/2,0)
PositionEntity(DebugMesh,EntityX(DebugFeet,True),EntityY(DebugFeet,True),EntityZ(DebugFeet,True))
RotateEntity(DebugMesh,EntityPitch(DebugFeet,True),EntityYaw(DebugFeet,True),EntityRoll(DebugFeet,True))
EntityParent(DebugMesh,DebugFeet,True)
EntityColor(DebugMesh,000,000,255)

Global MXSpeed# = 0
Global MYSpeed# = 0
Global DebugFeetYaw# = 0
Global DebugEyesPitch# = 0

Const CEditView% = 1
Const CDebugView% = 2
Global CameraMode% = 0
CameraMode = CDebugView
EntityParent(Camera,0)
PositionEntity(Camera,EntityX(DebugEyes,True),EntityY(DebugEyes,True),EntityZ(DebugEyes,True))
RotateEntity(Camera,EntityPitch(DebugEyes,True),EntityYaw(DebugEyes,True),EntityRoll(DebugEyes,True))  
EntityParent(Camera,DebugEyes,True)
 
PositionEntity(DebugFeet,0,0,-5)
 
;ViewMode
;1: fixed (sprite always faces camera - Default)
;2: free (sprite is independent of camera)
;3: upright1 (sprite always faces camera, but rolls with camera as well, unlike mode no.1)
;4: upright2 (sprite always remains upright. Gives a 'billboard' effect. Good For trees, spectators etc.)
ViewMode% = 1

SpriteMesh = CreateMesh()
Surface = CreateSurface(SpriteMesh)
AddVertex(Surface, -0.5, 0.5, 0.0, 0.000, 0.000)
AddVertex(Surface, 0.5, 0.5, 0.0, 1.000, 0.000)
AddVertex(Surface, -0.5, -0.5, 0.0, 0.000, 1.000)
AddVertex(Surface, 0.5, -0.5, 0.0, 1.000, 1.000)
AddTriangle(Surface,0,1,2)
AddTriangle(Surface,2,1,3)
UpdateNormals(SpriteMesh)
PositionEntity(SpriteMesh,1,0,0)
EntityFX(SpriteMesh,1)

SpriteOriginal = CreateSprite()
ScaleSprite(SpriteOriginal,0.5,0.5)
SpriteViewMode(SpriteOriginal,ViewMode)  
PositionEntity(SpriteOriginal,-1,0,0)
 
SmileyTexDiffuse = CreateTexture(128,128)
SetBuffer(TextureBuffer(SmileyTexDiffuse))
ClsColor(125,125,125)
Cls()
Color(255,255,000)
Oval(0,0,128,128,1)
Color(001,001,001)
Oval(33,20,20,40)
Oval(73,20,20,40)
Plot(60,75)
Plot(66,75)
Line(63,95,43,95)
Line(43,95,33,80)
Line(64,95,84,95)
Line(84,95,94,80)
SetBuffer(BackBuffer())
TextureBlend(SmileyTexDiffuse,2)
EntityTexture(SpriteMesh,SmileyTexDiffuse,0,0)
EntityTexture(SpriteOriginal,SmileyTexDiffuse,0,0)

DLight = CreateLight(1)
LightColor(DLight,255,255,255)
PositionEntity(DLight,0,1024,-1024)
RotateEntity(DLight,45,0,0)
AmbientLight(125,125,125)
 
Repeat

 MainLoopStart% = MilliSecs()

 Cls()

 CameraModeSelect()

 DebugUpdate()

 If(ViewMode = 1)
  RotateEntity(SpriteMesh,EntityPitch#(Camera,True),EntityYaw#(Camera,True),EntityRoll#(Camera,True))
 ElseIf(ViewMode = 2)
  ;
 ElseIf(ViewMode = 3)
  RotateEntity(SpriteMesh,EntityPitch#(Camera,True),EntityYaw#(Camera,True),0)
 ElseIf(ViewMode = 4)
  RotateEntity(SpriteMesh,0,EntityYaw#(Camera,True),0)
 EndIf

 If(KeyDown(2)>0)  
  Wireframe(True)  
 Else  
  Wireframe(False)  
 EndIf

 SetBuffer(BackBuffer())
 RenderWorld()

 Color(255,255,255)
 Text(0,0,"Tris : "+TrisRendered())
 Text(0,20,"FPS = "+FPS)

 Flip(True)

 MainLoopTime% = MilliSecs() - MainLoopStart

 FPS = 1000/MainLoopTime

Until(KeyDown(1)>0)

End

Function CameraModeSelect()
 ;Select between DebugView and EditView
 If(KeyHit(15)>0)
  If(CameraMode = CDebugView)
   CameraMode = CEditView
   EntityParent(Camera,0)
  ElseIf(CameraMode = CEditView)
   CameraMode = CDebugView
   EntityParent(Camera,0)
   PositionEntity(Camera,EntityX(DebugEyes,True),EntityY(DebugEyes,True),EntityZ(DebugEyes,True))
   RotateEntity(Camera,EntityPitch(DebugEyes,True),EntityYaw(DebugEyes,True),EntityRoll(DebugEyes,True))  
   EntityParent(Camera,DebugEyes,True)
  EndIf
 EndIf
End Function

Function DebugUpdate()
 If(CameraMode = CDebugView)
  MXSpeed = MouseXSpeed()  
  MYSpeed = MouseYSpeed()  
  MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2)
  DebugEyesPitch = DebugEyesPitch+MYSpeed*0.1
  If(DebugEyesPitch > 89)
   DebugEyesPitch = 89
  EndIf
  If(DebugEyesPitch < -89)
   DebugEyesPitch = -89
  EndIf
  DebugFeetYaw = DebugFeetYaw-MXSpeed*0.1  
  RotateEntity(DebugEyes,DebugEyesPitch,0,0)
  RotateEntity(DebugFeet,0,DebugFeetYaw,0)  
  If(KeyDown(42)>0)
   SpeedCoeff# = 10.0
  ElseIf(KeyDown(29)>0)
   SpeedCoeff# = 0.1
  Else
   SpeedCoeff# = 1.0
  EndIf
  If(KeyDown(17)>0)  
   MoveEntity(DebugFeet,0,0,0.1*SpeedCoeff)  
  EndIf  
  If(KeyDown(31)>0)  
   MoveEntity(DebugFeet,0,0,-0.1*SpeedCoeff)  
  EndIf  
  If(KeyDown(30)>0)  
   MoveEntity(DebugFeet,-0.1*SpeedCoeff,0,0)  
  EndIf  
  If(KeyDown(32)>0)  
   MoveEntity(DebugFeet,0.1*SpeedCoeff,0,0)  
  EndIf  
  If(KeyDown(16)>0)  
   MoveEntity(DebugFeet,0,-0.1*SpeedCoeff,0)  
   EndIf
  If(KeyDown(18)>0)  
   MoveEntity(DebugFeet,0,0.1*SpeedCoeff,0)  
  EndIf
  If(KeyHit(201)>0)
   MoveEntity(Camera,0,0,0.1)
  EndIf
  If(KeyHit(209)>0)
   MoveEntity(Camera,0,0,-0.1)
  EndIf
  If(KeyDown(44)>0)
   TurnEntity(Camera,0,0,-1)
  EndIf
  If(KeyDown(45)>0)
   TurnEntity(Camera,0,0,1)
  EndIf
 ElseIf(CameraMode = CEditView)
  MXSpeed = MouseXSpeed()  
  MYSpeed = MouseYSpeed()  
  ;MoveMouse(GWidth/2,GHeight/2)
 EndIf
End Function


Comments :


_PJ_(Posted 1+ years ago)

 I think this should be more accurate in terms of how the 'standard' SpriteViewMode works:
;Sprite Overload

;1: Sprite changes its pitch And yaw values To face camera, but doesn't roll. (Default)
;2: Sprite does Not change either its pitch, yaw Or roll values.
;3: Sprite changes its yaw And pitch To face camera, And changes its roll value To match cameras.
;4: Sprite changes its yaw value To face camera, but Not its pitch value, And changes its roll value To match cameras.

; Note:
; ClearWorld will destroy sprite meshes, but not the TYPES.
; EntityClass will not return "Sprite" results: Type Handle = "Entity does not exist"
; EntityClass will not return "Sprite" results: Quad Handle = "Mesh"
; RotateSprite is only valid for SpriteViewMode 1 or 2

;Necessary Additions

Type SPRITES
Field SpriteMesh
Field ViewMode
End Type

Function UpdateSprite(Sprite,Camera=0)
;When using Sprites of Mode 1,3 or 4 This must be used befrore every Render
;For every CAMERA for every SPRITE
;Whenever that camera moves or rotates wrt the sprite
If (Not(Sprite))
Return
End If

Local This.SPRITES=Object.SPRITES(Sprite)
If (This=Null)
Return
End If

Local Quad=ThisSpriteMesh

If (Not(Quad))
FreeSprite(Sprite)
Else

Local P#=EntityPitch#(Quad,True)
Local Y#=EntityYaw#(Quad,True)+DeltaYaw(Quad,Camera)
Local R#=EntityRoll#(Quad,True)

Local Mode=ThisViewMode
If (Mode<>2)
If (Mode=1)
P=P+DeltaPitch#(Quad,Camera)
Else
R=EntityRoll#(Camera,True)
End If
RotateEntity Quad,P,Y,R,True
End If

End If

End Function

;Override Functions

Function LoadSprite(FilePath$, Flags=1, Parent=0)
If (FileType(FilePath=1))
Local Texture=LoadTexture(FilePath,Flags)
If (Texture)
Local This.SPRITES=New SPRITES
ThisSpriteMesh=CreateQuad(Parent)
EntityTexture ThisSpriteMesh,Texture
FreeTexture Texture
ThisViewMode=1
;It might be adviseable to call UpdateSprite() here
Return Handle(This.SPRITES)
End If
End If
Return 0
End Function

Function FreeSprite(Sprite)
; Use this instead of FreeEntity to ensure Sprites are effectively removed from memory
If (Not(Sprite))
Return
End If

Local This.SPRITES=Object.SPRITES(Sprite)
If (This.SPRITES=Null)
Return
End If

If (ThisSpriteMesh)
FreeEntity ThisSpriteMesh
ThisSpriteMesh=0
ThisViewMode=0
End If
Delete This
End Function

Function HandleSprite(Sprite, X#=0.5, Y#=0.5)
Local Quad=GetSpriteMesh(Sprite)
If (Quad)
PositionMesh Quad,X*MeshWidth(Quad),Y*MeshHeight(Quad),0.5*MeshDepth(Quad)
End If
End Function

Function RotateSprite(Sprite, Angle#)
Local Quad=GetSpriteMesh(Sprite)
If (Quad)
TurnEntity Quad,0,0,Angle,False
End If
End Function

Function ScaleSprite(Sprite, X#, Y#)
Local Quad=GetSpriteMesh(Sprite)
If (Quad)
ScaleMesh Quad,X,Y,1.0
End If
End Function

Function SpriteViewMode(Sprite, Mode=2)
Mode=((Mode>0)*(Mode<5)*Mode)+(2*((Mode<1)+(Mode>4)))

If (Not(Sprite))
Return
End If
Local This.SPRITES=Object.SPRITES(Sprite)

If (ThisSpriteMesh)
ThisViewMode=Mode
;It might be adviseable to call UpdateSprite() here
Else
FreeSprite(Sprite)
End If
End Function

; For Direct Manipulation & Helper functions

Function GetSpriteMesh(Sprite)
If (Not(Sprite))
Return 0
End If

Local This.SPRITES=Object.SPRITES(Sprite)
If (This.SPRITES=Null)
Return 0
End If

Return ThisSpriteMesh
End Function

Function CreateQuad(Parent=False)
Local Mesh=CreateMesh(Parent)
Local Surface=CreateSurface(Mesh)

AddVertex(Surface,-0.5,0.5,0,1,0)
VertexColor Surface,0,255,255,255
AddVertex(Surface,0.5,0.5,0,0,0)
VertexColor Surface,1,255,255,255
AddVertex(Surface,-0.5,-0.5,0,1,1)
VertexColor Surface,2,255,255,255
AddVertex(Surface,0.5,-0.5,0,0,1)
VertexColor Surface,3,255,255,255
AddTriangle(Surface,0,1,2)
AddTriangle(Surface,3,2,1)

UpdateNormals Mesh

Return Mesh
End Function