Changed indentation of StdMesh*.{h,cpp} from spaces to tabs

stable-5.2
Armin Burgmeier 2009-08-01 15:36:13 -04:00
parent 4c186f821c
commit 12ddf2b889
4 changed files with 1034 additions and 1034 deletions

View File

@ -1,7 +1,7 @@
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 2009 Armin Burgmeier
* Copyright (c) 2009 Armin Burgmeier
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de
*
* Portions might be copyrighted by other authors who have contributed
@ -26,13 +26,13 @@
class StdMeshError: public std::exception
{
public:
StdMeshError(const StdStrBuf& message, const char* file, unsigned int line);
virtual ~StdMeshError() throw() {}
StdMeshError(const StdStrBuf& message, const char* file, unsigned int line);
virtual ~StdMeshError() throw() {}
virtual const char* what() const throw() { return Buf.getData(); }
virtual const char* what() const throw() { return Buf.getData(); }
protected:
StdStrBuf Buf;
StdStrBuf Buf;
};
// Interface to load skeleton files. Given a filename occuring in the
@ -42,228 +42,228 @@ protected:
class StdMeshSkeletonLoader
{
public:
virtual StdStrBuf LoadSkeleton(const char* filename) = 0;
virtual StdStrBuf LoadSkeleton(const char* filename) = 0;
};
class StdMeshMatrix
{
public:
void SetIdentity();
void SetTranslate(float dx, float dy, float dz);
void SetScale(float sx, float sy, float sz);
void SetRotate(float angle, float rx, float ry, float rz);
void SetIdentity();
void SetTranslate(float dx, float dy, float dz);
void SetScale(float sx, float sy, float sz);
void SetRotate(float angle, float rx, float ry, float rz);
float& operator()(int i, int j) { return a[i][j]; }
float operator()(int i, int j) const { return a[i][j]; }
float& operator()(int i, int j) { return a[i][j]; }
float operator()(int i, int j) const { return a[i][j]; }
// *this *= other
void Mul(const StdMeshMatrix& other);
void Mul(float f);
// *this += other
void Add(const StdMeshMatrix& other);
// *this *= other
void Mul(const StdMeshMatrix& other);
void Mul(float f);
// *this += other
void Add(const StdMeshMatrix& other);
// *this = other * *this
void Transform(const StdMeshMatrix& other);
// *this = other * *this
void Transform(const StdMeshMatrix& other);
private:
// 3x3 orthogonal + translation in last column
float a[3][4];
// 3x3 orthogonal + translation in last column
float a[3][4];
};
class StdMeshBone
{
friend class StdMesh;
friend class StdMesh;
public:
StdMeshBone() {}
StdMeshBone() {}
unsigned int Index; // Index in master bone table
int ID; // Bone ID
StdStrBuf Name; // Bone name
unsigned int Index; // Index in master bone table
int ID; // Bone ID
StdStrBuf Name; // Bone name
// Bone transformation
StdMeshMatrix Trans;
// Inverse transformation
StdMeshMatrix InverseTrans;
// Bone transformation
StdMeshMatrix Trans;
// Inverse transformation
StdMeshMatrix InverseTrans;
const StdMeshBone* GetParent() const { return Parent; }
const StdMeshBone* GetParent() const { return Parent; }
const StdMeshBone& GetChild(unsigned int i) const { return *Children[i]; }
unsigned int GetNumChildren() const { return Children.size(); }
const StdMeshBone& GetChild(unsigned int i) const { return *Children[i]; }
unsigned int GetNumChildren() const { return Children.size(); }
private:
StdMeshBone* Parent; // Parent bone
std::vector<StdMeshBone*> Children; // Children. Not owned.
StdMeshBone* Parent; // Parent bone
std::vector<StdMeshBone*> Children; // Children. Not owned.
StdMeshBone(const StdMeshBone&); // non-copyable
StdMeshBone& operator=(const StdMeshBone&); // non-assignable
StdMeshBone(const StdMeshBone&); // non-copyable
StdMeshBone& operator=(const StdMeshBone&); // non-assignable
};
class StdMeshVertexBoneAssignment
{
public:
unsigned int BoneIndex;
float Weight;
unsigned int BoneIndex;
float Weight;
};
class StdMeshVertex
{
public:
float x, y, z;
float nx, ny, nz;
float u, v;
float x, y, z;
float nx, ny, nz;
float u, v;
// *this = trans * *this
void Transform(const StdMeshMatrix& trans);
// *this = trans * *this
void Transform(const StdMeshMatrix& trans);
// *this *= f;
void Mul(float f);
// *this += other;
void Add(const StdMeshVertex& other);
// *this *= f;
void Mul(float f);
// *this += other;
void Add(const StdMeshVertex& other);
};
class StdMeshFace
{
public:
unsigned int Vertices[3];
unsigned int Vertices[3];
};
// Keyframe, specifies transformation for one bone in a particular frame
class StdMeshKeyFrame
{
public:
StdMeshMatrix Trans;
StdMeshMatrix Trans;
};
// Animation track, specifies transformation for one bone for each keyframe
class StdMeshTrack
{
friend class StdMesh;
friend class StdMesh;
public:
StdMeshMatrix GetTransformAt(float time) const;
StdMeshMatrix GetTransformAt(float time) const;
private:
std::map<float, StdMeshKeyFrame> Frames;
std::map<float, StdMeshKeyFrame> Frames;
};
// Animation, consists of one Track for each animated Bone
class StdMeshAnimation
{
friend class StdMesh;
friend class StdMeshInstance;
friend class StdMesh;
friend class StdMeshInstance;
public:
StdMeshAnimation() {}
StdMeshAnimation(const StdMeshAnimation& other);
~StdMeshAnimation();
StdMeshAnimation() {}
StdMeshAnimation(const StdMeshAnimation& other);
~StdMeshAnimation();
StdMeshAnimation& operator=(const StdMeshAnimation& other);
StdMeshAnimation& operator=(const StdMeshAnimation& other);
StdCopyStrBuf Name;
float Length;
StdCopyStrBuf Name;
float Length;
private:
std::vector<StdMeshTrack*> Tracks; // bone-indexed
std::vector<StdMeshTrack*> Tracks; // bone-indexed
};
struct StdMeshBox
{
float x1, y1, z1;
float x2, y2, z2;
float x1, y1, z1;
float x2, y2, z2;
};
class StdMesh
{
friend class StdMeshInstance;
friend class StdMeshInstance;
public:
StdMesh();
~StdMesh();
StdMesh();
~StdMesh();
// filename is only used to show it in error messages. The model is
// loaded from xml_data.
// Throws StdMeshError.
void InitXML(const char* filename, const char* xml_data, StdMeshSkeletonLoader& skel_loader, const StdMeshMatManager& manager);
// filename is only used to show it in error messages. The model is
// loaded from xml_data.
// Throws StdMeshError.
void InitXML(const char* filename, const char* xml_data, StdMeshSkeletonLoader& skel_loader, const StdMeshMatManager& manager);
const StdMeshVertex& GetVertex(unsigned int i) const { return Vertices[i]; }
unsigned int GetNumVertices() const { return Vertices.size(); }
const StdMeshVertex& GetVertex(unsigned int i) const { return Vertices[i]; }
unsigned int GetNumVertices() const { return Vertices.size(); }
const StdMeshFace& GetFace(unsigned int i) const { return Faces[i]; }
unsigned int GetNumFaces() const { return Faces.size(); }
const StdMeshFace& GetFace(unsigned int i) const { return Faces[i]; }
unsigned int GetNumFaces() const { return Faces.size(); }
const StdMeshBone& GetBone(unsigned int i) const { return *Bones[i]; }
unsigned int GetNumBones() const { return Bones.size(); }
const StdMeshBone& GetBone(unsigned int i) const { return *Bones[i]; }
unsigned int GetNumBones() const { return Bones.size(); }
const StdMeshAnimation* GetAnimationByName(const StdStrBuf& name) const;
const StdMeshMaterial& GetMaterial() const { return *Material; }
const StdMeshAnimation* GetAnimationByName(const StdStrBuf& name) const;
const StdMeshMaterial& GetMaterial() const { return *Material; }
const StdMeshBox& GetBoundingBox() const { return BoundingBox; }
const StdMeshBox& GetBoundingBox() const { return BoundingBox; }
private:
void AddMasterBone(StdMeshBone* bone);
void AddMasterBone(StdMeshBone* bone);
StdMesh(const StdMesh& other); // non-copyable
StdMesh& operator=(const StdMesh& other); // non-assignable
StdMesh(const StdMesh& other); // non-copyable
StdMesh& operator=(const StdMesh& other); // non-assignable
// Remember bone assignments for vertices
class Vertex: public StdMeshVertex
{
public:
std::vector<StdMeshVertexBoneAssignment> BoneAssignments;
};
// Remember bone assignments for vertices
class Vertex: public StdMeshVertex
{
public:
std::vector<StdMeshVertexBoneAssignment> BoneAssignments;
};
std::vector<Vertex> Vertices;
std::vector<StdMeshFace> Faces;
std::vector<StdMeshBone*> Bones; // Master Bone Table
std::vector<Vertex> Vertices;
std::vector<StdMeshFace> Faces;
std::vector<StdMeshBone*> Bones; // Master Bone Table
std::map<StdCopyStrBuf, StdMeshAnimation> Animations;
std::map<StdCopyStrBuf, StdMeshAnimation> Animations;
StdMeshBox BoundingBox;
const StdMeshMaterial* Material;
StdMeshBox BoundingBox;
const StdMeshMaterial* Material;
};
class StdMeshInstance
{
public:
StdMeshInstance(const StdMesh& mesh);
StdMeshInstance(const StdMesh& mesh);
enum FaceOrdering {
FO_Fixed, // don't reorder, keep faces as in mesh
FO_FarthestToNearest,
FO_NearestToFarthest
};
enum FaceOrdering {
FO_Fixed, // don't reorder, keep faces as in mesh
FO_FarthestToNearest,
FO_NearestToFarthest
};
FaceOrdering GetFaceOrdering() const { return CurrentFaceOrdering; }
void SetFaceOrdering(FaceOrdering ordering);
FaceOrdering GetFaceOrdering() const { return CurrentFaceOrdering; }
void SetFaceOrdering(FaceOrdering ordering);
bool SetAnimationByName(const StdStrBuf& animation_name);
void SetAnimation(const StdMeshAnimation& animation);
void UnsetAnimation();
bool SetAnimationByName(const StdStrBuf& animation_name);
void SetAnimation(const StdMeshAnimation& animation);
void UnsetAnimation();
const StdMeshAnimation* GetAnimation() const { return Animation; }
const StdMeshAnimation* GetAnimation() const { return Animation; }
void SetPosition(float position);
float GetPosition() const { return Position; }
void SetPosition(float position);
float GetPosition() const { return Position; }
// Get vertex of instance, with current animation applied. This needs to
// go elsewhere if/when we want to calculate this on the hardware.
const StdMeshVertex& GetVertex(unsigned int i) const { return Vertices[i]; }
unsigned int GetNumVertices() const { return Vertices.size(); }
// Get vertex of instance, with current animation applied. This needs to
// go elsewhere if/when we want to calculate this on the hardware.
const StdMeshVertex& GetVertex(unsigned int i) const { return Vertices[i]; }
unsigned int GetNumVertices() const { return Vertices.size(); }
// Get face of instance. The instance faces are the same as the mesh faces,
// with the exception that they are differently ordered, depending on the
// current FaceOrdering. See also SetFaceOrdering.
const StdMeshFace& GetFace(unsigned int i) const { return *Faces[i]; }
unsigned int GetNumFaces() const { return Faces.size(); }
// Get face of instance. The instance faces are the same as the mesh faces,
// with the exception that they are differently ordered, depending on the
// current FaceOrdering. See also SetFaceOrdering.
const StdMeshFace& GetFace(unsigned int i) const { return *Faces[i]; }
unsigned int GetNumFaces() const { return Faces.size(); }
const StdMesh& Mesh;
const StdMesh& Mesh;
protected:
void ReorderFaces();
void ReorderFaces();
FaceOrdering CurrentFaceOrdering;
const StdMeshAnimation* Animation;
float Position;
FaceOrdering CurrentFaceOrdering;
const StdMeshAnimation* Animation;
float Position;
std::vector<StdMeshMatrix> BoneTransforms;
std::vector<StdMeshVertex> Vertices;
std::vector<const StdMeshFace*> Faces;
std::vector<StdMeshMatrix> BoneTransforms;
std::vector<StdMeshVertex> Vertices;
std::vector<const StdMeshFace*> Faces;
};
#endif

View File

@ -35,13 +35,13 @@ class StdMeshMaterialParserCtx;
class StdMeshMaterialError: public std::exception
{
public:
StdMeshMaterialError(const StdStrBuf& message, const char* file, unsigned int line);
virtual ~StdMeshMaterialError() throw() {}
StdMeshMaterialError(const StdStrBuf& message, const char* file, unsigned int line);
virtual ~StdMeshMaterialError() throw() {}
virtual const char* what() const throw() { return Buf.getData(); }
virtual const char* what() const throw() { return Buf.getData(); }
protected:
StdCopyStrBuf Buf;
StdCopyStrBuf Buf;
};
// Interface to load textures. Given a texture filename occuring in the
@ -50,100 +50,100 @@ protected:
class StdMeshMaterialTextureLoader
{
public:
virtual bool LoadTexture(const char* filename, CPNGFile& dest) = 0;
virtual bool LoadTexture(const char* filename, CPNGFile& dest) = 0;
};
class StdMeshMaterialTextureUnit
{
public:
// Ref-counted texture. When a meterial inherits from one which contains
// a TextureUnit, then they will share the same CTexRef.
class TexRef
{
public:
TexRef(unsigned int size);
~TexRef();
// Ref-counted texture. When a meterial inherits from one which contains
// a TextureUnit, then they will share the same CTexRef.
class TexRef
{
public:
TexRef(unsigned int size);
~TexRef();
unsigned int RefCount;
CTexRef Tex;
};
unsigned int RefCount;
CTexRef Tex;
};
StdMeshMaterialTextureUnit();
StdMeshMaterialTextureUnit(const StdMeshMaterialTextureUnit& other);
~StdMeshMaterialTextureUnit();
StdMeshMaterialTextureUnit();
StdMeshMaterialTextureUnit(const StdMeshMaterialTextureUnit& other);
~StdMeshMaterialTextureUnit();
StdMeshMaterialTextureUnit& operator=(const StdMeshMaterialTextureUnit&);
StdMeshMaterialTextureUnit& operator=(const StdMeshMaterialTextureUnit&);
void Load(StdMeshMaterialParserCtx& ctx);
void Load(StdMeshMaterialParserCtx& ctx);
const CTexRef& GetTexture() const { return Texture->Tex; }
const CTexRef& GetTexture() const { return Texture->Tex; }
private:
TexRef* Texture;
TexRef* Texture;
};
class StdMeshMaterialPass
{
public:
StdMeshMaterialPass();
void Load(StdMeshMaterialParserCtx& ctx);
StdMeshMaterialPass();
void Load(StdMeshMaterialParserCtx& ctx);
std::vector<StdMeshMaterialTextureUnit> TextureUnits;
std::vector<StdMeshMaterialTextureUnit> TextureUnits;
float Ambient[4];
float Diffuse[4];
float Specular[4];
float Emissive[4];
float Shininess;
float Ambient[4];
float Diffuse[4];
float Specular[4];
float Emissive[4];
float Shininess;
};
class StdMeshMaterialTechnique
{
public:
void Load(StdMeshMaterialParserCtx& ctx);
void Load(StdMeshMaterialParserCtx& ctx);
std::vector<StdMeshMaterialPass> Passes;
std::vector<StdMeshMaterialPass> Passes;
};
class StdMeshMaterial
{
public:
StdMeshMaterial();
void Load(StdMeshMaterialParserCtx& ctx);
StdMeshMaterial();
void Load(StdMeshMaterialParserCtx& ctx);
// Location the Material was loaded from
StdCopyStrBuf FileName;
unsigned int Line;
// Location the Material was loaded from
StdCopyStrBuf FileName;
unsigned int Line;
// Material name
StdCopyStrBuf Name;
// Material name
StdCopyStrBuf Name;
// Not currently used in Clonk, but don't fail when we see this in a
// Material script:
bool ReceiveShadows;
// Not currently used in Clonk, but don't fail when we see this in a
// Material script:
bool ReceiveShadows;
// Available techniques
std::vector<StdMeshMaterialTechnique> Techniques;
// Available techniques
std::vector<StdMeshMaterialTechnique> Techniques;
};
class StdMeshMatManager
{
public:
// Remove all materials from manager. Make sure there is no StdMesh
// referencing any out there before calling this.
void Clear();
// Remove all materials from manager. Make sure there is no StdMesh
// referencing any out there before calling this.
void Clear();
// Parse a material script file, and add the materials to the manager.
// filename may be NULL if the source is not a file. It will only be used
// for error messages.
// Throws StdMeshMaterialError.
void Parse(const char* mat_script, const char* filename, StdMeshMaterialTextureLoader& tex_loader);
// Parse a material script file, and add the materials to the manager.
// filename may be NULL if the source is not a file. It will only be used
// for error messages.
// Throws StdMeshMaterialError.
void Parse(const char* mat_script, const char* filename, StdMeshMaterialTextureLoader& tex_loader);
// Get material by name. NULL if there is no such material with this name.
const StdMeshMaterial* GetMaterial(const char* material_name) const;
// Get material by name. NULL if there is no such material with this name.
const StdMeshMaterial* GetMaterial(const char* material_name) const;
private:
std::map<StdCopyStrBuf, StdMeshMaterial> Materials;
std::map<StdCopyStrBuf, StdMeshMaterial> Materials;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -22,119 +22,119 @@
StdMeshMaterialError::StdMeshMaterialError(const StdStrBuf& message, const char* file, unsigned int line)
{
Buf.Format("%s:%u: %s", file, line, message.getData());
Buf.Format("%s:%u: %s", file, line, message.getData());
}
enum Token
{
TOKEN_IDTF,
TOKEN_BRACE_OPEN,
TOKEN_BRACE_CLOSE,
TOKEN_COLON,
TOKEN_EOF
TOKEN_IDTF,
TOKEN_BRACE_OPEN,
TOKEN_BRACE_CLOSE,
TOKEN_COLON,
TOKEN_EOF
};
class StdMeshMaterialParserCtx
{
public:
StdMeshMaterialParserCtx(const char* mat_script, const char* filename, StdMeshMaterialTextureLoader& tex_loader);
StdMeshMaterialParserCtx(const char* mat_script, const char* filename, StdMeshMaterialTextureLoader& tex_loader);
void SkipWhitespace();
Token Peek(StdStrBuf& name);
Token Advance(StdStrBuf& name);
Token AdvanceNonEOF(StdStrBuf& name);
Token AdvanceRequired(StdStrBuf& name, Token expect);
Token AdvanceRequired(StdStrBuf& name, Token expect1, Token expect2);
float AdvanceFloat();
bool AdvanceFloatOptional(float& value);
bool AdvanceBoolean();
void Error(const StdStrBuf& message);
void ErrorUnexpectedIdentifier(const StdStrBuf& identifier);
void SkipWhitespace();
Token Peek(StdStrBuf& name);
Token Advance(StdStrBuf& name);
Token AdvanceNonEOF(StdStrBuf& name);
Token AdvanceRequired(StdStrBuf& name, Token expect);
Token AdvanceRequired(StdStrBuf& name, Token expect1, Token expect2);
float AdvanceFloat();
bool AdvanceFloatOptional(float& value);
bool AdvanceBoolean();
void Error(const StdStrBuf& message);
void ErrorUnexpectedIdentifier(const StdStrBuf& identifier);
// Current parsing data
unsigned int Line;
const char* Script;
// Current parsing data
unsigned int Line;
const char* Script;
StdCopyStrBuf FileName;
StdMeshMaterialTextureLoader& TextureLoader;
StdCopyStrBuf FileName;
StdMeshMaterialTextureLoader& TextureLoader;
};
StdMeshMaterialParserCtx::StdMeshMaterialParserCtx(const char* mat_script, const char* filename, StdMeshMaterialTextureLoader& tex_loader):
Line(0), Script(mat_script), FileName(filename), TextureLoader(tex_loader)
Line(0), Script(mat_script), FileName(filename), TextureLoader(tex_loader)
{
}
void StdMeshMaterialParserCtx::SkipWhitespace()
{
while(isspace(*Script))
{
if(*Script == '\n') ++Line;
++Script;
}
while(isspace(*Script))
{
if(*Script == '\n') ++Line;
++Script;
}
}
Token StdMeshMaterialParserCtx::Peek(StdStrBuf& name)
{
SkipWhitespace();
SkipWhitespace();
const char* before = Script;
Token tok = Advance(name);
Script = before;
return tok;
const char* before = Script;
Token tok = Advance(name);
Script = before;
return tok;
}
Token StdMeshMaterialParserCtx::Advance(StdStrBuf& name)
{
SkipWhitespace();
SkipWhitespace();
switch(*Script)
{
case '\0':
name.Clear();
return TOKEN_EOF;
case '{':
++Script;
name = "{";
return TOKEN_BRACE_OPEN;
case '}':
++Script;
name = "}";
return TOKEN_BRACE_CLOSE;
case ':':
++Script;
name = ":";
return TOKEN_COLON;
default:
const char* begin = Script;
// Advance to next whitespace
do { ++Script; } while(!isspace(*Script) && *Script != '{' && *Script != '}' && *Script != ':');
name.Copy(begin, Script - begin);
return TOKEN_IDTF;
}
switch(*Script)
{
case '\0':
name.Clear();
return TOKEN_EOF;
case '{':
++Script;
name = "{";
return TOKEN_BRACE_OPEN;
case '}':
++Script;
name = "}";
return TOKEN_BRACE_CLOSE;
case ':':
++Script;
name = ":";
return TOKEN_COLON;
default:
const char* begin = Script;
// Advance to next whitespace
do { ++Script; } while(!isspace(*Script) && *Script != '{' && *Script != '}' && *Script != ':');
name.Copy(begin, Script - begin);
return TOKEN_IDTF;
}
}
Token StdMeshMaterialParserCtx::AdvanceNonEOF(StdStrBuf& name)
{
Token token = Advance(name);
if(token == TOKEN_EOF) Error(StdCopyStrBuf("Unexpected end of file"));
return token;
Token token = Advance(name);
if(token == TOKEN_EOF) Error(StdCopyStrBuf("Unexpected end of file"));
return token;
}
Token StdMeshMaterialParserCtx::AdvanceRequired(StdStrBuf& name, Token expect)
{
Token token = AdvanceNonEOF(name);
// TODO: Explain what was actually expected
if(token != expect) Error(StdCopyStrBuf("'") + name + "' unexpected");
return token;
Token token = AdvanceNonEOF(name);
// TODO: Explain what was actually expected
if(token != expect) Error(StdCopyStrBuf("'") + name + "' unexpected");
return token;
}
Token StdMeshMaterialParserCtx::AdvanceRequired(StdStrBuf& name, Token expect1, Token expect2)
{
Token token = AdvanceNonEOF(name);
// TODO: Explain what was actually expected
if(token != expect1 && token != expect2)
Error(StdStrBuf("'") + name + "' unexpected");
return token;
Token token = AdvanceNonEOF(name);
// TODO: Explain what was actually expected
if(token != expect1 && token != expect2)
Error(StdStrBuf("'") + name + "' unexpected");
return token;
}
#ifdef _MSC_VER
@ -146,310 +146,310 @@ static inline float strtof(const char *_Str, char **_EndPtr)
float StdMeshMaterialParserCtx::AdvanceFloat()
{
StdStrBuf buf;
AdvanceRequired(buf, TOKEN_IDTF);
char* end;
float f = strtof(buf.getData(), &end);
if(*end != '\0') Error(StdStrBuf("Floating point value expected"));
return f;
StdStrBuf buf;
AdvanceRequired(buf, TOKEN_IDTF);
char* end;
float f = strtof(buf.getData(), &end);
if(*end != '\0') Error(StdStrBuf("Floating point value expected"));
return f;
}
bool StdMeshMaterialParserCtx::AdvanceFloatOptional(float& value)
{
StdStrBuf buf;
Token tok = Peek(buf);
StdStrBuf buf;
Token tok = Peek(buf);
if(tok == TOKEN_IDTF && isdigit(buf[0]))
{
value = AdvanceFloat();
return true;
}
if(tok == TOKEN_IDTF && isdigit(buf[0]))
{
value = AdvanceFloat();
return true;
}
return false;
return false;
}
bool StdMeshMaterialParserCtx::AdvanceBoolean()
{
StdCopyStrBuf buf;
AdvanceRequired(buf, TOKEN_IDTF);
if(buf == "on") return true;
if(buf == "off") return false;
Error(StdCopyStrBuf("Expected either 'on' or 'off', but not '") + buf + "'");
return false; // Never reached
StdCopyStrBuf buf;
AdvanceRequired(buf, TOKEN_IDTF);
if(buf == "on") return true;
if(buf == "off") return false;
Error(StdCopyStrBuf("Expected either 'on' or 'off', but not '") + buf + "'");
return false; // Never reached
}
void StdMeshMaterialParserCtx::Error(const StdStrBuf& message)
{
throw StdMeshMaterialError(message, FileName.getData(), Line);
throw StdMeshMaterialError(message, FileName.getData(), Line);
}
void StdMeshMaterialParserCtx::ErrorUnexpectedIdentifier(const StdStrBuf& identifier)
{
Error(StdCopyStrBuf("Unexpected identifier: '") + identifier + "'");
Error(StdCopyStrBuf("Unexpected identifier: '") + identifier + "'");
}
StdMeshMaterialTextureUnit::TexRef::TexRef(unsigned int size):
RefCount(1), Tex(size, false)
RefCount(1), Tex(size, false)
{
}
StdMeshMaterialTextureUnit::TexRef::~TexRef()
{
assert(RefCount == 0);
assert(RefCount == 0);
}
StdMeshMaterialTextureUnit::StdMeshMaterialTextureUnit():
Texture(NULL)
Texture(NULL)
{
}
StdMeshMaterialTextureUnit::StdMeshMaterialTextureUnit(const StdMeshMaterialTextureUnit& other):
Texture(other.Texture)
Texture(other.Texture)
{
if(Texture)
++Texture->RefCount;
if(Texture)
++Texture->RefCount;
}
StdMeshMaterialTextureUnit::~StdMeshMaterialTextureUnit()
{
if(Texture && !--Texture->RefCount)
delete Texture;
if(Texture && !--Texture->RefCount)
delete Texture;
}
StdMeshMaterialTextureUnit& StdMeshMaterialTextureUnit::operator=(const StdMeshMaterialTextureUnit& other)
{
if(this == &other) return *this;
if(Texture) if(!--Texture->RefCount) delete Texture;
Texture = other.Texture;
if(Texture) ++Texture->RefCount;
return *this;
if(this == &other) return *this;
if(Texture) if(!--Texture->RefCount) delete Texture;
Texture = other.Texture;
if(Texture) ++Texture->RefCount;
return *this;
}
void StdMeshMaterialTextureUnit::Load(StdMeshMaterialParserCtx& ctx)
{
Token token;
StdCopyStrBuf token_name;
while((token = ctx.AdvanceNonEOF(token_name)) == TOKEN_IDTF)
{
if(token_name == "texture")
{
ctx.AdvanceRequired(token_name, TOKEN_IDTF);
Token token;
StdCopyStrBuf token_name;
while((token = ctx.AdvanceNonEOF(token_name)) == TOKEN_IDTF)
{
if(token_name == "texture")
{
ctx.AdvanceRequired(token_name, TOKEN_IDTF);
CPNGFile png;
if(!ctx.TextureLoader.LoadTexture(token_name.getData(), png))
ctx.Error(StdCopyStrBuf("Could not load texture '") + token_name + "'");
CPNGFile png;
if(!ctx.TextureLoader.LoadTexture(token_name.getData(), png))
ctx.Error(StdCopyStrBuf("Could not load texture '") + token_name + "'");
if(png.iWdt != png.iHgt)
ctx.Error(StdCopyStrBuf("Texture '") + token_name + "' is not quadratic");
if(png.iWdt != png.iHgt)
ctx.Error(StdCopyStrBuf("Texture '") + token_name + "' is not quadratic");
Texture = new TexRef(png.iWdt);
Texture = new TexRef(png.iWdt);
Texture->Tex.Lock();
for(unsigned int y = 0; y < png.iHgt; ++y)
for(unsigned int x = 0; x < png.iWdt; ++x)
Texture->Tex.SetPix4(x, y, png.GetPix(x, y));
Texture->Tex.Unlock();
}
else
ctx.ErrorUnexpectedIdentifier(token_name);
}
Texture->Tex.Lock();
for(unsigned int y = 0; y < png.iHgt; ++y)
for(unsigned int x = 0; x < png.iWdt; ++x)
Texture->Tex.SetPix4(x, y, png.GetPix(x, y));
Texture->Tex.Unlock();
}
else
ctx.ErrorUnexpectedIdentifier(token_name);
}
if(token != TOKEN_BRACE_CLOSE)
ctx.Error(StdCopyStrBuf("'") + token_name.getData() + "' unexpected");
if(token != TOKEN_BRACE_CLOSE)
ctx.Error(StdCopyStrBuf("'") + token_name.getData() + "' unexpected");
}
StdMeshMaterialPass::StdMeshMaterialPass()
{
Ambient[0] = Ambient[1] = Ambient[2] = 1.0f; Ambient[3] = 0.0f;
Diffuse[0] = Diffuse[1] = Diffuse[2] = 1.0f; Diffuse[3] = 0.0f;
Specular[0] = Specular[1] = Specular[2] = 0.0f; Specular[3] = 1.0f;
Emissive[0] = Emissive[1] = Emissive[2] = 0.0f; Emissive[3] = 1.0f;
Shininess = 0.0f;
Ambient[0] = Ambient[1] = Ambient[2] = 1.0f; Ambient[3] = 0.0f;
Diffuse[0] = Diffuse[1] = Diffuse[2] = 1.0f; Diffuse[3] = 0.0f;
Specular[0] = Specular[1] = Specular[2] = 0.0f; Specular[3] = 1.0f;
Emissive[0] = Emissive[1] = Emissive[2] = 0.0f; Emissive[3] = 1.0f;
Shininess = 0.0f;
}
void StdMeshMaterialPass::Load(StdMeshMaterialParserCtx& ctx)
{
Token token;
StdCopyStrBuf token_name;
while((token = ctx.AdvanceNonEOF(token_name)) == TOKEN_IDTF)
{
if(token_name == "texture_unit")
{
// TODO: Can there be an optional name?
ctx.AdvanceRequired(token_name, TOKEN_BRACE_OPEN);
TextureUnits.push_back(StdMeshMaterialTextureUnit());
TextureUnits.back().Load(ctx);
}
else if(token_name == "ambient")
{
Ambient[0] = ctx.AdvanceFloat();
Ambient[1] = ctx.AdvanceFloat();
Ambient[2] = ctx.AdvanceFloat();
if(ctx.AdvanceFloatOptional(Ambient[3]))
Ambient[3] = 1 - Ambient[3];
}
else if(token_name == "diffuse")
{
Diffuse[0] = ctx.AdvanceFloat();
Diffuse[1] = ctx.AdvanceFloat();
Diffuse[2] = ctx.AdvanceFloat();
if(ctx.AdvanceFloatOptional(Diffuse[3]))
Diffuse[3] = 1 - Diffuse[3];
}
else if(token_name == "specular")
{
Specular[0] = ctx.AdvanceFloat();
Specular[1] = ctx.AdvanceFloat();
Specular[2] = ctx.AdvanceFloat();
Token token;
StdCopyStrBuf token_name;
while((token = ctx.AdvanceNonEOF(token_name)) == TOKEN_IDTF)
{
if(token_name == "texture_unit")
{
// TODO: Can there be an optional name?
ctx.AdvanceRequired(token_name, TOKEN_BRACE_OPEN);
TextureUnits.push_back(StdMeshMaterialTextureUnit());
TextureUnits.back().Load(ctx);
}
else if(token_name == "ambient")
{
Ambient[0] = ctx.AdvanceFloat();
Ambient[1] = ctx.AdvanceFloat();
Ambient[2] = ctx.AdvanceFloat();
if(ctx.AdvanceFloatOptional(Ambient[3]))
Ambient[3] = 1 - Ambient[3];
}
else if(token_name == "diffuse")
{
Diffuse[0] = ctx.AdvanceFloat();
Diffuse[1] = ctx.AdvanceFloat();
Diffuse[2] = ctx.AdvanceFloat();
if(ctx.AdvanceFloatOptional(Diffuse[3]))
Diffuse[3] = 1 - Diffuse[3];
}
else if(token_name == "specular")
{
Specular[0] = ctx.AdvanceFloat();
Specular[1] = ctx.AdvanceFloat();
Specular[2] = ctx.AdvanceFloat();
// The fourth argument is optional, not the fifth:
float specular3 = ctx.AdvanceFloat();
// The fourth argument is optional, not the fifth:
float specular3 = ctx.AdvanceFloat();
float shininess;
if(ctx.AdvanceFloatOptional(shininess))
{
Specular[3] = 1 - specular3;
Shininess = shininess;
}
else
{
Shininess = specular3;
}
}
else if(token_name == "emissive")
{
Emissive[0] = ctx.AdvanceFloat();
Emissive[1] = ctx.AdvanceFloat();
Emissive[2] = ctx.AdvanceFloat();
if(ctx.AdvanceFloatOptional(Emissive[3]))
Emissive[3] = 1 - Emissive[3];
}
else
ctx.ErrorUnexpectedIdentifier(token_name);
}
float shininess;
if(ctx.AdvanceFloatOptional(shininess))
{
Specular[3] = 1 - specular3;
Shininess = shininess;
}
else
{
Shininess = specular3;
}
}
else if(token_name == "emissive")
{
Emissive[0] = ctx.AdvanceFloat();
Emissive[1] = ctx.AdvanceFloat();
Emissive[2] = ctx.AdvanceFloat();
if(ctx.AdvanceFloatOptional(Emissive[3]))
Emissive[3] = 1 - Emissive[3];
}
else
ctx.ErrorUnexpectedIdentifier(token_name);
}
if(token != TOKEN_BRACE_CLOSE)
ctx.Error(StdCopyStrBuf("'") + token_name.getData() + "' unexpected");
if(token != TOKEN_BRACE_CLOSE)
ctx.Error(StdCopyStrBuf("'") + token_name.getData() + "' unexpected");
}
void StdMeshMaterialTechnique::Load(StdMeshMaterialParserCtx& ctx)
{
Token token;
StdCopyStrBuf token_name;
while((token = ctx.AdvanceNonEOF(token_name)) == TOKEN_IDTF)
{
if(token_name == "pass")
{
// TODO: Can there be an optional name?
ctx.AdvanceRequired(token_name, TOKEN_BRACE_OPEN);
Passes.push_back(StdMeshMaterialPass());
Passes.back().Load(ctx);
}
else
ctx.ErrorUnexpectedIdentifier(token_name);
}
Token token;
StdCopyStrBuf token_name;
while((token = ctx.AdvanceNonEOF(token_name)) == TOKEN_IDTF)
{
if(token_name == "pass")
{
// TODO: Can there be an optional name?
ctx.AdvanceRequired(token_name, TOKEN_BRACE_OPEN);
Passes.push_back(StdMeshMaterialPass());
Passes.back().Load(ctx);
}
else
ctx.ErrorUnexpectedIdentifier(token_name);
}
if(token != TOKEN_BRACE_CLOSE)
ctx.Error(StdCopyStrBuf("'") + token_name.getData() + "' unexpected");
if(token != TOKEN_BRACE_CLOSE)
ctx.Error(StdCopyStrBuf("'") + token_name.getData() + "' unexpected");
}
StdMeshMaterial::StdMeshMaterial():
Line(0), ReceiveShadows(true)
Line(0), ReceiveShadows(true)
{
}
void StdMeshMaterial::Load(StdMeshMaterialParserCtx& ctx)
{
Token token;
StdCopyStrBuf token_name;
while((token = ctx.AdvanceNonEOF(token_name)) == TOKEN_IDTF)
{
if(token_name == "technique")
{
// TODO: Can there be an optional name?
ctx.AdvanceRequired(token_name, TOKEN_BRACE_OPEN);
Techniques.push_back(StdMeshMaterialTechnique());
Techniques.back().Load(ctx);
}
else if(token_name == "receive_shadows")
{
ReceiveShadows = ctx.AdvanceBoolean();
}
else
ctx.ErrorUnexpectedIdentifier(token_name);
}
if(token != TOKEN_BRACE_CLOSE)
ctx.Error(StdCopyStrBuf("'") + token_name.getData() + "' unexpected");
Token token;
StdCopyStrBuf token_name;
while((token = ctx.AdvanceNonEOF(token_name)) == TOKEN_IDTF)
{
if(token_name == "technique")
{
// TODO: Can there be an optional name?
ctx.AdvanceRequired(token_name, TOKEN_BRACE_OPEN);
Techniques.push_back(StdMeshMaterialTechnique());
Techniques.back().Load(ctx);
}
else if(token_name == "receive_shadows")
{
ReceiveShadows = ctx.AdvanceBoolean();
}
else
ctx.ErrorUnexpectedIdentifier(token_name);
}
if(token != TOKEN_BRACE_CLOSE)
ctx.Error(StdCopyStrBuf("'") + token_name.getData() + "' unexpected");
}
void StdMeshMatManager::Clear()
{
Materials.clear();
Materials.clear();
}
void StdMeshMatManager::Parse(const char* mat_script, const char* filename, StdMeshMaterialTextureLoader& tex_loader)
{
StdMeshMaterialParserCtx ctx(mat_script, filename, tex_loader);
StdMeshMaterialParserCtx ctx(mat_script, filename, tex_loader);
Token token;
StdCopyStrBuf token_name;
while((token = ctx.Advance(token_name)) == TOKEN_IDTF)
{
if(token_name == "material")
{
// Read name
StdCopyStrBuf material_name;
ctx.AdvanceRequired(material_name, TOKEN_IDTF);
Token token;
StdCopyStrBuf token_name;
while((token = ctx.Advance(token_name)) == TOKEN_IDTF)
{
if(token_name == "material")
{
// Read name
StdCopyStrBuf material_name;
ctx.AdvanceRequired(material_name, TOKEN_IDTF);
// Check for uniqueness
std::map<StdCopyStrBuf, StdMeshMaterial>::iterator iter = Materials.find(material_name);
if(iter != Materials.end())
ctx.Error(FormatString("Material with name '%s' is already defined in %s:%u", material_name.getData(), iter->second.FileName.getData(), iter->second.Line));
// Check for uniqueness
std::map<StdCopyStrBuf, StdMeshMaterial>::iterator iter = Materials.find(material_name);
if(iter != Materials.end())
ctx.Error(FormatString("Material with name '%s' is already defined in %s:%u", material_name.getData(), iter->second.FileName.getData(), iter->second.Line));
// Check if there is a parent given
Token next = ctx.AdvanceRequired(token_name, TOKEN_BRACE_OPEN, TOKEN_COLON);
// Read parent name, if any
StdMeshMaterial* parent = NULL;
if(next == TOKEN_COLON)
{
// Note that if there is a parent, then it needs to be loaded
// already. This currently makes only sense when its defined above
// in the same material script file or in a parent definition.
// We could later support material scripts in the System.c4g.
StdCopyStrBuf parent_name;
ctx.AdvanceRequired(parent_name, TOKEN_IDTF);
ctx.AdvanceRequired(token_name, TOKEN_BRACE_OPEN);
// Check if there is a parent given
Token next = ctx.AdvanceRequired(token_name, TOKEN_BRACE_OPEN, TOKEN_COLON);
// Read parent name, if any
StdMeshMaterial* parent = NULL;
if(next == TOKEN_COLON)
{
// Note that if there is a parent, then it needs to be loaded
// already. This currently makes only sense when its defined above
// in the same material script file or in a parent definition.
// We could later support material scripts in the System.c4g.
StdCopyStrBuf parent_name;
ctx.AdvanceRequired(parent_name, TOKEN_IDTF);
ctx.AdvanceRequired(token_name, TOKEN_BRACE_OPEN);
iter = Materials.find(parent_name);
if(iter == Materials.end())
ctx.Error(StdCopyStrBuf("Parent material '") + parent_name + "' does not exist (or is not yet loaded)");
parent = &iter->second;
}
iter = Materials.find(parent_name);
if(iter == Materials.end())
ctx.Error(StdCopyStrBuf("Parent material '") + parent_name + "' does not exist (or is not yet loaded)");
parent = &iter->second;
}
// Copy properties from parent if one is given, otherwise
// default-construct the material.
StdMeshMaterial& mat = Materials.insert(std::make_pair(material_name, parent ? StdMeshMaterial(*parent) : StdMeshMaterial())).first->second;
// Set/Overwrite source and name
mat.Name = material_name;
mat.FileName = ctx.FileName;
mat.Line = ctx.Line;
// Copy properties from parent if one is given, otherwise
// default-construct the material.
StdMeshMaterial& mat = Materials.insert(std::make_pair(material_name, parent ? StdMeshMaterial(*parent) : StdMeshMaterial())).first->second;
// Set/Overwrite source and name
mat.Name = material_name;
mat.FileName = ctx.FileName;
mat.Line = ctx.Line;
mat.Load(ctx);
}
else
ctx.ErrorUnexpectedIdentifier(token_name);
}
mat.Load(ctx);
}
else
ctx.ErrorUnexpectedIdentifier(token_name);
}
if(token != TOKEN_EOF)
ctx.Error(StdCopyStrBuf("'") + token_name.getData() + "' unexpected");
if(token != TOKEN_EOF)
ctx.Error(StdCopyStrBuf("'") + token_name.getData() + "' unexpected");
}
const StdMeshMaterial* StdMeshMatManager::GetMaterial(const char* material_name) const
{
std::map<StdCopyStrBuf, StdMeshMaterial>::const_iterator iter = Materials.find(StdCopyStrBuf(material_name));
if(iter == Materials.end()) return NULL;
return &iter->second;
std::map<StdCopyStrBuf, StdMeshMaterial>::const_iterator iter = Materials.find(StdCopyStrBuf(material_name));
if(iter == Materials.end()) return NULL;
return &iter->second;
}
// vim: et ts=2 sw=2