Merge revisions r5337:r5415 from trunk to ogl-es.
git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@5416 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
63c2864db5
commit
f1ee785039
26
changes.txt
26
changes.txt
|
@ -9,6 +9,19 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point)
|
||||||
--------------------------
|
--------------------------
|
||||||
Changes in 1.9 (not yet released)
|
Changes in 1.9 (not yet released)
|
||||||
|
|
||||||
|
- Improve speed of draw3DBox (OpenGL and D3D9). Thanks @zerochen for patch (https://sourceforge.net/p/irrlicht/patches/256)
|
||||||
|
- Support more keys on OSX "[]\". Thanks @neoascetic for patch (#313).
|
||||||
|
- Fix IBillboardTextSceneNode::setTextColor which did nothing in the past. It now maps to setColor instead.
|
||||||
|
- Add access functions to IBillboardTextSceneNode (getText, getFont).
|
||||||
|
- Add access functions to ITextSceneNode (getText, getTextColor, setFont, getFont).
|
||||||
|
- Try harder to move Window to custom WindowPosition set in SIrrlichtCreationParameters on X11. Thx@ Hernan Ezequiel Di Giorgi for the patch (#304).
|
||||||
|
- Fix bug in virtual filessystem which prevented createFileList from working. Thx @Cube for reporting a problem.
|
||||||
|
- ITriangleSelector now can also return meshbuffer collision information.
|
||||||
|
- core::string::split now adds delimiter to token before delimiter when keepSeparators is true. That way we never end up with 2 tokens for an original string with a single character.
|
||||||
|
- Bugfix: SMesh::recalculateBoundingBox() does now ignore empty boundingboxes of meshbuffers instead of adding them.
|
||||||
|
- IIrrXMLReader::getAttributeValueAsInt and IIrrXMLReader::getAttributeValueAsFloat can now return a custom default-value when the attribute is not found.
|
||||||
|
- core::string::split now handles ignoreEmptyTokens=false correct. Thanks @manni63 for bugreport: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=7&t=51551&p=299375#p299375
|
||||||
|
- Bugfix: Previously when some material had a texture matrix and another didn't those materials were still considered identical. Which had prevented correct switching between materials with and without texture matrices.
|
||||||
- IWriteFile::write now returning size_t (like fwrite in c-lib). Also sizeToWrite parameter changed from u32 to size_t.
|
- IWriteFile::write now returning size_t (like fwrite in c-lib). Also sizeToWrite parameter changed from u32 to size_t.
|
||||||
- IReadFile::read now returning size_t (like fread in c-lib). Also sizeToRead parameter changed from u32 to size_t.
|
- IReadFile::read now returning size_t (like fread in c-lib). Also sizeToRead parameter changed from u32 to size_t.
|
||||||
- add clear function to strings.
|
- add clear function to strings.
|
||||||
|
@ -160,6 +173,17 @@ should now be fps independentn
|
||||||
|
|
||||||
--------------------------
|
--------------------------
|
||||||
Changes in 1.8.5
|
Changes in 1.8.5
|
||||||
|
- Fix bug in cursor positions when compiled with newer Windows SDK's (v110 in VS2012) and running on Systems >= Windows Vista in windowed mode.
|
||||||
|
Thanks @Mustapha Tachouct for the bugreport and patch proposal. Also thanks @BakeMyCake for an earlier report.
|
||||||
|
- IOSOperator::getSysteMemory() no longer returns incorrect values with >2GB. Thanks @Eduline - human development for report and patch.
|
||||||
|
- Increase KEY_KEY_CODES_COUNT to fix problem with laptop keyboards which return the keycode 0xff for the function key. Thx @Klokancz for bugreport and patch.
|
||||||
|
- Fix bug when calling activateJoysticks on windows several times. It had appened joystick information instead of replacing it, thereby increasing joystick number on each call.
|
||||||
|
Only happened compiling with _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ (which is the default). Linux and SDL implementation not affected.
|
||||||
|
Thx @Andrea Demetrio for the bugreport.
|
||||||
|
- Fix bug in fast_atof when reading floating point numbers with more than 16 digits past the dot. Those produced completely wrong results (sometimes even causing INF numbers).
|
||||||
|
This bug also did cause many meshloaders to have problems with certain meshes (basically all text-based formats are affected).
|
||||||
|
- Accuracy of fast_atof is back to older Irrlicht versions (fixes test warnings, usually not a noticable problem).
|
||||||
|
- Fix crash in eventhandling when calling remove() on a contextmenu while it has focus.
|
||||||
- CImageLoaderJPG::isALoadableFileFormat uses a test which allows to load more jpg formats (for example uncompressed jpg's). Thx @Yaron Cohen-Tal for report, test-image and his help with the patch.
|
- CImageLoaderJPG::isALoadableFileFormat uses a test which allows to load more jpg formats (for example uncompressed jpg's). Thx @Yaron Cohen-Tal for report, test-image and his help with the patch.
|
||||||
|
|
||||||
--------------------------
|
--------------------------
|
||||||
|
@ -255,7 +279,7 @@ Changes in 1.8 (7.11.2012)
|
||||||
|
|
||||||
- quaternion conversions to and from matrix4 no longer invert rotations.
|
- quaternion conversions to and from matrix4 no longer invert rotations.
|
||||||
To test if your code was affected by this you can set IRR_TEST_BROKEN_QUATERNION_USE in quaternion.h and try to compile your application.
|
To test if your code was affected by this you can set IRR_TEST_BROKEN_QUATERNION_USE in quaternion.h and try to compile your application.
|
||||||
Then on all compile-errors when you pass the matrix to the quaternion you can replace the matrix transposed matrix.
|
Then on all compile-errors when you pass the matrix to the quaternion you can replace the matrix with the transposed matrix.
|
||||||
For all errors you get on getMatrix() you can use quaternion::getMatrix_transposed instead.
|
For all errors you get on getMatrix() you can use quaternion::getMatrix_transposed instead.
|
||||||
|
|
||||||
- CGUIEnvironment::loadGui - loading a gui into a target-element no longer messes up when the gui-file contained guienvironment serialization.
|
- CGUIEnvironment::loadGui - loading a gui into a target-element no longer messes up when the gui-file contained guienvironment serialization.
|
||||||
|
|
|
@ -36,6 +36,13 @@ enum
|
||||||
IDFlag_IsHighlightable = 1 << 1
|
IDFlag_IsHighlightable = 1 << 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Some triangle selectors allow to get collisions either per mesh or per meshbuffer.
|
||||||
|
Getting them per mesh can be faster. But if you need information about the hit
|
||||||
|
material you have to get the meshbuffer information as well.
|
||||||
|
*/
|
||||||
|
const bool separateMeshBuffers = true;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// ask user for driver
|
// ask user for driver
|
||||||
|
@ -86,8 +93,34 @@ int main()
|
||||||
{
|
{
|
||||||
q3node->setPosition(core::vector3df(-1350,-130,-1400));
|
q3node->setPosition(core::vector3df(-1350,-130,-1400));
|
||||||
|
|
||||||
selector = smgr->createOctreeTriangleSelector(
|
/*
|
||||||
q3node->getMesh(), q3node, 128);
|
There is currently no way to split an octree by material.
|
||||||
|
So if we need that we have to create one octree per meshbuffer
|
||||||
|
and put them together in a MetaTriangleSelector.
|
||||||
|
*/
|
||||||
|
if ( separateMeshBuffers && q3node->getMesh()->getMeshBufferCount() > 1)
|
||||||
|
{
|
||||||
|
scene::IMetaTriangleSelector * metaSelector = smgr->createMetaTriangleSelector();
|
||||||
|
for ( irr::u32 m=0; m < q3node->getMesh()->getMeshBufferCount(); ++m )
|
||||||
|
{
|
||||||
|
scene::ITriangleSelector*
|
||||||
|
bufferSelector = smgr->createOctreeTriangleSelector(
|
||||||
|
q3node->getMesh()->getMeshBuffer(m), m, q3node);
|
||||||
|
if ( bufferSelector )
|
||||||
|
{
|
||||||
|
metaSelector->addTriangleSelector( bufferSelector );
|
||||||
|
bufferSelector->drop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selector = metaSelector;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Just one octree for the whole mesh.
|
||||||
|
// Can't get information which material got hit, but for many situations that's enough.
|
||||||
|
selector = smgr->createOctreeTriangleSelector(
|
||||||
|
q3node->getMesh(), q3node, 128);
|
||||||
|
}
|
||||||
q3node->setTriangleSelector(selector);
|
q3node->setTriangleSelector(selector);
|
||||||
// We're not done with this selector yet, so don't drop it.
|
// We're not done with this selector yet, so don't drop it.
|
||||||
}
|
}
|
||||||
|
@ -138,7 +171,7 @@ int main()
|
||||||
|
|
||||||
if (selector)
|
if (selector)
|
||||||
{
|
{
|
||||||
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
|
scene::ISceneNodeAnimatorCollisionResponse * anim = smgr->createCollisionResponseAnimator(
|
||||||
selector, camera, core::vector3df(30,50,30),
|
selector, camera, core::vector3df(30,50,30),
|
||||||
core::vector3df(0,-1000,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.
|
selector->drop(); // As soon as we're done with the selector, drop it.
|
||||||
|
@ -183,7 +216,7 @@ int main()
|
||||||
|
|
||||||
// Now create a triangle selector for it. The selector will know that it
|
// Now create a triangle selector for it. The selector will know that it
|
||||||
// is associated with an animated node, and will update itself as necessary.
|
// is associated with an animated node, and will update itself as necessary.
|
||||||
selector = smgr->createTriangleSelector(node);
|
selector = smgr->createTriangleSelector(node, separateMeshBuffers);
|
||||||
node->setTriangleSelector(selector);
|
node->setTriangleSelector(selector);
|
||||||
selector->drop(); // We're done with this selector, so drop it now.
|
selector->drop(); // We're done with this selector, so drop it now.
|
||||||
|
|
||||||
|
@ -197,7 +230,7 @@ int main()
|
||||||
node->getMaterial(0).NormalizeNormals = true;
|
node->getMaterial(0).NormalizeNormals = true;
|
||||||
node->getMaterial(0).Lighting = true;
|
node->getMaterial(0).Lighting = true;
|
||||||
// Just do the same as we did above.
|
// Just do the same as we did above.
|
||||||
selector = smgr->createTriangleSelector(node);
|
selector = smgr->createTriangleSelector(node, separateMeshBuffers);
|
||||||
node->setTriangleSelector(selector);
|
node->setTriangleSelector(selector);
|
||||||
selector->drop();
|
selector->drop();
|
||||||
|
|
||||||
|
@ -208,11 +241,10 @@ int main()
|
||||||
node->setRotation(core::vector3df(0,-90,0)); // And turn it towards the camera.
|
node->setRotation(core::vector3df(0,-90,0)); // And turn it towards the camera.
|
||||||
node->setAnimationSpeed(20.f);
|
node->setAnimationSpeed(20.f);
|
||||||
node->getMaterial(0).Lighting = true;
|
node->getMaterial(0).Lighting = true;
|
||||||
selector = smgr->createTriangleSelector(node);
|
selector = smgr->createTriangleSelector(node, separateMeshBuffers);
|
||||||
node->setTriangleSelector(selector);
|
node->setTriangleSelector(selector);
|
||||||
selector->drop();
|
selector->drop();
|
||||||
|
|
||||||
|
|
||||||
// And this mdl file uses skinned skeletal animation.
|
// And this mdl file uses skinned skeletal animation.
|
||||||
node = smgr->addAnimatedMeshSceneNode(smgr->getMesh(mediaPath + "yodan.mdl"),
|
node = smgr->addAnimatedMeshSceneNode(smgr->getMesh(mediaPath + "yodan.mdl"),
|
||||||
0, IDFlag_IsPickable | IDFlag_IsHighlightable);
|
0, IDFlag_IsPickable | IDFlag_IsHighlightable);
|
||||||
|
@ -222,7 +254,7 @@ int main()
|
||||||
node->setAnimationSpeed(20.f);
|
node->setAnimationSpeed(20.f);
|
||||||
|
|
||||||
// Just do the same as we did above.
|
// Just do the same as we did above.
|
||||||
selector = smgr->createTriangleSelector(node);
|
selector = smgr->createTriangleSelector(node, separateMeshBuffers);
|
||||||
node->setTriangleSelector(selector);
|
node->setTriangleSelector(selector);
|
||||||
selector->drop();
|
selector->drop();
|
||||||
|
|
||||||
|
@ -237,7 +269,6 @@ int main()
|
||||||
// Remember which scene node is highlighted
|
// Remember which scene node is highlighted
|
||||||
scene::ISceneNode* highlightedSceneNode = 0;
|
scene::ISceneNode* highlightedSceneNode = 0;
|
||||||
scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();
|
scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();
|
||||||
int lastFPS = -1;
|
|
||||||
|
|
||||||
// draw the selection triangle only as wireframe
|
// draw the selection triangle only as wireframe
|
||||||
material.Wireframe=true;
|
material.Wireframe=true;
|
||||||
|
@ -263,10 +294,6 @@ int main()
|
||||||
ray.start = camera->getPosition();
|
ray.start = camera->getPosition();
|
||||||
ray.end = ray.start + (camera->getTarget() - ray.start).normalize() * 1000.0f;
|
ray.end = ray.start + (camera->getTarget() - ray.start).normalize() * 1000.0f;
|
||||||
|
|
||||||
// Tracks the current intersection point with the level or a mesh
|
|
||||||
core::vector3df intersection;
|
|
||||||
// Used to show with triangle has been hit
|
|
||||||
core::triangle3df hitTriangle;
|
|
||||||
|
|
||||||
// This call is all you need to perform ray/triangle collision on every scene node
|
// This call is all you need to perform ray/triangle collision on every scene node
|
||||||
// that has a triangle selector, including the Quake level mesh. It finds the nearest
|
// that has a triangle selector, including the Quake level mesh. It finds the nearest
|
||||||
|
@ -274,25 +301,27 @@ int main()
|
||||||
// Irrlicht provides other types of selection, including ray/triangle selector,
|
// Irrlicht provides other types of selection, including ray/triangle selector,
|
||||||
// ray/box and ellipse/triangle selector, plus associated helpers.
|
// ray/box and ellipse/triangle selector, plus associated helpers.
|
||||||
// See the methods of ISceneCollisionManager
|
// See the methods of ISceneCollisionManager
|
||||||
scene::ISceneNode * selectedSceneNode =
|
|
||||||
collMan->getSceneNodeAndCollisionPointFromRay(
|
irr::io::SNamedPath hitTextureName;
|
||||||
|
scene::SCollisionHit hitResult;
|
||||||
|
scene::ISceneNode * selectedSceneNode =collMan->getSceneNodeAndCollisionPointFromRay(
|
||||||
|
hitResult, // Returns all kind of info about the collision
|
||||||
ray,
|
ray,
|
||||||
intersection, // This will be the position of the collision
|
|
||||||
hitTriangle, // This will be the triangle hit in the collision
|
|
||||||
IDFlag_IsPickable, // This ensures that only nodes that we have
|
IDFlag_IsPickable, // This ensures that only nodes that we have
|
||||||
// set up to be pickable are considered
|
// set up to be pickable are considered
|
||||||
0); // Check the entire scene (this is actually the implicit default)
|
0); // Check the entire scene (this is actually the implicit default)
|
||||||
|
|
||||||
|
|
||||||
// If the ray hit anything, move the billboard to the collision position
|
// If the ray hit anything, move the billboard to the collision position
|
||||||
// and draw the triangle that was hit.
|
// and draw the triangle that was hit.
|
||||||
if(selectedSceneNode)
|
if(selectedSceneNode)
|
||||||
{
|
{
|
||||||
bill->setPosition(intersection);
|
bill->setPosition(hitResult.Intersection); // Show the current intersection point with the level or a mesh
|
||||||
|
|
||||||
// We need to reset the transform before doing our own rendering.
|
// We need to reset the transform before doing our own rendering.
|
||||||
driver->setTransform(video::ETS_WORLD, core::matrix4());
|
driver->setTransform(video::ETS_WORLD, core::matrix4());
|
||||||
driver->setMaterial(material);
|
driver->setMaterial(material);
|
||||||
driver->draw3DTriangle(hitTriangle, video::SColor(0,255,0,0));
|
driver->draw3DTriangle(hitResult.Triangle, video::SColor(0,255,0,0)); // Show which triangle has been hit
|
||||||
|
|
||||||
// We can check the flags for the scene node that was hit to see if it should be
|
// We can check the flags for the scene node that was hit to see if it should be
|
||||||
// highlighted. The animated nodes can be highlighted, but not the Quake level mesh
|
// highlighted. The animated nodes can be highlighted, but not the Quake level mesh
|
||||||
|
@ -304,23 +333,31 @@ int main()
|
||||||
// which means that it will be drawn with full brightness.
|
// which means that it will be drawn with full brightness.
|
||||||
highlightedSceneNode->setMaterialFlag(video::EMF_LIGHTING, false);
|
highlightedSceneNode->setMaterialFlag(video::EMF_LIGHTING, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( hitResult.MeshBuffer && hitResult.Node && hitResult.Node->getMaterial(hitResult.MaterialIndex).TextureLayer[0].Texture )
|
||||||
|
{
|
||||||
|
// Note we are interested in the node material and not in the meshbuffer material.
|
||||||
|
// Otherwise we wouldn't get the fairy2 texture which is only set on the node.
|
||||||
|
hitTextureName = hitResult.Node->getMaterial(hitResult.MaterialIndex).TextureLayer[0].Texture->getName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're all done drawing, so end the scene.
|
// We're all done drawing, so end the scene.
|
||||||
driver->endScene();
|
driver->endScene();
|
||||||
|
|
||||||
|
// Show some info in title-bar
|
||||||
int fps = driver->getFPS();
|
int fps = driver->getFPS();
|
||||||
|
core::stringw str = L"Collision detection example - Irrlicht Engine [";
|
||||||
if (lastFPS != fps)
|
str += driver->getName();
|
||||||
|
str += "] FPS:";
|
||||||
|
str += fps;
|
||||||
|
if ( !hitTextureName.getInternalName().empty() )
|
||||||
{
|
{
|
||||||
core::stringw str = L"Collision detection example - Irrlicht Engine [";
|
str += " ";
|
||||||
str += driver->getName();
|
irr::io::path texName(hitTextureName.getInternalName());
|
||||||
str += "] FPS:";
|
str += core::deletePathFromFilename(texName);
|
||||||
str += fps;
|
|
||||||
|
|
||||||
device->setWindowCaption(str.c_str());
|
|
||||||
lastFPS = fps;
|
|
||||||
}
|
}
|
||||||
|
device->setWindowCaption(str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
device->drop();
|
device->drop();
|
||||||
|
|
|
@ -30,6 +30,9 @@ namespace scene
|
||||||
//! Text Scene Node
|
//! Text Scene Node
|
||||||
ESNT_TEXT = MAKE_IRR_ID('t','e','x','t'),
|
ESNT_TEXT = MAKE_IRR_ID('t','e','x','t'),
|
||||||
|
|
||||||
|
//! Billboard text scene node
|
||||||
|
ESNT_BILLBOARD_TEXT = MAKE_IRR_ID('b','t','x','t'),
|
||||||
|
|
||||||
//! Water Surface Scene Node
|
//! Water Surface Scene Node
|
||||||
ESNT_WATER_SURFACE = MAKE_IRR_ID('w','a','t','r'),
|
ESNT_WATER_SURFACE = MAKE_IRR_ID('w','a','t','r'),
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,12 @@
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace gui
|
||||||
|
{
|
||||||
|
class IGUIFont;
|
||||||
|
}
|
||||||
|
|
||||||
namespace scene
|
namespace scene
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -50,8 +56,18 @@ public:
|
||||||
//! sets the text string
|
//! sets the text string
|
||||||
virtual void setText(const wchar_t* text) = 0;
|
virtual void setText(const wchar_t* text) = 0;
|
||||||
|
|
||||||
|
//! get the text string
|
||||||
|
virtual const wchar_t* getText() const = 0;
|
||||||
|
|
||||||
//! sets the color of the text
|
//! sets the color of the text
|
||||||
virtual void setTextColor(video::SColor color) = 0;
|
//! You can use setColor instead which does the same
|
||||||
|
virtual void setTextColor(video::SColor color)
|
||||||
|
{
|
||||||
|
setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get the font used to draw the text
|
||||||
|
virtual gui::IGUIFont* getFont() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace scene
|
} // end namespace scene
|
||||||
|
|
|
@ -38,10 +38,10 @@ public:
|
||||||
virtual bool getProcessorSpeedMHz(u32* MHz) const = 0;
|
virtual bool getProcessorSpeedMHz(u32* MHz) const = 0;
|
||||||
|
|
||||||
//! Get the total and available system RAM
|
//! Get the total and available system RAM
|
||||||
/** \param Total: will contain the total system memory
|
/** \param totalBytes: will contain the total system memory in bytes
|
||||||
\param Avail: will contain the available memory
|
\param availableBytes: will contain the available memory in bytes
|
||||||
\return True if successful, false if not */
|
\return True if successful, false if not */
|
||||||
virtual bool getSystemMemory(u32* Total, u32* Avail) const = 0;
|
virtual bool getSystemMemory(u32* totalBytes, u32* availableBytes) const = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,45 @@ namespace scene
|
||||||
class ISceneNode;
|
class ISceneNode;
|
||||||
class ICameraSceneNode;
|
class ICameraSceneNode;
|
||||||
class ITriangleSelector;
|
class ITriangleSelector;
|
||||||
|
class IMeshBuffer;
|
||||||
|
|
||||||
|
struct SCollisionHit
|
||||||
|
{
|
||||||
|
//! Point of collision
|
||||||
|
core::vector3df Intersection;
|
||||||
|
|
||||||
|
//! Triangle with which we collided
|
||||||
|
core::triangle3df Triangle;
|
||||||
|
|
||||||
|
//! Triangle selector which contained the colliding triangle (useful when having MetaTriangleSelector)
|
||||||
|
ITriangleSelector* TriangleSelector;
|
||||||
|
|
||||||
|
//! Node which contained the triangle (is 0 when selector doesn't have that information)
|
||||||
|
ISceneNode* Node;
|
||||||
|
|
||||||
|
//! Meshbuffer which contained the triangle (is 0 when the selector doesn't have that information, only works when selectors are created per meshbuffer)
|
||||||
|
const IMeshBuffer* MeshBuffer;
|
||||||
|
|
||||||
|
//! Index of selected material of the triangle in the SceneNode. Usually only valid when MeshBuffer is also set, otherwise always 0
|
||||||
|
irr::u32 MaterialIndex;
|
||||||
|
|
||||||
|
SCollisionHit() : TriangleSelector(0), Node(0), MeshBuffer(0), MaterialIndex(0)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
//! The Scene Collision Manager provides methods for performing collision tests and picking on scene nodes.
|
//! The Scene Collision Manager provides methods for performing collision tests and picking on scene nodes.
|
||||||
class ISceneCollisionManager : public virtual IReferenceCounted
|
class ISceneCollisionManager : public virtual IReferenceCounted
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
//! Finds the nearest collision point of a line and lots of triangles, if there is one.
|
||||||
|
/** \param hitResult: Contains collision result when there was a collision detected.
|
||||||
|
\param ray: Line with which collisions are tested.
|
||||||
|
\param selector: TriangleSelector to be used for the collision check.
|
||||||
|
\return true if a collision was detected and false if not. */
|
||||||
|
virtual bool getCollisionPoint(SCollisionHit& hitResult, const core::line3d<f32>& ray,
|
||||||
|
ITriangleSelector* selector) = 0;
|
||||||
|
|
||||||
//! Finds the nearest collision point of a line and lots of triangles, if there is one.
|
//! Finds the nearest collision point of a line and lots of triangles, if there is one.
|
||||||
/** \param ray: Line with which collisions are tested.
|
/** \param ray: Line with which collisions are tested.
|
||||||
\param selector: TriangleSelector containing the triangles. It
|
\param selector: TriangleSelector containing the triangles. It
|
||||||
|
@ -40,7 +73,18 @@ namespace scene
|
||||||
\return True if a collision was detected and false if not. */
|
\return True if a collision was detected and false if not. */
|
||||||
virtual bool getCollisionPoint(const core::line3d<f32>& ray,
|
virtual bool getCollisionPoint(const core::line3d<f32>& ray,
|
||||||
ITriangleSelector* selector, core::vector3df& outCollisionPoint,
|
ITriangleSelector* selector, core::vector3df& outCollisionPoint,
|
||||||
core::triangle3df& outTriangle, ISceneNode*& outNode) =0;
|
core::triangle3df& outTriangle, ISceneNode*& outNode)
|
||||||
|
{
|
||||||
|
SCollisionHit hitResult;
|
||||||
|
if ( getCollisionPoint(hitResult, ray, selector) )
|
||||||
|
{
|
||||||
|
outCollisionPoint = hitResult.Intersection;
|
||||||
|
outTriangle = hitResult.Triangle;
|
||||||
|
outNode = hitResult.Node;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//! Collides a moving ellipsoid with a 3d world with gravity and returns the resulting new position of the ellipsoid.
|
//! Collides a moving ellipsoid with a 3d world with gravity and returns the resulting new position of the ellipsoid.
|
||||||
/** This can be used for moving a character in a 3d world: The
|
/** This can be used for moving a character in a 3d world: The
|
||||||
|
@ -161,6 +205,7 @@ namespace scene
|
||||||
virtual ISceneNode* getSceneNodeFromCameraBB(const ICameraSceneNode* camera,
|
virtual ISceneNode* getSceneNodeFromCameraBB(const ICameraSceneNode* camera,
|
||||||
s32 idBitMask=0, bool bNoDebugObjects = false) = 0;
|
s32 idBitMask=0, bool bNoDebugObjects = false) = 0;
|
||||||
|
|
||||||
|
|
||||||
//! Perform a ray/box and ray/triangle collision check on a hierarchy of scene nodes.
|
//! Perform a ray/box and ray/triangle collision check on a hierarchy of scene nodes.
|
||||||
/** This checks all scene nodes under the specified one, first by ray/bounding
|
/** This checks all scene nodes under the specified one, first by ray/bounding
|
||||||
box, and then by accurate ray/triangle collision, finding the nearest collision,
|
box, and then by accurate ray/triangle collision, finding the nearest collision,
|
||||||
|
@ -173,6 +218,31 @@ namespace scene
|
||||||
You do not have to build a meta triangle selector; the individual triangle selectors
|
You do not have to build a meta triangle selector; the individual triangle selectors
|
||||||
of each candidate scene node are used automatically.
|
of each candidate scene node are used automatically.
|
||||||
|
|
||||||
|
\param ray: Line with which collisions are tested.
|
||||||
|
\param outCollisionPoint: If a collision is detected, this will contain the
|
||||||
|
position of the nearest collision.
|
||||||
|
\param outTriangle: If a collision is detected, this will contain the triangle
|
||||||
|
with which the ray collided.
|
||||||
|
\param idBitMask: Only scene nodes with an id which matches at least one of the
|
||||||
|
bits contained in this mask will be tested. However, if this parameter is 0, then
|
||||||
|
all nodes are checked.
|
||||||
|
\param collisionRootNode: the scene node at which to begin checking. Only this
|
||||||
|
node and its children will be checked. If you want to check the entire scene,
|
||||||
|
pass 0, and the root scene node will be used (this is the default).
|
||||||
|
\param noDebugObjects: when true, debug objects are not considered viable targets.
|
||||||
|
Debug objects are scene nodes with IsDebugObject() = true.
|
||||||
|
\return Returns the scene node containing the hit triangle nearest to ray.start.
|
||||||
|
If no collision is detected, then 0 is returned. */
|
||||||
|
virtual ISceneNode* getSceneNodeAndCollisionPointFromRay(
|
||||||
|
SCollisionHit& hitResult,
|
||||||
|
const core::line3df& ray,
|
||||||
|
s32 idBitMask = 0,
|
||||||
|
ISceneNode * collisionRootNode = 0,
|
||||||
|
bool noDebugObjects = false) = 0;
|
||||||
|
|
||||||
|
//! Perform a ray/box and ray/triangle collision check on a hierarchy of scene nodes.
|
||||||
|
/** Works same as other getSceneNodeAndCollisionPointFromRay but returns less information.
|
||||||
|
(was written before the other getSceneNodeAndCollisionPointFromRay implementation).
|
||||||
\param ray: Line with which collisions are tested.
|
\param ray: Line with which collisions are tested.
|
||||||
\param outCollisionPoint: If a collision is detected, this will contain the
|
\param outCollisionPoint: If a collision is detected, this will contain the
|
||||||
position of the nearest collision.
|
position of the nearest collision.
|
||||||
|
@ -194,12 +264,21 @@ namespace scene
|
||||||
core::triangle3df& outTriangle,
|
core::triangle3df& outTriangle,
|
||||||
s32 idBitMask = 0,
|
s32 idBitMask = 0,
|
||||||
ISceneNode * collisionRootNode = 0,
|
ISceneNode * collisionRootNode = 0,
|
||||||
bool noDebugObjects = false) = 0;
|
bool noDebugObjects = false)
|
||||||
};
|
{
|
||||||
|
SCollisionHit hitResult;
|
||||||
|
ISceneNode* node = getSceneNodeAndCollisionPointFromRay(hitResult, ray, idBitMask, collisionRootNode, noDebugObjects);
|
||||||
|
if ( node )
|
||||||
|
{
|
||||||
|
outCollisionPoint = hitResult.Intersection;
|
||||||
|
outTriangle = hitResult.Triangle;
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace scene
|
} // end namespace scene
|
||||||
} // end namespace irr
|
} // end namespace irr
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -322,7 +322,7 @@ namespace scene
|
||||||
* files thanks to<br> the importer created by Jonas
|
* files thanks to<br> the importer created by Jonas
|
||||||
* Petersen.
|
* Petersen.
|
||||||
* Notes for<br> this version of the loader:<br>
|
* Notes for<br> this version of the loader:<br>
|
||||||
* - It does not recognise/support user data in the
|
* - It does not recognize/support user data in the
|
||||||
* *.lmts files.<br>
|
* *.lmts files.<br>
|
||||||
* - The TGAs generated by LMTools don't work in
|
* - The TGAs generated by LMTools don't work in
|
||||||
* Irrlicht for some reason (the textures are upside
|
* Irrlicht for some reason (the textures are upside
|
||||||
|
@ -1271,19 +1271,30 @@ namespace scene
|
||||||
s->drop();
|
s->drop();
|
||||||
\endcode
|
\endcode
|
||||||
\param mesh: Mesh of which the triangles are taken.
|
\param mesh: Mesh of which the triangles are taken.
|
||||||
\param node: Scene node of which visibility and transformation is used.
|
\param node: Scene node of which transformation is used.
|
||||||
|
\param separateMeshbuffers: When true it's possible to get information which meshbuffer
|
||||||
|
got hit in collision tests. But has a slight speed cost.
|
||||||
\return The selector, or null if not successful.
|
\return The selector, or null if not successful.
|
||||||
If you no longer need the selector, you should call ITriangleSelector::drop().
|
If you no longer need the selector, you should call ITriangleSelector::drop().
|
||||||
See IReferenceCounted::drop() for more information. */
|
See IReferenceCounted::drop() for more information. */
|
||||||
virtual ITriangleSelector* createTriangleSelector(IMesh* mesh, ISceneNode* node) = 0;
|
virtual ITriangleSelector* createTriangleSelector(IMesh* mesh, ISceneNode* node, bool separateMeshbuffers=false) = 0;
|
||||||
|
|
||||||
|
//! Creates a simple ITriangleSelector, based on a meshbuffer.
|
||||||
|
/**
|
||||||
|
This is a static selector which won't update when the mesh changes.
|
||||||
|
\param meshBuffer Triangles of that meshbuffer are used
|
||||||
|
\param materialIndex If you pass a material index that index can be returned by the triangle selector.
|
||||||
|
\para node: Scene node of which transformation is used.
|
||||||
|
*/
|
||||||
|
virtual ITriangleSelector* createTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node) = 0;
|
||||||
|
|
||||||
//! Creates a simple ITriangleSelector, based on an animated mesh scene node.
|
//! Creates a simple ITriangleSelector, based on an animated mesh scene node.
|
||||||
/** Details of the mesh associated with the node will be extracted internally.
|
/** Details of the mesh associated with the node will be extracted internally.
|
||||||
Call ITriangleSelector::update() to have the triangle selector updated based
|
|
||||||
on the current frame of the animated mesh scene node.
|
|
||||||
\param node The animated mesh scene node from which to build the selector
|
\param node The animated mesh scene node from which to build the selector
|
||||||
|
\param separateMeshbuffers: When true it's possible to get information which meshbuffer
|
||||||
|
got hit in collision tests. But has a slight speed cost.
|
||||||
*/
|
*/
|
||||||
virtual ITriangleSelector* createTriangleSelector(IAnimatedMeshSceneNode* node) = 0;
|
virtual ITriangleSelector* createTriangleSelector(IAnimatedMeshSceneNode* node, bool separateMeshbuffers=false) = 0;
|
||||||
|
|
||||||
|
|
||||||
//! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box.
|
//! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box.
|
||||||
|
@ -1323,6 +1334,33 @@ namespace scene
|
||||||
virtual ITriangleSelector* createOctreeTriangleSelector(IMesh* mesh,
|
virtual ITriangleSelector* createOctreeTriangleSelector(IMesh* mesh,
|
||||||
ISceneNode* node, s32 minimalPolysPerNode=32) = 0;
|
ISceneNode* node, s32 minimalPolysPerNode=32) = 0;
|
||||||
|
|
||||||
|
//! Creates a Triangle Selector for a single meshbuffer, optimized by an octree.
|
||||||
|
/** Triangle selectors
|
||||||
|
can be used for doing collision detection. This triangle selector is
|
||||||
|
optimized for huge amounts of triangle, it organizes them in an octree.
|
||||||
|
Please note that the created triangle selector is not automatically attached
|
||||||
|
to the scene node. You will have to call ISceneNode::setTriangleSelector()
|
||||||
|
for this. To create and attach a triangle selector is done like this:
|
||||||
|
\code
|
||||||
|
ITriangleSelector* s = sceneManager->createOctreeTriangleSelector(yourMesh,
|
||||||
|
yourSceneNode);
|
||||||
|
yourSceneNode->setTriangleSelector(s);
|
||||||
|
s->drop();
|
||||||
|
\endcode
|
||||||
|
For more information and examples on this, take a look at the collision
|
||||||
|
tutorial in the SDK.
|
||||||
|
\param meshBuffer: Meshbuffer of which the triangles are taken.
|
||||||
|
\param materialIndex: Setting this value allows the triangle selector to return the material index
|
||||||
|
\param node: Scene node of which visibility and transformation is used.
|
||||||
|
\param minimalPolysPerNode: Specifies the minimal polygons contained a octree node.
|
||||||
|
If a node gets less polys than this value, it will not be split into
|
||||||
|
smaller nodes.
|
||||||
|
\return The selector, or null if not successful.
|
||||||
|
If you no longer need the selector, you should call ITriangleSelector::drop().
|
||||||
|
See IReferenceCounted::drop() for more information. */
|
||||||
|
virtual ITriangleSelector* createOctreeTriangleSelector(IMeshBuffer* meshBuffer, irr::u32 materialIndex,
|
||||||
|
ISceneNode* node, s32 minimalPolysPerNode=32) = 0;
|
||||||
|
|
||||||
//! //! Creates a Triangle Selector, optimized by an octree.
|
//! //! Creates a Triangle Selector, optimized by an octree.
|
||||||
/** \deprecated Use createOctreeTriangleSelector instead. This method may be removed by Irrlicht 1.9. */
|
/** \deprecated Use createOctreeTriangleSelector instead. This method may be removed by Irrlicht 1.9. */
|
||||||
_IRR_DEPRECATED_ ITriangleSelector* createOctTreeTriangleSelector(IMesh* mesh,
|
_IRR_DEPRECATED_ ITriangleSelector* createOctTreeTriangleSelector(IMesh* mesh,
|
||||||
|
@ -1589,7 +1627,7 @@ namespace scene
|
||||||
using ISceneManager::saveScene().
|
using ISceneManager::saveScene().
|
||||||
\param file File where the scene is loaded from.
|
\param file File where the scene is loaded from.
|
||||||
\param userDataSerializer If you want to load user data
|
\param userDataSerializer If you want to load user data
|
||||||
possibily saved in that file for some scene nodes in the file,
|
saved in that file for some scene nodes in the file,
|
||||||
implement the ISceneUserDataSerializer interface and provide it
|
implement the ISceneUserDataSerializer interface and provide it
|
||||||
as parameter here. Otherwise, simply specify 0 as this
|
as parameter here. Otherwise, simply specify 0 as this
|
||||||
parameter.
|
parameter.
|
||||||
|
|
|
@ -9,6 +9,12 @@
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace gui
|
||||||
|
{
|
||||||
|
class IGUIFont;
|
||||||
|
}
|
||||||
|
|
||||||
namespace scene
|
namespace scene
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -25,8 +31,20 @@ public:
|
||||||
//! sets the text string
|
//! sets the text string
|
||||||
virtual void setText(const wchar_t* text) = 0;
|
virtual void setText(const wchar_t* text) = 0;
|
||||||
|
|
||||||
|
//! get the text string
|
||||||
|
virtual const wchar_t* getText() const = 0;
|
||||||
|
|
||||||
//! sets the color of the text
|
//! sets the color of the text
|
||||||
virtual void setTextColor(video::SColor color) = 0;
|
virtual void setTextColor(video::SColor color) = 0;
|
||||||
|
|
||||||
|
//! get the color of the text
|
||||||
|
virtual video::SColor getTextColor() const = 0;
|
||||||
|
|
||||||
|
//! set the font used to draw the text
|
||||||
|
virtual void setFont(gui::IGUIFont* font) = 0;
|
||||||
|
|
||||||
|
//! Get the font used to draw the text
|
||||||
|
virtual gui::IGUIFont* getFont() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace scene
|
} // end namespace scene
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "aabbox3d.h"
|
#include "aabbox3d.h"
|
||||||
#include "matrix4.h"
|
#include "matrix4.h"
|
||||||
#include "line3d.h"
|
#include "line3d.h"
|
||||||
|
#include "irrArray.h"
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
|
@ -17,6 +18,49 @@ namespace scene
|
||||||
{
|
{
|
||||||
|
|
||||||
class ISceneNode;
|
class ISceneNode;
|
||||||
|
class ITriangleSelector;
|
||||||
|
class IMeshBuffer;
|
||||||
|
|
||||||
|
//! Additional information about the triangle arrays returned by ITriangleSelector::getTriangles
|
||||||
|
/** ITriangleSelector are free to fill out this information fully, partly or ignore it.
|
||||||
|
Usually they will try to fill it when they can and set values to 0 otherwise.
|
||||||
|
*/
|
||||||
|
struct SCollisionTriangleRange
|
||||||
|
{
|
||||||
|
SCollisionTriangleRange()
|
||||||
|
: RangeStart(0), RangeSize(0)
|
||||||
|
, Selector(0), SceneNode(0)
|
||||||
|
, MeshBuffer(0), MaterialIndex(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! Check if this triangle index inside the range
|
||||||
|
/**
|
||||||
|
\param triangleIndex Index to an element inside the array of triangles returned by ITriangleSelector::getTriangles
|
||||||
|
*/
|
||||||
|
bool isIndexInRange(irr::u32 triangleIndex) const
|
||||||
|
{
|
||||||
|
return triangleIndex >= RangeStart && triangleIndex < RangeStart+RangeSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! First index in the array for which this struct is valid
|
||||||
|
irr::u32 RangeStart;
|
||||||
|
|
||||||
|
//! Number of elements in the array for which this struct is valid (starting with RangeStart)
|
||||||
|
irr::u32 RangeSize;
|
||||||
|
|
||||||
|
//! Real selector which contained those triangles (useful when working with MetaTriangleSelector)
|
||||||
|
ITriangleSelector* Selector;
|
||||||
|
|
||||||
|
//! SceneNode from which the triangles are from
|
||||||
|
ISceneNode* SceneNode;
|
||||||
|
|
||||||
|
//! Meshbuffer from which the triangles are from
|
||||||
|
//! Is 0 when the ITriangleSelector doesn't support meshbuffer selection
|
||||||
|
const IMeshBuffer* MeshBuffer;
|
||||||
|
|
||||||
|
//! Index of selected material in the SceneNode. Usually only valid when MeshBuffer is also set, otherwise always 0
|
||||||
|
irr::u32 MaterialIndex;
|
||||||
|
};
|
||||||
|
|
||||||
//! Interface to return triangles with specific properties.
|
//! Interface to return triangles with specific properties.
|
||||||
/** Every ISceneNode may have a triangle selector, available with
|
/** Every ISceneNode may have a triangle selector, available with
|
||||||
|
@ -45,10 +89,18 @@ public:
|
||||||
into the array.
|
into the array.
|
||||||
\param transform Pointer to matrix for transforming the triangles
|
\param transform Pointer to matrix for transforming the triangles
|
||||||
before they are returned. Useful for example to scale all triangles
|
before they are returned. Useful for example to scale all triangles
|
||||||
down into an ellipsoid space. If this pointer is null, no
|
down into an ellipsoid space.
|
||||||
transformation will be done. */
|
\param useNodeTransform When the selector has a node then transform the
|
||||||
|
triangles by that node's transformation matrix.
|
||||||
|
\param outTriangleInfo When a pointer to an array is passed then that
|
||||||
|
array is filled with additional information about the returned triangles.
|
||||||
|
One element of SCollisionTriangleRange added for each range of triangles which
|
||||||
|
has distinguishable information. For example one range per meshbuffer.
|
||||||
|
*/
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::matrix4* transform=0) const = 0;
|
s32& outTriangleCount, const core::matrix4* transform=0,
|
||||||
|
bool useNodeTransform=true,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo=0) const = 0;
|
||||||
|
|
||||||
//! Gets the triangles for one associated node which may lie within a specific bounding box.
|
//! Gets the triangles for one associated node which may lie within a specific bounding box.
|
||||||
/**
|
/**
|
||||||
|
@ -68,11 +120,17 @@ public:
|
||||||
will be written into the array.
|
will be written into the array.
|
||||||
\param transform Pointer to matrix for transforming the triangles
|
\param transform Pointer to matrix for transforming the triangles
|
||||||
before they are returned. Useful for example to scale all triangles
|
before they are returned. Useful for example to scale all triangles
|
||||||
down into an ellipsoid space. If this pointer is null, no
|
down into an ellipsoid space.
|
||||||
transformation will be done. */
|
\param useNodeTransform When the selector has a node then transform the
|
||||||
|
triangles by that node's transformation matrix.
|
||||||
|
\param outTriangleInfo When a pointer to an array is passed then that
|
||||||
|
array is filled with additional information about the returned triangles.
|
||||||
|
One element of SCollisionTriangleRange added for each range of triangles which
|
||||||
|
has distinguishable information. For example one range per meshbuffer. */
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::aabbox3d<f32>& box,
|
s32& outTriangleCount, const core::aabbox3d<f32>& box,
|
||||||
const core::matrix4* transform=0) const = 0;
|
const core::matrix4* transform=0, bool useNodeTransform=true,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo=0) const = 0;
|
||||||
|
|
||||||
//! Gets the triangles for one associated node which have or may have contact with a 3d line.
|
//! Gets the triangles for one associated node which have or may have contact with a 3d line.
|
||||||
/**
|
/**
|
||||||
|
@ -92,22 +150,17 @@ public:
|
||||||
will be written into the array.
|
will be written into the array.
|
||||||
\param transform Pointer to matrix for transforming the triangles
|
\param transform Pointer to matrix for transforming the triangles
|
||||||
before they are returned. Useful for example to scale all triangles
|
before they are returned. Useful for example to scale all triangles
|
||||||
down into an ellipsoid space. If this pointer is null, no
|
down into an ellipsoid space.
|
||||||
transformation will be done. */
|
\param useNodeTransform When the selector has a node then transform the
|
||||||
|
triangles by that node's transformation matrix.
|
||||||
|
\param outTriangleInfo When a pointer to an array is passed then that
|
||||||
|
array is filled with additional information about the returned triangles.
|
||||||
|
One element of SCollisionTriangleRange added for each range of triangles which
|
||||||
|
has distinguishable information. For example one range per meshbuffer. */
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::line3d<f32>& line,
|
s32& outTriangleCount, const core::line3d<f32>& line,
|
||||||
const core::matrix4* transform=0) const = 0;
|
const core::matrix4* transform=0, bool useNodeTransform=true,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo=0) const = 0;
|
||||||
//! Get scene node associated with a given triangle.
|
|
||||||
/**
|
|
||||||
This allows to find which scene node (potentially of several) is
|
|
||||||
associated with a specific triangle.
|
|
||||||
|
|
||||||
\param triangleIndex: the index of the triangle for which you want to find
|
|
||||||
the associated scene node.
|
|
||||||
\return The scene node associated with that triangle.
|
|
||||||
*/
|
|
||||||
virtual ISceneNode* getSceneNodeForTriangle(u32 triangleIndex) const = 0;
|
|
||||||
|
|
||||||
//! Get number of TriangleSelectors that are part of this one
|
//! Get number of TriangleSelectors that are part of this one
|
||||||
/** Only useful for MetaTriangleSelector, others return 1
|
/** Only useful for MetaTriangleSelector, others return 1
|
||||||
|
@ -123,6 +176,17 @@ public:
|
||||||
/** Only useful for MetaTriangleSelector, others return 'this' or 0
|
/** Only useful for MetaTriangleSelector, others return 'this' or 0
|
||||||
*/
|
*/
|
||||||
virtual const ITriangleSelector* getSelector(u32 index) const = 0;
|
virtual const ITriangleSelector* getSelector(u32 index) const = 0;
|
||||||
|
|
||||||
|
//! Get scene node associated with a given triangle.
|
||||||
|
/** With CMetaTriangleSelector-selectors it's possible to find out a node
|
||||||
|
belonging to a certain triangle index.
|
||||||
|
NOTE: triangleIndex has nothing to do with the order of triangles returned by getTriangles functions!
|
||||||
|
So you can _not_ use this function to find out anything about to which node returned triangles belong.
|
||||||
|
Use STriangleCollisionInfo struct for that.
|
||||||
|
\param triangleIndex: the index of the triangle for which you want to find.
|
||||||
|
\return The scene node associated with that triangle.
|
||||||
|
*/
|
||||||
|
virtual ISceneNode* getSceneNodeForTriangle(u32 triangleIndex) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace scene
|
} // end namespace scene
|
||||||
|
|
|
@ -177,9 +177,10 @@ namespace irr
|
||||||
KEY_PLAY = 0xFA, // Play key
|
KEY_PLAY = 0xFA, // Play key
|
||||||
KEY_ZOOM = 0xFB, // Zoom key
|
KEY_ZOOM = 0xFB, // Zoom key
|
||||||
KEY_PA1 = 0xFD, // PA1 key
|
KEY_PA1 = 0xFD, // PA1 key
|
||||||
KEY_OEM_CLEAR = 0xFE, // Clear key
|
KEY_OEM_CLEAR = 0xFE, // Clear key
|
||||||
|
KEY_NONE = 0xFF, // usually no key mapping, but some laptops use it for fn key
|
||||||
|
|
||||||
KEY_KEY_CODES_COUNT = 0xFF // this is not a key, but the amount of keycodes there are.
|
KEY_KEY_CODES_COUNT = 0x100 // this is not a key, but the amount of keycodes there are.
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace irr
|
} // end namespace irr
|
||||||
|
|
|
@ -165,8 +165,7 @@ namespace video
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
different |= (TextureMatrix != b.TextureMatrix) &&
|
different |= (TextureMatrix != b.TextureMatrix) &&
|
||||||
TextureMatrix && b.TextureMatrix &&
|
(!TextureMatrix || !b.TextureMatrix || (*TextureMatrix != *(b.TextureMatrix)));
|
||||||
(*TextureMatrix != *(b.TextureMatrix));
|
|
||||||
return different;
|
return different;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,13 +83,26 @@ namespace scene
|
||||||
//! recalculates the bounding box
|
//! recalculates the bounding box
|
||||||
void recalculateBoundingBox()
|
void recalculateBoundingBox()
|
||||||
{
|
{
|
||||||
if (MeshBuffers.size())
|
bool hasMeshBufferBBox = false;
|
||||||
|
for (u32 i=0; i<MeshBuffers.size(); ++i)
|
||||||
{
|
{
|
||||||
BoundingBox = MeshBuffers[0]->getBoundingBox();
|
const core::aabbox3df& bb = MeshBuffers[i]->getBoundingBox();
|
||||||
for (u32 i=1; i<MeshBuffers.size(); ++i)
|
if ( !bb.isEmpty() )
|
||||||
BoundingBox.addInternalBox(MeshBuffers[i]->getBoundingBox());
|
{
|
||||||
|
if ( !hasMeshBufferBBox )
|
||||||
|
{
|
||||||
|
hasMeshBufferBBox = true;
|
||||||
|
BoundingBox = bb;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BoundingBox.addInternalBox(bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if ( !hasMeshBufferBBox )
|
||||||
BoundingBox.reset(0.0f, 0.0f, 0.0f);
|
BoundingBox.reset(0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,8 @@ namespace core
|
||||||
// the float-to-string code used there has to be rewritten first.
|
// the float-to-string code used there has to be rewritten first.
|
||||||
IRRLICHT_API extern irr::core::stringc LOCALE_DECIMAL_POINTS;
|
IRRLICHT_API extern irr::core::stringc LOCALE_DECIMAL_POINTS;
|
||||||
|
|
||||||
// we write [17] here instead of [] to work around a swig bug
|
#define IRR_ATOF_TABLE_SIZE 17
|
||||||
|
// we write [IRR_ATOF_TABLE_SIZE] here instead of [] to work around a swig bug
|
||||||
const float fast_atof_table[17] = {
|
const float fast_atof_table[17] = {
|
||||||
0.f,
|
0.f,
|
||||||
0.1f,
|
0.1f,
|
||||||
|
@ -323,8 +324,16 @@ inline const char* fast_atof_move(const char* in, f32& result)
|
||||||
if ( LOCALE_DECIMAL_POINTS.findFirst(*in) >= 0 )
|
if ( LOCALE_DECIMAL_POINTS.findFirst(*in) >= 0 )
|
||||||
{
|
{
|
||||||
const char* afterDecimal = ++in;
|
const char* afterDecimal = ++in;
|
||||||
const f32 decimal = strtof10(in, &afterDecimal);
|
f32 decimal = strtof10(in, &afterDecimal);
|
||||||
value += decimal * fast_atof_table[afterDecimal - in];
|
size_t numDecimals = afterDecimal - in;
|
||||||
|
if (numDecimals < IRR_ATOF_TABLE_SIZE)
|
||||||
|
{
|
||||||
|
value += decimal * fast_atof_table[numDecimals];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value += decimal * (f32)pow(10.f, -(float)numDecimals);
|
||||||
|
}
|
||||||
in = afterDecimal;
|
in = afterDecimal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,7 +343,8 @@ inline const char* fast_atof_move(const char* in, f32& result)
|
||||||
// Assume that the exponent is a whole number.
|
// Assume that the exponent is a whole number.
|
||||||
// strtol10() will deal with both + and - signs,
|
// strtol10() will deal with both + and - signs,
|
||||||
// but calculate as f32 to prevent overflow at FLT_MAX
|
// but calculate as f32 to prevent overflow at FLT_MAX
|
||||||
value *= powf(10.f, (f32)strtol10(in, &in));
|
// Using pow with float cast instead of powf as otherwise accuracy decreases.
|
||||||
|
value *= (f32)pow(10.f, (f32)strtol10(in, &in));
|
||||||
}
|
}
|
||||||
|
|
||||||
result = negative?-value:value;
|
result = negative?-value:value;
|
||||||
|
|
|
@ -43,6 +43,7 @@ namespace core
|
||||||
//! Rounding error constant often used when comparing f32 values.
|
//! Rounding error constant often used when comparing f32 values.
|
||||||
|
|
||||||
const s32 ROUNDING_ERROR_S32 = 0;
|
const s32 ROUNDING_ERROR_S32 = 0;
|
||||||
|
|
||||||
#ifdef __IRR_HAS_S64
|
#ifdef __IRR_HAS_S64
|
||||||
const s64 ROUNDING_ERROR_S64 = 0;
|
const s64 ROUNDING_ERROR_S64 = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -181,16 +182,85 @@ namespace core
|
||||||
b = c;
|
b = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T roundingError();
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline f32 roundingError()
|
||||||
|
{
|
||||||
|
return ROUNDING_ERROR_f32;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline f64 roundingError()
|
||||||
|
{
|
||||||
|
return ROUNDING_ERROR_f64;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline s32 roundingError()
|
||||||
|
{
|
||||||
|
return ROUNDING_ERROR_S32;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline u32 roundingError()
|
||||||
|
{
|
||||||
|
return ROUNDING_ERROR_S32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __IRR_HAS_S64
|
||||||
|
template <>
|
||||||
|
inline s64 roundingError()
|
||||||
|
{
|
||||||
|
return ROUNDING_ERROR_S64;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline u64 roundingError()
|
||||||
|
{
|
||||||
|
return ROUNDING_ERROR_S64;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T relativeErrorFactor()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline f32 relativeErrorFactor()
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline f64 relativeErrorFactor()
|
||||||
|
{
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
//! returns if a equals b, taking possible rounding errors into account
|
//! returns if a equals b, taking possible rounding errors into account
|
||||||
inline bool equals(const f64 a, const f64 b, const f64 tolerance = ROUNDING_ERROR_f64)
|
template <class T>
|
||||||
|
inline T equals(const T a, const T b, const T tolerance = roundingError<T>())
|
||||||
{
|
{
|
||||||
return (a + tolerance >= b) && (a - tolerance <= b);
|
return (a + tolerance >= b) && (a - tolerance <= b);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! returns if a equals b, taking possible rounding errors into account
|
|
||||||
inline bool equals(const f32 a, const f32 b, const f32 tolerance = ROUNDING_ERROR_f32)
|
//! returns if a equals b, taking relative error in form of factor
|
||||||
|
//! this particular function does not involve any division.
|
||||||
|
template <class T>
|
||||||
|
inline bool equalsRelative( const T a, const T b, const T factor = relativeErrorFactor<T>())
|
||||||
{
|
{
|
||||||
return (a + tolerance >= b) && (a - tolerance <= b);
|
//https://eagergames.wordpress.com/2017/04/01/fast-parallel-lines-and-vectors-test/
|
||||||
|
|
||||||
|
const T maxi = max_( a, b);
|
||||||
|
const T mini = min_( a, b);
|
||||||
|
const T maxMagnitude = max_( maxi, -mini);
|
||||||
|
|
||||||
|
return (maxMagnitude*factor + maxi) == (maxMagnitude*factor + mini); // MAD Wise
|
||||||
}
|
}
|
||||||
|
|
||||||
union FloatIntUnion32
|
union FloatIntUnion32
|
||||||
|
@ -233,39 +303,6 @@ namespace core
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
//! returns if a equals b, not using any rounding tolerance
|
|
||||||
inline bool equals(const s32 a, const s32 b)
|
|
||||||
{
|
|
||||||
return (a == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! returns if a equals b, not using any rounding tolerance
|
|
||||||
inline bool equals(const u32 a, const u32 b)
|
|
||||||
{
|
|
||||||
return (a == b);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//! returns if a equals b, taking an explicit rounding tolerance into account
|
|
||||||
inline bool equals(const s32 a, const s32 b, const s32 tolerance = ROUNDING_ERROR_S32)
|
|
||||||
{
|
|
||||||
return (a + tolerance >= b) && (a - tolerance <= b);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! returns if a equals b, taking an explicit rounding tolerance into account
|
|
||||||
inline bool equals(const u32 a, const u32 b, const s32 tolerance = ROUNDING_ERROR_S32)
|
|
||||||
{
|
|
||||||
return (a + tolerance >= b) && (a - tolerance <= b);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __IRR_HAS_S64
|
|
||||||
//! returns if a equals b, taking an explicit rounding tolerance into account
|
|
||||||
inline bool equals(const s64 a, const s64 b, const s64 tolerance = ROUNDING_ERROR_S64)
|
|
||||||
{
|
|
||||||
return (a + tolerance >= b) && (a - tolerance <= b);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//! returns if a equals zero, taking rounding errors into account
|
//! returns if a equals zero, taking rounding errors into account
|
||||||
inline bool iszero(const f64 a, const f64 tolerance = ROUNDING_ERROR_f64)
|
inline bool iszero(const f64 a, const f64 tolerance = ROUNDING_ERROR_f64)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1306,14 +1306,14 @@ public:
|
||||||
return used > 1 ? array[used-2] : 0;
|
return used > 1 ? array[used-2] : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! split string into parts.
|
//! Split string into parts (tokens).
|
||||||
/** This method will split a string at certain delimiter characters
|
/** This method will split a string at certain delimiter characters
|
||||||
into the container passed in as reference. The type of the container
|
into the container passed in as reference. The type of the container
|
||||||
has to be given as template parameter. It must provide a push_back and
|
has to be given as template parameter. It must provide a push_back and
|
||||||
a size method.
|
a size method.
|
||||||
\param ret The result container
|
\param ret The result container. Tokens are added, the container is not cleared.
|
||||||
\param c C-style string of delimiter characters
|
\param delimiter C-style string of delimiter characters
|
||||||
\param count Number of delimiter characters
|
\param countDelimiters Number of delimiter characters
|
||||||
\param ignoreEmptyTokens Flag to avoid empty substrings in the result
|
\param ignoreEmptyTokens Flag to avoid empty substrings in the result
|
||||||
container. If two delimiters occur without a character in between, an
|
container. If two delimiters occur without a character in between, an
|
||||||
empty substring would be placed in the result. If this flag is set,
|
empty substring would be placed in the result. If this flag is set,
|
||||||
|
@ -1325,33 +1325,39 @@ public:
|
||||||
\return The number of resulting substrings
|
\return The number of resulting substrings
|
||||||
*/
|
*/
|
||||||
template<class container>
|
template<class container>
|
||||||
u32 split(container& ret, const T* const c, u32 count=1, bool ignoreEmptyTokens=true, bool keepSeparators=false) const
|
u32 split(container& ret, const T* const delimiter, u32 countDelimiters=1, bool ignoreEmptyTokens=true, bool keepSeparators=false) const
|
||||||
{
|
{
|
||||||
if (!c)
|
if (!delimiter)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const u32 oldSize=ret.size();
|
const u32 oldSize=ret.size();
|
||||||
u32 lastpos = 0;
|
|
||||||
bool lastWasSeparator = false;
|
u32 tokenStartIdx = 0;
|
||||||
for (u32 i=0; i<used; ++i)
|
for (u32 i=0; i<used; ++i)
|
||||||
{
|
{
|
||||||
bool foundSeparator = false;
|
for (u32 j=0; j<countDelimiters; ++j)
|
||||||
for (u32 j=0; j<count; ++j)
|
|
||||||
{
|
{
|
||||||
if (array[i] == c[j])
|
if (array[i] == delimiter[j])
|
||||||
{
|
{
|
||||||
if ((!ignoreEmptyTokens || i - lastpos != 0) &&
|
if ( keepSeparators )
|
||||||
!lastWasSeparator)
|
{
|
||||||
ret.push_back(string<T,TAlloc>(&array[lastpos], i - lastpos));
|
ret.push_back(string<T,TAlloc>(&array[tokenStartIdx], i+1 - tokenStartIdx));
|
||||||
foundSeparator = true;
|
}
|
||||||
lastpos = (keepSeparators ? i : i + 1);
|
else
|
||||||
|
{
|
||||||
|
if (i - tokenStartIdx > 0)
|
||||||
|
ret.push_back(string<T,TAlloc>(&array[tokenStartIdx], i - tokenStartIdx));
|
||||||
|
else if ( !ignoreEmptyTokens )
|
||||||
|
ret.push_back(string<T,TAlloc>());
|
||||||
|
}
|
||||||
|
tokenStartIdx = i+1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastWasSeparator = foundSeparator;
|
|
||||||
}
|
}
|
||||||
if ((used - 1) > lastpos)
|
if ((used - 1) > tokenStartIdx)
|
||||||
ret.push_back(string<T,TAlloc>(&array[lastpos], (used - 1) - lastpos));
|
ret.push_back(string<T,TAlloc>(&array[tokenStartIdx], (used - 1) - tokenStartIdx));
|
||||||
|
|
||||||
return ret.size()-oldSize;
|
return ret.size()-oldSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -316,27 +316,31 @@ namespace io
|
||||||
|
|
||||||
//! Returns the value of an attribute as integer.
|
//! Returns the value of an attribute as integer.
|
||||||
/** \param name Name of the attribute.
|
/** \param name Name of the attribute.
|
||||||
\return Value of the attribute as integer, and 0 if an attribute with this name does not exist or
|
\param defaultNotFound Value returned when name does not exist
|
||||||
the value could not be interpreted as integer. */
|
\return Value of the attribute as integer or value of defaultNotFound
|
||||||
virtual int getAttributeValueAsInt(const char_type* name) const = 0;
|
when name was not found or 0 when value could not be interpreted as integer */
|
||||||
|
virtual int getAttributeValueAsInt(const char_type* name, int defaultNotFound=0) const = 0;
|
||||||
|
|
||||||
//! Returns the value of an attribute as integer.
|
//! Returns the value of an attribute as integer.
|
||||||
/** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1.
|
/** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1.
|
||||||
\return Value of the attribute as integer, and 0 if an attribute with this index does not exist or
|
\param defaultNotFound Value returned when index does not exist.
|
||||||
the value could not be interpreted as integer. */
|
\return Value of the attribute as integer or value of defaultNotFound parameter for invalid index
|
||||||
virtual int getAttributeValueAsInt(int idx) const = 0;
|
or 0 when value could not be interpreted as integer */
|
||||||
|
virtual int getAttributeValueAsInt(int idx, int defaultNotFound=0) const = 0;
|
||||||
|
|
||||||
//! Returns the value of an attribute as float.
|
//! Returns the value of an attribute as float.
|
||||||
/** \param name: Name of the attribute.
|
/** \param name: Name of the attribute.
|
||||||
\return Value of the attribute as float, and 0 if an attribute with this name does not exist or
|
\param defaultNotFound Value returned when name does not exist.
|
||||||
the value could not be interpreted as float. */
|
\return Value of the attribute as float or value of defaultNotFound parameter on failure
|
||||||
virtual float getAttributeValueAsFloat(const char_type* name) const = 0;
|
or 0 when value could not be interpreted as float. */
|
||||||
|
virtual float getAttributeValueAsFloat(const char_type* name, float defaultNotFound=0.f) const = 0;
|
||||||
|
|
||||||
//! Returns the value of an attribute as float.
|
//! Returns the value of an attribute as float.
|
||||||
/** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1.
|
/** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1.
|
||||||
\return Value of the attribute as float, and 0 if an attribute with this index does not exist or
|
\param defaultNotFound Value returned when index does not exist.
|
||||||
the value could not be interpreted as float. */
|
\return Value of the attribute as float or value of defaultNotFound parameter on failure
|
||||||
virtual float getAttributeValueAsFloat(int idx) const = 0;
|
or 0 when value could not be interpreted as float. */
|
||||||
|
virtual float getAttributeValueAsFloat(int idx, float defaultNotFound=0.f) const = 0;
|
||||||
|
|
||||||
//! Returns the name of the current node.
|
//! Returns the name of the current node.
|
||||||
/** Only valid, if the node type is EXN_ELEMENT.
|
/** Only valid, if the node type is EXN_ELEMENT.
|
||||||
|
|
|
@ -65,7 +65,85 @@ class line2d
|
||||||
|
|
||||||
//! Get the vector of the line.
|
//! Get the vector of the line.
|
||||||
/** \return The vector of the line. */
|
/** \return The vector of the line. */
|
||||||
vector2d<T> getVector() const { return vector2d<T>(end.X - start.X, end.Y - start.Y); }
|
vector2d<T> getVector() const { return vector2d<T>( end.X - start.X, end.Y - start.Y); }
|
||||||
|
|
||||||
|
/*! Check if this segment intersects another segment,
|
||||||
|
or if segments are coincindent (colinear). */
|
||||||
|
bool intersectAsSegments( const line2d<T>& other) const
|
||||||
|
{
|
||||||
|
// Taken from:
|
||||||
|
// http://www.geeksforgeeks.org/check-if-two-given-line-segments-intersect/
|
||||||
|
|
||||||
|
// Find the four orientations needed for general and
|
||||||
|
// special cases
|
||||||
|
s32 o1 = start.checkOrientation( end, other.start);
|
||||||
|
s32 o2 = start.checkOrientation( end, other.end);
|
||||||
|
s32 o3 = other.start.checkOrientation( other.end, start);
|
||||||
|
s32 o4 = other.start.checkOrientation( other.end, end);
|
||||||
|
|
||||||
|
// General case
|
||||||
|
if (o1 != o2 && o3 != o4)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Special Cases to check if segments are coolinear
|
||||||
|
if (o1 == 0 && other.start.isBetweenPoints( start, end)) return true;
|
||||||
|
if (o2 == 0 && other.end.isBetweenPoints( start, end)) return true;
|
||||||
|
if (o3 == 0 && start.isBetweenPoints( other.start, other.end)) return true;
|
||||||
|
if (o4 == 0 && end.isBetweenPoints( other.start, other.end)) return true;
|
||||||
|
|
||||||
|
return false; // Doesn't fall in any of the above cases
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Check if 2 segments are incident (intersects in exactly 1 point).*/
|
||||||
|
bool incidentSegments( const line2d<T>& other) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
start.checkOrientation( end, other.start) != start.checkOrientation( end, other.end)
|
||||||
|
&& other.start.checkOrientation( other.end, start) != other.start.checkOrientation( other.end, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Check if 2 lines/segments are parallel or nearly parallel.*/
|
||||||
|
bool nearlyParallel( const line2d<T>& line, const T factor = relativeErrorFactor<T>()) const
|
||||||
|
{
|
||||||
|
const vector2d<T> a = getVector();
|
||||||
|
const vector2d<T> b = line.getVector();
|
||||||
|
|
||||||
|
return a.nearlyParallel( b, factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! returns a intersection point of 2 lines (if lines are not parallel). Behaviour
|
||||||
|
undefined if lines are parallel or coincident.*/
|
||||||
|
vector2d<T> fastLinesIntersection( const line2d<T>& l) const
|
||||||
|
{
|
||||||
|
const f32 commonDenominator = (f32)((l.end.Y - l.start.Y)*(end.X - start.X) -
|
||||||
|
(l.end.X - l.start.X)*(end.Y - start.Y));
|
||||||
|
|
||||||
|
const f32 numeratorA = (f32)((l.end.X - l.start.X)*(start.Y - l.start.Y) -
|
||||||
|
(l.end.Y - l.start.Y)*(start.X - l.start.X));
|
||||||
|
|
||||||
|
const f32 numeratorB = (f32)((end.X - start.X)*(start.Y - l.start.Y) -
|
||||||
|
(end.Y - start.Y)*(start.X - l.start.X));
|
||||||
|
|
||||||
|
const f32 uA = numeratorA / commonDenominator;
|
||||||
|
const f32 uB = numeratorB / commonDenominator;
|
||||||
|
|
||||||
|
// Calculate the intersection point.
|
||||||
|
return vector2d<T> (
|
||||||
|
(T)(start.X + uA * (end.X - start.X)),
|
||||||
|
(T)(start.Y + uA * (end.Y - start.Y))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Check if this line intersect a segment. The eventual intersection point is returned in "out".*/
|
||||||
|
bool lineIntersectSegment( const line2d<T>& segment, vector2d<T> & out) const
|
||||||
|
{
|
||||||
|
if (nearlyParallel( segment))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
out = fastLinesIntersection( segment);
|
||||||
|
|
||||||
|
return out.isBetweenPoints( segment.start, segment.end);
|
||||||
|
}
|
||||||
|
|
||||||
//! Tests if this line intersects with another line.
|
//! Tests if this line intersects with another line.
|
||||||
/** \param l: Other line to test intersection with.
|
/** \param l: Other line to test intersection with.
|
||||||
|
@ -209,7 +287,7 @@ class line2d
|
||||||
/** Assumes that the point is already somewhere on the line. */
|
/** Assumes that the point is already somewhere on the line. */
|
||||||
bool isPointBetweenStartAndEnd(const vector2d<T>& point) const
|
bool isPointBetweenStartAndEnd(const vector2d<T>& point) const
|
||||||
{
|
{
|
||||||
return point.isBetweenPoints(start, end);
|
return point.isBetweenPoints(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get the closest point on this line to a point
|
//! Get the closest point on this line to a point
|
||||||
|
|
|
@ -221,18 +221,25 @@ namespace core
|
||||||
void rotateVect(T *out,const core::vector3df &in) const;
|
void rotateVect(T *out,const core::vector3df &in) const;
|
||||||
|
|
||||||
//! Transforms the vector by this matrix
|
//! Transforms the vector by this matrix
|
||||||
|
/** This operation is performed as if the vector was 4d with the 4th component =1 */
|
||||||
void transformVect( vector3df& vect) const;
|
void transformVect( vector3df& vect) const;
|
||||||
|
|
||||||
//! Transforms input vector by this matrix and stores result in output vector
|
//! Transforms input vector by this matrix and stores result in output vector
|
||||||
|
/** This operation is performed as if the vector was 4d with the 4th component =1 */
|
||||||
void transformVect( vector3df& out, const vector3df& in ) const;
|
void transformVect( vector3df& out, const vector3df& in ) const;
|
||||||
|
|
||||||
//! An alternate transform vector method, writing into an array of 4 floats
|
//! An alternate transform vector method, writing into an array of 4 floats
|
||||||
|
/** This operation is performed as if the vector was 4d with the 4th component =1.
|
||||||
|
NOTE: out[3] will be written to (4th vector component)*/
|
||||||
void transformVect(T *out,const core::vector3df &in) const;
|
void transformVect(T *out,const core::vector3df &in) const;
|
||||||
|
|
||||||
//! An alternate transform vector method, reading from and writing to an array of 3 floats
|
//! An alternate transform vector method, reading from and writing to an array of 3 floats
|
||||||
|
/** This operation is performed as if the vector was 4d with the 4th component =1
|
||||||
|
NOTE: out[3] will be written to (4th vector component)*/
|
||||||
void transformVec3(T *out, const T * in) const;
|
void transformVec3(T *out, const T * in) const;
|
||||||
|
|
||||||
//! Translate a vector by the translation part of this matrix.
|
//! Translate a vector by the translation part of this matrix.
|
||||||
|
/** This operation is performed as if the vector was 4d with the 4th component =1 */
|
||||||
void translateVect( vector3df& vect ) const;
|
void translateVect( vector3df& vect ) const;
|
||||||
|
|
||||||
//! Transforms a plane by this matrix
|
//! Transforms a plane by this matrix
|
||||||
|
@ -247,7 +254,7 @@ namespace core
|
||||||
void transformBox(core::aabbox3d<f32>& box) const;
|
void transformBox(core::aabbox3d<f32>& box) const;
|
||||||
|
|
||||||
//! Transforms a axis aligned bounding box
|
//! Transforms a axis aligned bounding box
|
||||||
/** The result box of this operation should by accurate, but this operation
|
/** The result box of this operation should be accurate, but this operation
|
||||||
is slower than transformBox(). */
|
is slower than transformBox(). */
|
||||||
void transformBoxEx(core::aabbox3d<f32>& box) const;
|
void transformBoxEx(core::aabbox3d<f32>& box) const;
|
||||||
|
|
||||||
|
@ -2233,6 +2240,8 @@ namespace core
|
||||||
{
|
{
|
||||||
#if defined ( USE_MATRIX_TEST )
|
#if defined ( USE_MATRIX_TEST )
|
||||||
definitelyIdentityMatrix = isDefinitelyIdentityMatrix;
|
definitelyIdentityMatrix = isDefinitelyIdentityMatrix;
|
||||||
|
#else
|
||||||
|
(void)isDefinitelyIdentityMatrix; // prevent compiler warning
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,8 @@ class quaternion
|
||||||
//! Creates a matrix from this quaternion
|
//! Creates a matrix from this quaternion
|
||||||
matrix4 getMatrix() const;
|
matrix4 getMatrix() const;
|
||||||
#endif
|
#endif
|
||||||
|
//! Faster method to create a rotation matrix, you should normalize the quaternion before!
|
||||||
|
void getMatrixFast(matrix4 &dest) const;
|
||||||
|
|
||||||
//! Creates a matrix from this quaternion
|
//! Creates a matrix from this quaternion
|
||||||
void getMatrix( matrix4 &dest, const core::vector3df &translation=core::vector3df() ) const;
|
void getMatrix( matrix4 &dest, const core::vector3df &translation=core::vector3df() ) const;
|
||||||
|
@ -349,12 +351,51 @@ inline matrix4 quaternion::getMatrix() const
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//! Faster method to create a rotation matrix, you should normalize the quaternion before!
|
||||||
|
inline void quaternion::getMatrixFast( matrix4 &dest) const
|
||||||
|
{
|
||||||
|
// TODO:
|
||||||
|
// gpu quaternion skinning => fast Bones transform chain O_O YEAH!
|
||||||
|
// http://www.mrelusive.com/publications/papers/SIMD-From-Quaternion-to-Matrix-and-Back.pdf
|
||||||
|
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
|
||||||
|
dest[1] = 2.0f*X*Y + 2.0f*Z*W;
|
||||||
|
dest[2] = 2.0f*X*Z - 2.0f*Y*W;
|
||||||
|
dest[3] = 0.0f;
|
||||||
|
|
||||||
|
dest[4] = 2.0f*X*Y - 2.0f*Z*W;
|
||||||
|
dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
|
||||||
|
dest[6] = 2.0f*Z*Y + 2.0f*X*W;
|
||||||
|
dest[7] = 0.0f;
|
||||||
|
|
||||||
|
dest[8] = 2.0f*X*Z + 2.0f*Y*W;
|
||||||
|
dest[9] = 2.0f*Z*Y - 2.0f*X*W;
|
||||||
|
dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
|
||||||
|
dest[11] = 0.0f;
|
||||||
|
|
||||||
|
dest[12] = 0.f;
|
||||||
|
dest[13] = 0.f;
|
||||||
|
dest[14] = 0.f;
|
||||||
|
dest[15] = 1.f;
|
||||||
|
|
||||||
|
dest.setDefinitelyIdentityMatrix(false);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Creates a matrix from this quaternion
|
Creates a matrix from this quaternion
|
||||||
*/
|
*/
|
||||||
inline void quaternion::getMatrix(matrix4 &dest,
|
inline void quaternion::getMatrix(matrix4 &dest,
|
||||||
const core::vector3df ¢er) const
|
const core::vector3df ¢er) const
|
||||||
{
|
{
|
||||||
|
// ok creating a copy may be slower, but at least avoid internal
|
||||||
|
// state chance (also because otherwise we cannot keep this method "const").
|
||||||
|
|
||||||
|
quaternion q( *this);
|
||||||
|
q.normalize();
|
||||||
|
f32 X = q.X;
|
||||||
|
f32 Y = q.Y;
|
||||||
|
f32 Z = q.Z;
|
||||||
|
f32 W = q.W;
|
||||||
|
|
||||||
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
|
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
|
||||||
dest[1] = 2.0f*X*Y + 2.0f*Z*W;
|
dest[1] = 2.0f*X*Y + 2.0f*Z*W;
|
||||||
dest[2] = 2.0f*X*Z - 2.0f*Y*W;
|
dest[2] = 2.0f*X*Z - 2.0f*Y*W;
|
||||||
|
@ -395,6 +436,13 @@ inline void quaternion::getMatrixCenter(matrix4 &dest,
|
||||||
const core::vector3df ¢er,
|
const core::vector3df ¢er,
|
||||||
const core::vector3df &translation) const
|
const core::vector3df &translation) const
|
||||||
{
|
{
|
||||||
|
quaternion q(*this);
|
||||||
|
q.normalize();
|
||||||
|
f32 X = q.X;
|
||||||
|
f32 Y = q.Y;
|
||||||
|
f32 Z = q.Z;
|
||||||
|
f32 W = q.W;
|
||||||
|
|
||||||
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
|
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
|
||||||
dest[1] = 2.0f*X*Y + 2.0f*Z*W;
|
dest[1] = 2.0f*X*Y + 2.0f*Z*W;
|
||||||
dest[2] = 2.0f*X*Z - 2.0f*Y*W;
|
dest[2] = 2.0f*X*Z - 2.0f*Y*W;
|
||||||
|
@ -416,6 +464,13 @@ inline void quaternion::getMatrixCenter(matrix4 &dest,
|
||||||
// Creates a matrix from this quaternion
|
// Creates a matrix from this quaternion
|
||||||
inline void quaternion::getMatrix_transposed(matrix4 &dest) const
|
inline void quaternion::getMatrix_transposed(matrix4 &dest) const
|
||||||
{
|
{
|
||||||
|
quaternion q(*this);
|
||||||
|
q.normalize();
|
||||||
|
f32 X = q.X;
|
||||||
|
f32 Y = q.Y;
|
||||||
|
f32 Z = q.Z;
|
||||||
|
f32 W = q.W;
|
||||||
|
|
||||||
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
|
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
|
||||||
dest[4] = 2.0f*X*Y + 2.0f*Z*W;
|
dest[4] = 2.0f*X*Y + 2.0f*Z*W;
|
||||||
dest[8] = 2.0f*X*Z - 2.0f*Y*W;
|
dest[8] = 2.0f*X*Z - 2.0f*Y*W;
|
||||||
|
@ -492,7 +547,7 @@ inline quaternion& quaternion::set(f32 x, f32 y, f32 z)
|
||||||
// sets new quaternion based on Euler angles
|
// sets new quaternion based on Euler angles
|
||||||
inline quaternion& quaternion::set(const core::vector3df& vec)
|
inline quaternion& quaternion::set(const core::vector3df& vec)
|
||||||
{
|
{
|
||||||
return set(vec.X, vec.Y, vec.Z);
|
return set( vec.X, vec.Y, vec.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sets new quaternion based on other quaternion
|
// sets new quaternion based on other quaternion
|
||||||
|
@ -505,28 +560,23 @@ inline quaternion& quaternion::set(const core::quaternion& quat)
|
||||||
//! returns if this quaternion equals the other one, taking floating point rounding errors into account
|
//! returns if this quaternion equals the other one, taking floating point rounding errors into account
|
||||||
inline bool quaternion::equals(const quaternion& other, const f32 tolerance) const
|
inline bool quaternion::equals(const quaternion& other, const f32 tolerance) const
|
||||||
{
|
{
|
||||||
return core::equals(X, other.X, tolerance) &&
|
return core::equals( X, other.X, tolerance) &&
|
||||||
core::equals(Y, other.Y, tolerance) &&
|
core::equals( Y, other.Y, tolerance) &&
|
||||||
core::equals(Z, other.Z, tolerance) &&
|
core::equals( Z, other.Z, tolerance) &&
|
||||||
core::equals(W, other.W, tolerance);
|
core::equals( W, other.W, tolerance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// normalizes the quaternion
|
// normalizes the quaternion
|
||||||
inline quaternion& quaternion::normalize()
|
inline quaternion& quaternion::normalize()
|
||||||
{
|
{
|
||||||
const f32 n = X*X + Y*Y + Z*Z + W*W;
|
// removed conditional branch since it may slow down and anyway the condition was
|
||||||
|
// false even after normalization in some cases.
|
||||||
if (n == 1)
|
return (*this *= reciprocal_squareroot ( X*X + Y*Y + Z*Z + W*W ));
|
||||||
return *this;
|
|
||||||
|
|
||||||
//n = 1.0f / sqrtf(n);
|
|
||||||
return (*this *= reciprocal_squareroot ( n ));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// set this quaternion to the result of the linear interpolation between two quaternions
|
// set this quaternion to the result of the linear interpolation between two quaternions
|
||||||
inline quaternion& quaternion::lerp(quaternion q1, quaternion q2, f32 time)
|
inline quaternion& quaternion::lerp( quaternion q1, quaternion q2, f32 time)
|
||||||
{
|
{
|
||||||
const f32 scale = 1.0f - time;
|
const f32 scale = 1.0f - time;
|
||||||
return (*this = (q1*scale) + (q2*time));
|
return (*this = (q1*scale) + (q2*time));
|
||||||
|
@ -534,7 +584,7 @@ inline quaternion& quaternion::lerp(quaternion q1, quaternion q2, f32 time)
|
||||||
|
|
||||||
|
|
||||||
// set this quaternion to the result of the interpolation between two quaternions
|
// set this quaternion to the result of the interpolation between two quaternions
|
||||||
inline quaternion& quaternion::slerp(quaternion q1, quaternion q2, f32 time, f32 threshold)
|
inline quaternion& quaternion::slerp( quaternion q1, quaternion q2, f32 time, f32 threshold)
|
||||||
{
|
{
|
||||||
f32 angle = q1.dotProduct(q2);
|
f32 angle = q1.dotProduct(q2);
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,20 @@ public:
|
||||||
return X*other.X + Y*other.Y;
|
return X*other.X + Y*other.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! check if this vector is parallel to another vector
|
||||||
|
bool nearlyParallel( const vector2d<T> & other, const T factor = relativeErrorFactor<T>()) const
|
||||||
|
{
|
||||||
|
// https://eagergames.wordpress.com/2017/04/01/fast-parallel-lines-and-vectors-test/
|
||||||
|
// if a || b then a.x/a.y = b.x/b.y (similiar triangles)
|
||||||
|
// if a || b then either both x are 0 or both y are 0.
|
||||||
|
|
||||||
|
return equalsRelative( X*other.Y, other.X* Y, factor)
|
||||||
|
&& // a bit counterintuitive, but makes sure that
|
||||||
|
// only y or only x are 0, and at same time deals
|
||||||
|
// with the case where one vector is zero vector.
|
||||||
|
(X*other.X + Y*other.Y) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
//! Gets distance from another point.
|
//! Gets distance from another point.
|
||||||
/** Here, the vector is interpreted as a point in 2-dimensional space.
|
/** Here, the vector is interpreted as a point in 2-dimensional space.
|
||||||
\param other Other vector to measure from.
|
\param other Other vector to measure from.
|
||||||
|
@ -259,15 +273,24 @@ public:
|
||||||
\return True if this vector is between begin and end, false if not. */
|
\return True if this vector is between begin and end, false if not. */
|
||||||
bool isBetweenPoints(const vector2d<T>& begin, const vector2d<T>& end) const
|
bool isBetweenPoints(const vector2d<T>& begin, const vector2d<T>& end) const
|
||||||
{
|
{
|
||||||
|
// . end
|
||||||
|
// /
|
||||||
|
// /
|
||||||
|
// /
|
||||||
|
// . begin
|
||||||
|
// -
|
||||||
|
// -
|
||||||
|
// . this point (am I inside or outside)?
|
||||||
|
//
|
||||||
if (begin.X != end.X)
|
if (begin.X != end.X)
|
||||||
{
|
{
|
||||||
return ((begin.X <= X && X <= end.X) ||
|
return ((begin.X <= X && X <= end.X) ||
|
||||||
(begin.X >= X && X >= end.X));
|
(begin.X >= X && X >= end.X));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return ((begin.Y <= Y && Y <= end.Y) ||
|
return ((begin.Y <= Y && Y <= end.Y) ||
|
||||||
(begin.Y >= Y && Y >= end.Y));
|
(begin.Y >= Y && Y >= end.Y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,13 +323,55 @@ public:
|
||||||
(T)(Y * mul0 + v2.Y * mul1 + v3.Y * mul2));
|
(T)(Y * mul0 + v2.Y * mul1 + v3.Y * mul2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Test if this point and another 2 poitns taken as triplet
|
||||||
|
are colinear, clockwise, anticlockwise. This can be used also
|
||||||
|
to check winding order in triangles for 2D meshes.
|
||||||
|
\return 0 if points are colinear, 1 if clockwise, 2 if anticlockwise
|
||||||
|
*/
|
||||||
|
s32 checkOrientation( const vector2d<T> & b, const vector2d<T> & c) const
|
||||||
|
{
|
||||||
|
// Example of clockwise points
|
||||||
|
//
|
||||||
|
// ^ Y
|
||||||
|
// | A
|
||||||
|
// | . .
|
||||||
|
// | . .
|
||||||
|
// | C.....B
|
||||||
|
// +---------------> X
|
||||||
|
|
||||||
|
T val = (b.Y - Y) * (c.X - b.X) -
|
||||||
|
(b.X - X) * (c.Y - b.Y);
|
||||||
|
|
||||||
|
if (val == 0) return 0; // colinear
|
||||||
|
|
||||||
|
return (val > 0) ? 1 : 2; // clock or counterclock wise
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Returns true if points (a,b,c) are clockwise on the X,Y plane*/
|
||||||
|
inline bool areClockwise( const vector2d<T> & b, const vector2d<T> & c) const
|
||||||
|
{
|
||||||
|
T val = (b.Y - Y) * (c.X - b.X) -
|
||||||
|
(b.X - X) * (c.Y - b.Y);
|
||||||
|
|
||||||
|
return val > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Returns true if points (a,b,c) are counterclockwise on the X,Y plane*/
|
||||||
|
inline bool areCounterClockwise( const vector2d<T> & b, const vector2d<T> & c) const
|
||||||
|
{
|
||||||
|
T val = (b.Y - Y) * (c.X - b.X) -
|
||||||
|
(b.X - X) * (c.Y - b.Y);
|
||||||
|
|
||||||
|
return val < 0;
|
||||||
|
}
|
||||||
|
|
||||||
//! Sets this vector to the linearly interpolated vector between a and b.
|
//! Sets this vector to the linearly interpolated vector between a and b.
|
||||||
/** \param a first vector to interpolate with, maximum at 1.0f
|
/** \param a first vector to interpolate with, maximum at 1.0f
|
||||||
\param b second vector to interpolate with, maximum at 0.0f
|
\param b second vector to interpolate with, maximum at 0.0f
|
||||||
\param d Interpolation value between 0.0f (all vector b) and 1.0f (all vector a)
|
\param d Interpolation value between 0.0f (all vector b) and 1.0f (all vector a)
|
||||||
Note that this is the opposite direction of interpolation to getInterpolated_quadratic()
|
Note that this is the opposite direction of interpolation to getInterpolated_quadratic()
|
||||||
*/
|
*/
|
||||||
vector2d<T>& interpolate(const vector2d<T>& a, const vector2d<T>& b, f64 d)
|
vector2d<T>& interpolate( const vector2d<T>& a, const vector2d<T>& b, f64 d)
|
||||||
{
|
{
|
||||||
X = (T)((f64)b.X + ( ( a.X - b.X ) * d ));
|
X = (T)((f64)b.X + ( ( a.X - b.X ) * d ));
|
||||||
Y = (T)((f64)b.Y + ( ( a.Y - b.Y ) * d ));
|
Y = (T)((f64)b.Y + ( ( a.Y - b.Y ) * d ));
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace scene
|
||||||
{
|
{
|
||||||
BinaryFileReader(io::IReadFile* pFile) : file(pFile) { }
|
BinaryFileReader(io::IReadFile* pFile) : file(pFile) { }
|
||||||
|
|
||||||
s32 readBuffer(void* buffer, s32 len)
|
size_t readBuffer(void* buffer, s32 len)
|
||||||
{
|
{
|
||||||
return file->read(buffer,len);
|
return file->read(buffer,len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2830,6 +2830,47 @@ void CD3D9Driver::draw3DLine(const core::vector3df& start,
|
||||||
pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, v, sizeof(S3DVertex));
|
pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, v, sizeof(S3DVertex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CD3D9Driver::draw3DBox( const core::aabbox3d<f32>& box, SColor color)
|
||||||
|
{
|
||||||
|
core::vector3df edges[8];
|
||||||
|
box.getEdges(edges);
|
||||||
|
|
||||||
|
setVertexShader(EVT_STANDARD);
|
||||||
|
setRenderStates3DMode();
|
||||||
|
|
||||||
|
video::S3DVertex v[24];
|
||||||
|
|
||||||
|
for(u32 i = 0; i < 24; i++)
|
||||||
|
v[i].Color = color;
|
||||||
|
|
||||||
|
v[0].Pos = edges[5];
|
||||||
|
v[1].Pos = edges[1];
|
||||||
|
v[2].Pos = edges[1];
|
||||||
|
v[3].Pos = edges[3];
|
||||||
|
v[4].Pos = edges[3];
|
||||||
|
v[5].Pos = edges[7];
|
||||||
|
v[6].Pos = edges[7];
|
||||||
|
v[7].Pos = edges[5];
|
||||||
|
v[8].Pos = edges[0];
|
||||||
|
v[9].Pos = edges[2];
|
||||||
|
v[10].Pos = edges[2];
|
||||||
|
v[11].Pos = edges[6];
|
||||||
|
v[12].Pos = edges[6];
|
||||||
|
v[13].Pos = edges[4];
|
||||||
|
v[14].Pos = edges[4];
|
||||||
|
v[15].Pos = edges[0];
|
||||||
|
v[16].Pos = edges[1];
|
||||||
|
v[17].Pos = edges[0];
|
||||||
|
v[18].Pos = edges[3];
|
||||||
|
v[19].Pos = edges[2];
|
||||||
|
v[20].Pos = edges[7];
|
||||||
|
v[21].Pos = edges[6];
|
||||||
|
v[22].Pos = edges[5];
|
||||||
|
v[23].Pos = edges[4];
|
||||||
|
|
||||||
|
pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 12, v, sizeof(S3DVertex));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! resets the device
|
//! resets the device
|
||||||
bool CD3D9Driver::reset()
|
bool CD3D9Driver::reset()
|
||||||
|
|
|
@ -170,6 +170,9 @@ namespace video
|
||||||
virtual void draw3DLine(const core::vector3df& start,
|
virtual void draw3DLine(const core::vector3df& start,
|
||||||
const core::vector3df& end, SColor color = SColor(255,255,255,255)) _IRR_OVERRIDE_;
|
const core::vector3df& end, SColor color = SColor(255,255,255,255)) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
//! Draws a 3d box.
|
||||||
|
virtual void draw3DBox( const core::aabbox3d<f32>& box, SColor color = SColor(255,255,255,255 ) ) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! initialises the Direct3D API
|
//! initialises the Direct3D API
|
||||||
bool initDriver(HWND hwnd, bool pureSoftware);
|
bool initDriver(HWND hwnd, bool pureSoftware);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "CDefaultSceneNodeFactory.h"
|
#include "CDefaultSceneNodeFactory.h"
|
||||||
#include "ISceneManager.h"
|
#include "ISceneManager.h"
|
||||||
#include "ITextSceneNode.h"
|
#include "ITextSceneNode.h"
|
||||||
|
#include "IBillboardTextSceneNode.h"
|
||||||
#include "ITerrainSceneNode.h"
|
#include "ITerrainSceneNode.h"
|
||||||
#include "IDummyTransformationSceneNode.h"
|
#include "IDummyTransformationSceneNode.h"
|
||||||
#include "ICameraSceneNode.h"
|
#include "ICameraSceneNode.h"
|
||||||
|
@ -33,6 +34,7 @@ CDefaultSceneNodeFactory::CDefaultSceneNodeFactory(ISceneManager* mgr)
|
||||||
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_CUBE, "cube"));
|
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_CUBE, "cube"));
|
||||||
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_SPHERE, "sphere"));
|
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_SPHERE, "sphere"));
|
||||||
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_TEXT, "text"));
|
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_TEXT, "text"));
|
||||||
|
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_BILLBOARD_TEXT, "billboardText"));
|
||||||
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_WATER_SURFACE, "waterSurface"));
|
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_WATER_SURFACE, "waterSurface"));
|
||||||
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_TERRAIN, "terrain"));
|
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_TERRAIN, "terrain"));
|
||||||
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_SKY_BOX, "skyBox"));
|
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_SKY_BOX, "skyBox"));
|
||||||
|
@ -70,6 +72,8 @@ ISceneNode* CDefaultSceneNodeFactory::addSceneNode(ESCENE_NODE_TYPE type, IScene
|
||||||
return Manager->addSphereSceneNode(5, 16, parent);
|
return Manager->addSphereSceneNode(5, 16, parent);
|
||||||
case ESNT_TEXT:
|
case ESNT_TEXT:
|
||||||
return Manager->addTextSceneNode(0, L"example");
|
return Manager->addTextSceneNode(0, L"example");
|
||||||
|
case ESNT_BILLBOARD_TEXT:
|
||||||
|
return Manager->addBillboardTextSceneNode(0, L"example");
|
||||||
case ESNT_WATER_SURFACE:
|
case ESNT_WATER_SURFACE:
|
||||||
return Manager->addWaterSurfaceSceneNode(0, 2.0f, 300.0f, 10.0f, parent);
|
return Manager->addWaterSurfaceSceneNode(0, 2.0f, 300.0f, 10.0f, parent);
|
||||||
case ESNT_TERRAIN:
|
case ESNT_TERRAIN:
|
||||||
|
|
|
@ -826,7 +826,7 @@ IFileList* CFileSystem::createFileList()
|
||||||
CFileList* r = 0;
|
CFileList* r = 0;
|
||||||
io::path Path = getWorkingDirectory();
|
io::path Path = getWorkingDirectory();
|
||||||
Path.replace('\\', '/');
|
Path.replace('\\', '/');
|
||||||
if (Path.lastChar() != '/')
|
if (!Path.empty() && Path.lastChar() != '/')
|
||||||
Path.append('/');
|
Path.append('/');
|
||||||
|
|
||||||
//! Construct from native filesystem
|
//! Construct from native filesystem
|
||||||
|
|
|
@ -285,22 +285,25 @@ bool CGUIContextMenu::OnEvent(const SEvent& event)
|
||||||
{
|
{
|
||||||
// set event parent of submenus
|
// set event parent of submenus
|
||||||
IGUIElement * p = EventParent ? EventParent : Parent;
|
IGUIElement * p = EventParent ? EventParent : Parent;
|
||||||
setEventParent(p);
|
if ( p ) // can be 0 when element got removed already
|
||||||
|
|
||||||
SEvent event;
|
|
||||||
event.EventType = EET_GUI_EVENT;
|
|
||||||
event.GUIEvent.Caller = this;
|
|
||||||
event.GUIEvent.Element = 0;
|
|
||||||
event.GUIEvent.EventType = EGET_ELEMENT_CLOSED;
|
|
||||||
if ( !p->OnEvent(event) )
|
|
||||||
{
|
{
|
||||||
if ( CloseHandling & ECMC_HIDE )
|
setEventParent(p);
|
||||||
|
|
||||||
|
SEvent event;
|
||||||
|
event.EventType = EET_GUI_EVENT;
|
||||||
|
event.GUIEvent.Caller = this;
|
||||||
|
event.GUIEvent.Element = 0;
|
||||||
|
event.GUIEvent.EventType = EGET_ELEMENT_CLOSED;
|
||||||
|
if ( !p->OnEvent(event) )
|
||||||
{
|
{
|
||||||
setVisible(false);
|
if ( CloseHandling & ECMC_HIDE )
|
||||||
}
|
{
|
||||||
if ( CloseHandling & ECMC_REMOVE )
|
setVisible(false);
|
||||||
{
|
}
|
||||||
remove();
|
if ( CloseHandling & ECMC_REMOVE )
|
||||||
|
{
|
||||||
|
remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ bool CImageLoaderJPG::isALoadableFileFormat(io::IReadFile* file) const
|
||||||
if (!(file && file->seek(0)))
|
if (!(file && file->seek(0)))
|
||||||
return false;
|
return false;
|
||||||
unsigned char header[3];
|
unsigned char header[3];
|
||||||
int headerLen = file->read(header, sizeof(header));
|
size_t headerLen = file->read(header, sizeof(header));
|
||||||
return headerLen >= 3 && !memcmp(header, "\xFF\xD8\xFF", 3);
|
return headerLen >= 3 && !memcmp(header, "\xFF\xD8\xFF", 3);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -498,6 +498,11 @@ bool CIrrDeviceLinux::createWindow()
|
||||||
IrrPrintXGrabError(grabPointer, "XGrabPointer");
|
IrrPrintXGrabError(grabPointer, "XGrabPointer");
|
||||||
XWarpPointer(XDisplay, None, XWindow, 0, 0, 0, 0, 0, 0);
|
XWarpPointer(XDisplay, None, XWindow, 0, 0, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
else if (CreationParams.WindowPosition.X >= 0 || CreationParams.WindowPosition.Y >= 0) // default is -1, -1
|
||||||
|
{
|
||||||
|
// Window managers are free to ignore positions above, so give it another shot
|
||||||
|
XMoveWindow(XDisplay,XWindow,x,y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1395,6 +1395,10 @@ void CIrrDeviceMacOSX::initKeycodes()
|
||||||
KeyCodes[kVK_ANSI_KeypadDivide] = irr::KEY_DIVIDE;
|
KeyCodes[kVK_ANSI_KeypadDivide] = irr::KEY_DIVIDE;
|
||||||
KeyCodes[kVK_ANSI_KeypadEnter] = irr::KEY_RETURN;
|
KeyCodes[kVK_ANSI_KeypadEnter] = irr::KEY_RETURN;
|
||||||
KeyCodes[kVK_ANSI_KeypadMinus] = irr::KEY_SUBTRACT;
|
KeyCodes[kVK_ANSI_KeypadMinus] = irr::KEY_SUBTRACT;
|
||||||
|
|
||||||
|
KeyCodes[kVK_ANSI_LeftBracket] = irr::KEY_OEM_4;
|
||||||
|
KeyCodes[kVK_ANSI_Backslash] = irr::KEY_OEM_5;
|
||||||
|
KeyCodes[kVK_ANSI_RightBracket] = irr::KEY_OEM_6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -455,6 +455,8 @@ irr::core::stringc SJoystickWin32Control::findJoystickName(int index, const JOYC
|
||||||
bool SJoystickWin32Control::activateJoysticks(core::array<SJoystickInfo> & joystickInfo)
|
bool SJoystickWin32Control::activateJoysticks(core::array<SJoystickInfo> & joystickInfo)
|
||||||
{
|
{
|
||||||
#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
|
#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
|
||||||
|
joystickInfo.clear();
|
||||||
|
ActiveJoysticks.clear();
|
||||||
#ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
|
#ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
|
||||||
if (!DirectInputDevice || (DirectInputDevice->EnumDevices(DI8DEVCLASS_GAMECTRL, SJoystickWin32Control::EnumJoysticks, this, DIEDFL_ATTACHEDONLY )))
|
if (!DirectInputDevice || (DirectInputDevice->EnumDevices(DI8DEVCLASS_GAMECTRL, SJoystickWin32Control::EnumJoysticks, this, DIEDFL_ATTACHEDONLY )))
|
||||||
{
|
{
|
||||||
|
@ -475,9 +477,6 @@ bool SJoystickWin32Control::activateJoysticks(core::array<SJoystickInfo> & joyst
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
joystickInfo.clear();
|
|
||||||
ActiveJoysticks.clear();
|
|
||||||
|
|
||||||
const u32 numberOfJoysticks = ::joyGetNumDevs();
|
const u32 numberOfJoysticks = ::joyGetNumDevs();
|
||||||
JOYINFOEX info;
|
JOYINFOEX info;
|
||||||
info.dwSize = sizeof(info);
|
info.dwSize = sizeof(info);
|
||||||
|
@ -2002,6 +2001,26 @@ void CIrrDeviceWin32::ReportLastWinApiError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Same function Windows offers in VersionHelpers.h, but we can't use that as it's not available in older sdk's (minimum is SDK 8.1)
|
||||||
|
bool CIrrDeviceWin32::isWindowsVistaOrGreater()
|
||||||
|
{
|
||||||
|
#if (_WIN32_WINNT >= 0x0500)
|
||||||
|
OSVERSIONINFOEX osvi;
|
||||||
|
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
||||||
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||||
|
osvi.dwMajorVersion = 6; // Windows Vista
|
||||||
|
|
||||||
|
if ( !GetVersionEx((OSVERSIONINFO*)&osvi) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VerifyVersionInfo(&osvi, VER_MAJORVERSION, VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL));
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Convert an Irrlicht texture to a Windows cursor
|
// Convert an Irrlicht texture to a Windows cursor
|
||||||
// Based on http://www.codeguru.com/cpp/w-p/win32/cursors/article.php/c4529/
|
// Based on http://www.codeguru.com/cpp/w-p/win32/cursors/article.php/c4529/
|
||||||
HCURSOR CIrrDeviceWin32::TextureToCursor(HWND hwnd, irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot)
|
HCURSOR CIrrDeviceWin32::TextureToCursor(HWND hwnd, irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot)
|
||||||
|
|
|
@ -118,13 +118,16 @@ namespace irr
|
||||||
return CIrrDeviceStub::checkSuccessiveClicks(mouseX, mouseY, inputEvent );
|
return CIrrDeviceStub::checkSuccessiveClicks(mouseX, mouseY, inputEvent );
|
||||||
}
|
}
|
||||||
|
|
||||||
//! switchs to fullscreen
|
//! Switch to fullscreen
|
||||||
bool switchToFullScreen(bool reset=false);
|
bool switchToFullScreen(bool reset=false);
|
||||||
|
|
||||||
//! Check for and show last Windows API error to help internal debugging.
|
//! Check for and show last Windows API error to help internal debugging.
|
||||||
//! Does call GetLastError and on errors formats the errortext and displays it in a messagebox.
|
//! Does call GetLastError and on errors formats the error text and displays it in a messagebox.
|
||||||
static void ReportLastWinApiError();
|
static void ReportLastWinApiError();
|
||||||
|
|
||||||
|
//! Same function Windows offers in VersionHelpers.h, but we can't use that as it's not available before SDK 8.1
|
||||||
|
static bool isWindowsVistaOrGreater();
|
||||||
|
|
||||||
// convert an Irrlicht texture to a windows cursor
|
// convert an Irrlicht texture to a windows cursor
|
||||||
HCURSOR TextureToCursor(HWND hwnd, irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
|
HCURSOR TextureToCursor(HWND hwnd, irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
|
||||||
|
|
||||||
|
@ -282,15 +285,21 @@ namespace irr
|
||||||
{
|
{
|
||||||
if (!fullscreen)
|
if (!fullscreen)
|
||||||
{
|
{
|
||||||
|
s32 paddingBorder = 0;
|
||||||
|
#if defined (SM_CXPADDEDBORDER)
|
||||||
|
if (CIrrDeviceWin32::isWindowsVistaOrGreater())
|
||||||
|
paddingBorder = GetSystemMetrics(SM_CXPADDEDBORDER);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (resizable)
|
if (resizable)
|
||||||
{
|
{
|
||||||
BorderX = GetSystemMetrics(SM_CXSIZEFRAME);
|
BorderX = GetSystemMetrics(SM_CXSIZEFRAME) + paddingBorder;
|
||||||
BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYSIZEFRAME);
|
BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYSIZEFRAME) + paddingBorder;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BorderX = GetSystemMetrics(SM_CXDLGFRAME);
|
BorderX = GetSystemMetrics(SM_CXDLGFRAME) + paddingBorder;
|
||||||
BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME);
|
BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME) + paddingBorder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -159,7 +159,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
|
||||||
// read whole file
|
// read whole file
|
||||||
|
|
||||||
u8* buffer = new u8[fileSize];
|
u8* buffer = new u8[fileSize];
|
||||||
s32 read = file->read(buffer, fileSize);
|
long read = (long)file->read(buffer, fileSize);
|
||||||
if (read != fileSize)
|
if (read != fileSize)
|
||||||
{
|
{
|
||||||
delete [] buffer;
|
delete [] buffer;
|
||||||
|
|
|
@ -38,14 +38,27 @@ s32 CMetaTriangleSelector::getTriangleCount() const
|
||||||
|
|
||||||
//! Gets all triangles.
|
//! Gets all triangles.
|
||||||
void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
|
void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::matrix4* transform) const
|
s32& outTriangleCount, const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
s32 outWritten = 0;
|
s32 outWritten = 0;
|
||||||
|
irr::u32 outTriangleInfoSize = outTriangleInfo ? outTriangleInfo->size() : 0;
|
||||||
for (u32 i=0; i<TriangleSelectors.size(); ++i)
|
for (u32 i=0; i<TriangleSelectors.size(); ++i)
|
||||||
{
|
{
|
||||||
s32 t = 0;
|
s32 t = 0;
|
||||||
TriangleSelectors[i]->getTriangles(triangles + outWritten,
|
TriangleSelectors[i]->getTriangles(triangles + outWritten,
|
||||||
arraySize - outWritten, t, transform);
|
arraySize - outWritten, t, transform, useNodeTransform, outTriangleInfo);
|
||||||
|
|
||||||
|
if ( outTriangleInfo )
|
||||||
|
{
|
||||||
|
irr::u32 newTriangleInfoSize = outTriangleInfo->size();
|
||||||
|
for ( u32 ti=outTriangleInfoSize; ti<newTriangleInfoSize; ++ti )
|
||||||
|
{
|
||||||
|
(*outTriangleInfo)[ti].RangeStart += outWritten;
|
||||||
|
}
|
||||||
|
outTriangleInfoSize = newTriangleInfoSize;
|
||||||
|
}
|
||||||
|
|
||||||
outWritten += t;
|
outWritten += t;
|
||||||
if (outWritten==arraySize)
|
if (outWritten==arraySize)
|
||||||
break;
|
break;
|
||||||
|
@ -58,14 +71,27 @@ void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 array
|
||||||
//! Gets all triangles which lie within a specific bounding box.
|
//! Gets all triangles which lie within a specific bounding box.
|
||||||
void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
|
void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::aabbox3d<f32>& box,
|
s32& outTriangleCount, const core::aabbox3d<f32>& box,
|
||||||
const core::matrix4* transform) const
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
s32 outWritten = 0;
|
s32 outWritten = 0;
|
||||||
|
irr::u32 outTriangleInfoSize = outTriangleInfo ? outTriangleInfo->size() : 0;
|
||||||
for (u32 i=0; i<TriangleSelectors.size(); ++i)
|
for (u32 i=0; i<TriangleSelectors.size(); ++i)
|
||||||
{
|
{
|
||||||
s32 t = 0;
|
s32 t = 0;
|
||||||
TriangleSelectors[i]->getTriangles(triangles + outWritten,
|
TriangleSelectors[i]->getTriangles(triangles + outWritten,
|
||||||
arraySize - outWritten, t, box, transform);
|
arraySize - outWritten, t, box, transform, useNodeTransform, outTriangleInfo);
|
||||||
|
|
||||||
|
if ( outTriangleInfo )
|
||||||
|
{
|
||||||
|
irr::u32 newTriangleInfoSize = outTriangleInfo->size();
|
||||||
|
for ( u32 ti=outTriangleInfoSize; ti<newTriangleInfoSize; ++ti )
|
||||||
|
{
|
||||||
|
(*outTriangleInfo)[ti].RangeStart += outWritten;
|
||||||
|
}
|
||||||
|
outTriangleInfoSize = newTriangleInfoSize;
|
||||||
|
}
|
||||||
|
|
||||||
outWritten += t;
|
outWritten += t;
|
||||||
if (outWritten==arraySize)
|
if (outWritten==arraySize)
|
||||||
break;
|
break;
|
||||||
|
@ -78,14 +104,27 @@ void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 array
|
||||||
//! Gets all triangles which have or may have contact with a 3d line.
|
//! Gets all triangles which have or may have contact with a 3d line.
|
||||||
void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
|
void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::line3d<f32>& line,
|
s32& outTriangleCount, const core::line3d<f32>& line,
|
||||||
const core::matrix4* transform) const
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
s32 outWritten = 0;
|
s32 outWritten = 0;
|
||||||
|
irr::u32 outTriangleInfoSize = outTriangleInfo ? outTriangleInfo->size() : 0;
|
||||||
for (u32 i=0; i<TriangleSelectors.size(); ++i)
|
for (u32 i=0; i<TriangleSelectors.size(); ++i)
|
||||||
{
|
{
|
||||||
s32 t = 0;
|
s32 t = 0;
|
||||||
TriangleSelectors[i]->getTriangles(triangles + outWritten,
|
TriangleSelectors[i]->getTriangles(triangles + outWritten,
|
||||||
arraySize - outWritten, t, line, transform);
|
arraySize - outWritten, t, line, transform, useNodeTransform, outTriangleInfo);
|
||||||
|
|
||||||
|
if ( outTriangleInfo )
|
||||||
|
{
|
||||||
|
irr::u32 newTriangleInfoSize = outTriangleInfo->size();
|
||||||
|
for ( u32 ti=outTriangleInfoSize; ti<newTriangleInfoSize; ++ti )
|
||||||
|
{
|
||||||
|
(*outTriangleInfo)[ti].RangeStart += outWritten;
|
||||||
|
}
|
||||||
|
outTriangleInfoSize = newTriangleInfoSize;
|
||||||
|
}
|
||||||
|
|
||||||
outWritten += t;
|
outWritten += t;
|
||||||
if (outWritten==arraySize)
|
if (outWritten==arraySize)
|
||||||
break;
|
break;
|
||||||
|
@ -147,11 +186,9 @@ ISceneNode* CMetaTriangleSelector::getSceneNodeForTriangle(u32 triangleIndex) co
|
||||||
return TriangleSelectors[i]->getSceneNodeForTriangle(0);
|
return TriangleSelectors[i]->getSceneNodeForTriangle(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For lack of anything more sensible, return the first selector.
|
return 0;
|
||||||
return TriangleSelectors[0]->getSceneNodeForTriangle(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return the number of TriangleSelectors that are inside this one,
|
/* Return the number of TriangleSelectors that are inside this one,
|
||||||
Only useful for MetaTriangleSelector others return 1
|
Only useful for MetaTriangleSelector others return 1
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -29,17 +29,20 @@ public:
|
||||||
|
|
||||||
//! Gets all triangles.
|
//! Gets all triangles.
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
s32& outTriangleCount, const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Gets all triangles which lie within a specific bounding box.
|
//! Gets all triangles which lie within a specific bounding box.
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::aabbox3d<f32>& box,
|
s32& outTriangleCount, const core::aabbox3d<f32>& box,
|
||||||
const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Gets all triangles which have or may have contact with a 3d line.
|
//! Gets all triangles which have or may have contact with a 3d line.
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::line3d<f32>& line,
|
s32& outTriangleCount, const core::line3d<f32>& line,
|
||||||
const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Adds a triangle selector to the collection of triangle selectors
|
//! Adds a triangle selector to the collection of triangle selectors
|
||||||
//! in this metaTriangleSelector.
|
//! in this metaTriangleSelector.
|
||||||
|
|
|
@ -100,6 +100,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
|
||||||
bool mtlChanged=false;
|
bool mtlChanged=false;
|
||||||
bool useGroups = !SceneManager->getParameters()->getAttributeAsBool(OBJ_LOADER_IGNORE_GROUPS);
|
bool useGroups = !SceneManager->getParameters()->getAttributeAsBool(OBJ_LOADER_IGNORE_GROUPS);
|
||||||
bool useMaterials = !SceneManager->getParameters()->getAttributeAsBool(OBJ_LOADER_IGNORE_MATERIAL_FILES);
|
bool useMaterials = !SceneManager->getParameters()->getAttributeAsBool(OBJ_LOADER_IGNORE_MATERIAL_FILES);
|
||||||
|
irr::u32 lineNr = 1; // only counts non-empty lines, still useful in debugging to locate errors
|
||||||
while(bufPtr != bufEnd)
|
while(bufPtr != bufEnd)
|
||||||
{
|
{
|
||||||
switch(bufPtr[0])
|
switch(bufPtr[0])
|
||||||
|
@ -289,6 +290,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
|
||||||
} // end switch(bufPtr[0])
|
} // end switch(bufPtr[0])
|
||||||
// eat up rest of line
|
// eat up rest of line
|
||||||
bufPtr = goNextLine(bufPtr, bufEnd);
|
bufPtr = goNextLine(bufPtr, bufEnd);
|
||||||
|
++lineNr;
|
||||||
} // end while(bufPtr && (bufPtr-buf<filesize))
|
} // end while(bufPtr && (bufPtr-buf<filesize))
|
||||||
|
|
||||||
SMesh* mesh = new SMesh();
|
SMesh* mesh = new SMesh();
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
#else
|
#else
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#ifndef _IRR_SOLARIS_PLATFORM_
|
|
||||||
#ifndef _IRR_ANDROID_PLATFORM_
|
#ifndef _IRR_ANDROID_PLATFORM_
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#ifdef _IRR_OSX_PLATFORM_
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -84,7 +84,7 @@ void COSOperator::copyToClipboard(const c8* text) const
|
||||||
#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
|
#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
|
||||||
NSString *str = nil;
|
NSString *str = nil;
|
||||||
NSPasteboard *board = nil;
|
NSPasteboard *board = nil;
|
||||||
|
|
||||||
if ((text != NULL) && (strlen(text) > 0))
|
if ((text != NULL) && (strlen(text) > 0))
|
||||||
{
|
{
|
||||||
str = [NSString stringWithCString:text encoding:NSWindowsCP1252StringEncoding];
|
str = [NSString stringWithCString:text encoding:NSWindowsCP1252StringEncoding];
|
||||||
|
@ -92,7 +92,7 @@ void COSOperator::copyToClipboard(const c8* text) const
|
||||||
[board declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:NSApp];
|
[board declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:NSApp];
|
||||||
[board setString:str forType:NSStringPboardType];
|
[board setString:str forType:NSStringPboardType];
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
||||||
if ( IrrDeviceLinux )
|
if ( IrrDeviceLinux )
|
||||||
IrrDeviceLinux->copyToClipboard(text);
|
IrrDeviceLinux->copyToClipboard(text);
|
||||||
|
@ -127,10 +127,10 @@ const c8* COSOperator::getTextFromClipboard() const
|
||||||
|
|
||||||
board = [NSPasteboard generalPasteboard];
|
board = [NSPasteboard generalPasteboard];
|
||||||
str = [board stringForType:NSStringPboardType];
|
str = [board stringForType:NSStringPboardType];
|
||||||
|
|
||||||
if (str != nil)
|
if (str != nil)
|
||||||
result = (char*)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding];
|
result = (char*)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding];
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
|
|
||||||
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
||||||
|
@ -208,18 +208,32 @@ bool COSOperator::getProcessorSpeedMHz(u32* MHz) const
|
||||||
bool COSOperator::getSystemMemory(u32* Total, u32* Avail) const
|
bool COSOperator::getSystemMemory(u32* Total, u32* Avail) const
|
||||||
{
|
{
|
||||||
#if defined(_IRR_WINDOWS_API_) && !defined (_IRR_XBOX_PLATFORM_)
|
#if defined(_IRR_WINDOWS_API_) && !defined (_IRR_XBOX_PLATFORM_)
|
||||||
|
|
||||||
|
#if (_WIN32_WINNT >= 0x0500)
|
||||||
|
MEMORYSTATUSEX MemoryStatusEx;
|
||||||
|
MemoryStatusEx.dwLength = sizeof(MEMORYSTATUSEX);
|
||||||
|
|
||||||
|
// cannot fail
|
||||||
|
GlobalMemoryStatusEx(&MemoryStatusEx);
|
||||||
|
|
||||||
|
if (Total)
|
||||||
|
*Total = (u32)(MemoryStatusEx.ullTotalPhys>>10);
|
||||||
|
if (Avail)
|
||||||
|
*Avail = (u32)(MemoryStatusEx.ullAvailPhys>>10);
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
MEMORYSTATUS MemoryStatus;
|
MEMORYSTATUS MemoryStatus;
|
||||||
MemoryStatus.dwLength = sizeof(MEMORYSTATUS);
|
MemoryStatus.dwLength = sizeof(MEMORYSTATUS);
|
||||||
|
|
||||||
// cannot fail
|
// cannot fail
|
||||||
GlobalMemoryStatus(&MemoryStatus);
|
GlobalMemoryStatus(&MemoryStatus);
|
||||||
|
|
||||||
if (Total)
|
if (Total)
|
||||||
*Total = (u32)(MemoryStatus.dwTotalPhys>>10);
|
*Total = (u32)(MemoryStatus.dwTotalPhys>>10);
|
||||||
if (Avail)
|
if (Avail)
|
||||||
*Avail = (u32)(MemoryStatus.dwAvailPhys>>10);
|
*Avail = (u32)(MemoryStatus.dwAvailPhys>>10);
|
||||||
|
return true;
|
||||||
return true;
|
#endif
|
||||||
|
|
||||||
#elif defined(_IRR_POSIX_API_) && !defined(__FreeBSD__)
|
#elif defined(_IRR_POSIX_API_) && !defined(__FreeBSD__)
|
||||||
#if defined(_SC_PHYS_PAGES) && defined(_SC_AVPHYS_PAGES)
|
#if defined(_SC_PHYS_PAGES) && defined(_SC_AVPHYS_PAGES)
|
||||||
|
@ -236,7 +250,7 @@ bool COSOperator::getSystemMemory(u32* Total, u32* Avail) const
|
||||||
*Avail = (u32)((ps*(long long)ap)>>10);
|
*Avail = (u32)((ps*(long long)ap)>>10);
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
// TODO: implement for non-availablity of symbols/features
|
// TODO: implement for non-availability of symbols/features
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
#elif defined(_IRR_OSX_PLATFORM_)
|
#elif defined(_IRR_OSX_PLATFORM_)
|
||||||
|
|
|
@ -15,8 +15,9 @@ namespace scene
|
||||||
//! constructor
|
//! constructor
|
||||||
COctreeTriangleSelector::COctreeTriangleSelector(const IMesh* mesh,
|
COctreeTriangleSelector::COctreeTriangleSelector(const IMesh* mesh,
|
||||||
ISceneNode* node, s32 minimalPolysPerNode)
|
ISceneNode* node, s32 minimalPolysPerNode)
|
||||||
: CTriangleSelector(mesh, node), Root(0), NodeCount(0),
|
: CTriangleSelector(mesh, node, false)
|
||||||
MinimalPolysPerNode(minimalPolysPerNode)
|
, Root(0), NodeCount(0)
|
||||||
|
, MinimalPolysPerNode(minimalPolysPerNode)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
setDebugName("COctreeTriangleSelector");
|
setDebugName("COctreeTriangleSelector");
|
||||||
|
@ -38,6 +39,30 @@ COctreeTriangleSelector::COctreeTriangleSelector(const IMesh* mesh,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
COctreeTriangleSelector::COctreeTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node, s32 minimalPolysPerNode)
|
||||||
|
: CTriangleSelector(meshBuffer, materialIndex, node)
|
||||||
|
, Root(0), NodeCount(0)
|
||||||
|
, MinimalPolysPerNode(minimalPolysPerNode)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
setDebugName("COctreeTriangleSelector");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!Triangles.empty())
|
||||||
|
{
|
||||||
|
const u32 start = os::Timer::getRealTime();
|
||||||
|
|
||||||
|
// create the triangle octree
|
||||||
|
Root = new SOctreeNode();
|
||||||
|
Root->Triangles = Triangles;
|
||||||
|
constructOctree(Root);
|
||||||
|
|
||||||
|
c8 tmp[256];
|
||||||
|
sprintf(tmp, "Needed %ums to create OctreeTriangleSelector.(%d nodes, %u polys)",
|
||||||
|
os::Timer::getRealTime() - start, NodeCount, Triangles.size());
|
||||||
|
os::Printer::log(tmp, ELL_INFORMATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//! destructor
|
//! destructor
|
||||||
COctreeTriangleSelector::~COctreeTriangleSelector()
|
COctreeTriangleSelector::~COctreeTriangleSelector()
|
||||||
|
@ -111,15 +136,19 @@ void COctreeTriangleSelector::constructOctree(SOctreeNode* node)
|
||||||
void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles,
|
void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
s32 arraySize, s32& outTriangleCount,
|
s32 arraySize, s32& outTriangleCount,
|
||||||
const core::aabbox3d<f32>& box,
|
const core::aabbox3d<f32>& box,
|
||||||
const core::matrix4* transform) const
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
core::matrix4 mat(core::matrix4::EM4CONST_NOTHING);
|
core::matrix4 mat(core::matrix4::EM4CONST_NOTHING);
|
||||||
core::aabbox3d<f32> invbox = box;
|
core::aabbox3d<f32> invbox = box;
|
||||||
|
|
||||||
if (SceneNode)
|
if (SceneNode && useNodeTransform)
|
||||||
{
|
{
|
||||||
SceneNode->getAbsoluteTransformation().getInverse(mat);
|
if ( SceneNode->getAbsoluteTransformation().getInverse(mat) )
|
||||||
mat.transformBoxEx(invbox);
|
mat.transformBoxEx(invbox);
|
||||||
|
else
|
||||||
|
// TODO: case not handled well, we can only return all triangles
|
||||||
|
return CTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, transform, useNodeTransform, outTriangleInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transform)
|
if (transform)
|
||||||
|
@ -127,7 +156,7 @@ void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
else
|
else
|
||||||
mat.makeIdentity();
|
mat.makeIdentity();
|
||||||
|
|
||||||
if (SceneNode)
|
if (SceneNode && useNodeTransform)
|
||||||
mat *= SceneNode->getAbsoluteTransformation();
|
mat *= SceneNode->getAbsoluteTransformation();
|
||||||
|
|
||||||
s32 trianglesWritten = 0;
|
s32 trianglesWritten = 0;
|
||||||
|
@ -136,6 +165,17 @@ void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
getTrianglesFromOctree(Root, trianglesWritten,
|
getTrianglesFromOctree(Root, trianglesWritten,
|
||||||
arraySize, invbox, &mat, triangles);
|
arraySize, invbox, &mat, triangles);
|
||||||
|
|
||||||
|
if ( outTriangleInfo )
|
||||||
|
{
|
||||||
|
SCollisionTriangleRange triRange;
|
||||||
|
triRange.RangeSize = trianglesWritten;
|
||||||
|
triRange.Selector = const_cast<COctreeTriangleSelector*>(this);
|
||||||
|
triRange.SceneNode = SceneNode;
|
||||||
|
triRange.MeshBuffer = MeshBuffer;
|
||||||
|
triRange.MaterialIndex = MaterialIndex;
|
||||||
|
outTriangleInfo->push_back(triRange);
|
||||||
|
}
|
||||||
|
|
||||||
outTriangleCount = trianglesWritten;
|
outTriangleCount = trianglesWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +220,8 @@ void COctreeTriangleSelector::getTrianglesFromOctree(
|
||||||
// new version: from user Piraaate
|
// new version: from user Piraaate
|
||||||
void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
|
void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::line3d<f32>& line,
|
s32& outTriangleCount, const core::line3d<f32>& line,
|
||||||
const core::matrix4* transform) const
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
core::aabbox3d<f32> box(line.start);
|
core::aabbox3d<f32> box(line.start);
|
||||||
|
@ -194,7 +235,7 @@ void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arr
|
||||||
core::matrix4 mat ( core::matrix4::EM4CONST_NOTHING );
|
core::matrix4 mat ( core::matrix4::EM4CONST_NOTHING );
|
||||||
|
|
||||||
core::vector3df vectStartInv ( line.start ), vectEndInv ( line.end );
|
core::vector3df vectStartInv ( line.start ), vectEndInv ( line.end );
|
||||||
if (SceneNode)
|
if (SceneNode && useNodeTransform)
|
||||||
{
|
{
|
||||||
mat = SceneNode->getAbsoluteTransformation();
|
mat = SceneNode->getAbsoluteTransformation();
|
||||||
mat.makeInverse();
|
mat.makeInverse();
|
||||||
|
@ -208,7 +249,7 @@ void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arr
|
||||||
if (transform)
|
if (transform)
|
||||||
mat = (*transform);
|
mat = (*transform);
|
||||||
|
|
||||||
if (SceneNode)
|
if (SceneNode && useNodeTransform)
|
||||||
mat *= SceneNode->getAbsoluteTransformation();
|
mat *= SceneNode->getAbsoluteTransformation();
|
||||||
|
|
||||||
s32 trianglesWritten = 0;
|
s32 trianglesWritten = 0;
|
||||||
|
@ -216,6 +257,17 @@ void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arr
|
||||||
if (Root)
|
if (Root)
|
||||||
getTrianglesFromOctree(Root, trianglesWritten, arraySize, invline, &mat, triangles);
|
getTrianglesFromOctree(Root, trianglesWritten, arraySize, invline, &mat, triangles);
|
||||||
|
|
||||||
|
if ( outTriangleInfo )
|
||||||
|
{
|
||||||
|
SCollisionTriangleRange triRange;
|
||||||
|
triRange.RangeSize = trianglesWritten;
|
||||||
|
triRange.Selector = const_cast<COctreeTriangleSelector*>(this);
|
||||||
|
triRange.SceneNode = SceneNode;
|
||||||
|
triRange.MeshBuffer = MeshBuffer;
|
||||||
|
triRange.MaterialIndex = MaterialIndex;
|
||||||
|
outTriangleInfo->push_back(triRange);
|
||||||
|
}
|
||||||
|
|
||||||
outTriangleCount = trianglesWritten;
|
outTriangleCount = trianglesWritten;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -262,4 +314,3 @@ void COctreeTriangleSelector::getTrianglesFromOctree(SOctreeNode* node,
|
||||||
|
|
||||||
} // end namespace scene
|
} // end namespace scene
|
||||||
} // end namespace irr
|
} // end namespace irr
|
||||||
|
|
||||||
|
|
|
@ -22,16 +22,21 @@ public:
|
||||||
//! Constructs a selector based on a mesh
|
//! Constructs a selector based on a mesh
|
||||||
COctreeTriangleSelector(const IMesh* mesh, ISceneNode* node, s32 minimalPolysPerNode);
|
COctreeTriangleSelector(const IMesh* mesh, ISceneNode* node, s32 minimalPolysPerNode);
|
||||||
|
|
||||||
|
//! Constructs a selector based on a meshbuffer
|
||||||
|
COctreeTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node, s32 minimalPolysPerNode);
|
||||||
|
|
||||||
virtual ~COctreeTriangleSelector();
|
virtual ~COctreeTriangleSelector();
|
||||||
|
|
||||||
//! Gets all triangles which lie within a specific bounding box.
|
//! Gets all triangles which lie within a specific bounding box.
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
||||||
const core::aabbox3d<f32>& box, const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
const core::aabbox3d<f32>& box, const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Gets all triangles which have or may have contact with a 3d line.
|
//! Gets all triangles which have or may have contact with a 3d line.
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::line3d<f32>& line,
|
s32& outTriangleCount, const core::line3d<f32>& line,
|
||||||
const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,6 @@ COpenGLCacheHandler::COpenGLCacheHandler(COpenGLDriver* driver) :
|
||||||
glAlphaFunc(AlphaMode, AlphaRef);
|
glAlphaFunc(AlphaMode, AlphaRef);
|
||||||
glDisable(GL_ALPHA_TEST);
|
glDisable(GL_ALPHA_TEST);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
glMatrixMode(MatrixMode);
|
glMatrixMode(MatrixMode);
|
||||||
|
|
||||||
Driver->irrGlClientActiveTexture(ClientActiveTexture);
|
Driver->irrGlClientActiveTexture(ClientActiveTexture);
|
||||||
|
|
|
@ -1087,14 +1087,19 @@ void COpenGLDriver::renderArray(const void* indexList, u32 primitiveCount,
|
||||||
glPointSize(particleSize);
|
glPointSize(particleSize);
|
||||||
|
|
||||||
#ifdef GL_ARB_point_sprite
|
#ifdef GL_ARB_point_sprite
|
||||||
if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite])
|
if (pType == scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite])
|
||||||
glTexEnvf(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE, GL_TRUE);
|
{
|
||||||
|
CacheHandler->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
|
glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE, GL_TRUE);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
glDrawArrays(GL_POINTS, 0, primitiveCount);
|
glDrawArrays(GL_POINTS, 0, primitiveCount);
|
||||||
#ifdef GL_ARB_point_sprite
|
#ifdef GL_ARB_point_sprite
|
||||||
if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite])
|
if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite])
|
||||||
{
|
{
|
||||||
glDisable(GL_POINT_SPRITE_ARB);
|
glDisable(GL_POINT_SPRITE_ARB);
|
||||||
|
|
||||||
|
CacheHandler->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
glTexEnvf(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE, GL_FALSE);
|
glTexEnvf(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE, GL_FALSE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2098,8 +2103,6 @@ void COpenGLDriver::setMaterial(const SMaterial& material)
|
||||||
CacheHandler->getTextureCache().set(i, material.getTexture(i));
|
CacheHandler->getTextureCache().set(i, material.getTexture(i));
|
||||||
setTransform((E_TRANSFORMATION_STATE)(ETS_TEXTURE_0 + i), material.getTextureMatrix(i));
|
setTransform((E_TRANSFORMATION_STATE)(ETS_TEXTURE_0 + i), material.getTextureMatrix(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
CacheHandler->setActiveTexture(GL_TEXTURE0_ARB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2148,6 +2151,8 @@ void COpenGLDriver::setRenderStates3DMode()
|
||||||
CacheHandler->setBlend(false);
|
CacheHandler->setBlend(false);
|
||||||
CacheHandler->setAlphaTest(false);
|
CacheHandler->setAlphaTest(false);
|
||||||
CacheHandler->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
CacheHandler->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
CacheHandler->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
|
||||||
// switch back the matrices
|
// switch back the matrices
|
||||||
CacheHandler->setMatrixMode(GL_MODELVIEW);
|
CacheHandler->setMatrixMode(GL_MODELVIEW);
|
||||||
|
@ -2747,7 +2752,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
|
||||||
{
|
{
|
||||||
// Set textures to TU/TIU and apply filters to them
|
// Set textures to TU/TIU and apply filters to them
|
||||||
|
|
||||||
for (s32 i = Feature.TextureUnit - 1; i>= 0; --i)
|
for (s32 i = Feature.TextureUnit - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
bool fixedPipeline = false;
|
bool fixedPipeline = false;
|
||||||
|
|
||||||
|
@ -2756,149 +2761,146 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
|
||||||
|
|
||||||
const COpenGLTexture* tmpTexture = CacheHandler->getTextureCache().get(i);
|
const COpenGLTexture* tmpTexture = CacheHandler->getTextureCache().get(i);
|
||||||
|
|
||||||
if (!tmpTexture)
|
if (tmpTexture)
|
||||||
continue;
|
|
||||||
|
|
||||||
CacheHandler->setActiveTexture(GL_TEXTURE0 + i);
|
|
||||||
|
|
||||||
if (fixedPipeline)
|
|
||||||
{
|
{
|
||||||
const bool isRTT = tmpTexture->isRenderTarget();
|
CacheHandler->setActiveTexture(GL_TEXTURE0 + i);
|
||||||
|
|
||||||
CacheHandler->setMatrixMode(GL_TEXTURE);
|
if (fixedPipeline)
|
||||||
|
|
||||||
if (!isRTT && Matrices[ETS_TEXTURE_0 + i].isIdentity())
|
|
||||||
glLoadIdentity();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
GLfloat glmat[16];
|
const bool isRTT = tmpTexture->isRenderTarget();
|
||||||
if (isRTT)
|
|
||||||
getGLTextureMatrix(glmat, Matrices[ETS_TEXTURE_0 + i] * TextureFlipMatrix);
|
CacheHandler->setMatrixMode(GL_TEXTURE);
|
||||||
|
|
||||||
|
if (!isRTT && Matrices[ETS_TEXTURE_0 + i].isIdentity())
|
||||||
|
glLoadIdentity();
|
||||||
else
|
else
|
||||||
getGLTextureMatrix(glmat, Matrices[ETS_TEXTURE_0 + i]);
|
{
|
||||||
glLoadMatrixf(glmat);
|
GLfloat glmat[16];
|
||||||
|
if (isRTT)
|
||||||
|
getGLTextureMatrix(glmat, Matrices[ETS_TEXTURE_0 + i] * TextureFlipMatrix);
|
||||||
|
else
|
||||||
|
getGLTextureMatrix(glmat, Matrices[ETS_TEXTURE_0 + i]);
|
||||||
|
glLoadMatrixf(glmat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const GLenum tmpType = tmpTexture->getOpenGLTextureType();
|
const GLenum tmpType = tmpTexture->getOpenGLTextureType();
|
||||||
|
|
||||||
COpenGLTexture::SStatesCache& statesCache = tmpTexture->getStatesCache();
|
COpenGLTexture::SStatesCache& statesCache = tmpTexture->getStatesCache();
|
||||||
|
|
||||||
if (resetAllRenderstates)
|
if (resetAllRenderstates)
|
||||||
statesCache.IsCached = false;
|
statesCache.IsCached = false;
|
||||||
|
|
||||||
#ifdef GL_VERSION_2_1
|
#ifdef GL_VERSION_2_1
|
||||||
if (Version>=210)
|
if (Version >= 210)
|
||||||
{
|
{
|
||||||
if (!statesCache.IsCached || material.TextureLayer[i].LODBias != statesCache.LODBias)
|
if (!statesCache.IsCached || material.TextureLayer[i].LODBias != statesCache.LODBias)
|
||||||
|
{
|
||||||
|
if (material.TextureLayer[i].LODBias)
|
||||||
|
{
|
||||||
|
const float tmp = core::clamp(material.TextureLayer[i].LODBias * 0.125f, -MaxTextureLODBias, MaxTextureLODBias);
|
||||||
|
glTexParameterf(tmpType, GL_TEXTURE_LOD_BIAS, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
glTexParameterf(tmpType, GL_TEXTURE_LOD_BIAS, 0.f);
|
||||||
|
|
||||||
|
statesCache.LODBias = material.TextureLayer[i].LODBias;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (FeatureAvailable[IRR_EXT_texture_lod_bias])
|
||||||
{
|
{
|
||||||
if (material.TextureLayer[i].LODBias)
|
if (material.TextureLayer[i].LODBias)
|
||||||
{
|
{
|
||||||
const float tmp = core::clamp(material.TextureLayer[i].LODBias * 0.125f, -MaxTextureLODBias, MaxTextureLODBias);
|
const float tmp = core::clamp(material.TextureLayer[i].LODBias * 0.125f, -MaxTextureLODBias, MaxTextureLODBias);
|
||||||
glTexParameterf(tmpType, GL_TEXTURE_LOD_BIAS, tmp);
|
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, tmp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
glTexParameterf(tmpType, GL_TEXTURE_LOD_BIAS, 0.f);
|
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.f);
|
||||||
|
|
||||||
statesCache.LODBias = material.TextureLayer[i].LODBias;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (FeatureAvailable[IRR_EXT_texture_lod_bias])
|
|
||||||
{
|
|
||||||
if (material.TextureLayer[i].LODBias)
|
|
||||||
{
|
|
||||||
const float tmp = core::clamp(material.TextureLayer[i].LODBias * 0.125f, -MaxTextureLODBias, MaxTextureLODBias);
|
|
||||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, tmp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.f);
|
|
||||||
}
|
|
||||||
#elif defined(GL_EXT_texture_lod_bias)
|
#elif defined(GL_EXT_texture_lod_bias)
|
||||||
if (FeatureAvailable[IRR_EXT_texture_lod_bias])
|
if (FeatureAvailable[IRR_EXT_texture_lod_bias])
|
||||||
{
|
|
||||||
if (material.TextureLayer[i].LODBias)
|
|
||||||
{
|
{
|
||||||
const float tmp = core::clamp(material.TextureLayer[i].LODBias * 0.125f, -MaxTextureLODBias, MaxTextureLODBias);
|
if (material.TextureLayer[i].LODBias)
|
||||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, tmp);
|
{
|
||||||
|
const float tmp = core::clamp(material.TextureLayer[i].LODBias * 0.125f, -MaxTextureLODBias, MaxTextureLODBias);
|
||||||
|
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.f);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.f);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
|
|
||||||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter)
|
|
||||||
{
|
|
||||||
glTexParameteri(tmpType, GL_TEXTURE_MAG_FILTER,
|
|
||||||
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST);
|
|
||||||
|
|
||||||
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter;
|
|
||||||
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (material.UseMipMaps && tmpTexture->hasMipMaps())
|
|
||||||
{
|
|
||||||
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
|
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
|
||||||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter || !statesCache.MipMapStatus)
|
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter)
|
||||||
{
|
{
|
||||||
glTexParameteri(tmpType, GL_TEXTURE_MIN_FILTER,
|
glTexParameteri(tmpType, GL_TEXTURE_MAG_FILTER,
|
||||||
material.TextureLayer[i].TrilinearFilter ? GL_LINEAR_MIPMAP_LINEAR :
|
|
||||||
material.TextureLayer[i].BilinearFilter ? GL_LINEAR_MIPMAP_NEAREST :
|
|
||||||
GL_NEAREST_MIPMAP_NEAREST);
|
|
||||||
|
|
||||||
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter;
|
|
||||||
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
|
|
||||||
statesCache.MipMapStatus = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
|
|
||||||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter || statesCache.MipMapStatus)
|
|
||||||
{
|
|
||||||
glTexParameteri(tmpType, GL_TEXTURE_MIN_FILTER,
|
|
||||||
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST);
|
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST);
|
||||||
|
|
||||||
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter;
|
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter;
|
||||||
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
|
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
|
||||||
statesCache.MipMapStatus = false;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (material.UseMipMaps && tmpTexture->hasMipMaps())
|
||||||
|
{
|
||||||
|
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
|
||||||
|
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter || !statesCache.MipMapStatus)
|
||||||
|
{
|
||||||
|
glTexParameteri(tmpType, GL_TEXTURE_MIN_FILTER,
|
||||||
|
material.TextureLayer[i].TrilinearFilter ? GL_LINEAR_MIPMAP_LINEAR :
|
||||||
|
material.TextureLayer[i].BilinearFilter ? GL_LINEAR_MIPMAP_NEAREST :
|
||||||
|
GL_NEAREST_MIPMAP_NEAREST);
|
||||||
|
|
||||||
|
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter;
|
||||||
|
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
|
||||||
|
statesCache.MipMapStatus = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
|
||||||
|
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter || statesCache.MipMapStatus)
|
||||||
|
{
|
||||||
|
glTexParameteri(tmpType, GL_TEXTURE_MIN_FILTER,
|
||||||
|
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST);
|
||||||
|
|
||||||
|
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter;
|
||||||
|
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
|
||||||
|
statesCache.MipMapStatus = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef GL_EXT_texture_filter_anisotropic
|
#ifdef GL_EXT_texture_filter_anisotropic
|
||||||
if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic] &&
|
if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic] &&
|
||||||
(!statesCache.IsCached || material.TextureLayer[i].AnisotropicFilter != statesCache.AnisotropicFilter))
|
(!statesCache.IsCached || material.TextureLayer[i].AnisotropicFilter != statesCache.AnisotropicFilter))
|
||||||
{
|
{
|
||||||
glTexParameteri(tmpType, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
glTexParameteri(tmpType, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||||
material.TextureLayer[i].AnisotropicFilter>1 ? core::min_(MaxAnisotropy, material.TextureLayer[i].AnisotropicFilter) : 1);
|
material.TextureLayer[i].AnisotropicFilter > 1 ? core::min_(MaxAnisotropy, material.TextureLayer[i].AnisotropicFilter) : 1);
|
||||||
|
|
||||||
statesCache.AnisotropicFilter = material.TextureLayer[i].AnisotropicFilter;
|
statesCache.AnisotropicFilter = material.TextureLayer[i].AnisotropicFilter;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapU != statesCache.WrapU)
|
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapU != statesCache.WrapU)
|
||||||
{
|
{
|
||||||
glTexParameteri(tmpType, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayer[i].TextureWrapU));
|
glTexParameteri(tmpType, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayer[i].TextureWrapU));
|
||||||
statesCache.WrapU = material.TextureLayer[i].TextureWrapU;
|
statesCache.WrapU = material.TextureLayer[i].TextureWrapU;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapV != statesCache.WrapV)
|
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapV != statesCache.WrapV)
|
||||||
{
|
{
|
||||||
glTexParameteri(tmpType, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayer[i].TextureWrapV));
|
glTexParameteri(tmpType, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayer[i].TextureWrapV));
|
||||||
statesCache.WrapV = material.TextureLayer[i].TextureWrapV;
|
statesCache.WrapV = material.TextureLayer[i].TextureWrapV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapW != statesCache.WrapW)
|
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapW != statesCache.WrapW)
|
||||||
{
|
{
|
||||||
glTexParameteri(tmpType, GL_TEXTURE_WRAP_R, getTextureWrapMode(material.TextureLayer[i].TextureWrapW));
|
glTexParameteri(tmpType, GL_TEXTURE_WRAP_R, getTextureWrapMode(material.TextureLayer[i].TextureWrapW));
|
||||||
statesCache.WrapW = material.TextureLayer[i].TextureWrapW;
|
statesCache.WrapW = material.TextureLayer[i].TextureWrapW;
|
||||||
}
|
}
|
||||||
|
|
||||||
statesCache.IsCached = true;
|
statesCache.IsCached = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// be sure to leave in texture stage 0
|
|
||||||
CacheHandler->setActiveTexture(GL_TEXTURE0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2920,6 +2922,8 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
|
||||||
else
|
else
|
||||||
FixedPipelineState = COpenGLDriver::EOFPS_ENABLE;
|
FixedPipelineState = COpenGLDriver::EOFPS_ENABLE;
|
||||||
|
|
||||||
|
bool resetAllRenderStates = false;
|
||||||
|
|
||||||
if (CurrentRenderMode != ERM_2D || Transformation3DChanged)
|
if (CurrentRenderMode != ERM_2D || Transformation3DChanged)
|
||||||
{
|
{
|
||||||
// unset last 3d material
|
// unset last 3d material
|
||||||
|
@ -2928,6 +2932,7 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
|
||||||
if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size())
|
if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size())
|
||||||
MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial();
|
MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Transformation3DChanged)
|
if (Transformation3DChanged)
|
||||||
{
|
{
|
||||||
CacheHandler->setMatrixMode(GL_PROJECTION);
|
CacheHandler->setMatrixMode(GL_PROJECTION);
|
||||||
|
@ -2940,32 +2945,40 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
|
||||||
|
|
||||||
CacheHandler->setMatrixMode(GL_MODELVIEW);
|
CacheHandler->setMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
glTranslatef(0.375f, 0.375f, 0.0f);
|
glTranslatef(0.375f, 0.375f, 0.0f);
|
||||||
|
|
||||||
// Make sure we set first texture matrix
|
|
||||||
CacheHandler->setActiveTexture(GL_TEXTURE0);
|
|
||||||
|
|
||||||
Transformation3DChanged = false;
|
Transformation3DChanged = false;
|
||||||
}
|
}
|
||||||
if (!OverrideMaterial2DEnabled)
|
|
||||||
{
|
|
||||||
setBasicRenderStates(InitMaterial2D, LastMaterial, true);
|
|
||||||
LastMaterial = InitMaterial2D;
|
|
||||||
}
|
|
||||||
CacheHandler->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
CacheHandler->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
#ifdef GL_EXT_clip_volume_hint
|
#ifdef GL_EXT_clip_volume_hint
|
||||||
if (FeatureAvailable[IRR_EXT_clip_volume_hint])
|
if (FeatureAvailable[IRR_EXT_clip_volume_hint])
|
||||||
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST);
|
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
resetAllRenderStates = true;
|
||||||
}
|
}
|
||||||
if (OverrideMaterial2DEnabled)
|
|
||||||
|
SMaterial currentMaterial = (!OverrideMaterial2DEnabled) ? InitMaterial2D : OverrideMaterial2D;
|
||||||
|
currentMaterial.Lighting = false;
|
||||||
|
|
||||||
|
if (texture)
|
||||||
{
|
{
|
||||||
OverrideMaterial2D.Lighting=false;
|
setTransform(ETS_TEXTURE_0, core::IdentityMatrix);
|
||||||
setBasicRenderStates(OverrideMaterial2D, LastMaterial, false);
|
|
||||||
LastMaterial = OverrideMaterial2D;
|
// Due to the transformation change, the previous line would call a reset each frame
|
||||||
|
// but we can safely reset the variable as it was false before
|
||||||
|
Transformation3DChanged = false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CacheHandler->getTextureCache().set(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
setBasicRenderStates(currentMaterial, LastMaterial, resetAllRenderStates);
|
||||||
|
|
||||||
|
LastMaterial = currentMaterial;
|
||||||
|
|
||||||
// no alphaChannel without texture
|
// no alphaChannel without texture
|
||||||
alphaChannel &= texture;
|
alphaChannel &= texture;
|
||||||
|
@ -2984,23 +2997,14 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
|
||||||
|
|
||||||
if (texture)
|
if (texture)
|
||||||
{
|
{
|
||||||
if (OverrideMaterial2DEnabled)
|
CacheHandler->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
setTextureRenderStates(OverrideMaterial2D, false);
|
|
||||||
else
|
|
||||||
setTextureRenderStates(InitMaterial2D, false);
|
|
||||||
|
|
||||||
Material.setTexture(0, const_cast<COpenGLTexture*>(CacheHandler->getTextureCache()[0]));
|
|
||||||
setTransform(ETS_TEXTURE_0, core::IdentityMatrix);
|
|
||||||
// Due to the transformation change, the previous line would call a reset each frame
|
|
||||||
// but we can safely reset the variable as it was false before
|
|
||||||
Transformation3DChanged=false;
|
|
||||||
|
|
||||||
if (alphaChannel)
|
if (alphaChannel)
|
||||||
{
|
{
|
||||||
// if alpha and alpha texture just modulate, otherwise use only the alpha channel
|
// if alpha and alpha texture just modulate, otherwise use only the alpha channel
|
||||||
if (alpha)
|
if (alpha)
|
||||||
{
|
{
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3008,26 +3012,26 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
|
||||||
if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine])
|
if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine])
|
||||||
{
|
{
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||||
// rgb always modulates
|
// rgb always modulates
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB);
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
||||||
// rgb always modulates
|
// rgb always modulates
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3038,21 +3042,21 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
|
||||||
if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine])
|
if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine])
|
||||||
{
|
{
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
||||||
// rgb always modulates
|
// rgb always modulates
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB);
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
|
||||||
// rgb always modulates
|
// rgb always modulates
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3532,6 +3536,67 @@ void COpenGLDriver::setFog(SColor c, E_FOG_TYPE fogType, f32 start,
|
||||||
glFogfv(GL_FOG_COLOR, data);
|
glFogfv(GL_FOG_COLOR, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Draws a 3d box.
|
||||||
|
void COpenGLDriver::draw3DBox( const core::aabbox3d<f32>& box, SColor color )
|
||||||
|
{
|
||||||
|
core::vector3df edges[8];
|
||||||
|
box.getEdges(edges);
|
||||||
|
|
||||||
|
setRenderStates3DMode();
|
||||||
|
|
||||||
|
video::S3DVertex v[24];
|
||||||
|
|
||||||
|
for(u32 i = 0; i < 24; i++)
|
||||||
|
v[i].Color = color;
|
||||||
|
|
||||||
|
v[0].Pos = edges[5];
|
||||||
|
v[1].Pos = edges[1];
|
||||||
|
v[2].Pos = edges[1];
|
||||||
|
v[3].Pos = edges[3];
|
||||||
|
v[4].Pos = edges[3];
|
||||||
|
v[5].Pos = edges[7];
|
||||||
|
v[6].Pos = edges[7];
|
||||||
|
v[7].Pos = edges[5];
|
||||||
|
v[8].Pos = edges[0];
|
||||||
|
v[9].Pos = edges[2];
|
||||||
|
v[10].Pos = edges[2];
|
||||||
|
v[11].Pos = edges[6];
|
||||||
|
v[12].Pos = edges[6];
|
||||||
|
v[13].Pos = edges[4];
|
||||||
|
v[14].Pos = edges[4];
|
||||||
|
v[15].Pos = edges[0];
|
||||||
|
v[16].Pos = edges[1];
|
||||||
|
v[17].Pos = edges[0];
|
||||||
|
v[18].Pos = edges[3];
|
||||||
|
v[19].Pos = edges[2];
|
||||||
|
v[20].Pos = edges[7];
|
||||||
|
v[21].Pos = edges[6];
|
||||||
|
v[22].Pos = edges[5];
|
||||||
|
v[23].Pos = edges[4];
|
||||||
|
|
||||||
|
if (!FeatureAvailable[IRR_ARB_vertex_array_bgra] && !FeatureAvailable[IRR_EXT_vertex_array_bgra])
|
||||||
|
getColorBuffer(v, 24, EVT_STANDARD);
|
||||||
|
|
||||||
|
CacheHandler->setClientState(true, false, true, false);
|
||||||
|
|
||||||
|
glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(v))[0].Pos);
|
||||||
|
|
||||||
|
#ifdef GL_BGRA
|
||||||
|
const GLint colorSize=(FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])?GL_BGRA:4;
|
||||||
|
#else
|
||||||
|
const GLint colorSize=4;
|
||||||
|
#endif
|
||||||
|
if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])
|
||||||
|
glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(v))[0].Color);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_IRR_DEBUG_BREAK_IF(ColorBuffer.size()==0);
|
||||||
|
glColorPointer(colorSize, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
glDrawArrays(GL_LINES, 0, 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Draws a 3d line.
|
//! Draws a 3d line.
|
||||||
void COpenGLDriver::draw3DLine(const core::vector3df& start,
|
void COpenGLDriver::draw3DLine(const core::vector3df& start,
|
||||||
|
@ -4287,7 +4352,7 @@ void COpenGLDriver::getColorFormatParameters(ECOLOR_FORMAT format, GLint& intern
|
||||||
case ECF_G32R32F:
|
case ECF_G32R32F:
|
||||||
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
|
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
|
||||||
{
|
{
|
||||||
internalFormat = GL_RG32F;
|
internalFormat = GL_RG32F;
|
||||||
pixelFormat = GL_RG;
|
pixelFormat = GL_RG;
|
||||||
pixelType = GL_FLOAT;
|
pixelType = GL_FLOAT;
|
||||||
}
|
}
|
||||||
|
@ -4297,7 +4362,7 @@ void COpenGLDriver::getColorFormatParameters(ECOLOR_FORMAT format, GLint& intern
|
||||||
case ECF_A32B32G32R32F:
|
case ECF_A32B32G32R32F:
|
||||||
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_float))
|
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_float))
|
||||||
{
|
{
|
||||||
internalFormat = GL_RGBA32F_ARB;
|
internalFormat = GL_RGBA32F_ARB;
|
||||||
pixelFormat = GL_RGBA;
|
pixelFormat = GL_RGBA;
|
||||||
pixelType = GL_FLOAT;
|
pixelType = GL_FLOAT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,6 +198,9 @@ namespace video
|
||||||
//! Draws a single pixel
|
//! Draws a single pixel
|
||||||
virtual void drawPixel(u32 x, u32 y, const SColor & color) _IRR_OVERRIDE_;
|
virtual void drawPixel(u32 x, u32 y, const SColor & color) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
//! Draws a 3d box
|
||||||
|
virtual void draw3DBox( const core::aabbox3d<f32>& box, SColor color = SColor(255,255,255,255 ) ) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Draws a 3d line.
|
//! Draws a 3d line.
|
||||||
virtual void draw3DLine(const core::vector3df& start,
|
virtual void draw3DLine(const core::vector3df& start,
|
||||||
const core::vector3df& end,
|
const core::vector3df& end,
|
||||||
|
|
|
@ -35,13 +35,6 @@ public:
|
||||||
|
|
||||||
Driver->disableTextures(1);
|
Driver->disableTextures(1);
|
||||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||||
|
|
||||||
if (resetAllRenderstates || (material.MaterialType != lastMaterial.MaterialType))
|
|
||||||
{
|
|
||||||
// thanks to Murphy, the following line removed some
|
|
||||||
// bugs with several OpenGL implementations.
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -89,17 +82,19 @@ public:
|
||||||
Driver->getCacheHandler()->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));
|
Driver->getCacheHandler()->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
|
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (f32) modulate );
|
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (f32) modulate );
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate );
|
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -109,33 +104,33 @@ public:
|
||||||
if (alphaSource==EAS_VERTEX_COLOR)
|
if (alphaSource==EAS_VERTEX_COLOR)
|
||||||
{
|
{
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (alphaSource==EAS_TEXTURE)
|
else if (alphaSource==EAS_TEXTURE)
|
||||||
{
|
{
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_TEXTURE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,15 +139,18 @@ public:
|
||||||
|
|
||||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||||
{
|
{
|
||||||
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.f );
|
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.f );
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
|
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Driver->getCacheHandler()->setBlend(false);
|
Driver->getCacheHandler()->setBlend(false);
|
||||||
|
@ -195,23 +193,23 @@ public:
|
||||||
{
|
{
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PRIMARY_COLOR);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PRIMARY_COLOR);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,13 +220,14 @@ public:
|
||||||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||||
{
|
{
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||||
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
|
||||||
#endif
|
#endif
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,9 +257,6 @@ public:
|
||||||
|
|
||||||
Driver->getCacheHandler()->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
|
Driver->getCacheHandler()->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
|
||||||
Driver->getCacheHandler()->setBlend(true);
|
Driver->getCacheHandler()->setBlend(true);
|
||||||
|
|
||||||
if ((material.MaterialType != lastMaterial.MaterialType) || resetAllRenderstates)
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||||
|
@ -303,35 +299,39 @@ public:
|
||||||
|
|
||||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||||
{
|
{
|
||||||
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
|
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT );
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT );
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||||
{
|
{
|
||||||
// default values
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE );
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE );
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Driver->getCacheHandler()->setBlend(false);
|
Driver->getCacheHandler()->setBlend(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,34 +370,37 @@ public:
|
||||||
Driver->getCacheHandler()->setAlphaTest(true);
|
Driver->getCacheHandler()->setAlphaTest(true);
|
||||||
Driver->getCacheHandler()->setAlphaFunc(GL_GREATER, material.MaterialTypeParam);
|
Driver->getCacheHandler()->setAlphaFunc(GL_GREATER, material.MaterialTypeParam);
|
||||||
|
|
||||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates
|
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates || material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
|
||||||
|| material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
|
|
||||||
{
|
{
|
||||||
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
|
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||||
{
|
{
|
||||||
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
|
||||||
#endif
|
#endif
|
||||||
Driver->getCacheHandler()->setAlphaTest(false);
|
Driver->getCacheHandler()->setAlphaTest(false);
|
||||||
Driver->getCacheHandler()->setBlend(false);
|
Driver->getCacheHandler()->setBlend(false);
|
||||||
|
@ -437,7 +440,6 @@ public:
|
||||||
{
|
{
|
||||||
Driver->getCacheHandler()->setAlphaTest(true);
|
Driver->getCacheHandler()->setAlphaTest(true);
|
||||||
Driver->getCacheHandler()->setAlphaFunc(GL_GREATER, 0.5f);
|
Driver->getCacheHandler()->setAlphaFunc(GL_GREATER, 0.5f);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,6 +480,8 @@ public:
|
||||||
|
|
||||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||||
{
|
{
|
||||||
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
|
|
||||||
// diffuse map
|
// diffuse map
|
||||||
|
|
||||||
switch (material.MaterialType)
|
switch (material.MaterialType)
|
||||||
|
@ -511,7 +515,7 @@ public:
|
||||||
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB);
|
||||||
#else
|
#else
|
||||||
|
@ -524,7 +528,7 @@ public:
|
||||||
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT);
|
||||||
#endif
|
#endif
|
||||||
|
@ -554,7 +558,6 @@ public:
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f);
|
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -564,15 +567,17 @@ public:
|
||||||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||||
{
|
{
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||||
|
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.f );
|
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.f );
|
||||||
#else
|
#else
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
|
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
|
||||||
#endif
|
#endif
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -602,12 +607,11 @@ public:
|
||||||
|
|
||||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||||
{
|
{
|
||||||
// diffuse map is default modulated
|
|
||||||
|
|
||||||
// detail map on second layer
|
// detail map on second layer
|
||||||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||||
{
|
{
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||||
|
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB);
|
||||||
|
@ -628,8 +632,8 @@ public:
|
||||||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||||
{
|
{
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||||
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,6 +667,8 @@ public:
|
||||||
|
|
||||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||||
{
|
{
|
||||||
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
|
|
||||||
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
||||||
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
||||||
|
|
||||||
|
@ -673,6 +679,8 @@ public:
|
||||||
|
|
||||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||||
{
|
{
|
||||||
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_GEN_S);
|
glDisable(GL_TEXTURE_GEN_S);
|
||||||
glDisable(GL_TEXTURE_GEN_T);
|
glDisable(GL_TEXTURE_GEN_T);
|
||||||
}
|
}
|
||||||
|
@ -706,6 +714,7 @@ public:
|
||||||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||||
{
|
{
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||||
|
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||||
|
@ -717,11 +726,12 @@ public:
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
||||||
|
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
||||||
|
glEnable(GL_TEXTURE_GEN_S);
|
||||||
|
glEnable(GL_TEXTURE_GEN_T);
|
||||||
}
|
}
|
||||||
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
|
||||||
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
|
||||||
glEnable(GL_TEXTURE_GEN_S);
|
|
||||||
glEnable(GL_TEXTURE_GEN_T);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,13 +740,10 @@ public:
|
||||||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||||
{
|
{
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||||
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
}
|
glDisable(GL_TEXTURE_GEN_S);
|
||||||
glDisable(GL_TEXTURE_GEN_S);
|
glDisable(GL_TEXTURE_GEN_T);
|
||||||
glDisable(GL_TEXTURE_GEN_T);
|
|
||||||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
|
||||||
{
|
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,20 +776,22 @@ public:
|
||||||
|
|
||||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||||
{
|
{
|
||||||
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
|
|
||||||
#ifdef GL_ARB_texture_env_combine
|
#ifdef GL_ARB_texture_env_combine
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
|
||||||
#else
|
#else
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB);
|
||||||
#endif
|
#endif
|
||||||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||||
{
|
{
|
||||||
|
@ -802,11 +811,12 @@ public:
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
||||||
|
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
||||||
|
glEnable(GL_TEXTURE_GEN_S);
|
||||||
|
glEnable(GL_TEXTURE_GEN_T);
|
||||||
}
|
}
|
||||||
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
|
||||||
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
|
||||||
glEnable(GL_TEXTURE_GEN_S);
|
|
||||||
glEnable(GL_TEXTURE_GEN_T);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,14 +825,17 @@ public:
|
||||||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||||
{
|
{
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||||
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
|
||||||
|
glDisable(GL_TEXTURE_GEN_S);
|
||||||
|
glDisable(GL_TEXTURE_GEN_T);
|
||||||
}
|
}
|
||||||
glDisable(GL_TEXTURE_GEN_S);
|
|
||||||
glDisable(GL_TEXTURE_GEN_T);
|
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
|
||||||
{
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
|
||||||
}
|
|
||||||
Driver->getCacheHandler()->setBlend(false);
|
Driver->getCacheHandler()->setBlend(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -469,7 +469,7 @@ void CPLYMeshFileLoader::fillBuffer()
|
||||||
if (EndOfFile)
|
if (EndOfFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u32 length = (u32)(EndPointer - StartPointer);
|
size_t length = (size_t)(EndPointer - StartPointer);
|
||||||
if (length && StartPointer != Buffer)
|
if (length && StartPointer != Buffer)
|
||||||
{
|
{
|
||||||
// copy the remaining data to the start of the buffer
|
// copy the remaining data to the start of the buffer
|
||||||
|
@ -486,7 +486,7 @@ void CPLYMeshFileLoader::fillBuffer()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// read data from the file
|
// read data from the file
|
||||||
u32 count = File->read(EndPointer, PLY_INPUT_BUFFER_SIZE - length);
|
size_t count = File->read(EndPointer, PLY_INPUT_BUFFER_SIZE - length);
|
||||||
|
|
||||||
// increment the end pointer by the number of bytes read
|
// increment the end pointer by the number of bytes read
|
||||||
EndPointer = EndPointer + count;
|
EndPointer = EndPointer + count;
|
||||||
|
|
|
@ -225,16 +225,12 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root,
|
||||||
|
|
||||||
|
|
||||||
ISceneNode* CSceneCollisionManager::getSceneNodeAndCollisionPointFromRay(
|
ISceneNode* CSceneCollisionManager::getSceneNodeAndCollisionPointFromRay(
|
||||||
|
SCollisionHit& hitResult,
|
||||||
const core::line3df& ray,
|
const core::line3df& ray,
|
||||||
core::vector3df & outCollisionPoint,
|
|
||||||
core::triangle3df & outTriangle,
|
|
||||||
s32 idBitMask,
|
s32 idBitMask,
|
||||||
ISceneNode * collisionRootNode,
|
ISceneNode * collisionRootNode,
|
||||||
bool noDebugObjects)
|
bool noDebugObjects)
|
||||||
{
|
{
|
||||||
ISceneNode* bestNode = 0;
|
|
||||||
f32 bestDistanceSquared = FLT_MAX;
|
|
||||||
|
|
||||||
if(0 == collisionRootNode)
|
if(0 == collisionRootNode)
|
||||||
collisionRootNode = SceneManager->getRootSceneNode();
|
collisionRootNode = SceneManager->getRootSceneNode();
|
||||||
|
|
||||||
|
@ -261,23 +257,21 @@ ISceneNode* CSceneCollisionManager::getSceneNodeAndCollisionPointFromRay(
|
||||||
// node in order to find the nearest collision point, so sorting them by
|
// node in order to find the nearest collision point, so sorting them by
|
||||||
// bounding box would be pointless.
|
// bounding box would be pointless.
|
||||||
|
|
||||||
|
f32 bestDistanceSquared = FLT_MAX;
|
||||||
core::line3df rayRest(ray);
|
core::line3df rayRest(ray);
|
||||||
getPickedNodeFromBBAndSelector(collisionRootNode, rayRest, idBitMask,
|
getPickedNodeFromBBAndSelector(hitResult, collisionRootNode, rayRest, idBitMask,
|
||||||
noDebugObjects, bestDistanceSquared, bestNode,
|
noDebugObjects, bestDistanceSquared);
|
||||||
outCollisionPoint, outTriangle);
|
return hitResult.Node;
|
||||||
return bestNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CSceneCollisionManager::getPickedNodeFromBBAndSelector(
|
void CSceneCollisionManager::getPickedNodeFromBBAndSelector(
|
||||||
|
SCollisionHit& hitResult,
|
||||||
ISceneNode * root,
|
ISceneNode * root,
|
||||||
core::line3df & ray,
|
core::line3df & ray,
|
||||||
s32 bits,
|
s32 bits,
|
||||||
bool noDebugObjects,
|
bool noDebugObjects,
|
||||||
f32 & outBestDistanceSquared,
|
f32 & outBestDistanceSquared)
|
||||||
ISceneNode * & outBestNode,
|
|
||||||
core::vector3df & outBestCollisionPoint,
|
|
||||||
core::triangle3df & outBestTriangle)
|
|
||||||
{
|
{
|
||||||
const ISceneNodeList& children = root->getChildren();
|
const ISceneNodeList& children = root->getChildren();
|
||||||
|
|
||||||
|
@ -303,31 +297,26 @@ void CSceneCollisionManager::getPickedNodeFromBBAndSelector(
|
||||||
|
|
||||||
const core::aabbox3df& box = current->getBoundingBox();
|
const core::aabbox3df& box = current->getBoundingBox();
|
||||||
|
|
||||||
core::vector3df candidateCollisionPoint;
|
SCollisionHit candidateHitResult;
|
||||||
core::triangle3df candidateTriangle;
|
|
||||||
|
|
||||||
// do intersection test in object space
|
// do intersection test in object space
|
||||||
ISceneNode * hitNode = 0;
|
|
||||||
if (box.intersectsWithLine(line) &&
|
if (box.intersectsWithLine(line) &&
|
||||||
getCollisionPoint(ray, selector, candidateCollisionPoint, candidateTriangle, hitNode))
|
getCollisionPoint(candidateHitResult, ray, selector))
|
||||||
{
|
{
|
||||||
const f32 distanceSquared = (candidateCollisionPoint - ray.start).getLengthSQ();
|
const f32 distanceSquared = (candidateHitResult.Intersection - ray.start).getLengthSQ();
|
||||||
|
|
||||||
if(distanceSquared < outBestDistanceSquared)
|
if(distanceSquared < outBestDistanceSquared)
|
||||||
{
|
{
|
||||||
outBestDistanceSquared = distanceSquared;
|
outBestDistanceSquared = distanceSquared;
|
||||||
outBestNode = current;
|
hitResult = candidateHitResult;
|
||||||
outBestCollisionPoint = candidateCollisionPoint;
|
|
||||||
outBestTriangle = candidateTriangle;
|
|
||||||
const core::vector3df rayVector = ray.getVector().normalize();
|
const core::vector3df rayVector = ray.getVector().normalize();
|
||||||
ray.end = ray.start + (rayVector * sqrtf(distanceSquared));
|
ray.end = ray.start + (rayVector * sqrtf(distanceSquared));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getPickedNodeFromBBAndSelector(current, ray, bits, noDebugObjects,
|
getPickedNodeFromBBAndSelector(hitResult, current, ray, bits, noDebugObjects,
|
||||||
outBestDistanceSquared, outBestNode,
|
outBestDistanceSquared);
|
||||||
outBestCollisionPoint, outBestTriangle);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,12 +337,7 @@ ISceneNode* CSceneCollisionManager::getSceneNodeFromCameraBB(
|
||||||
return getSceneNodeFromRayBB(core::line3d<f32>(start, end), idBitMask, noDebugObjects);
|
return getSceneNodeFromRayBB(core::line3d<f32>(start, end), idBitMask, noDebugObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSceneCollisionManager::getCollisionPoint(SCollisionHit& hitResult, const core::line3d<f32>& ray, ITriangleSelector* selector)
|
||||||
//! Finds the collision point of a line and lots of triangles, if there is one.
|
|
||||||
bool CSceneCollisionManager::getCollisionPoint(const core::line3d<f32>& ray,
|
|
||||||
ITriangleSelector* selector, core::vector3df& outIntersection,
|
|
||||||
core::triangle3df& outTriangle,
|
|
||||||
ISceneNode*& outNode)
|
|
||||||
{
|
{
|
||||||
if (!selector)
|
if (!selector)
|
||||||
{
|
{
|
||||||
|
@ -367,12 +351,13 @@ bool CSceneCollisionManager::getCollisionPoint(const core::line3d<f32>& ray,
|
||||||
Triangles.set_used(totalcnt);
|
Triangles.set_used(totalcnt);
|
||||||
|
|
||||||
s32 cnt = 0;
|
s32 cnt = 0;
|
||||||
selector->getTriangles(Triangles.pointer(), totalcnt, cnt, ray);
|
irr::core::array<SCollisionTriangleRange> outTriangleInfo;
|
||||||
|
selector->getTriangles(Triangles.pointer(), totalcnt, cnt, ray, 0, true, &outTriangleInfo);
|
||||||
|
|
||||||
const core::vector3df linevect = ray.getVector().normalize();
|
const core::vector3df linevect = ray.getVector().normalize();
|
||||||
core::vector3df intersection;
|
core::vector3df intersection;
|
||||||
f32 nearest = FLT_MAX;
|
f32 nearest = FLT_MAX;
|
||||||
bool found = false;
|
irr::s32 foundIndex = -1;
|
||||||
const f32 raylength = ray.getLengthSQ();
|
const f32 raylength = ray.getLengthSQ();
|
||||||
|
|
||||||
const f32 minX = core::min_(ray.start.X, ray.end.X);
|
const f32 minX = core::min_(ray.start.X, ray.end.X);
|
||||||
|
@ -407,17 +392,34 @@ bool CSceneCollisionManager::getCollisionPoint(const core::line3d<f32>& ray,
|
||||||
if (tmp < raylength && tmp2 < raylength && tmp < nearest)
|
if (tmp < raylength && tmp2 < raylength && tmp < nearest)
|
||||||
{
|
{
|
||||||
nearest = tmp;
|
nearest = tmp;
|
||||||
outTriangle = triangle;
|
|
||||||
outIntersection = intersection;
|
hitResult.Triangle = triangle;
|
||||||
outNode = selector->getSceneNodeForTriangle(i);
|
hitResult.Intersection = intersection;
|
||||||
found = true;
|
foundIndex = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
if ( foundIndex >= 0 )
|
||||||
}
|
{
|
||||||
|
for ( irr::u32 t=0; t<outTriangleInfo.size(); ++t )
|
||||||
|
{
|
||||||
|
if ( outTriangleInfo[t].isIndexInRange(foundIndex) )
|
||||||
|
{
|
||||||
|
hitResult.Node = outTriangleInfo[t].SceneNode;
|
||||||
|
hitResult.MeshBuffer = outTriangleInfo[t].MeshBuffer;
|
||||||
|
hitResult.MaterialIndex = outTriangleInfo[t].MaterialIndex;
|
||||||
|
hitResult.TriangleSelector = outTriangleInfo[t].Selector;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//! Collides a moving ellipsoid with a 3d world with gravity and returns
|
//! Collides a moving ellipsoid with a 3d world with gravity and returns
|
||||||
//! the resulting new position of the ellipsoid.
|
//! the resulting new position of the ellipsoid.
|
||||||
|
@ -666,6 +668,8 @@ bool CSceneCollisionManager::testTriangleIntersection(SCollisionData* colData,
|
||||||
// set result:
|
// set result:
|
||||||
if (foundCollision)
|
if (foundCollision)
|
||||||
{
|
{
|
||||||
|
++colData->triangleHits;
|
||||||
|
|
||||||
// distance to collision is t
|
// distance to collision is t
|
||||||
f32 distToCollision = t*colData->velocity.getLength();
|
f32 distToCollision = t*colData->velocity.getLength();
|
||||||
|
|
||||||
|
@ -677,7 +681,6 @@ bool CSceneCollisionManager::testTriangleIntersection(SCollisionData* colData,
|
||||||
colData->intersectionPoint = collisionPoint;
|
colData->intersectionPoint = collisionPoint;
|
||||||
colData->foundCollision = true;
|
colData->foundCollision = true;
|
||||||
colData->intersectionTriangle = triangle;
|
colData->intersectionTriangle = triangle;
|
||||||
++colData->triangleHits;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}// end found collision
|
}// end found collision
|
||||||
|
@ -712,7 +715,7 @@ core::vector3df CSceneCollisionManager::collideEllipsoidWithWorld(
|
||||||
colData.selector = selector;
|
colData.selector = selector;
|
||||||
colData.slidingSpeed = slidingSpeed;
|
colData.slidingSpeed = slidingSpeed;
|
||||||
colData.triangleHits = 0;
|
colData.triangleHits = 0;
|
||||||
colData.triangleIndex = -1;
|
colData.node = 0;
|
||||||
|
|
||||||
core::vector3df eSpacePosition = colData.R3Position / colData.eRadius;
|
core::vector3df eSpacePosition = colData.R3Position / colData.eRadius;
|
||||||
core::vector3df eSpaceVelocity = colData.R3Velocity / colData.eRadius;
|
core::vector3df eSpaceVelocity = colData.R3Velocity / colData.eRadius;
|
||||||
|
@ -746,7 +749,7 @@ core::vector3df CSceneCollisionManager::collideEllipsoidWithWorld(
|
||||||
triout.pointA *= colData.eRadius;
|
triout.pointA *= colData.eRadius;
|
||||||
triout.pointB *= colData.eRadius;
|
triout.pointB *= colData.eRadius;
|
||||||
triout.pointC *= colData.eRadius;
|
triout.pointC *= colData.eRadius;
|
||||||
outNode = selector->getSceneNodeForTriangle(colData.triangleIndex);
|
outNode = colData.node;
|
||||||
}
|
}
|
||||||
|
|
||||||
finalPos *= colData.eRadius;
|
finalPos *= colData.eRadius;
|
||||||
|
@ -787,12 +790,30 @@ core::vector3df CSceneCollisionManager::collideWithWorld(s32 recursionDepth,
|
||||||
1.0f / colData.eRadius.Y,
|
1.0f / colData.eRadius.Y,
|
||||||
1.0f / colData.eRadius.Z));
|
1.0f / colData.eRadius.Z));
|
||||||
|
|
||||||
|
irr::core::array<SCollisionTriangleRange> outTriangleInfo;
|
||||||
s32 triangleCnt = 0;
|
s32 triangleCnt = 0;
|
||||||
colData.selector->getTriangles(Triangles.pointer(), totalTriangleCnt, triangleCnt, box, &scaleMatrix);
|
colData.selector->getTriangles(Triangles.pointer(), totalTriangleCnt, triangleCnt, box, &scaleMatrix, true, &outTriangleInfo);
|
||||||
|
|
||||||
|
// Find closest intersection
|
||||||
|
irr::s32 nearestTriangleIndex = -1;
|
||||||
for (s32 i=0; i<triangleCnt; ++i)
|
for (s32 i=0; i<triangleCnt; ++i)
|
||||||
|
{
|
||||||
if(testTriangleIntersection(&colData, Triangles[i]))
|
if(testTriangleIntersection(&colData, Triangles[i]))
|
||||||
colData.triangleIndex = i;
|
{
|
||||||
|
nearestTriangleIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( nearestTriangleIndex >= 0 )
|
||||||
|
{
|
||||||
|
for ( irr::u32 t=0; t<outTriangleInfo.size(); ++t )
|
||||||
|
{
|
||||||
|
if ( outTriangleInfo[t].isIndexInRange(nearestTriangleIndex) )
|
||||||
|
{
|
||||||
|
colData.node = outTriangleInfo[t].SceneNode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---------------- end collide with world
|
//---------------- end collide with world
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,9 @@ namespace scene
|
||||||
virtual ISceneNode* getSceneNodeFromCameraBB(const ICameraSceneNode* camera,
|
virtual ISceneNode* getSceneNodeFromCameraBB(const ICameraSceneNode* camera,
|
||||||
s32 idBitMask=0, bool bNoDebugObjects = false) _IRR_OVERRIDE_;
|
s32 idBitMask=0, bool bNoDebugObjects = false) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Finds the collision point of a line and lots of triangles, if there is one.
|
//! Finds the nearest collision point of a line and lots of triangles, if there is one.
|
||||||
virtual bool getCollisionPoint(const core::line3d<f32>& ray,
|
virtual bool getCollisionPoint(SCollisionHit& hitResult, const core::line3d<f32>& ray,
|
||||||
ITriangleSelector* selector, core::vector3df& outCollisionPoint,
|
ITriangleSelector* selector) _IRR_OVERRIDE_;
|
||||||
core::triangle3df& outTriangle,
|
|
||||||
ISceneNode* & outNode) _IRR_OVERRIDE_;
|
|
||||||
|
|
||||||
//! Collides a moving ellipsoid with a 3d world with gravity and returns
|
//! Collides a moving ellipsoid with a 3d world with gravity and returns
|
||||||
//! the resulting new position of the ellipsoid.
|
//! the resulting new position of the ellipsoid.
|
||||||
|
@ -72,13 +70,11 @@ namespace scene
|
||||||
//! Gets the scene node and nearest collision point for a ray based on
|
//! Gets the scene node and nearest collision point for a ray based on
|
||||||
//! the nodes' id bitmasks, bounding boxes and triangle selectors.
|
//! the nodes' id bitmasks, bounding boxes and triangle selectors.
|
||||||
virtual ISceneNode* getSceneNodeAndCollisionPointFromRay(
|
virtual ISceneNode* getSceneNodeAndCollisionPointFromRay(
|
||||||
|
SCollisionHit& hitResult,
|
||||||
const core::line3df& ray,
|
const core::line3df& ray,
|
||||||
core::vector3df& outCollisionPoint,
|
|
||||||
core::triangle3df& outTriangle,
|
|
||||||
s32 idBitMask = 0,
|
s32 idBitMask = 0,
|
||||||
ISceneNode * collisionRootNode = 0,
|
ISceneNode * collisionRootNode = 0,
|
||||||
bool noDebugObjects = false) _IRR_OVERRIDE_;
|
bool noDebugObjects = false) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -88,14 +84,13 @@ namespace scene
|
||||||
f32& outbestdistance, ISceneNode*& outbestnode);
|
f32& outbestdistance, ISceneNode*& outbestnode);
|
||||||
|
|
||||||
//! recursive method for going through all scene nodes
|
//! recursive method for going through all scene nodes
|
||||||
void getPickedNodeFromBBAndSelector(ISceneNode * root,
|
void getPickedNodeFromBBAndSelector(
|
||||||
|
SCollisionHit& hitResult,
|
||||||
|
ISceneNode * root,
|
||||||
core::line3df & ray,
|
core::line3df & ray,
|
||||||
s32 bits,
|
s32 bits,
|
||||||
bool noDebugObjects,
|
bool noDebugObjects,
|
||||||
f32 & outBestDistanceSquared,
|
f32 & outBestDistanceSquared);
|
||||||
ISceneNode * & outBestNode,
|
|
||||||
core::vector3df & outBestCollisionPoint,
|
|
||||||
core::triangle3df & outBestTriangle);
|
|
||||||
|
|
||||||
|
|
||||||
struct SCollisionData
|
struct SCollisionData
|
||||||
|
@ -114,7 +109,7 @@ namespace scene
|
||||||
core::vector3df intersectionPoint;
|
core::vector3df intersectionPoint;
|
||||||
|
|
||||||
core::triangle3df intersectionTriangle;
|
core::triangle3df intersectionTriangle;
|
||||||
s32 triangleIndex;
|
irr::scene::ISceneNode* node;
|
||||||
s32 triangleHits;
|
s32 triangleHits;
|
||||||
|
|
||||||
f32 slidingSpeed;
|
f32 slidingSpeed;
|
||||||
|
|
|
@ -1847,23 +1847,29 @@ IMeshManipulator* CSceneManager::getMeshManipulator()
|
||||||
|
|
||||||
|
|
||||||
//! Creates a simple ITriangleSelector, based on a mesh.
|
//! Creates a simple ITriangleSelector, based on a mesh.
|
||||||
ITriangleSelector* CSceneManager::createTriangleSelector(IMesh* mesh, ISceneNode* node)
|
ITriangleSelector* CSceneManager::createTriangleSelector(IMesh* mesh, ISceneNode* node, bool separateMeshbuffers)
|
||||||
{
|
{
|
||||||
if (!mesh)
|
if (!mesh)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return new CTriangleSelector(mesh, node);
|
return new CTriangleSelector(mesh, node, separateMeshbuffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
ITriangleSelector* CSceneManager::createTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node)
|
||||||
|
{
|
||||||
|
if ( !meshBuffer)
|
||||||
|
return 0;
|
||||||
|
return new CTriangleSelector(meshBuffer, materialIndex, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Creates a simple and updatable ITriangleSelector, based on a the mesh owned by an
|
//! Creates a ITriangleSelector, based on a the mesh owned by an animated scene node
|
||||||
//! animated scene node
|
ITriangleSelector* CSceneManager::createTriangleSelector(IAnimatedMeshSceneNode* node, bool separateMeshbuffers)
|
||||||
ITriangleSelector* CSceneManager::createTriangleSelector(IAnimatedMeshSceneNode* node)
|
|
||||||
{
|
{
|
||||||
if (!node || !node->getMesh())
|
if (!node || !node->getMesh())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return new CTriangleSelector(node);
|
return new CTriangleSelector(node, separateMeshbuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1887,6 +1893,14 @@ ITriangleSelector* CSceneManager::createOctreeTriangleSelector(IMesh* mesh,
|
||||||
return new COctreeTriangleSelector(mesh, node, minimalPolysPerNode);
|
return new COctreeTriangleSelector(mesh, node, minimalPolysPerNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ITriangleSelector* CSceneManager::createOctreeTriangleSelector(IMeshBuffer* meshBuffer, irr::u32 materialIndex,
|
||||||
|
ISceneNode* node, s32 minimalPolysPerNode)
|
||||||
|
{
|
||||||
|
if ( !meshBuffer)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return new COctreeTriangleSelector(meshBuffer, materialIndex, node, minimalPolysPerNode);
|
||||||
|
}
|
||||||
|
|
||||||
//! Creates a meta triangle selector.
|
//! Creates a meta triangle selector.
|
||||||
IMetaTriangleSelector* CSceneManager::createMetaTriangleSelector()
|
IMetaTriangleSelector* CSceneManager::createMetaTriangleSelector()
|
||||||
|
|
|
@ -343,19 +343,26 @@ namespace scene
|
||||||
|
|
||||||
|
|
||||||
//! Creates a simple ITriangleSelector, based on a mesh.
|
//! Creates a simple ITriangleSelector, based on a mesh.
|
||||||
virtual ITriangleSelector* createTriangleSelector(IMesh* mesh, ISceneNode* node) _IRR_OVERRIDE_;
|
virtual ITriangleSelector* createTriangleSelector(IMesh* mesh, ISceneNode* node, bool separateMeshbuffers) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
//! Creates a simple ITriangleSelector, based on a meshbuffer.
|
||||||
|
virtual ITriangleSelector* createTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Creates a simple ITriangleSelector, based on an animated mesh scene node.
|
//! Creates a simple ITriangleSelector, based on an animated mesh scene node.
|
||||||
//! Details of the mesh associated with the node will be extracted internally.
|
//! Details of the mesh associated with the node will be extracted internally.
|
||||||
//! Call ITriangleSelector::update() to have the triangle selector updated based
|
//! Call ITriangleSelector::update() to have the triangle selector updated based
|
||||||
//! on the current frame of the animated mesh scene node.
|
//! on the current frame of the animated mesh scene node.
|
||||||
//! \param: The animated mesh scene node from which to build the selector
|
//! \param: The animated mesh scene node from which to build the selector
|
||||||
virtual ITriangleSelector* createTriangleSelector(IAnimatedMeshSceneNode* node) _IRR_OVERRIDE_;
|
virtual ITriangleSelector* createTriangleSelector(IAnimatedMeshSceneNode* node, bool separateMeshbuffers) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Creates a simple ITriangleSelector, based on a mesh.
|
//! Creates a simple ITriangleSelector, based on a mesh.
|
||||||
virtual ITriangleSelector* createOctreeTriangleSelector(IMesh* mesh,
|
virtual ITriangleSelector* createOctreeTriangleSelector(IMesh* mesh,
|
||||||
ISceneNode* node, s32 minimalPolysPerNode) _IRR_OVERRIDE_;
|
ISceneNode* node, s32 minimalPolysPerNode) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
//! Creates a simple ITriangleSelector, based on a meshbuffer.
|
||||||
|
virtual ITriangleSelector* createOctreeTriangleSelector(IMeshBuffer* meshBuffer, irr::u32 materialIndex,
|
||||||
|
ISceneNode* node, s32 minimalPolysPerNode=32) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box.
|
//! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box.
|
||||||
virtual ITriangleSelector* createTriangleSelectorFromBoundingBox(
|
virtual ITriangleSelector* createTriangleSelectorFromBoundingBox(
|
||||||
ISceneNode* node) _IRR_OVERRIDE_;
|
ISceneNode* node) _IRR_OVERRIDE_;
|
||||||
|
|
|
@ -202,7 +202,8 @@ void CSceneNodeAnimatorCollisionResponse::animateNode(ISceneNode* node, u32 time
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Falling = false;
|
if ( CollisionOccurred ) // f can also happen to be false when FallingVelocity was already 0 (p.e. at top of a jump)
|
||||||
|
Falling = false;
|
||||||
FallingVelocity.set(0, 0, 0);
|
FallingVelocity.set(0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,8 @@ void CTerrainTriangleSelector::setTriangleData(ITerrainSceneNode* node, s32 LOD)
|
||||||
//! Gets all triangles.
|
//! Gets all triangles.
|
||||||
void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
s32 arraySize, s32& outTriangleCount,
|
s32 arraySize, s32& outTriangleCount,
|
||||||
const core::matrix4* transform) const
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
s32 count = TrianglePatches.TotalTriangles;
|
s32 count = TrianglePatches.TotalTriangles;
|
||||||
|
|
||||||
|
@ -106,6 +107,15 @@ void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( outTriangleInfo )
|
||||||
|
{
|
||||||
|
SCollisionTriangleRange triRange;
|
||||||
|
triRange.RangeSize = tIndex;
|
||||||
|
triRange.Selector = const_cast<CTerrainTriangleSelector*>(this);
|
||||||
|
triRange.SceneNode = SceneNode;
|
||||||
|
outTriangleInfo->push_back(triRange);
|
||||||
|
}
|
||||||
|
|
||||||
outTriangleCount = tIndex;
|
outTriangleCount = tIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +123,9 @@ void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
//! Gets all triangles which lie within a specific bounding box.
|
//! Gets all triangles which lie within a specific bounding box.
|
||||||
void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
s32 arraySize, s32& outTriangleCount,
|
s32 arraySize, s32& outTriangleCount,
|
||||||
const core::aabbox3d<f32>& box, const core::matrix4* transform) const
|
const core::aabbox3d<f32>& box,
|
||||||
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
s32 count = TrianglePatches.TotalTriangles;
|
s32 count = TrianglePatches.TotalTriangles;
|
||||||
|
|
||||||
|
@ -143,6 +155,15 @@ void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( outTriangleInfo )
|
||||||
|
{
|
||||||
|
SCollisionTriangleRange triRange;
|
||||||
|
triRange.RangeSize = tIndex;
|
||||||
|
triRange.Selector = const_cast<CTerrainTriangleSelector*>(this);
|
||||||
|
triRange.SceneNode = SceneNode;
|
||||||
|
outTriangleInfo->push_back(triRange);
|
||||||
|
}
|
||||||
|
|
||||||
outTriangleCount = tIndex;
|
outTriangleCount = tIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +171,8 @@ void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
//! Gets all triangles which have or may have contact with a 3d line.
|
//! Gets all triangles which have or may have contact with a 3d line.
|
||||||
void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
s32 arraySize, s32& outTriangleCount, const core::line3d<f32>& line,
|
s32 arraySize, s32& outTriangleCount, const core::line3d<f32>& line,
|
||||||
const core::matrix4* transform) const
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
const s32 count = core::min_((s32)TrianglePatches.TotalTriangles, arraySize);
|
const s32 count = core::min_((s32)TrianglePatches.TotalTriangles, arraySize);
|
||||||
|
|
||||||
|
@ -179,6 +201,15 @@ void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( outTriangleInfo )
|
||||||
|
{
|
||||||
|
SCollisionTriangleRange triRange;
|
||||||
|
triRange.RangeSize = tIndex;
|
||||||
|
triRange.Selector = const_cast<CTerrainTriangleSelector*>(this);
|
||||||
|
triRange.SceneNode = SceneNode;
|
||||||
|
outTriangleInfo->push_back(triRange);
|
||||||
|
}
|
||||||
|
|
||||||
outTriangleCount = tIndex;
|
outTriangleCount = tIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ class ITerrainSceneNode;
|
||||||
//! Triangle Selector for the TerrainSceneNode
|
//! Triangle Selector for the TerrainSceneNode
|
||||||
/** The code for the TerrainTriangleSelector is based on the GeoMipMapSelector
|
/** The code for the TerrainTriangleSelector is based on the GeoMipMapSelector
|
||||||
developed by Spintz. He made it available for Irrlicht and allowed it to be
|
developed by Spintz. He made it available for Irrlicht and allowed it to be
|
||||||
distributed under this licence. I only modified some parts. A lot of thanks go
|
distributed under this license. I only modified some parts. A lot of thanks go
|
||||||
to him.
|
to him.
|
||||||
*/
|
*/
|
||||||
class CTerrainTriangleSelector : public ITriangleSelector
|
class CTerrainTriangleSelector : public ITriangleSelector
|
||||||
|
@ -40,16 +40,19 @@ public:
|
||||||
|
|
||||||
//! Gets all triangles.
|
//! Gets all triangles.
|
||||||
void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
||||||
const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Gets all triangles which lie within a specific bounding box.
|
//! Gets all triangles which lie within a specific bounding box.
|
||||||
void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
||||||
const core::aabbox3d<f32>& box, const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
const core::aabbox3d<f32>& box, const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Gets all triangles which have or may have contact with a 3d line.
|
//! Gets all triangles which have or may have contact with a 3d line.
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::line3d<f32>& line,
|
s32& outTriangleCount, const core::line3d<f32>& line,
|
||||||
const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Returns amount of all available triangles in this selector
|
//! Returns amount of all available triangles in this selector
|
||||||
virtual s32 getTriangleCount() const _IRR_OVERRIDE_;
|
virtual s32 getTriangleCount() const _IRR_OVERRIDE_;
|
||||||
|
|
|
@ -77,6 +77,11 @@ void CTextSceneNode::setText(const wchar_t* text)
|
||||||
Text = text;
|
Text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! get the text string
|
||||||
|
const wchar_t* CTextSceneNode::getText() const
|
||||||
|
{
|
||||||
|
return Text.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
//! sets the color of the text
|
//! sets the color of the text
|
||||||
void CTextSceneNode::setTextColor(video::SColor color)
|
void CTextSceneNode::setTextColor(video::SColor color)
|
||||||
|
@ -84,6 +89,30 @@ void CTextSceneNode::setTextColor(video::SColor color)
|
||||||
Color = color;
|
Color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! get the color of the text
|
||||||
|
video::SColor CTextSceneNode::getTextColor() const
|
||||||
|
{
|
||||||
|
return Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextSceneNode::setFont(gui::IGUIFont* font)
|
||||||
|
{
|
||||||
|
if ( font != Font )
|
||||||
|
{
|
||||||
|
if ( font )
|
||||||
|
font->grab();
|
||||||
|
if ( Font )
|
||||||
|
Font->drop();
|
||||||
|
Font = font;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get the font used to draw the text
|
||||||
|
gui::IGUIFont* CTextSceneNode::getFont() const
|
||||||
|
{
|
||||||
|
return Font;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//!--------------------------------- CBillboardTextSceneNode ----------------------------------------------
|
//!--------------------------------- CBillboardTextSceneNode ----------------------------------------------
|
||||||
|
|
||||||
|
@ -234,6 +263,11 @@ void CBillboardTextSceneNode::setText(const wchar_t* text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! get the text string
|
||||||
|
const wchar_t* CBillboardTextSceneNode::getText() const
|
||||||
|
{
|
||||||
|
return Text.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
//! pre render event
|
//! pre render event
|
||||||
void CBillboardTextSceneNode::OnAnimate(u32 timeMs)
|
void CBillboardTextSceneNode::OnAnimate(u32 timeMs)
|
||||||
|
@ -408,11 +442,10 @@ const core::dimension2d<f32>& CBillboardTextSceneNode::getSize() const
|
||||||
return Size;
|
return Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Get the font used to draw the text
|
||||||
//! sets the color of the text
|
gui::IGUIFont* CBillboardTextSceneNode::getFont() const
|
||||||
void CBillboardTextSceneNode::setTextColor(video::SColor color)
|
|
||||||
{
|
{
|
||||||
Color = color;
|
return Font;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Set the color of all vertices of the billboard
|
//! Set the color of all vertices of the billboard
|
||||||
|
|
|
@ -41,9 +41,21 @@ namespace scene
|
||||||
//! sets the text string
|
//! sets the text string
|
||||||
virtual void setText(const wchar_t* text) _IRR_OVERRIDE_;
|
virtual void setText(const wchar_t* text) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
//! get the text string
|
||||||
|
virtual const wchar_t* getText() const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! sets the color of the text
|
//! sets the color of the text
|
||||||
virtual void setTextColor(video::SColor color) _IRR_OVERRIDE_;
|
virtual void setTextColor(video::SColor color) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
//! get the color of the text
|
||||||
|
virtual video::SColor getTextColor() const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
//! set the font used to draw the text
|
||||||
|
virtual void setFont(gui::IGUIFont* font) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
//! Get the font used to draw the text
|
||||||
|
virtual gui::IGUIFont* getFont() const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Returns type of the scene node
|
//! Returns type of the scene node
|
||||||
virtual ESCENE_NODE_TYPE getType() const _IRR_OVERRIDE_ { return ESNT_TEXT; }
|
virtual ESCENE_NODE_TYPE getType() const _IRR_OVERRIDE_ { return ESNT_TEXT; }
|
||||||
|
|
||||||
|
@ -83,8 +95,11 @@ namespace scene
|
||||||
//! sets the text string
|
//! sets the text string
|
||||||
virtual void setText(const wchar_t* text) _IRR_OVERRIDE_;
|
virtual void setText(const wchar_t* text) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! sets the color of the text
|
//! get the text string
|
||||||
virtual void setTextColor(video::SColor color) _IRR_OVERRIDE_;
|
virtual const wchar_t* getText() const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
//! Get the font used to draw the text
|
||||||
|
virtual gui::IGUIFont* getFont() const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! sets the size of the billboard
|
//! sets the size of the billboard
|
||||||
virtual void setSize(const core::dimension2d<f32>& size) _IRR_OVERRIDE_;
|
virtual void setSize(const core::dimension2d<f32>& size) _IRR_OVERRIDE_;
|
||||||
|
@ -98,7 +113,7 @@ namespace scene
|
||||||
virtual u32 getMaterialCount() const _IRR_OVERRIDE_;
|
virtual u32 getMaterialCount() const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Returns type of the scene node
|
//! Returns type of the scene node
|
||||||
virtual ESCENE_NODE_TYPE getType() const _IRR_OVERRIDE_ { return ESNT_TEXT; }
|
virtual ESCENE_NODE_TYPE getType() const _IRR_OVERRIDE_ { return ESNT_BILLBOARD_TEXT; }
|
||||||
|
|
||||||
//! Set the color of all vertices of the billboard
|
//! Set the color of all vertices of the billboard
|
||||||
//! \param overallColor: the color to set
|
//! \param overallColor: the color to set
|
||||||
|
@ -129,7 +144,6 @@ namespace scene
|
||||||
private:
|
private:
|
||||||
|
|
||||||
core::stringw Text;
|
core::stringw Text;
|
||||||
video::SColor Color;
|
|
||||||
gui::IGUIFontBitmap* Font;
|
gui::IGUIFontBitmap* Font;
|
||||||
|
|
||||||
core::dimension2d<f32> Size;
|
core::dimension2d<f32> Size;
|
||||||
|
|
|
@ -21,60 +21,68 @@ CTriangleBBSelector::CTriangleBBSelector(ISceneNode* node)
|
||||||
Triangles.set_used(12); // a box has 12 triangles.
|
Triangles.set_used(12); // a box has 12 triangles.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! Gets all triangles.
|
//! Gets all triangles.
|
||||||
void CTriangleBBSelector::getTriangles(core::triangle3df* triangles,
|
void CTriangleBBSelector::getTriangles(core::triangle3df* triangles,
|
||||||
s32 arraySize, s32& outTriangleCount,
|
s32 arraySize, s32& outTriangleCount,
|
||||||
const core::matrix4* transform) const
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
if (!SceneNode)
|
fillTriangles();
|
||||||
return;
|
|
||||||
|
|
||||||
// construct triangles
|
|
||||||
const core::aabbox3d<f32>& box = SceneNode->getBoundingBox();
|
|
||||||
core::vector3df edges[8];
|
|
||||||
box.getEdges(edges);
|
|
||||||
|
|
||||||
Triangles[0].set( edges[3], edges[0], edges[2]);
|
|
||||||
Triangles[1].set( edges[3], edges[1], edges[0]);
|
|
||||||
|
|
||||||
Triangles[2].set( edges[3], edges[2], edges[7]);
|
|
||||||
Triangles[3].set( edges[7], edges[2], edges[6]);
|
|
||||||
|
|
||||||
Triangles[4].set( edges[7], edges[6], edges[4]);
|
|
||||||
Triangles[5].set( edges[5], edges[7], edges[4]);
|
|
||||||
|
|
||||||
Triangles[6].set( edges[5], edges[4], edges[0]);
|
|
||||||
Triangles[7].set( edges[5], edges[0], edges[1]);
|
|
||||||
|
|
||||||
Triangles[8].set( edges[1], edges[3], edges[7]);
|
|
||||||
Triangles[9].set( edges[1], edges[7], edges[5]);
|
|
||||||
|
|
||||||
Triangles[10].set(edges[0], edges[6], edges[2]);
|
|
||||||
Triangles[11].set(edges[0], edges[4], edges[6]);
|
|
||||||
|
|
||||||
// call parent
|
// call parent
|
||||||
CTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, transform);
|
CTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, transform, useNodeTransform, outTriangleInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTriangleBBSelector::getTriangles(core::triangle3df* triangles,
|
void CTriangleBBSelector::getTriangles(core::triangle3df* triangles,
|
||||||
s32 arraySize, s32& outTriangleCount,
|
s32 arraySize, s32& outTriangleCount,
|
||||||
const core::aabbox3d<f32>& box,
|
const core::aabbox3d<f32>& box,
|
||||||
const core::matrix4* transform) const
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
return getTriangles(triangles, arraySize, outTriangleCount, transform);
|
fillTriangles();
|
||||||
|
return CTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, box, transform, useNodeTransform, outTriangleInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTriangleBBSelector::getTriangles(core::triangle3df* triangles,
|
void CTriangleBBSelector::getTriangles(core::triangle3df* triangles,
|
||||||
s32 arraySize, s32& outTriangleCount,
|
s32 arraySize, s32& outTriangleCount,
|
||||||
const core::line3d<f32>& line,
|
const core::line3d<f32>& line,
|
||||||
const core::matrix4* transform) const
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
return getTriangles(triangles, arraySize, outTriangleCount, transform);
|
fillTriangles();
|
||||||
|
return CTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, line, transform, useNodeTransform, outTriangleInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTriangleBBSelector::fillTriangles() const
|
||||||
|
{
|
||||||
|
if (SceneNode)
|
||||||
|
{
|
||||||
|
// construct triangles
|
||||||
|
const core::aabbox3d<f32>& box = SceneNode->getBoundingBox();
|
||||||
|
core::vector3df edges[8];
|
||||||
|
box.getEdges(edges);
|
||||||
|
|
||||||
|
// yeah, not really const... Triangles are mutable
|
||||||
|
Triangles[0].set( edges[3], edges[0], edges[2]);
|
||||||
|
Triangles[1].set( edges[3], edges[1], edges[0]);
|
||||||
|
|
||||||
|
Triangles[2].set( edges[3], edges[2], edges[7]);
|
||||||
|
Triangles[3].set( edges[7], edges[2], edges[6]);
|
||||||
|
|
||||||
|
Triangles[4].set( edges[7], edges[6], edges[4]);
|
||||||
|
Triangles[5].set( edges[5], edges[7], edges[4]);
|
||||||
|
|
||||||
|
Triangles[6].set( edges[5], edges[4], edges[0]);
|
||||||
|
Triangles[7].set( edges[5], edges[0], edges[1]);
|
||||||
|
|
||||||
|
Triangles[8].set( edges[1], edges[3], edges[7]);
|
||||||
|
Triangles[9].set( edges[1], edges[7], edges[5]);
|
||||||
|
|
||||||
|
Triangles[10].set(edges[0], edges[6], edges[2]);
|
||||||
|
Triangles[11].set(edges[0], edges[4], edges[6]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // end namespace scene
|
} // end namespace scene
|
||||||
} // end namespace irr
|
} // end namespace irr
|
||||||
|
|
||||||
|
|
|
@ -22,16 +22,22 @@ public:
|
||||||
|
|
||||||
//! Gets all triangles.
|
//! Gets all triangles.
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
||||||
const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Gets all triangles which lie within a specific bounding box.
|
//! Gets all triangles which lie within a specific bounding box.
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
||||||
const core::aabbox3d<f32>& box, const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
const core::aabbox3d<f32>& box, const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Gets all triangles which have or may have contact with a 3d line.
|
//! Gets all triangles which have or may have contact with a 3d line.
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::line3d<f32>& line,
|
s32& outTriangleCount, const core::line3d<f32>& line,
|
||||||
const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void fillTriangles() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace scene
|
||||||
|
|
||||||
//! constructor
|
//! constructor
|
||||||
CTriangleSelector::CTriangleSelector(ISceneNode* node)
|
CTriangleSelector::CTriangleSelector(ISceneNode* node)
|
||||||
: SceneNode(node), AnimatedNode(0), LastMeshFrame(0)
|
: SceneNode(node), MeshBuffer(0), MaterialIndex(0), AnimatedNode(0), LastMeshFrame(0)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
setDebugName("CTriangleSelector");
|
setDebugName("CTriangleSelector");
|
||||||
|
@ -27,7 +27,7 @@ CTriangleSelector::CTriangleSelector(ISceneNode* node)
|
||||||
|
|
||||||
//! constructor
|
//! constructor
|
||||||
CTriangleSelector::CTriangleSelector(const core::aabbox3d<f32>& box, ISceneNode* node)
|
CTriangleSelector::CTriangleSelector(const core::aabbox3d<f32>& box, ISceneNode* node)
|
||||||
: SceneNode(node), AnimatedNode(0), LastMeshFrame(0)
|
: SceneNode(node), MeshBuffer(0), MaterialIndex(0), AnimatedNode(0), LastMeshFrame(0)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
setDebugName("CTriangleSelector");
|
setDebugName("CTriangleSelector");
|
||||||
|
@ -39,18 +39,27 @@ CTriangleSelector::CTriangleSelector(const core::aabbox3d<f32>& box, ISceneNode*
|
||||||
|
|
||||||
|
|
||||||
//! constructor
|
//! constructor
|
||||||
CTriangleSelector::CTriangleSelector(const IMesh* mesh, ISceneNode* node)
|
CTriangleSelector::CTriangleSelector(const IMesh* mesh, ISceneNode* node, bool separateMeshbuffers)
|
||||||
: SceneNode(node), AnimatedNode(0), LastMeshFrame(0)
|
: SceneNode(node), MeshBuffer(0), MaterialIndex(0), AnimatedNode(0), LastMeshFrame(0)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
setDebugName("CTriangleSelector");
|
setDebugName("CTriangleSelector");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
createFromMesh(mesh);
|
createFromMesh(mesh, separateMeshbuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CTriangleSelector::CTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node)
|
||||||
|
: SceneNode(node), MeshBuffer(meshBuffer), MaterialIndex(materialIndex), AnimatedNode(0), LastMeshFrame(0)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
setDebugName("CTriangleSelector");
|
||||||
|
#endif
|
||||||
|
|
||||||
CTriangleSelector::CTriangleSelector(IAnimatedMeshSceneNode* node)
|
createFromMeshBuffer(meshBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
CTriangleSelector::CTriangleSelector(IAnimatedMeshSceneNode* node, bool separateMeshbuffers)
|
||||||
: SceneNode(node), AnimatedNode(node), LastMeshFrame(0)
|
: SceneNode(node), AnimatedNode(node), LastMeshFrame(0)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
@ -68,22 +77,51 @@ CTriangleSelector::CTriangleSelector(IAnimatedMeshSceneNode* node)
|
||||||
IMesh* mesh = animatedMesh->getMesh(LastMeshFrame);
|
IMesh* mesh = animatedMesh->getMesh(LastMeshFrame);
|
||||||
|
|
||||||
if (mesh)
|
if (mesh)
|
||||||
createFromMesh(mesh);
|
createFromMesh(mesh, separateMeshbuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CTriangleSelector::createFromMesh(const IMesh* mesh)
|
void CTriangleSelector::createFromMesh(const IMesh* mesh, bool createBufferRanges)
|
||||||
{
|
{
|
||||||
|
BufferRanges.clear();
|
||||||
|
Triangles.clear();
|
||||||
|
|
||||||
const u32 cnt = mesh->getMeshBufferCount();
|
const u32 cnt = mesh->getMeshBufferCount();
|
||||||
u32 totalFaceCount = 0;
|
u32 totalFaceCount = 0;
|
||||||
for (u32 j=0; j<cnt; ++j)
|
for (u32 j=0; j<cnt; ++j)
|
||||||
totalFaceCount += mesh->getMeshBuffer(j)->getIndexCount();
|
{
|
||||||
totalFaceCount /= 3;
|
SCollisionTriangleRange range;
|
||||||
|
range.MeshBuffer = mesh->getMeshBuffer(j);
|
||||||
|
range.MaterialIndex = j;
|
||||||
|
range.RangeSize = range.MeshBuffer->getIndexCount() / 3;
|
||||||
|
|
||||||
|
if ( createBufferRanges )
|
||||||
|
{
|
||||||
|
range.RangeStart = totalFaceCount;
|
||||||
|
|
||||||
|
BufferRanges.push_back(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
totalFaceCount += range.RangeSize;
|
||||||
|
}
|
||||||
Triangles.set_used(totalFaceCount);
|
Triangles.set_used(totalFaceCount);
|
||||||
|
|
||||||
updateFromMesh(mesh);
|
updateFromMesh(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CTriangleSelector::createFromMeshBuffer(const IMeshBuffer* meshBuffer)
|
||||||
|
{
|
||||||
|
BufferRanges.clear();
|
||||||
|
Triangles.clear();
|
||||||
|
|
||||||
|
if ( meshBuffer )
|
||||||
|
{
|
||||||
|
Triangles.set_used(meshBuffer->getIndexCount() / 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFromMeshBuffer(meshBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TIndex>
|
template <typename TIndex>
|
||||||
static void updateTriangles(u32& triangleCount, core::array<core::triangle3df>& triangles, u32 idxCnt, const TIndex* indices, const u8* vertices, u32 vertexPitch, const core::matrix4* bufferTransform)
|
static void updateTriangles(u32& triangleCount, core::array<core::triangle3df>& triangles, u32 idxCnt, const TIndex* indices, const u8* vertices, u32 vertexPitch, const core::matrix4* bufferTransform)
|
||||||
{
|
{
|
||||||
|
@ -151,10 +189,41 @@ void CTriangleSelector::updateFromMesh(const IMesh* mesh) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update bounding box
|
// Update bounding box
|
||||||
if ( triangleCount )
|
updateBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTriangleSelector::updateFromMeshBuffer(const IMeshBuffer* meshBuffer) const
|
||||||
|
{
|
||||||
|
if ( !meshBuffer )
|
||||||
|
return;
|
||||||
|
|
||||||
|
u32 idxCnt = meshBuffer->getIndexCount();
|
||||||
|
u32 vertexPitch = getVertexPitchFromType(meshBuffer->getVertexType());
|
||||||
|
u8* vertices = (u8*)meshBuffer->getVertices();
|
||||||
|
u32 triangleCount = 0;
|
||||||
|
switch ( meshBuffer->getIndexType() )
|
||||||
|
{
|
||||||
|
case video::EIT_16BIT:
|
||||||
|
{
|
||||||
|
const u16* indices = meshBuffer->getIndices();
|
||||||
|
updateTriangles(triangleCount, Triangles, idxCnt, indices, vertices, vertexPitch, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case video::EIT_32BIT:
|
||||||
|
{
|
||||||
|
const u32* indices = (u32*)meshBuffer->getIndices();
|
||||||
|
updateTriangles(triangleCount, Triangles, idxCnt, indices, vertices, vertexPitch, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTriangleSelector::updateBoundingBox() const
|
||||||
|
{
|
||||||
|
if ( !Triangles.empty() )
|
||||||
{
|
{
|
||||||
BoundingBox.reset( Triangles[0].pointA );
|
BoundingBox.reset( Triangles[0].pointA );
|
||||||
for (u32 i=0; i < triangleCount; ++i)
|
for (u32 i=0; i < Triangles.size(); ++i)
|
||||||
{
|
{
|
||||||
const core::triangle3df& tri = Triangles[i];
|
const core::triangle3df& tri = Triangles[i];
|
||||||
BoundingBox.addInternalPoint(tri.pointA);
|
BoundingBox.addInternalPoint(tri.pointA);
|
||||||
|
@ -168,7 +237,6 @@ void CTriangleSelector::updateFromMesh(const IMesh* mesh) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CTriangleSelector::update(void) const
|
void CTriangleSelector::update(void) const
|
||||||
{
|
{
|
||||||
if (!AnimatedNode)
|
if (!AnimatedNode)
|
||||||
|
@ -194,7 +262,8 @@ void CTriangleSelector::update(void) const
|
||||||
//! Gets all triangles.
|
//! Gets all triangles.
|
||||||
void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
s32 arraySize, s32& outTriangleCount,
|
s32 arraySize, s32& outTriangleCount,
|
||||||
const core::matrix4* transform) const
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
// Update my triangles if necessary
|
// Update my triangles if necessary
|
||||||
update();
|
update();
|
||||||
|
@ -206,7 +275,7 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
core::matrix4 mat;
|
core::matrix4 mat;
|
||||||
if (transform)
|
if (transform)
|
||||||
mat = *transform;
|
mat = *transform;
|
||||||
if (SceneNode)
|
if (SceneNode&&useNodeTransform)
|
||||||
mat *= SceneNode->getAbsoluteTransformation();
|
mat *= SceneNode->getAbsoluteTransformation();
|
||||||
|
|
||||||
for (u32 i=0; i<cnt; ++i)
|
for (u32 i=0; i<cnt; ++i)
|
||||||
|
@ -216,6 +285,43 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
mat.transformVect( triangles[i].pointC, Triangles[i].pointC );
|
mat.transformVect( triangles[i].pointC, Triangles[i].pointC );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( outTriangleInfo )
|
||||||
|
{
|
||||||
|
if ( BufferRanges.empty() )
|
||||||
|
{
|
||||||
|
SCollisionTriangleRange triRange;
|
||||||
|
|
||||||
|
triRange.RangeStart = 0;
|
||||||
|
triRange.RangeSize = cnt;
|
||||||
|
triRange.Selector = const_cast<CTriangleSelector*>(this);
|
||||||
|
triRange.SceneNode = SceneNode;
|
||||||
|
triRange.MeshBuffer = MeshBuffer;
|
||||||
|
triRange.MaterialIndex = MaterialIndex;
|
||||||
|
outTriangleInfo->push_back(triRange);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
irr::u32 rangeIndex = 0;
|
||||||
|
for (u32 i=0; i<cnt; )
|
||||||
|
{
|
||||||
|
while ( i >= (BufferRanges[rangeIndex].RangeStart + BufferRanges[rangeIndex].RangeSize) )
|
||||||
|
++rangeIndex;
|
||||||
|
|
||||||
|
SCollisionTriangleRange triRange;
|
||||||
|
|
||||||
|
triRange.MaterialIndex = BufferRanges[rangeIndex].MaterialIndex;
|
||||||
|
triRange.MeshBuffer = BufferRanges[rangeIndex].MeshBuffer;
|
||||||
|
triRange.RangeStart = BufferRanges[rangeIndex].RangeStart;
|
||||||
|
triRange.RangeSize = core::min_( cnt-BufferRanges[rangeIndex].RangeStart, BufferRanges[rangeIndex].RangeSize);
|
||||||
|
triRange.Selector = const_cast<CTriangleSelector*>(this);
|
||||||
|
triRange.SceneNode = SceneNode;
|
||||||
|
outTriangleInfo->push_back(triRange);
|
||||||
|
|
||||||
|
i += triRange.RangeSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
outTriangleCount = cnt;
|
outTriangleCount = cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +330,8 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
s32 arraySize, s32& outTriangleCount,
|
s32 arraySize, s32& outTriangleCount,
|
||||||
const core::aabbox3d<f32>& box,
|
const core::aabbox3d<f32>& box,
|
||||||
const core::matrix4* transform) const
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
// Update my triangles if necessary
|
// Update my triangles if necessary
|
||||||
update();
|
update();
|
||||||
|
@ -232,16 +339,23 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
core::matrix4 mat(core::matrix4::EM4CONST_NOTHING);
|
core::matrix4 mat(core::matrix4::EM4CONST_NOTHING);
|
||||||
core::aabbox3df tBox(box);
|
core::aabbox3df tBox(box);
|
||||||
|
|
||||||
if (SceneNode)
|
if (SceneNode && useNodeTransform)
|
||||||
{
|
{
|
||||||
SceneNode->getAbsoluteTransformation().getInverse(mat);
|
if ( SceneNode->getAbsoluteTransformation().getInverse(mat) )
|
||||||
mat.transformBoxEx(tBox);
|
mat.transformBoxEx(tBox);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: else is not yet handled optimally.
|
||||||
|
// If a node has an axis scaled to 0 we return all triangles without any check
|
||||||
|
return getTriangles(triangles, arraySize, outTriangleCount,
|
||||||
|
transform, useNodeTransform, outTriangleInfo );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (transform)
|
if (transform)
|
||||||
mat = *transform;
|
mat = *transform;
|
||||||
else
|
else
|
||||||
mat.makeIdentity();
|
mat.makeIdentity();
|
||||||
if (SceneNode)
|
if (SceneNode && useNodeTransform)
|
||||||
mat *= SceneNode->getAbsoluteTransformation();
|
mat *= SceneNode->getAbsoluteTransformation();
|
||||||
|
|
||||||
outTriangleCount = 0;
|
outTriangleCount = 0;
|
||||||
|
@ -251,22 +365,80 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
|
|
||||||
s32 triangleCount = 0;
|
s32 triangleCount = 0;
|
||||||
const u32 cnt = Triangles.size();
|
const u32 cnt = Triangles.size();
|
||||||
for (u32 i=0; i<cnt; ++i)
|
|
||||||
|
if ( outTriangleInfo && !BufferRanges.empty() )
|
||||||
{
|
{
|
||||||
// This isn't an accurate test, but it's fast, and the
|
irr::u32 activeRange = 0;
|
||||||
// API contract doesn't guarantee complete accuracy.
|
SCollisionTriangleRange triRange;
|
||||||
if (Triangles[i].isTotalOutsideBox(tBox))
|
triRange.Selector = const_cast<CTriangleSelector*>(this);
|
||||||
continue;
|
triRange.SceneNode = SceneNode;
|
||||||
|
triRange.RangeStart = triangleCount;
|
||||||
|
triRange.MeshBuffer = BufferRanges[activeRange].MeshBuffer;
|
||||||
|
triRange.MaterialIndex = BufferRanges[activeRange].MaterialIndex;
|
||||||
|
|
||||||
triangles[triangleCount] = Triangles[i];
|
for (u32 i=0; i<cnt; ++i)
|
||||||
mat.transformVect(triangles[triangleCount].pointA);
|
{
|
||||||
mat.transformVect(triangles[triangleCount].pointB);
|
// This isn't an accurate test, but it's fast, and the
|
||||||
mat.transformVect(triangles[triangleCount].pointC);
|
// API contract doesn't guarantee complete accuracy.
|
||||||
|
if (Triangles[i].isTotalOutsideBox(tBox))
|
||||||
|
continue;
|
||||||
|
|
||||||
++triangleCount;
|
if ( i >= BufferRanges[activeRange].RangeStart + BufferRanges[activeRange].RangeSize )
|
||||||
|
{
|
||||||
|
triRange.RangeSize = triangleCount-triRange.RangeStart;
|
||||||
|
if ( triRange.RangeSize > 0 )
|
||||||
|
outTriangleInfo->push_back(triRange);
|
||||||
|
|
||||||
if (triangleCount == arraySize)
|
++activeRange;
|
||||||
break;
|
triRange.RangeStart = triangleCount;
|
||||||
|
triRange.MeshBuffer = BufferRanges[activeRange].MeshBuffer;
|
||||||
|
triRange.MaterialIndex = BufferRanges[activeRange].MaterialIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
triangles[triangleCount] = Triangles[i];
|
||||||
|
mat.transformVect(triangles[triangleCount].pointA);
|
||||||
|
mat.transformVect(triangles[triangleCount].pointB);
|
||||||
|
mat.transformVect(triangles[triangleCount].pointC);
|
||||||
|
|
||||||
|
++triangleCount;
|
||||||
|
|
||||||
|
if (triangleCount == arraySize)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
triRange.RangeSize = triangleCount-triRange.RangeStart;
|
||||||
|
if ( triRange.RangeSize > 0 )
|
||||||
|
outTriangleInfo->push_back(triRange);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (u32 i=0; i<cnt; ++i)
|
||||||
|
{
|
||||||
|
// This isn't an accurate test, but it's fast, and the
|
||||||
|
// API contract doesn't guarantee complete accuracy.
|
||||||
|
if (Triangles[i].isTotalOutsideBox(tBox))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
triangles[triangleCount] = Triangles[i];
|
||||||
|
mat.transformVect(triangles[triangleCount].pointA);
|
||||||
|
mat.transformVect(triangles[triangleCount].pointB);
|
||||||
|
mat.transformVect(triangles[triangleCount].pointC);
|
||||||
|
|
||||||
|
++triangleCount;
|
||||||
|
|
||||||
|
if (triangleCount == arraySize)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( outTriangleInfo )
|
||||||
|
{
|
||||||
|
SCollisionTriangleRange triRange;
|
||||||
|
triRange.RangeSize = triangleCount;
|
||||||
|
triRange.Selector = const_cast<CTriangleSelector*>(this);
|
||||||
|
triRange.SceneNode = SceneNode;
|
||||||
|
triRange.MeshBuffer = MeshBuffer;
|
||||||
|
triRange.MaterialIndex = MaterialIndex;
|
||||||
|
outTriangleInfo->push_back(triRange);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outTriangleCount = triangleCount;
|
outTriangleCount = triangleCount;
|
||||||
|
@ -277,7 +449,8 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
s32 arraySize, s32& outTriangleCount,
|
s32 arraySize, s32& outTriangleCount,
|
||||||
const core::line3d<f32>& line,
|
const core::line3d<f32>& line,
|
||||||
const core::matrix4* transform) const
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||||
{
|
{
|
||||||
// Update my triangles if necessary
|
// Update my triangles if necessary
|
||||||
update();
|
update();
|
||||||
|
@ -287,7 +460,7 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||||
|
|
||||||
// TODO: Could be optimized for line a little bit more.
|
// TODO: Could be optimized for line a little bit more.
|
||||||
getTriangles(triangles, arraySize, outTriangleCount,
|
getTriangles(triangles, arraySize, outTriangleCount,
|
||||||
box, transform);
|
box, transform, useNodeTransform, outTriangleInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,27 +27,33 @@ public:
|
||||||
CTriangleSelector(ISceneNode* node);
|
CTriangleSelector(ISceneNode* node);
|
||||||
|
|
||||||
//! Constructs a selector based on a mesh
|
//! Constructs a selector based on a mesh
|
||||||
CTriangleSelector(const IMesh* mesh, ISceneNode* node);
|
CTriangleSelector(const IMesh* mesh, ISceneNode* node, bool separateMeshbuffers);
|
||||||
|
|
||||||
|
//! Constructs a selector based on a meshbuffer
|
||||||
|
CTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node);
|
||||||
|
|
||||||
//! Constructs a selector based on an animated mesh scene node
|
//! Constructs a selector based on an animated mesh scene node
|
||||||
//!\param node An animated mesh scene node, which must have a valid mesh
|
//!\param node An animated mesh scene node, which must have a valid mesh
|
||||||
CTriangleSelector(IAnimatedMeshSceneNode* node);
|
CTriangleSelector(IAnimatedMeshSceneNode* node, bool separateMeshbuffers);
|
||||||
|
|
||||||
//! Constructs a selector based on a bounding box
|
//! Constructs a selector based on a bounding box
|
||||||
CTriangleSelector(const core::aabbox3d<f32>& box, ISceneNode* node);
|
CTriangleSelector(const core::aabbox3d<f32>& box, ISceneNode* node);
|
||||||
|
|
||||||
//! Gets all triangles.
|
//! Gets all triangles.
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
||||||
const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Gets all triangles which lie within a specific bounding box.
|
//! Gets all triangles which lie within a specific bounding box.
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
|
||||||
const core::aabbox3d<f32>& box, const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
const core::aabbox3d<f32>& box, const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Gets all triangles which have or may have contact with a 3d line.
|
//! Gets all triangles which have or may have contact with a 3d line.
|
||||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||||
s32& outTriangleCount, const core::line3d<f32>& line,
|
s32& outTriangleCount, const core::line3d<f32>& line,
|
||||||
const core::matrix4* transform=0) const _IRR_OVERRIDE_;
|
const core::matrix4* transform, bool useNodeTransform,
|
||||||
|
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Returns amount of all available triangles in this selector
|
//! Returns amount of all available triangles in this selector
|
||||||
virtual s32 getTriangleCount() const _IRR_OVERRIDE_;
|
virtual s32 getTriangleCount() const _IRR_OVERRIDE_;
|
||||||
|
@ -66,20 +72,33 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! Create from a mesh
|
//! Create from a mesh
|
||||||
virtual void createFromMesh(const IMesh* mesh);
|
virtual void createFromMesh(const IMesh* mesh, bool createBufferRanges);
|
||||||
|
|
||||||
|
//! Create from a meshbuffer
|
||||||
|
virtual void createFromMeshBuffer(const IMeshBuffer* meshBuffer);
|
||||||
|
|
||||||
//! Update when the mesh has changed
|
//! Update when the mesh has changed
|
||||||
virtual void updateFromMesh(const IMesh* mesh) const;
|
virtual void updateFromMesh(const IMesh* mesh) const;
|
||||||
|
|
||||||
|
//! Update when the meshbuffer has changed
|
||||||
|
virtual void updateFromMeshBuffer(const IMeshBuffer* meshBuffer) const;
|
||||||
|
|
||||||
|
//! Update bounding box from triangles
|
||||||
|
void updateBoundingBox() const;
|
||||||
|
|
||||||
//! Update the triangle selector, which will only have an effect if it
|
//! Update the triangle selector, which will only have an effect if it
|
||||||
//! was built from an animated mesh and that mesh's frame has changed
|
//! was built from an animated mesh and that mesh's frame has changed
|
||||||
//! since the last time it was updated.
|
//! since the last time it was updated.
|
||||||
virtual void update(void) const;
|
virtual void update(void) const;
|
||||||
|
|
||||||
|
irr::core::array<SCollisionTriangleRange> BufferRanges;
|
||||||
|
|
||||||
ISceneNode* SceneNode;
|
ISceneNode* SceneNode;
|
||||||
mutable core::array<core::triangle3df> Triangles; // (mutable for CTriangleBBSelector)
|
mutable core::array<core::triangle3df> Triangles; // (mutable for CTriangleBBSelector)
|
||||||
mutable core::aabbox3df BoundingBox; // Allows for trivial rejection
|
mutable core::aabbox3df BoundingBox; // Allows for trivial rejection
|
||||||
|
|
||||||
|
const IMeshBuffer* MeshBuffer; // non-zero when the selector is for a single meshbuffer
|
||||||
|
irr::u32 MaterialIndex; // Only set when MeshBuffer is non-zero
|
||||||
IAnimatedMeshSceneNode* AnimatedNode;
|
IAnimatedMeshSceneNode* AnimatedNode;
|
||||||
mutable u32 LastMeshFrame;
|
mutable u32 LastMeshFrame;
|
||||||
};
|
};
|
||||||
|
@ -87,6 +106,4 @@ protected:
|
||||||
} // end namespace scene
|
} // end namespace scene
|
||||||
} // end namespace irr
|
} // end namespace irr
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ bool CWriteFile::flush()
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !(bool) fflush(File);
|
return fflush(File) == 0; // 0 indicates success, otherwise EOF and errno is set
|
||||||
}
|
}
|
||||||
|
|
||||||
IWriteFile* CWriteFile::createWriteFile(const io::path& fileName, bool append)
|
IWriteFile* CWriteFile::createWriteFile(const io::path& fileName, bool append)
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace io
|
||||||
//! Reads an amount of bytes from the file.
|
//! Reads an amount of bytes from the file.
|
||||||
virtual int read(void* buffer, int sizeToRead)
|
virtual int read(void* buffer, int sizeToRead)
|
||||||
{
|
{
|
||||||
return ReadFile->read(buffer, sizeToRead);
|
return (int)ReadFile->read(buffer, sizeToRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Returns size of file in bytes
|
//! Returns size of file in bytes
|
||||||
|
|
|
@ -136,11 +136,11 @@ public:
|
||||||
|
|
||||||
|
|
||||||
//! Returns the value of an attribute as integer.
|
//! Returns the value of an attribute as integer.
|
||||||
virtual int getAttributeValueAsInt(const char_type* name) const _IRR_OVERRIDE_
|
virtual int getAttributeValueAsInt(const char_type* name, int defaultNotFound) const _IRR_OVERRIDE_
|
||||||
{
|
{
|
||||||
const SAttribute* attr = getAttributeByName(name);
|
const SAttribute* attr = getAttributeByName(name);
|
||||||
if (!attr)
|
if (!attr)
|
||||||
return 0;
|
return defaultNotFound;
|
||||||
|
|
||||||
core::stringc c(attr->Value.c_str());
|
core::stringc c(attr->Value.c_str());
|
||||||
return core::strtol10(c.c_str());
|
return core::strtol10(c.c_str());
|
||||||
|
@ -148,11 +148,11 @@ public:
|
||||||
|
|
||||||
|
|
||||||
//! Returns the value of an attribute as integer.
|
//! Returns the value of an attribute as integer.
|
||||||
virtual int getAttributeValueAsInt(int idx) const _IRR_OVERRIDE_
|
virtual int getAttributeValueAsInt(int idx, int defaultNotFound) const _IRR_OVERRIDE_
|
||||||
{
|
{
|
||||||
const char_type* attrvalue = getAttributeValue(idx);
|
const char_type* attrvalue = getAttributeValue(idx);
|
||||||
if (!attrvalue)
|
if (!attrvalue)
|
||||||
return 0;
|
return defaultNotFound;
|
||||||
|
|
||||||
core::stringc c(attrvalue);
|
core::stringc c(attrvalue);
|
||||||
return core::strtol10(c.c_str());
|
return core::strtol10(c.c_str());
|
||||||
|
@ -160,11 +160,11 @@ public:
|
||||||
|
|
||||||
|
|
||||||
//! Returns the value of an attribute as float.
|
//! Returns the value of an attribute as float.
|
||||||
virtual float getAttributeValueAsFloat(const char_type* name) const _IRR_OVERRIDE_
|
virtual float getAttributeValueAsFloat(const char_type* name, float defaultNotFound) const _IRR_OVERRIDE_
|
||||||
{
|
{
|
||||||
const SAttribute* attr = getAttributeByName(name);
|
const SAttribute* attr = getAttributeByName(name);
|
||||||
if (!attr)
|
if (!attr)
|
||||||
return 0;
|
return defaultNotFound;
|
||||||
|
|
||||||
core::stringc c = attr->Value.c_str();
|
core::stringc c = attr->Value.c_str();
|
||||||
return core::fast_atof(c.c_str());
|
return core::fast_atof(c.c_str());
|
||||||
|
@ -172,11 +172,11 @@ public:
|
||||||
|
|
||||||
|
|
||||||
//! Returns the value of an attribute as float.
|
//! Returns the value of an attribute as float.
|
||||||
virtual float getAttributeValueAsFloat(int idx) const _IRR_OVERRIDE_
|
virtual float getAttributeValueAsFloat(int idx, float defaultNotFound) const _IRR_OVERRIDE_
|
||||||
{
|
{
|
||||||
const char_type* attrvalue = getAttributeValue(idx);
|
const char_type* attrvalue = getAttributeValue(idx);
|
||||||
if (!attrvalue)
|
if (!attrvalue)
|
||||||
return 0;
|
return defaultNotFound;
|
||||||
|
|
||||||
core::stringc c = attrvalue;
|
core::stringc c = attrvalue;
|
||||||
return core::fast_atof(c.c_str());
|
return core::fast_atof(c.c_str());
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
<ProjectName>Irrlicht</ProjectName>
|
<ProjectName>Irrlicht</ProjectName>
|
||||||
<ProjectGuid>{E08E042A-6C45-411B-92BE-3CC31331019F}</ProjectGuid>
|
<ProjectGuid>{E08E042A-6C45-411B-92BE-3CC31331019F}</ProjectGuid>
|
||||||
<RootNamespace>Irrlicht</RootNamespace>
|
<RootNamespace>Irrlicht</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SDL-Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SDL-Debug|Win32'" Label="Configuration">
|
||||||
|
|
|
@ -131,10 +131,8 @@ void fcrypt_decrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1
|
||||||
|
|
||||||
int fcrypt_end(unsigned char mac[], fcrypt_ctx cx[1])
|
int fcrypt_end(unsigned char mac[], fcrypt_ctx cx[1])
|
||||||
{
|
{
|
||||||
unsigned int res = cx->mode;
|
|
||||||
|
|
||||||
hmac_sha_end(mac, MAC_LENGTH(cx->mode), cx->auth_ctx);
|
hmac_sha_end(mac, MAC_LENGTH(cx->mode), cx->auth_ctx);
|
||||||
memset(cx, 0, sizeof(fcrypt_ctx)); /* clear the encryption context */
|
memset(cx, 0, sizeof(fcrypt_ctx)); /* clear the encryption context */
|
||||||
return MAC_LENGTH(res); /* return MAC length in bytes */
|
return MAC_LENGTH(cx->mode); /* return MAC length in bytes */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,12 @@ Target = tests
|
||||||
Sources = $(wildcard *.cpp)
|
Sources = $(wildcard *.cpp)
|
||||||
|
|
||||||
CPPFLAGS = -I../include -I/usr/X11R6/include -pipe
|
CPPFLAGS = -I../include -I/usr/X11R6/include -pipe
|
||||||
# CXXFLAGS += -O3
|
CXXFLAGS += -Wall -ansi -pedantic -fno-exceptions
|
||||||
CXXFLAGS += -Wall -ansi -pedantic -O0 -g -D_DEBUG -fno-exceptions
|
ifndef NDEBUG
|
||||||
|
CXXFLAGS += -O0 -g -D_DEBUG
|
||||||
|
else
|
||||||
|
CXXFLAGS += -fexpensive-optimizations -O3
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(HOSTTYPE), x86_64)
|
ifeq ($(HOSTTYPE), x86_64)
|
||||||
LIBSELECT=64
|
LIBSELECT=64
|
||||||
|
|
|
@ -148,6 +148,8 @@ bool test_fast_atof(void)
|
||||||
accurate &= testCalculation_atof("0000123456.789");
|
accurate &= testCalculation_atof("0000123456.789");
|
||||||
accurate &= testCalculation_atof("-0000123456.789");
|
accurate &= testCalculation_atof("-0000123456.789");
|
||||||
accurate &= testCalculation_atof("-0.0690462109446526");
|
accurate &= testCalculation_atof("-0.0690462109446526");
|
||||||
|
accurate &= testCalculation_atof("0.11999999731779099"); // more numbers past dot than in lookup table
|
||||||
|
accurate &= testCalculation_atof("0.119999997317790999");
|
||||||
|
|
||||||
if (!accurate)
|
if (!accurate)
|
||||||
{
|
{
|
||||||
|
|
|
@ -113,6 +113,56 @@ static bool testSwap()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add numbers to the array going down from size to 1
|
||||||
|
static void addInvNumbers(irr::core::array<int>& arr, irr::u32 size)
|
||||||
|
{
|
||||||
|
for ( irr::u32 i=0; i<size; ++i )
|
||||||
|
{
|
||||||
|
arr.push_back(size-i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure numbers are sorted in ascending order
|
||||||
|
static bool validateSortedAscending(const irr::core::array<int>& arr)
|
||||||
|
{
|
||||||
|
for ( irr::u32 i=1; i< arr.size(); ++ i)
|
||||||
|
{
|
||||||
|
if ( arr[i-1] > arr[i] )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool testSort()
|
||||||
|
{
|
||||||
|
irr::core::array<int> arr;
|
||||||
|
for ( irr::u32 i=0; i<1000; ++i )
|
||||||
|
{
|
||||||
|
arr.clear();
|
||||||
|
addInvNumbers(arr, i);
|
||||||
|
arr.sort();
|
||||||
|
if ( !validateSortedAscending(arr) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( irr::u32 i=0; i<1000; ++i )
|
||||||
|
{
|
||||||
|
arr.clear();
|
||||||
|
addInvNumbers(arr, i);
|
||||||
|
addInvNumbers(arr, i);
|
||||||
|
arr.sort();
|
||||||
|
if ( !validateSortedAscending(arr) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Test the functionality of core::array
|
// Test the functionality of core::array
|
||||||
bool testIrrArray(void)
|
bool testIrrArray(void)
|
||||||
{
|
{
|
||||||
|
@ -123,6 +173,7 @@ bool testIrrArray(void)
|
||||||
allExpected &= testSelfAssignment();
|
allExpected &= testSelfAssignment();
|
||||||
allExpected &= testSwap();
|
allExpected &= testSwap();
|
||||||
allExpected &= testErase();
|
allExpected &= testErase();
|
||||||
|
allExpected &= testSort();
|
||||||
|
|
||||||
if(allExpected)
|
if(allExpected)
|
||||||
logTestString("\nAll tests passed\n");
|
logTestString("\nAll tests passed\n");
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
// Copyright (C) 2017 Dario Oliveri
|
||||||
|
// No rights reserved: this software is in the public domain.
|
||||||
|
|
||||||
|
#include "testUtils.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace irr;
|
||||||
|
using namespace irr::core;
|
||||||
|
|
||||||
|
#define EXPECT( condition, value, name) if( condition != value) \
|
||||||
|
{ std::cout<< name << ": test failed"<< std::endl; return false;}
|
||||||
|
|
||||||
|
//! Tests the basic functionality of the software device.
|
||||||
|
bool line2DTest(void)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
line2d< f32> a(0, 0, 0, 1);
|
||||||
|
line2d< f32> b(2, 0, 2, 1);
|
||||||
|
line2d< f32> c(2, 0, 2, 1 + 0.00001f);
|
||||||
|
|
||||||
|
EXPECT( a.nearlyParallel( b), true, "parallel Lines are parallel");
|
||||||
|
EXPECT( a.nearlyParallel( c, (f32)32), true, "nearly parallel lines are parallel");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
line2d< f32> a( 0, 0, 0, 1);
|
||||||
|
line2d< f32> b( 0, 2, 2, 1);
|
||||||
|
EXPECT( a.nearlyParallel( b, 1), false, "orthogonal lines are NOT parallel");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
line2d< f32> a( 0, 0, 100, 100);
|
||||||
|
line2d< f32> b( 100, 0, 0, 100);
|
||||||
|
|
||||||
|
EXPECT( a.nearlyParallel( b, 1), false, "orthogonal lines are NOT parallel 2");
|
||||||
|
|
||||||
|
vector2df t = a.fastLinesIntersection( b);
|
||||||
|
vector2df u = vector2df( 50.0f, 50.0f);
|
||||||
|
|
||||||
|
EXPECT( t.equals( u, roundingError<f32>() ), true, "fast intersection in known point");
|
||||||
|
|
||||||
|
EXPECT( a .intersectAsSegments(b), true, "intersect as Segments");
|
||||||
|
|
||||||
|
EXPECT( a.incidentSegments(b), true, "incidentSegments");
|
||||||
|
|
||||||
|
vector2df out;
|
||||||
|
EXPECT( a.lineIntersectSegment( b, out), true, "lineIntersectSegment");
|
||||||
|
EXPECT( t.equals( out), true, "line intersect segment in known point");
|
||||||
|
|
||||||
|
EXPECT( a.isPointBetweenStartAndEnd( out), true, "point isBetween StartEnd of first line");
|
||||||
|
EXPECT( b.isPointBetweenStartAndEnd( out), true, "point isBetween StartEnd of second line");
|
||||||
|
|
||||||
|
EXPECT( a.isPointOnLine( out), true, "is point on first line");
|
||||||
|
EXPECT( b.isPointOnLine( out), true, "is point on second line");
|
||||||
|
|
||||||
|
EXPECT( out.isBetweenPoints( a.start, a.end), true, "test point is on segment with first line");
|
||||||
|
EXPECT( out.isBetweenPoints( b.start, b.end), true, "test point is on segment with first line");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
vector2df a( 0, 0);
|
||||||
|
vector2df b( 10, 0);
|
||||||
|
vector2df c( 0, 10);
|
||||||
|
vector2df d( 0, 40);
|
||||||
|
|
||||||
|
EXPECT( a.areClockwise( c, b), true, "test if points are clockwise");
|
||||||
|
EXPECT( a.areClockwise( b, c), false, "test if points are NOT clockwise");
|
||||||
|
EXPECT( a.areCounterClockwise( b, c), true, "test if points are counter clockwise");
|
||||||
|
EXPECT( a.areCounterClockwise( c, b), false, "test if points are NOT counter clockwise");
|
||||||
|
|
||||||
|
EXPECT( a.checkOrientation( c, b), 1, "test if orientation is clockwise");
|
||||||
|
EXPECT( a.checkOrientation( b, c), 2, "test if orientation is anticlockwise");
|
||||||
|
EXPECT( a.checkOrientation( c, d), 0, "test if orientation is colinear");
|
||||||
|
EXPECT( a.checkOrientation( d, c), 0, "test if orientation is colinear 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -129,6 +129,7 @@ int main(int argumentCount, char * arguments[])
|
||||||
TEST(terrainSceneNode);
|
TEST(terrainSceneNode);
|
||||||
TEST(lightMaps);
|
TEST(lightMaps);
|
||||||
TEST(triangleSelector);
|
TEST(triangleSelector);
|
||||||
|
TEST(line2DTest);
|
||||||
|
|
||||||
unsigned int numberOfTests = tests.size();
|
unsigned int numberOfTests = tests.size();
|
||||||
unsigned int testToRun = 0;
|
unsigned int testToRun = 0;
|
||||||
|
|
|
@ -1,20 +1,16 @@
|
||||||
// Copyright (C) 2008-2012 Colin MacDonald
|
// Copyright (C) 2008-2012 Colin MacDonald
|
||||||
// No rights reserved: this software is in the public domain.
|
// No rights reserved: this software is in the public domain.
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS 1
|
|
||||||
#define TESTING_ON_WINDOWS
|
|
||||||
#endif // _MSC_VER
|
|
||||||
|
|
||||||
#include "testUtils.h"
|
#include "testUtils.h"
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#if defined(TESTING_ON_WINDOWS)
|
#if defined(_MSC_VER) || defined(_IRR_WINDOWS_API_)
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS 1
|
||||||
#include <windows.h> // For OutputDebugString()
|
#include <windows.h> // For OutputDebugString()
|
||||||
#endif // #if defined(TESTING_ON_WINDOWS)
|
#endif // _MSC_VER || _IRR_WINDOWS_API_
|
||||||
|
|
||||||
using namespace irr;
|
using namespace irr;
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,7 @@
|
||||||
<Unit filename="irrString.cpp" />
|
<Unit filename="irrString.cpp" />
|
||||||
<Unit filename="lightMaps.cpp" />
|
<Unit filename="lightMaps.cpp" />
|
||||||
<Unit filename="lights.cpp" />
|
<Unit filename="lights.cpp" />
|
||||||
|
<Unit filename="line2d.cpp" />
|
||||||
<Unit filename="loadTextures.cpp" />
|
<Unit filename="loadTextures.cpp" />
|
||||||
<Unit filename="main.cpp" />
|
<Unit filename="main.cpp" />
|
||||||
<Unit filename="makeColorKeyTexture.cpp" />
|
<Unit filename="makeColorKeyTexture.cpp" />
|
||||||
|
|
|
@ -179,6 +179,7 @@
|
||||||
<ClCompile Include="irrString.cpp" />
|
<ClCompile Include="irrString.cpp" />
|
||||||
<ClCompile Include="lightMaps.cpp" />
|
<ClCompile Include="lightMaps.cpp" />
|
||||||
<ClCompile Include="lights.cpp" />
|
<ClCompile Include="lights.cpp" />
|
||||||
|
<ClCompile Include="line2d.cpp" />
|
||||||
<ClCompile Include="loadTextures.cpp" />
|
<ClCompile Include="loadTextures.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="makeColorKeyTexture.cpp" />
|
<ClCompile Include="makeColorKeyTexture.cpp" />
|
||||||
|
|
|
@ -179,6 +179,7 @@
|
||||||
<ClCompile Include="irrString.cpp" />
|
<ClCompile Include="irrString.cpp" />
|
||||||
<ClCompile Include="lightMaps.cpp" />
|
<ClCompile Include="lightMaps.cpp" />
|
||||||
<ClCompile Include="lights.cpp" />
|
<ClCompile Include="lights.cpp" />
|
||||||
|
<ClCompile Include="line2d.cpp" />
|
||||||
<ClCompile Include="loadTextures.cpp" />
|
<ClCompile Include="loadTextures.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="makeColorKeyTexture.cpp" />
|
<ClCompile Include="makeColorKeyTexture.cpp" />
|
||||||
|
|
|
@ -179,6 +179,7 @@
|
||||||
<ClCompile Include="irrString.cpp" />
|
<ClCompile Include="irrString.cpp" />
|
||||||
<ClCompile Include="lightMaps.cpp" />
|
<ClCompile Include="lightMaps.cpp" />
|
||||||
<ClCompile Include="lights.cpp" />
|
<ClCompile Include="lights.cpp" />
|
||||||
|
<ClCompile Include="line2d.cpp" />
|
||||||
<ClCompile Include="loadTextures.cpp" />
|
<ClCompile Include="loadTextures.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="makeColorKeyTexture.cpp" />
|
<ClCompile Include="makeColorKeyTexture.cpp" />
|
||||||
|
|
|
@ -179,6 +179,7 @@
|
||||||
<ClCompile Include="irrString.cpp" />
|
<ClCompile Include="irrString.cpp" />
|
||||||
<ClCompile Include="lightMaps.cpp" />
|
<ClCompile Include="lightMaps.cpp" />
|
||||||
<ClCompile Include="lights.cpp" />
|
<ClCompile Include="lights.cpp" />
|
||||||
|
<ClCompile Include="line2d.cpp" />
|
||||||
<ClCompile Include="loadTextures.cpp" />
|
<ClCompile Include="loadTextures.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="makeColorKeyTexture.cpp" />
|
<ClCompile Include="makeColorKeyTexture.cpp" />
|
||||||
|
|
|
@ -132,7 +132,7 @@ inline u32 getTextureSizeFromSurfaceSize(u32 size)
|
||||||
wchar_t currentchar = ch;
|
wchar_t currentchar = ch;
|
||||||
|
|
||||||
if ( IsDBCSLeadByte((BYTE) ch))
|
if ( IsDBCSLeadByte((BYTE) ch))
|
||||||
continue; // surragate pairs unsupported
|
continue; // surrogate pairs unsupported
|
||||||
|
|
||||||
// get the dimensions
|
// get the dimensions
|
||||||
SIZE size;
|
SIZE size;
|
||||||
|
@ -144,9 +144,9 @@ inline u32 getTextureSizeFromSurfaceSize(u32 size)
|
||||||
|
|
||||||
if (GetCharABCWidthsW(dc, currentchar, currentchar, &abc)) // for unicode fonts, get overhang, underhang, width
|
if (GetCharABCWidthsW(dc, currentchar, currentchar, &abc)) // for unicode fonts, get overhang, underhang, width
|
||||||
{
|
{
|
||||||
size.cx = abc.abcB;
|
size.cx = abc.abcB; // full font width (ignoring padding/underhang )
|
||||||
fa.underhang = abc.abcA;
|
fa.underhang = abc.abcA; // underhang/padding left - can also be negative (in which case it's overhang left)
|
||||||
fa.overhang = abc.abcC;
|
fa.overhang = abc.abcC; // overhang/padding right - can also be negative (in which case it's underhand right)
|
||||||
|
|
||||||
if (abc.abcB-abc.abcA+abc.abcC<1)
|
if (abc.abcB-abc.abcA+abc.abcC<1)
|
||||||
continue; // nothing of width 0
|
continue; // nothing of width 0
|
||||||
|
@ -236,7 +236,7 @@ inline u32 getTextureSizeFromSurfaceSize(u32 size)
|
||||||
{
|
{
|
||||||
s32 currentArea = (*it).getValue();
|
s32 currentArea = (*it).getValue();
|
||||||
wchar_t wch = (*it).getKey();
|
wchar_t wch = (*it).getKey();
|
||||||
// sloppy but I couldnt be bothered rewriting it
|
// sloppy but I couldn't be bothered rewriting it
|
||||||
if (Areas[currentArea].sourceimage == currentImage)
|
if (Areas[currentArea].sourceimage == currentImage)
|
||||||
{
|
{
|
||||||
// draw letter
|
// draw letter
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Tool for creating Irrlicht bitmap+vector fonts,
|
Tool for creating Irrlicht bitmap+vector fonts,
|
||||||
started by Gaz Davidson in December 2006
|
started by Gaz Davidson in December 2006
|
||||||
|
|
||||||
Due to my laziness and Microsoft's unituitive API, surragate pairs and
|
Due to my laziness and Microsoft's unintuitive API, surrogate pairs and
|
||||||
nonspacing diacritical marks are not supported!
|
nonspacing diacritical marks are not supported!
|
||||||
|
|
||||||
Linux bitmap font support added by Neil Burlock Oct 2008
|
Linux bitmap font support added by Neil Burlock Oct 2008
|
||||||
|
|
Loading…
Reference in New Issue