+void Part::Read(TokenStreamReader &in, ResourceIndex &tex_index, const ShapeRegistry &shapes) {
+ std::string name;
+ std::string shape_name;
+ std::string tex_name;
+ glm::vec3 color_conv;
+ in.Skip(Token::ANGLE_BRACKET_OPEN);
+ while (in.HasMore() && in.Peek().type != Token::ANGLE_BRACKET_CLOSE) {
+ in.ReadIdentifier(name);
+ in.Skip(Token::EQUALS);
+ if (name == "shape") {
+ in.ReadIdentifier(shape_name);
+ shape = &shapes.Get(shape_name);
+ } else if (name == "position") {
+ in.ReadVec(initial.position);
+ } else if (name == "orientation") {
+ in.ReadQuat(initial.orientation);
+ } else if (name == "hsl_mod") {
+ in.ReadVec(color_conv);
+ hsl_mod = EntityMesh::ColorMod(color_conv * 255.0f);
+ } else if (name == "rgb_mod") {
+ in.ReadVec(color_conv);
+ rgb_mod = EntityMesh::ColorMod(color_conv * 255.0f);
+ } else if (name == "textures") {
+ in.Skip(Token::BRACKET_OPEN);
+ while (in.HasMore() && in.Peek().type != Token::BRACKET_CLOSE) {
+ in.ReadString(tex_name);
+ tex_map.push_back(tex_index.GetID(tex_name));
+ if (in.Peek().type == Token::COMMA) {
+ in.Skip(Token::COMMA);
+ }
+ }
+ in.Skip(Token::BRACKET_CLOSE);
+ } else if (name == "children") {
+ in.Skip(Token::BRACKET_OPEN);
+ while (in.HasMore() && in.Peek().type != Token::BRACKET_CLOSE) {
+ Part &child = AddChild();
+ child.Read(in, tex_index, shapes);
+ if (in.Peek().type == Token::COMMA) {
+ in.Skip(Token::COMMA);
+ }
+ }
+ in.Skip(Token::BRACKET_CLOSE);
+ } else {
+ while (in.HasMore() && in.Peek().type != Token::SEMICOLON) {
+ in.Next();
+ }
+ }
+ in.Skip(Token::SEMICOLON);
+ }
+ in.Skip(Token::ANGLE_BRACKET_CLOSE);
+}
+
+Part &Part::AddChild() {
+ children.emplace_back();
+ children.back().parent = this;
+ return children.back();
+}
+
+std::uint16_t Part::Enumerate(std::uint16_t counter) noexcept {
+ id = counter++;
+ for (Part &part : children) {
+ counter = part.Enumerate(counter);
+ }
+ return counter;
+}