[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
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:
Code: BASIC
;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