mirror of
https://github.com/rwengine/openrw.git
synced 2024-09-18 16:32:32 +02:00
Avoid making unnecessary copies (#337)
* frames.emplace_back * vehicleColours.emplace_back * colours.emplace_back * waterBlocks.emplace_back * state.garages.emplace_back * bonedata->frames.emplace_back * lines.emplace_back * circleVerts.emplace_back * geo.emplace_back * Water renderer * perf_colours.emplace_back
This commit is contained in:
parent
9aa01b69e1
commit
c54cfa0ae8
@ -51,9 +51,9 @@ bool ChaseKeyframe::load(const std::string &filePath,
|
|||||||
rec.up[0] / 127.5f, rec.up[1] / 127.5f, rec.up[2] / 127.5f,
|
rec.up[0] / 127.5f, rec.up[1] / 127.5f, rec.up[2] / 127.5f,
|
||||||
};
|
};
|
||||||
glm::mat3 rotation(right, up, glm::cross(right, up));
|
glm::mat3 rotation(right, up, glm::cross(right, up));
|
||||||
frames.push_back({velocity, rec.steering, rec.driving, rec.braking,
|
frames.emplace_back(velocity, rec.steering, rec.driving, rec.braking,
|
||||||
!!rec.handbrake, rec.position,
|
!!rec.handbrake, rec.position,
|
||||||
glm::quat_cast(rotation)});
|
glm::quat_cast(rotation));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -18,6 +18,16 @@ struct ChaseKeyframe {
|
|||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
glm::quat rotation;
|
glm::quat rotation;
|
||||||
|
|
||||||
|
ChaseKeyframe(glm::vec3 _velocity, int _steeringAngle, int _acceleratorPower, int _brakePower, bool _handbrake, glm::vec3 _position, glm::quat _rotation)
|
||||||
|
: velocity(_velocity)
|
||||||
|
, steeringAngle(_steeringAngle)
|
||||||
|
, acceleratorPower(_acceleratorPower)
|
||||||
|
, brakePower(_brakePower)
|
||||||
|
, handbrake(_handbrake)
|
||||||
|
, position(_position)
|
||||||
|
, rotation(_rotation) {
|
||||||
|
}
|
||||||
|
|
||||||
static bool load(const std::string& filePath,
|
static bool load(const std::string& filePath,
|
||||||
std::vector<ChaseKeyframe>& frames);
|
std::vector<ChaseKeyframe>& frames);
|
||||||
};
|
};
|
||||||
|
@ -247,8 +247,8 @@ void GameData::loadCarcols(const std::string& path) {
|
|||||||
|
|
||||||
if (std::getline(ss, r, ',') && std::getline(ss, g, ',') &&
|
if (std::getline(ss, r, ',') && std::getline(ss, g, ',') &&
|
||||||
std::getline(ss, b)) {
|
std::getline(ss, b)) {
|
||||||
vehicleColours.push_back(glm::u8vec3(
|
vehicleColours.emplace_back(
|
||||||
atoi(r.c_str()), atoi(g.c_str()), atoi(b.c_str())));
|
atoi(r.c_str()), atoi(g.c_str()), atoi(b.c_str()));
|
||||||
}
|
}
|
||||||
} else if (currentSection == CAR) {
|
} else if (currentSection == CAR) {
|
||||||
std::string vehicle, p, s;
|
std::string vehicle, p, s;
|
||||||
@ -258,7 +258,7 @@ void GameData::loadCarcols(const std::string& path) {
|
|||||||
std::vector<std::pair<size_t, size_t>> colours;
|
std::vector<std::pair<size_t, size_t>> colours;
|
||||||
|
|
||||||
while (std::getline(ss, p, ',') && std::getline(ss, s, ',')) {
|
while (std::getline(ss, p, ',') && std::getline(ss, s, ',')) {
|
||||||
colours.push_back({atoi(p.c_str()), atoi(s.c_str())});
|
colours.emplace_back(atoi(p.c_str()), atoi(s.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
vehiclePalettes.insert({vehicle, colours});
|
vehiclePalettes.insert({vehicle, colours});
|
||||||
@ -324,17 +324,17 @@ void GameData::loadWater(const std::string& path) {
|
|||||||
std::stringstream ss(line);
|
std::stringstream ss(line);
|
||||||
|
|
||||||
std::string a, b, c, d, e;
|
std::string a, b, c, d, e;
|
||||||
float fa, fb, fc, fd, fe;
|
|
||||||
|
|
||||||
if (std::getline(ss, a, ',') && std::getline(ss, b, ',') &&
|
if (std::getline(ss, a, ',') && std::getline(ss, b, ',') &&
|
||||||
std::getline(ss, c, ',') && std::getline(ss, d, ',') &&
|
std::getline(ss, c, ',') && std::getline(ss, d, ',') &&
|
||||||
std::getline(ss, e, ',')) {
|
std::getline(ss, e, ',')) {
|
||||||
fa = atof(a.c_str());
|
|
||||||
fb = atof(b.c_str());
|
waterBlocks.emplace_back(
|
||||||
fc = atof(c.c_str());
|
atof(a.c_str()),
|
||||||
fd = atof(d.c_str());
|
atof(b.c_str()),
|
||||||
fe = atof(e.c_str());
|
atof(c.c_str()),
|
||||||
waterBlocks.push_back({fa, fb, fc, fd, fe});
|
atof(d.c_str()),
|
||||||
|
atof(e.c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,6 +323,14 @@ public:
|
|||||||
float height;
|
float height;
|
||||||
float xLeft, yBottom;
|
float xLeft, yBottom;
|
||||||
float xRight, yTop;
|
float xRight, yTop;
|
||||||
|
|
||||||
|
WaterArea(float _height, float _xLeft, float _yBottom, float _xRight, float _yTop)
|
||||||
|
: height(_height)
|
||||||
|
, xLeft(_xLeft)
|
||||||
|
, yBottom(_yBottom)
|
||||||
|
, xRight(_xRight)
|
||||||
|
, yTop(_yTop) {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1251,9 +1251,9 @@ bool SaveGame::loadGame(GameState& state, const std::string& file) {
|
|||||||
// http://gtaforums.com/topic/758692-gta-iii-save-file-documentation/
|
// http://gtaforums.com/topic/758692-gta-iii-save-file-documentation/
|
||||||
for (size_t g = 0; g < garageData.garageCount; ++g) {
|
for (size_t g = 0; g < garageData.garageCount; ++g) {
|
||||||
auto& garage = garages[g];
|
auto& garage = garages[g];
|
||||||
state.garages.push_back(
|
state.garages.emplace_back(
|
||||||
{(int)g, glm::vec3(garage.x1, garage.y1, garage.z1),
|
(int)g, glm::vec3(garage.x1, garage.y1, garage.z1),
|
||||||
glm::vec3(garage.x2, garage.y2, garage.z2), garage.type});
|
glm::vec3(garage.x2, garage.y2, garage.z2), garage.type);
|
||||||
}
|
}
|
||||||
for (int c = 0; c < 18; ++c) {
|
for (int c = 0; c < 18; ++c) {
|
||||||
if (garageData.cars[c].modelId == 0) continue;
|
if (garageData.cars[c].modelId == 0) continue;
|
||||||
|
@ -95,9 +95,9 @@ bool LoaderIFP::loadFromMemory(char* data) {
|
|||||||
for (int d = 0; d < frames->frames; ++d) {
|
for (int d = 0; d < frames->frames; ++d) {
|
||||||
glm::quat q = glm::conjugate(*read<glm::quat>(data, dataI));
|
glm::quat q = glm::conjugate(*read<glm::quat>(data, dataI));
|
||||||
time = *read<float>(data, dataI);
|
time = *read<float>(data, dataI);
|
||||||
bonedata->frames.push_back({q, glm::vec3(0.f, 0.f, 0.f),
|
bonedata->frames.emplace_back(q, glm::vec3(0.f, 0.f, 0.f),
|
||||||
glm::vec3(1.f, 1.f, 1.f), time,
|
glm::vec3(1.f, 1.f, 1.f), time,
|
||||||
d});
|
d);
|
||||||
}
|
}
|
||||||
} else if (type == "KRT0") {
|
} else if (type == "KRT0") {
|
||||||
bonedata->type = AnimationBone::RT0;
|
bonedata->type = AnimationBone::RT0;
|
||||||
@ -105,8 +105,8 @@ bool LoaderIFP::loadFromMemory(char* data) {
|
|||||||
glm::quat q = glm::conjugate(*read<glm::quat>(data, dataI));
|
glm::quat q = glm::conjugate(*read<glm::quat>(data, dataI));
|
||||||
glm::vec3 p = *read<glm::vec3>(data, dataI);
|
glm::vec3 p = *read<glm::vec3>(data, dataI);
|
||||||
time = *read<float>(data, dataI);
|
time = *read<float>(data, dataI);
|
||||||
bonedata->frames.push_back(
|
bonedata->frames.emplace_back(
|
||||||
{q, p, glm::vec3(1.f, 1.f, 1.f), time, d});
|
q, p, glm::vec3(1.f, 1.f, 1.f), time, d);
|
||||||
}
|
}
|
||||||
} else if (type == "KRTS") {
|
} else if (type == "KRTS") {
|
||||||
bonedata->type = AnimationBone::RTS;
|
bonedata->type = AnimationBone::RTS;
|
||||||
@ -115,7 +115,7 @@ bool LoaderIFP::loadFromMemory(char* data) {
|
|||||||
glm::vec3 p = *read<glm::vec3>(data, dataI);
|
glm::vec3 p = *read<glm::vec3>(data, dataI);
|
||||||
glm::vec3 s = *read<glm::vec3>(data, dataI);
|
glm::vec3 s = *read<glm::vec3>(data, dataI);
|
||||||
time = *read<float>(data, dataI);
|
time = *read<float>(data, dataI);
|
||||||
bonedata->frames.push_back({q, p, s, time, d});
|
bonedata->frames.emplace_back(q, p, s, time, d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,19 @@ struct AnimationKeyframe {
|
|||||||
glm::quat rotation;
|
glm::quat rotation;
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
glm::vec3 scale;
|
glm::vec3 scale;
|
||||||
float starttime;
|
float starttime = 0.f;
|
||||||
int id;
|
int id = 0;
|
||||||
|
|
||||||
|
AnimationKeyframe(glm::quat _rotation, glm::vec3 _position, glm::vec3 _scale, float _starttime, int _id)
|
||||||
|
: rotation(_rotation)
|
||||||
|
, position(_position)
|
||||||
|
, scale(_scale)
|
||||||
|
, starttime(_starttime)
|
||||||
|
, id(_id) {
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimationKeyframe() {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnimationBone {
|
struct AnimationBone {
|
||||||
|
@ -32,12 +32,12 @@ DebugDraw::~DebugDraw() {
|
|||||||
void DebugDraw::drawLine(const btVector3 &from, const btVector3 &to,
|
void DebugDraw::drawLine(const btVector3 &from, const btVector3 &to,
|
||||||
const btVector3 &color) {
|
const btVector3 &color) {
|
||||||
btVector3 c = color * 255;
|
btVector3 c = color * 255;
|
||||||
lines.push_back({glm::vec3(from.getX(), from.getY(), from.getZ()),
|
lines.emplace_back(glm::vec3(from.getX(), from.getY(), from.getZ()),
|
||||||
glm::vec3(0.f), glm::vec2(0.f),
|
glm::vec3(0.f), glm::vec2(0.f),
|
||||||
glm::u8vec4(c.getX(), c.getY(), c.getZ(), 255)});
|
glm::u8vec4(c.getX(), c.getY(), c.getZ(), 255));
|
||||||
lines.push_back({glm::vec3(to.getX(), to.getY(), to.getZ()), glm::vec3(0.f),
|
lines.emplace_back(glm::vec3(to.getX(), to.getY(), to.getZ()), glm::vec3(0.f),
|
||||||
glm::vec2(0.f),
|
glm::vec2(0.f),
|
||||||
glm::u8vec4(c.getX(), c.getY(), c.getZ(), 255)});
|
glm::u8vec4(c.getX(), c.getY(), c.getZ(), 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugDraw::drawContactPoint(const btVector3 &pointOnB,
|
void DebugDraw::drawContactPoint(const btVector3 &pointOnB,
|
||||||
|
@ -45,11 +45,11 @@ MapRenderer::MapRenderer(std::shared_ptr<Renderer> renderer, GameData* _data)
|
|||||||
rect.setFaceType(GL_TRIANGLE_FAN);
|
rect.setFaceType(GL_TRIANGLE_FAN);
|
||||||
|
|
||||||
std::vector<VertexP2> circleVerts;
|
std::vector<VertexP2> circleVerts;
|
||||||
circleVerts.push_back({0.f, 0.f});
|
circleVerts.emplace_back(0.f, 0.f);
|
||||||
for (int v = 0; v < 181; ++v) {
|
for (int v = 0; v < 181; ++v) {
|
||||||
circleVerts.push_back(
|
circleVerts.emplace_back(
|
||||||
{0.5f * glm::cos(2 * (v / 180.f) * glm::pi<float>()),
|
0.5f * glm::cos(2 * (v / 180.f) * glm::pi<float>()),
|
||||||
0.5f * glm::sin(2 * (v / 180.f) * glm::pi<float>())});
|
0.5f * glm::sin(2 * (v / 180.f) * glm::pi<float>()));
|
||||||
}
|
}
|
||||||
circleGeom.uploadVertices(circleVerts);
|
circleGeom.uploadVertices(circleVerts);
|
||||||
circle.addGeometry(&circleGeom);
|
circle.addGeometry(&circleGeom);
|
||||||
|
@ -14,6 +14,22 @@ typedef uint64_t RenderKey;
|
|||||||
|
|
||||||
typedef std::uint32_t RenderIndex;
|
typedef std::uint32_t RenderIndex;
|
||||||
|
|
||||||
|
struct VertexP2 {
|
||||||
|
glm::vec2 position;
|
||||||
|
|
||||||
|
static const AttributeList vertex_attributes() {
|
||||||
|
return {{ATRS_Position, 2, sizeof(VertexP2), 0ul}};
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexP2(float _x, float _y)
|
||||||
|
: position({_x, _y}) {
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexP2() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct VertexP3 {
|
struct VertexP3 {
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
|
|
||||||
@ -22,15 +38,13 @@ struct VertexP3 {
|
|||||||
{ATRS_Position, 3, sizeof(VertexP3), 0ul},
|
{ATRS_Position, 3, sizeof(VertexP3), 0ul},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/// @todo normalize this to have the same interface as VertexP3
|
VertexP3(float _x, float _y, float _z)
|
||||||
struct VertexP2 {
|
: position({_x, _y, _z}) {
|
||||||
static const AttributeList vertex_attributes() {
|
|
||||||
return {{ATRS_Position, 2, sizeof(VertexP2), 0ul}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float x, y;
|
VertexP3() {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Renderer {
|
class Renderer {
|
||||||
|
@ -58,6 +58,15 @@ struct TextVertex {
|
|||||||
glm::vec2 texcoord;
|
glm::vec2 texcoord;
|
||||||
glm::vec3 colour;
|
glm::vec3 colour;
|
||||||
|
|
||||||
|
TextVertex(glm::vec2 _position, glm::vec2 _texcoord, glm::vec3 _colour)
|
||||||
|
: position(_position)
|
||||||
|
, texcoord(_texcoord)
|
||||||
|
, colour(_colour) {
|
||||||
|
}
|
||||||
|
|
||||||
|
TextVertex() {
|
||||||
|
}
|
||||||
|
|
||||||
static const AttributeList vertex_attributes() {
|
static const AttributeList vertex_attributes() {
|
||||||
return {
|
return {
|
||||||
{ATRS_Position, 2, sizeof(TextVertex), 0ul},
|
{ATRS_Position, 2, sizeof(TextVertex), 0ul},
|
||||||
@ -247,13 +256,13 @@ void TextRenderer::renderText(const TextRenderer::TextInfo& ti,
|
|||||||
coord.x += ss.x;
|
coord.x += ss.x;
|
||||||
maxWidth = std::max(coord.x, maxWidth);
|
maxWidth = std::max(coord.x, maxWidth);
|
||||||
|
|
||||||
geo.push_back({{p.x, p.y + ss.y}, {tex.x, tex.w}, colour});
|
geo.emplace_back(glm::vec2{p.x, p.y + ss.y}, glm::vec2{tex.x, tex.w}, colour);
|
||||||
geo.push_back({{p.x + ss.x, p.y + ss.y}, {tex.z, tex.w}, colour});
|
geo.emplace_back(glm::vec2{p.x + ss.x, p.y + ss.y}, glm::vec2{tex.z, tex.w}, colour);
|
||||||
geo.push_back({{p.x, p.y}, {tex.x, tex.y}, colour});
|
geo.emplace_back(glm::vec2{p.x, p.y}, glm::vec2{tex.x, tex.y}, colour);
|
||||||
|
|
||||||
geo.push_back({{p.x + ss.x, p.y}, {tex.z, tex.y}, colour});
|
geo.emplace_back(glm::vec2{p.x + ss.x, p.y}, glm::vec2{tex.z, tex.y}, colour);
|
||||||
geo.push_back({{p.x, p.y}, {tex.x, tex.y}, colour});
|
geo.emplace_back(glm::vec2{p.x, p.y}, glm::vec2{tex.x, tex.y}, colour);
|
||||||
geo.push_back({{p.x + ss.x, p.y + ss.y}, {tex.z, tex.w}, colour});
|
geo.emplace_back(glm::vec2{p.x + ss.x, p.y + ss.y}, glm::vec2{tex.z, tex.w}, colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ti.align == TextInfo::Right) {
|
if (ti.align == TextInfo::Right) {
|
||||||
|
@ -31,19 +31,19 @@ WaterRenderer::WaterRenderer(GameRenderer* renderer) : waterProg(nullptr) {
|
|||||||
glm::vec2 tMax(b + glm::vec2(x + 1, y + 1) * gridresinv);
|
glm::vec2 tMax(b + glm::vec2(x + 1, y + 1) * gridresinv);
|
||||||
|
|
||||||
// Build geometry
|
// Build geometry
|
||||||
grid.push_back(glm::vec2(tMax.x, tMax.y));
|
grid.emplace_back(tMax.x, tMax.y);
|
||||||
grid.push_back(glm::vec2(tMax.x, tMin.y));
|
grid.emplace_back(tMax.x, tMin.y);
|
||||||
grid.push_back(glm::vec2(tMin.x, tMin.y));
|
grid.emplace_back(tMin.x, tMin.y);
|
||||||
|
|
||||||
grid.push_back(glm::vec2(tMin.x, tMin.y));
|
grid.emplace_back(tMin.x, tMin.y);
|
||||||
grid.push_back(glm::vec2(tMin.x, tMax.y));
|
grid.emplace_back(tMin.x, tMax.y);
|
||||||
grid.push_back(glm::vec2(tMax.x, tMax.y));
|
grid.emplace_back(tMax.x, tMax.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gridGeom.uploadVertices(grid.size(), sizeof(glm::vec2) * grid.size(),
|
gridGeom.uploadVertices(grid.size(), sizeof(glm::vec2) * grid.size(),
|
||||||
grid.data());
|
grid.data());
|
||||||
gridGeom.getDataAttributes().push_back({ATRS_Position, 2, 0, 0, GL_FLOAT});
|
gridGeom.getDataAttributes().emplace_back(ATRS_Position, 2, 0, 0, GL_FLOAT);
|
||||||
gridDraw.addGeometry(&gridGeom);
|
gridDraw.addGeometry(&gridGeom);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,20 +72,20 @@ void WaterRenderer::setWaterTable(float* waterHeights, unsigned int nHeights,
|
|||||||
glm::vec2 tMax(wO + glm::vec2(x + 1, y + 1) * tileSize);
|
glm::vec2 tMax(wO + glm::vec2(x + 1, y + 1) * tileSize);
|
||||||
|
|
||||||
// Build geometry
|
// Build geometry
|
||||||
vertexData.push_back(glm::vec3(tMax.x, tMax.y, hMax));
|
vertexData.emplace_back(tMax.x, tMax.y, hMax);
|
||||||
vertexData.push_back(glm::vec3(tMax.x, tMin.y, hMax));
|
vertexData.emplace_back(tMax.x, tMin.y, hMax);
|
||||||
vertexData.push_back(glm::vec3(tMin.x, tMin.y, hMax));
|
vertexData.emplace_back(tMin.x, tMin.y, hMax);
|
||||||
|
|
||||||
vertexData.push_back(glm::vec3(tMin.x, tMin.y, hMax));
|
vertexData.emplace_back(tMin.x, tMin.y, hMax);
|
||||||
vertexData.push_back(glm::vec3(tMin.x, tMax.y, hMax));
|
vertexData.emplace_back(tMin.x, tMax.y, hMax);
|
||||||
vertexData.push_back(glm::vec3(tMax.x, tMax.y, hMax));
|
vertexData.emplace_back(tMax.x, tMax.y, hMax);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
maskGeom.uploadVertices(vertexData.size(),
|
maskGeom.uploadVertices(vertexData.size(),
|
||||||
sizeof(glm::vec3) * vertexData.size(),
|
sizeof(glm::vec3) * vertexData.size(),
|
||||||
vertexData.data());
|
vertexData.data());
|
||||||
maskGeom.getDataAttributes().push_back({ATRS_Position, 3, 0, 0, GL_FLOAT});
|
maskGeom.getDataAttributes().emplace_back(ATRS_Position, 3, 0, 0, GL_FLOAT);
|
||||||
maskDraw.addGeometry(&maskGeom);
|
maskDraw.addGeometry(&maskGeom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,7 +793,7 @@ void RWGame::renderProfile() {
|
|||||||
for (int r = 0; r < c; ++r) {
|
for (int r = 0; r < c; ++r) {
|
||||||
for (int g = 0; g < c; ++g) {
|
for (int g = 0; g < c; ++g) {
|
||||||
for (int b = 0; b < c; ++b) {
|
for (int b = 0; b < c; ++b) {
|
||||||
perf_colours.push_back({r / c, g / c, b / c, 1.f});
|
perf_colours.emplace_back(r / c, g / c, b / c, 1.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,16 @@ struct GeometryVertex {
|
|||||||
{ATRS_Colour, 4, sizeof(GeometryVertex), sizeof(float) * 8,
|
{ATRS_Colour, 4, sizeof(GeometryVertex), sizeof(float) * 8,
|
||||||
GL_UNSIGNED_BYTE}};
|
GL_UNSIGNED_BYTE}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GeometryVertex(glm::vec3 _position, glm::vec3 _normal, glm::vec2 _texcoord, glm::u8vec4 _colour)
|
||||||
|
: position(_position)
|
||||||
|
, normal(_normal)
|
||||||
|
, texcoord(_texcoord)
|
||||||
|
, colour(_colour) {
|
||||||
|
}
|
||||||
|
|
||||||
|
GeometryVertex() {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user