only animate a single primitive
This commit is contained in:
@@ -83,8 +83,10 @@ static void* freeResourceGlobal(void* mem, size_t size, void* misc) {
|
|||||||
if(!_viewer)
|
if(!_viewer)
|
||||||
return;
|
return;
|
||||||
_viewer->manipulator->grabEnd();
|
_viewer->manipulator->grabEnd();
|
||||||
|
} else if([@"releaseSourceAssets" isEqualToString:call.method]) {
|
||||||
|
_viewer->releaseSourceAssets();
|
||||||
} else if([@"createMorpher" isEqualToString:call.method]) {
|
} else if([@"createMorpher" isEqualToString:call.method]) {
|
||||||
_viewer->createMorpher([call.arguments[0] UTF8String], [call.arguments[1] UTF8String],[call.arguments[2] UTF8String]);
|
_viewer->createMorpher([call.arguments[0] UTF8String], [call.arguments[1] intValue]);
|
||||||
} else if([@"getTargetNames" isEqualToString:call.method]) {
|
} else if([@"getTargetNames" isEqualToString:call.method]) {
|
||||||
mimetic::StringList list = _viewer->getTargetNames([call.arguments UTF8String]);
|
mimetic::StringList list = _viewer->getTargetNames([call.arguments UTF8String]);
|
||||||
NSMutableArray* asArray = [NSMutableArray arrayWithCapacity:list.count];
|
NSMutableArray* asArray = [NSMutableArray arrayWithCapacity:list.count];
|
||||||
@@ -96,15 +98,13 @@ static void* freeResourceGlobal(void* mem, size_t size, void* misc) {
|
|||||||
if(!_viewer)
|
if(!_viewer)
|
||||||
return;
|
return;
|
||||||
NSArray* nWeights = call.arguments[0];
|
NSArray* nWeights = call.arguments[0];
|
||||||
NSNumber* nPrimitiveIndex = call.arguments[1];
|
|
||||||
int primitiveIndex = [nPrimitiveIndex intValue];
|
|
||||||
|
|
||||||
int count = [nWeights count];
|
int count = [nWeights count];
|
||||||
float weights[count];
|
float weights[count];
|
||||||
for(int i=0; i < count; i++) {
|
for(int i=0; i < count; i++) {
|
||||||
weights[i] = [nWeights[i] floatValue];
|
weights[i] = [nWeights[i] floatValue];
|
||||||
}
|
}
|
||||||
_viewer->morphHelper->applyWeights(weights, count, primitiveIndex);
|
_viewer->morphHelper->applyWeights(weights, count);
|
||||||
} else if([@"zoom" isEqualToString:call.method]) {
|
} else if([@"zoom" isEqualToString:call.method]) {
|
||||||
if(!_viewer)
|
if(!_viewer)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -142,11 +142,14 @@ void FilamentViewer::loadResources(string relativeResourcePath) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_animator = _asset->getAnimator();
|
_animator = _asset->getAnimator();
|
||||||
// _asset->releaseSourceData(); // we need to wait until the Morpher is created to release the source data
|
|
||||||
|
|
||||||
_scene->addEntities(_asset->getEntities(), _asset->getEntityCount());
|
_scene->addEntities(_asset->getEntities(), _asset->getEntityCount());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void FilamentViewer::releaseSourceAssets() {
|
||||||
|
_asset->releaseSourceData();
|
||||||
|
}
|
||||||
|
|
||||||
void FilamentViewer::loadGltf(const char* const uri, const char* const relativeResourcePath) {
|
void FilamentViewer::loadGltf(const char* const uri, const char* const relativeResourcePath) {
|
||||||
if(_asset) {
|
if(_asset) {
|
||||||
_resourceLoader->evictResourceData();
|
_resourceLoader->evictResourceData();
|
||||||
@@ -192,8 +195,8 @@ StringList FilamentViewer::getTargetNames(const char* meshName) {
|
|||||||
return StringList(nullptr, 0);
|
return StringList(nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilamentViewer::createMorpher(const char* meshName, const char* entityName, const char* materialInstanceName) {
|
void FilamentViewer::createMorpher(const char* meshName, int primitiveIndex) {
|
||||||
morphHelper = new gltfio::GPUMorphHelper((FFilamentAsset*)_asset, meshName, entityName, materialInstanceName);
|
morphHelper = new gltfio::GPUMorphHelper((FFilamentAsset*)_asset, meshName, primitiveIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ namespace mimetic {
|
|||||||
void loadSkybox(const char* const skyboxUri, const char* const iblUri);
|
void loadSkybox(const char* const skyboxUri, const char* const iblUri);
|
||||||
void updateViewportAndCameraProjection(int height, int width, float scaleFactor);
|
void updateViewportAndCameraProjection(int height, int width, float scaleFactor);
|
||||||
void render();
|
void render();
|
||||||
void createMorpher(const char* meshName, const char* entityName, const char* materialInstanceName);
|
void createMorpher(const char* meshName, int primitiveIndex);
|
||||||
|
void releaseSourceAssets();
|
||||||
StringList getTargetNames(const char* meshName);
|
StringList getTargetNames(const char* meshName);
|
||||||
Manipulator<float>* manipulator;
|
Manipulator<float>* manipulator;
|
||||||
GPUMorphHelper* morphHelper;
|
GPUMorphHelper* morphHelper;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace gltfio {
|
|||||||
free(mem);
|
free(mem);
|
||||||
};
|
};
|
||||||
|
|
||||||
GPUMorphHelper::GPUMorphHelper(FFilamentAsset *asset, const char* meshName, const char* entityName, int primitiveIndex) : mAsset(asset) {
|
GPUMorphHelper::GPUMorphHelper(FFilamentAsset *asset, const char* meshName, int primitiveIndex) : mAsset(asset), mPrimitiveIndex(primitiveIndex) {
|
||||||
|
|
||||||
cgltf_size num_primitives = 0;
|
cgltf_size num_primitives = 0;
|
||||||
NodeMap &sourceNodes = asset->isInstanced() ? asset->mInstances[0]->nodeMap
|
NodeMap &sourceNodes = asset->isInstanced() ? asset->mInstances[0]->nodeMap
|
||||||
@@ -64,15 +64,13 @@ namespace gltfio {
|
|||||||
if(strcmp(meshName, mesh->name) == 0) {
|
if(strcmp(meshName, mesh->name) == 0) {
|
||||||
targetMesh = mesh;
|
targetMesh = mesh;
|
||||||
num_primitives = mesh->primitives_count;
|
num_primitives = mesh->primitives_count;
|
||||||
for (cgltf_size pi = 0, count = mesh->primitives_count; pi < count; ++pi) {
|
addPrimitive(mesh);
|
||||||
addPrimitive(mesh, pi, &mMorphTable[pair.second]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto materialInstances = mAsset->getMaterialInstances();
|
auto materialInstances = mAsset->getMaterialInstances();
|
||||||
|
|
||||||
std::cout << "Listing all material instances in asset" << std::endl;
|
std::cout << "MaterialInstances in asset:" << std::endl;
|
||||||
for(int i = 0; i < mAsset->getMaterialInstanceCount(); i++) {
|
for(int i = 0; i < mAsset->getMaterialInstanceCount(); i++) {
|
||||||
const char* name = materialInstances[i]->getName();
|
const char* name = materialInstances[i]->getName();
|
||||||
std::cout << "Material : " << name << std::endl;
|
std::cout << "Material : " << name << std::endl;
|
||||||
@@ -92,134 +90,108 @@ namespace gltfio {
|
|||||||
void GPUMorphHelper::createTextures() {
|
void GPUMorphHelper::createTextures() {
|
||||||
auto materialInstances = mAsset->getMaterialInstances();
|
auto materialInstances = mAsset->getMaterialInstances();
|
||||||
auto &engine = *(mAsset->mEngine);
|
auto &engine = *(mAsset->mEngine);
|
||||||
|
|
||||||
|
auto& prim = animatedPrimitive;
|
||||||
|
|
||||||
for (auto&& entry : mMorphTable) {
|
// for a single morph target, each vertex will be assigned 2 pixels, corresponding to a position vec3 and a normal vec3
|
||||||
std::vector<GltfPrimitive>& prims = (std::vector<GltfPrimitive>&)entry.second.primitives;
|
// these two vectors will be laid out adjacent in memory
|
||||||
for(int i = 0; i < prims.size(); i++) {
|
// the total texture "width" is the total number of these pixels
|
||||||
// prims.at(i).texture = nullptr;
|
// morph targets are then assigned to the depth channel
|
||||||
auto& prim = prims.at(i);
|
auto textureWidth = prim->numVertices * 2;
|
||||||
// }
|
|
||||||
// for (auto&& prim : entry.second.primitives) {
|
|
||||||
// for a single morph target, each vertex will be assigned 2 pixels, corresponding to a position vec3 and a normal vec3
|
|
||||||
// these two vectors will be laid out adjacent in memory
|
|
||||||
// the total texture "width" is the total number of these pixels
|
|
||||||
// morph targets are then assigned to the depth channel
|
|
||||||
auto textureWidth = prim.numVertices * 2;
|
|
||||||
|
|
||||||
// the total size of the texture in bytes
|
// the total size of the texture in bytes
|
||||||
// equal to (numVertices * numAttributes * vectorSize (3) * sizeof(float) * numMorphTargets)
|
// equal to (numVertices * numAttributes * vectorSize (3) * sizeof(float) * numMorphTargets)
|
||||||
auto textureSize = textureWidth * 3 * sizeof(float) * prim.numTargets;
|
auto textureSize = textureWidth * 3 * sizeof(float) * prim->numTargets;
|
||||||
auto textureBuffer = (float *const) malloc(textureSize);
|
auto textureBuffer = (float *const) malloc(textureSize);
|
||||||
|
|
||||||
if(!textureBuffer) {
|
if(!textureBuffer) {
|
||||||
std::cout << "Error allocating texture buffer" << std::endl;
|
std::cout << "Error allocating texture buffer" << std::endl;
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
|
|
||||||
// assume the primitive morph target source buffer is laid out like:
|
// assume the primitive morph target source buffer is laid out like:
|
||||||
// |target0_v0_pos * 3|target0_v0_norm * 3|target0_v1_pos * 3|target0_v1_norm * 3|...|target1_v0_pos * 3|target1_v0_norm * 3|target1_v1_pos * 3|target1_v1_norm * 3|...
|
// |target0_v0_pos * 3|target0_v0_norm * 3|target0_v1_pos * 3|target0_v1_norm * 3|...|target1_v0_pos * 3|target1_v0_norm * 3|target1_v1_pos * 3|target1_v1_norm * 3|...
|
||||||
// where:
|
// where:
|
||||||
// - target0/target1/etc is the first/second/etc morph target
|
// - target0/target1/etc is the first/second/etc morph target
|
||||||
// - v0/v1/etc is the first/second/etc vertex
|
// - v0/v1/etc is the first/second/etc vertex
|
||||||
// - pos/norm are each 3-float vectors
|
// - pos/norm are each 3-float vectors
|
||||||
for (auto &target : prim.targets) {
|
for (auto &target : prim->targets) {
|
||||||
if(target.type == cgltf_attribute_type_position
|
if(target.type == cgltf_attribute_type_position
|
||||||
|| target.type == cgltf_attribute_type_normal
|
|| target.type == cgltf_attribute_type_normal
|
||||||
) {
|
) {
|
||||||
memcpy(textureBuffer+offset, target.bufferObject, target.bufferSize);
|
memcpy(textureBuffer+offset, target.bufferObject, target.bufferSize);
|
||||||
offset += int(target.bufferSize / sizeof(float));
|
offset += int(target.bufferSize / sizeof(float));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture* texture = Texture::Builder()
|
|
||||||
.width(textureWidth) //
|
|
||||||
.height(1)
|
|
||||||
.depth(prim.numTargets)
|
|
||||||
.sampler(Texture::Sampler::SAMPLER_2D_ARRAY)
|
|
||||||
.format(Texture::InternalFormat::RGB32F)
|
|
||||||
.levels(0x01)
|
|
||||||
.build(engine);
|
|
||||||
|
|
||||||
prim.texture = texture; //std::unique_ptr<Texture>(texture);
|
|
||||||
|
|
||||||
Texture::PixelBufferDescriptor descriptor(
|
|
||||||
textureBuffer,
|
|
||||||
textureSize,
|
|
||||||
Texture::Format::RGB,
|
|
||||||
Texture::Type::FLOAT,
|
|
||||||
FREE_CALLBACK,
|
|
||||||
nullptr);
|
|
||||||
prim.texture->setImage(engine, 0, 0,0, 0, textureWidth, 1, prim.numTargets, std::move(descriptor));
|
|
||||||
|
|
||||||
for(int i = 0; i < mAsset->getMaterialInstanceCount(); i++) {
|
|
||||||
const char* name = materialInstances[i]->getName();
|
|
||||||
|
|
||||||
if(strcmp(name, prim.materialName) == 0) {
|
|
||||||
std::cout << "Found material instance for primitive under name : " << name << std::endl;
|
|
||||||
prim.materialInstance = materialInstances[i]; //std::unique_ptr<MaterialInstance>(materialInstances[i]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!prim.materialInstance) {
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this won't work if material instance is shared between primitives?
|
|
||||||
prim.materialInstance->setParameter("dimensions", filament::math::int3 { prim.numVertices * 2, numAttributes, prim.numTargets });
|
|
||||||
prim.materialInstance->setParameter("morphTargets", prim.texture, TextureSampler());
|
|
||||||
float weights[prim.numTargets];
|
|
||||||
memset(weights, 0, prim.numTargets * sizeof(float));
|
|
||||||
prim.materialInstance->setParameter("morphTargetWeights", weights, prim.numTargets);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Texture* texture = Texture::Builder()
|
||||||
|
.width(textureWidth) //
|
||||||
|
.height(1)
|
||||||
|
.depth(prim->numTargets)
|
||||||
|
.sampler(Texture::Sampler::SAMPLER_2D_ARRAY)
|
||||||
|
.format(Texture::InternalFormat::RGB32F)
|
||||||
|
.levels(0x01)
|
||||||
|
.build(engine);
|
||||||
|
|
||||||
|
prim->texture = texture; //std::unique_ptr<Texture>(texture);
|
||||||
|
|
||||||
|
Texture::PixelBufferDescriptor descriptor(
|
||||||
|
textureBuffer,
|
||||||
|
textureSize,
|
||||||
|
Texture::Format::RGB,
|
||||||
|
Texture::Type::FLOAT,
|
||||||
|
FREE_CALLBACK,
|
||||||
|
nullptr);
|
||||||
|
prim->texture->setImage(engine, 0, 0,0, 0, textureWidth, 1, prim->numTargets, std::move(descriptor));
|
||||||
|
|
||||||
|
for(int i = 0; i < mAsset->getMaterialInstanceCount(); i++) {
|
||||||
|
const char* name = materialInstances[i]->getName();
|
||||||
|
if(strcmp(name, prim->materialName) == 0) {
|
||||||
|
std::cout << "Found material instance for primitive under name : " << name << std::endl;
|
||||||
|
prim->materialInstance = materialInstances[i]; //std::unique_ptr<MaterialInstance>(materialInstances[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!prim->materialInstance) {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
prim->materialInstance->setParameter("dimensions", filament::math::int3 { prim->numVertices * 2, numAttributes, prim->numTargets });
|
||||||
|
prim->materialInstance->setParameter("morphTargets", prim->texture, TextureSampler());
|
||||||
|
float weights[prim->numTargets];
|
||||||
|
memset(weights, 0, prim->numTargets * sizeof(float));
|
||||||
|
prim->materialInstance->setParameter("morphTargetWeights", weights, prim->numTargets);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUMorphHelper::applyWeights(float const *weights, size_t count, int primitiveIndex) noexcept {
|
void GPUMorphHelper::applyWeights(float const *weights, size_t count) noexcept {
|
||||||
std::cout << "Applying " << count << " weights to primitive index " << primitiveIndex << std::endl;
|
std::cout << "Applying " << count << " weights " << std::endl;
|
||||||
for (auto &entry : mMorphTable) {
|
animatedPrimitive->materialInstance->setParameter("morphTargetWeights", weights, count);
|
||||||
int i = 0 ;
|
|
||||||
for (auto &prim : entry.second.primitives) {
|
|
||||||
if(i == primitiveIndex) {
|
|
||||||
if(!prim.materialInstance) {
|
|
||||||
std::cout << "Error, couldn't find material instance for primitive under name " << prim.materialName << std::endl;
|
|
||||||
} else {
|
|
||||||
prim.materialInstance->setParameter("morphTargetWeights", weights, count);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GPUMorphHelper::addPrimitive(cgltf_mesh const *mesh, int primitiveIndex, TableEntry *entry) {
|
GPUMorphHelper::addPrimitive(cgltf_mesh const *mesh) {
|
||||||
auto &engine = *mAsset->mEngine;
|
auto &engine = *mAsset->mEngine;
|
||||||
const cgltf_primitive &prim = mesh->primitives[primitiveIndex];
|
const cgltf_primitive &prim = mesh->primitives[mPrimitiveIndex];
|
||||||
|
|
||||||
const auto &gltfioPrim = mAsset->mMeshCache.at(mesh)[primitiveIndex];
|
const auto &gltfioPrim = mAsset->mMeshCache.at(mesh)[mPrimitiveIndex];
|
||||||
VertexBuffer *vertexBuffer = gltfioPrim.vertices;
|
VertexBuffer *vertexBuffer = gltfioPrim.vertices;
|
||||||
|
|
||||||
entry->primitives.push_back({vertexBuffer});
|
animatedPrimitive = std::make_unique<GltfPrimitive>(GltfPrimitive{vertexBuffer});
|
||||||
|
|
||||||
auto &morphHelperPrim = entry->primitives.back();
|
animatedPrimitive->materialName = prim.material->name;
|
||||||
morphHelperPrim.materialName = prim.material->name;
|
animatedPrimitive->numTargets = prim.targets_count;
|
||||||
morphHelperPrim.numTargets = prim.targets_count;
|
animatedPrimitive->numVertices = vertexBuffer->getVertexCount();
|
||||||
morphHelperPrim.numVertices = vertexBuffer->getVertexCount();
|
|
||||||
cgltf_size maxIndex = 0;
|
cgltf_size maxIndex = 0;
|
||||||
for(int i = 0; i < prim.indices->count; i++) {
|
for(int i = 0; i < prim.indices->count; i++) {
|
||||||
maxIndex = std::max(cgltf_accessor_read_index(prim.indices, i), maxIndex);
|
maxIndex = std::max(cgltf_accessor_read_index(prim.indices, i), maxIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Max index for primitive index " << primitiveIndex << " is " << maxIndex << " and numVertices was " << morphHelperPrim.numVertices << std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
const cgltf_accessor *previous = nullptr;
|
const cgltf_accessor *previous = nullptr;
|
||||||
|
|
||||||
// for this primitive, iterate over every target
|
// iterate over every target for the primitive,
|
||||||
for (int targetIndex = 0; targetIndex < prim.targets_count; targetIndex++) {
|
for (int targetIndex = 0; targetIndex < prim.targets_count; targetIndex++) {
|
||||||
const cgltf_morph_target &morphTarget = prim.targets[targetIndex];
|
const cgltf_morph_target &morphTarget = prim.targets[targetIndex];
|
||||||
for (cgltf_size aindex = 0; aindex < morphTarget.attributes_count; aindex++) {
|
for (cgltf_size aindex = 0; aindex < morphTarget.attributes_count; aindex++) {
|
||||||
@@ -237,10 +209,6 @@ namespace gltfio {
|
|||||||
//
|
//
|
||||||
// the texture needs to be sized according to the total number of vertices in the mesh
|
// the texture needs to be sized according to the total number of vertices in the mesh
|
||||||
// this is identified by the highest vertex index of all primitives in the mesh
|
// this is identified by the highest vertex index of all primitives in the mesh
|
||||||
//
|
|
||||||
// if(numVertices == 0)
|
|
||||||
// numVertices = accessor->count;
|
|
||||||
//assert(numVertices == accessor->count);
|
|
||||||
|
|
||||||
// All position & normal attributes must have the same data type.
|
// All position & normal attributes must have the same data type.
|
||||||
assert_invariant(
|
assert_invariant(
|
||||||
@@ -254,141 +222,10 @@ namespace gltfio {
|
|||||||
assert_invariant(bufferData);
|
assert_invariant(bufferData);
|
||||||
const uint8_t *data = computeBindingOffset(accessor) + bufferData;
|
const uint8_t *data = computeBindingOffset(accessor) + bufferData;
|
||||||
const uint32_t size = computeBindingSize(accessor);
|
const uint32_t size = computeBindingSize(accessor);
|
||||||
morphHelperPrim.targets.push_back({data, size, targetIndex, atype});
|
animatedPrimitive->targets.push_back({data, size, targetIndex, atype});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//VertexBuffer* vBuf = VertexBuffer::Builder()
|
|
||||||
// .vertexCount(numVertices)
|
|
||||||
// .bufferCount(numPrimitives)
|
|
||||||
// .attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT4, 0)
|
|
||||||
// .build(*engine);
|
|
||||||
|
|
||||||
//numIndices = maxIndex+1; */
|
|
||||||
//numIndices = prim.indices->count;
|
|
||||||
|
|
||||||
/*indicesBuffer = (uint32_t*)malloc(sizeof(unsigned int) * prim.indices->count);
|
|
||||||
|
|
||||||
//materialInstance->setParameter("vertexIndices", indicesBuffer, numIndices);
|
|
||||||
|
|
||||||
//.require(VertexAttribute::UV0)
|
|
||||||
//.require(MaterialBuilder.VertexAttribute.CUSTOM0)
|
|
||||||
//MaterialBuilder::init();
|
|
||||||
//MaterialBuilder builder = MaterialBuilder()
|
|
||||||
// .name("DefaultMaterial")
|
|
||||||
// .platform(MaterialBuilder::Platform::MOBILE)
|
|
||||||
// .targetApi(MaterialBuilder::TargetApi::ALL)
|
|
||||||
// .optimization(MaterialBuilderBase::Optimization::NONE)
|
|
||||||
// .shading(MaterialBuilder::Shading::LIT)
|
|
||||||
// .parameter(MaterialBuilder::UniformType::FLOAT3, "baseColor")
|
|
||||||
// .parameter(MaterialBuilder::UniformType::INT3, "dimensions")
|
|
||||||
// .parameter(MaterialBuilder::UniformType::FLOAT, numTargets, MaterialBuilder::ParameterPrecision::DEFAULT, "morphTargetWeights")
|
|
||||||
// .parameter(MaterialBuilder::SamplerType::SAMPLER_2D_ARRAY, MaterialBuilder::SamplerFormat::FLOAT, MaterialBuilder::ParameterPrecision::DEFAULT, "morphTargets")
|
|
||||||
// .vertexDomain(VertexDomain::WORLD)
|
|
||||||
// .material(R"SHADER(void material(inout MaterialInputs material) {
|
|
||||||
// prepareMaterial(material);
|
|
||||||
// material.baseColor.rgb = materialParams.baseColor;
|
|
||||||
// })SHADER")
|
|
||||||
// .materialVertex(R"SHADER(
|
|
||||||
// vec3 getMorphTarget(int vertexIndex, int morphTargetIndex) {
|
|
||||||
// // our texture is laid out as (x,y,z) where y is 1, z is the number of morph targets, and x is the number of vertices * 2 (multiplication accounts for position + normal)
|
|
||||||
// // UV coordinates are normalized to (-1,1), so we divide the current vertex index by the total number of vertices to find the correct coordinate for this vertex
|
|
||||||
// vec3 uv = vec3(
|
|
||||||
// (float(vertexIndex) + 0.5) / float(materialParams.dimensions.x),
|
|
||||||
// 0.0f,
|
|
||||||
// //(float(morphTargetIndex) + 0.5f) / float(materialParams.dimensions.z));
|
|
||||||
// float(morphTargetIndex));
|
|
||||||
// return texture(materialParams_morphTargets, uv).xyz;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// void materialVertex(inout MaterialVertexInputs material) {
|
|
||||||
// return;
|
|
||||||
// // for every morph target
|
|
||||||
// for(int morphTargetIndex = 0; morphTargetIndex < materialParams.dimensions.z; morphTargetIndex++) {
|
|
||||||
//
|
|
||||||
// // get the weight to apply
|
|
||||||
// float weight = materialParams.morphTargetWeights[morphTargetIndex];
|
|
||||||
//
|
|
||||||
// // get the ID of this vertex, which will be the x-offset of the position attribute in the texture sampler
|
|
||||||
// int vertexId = getVertexIndex();
|
|
||||||
//
|
|
||||||
// // get the position of the target for this vertex
|
|
||||||
// vec3 morphTargetPosition = getMorphTarget(vertexId, morphTargetIndex);
|
|
||||||
// // update the world position of this vertex
|
|
||||||
// material.worldPosition.xyz += (weight * morphTargetPosition);
|
|
||||||
//
|
|
||||||
// // increment the vertexID by half the size of the texture to get the x-offset of the normal (all positions stored in the first half, all normals stored in the second half)
|
|
||||||
//
|
|
||||||
// vertexId += (materialParams.dimensions.x / 2);
|
|
||||||
//
|
|
||||||
// // get the normal of this target for this vertex
|
|
||||||
// vec3 morphTargetNormal = getMorphTarget(vertexId, morphTargetIndex);
|
|
||||||
// material.worldNormal += (weight * morphTargetNormal);
|
|
||||||
// }
|
|
||||||
// mat4 transform = getWorldFromModelMatrix();
|
|
||||||
// material.worldPosition = mulMat4x4Float3(transform, material.worldPosition.xyz);
|
|
||||||
// })SHADER");
|
|
||||||
//
|
|
||||||
//Package pkg = builder.build(mAsset->mEngine->getJobSystem());
|
|
||||||
//Material* material = Material::Builder().package(pkg.getData(), pkg.getSize())
|
|
||||||
// .build(*mAsset->mEngine);
|
|
||||||
|
|
||||||
//size_t normal_size = sizeof(short4);
|
|
||||||
//assert(textureWidth * (position_size + normal_size) == textureSize);
|
|
||||||
//assert(textureWidth * position_size == textureSize);
|
|
||||||
/*__android_log_print(ANDROID_LOG_INFO, "MyTag", "Expected size %d width at level 0 %d height", Texture::PixelBufferDescriptor::computeDataSize(Texture::Format::RGB,
|
|
||||||
Texture::Type::FLOAT, 24, 1, 4), texture->getWidth(0),texture->getHeight(0)); */
|
|
||||||
|
|
||||||
/* Texture::PixelBufferDescriptor descriptor(
|
|
||||||
textureBuffer,
|
|
||||||
textureSize,
|
|
||||||
Texture::Format::RGB,
|
|
||||||
Texture::Type::FLOAT,
|
|
||||||
4, 0,0, 24,
|
|
||||||
FREE_CALLBACK,
|
|
||||||
nullptr); */
|
|
||||||
|
|
||||||
/*for(int i = 0; i < int(textureSize / sizeof(float)); i++) {
|
|
||||||
__android_log_print(ANDROID_LOG_INFO, "MyTag", "offset %d %f", i, *(textureBuffer+i));
|
|
||||||
//}*/
|
|
||||||
//std::cout << "Checking for " << materialInstanceName << std::endl;
|
|
||||||
//if(materialInstanceName) {
|
|
||||||
// for(int i = 0; i < asset->getMaterialInstanceCount(); i++) {
|
|
||||||
// const char* name = instances[i]->getName();
|
|
||||||
// std::cout << name << std::endl;
|
|
||||||
// if(strcmp(name, materialInstanceName) == 0) {
|
|
||||||
// materialInstance = instances[i];
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//} else {
|
|
||||||
// materialInstance = instances[0];
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//if(!materialInstance) {
|
|
||||||
// exit(-1);
|
|
||||||
//}
|
|
||||||
|
|
||||||
// std::cout << std::endl;
|
|
||||||
/* for (int i = 0; i < 4; i++) {
|
|
||||||
morphHelperPrim.positions[i] = gltfioPrim.morphPositions[i];
|
|
||||||
morphHelperPrim.tangents[i] = gltfioPrim.morphTangents[i];
|
|
||||||
} */
|
|
||||||
|
|
||||||
// applyTextures(materialInstance);
|
|
||||||
|
|
||||||
/* const Entity* entities = mAsset->getEntities();
|
|
||||||
for(int i=0; i < mAsset->getEntityCount();i++) {
|
|
||||||
std::cout << mAsset->getName(entities[i]);
|
|
||||||
} */
|
|
||||||
|
|
||||||
// Entity entity = mAsset->getFirstEntityByName(entityName);
|
|
||||||
// RenderableManager::Instance rInst = mAsset->mEngine->getRenderableManager().getInstance(entity);
|
|
||||||
// for(int i = 0; i<num_primitives;i++) {
|
|
||||||
// mAsset->mEngine->getRenderableManager().setMaterialInstanceAt(rInst, i, materialInstance);
|
|
||||||
// }
|
|
||||||
|
|||||||
@@ -42,13 +42,14 @@ namespace gltfio {
|
|||||||
public:
|
public:
|
||||||
using Entity = utils::Entity;
|
using Entity = utils::Entity;
|
||||||
|
|
||||||
GPUMorphHelper(FFilamentAsset *asset, const char* meshName, const char* entityName, const char* materialInstanceName);
|
GPUMorphHelper(FFilamentAsset *asset, const char* meshName, int primitiveIndex);
|
||||||
|
|
||||||
~GPUMorphHelper();
|
~GPUMorphHelper();
|
||||||
|
|
||||||
void applyWeights(float const *weights, size_t count, int primitiveIndex) noexcept;
|
void applyWeights(float const *weights, size_t count) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int mPrimitiveIndex;
|
||||||
struct GltfTarget {
|
struct GltfTarget {
|
||||||
const void *bufferObject;
|
const void *bufferObject;
|
||||||
uint32_t bufferSize;
|
uint32_t bufferSize;
|
||||||
@@ -58,32 +59,25 @@ namespace gltfio {
|
|||||||
|
|
||||||
struct GltfPrimitive {
|
struct GltfPrimitive {
|
||||||
filament::VertexBuffer *vertexBuffer;
|
filament::VertexBuffer *vertexBuffer;
|
||||||
// const std::unique_ptr<Texture> texture;
|
|
||||||
Texture* texture;
|
Texture* texture;
|
||||||
std::vector <GltfTarget> targets; // TODO: flatten this?
|
std::vector <GltfTarget> targets; // TODO: flatten this?
|
||||||
const char* materialName;
|
const char* materialName;
|
||||||
cgltf_size numTargets = 0;
|
cgltf_size numTargets = 0;
|
||||||
cgltf_size numVertices = 0;
|
cgltf_size numVertices = 0;
|
||||||
//const std::unique_ptr<MaterialInstance> materialInstance;
|
|
||||||
MaterialInstance* materialInstance;
|
MaterialInstance* materialInstance;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TableEntry {
|
|
||||||
std::vector <GltfPrimitive> primitives; // TODO: flatten this?
|
|
||||||
};
|
|
||||||
|
|
||||||
int numAttributes = 2; // position & normal
|
int numAttributes = 2; // position & normal
|
||||||
|
|
||||||
uint32_t* indicesBuffer = nullptr;
|
uint32_t* indicesBuffer = nullptr;
|
||||||
|
|
||||||
void addPrimitive(cgltf_mesh const *mesh, int primitiveIndex, TableEntry *entry);
|
void addPrimitive(cgltf_mesh const *mesh);
|
||||||
|
|
||||||
void createTextures();
|
void createTextures();
|
||||||
|
|
||||||
|
|
||||||
cgltf_mesh const* targetMesh;
|
cgltf_mesh const* targetMesh;
|
||||||
|
|
||||||
tsl::robin_map <Entity, TableEntry> mMorphTable;
|
|
||||||
FFilamentAsset *mAsset;
|
FFilamentAsset *mAsset;
|
||||||
|
std::unique_ptr<GltfPrimitive> animatedPrimitive;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ abstract class FilamentController {
|
|||||||
|
|
||||||
void animate(
|
void animate(
|
||||||
List<List<double>> weights, int primitiveIndex, double frameRate);
|
List<List<double>> weights, int primitiveIndex, double frameRate);
|
||||||
Future createMorpher(String meshName, String entityName,
|
Future createMorpher(String meshName, int primitiveIndex);
|
||||||
{String? materialName});
|
|
||||||
Future zoom(double z);
|
Future zoom(double z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +46,8 @@ class MimeticFilamentController extends FilamentController {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future _initialize() async {
|
Future _initialize() async {
|
||||||
print("Initializing");
|
final foo = await rootBundle.load(materialPath);
|
||||||
|
print("Initializing with material path of size ${foo.lengthInBytes}");
|
||||||
await _channel.invokeMethod("initialize", materialPath);
|
await _channel.invokeMethod("initialize", materialPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,13 +114,15 @@ class MimeticFilamentController extends FilamentController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future releaseSourceAssets() async {
|
||||||
|
await _channel.invokeMethod("releaseSourceAssets");
|
||||||
|
}
|
||||||
|
|
||||||
Future zoom(double z) async {
|
Future zoom(double z) async {
|
||||||
await _channel.invokeMethod("zoom", z);
|
await _channel.invokeMethod("zoom", z);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future createMorpher(String meshName, String entityName,
|
Future createMorpher(String meshName, int primitiveIndex) async {
|
||||||
{String? materialName}) async {
|
await _channel.invokeMethod("createMorpher", [meshName, primitiveIndex]);
|
||||||
await _channel
|
|
||||||
.invokeMethod("createMorpher", [meshName, entityName, materialName]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user