Jump to content

Model->SetViewRange() causes crash!


Scott Richmond
 Share

Recommended Posts

I'm developing something that requires creation and destruction of entities at runtime, so I've just been doing some tests and getting my framework going and I've noticed that when I call Model->SetViewRange() on a pointer to a Model entity it crashes! I thought for awhile that maybe its simply bad coding on my part like some sort of pointer out-of-scope issue, but the following fairly simple code does not work.

Can someone browse over it and confirm I'm not doing anything silly before I officially put in a bug request?

 

int main (int argc, char *argv[])
{
// Set graphics mode
Engine engine("3DF",1024,768);
engine.AddAbstractPath( "./Data" );

Framework fw(CREATENOW);
fw.main.world.SetAmbientLight(Vec3(0.13,0.14,0.17));
//fw.main.world.SetCullRange(...);

Cube box1(CREATENOW);
box1.Move(0,0.3,4);
box1.SetColor(Vec4(0,0,1,1)); //Blue 
box1.SetViewRange(VIEWRANGE_NEAR, RECURSIVE);

Sphere ball1(CREATENOW, 16);
ball1.SetColor(Vec4(1,0,0,1)); //Red
ball1.Move(-1,0,4);
ball1.SetViewRange(VIEWRANGE_NEAR, RECURSIVE);

Sphere ball2( ball1.Copy() );
ball2.Move(2,0,0);
ball2.SetColor(Vec4(0,1,0,1)); //Green
ball2.SetViewRange(VIEWRANGE_NEAR, RECURSIVE);

Cube ground(CREATENOW);
ground.SetPosition(0,0,0);
ground.Move(0,-1,5);
ScaleMesh(ground,Vec3(100,1,100));

Model *leModel = new Model();
leModel->Load("abstract::crates_small.gmf");
leModel->Move(3,0,0);
leModel->SetViewRange(10, RECURSIVE); /* <----- CRASH: Comment this line out and it will run fine */

DirectionalLight lig2(CREATENOW);
lig2.SetShadowmapSize(1024);
lig2.Turn(5,0,0);

OcclusionCulling(false);
SetWireframe(false);
SetStats(2); // Detailed stats

PlayerController playerController;

Game game;

while( !Keyboard::I****() && !engine.IsTerminated() ) {

	fw.Update();

	char msg[256];
	sprintf( msg, "Camera Pos: %fx%fy%fz",  playerController.getPosition().X,
											playerController.getPosition().Y,
											playerController.getPosition().Z);

	if( !engine.IsSuspended() ) {
		playerController.update();
		fw.Render();
		DrawText(0,250,msg);

		engine.Flip( 0 );
	}

	game.updateMessageQueue();
}
return engine.Free();
}

Programmer, Modeller

Intel Core i7 930 @ 3.5GHz | GeForce 480 GTX | 6GB DDR3 RAM | Windows 7 Premium x64

Visual Studio 2008 | Photoshop CS3 | Maya 2009

Website: http://srichnet.info

Link to comment
Share on other sites

ViewRange can not be 10, but only 0-3:

const int VIEWRANGE_NEAR			=	   0;
const int VIEWRANGE_MEDIUM			=	   1;
const int VIEWRANGE_FAR				=	   2;
const int VIEWRANGE_INFINITE		=	   3;

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

Ok so I've just tried it. Unfortunately its not giving me the speed-up I thought it would. I would have thought that objects outside the set distance would do a hide(), but they don't. I don't get nearly the speed I would if I did a hide(). Why is that? Is it because the models still take up time when the engine has to check each one and do a distance calc?

How can I avoid that? Would be good if I could extend the distance culling function to get it to hide models as well.

Programmer, Modeller

Intel Core i7 930 @ 3.5GHz | GeForce 480 GTX | 6GB DDR3 RAM | Windows 7 Premium x64

Visual Studio 2008 | Photoshop CS3 | Maya 2009

Website: http://srichnet.info

Link to comment
Share on other sites

No that does not appear to have helped. The entity cull time is still quite high, driving FPS down. I'm guessing hide() rips the entity all the way out of the engine whereas culling on camera distance only prevents it from being drawn.

Programmer, Modeller

Intel Core i7 930 @ 3.5GHz | GeForce 480 GTX | 6GB DDR3 RAM | Windows 7 Premium x64

Visual Studio 2008 | Photoshop CS3 | Maya 2009

Website: http://srichnet.info

Link to comment
Share on other sites

You get the best FPS when you set OcclusionCulling(0), but still set it to 1 for each entity recursively.

And EntityViewRange(0) works for me, and it increases FPS.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

josh, understood. So 'occlusion culling' includes viewrange culling? If so, can I use occlusion groups to group entire regions of my map? That would greatly speed up.

Programmer, Modeller

Intel Core i7 930 @ 3.5GHz | GeForce 480 GTX | 6GB DDR3 RAM | Windows 7 Premium x64

Visual Studio 2008 | Photoshop CS3 | Maya 2009

Website: http://srichnet.info

Link to comment
Share on other sites

josh, understood. So 'occlusion culling' includes viewrange culling

No, they are unrelated.

 

Don't worry about occlusion culling. It's automatically used for light and animated models.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Well, I sort of need to worry. If I have 20,000 model entities I need to know how best to render them. If LE2 simply cannot handle that number of objects I need to know so I can start writing some sort of method that does a hide() when objects are out of viewing range.

Programmer, Modeller

Intel Core i7 930 @ 3.5GHz | GeForce 480 GTX | 6GB DDR3 RAM | Windows 7 Premium x64

Visual Studio 2008 | Photoshop CS3 | Maya 2009

Website: http://srichnet.info

Link to comment
Share on other sites

Ok. So I've put together the below demo that spawns 25,000 barrels. Playing with the demo on its own let me see that it does sort of work well - View range culling to nothing still seems to take up a fair bit of time at 10ms for 25k barrels. I suppose at this point the aim is to find further optimisations such as culling groups, or any other ideas?

 

// Leadwerks engine:
#include "leo.h"
using namespace LEO;

int main (int argc, char *argv[])
{
// Set graphics mode
Engine engine("3DF",1024,768);
engine.AddAbstractPath( "./Data" );

Framework fw(CREATENOW);
fw.main.world.SetAmbientLight(Vec3(0.13,0.14,0.17));
fw.main.world.SetCullRange(20.0F, 250.0F, 500.0F); // Near, Medium and Far view ranges

DirectionalLight lig2(CREATENOW);
lig2.SetShadowmapSize(1024);
lig2.Turn(5,0,0);

OcclusionCulling(false);
SetWireframe(false);
SetStats(2); // Detailed stats

for(int x = 1; x < 50; x++) {
	for(int y = 1; y < 50; y++) {
		for(int z = 1; z < 10; z++) {
			Model *model = new Model();
			model->Load("abstract::oildrum.gmf");
			model->SetViewRange(VIEWRANGE_NEAR, RECURSIVE);
			model->SetShadowMode(false);
			model->Move(x, y, z);
			//model->Hide();
		}
	}
}

Body player			= CreateBodySphere(); //Create the player object
Camera playerCamera	= CreateCamera(); // Create the player camera object
MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2);
// Initialize variables:
TVec3 camRotation		= Vec3(0);
float mouseX			= 0;
float mouseY			= 0;
float playerMove		= 0;
float playerStrafeUD	= 0;
float playerStrafeLR	= 0;
HideMouse();
player.SetMass(1);
player.SetGravityMode(0); // Sets whether player should be affected by gravity.
player.SetDamping(1.0F);
player.SetType(3);
player.SetPosition( Vec3(0,0,0) );
playerCamera.SetPosition( Vec3(0, 0 ,0) );
playerCamera.SetRotation( Vec3(0, 0, 0) );
playerCamera.SetParent(player); // Sert the player object as the parent.
playerCamera.SetRange(0.1F, 20.0F);

//Game game;

while( !Keyboard::I****() && !engine.IsTerminated() ) {

	fw.Update();

	if( !engine.IsSuspended() ) {
		/****** Update player camera ******/
		//Camera look
		mouseX = Curve( MouseX() - GraphicsWidth()/2, mouseX, 6);
		mouseY = Curve( MouseY() - GraphicsHeight()/2, mouseY, 6);
		MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2);
		camRotation.X	= camRotation.X + mouseY / 10.0F;
		camRotation.Y	= camRotation.Y - mouseX / 10.0F;
		RotateEntity(player, camRotation);
		playerMove		= KeyDown(KEY_W)-KeyDown(KEY_S);
		playerStrafeLR	= KeyDown(KEY_D)-KeyDown(KEY_A);
		// Double movement speed with shift
		if (KeyDown(KEY_LSHIFT)||KeyDown(KEY_RSHIFT)) {
			playerMove*=20.0;
			playerStrafeLR*=20.0;
		}
		// Make the player travel for slightly longer after keypress:
		TVec3 playerForce = Vec3(playerStrafeLR*10.0, 0, playerMove*10.0);
		playerForce = TFormVector(playerForce, player, 0);
		player.AddForce(playerForce);
		fw.Render();

		engine.Flip( 0 );
	}
}

return engine.Free();
}

Programmer, Modeller

Intel Core i7 930 @ 3.5GHz | GeForce 480 GTX | 6GB DDR3 RAM | Windows 7 Premium x64

Visual Studio 2008 | Photoshop CS3 | Maya 2009

Website: http://srichnet.info

Link to comment
Share on other sites

I can't run your code because their does not appear to be a LEO VC2008 template.

 

Like I said, you should still put model->SetOcclusionMode(true); because it gives more FPS when OcclusionCulling(0); is set also.

Don't do this.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Don't do this.

Why not? At the moment, in LE 2.5, it gives an FPS increase, so there might be actually a bug in the engine, because it should not give an FPS increase when the whole occllusion culling is turned off.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

I tested it again today, and it's now giving 1 FPS less. So it seems to be a bit random behaviour, and probably best to keep it turned off then.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

I can't run your code because their does not appear to be a LEO VC2008 template.

the code should compile on whatever system you choose providing you include LEO. I can send you a vc2010 project if you like.

Programmer, Modeller

Intel Core i7 930 @ 3.5GHz | GeForce 480 GTX | 6GB DDR3 RAM | Windows 7 Premium x64

Visual Studio 2008 | Photoshop CS3 | Maya 2009

Website: http://srichnet.info

Link to comment
Share on other sites

  • 2 weeks later...

I also have the problem with high entity cull times. My projects tend to generate large world from 3d "tiles". When the tile count rises to tens of thousands there is a huge drop in performance due to the entity culling. Is there any way to group many entities under one cull check manually? Can such feature be added?

Core i5-750 - GTX 460 1GB - 12GB DDR3 - Win 7 x64

Link to comment
Share on other sites

I haven't tried this yet but you'll probably need to .hide() all models by default, and .unhide() models that are within the camera frustum. The .hide() method takes the model right out of the OC detection so massively reduces the OC time. But it'll need to be done cheaply. Like if the 'tiles' are a 3D matrix then it should be cheap to know that when the camera moves from (1,1,1) in the world to (1,1,2) then you need to .unhide() all the models at (x,1,32).

Not sure if that makes sense to you or not - I'm avoiding the problem for now and working on stuff not specific to the engine. I might have to find a new engine for this project unfortunately.

 

TGroup group1=CreateGroup();
SetEntityGroup(cube1,group1);
SetEntityGroup(cube2,group1);

Ah that too! I must say I haven't tried groups yet. That would probably be the best way.

Programmer, Modeller

Intel Core i7 930 @ 3.5GHz | GeForce 480 GTX | 6GB DDR3 RAM | Windows 7 Premium x64

Visual Studio 2008 | Photoshop CS3 | Maya 2009

Website: http://srichnet.info

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...