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));
refs[i].index = std::stoi(tokens.at(0));
refs[i].coord[0] = std::stod(tokens.at(1));
refs[i].coord[1] = std::stod(tokens.at(2));
refs[i].coords[0][0] = std::stod(tokens.at(1));
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++;
}
break;
@ -239,7 +260,26 @@ void Ac3d::Surface::write(std::ofstream &fout) const
fout << "mat " << mat << std::endl;
fout << "refs " << refs.size() << std::endl;
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 ------------------------------------
@ -540,7 +580,7 @@ Ac3d::Object::Object(std::ifstream &fin)
parse(fin, tokens.at(1));
return;
}
throw Exception("Invalid AC3D file");
}
}
@ -574,7 +614,15 @@ void Ac3d::Object::parse(std::ifstream &fin, const std::string &objType)
}
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")
{
@ -632,6 +680,10 @@ void Ac3d::Object::parse(std::ifstream &fin, const std::string &objType)
tokenizeLine(line, tokens);
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++;
}
}
@ -645,7 +697,21 @@ void Ac3d::Object::parse(std::ifstream &fin, const std::string &objType)
{
const int numKids = std::stoi(tokens.at(1));
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);
}
return;
}
}
@ -663,9 +729,19 @@ void Ac3d::Object::write(std::ofstream &fout, bool all) const
fout << "data " << data.length() << 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)
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())
{
fout << "numvert " << vertices.size() << std::endl;
for (const auto &vertex : vertices)
fout << vertex[0] << " " << vertex[1] << " " << vertex[2] << std::endl;
for (size_t i = 0; i < vertices.size(); i++)
{
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())
{

View file

@ -37,6 +37,20 @@
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>
{
V3d()
@ -113,34 +127,40 @@ struct Ac3d
{
struct Ref
{
int index = 0;
std::array<double, 2> coord{ 0, 0 };
int index = 0;
int count = 1;
std::array<V2d, 4> coords;
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 {
Polygon = 0x00,
ClosedLine = 0x01,
OpenLine = 0x02,
TypeMask = 0x0f,
SingleSided = 0x00,
DoubleSided = 0x20,
Flat = 0x00,
Smooth = 0x10,
PolygonSingleSidedFlat = Polygon | SingleSided | Flat, // 0x00
ClosedLineSingleSidedFlat = ClosedLine | SingleSided | Flat, // 0x01
OpenLineSingleSidedFlat = OpenLine | SingleSided | Flat, // 0x02
PolygonSingleSidedSmooth = Polygon | SingleSided | Smooth, // 0x10
ClosedLineSingleSidedSmooth = ClosedLine | SingleSided | Smooth, // 0x11
OpenLineSingleSidedSmooth = OpenLine | SingleSided | Smooth, // 0x12
PolygonDoubleSidedFlat = Polygon | DoubleSided | Flat, // 0x20
ClosedLineDoubleSidedFlat = ClosedLine | DoubleSided | Flat, // 0x21
OpenLineDoubleSidedFlat = OpenLine | DoubleSided | Flat, // 0x22
PolygonDoubleSidedSmooth = Polygon | DoubleSided | Smooth, // 0x30
ClosedLineDoubleSidedSmooth = ClosedLine | DoubleSided | Smooth, // 0x31
OpenLineDoubleSidedSmooth = OpenLine | DoubleSided | Smooth, // 0x32
Polygon = 0x00,
ClosedLine = 0x01,
OpenLine = 0x02,
TriangleStrip = 0x04,
TypeMask = 0x0f,
SingleSided = 0x00,
DoubleSided = 0x20,
Flat = 0x00,
Smooth = 0x10,
PolygonSingleSidedFlat = Polygon | SingleSided | Flat, // 0x00
ClosedLineSingleSidedFlat = ClosedLine | SingleSided | Flat, // 0x01
OpenLineSingleSidedFlat = OpenLine | SingleSided | Flat, // 0x02
TriangleStripSingleSidedFlat = TriangleStrip | SingleSided | Flat, // 0x04
PolygonSingleSidedSmooth = Polygon | SingleSided | Smooth, // 0x10
ClosedLineSingleSidedSmooth = ClosedLine | SingleSided | Smooth, // 0x11
OpenLineSingleSidedSmooth = OpenLine | SingleSided | Smooth, // 0x12
TriangleStripSingleSidedSmooth = TriangleStrip | SingleSided | Smooth, // 0x14
PolygonDoubleSidedFlat = Polygon | DoubleSided | Flat, // 0x20
ClosedLineDoubleSidedFlat = ClosedLine | DoubleSided | Flat, // 0x21
OpenLineDoubleSidedFlat = OpenLine | DoubleSided | Flat, // 0x22
TriangleStripDoubleSidedFlat = TriangleStrip | DoubleSided | Flat, // 0x24
PolygonDoubleSidedSmooth = Polygon | DoubleSided | Smooth, // 0x30
ClosedLineDoubleSidedSmooth = ClosedLine | DoubleSided | Smooth, // 0x31
OpenLineDoubleSidedSmooth = OpenLine | DoubleSided | Smooth, // 0x32
TriangleStripDoubleSidedSmooth = TriangleStrip | DoubleSided | Smooth, // 0x34
};
SURF surf = PolygonSingleSidedFlat;
int mat = 0;
@ -231,29 +251,30 @@ struct Ac3d
struct Object
{
std::string type;
std::string name;
std::string data;
std::string texture;
v2 texrep;
v2 texoff;
Value<int> subdiv;
Value<double> crease;
v9 rot;
v3 loc;
std::string url;
bool hidden = false;
bool locked = false;
bool folded = false;
std::vector<V3d> vertices;
std::list<Surface> surfaces;
std::list<Object> kids;
std::string type;
std::string name;
std::string data;
std::vector<std::string> textures;
v2 texrep;
v2 texoff;
Value<int> subdiv;
Value<double> crease;
v9 rot;
v3 loc;
std::string url;
bool hidden = false;
bool locked = false;
bool folded = false;
std::vector<V3d> vertices;
std::vector<V3d> normals;
std::list<Surface> surfaces;
std::list<Object> kids;
// not part of AC3D file
mutable bool hasBoundingBox = false;
mutable BoundingBox boundingBox;
mutable bool hasBoundingSphere = false;
mutable BoundingSphere boundingSphere;
mutable bool hasBoundingBox = false;
mutable BoundingBox boundingBox;
mutable bool hasBoundingSphere = false;
mutable BoundingSphere boundingSphere;
Object() = default;
Object(const std::string &type, const std::string &name) : type(type), name(name) { }

View file

@ -1843,12 +1843,12 @@ static void insert_elem_in_group(struct ele *el, struct nod *nods)
surf.surf = Ac3d::Surface::PolygonSingleSidedSmooth;
surf.refs.resize(3);
surf.refs[0].coord[0] = nods[el->i].x / TexSize;
surf.refs[0].coord[1] = nods[el->i].y / TexSize;
surf.refs[1].coord[0] = nods[el->j].x / TexSize;
surf.refs[1].coord[1] = nods[el->j].y / TexSize;
surf.refs[2].coord[0] = nods[el->k].x / TexSize;
surf.refs[2].coord[1] = nods[el->k].y / TexSize;
surf.refs[0].coords[0][0] = nods[el->i].x / TexSize;
surf.refs[0].coords[0][1] = nods[el->i].y / TexSize;
surf.refs[1].coords[0][0] = nods[el->j].x / TexSize;
surf.refs[1].coords[0][1] = nods[el->j].y / TexSize;
surf.refs[2].coords[0][0] = nods[el->k].x / 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[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.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.stack.pop();

View file

@ -98,7 +98,7 @@ public:
//! Constructor.
Application::Application()
: GfApplication("TrackGen", "1.6.0.21", "Terrain generator for tracks")
: GfApplication("TrackGen", "1.6.0.22", "Terrain generator for tracks")
, HeightSteps(30)
, Bump(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;
object.type = "poly";
object.name = name;
object.texture = texture;
object.textures.emplace_back(texture);
for (int i = 0; i < nb; i++)
{