From be5793727dae865fa38187c1d1f4ebfb3aaac8d8 Mon Sep 17 00:00:00 2001 From: cutealien Date: Fri, 8 Jul 2016 22:11:55 +0000 Subject: [PATCH] Merge revision 5303:5311 from trunk to ogl-es git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@5312 dfc29bdd-3216-0410-991c-e03cc46cb475 --- changes.txt | 15 ++++ examples/07.Collision/main.cpp | 6 +- examples/21.Quake3Explorer/main.cpp | 2 +- examples/21.Quake3Explorer/q3factory.cpp | 8 +- examples/Demo/CDemo.cpp | 4 +- source/Irrlicht/CAttributeImpl.h | 8 +- .../CSceneNodeAnimatorCollisionResponse.cpp | 25 +++--- source/Irrlicht/CTriangleSelector.cpp | 81 +++++++++++++----- tests/media/OpenGL-drawRectOutline.png | Bin 622 -> 608 bytes tests/testUtils.h | 34 +++++++- 10 files changed, 133 insertions(+), 50 deletions(-) diff --git a/changes.txt b/changes.txt index 6f2f0a11..ecff8a64 100644 --- a/changes.txt +++ b/changes.txt @@ -8,6 +8,18 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point) -------------------------- Changes in 1.9 (not yet released) +- Several fixes for SceneNodeAnimatorCollisionResponse, based on http://irrlicht.sourceforge.net/forum/viewtopic.php?f=7&t=33098&p=290746 + Thanks to all people who reported and to JLouisB and kinkreet for the patches: + - Gravity is now fps independent + - Values of gravity now like documented (wasn't 1 unit = 1m before, had been 1m = current frames per second, so maybe 100 units = 1m). + Note that jump-values for fps-camera must also change when adapting gravity! + Several examples got adapted for new ranges. + - Pausing timer now pauses animator. Also doesn't reset values anymore with pauses. + - Clones no longer have 1000 times the gravity of original animator. +should now be fps independentn +- Speedup CTriangleSelector (mainly for animated meshes) +- CTriangleSelector now supports 32-bit meshbuffers. Thanks @Wol101 for reporting and patch-proposal. +- Fix: CTriangleSelector no longer resets it's boundingbox to 0,0,0 (was wrong when a meshbuffer was not around 0) - Fix: Collada writer now uses wrap_p for third texture wrap value instead of invalid wrap_w (thx @Yoran for bugreport) - Several getter functions in IAttributes made const (thx @Erik Schultheis for the patch) - Fix: CTriangleSelector no longer ignores meshbuffer transformations from skinned meshes (thx @AlexAzazel for report and test-model). @@ -143,6 +155,9 @@ Changes in 1.9 (not yet released) -------------------------- Changes in 1.8.4 + - Tests on Unix now have a short pause between switching drivers to avoid certain X11 errors. + - Fix CEnumAttribute::getInt() which could crash (thx @ luthyr for reporting) + - No longer try to run tests for drivers not supported on a platform - Update lights and renderTargetTexture tests to work with Windows 10 (can't have so tiny Windows anymore). - Deprecate CMatrix4::transformBox as the result is no longer a boundingbox. Use CMatrix4::transformBoxEx instead (which has been available for a long time). - Fix CSceneCollisionManager::getPickedNodeBB which could sometimes miss collisions. diff --git a/examples/07.Collision/main.cpp b/examples/07.Collision/main.cpp index 6d785268..842a0f09 100644 --- a/examples/07.Collision/main.cpp +++ b/examples/07.Collision/main.cpp @@ -119,7 +119,7 @@ int main() values, the camera will be able to move closer to walls after this. The next parameter is the direction and speed of gravity. We'll set it to (0, -10, 0), which approximates to realistic gravity, assuming that our - units are metres. You could set it to (0,0,0) to disable gravity. And the + units are meters. You could set it to (0,0,0) to disable gravity. And the last value is just a translation: Without this, the ellipsoid with which collision detection is done would be around the camera, and the camera would be in the middle of the ellipsoid. But as human beings, we are used to have our @@ -132,7 +132,7 @@ int main() // Set a jump speed of 3 units per second, which gives a fairly realistic jump // when used with the gravity of (0, -10, 0) in the collision response animator. scene::ICameraSceneNode* camera = - smgr->addCameraSceneNodeFPS(0, 100.0f, .3f, ID_IsNotPickable, 0, 0, true, 3.f); + smgr->addCameraSceneNodeFPS(0, 100.0f, .3f, ID_IsNotPickable, 0, 0, true, 300.f); camera->setPosition(core::vector3df(50,50,-60)); camera->setTarget(core::vector3df(-70,30,-60)); @@ -140,7 +140,7 @@ int main() { scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator( selector, camera, core::vector3df(30,50,30), - core::vector3df(0,-10,0), core::vector3df(0,30,0)); + core::vector3df(0,-1000,0), core::vector3df(0,30,0)); selector->drop(); // As soon as we're done with the selector, drop it. camera->addAnimator(anim); anim->drop(); // And likewise, drop the animator when we're done referring to it. diff --git a/examples/21.Quake3Explorer/main.cpp b/examples/21.Quake3Explorer/main.cpp index 7ebc4700..8fd7d26b 100644 --- a/examples/21.Quake3Explorer/main.cpp +++ b/examples/21.Quake3Explorer/main.cpp @@ -316,7 +316,7 @@ void Q3Player::create ( IrrlichtDevice *device, IQ3LevelMesh* mesh, ISceneNode * keyMap[9].Action = EKA_CROUCH; keyMap[9].KeyCode = KEY_KEY_C; - camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 0.6f, -1, keyMap, 10, false, 0.6f); + camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 0.6f, -1, keyMap, 10, false, 600.f); camera->setName ( "First Person Camera" ); //camera->setFOV ( 100.f * core::DEGTORAD ); camera->setFarValue( 20000.f ); diff --git a/examples/21.Quake3Explorer/q3factory.cpp b/examples/21.Quake3Explorer/q3factory.cpp index 0c98a080..476a2ed4 100644 --- a/examples/21.Quake3Explorer/q3factory.cpp +++ b/examples/21.Quake3Explorer/q3factory.cpp @@ -735,10 +735,10 @@ s32 Q3StartPosition ( IQ3LevelMesh* mesh, */ vector3df getGravity ( const c8 * surface ) { - if ( 0 == strcmp ( surface, "earth" ) ) return vector3df ( 0.f, -90.f, 0.f ); - if ( 0 == strcmp ( surface, "moon" ) ) return vector3df ( 0.f, -6.f / 100.f, 0.f ); - if ( 0 == strcmp ( surface, "water" ) ) return vector3df ( 0.1f / 100.f, -2.f / 100.f, 0.f ); - if ( 0 == strcmp ( surface, "ice" ) ) return vector3df ( 0.2f / 100.f, -9.f / 100.f, 0.3f / 100.f ); + if ( 0 == strcmp ( surface, "earth" ) ) return vector3df ( 0.f, -900.f, 0.f ); + if ( 0 == strcmp ( surface, "moon" ) ) return vector3df ( 0.f, -6.f , 0.f ); + if ( 0 == strcmp ( surface, "water" ) ) return vector3df ( 0.1f, -2.f, 0.f ); + if ( 0 == strcmp ( surface, "ice" ) ) return vector3df ( 0.2f, -9.f, 0.3f ); return vector3df ( 0.f, 0.f, 0.f ); } diff --git a/examples/Demo/CDemo.cpp b/examples/Demo/CDemo.cpp index e9babcdf..fe7a9d0d 100644 --- a/examples/Demo/CDemo.cpp +++ b/examples/Demo/CDemo.cpp @@ -328,14 +328,14 @@ void CDemo::switchToNextScene() keyMap[8].Action = EKA_JUMP_UP; keyMap[8].KeyCode = KEY_KEY_J; - camera = sm->addCameraSceneNodeFPS(0, 100.0f, .4f, -1, keyMap, 9, false, 3.f); + camera = sm->addCameraSceneNodeFPS(0, 100.0f, .4f, -1, keyMap, 9, false, 300.f); camera->setPosition(core::vector3df(108,140,-140)); camera->setFarValue(5000.0f); scene::ISceneNodeAnimatorCollisionResponse* collider = sm->createCollisionResponseAnimator( metaSelector, camera, core::vector3df(25,50,25), - core::vector3df(0, quakeLevelMesh ? -10.f : 0.0f,0), + core::vector3df(0, quakeLevelMesh ? -1000.f : 0.0f,0), core::vector3df(0,45,0), 0.005f); camera->addAnimator(collider); diff --git a/source/Irrlicht/CAttributeImpl.h b/source/Irrlicht/CAttributeImpl.h index 570045e8..d7096b60 100644 --- a/source/Irrlicht/CAttributeImpl.h +++ b/source/Irrlicht/CAttributeImpl.h @@ -1576,7 +1576,7 @@ public: virtual void setEnum(const char* enumValue, const char* const* enumerationLiterals) _IRR_OVERRIDE_ { - int literalCount = 0; + u32 literalCount = 0; if (enumerationLiterals) { @@ -1594,11 +1594,13 @@ public: virtual s32 getInt() _IRR_OVERRIDE_ { - for (s32 i=0; EnumLiterals.size(); ++i) + for (u32 i=0; i < EnumLiterals.size(); ++i) + { if (Value.equals_ignore_case(EnumLiterals[i])) { - return i; + return (s32)i; } + } return -1; } diff --git a/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp b/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp index 64e57d00..f6a7d204 100644 --- a/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp +++ b/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp @@ -164,13 +164,13 @@ void CSceneNodeAnimatorCollisionResponse::animateNode(ISceneNode* node, u32 time FirstUpdate = false; } - const u32 diff = timeMs - LastTime; + const f32 diffSec = (f32)(timeMs - LastTime)*0.001f; LastTime = timeMs; CollisionResultPosition = Object->getPosition(); core::vector3df vel = CollisionResultPosition - LastPosition; - FallingVelocity += Gravity * (f32)diff * 0.001f; + FallingVelocity += Gravity * diffSec; CollisionTriangle = RefTriangle; CollisionPoint = core::vector3df(); @@ -188,20 +188,23 @@ void CSceneNodeAnimatorCollisionResponse::animateNode(ISceneNode* node, u32 time = SceneManager->getSceneCollisionManager()->getCollisionResultPosition( World, LastPosition-Translation, Radius, vel, CollisionTriangle, CollisionPoint, f, - CollisionNode, SlidingSpeed, FallingVelocity); + CollisionNode, SlidingSpeed, FallingVelocity*diffSec); CollisionOccurred = (CollisionTriangle != RefTriangle); CollisionResultPosition += Translation; - if (f)//CollisionTriangle == RefTriangle) + if ( diffSec > 0 ) // don't change the state when there was no time { - Falling = true; - } - else - { - Falling = false; - FallingVelocity.set(0, 0, 0); + if (f)//CollisionTriangle == RefTriangle) + { + Falling = true; + } + else + { + Falling = false; + FallingVelocity.set(0, 0, 0); + } } bool collisionConsumed = false; @@ -269,7 +272,7 @@ ISceneNodeAnimator* CSceneNodeAnimatorCollisionResponse::createClone(ISceneNode* CSceneNodeAnimatorCollisionResponse * newAnimator = new CSceneNodeAnimatorCollisionResponse(newManager, World, Object, Radius, - (Gravity * 1000.0f), Translation, SlidingSpeed); + Gravity, Translation, SlidingSpeed); newAnimator->cloneMembers(this); return newAnimator; } diff --git a/source/Irrlicht/CTriangleSelector.cpp b/source/Irrlicht/CTriangleSelector.cpp index 78965d1f..8b9b948b 100644 --- a/source/Irrlicht/CTriangleSelector.cpp +++ b/source/Irrlicht/CTriangleSelector.cpp @@ -84,6 +84,30 @@ void CTriangleSelector::createFromMesh(const IMesh* mesh) updateFromMesh(mesh); } +template +static void updateTriangles(u32& triangleCount, core::array& triangles, u32 idxCnt, const TIndex* indices, const u8* vertices, u32 vertexPitch, const core::matrix4* bufferTransform) +{ + if ( bufferTransform ) + { + for (u32 index = 0; index < idxCnt; index += 3) + { + core::triangle3df& tri = triangles[triangleCount++]; + bufferTransform->transformVect( tri.pointA, (*reinterpret_cast(&vertices[indices[index + 0]*vertexPitch])).Pos ); + bufferTransform->transformVect( tri.pointB, (*reinterpret_cast(&vertices[indices[index + 1]*vertexPitch])).Pos ); + bufferTransform->transformVect( tri.pointC, (*reinterpret_cast(&vertices[indices[index + 2]*vertexPitch])).Pos ); + } + } + else + { + for (u32 index = 0; index < idxCnt; index += 3) + { + core::triangle3df& tri = triangles[triangleCount++]; + tri.pointA = (*reinterpret_cast(&vertices[indices[index + 0]*vertexPitch])).Pos; + tri.pointB = (*reinterpret_cast(&vertices[indices[index + 1]*vertexPitch])).Pos; + tri.pointC = (*reinterpret_cast(&vertices[indices[index + 2]*vertexPitch])).Pos; + } + } +} void CTriangleSelector::updateFromMesh(const IMesh* mesh) const { @@ -94,41 +118,54 @@ void CTriangleSelector::updateFromMesh(const IMesh* mesh) const u32 meshBuffers = mesh->getMeshBufferCount(); u32 triangleCount = 0; - BoundingBox.reset(0.f, 0.f, 0.f); for (u32 i = 0; i < meshBuffers; ++i) { IMeshBuffer* buf = mesh->getMeshBuffer(i); u32 idxCnt = buf->getIndexCount(); - const u16* indices = buf->getIndices(); + u32 vertexPitch = getVertexPitchFromType(buf->getVertexType()); + u8* vertices = (u8*)buf->getVertices(); + const core::matrix4* bufferTransform = 0; if ( skinnnedMesh ) { - const core::matrix4& bufferTransform = ((scene::SSkinMeshBuffer*)buf)->Transformation; - for (u32 index = 0; index < idxCnt; index += 3) - { - core::triangle3df& tri = Triangles[triangleCount++]; - bufferTransform.transformVect(tri.pointA, buf->getPosition(indices[index + 0])); - bufferTransform.transformVect(tri.pointB, buf->getPosition(indices[index + 1])); - bufferTransform.transformVect(tri.pointC, buf->getPosition(indices[index + 2])); - BoundingBox.addInternalPoint(tri.pointA); - BoundingBox.addInternalPoint(tri.pointB); - BoundingBox.addInternalPoint(tri.pointC); - } + bufferTransform = &(((scene::SSkinMeshBuffer*)buf)->Transformation); + if ( bufferTransform->isIdentity() ) + bufferTransform = 0; } - else + + switch ( buf->getIndexType() ) { - for (u32 index = 0; index < idxCnt; index += 3) + case video::EIT_16BIT: { - core::triangle3df& tri = Triangles[triangleCount++]; - tri.pointA = buf->getPosition(indices[index + 0]); - tri.pointB = buf->getPosition(indices[index + 1]); - tri.pointC = buf->getPosition(indices[index + 2]); - BoundingBox.addInternalPoint(tri.pointA); - BoundingBox.addInternalPoint(tri.pointB); - BoundingBox.addInternalPoint(tri.pointC); + const u16* indices = buf->getIndices(); + updateTriangles(triangleCount, Triangles, idxCnt, indices, vertices, vertexPitch, bufferTransform); } + break; + case video::EIT_32BIT: + { + const u32* indices = (u32*)buf->getIndices(); + updateTriangles(triangleCount, Triangles, idxCnt, indices, vertices, vertexPitch, bufferTransform); + } + break; } } + + // Update bounding box + if ( triangleCount ) + { + BoundingBox.reset( Triangles[0].pointA ); + for (u32 i=0; i < triangleCount; ++i) + { + const core::triangle3df& tri = Triangles[i]; + BoundingBox.addInternalPoint(tri.pointA); + BoundingBox.addInternalPoint(tri.pointB); + BoundingBox.addInternalPoint(tri.pointC); + } + } + else + { + BoundingBox.reset(0.f, 0.f, 0.f); + } } diff --git a/tests/media/OpenGL-drawRectOutline.png b/tests/media/OpenGL-drawRectOutline.png index 274fc3c311ee0c46245188fb231040cd6641e18c..6032237aed0a181652a1c75aa6e48587758da876 100644 GIT binary patch literal 608 zcmeAS@N?(olHy`uVBq!ia0vp^3xK$Sg9%9fI*@0EaktG3V{gyP1aqWE?); zmYT9}M_YCZvxW2hnqYw%fm5bORg%sgfA}X(t{xhb!iAYpJGb;!`0s}a$hz%yKQ%M{o7|V zAE-)!b+0bv*SmOD`uyq;-pHr--Lx0?q{GciZ`ZkNEIF6^{SoDeWajIK8@Zd49wxu( zZ%!{?QvVccKy}#(tve+*_gjbln1zig}X2p_+|ak%rRqH@(%f(}|Q>A0l4SiRmlPxvn1%_nv$aQ@nK70;_^D ziDT`e{+sf|SC_^uf<#G_bJ)&`H$^9YeJz)|E6;v5|FAJE*6y%s3i(D{v`9Y>OgRjm Lu6{1-oD!M<5Ge?T delta 431 zcmaFB@{VPKO1-J4i(^Q|oVPdk<{olja7a{-h%hOc*=QQUu#7{e!H6}H@r7gq=N<-T z17=xYmPt!RJUCwV%$5Ie@Nq5gq@9mS{OxL(B1HdLTs3VIKeP zcJKIao04|DHL;vKe+B=Zo7=;7moW$LtZ%NX-x?GDYuln)m%NJwY;DF6lfwUt#J;tY zm(5@LZbrynsX#vEdk2BCzaNX$-s-N3EZp^id;Nuuw~T)tx0+ZOTD_fy{9 z3ZF4?-6>ruuq(hGcr|~~>bdiI=lz)x@~WoR?048_8Q~9nK+oMVkBtrv6XEm?VE_V8 LS3j3^P6 +// Small hack. Some newer X11 systems can't handle switching drivers too fast (causing BadWindow errors in X_ChangeWindowAttributes). +// Could be they don't like when Windows with different Visuals are created very quickly (it always happened after creating a new Window with different Visual to previous one). +// timeMs value set by try&error +#ifdef _IRR_POSIX_API_ + #include + #define SLOW_SWITCH \ + do { \ + struct timespec ts; \ + const int timeMs = 250; \ + ts.tv_sec = (time_t) (timeMs / 1000); \ + ts.tv_nsec = (long) (timeMs % 1000) * 1000000; \ + nanosleep(&ts, NULL);\ + } while (false) +#else + #define SLOW_SWITCH +#endif + #define TestWithAllDrivers(X) \ logTestString("Running test " #X "\n"); \ - for (u32 i=1; i