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)
|
||||
|
||||
- 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.
|
||||
- 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.
|
||||
|
@ -160,6 +173,17 @@ should now be fps independentn
|
|||
|
||||
--------------------------
|
||||
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.
|
||||
|
||||
--------------------------
|
||||
|
@ -255,7 +279,7 @@ Changes in 1.8 (7.11.2012)
|
|||
|
||||
- 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.
|
||||
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.
|
||||
|
||||
- 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
|
||||
};
|
||||
|
||||
/*
|
||||
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()
|
||||
{
|
||||
// ask user for driver
|
||||
|
@ -86,8 +93,34 @@ int main()
|
|||
{
|
||||
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);
|
||||
// We're not done with this selector yet, so don't drop it.
|
||||
}
|
||||
|
@ -138,7 +171,7 @@ int main()
|
|||
|
||||
if (selector)
|
||||
{
|
||||
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
|
||||
scene::ISceneNodeAnimatorCollisionResponse * anim = smgr->createCollisionResponseAnimator(
|
||||
selector, camera, core::vector3df(30,50,30),
|
||||
core::vector3df(0,-1000,0), core::vector3df(0,30,0));
|
||||
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
|
||||
// is associated with an animated node, and will update itself as necessary.
|
||||
selector = smgr->createTriangleSelector(node);
|
||||
selector = smgr->createTriangleSelector(node, separateMeshBuffers);
|
||||
node->setTriangleSelector(selector);
|
||||
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).Lighting = true;
|
||||
// Just do the same as we did above.
|
||||
selector = smgr->createTriangleSelector(node);
|
||||
selector = smgr->createTriangleSelector(node, separateMeshBuffers);
|
||||
node->setTriangleSelector(selector);
|
||||
selector->drop();
|
||||
|
||||
|
@ -208,11 +241,10 @@ int main()
|
|||
node->setRotation(core::vector3df(0,-90,0)); // And turn it towards the camera.
|
||||
node->setAnimationSpeed(20.f);
|
||||
node->getMaterial(0).Lighting = true;
|
||||
selector = smgr->createTriangleSelector(node);
|
||||
selector = smgr->createTriangleSelector(node, separateMeshBuffers);
|
||||
node->setTriangleSelector(selector);
|
||||
selector->drop();
|
||||
|
||||
|
||||
// And this mdl file uses skinned skeletal animation.
|
||||
node = smgr->addAnimatedMeshSceneNode(smgr->getMesh(mediaPath + "yodan.mdl"),
|
||||
0, IDFlag_IsPickable | IDFlag_IsHighlightable);
|
||||
|
@ -222,7 +254,7 @@ int main()
|
|||
node->setAnimationSpeed(20.f);
|
||||
|
||||
// Just do the same as we did above.
|
||||
selector = smgr->createTriangleSelector(node);
|
||||
selector = smgr->createTriangleSelector(node, separateMeshBuffers);
|
||||
node->setTriangleSelector(selector);
|
||||
selector->drop();
|
||||
|
||||
|
@ -237,7 +269,6 @@ int main()
|
|||
// Remember which scene node is highlighted
|
||||
scene::ISceneNode* highlightedSceneNode = 0;
|
||||
scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();
|
||||
int lastFPS = -1;
|
||||
|
||||
// draw the selection triangle only as wireframe
|
||||
material.Wireframe=true;
|
||||
|
@ -263,10 +294,6 @@ int main()
|
|||
ray.start = camera->getPosition();
|
||||
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
|
||||
// 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,
|
||||
// ray/box and ellipse/triangle selector, plus associated helpers.
|
||||
// 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,
|
||||
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
|
||||
// set up to be pickable are considered
|
||||
0); // Check the entire scene (this is actually the implicit default)
|
||||
|
||||
|
||||
// If the ray hit anything, move the billboard to the collision position
|
||||
// and draw the triangle that was hit.
|
||||
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.
|
||||
driver->setTransform(video::ETS_WORLD, core::matrix4());
|
||||
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
|
||||
// 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.
|
||||
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.
|
||||
driver->endScene();
|
||||
|
||||
// Show some info in title-bar
|
||||
int fps = driver->getFPS();
|
||||
|
||||
if (lastFPS != fps)
|
||||
core::stringw str = L"Collision detection example - Irrlicht Engine [";
|
||||
str += driver->getName();
|
||||
str += "] FPS:";
|
||||
str += fps;
|
||||
if ( !hitTextureName.getInternalName().empty() )
|
||||
{
|
||||
core::stringw str = L"Collision detection example - Irrlicht Engine [";
|
||||
str += driver->getName();
|
||||
str += "] FPS:";
|
||||
str += fps;
|
||||
|
||||
device->setWindowCaption(str.c_str());
|
||||
lastFPS = fps;
|
||||
str += " ";
|
||||
irr::io::path texName(hitTextureName.getInternalName());
|
||||
str += core::deletePathFromFilename(texName);
|
||||
}
|
||||
device->setWindowCaption(str.c_str());
|
||||
}
|
||||
|
||||
device->drop();
|
||||
|
|
|
@ -30,6 +30,9 @@ namespace scene
|
|||
//! Text Scene Node
|
||||
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
|
||||
ESNT_WATER_SURFACE = MAKE_IRR_ID('w','a','t','r'),
|
||||
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
|
||||
namespace irr
|
||||
{
|
||||
|
||||
namespace gui
|
||||
{
|
||||
class IGUIFont;
|
||||
}
|
||||
|
||||
namespace scene
|
||||
{
|
||||
|
||||
|
@ -50,8 +56,18 @@ public:
|
|||
//! sets the text string
|
||||
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
|
||||
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
|
||||
|
|
|
@ -38,10 +38,10 @@ public:
|
|||
virtual bool getProcessorSpeedMHz(u32* MHz) const = 0;
|
||||
|
||||
//! Get the total and available system RAM
|
||||
/** \param Total: will contain the total system memory
|
||||
\param Avail: will contain the available memory
|
||||
/** \param totalBytes: will contain the total system memory in bytes
|
||||
\param availableBytes: will contain the available memory in bytes
|
||||
\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 ICameraSceneNode;
|
||||
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.
|
||||
class ISceneCollisionManager : public virtual IReferenceCounted
|
||||
{
|
||||
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.
|
||||
/** \param ray: Line with which collisions are tested.
|
||||
\param selector: TriangleSelector containing the triangles. It
|
||||
|
@ -40,7 +73,18 @@ namespace scene
|
|||
\return True if a collision was detected and false if not. */
|
||||
virtual bool getCollisionPoint(const core::line3d<f32>& ray,
|
||||
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.
|
||||
/** 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,
|
||||
s32 idBitMask=0, bool bNoDebugObjects = false) = 0;
|
||||
|
||||
|
||||
//! 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
|
||||
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
|
||||
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 outCollisionPoint: If a collision is detected, this will contain the
|
||||
position of the nearest collision.
|
||||
|
@ -194,12 +264,21 @@ namespace scene
|
|||
core::triangle3df& outTriangle,
|
||||
s32 idBitMask = 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 irr
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -322,7 +322,7 @@ namespace scene
|
|||
* files thanks to<br> the importer created by Jonas
|
||||
* Petersen.
|
||||
* 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>
|
||||
* - The TGAs generated by LMTools don't work in
|
||||
* Irrlicht for some reason (the textures are upside
|
||||
|
@ -1271,19 +1271,30 @@ namespace scene
|
|||
s->drop();
|
||||
\endcode
|
||||
\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.
|
||||
If you no longer need the selector, you should call ITriangleSelector::drop().
|
||||
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.
|
||||
/** 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 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.
|
||||
|
@ -1323,6 +1334,33 @@ namespace scene
|
|||
virtual ITriangleSelector* createOctreeTriangleSelector(IMesh* mesh,
|
||||
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.
|
||||
/** \deprecated Use createOctreeTriangleSelector instead. This method may be removed by Irrlicht 1.9. */
|
||||
_IRR_DEPRECATED_ ITriangleSelector* createOctTreeTriangleSelector(IMesh* mesh,
|
||||
|
@ -1589,7 +1627,7 @@ namespace scene
|
|||
using ISceneManager::saveScene().
|
||||
\param file File where the scene is loaded from.
|
||||
\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
|
||||
as parameter here. Otherwise, simply specify 0 as this
|
||||
parameter.
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
|
||||
namespace irr
|
||||
{
|
||||
|
||||
namespace gui
|
||||
{
|
||||
class IGUIFont;
|
||||
}
|
||||
|
||||
namespace scene
|
||||
{
|
||||
|
||||
|
@ -25,8 +31,20 @@ public:
|
|||
//! sets the text string
|
||||
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
|
||||
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
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "aabbox3d.h"
|
||||
#include "matrix4.h"
|
||||
#include "line3d.h"
|
||||
#include "irrArray.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
@ -17,6 +18,49 @@ namespace scene
|
|||
{
|
||||
|
||||
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.
|
||||
/** Every ISceneNode may have a triangle selector, available with
|
||||
|
@ -45,10 +89,18 @@ public:
|
|||
into the array.
|
||||
\param transform Pointer to matrix for transforming the triangles
|
||||
before they are returned. Useful for example to scale all triangles
|
||||
down into an ellipsoid space. If this pointer is null, no
|
||||
transformation will be done. */
|
||||
down into an ellipsoid space.
|
||||
\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,
|
||||
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.
|
||||
/**
|
||||
|
@ -68,11 +120,17 @@ public:
|
|||
will be written into the array.
|
||||
\param transform Pointer to matrix for transforming the triangles
|
||||
before they are returned. Useful for example to scale all triangles
|
||||
down into an ellipsoid space. If this pointer is null, no
|
||||
transformation will be done. */
|
||||
down into an ellipsoid space.
|
||||
\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,
|
||||
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.
|
||||
/**
|
||||
|
@ -92,22 +150,17 @@ public:
|
|||
will be written into the array.
|
||||
\param transform Pointer to matrix for transforming the triangles
|
||||
before they are returned. Useful for example to scale all triangles
|
||||
down into an ellipsoid space. If this pointer is null, no
|
||||
transformation will be done. */
|
||||
down into an ellipsoid space.
|
||||
\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,
|
||||
s32& outTriangleCount, const core::line3d<f32>& line,
|
||||
const core::matrix4* transform=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;
|
||||
const core::matrix4* transform=0, bool useNodeTransform=true,
|
||||
irr::core::array<SCollisionTriangleRange>* outTriangleInfo=0) const = 0;
|
||||
|
||||
//! Get number of TriangleSelectors that are part of this one
|
||||
/** Only useful for MetaTriangleSelector, others return 1
|
||||
|
@ -123,6 +176,17 @@ public:
|
|||
/** Only useful for MetaTriangleSelector, others return 'this' or 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
|
||||
|
|
|
@ -177,9 +177,10 @@ namespace irr
|
|||
KEY_PLAY = 0xFA, // Play key
|
||||
KEY_ZOOM = 0xFB, // Zoom 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
|
||||
|
|
|
@ -165,8 +165,7 @@ namespace video
|
|||
return true;
|
||||
else
|
||||
different |= (TextureMatrix != b.TextureMatrix) &&
|
||||
TextureMatrix && b.TextureMatrix &&
|
||||
(*TextureMatrix != *(b.TextureMatrix));
|
||||
(!TextureMatrix || !b.TextureMatrix || (*TextureMatrix != *(b.TextureMatrix)));
|
||||
return different;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,13 +83,26 @@ namespace scene
|
|||
//! recalculates the bounding box
|
||||
void recalculateBoundingBox()
|
||||
{
|
||||
if (MeshBuffers.size())
|
||||
bool hasMeshBufferBBox = false;
|
||||
for (u32 i=0; i<MeshBuffers.size(); ++i)
|
||||
{
|
||||
BoundingBox = MeshBuffers[0]->getBoundingBox();
|
||||
for (u32 i=1; i<MeshBuffers.size(); ++i)
|
||||
BoundingBox.addInternalBox(MeshBuffers[i]->getBoundingBox());
|
||||
const core::aabbox3df& bb = MeshBuffers[i]->getBoundingBox();
|
||||
if ( !bb.isEmpty() )
|
||||
{
|
||||
if ( !hasMeshBufferBBox )
|
||||
{
|
||||
hasMeshBufferBBox = true;
|
||||
BoundingBox = bb;
|
||||
}
|
||||
else
|
||||
{
|
||||
BoundingBox.addInternalBox(bb);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if ( !hasMeshBufferBBox )
|
||||
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.
|
||||
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] = {
|
||||
0.f,
|
||||
0.1f,
|
||||
|
@ -323,8 +324,16 @@ inline const char* fast_atof_move(const char* in, f32& result)
|
|||
if ( LOCALE_DECIMAL_POINTS.findFirst(*in) >= 0 )
|
||||
{
|
||||
const char* afterDecimal = ++in;
|
||||
const f32 decimal = strtof10(in, &afterDecimal);
|
||||
value += decimal * fast_atof_table[afterDecimal - in];
|
||||
f32 decimal = strtof10(in, &afterDecimal);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -334,7 +343,8 @@ inline const char* fast_atof_move(const char* in, f32& result)
|
|||
// Assume that the exponent is a whole number.
|
||||
// strtol10() will deal with both + and - signs,
|
||||
// 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;
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace core
|
|||
//! Rounding error constant often used when comparing f32 values.
|
||||
|
||||
const s32 ROUNDING_ERROR_S32 = 0;
|
||||
|
||||
#ifdef __IRR_HAS_S64
|
||||
const s64 ROUNDING_ERROR_S64 = 0;
|
||||
#endif
|
||||
|
@ -181,16 +182,85 @@ namespace core
|
|||
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
|
||||
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);
|
||||
}
|
||||
|
||||
//! 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
|
||||
|
@ -233,39 +303,6 @@ namespace core
|
|||
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
|
||||
inline bool iszero(const f64 a, const f64 tolerance = ROUNDING_ERROR_f64)
|
||||
{
|
||||
|
|
|
@ -1306,14 +1306,14 @@ public:
|
|||
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
|
||||
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
|
||||
a size method.
|
||||
\param ret The result container
|
||||
\param c C-style string of delimiter characters
|
||||
\param count Number of delimiter characters
|
||||
\param ret The result container. Tokens are added, the container is not cleared.
|
||||
\param delimiter C-style string of delimiter characters
|
||||
\param countDelimiters Number of delimiter characters
|
||||
\param ignoreEmptyTokens Flag to avoid empty substrings in the result
|
||||
container. If two delimiters occur without a character in between, an
|
||||
empty substring would be placed in the result. If this flag is set,
|
||||
|
@ -1325,33 +1325,39 @@ public:
|
|||
\return The number of resulting substrings
|
||||
*/
|
||||
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;
|
||||
|
||||
const u32 oldSize=ret.size();
|
||||
u32 lastpos = 0;
|
||||
bool lastWasSeparator = false;
|
||||
|
||||
u32 tokenStartIdx = 0;
|
||||
for (u32 i=0; i<used; ++i)
|
||||
{
|
||||
bool foundSeparator = false;
|
||||
for (u32 j=0; j<count; ++j)
|
||||
for (u32 j=0; j<countDelimiters; ++j)
|
||||
{
|
||||
if (array[i] == c[j])
|
||||
if (array[i] == delimiter[j])
|
||||
{
|
||||
if ((!ignoreEmptyTokens || i - lastpos != 0) &&
|
||||
!lastWasSeparator)
|
||||
ret.push_back(string<T,TAlloc>(&array[lastpos], i - lastpos));
|
||||
foundSeparator = true;
|
||||
lastpos = (keepSeparators ? i : i + 1);
|
||||
if ( keepSeparators )
|
||||
{
|
||||
ret.push_back(string<T,TAlloc>(&array[tokenStartIdx], i+1 - tokenStartIdx));
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
lastWasSeparator = foundSeparator;
|
||||
}
|
||||
if ((used - 1) > lastpos)
|
||||
ret.push_back(string<T,TAlloc>(&array[lastpos], (used - 1) - lastpos));
|
||||
if ((used - 1) > tokenStartIdx)
|
||||
ret.push_back(string<T,TAlloc>(&array[tokenStartIdx], (used - 1) - tokenStartIdx));
|
||||
|
||||
return ret.size()-oldSize;
|
||||
}
|
||||
|
||||
|
|
|
@ -316,27 +316,31 @@ namespace io
|
|||
|
||||
//! Returns the value of an attribute as integer.
|
||||
/** \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
|
||||
the value could not be interpreted as integer. */
|
||||
virtual int getAttributeValueAsInt(const char_type* name) const = 0;
|
||||
\param defaultNotFound Value returned when name does not exist
|
||||
\return Value of the attribute as integer or value of defaultNotFound
|
||||
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.
|
||||
/** \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
|
||||
the value could not be interpreted as integer. */
|
||||
virtual int getAttributeValueAsInt(int idx) const = 0;
|
||||
\param defaultNotFound Value returned when index does not exist.
|
||||
\return Value of the attribute as integer or value of defaultNotFound parameter for invalid index
|
||||
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.
|
||||
/** \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
|
||||
the value could not be interpreted as float. */
|
||||
virtual float getAttributeValueAsFloat(const char_type* name) const = 0;
|
||||
\param defaultNotFound Value returned when name does not exist.
|
||||
\return Value of the attribute as float or value of defaultNotFound parameter on failure
|
||||
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.
|
||||
/** \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
|
||||
the value could not be interpreted as float. */
|
||||
virtual float getAttributeValueAsFloat(int idx) const = 0;
|
||||
\param defaultNotFound Value returned when index does not exist.
|
||||
\return Value of the attribute as float or value of defaultNotFound parameter on failure
|
||||
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.
|
||||
/** Only valid, if the node type is EXN_ELEMENT.
|
||||
|
|
|
@ -65,7 +65,85 @@ class line2d
|
|||
|
||||
//! Get 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.
|
||||
/** \param l: Other line to test intersection with.
|
||||
|
@ -209,7 +287,7 @@ class line2d
|
|||
/** Assumes that the point is already somewhere on the line. */
|
||||
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
|
||||
|
|
|
@ -221,18 +221,25 @@ namespace core
|
|||
void rotateVect(T *out,const core::vector3df &in) const;
|
||||
|
||||
//! 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;
|
||||
|
||||
//! 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;
|
||||
|
||||
//! 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;
|
||||
|
||||
//! 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;
|
||||
|
||||
//! 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;
|
||||
|
||||
//! Transforms a plane by this matrix
|
||||
|
@ -247,7 +254,7 @@ namespace core
|
|||
void transformBox(core::aabbox3d<f32>& box) const;
|
||||
|
||||
//! 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(). */
|
||||
void transformBoxEx(core::aabbox3d<f32>& box) const;
|
||||
|
||||
|
@ -2233,6 +2240,8 @@ namespace core
|
|||
{
|
||||
#if defined ( USE_MATRIX_TEST )
|
||||
definitelyIdentityMatrix = isDefinitelyIdentityMatrix;
|
||||
#else
|
||||
(void)isDefinitelyIdentityMatrix; // prevent compiler warning
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,8 @@ class quaternion
|
|||
//! Creates a matrix from this quaternion
|
||||
matrix4 getMatrix() const;
|
||||
#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
|
||||
void getMatrix( matrix4 &dest, const core::vector3df &translation=core::vector3df() ) const;
|
||||
|
@ -349,12 +351,51 @@ inline matrix4 quaternion::getMatrix() const
|
|||
}
|
||||
#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
|
||||
*/
|
||||
inline void quaternion::getMatrix(matrix4 &dest,
|
||||
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[1] = 2.0f*X*Y + 2.0f*Z*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 &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[1] = 2.0f*X*Y + 2.0f*Z*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
|
||||
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[4] = 2.0f*X*Y + 2.0f*Z*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
|
||||
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
|
||||
|
@ -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
|
||||
inline bool quaternion::equals(const quaternion& other, const f32 tolerance) const
|
||||
{
|
||||
return core::equals(X, other.X, tolerance) &&
|
||||
core::equals(Y, other.Y, tolerance) &&
|
||||
core::equals(Z, other.Z, tolerance) &&
|
||||
core::equals(W, other.W, tolerance);
|
||||
return core::equals( X, other.X, tolerance) &&
|
||||
core::equals( Y, other.Y, tolerance) &&
|
||||
core::equals( Z, other.Z, tolerance) &&
|
||||
core::equals( W, other.W, tolerance);
|
||||
}
|
||||
|
||||
|
||||
// normalizes the quaternion
|
||||
inline quaternion& quaternion::normalize()
|
||||
{
|
||||
const f32 n = X*X + Y*Y + Z*Z + W*W;
|
||||
|
||||
if (n == 1)
|
||||
return *this;
|
||||
|
||||
//n = 1.0f / sqrtf(n);
|
||||
return (*this *= reciprocal_squareroot ( n ));
|
||||
// removed conditional branch since it may slow down and anyway the condition was
|
||||
// false even after normalization in some cases.
|
||||
return (*this *= reciprocal_squareroot ( X*X + Y*Y + Z*Z + W*W ));
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
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
|
||||
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);
|
||||
|
||||
|
|
|
@ -127,6 +127,20 @@ public:
|
|||
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.
|
||||
/** Here, the vector is interpreted as a point in 2-dimensional space.
|
||||
\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. */
|
||||
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)
|
||||
{
|
||||
return ((begin.X <= X && X <= end.X) ||
|
||||
(begin.X >= X && X >= end.X));
|
||||
(begin.X >= X && X >= end.X));
|
||||
}
|
||||
else
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
/*! 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.
|
||||
/** \param a first vector to interpolate with, maximum at 1.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)
|
||||
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 ));
|
||||
Y = (T)((f64)b.Y + ( ( a.Y - b.Y ) * d ));
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace scene
|
|||
{
|
||||
BinaryFileReader(io::IReadFile* pFile) : file(pFile) { }
|
||||
|
||||
s32 readBuffer(void* buffer, s32 len)
|
||||
size_t readBuffer(void* buffer, s32 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));
|
||||
}
|
||||
|
||||
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
|
||||
bool CD3D9Driver::reset()
|
||||
|
|
|
@ -170,6 +170,9 @@ namespace video
|
|||
virtual void draw3DLine(const core::vector3df& start,
|
||||
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
|
||||
bool initDriver(HWND hwnd, bool pureSoftware);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "CDefaultSceneNodeFactory.h"
|
||||
#include "ISceneManager.h"
|
||||
#include "ITextSceneNode.h"
|
||||
#include "IBillboardTextSceneNode.h"
|
||||
#include "ITerrainSceneNode.h"
|
||||
#include "IDummyTransformationSceneNode.h"
|
||||
#include "ICameraSceneNode.h"
|
||||
|
@ -33,6 +34,7 @@ CDefaultSceneNodeFactory::CDefaultSceneNodeFactory(ISceneManager* mgr)
|
|||
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_CUBE, "cube"));
|
||||
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_SPHERE, "sphere"));
|
||||
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_TERRAIN, "terrain"));
|
||||
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);
|
||||
case ESNT_TEXT:
|
||||
return Manager->addTextSceneNode(0, L"example");
|
||||
case ESNT_BILLBOARD_TEXT:
|
||||
return Manager->addBillboardTextSceneNode(0, L"example");
|
||||
case ESNT_WATER_SURFACE:
|
||||
return Manager->addWaterSurfaceSceneNode(0, 2.0f, 300.0f, 10.0f, parent);
|
||||
case ESNT_TERRAIN:
|
||||
|
|
|
@ -826,7 +826,7 @@ IFileList* CFileSystem::createFileList()
|
|||
CFileList* r = 0;
|
||||
io::path Path = getWorkingDirectory();
|
||||
Path.replace('\\', '/');
|
||||
if (Path.lastChar() != '/')
|
||||
if (!Path.empty() && Path.lastChar() != '/')
|
||||
Path.append('/');
|
||||
|
||||
//! Construct from native filesystem
|
||||
|
|
|
@ -285,22 +285,25 @@ bool CGUIContextMenu::OnEvent(const SEvent& event)
|
|||
{
|
||||
// set event parent of submenus
|
||||
IGUIElement * p = EventParent ? EventParent : Parent;
|
||||
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) )
|
||||
if ( p ) // can be 0 when element got removed already
|
||||
{
|
||||
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_REMOVE )
|
||||
{
|
||||
remove();
|
||||
if ( CloseHandling & ECMC_HIDE )
|
||||
{
|
||||
setVisible(false);
|
||||
}
|
||||
if ( CloseHandling & ECMC_REMOVE )
|
||||
{
|
||||
remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ bool CImageLoaderJPG::isALoadableFileFormat(io::IReadFile* file) const
|
|||
if (!(file && file->seek(0)))
|
||||
return false;
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -498,6 +498,11 @@ bool CIrrDeviceLinux::createWindow()
|
|||
IrrPrintXGrabError(grabPointer, "XGrabPointer");
|
||||
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
|
||||
{
|
||||
|
|
|
@ -1395,6 +1395,10 @@ void CIrrDeviceMacOSX::initKeycodes()
|
|||
KeyCodes[kVK_ANSI_KeypadDivide] = irr::KEY_DIVIDE;
|
||||
KeyCodes[kVK_ANSI_KeypadEnter] = irr::KEY_RETURN;
|
||||
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)
|
||||
{
|
||||
#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
|
||||
joystickInfo.clear();
|
||||
ActiveJoysticks.clear();
|
||||
#ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
|
||||
if (!DirectInputDevice || (DirectInputDevice->EnumDevices(DI8DEVCLASS_GAMECTRL, SJoystickWin32Control::EnumJoysticks, this, DIEDFL_ATTACHEDONLY )))
|
||||
{
|
||||
|
@ -475,9 +477,6 @@ bool SJoystickWin32Control::activateJoysticks(core::array<SJoystickInfo> & joyst
|
|||
}
|
||||
return true;
|
||||
#else
|
||||
joystickInfo.clear();
|
||||
ActiveJoysticks.clear();
|
||||
|
||||
const u32 numberOfJoysticks = ::joyGetNumDevs();
|
||||
JOYINFOEX 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
|
||||
// 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)
|
||||
|
|
|
@ -118,13 +118,16 @@ namespace irr
|
|||
return CIrrDeviceStub::checkSuccessiveClicks(mouseX, mouseY, inputEvent );
|
||||
}
|
||||
|
||||
//! switchs to fullscreen
|
||||
//! Switch to fullscreen
|
||||
bool switchToFullScreen(bool reset=false);
|
||||
|
||||
//! 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();
|
||||
|
||||
//! 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
|
||||
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)
|
||||
{
|
||||
s32 paddingBorder = 0;
|
||||
#if defined (SM_CXPADDEDBORDER)
|
||||
if (CIrrDeviceWin32::isWindowsVistaOrGreater())
|
||||
paddingBorder = GetSystemMetrics(SM_CXPADDEDBORDER);
|
||||
#endif
|
||||
|
||||
if (resizable)
|
||||
{
|
||||
BorderX = GetSystemMetrics(SM_CXSIZEFRAME);
|
||||
BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYSIZEFRAME);
|
||||
BorderX = GetSystemMetrics(SM_CXSIZEFRAME) + paddingBorder;
|
||||
BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYSIZEFRAME) + paddingBorder;
|
||||
}
|
||||
else
|
||||
{
|
||||
BorderX = GetSystemMetrics(SM_CXDLGFRAME);
|
||||
BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME);
|
||||
BorderX = GetSystemMetrics(SM_CXDLGFRAME) + paddingBorder;
|
||||
BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME) + paddingBorder;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -159,7 +159,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
|
|||
// read whole file
|
||||
|
||||
u8* buffer = new u8[fileSize];
|
||||
s32 read = file->read(buffer, fileSize);
|
||||
long read = (long)file->read(buffer, fileSize);
|
||||
if (read != fileSize)
|
||||
{
|
||||
delete [] buffer;
|
||||
|
|
|
@ -38,14 +38,27 @@ s32 CMetaTriangleSelector::getTriangleCount() const
|
|||
|
||||
//! Gets all triangles.
|
||||
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;
|
||||
irr::u32 outTriangleInfoSize = outTriangleInfo ? outTriangleInfo->size() : 0;
|
||||
for (u32 i=0; i<TriangleSelectors.size(); ++i)
|
||||
{
|
||||
s32 t = 0;
|
||||
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;
|
||||
if (outWritten==arraySize)
|
||||
break;
|
||||
|
@ -58,14 +71,27 @@ void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 array
|
|||
//! Gets all triangles which lie within a specific bounding box.
|
||||
void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||
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;
|
||||
irr::u32 outTriangleInfoSize = outTriangleInfo ? outTriangleInfo->size() : 0;
|
||||
for (u32 i=0; i<TriangleSelectors.size(); ++i)
|
||||
{
|
||||
s32 t = 0;
|
||||
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;
|
||||
if (outWritten==arraySize)
|
||||
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.
|
||||
void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, 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
|
||||
{
|
||||
s32 outWritten = 0;
|
||||
irr::u32 outTriangleInfoSize = outTriangleInfo ? outTriangleInfo->size() : 0;
|
||||
for (u32 i=0; i<TriangleSelectors.size(); ++i)
|
||||
{
|
||||
s32 t = 0;
|
||||
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;
|
||||
if (outWritten==arraySize)
|
||||
break;
|
||||
|
@ -147,11 +186,9 @@ ISceneNode* CMetaTriangleSelector::getSceneNodeForTriangle(u32 triangleIndex) co
|
|||
return TriangleSelectors[i]->getSceneNodeForTriangle(0);
|
||||
}
|
||||
|
||||
// For lack of anything more sensible, return the first selector.
|
||||
return TriangleSelectors[0]->getSceneNodeForTriangle(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Return the number of TriangleSelectors that are inside this one,
|
||||
Only useful for MetaTriangleSelector others return 1
|
||||
*/
|
||||
|
|
|
@ -29,17 +29,20 @@ public:
|
|||
|
||||
//! Gets all triangles.
|
||||
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.
|
||||
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::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.
|
||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||
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
|
||||
//! in this metaTriangleSelector.
|
||||
|
|
|
@ -100,6 +100,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
|
|||
bool mtlChanged=false;
|
||||
bool useGroups = !SceneManager->getParameters()->getAttributeAsBool(OBJ_LOADER_IGNORE_GROUPS);
|
||||
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)
|
||||
{
|
||||
switch(bufPtr[0])
|
||||
|
@ -289,6 +290,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
|
|||
} // end switch(bufPtr[0])
|
||||
// eat up rest of line
|
||||
bufPtr = goNextLine(bufPtr, bufEnd);
|
||||
++lineNr;
|
||||
} // end while(bufPtr && (bufPtr-buf<filesize))
|
||||
|
||||
SMesh* mesh = new SMesh();
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
#else
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#ifndef _IRR_SOLARIS_PLATFORM_
|
||||
#ifndef _IRR_ANDROID_PLATFORM_
|
||||
#include <sys/types.h>
|
||||
#ifdef _IRR_OSX_PLATFORM_
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#endif
|
||||
|
@ -84,7 +84,7 @@ void COSOperator::copyToClipboard(const c8* text) const
|
|||
#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
|
||||
NSString *str = nil;
|
||||
NSPasteboard *board = nil;
|
||||
|
||||
|
||||
if ((text != NULL) && (strlen(text) > 0))
|
||||
{
|
||||
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 setString:str forType:NSStringPboardType];
|
||||
}
|
||||
|
||||
|
||||
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
||||
if ( IrrDeviceLinux )
|
||||
IrrDeviceLinux->copyToClipboard(text);
|
||||
|
@ -127,10 +127,10 @@ const c8* COSOperator::getTextFromClipboard() const
|
|||
|
||||
board = [NSPasteboard generalPasteboard];
|
||||
str = [board stringForType:NSStringPboardType];
|
||||
|
||||
|
||||
if (str != nil)
|
||||
result = (char*)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding];
|
||||
|
||||
|
||||
return (result);
|
||||
|
||||
#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
|
||||
{
|
||||
#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.dwLength = sizeof(MEMORYSTATUS);
|
||||
|
||||
// cannot fail
|
||||
// cannot fail
|
||||
GlobalMemoryStatus(&MemoryStatus);
|
||||
|
||||
if (Total)
|
||||
if (Total)
|
||||
*Total = (u32)(MemoryStatus.dwTotalPhys>>10);
|
||||
if (Avail)
|
||||
if (Avail)
|
||||
*Avail = (u32)(MemoryStatus.dwAvailPhys>>10);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#elif defined(_IRR_POSIX_API_) && !defined(__FreeBSD__)
|
||||
#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);
|
||||
return true;
|
||||
#else
|
||||
// TODO: implement for non-availablity of symbols/features
|
||||
// TODO: implement for non-availability of symbols/features
|
||||
return false;
|
||||
#endif
|
||||
#elif defined(_IRR_OSX_PLATFORM_)
|
||||
|
|
|
@ -15,8 +15,9 @@ namespace scene
|
|||
//! constructor
|
||||
COctreeTriangleSelector::COctreeTriangleSelector(const IMesh* mesh,
|
||||
ISceneNode* node, s32 minimalPolysPerNode)
|
||||
: CTriangleSelector(mesh, node), Root(0), NodeCount(0),
|
||||
MinimalPolysPerNode(minimalPolysPerNode)
|
||||
: CTriangleSelector(mesh, node, false)
|
||||
, Root(0), NodeCount(0)
|
||||
, MinimalPolysPerNode(minimalPolysPerNode)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
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
|
||||
COctreeTriangleSelector::~COctreeTriangleSelector()
|
||||
|
@ -111,15 +136,19 @@ void COctreeTriangleSelector::constructOctree(SOctreeNode* node)
|
|||
void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||
s32 arraySize, s32& outTriangleCount,
|
||||
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::aabbox3d<f32> invbox = box;
|
||||
|
||||
if (SceneNode)
|
||||
if (SceneNode && useNodeTransform)
|
||||
{
|
||||
SceneNode->getAbsoluteTransformation().getInverse(mat);
|
||||
mat.transformBoxEx(invbox);
|
||||
if ( SceneNode->getAbsoluteTransformation().getInverse(mat) )
|
||||
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)
|
||||
|
@ -127,7 +156,7 @@ void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles,
|
|||
else
|
||||
mat.makeIdentity();
|
||||
|
||||
if (SceneNode)
|
||||
if (SceneNode && useNodeTransform)
|
||||
mat *= SceneNode->getAbsoluteTransformation();
|
||||
|
||||
s32 trianglesWritten = 0;
|
||||
|
@ -136,6 +165,17 @@ void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles,
|
|||
getTrianglesFromOctree(Root, trianglesWritten,
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -180,7 +220,8 @@ void COctreeTriangleSelector::getTrianglesFromOctree(
|
|||
// new version: from user Piraaate
|
||||
void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles, 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
|
||||
{
|
||||
#if 0
|
||||
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::vector3df vectStartInv ( line.start ), vectEndInv ( line.end );
|
||||
if (SceneNode)
|
||||
if (SceneNode && useNodeTransform)
|
||||
{
|
||||
mat = SceneNode->getAbsoluteTransformation();
|
||||
mat.makeInverse();
|
||||
|
@ -208,7 +249,7 @@ void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arr
|
|||
if (transform)
|
||||
mat = (*transform);
|
||||
|
||||
if (SceneNode)
|
||||
if (SceneNode && useNodeTransform)
|
||||
mat *= SceneNode->getAbsoluteTransformation();
|
||||
|
||||
s32 trianglesWritten = 0;
|
||||
|
@ -216,6 +257,17 @@ void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arr
|
|||
if (Root)
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
|
@ -262,4 +314,3 @@ void COctreeTriangleSelector::getTrianglesFromOctree(SOctreeNode* node,
|
|||
|
||||
} // end namespace scene
|
||||
} // end namespace irr
|
||||
|
||||
|
|
|
@ -22,16 +22,21 @@ public:
|
|||
//! Constructs a selector based on a mesh
|
||||
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();
|
||||
|
||||
//! Gets all triangles which lie within a specific bounding box.
|
||||
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.
|
||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||
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:
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@ COpenGLCacheHandler::COpenGLCacheHandler(COpenGLDriver* driver) :
|
|||
glAlphaFunc(AlphaMode, AlphaRef);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
|
||||
|
||||
glMatrixMode(MatrixMode);
|
||||
|
||||
Driver->irrGlClientActiveTexture(ClientActiveTexture);
|
||||
|
|
|
@ -1087,14 +1087,19 @@ void COpenGLDriver::renderArray(const void* indexList, u32 primitiveCount,
|
|||
glPointSize(particleSize);
|
||||
|
||||
#ifdef GL_ARB_point_sprite
|
||||
if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite])
|
||||
glTexEnvf(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE, GL_TRUE);
|
||||
if (pType == scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite])
|
||||
{
|
||||
CacheHandler->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE, GL_TRUE);
|
||||
}
|
||||
#endif
|
||||
glDrawArrays(GL_POINTS, 0, primitiveCount);
|
||||
#ifdef GL_ARB_point_sprite
|
||||
if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite])
|
||||
{
|
||||
glDisable(GL_POINT_SPRITE_ARB);
|
||||
|
||||
CacheHandler->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
glTexEnvf(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE, GL_FALSE);
|
||||
}
|
||||
#endif
|
||||
|
@ -2098,8 +2103,6 @@ void COpenGLDriver::setMaterial(const SMaterial& material)
|
|||
CacheHandler->getTextureCache().set(i, material.getTexture(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->setAlphaTest(false);
|
||||
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
|
||||
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
|
||||
|
||||
for (s32 i = Feature.TextureUnit - 1; i>= 0; --i)
|
||||
for (s32 i = Feature.TextureUnit - 1; i >= 0; --i)
|
||||
{
|
||||
bool fixedPipeline = false;
|
||||
|
||||
|
@ -2756,149 +2761,146 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
|
|||
|
||||
const COpenGLTexture* tmpTexture = CacheHandler->getTextureCache().get(i);
|
||||
|
||||
if (!tmpTexture)
|
||||
continue;
|
||||
|
||||
CacheHandler->setActiveTexture(GL_TEXTURE0 + i);
|
||||
|
||||
if (fixedPipeline)
|
||||
if (tmpTexture)
|
||||
{
|
||||
const bool isRTT = tmpTexture->isRenderTarget();
|
||||
CacheHandler->setActiveTexture(GL_TEXTURE0 + i);
|
||||
|
||||
CacheHandler->setMatrixMode(GL_TEXTURE);
|
||||
|
||||
if (!isRTT && Matrices[ETS_TEXTURE_0 + i].isIdentity())
|
||||
glLoadIdentity();
|
||||
else
|
||||
if (fixedPipeline)
|
||||
{
|
||||
GLfloat glmat[16];
|
||||
if (isRTT)
|
||||
getGLTextureMatrix(glmat, Matrices[ETS_TEXTURE_0 + i] * TextureFlipMatrix);
|
||||
const bool isRTT = tmpTexture->isRenderTarget();
|
||||
|
||||
CacheHandler->setMatrixMode(GL_TEXTURE);
|
||||
|
||||
if (!isRTT && Matrices[ETS_TEXTURE_0 + i].isIdentity())
|
||||
glLoadIdentity();
|
||||
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)
|
||||
statesCache.IsCached = false;
|
||||
if (resetAllRenderstates)
|
||||
statesCache.IsCached = false;
|
||||
|
||||
#ifdef GL_VERSION_2_1
|
||||
if (Version>=210)
|
||||
{
|
||||
if (!statesCache.IsCached || material.TextureLayer[i].LODBias != statesCache.LODBias)
|
||||
if (Version >= 210)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
glTexParameterf(tmpType, GL_TEXTURE_LOD_BIAS, 0.f);
|
||||
|
||||
statesCache.LODBias = material.TextureLayer[i].LODBias;
|
||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.f);
|
||||
}
|
||||
}
|
||||
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)
|
||||
if (FeatureAvailable[IRR_EXT_texture_lod_bias])
|
||||
{
|
||||
if (material.TextureLayer[i].LODBias)
|
||||
if (FeatureAvailable[IRR_EXT_texture_lod_bias])
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
else
|
||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.f);
|
||||
}
|
||||
#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 ||
|
||||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter || !statesCache.MipMapStatus)
|
||||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter)
|
||||
{
|
||||
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,
|
||||
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;
|
||||
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
|
||||
if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic] &&
|
||||
(!statesCache.IsCached || material.TextureLayer[i].AnisotropicFilter != statesCache.AnisotropicFilter))
|
||||
{
|
||||
glTexParameteri(tmpType, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||
material.TextureLayer[i].AnisotropicFilter>1 ? core::min_(MaxAnisotropy, material.TextureLayer[i].AnisotropicFilter) : 1);
|
||||
if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic] &&
|
||||
(!statesCache.IsCached || material.TextureLayer[i].AnisotropicFilter != statesCache.AnisotropicFilter))
|
||||
{
|
||||
glTexParameteri(tmpType, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||
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
|
||||
|
||||
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapU != statesCache.WrapU)
|
||||
{
|
||||
glTexParameteri(tmpType, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayer[i].TextureWrapU));
|
||||
statesCache.WrapU = material.TextureLayer[i].TextureWrapU;
|
||||
}
|
||||
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapU != statesCache.WrapU)
|
||||
{
|
||||
glTexParameteri(tmpType, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayer[i].TextureWrapU));
|
||||
statesCache.WrapU = material.TextureLayer[i].TextureWrapU;
|
||||
}
|
||||
|
||||
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapV != statesCache.WrapV)
|
||||
{
|
||||
glTexParameteri(tmpType, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayer[i].TextureWrapV));
|
||||
statesCache.WrapV = material.TextureLayer[i].TextureWrapV;
|
||||
}
|
||||
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapV != statesCache.WrapV)
|
||||
{
|
||||
glTexParameteri(tmpType, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayer[i].TextureWrapV));
|
||||
statesCache.WrapV = material.TextureLayer[i].TextureWrapV;
|
||||
}
|
||||
|
||||
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapW != statesCache.WrapW)
|
||||
{
|
||||
glTexParameteri(tmpType, GL_TEXTURE_WRAP_R, getTextureWrapMode(material.TextureLayer[i].TextureWrapW));
|
||||
statesCache.WrapW = material.TextureLayer[i].TextureWrapW;
|
||||
}
|
||||
if (!statesCache.IsCached || material.TextureLayer[i].TextureWrapW != statesCache.WrapW)
|
||||
{
|
||||
glTexParameteri(tmpType, GL_TEXTURE_WRAP_R, getTextureWrapMode(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
|
||||
FixedPipelineState = COpenGLDriver::EOFPS_ENABLE;
|
||||
|
||||
bool resetAllRenderStates = false;
|
||||
|
||||
if (CurrentRenderMode != ERM_2D || Transformation3DChanged)
|
||||
{
|
||||
// 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())
|
||||
MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial();
|
||||
}
|
||||
|
||||
if (Transformation3DChanged)
|
||||
{
|
||||
CacheHandler->setMatrixMode(GL_PROJECTION);
|
||||
|
@ -2940,32 +2945,40 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
|
|||
|
||||
CacheHandler->setMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glTranslatef(0.375f, 0.375f, 0.0f);
|
||||
|
||||
// Make sure we set first texture matrix
|
||||
CacheHandler->setActiveTexture(GL_TEXTURE0);
|
||||
|
||||
Transformation3DChanged = false;
|
||||
}
|
||||
if (!OverrideMaterial2DEnabled)
|
||||
{
|
||||
setBasicRenderStates(InitMaterial2D, LastMaterial, true);
|
||||
LastMaterial = InitMaterial2D;
|
||||
}
|
||||
|
||||
CacheHandler->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
#ifdef GL_EXT_clip_volume_hint
|
||||
if (FeatureAvailable[IRR_EXT_clip_volume_hint])
|
||||
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST);
|
||||
#endif
|
||||
|
||||
resetAllRenderStates = true;
|
||||
}
|
||||
if (OverrideMaterial2DEnabled)
|
||||
|
||||
SMaterial currentMaterial = (!OverrideMaterial2DEnabled) ? InitMaterial2D : OverrideMaterial2D;
|
||||
currentMaterial.Lighting = false;
|
||||
|
||||
if (texture)
|
||||
{
|
||||
OverrideMaterial2D.Lighting=false;
|
||||
setBasicRenderStates(OverrideMaterial2D, LastMaterial, false);
|
||||
LastMaterial = OverrideMaterial2D;
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
CacheHandler->getTextureCache().set(0, 0);
|
||||
}
|
||||
|
||||
setBasicRenderStates(currentMaterial, LastMaterial, resetAllRenderStates);
|
||||
|
||||
LastMaterial = currentMaterial;
|
||||
|
||||
// no alphaChannel without texture
|
||||
alphaChannel &= texture;
|
||||
|
@ -2984,23 +2997,14 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
|
|||
|
||||
if (texture)
|
||||
{
|
||||
if (OverrideMaterial2DEnabled)
|
||||
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;
|
||||
CacheHandler->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
|
||||
if (alphaChannel)
|
||||
{
|
||||
// if alpha and alpha texture just modulate, otherwise use only the alpha channel
|
||||
if (alpha)
|
||||
{
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
}
|
||||
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])
|
||||
{
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
// rgb always modulates
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvf(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_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB);
|
||||
#else
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
||||
// rgb always modulates
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
||||
glTexEnvf(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_COMBINE_RGB_EXT, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
}
|
||||
}
|
||||
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])
|
||||
{
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
glTexEnvf(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_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
||||
// rgb always modulates
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvf(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_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB);
|
||||
#else
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||
glTexEnvf(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_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
|
||||
// rgb always modulates
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
||||
glTexEnvf(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_COMBINE_RGB_EXT, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
@ -3532,6 +3536,67 @@ void COpenGLDriver::setFog(SColor c, E_FOG_TYPE fogType, f32 start,
|
|||
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.
|
||||
void COpenGLDriver::draw3DLine(const core::vector3df& start,
|
||||
|
@ -4287,7 +4352,7 @@ void COpenGLDriver::getColorFormatParameters(ECOLOR_FORMAT format, GLint& intern
|
|||
case ECF_G32R32F:
|
||||
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
|
||||
{
|
||||
internalFormat = GL_RG32F;
|
||||
internalFormat = GL_RG32F;
|
||||
pixelFormat = GL_RG;
|
||||
pixelType = GL_FLOAT;
|
||||
}
|
||||
|
@ -4297,7 +4362,7 @@ void COpenGLDriver::getColorFormatParameters(ECOLOR_FORMAT format, GLint& intern
|
|||
case ECF_A32B32G32R32F:
|
||||
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_float))
|
||||
{
|
||||
internalFormat = GL_RGBA32F_ARB;
|
||||
internalFormat = GL_RGBA32F_ARB;
|
||||
pixelFormat = GL_RGBA;
|
||||
pixelType = GL_FLOAT;
|
||||
}
|
||||
|
|
|
@ -198,6 +198,9 @@ namespace video
|
|||
//! Draws a single pixel
|
||||
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.
|
||||
virtual void draw3DLine(const core::vector3df& start,
|
||||
const core::vector3df& end,
|
||||
|
|
|
@ -35,13 +35,6 @@ public:
|
|||
|
||||
Driver->disableTextures(1);
|
||||
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:
|
||||
|
@ -89,17 +82,19 @@ public:
|
|||
Driver->getCacheHandler()->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));
|
||||
}
|
||||
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvf(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_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
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_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (f32) modulate );
|
||||
#else
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
||||
glTexEnvf(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_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||
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_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate );
|
||||
#endif
|
||||
|
||||
|
@ -109,33 +104,33 @@ public:
|
|||
if (alphaSource==EAS_VERTEX_COLOR)
|
||||
{
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
glTexEnvf(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_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
||||
#else
|
||||
glTexEnvf(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_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
|
||||
#endif
|
||||
}
|
||||
else if (alphaSource==EAS_TEXTURE)
|
||||
{
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
#else
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
|
||||
glTexEnvf(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_COMBINE_ALPHA_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
|
||||
#else
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
|
||||
glTexEnvf(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_COMBINE_ALPHA_EXT, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_TEXTURE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -144,15 +139,18 @@ public:
|
|||
|
||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
#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_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||
#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_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||
#endif
|
||||
|
||||
Driver->getCacheHandler()->setBlend(false);
|
||||
|
@ -195,23 +193,23 @@ public:
|
|||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||
glTexEnvf(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_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE);
|
||||
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_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
|
||||
#else
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||
glTexEnvf(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_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE);
|
||||
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_SOURCE2_RGB_EXT, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -222,13 +220,14 @@ public:
|
|||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
#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
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
|
||||
#endif
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,9 +257,6 @@ public:
|
|||
|
||||
Driver->getCacheHandler()->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
|
||||
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_
|
||||
|
@ -303,35 +299,39 @@ public:
|
|||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvf(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_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
||||
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_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||
#else
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT );
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
||||
glTexEnvf(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_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT );
|
||||
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_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||
{
|
||||
// default values
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE );
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE );
|
||||
#else
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
|
||||
#endif
|
||||
|
||||
Driver->getCacheHandler()->setBlend(false);
|
||||
}
|
||||
|
||||
|
@ -370,34 +370,37 @@ public:
|
|||
Driver->getCacheHandler()->setAlphaTest(true);
|
||||
Driver->getCacheHandler()->setAlphaFunc(GL_GREATER, material.MaterialTypeParam);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates
|
||||
|| material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates || material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
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_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
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_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
#else
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
||||
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_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||
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_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
#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
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
|
||||
#endif
|
||||
Driver->getCacheHandler()->setAlphaTest(false);
|
||||
Driver->getCacheHandler()->setBlend(false);
|
||||
|
@ -437,7 +440,6 @@ public:
|
|||
{
|
||||
Driver->getCacheHandler()->setAlphaTest(true);
|
||||
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)
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
|
||||
// diffuse map
|
||||
|
||||
switch (material.MaterialType)
|
||||
|
@ -511,7 +515,7 @@ public:
|
|||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
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_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB);
|
||||
#else
|
||||
|
@ -524,7 +528,7 @@ public:
|
|||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||
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_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT);
|
||||
#endif
|
||||
|
@ -554,7 +558,6 @@ public:
|
|||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f);
|
||||
#endif
|
||||
}
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -564,15 +567,17 @@ public:
|
|||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.f );
|
||||
#else
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
|
||||
#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:
|
||||
|
@ -602,12 +607,11 @@ public:
|
|||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
// diffuse map is default modulated
|
||||
|
||||
// detail map on second layer
|
||||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB);
|
||||
|
@ -628,8 +632,8 @@ public:
|
|||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||
|
||||
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)
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
|
||||
glTexGeni(GL_S, 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_
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
|
||||
glDisable(GL_TEXTURE_GEN_S);
|
||||
glDisable(GL_TEXTURE_GEN_T);
|
||||
}
|
||||
|
@ -706,6 +714,7 @@ public:
|
|||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
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_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
|
||||
#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))
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
}
|
||||
glDisable(GL_TEXTURE_GEN_S);
|
||||
glDisable(GL_TEXTURE_GEN_T);
|
||||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
glDisable(GL_TEXTURE_GEN_S);
|
||||
glDisable(GL_TEXTURE_GEN_T);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -769,20 +776,22 @@ public:
|
|||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
|
||||
#ifdef GL_ARB_texture_env_combine
|
||||
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_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
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_SOURCE0_ALPHA_ARB, GL_PREVIOUS_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_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
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_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
|
||||
#else
|
||||
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_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||
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_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB);
|
||||
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_SOURCE0_RGB_EXT, GL_TEXTURE);
|
||||
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_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB);
|
||||
#endif
|
||||
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_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB);
|
||||
#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))
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
|
||||
|
||||
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);
|
||||
if (Driver->queryFeature(EVDF_MULTITEXTURE))
|
||||
{
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
}
|
||||
|
||||
Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
Driver->getCacheHandler()->setBlend(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -469,7 +469,7 @@ void CPLYMeshFileLoader::fillBuffer()
|
|||
if (EndOfFile)
|
||||
return;
|
||||
|
||||
u32 length = (u32)(EndPointer - StartPointer);
|
||||
size_t length = (size_t)(EndPointer - StartPointer);
|
||||
if (length && StartPointer != Buffer)
|
||||
{
|
||||
// copy the remaining data to the start of the buffer
|
||||
|
@ -486,7 +486,7 @@ void CPLYMeshFileLoader::fillBuffer()
|
|||
else
|
||||
{
|
||||
// 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
|
||||
EndPointer = EndPointer + count;
|
||||
|
|
|
@ -225,16 +225,12 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root,
|
|||
|
||||
|
||||
ISceneNode* CSceneCollisionManager::getSceneNodeAndCollisionPointFromRay(
|
||||
SCollisionHit& hitResult,
|
||||
const core::line3df& ray,
|
||||
core::vector3df & outCollisionPoint,
|
||||
core::triangle3df & outTriangle,
|
||||
s32 idBitMask,
|
||||
ISceneNode * collisionRootNode,
|
||||
bool noDebugObjects)
|
||||
{
|
||||
ISceneNode* bestNode = 0;
|
||||
f32 bestDistanceSquared = FLT_MAX;
|
||||
|
||||
if(0 == collisionRootNode)
|
||||
collisionRootNode = SceneManager->getRootSceneNode();
|
||||
|
||||
|
@ -261,23 +257,21 @@ ISceneNode* CSceneCollisionManager::getSceneNodeAndCollisionPointFromRay(
|
|||
// node in order to find the nearest collision point, so sorting them by
|
||||
// bounding box would be pointless.
|
||||
|
||||
f32 bestDistanceSquared = FLT_MAX;
|
||||
core::line3df rayRest(ray);
|
||||
getPickedNodeFromBBAndSelector(collisionRootNode, rayRest, idBitMask,
|
||||
noDebugObjects, bestDistanceSquared, bestNode,
|
||||
outCollisionPoint, outTriangle);
|
||||
return bestNode;
|
||||
getPickedNodeFromBBAndSelector(hitResult, collisionRootNode, rayRest, idBitMask,
|
||||
noDebugObjects, bestDistanceSquared);
|
||||
return hitResult.Node;
|
||||
}
|
||||
|
||||
|
||||
void CSceneCollisionManager::getPickedNodeFromBBAndSelector(
|
||||
SCollisionHit& hitResult,
|
||||
ISceneNode * root,
|
||||
core::line3df & ray,
|
||||
s32 bits,
|
||||
bool noDebugObjects,
|
||||
f32 & outBestDistanceSquared,
|
||||
ISceneNode * & outBestNode,
|
||||
core::vector3df & outBestCollisionPoint,
|
||||
core::triangle3df & outBestTriangle)
|
||||
f32 & outBestDistanceSquared)
|
||||
{
|
||||
const ISceneNodeList& children = root->getChildren();
|
||||
|
||||
|
@ -303,31 +297,26 @@ void CSceneCollisionManager::getPickedNodeFromBBAndSelector(
|
|||
|
||||
const core::aabbox3df& box = current->getBoundingBox();
|
||||
|
||||
core::vector3df candidateCollisionPoint;
|
||||
core::triangle3df candidateTriangle;
|
||||
SCollisionHit candidateHitResult;
|
||||
|
||||
// do intersection test in object space
|
||||
ISceneNode * hitNode = 0;
|
||||
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)
|
||||
{
|
||||
outBestDistanceSquared = distanceSquared;
|
||||
outBestNode = current;
|
||||
outBestCollisionPoint = candidateCollisionPoint;
|
||||
outBestTriangle = candidateTriangle;
|
||||
hitResult = candidateHitResult;
|
||||
const core::vector3df rayVector = ray.getVector().normalize();
|
||||
ray.end = ray.start + (rayVector * sqrtf(distanceSquared));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getPickedNodeFromBBAndSelector(current, ray, bits, noDebugObjects,
|
||||
outBestDistanceSquared, outBestNode,
|
||||
outBestCollisionPoint, outBestTriangle);
|
||||
getPickedNodeFromBBAndSelector(hitResult, current, ray, bits, noDebugObjects,
|
||||
outBestDistanceSquared);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,12 +337,7 @@ ISceneNode* CSceneCollisionManager::getSceneNodeFromCameraBB(
|
|||
return getSceneNodeFromRayBB(core::line3d<f32>(start, end), idBitMask, noDebugObjects);
|
||||
}
|
||||
|
||||
|
||||
//! 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)
|
||||
bool CSceneCollisionManager::getCollisionPoint(SCollisionHit& hitResult, const core::line3d<f32>& ray, ITriangleSelector* selector)
|
||||
{
|
||||
if (!selector)
|
||||
{
|
||||
|
@ -367,12 +351,13 @@ bool CSceneCollisionManager::getCollisionPoint(const core::line3d<f32>& ray,
|
|||
Triangles.set_used(totalcnt);
|
||||
|
||||
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();
|
||||
core::vector3df intersection;
|
||||
f32 nearest = FLT_MAX;
|
||||
bool found = false;
|
||||
irr::s32 foundIndex = -1;
|
||||
const f32 raylength = ray.getLengthSQ();
|
||||
|
||||
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)
|
||||
{
|
||||
nearest = tmp;
|
||||
outTriangle = triangle;
|
||||
outIntersection = intersection;
|
||||
outNode = selector->getSceneNodeForTriangle(i);
|
||||
found = true;
|
||||
|
||||
hitResult.Triangle = triangle;
|
||||
hitResult.Intersection = intersection;
|
||||
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
|
||||
//! the resulting new position of the ellipsoid.
|
||||
|
@ -666,6 +668,8 @@ bool CSceneCollisionManager::testTriangleIntersection(SCollisionData* colData,
|
|||
// set result:
|
||||
if (foundCollision)
|
||||
{
|
||||
++colData->triangleHits;
|
||||
|
||||
// distance to collision is t
|
||||
f32 distToCollision = t*colData->velocity.getLength();
|
||||
|
||||
|
@ -677,7 +681,6 @@ bool CSceneCollisionManager::testTriangleIntersection(SCollisionData* colData,
|
|||
colData->intersectionPoint = collisionPoint;
|
||||
colData->foundCollision = true;
|
||||
colData->intersectionTriangle = triangle;
|
||||
++colData->triangleHits;
|
||||
return true;
|
||||
}
|
||||
}// end found collision
|
||||
|
@ -712,7 +715,7 @@ core::vector3df CSceneCollisionManager::collideEllipsoidWithWorld(
|
|||
colData.selector = selector;
|
||||
colData.slidingSpeed = slidingSpeed;
|
||||
colData.triangleHits = 0;
|
||||
colData.triangleIndex = -1;
|
||||
colData.node = 0;
|
||||
|
||||
core::vector3df eSpacePosition = colData.R3Position / colData.eRadius;
|
||||
core::vector3df eSpaceVelocity = colData.R3Velocity / colData.eRadius;
|
||||
|
@ -746,7 +749,7 @@ core::vector3df CSceneCollisionManager::collideEllipsoidWithWorld(
|
|||
triout.pointA *= colData.eRadius;
|
||||
triout.pointB *= colData.eRadius;
|
||||
triout.pointC *= colData.eRadius;
|
||||
outNode = selector->getSceneNodeForTriangle(colData.triangleIndex);
|
||||
outNode = colData.node;
|
||||
}
|
||||
|
||||
finalPos *= colData.eRadius;
|
||||
|
@ -787,12 +790,30 @@ core::vector3df CSceneCollisionManager::collideWithWorld(s32 recursionDepth,
|
|||
1.0f / colData.eRadius.Y,
|
||||
1.0f / colData.eRadius.Z));
|
||||
|
||||
irr::core::array<SCollisionTriangleRange> outTriangleInfo;
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
||||
|
|
|
@ -41,11 +41,9 @@ namespace scene
|
|||
virtual ISceneNode* getSceneNodeFromCameraBB(const ICameraSceneNode* camera,
|
||||
s32 idBitMask=0, bool bNoDebugObjects = false) _IRR_OVERRIDE_;
|
||||
|
||||
//! Finds the collision point of a line and lots of triangles, if there is one.
|
||||
virtual bool getCollisionPoint(const core::line3d<f32>& ray,
|
||||
ITriangleSelector* selector, core::vector3df& outCollisionPoint,
|
||||
core::triangle3df& outTriangle,
|
||||
ISceneNode* & outNode) _IRR_OVERRIDE_;
|
||||
//! Finds the nearest collision point of a line and lots of triangles, if there is one.
|
||||
virtual bool getCollisionPoint(SCollisionHit& hitResult, const core::line3d<f32>& ray,
|
||||
ITriangleSelector* selector) _IRR_OVERRIDE_;
|
||||
|
||||
//! Collides a moving ellipsoid with a 3d world with gravity and returns
|
||||
//! 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
|
||||
//! the nodes' id bitmasks, bounding boxes and triangle selectors.
|
||||
virtual ISceneNode* getSceneNodeAndCollisionPointFromRay(
|
||||
SCollisionHit& hitResult,
|
||||
const core::line3df& ray,
|
||||
core::vector3df& outCollisionPoint,
|
||||
core::triangle3df& outTriangle,
|
||||
s32 idBitMask = 0,
|
||||
ISceneNode * collisionRootNode = 0,
|
||||
bool noDebugObjects = false) _IRR_OVERRIDE_;
|
||||
|
||||
bool noDebugObjects = false) _IRR_OVERRIDE_;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -88,14 +84,13 @@ namespace scene
|
|||
f32& outbestdistance, ISceneNode*& outbestnode);
|
||||
|
||||
//! recursive method for going through all scene nodes
|
||||
void getPickedNodeFromBBAndSelector(ISceneNode * root,
|
||||
void getPickedNodeFromBBAndSelector(
|
||||
SCollisionHit& hitResult,
|
||||
ISceneNode * root,
|
||||
core::line3df & ray,
|
||||
s32 bits,
|
||||
bool noDebugObjects,
|
||||
f32 & outBestDistanceSquared,
|
||||
ISceneNode * & outBestNode,
|
||||
core::vector3df & outBestCollisionPoint,
|
||||
core::triangle3df & outBestTriangle);
|
||||
f32 & outBestDistanceSquared);
|
||||
|
||||
|
||||
struct SCollisionData
|
||||
|
@ -114,7 +109,7 @@ namespace scene
|
|||
core::vector3df intersectionPoint;
|
||||
|
||||
core::triangle3df intersectionTriangle;
|
||||
s32 triangleIndex;
|
||||
irr::scene::ISceneNode* node;
|
||||
s32 triangleHits;
|
||||
|
||||
f32 slidingSpeed;
|
||||
|
|
|
@ -1847,23 +1847,29 @@ IMeshManipulator* CSceneManager::getMeshManipulator()
|
|||
|
||||
|
||||
//! 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)
|
||||
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
|
||||
//! animated scene node
|
||||
ITriangleSelector* CSceneManager::createTriangleSelector(IAnimatedMeshSceneNode* node)
|
||||
//! Creates a ITriangleSelector, based on a the mesh owned by an animated scene node
|
||||
ITriangleSelector* CSceneManager::createTriangleSelector(IAnimatedMeshSceneNode* node, bool separateMeshbuffers)
|
||||
{
|
||||
if (!node || !node->getMesh())
|
||||
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);
|
||||
}
|
||||
|
||||
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.
|
||||
IMetaTriangleSelector* CSceneManager::createMetaTriangleSelector()
|
||||
|
|
|
@ -343,19 +343,26 @@ namespace scene
|
|||
|
||||
|
||||
//! 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.
|
||||
//! 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: 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.
|
||||
virtual ITriangleSelector* createOctreeTriangleSelector(IMesh* mesh,
|
||||
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.
|
||||
virtual ITriangleSelector* createTriangleSelectorFromBoundingBox(
|
||||
ISceneNode* node) _IRR_OVERRIDE_;
|
||||
|
|
|
@ -202,7 +202,8 @@ void CSceneNodeAnimatorCollisionResponse::animateNode(ISceneNode* node, u32 time
|
|||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,8 @@ void CTerrainTriangleSelector::setTriangleData(ITerrainSceneNode* node, s32 LOD)
|
|||
//! Gets all triangles.
|
||||
void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||
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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -113,7 +123,9 @@ void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
|||
//! Gets all triangles which lie within a specific bounding box.
|
||||
void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||
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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -150,7 +171,8 @@ void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
|||
//! Gets all triangles which have or may have contact with a 3d line.
|
||||
void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||
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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class ITerrainSceneNode;
|
|||
//! Triangle Selector for the TerrainSceneNode
|
||||
/** The code for the TerrainTriangleSelector is based on the GeoMipMapSelector
|
||||
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.
|
||||
*/
|
||||
class CTerrainTriangleSelector : public ITriangleSelector
|
||||
|
@ -40,16 +40,19 @@ public:
|
|||
|
||||
//! Gets all triangles.
|
||||
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.
|
||||
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.
|
||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||
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
|
||||
virtual s32 getTriangleCount() const _IRR_OVERRIDE_;
|
||||
|
|
|
@ -77,6 +77,11 @@ void CTextSceneNode::setText(const wchar_t* text)
|
|||
Text = text;
|
||||
}
|
||||
|
||||
//! get the text string
|
||||
const wchar_t* CTextSceneNode::getText() const
|
||||
{
|
||||
return Text.c_str();
|
||||
}
|
||||
|
||||
//! sets the color of the text
|
||||
void CTextSceneNode::setTextColor(video::SColor color)
|
||||
|
@ -84,6 +89,30 @@ void CTextSceneNode::setTextColor(video::SColor 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 ----------------------------------------------
|
||||
|
||||
|
@ -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
|
||||
void CBillboardTextSceneNode::OnAnimate(u32 timeMs)
|
||||
|
@ -408,11 +442,10 @@ const core::dimension2d<f32>& CBillboardTextSceneNode::getSize() const
|
|||
return Size;
|
||||
}
|
||||
|
||||
|
||||
//! sets the color of the text
|
||||
void CBillboardTextSceneNode::setTextColor(video::SColor color)
|
||||
//! Get the font used to draw the text
|
||||
gui::IGUIFont* CBillboardTextSceneNode::getFont() const
|
||||
{
|
||||
Color = color;
|
||||
return Font;
|
||||
}
|
||||
|
||||
//! Set the color of all vertices of the billboard
|
||||
|
|
|
@ -41,9 +41,21 @@ namespace scene
|
|||
//! sets the text string
|
||||
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
|
||||
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
|
||||
virtual ESCENE_NODE_TYPE getType() const _IRR_OVERRIDE_ { return ESNT_TEXT; }
|
||||
|
||||
|
@ -83,8 +95,11 @@ namespace scene
|
|||
//! sets the text string
|
||||
virtual void setText(const wchar_t* text) _IRR_OVERRIDE_;
|
||||
|
||||
//! sets the color of the text
|
||||
virtual void setTextColor(video::SColor color) _IRR_OVERRIDE_;
|
||||
//! get the text string
|
||||
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
|
||||
virtual void setSize(const core::dimension2d<f32>& size) _IRR_OVERRIDE_;
|
||||
|
@ -98,7 +113,7 @@ namespace scene
|
|||
virtual u32 getMaterialCount() const _IRR_OVERRIDE_;
|
||||
|
||||
//! 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
|
||||
//! \param overallColor: the color to set
|
||||
|
@ -129,7 +144,6 @@ namespace scene
|
|||
private:
|
||||
|
||||
core::stringw Text;
|
||||
video::SColor Color;
|
||||
gui::IGUIFontBitmap* Font;
|
||||
|
||||
core::dimension2d<f32> Size;
|
||||
|
|
|
@ -21,60 +21,68 @@ CTriangleBBSelector::CTriangleBBSelector(ISceneNode* node)
|
|||
Triangles.set_used(12); // a box has 12 triangles.
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Gets all triangles.
|
||||
void CTriangleBBSelector::getTriangles(core::triangle3df* triangles,
|
||||
s32 arraySize, s32& outTriangleCount,
|
||||
const core::matrix4* transform) const
|
||||
const core::matrix4* transform, bool useNodeTransform,
|
||||
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||
{
|
||||
if (!SceneNode)
|
||||
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]);
|
||||
fillTriangles();
|
||||
|
||||
// call parent
|
||||
CTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, transform);
|
||||
CTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, transform, useNodeTransform, outTriangleInfo);
|
||||
}
|
||||
|
||||
void CTriangleBBSelector::getTriangles(core::triangle3df* triangles,
|
||||
s32 arraySize, s32& outTriangleCount,
|
||||
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,
|
||||
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
|
||||
{
|
||||
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 irr
|
||||
|
||||
|
|
|
@ -22,16 +22,22 @@ public:
|
|||
|
||||
//! Gets all triangles.
|
||||
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.
|
||||
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.
|
||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||
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
|
||||
CTriangleSelector::CTriangleSelector(ISceneNode* node)
|
||||
: SceneNode(node), AnimatedNode(0), LastMeshFrame(0)
|
||||
: SceneNode(node), MeshBuffer(0), MaterialIndex(0), AnimatedNode(0), LastMeshFrame(0)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CTriangleSelector");
|
||||
|
@ -27,7 +27,7 @@ CTriangleSelector::CTriangleSelector(ISceneNode* node)
|
|||
|
||||
//! constructor
|
||||
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
|
||||
setDebugName("CTriangleSelector");
|
||||
|
@ -39,18 +39,27 @@ CTriangleSelector::CTriangleSelector(const core::aabbox3d<f32>& box, ISceneNode*
|
|||
|
||||
|
||||
//! constructor
|
||||
CTriangleSelector::CTriangleSelector(const IMesh* mesh, ISceneNode* node)
|
||||
: SceneNode(node), AnimatedNode(0), LastMeshFrame(0)
|
||||
CTriangleSelector::CTriangleSelector(const IMesh* mesh, ISceneNode* node, bool separateMeshbuffers)
|
||||
: SceneNode(node), MeshBuffer(0), MaterialIndex(0), AnimatedNode(0), LastMeshFrame(0)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CTriangleSelector");
|
||||
#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)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
|
@ -68,22 +77,51 @@ CTriangleSelector::CTriangleSelector(IAnimatedMeshSceneNode* node)
|
|||
IMesh* mesh = animatedMesh->getMesh(LastMeshFrame);
|
||||
|
||||
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();
|
||||
u32 totalFaceCount = 0;
|
||||
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);
|
||||
|
||||
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>
|
||||
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
|
||||
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 );
|
||||
for (u32 i=0; i < triangleCount; ++i)
|
||||
for (u32 i=0; i < Triangles.size(); ++i)
|
||||
{
|
||||
const core::triangle3df& tri = Triangles[i];
|
||||
BoundingBox.addInternalPoint(tri.pointA);
|
||||
|
@ -168,7 +237,6 @@ void CTriangleSelector::updateFromMesh(const IMesh* mesh) const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void CTriangleSelector::update(void) const
|
||||
{
|
||||
if (!AnimatedNode)
|
||||
|
@ -194,7 +262,8 @@ void CTriangleSelector::update(void) const
|
|||
//! Gets all triangles.
|
||||
void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||
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();
|
||||
|
@ -206,7 +275,7 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
|||
core::matrix4 mat;
|
||||
if (transform)
|
||||
mat = *transform;
|
||||
if (SceneNode)
|
||||
if (SceneNode&&useNodeTransform)
|
||||
mat *= SceneNode->getAbsoluteTransformation();
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -224,7 +330,8 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
|||
void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||
s32 arraySize, s32& outTriangleCount,
|
||||
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();
|
||||
|
@ -232,16 +339,23 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
|||
core::matrix4 mat(core::matrix4::EM4CONST_NOTHING);
|
||||
core::aabbox3df tBox(box);
|
||||
|
||||
if (SceneNode)
|
||||
if (SceneNode && useNodeTransform)
|
||||
{
|
||||
SceneNode->getAbsoluteTransformation().getInverse(mat);
|
||||
mat.transformBoxEx(tBox);
|
||||
if ( SceneNode->getAbsoluteTransformation().getInverse(mat) )
|
||||
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)
|
||||
mat = *transform;
|
||||
else
|
||||
mat.makeIdentity();
|
||||
if (SceneNode)
|
||||
if (SceneNode && useNodeTransform)
|
||||
mat *= SceneNode->getAbsoluteTransformation();
|
||||
|
||||
outTriangleCount = 0;
|
||||
|
@ -251,22 +365,80 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
|||
|
||||
s32 triangleCount = 0;
|
||||
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
|
||||
// API contract doesn't guarantee complete accuracy.
|
||||
if (Triangles[i].isTotalOutsideBox(tBox))
|
||||
continue;
|
||||
irr::u32 activeRange = 0;
|
||||
SCollisionTriangleRange triRange;
|
||||
triRange.Selector = const_cast<CTriangleSelector*>(this);
|
||||
triRange.SceneNode = SceneNode;
|
||||
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);
|
||||
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;
|
||||
|
||||
++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)
|
||||
break;
|
||||
++activeRange;
|
||||
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;
|
||||
|
@ -277,7 +449,8 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
|||
void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
||||
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
|
||||
{
|
||||
// Update my triangles if necessary
|
||||
update();
|
||||
|
@ -287,7 +460,7 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
|
|||
|
||||
// TODO: Could be optimized for line a little bit more.
|
||||
getTriangles(triangles, arraySize, outTriangleCount,
|
||||
box, transform);
|
||||
box, transform, useNodeTransform, outTriangleInfo);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -27,27 +27,33 @@ public:
|
|||
CTriangleSelector(ISceneNode* node);
|
||||
|
||||
//! 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
|
||||
//!\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
|
||||
CTriangleSelector(const core::aabbox3d<f32>& box, ISceneNode* node);
|
||||
|
||||
//! Gets all triangles.
|
||||
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.
|
||||
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.
|
||||
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
|
||||
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
|
||||
virtual s32 getTriangleCount() const _IRR_OVERRIDE_;
|
||||
|
@ -66,20 +72,33 @@ public:
|
|||
|
||||
protected:
|
||||
//! 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
|
||||
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
|
||||
//! was built from an animated mesh and that mesh's frame has changed
|
||||
//! since the last time it was updated.
|
||||
virtual void update(void) const;
|
||||
|
||||
irr::core::array<SCollisionTriangleRange> BufferRanges;
|
||||
|
||||
ISceneNode* SceneNode;
|
||||
mutable core::array<core::triangle3df> Triangles; // (mutable for CTriangleBBSelector)
|
||||
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;
|
||||
mutable u32 LastMeshFrame;
|
||||
};
|
||||
|
@ -87,6 +106,4 @@ protected:
|
|||
} // end namespace scene
|
||||
} // end namespace irr
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ bool CWriteFile::flush()
|
|||
if (!isOpen())
|
||||
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)
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace io
|
|||
//! Reads an amount of bytes from the file.
|
||||
virtual int read(void* buffer, int sizeToRead)
|
||||
{
|
||||
return ReadFile->read(buffer, sizeToRead);
|
||||
return (int)ReadFile->read(buffer, sizeToRead);
|
||||
}
|
||||
|
||||
//! Returns size of file in bytes
|
||||
|
|
|
@ -136,11 +136,11 @@ public:
|
|||
|
||||
|
||||
//! 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);
|
||||
if (!attr)
|
||||
return 0;
|
||||
return defaultNotFound;
|
||||
|
||||
core::stringc c(attr->Value.c_str());
|
||||
return core::strtol10(c.c_str());
|
||||
|
@ -148,11 +148,11 @@ public:
|
|||
|
||||
|
||||
//! 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);
|
||||
if (!attrvalue)
|
||||
return 0;
|
||||
return defaultNotFound;
|
||||
|
||||
core::stringc c(attrvalue);
|
||||
return core::strtol10(c.c_str());
|
||||
|
@ -160,11 +160,11 @@ public:
|
|||
|
||||
|
||||
//! 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);
|
||||
if (!attr)
|
||||
return 0;
|
||||
return defaultNotFound;
|
||||
|
||||
core::stringc c = attr->Value.c_str();
|
||||
return core::fast_atof(c.c_str());
|
||||
|
@ -172,11 +172,11 @@ public:
|
|||
|
||||
|
||||
//! 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);
|
||||
if (!attrvalue)
|
||||
return 0;
|
||||
return defaultNotFound;
|
||||
|
||||
core::stringc c = attrvalue;
|
||||
return core::fast_atof(c.c_str());
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
<ProjectName>Irrlicht</ProjectName>
|
||||
<ProjectGuid>{E08E042A-6C45-411B-92BE-3CC31331019F}</ProjectGuid>
|
||||
<RootNamespace>Irrlicht</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<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])
|
||||
{
|
||||
unsigned int res = cx->mode;
|
||||
|
||||
hmac_sha_end(mac, MAC_LENGTH(cx->mode), cx->auth_ctx);
|
||||
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)
|
||||
|
||||
CPPFLAGS = -I../include -I/usr/X11R6/include -pipe
|
||||
# CXXFLAGS += -O3
|
||||
CXXFLAGS += -Wall -ansi -pedantic -O0 -g -D_DEBUG -fno-exceptions
|
||||
CXXFLAGS += -Wall -ansi -pedantic -fno-exceptions
|
||||
ifndef NDEBUG
|
||||
CXXFLAGS += -O0 -g -D_DEBUG
|
||||
else
|
||||
CXXFLAGS += -fexpensive-optimizations -O3
|
||||
endif
|
||||
|
||||
ifeq ($(HOSTTYPE), x86_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("-0.0690462109446526");
|
||||
accurate &= testCalculation_atof("0.11999999731779099"); // more numbers past dot than in lookup table
|
||||
accurate &= testCalculation_atof("0.119999997317790999");
|
||||
|
||||
if (!accurate)
|
||||
{
|
||||
|
|
|
@ -113,6 +113,56 @@ static bool testSwap()
|
|||
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
|
||||
bool testIrrArray(void)
|
||||
{
|
||||
|
@ -123,6 +173,7 @@ bool testIrrArray(void)
|
|||
allExpected &= testSelfAssignment();
|
||||
allExpected &= testSwap();
|
||||
allExpected &= testErase();
|
||||
allExpected &= testSort();
|
||||
|
||||
if(allExpected)
|
||||
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(lightMaps);
|
||||
TEST(triangleSelector);
|
||||
TEST(line2DTest);
|
||||
|
||||
unsigned int numberOfTests = tests.size();
|
||||
unsigned int testToRun = 0;
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
// Copyright (C) 2008-2012 Colin MacDonald
|
||||
// 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 <memory.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.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()
|
||||
#endif // #if defined(TESTING_ON_WINDOWS)
|
||||
#endif // _MSC_VER || _IRR_WINDOWS_API_
|
||||
|
||||
using namespace irr;
|
||||
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
<Unit filename="irrString.cpp" />
|
||||
<Unit filename="lightMaps.cpp" />
|
||||
<Unit filename="lights.cpp" />
|
||||
<Unit filename="line2d.cpp" />
|
||||
<Unit filename="loadTextures.cpp" />
|
||||
<Unit filename="main.cpp" />
|
||||
<Unit filename="makeColorKeyTexture.cpp" />
|
||||
|
|
|
@ -179,6 +179,7 @@
|
|||
<ClCompile Include="irrString.cpp" />
|
||||
<ClCompile Include="lightMaps.cpp" />
|
||||
<ClCompile Include="lights.cpp" />
|
||||
<ClCompile Include="line2d.cpp" />
|
||||
<ClCompile Include="loadTextures.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="makeColorKeyTexture.cpp" />
|
||||
|
|
|
@ -179,6 +179,7 @@
|
|||
<ClCompile Include="irrString.cpp" />
|
||||
<ClCompile Include="lightMaps.cpp" />
|
||||
<ClCompile Include="lights.cpp" />
|
||||
<ClCompile Include="line2d.cpp" />
|
||||
<ClCompile Include="loadTextures.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="makeColorKeyTexture.cpp" />
|
||||
|
|
|
@ -179,6 +179,7 @@
|
|||
<ClCompile Include="irrString.cpp" />
|
||||
<ClCompile Include="lightMaps.cpp" />
|
||||
<ClCompile Include="lights.cpp" />
|
||||
<ClCompile Include="line2d.cpp" />
|
||||
<ClCompile Include="loadTextures.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="makeColorKeyTexture.cpp" />
|
||||
|
|
|
@ -179,6 +179,7 @@
|
|||
<ClCompile Include="irrString.cpp" />
|
||||
<ClCompile Include="lightMaps.cpp" />
|
||||
<ClCompile Include="lights.cpp" />
|
||||
<ClCompile Include="line2d.cpp" />
|
||||
<ClCompile Include="loadTextures.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="makeColorKeyTexture.cpp" />
|
||||
|
|
|
@ -132,7 +132,7 @@ inline u32 getTextureSizeFromSurfaceSize(u32 size)
|
|||
wchar_t currentchar = ch;
|
||||
|
||||
if ( IsDBCSLeadByte((BYTE) ch))
|
||||
continue; // surragate pairs unsupported
|
||||
continue; // surrogate pairs unsupported
|
||||
|
||||
// get the dimensions
|
||||
SIZE size;
|
||||
|
@ -144,9 +144,9 @@ inline u32 getTextureSizeFromSurfaceSize(u32 size)
|
|||
|
||||
if (GetCharABCWidthsW(dc, currentchar, currentchar, &abc)) // for unicode fonts, get overhang, underhang, width
|
||||
{
|
||||
size.cx = abc.abcB;
|
||||
fa.underhang = abc.abcA;
|
||||
fa.overhang = abc.abcC;
|
||||
size.cx = abc.abcB; // full font width (ignoring padding/underhang )
|
||||
fa.underhang = abc.abcA; // underhang/padding left - can also be negative (in which case it's overhang left)
|
||||
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)
|
||||
continue; // nothing of width 0
|
||||
|
@ -236,7 +236,7 @@ inline u32 getTextureSizeFromSurfaceSize(u32 size)
|
|||
{
|
||||
s32 currentArea = (*it).getValue();
|
||||
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)
|
||||
{
|
||||
// draw letter
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Tool for creating Irrlicht bitmap+vector fonts,
|
||||
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!
|
||||
|
||||
Linux bitmap font support added by Neil Burlock Oct 2008
|
||||
|
|
Loading…
Reference in New Issue