Page 1 of 1

Retrieving the size of a scaled entity. (Solved)

Posted: Tue Aug 13, 2013 6:55 pm
by DK_PETER
Hi

So...While in the progress of learning mesh handling and scripts, I've stumbled onto this problem
Suppose you create an entity, which varies on all sizes...
How do you retrieve an entity's current x,y,z sizes?

Best regards
Peter

Re: Retrieving the size of a scaled entity..??

Posted: Tue Aug 13, 2013 7:42 pm
by Olby
Have a look at EntityBoundingBox(). Bounding box gets updated when you scale the entity. It will tell you the size of the smallest imaginary box that can fit the entity. Which is essentially "size" of the given object.

[Edit]

Also as far as I remember, in PB bounding boxes are not rotated. In other words, if your rotate the object it will return different results.

Re: Retrieving the size of a scaled entity..??

Posted: Tue Aug 13, 2013 7:53 pm
by DK_PETER
Thanks Olby, but that dog wont hunt.

I've already tried EntityBoundingBox(ID, #PB_Entity_MinBoundingBoxY) / EntityBoundingBox(ID, #PB_Entity_MaxBoundingBoxY) and it gives me weird values.
I've also tried with the flags #PB_Entity_LocalBoundingBox and #PB_Entity_WorldBoundingBox.

I get values of 0.5 and -1.xxxxxx ...?

The entities are scaled at random on x,y and z, which raises a problem: "Where to put the suckers". :-)

Edit: Entities are not rotated..

Re: Retrieving the size of a scaled entity..??

Posted: Tue Aug 13, 2013 8:35 pm
by Comtois
try this

Code: Select all

Debug EntityBoundingBox(1, #PB_Entity_MinBoundingBoxX | #PB_Entity_WorldBoundingBox) / EntityBoundingBox(1, #PB_Entity_MinBoundingBoxX | #PB_Entity_LocalBoundingBox)
Debug EntityBoundingBox(1, #PB_Entity_MinBoundingBoxY | #PB_Entity_WorldBoundingBox) / EntityBoundingBox(1, #PB_Entity_MinBoundingBoxY | #PB_Entity_LocalBoundingBox)
Debug EntityBoundingBox(1, #PB_Entity_MinBoundingBoxZ | #PB_Entity_WorldBoundingBox) / EntityBoundingBox(1, #PB_Entity_MinBoundingBoxZ | #PB_Entity_LocalBoundingBox)

Re: Retrieving the size of a scaled entity..??

Posted: Tue Aug 13, 2013 8:47 pm
by DK_PETER
Comtois wrote:try this

Code: Select all

Debug EntityBoundingBox(1, #PB_Entity_MinBoundingBoxX | #PB_Entity_WorldBoundingBox) / EntityBoundingBox(1, #PB_Entity_MinBoundingBoxX | #PB_Entity_LocalBoundingBox)
Debug EntityBoundingBox(1, #PB_Entity_MinBoundingBoxY | #PB_Entity_WorldBoundingBox) / EntityBoundingBox(1, #PB_Entity_MinBoundingBoxY | #PB_Entity_LocalBoundingBox)
Debug EntityBoundingBox(1, #PB_Entity_MinBoundingBoxZ | #PB_Entity_WorldBoundingBox) / EntityBoundingBox(1, #PB_Entity_MinBoundingBoxZ | #PB_Entity_LocalBoundingBox)
Nope..
This is what I get:
:lol:
Image

The numbers/results are waaay off. Entities are scaled randomly from 50 to 150 on x, y, z.
so those numbers can't be right.

Re: Retrieving the size of a scaled entity..??

Posted: Tue Aug 13, 2013 9:26 pm
by Comtois
here is my test, it seem RenderWorld() should be called before

Code: Select all

IncludeFile "Screen3DRequester.pb"

Define.f KeyX, KeyY, MouseX, MouseY, Speed = 0.3
Define.f x1, y1, z1, x2, y2, z2
Define Color = RGB(255, 0, 0)

If InitEngine3D()
  
  
  Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive("Data/Models", #PB_3DArchive_FileSystem)
  Add3DArchive("Data/Scripts", #PB_3DArchive_FileSystem)
  Add3DArchive("Data/Packs/Desert.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    
    ; Entity
    ;
    CreateEntity(1, LoadMesh(1, "robot.mesh"), #PB_Material_None)
    ScaleEntity(1, 2, 3, 4)
    
    ; Animation
    ;
    StartEntityAnimation(1, "Walk", #PB_EntityAnimation_Manual)
    
    ; SkyBox
    ;
    SkyBox("Desert07.jpg")
    
    ; Camera
    ;
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 50, 100, 80, #PB_Absolute)
    CameraLookAt(0, EntityX(1), EntityY(1) + 40, EntityZ(1))
    
    CreateLight(0, RGB(255, 255, 255), -40, 100, 80)
    AmbientColor(RGB(80, 80, 80))
    KeyboardMode(#PB_Keyboard_International)
    
TimeSinceLastFrame = RenderWorld()
    
    Debug EntityBoundingBox(1, #PB_Entity_MinBoundingBoxX | #PB_Entity_WorldBoundingBox) / EntityBoundingBox(1, #PB_Entity_MinBoundingBoxX | #PB_Entity_LocalBoundingBox)
    Debug EntityBoundingBox(1, #PB_Entity_MinBoundingBoxY | #PB_Entity_WorldBoundingBox) / EntityBoundingBox(1, #PB_Entity_MinBoundingBoxY | #PB_Entity_LocalBoundingBox)
    Debug EntityBoundingBox(1, #PB_Entity_MinBoundingBoxZ | #PB_Entity_WorldBoundingBox) / EntityBoundingBox(1, #PB_Entity_MinBoundingBoxZ | #PB_Entity_LocalBoundingBox)  
    End  
    
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf

End

Re: Retrieving the size of a scaled entity..??

Posted: Tue Aug 13, 2013 9:41 pm
by DK_PETER
Comtois wrote:here is my test, it seem RenderWorld() should be called before....
Yes..Now I get values above 1 and below -1 , but could you explain to me, why I receive values such as this:
-536.06553306595504
1050.0004583934387
-2071.4410898425531

Why negative values and why must renderworld() be executed first?

And can I assume, that EntityBoundingBox(#Entity, Flags) must always be used after RenderWorld() and not before
or are there exceptions?


Thanks for your help Comtois.

Re: Retrieving the size of a scaled entity..??

Posted: Tue Aug 13, 2013 10:10 pm
by Olby
I think the reason EntityBoundingBox() needs to be called after RenderWorld() is because entities bounding box gets updated during the rendering stage. So if you'd place a call before and after the render command the numbers would represent entity size before the bounding box got updated and after. Sounds like it, hopefully Comtois can provide more insight on this.

Re: Retrieving the size of a scaled entity..??

Posted: Tue Aug 13, 2013 10:36 pm
by DK_PETER
Olby wrote:I think the reason EntityBoundingBox() needs to be called after RenderWorld() is because entities bounding box gets updated during the rendering stage. So if you'd place a call before and after the render command the numbers would represent entity size before the bounding box got updated and after. Sounds like it, hopefully Comtois can provide more insight on this.
Yeah...I got it working on the Y axis using Comtois's formulae: I'm a bit concerned,though, when you need to load a mesh of unknown dimensions.
There's MeshRadius() and....?

Okay..A little messy, but you'll get the point. The Y are placed correctly now, but...

Code: Select all

InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()


DeclareModule _3D_Eggs
	
	Structure Mesh_Data
		ID.i
		Mesh.i
		Tex.i
		Mat.i
	EndStructure
	
	
	Global CamSpeed = 10
	Global MouseSpeed = 10
	Global DefaultCam.i
	Global Win.i, Light.i
	Global earth.Mesh_Data
	Global MotherEgg.Mesh_Data
	Global NewList KidsEgg.Mesh_Data()
	
	Declare SetupWinScreen(Width.i, Height.i, Title.s = "")
	Declare MakeTestTerrain()
	Declare MakeEggs()
	Declare Do_Mouse()
	Declare Do_Keyboard()
	
EndDeclareModule

Module _3D_Eggs
	
	Procedure SetupWinScreen(Width.i, Height.i, Title.s = "") ; Setup screen, Get Dimensions, and set a default camera
		
		winWidth = Width: winHeight = Height-5
		Win = OpenWindow(#PB_Any, 0, 0, Width, Height, Title, #PB_Window_SystemMenu )
		OpenWindowedScreen(WindowID(Win), 0, 0, Width, Height-5, 0, 0, 0,#PB_Screen_SmartSynchronization)
		DefaultCam = CreateCamera(#PB_Any,0,0,100,100) 
		MoveCamera(DefaultCam,0,100,150)		
		CameraProjectionMode(DefaultCam, #PB_Camera_Perspective)
		
		light = CreateLight(#PB_Any ,RGB(190, 190, 190), 4000, 1200, 1000,#PB_Light_Directional)
		SetLightColor(light, #PB_Light_SpecularColor, RGB(255*0.4, 255*0.4,255*0.4)) 
		LightDirection(light ,0.55, -0.3, -0.75) 
		AmbientColor(RGB(255*0.2, 255*0.2,255*0.2))
		
	EndProcedure
	
	Procedure MakeTestTerrain()
		earth\Mesh = CreatePlane(#PB_Any,100000,100000,2,2,1,1)
		earth\Tex = CreateTexture(#PB_Any,512,512)
		
		StartDrawing(TextureOutput(earth\Tex))
		Box(0,0,512,512,$FFFFFF)
		StopDrawing()
		
		earth\Mat = CreateMaterial(#PB_Any,TextureID(earth\Tex))
		earth\ID 	= CreateEntity(#PB_Any,MeshID(earth\Mesh),MaterialID(earth\Mat))
		MoveEntity(earth\ID,0,0,0,#PB_Absolute)
	EndProcedure		
	
	
	
	Procedure MakeEggs()
		MotherEgg\Mesh = CreateSphere(#PB_Any,50,20,20)
		MotherEgg\Tex = CreateTexture(#PB_Any,256,256)
		
		StartDrawing(TextureOutput(MotherEgg\Tex))
		Box(0,0,256,256,$00FF00)
		StopDrawing()
		
		MotherEgg\Mat = CreateMaterial(#PB_Any,TextureID(MotherEgg\Tex))
		MotherEgg\ID = CreateEntity(#PB_Any, MeshID(MotherEgg\Mesh), MaterialID(MotherEgg\Mat))
		
		MoveEntity(MotherEgg\ID,0,0,0)
		
		RenderWorld()  ;Update
		
		For x = 0 To 30
			AddElement(KidsEgg())
			KidsEgg()\ID = CopyEntity(MotherEgg\ID,#PB_Any)
			ScaleEntity(KidsEgg()\ID,Random(10,5),Random(10,5),Random(10,5))
			MoveEntity(KidsEgg()\ID, Random(20000,10), 0, Random(20000,10))
		Next x
		
		RenderWorld()  ;update again, just in case
	EndProcedure	
	
	Procedure Do_Mouse()
		
		ExamineMouse()
		MouseX = -MouseDeltaX() * MouseSpeed * 0.01
		MouseY = -MouseDeltaY() * MouseSpeed * 0.01
		RotateCamera(DefaultCam, MouseY, MouseX, 0, #PB_Relative)
		
	EndProcedure		
	
	Procedure Do_Keyboard()
		
		ExamineKeyboard()
		
		If KeyboardPushed(#PB_Key_A)
			KeyX = 0 - CamSpeed 
		EndIf
		If KeyboardPushed(#PB_Key_D)
			KeyX = CamSpeed 
		EndIf
		
		If KeyboardPushed(#PB_Key_W)
			KeyY = 0 - CamSpeed
		EndIf
		
		If KeyboardPushed(#PB_Key_S)
			KeyY = CamSpeed
		EndIf
		
		MoveCamera(DefaultCam, KeyX, 0, KeyY)
		
		If Not KeyboardReleased(#PB_Key_Escape)
			KeyX = 0: KeyY = 0
		EndIf
	EndProcedure	
	
EndModule


_3D_Eggs::SetupWinScreen(1024,768)
_3D_Eggs::MakeTestTerrain()
_3D_Eggs::MakeEggs()

onlyonce = 0

Repeat
	
	ev = WindowEvent()
	
	elaps = RenderWorld()
	
	If onlyonce = 0  ;Only run the test once
		; Since I made the MotherEgg, I know that the size is 50, but what if I don't know the original size in advanced?
		stdval = EntityBoundingBox(_3D_Eggs::MotherEgg\ID , #PB_Entity_MinBoundingBoxY | #PB_Entity_WorldBoundingBox) / EntityBoundingBox(_3D_Eggs::MotherEgg\ID , #PB_Entity_MinBoundingBoxY | #PB_Entity_LocalBoundingBox)
		Debug "Org Y MotherEgg: " + stdval  ; as espected..Value of 1
		ForEach _3D_Eggs::KidsEgg()
			newvalX = 0: newvalY = 0: newvalZ = 0
			newvalX = EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxX | #PB_Entity_WorldBoundingBox) / EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxX | #PB_Entity_LocalBoundingBox) 
			newvalY = EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxY | #PB_Entity_WorldBoundingBox) / EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxY | #PB_Entity_LocalBoundingBox) 
			newvalZ = EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxZ | #PB_Entity_WorldBoundingBox) / EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxZ | #PB_Entity_LocalBoundingBox) 
			Debug " X : " + newvalX 
			Debug " Y : " + newvalY 
			Debug " Z : " + newvalZ 
			MoveEntity(_3D_Eggs::KidsEgg()\ID,Random(10000,10), 50 * newvalY, Random(10000,10))  ;Just crap locations
		Next 
		onlyonce = 1
	EndIf
	
	_3D_Eggs::Do_Mouse()
	_3D_Eggs::Do_Keyboard()
	
	FlipBuffers()
	
Until  KeyboardPushed(#PB_Key_Escape)

But for the life of me, I don't get the negative values on x and z.

Oh well.. I'm still learning bigtime and I'm sure Comtois 'the wizard' will provide enlightenment soon. :-)

Best regards
Peter

Re: Retrieving the size of a scaled entity..??

Posted: Wed Aug 14, 2013 7:38 pm
by Comtois
Try this

Code: Select all

   newvalX = (EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxX | #PB_Entity_WorldBoundingBox) - EntityX(_3D_Eggs::KidsEgg()\ID)) / EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxX | #PB_Entity_LocalBoundingBox)
         newvalY = (EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxY | #PB_Entity_WorldBoundingBox) - EntityY(_3D_Eggs::KidsEgg()\ID)) / EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxY | #PB_Entity_LocalBoundingBox)
         newvalZ = (EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxZ | #PB_Entity_WorldBoundingBox) - EntityZ(_3D_Eggs::KidsEgg()\ID)) / EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxZ | #PB_Entity_LocalBoundingBox)
       

Re: Retrieving the size of a scaled entity..??

Posted: Wed Aug 14, 2013 7:47 pm
by DK_PETER
Comtois wrote:Try this

Code: Select all

   newvalX = (EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxX | #PB_Entity_WorldBoundingBox) - EntityX(_3D_Eggs::KidsEgg()\ID)) / EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxX | #PB_Entity_LocalBoundingBox)
         newvalY = (EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxY | #PB_Entity_WorldBoundingBox) - EntityY(_3D_Eggs::KidsEgg()\ID)) / EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxY | #PB_Entity_LocalBoundingBox)
         newvalZ = (EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxZ | #PB_Entity_WorldBoundingBox) - EntityZ(_3D_Eggs::KidsEgg()\ID)) / EntityBoundingBox(_3D_Eggs::KidsEgg()\ID , #PB_Entity_MinBoundingBoxZ | #PB_Entity_LocalBoundingBox)
       
LOL!! And THAT'S what I definately like about you Comtois. You're ready to bend over backwards to solve a problem.
True admiration from here goes to you. It works now on x and z. :-)

Thank you!