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-e03cc46cb475master
parent
0f217d3c5a
commit
d236d99c6c
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -168,6 +168,8 @@ namespace scene
|
|||
|
||||
bool InputReceiverEnabled;
|
||||
bool TargetAndRotationAreBound;
|
||||
|
||||
bool HasD3DStyleProjectionMatrix; // true: projection from 0 to w; false: -w to w
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_;
|
||||
|
||||
|
|
|
@ -16,10 +16,7 @@
|
|||
|
||||
namespace irr
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
class IXMLWriter;
|
||||
}
|
||||
|
||||
namespace gui
|
||||
{
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -203,8 +203,6 @@ public:
|
|||
|
||||
virtual ~COpenGLCoreTexture()
|
||||
{
|
||||
Driver->getCacheHandler()->getTextureCache().remove(this);
|
||||
|
||||
if (TextureName)
|
||||
glDeleteTextures(1, &TextureName);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -18,7 +18,6 @@ namespace irr
|
|||
{
|
||||
namespace io
|
||||
{
|
||||
class IXMLWriter;
|
||||
class IFileSystem;
|
||||
}
|
||||
namespace scene
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"&" },
|
||||
{ L'<', L"<" },
|
||||
{ L'>', L">" },
|
||||
{ L'"', L""" },
|
||||
{ L'\0', 0 }
|
||||
};
|
||||
|
||||
|
||||
//! Writes a text into the file. All occurrences of special characters like
|
||||
//! & (&), < (<), > (>), and " (") 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"&" },
|
||||
{ L'<', L"<" },
|
||||
{ L'>', L">" },
|
||||
{ L'"', L""" },
|
||||
{ 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
|
||||
//! & (&), < (<), > (>), and " (") are automatically replaced.
|
||||
void CXMLWriterUTF8::writeText(const c8* text)
|
||||
{
|
||||
if (!File || !text)
|
||||
return;
|
||||
|
||||
static const CXMLWriterUTF8::XMLSpecialCharacters XMLWSChar[] =
|
||||
{
|
||||
{ '&', "&" },
|
||||
{ '<', "<" },
|
||||
{ '>', ">" },
|
||||
{ '"', """ },
|
||||
{ '\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
|
||||
|
||||
|
|
|
@ -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
|
||||
//! & (&), < (<), > (>), and " (") 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
|
||||
|
||||
|
|
Loading…
Reference in New Issue