Updated wxIrrlicht

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Updated wxIrrlicht

Post by Noiecity »

:D
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Updated wxIrrlicht

Post by Noiecity »

CuteAlien wrote: Mon Mar 18, 2024 10:57 am @Noiecity: Yeah - it's about Windows timer in general which are used for example in Windows sleep(). Irrlicht uses those for it's device->sleep(). Which I don't recommend using anymore therefore. Up to (including) Irrlicht 1.8 we also used sleep(1) for device->yield(), so that was just as bad. But that is now using sleep(0) in Irrlicht svn trunk (aka Irrlicht 1.9), so that can be used again as it now only gives up the thread (reason it used sleep(1) in the past was some Windows 98 behavior where using sleep(0) wasn't guarenteed to give up threads, but Microsoft changed that behavior afterwards).

@n00bc0de: Are you on Irrlicht 1.8 or svn trunk? Could be something changed. Also if you show me your main-loop I might have more ideas.
I was doing some tests with the timer, it is quite accurate, although with approximately 11 ms is 98% accurate most of the time, I created two timers, each with a counter, one average every 1 second, and the other every 11 ms, the one with 11 ms gave between 89 to 91 in the counter for each second most of the time, but if I put it at 1 ms it gave me 50% of the total needed, that is, instead of giving me 1000 which would be 1 second, it gave me 450 or 560, or 720, in fact it gave me the amount of fps on screen, this with version 1. 8.5, then I thought I would have 1 ms of sleep something in the code, remembering again and reading your comment I confirm it, but instead of using 0 in sleep, how about changing from milliseconds to microseconds? in the standard library it would be something like std::this_thread::sleep_for(std::chrono::microseconds(100));, which is 0.1 ms, instead of std::this_thread::sleep_for(std::chrono::milliseconds(1)); which is 1 ms.

I want to use svn now, but it would be great to be able to configure the sleep inside the project somehow, although maybe it's already there, I don't know.
Also maybe the sleep time should vary between what is rendered and what is calculated metrically, the only way I have thought of is with two loops, some time ago I programmed a game in java where something like this was executed: the server executed all the mathematical logic and was assigned an amount of ram memory, while another application was in charge of rendering, so that if the animations were lagged or an error occurred, the server was not affected and the character returned to the place where it should be, because it was only the visible part.

Nowadays it is normal to see in other engines characters crossing the floor and falling infinitely because of these errors in the memory that cause problems in collisions, even with a real engine, it could be corrected by normalizing every certain amount of time also based on some conditions, as the movement is limited to the coordinates of a mesh, instead of calculating using a timer that collides one mesh with another, in an error, the mesh could move beyond what is allowed. This happened to me in irrlicht by the way, in some tests with very low FPS, this really could happen, characters going through the collisions, although it was rare, but it happened, although it was more because of how I had programmed it, something like "move every 15 ms" and when it lagged 15 ms turned out to be seconds and the condition was skipped, I spent about two days without understanding why it happened, if literally in the if I placed that the movement was not executed if the calculated movement added gave more than the specified limit, I do not have the code but I remember that it was like that, it was probably my mistake, I do not know.

At the moment I have thought of some solutions in case of an extreme lag out of the blue, for example, if irrlicht is currently giving me with a deltatime of 1 ms half, it can be fixed by normalizing every 10 ms, if in 10 ms the counter gives me 5, it means that I can normalize by multiplying the 1 ms*2, of course, this normalization would have to be updated according to the average performance of the application in case of a discontinuous performance.

At the moment I can't use 1 ms if I have less than 1000 fps, but, probably in svn I can.

Code: Select all

#include <iostream>
#include <irrlicht.h>
#include <Windows.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
int main() {
	IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D9, core::dimension2d<u32>(800, 600), 32, false, false, false, 0);
	if (!device) {
		std::cerr << "Error" << std::endl;
		return 1;
	}



	u32 lastTime = device->getTimer()->getTime();

	u32 lastTime2 = device->getTimer()->getTime();
	u32 count = 0;
	u32 count2 = 0;

	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	IGUIEnvironment* guienv = device->getGUIEnvironment();



	smgr->addCameraSceneNode(0, vector3df(0, 30, -40), vector3df(0, 5, 0));

	bool disableTime = false; //for later
	
	while (device->run()) 
	{

			u32 currentTime = device->getTimer()->getTime();
			u32 currentTime2 = device->getTimer()->getTime();
			u32 elapsedTime = currentTime - lastTime;
			u32 elapsedTime2 = currentTime2 - lastTime2;
			
			if (elapsedTime >= 1 && disableTime==false) {
				count++;
				lastTime = currentTime;
			}
			
			if (elapsedTime2 >= 1000 && disableTime==false) {
				count2++;

				std::cout << "count1: " << count << std::endl;
				std::cout << "count2: " << count2 << std::endl;
				count = 0;
				count2 = 0;
				lastTime2 = currentTime2;
			}
			//driver->beginScene(true, true, SColor(255, 100, 101, 140));
			//smgr->drawAll();
			//guienv->drawAll();
			//driver->endScene();
	}

	device->drop();

	return 0;
}
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
CuteAlien
Admin
Posts: 9638
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Updated wxIrrlicht

Post by CuteAlien »

Irrlicht should probably user multimedia timers on Windows some day. I'll look into that at some point. But unlikely for Irrlicht 1.9.

Falling through floors is an old thing in 3d, not just new engines ;-) And it's sometimes, but not always about timers. The timer part can be avoided by using a fixed-step physics timer. Like you only advance physics by 30ms each time (but remember the remainder). So you can have more or less phyiscs steps for one frame update. And then ensure your fastest speed for your smallest object will collide the thinnest wall in one such step-size. Alternative options are using collisions which go from last position to current position of your objects (like a stretchy rubber piece around your old and new position which is then used for collision). Then it doesn't miss collisions (but stuff like hitting arms exactly can get harder).

The non-timer reason for it to happen has to do with resolving many object collisions and getting back in a non-colliding state is a pretty hard problem. Which is why this kind of stuff often happens if something else with collision pushes you. Then the physics engine can just give up after a while and use any position. And you get pushed step by step through the floor because it never gets back to non-colliding.

And one option many games miss - you can simply check once in a while if any of your objects is below the floor and place it back up ;-) Thought you might end up "inside" geometry" or above the roof when doing that hack.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Updated wxIrrlicht

Post by Noiecity »

Noiecity wrote: Fri Apr 19, 2024 12:23 am
CuteAlien wrote: Mon Mar 18, 2024 10:57 am @Noiecity: Yeah - it's about Windows timer in general which are used for example in Windows sleep(). Irrlicht uses those for it's device->sleep(). Which I don't recommend using anymore therefore. Up to (including) Irrlicht 1.8 we also used sleep(1) for device->yield(), so that was just as bad. But that is now using sleep(0) in Irrlicht svn trunk (aka Irrlicht 1.9), so that can be used again as it now only gives up the thread (reason it used sleep(1) in the past was some Windows 98 behavior where using sleep(0) wasn't guarenteed to give up threads, but Microsoft changed that behavior afterwards).

@n00bc0de: Are you on Irrlicht 1.8 or svn trunk? Could be something changed. Also if you show me your main-loop I might have more ideas.
I was doing some tests with the timer, it is quite accurate, although with approximately 11 ms is 98% accurate most of the time, I created two timers, each with a counter, one average every 1 second, and the other every 11 ms, the one with 11 ms gave between 89 to 91 in the counter for each second most of the time, but if I put it at 1 ms it gave me 50% of the total needed, that is, instead of giving me 1000 which would be 1 second, it gave me 450 or 560, or 720, in fact it gave me the amount of fps on screen, this with version 1. 8.5, then I thought I would have 1 ms of sleep something in the code, remembering again and reading your comment I confirm it, but instead of using 0 in sleep, how about changing from milliseconds to microseconds? in the standard library it would be something like std::this_thread::sleep_for(std::chrono::microseconds(100));, which is 0.1 ms, instead of std::this_thread::sleep_for(std::chrono::milliseconds(1)); which is 1 ms.

I want to use svn now, but it would be great to be able to configure the sleep inside the project somehow, although maybe it's already there, I don't know.
Also maybe the sleep time should vary between what is rendered and what is calculated metrically, the only way I have thought of is with two loops, some time ago I programmed a game in java where something like this was executed: the server executed all the mathematical logic and was assigned an amount of ram memory, while another application was in charge of rendering, so that if the animations were lagged or an error occurred, the server was not affected and the character returned to the place where it should be, because it was only the visible part.

Nowadays it is normal to see in other engines characters crossing the floor and falling infinitely because of these errors in the memory that cause problems in collisions, even with a real engine, it could be corrected by normalizing every certain amount of time also based on some conditions, as the movement is limited to the coordinates of a mesh, instead of calculating using a timer that collides one mesh with another, in an error, the mesh could move beyond what is allowed. This happened to me in irrlicht by the way, in some tests with very low FPS, this really could happen, characters going through the collisions, although it was rare, but it happened, although it was more because of how I had programmed it, something like "move every 15 ms" and when it lagged 15 ms turned out to be seconds and the condition was skipped, I spent about two days without understanding why it happened, if literally in the if I placed that the movement was not executed if the calculated movement added gave more than the specified limit, I do not have the code but I remember that it was like that, it was probably my mistake, I do not know.

At the moment I have thought of some solutions in case of an extreme lag out of the blue, for example, if irrlicht is currently giving me with a deltatime of 1 ms half, it can be fixed by normalizing every 10 ms, if in 10 ms the counter gives me 5, it means that I can normalize by multiplying the 1 ms*2, of course, this normalization would have to be updated according to the average performance of the application in case of a discontinuous performance.

At the moment I can't use 1 ms if I have less than 1000 fps, but, probably in svn I can.

Code: Select all

#include <iostream>
#include <irrlicht.h>
#include <Windows.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
int main() {
	IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D9, core::dimension2d<u32>(800, 600), 32, false, false, false, 0);
	if (!device) {
		std::cerr << "Error" << std::endl;
		return 1;
	}



	u32 lastTime = device->getTimer()->getTime();

	u32 lastTime2 = device->getTimer()->getTime();
	u32 count = 0;
	u32 count2 = 0;

	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	IGUIEnvironment* guienv = device->getGUIEnvironment();



	smgr->addCameraSceneNode(0, vector3df(0, 30, -40), vector3df(0, 5, 0));

	bool disableTime = false; //for later
	
	while (device->run()) 
	{

			u32 currentTime = device->getTimer()->getTime();
			u32 currentTime2 = device->getTimer()->getTime();
			u32 elapsedTime = currentTime - lastTime;
			u32 elapsedTime2 = currentTime2 - lastTime2;
			
			if (elapsedTime >= 1 && disableTime==false) {
				count++;
				lastTime = currentTime;
			}
			
			if (elapsedTime2 >= 1000 && disableTime==false) {
				count2++;

				std::cout << "count1: " << count << std::endl;
				std::cout << "count2: " << count2 << std::endl;
				count = 0;
				count2 = 0;
				lastTime2 = currentTime2;
			}
			//driver->beginScene(true, true, SColor(255, 100, 101, 140));
			//smgr->drawAll();
			//guienv->drawAll();
			//driver->endScene();
	}

	device->drop();

	return 0;
}
Yes, something like checking if the object is not within the parameters and restart it to a point close, I also think that this problem may be that when adding the current position + value, this, in case of overload and saturate the cpu, it is possible to continue adding, despite the condition, for example, the error that happened to me in irrlicht was something like "if current position + value is ! < another value" that is to say, first it verified that the value did not exceed the allowed, then it added, but, equally, when there was much lag, it still added values that were greater! and only when there was much lag, it is probably a physical problem, the transistors when having the cpu overloaded must first see that the condition is fulfilled, that is to say, it adds the first value, and probably, when saturated it begins to add and add in binary, making the character "teleport".

This happened to me when I studied industrial electricity, the if here were the contactors, but it was limited to its speed, ie, the circuit could make mistakes if the speed of change was slower, ie, the condition was activated, and it took time to return to its state and to activate a second state took longer than the speed of electricity came and made the circuit fail. I was the only one to solve this problem, and everyone, including my teacher, thought it was the circuit or the motor, it was a problem that no student had solved, and I was the only one who solved it.

It was not the circuit, or the motor, it was a question of speed and reaction of the physical circuit, since in the diagrams it does not consider the speed that it takes to pass from one state to another.
And do you know how I solved it?
I added a much longer wire and a shorter one, out of the blue, it was just like that, depending on how long the wire was connected, the circuit failed or worked. That, to this day, I have not seen in any industrial electrical book.

For sure the same thing happens here, since even in the timers there is a lack of synchronization between one point and another, and the results vary a lot if the cpu is being used or not.

I think that for my game I will avoid the excessive use of real time calculations, I can use a system of squares like the isometric turn-based games, like Dofus, only on a larger scale in terms of number of squares, but for a 3d game in first person or third person, that moves with WASD, this will limit the freedom of mobility and will give me more work, but I think it is the right thing to do.
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
Post Reply