mirror of
https://github.com/overte-org/overte.git
synced 2025-04-13 18:42:11 +02:00
Entities.voxelsToMesh, Model.transformMesh, Model.appendMeshes, Model.meshToOBJ appear to work now
This commit is contained in:
parent
16c3eb62b1
commit
b3603ce8b3
9 changed files with 238 additions and 92 deletions
|
@ -664,11 +664,8 @@ void RenderablePolyVoxEntityItem::setZTextureURL(QString zTextureURL) {
|
|||
}
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
|
||||
assert(getType() == EntityTypes::PolyVox);
|
||||
Q_ASSERT(args->_batch);
|
||||
|
||||
bool RenderablePolyVoxEntityItem::updateDependents() {
|
||||
bool voxelDataDirty;
|
||||
bool volDataDirty;
|
||||
withWriteLock([&] {
|
||||
|
@ -686,6 +683,17 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
|||
recomputeMesh();
|
||||
}
|
||||
|
||||
return !volDataDirty;
|
||||
}
|
||||
|
||||
|
||||
void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
|
||||
assert(getType() == EntityTypes::PolyVox);
|
||||
Q_ASSERT(args->_batch);
|
||||
|
||||
updateDependents();
|
||||
|
||||
model::MeshPointer mesh;
|
||||
glm::vec3 voxelVolumeSize;
|
||||
withReadLock([&] {
|
||||
|
@ -1571,13 +1579,22 @@ void RenderablePolyVoxEntityItem::locationChanged(bool tellPhysics) {
|
|||
scene->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
|
||||
bool RenderablePolyVoxEntityItem::getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) const {
|
||||
bool RenderablePolyVoxEntityItem::getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) {
|
||||
if (!updateDependents()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
MeshProxy* meshProxy = nullptr;
|
||||
glm::mat4 transform = voxelToLocalMatrix();
|
||||
withReadLock([&] {
|
||||
if (_meshInitialized) {
|
||||
success = true;
|
||||
meshProxy = new MeshProxy(_mesh);
|
||||
// the mesh will be in voxel-space. transform it into object-space
|
||||
meshProxy = new MeshProxy(
|
||||
_mesh->map([=](glm::vec3 position){ return glm::vec3(transform * glm::vec4(position, 1.0f)); },
|
||||
[=](glm::vec3 normal){ return glm::vec3(transform * glm::vec4(normal, 0.0f)); },
|
||||
[](uint32_t index){ return index; }));
|
||||
}
|
||||
});
|
||||
result = meshToScriptValue(engine, meshProxy);
|
||||
|
|
|
@ -133,7 +133,7 @@ public:
|
|||
QByteArray volDataToArray(quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize) const;
|
||||
|
||||
void setMesh(model::MeshPointer mesh);
|
||||
bool getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) const override;
|
||||
bool getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) override;
|
||||
void setCollisionPoints(ShapeInfo::PointCollection points, AABox box);
|
||||
PolyVox::SimpleVolume<uint8_t>* getVolData() { return _volData; }
|
||||
|
||||
|
@ -192,6 +192,7 @@ private:
|
|||
void cacheNeighbors();
|
||||
void copyUpperEdgesFromNeighbors();
|
||||
void bonkNeighbors();
|
||||
bool updateDependents();
|
||||
};
|
||||
|
||||
bool inUserBounds(const PolyVox::SimpleVolume<uint8_t>* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle,
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
#include "EntityScriptingInterface.h"
|
||||
|
||||
#include "EntityItemID.h"
|
||||
|
@ -926,13 +930,16 @@ bool EntityScriptingInterface::setVoxelsInCuboid(QUuid entityID, const glm::vec3
|
|||
void EntityScriptingInterface::voxelsToMesh(QUuid entityID, QScriptValue callback) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
polyVoxWorker(entityID, [callback](PolyVoxEntityItem& polyVoxEntity) mutable {
|
||||
QScriptValue mesh;
|
||||
polyVoxEntity.getMeshAsScriptValue(callback.engine(), mesh);
|
||||
QScriptValueList args { mesh };
|
||||
callback.call(QScriptValue(), args);
|
||||
bool success;
|
||||
QScriptValue mesh;
|
||||
|
||||
polyVoxWorker(entityID, [&](PolyVoxEntityItem& polyVoxEntity) mutable {
|
||||
success = polyVoxEntity.getMeshAsScriptValue(callback.engine(), mesh);
|
||||
return true;
|
||||
});
|
||||
|
||||
QScriptValueList args { mesh, success };
|
||||
callback.call(QScriptValue(), args);
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::setAllPoints(QUuid entityID, const QVector<glm::vec3>& points) {
|
||||
|
@ -1557,7 +1564,11 @@ glm::mat4 EntityScriptingInterface::getEntityTransform(const QUuid& entityID) {
|
|||
_entityTree->withReadLock([&] {
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(entityID));
|
||||
if (entity) {
|
||||
result = entity->getEntityToWorldMatrix();
|
||||
glm::mat4 translation = glm::translate(entity->getPosition());
|
||||
glm::mat4 rotation = glm::mat4_cast(entity->getRotation());
|
||||
glm::mat4 registration = glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT -
|
||||
entity->getRegistrationPoint());
|
||||
result = translation * rotation * registration;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -294,6 +294,14 @@ public slots:
|
|||
Q_INVOKABLE bool AABoxIntersectsCapsule(const glm::vec3& low, const glm::vec3& dimensions,
|
||||
const glm::vec3& start, const glm::vec3& end, float radius);
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Returns object to world transform, excluding scale
|
||||
*
|
||||
* @function Entities.getEntityTransform
|
||||
* @param {EntityID} entityID The ID of the entity whose transform is to be returned
|
||||
* @return {Mat4} Entity's object to world transform, excluding scale
|
||||
*/
|
||||
Q_INVOKABLE glm::mat4 getEntityTransform(const QUuid& entityID);
|
||||
|
||||
signals:
|
||||
|
|
|
@ -243,6 +243,6 @@ const QByteArray PolyVoxEntityItem::getVoxelData() const {
|
|||
return voxelDataCopy;
|
||||
}
|
||||
|
||||
bool PolyVoxEntityItem::getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) const {
|
||||
bool PolyVoxEntityItem::getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ class PolyVoxEntityItem : public EntityItem {
|
|||
void setVoxelDataDirty(bool value) { withWriteLock([&] { _voxelDataDirty = value; }); }
|
||||
virtual void recomputeMesh() {};
|
||||
|
||||
virtual bool getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) const;
|
||||
virtual bool getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result);
|
||||
|
||||
protected:
|
||||
glm::vec3 _voxelVolumeSize; // this is always 3 bytes
|
||||
|
|
|
@ -117,7 +117,7 @@ Box Mesh::evalPartsBound(int partStart, int partEnd) const {
|
|||
auto partItEnd = _partBuffer.cbegin<Part>() + partEnd;
|
||||
|
||||
for (;part != partItEnd; part++) {
|
||||
|
||||
|
||||
Box partBound;
|
||||
auto index = _indexBuffer.cbegin<uint>() + (*part)._startIndex;
|
||||
auto endIndex = index + (*part)._numIndices;
|
||||
|
@ -134,6 +134,87 @@ Box Mesh::evalPartsBound(int partStart, int partEnd) const {
|
|||
return totalBound;
|
||||
}
|
||||
|
||||
|
||||
model::MeshPointer Mesh::map(std::function<glm::vec3(glm::vec3)> vertexFunc,
|
||||
std::function<glm::vec3(glm::vec3)> normalFunc,
|
||||
std::function<uint32_t(uint32_t)> indexFunc) {
|
||||
int attributeTypeNormal = gpu::Stream::InputSlot::NORMAL; // libraries/gpu/src/gpu/Stream.h
|
||||
|
||||
gpu::Resource::Size vertexSize = getNumVertices() * sizeof(glm::vec3);
|
||||
unsigned char* resultVertexData = new unsigned char[vertexSize];
|
||||
unsigned char* vertexDataCursor = resultVertexData;
|
||||
|
||||
gpu::Resource::Size normalSize = getNumAttributes() * sizeof(glm::vec3);
|
||||
unsigned char* resultNormalData = new unsigned char[normalSize];
|
||||
unsigned char* normalDataCursor = resultNormalData;
|
||||
|
||||
gpu::Resource::Size indexSize = getNumIndices() * sizeof(uint32_t);
|
||||
unsigned char* resultIndexData = new unsigned char[indexSize];
|
||||
unsigned char* indexDataCursor = resultIndexData;
|
||||
|
||||
// vertex data
|
||||
const gpu::BufferView& vertexBufferView = getVertexBuffer();
|
||||
gpu::BufferView::Index numVertices = (gpu::BufferView::Index)getNumVertices();
|
||||
for (gpu::BufferView::Index i = 0; i < numVertices; i ++) {
|
||||
glm::vec3 pos = vertexFunc(vertexBufferView.get<glm::vec3>(i));
|
||||
memcpy(vertexDataCursor, &pos, sizeof(pos));
|
||||
vertexDataCursor += sizeof(pos);
|
||||
}
|
||||
|
||||
// normal data
|
||||
const gpu::BufferView& normalsBufferView = getAttributeBuffer(attributeTypeNormal);
|
||||
gpu::BufferView::Index numNormals = (gpu::BufferView::Index)getNumAttributes();
|
||||
for (gpu::BufferView::Index i = 0; i < numNormals; i ++) {
|
||||
glm::vec3 normal = normalFunc(normalsBufferView.get<glm::vec3>(i));
|
||||
memcpy(normalDataCursor, &normal, sizeof(normal));
|
||||
normalDataCursor += sizeof(normal);
|
||||
}
|
||||
// TODO -- other attributes
|
||||
|
||||
// face data
|
||||
const gpu::BufferView& indexBufferView = getIndexBuffer();
|
||||
gpu::BufferView::Index numIndexes = (gpu::BufferView::Index)getNumIndices();
|
||||
for (gpu::BufferView::Index i = 0; i < numIndexes; i ++) {
|
||||
uint32_t index = indexFunc(indexBufferView.get<uint32_t>(i));
|
||||
memcpy(indexDataCursor, &index, sizeof(index));
|
||||
indexDataCursor += sizeof(index);
|
||||
}
|
||||
|
||||
model::MeshPointer result(new model::Mesh());
|
||||
|
||||
gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
||||
gpu::Buffer* resultVertexBuffer = new gpu::Buffer(vertexSize, resultVertexData);
|
||||
gpu::BufferPointer resultVertexBufferPointer(resultVertexBuffer);
|
||||
gpu::BufferView resultVertexBufferView(resultVertexBufferPointer, vertexElement);
|
||||
result->setVertexBuffer(resultVertexBufferView);
|
||||
|
||||
gpu::Element normalElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
||||
gpu::Buffer* resultNormalsBuffer = new gpu::Buffer(normalSize, resultNormalData);
|
||||
gpu::BufferPointer resultNormalsBufferPointer(resultNormalsBuffer);
|
||||
gpu::BufferView resultNormalsBufferView(resultNormalsBufferPointer, normalElement);
|
||||
result->addAttribute(attributeTypeNormal, resultNormalsBufferView);
|
||||
|
||||
gpu::Element indexElement = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW);
|
||||
gpu::Buffer* resultIndexesBuffer = new gpu::Buffer(indexSize, resultIndexData);
|
||||
gpu::BufferPointer resultIndexesBufferPointer(resultIndexesBuffer);
|
||||
gpu::BufferView resultIndexesBufferView(resultIndexesBufferPointer, indexElement);
|
||||
result->setIndexBuffer(resultIndexesBufferView);
|
||||
|
||||
|
||||
// TODO -- shouldn't assume just one part
|
||||
|
||||
std::vector<model::Mesh::Part> parts;
|
||||
parts.emplace_back(model::Mesh::Part((model::Index)0, // startIndex
|
||||
(model::Index)result->getNumIndices(), // numIndices
|
||||
(model::Index)0, // baseVertex
|
||||
model::Mesh::TRIANGLES)); // topology
|
||||
result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part),
|
||||
(gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Geometry::Geometry() {
|
||||
}
|
||||
|
||||
|
@ -148,4 +229,3 @@ Geometry::~Geometry() {
|
|||
void Geometry::setMesh(const MeshPointer& mesh) {
|
||||
_mesh = mesh;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,10 @@ typedef AABox Box;
|
|||
typedef std::vector< Box > Boxes;
|
||||
typedef glm::vec3 Vec3;
|
||||
|
||||
class Mesh;
|
||||
using MeshPointer = std::shared_ptr< Mesh >;
|
||||
|
||||
|
||||
class Mesh {
|
||||
public:
|
||||
const static Index PRIMITIVE_RESTART_INDEX = -1;
|
||||
|
@ -114,6 +118,11 @@ public:
|
|||
|
||||
static gpu::Primitive topologyToPrimitive(Topology topo) { return static_cast<gpu::Primitive>(topo); }
|
||||
|
||||
// create a copy of this mesh after passing its vertices, normals, and indexes though the provided functions
|
||||
MeshPointer map(std::function<glm::vec3(glm::vec3)> vertexFunc,
|
||||
std::function<glm::vec3(glm::vec3)> normalFunc,
|
||||
std::function<uint32_t(uint32_t)> indexFunc);
|
||||
|
||||
protected:
|
||||
|
||||
gpu::Stream::FormatPointer _vertexFormat;
|
||||
|
@ -130,7 +139,6 @@ protected:
|
|||
void evalVertexStream();
|
||||
|
||||
};
|
||||
using MeshPointer = std::shared_ptr< Mesh >;
|
||||
|
||||
|
||||
class Geometry {
|
||||
|
|
|
@ -151,84 +151,105 @@ QScriptValue ModelScriptingInterface::appendMeshes(MeshProxyList in) {
|
|||
}
|
||||
|
||||
|
||||
// QScriptValue ModelScriptingInterface::transformMesh(glm::mat4 transform, MeshProxy* meshProxy) {
|
||||
// int attributeTypeNormal = gpu::Stream::InputSlot::NORMAL; // libraries/gpu/src/gpu/Stream.h
|
||||
|
||||
// if (!meshProxy) {
|
||||
// return QScriptValue(false);
|
||||
// }
|
||||
|
||||
// MeshPointer mesh = meshProxy->getMeshPointer();
|
||||
|
||||
// gpu::Resource::Size vertexSize = mesh->getNumVertices() * sizeof(glm::vec3);
|
||||
// unsigned char* resultVertexData = new unsigned char[vertexSize];
|
||||
// unsigned char* vertexDataCursor = resultVertexData;
|
||||
|
||||
// gpu::Resource::Size normalSize = mesh->getNumAttributes() * sizeof(glm::vec3);
|
||||
// unsigned char* resultNormalData = new unsigned char[normalSize];
|
||||
// unsigned char* normalDataCursor = resultNormalData;
|
||||
|
||||
// gpu::Resource::Size indexSize = mesh->getNumIndices() * sizeof(uint32_t);
|
||||
// unsigned char* resultIndexData = new unsigned char[indexSize];
|
||||
// unsigned char* indexDataCursor = resultIndexData;
|
||||
|
||||
// // vertex data
|
||||
// const gpu::BufferView& vertexBufferView = mesh->getVertexBuffer();
|
||||
// gpu::BufferView::Index numVertices = (gpu::BufferView::Index)mesh->getNumVertices();
|
||||
// for (gpu::BufferView::Index i = 0; i < numVertices; i ++) {
|
||||
// glm::vec3 pos = vertexBufferView.get<glm::vec3>(i);
|
||||
// pos = glm::vec3(transform * glm::vec4(pos, 1.0f));
|
||||
// memcpy(vertexDataCursor, &pos, sizeof(pos));
|
||||
// vertexDataCursor += sizeof(pos);
|
||||
// }
|
||||
|
||||
// // normal data
|
||||
// const gpu::BufferView& normalsBufferView = mesh->getAttributeBuffer(attributeTypeNormal);
|
||||
// gpu::BufferView::Index numNormals = (gpu::BufferView::Index)mesh->getNumAttributes();
|
||||
// for (gpu::BufferView::Index i = 0; i < numNormals; i ++) {
|
||||
// glm::vec3 normal = normalsBufferView.get<glm::vec3>(i);
|
||||
// normal = glm::vec3(transform * glm::vec4(normal, 0.0f));
|
||||
// memcpy(normalDataCursor, &normal, sizeof(normal));
|
||||
// normalDataCursor += sizeof(normal);
|
||||
// }
|
||||
// // TODO -- other attributes
|
||||
|
||||
// // face data
|
||||
// const gpu::BufferView& indexBufferView = mesh->getIndexBuffer();
|
||||
// gpu::BufferView::Index numIndexes = (gpu::BufferView::Index)mesh->getNumIndices();
|
||||
// for (gpu::BufferView::Index i = 0; i < numIndexes; i ++) {
|
||||
// uint32_t index = indexBufferView.get<uint32_t>(i);
|
||||
// memcpy(indexDataCursor, &index, sizeof(index));
|
||||
// indexDataCursor += sizeof(index);
|
||||
// }
|
||||
|
||||
// model::MeshPointer result(new model::Mesh());
|
||||
|
||||
// gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
||||
// gpu::Buffer* resultVertexBuffer = new gpu::Buffer(vertexSize, resultVertexData);
|
||||
// gpu::BufferPointer resultVertexBufferPointer(resultVertexBuffer);
|
||||
// gpu::BufferView resultVertexBufferView(resultVertexBufferPointer, vertexElement);
|
||||
// result->setVertexBuffer(resultVertexBufferView);
|
||||
|
||||
// gpu::Element normalElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
||||
// gpu::Buffer* resultNormalsBuffer = new gpu::Buffer(normalSize, resultNormalData);
|
||||
// gpu::BufferPointer resultNormalsBufferPointer(resultNormalsBuffer);
|
||||
// gpu::BufferView resultNormalsBufferView(resultNormalsBufferPointer, normalElement);
|
||||
// result->addAttribute(attributeTypeNormal, resultNormalsBufferView);
|
||||
|
||||
// gpu::Element indexElement = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW);
|
||||
// gpu::Buffer* resultIndexesBuffer = new gpu::Buffer(indexSize, resultIndexData);
|
||||
// gpu::BufferPointer resultIndexesBufferPointer(resultIndexesBuffer);
|
||||
// gpu::BufferView resultIndexesBufferView(resultIndexesBufferPointer, indexElement);
|
||||
// result->setIndexBuffer(resultIndexesBufferView);
|
||||
|
||||
|
||||
// std::vector<model::Mesh::Part> parts;
|
||||
// parts.emplace_back(model::Mesh::Part((model::Index)0, // startIndex
|
||||
// (model::Index)result->getNumIndices(), // numIndices
|
||||
// (model::Index)0, // baseVertex
|
||||
// model::Mesh::TRIANGLES)); // topology
|
||||
// result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part),
|
||||
// (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
|
||||
|
||||
|
||||
|
||||
// MeshProxy* resultProxy = new MeshProxy(result);
|
||||
// return meshToScriptValue(_modelScriptEngine, resultProxy);
|
||||
// }
|
||||
|
||||
|
||||
QScriptValue ModelScriptingInterface::transformMesh(glm::mat4 transform, MeshProxy* meshProxy) {
|
||||
int attributeTypeNormal = gpu::Stream::InputSlot::NORMAL; // libraries/gpu/src/gpu/Stream.h
|
||||
|
||||
if (!meshProxy) {
|
||||
return QScriptValue(false);
|
||||
}
|
||||
MeshPointer mesh = meshProxy->getMeshPointer();
|
||||
|
||||
gpu::Resource::Size vertexSize = mesh->getNumVertices() * sizeof(glm::vec3);
|
||||
unsigned char* resultVertexData = new unsigned char[vertexSize];
|
||||
unsigned char* vertexDataCursor = resultVertexData;
|
||||
|
||||
gpu::Resource::Size normalSize = mesh->getNumAttributes() * sizeof(glm::vec3);
|
||||
unsigned char* resultNormalData = new unsigned char[normalSize];
|
||||
unsigned char* normalDataCursor = resultNormalData;
|
||||
|
||||
gpu::Resource::Size indexSize = mesh->getNumIndices() * sizeof(uint32_t);
|
||||
unsigned char* resultIndexData = new unsigned char[indexSize];
|
||||
unsigned char* indexDataCursor = resultIndexData;
|
||||
|
||||
// vertex data
|
||||
const gpu::BufferView& vertexBufferView = mesh->getVertexBuffer();
|
||||
gpu::BufferView::Index numVertices = (gpu::BufferView::Index)mesh->getNumVertices();
|
||||
for (gpu::BufferView::Index i = 0; i < numVertices; i ++) {
|
||||
glm::vec3 pos = vertexBufferView.get<glm::vec3>(i);
|
||||
pos = glm::vec3(transform * glm::vec4(pos, 0.0f));
|
||||
memcpy(vertexDataCursor, &pos, sizeof(pos));
|
||||
vertexDataCursor += sizeof(pos);
|
||||
if (!mesh) {
|
||||
return QScriptValue(false);
|
||||
}
|
||||
|
||||
// normal data
|
||||
const gpu::BufferView& normalsBufferView = mesh->getAttributeBuffer(attributeTypeNormal);
|
||||
gpu::BufferView::Index numNormals = (gpu::BufferView::Index)mesh->getNumAttributes();
|
||||
for (gpu::BufferView::Index i = 0; i < numNormals; i ++) {
|
||||
glm::vec3 normal = normalsBufferView.get<glm::vec3>(i);
|
||||
normal = glm::vec3(transform * glm::vec4(normal, 0.0f));
|
||||
memcpy(normalDataCursor, &normal, sizeof(normal));
|
||||
normalDataCursor += sizeof(normal);
|
||||
}
|
||||
// TODO -- other attributes
|
||||
|
||||
// face data
|
||||
const gpu::BufferView& indexBufferView = mesh->getIndexBuffer();
|
||||
gpu::BufferView::Index numIndexes = (gpu::BufferView::Index)mesh->getNumIndices();
|
||||
for (gpu::BufferView::Index i = 0; i < numIndexes; i ++) {
|
||||
uint32_t index = indexBufferView.get<uint32_t>(i);
|
||||
memcpy(indexDataCursor, &index, sizeof(index));
|
||||
indexDataCursor += sizeof(index);
|
||||
}
|
||||
|
||||
model::MeshPointer result(new model::Mesh());
|
||||
|
||||
gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
||||
gpu::Buffer* resultVertexBuffer = new gpu::Buffer(vertexSize, resultVertexData);
|
||||
gpu::BufferPointer resultVertexBufferPointer(resultVertexBuffer);
|
||||
gpu::BufferView resultVertexBufferView(resultVertexBufferPointer, vertexElement);
|
||||
result->setVertexBuffer(resultVertexBufferView);
|
||||
|
||||
gpu::Element normalElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
||||
gpu::Buffer* resultNormalsBuffer = new gpu::Buffer(normalSize, resultNormalData);
|
||||
gpu::BufferPointer resultNormalsBufferPointer(resultNormalsBuffer);
|
||||
gpu::BufferView resultNormalsBufferView(resultNormalsBufferPointer, normalElement);
|
||||
result->addAttribute(attributeTypeNormal, resultNormalsBufferView);
|
||||
|
||||
gpu::Element indexElement = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW);
|
||||
gpu::Buffer* resultIndexesBuffer = new gpu::Buffer(indexSize, resultIndexData);
|
||||
gpu::BufferPointer resultIndexesBufferPointer(resultIndexesBuffer);
|
||||
gpu::BufferView resultIndexesBufferView(resultIndexesBufferPointer, indexElement);
|
||||
result->setIndexBuffer(resultIndexesBufferView);
|
||||
|
||||
|
||||
std::vector<model::Mesh::Part> parts;
|
||||
parts.emplace_back(model::Mesh::Part((model::Index)0, // startIndex
|
||||
(model::Index)result->getNumIndices(), // numIndices
|
||||
(model::Index)0, // baseVertex
|
||||
model::Mesh::TRIANGLES)); // topology
|
||||
result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part),
|
||||
(gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
|
||||
|
||||
|
||||
|
||||
model::MeshPointer result = mesh->map([&](glm::vec3 position){ return glm::vec3(transform * glm::vec4(position, 1.0f)); },
|
||||
[&](glm::vec3 normal){ return glm::vec3(transform * glm::vec4(normal, 0.0f)); },
|
||||
[&](uint32_t index){ return index; });
|
||||
MeshProxy* resultProxy = new MeshProxy(result);
|
||||
return meshToScriptValue(_modelScriptEngine, resultProxy);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue