Sswift EntityScale functions

Blitz3D Forums/Blitz3D Programming/Sswift EntityScale functions

_PJ_(Posted 2003) [#1]
I have been trying to use the EntityScale functions from the code archives . The effect I am after is a separate image of specific entities, however the entities vary in size and scale a lot.

The problem I have is that the functions only refer to the Original scale of the meshes, not the scaled-up/down versions I need in my game.

Is there any way around this? All I need is to move the camera far enough away so that the meshes fit in the camera viewport.

here's my code:

	Vx# = GetMatElement(targetEntity, 0, 0)
	Vy# = GetMatElement(targetEntity, 0, 1)
	Vz# = GetMatElement(targetEntity, 0, 2)	
	
	ScaleX# = Sqr(Vx#*Vx# + Vy#*Vy# + Vz#*Vz#)

	Vx# = GetMatElement(targetEntity, 1, 0)
	Vy# = GetMatElement(targetEntity, 1, 1)
	Vz# = GetMatElement(targetEntity, 1, 2)	
	
	ScaleY# = Sqr(Vx#*Vx# + Vy#*Vy# + Vz#*Vz#)

	Vx# = GetMatElement(targetEntity, 2, 0)
	Vy# = GetMatElement(targetEntity, 2, 1)
	Vz# = GetMatElement(targetEntity, 2, 2)		
	ScaleZ# = Sqr(Vx#*Vx# + Vy#*Vy# + Vz#*Vz#)


PositionEntity target,EntityX#(targetentity,1),EntityY#(targetentity,1),EntityZ#(targetentity,1)

TranslateEntity target,0,0,((scaleX#+ScaleY#+ScaleZ)/3)

PointEntity target,targetentity



Where target = camera
and targetentity = mesh


sswift(Posted 2003) [#2]
You're going to have to explain further because I can't understand what it is you want to accomplish.


DJWoodgate(Posted 2003) [#3]
He wants to maximise an arbitrary entity into an arbitrary 3d viewport. This will probably be some adaptation of your bounding box stuf and the resulting projection to screen space.


_PJ_(Posted 2003) [#4]
It doesn't need to be maximised specifically, just to ensure that the entities are clearly visible.

I also notice that Sprites hold very low original scale values compared to meshes and primitives.

I guess it's a lot harder because I have spheres scaled up by hundreds (even over 1000) and sprites and smaller meshes approximately 20 units in diameter.

If there was a way of perhaps reading the actual diameter of scaled-up meshes even just in one dimension, then I could translate the camera to a distance proportional to this.




The problem lies with Blitz' internal code 'remembering' the initial entity sizes.











-________________________________________________________-



@Sswift
(2003-06-24 23:20:48)

You're going to have to explain further because I can't understand what it is you want to accomplish.



Please see the difference between these two examples:



;ORIGINAL SCALE VERSION
Graphics3d 1024,768,16,1
setbuffer backbuffer()
Camera target=createcamera()
cameraviewport target,0,0,1024,768
targetentity=createsphere(20)

	Vx# = GetMatElement(targetEntity, 0, 0)
	Vy# = GetMatElement(targetEntity, 0, 1)
	Vz# = GetMatElement(targetEntity, 0, 2)	
	
	ScaleX# = Sqr(Vx#*Vx# + Vy#*Vy# + Vz#*Vz#)

	Vx# = GetMatElement(targetEntity, 1, 0)
	Vy# = GetMatElement(targetEntity, 1, 1)
	Vz# = GetMatElement(targetEntity, 1, 2)	
	
	ScaleY# = Sqr(Vx#*Vx# + Vy#*Vy# + Vz#*Vz#)

	Vx# = GetMatElement(targetEntity, 2, 0)
	Vy# = GetMatElement(targetEntity, 2, 1)
	Vz# = GetMatElement(targetEntity, 2, 2)		
	ScaleZ# = Sqr(Vx#*Vx# + Vy#*Vy# + Vz#*Vz#)


PositionEntity target,EntityX#(targetentity,1),EntityY#(targetentity,1),EntityZ#(targetentity,1)

TranslateEntity target,0,0,((scaleX#+ScaleY#+ScaleZ)/3)

PointEntity target,targetentity
while not keydown(1)
updateworld
renderworld
flip
wend
end







;LARGE SCALE VERSION
Graphics3d 1024,768,16,1
setbuffer backbuffer()
Camera target=createcamera()
cameraviewport target,0,0,1024,768
targetentity=createsphere(20)
scaleentity targetentity,500,500,500

	Vx# = GetMatElement(targetEntity, 0, 0)
	Vy# = GetMatElement(targetEntity, 0, 1)
	Vz# = GetMatElement(targetEntity, 0, 2)	
	
	ScaleX# = Sqr(Vx#*Vx# + Vy#*Vy# + Vz#*Vz#)

	Vx# = GetMatElement(targetEntity, 1, 0)
	Vy# = GetMatElement(targetEntity, 1, 1)
	Vz# = GetMatElement(targetEntity, 1, 2)	
	
	ScaleY# = Sqr(Vx#*Vx# + Vy#*Vy# + Vz#*Vz#)

	Vx# = GetMatElement(targetEntity, 2, 0)
	Vy# = GetMatElement(targetEntity, 2, 1)
	Vz# = GetMatElement(targetEntity, 2, 2)		
	ScaleZ# = Sqr(Vx#*Vx# + Vy#*Vy# + Vz#*Vz#)


PositionEntity target,EntityX#(targetentity,1),EntityY#(targetentity,1),EntityZ#(targetentity,1)

TranslateEntity target,0,0,((scaleX#+ScaleY#+ScaleZ)/3)

PointEntity target,targetentity

while not keydown(1)
updateworld
renderworld
flip
wend
end




Jeppe Nielsen(Posted 2003) [#5]
Remember the last scale value, and do this

ScaleEntity e,1/scalebefore#,1/scalebefore#,1/scalebefore#


And then scale normaly:

ScaleEntity e,scale#,scale#,scale#



_PJ_(Posted 2003) [#6]
Unfortunately The scale values are a combination of amendments made during the setup process, and some randomisation too. Otherwise, I would just hold the value in a variable.
Also, to make things a little more awkward, the actual entities in question are handles within Types. The targetEntity variable in my code example is just a 'pointer' to the correct entity instance.


sswift(Posted 2003) [#7]
I still don't think you've clearly defined what it is you want to do.

But here's some code to find the size of the bounding box you will need to create to contain the mesh. Note that if the mesh if offset from center then the box will be bigger than it may actually need to be.

	; Get the radius of shadow which we need to create to cast a shadow from this caster.
	
		; Loop through all vertices in all surfaces of the caster.
		Surfaces = CountSurfaces(ThisCaster\Entity)
		For LOOP_Surface = 1 To Surfaces

			Surface_Handle = GetSurface(ThisCaster\Entity, LOOP_Surface)
			
			Verts = CountVertices(Surface_Handle) 
			For LOOP_Verts = 0 To Verts-1
			
				VX# = Abs(VertexX#(Surface_Handle, LOOP_Verts))
				VY# = Abs(VertexY#(Surface_Handle, LOOP_Verts))
				VZ# = Abs(VertexZ#(Surface_Handle, LOOP_Verts))
			
				If (VX# > ThisCaster\Max_X#) Then ThisCaster\Max_X# = VX#
				If (VY# > ThisCaster\Max_Y#) Then ThisCaster\Max_Y# = VY#
				If (VZ# > ThisCaster\Max_Z#) Then ThisCaster\Max_Z# = VZ#
				
			Next
		
		Next


Once you calculate these values, store them. Do not recalculate this every frame. These values will only be affected by scalemesh, not scalenetity.

You can then calculate a "radius" for the object by multiplying Max_X,Y,Z by the object's scale on each axis each frame, (putting the new value in XYZ) and then doing this: R# = Sqr(X#^2 + Y#^2 + Z#^2)


Rob(Posted 2003) [#8]
use fitmesh() to fit the mesh within an acceptible viewport boundary.


_PJ_(Posted 2003) [#9]
Thanks Sswift - looks like the kind of thing I need! I will try that soon as I can!

------------

@Rob - Thanks, a great idea, only I cannot affect the actual meshes as they are also viewed by the main game camera.


_PJ_(Posted 2003) [#10]
Sswift,
Because of the surfaces, that won't work for sprites. Is there any way to tell if a handle refers to a sprite or a mesh?


sswift(Posted 2003) [#11]
Nope. I'm afraid you're going to have to bodge it if you insist on mucking about with sprites instead of quads you make face the camera. :-)


big10p(Posted 2003) [#12]
You could name your entities with NameEntity to say whether they're sprites or meshes. e.g. "0" for meshes, "1" for sprites.


_PJ_(Posted 2003) [#13]
Thanks big10p - I have now got a working combination of both. I hope to have a nice demo of my spaceflight engine source available for download soon!


Bobysait(Posted 2007) [#14]
really old topic
"You could name your entities with NameEntity to say whether they're sprites or meshes. e.g. "0" for meshes, "1" for sprites. "

one simple way :
use EntityClass$(Entity ) , and you'll know either if the entity is "Mesh" ,"Sprite" ,"Pivot" ,"Camera", or "Terrain"

For the bounding box : I use TFormPoint on each vertex from entity to world. That return the real 3D coordinates of each vertices after any transformations


big10p(Posted 2007) [#15]
one simple way :
use EntityClass$(Entity ) , and you'll know either if the entity is "Mesh" ,"Sprite" ,"Pivot" ,"Camera", or "Terrain"
That command didn't exist 4 years ago!!! :D