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:
iobyte 2023-04-20 21:41:07 +00:00
parent d3368ab91d
commit ea44a5dfe0
2 changed files with 285 additions and 24 deletions

View file

@ -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);
}

View file

@ -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_ */