mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-12 14:31:50 +00:00
Merge pull request #764 from MihailRis/vcm-update
vcm models: add triangle shape
This commit is contained in:
commit
6b8d70c792
8 changed files with 107 additions and 4 deletions
|
|
@ -1,4 +1,7 @@
|
||||||
# Block Models
|
# Block Models (depricated)
|
||||||
|
|
||||||
|
> ![WARNING]
|
||||||
|
> The `model-primitives` property is deprecated. Use the [VCM format](vcm.md) for a textual description of the model's primitives.
|
||||||
|
|
||||||
Block model may be created with following properties:
|
Block model may be created with following properties:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
# Модели блоков
|
# Модели блоков (устарело)
|
||||||
|
|
||||||
|
> ![WARNING]
|
||||||
|
> Свойство `model-primitives` является устаревшим, используйте [формат VCM](vcm.md) для текстового описания модели из примитивов.
|
||||||
|
|
||||||
Создание собственной модели блока может быть реализовано при указании у блока свойств:
|
Создание собственной модели блока может быть реализовано при указании у блока свойств:
|
||||||
```js
|
```js
|
||||||
|
|
|
||||||
|
|
@ -20,15 +20,32 @@
|
||||||
|
|
||||||
В отличие от XML в корне может находиться несколько элементов.
|
В отличие от XML в корне может находиться несколько элементов.
|
||||||
|
|
||||||
На данный момент существует два вида примитивов: box и rect, а также, part (описывает часть примитива, такую как, например, сторона куба).
|
На данный момент существует три вида примитивов: tri, box и rect, а также, part (описывает часть примитива, такую как, например, сторона куба).
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> По-умолчанию текстурные координаты определяются размерами примитивов.
|
> По-умолчанию текстурные координаты определяются размерами примитивов.
|
||||||
> При размерах более 1.0 результат не определён и может измениться в последующих обновлениях.
|
> При размерах более 1.0 результат не определён и может измениться в последующих обновлениях.
|
||||||
> Используйте `region` или `region-scale` для ручной настройки.
|
> Используйте `region` или `region-scale` для ручной настройки.
|
||||||
|
|
||||||
|
### Свойства `tri`
|
||||||
|
|
||||||
|
Примитив описывает треугольник.
|
||||||
|
|
||||||
|
- `a` - точка A. Пример: `a (0,0,0)`
|
||||||
|
- `b` - точка B. Пример: `b (1,0,0)`
|
||||||
|
- `c` - точка С. Пример: `c (1,1,0)`
|
||||||
|
- `uv` - нормализованные текстурные координаты точек (6 чисел, по 2 на точку). Пример: `uv (0,0, 1,0, 1,1)`
|
||||||
|
- `texture` - отображаемая текстура. По-умолчанию: `$0`. Пример: `texture "blocks:sand"`
|
||||||
|
- `region` - UV регион в границах выбранной текстуры, определяется позициями противоположных углов квадрата нормализованных текстурных координат. Пример: `region (0,0,1,1)`
|
||||||
|
- `region-scale` вектор-множитель для UV региона. Пример: `region-scale (0.5,1)`
|
||||||
|
- `shading` определяет возможность затенения на примитиве. Пример: `shading off`
|
||||||
|
|
||||||
|
Текстурные координаты по-умолчанию не зависят от формы из размера, в отличие от других примитивов.
|
||||||
|
|
||||||
### Свойства `rect`
|
### Свойства `rect`
|
||||||
|
|
||||||
|
Примитив описывает параллелограмм через векторы right и up.
|
||||||
|
|
||||||
- `from` - точка начала примитива. Пример: `from (0,0.5,0.125)`
|
- `from` - точка начала примитива. Пример: `from (0,0.5,0.125)`
|
||||||
- `right` - вектор X, также определяющий ширину примитива. Пример: `right (1,0,0)`
|
- `right` - вектор X, также определяющий ширину примитива. Пример: `right (1,0,0)`
|
||||||
- `up` - вектор Y, также определяющий высоту примитива. Пример: `up (0,1,0)`
|
- `up` - вектор Y, также определяющий высоту примитива. Пример: `up (0,1,0)`
|
||||||
|
|
@ -40,6 +57,8 @@
|
||||||
|
|
||||||
### Свойства `box`
|
### Свойства `box`
|
||||||
|
|
||||||
|
Примитив описывает прямоугольный параллелепипед.
|
||||||
|
|
||||||
- `from` - точка начала примитива. Пример: `from (0,0,0)`
|
- `from` - точка начала примитива. Пример: `from (0,0,0)`
|
||||||
- `to` - противоположная от начала точка. Пример: `to (1,1,1)`
|
- `to` - противоположная от начала точка. Пример: `to (1,1,1)`
|
||||||
- `origin` - точка, относительно которой будет применено вращение. По-умолчанию: центр примитива. Пример: `origin (0.5,0.5,0.5)`
|
- `origin` - точка, относительно которой будет применено вращение. По-умолчанию: центр примитива. Пример: `origin (0.5,0.5,0.5)`
|
||||||
|
|
@ -48,7 +67,9 @@
|
||||||
- `shading` определяет возможность затенения на примитиве. Пример: `shading off`
|
- `shading` определяет возможность затенения на примитиве. Пример: `shading off`
|
||||||
- `delete` удаляет стороны по именам (top, bottom, east, west, north, south)
|
- `delete` удаляет стороны по именам (top, bottom, east, west, north, south)
|
||||||
|
|
||||||
### Свойства `part` (в `box`)
|
### Свойства `part` (вложен в `box`)
|
||||||
|
|
||||||
|
Примитив описывает свойства сторон прямоугольного параллелепипеда с указанными тегами (top/bottom/north/south/east/west).
|
||||||
|
|
||||||
- `tags` - определяет то, на какаие из сторон будут применены свойства. Пример: `tags (top,bottom)`
|
- `tags` - определяет то, на какаие из сторон будут применены свойства. Пример: `tags (top,bottom)`
|
||||||
- `texture` - отображаемая текстура. По-умолчанию: `$индекс_стороны`.
|
- `texture` - отображаемая текстура. По-умолчанию: `$индекс_стороны`.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
#include "xml.hpp"
|
#include "xml.hpp"
|
||||||
#include "util/stringutil.hpp"
|
#include "util/stringutil.hpp"
|
||||||
|
|
@ -71,6 +72,42 @@ static void perform_rect(const xmlelement& root, model::Model& model) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void perform_triangle(const xmlelement& root, model::Model& model) {
|
||||||
|
auto pointA = root.attr("a").asVec3();
|
||||||
|
auto pointB = root.attr("b").asVec3();
|
||||||
|
auto pointC = root.attr("c").asVec3();
|
||||||
|
|
||||||
|
glm::vec2 uvs[3] {{0, 0}, {1, 0}, {1, 1}};
|
||||||
|
|
||||||
|
bool shading = true;
|
||||||
|
if (root.has("shading")) {
|
||||||
|
shading = to_boolean(root.attr("shading"));
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 ba = pointB - pointA;
|
||||||
|
glm::vec3 ca = pointC - pointA;
|
||||||
|
glm::vec3 normal = glm::normalize(glm::cross(ba, ca));
|
||||||
|
|
||||||
|
if (root.has("uv")) {
|
||||||
|
root.attr("uv").asNumbers(glm::value_ptr(uvs[0]), 6);
|
||||||
|
} else {
|
||||||
|
UVRegion region {};
|
||||||
|
if (root.has("region")) {
|
||||||
|
region.set(root.attr("region").asVec4());
|
||||||
|
}
|
||||||
|
if (root.has("region-scale")) {
|
||||||
|
region.scale(root.attr("region-scale").asVec2());
|
||||||
|
}
|
||||||
|
for (auto& uv : uvs) {
|
||||||
|
uv = region.apply(uv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string texture = root.attr("texture", "$0").getText();
|
||||||
|
auto& mesh = model.addMesh(texture, shading);
|
||||||
|
mesh.addTriangle(pointA, pointB, pointC, normal, uvs[0], uvs[1], uvs[2]);
|
||||||
|
}
|
||||||
|
|
||||||
static void perform_box(const xmlelement& root, model::Model& model) {
|
static void perform_box(const xmlelement& root, model::Model& model) {
|
||||||
auto from = root.attr("from").asVec3();
|
auto from = root.attr("from").asVec3();
|
||||||
auto to = root.attr("to").asVec3();
|
auto to = root.attr("to").asVec3();
|
||||||
|
|
@ -181,6 +218,8 @@ static std::unique_ptr<model::Model> load_model(const xmlelement& root) {
|
||||||
perform_rect(*elem, model);
|
perform_rect(*elem, model);
|
||||||
} else if (tag == "box") {
|
} else if (tag == "box") {
|
||||||
perform_box(*elem, model);
|
perform_box(*elem, model);
|
||||||
|
} else if (tag == "tri") {
|
||||||
|
perform_triangle(*elem, model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,19 @@ glm::vec4 Attribute::asColor() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Attribute::asNumbers(float* dst, size_t dstSize) const {
|
||||||
|
size_t pos = 0;
|
||||||
|
size_t count = 0;
|
||||||
|
while (pos < text.length() && count < dstSize) {
|
||||||
|
size_t end = text.find(',', pos);
|
||||||
|
dst[count++] = util::parse_double(
|
||||||
|
text, pos, std::min<size_t>(end - pos, text.length() - pos)
|
||||||
|
);
|
||||||
|
pos = end + 1;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
Node::Node(std::string tag) : tag(std::move(tag)) {
|
Node::Node(std::string tag) : tag(std::move(tag)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ namespace xml {
|
||||||
glm::vec3 asVec3() const;
|
glm::vec3 asVec3() const;
|
||||||
glm::vec4 asVec4() const;
|
glm::vec4 asVec4() const;
|
||||||
glm::vec4 asColor() const;
|
glm::vec4 asColor() const;
|
||||||
|
int asNumbers(float* dst, size_t dstSize) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief XML element class. Text element has tag 'text' and attribute
|
/// @brief XML element class. Text element has tag 'text' and attribute
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,20 @@ void Mesh::addPlane(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mesh::addTriangle(
|
||||||
|
const glm::vec3& a,
|
||||||
|
const glm::vec3& b,
|
||||||
|
const glm::vec3& c,
|
||||||
|
const glm::vec3& norm,
|
||||||
|
const glm::vec2& uvA,
|
||||||
|
const glm::vec2& uvB,
|
||||||
|
const glm::vec2& uvC
|
||||||
|
) {
|
||||||
|
vertices.push_back({a, uvA, norm});
|
||||||
|
vertices.push_back({b, uvB, norm});
|
||||||
|
vertices.push_back({c, uvC, norm});
|
||||||
|
}
|
||||||
|
|
||||||
void Mesh::addRect(
|
void Mesh::addRect(
|
||||||
const glm::vec3& pos,
|
const glm::vec3& pos,
|
||||||
const glm::vec3& right,
|
const glm::vec3& right,
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,15 @@ namespace model {
|
||||||
const glm::vec3& up,
|
const glm::vec3& up,
|
||||||
const glm::vec3& norm,
|
const glm::vec3& norm,
|
||||||
const UVRegion& region
|
const UVRegion& region
|
||||||
|
);
|
||||||
|
void addTriangle(
|
||||||
|
const glm::vec3& a,
|
||||||
|
const glm::vec3& b,
|
||||||
|
const glm::vec3& c,
|
||||||
|
const glm::vec3& norm,
|
||||||
|
const glm::vec2& uvA,
|
||||||
|
const glm::vec2& uvB,
|
||||||
|
const glm::vec2& uvC
|
||||||
);
|
);
|
||||||
void addBox(const glm::vec3& pos, const glm::vec3& size);
|
void addBox(const glm::vec3& pos, const glm::vec3& size);
|
||||||
void addBox(
|
void addBox(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue