MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
-
- Gnoll
- Posts: 653
- Joined: Thu May 11, 2006 9:12 pm
- Location: Bavaria
- x 36
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
@compvis: I am not sure if that is the best way of doing it, but you could either create a threaded projectile class that either selfterminates after a certain range or reports the hit back, or you simply just update the movement each frame and check for collision, either in your framestarted method or your applications mainloop.
ARTIFEX TERRA 3D - Artist-friendly, free and easy WYSIWYG realtime outdoor scene Editor & Painter
New loader now with Ogre::Terrain support: Addons for Artifex on SourceForge
MOC - Minimal Ogre Collision & Mousepicking
Simple TerrainMaterialGenerator for the use of standard Ogre material with Ogre::Terrain
Support me on Patreon
-
- Silver Sponsor
- Posts: 244
- Joined: Thu Apr 12, 2007 9:21 pm
- Location: Germany
- x 14
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
good to hear, looking forward to your ideasNauk wrote:@tdev: I was pondering with the idea of implementing caching anyway, so you don't have to pull the same vertex data each single frame over and over. I am wondering what the speed gain is like that can be gotten from a "smart" caching system or if there is any at all. Either way I am looking forward to play with your code.
meanwhile i added some simple cache discarding. You can find my latest version there:
http://rigsofrods.svn.sourceforge.net/v ... ionTools.h
http://rigsofrods.svn.sourceforge.net/v ... nTools.cpp
-
- Gnoblar
- Posts: 16
- Joined: Sat Feb 07, 2009 8:28 pm
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
I've made some updates to MOC that I wanted to share with the community. I have added both smooth stepping and falling, which also makes MOC more easy to use with 3rd person camera systems where the character is being past into updateY() instead of just the camera. Now stairs and other objects can be climbed up to a specified height, and the scene node (camera or character) will smoothly step up (if you want it even smoother, it is easy to tweak the value to your own desire). When falling, you will now fall smoothly from a high distance rather than of instantaneously warping to the ground.
Nauk, you're also more than welcome to modify it and include it in your next release as you see fit. I have only tested it out with objects, and not either of the terrain systems, but it should work fine with them as well.
If you find any bugs, fixes, or optimizations, please post them for the community. If anyone is up to also implement sliding, you'll have yourself a nice character controller! Please share your sliding implementation as well!
Here is the changed code:
Code from CollisionTools.cpp:
Updated the constructor to add some member initialization.
Code: Select all
CollisionTools::CollisionTools(Ogre::SceneManager *sceneMgr)
{
mSceneMgr = sceneMgr;
mRaySceneQuery = mSceneMgr->createRayQuery(Ogre::Ray());
if (NULL == mRaySceneQuery)
{
// LOG_ERROR << "Failed to create Ogre::RaySceneQuery instance" << ENDLOG;
return;
}
mRaySceneQuery->setSortByDistance(true);
mTSMRaySceneQuery = mSceneMgr->createRayQuery(Ogre::Ray());
_heightAdjust = 0.0f;
_origY = 0.0f;
_newY = 0.0f;
}
Code: Select all
/*
* This function can be called to calculate the Y coordinate of a scene node
* so it will follow ground, terrain, or other objects. This function now also
* supports both smooth stepping and falling.
*
* initial
* Is this the first call to set the initial height?
*
* steppingSize
* The location we should cast our ray down from. This is useful when we want
* to be able to step up on objects up to a certain height. This also adds
* realism so we don't just step up onto anything that is below our scene node,
* as realistically, we could step up on a 50 meter building.
*/
void CollisionTools::calculateY(Ogre::SceneNode *n, const bool initial, const bool doTerrainCheck,
const bool doGridCheck, const float gridWidth,
const float steppingSize, const Ogre::uint32 queryMask)
{
// Get the current position of the scene node:
Ogre::Vector3 pos = n->getPosition();
// Save the y position to a member variable as we may need to use it later:
_origY = pos.y;
float x = pos.x;
float z = pos.z;
float y = pos.y + steppingSize - _heightAdjust; // Use the actual height of the object and the stepping size.
Ogre::Vector3 myResult(0,0,0);
Ogre::MovableObject *myObject=NULL;
float distToColl = 0.0f;
float terrY = 0, colY = 0, colY2 = 0;
if( raycastFromPoint(Ogre::Vector3(x,y,z),Ogre::Vector3::NEGATIVE_UNIT_Y,myResult,myObject, distToColl, queryMask)){
if (myObject != NULL) {
colY = myResult.y;
} else {
colY = -99999;
}
}
//if doGridCheck is on, repeat not to fall through small holes for example when crossing a hangbridge
if (doGridCheck) {
if( raycastFromPoint(Ogre::Vector3(x,y,z)+(n->getOrientation()*Ogre::Vector3(0,0,gridWidth)),Ogre::Vector3::NEGATIVE_UNIT_Y,myResult, myObject, distToColl, queryMask)){
if (myObject != NULL) {
colY = myResult.y;
} else {
colY = -99999;
}
}
if (colY<colY2) colY = colY2;
}
// set the parameter to false if you are not using ETM or TSM
if (doTerrainCheck) {
#ifdef ETM_TERRAIN
// ETM height value
terrY = mTerrainInfo->getHeightAt(x,z);
#else
// TSM height value
terrY = getTSMHeightAt(x,z);
#endif
if(terrY < colY ) {
_newY = colY+_heightAdjust;
} else {
_newY = terrY+_heightAdjust;
}
} else {
if (!doTerrainCheck && colY == -99999)
colY = y;
_newY = colY+_heightAdjust;
}
// If this is the first time the function is called to set an initial y position,
// we aren't stepping or falling, so rather than animating toward the new position
// over time, we just set it now:
if (initial) {
n->setPosition(x, _newY, z);
}
}
Code: Select all
/*
* This function should be called to smoothly update the Y coordinate of a
* scene node so it follows the ground or other objects. This function
* supports both smooth stepping and falling.
*/
void CollisionTools::updateY(Ogre::SceneNode *n)
{
// Get the position of the scene node:
float currY = n->getPosition().y;
// If we don't need to update, just return:
if (_newY == currY)
return;
// Determine the distance as the difference between the new height
// and the original height:
float distY = _newY - _origY;
// If the distance is greater than 2 meters, fall at a rate of 4%,
// otherwise, fall or step at a rate of 20%, both giving the appearance
// of a smooth transition:
float newY;
if (abs(distY) > 2)
newY = distY * 0.04;
else
newY = distY * 0.2;
// If the current update will put us higher or lower than the amount we are
// supposed to go, just use the amount we're supposed to go instead. We do
// this for precision:
if ( ( (newY >= 0) && ((currY + newY) > _newY) ) || ( (newY < 0) && ((currY + newY) < _newY) ) )
{
newY = _newY;
n->translate( 0, newY - currY, 0 );
}
else
{
// Otherwise, move from the current position by the new Y amount:
n->translate( 0, newY, 0 );
}
}
Code: Select all
//--------------------------------------------------------------------------------------
// Function used to test for collisions between the camera and objects in the scene.
//--------------------------------------------------------------------------------------
void Camera1P::collisionTestWithMOC(Real timeSinceLastFrame)
{
// Continue moving toward a new Y position until it is reached:
mCollisionTools->updateY(mMoveCamNode);
// If the camera is moving via input:
if (mDirection != Vector3::ZERO)
{
// Save the last position
Vector3 oldPos = mMoveCamNode->getPosition();
// Commit move
moveCamera(timeSinceLastFrame);
// Calculate the new Y position. Check terrain and all objects flagged with ENTITY_MASK.
// Multiple masks are possible like e.g. ENTITY_MASK|MY_MASK|ETC_MASK.
// doGridCheck casts a 2nd ray. gridWidth=2.0f ogre units away from the exact camera position to
// avoid falling through small holes or gaps in hangbridges for example.
mCollisionTools->calculateY(mMoveCamNode, false, false, true, 0.1f, 1.0f, CollisionTools::WALKABLE_OBJECTS);
// Start moving toward the new Y position immediately after finishing calculations:
mCollisionTools->updateY(mMoveCamNode);
// Check if we are colliding with anything. We pass in the camera's previous position,
// the camera's new position that will occur if there is no collision, and a collision radius
// of 1.0 units, which means that we will leave 1.0 units between the player and a collision.
// The next parameter is the height we want the ray to originate from, and the last parameter
// is the query mask which we have assigned all objects we want to check against for collisions.
// The query mask is used for efficiency so only objects we want tested are tested.
// If we collide, we undo the move:
if (mCollisionTools->collidesWithEntity(oldPos, mMoveCamNode->getPosition(), 1.0f,
-((mMoveCamNode->getPosition()).y * .8), CollisionTools::STATIONARY_OBJECTS))
mMoveCamNode->setPosition(oldPos);
}
}
-- Corn
-
- Gnoblar
- Posts: 16
- Joined: Sat Feb 07, 2009 8:28 pm
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
-
- Gnoll
- Posts: 653
- Joined: Thu May 11, 2006 9:12 pm
- Location: Bavaria
- x 36
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
ARTIFEX TERRA 3D - Artist-friendly, free and easy WYSIWYG realtime outdoor scene Editor & Painter
New loader now with Ogre::Terrain support: Addons for Artifex on SourceForge
MOC - Minimal Ogre Collision & Mousepicking
Simple TerrainMaterialGenerator for the use of standard Ogre material with Ogre::Terrain
Support me on Patreon
-
- Gnoblar
- Posts: 20
- Joined: Wed Feb 25, 2009 2:59 pm
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
how can I exclude the nodes/objects I don't want to detect collisions for?
-
- Gnoll
- Posts: 653
- Joined: Thu May 11, 2006 9:12 pm
- Location: Bavaria
- x 36
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
... and then you can pass the masks to the MOC methods as parameter.
HTH
ARTIFEX TERRA 3D - Artist-friendly, free and easy WYSIWYG realtime outdoor scene Editor & Painter
New loader now with Ogre::Terrain support: Addons for Artifex on SourceForge
MOC - Minimal Ogre Collision & Mousepicking
Simple TerrainMaterialGenerator for the use of standard Ogre material with Ogre::Terrain
Support me on Patreon
-
- Halfling
- Posts: 62
- Joined: Fri Mar 23, 2007 2:48 pm
- x 2
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
-
- Gnoblar
- Posts: 20
- Joined: Wed Feb 25, 2009 2:59 pm
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
Thank you. Works now.Nauk wrote:Assign a query mask for the objects you want to include. http://www.ogre3d.org/docs/api/html/cla ... ff5a74f54d
... and then you can pass the masks to the MOC methods as parameter.
HTH
-
- Gnoblar
- Posts: 12
- Joined: Sun Apr 05, 2009 12:02 pm
- Location: Pretoria, South Africa
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
I do have 2 minor problems though - first, I'm using this on a third-person system and (depending on ray height) it seems to catch the character model itself and prevent strafing left and right (model is wider in this area) - but I think my masks are just messed up, although they should be working ok...can anyone direct me to help with that?
Second, and this is more related to MOC, my character movement works on WASD - collisions work unless I hold down 2 keys at once and move diagonally (for instance, W and A) - is there any way to prevent this without messy if statements?
-
- Gnoblar
- Posts: 23
- Joined: Sun Feb 19, 2006 9:06 pm
- Location: Greece, Crete
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
I recently came across another issue. Has anyone tried to integrate MOC and PLSM2? I have modified the method to also return world fragment results, and it worked fine with the generic scene manager. when I switched to PLSM2, it stopped working. Reading the plsm forum it seems that it might work if I set WFT_SINGLE_INTERSECTION however, I don't want only a single result..
-
- Gnoblar
- Posts: 19
- Joined: Sat Jun 27, 2009 3:58 pm
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
I don't know how I have to use MOC. I need implement collision between a car and a track, both of them are maya mesh exported
thank you
-
- Goblin
- Posts: 236
- Joined: Tue Feb 26, 2008 5:48 pm
- x 3
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
-
- Gnoblar
- Posts: 16
- Joined: Sat Feb 07, 2009 8:28 pm
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
So far, I set one mask for objects that I wanted to test for collisions against, and a different mask for shapes that I wanted my character to be able to walk on or climb up (in the case of stairs and other objects that I wanted to support stepping).Jdog wrote: I do have 2 minor problems though - first, I'm using this on a third-person system and (depending on ray height) it seems to catch the character model itself and prevent strafing left and right (model is wider in this area) - but I think my masks are just messed up, although they should be working ok...can anyone direct me to help with that?
Second, and this is more related to MOC, my character movement works on WASD - collisions work unless I hold down 2 keys at once and move diagonally (for instance, W and A) - is there any way to prevent this without messy if statements?
I'll be happy to share my MOC related code in the third person camera controller I'm using in hopes that it helps you to identify and solve your problems.
Code: Select all
//--------------------------------------------------------------------------------------
void Camera3P::update ( Real timeSinceLastFrame )
{
// If we should use MOC for collision detection:
if (mCollisionType == collision_moc) {
collisionTestWithMOC(timeSinceLastFrame);
} else {
moveCharacter(timeSinceLastFrame);
moveCamera();
}
}
Code: Select all
//--------------------------------------------------------------------------------------
// Function used to test for collisions between the character and objects in the scene.
//--------------------------------------------------------------------------------------
void Camera3P::collisionTestWithMOC(Real timeSinceLastFrame)
{
// If we're still updating the Y position due to a step or a fall that
// was too large to complete in a single frame:
mCollisionTools->updateY(mCharMainNode);
// If there's no direction or orientation change:
if ((mDirection == 0) && (mOrientation == 0))
{
// Even if the character isn't moving, we may still need to complete both
// camera nodes' translation based on displacement:
moveCamera();
return;
}
// If we're only orienting the character:
if ((mDirection == 0) && (mOrientation != 0))
{
// Orient the character, and also adjust the camera diplacement
// if necessary by calling moveCamera():
moveCharacter(timeSinceLastFrame);
moveCamera();
return;
}
// If the character is moving via input:
if (mDirection != 0)
{
// Save the position of the character node before we commit
// the current move:
Vector3 charMainNode_PrevPos = mCharMainNode->getPosition();
// Commit move
moveCharacter(timeSinceLastFrame);
// Calculate the new Y position. Check terrain and all objects flagged with ENTITY_MASK.
// Multiple masks are possible like e.g. ENTITY_MASK|MY_MASK|ETC_MASK.
// doGridCheck casts a 2nd ray.
mCollisionTools->calculateY(mCharMainNode, false, false, true, 0.5f, 1.0f, CollisionTools::WALKABLE_OBJECTS);
// Move toward the new Y position at a rate of 1 m/s. If the return value is true, the
// update couldn't complete in one shot, so we will need to block movement and continue
// to update until completion:
mCollisionTools->updateY(mCharMainNode);
// Check if we are colliding with anything. We pass in the player's previous position,
// the player's new position that will occur if there is no collision, and a collision radius
// of 1.0 units, which means that we will leave 1.0 units between the player and a collision.
// The next parameter is the height we want the ray to originate from, and the last parameter
// is the query mask which we have assigned all objects we want to check against for collisions.
// The query mask is used for efficiency so only objects we want tested are tested.
// If we collide, we undo the move:
if (mCollisionTools->collidesWithEntity(charMainNode_PrevPos, mCharMainNode->getPosition(), 1.0f,
0.35f, CollisionTools::STATIONARY_OBJECTS))
{
// There was a collision with the sweep, so revert back to the last position so we don't
// collide:
mCharMainNode->setPosition(charMainNode_PrevPos);
}
else // If there was no collision:
{
moveCamera();
// If the y-position changed due to the ground changing, make sure the camera's nodes
// are also updated to the new height:
Ogre::Real r = mCharMainNode->getPosition().y - charMainNode_PrevPos.y;
if(r != 0)
{
mCameraNode->translate(0, r, 0);
mCameraTargetNode->translate(0, r, 0);
}
}
}
}
-
- Gnoblar
- Posts: 16
- Joined: Sat Feb 07, 2009 8:28 pm
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
My pleasure. You've done a great job on MOC! If I make any additional useful changes, I will continue to post them for the community to share.Nauk wrote:Very nice corn, those are good and usefull additions, thanks a lot for sharing, I will definately add them
-
- Gnoblar
- Posts: 19
- Joined: Sat Jun 27, 2009 3:58 pm
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
m_collisionTools = new CollisionTools(m_scene);
When I compile the program it crashes. The program says that the error is in the line:
mRaySceneQuery = mSceneMgr->createRayQuery(Ogre::Ray());
of the CollisionTools constructor. Someone can help me?
-
- Gnoblar
- Posts: 19
- Joined: Sat Jun 27, 2009 3:58 pm
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
Now the program crashes when I use the collidesWithEntity() method in myFrameListeners
m_collision = m_collisionTools->collidesWithEntity(oldPosition, m_animData->corpo->getPosition());
if(m_collision)
m_animData->corpo->setPosition(oldPosition);
Someone can help me?
-
- Gnoblar
- Posts: 19
- Joined: Sat Jun 27, 2009 3:58 pm
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
if(oldPosition.squaredDistance(m_animData->corpo->getPosition()) > 10) {
if (m_collisionTools->collidesWithEntity(oldPosition, m_animData->corpo->_getDerivedPosition(), 10.0f, 5.0f,SceneManager::ENTITY_TYPE_MASK))
{
// undo move
m_animData->corpo->setPosition(oldPosition);
}
}
to detect collision between character and walls.
The method works but I don't know why sometimes character stops even if it doesn't touch any wall.
-
- Halfling
- Posts: 89
- Joined: Sun Sep 06, 2009 12:36 pm
- x 18
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
I would like to implement collision sliding for an FPS camera and use the common method:
1) know the point of collision with the sphere
2) Calculate the normal of collision : normal = (CameraPos - CollisionPos).normalised()
3) Create a sliding vector: CameraVelocity -= normal * (CameraVelocity .dotProduct(normal ));
How can I know the position of the point where the sphere collide with an entity, using collidesWithEntity() ?
Thanks,
S.
https://twitter.com/bulostudio : follow me on twitter!
-
- Halfling
- Posts: 59
- Joined: Thu Oct 18, 2007 2:37 pm
- Location: The Netherlands
Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]
It currently, using the 1.0 release, doesn't work with manual objects for me. I've tried looking at the code but I haven't done anything with ray casting in Ogre yet.mickeyren wrote:Does this work on manual objects or just entity?
Since its based from the wiki entry - the wiki entry needs the mesh information from the entity - i don't think manual objects returns these information?
I'm aware of manualObject->convertToMesh but I'm using a lot of dynamically generated manual objects in my project that need to be updated pretty often so converting them to a mesh every time would not be ideal.
Is there any way to make MOC work for manual objects?
-
- Gnoblar
- Posts: 24
- Joined: Thu Aug 27, 2009 7:53 pm
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
MOC is really great thing
I'm using the latest version of it (1.0) with latest Ogre 1.6.3. And there are some problems with demo (I've recompiled it in order to support Ogre 1.6.3, with one minor change in the SampleApp.cpp):
- in OpenGL mode, all the terrain is white-colored - and there are errors about CG in the console;
- in DirectX mode, water is static now (it was dynamic in the original demo, however);
- FPS value sometimes breaks down to 12-15 FPS, especially when entering the house (enabling-disabling MOC does not change anything).
-
- Gnoblar
- Posts: 24
- Joined: Thu Aug 27, 2009 7:53 pm
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
how to correctly make sure that the camera does not pass through small gaps in walls?
i.e. in my app, i have 2 walls and a small gap between them, is it possible to tell MOC to still "collide" with the walls if the gap is less than some value?
-
- Halfling
- Posts: 59
- Joined: Thu Oct 18, 2007 2:37 pm
- Location: The Netherlands
Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]
Yes, there is. Read the source code better next time.aerique wrote:Is there any way to make MOC work for manual objects?
Anyway, I've got this working for ManualObjects now with a really ugly hack that suffices for now . I changed the check for an Entity into a check for an Entity or a ManualObject in the raycast method and I made sure the MeshPtr that's passed to GetMeshInformation comes from either Entity->getMesh() or ManualObject->convertToMesh().
You can find the changes here, but like I said it's very hackish: http://github.com/aerique/okra/commit/3 ... 694#diff-0
edit: Oh! and I also added a check for MovableObject->isVisible which might be handy for other people as well:
Code: Select all
...
// Only check this result if its a hit against an Entity or a ManualObject.
if ((query_result[qr_idx].movable != NULL) &&
(query_result[qr_idx].movable->isVisible()) &&
((query_result[qr_idx].movable->getMovableType().compare("Entity") == 0) || (query_result[qr_idx].movable->getMovableType().compare("ManualObject") == 0)))
{
...
-
- Gnoblar
- Posts: 5
- Joined: Tue Oct 06, 2009 10:53 pm
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
Maybe someone know how solve it?Jdog wrote: Second, and this is more related to MOC, my character movement works on WASD - collisions work unless I hold down 2 keys at once and move diagonally (for instance, W and A) - is there any way to prevent this without messy if statements?
btw Thanks very much for these tools!
-
- Gremlin
- Posts: 155
- Joined: Thu Sep 17, 2009 8:43 pm
- Location: Austria
- x 9
Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]
The method raycastFromCamera(...) uses a MouseEvent as parameter, in my opinion this is quite bad because it requires being called after a mouseEvent was produced, sounds not THAT bad at first but think of some issues like this one:
You don't move the mouse -> so no mouseevents are being produced, however although your surroundings move or some object moves at the position your mouse is pointing to- what happens is that there wont be an update on the object / point your target with your mouse, however altho it is in fact pointing on something different than what you have as result
Or: You make your character run into the direction you point at and you point somewhere on the ground and start moving character, but you dont move your mouse anymore -> the character will move to this point and then move back and forth on that point, altho meanwhile because your camera might have moved, too, the mouse is pointing on another point on the ground mesh
LONG BORING STORY SHORT:
To solve this small issues just use a mouseCursor Object or a pointer to such an object as parameter instead, and every time you actualize the mouseEvent you also actualize that pointer, thus you can update the targeted point even without a mouseevent and thus in the end guaranteeing that YOU GET WHAT YOU SEE and not some old buggy result because you didn't move your mouse around like a maniac without a break
nothing big really
Code: Select all
bool CollisionTools::raycastFromCamera(RenderWindow* rw, Camera* camera, Generals::mouseCursor* mouseCursorPos, Vector3 &result, ulong &target,float &closest_distance, const uint32 queryMask)
{
// Create the ray to test
Real tx = (Real) mouseCursorPos->x / (Real) rw->getWidth();
Real ty = (Real) mouseCursorPos->y / (Real) rw->getHeight();
Ray ray = camera->getCameraToViewportRay(tx, ty);
return raycast(ray, result, target, closest_distance, queryMask);
}
Code: Select all
struct mouseCursor
{
int x;
int y;
};
Code: Select all
//update mouseCursor
mouseCursor.x = evt.state.X.abs;
mouseCursor.y = evt.state.Y.abs;
any suggestions, criticism, or praises are appreciated (except maybe for the criticism)