Getting rid of the NetworkMEshPart and simplifying the thinking around the MOdel regarding its RenderItems

This commit is contained in:
Sam Gateau 2015-08-28 08:12:50 -07:00
parent 4f7b857130
commit 85f230bf17
4 changed files with 82 additions and 126 deletions

View file

@ -1761,15 +1761,14 @@ bool NetworkGeometry::isLoadedWithTextures() const {
if (!isLoaded()) {
return false;
}
if (!_isLoadedWithTextures) {
for (auto&& mesh : _meshes) {
for (auto && part : mesh->_parts) {
if ((part->diffuseTexture && !part->diffuseTexture->isLoaded()) ||
(part->normalTexture && !part->normalTexture->isLoaded()) ||
(part->specularTexture && !part->specularTexture->isLoaded()) ||
(part->emissiveTexture && !part->emissiveTexture->isLoaded())) {
return false;
}
for (auto&& material : _materials) {
if ((material->diffuseTexture && !material->diffuseTexture->isLoaded()) ||
(material->normalTexture && !material->normalTexture->isLoaded()) ||
(material->specularTexture && !material->specularTexture->isLoaded()) ||
(material->emissiveTexture && !material->emissiveTexture->isLoaded())) {
return false;
}
}
_isLoadedWithTextures = true;
@ -1778,8 +1777,23 @@ bool NetworkGeometry::isLoadedWithTextures() const {
}
void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& url) {
if (_meshes.size() > 0) {
auto textureCache = DependencyManager::get<TextureCache>();
for (auto&& material : _materials) {
QSharedPointer<NetworkTexture> matchingTexture = QSharedPointer<NetworkTexture>();
if (material->diffuseTextureName == name) {
material->diffuseTexture = textureCache->getTexture(url, DEFAULT_TEXTURE, /* _geometry->meshes[i].isEye*/ false);
} else if (material->normalTextureName == name) {
material->normalTexture = textureCache->getTexture(url);
} else if (material->specularTextureName == name) {
material->specularTexture = textureCache->getTexture(url);
} else if (material->emissiveTextureName == name) {
material->emissiveTexture = textureCache->getTexture(url);
}
}
/*
for (size_t i = 0; i < _meshes.size(); i++) {
NetworkMesh& mesh = *(_meshes[i].get());
for (size_t j = 0; j < mesh._parts.size(); j++) {
@ -1795,7 +1809,7 @@ void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& u
part.emissiveTexture = textureCache->getTexture(url);
}
}
}
}*/
} else {
qCWarning(renderutils) << "Ignoring setTextureWirthNameToURL() geometry not ready." << name << url;
}
@ -1804,7 +1818,28 @@ void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& u
QStringList NetworkGeometry::getTextureNames() const {
QStringList result;
for (size_t i = 0; i < _meshes.size(); i++) {
for (auto&& material : _materials) {
if (!material->diffuseTextureName.isEmpty() && material->diffuseTexture) {
QString textureURL = material->diffuseTexture->getURL().toString();
result << material->diffuseTextureName + ":" + textureURL;
}
if (!material->normalTextureName.isEmpty() && material->normalTexture) {
QString textureURL = material->normalTexture->getURL().toString();
result << material->normalTextureName + ":" + textureURL;
}
if (!material->specularTextureName.isEmpty() && material->specularTexture) {
QString textureURL = material->specularTexture->getURL().toString();
result << material->specularTextureName + ":" + textureURL;
}
if (!material->emissiveTextureName.isEmpty() && material->emissiveTexture) {
QString textureURL = material->emissiveTexture->getURL().toString();
result << material->emissiveTextureName + ":" + textureURL;
}
}
/* for (size_t i = 0; i < _meshes.size(); i++) {
const NetworkMesh& mesh = *(_meshes[i].get());
for (size_t j = 0; j < mesh._parts.size(); j++) {
const NetworkMeshPart& part = *(mesh._parts[j].get());
@ -1829,7 +1864,7 @@ QStringList NetworkGeometry::getTextureNames() const {
result << part.emissiveTextureName + ":" + textureURL;
}
}
}
}*/
return result;
}
@ -1915,8 +1950,8 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas
// process network parts
foreach (const FBXMeshPart& part, mesh.parts) {
NetworkMeshPart* networkPart = new NetworkMeshPart();
/*
/* NetworkMeshPart* networkPart = new NetworkMeshPart();
if (!part.diffuseTexture.filename.isEmpty()) {
networkPart->diffuseTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(part.diffuseTexture.filename)), DEFAULT_TEXTURE,
mesh.isEye, part.diffuseTexture.content);
@ -1937,8 +1972,9 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas
false, part.emissiveTexture.content);
networkPart->emissiveTextureName = part.emissiveTexture.name;
checkForTexcoordLightmap = true;
}*/
}
networkMesh->_parts.emplace_back(networkPart);
*/
totalIndices += (part.quadIndices.size() + part.triangleIndices.size());
}
@ -2151,25 +2187,3 @@ const NetworkMaterial* NetworkGeometry::getShapeMaterial(int shapeID) {
}
}
bool NetworkMeshPart::isTranslucent() const {
return diffuseTexture && diffuseTexture->isTranslucent();
}
bool NetworkMesh::isPartTranslucent(const FBXMesh& fbxMesh, int partIndex) const {
assert(partIndex >= 0);
assert((size_t)partIndex < _parts.size());
// return (_parts.at(partIndex)->isTranslucent() || fbxMesh.parts.at(partIndex).opacity != 1.0f);
// TODO FIX That
return (_parts.at(partIndex)->isTranslucent());
}
int NetworkMesh::getTranslucentPartCount(const FBXMesh& fbxMesh) const {
int count = 0;
for (size_t i = 0; i < _parts.size(); i++) {
if (isPartTranslucent(fbxMesh, i)) {
count++;
}
}
return count;
}

View file

@ -338,7 +338,7 @@ public:
// model::MeshPointer getShapeMesh(int shapeID);
// int getShapePart(int shapeID);
// THis would be the finale verison
// This would be the final verison
// model::MaterialPointer getShapeMaterial(int shapeID);
const NetworkMaterial* getShapeMaterial(int shapeID);
@ -442,21 +442,6 @@ public:
glm::vec2 _emissiveParams;
};
/// The state associated with a single mesh part.
class NetworkMeshPart {
public:
QString diffuseTextureName;
QSharedPointer<NetworkTexture> diffuseTexture;
QString normalTextureName;
QSharedPointer<NetworkTexture> normalTexture;
QString specularTextureName;
QSharedPointer<NetworkTexture> specularTexture;
QString emissiveTextureName;
QSharedPointer<NetworkTexture> emissiveTexture;
bool isTranslucent() const;
};
/// The state associated with a single mesh.
class NetworkMesh {
@ -468,8 +453,6 @@ public:
gpu::Stream::FormatPointer _vertexFormat;
std::vector<std::unique_ptr<NetworkMeshPart>> _parts;
int getTranslucentPartCount(const FBXMesh& fbxMesh) const;
bool isPartTranslucent(const FBXMesh& fbxMesh, int partIndex) const;
};

View file

@ -761,13 +761,12 @@ public:
/* MeshPartPayload(bool transparent, Model* model, int meshIndex, int partIndex) :
transparent(transparent), model(model), url(model->getURL()), meshIndex(meshIndex), partIndex(partIndex) { }
*/
MeshPartPayload(bool transparent, Model* model, int meshIndex, int partIndex, int shapeIndex) :
transparent(transparent), model(model), url(model->getURL()), meshIndex(meshIndex), partIndex(partIndex), _shapeID(shapeIndex) { }
MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex) :
model(model), url(model->getURL()), meshIndex(meshIndex), partIndex(partIndex), _shapeID(shapeIndex) { }
typedef render::Payload<MeshPartPayload> Payload;
typedef Payload::DataPointer Pointer;
bool transparent;
Model* model;
QUrl url;
int meshIndex;
@ -783,7 +782,21 @@ namespace render {
if (!payload->model->isVisible()) {
return ItemKey::Builder().withInvisible().build();
}
return payload->transparent ? ItemKey::Builder::transparentShape() : ItemKey::Builder::opaqueShape();
auto geometry = payload->model->getGeometry();
if (!geometry.isNull()) {
auto drawMaterial = geometry->getShapeMaterial(payload->_shapeID);
if (drawMaterial) {
auto matKey = drawMaterial->_material->getKey();
if (matKey.isTransparent() || matKey.isTransparentMap()) {
return ItemKey::Builder::transparentShape();
} else {
return ItemKey::Builder::opaqueShape();
}
}
}
// Return opaque for lack of a better idea
return ItemKey::Builder::opaqueShape();
}
template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) {
@ -794,8 +807,7 @@ namespace render {
}
template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args) {
if (args) {
// return payload->model->renderPart(args, payload->meshIndex, payload->partIndex, payload->transparent);
return payload->model->renderPart(args, payload->meshIndex, payload->partIndex, payload->transparent, payload->_shapeID);
return payload->model->renderPart(args, payload->meshIndex, payload->partIndex, payload->_shapeID);
}
}
@ -824,16 +836,7 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, render::PendingChan
bool somethingAdded = false;
foreach (auto renderItem, _transparentRenderItems) {
auto item = scene->allocateID();
auto renderData = MeshPartPayload::Pointer(renderItem);
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderData);
pendingChanges.resetItem(item, renderPayload);
_renderItems.insert(item, renderPayload);
somethingAdded = true;
}
foreach (auto renderItem, _opaqueRenderItems) {
foreach (auto renderItem, _renderItemsSet) {
auto item = scene->allocateID();
auto renderData = MeshPartPayload::Pointer(renderItem);
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderData);
@ -854,17 +857,7 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, render::PendingChan
bool somethingAdded = false;
foreach (auto renderItem, _transparentRenderItems) {
auto item = scene->allocateID();
auto renderData = MeshPartPayload::Pointer(renderItem);
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderData);
renderPayload->addStatusGetters(statusGetters);
pendingChanges.resetItem(item, renderPayload);
_renderItems.insert(item, renderPayload);
somethingAdded = true;
}
foreach (auto renderItem, _opaqueRenderItems) {
foreach (auto renderItem, _renderItemsSet) {
auto item = scene->allocateID();
auto renderData = MeshPartPayload::Pointer(renderItem);
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderData);
@ -1456,7 +1449,7 @@ AABox Model::getPartBounds(int meshIndex, int partIndex) {
return AABox();
}
void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool translucent, int shapeID) {
void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID) {
//void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool translucent) {
// PROFILE_RANGE(__FUNCTION__);
PerformanceTimer perfTimer("Model::renderPart");
@ -1607,11 +1600,10 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
}
// guard against partially loaded meshes
if (partIndex >= (int)networkMesh._parts.size() || partIndex >= mesh.parts.size()) {
if (/*partIndex >= (int)networkMesh._parts.size() ||*/ partIndex >= mesh.parts.size()) {
return;
}
const NetworkMeshPart& networkPart = *(networkMesh._parts.at(partIndex).get());
const FBXMeshPart& part = mesh.parts.at(partIndex);
//model::MaterialPointer material = part._material;
@ -1637,7 +1629,6 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
batch.setUniformBuffer(locations->materialBufferUnit, material->getSchemaBuffer());
}
//Texture* diffuseMap = networkPart.diffuseTexture.data();
Texture* diffuseMap = drawMaterial->diffuseTexture.data();
if (mesh.isEye && diffuseMap) {
// FIXME - guard against out of bounds here
@ -1656,12 +1647,6 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
if (locations->texcoordMatrices >= 0) {
glm::mat4 texcoordTransform[2];
/* if (!part.diffuseTexture.transform.isIdentity()) {
part.diffuseTexture.transform.getMatrix(texcoordTransform[0]);
}
if (!part.emissiveTexture.transform.isIdentity()) {
part.emissiveTexture.transform.getMatrix(texcoordTransform[1]);
}*/
if (!drawMaterial->_diffuseTexTransform.isIdentity()) {
drawMaterial->_diffuseTexTransform.getMatrix(texcoordTransform[0]);
}
@ -1673,13 +1658,13 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
}
if (!mesh.tangents.isEmpty()) {
NetworkTexture* normalMap = networkPart.normalTexture.data();
NetworkTexture* normalMap = drawMaterial->normalTexture.data();
batch.setResourceTexture(1, (!normalMap || !normalMap->isLoaded()) ?
textureCache->getBlueTexture() : normalMap->getGPUTexture());
}
if (locations->specularTextureUnit >= 0) {
NetworkTexture* specularMap = networkPart.specularTexture.data();
NetworkTexture* specularMap = drawMaterial->specularTexture.data();
batch.setResourceTexture(locations->specularTextureUnit, (!specularMap || !specularMap->isLoaded()) ?
textureCache->getBlackTexture() : specularMap->getGPUTexture());
}
@ -1698,12 +1683,12 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
float emissiveScale = drawMaterial->_emissiveParams.y;
batch._glUniform2f(locations->emissiveParams, emissiveOffset, emissiveScale);
NetworkTexture* emissiveMap = networkPart.emissiveTexture.data();
NetworkTexture* emissiveMap = drawMaterial->emissiveTexture.data();
batch.setResourceTexture(locations->emissiveTextureUnit, (!emissiveMap || !emissiveMap->isLoaded()) ?
textureCache->getGrayTexture() : emissiveMap->getGPUTexture());
}
if (translucent && locations->lightBufferUnit >= 0) {
if (translucentMesh && locations->lightBufferUnit >= 0) {
DependencyManager::get<DeferredLightingEffect>()->setupTransparent(args, locations->lightBufferUnit);
}
}
@ -1749,8 +1734,7 @@ void Model::segregateMeshGroups() {
return;
}
_transparentRenderItems.clear();
_opaqueRenderItems.clear();
_renderItemsSet.clear();
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
int shapeID = 0;
@ -1759,25 +1743,10 @@ void Model::segregateMeshGroups() {
const FBXMesh& mesh = geometry.meshes.at(i);
const MeshState& state = _meshStates.at(i);
bool translucentMesh = networkMesh.getTranslucentPartCount(mesh) == (int)networkMesh._parts.size();
bool hasTangents = !mesh.tangents.isEmpty();
bool hasSpecular = mesh.hasSpecularTexture();
bool hasLightmap = mesh.hasEmissiveTexture();
bool isSkinned = state.clusterMatrices.size() > 1;
bool wireframe = isWireframe();
if (wireframe) {
translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
}
// Create the render payloads
int totalParts = mesh.parts.size();
for (int partIndex = 0; partIndex < totalParts; partIndex++) {
if (networkMesh.isPartTranslucent(mesh, partIndex)) {
_transparentRenderItems << std::make_shared<MeshPartPayload>(true, this, i, partIndex, shapeID);
} else {
_opaqueRenderItems << std::make_shared<MeshPartPayload>(false, this, i, partIndex, shapeID);
}
_renderItemsSet << std::make_shared<MeshPartPayload>(this, i, partIndex, shapeID);
shapeID++;
}
}
@ -1827,15 +1796,7 @@ bool Model::initWhenReady(render::ScenePointer scene) {
render::PendingChanges pendingChanges;
foreach (auto renderItem, _transparentRenderItems) {
auto item = scene->allocateID();
auto renderData = MeshPartPayload::Pointer(renderItem);
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderData);
_renderItems.insert(item, renderPayload);
pendingChanges.resetItem(item, renderPayload);
}
foreach (auto renderItem, _opaqueRenderItems) {
foreach (auto renderItem, _renderItemsSet) {
auto item = scene->allocateID();
auto renderData = MeshPartPayload::Pointer(renderItem);
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderData);

View file

@ -90,8 +90,7 @@ public:
bool isVisible() const { return _isVisible; }
AABox getPartBounds(int meshIndex, int partIndex);
void renderPart(RenderArgs* args, int meshIndex, int partIndex, bool translucent, int shapeID);
// void renderPart(RenderArgs* args, int meshIndex, int partIndex, bool translucent);
void renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID);
bool maybeStartBlender();
@ -487,8 +486,7 @@ private:
bool _renderCollisionHull;
QSet<std::shared_ptr<MeshPartPayload>> _transparentRenderItems;
QSet<std::shared_ptr<MeshPartPayload>> _opaqueRenderItems;
QSet<std::shared_ptr<MeshPartPayload>> _renderItemsSet;
QMap<render::ItemID, render::PayloadPointer> _renderItems;
bool _readyWhenAdded = false;
bool _needsReload = true;