trackgen: add Ac3d::flattenGeometry
git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@8889 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: d84a9a2af471f8aa32ef09fa42e999e3243b0e44 Former-commit-id: d83c59db3abe4b8f1a06428a6bf4a6ef973d7a28
This commit is contained in:
parent
d3368ab91d
commit
ea44a5dfe0
2 changed files with 285 additions and 24 deletions
|
@ -87,9 +87,9 @@ Ac3d::Material::Material(std::ifstream &fin, const std::string &name) : name(nam
|
|||
}
|
||||
else if (tokens.at(0) == "emis")
|
||||
{
|
||||
emis[0] = std::stod(tokens.at(1));;
|
||||
emis[1] = std::stod(tokens.at(2));;
|
||||
emis[2] = std::stod(tokens.at(3));;
|
||||
emis[0] = std::stod(tokens.at(1));
|
||||
emis[1] = std::stod(tokens.at(2));
|
||||
emis[2] = std::stod(tokens.at(3));
|
||||
}
|
||||
else if (tokens.at(0) == "spec")
|
||||
{
|
||||
|
@ -141,6 +141,16 @@ void Ac3d::Material::write(std::ofstream &fout, bool versionC) const
|
|||
}
|
||||
}
|
||||
|
||||
bool Ac3d::Material::same(const Material &material) const
|
||||
{
|
||||
return rgb == material.rgb &&
|
||||
amb == material.amb &&
|
||||
emis == material.emis &&
|
||||
spec == material.spec &&
|
||||
shi == material.shi &&
|
||||
trans == material.trans;
|
||||
}
|
||||
|
||||
Ac3d::Surface::Surface(std::ifstream &fin)
|
||||
{
|
||||
std::string line;
|
||||
|
@ -157,7 +167,7 @@ Ac3d::Surface::Surface(std::ifstream &fin)
|
|||
if (tokens.empty())
|
||||
continue;
|
||||
if (tokens.at(0) == "SURF")
|
||||
surf = std::stoi(tokens.at(1));
|
||||
surf = std::stoi(tokens.at(1), nullptr, 16);
|
||||
else if (tokens.at(0) == "mat")
|
||||
mat = std::stoi(tokens.at(1));
|
||||
else if (tokens.at(0) == "refs")
|
||||
|
@ -384,7 +394,7 @@ void Ac3d::Object::write(std::ofstream &fout) const
|
|||
{
|
||||
fout << "numvert " << vertices.size() << std::endl;
|
||||
for (const auto &vertex : vertices)
|
||||
fout << vertex.x << " " << vertex.y << " " << vertex.z << std::endl;
|
||||
fout << vertex[0] << " " << vertex[1] << " " << vertex[2] << std::endl;
|
||||
}
|
||||
if (!surfaces.empty())
|
||||
{
|
||||
|
@ -397,6 +407,192 @@ void Ac3d::Object::write(std::ofstream &fout) const
|
|||
kid.write(fout);
|
||||
}
|
||||
|
||||
void Ac3d::Object::transform(const Matrix &matrix)
|
||||
{
|
||||
Matrix thisMatrix;
|
||||
|
||||
if (loc.initialized)
|
||||
{
|
||||
thisMatrix.setLocation(loc);
|
||||
loc.initialized = false;
|
||||
}
|
||||
loc[0] = 0;
|
||||
loc[1] = 0;
|
||||
loc[2] = 0;
|
||||
|
||||
if (rot.initialized)
|
||||
{
|
||||
thisMatrix.setRotation(rot);
|
||||
rot.initialized = false;
|
||||
}
|
||||
|
||||
rot[0] = 1; rot[1] = 0; rot[2] = 0;
|
||||
rot[3] = 0; rot[4] = 1; rot[5] = 0;
|
||||
rot[6] = 0; rot[7] = 0; rot[8] = 1;
|
||||
|
||||
const Matrix newMatrix = thisMatrix.multiply(matrix);
|
||||
|
||||
if (type == "poly")
|
||||
{
|
||||
for (auto &vertex : vertices)
|
||||
newMatrix.transformPoint(vertex);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto &kid : kids)
|
||||
kid.transform(newMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
Ac3d::Matrix::Matrix()
|
||||
{
|
||||
makeIdentity();
|
||||
}
|
||||
|
||||
Ac3d::Matrix::Matrix(double m0, double m1, double m2, double m3,
|
||||
double m4, double m5, double m6, double m7,
|
||||
double m8, double m9, double m10, double m11,
|
||||
double m12, double m13, double m14, double m15)
|
||||
{
|
||||
(*this)[0][0] = m0; (*this)[0][1] = m1; (*this)[0][2] = m2; (*this)[0][3] = m3;
|
||||
(*this)[1][0] = m4; (*this)[1][1] = m5; (*this)[1][2] = m6; (*this)[1][3] = m7;
|
||||
(*this)[2][0] = m8; (*this)[2][1] = m9; (*this)[2][2] = m10; (*this)[2][3] = m11;
|
||||
(*this)[3][0] = m12; (*this)[3][1] = m13; (*this)[3][2] = m14; (*this)[3][3] = m15;
|
||||
}
|
||||
|
||||
void Ac3d::Matrix::setLocation(const v3 &location)
|
||||
{
|
||||
(*this)[3][0] = location[0];
|
||||
(*this)[3][1] = location[1];
|
||||
(*this)[3][2] = location[2];
|
||||
}
|
||||
|
||||
void Ac3d::Matrix::setLocation(double x, double y, double z)
|
||||
{
|
||||
(*this)[3][0] = x;
|
||||
(*this)[3][1] = y;
|
||||
(*this)[3][2] = z;
|
||||
}
|
||||
|
||||
void Ac3d::Matrix::setRotation(const std::array<double, 9> &rotation)
|
||||
{
|
||||
(*this)[0][0] = rotation[0]; (*this)[0][1] = rotation[1]; (*this)[0][2] = rotation[2];
|
||||
(*this)[1][0] = rotation[3]; (*this)[1][1] = rotation[4]; (*this)[1][2] = rotation[5];
|
||||
(*this)[2][0] = rotation[6]; (*this)[2][1] = rotation[7]; (*this)[2][2] = rotation[8];
|
||||
}
|
||||
|
||||
void Ac3d::Matrix::setScale(double scale)
|
||||
{
|
||||
(*this)[0][0] = scale;
|
||||
(*this)[1][1] = scale;
|
||||
(*this)[2][2] = scale;
|
||||
(*this)[3][2] = 1;
|
||||
}
|
||||
|
||||
void Ac3d::Matrix::makeIdentity()
|
||||
{
|
||||
(*this)[0][0] = 1; (*this)[0][1] = 0; (*this)[0][2] = 0; (*this)[0][3] = 0;
|
||||
(*this)[1][0] = 0; (*this)[1][1] = 1; (*this)[1][2] = 0; (*this)[1][3] = 0;
|
||||
(*this)[2][0] = 0; (*this)[2][1] = 0; (*this)[2][2] = 1; (*this)[2][3] = 0;
|
||||
(*this)[3][0] = 0; (*this)[3][1] = 0; (*this)[3][2] = 0; (*this)[3][3] = 1;
|
||||
}
|
||||
|
||||
void Ac3d::Matrix::makeLocation(const v3 &location)
|
||||
{
|
||||
(*this)[0][0] = 1; (*this)[0][1] = 0; (*this)[0][2] = 0; (*this)[0][3] = 0;
|
||||
(*this)[1][0] = 0; (*this)[1][1] = 1; (*this)[1][2] = 0; (*this)[1][3] = 0;
|
||||
(*this)[2][0] = 0; (*this)[2][1] = 0; (*this)[2][2] = 1; (*this)[2][3] = 0;
|
||||
(*this)[3][0] = location[0];
|
||||
(*this)[3][1] = location[1];
|
||||
(*this)[3][2] = location[2];
|
||||
(*this)[3][3] = 1;
|
||||
}
|
||||
|
||||
void Ac3d::Matrix::makeLocation(double x, double y, double z)
|
||||
{
|
||||
(*this)[0][0] = 1; (*this)[0][1] = 0; (*this)[0][2] = 0; (*this)[0][3] = 0;
|
||||
(*this)[1][0] = 0; (*this)[1][1] = 1; (*this)[1][2] = 0; (*this)[1][3] = 0;
|
||||
(*this)[2][0] = 0; (*this)[2][1] = 0; (*this)[2][2] = 1; (*this)[2][3] = 0;
|
||||
(*this)[3][0] = x; (*this)[3][1] = y; (*this)[3][2] = z; (*this)[3][3] = 1;
|
||||
}
|
||||
|
||||
void Ac3d::Matrix::makeRotation(const std::array<double, 9> &rotation)
|
||||
{
|
||||
(*this)[0][0] = rotation[0]; (*this)[0][1] = rotation[1]; (*this)[0][2] = rotation[2]; (*this)[0][3] = 0;
|
||||
(*this)[1][0] = rotation[3]; (*this)[1][1] = rotation[4]; (*this)[1][2] = rotation[5]; (*this)[1][3] = 0;
|
||||
(*this)[2][0] = rotation[6]; (*this)[2][1] = rotation[7]; (*this)[2][2] = rotation[8]; (*this)[2][3] = 0;
|
||||
(*this)[3][0] = 0; (*this)[3][1] = 0; (*this)[3][2] = 0; (*this)[3][3] = 1;
|
||||
|
||||
}
|
||||
|
||||
void Ac3d::Matrix::makeScale(double scale)
|
||||
{
|
||||
(*this)[0][0] = scale; (*this)[0][1] = 0; (*this)[0][2] = 0; (*this)[0][3] = 0;
|
||||
(*this)[1][0] = 0; (*this)[1][1] = scale; (*this)[1][2] = 0; (*this)[1][3] = 0;
|
||||
(*this)[2][0] = 0; (*this)[2][1] = 0; (*this)[2][2] = scale; (*this)[2][3] = 0;
|
||||
(*this)[3][0] = 0; (*this)[3][1] = 0; (*this)[3][2] = 0; (*this)[3][3] = 1;
|
||||
}
|
||||
|
||||
void Ac3d::Matrix::transformPoint(v3d &point) const
|
||||
{
|
||||
v3d dst;
|
||||
|
||||
const double t0 = point[0];
|
||||
const double t1 = point[1];
|
||||
const double t2 = point[2];
|
||||
|
||||
dst[0] = t0 * (*this)[0][0] + t1 * (*this)[1][0] + t2 * (*this)[2][0] + (*this)[3][0];
|
||||
dst[1] = t0 * (*this)[0][1] + t1 * (*this)[1][1] + t2 * (*this)[2][1] + (*this)[3][1];
|
||||
dst[2] = t0 * (*this)[0][2] + t1 * (*this)[1][2] + t2 * (*this)[2][2] + (*this)[3][2];
|
||||
|
||||
point = dst;
|
||||
}
|
||||
|
||||
void Ac3d::Matrix::transformNormal(v3d &normal) const
|
||||
{
|
||||
v3d dst;
|
||||
|
||||
const double t0 = normal[0];
|
||||
const double t1 = normal[1];
|
||||
const double t2 = normal[2];
|
||||
|
||||
dst[0] = t0 * (*this)[0][0] + t1 * (*this)[1][0] + t2 * (*this)[2][0];
|
||||
dst[1] = t0 * (*this)[0][1] + t1 * (*this)[1][1] + t2 * (*this)[2][1];
|
||||
dst[2] = t0 * (*this)[0][2] + t1 * (*this)[1][2] + t2 * (*this)[2][2];
|
||||
|
||||
normal = dst;
|
||||
}
|
||||
|
||||
Ac3d::Matrix Ac3d::Matrix::multiply(const Matrix &matrix)
|
||||
{
|
||||
Matrix result;
|
||||
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
result[0][j] = matrix[0][0] * (*this)[0][j] +
|
||||
matrix[0][1] * (*this)[1][j] +
|
||||
matrix[0][2] * (*this)[2][j] +
|
||||
matrix[0][3] * (*this)[3][j];
|
||||
|
||||
result[1][j] = matrix[1][0] * (*this)[0][j] +
|
||||
matrix[1][1] * (*this)[1][j] +
|
||||
matrix[1][2] * (*this)[2][j] +
|
||||
matrix[1][3] * (*this)[3][j];
|
||||
|
||||
result[2][j] = matrix[2][0] * (*this)[0][j] +
|
||||
matrix[2][1] * (*this)[1][j] +
|
||||
matrix[2][2] * (*this)[2][j] +
|
||||
matrix[2][3] * (*this)[3][j];
|
||||
|
||||
result[3][j] = matrix[3][0] * (*this)[0][j] +
|
||||
matrix[3][1] * (*this)[1][j] +
|
||||
matrix[3][2] * (*this)[2][j] +
|
||||
matrix[3][3] * (*this)[3][j];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Ac3d::Ac3d()
|
||||
{
|
||||
root.type = "world";
|
||||
|
@ -414,10 +610,10 @@ void Ac3d::addDefaultMaterial()
|
|||
Ac3d::Material mat;
|
||||
|
||||
mat.name = "\"\"";
|
||||
mat.rgb = { 0.4, 0.4, 0.4 };
|
||||
mat.amb = { 0.8, 0.8, 0.8 };
|
||||
mat.emis = { 0.4, 0.4, 0.4 };
|
||||
mat.spec = { 0.5, 0.5, 0.5 };
|
||||
mat.rgb.set(0.4, 0.4, 0.4);
|
||||
mat.amb.set(0.8, 0.8, 0.8);
|
||||
mat.emis.set(0.4, 0.4, 0.4);
|
||||
mat.spec.set(0.5, 0.5, 0.5);
|
||||
mat.shi = 50;
|
||||
mat.trans = 0;
|
||||
|
||||
|
@ -488,3 +684,15 @@ void Ac3d::writeFile(const std::string &fileName) const
|
|||
|
||||
root.write(fout);
|
||||
}
|
||||
|
||||
void Ac3d::transform(const Matrix &matrix)
|
||||
{
|
||||
root.transform(matrix);
|
||||
}
|
||||
|
||||
void Ac3d::flattenGeometry()
|
||||
{
|
||||
const Matrix matrix;
|
||||
|
||||
transform(matrix);
|
||||
}
|
||||
|
|
|
@ -30,14 +30,42 @@
|
|||
#include <stack>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <fstream>
|
||||
#include <v3_t.h>
|
||||
|
||||
typedef v3t<double> v3d;
|
||||
|
||||
struct Ac3d
|
||||
{
|
||||
typedef std::array<double, 3> Color;
|
||||
struct v3d : public std::array<double, 3>
|
||||
{
|
||||
v3d()
|
||||
{
|
||||
at(0) = 0;
|
||||
at(1) = 0;
|
||||
at(2) = 0;
|
||||
}
|
||||
v3d(double x, double y, double z)
|
||||
{
|
||||
at(0) = x;
|
||||
at(1) = y;
|
||||
at(2) = z;
|
||||
}
|
||||
};
|
||||
|
||||
struct Color : public std::array<double, 3>
|
||||
{
|
||||
Color()
|
||||
{
|
||||
at(0) = 0;
|
||||
at(1) = 0;
|
||||
at(2) = 0;
|
||||
}
|
||||
void set(double r, double g, double b)
|
||||
{
|
||||
at(0) = r;
|
||||
at(1) = g;
|
||||
at(2) = b;
|
||||
}
|
||||
};
|
||||
|
||||
class Exception : public std::exception
|
||||
{
|
||||
|
@ -45,7 +73,7 @@ struct Ac3d
|
|||
const char *message;
|
||||
|
||||
public:
|
||||
Exception(const char *msg) : message(msg)
|
||||
explicit Exception(const char *msg) : message(msg)
|
||||
{
|
||||
}
|
||||
const char *what()
|
||||
|
@ -61,23 +89,23 @@ struct Ac3d
|
|||
Color amb;
|
||||
Color emis;
|
||||
Color spec;
|
||||
int shi;
|
||||
double trans;
|
||||
int shi = 0;
|
||||
double trans = 0;
|
||||
std::string data;
|
||||
|
||||
Material() = default;
|
||||
|
||||
Material(const std::vector<std::string> &tokens);
|
||||
explicit Material(const std::vector<std::string> &tokens);
|
||||
Material(std::ifstream &fin, const std::string &name);
|
||||
void write(std::ofstream &fout, bool versionC) const;
|
||||
bool same(const Material &material) const;
|
||||
};
|
||||
|
||||
struct Surface
|
||||
{
|
||||
struct Ref
|
||||
{
|
||||
int index;
|
||||
std::array<double,2> coord;
|
||||
int index = 0;
|
||||
std::array<double, 2> coord{ 0, 0 };
|
||||
|
||||
Ref() = default;
|
||||
Ref(int index, double u, double v) : index(index), coord{ u, v } { }
|
||||
|
@ -88,7 +116,7 @@ struct Ac3d
|
|||
std::vector<Ref> refs;
|
||||
|
||||
Surface() = default;
|
||||
Surface(std::ifstream &fin);
|
||||
explicit Surface(std::ifstream &fin);
|
||||
void write(std::ofstream &fout) const;
|
||||
};
|
||||
|
||||
|
@ -97,7 +125,7 @@ struct Ac3d
|
|||
public:
|
||||
bool initialized = false;
|
||||
};
|
||||
class v3 : public std::array<double, 3>
|
||||
class v3 : public v3d
|
||||
{
|
||||
public:
|
||||
bool initialized = false;
|
||||
|
@ -116,6 +144,28 @@ struct Ac3d
|
|||
T operator = (T i) { value = i; return value; }
|
||||
};
|
||||
|
||||
class Matrix : public std::array<std::array<double, 4>, 4>
|
||||
{
|
||||
public:
|
||||
Matrix();
|
||||
Matrix(double m0, double m1, double m2, double m3,
|
||||
double m4, double m5, double m6, double m7,
|
||||
double m8, double m9, double m10, double m11,
|
||||
double m12, double m13, double m14, double m15);
|
||||
void setLocation(const v3 &location);
|
||||
void setLocation(double x, double y, double z);
|
||||
void setRotation(const std::array<double, 9> &rotation);
|
||||
void setScale(double scale);
|
||||
void makeIdentity();
|
||||
void makeLocation(const v3 &location);
|
||||
void makeLocation(double x, double y, double z);
|
||||
void makeRotation(const std::array<double, 9> &rotation);
|
||||
void makeScale(double scale);
|
||||
void transformPoint(v3d &point) const;
|
||||
void transformNormal(v3d &normal) const;
|
||||
Matrix multiply(const Matrix &matrix);
|
||||
};
|
||||
|
||||
struct Object
|
||||
{
|
||||
std::string type;
|
||||
|
@ -134,7 +184,7 @@ struct Ac3d
|
|||
bool folded = false;
|
||||
std::vector<v3d> vertices;
|
||||
std::vector<Surface> surfaces;
|
||||
std::vector<Object> kids;
|
||||
std::list<Object> kids;
|
||||
|
||||
Object() = default;
|
||||
|
||||
|
@ -142,9 +192,10 @@ struct Ac3d
|
|||
{
|
||||
}
|
||||
|
||||
Object(std::ifstream &fin);
|
||||
explicit Object(std::ifstream &fin);
|
||||
void parse(std::ifstream &fin, const std::string &objType);
|
||||
void write(std::ofstream &fout) const;
|
||||
void transform(const Matrix &matrix);
|
||||
};
|
||||
|
||||
bool versionC = false;
|
||||
|
@ -157,6 +208,8 @@ struct Ac3d
|
|||
void addDefaultMaterial();
|
||||
void readFile(const std::string &fileName);
|
||||
void writeFile(const std::string &fileName) const;
|
||||
void flattenGeometry();
|
||||
void transform(const Matrix &matrix);
|
||||
};
|
||||
|
||||
#endif /* _AC3D_H_ */
|
||||
|
|
Loading…
Reference in a new issue