Merging r5686 through r5778 from trunk to ogl-es branch.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@5779 dfc29bdd-3216-0410-991c-e03cc46cb475
master
cutealien 2019-02-27 20:20:38 +00:00
parent 0f217d3c5a
commit d236d99c6c
17 changed files with 1073 additions and 811 deletions

View File

@ -19,7 +19,8 @@ CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 i
: ICameraSceneNode(parent, mgr, id, position),
BoundingBox(core::vector3df(0, 0, 0)), // Camera has no size. Still not sure if FLT_MAX might be the better variant
Target(lookat), UpVector(0.0f, 1.0f, 0.0f), ZNear(1.0f), ZFar(3000.0f),
InputReceiverEnabled(true), TargetAndRotationAreBound(false)
InputReceiverEnabled(true), TargetAndRotationAreBound(false),
HasD3DStyleProjectionMatrix(true)
{
#ifdef _DEBUG
setDebugName("CCameraSceneNode");
@ -30,8 +31,11 @@ CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 i
const video::IVideoDriver* const d = mgr?mgr->getVideoDriver():0;
if (d)
{
Aspect = (f32)d->getCurrentRenderTargetSize().Width /
(f32)d->getCurrentRenderTargetSize().Height;
HasD3DStyleProjectionMatrix = d->getDriverType() != video::EDT_OPENGL;
}
else
Aspect = 4.0f / 3.0f; // Aspect ratio.
@ -230,7 +234,9 @@ void CCameraSceneNode::setFOV(f32 f)
void CCameraSceneNode::recalculateProjectionMatrix()
{
ViewArea.getTransform ( video::ETS_PROJECTION ).buildProjectionMatrixPerspectiveFovLH(Fovy, Aspect, ZNear, ZFar);
video::E_DRIVER_TYPE driverType = SceneManager->getVideoDriver()->getDriverType();
ViewArea.getTransform ( video::ETS_PROJECTION ).buildProjectionMatrixPerspectiveFovLH(Fovy, Aspect, ZNear, ZFar, HasD3DStyleProjectionMatrix);
IsOrthogonal = false;
}
@ -305,7 +311,7 @@ void CCameraSceneNode::recalculateViewArea()
core::matrix4 m(core::matrix4::EM4CONST_NOTHING);
m.setbyproduct_nocheck(ViewArea.getTransform(video::ETS_PROJECTION),
ViewArea.getTransform(video::ETS_VIEW));
ViewArea.setFrom(m);
ViewArea.setFrom(m, HasD3DStyleProjectionMatrix);
}

View File

@ -168,6 +168,8 @@ namespace scene
bool InputReceiverEnabled;
bool TargetAndRotationAreBound;
bool HasD3DStyleProjectionMatrix; // true: projection from 0 to w; false: -w to w
};
} // end namespace

View File

@ -83,7 +83,6 @@ namespace
const core::stringc scaleNodeName = "scale";
const core::stringc translateNodeName = "translate";
const core::stringc skewNodeName = "skew";
const core::stringc bboxNodeName = "boundingbox";
const core::stringc minNodeName = "min";
const core::stringc maxNodeName = "max";
const core::stringc instanceName = "instance";
@ -645,7 +644,6 @@ void CColladaFileLoader::readSceneSection(io::IXMLReaderUTF8* reader)
// read the scene
core::matrix4 transform; // transformation of this node
core::aabbox3df bbox;
scene::IDummyTransformationSceneNode* node = 0;
while(reader->read())
@ -673,9 +671,6 @@ void CColladaFileLoader::readSceneSection(io::IXMLReaderUTF8* reader)
if (translateNodeName == reader->getNodeName())
transform *= readTranslateNode(reader);
else
if (bboxNodeName == reader->getNodeName())
readBboxNode(reader, bbox);
else
if (nodeSectionName == reader->getNodeName())
{
// create dummy node if there is none yet.
@ -751,7 +746,6 @@ void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISce
#endif
core::matrix4 transform; // transformation of this node
core::aabbox3df bbox;
scene::ISceneNode* node = 0; // instance
CScenePrefab* nodeprefab = 0; // prefab for library_nodes usage
@ -792,9 +786,6 @@ void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISce
if (translateNodeName == reader->getNodeName())
transform *= readTranslateNode(reader);
else
if (bboxNodeName == reader->getNodeName())
readBboxNode(reader, bbox);
else
if ((instanceName == reader->getNodeName()) ||
(instanceNodeName == reader->getNodeName()) ||
(instanceGeometryName == reader->getNodeName()) ||
@ -879,10 +870,20 @@ core::matrix4 CColladaFileLoader::readLookAtNode(io::IXMLReaderUTF8* reader)
f32 floats[9];
readFloatsInsideElement(reader, floats, 9);
mat.buildCameraLookAtMatrixLH(
core::vector3df(floats[0], floats[1], floats[2]),
core::vector3df(floats[3], floats[4], floats[5]),
core::vector3df(floats[6], floats[7], floats[8]));
if (FlipAxis)
{
mat.buildCameraLookAtMatrixLH(
core::vector3df(floats[0], floats[2], floats[1]),
core::vector3df(floats[3], floats[5], floats[4]),
core::vector3df(floats[6], floats[8], floats[7]));
}
else
{
mat.buildCameraLookAtMatrixLH(
core::vector3df(floats[0], floats[1], floats[2]*-1.f),
core::vector3df(floats[3], floats[4], floats[5]*-1.f),
core::vector3df(floats[6], floats[7], floats[8]*-1.f));
}
return mat;
}
@ -903,6 +904,8 @@ core::matrix4 CColladaFileLoader::readSkewNode(io::IXMLReaderUTF8* reader)
readFloatsInsideElement(reader, floats, 7);
// build skew matrix from these 7 floats
// TODO: missing example, not sure if rotation is in correct direction.
// TODO: shouldn't FlipAxis also be regarded here?
core::quaternion q;
q.fromAngleAxis(floats[0]*core::DEGTORAD, core::vector3df(floats[1], floats[2], floats[3]));
mat = q.getMatrix();
@ -931,53 +934,12 @@ core::matrix4 CColladaFileLoader::readSkewNode(io::IXMLReaderUTF8* reader)
mat[6]=0.f;
}
return mat;
if ( FlipAxis )
return mat;
else
return flipZAxis(mat);
}
//! reads a <boundingbox> element and its content and stores it in bbox
void CColladaFileLoader::readBboxNode(io::IXMLReaderUTF8* reader,
core::aabbox3df& bbox)
{
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading boundingbox node", ELL_DEBUG);
#endif
bbox.reset(core::aabbox3df());
if (reader->isEmptyElement())
return;
f32 floats[3];
while(reader->read())
{
if (reader->getNodeType() == io::EXN_ELEMENT)
{
if (minNodeName == reader->getNodeName())
{
readFloatsInsideElement(reader, floats, 3);
bbox.MinEdge.set(floats[0], floats[1], floats[2]);
}
else
if (maxNodeName == reader->getNodeName())
{
readFloatsInsideElement(reader, floats, 3);
bbox.MaxEdge.set(floats[0], floats[1], floats[2]);
}
else
skipSection(reader, true); // ignore all other sections
}
else
if (reader->getNodeType() == io::EXN_ELEMENT_END)
{
if (bboxNodeName == reader->getNodeName())
break;
}
}
}
//! reads a <matrix> element and its content and creates a matrix from it
core::matrix4 CColladaFileLoader::readMatrixNode(io::IXMLReaderUTF8* reader)
{
@ -990,6 +952,7 @@ core::matrix4 CColladaFileLoader::readMatrixNode(io::IXMLReaderUTF8* reader)
return mat;
readFloatsInsideElement(reader, mat.pointer(), 16);
// put translation into the correct place
if (FlipAxis)
{
@ -1008,7 +971,7 @@ core::matrix4 CColladaFileLoader::readMatrixNode(io::IXMLReaderUTF8* reader)
return mat2;
}
else
return core::matrix4(mat, core::matrix4::EM4CONST_TRANSPOSED);
return flipZAxis(core::matrix4(mat, core::matrix4::EM4CONST_TRANSPOSED));
}
@ -1026,7 +989,7 @@ core::matrix4 CColladaFileLoader::readPerspectiveNode(io::IXMLReaderUTF8* reader
f32 floats[1];
readFloatsInsideElement(reader, floats, 1);
// TODO: build perspecitve matrix from this float
// TODO: build perspective matrix from this float
os::Printer::log("COLLADA loader warning: <perspective> not implemented yet.", ELL_WARNING);
@ -1047,6 +1010,7 @@ core::matrix4 CColladaFileLoader::readRotateNode(io::IXMLReaderUTF8* reader)
f32 floats[4];
readFloatsInsideElement(reader, floats, 4);
floats[3] *= -1.f; // to left handed rotation
if (!core::iszero(floats[3]))
{
@ -1054,7 +1018,7 @@ core::matrix4 CColladaFileLoader::readRotateNode(io::IXMLReaderUTF8* reader)
if (FlipAxis)
q.fromAngleAxis(floats[3]*core::DEGTORAD, core::vector3df(floats[0], floats[2], floats[1]));
else
q.fromAngleAxis(floats[3]*core::DEGTORAD, core::vector3df(floats[0], floats[1], floats[2]));
q.fromAngleAxis(floats[3]*core::DEGTORAD, core::vector3df(floats[0], floats[1], floats[2]*-1.f));
return q.getMatrix();
}
else
@ -1102,7 +1066,7 @@ core::matrix4 CColladaFileLoader::readTranslateNode(io::IXMLReaderUTF8* reader)
if (FlipAxis)
mat.setTranslation(core::vector3df(floats[0], floats[2], floats[1]));
else
mat.setTranslation(core::vector3df(floats[0], floats[1], floats[2]));
mat.setTranslation(core::vector3df(floats[0], floats[1], floats[2]*-1.f));
return mat;
}
@ -2181,7 +2145,7 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
else
{
vtx.Pos.Y = localInputs[k].Data[idx+1];
vtx.Pos.Z = localInputs[k].Data[idx+2];
vtx.Pos.Z = localInputs[k].Data[idx+2] * -1.f;
}
break;
case ECIS_NORMAL:
@ -2194,7 +2158,7 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
else
{
vtx.Normal.Y = localInputs[k].Data[idx+1];
vtx.Normal.Z = localInputs[k].Data[idx+2];
vtx.Normal.Z = localInputs[k].Data[idx+2] * -1.f;
}
break;
case ECIS_TEXCOORD:
@ -2235,26 +2199,14 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
if (polygonsSectionName == polygonType &&
indices.size() > 3)
{
// need to tesselate for polygons of 4 or more vertices
// need to tessellate for polygons of 4 or more vertices
// for now we naively turn interpret it as a triangle fan
// as full tesselation is problematic
if (FlipAxis)
// as full tessellation is problematic
for (u32 ind = 0; ind+2 < indices.size(); ++ind)
{
for (u32 ind = indices.size()-3; ind>0 ; --ind)
{
mbuffer->Indices.push_back(indices[0]);
mbuffer->Indices.push_back(indices[ind+2]);
mbuffer->Indices.push_back(indices[ind+1]);
}
}
else
{
for (u32 ind = 0; ind+2 < indices.size(); ++ind)
{
mbuffer->Indices.push_back(indices[0]);
mbuffer->Indices.push_back(indices[ind+1]);
mbuffer->Indices.push_back(indices[ind+2]);
}
mbuffer->Indices.push_back(indices[0]);
mbuffer->Indices.push_back(indices[ind+2]);
mbuffer->Indices.push_back(indices[ind+1]);
}
}
else
@ -2262,18 +2214,9 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
// it's just triangles
for (u32 ind = 0; ind < indices.size(); ind+=3)
{
if (FlipAxis)
{
mbuffer->Indices.push_back(indices[ind+2]);
mbuffer->Indices.push_back(indices[ind+1]);
mbuffer->Indices.push_back(indices[ind+0]);
}
else
{
mbuffer->Indices.push_back(indices[ind+0]);
mbuffer->Indices.push_back(indices[ind+1]);
mbuffer->Indices.push_back(indices[ind+2]);
}
mbuffer->Indices.push_back(indices[ind+2]);
mbuffer->Indices.push_back(indices[ind+1]);
mbuffer->Indices.push_back(indices[ind+0]);
}
}
@ -2986,6 +2929,19 @@ void CColladaFileLoader::readParameter(io::IXMLReaderUTF8* reader, io::IAttribut
}
}
core::matrix4 CColladaFileLoader::flipZAxis(const core::matrix4& m)
{
core::matrix4 matrix(m);
matrix[2] *= -1.f;
matrix[6] *= -1.f;
matrix[8] *= -1.f;
matrix[9] *= -1.f;
matrix[11] *= -1.f;
matrix[14] *= -1.f;
return matrix;
}
} // end namespace scene
} // end namespace irr

View File

@ -340,6 +340,10 @@ private:
//! read a parameter and value
void readParameter(io::IXMLReaderUTF8* reader, io::IAttributes* parameters);
//! Flip z axis in matrix around to convert between right-handed and left-handed coordinate system.
//! Note that function is symmetric (no difference if called before or after a transpose).
core::matrix4 flipZAxis(const core::matrix4& m);
scene::ISceneManager* SceneManager;
io::IFileSystem* FileSystem;

File diff suppressed because it is too large Load Diff

View File

@ -9,12 +9,12 @@
#include "S3DVertex.h"
#include "irrMap.h"
#include "IVideoDriver.h"
#include "IXMLWriter.h"
namespace irr
{
namespace io
{
class IXMLWriter;
class IFileSystem;
}
@ -63,11 +63,11 @@ namespace scene
{
public:
CColladaMeshWriterNames(IColladaMeshWriter * writer);
virtual irr::core::stringw nameForMesh(const scene::IMesh* mesh, int instance) _IRR_OVERRIDE_;
virtual irr::core::stringw nameForNode(const scene::ISceneNode* node) _IRR_OVERRIDE_;
virtual irr::core::stringw nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node) _IRR_OVERRIDE_;
virtual irr::core::stringc nameForMesh(const scene::IMesh* mesh, int instance) _IRR_OVERRIDE_;
virtual irr::core::stringc nameForNode(const scene::ISceneNode* node) _IRR_OVERRIDE_;
virtual irr::core::stringc nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node) _IRR_OVERRIDE_;
protected:
irr::core::stringw nameForPtr(const void* ptr) const;
irr::core::stringc nameForPtr(const void* ptr) const;
private:
IColladaMeshWriter * ColladaMeshWriter;
};
@ -88,40 +88,39 @@ public:
virtual EMESH_WRITER_TYPE getType() const _IRR_OVERRIDE_;
//! writes a scene starting with the given node
virtual bool writeScene(io::IWriteFile* file, scene::ISceneNode* root) _IRR_OVERRIDE_;
virtual bool writeScene(io::IWriteFile* file, scene::ISceneNode* root, int writeRoot) _IRR_OVERRIDE_;
//! writes a mesh
virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE) _IRR_OVERRIDE_;
// Restrict the characters of oldString a set of allowed characters in xs::NCName and add the prefix.
virtual irr::core::stringw toNCName(const irr::core::stringw& oldString, const irr::core::stringw& prefix=irr::core::stringw(L"_NC_")) const _IRR_OVERRIDE_;
virtual irr::core::stringc toNCName(const irr::core::stringc& oldString, const irr::core::stringc& prefix=irr::core::stringc("_NC_")) const _IRR_OVERRIDE_;
//! After export you can find out which name had been used for writing the geometry for this node.
virtual const irr::core::stringw* findGeometryNameForNode(ISceneNode* node) _IRR_OVERRIDE_;
virtual const irr::core::stringc* findGeometryNameForNode(ISceneNode* node) _IRR_OVERRIDE_;
protected:
void reset();
bool hasSecondTextureCoordinates(video::E_VERTEX_TYPE type) const;
void writeUv(const irr::core::vector2df& vec);
void writeVector(const irr::core::vector2df& vec);
void writeVector(const irr::core::vector3df& vec);
void writeColor(const irr::video::SColorf& colorf, bool writeAlpha=true);
inline irr::core::stringw toString(const irr::video::ECOLOR_FORMAT format) const;
inline irr::core::stringw toString(const irr::video::E_TEXTURE_CLAMP clamp) const;
inline irr::core::stringw toString(const irr::scene::E_COLLADA_TRANSPARENT_FX opaque) const;
inline irr::core::stringw toRef(const irr::core::stringw& source) const;
inline irr::core::stringc toString(const irr::video::ECOLOR_FORMAT format) const;
inline irr::core::stringc toString(const irr::video::E_TEXTURE_CLAMP clamp) const;
inline irr::core::stringc toString(const irr::scene::E_COLLADA_TRANSPARENT_FX opaque) const;
inline irr::core::stringc toRef(const irr::core::stringc& source) const;
bool isCamera(const scene::ISceneNode* node) const;
irr::core::stringw nameForMesh(const scene::IMesh* mesh, int instance) const;
irr::core::stringw nameForNode(const scene::ISceneNode* node) const;
irr::core::stringw nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node);
irr::core::stringw nameForMaterialSymbol(const scene::IMesh* mesh, int materialId) const;
irr::core::stringw findCachedMaterialName(const irr::video::SMaterial& material) const;
irr::core::stringw minTexfilterToString(bool bilinear, bool trilinear) const;
irr::core::stringw magTexfilterToString(bool bilinear, bool trilinear) const;
irr::core::stringw pathToURI(const irr::io::path& path) const;
inline bool isXmlNameStartChar(wchar_t c) const;
inline bool isXmlNameChar(wchar_t c) const;
irr::core::stringc nameForMesh(const scene::IMesh* mesh, int instance) const;
irr::core::stringc nameForNode(const scene::ISceneNode* node) const;
irr::core::stringc nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node);
irr::core::stringc nameForMaterialSymbol(const scene::IMesh* mesh, int materialId) const;
irr::core::stringc findCachedMaterialName(const irr::video::SMaterial& material) const;
irr::core::stringc minTexfilterToString(bool bilinear, bool trilinear) const;
irr::core::stringc magTexfilterToString(bool bilinear, bool trilinear) const;
irr::core::stringc pathToURI(const irr::io::path& path) const;
inline bool isXmlNameStartChar(c8 c) const;
inline bool isXmlNameChar(c8 c) const;
s32 getCheckedTextureIdx(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs);
video::SColor getColorMapping(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs, E_COLLADA_IRR_COLOR colType);
void writeAsset();
@ -132,22 +131,22 @@ protected:
void writeNodeCameras(irr::scene::ISceneNode * node);
void writeAllMeshGeometries();
void writeSceneNode(irr::scene::ISceneNode * node);
void writeMeshMaterials(scene::IMesh* mesh, irr::core::array<irr::core::stringw> * materialNamesOut=0);
void writeMeshMaterials(scene::IMesh* mesh, irr::core::array<irr::core::stringc> * materialNamesOut=0);
void writeMeshEffects(scene::IMesh* mesh);
void writeMaterialEffect(const irr::core::stringw& materialname, const video::SMaterial & material);
void writeMeshGeometry(const irr::core::stringw& meshname, scene::IMesh* mesh);
void writeMeshInstanceGeometry(const irr::core::stringw& meshname, scene::IMesh* mesh, scene::ISceneNode* node=0);
void writeMaterial(const irr::core::stringw& materialname);
void writeLightInstance(const irr::core::stringw& lightName);
void writeCameraInstance(const irr::core::stringw& cameraName);
void writeMaterialEffect(const irr::core::stringc& materialname, const video::SMaterial & material);
void writeMeshGeometry(const irr::core::stringc& meshname, scene::IMesh* mesh);
void writeMeshInstanceGeometry(const irr::core::stringc& meshname, scene::IMesh* mesh, scene::ISceneNode* node=0);
void writeMaterial(const irr::core::stringc& materialname);
void writeLightInstance(const irr::core::stringc& lightName);
void writeCameraInstance(const irr::core::stringc& cameraName);
void writeLibraryImages();
void writeColorFx(const video::SMaterial & material, const wchar_t * colorname, E_COLLADA_COLOR_SAMPLER cs, const wchar_t* attr1Name=0, const wchar_t* attr1Value=0);
void writeColorFx(const video::SMaterial & material, const c8 * colorname, E_COLLADA_COLOR_SAMPLER cs, const c8* attr1Name=0, const c8* attr1Value=0);
void writeAmbientLightElement(const video::SColorf & col);
void writeColorElement(const video::SColor & col, bool writeAlpha=true);
void writeColorElement(const video::SColorf & col, bool writeAlpha=true);
void writeTextureSampler(s32 textureIdx);
void writeFxElement(const video::SMaterial & material, E_COLLADA_TECHNIQUE_FX techFx);
void writeNode(const wchar_t * nodeName, const wchar_t * content);
void writeNode(const c8 * nodeName, const c8 * content);
void writeFloatElement(irr::f32 value);
void writeRotateElement(const irr::core::vector3df& axis, irr::f32 angle);
void writeScaleElement(const irr::core::vector3df& scale);
@ -157,35 +156,28 @@ protected:
struct SComponentGlobalStartPos
{
SComponentGlobalStartPos() : PosStartIndex(-1), PosLastIndex(-1),
NormalStartIndex(-1), NormalLastIndex(-1),
TCoord0StartIndex(-1), TCoord0LastIndex(-1),
TCoord1StartIndex(-1), TCoord1LastIndex(-1)
SComponentGlobalStartPos() : PosStartIndex(0),
NormalStartIndex(0),
TCoord0StartIndex(0),
TCoord1StartIndex(0)
{ }
s32 PosStartIndex;
s32 PosLastIndex;
s32 NormalStartIndex;
s32 NormalLastIndex;
s32 TCoord0StartIndex;
s32 TCoord0LastIndex;
s32 TCoord1StartIndex;
s32 TCoord1LastIndex;
u32 PosStartIndex;
u32 NormalStartIndex;
u32 TCoord0StartIndex;
u32 TCoord1StartIndex;
};
io::IFileSystem* FileSystem;
video::IVideoDriver* VideoDriver;
io::IXMLWriter* Writer;
io::IXMLWriterUTF8* Writer;
core::array<video::ITexture*> LibraryImages;
io::path Directory;
// Helper struct for creating geometry copies for the ECGI_PER_MESH_AND_MATERIAL settings.
struct SGeometryMeshMaterials
{
bool equals(const core::array<irr::core::stringw>& names) const
bool equals(const core::array<irr::core::stringc>& names) const
{
if ( names.size() != MaterialNames.size() )
return false;
@ -195,8 +187,8 @@ protected:
return true;
}
irr::core::stringw GeometryName; // replacing the usual ColladaMesh::Name
core::array<irr::core::stringw> MaterialNames; // Material names exported for this instance
irr::core::stringc GeometryName; // replacing the usual ColladaMesh::Name
core::array<irr::core::stringc> MaterialNames; // Material names exported for this instance
core::array<const ISceneNode*> MaterialOwners; // Nodes using this specific mesh-material combination
};
@ -207,7 +199,7 @@ protected:
{
}
SGeometryMeshMaterials * findGeometryMeshMaterials(const irr::core::array<irr::core::stringw> materialNames)
SGeometryMeshMaterials * findGeometryMeshMaterials(const irr::core::array<irr::core::stringc> materialNames)
{
for ( irr::u32 i=0; i<GeometryMeshMaterials.size(); ++i )
{
@ -217,7 +209,7 @@ protected:
return NULL;
}
const irr::core::stringw& findGeometryNameForNode(const ISceneNode* node) const
const irr::core::stringc& findGeometryNameForNode(const ISceneNode* node) const
{
if ( GeometryMeshMaterials.size() < 2 )
return Name;
@ -229,7 +221,7 @@ protected:
return Name; // (shouldn't get here usually)
}
irr::core::stringw Name;
irr::core::stringc Name;
bool MaterialsWritten; // just an optimization doing that here in addition to the MaterialsWritten map
bool EffectsWritten; // just an optimization doing that here in addition to the EffectsWritten map
@ -242,30 +234,32 @@ protected:
struct SColladaLight
{
SColladaLight() {}
irr::core::stringw Name;
irr::core::stringc Name;
};
typedef core::map<ISceneNode*, SColladaLight>::Node LightNode;
core::map<ISceneNode*, SColladaLight> LightNodes;
// structure for the camera library
typedef core::map<ISceneNode*, irr::core::stringw>::Node CameraNode;
core::map<ISceneNode*, irr::core::stringw> CameraNodes;
typedef core::map<ISceneNode*, irr::core::stringc>::Node CameraNode;
core::map<ISceneNode*, irr::core::stringc> CameraNodes;
// Check per name if stuff has been written already
// TODO: second parameter not needed, we just don't have a core::set class yet in Irrlicht
core::map<irr::core::stringw, bool> MaterialsWritten;
core::map<irr::core::stringw, bool> EffectsWritten;
core::map<irr::core::stringc, bool> MaterialsWritten;
core::map<irr::core::stringc, bool> EffectsWritten;
// Cache material names
struct MaterialName
{
MaterialName(const irr::video::SMaterial & material, const irr::core::stringw& name)
MaterialName(const irr::video::SMaterial & material, const irr::core::stringc& name)
: Material(material), Name(name)
{}
irr::video::SMaterial Material;
irr::core::stringw Name;
irr::core::stringc Name;
};
irr::core::array< MaterialName > MaterialNameCache;
irr::core::stringc WriteBuffer; // use for writing short strings to avoid regular memory allocations
};

View File

@ -1070,7 +1070,37 @@ IXMLWriter* CFileSystem::createXMLWriter(const io::path& filename)
IXMLWriter* CFileSystem::createXMLWriter(IWriteFile* file)
{
#ifdef _IRR_COMPILE_WITH_XML_
return new CXMLWriter(file);
return createIXMLWriter(file);
#else
noXML();
return 0;
#endif
}
//! Creates a XML Writer from a file.
IXMLWriterUTF8* CFileSystem::createXMLWriterUTF8(const io::path& filename)
{
#ifdef _IRR_COMPILE_WITH_XML_
IWriteFile* file = createAndWriteFile(filename);
IXMLWriterUTF8* writer = 0;
if (file)
{
writer = createXMLWriterUTF8(file);
file->drop();
}
return writer;
#else
noXML();
return 0;
#endif
}
//! Creates a XML Writer from a file.
IXMLWriterUTF8* CFileSystem::createXMLWriterUTF8(IWriteFile* file)
{
#ifdef _IRR_COMPILE_WITH_XML_
return createIXMLWriterUTF8(file);
#else
noXML();
return 0;

View File

@ -145,6 +145,12 @@ public:
//! Creates a XML Writer from a file.
virtual IXMLWriter* createXMLWriter(IWriteFile* file) _IRR_OVERRIDE_;
//! Creates a XML Writer from a file which will write ASCII/UTF-8 characters (char*).
virtual IXMLWriterUTF8* createXMLWriterUTF8(const path& filename) _IRR_OVERRIDE_;
//! Creates a XML Writer from a file which will write ASCII/UTF-8 characters (char*).
virtual IXMLWriterUTF8* createXMLWriterUTF8(IWriteFile* file) _IRR_OVERRIDE_;
//! Creates a new empty collection of attributes, usable for serialization and more.
virtual IAttributes* createEmptyAttributes(video::IVideoDriver* driver) _IRR_OVERRIDE_;

View File

@ -16,10 +16,7 @@
namespace irr
{
namespace io
{
class IXMLWriter;
}
namespace gui
{

View File

@ -577,7 +577,7 @@ CIrrDeviceMacOSX::CIrrDeviceMacOSX(const SIrrlichtCreationParameters& param)
if (!CreationParams.WindowId)
{
[[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
[NSApp setDelegate:(id<NSApplicationDelegate>)[[[CIrrDelegateOSX alloc] initWithDevice:this] autorelease]];
// Create menu

View File

@ -9,13 +9,11 @@
#include "S3DVertex.h"
#include "IVideoDriver.h"
#include "IFileSystem.h"
#include "IXMLWriter.h"
namespace irr
{
namespace io
{
class IXMLWriter;
}
namespace scene
{
class IMeshBuffer;

View File

@ -203,8 +203,6 @@ public:
virtual ~COpenGLCoreTexture()
{
Driver->getCacheHandler()->getTextureCache().remove(this);
if (TextureName)
glDeleteTextures(1, &TextureName);

View File

@ -3584,10 +3584,11 @@ void COpenGLDriver::draw3DLine(const core::vector3df& start,
//! Removes a texture from the texture cache and deletes it, freeing lot of memory.
void COpenGLDriver::removeTexture(ITexture* texture)
{
if (!texture)
return;
CNullDriver::removeTexture(texture);
if (texture)
{
CacheHandler->getTextureCache().remove(texture);
CNullDriver::removeTexture(texture);
}
}
//! Check if the driver supports creating textures with the given color format

View File

@ -18,7 +18,6 @@ namespace irr
{
namespace io
{
class IXMLWriter;
class IFileSystem;
}
namespace scene

View File

@ -491,7 +491,7 @@ void CSoftwareDriver::drawClippedIndexedTriangleListT(const VERTEXTYPE* vertices
worldinv.makeInverse();
// calculate view frustum planes
scene::SViewFrustum frustum(TransformationMatrix[ETS_PROJECTION] * TransformationMatrix[ETS_VIEW]);
scene::SViewFrustum frustum(TransformationMatrix[ETS_PROJECTION] * TransformationMatrix[ETS_VIEW], true);
// copy and transform clipping planes ignoring far plane
core::plane3df planes[5]; // ordered by near, left, right, bottom, top

View File

@ -15,30 +15,28 @@ namespace irr
namespace io
{
//! creates an IXMLReader
IXMLWriter* createIXMLWriter(IWriteFile* file)
{
return new CXMLWriter(file);
}
//! creates an IXMLReader
IXMLWriterUTF8* createIXMLWriterUTF8(IWriteFile* file)
{
return new CXMLWriterUTF8(file);
}
//! Constructor
CXMLWriter::CXMLWriter(IWriteFile* file)
: File(file), Tabs(0), TextWrittenLast(false)
: CXMLWriterCommon(file)
{
#ifdef _DEBUG
setDebugName("CXMLWriter");
#endif
if (File)
File->grab();
}
//! Destructor
CXMLWriter::~CXMLWriter()
{
if (File)
File->drop();
}
//! Writes a xml 1.0 header like <?xml version="1.0"?>
void CXMLWriter::writeXMLHeader()
{
@ -189,18 +187,6 @@ void CXMLWriter::writeClosingTag(const wchar_t* name)
TextWrittenLast = false;
}
const CXMLWriter::XMLSpecialCharacters XMLWSChar[] =
{
{ L'&', L"&amp;" },
{ L'<', L"&lt;" },
{ L'>', L"&gt;" },
{ L'"', L"&quot;" },
{ L'\0', 0 }
};
//! Writes a text into the file. All occurrences of special characters like
//! & (&amp;), < (&lt;), > (&gt;), and " (&quot;) are automatically replaced.
void CXMLWriter::writeText(const wchar_t* text)
@ -208,6 +194,15 @@ void CXMLWriter::writeText(const wchar_t* text)
if (!File || !text)
return;
static const CXMLWriter::XMLSpecialCharacters XMLWSChar[] =
{
{ L'&', L"&amp;" },
{ L'<', L"&lt;" },
{ L'>', L"&gt;" },
{ L'"', L"&quot;" },
{ L'\0', 0 }
};
// TODO: we have to get rid of that reserve call as well as it slows down xml-writing seriously.
// Making a member-variable would work, but a lot of memory would stay around after writing.
// So the correct solution is probably using fixed block here and always write when that is full.
@ -255,6 +250,222 @@ void CXMLWriter::writeLineBreak()
}
//! Constructor
CXMLWriterUTF8::CXMLWriterUTF8(IWriteFile* file)
: CXMLWriterCommon(file)
{
#ifdef _DEBUG
setDebugName("CXMLWriter");
#endif
}
//! Writes a xml 1.0 header like <?xml version="1.0"?>
void CXMLWriterUTF8::writeXMLHeader()
{
if (!File)
return;
// No BOM as it's not necessarily utf8
const c8* const p = "<?xml version=\"1.0\"?>";
File->write(p, strlen(p) * sizeof(c8));
writeLineBreak();
TextWrittenLast = false;
}
//! Writes an xml element with maximal 5 attributes
void CXMLWriterUTF8::writeElement(const c8* name, bool empty,
const c8* attr1Name, const c8* attr1Value,
const c8* attr2Name, const c8* attr2Value,
const c8* attr3Name, const c8* attr3Value,
const c8* attr4Name, const c8* attr4Value,
const c8* attr5Name, const c8* attr5Value)
{
if (!File || !name)
return;
if (Tabs > 0)
{
for (int i=0; i<Tabs; ++i)
File->write("\t", sizeof(c8));
}
// write name
File->write("<", sizeof(c8));
File->write(name, strlen(name)*sizeof(c8));
// write attributes
writeAttribute(attr1Name, attr1Value);
writeAttribute(attr2Name, attr2Value);
writeAttribute(attr3Name, attr3Value);
writeAttribute(attr4Name, attr4Value);
writeAttribute(attr5Name, attr5Value);
// write closing tag
if (empty)
File->write(" />", 3*sizeof(c8));
else
{
File->write(">", sizeof(c8));
++Tabs;
}
TextWrittenLast = false;
}
//! Writes an xml element with any number of attributes
void CXMLWriterUTF8::writeElement(const c8* name, bool empty,
core::array<core::stringc> &names,
core::array<core::stringc> &values)
{
if (!File || !name)
return;
if (Tabs > 0)
{
for (int i=0; i<Tabs; ++i)
File->write("\t", sizeof(c8));
}
// write name
File->write("<", sizeof(c8));
File->write(name, strlen(name)*sizeof(c8));
// write attributes
u32 i=0;
for (; i < names.size() && i < values.size(); ++i)
writeAttribute(names[i].c_str(), values[i].c_str());
// write closing tag
if (empty)
File->write(" />", 3*sizeof(c8));
else
{
File->write(">", sizeof(c8));
++Tabs;
}
TextWrittenLast = false;
}
void CXMLWriterUTF8::writeAttribute(const c8* name, const c8* value)
{
if (!name || !value)
return;
File->write(" ", sizeof(c8));
File->write(name, strlen(name)*sizeof(c8));
File->write("=\"", 2*sizeof(c8));
writeText(value);
File->write("\"", sizeof(c8));
}
//! Writes a comment into the xml file
void CXMLWriterUTF8::writeComment(const c8* comment)
{
if (!File || !comment)
return;
File->write("<!--", 4*sizeof(c8));
writeText(comment);
File->write("-->", 3*sizeof(c8));
}
//! Writes the closing tag for an element. Like </foo>
void CXMLWriterUTF8::writeClosingTag(const c8* name)
{
if (!File || !name)
return;
--Tabs;
if (Tabs > 0 && !TextWrittenLast)
{
for (int i=0; i<Tabs; ++i)
File->write("\t", sizeof(c8));
}
File->write("</", 2*sizeof(c8));
File->write(name, strlen(name)*sizeof(c8));
File->write(">", sizeof(c8));
TextWrittenLast = false;
}
//! Writes a text into the file. All occurrences of special characters like
//! & (&amp;), < (&lt;), > (&gt;), and " (&quot;) are automatically replaced.
void CXMLWriterUTF8::writeText(const c8* text)
{
if (!File || !text)
return;
static const CXMLWriterUTF8::XMLSpecialCharacters XMLWSChar[] =
{
{ '&', "&amp;" },
{ '<', "&lt;" },
{ '>', "&gt;" },
{ '"', "&quot;" },
{ '\0', 0 }
};
// TODO: we have to get rid of that reserve call as well as it slows down xml-writing seriously.
// Making a member-variable would work, but a lot of memory would stay around after writing.
// So the correct solution is probably using fixed block here and always write when that is full.
core::stringc s;
s.reserve(strlen(text)+1);
const c8* p = text;
while(*p)
{
// check if it is matching
bool found = false;
for (s32 i=0; XMLWSChar[i].Character != '\0'; ++i)
if (*p == XMLWSChar[i].Character)
{
s.append(XMLWSChar[i].Symbol);
found = true;
break;
}
if (!found)
s.append(*p);
++p;
}
// write new string
File->write(s.c_str(), s.size()*sizeof(c8));
TextWrittenLast = true;
}
//! Writes a line break
void CXMLWriterUTF8::writeLineBreak()
{
if (!File)
return;
#if defined(_IRR_OSX_PLATFORM_)
File->write("\r", sizeof(c8));
#elif defined(_IRR_WINDOWS_API_)
File->write("\r\n", 2*sizeof(c8));
#else
File->write("\n", sizeof(c8));
#endif
}
} // end namespace irr
} // end namespace io

View File

@ -17,8 +17,49 @@ namespace irr
namespace io
{
//! Interface providing methods for making it easier to write XML files.
class CXMLWriter : public IXMLWriter
//! creates an IXMLReader
IXMLWriter* createIXMLWriter(IWriteFile* file);
//! creates an IXMLReader
IXMLWriterUTF8* createIXMLWriterUTF8(IWriteFile* file);
// Stuff needed by implementations for all character types
// TODO: With some more work it could maybe become a pure template based thing like CXMLReaderImpl
// and replace the type based writer implementations. Sorry, too lazy for now :-/
template<class char_type>
class CXMLWriterCommon
{
public:
//! Constructor
CXMLWriterCommon(IWriteFile* file): File(file), Tabs(0), TextWrittenLast(false)
{
if (File)
File->grab();
}
//! Destructor
virtual ~CXMLWriterCommon()
{
if (File)
File->drop();
}
struct XMLSpecialCharacters
{
char_type Character;
const char_type* Symbol;
};
protected:
IWriteFile* File;
s32 Tabs;
bool TextWrittenLast;
};
//! Implementation providing methods for making it easier to write XML files.
class CXMLWriter : public IXMLWriter, public CXMLWriterCommon<wchar_t>
{
public:
@ -26,7 +67,7 @@ namespace io
CXMLWriter(IWriteFile* file);
//! Destructor
virtual ~CXMLWriter();
virtual ~CXMLWriter() {}
//! Writes a xml 1.0 header like <?xml version="1.0"?>
virtual void writeXMLHeader() _IRR_OVERRIDE_;
@ -56,22 +97,56 @@ namespace io
//! Writes a line break
virtual void writeLineBreak() _IRR_OVERRIDE_;
struct XMLSpecialCharacters
{
wchar_t Character;
const wchar_t* Symbol;
};
private:
void writeAttribute(const wchar_t* att, const wchar_t* name);
IWriteFile* File;
s32 Tabs;
bool TextWrittenLast;
};
//! Implementation providing methods for making it easier to write XML files.
class CXMLWriterUTF8 : public IXMLWriterUTF8, public CXMLWriterCommon<c8>
{
public:
//! Constructor
CXMLWriterUTF8(IWriteFile* file);
//! Destructor
virtual ~CXMLWriterUTF8() {}
//! Writes a xml 1.0 header like <?xml version="1.0"?>
virtual void writeXMLHeader() _IRR_OVERRIDE_;
//! Writes an xml element with maximal 5 attributes
virtual void writeElement(const c8* name, bool empty=false,
const c8* attr1Name = 0, const c8* attr1Value = 0,
const c8* attr2Name = 0, const c8* attr2Value = 0,
const c8* attr3Name = 0, const c8* attr3Value = 0,
const c8* attr4Name = 0, const c8* attr4Value = 0,
const c8* attr5Name = 0, const c8* attr5Value = 0) _IRR_OVERRIDE_;
//! Writes an xml element with any number of attributes
virtual void writeElement(const c8* name, bool empty,
core::array<core::stringc> &names, core::array<core::stringc> &values) _IRR_OVERRIDE_;
//! Writes a comment into the xml file
virtual void writeComment(const c8* comment) _IRR_OVERRIDE_;
//! Writes the closing tag for an element. Like </foo>
virtual void writeClosingTag(const c8* name) _IRR_OVERRIDE_;
//! Writes a text into the file. All occurrences of special characters like
//! & (&amp;), < (&lt;), > (&gt;), and " (&quot;) are automatically replaced.
virtual void writeText(const c8* text) _IRR_OVERRIDE_;
//! Writes a line break
virtual void writeLineBreak() _IRR_OVERRIDE_;
private:
void writeAttribute(const c8* att, const c8* name);
};
} // end namespace irr
} // end namespace io