Skip to content

Commit

Permalink
https://github.com/KhronosGroup/glTF/issues/183
Browse files Browse the repository at this point in the history
  • Loading branch information
fabrobinet committed Jun 6, 2014
1 parent c95a65f commit fce6f92
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 29 deletions.
15 changes: 9 additions & 6 deletions converter/COLLADA2GLTF/COLLADA2GLTFWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ namespace GLTF
const InstanceControllerPointerArray& instanceControllers = node->getInstanceControllers();
unsigned int count = (unsigned int)instanceControllers.getCount();
if (count > 0) {
shared_ptr<JSONObject> skins = this->_asset->root()->createObjectIfNeeded("skins");
shared_ptr<JSONObject> skins = this->_asset->root()->createObjectIfNeeded(kSkins);
for (unsigned int i = 0 ; i < count; i++) {
InstanceController* instanceController = instanceControllers[i];
MaterialBindingArray &materialBindings = instanceController->getMaterialBindings();
Expand Down Expand Up @@ -1112,7 +1112,9 @@ namespace GLTF

if ( weights.getType() == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT ) {
const COLLADAFW::FloatArray* floatWeights = weights.getFloatValues();
for (size_t j = 0; j < pairCount; ++j, ++index) {


for (size_t j = 0; j < pairCount; ++j, ++index) {
if (j < bucketSize) {
bonesIndices[(i * bucketSize) + j] = (float)jointIndices[index];
weightsPtr[(i * bucketSize) + j] = (*floatWeights)[weightIndices[index]];
Expand All @@ -1130,7 +1132,7 @@ namespace GLTF
}
}
}

//inverse bind matrice
const Matrix4Array& matrices = skinControllerData->getInverseBindMatrices();
size_t matricesSize = sizeof(float) * 16 * skinControllerData->getJointsCount();
Expand Down Expand Up @@ -1170,8 +1172,9 @@ namespace GLTF
jointsAttribute->setCount(vertexCount);

glTFSkin->setJoints(jointsAttribute);

shared_ptr<JSONObject> skins = this->_asset->root()->createObjectIfNeeded("skins");
glTFSkin->setJointsCount(skinControllerData->getJointsCount());

shared_ptr<JSONObject> skins = this->_asset->root()->createObjectIfNeeded(kSkins);

//Also we work around here what looks to be a bug in OpenCOLLADA with a fileId == 0
COLLADAFW::UniqueId uniqueId = skinControllerData->getUniqueId();
Expand Down Expand Up @@ -1218,7 +1221,7 @@ namespace GLTF
COLLADAFW::SkinController* skinController = (COLLADAFW::SkinController*)controller;

//Now we get the skin and the mesh, and
shared_ptr<JSONObject> skins = this->_asset->root()->createObjectIfNeeded("skins");
shared_ptr<JSONObject> skins = this->_asset->root()->createObjectIfNeeded(kSkins);

COLLADAFW::UniqueId uniqueId = skinController->getSkinControllerData().toAscii();
if (uniqueId.getFileId() == 0) {
Expand Down
51 changes: 40 additions & 11 deletions converter/COLLADA2GLTF/GLTF/GLTFAsset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,16 +604,22 @@ namespace GLTF
}

shared_ptr<JSONObject> techniqueExtras(new JSONObject());
if ((meshExtras != nullptr) && meshExtras->contains("double_sided")) {
techniqueExtras->setBool("double_sided", meshExtras->getBool("double_sided"));
if (meshExtras != nullptr) {
if (meshExtras->contains("double_sided")) {
techniqueExtras->setBool("double_sided", meshExtras->getBool("double_sided"));
}
if (meshExtras->contains("jointsCount")) {
unsigned int jointsCount = meshExtras->getUnsignedInt32("jointsCount");
techniqueExtras->setUnsignedInt32("jointsCount", jointsCount);
}
}

if ((effectExtras != nullptr) && effectExtras->contains("double_sided")) {
techniqueExtras->setBool("double_sided", effectExtras->getBool("double_sided"));
}

//generate shaders if needed
shared_ptr <JSONObject> attributeSemantics = serializeAttributeSemanticsForPrimitiveAtIndex(mesh.get(), (unsigned int)j);

shared_ptr<JSONObject> techniqueGenerator(new JSONObject());

techniqueGenerator->setString("lightingModel", effect->getLightingModel());
Expand All @@ -622,6 +628,7 @@ namespace GLTF
techniqueGenerator->setValue("techniqueExtras", techniqueExtras);
techniqueGenerator->setValue("texcoordBindings", texcoordBindings);


effect->setTechniqueGenerator(techniqueGenerator);
effect->setName(materialName);
primitive->setMaterialID(effect->getID());
Expand Down Expand Up @@ -660,6 +667,18 @@ namespace GLTF
if (materialBindings == nullptr)
return false;

size_t jointsCount = 0;
if (node->contains(kInstanceSkin)) {
shared_ptr <JSONObject> instanceSkin = node->getObject(kInstanceSkin);
if (instanceSkin->contains(kSkin)) {
std::string skinOriginalID = instanceSkin->getString(kSkin);
shared_ptr <JSONObject> skins = this->_root->createObjectIfNeeded(kSkins);
std::vector <std::string> skinUIDs = skins->getAllKeys();
shared_ptr <GLTFSkin> skin = static_pointer_cast<GLTFSkin>(skins->getObject(skinOriginalID) );
jointsCount = skin->getJointsCount();
}
}

shared_ptr <JSONArray> meshesArray = nullptr;

MaterialBindingsForMeshUID::const_iterator materialBindingsIterator;
Expand Down Expand Up @@ -691,11 +710,16 @@ namespace GLTF
}

assert(meshesInSkinning || meshesInNode);

shared_ptr <MaterialBindingsPrimitiveMap> materialBindingsPrimitiveMap = (*materialBindingsIterator).second;

shared_ptr<JSONObject> meshExtras = this->_extras->contains(meshUID) ? this->_extras->getObject(meshUID) : nullptr;

if (jointsCount > 0) {
if (meshExtras == nullptr)
meshExtras = shared_ptr <JSONObject> (new JSONObject());
meshExtras->setUnsignedInt32("jointsCount", jointsCount);
}

shared_ptr<GLTFMesh> mesh = static_pointer_cast<GLTFMesh>(this->getValueForUniqueId(meshUID));

this->_applyMaterialBindings(mesh, materialBindingsPrimitiveMap, meshesArray, meshExtras);
Expand Down Expand Up @@ -783,6 +807,17 @@ namespace GLTF
}
}

// ----
shared_ptr <GLTF::JSONObject> skins = this->_root->createObjectIfNeeded(kSkins);
std::vector <std::string> skinsUIDs = skins->getAllKeys();
for (size_t skinIndex = 0 ; skinIndex < skinsUIDs.size() ; skinIndex++) {
shared_ptr <GLTFSkin> skin = static_pointer_cast<GLTFSkin>(skins->getObject(skinsUIDs[skinIndex]));
skins->setValue(skin->getId(), skin);
skins->removeValue(skinsUIDs[skinIndex]);
}
//we change the keys...
skinsUIDs = skins->getAllKeys();

//Handle late binding of material in node
//So we go through all nodes and if a mesh got different bindings than the ones needed we clone the "reference" mesh and assign the binding
//we delay this operation to now, so that we get the reference mesh splitted.
Expand Down Expand Up @@ -932,11 +967,7 @@ namespace GLTF
}

// ----
shared_ptr <GLTF::JSONObject> skins = this->_root->createObjectIfNeeded("skins");
std::vector <std::string> skinsUIDs = skins->getAllKeys();

for (size_t skinIndex = 0 ; skinIndex < skinsUIDs.size() ; skinIndex++) {

shared_ptr <GLTFSkin> skin = static_pointer_cast<GLTFSkin>(skins->getObject(skinsUIDs[skinIndex]));
shared_ptr<JSONArray> joints = skin->getJointsIds();
shared_ptr<JSONArray> jointsWithOriginalSids(new JSONArray());
Expand All @@ -954,8 +985,6 @@ namespace GLTF
shared_ptr <JSONObject> inverseBindMatrices = static_pointer_cast<JSONObject>(skin->extras()->getValue(kInverseBindMatrices));
inverseBindMatrices->setString(kBufferView, genericBufferView->getID());
skin->setValue(kInverseBindMatrices, inverseBindMatrices);
skins->setValue(skin->getId(), skin);
skins->removeValue(skinsUIDs[skinIndex]);
}

// ----
Expand Down
12 changes: 10 additions & 2 deletions converter/COLLADA2GLTF/GLTF/GLTFSkin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ namespace GLTF

//--- Skin

GLTFSkin::GLTFSkin() : GLTFController() {
GLTFSkin::GLTFSkin() : GLTFController(), _jointsCount(0) {
this->_id = GLTFUtils::generateIDForType(kSkin.c_str());
}

GLTFSkin::GLTFSkin(std::string id) : GLTFController() {
GLTFSkin::GLTFSkin(std::string id) : GLTFController(), _jointsCount(0) {
this->_id = id;
}

Expand Down Expand Up @@ -114,4 +114,12 @@ namespace GLTF
return this->_inverseBindMatrices;
}

void GLTFSkin::setJointsCount(size_t count) {
this->_jointsCount = count;
}

size_t GLTFSkin::getJointsCount() {
return this->_jointsCount;
}

};
5 changes: 5 additions & 0 deletions converter/COLLADA2GLTF/GLTF/GLTFSkin.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ namespace GLTF
//controller
std::string getType();

void setJointsCount(size_t count);
size_t getJointsCount();

private:
std::shared_ptr <GLTFBufferView> _inverseBindMatrices;

Expand All @@ -75,6 +78,8 @@ namespace GLTF

std::string _id;
std::string _sourceUID;

size_t _jointsCount;
};
}

Expand Down
1 change: 1 addition & 0 deletions converter/COLLADA2GLTF/GLTF/GLTFTypesAndConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ const std::string kChildren = "children";
const std::string kSources = "sources";
const std::string kSource = "source";
const std::string kSkin = "skin";
const std::string kSkins = "skins";
const std::string kInstanceSkin = "instanceSkin";
const std::string kImages = "images";
const std::string kImage = "image";
Expand Down
35 changes: 25 additions & 10 deletions converter/COLLADA2GLTF/shaders/commonProfileShaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ namespace GLTF
*/
static std::string buildTechniqueHash(shared_ptr<JSONObject> parameters, shared_ptr<JSONObject> techniqueExtras, GLTFAsset* asset) {
std::string techniqueHash = "";
bool doubleSided = false;
unsigned int jointsCount = 0;

techniqueHash += buildSlotHash(parameters, "diffuse", asset);
techniqueHash += buildSlotHash(parameters, "ambient", asset);
Expand All @@ -271,8 +273,13 @@ namespace GLTF
techniqueHash += buildSlotHash(parameters, "reflective", asset);
//techniqueHash += buildLightsHash(parameters, techniqueExtras, context);

if (techniqueExtras)
techniqueHash += "double_sided:" + GLTFUtils::toString(techniqueExtras->getBool("double_sided"));
if (techniqueExtras) {
jointsCount = techniqueExtras->getUnsignedInt32("jointsCount");
doubleSided = techniqueExtras->getBool("double_sided");
}

techniqueHash += "double_sided:" + GLTFUtils::toString(doubleSided);
techniqueHash += "jointsCount:" + GLTFUtils::toString(jointsCount);
techniqueHash += "opaque:"+ GLTFUtils::toString(isOpaque(parameters, asset));
techniqueHash += "hasTransparency:"+ GLTFUtils::toString(hasTransparency(parameters, asset));

Expand Down Expand Up @@ -671,7 +678,14 @@ namespace GLTF
bool useSimpleLambert = !(inputParameters->contains("specular") &&
inputParameters->contains("shininess"));

bool hasSkinning = attributeSemantics->contains("WEIGHT") && attributeSemantics->contains("JOINT");
unsigned int jointsCount = 0;
bool hasSkinning = false;
if (techniqueExtras != nullptr) {
jointsCount = techniqueExtras->getUnsignedInt32("jointsCount");
hasSkinning = attributeSemantics->contains("WEIGHT") &&
attributeSemantics->contains("JOINT") &&
(jointsCount > 0);
}

std::vector <std::string> allAttributes;
std::vector <std::string> allUniforms;
Expand All @@ -695,20 +709,22 @@ namespace GLTF

if (hasSkinning) {
addSemantic("vs", "attribute",
"JOINT", "joint", 1, true);
"JOINT", "joint", 1, false);
addSemantic("vs", "attribute",
"WEIGHT", "weight", 1, true);
//addValue("vs", "uniform", "FLOAT_MAT4", 60, "jointMat");
"WEIGHT", "weight", 1, false);

assert(techniqueExtras != nullptr);

addSemantic("vs", "uniform",
"JOINT_MATRIX", "jointMat", 60, false);

"JOINT_MATRIX", "jointMat", jointsCount, false);
}

if (hasNormals) {
//normal matrix
addSemantic("vs", "uniform",
MODELVIEWINVERSETRANSPOSE, "normalMatrix" , 1, false);
}

//modeliew matrix
addSemantic("vs", "uniform",
MODELVIEW, "modelViewMatrix" , 1, false);
Expand All @@ -717,8 +733,7 @@ namespace GLTF
addSemantic("vs", "uniform",
PROJECTION, "projectionMatrix" , 1, false);


/*
/*
Handle hardware skinning, for now with a fixed limit of 4 influences
*/

Expand Down

0 comments on commit fce6f92

Please sign in to comment.