trackgen: read/write acc files (not used yet)

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@9043 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: 3599d01478799579769351527057fa91cba8c946
Former-commit-id: 5eb96556b3f8280e0f2185ab10846918ae05411d
This commit is contained in:
iobyte 2023-06-25 16:55:17 +00:00
parent 92fc95facc
commit debccce304
5 changed files with 167 additions and 62 deletions

View file

@ -222,8 +222,29 @@ Ac3d::Surface::Surface(std::ifstream &fin)
std::back_inserter(tokens)); std::back_inserter(tokens));
refs[i].index = std::stoi(tokens.at(0)); refs[i].index = std::stoi(tokens.at(0));
refs[i].coord[0] = std::stod(tokens.at(1)); refs[i].coords[0][0] = std::stod(tokens.at(1));
refs[i].coord[1] = std::stod(tokens.at(2)); refs[i].coords[0][1] = std::stod(tokens.at(2));
if (tokens.size() >= 5)
{
refs[i].count = 2;
refs[i].coords[1][0] = std::stod(tokens.at(3));
refs[i].coords[1][1] = std::stod(tokens.at(4));
if (tokens.size() >= 7)
{
refs[i].count = 3;
refs[i].coords[2][0] = std::stod(tokens.at(5));
refs[i].coords[2][1] = std::stod(tokens.at(6));
if (tokens.size() >= 9)
{
refs[i].count = 4;
refs[i].coords[3][0] = std::stod(tokens.at(7));
refs[i].coords[3][1] = std::stod(tokens.at(8));
}
}
}
i++; i++;
} }
break; break;
@ -239,7 +260,26 @@ void Ac3d::Surface::write(std::ofstream &fout) const
fout << "mat " << mat << std::endl; fout << "mat " << mat << std::endl;
fout << "refs " << refs.size() << std::endl; fout << "refs " << refs.size() << std::endl;
for (const auto &ref : refs) for (const auto &ref : refs)
fout << ref.index << " " << ref.coord[0] << " " << ref.coord[1] << std::endl; {
fout << ref.index << " " << ref.coords[0][0] << " " << ref.coords[0][1];
if (ref.count >= 2)
{
fout << " " << ref.coords[1][0] << " " << ref.coords[1][1];
if (ref.count >= 3)
{
fout << " " << ref.coords[2][0] << " " << ref.coords[2][1];
if (ref.count == 4)
{
fout << " " << ref.coords[3][0] << " " << ref.coords[3][1];
}
}
}
fout << std::endl;
}
} }
//--------------------------------- Matrix ------------------------------------ //--------------------------------- Matrix ------------------------------------
@ -574,7 +614,15 @@ void Ac3d::Object::parse(std::ifstream &fin, const std::string &objType)
} }
else if (tokens.at(0) == "texture") else if (tokens.at(0) == "texture")
{ {
texture = tokens.at(1); if (tokens.size() == 2)
{
if (textures.size() == 0)
textures.push_back(tokens.at(1));
else
textures[0] = tokens.at(1);
}
else
textures.push_back(tokens.at(1));
} }
else if (tokens.at(0) == "texrep") else if (tokens.at(0) == "texrep")
{ {
@ -632,6 +680,10 @@ void Ac3d::Object::parse(std::ifstream &fin, const std::string &objType)
tokenizeLine(line, tokens); tokenizeLine(line, tokens);
vertices.emplace_back(std::stod(tokens.at(0)), std::stod(tokens.at(1)), std::stod(tokens.at(2))); vertices.emplace_back(std::stod(tokens.at(0)), std::stod(tokens.at(1)), std::stod(tokens.at(2)));
if (tokens.size() == 6)
normals.emplace_back(std::stod(tokens.at(3)), std::stod(tokens.at(4)), std::stod(tokens.at(5)));
i++; i++;
} }
} }
@ -645,7 +697,21 @@ void Ac3d::Object::parse(std::ifstream &fin, const std::string &objType)
{ {
const int numKids = std::stoi(tokens.at(1)); const int numKids = std::stoi(tokens.at(1));
for (int i = 0; i < numKids; i++) for (int i = 0; i < numKids; i++)
{
std::streambuf::pos_type len = fin.tellg();
std::string peekLine;
std::getline(fin, peekLine);
std::vector<std::string> peekTokens;
tokenizeLine(peekLine, peekTokens);
fin.seekg(len, std::ios_base::beg);
if (peekTokens.size() < 1 || peekTokens[0] != "OBJECT")
{
// this is a common problem with accc generated files so ignore it
// throw Exception("Invalid AC3D file: wrong number of kids");
return;
}
kids.emplace_back(fin); kids.emplace_back(fin);
}
return; return;
} }
} }
@ -663,9 +729,19 @@ void Ac3d::Object::write(std::ofstream &fout, bool all) const
fout << "data " << data.length() << std::endl; fout << "data " << data.length() << std::endl;
fout << data << std::endl; fout << data << std::endl;
} }
if (!texture.empty()) for (size_t i = 0; i < std::min(textures.size(), size_t(4)); i++)
{ {
fout << "texture \"" << texture << "\"" << std::endl; if (textures.size() == 1)
fout << "texture \"" << textures[0] << "\"" << std::endl;
else
{
const std::string types[4] = { "base", "tiled", "skids", "shad" };
if (textures[i] == "empty_texture_no_mapping")
fout << "texture " << textures[i] << " " << types[i] << std::endl;
else
fout << "texture \"" << textures[i] << "\" " << types[i] << std::endl;
}
} }
if (texrep.initialized) if (texrep.initialized)
fout << "texrep " << texrep[0] << " " << texrep[1] << std::endl; fout << "texrep " << texrep[0] << " " << texrep[1] << std::endl;
@ -697,8 +773,13 @@ void Ac3d::Object::write(std::ofstream &fout, bool all) const
if (!vertices.empty()) if (!vertices.empty())
{ {
fout << "numvert " << vertices.size() << std::endl; fout << "numvert " << vertices.size() << std::endl;
for (const auto &vertex : vertices) for (size_t i = 0; i < vertices.size(); i++)
fout << vertex[0] << " " << vertex[1] << " " << vertex[2] << std::endl; {
fout << vertices[i][0] << " " << vertices[i][1] << " " << vertices[i][2];
if (normals.size() == vertices.size())
fout << " " << normals[i][0] << " " << normals[i][1] << " " << normals[i][2];
fout << std::endl;
}
} }
if (!surfaces.empty()) if (!surfaces.empty())
{ {

View file

@ -37,6 +37,20 @@
struct Ac3d struct Ac3d
{ {
struct V2d : public std::array<double, 2>
{
V2d()
{
at(0) = 0;
at(1) = 0;
}
V2d(double x, double y)
{
at(0) = x;
at(1) = y;
}
};
struct V3d : public std::array<double, 3> struct V3d : public std::array<double, 3>
{ {
V3d() V3d()
@ -114,16 +128,18 @@ struct Ac3d
struct Ref struct Ref
{ {
int index = 0; int index = 0;
std::array<double, 2> coord{ 0, 0 }; int count = 1;
std::array<V2d, 4> coords;
Ref() = default; Ref() = default;
Ref(int index, double u, double v) : index(index), coord{ u, v } { } Ref(int index, double u, double v) : index(index) { coords[0] = { u, v }; }
}; };
enum SURF : int { enum SURF : int {
Polygon = 0x00, Polygon = 0x00,
ClosedLine = 0x01, ClosedLine = 0x01,
OpenLine = 0x02, OpenLine = 0x02,
TriangleStrip = 0x04,
TypeMask = 0x0f, TypeMask = 0x0f,
SingleSided = 0x00, SingleSided = 0x00,
DoubleSided = 0x20, DoubleSided = 0x20,
@ -132,15 +148,19 @@ struct Ac3d
PolygonSingleSidedFlat = Polygon | SingleSided | Flat, // 0x00 PolygonSingleSidedFlat = Polygon | SingleSided | Flat, // 0x00
ClosedLineSingleSidedFlat = ClosedLine | SingleSided | Flat, // 0x01 ClosedLineSingleSidedFlat = ClosedLine | SingleSided | Flat, // 0x01
OpenLineSingleSidedFlat = OpenLine | SingleSided | Flat, // 0x02 OpenLineSingleSidedFlat = OpenLine | SingleSided | Flat, // 0x02
TriangleStripSingleSidedFlat = TriangleStrip | SingleSided | Flat, // 0x04
PolygonSingleSidedSmooth = Polygon | SingleSided | Smooth, // 0x10 PolygonSingleSidedSmooth = Polygon | SingleSided | Smooth, // 0x10
ClosedLineSingleSidedSmooth = ClosedLine | SingleSided | Smooth, // 0x11 ClosedLineSingleSidedSmooth = ClosedLine | SingleSided | Smooth, // 0x11
OpenLineSingleSidedSmooth = OpenLine | SingleSided | Smooth, // 0x12 OpenLineSingleSidedSmooth = OpenLine | SingleSided | Smooth, // 0x12
TriangleStripSingleSidedSmooth = TriangleStrip | SingleSided | Smooth, // 0x14
PolygonDoubleSidedFlat = Polygon | DoubleSided | Flat, // 0x20 PolygonDoubleSidedFlat = Polygon | DoubleSided | Flat, // 0x20
ClosedLineDoubleSidedFlat = ClosedLine | DoubleSided | Flat, // 0x21 ClosedLineDoubleSidedFlat = ClosedLine | DoubleSided | Flat, // 0x21
OpenLineDoubleSidedFlat = OpenLine | DoubleSided | Flat, // 0x22 OpenLineDoubleSidedFlat = OpenLine | DoubleSided | Flat, // 0x22
TriangleStripDoubleSidedFlat = TriangleStrip | DoubleSided | Flat, // 0x24
PolygonDoubleSidedSmooth = Polygon | DoubleSided | Smooth, // 0x30 PolygonDoubleSidedSmooth = Polygon | DoubleSided | Smooth, // 0x30
ClosedLineDoubleSidedSmooth = ClosedLine | DoubleSided | Smooth, // 0x31 ClosedLineDoubleSidedSmooth = ClosedLine | DoubleSided | Smooth, // 0x31
OpenLineDoubleSidedSmooth = OpenLine | DoubleSided | Smooth, // 0x32 OpenLineDoubleSidedSmooth = OpenLine | DoubleSided | Smooth, // 0x32
TriangleStripDoubleSidedSmooth = TriangleStrip | DoubleSided | Smooth, // 0x34
}; };
SURF surf = PolygonSingleSidedFlat; SURF surf = PolygonSingleSidedFlat;
int mat = 0; int mat = 0;
@ -234,7 +254,7 @@ struct Ac3d
std::string type; std::string type;
std::string name; std::string name;
std::string data; std::string data;
std::string texture; std::vector<std::string> textures;
v2 texrep; v2 texrep;
v2 texoff; v2 texoff;
Value<int> subdiv; Value<int> subdiv;
@ -246,6 +266,7 @@ struct Ac3d
bool locked = false; bool locked = false;
bool folded = false; bool folded = false;
std::vector<V3d> vertices; std::vector<V3d> vertices;
std::vector<V3d> normals;
std::list<Surface> surfaces; std::list<Surface> surfaces;
std::list<Object> kids; std::list<Object> kids;

View file

@ -1843,12 +1843,12 @@ static void insert_elem_in_group(struct ele *el, struct nod *nods)
surf.surf = Ac3d::Surface::PolygonSingleSidedSmooth; surf.surf = Ac3d::Surface::PolygonSingleSidedSmooth;
surf.refs.resize(3); surf.refs.resize(3);
surf.refs[0].coord[0] = nods[el->i].x / TexSize; surf.refs[0].coords[0][0] = nods[el->i].x / TexSize;
surf.refs[0].coord[1] = nods[el->i].y / TexSize; surf.refs[0].coords[0][1] = nods[el->i].y / TexSize;
surf.refs[1].coord[0] = nods[el->j].x / TexSize; surf.refs[1].coords[0][0] = nods[el->j].x / TexSize;
surf.refs[1].coord[1] = nods[el->j].y / TexSize; surf.refs[1].coords[0][1] = nods[el->j].y / TexSize;
surf.refs[2].coord[0] = nods[el->k].x / TexSize; surf.refs[2].coords[0][0] = nods[el->k].x / TexSize;
surf.refs[2].coord[1] = nods[el->k].y / TexSize; surf.refs[2].coords[0][1] = nods[el->k].y / TexSize;
surf.refs[0].index = insert_node_in_group(&(nods[el->i]), curGrp); surf.refs[0].index = insert_node_in_group(&(nods[el->i]), curGrp);
surf.refs[1].index = insert_node_in_group(&(nods[el->j]), curGrp); surf.refs[1].index = insert_node_in_group(&(nods[el->j]), curGrp);
@ -1980,7 +1980,10 @@ static void draw_ac(Ac3d &ac3d, const char *name)
curGrp.type = "poly"; curGrp.type = "poly";
curGrp.name = std::string(name) + std::to_string(i); curGrp.name = std::string(name) + std::to_string(i);
curGrp.texture = TexName; if (curGrp.textures.empty())
curGrp.textures.emplace_back(TexName);
else
curGrp.textures[0] = TexName;
ac3d.addObject(curGrp); ac3d.addObject(curGrp);
ac3d.stack.pop(); ac3d.stack.pop();

View file

@ -98,7 +98,7 @@ public:
//! Constructor. //! Constructor.
Application::Application() Application::Application()
: GfApplication("TrackGen", "1.6.0.21", "Terrain generator for tracks") : GfApplication("TrackGen", "1.6.0.22", "Terrain generator for tracks")
, HeightSteps(30) , HeightSteps(30)
, Bump(false) , Bump(false)
, Raceline(false) , Raceline(false)

View file

@ -3079,7 +3079,7 @@ static void saveObject(Ac3d &ac3d, int nb, int start, char *texture, char *name,
Ac3d::Object object; Ac3d::Object object;
object.type = "poly"; object.type = "poly";
object.name = name; object.name = name;
object.texture = texture; object.textures.emplace_back(texture);
for (int i = 0; i < nb; i++) for (int i = 0; i < nb; i++)
{ {