mirror of https://github.com/axmolengine/axmol.git
parent
8493c4579b
commit
e4bbfad773
|
@ -72,27 +72,6 @@ void getChildMap(std::map<int, std::vector<int> >& map, SkinData* skinData, cons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getChildMapT(std::map<std::string, std::vector<std::string> >& map, const SkinData* skinData, const rapidjson::Value& val)
|
|
||||||
{
|
|
||||||
if (!skinData)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!val.HasMember("children"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string parent_name = val["id"].GetString();
|
|
||||||
const rapidjson::Value& children = val["children"];
|
|
||||||
for (rapidjson::SizeType i = 0; i < children.Size(); i++)
|
|
||||||
{
|
|
||||||
const rapidjson::Value& child = children[i];
|
|
||||||
std::string child_name = child["id"].GetString();
|
|
||||||
|
|
||||||
map[parent_name].push_back(child_name);
|
|
||||||
|
|
||||||
getChildMapT(map, skinData, child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bundle3D* Bundle3D::_instance = nullptr;
|
Bundle3D* Bundle3D::_instance = nullptr;
|
||||||
|
|
||||||
Bundle3D* Bundle3D::getInstance()
|
Bundle3D* Bundle3D::getInstance()
|
||||||
|
@ -107,39 +86,109 @@ void Bundle3D::purgeBundle3D()
|
||||||
CC_SAFE_DELETE(_instance);
|
CC_SAFE_DELETE(_instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bundle3D::clearBuffer()
|
||||||
|
{
|
||||||
|
CC_SAFE_DELETE_ARRAY(_jsonBuffer);
|
||||||
|
CC_SAFE_DELETE(_binaryBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
bool Bundle3D::load(const std::string& path)
|
bool Bundle3D::load(const std::string& path)
|
||||||
{
|
{
|
||||||
return loadBinary(path);//
|
|
||||||
|
|
||||||
if (_path == path)
|
if (_path == path)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
getModelPath(path);
|
getModelRelativePath(path);
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
std::string ext = path.substr(path.length() - 4, 4);
|
||||||
|
std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
||||||
|
if (ext == ".c3t")
|
||||||
|
{
|
||||||
|
_isBinary = false;
|
||||||
|
ret = loadJson(path);
|
||||||
|
}
|
||||||
|
else if (ext == ".c3b")
|
||||||
|
{
|
||||||
|
_isBinary = true;
|
||||||
|
ret = loadBinary(path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCLOGINFO("%s is invalid file formate", path);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret?(_path = path):(_path = "");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Bundle3D::loadMeshData(const std::string& id, MeshData* meshdata)
|
||||||
|
{
|
||||||
|
if (_isBinary)
|
||||||
|
{
|
||||||
|
return loadMeshDataBinary(meshdata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return loadMeshDataJson(meshdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Bundle3D::loadSkinData(const std::string& id, SkinData* skindata)
|
||||||
|
{
|
||||||
|
if (_isBinary)
|
||||||
|
{
|
||||||
|
return loadSkinDataBinary(skindata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return loadSkinDataJson(skindata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Bundle3D::loadMaterialData(const std::string& id, MaterialData* materialdata)
|
||||||
|
{
|
||||||
|
if (_isBinary)
|
||||||
|
{
|
||||||
|
return loadMaterialDataBinary(materialdata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return loadMaterialDataJson(materialdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Bundle3D::loadAnimationData(const std::string& id, Animation3DData* animationdata)
|
||||||
|
{
|
||||||
|
if (_isBinary)
|
||||||
|
{
|
||||||
|
return loadAnimationDataBinary(animationdata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return loadAnimationDataJson(animationdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Bundle3D::loadJson(const std::string& path)
|
||||||
|
{
|
||||||
std::string strFileString = FileUtils::getInstance()->getStringFromFile(path);
|
std::string strFileString = FileUtils::getInstance()->getStringFromFile(path);
|
||||||
ssize_t size = strFileString.length();
|
ssize_t size = strFileString.length();
|
||||||
CC_SAFE_DELETE_ARRAY(_documentBuffer);
|
CC_SAFE_DELETE_ARRAY(_jsonBuffer);
|
||||||
_documentBuffer = new char[size + 1];
|
_jsonBuffer = new char[size + 1];
|
||||||
memcpy(_documentBuffer, strFileString.c_str(), size);
|
memcpy(_jsonBuffer, strFileString.c_str(), size);
|
||||||
_documentBuffer[size] = '\0';
|
_jsonBuffer[size] = '\0';
|
||||||
if (_document.ParseInsitu<0>(_documentBuffer).HasParseError())
|
if (_document.ParseInsitu<0>(_jsonBuffer).HasParseError())
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
CC_SAFE_DELETE_ARRAY(_documentBuffer);
|
CC_SAFE_DELETE_ARRAY(_jsonBuffer);
|
||||||
_path = "";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_path = path;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
bool Bundle3D::loadMeshDataJson(MeshData* meshdata)
|
||||||
* load mesh data from bundle
|
|
||||||
* @param id The ID of the mesh, load the first Mesh in the bundle if it is empty
|
|
||||||
*/
|
|
||||||
bool Bundle3D::loadMeshData(const std::string& id, MeshData* meshdata)
|
|
||||||
{
|
{
|
||||||
return loadMeshDataBinary(meshdata);
|
|
||||||
|
|
||||||
meshdata->resetData();
|
meshdata->resetData();
|
||||||
|
|
||||||
assert(_document.HasMember("mesh"));
|
assert(_document.HasMember("mesh"));
|
||||||
|
@ -182,7 +231,7 @@ bool Bundle3D::loadMeshData(const std::string& id, MeshData* meshdata)
|
||||||
const rapidjson::Value& mesh_vertex_attribute_val = mesh_vertex_attribute[i];
|
const rapidjson::Value& mesh_vertex_attribute_val = mesh_vertex_attribute[i];
|
||||||
|
|
||||||
meshdata->attribs[i].size = mesh_vertex_attribute_val["size"].GetUint();
|
meshdata->attribs[i].size = mesh_vertex_attribute_val["size"].GetUint();
|
||||||
meshdata->attribs[i].attribSizeBytes = meshdata->attribs[i].size * parseGLTypeSize(mesh_vertex_attribute_val["type"].GetString());
|
meshdata->attribs[i].attribSizeBytes = meshdata->attribs[i].size * 4;
|
||||||
meshdata->attribs[i].type = parseGLType(mesh_vertex_attribute_val["type"].GetString());
|
meshdata->attribs[i].type = parseGLType(mesh_vertex_attribute_val["type"].GetString());
|
||||||
meshdata->attribs[i].vertexAttrib = parseGLProgramAttribute(mesh_vertex_attribute_val["attribute"].GetString());
|
meshdata->attribs[i].vertexAttrib = parseGLProgramAttribute(mesh_vertex_attribute_val["attribute"].GetString());
|
||||||
}
|
}
|
||||||
|
@ -195,7 +244,7 @@ bool Bundle3D::loadMeshData(const std::string& id, MeshData* meshdata)
|
||||||
* load skin data from bundle
|
* load skin data from bundle
|
||||||
* @param id The ID of the skin, load the first Skin in the bundle if it is empty
|
* @param id The ID of the skin, load the first Skin in the bundle if it is empty
|
||||||
*/
|
*/
|
||||||
bool Bundle3D::loadSkinData(const std::string& id, SkinData* skindata)
|
bool Bundle3D::loadSkinDataJson(SkinData* skindata)
|
||||||
{
|
{
|
||||||
if (!_document.HasMember("skin")) return false;
|
if (!_document.HasMember("skin")) return false;
|
||||||
|
|
||||||
|
@ -236,7 +285,7 @@ bool Bundle3D::loadSkinData(const std::string& id, SkinData* skindata)
|
||||||
* load material data from bundle
|
* load material data from bundle
|
||||||
* @param id The ID of the material, load the first Material in the bundle if it is empty
|
* @param id The ID of the material, load the first Material in the bundle if it is empty
|
||||||
*/
|
*/
|
||||||
bool Bundle3D::loadMaterialData(const std::string& id, MaterialData* materialdata)
|
bool Bundle3D::loadMaterialDataJson(MaterialData* materialdata)
|
||||||
{
|
{
|
||||||
if (!_document.HasMember("material"))
|
if (!_document.HasMember("material"))
|
||||||
return false;
|
return false;
|
||||||
|
@ -258,7 +307,7 @@ bool Bundle3D::loadMaterialData(const std::string& id, MaterialData* materialdat
|
||||||
* load material data from bundle
|
* load material data from bundle
|
||||||
* @param id The ID of the animation, load the first animation in the bundle if it is empty
|
* @param id The ID of the animation, load the first animation in the bundle if it is empty
|
||||||
*/
|
*/
|
||||||
bool Bundle3D::loadAnimationData(const std::string& id, Animation3DData* animationdata)
|
bool Bundle3D::loadAnimationDataJson(Animation3DData* animationdata)
|
||||||
{
|
{
|
||||||
if (!_document.HasMember("animation")) return false;
|
if (!_document.HasMember("animation")) return false;
|
||||||
|
|
||||||
|
@ -319,31 +368,26 @@ bool Bundle3D::loadAnimationData(const std::string& id, Animation3DData* animati
|
||||||
|
|
||||||
bool Bundle3D::loadBinary(const std::string& path)
|
bool Bundle3D::loadBinary(const std::string& path)
|
||||||
{
|
{
|
||||||
if (_path == path)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// get file data
|
// get file data
|
||||||
CC_SAFE_DELETE(_data);
|
CC_SAFE_DELETE(_binaryBuffer);
|
||||||
_data = new Data();
|
_binaryBuffer = new Data();
|
||||||
*_data = FileUtils::getInstance()->getDataFromFile(path);
|
*_binaryBuffer = FileUtils::getInstance()->getDataFromFile(path);
|
||||||
if (_data->isNull())
|
if (_binaryBuffer->isNull())
|
||||||
{
|
{
|
||||||
_path = "";
|
CCLOGINFO(false, "Failed to read file: %s", path.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create bundle reader
|
||||||
CC_SAFE_DELETE(_bundleReader);
|
CC_SAFE_DELETE(_bundleReader);
|
||||||
_bundleReader = BundleReader::create((char*)_data->getBytes(), _data->getSize());
|
_bundleReader = BundleReader::create((char*)_binaryBuffer->getBytes(), _binaryBuffer->getSize());
|
||||||
|
|
||||||
|
// Read identifier info
|
||||||
char identifier[] = { 'C', '3', 'B', '\0'};
|
char identifier[] = { 'C', '3', 'B', '\0'};
|
||||||
|
|
||||||
// Read header info
|
|
||||||
char sig[4];
|
char sig[4];
|
||||||
|
|
||||||
if (_bundleReader->read(sig, 1, 4) != 4 || memcmp(sig, identifier, 4) != 0)
|
if (_bundleReader->read(sig, 1, 4) != 4 || memcmp(sig, identifier, 4) != 0)
|
||||||
{
|
{
|
||||||
_path = "";
|
CCLOGINFO(false, "Invalid identifier: %s", path.c_str());
|
||||||
CCLOGINFO(false, "Invalid header: %s", path.c_str());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,99 +395,48 @@ bool Bundle3D::loadBinary(const std::string& path)
|
||||||
unsigned char ver[2];
|
unsigned char ver[2];
|
||||||
if (_bundleReader->read(ver, 1, 2) != 2 || ver[0] != 0 || ver[1] != 1)
|
if (_bundleReader->read(ver, 1, 2) != 2 || ver[0] != 0 || ver[1] != 1)
|
||||||
{
|
{
|
||||||
_path = "";
|
|
||||||
CCLOGINFO(false, "Unsupported version: (%d, %d)", ver[0], ver[1]);
|
CCLOGINFO(false, "Unsupported version: (%d, %d)", ver[0], ver[1]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read has skin
|
|
||||||
unsigned char isSkin;
|
|
||||||
if (!_bundleReader->read(&isSkin))
|
|
||||||
{
|
|
||||||
_path = "";
|
|
||||||
CCLOGINFO(false, "Invalid bundle header");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//// Read ref table
|
|
||||||
|
|
||||||
// Read ref table size
|
// Read ref table size
|
||||||
unsigned int refCount;
|
if (_bundleReader->read(&_referenceCount, 4, 1) != 1)
|
||||||
if (_bundleReader->read(&refCount, 4, 1) != 1)
|
|
||||||
{
|
{
|
||||||
_path = "";
|
|
||||||
CCLOGINFO("Failed to read ref table size '%s'.", path.c_str());
|
CCLOGINFO("Failed to read ref table size '%s'.", path.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_referenceCount = refCount;
|
|
||||||
|
|
||||||
// Read all refs
|
// Read all refs
|
||||||
CC_SAFE_DELETE_ARRAY(_references);
|
CC_SAFE_DELETE_ARRAY(_references);
|
||||||
_references = new Reference[refCount];
|
_references = new Reference[_referenceCount];
|
||||||
for (unsigned int i = 0; i < refCount; ++i)
|
for (unsigned int i = 0; i < _referenceCount; ++i)
|
||||||
{
|
{
|
||||||
if ((_references[i].id = _bundleReader->readString()).empty() ||
|
if ((_references[i].id = _bundleReader->readString()).empty() ||
|
||||||
_bundleReader->read(&_references[i].type, 4, 1) != 1 ||
|
_bundleReader->read(&_references[i].type, 4, 1) != 1 ||
|
||||||
_bundleReader->read(&_references[i].offset, 4, 1) != 1)
|
_bundleReader->read(&_references[i].offset, 4, 1) != 1)
|
||||||
{
|
{
|
||||||
_path = "";
|
|
||||||
CCLOGINFO("Failed to read ref number %d for bundle '%s'.", i, path.c_str());
|
CCLOGINFO("Failed to read ref number %d for bundle '%s'.", i, path.c_str());
|
||||||
CC_SAFE_DELETE_ARRAY(_references);
|
CC_SAFE_DELETE_ARRAY(_references);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
seekToFirstType(BUNDLE_TYPE_MESH);
|
|
||||||
|
|
||||||
/*unsigned int childrenCount;
|
|
||||||
if (!_bundleReader->read(&childrenCount))
|
|
||||||
{
|
|
||||||
_path = "";
|
|
||||||
CCLOGINFO("Failed to read childrenCount '%s'.", path.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int nodeType;
|
|
||||||
_bundleReader->read(&nodeType);
|
|
||||||
|
|
||||||
float transform[16];
|
|
||||||
if(_bundleReader->read(transform, sizeof(float), 16) != 16)
|
|
||||||
{
|
|
||||||
_path = "";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::string parentName = _bundleReader->readString();
|
|
||||||
|
|
||||||
if (!_bundleReader->read(&childrenCount))
|
|
||||||
{
|
|
||||||
_path = "";
|
|
||||||
CCLOGINFO("Failed to read childrenCount '%s'.", path.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char hasMesh;
|
|
||||||
_bundleReader->read(&hasMesh);
|
|
||||||
|
|
||||||
unsigned char hasMorph;
|
|
||||||
_bundleReader->read(&hasMorph);
|
|
||||||
|
|
||||||
unsigned char hasSkin;
|
|
||||||
_bundleReader->read(&hasSkin);
|
|
||||||
|
|
||||||
unsigned char hasMaterial;
|
|
||||||
_bundleReader->read(&hasMaterial);*/
|
|
||||||
|
|
||||||
_path = path;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bundle3D::loadMeshDataBinary(MeshData* meshdata)
|
bool Bundle3D::loadMeshDataBinary(MeshData* meshdata)
|
||||||
{
|
{
|
||||||
|
if (!seekToFirstType(BUNDLE_TYPE_MESH))
|
||||||
|
return false;
|
||||||
|
|
||||||
meshdata->resetData();
|
meshdata->resetData();
|
||||||
|
|
||||||
// read mesh data
|
// read mesh data
|
||||||
if (_bundleReader->read(&meshdata->attribCount, 4, 1) != 1 || meshdata->attribCount < 1)
|
if (_bundleReader->read(&meshdata->attribCount, 4, 1) != 1 || meshdata->attribCount < 1)
|
||||||
|
{
|
||||||
|
CCLOGINFO("Failed to read meshdata: attribCount '%s'.", _path.c_str());
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
meshdata->attribs.resize(meshdata->attribCount);
|
meshdata->attribs.resize(meshdata->attribCount);
|
||||||
for (ssize_t i = 0; i < meshdata->attribCount; i++)
|
for (ssize_t i = 0; i < meshdata->attribCount; i++)
|
||||||
|
@ -451,6 +444,7 @@ bool Bundle3D::loadMeshDataBinary(MeshData* meshdata)
|
||||||
unsigned int vUsage, vSize;
|
unsigned int vUsage, vSize;
|
||||||
if (_bundleReader->read(&vUsage, 4, 1) != 1 || _bundleReader->read(&vSize, 4, 1) != 1)
|
if (_bundleReader->read(&vUsage, 4, 1) != 1 || _bundleReader->read(&vSize, 4, 1) != 1)
|
||||||
{
|
{
|
||||||
|
CCLOGINFO("Failed to read meshdata: usage or size '%s'.", _path.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,37 +457,35 @@ bool Bundle3D::loadMeshDataBinary(MeshData* meshdata)
|
||||||
// Read vertex data
|
// Read vertex data
|
||||||
if (_bundleReader->read(&meshdata->vertexSizeInFloat, 4, 1) != 1 || meshdata->vertexSizeInFloat == 0)
|
if (_bundleReader->read(&meshdata->vertexSizeInFloat, 4, 1) != 1 || meshdata->vertexSizeInFloat == 0)
|
||||||
{
|
{
|
||||||
|
CCLOGINFO("Failed to read meshdata: vertexSizeInFloat '%s'.", _path.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
meshdata->vertex.resize(meshdata->vertexSizeInFloat);
|
meshdata->vertex.resize(meshdata->vertexSizeInFloat);
|
||||||
if (_bundleReader->read(&meshdata->vertex, 4, meshdata->vertexSizeInFloat) != meshdata->vertexSizeInFloat)
|
if (_bundleReader->read(&meshdata->vertex[0], 4, meshdata->vertexSizeInFloat) != meshdata->vertexSizeInFloat)
|
||||||
{
|
{
|
||||||
|
CCLOGINFO("Failed to read meshdata: vertex element '%s'.", _path.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read index data
|
// Read index data
|
||||||
unsigned int meshPartCount;
|
unsigned int meshPartCount = 1;
|
||||||
if (_bundleReader->read(&meshPartCount, 4, 1) != 1)
|
//_bundleReader->read(&meshPartCount, 4, 1);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < meshPartCount; ++i)
|
for (unsigned int i = 0; i < meshPartCount; ++i)
|
||||||
{
|
{
|
||||||
// Read primitive type, index format and index count
|
unsigned int nIndexCount;
|
||||||
unsigned int pType, iFormat, iByteCount;
|
if (_bundleReader->read(&nIndexCount, 4, 1) != 1)
|
||||||
if (_bundleReader->read(&pType, 4, 1) != 1 ||
|
|
||||||
_bundleReader->read(&iFormat, 4, 1) != 1 ||
|
|
||||||
_bundleReader->read(&iByteCount, 4, 1) != 1)
|
|
||||||
{
|
{
|
||||||
|
CCLOGINFO("Failed to read meshdata: nIndexCount '%s'.", _path.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
meshdata->numIndex = iByteCount / 4;
|
meshdata->numIndex = nIndexCount;
|
||||||
|
meshdata->indices.resize(meshdata->numIndex);
|
||||||
if (_bundleReader->read(&meshdata->indices, 2, iByteCount) != iByteCount)
|
if (_bundleReader->read(&meshdata->indices[0], 2, meshdata->numIndex) != nIndexCount)
|
||||||
{
|
{
|
||||||
|
CCLOGINFO("Failed to read meshdata: indices '%s'.", _path.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -501,42 +493,160 @@ bool Bundle3D::loadMeshDataBinary(MeshData* meshdata)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bundle3D::loadMeshSkin(SkinData* skindata)
|
bool Bundle3D::loadSkinDataBinary(SkinData* skindata)
|
||||||
{
|
{
|
||||||
|
if (!seekToFirstType(BUNDLE_TYPE_MESHSKIN))
|
||||||
|
return false;
|
||||||
|
|
||||||
skindata->resetData();
|
skindata->resetData();
|
||||||
|
|
||||||
// bind shape
|
// transform
|
||||||
float bindShape[16];
|
float bindShape[16];
|
||||||
_bundleReader->readMatrix(bindShape);
|
if (!_bundleReader->readMatrix(bindShape))
|
||||||
|
{
|
||||||
|
CCLOGINFO("Failed to read SkinData: bindShape matrix '%s'.", _path.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int jointCount;
|
// bone count
|
||||||
_bundleReader->read(&jointCount);
|
unsigned int boneNum;
|
||||||
|
if (!_bundleReader->read(&boneNum))
|
||||||
|
{
|
||||||
|
CCLOGINFO("Failed to read SkinData: boneNum '%s'.", _path.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < jointCount; i++)
|
// bone names and bind pos
|
||||||
|
float bindpos[16];
|
||||||
|
for (unsigned int i = 0; i < boneNum; i++)
|
||||||
{
|
{
|
||||||
skindata->boneNames.push_back(_bundleReader->readString());
|
skindata->boneNames.push_back(_bundleReader->readString());
|
||||||
}
|
if (!_bundleReader->readMatrix(bindpos))
|
||||||
|
|
||||||
unsigned int jointsBindPosesCount;
|
|
||||||
_bundleReader->read(&jointsBindPosesCount);
|
|
||||||
|
|
||||||
if (jointsBindPosesCount > 0)
|
|
||||||
{
|
{
|
||||||
assert(jointCount * 16 == jointsBindPosesCount);
|
CCLOGINFO("Failed to load SkinData: bindpos '%s'.", _path.c_str());
|
||||||
float m[16];
|
|
||||||
for (unsigned int i = 0; i < jointCount; i++)
|
|
||||||
{
|
|
||||||
if (!_bundleReader->readMatrix(m))
|
|
||||||
{
|
|
||||||
CCLOGINFO("Failed to load C3DMeshSkin in bundle '%s'.", _path.c_str());
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
skindata->inverseBindPoseMatrices.push_back(m);
|
skindata->inverseBindPoseMatrices.push_back(bindpos);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
skindata->rootBoneIndex = 0;//?????
|
// bind shape
|
||||||
|
bindShape[16];
|
||||||
|
_bundleReader->readMatrix(bindShape);
|
||||||
|
|
||||||
|
// read parent and child relationship map
|
||||||
|
float transform[16];
|
||||||
|
unsigned int linkNum;
|
||||||
|
_bundleReader->read(&linkNum);
|
||||||
|
for (unsigned int i = 0; i < linkNum; ++i)
|
||||||
|
{
|
||||||
|
std::string id = _bundleReader->readString();
|
||||||
|
int index = skindata->getBoneNameIndex(id);
|
||||||
|
|
||||||
|
if (index >= 0 && skindata->rootBoneIndex < 0)
|
||||||
|
skindata->rootBoneIndex = index;
|
||||||
|
|
||||||
|
std::string parentid = _bundleReader->readString();
|
||||||
|
int parentIndex = skindata->getBoneNameIndex(parentid);
|
||||||
|
|
||||||
|
if (!_bundleReader->readMatrix(transform))
|
||||||
|
{
|
||||||
|
CCLOGINFO("Failed to load SkinData: transform '%s'.", _path.c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parentIndex < 0 || index < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
skindata->boneChild[parentIndex].push_back(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Bundle3D::loadMaterialDataBinary(MaterialData* materialdata)
|
||||||
|
{
|
||||||
|
if (!seekToFirstType(BUNDLE_TYPE_MATERIAL))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string texturePath = _bundleReader->readString();
|
||||||
|
if (texturePath.empty())
|
||||||
|
{
|
||||||
|
CCLOGINFO("Failed to read Materialdata: texturePath is empty '%s'.", _path.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
materialdata->texturePath = _modelRelativePath + texturePath;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Bundle3D::loadAnimationDataBinary(Animation3DData* animationdata)
|
||||||
|
{
|
||||||
|
if (!seekToFirstType(BUNDLE_TYPE_ANIMATIONS))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
animationdata->_rotationKeys.clear();
|
||||||
|
animationdata->_scaleKeys.clear();
|
||||||
|
animationdata->_translationKeys.clear();
|
||||||
|
|
||||||
|
std::string id = _bundleReader->readString();
|
||||||
|
|
||||||
|
if (!_bundleReader->read(&animationdata->_totalTime))
|
||||||
|
{
|
||||||
|
CCLOGINFO("Failed to read AnimationData: totalTime '%s'.", _path.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int animNum;
|
||||||
|
if (!_bundleReader->read(&animNum))
|
||||||
|
{
|
||||||
|
CCLOGINFO("Failed to read AnimationData: animNum '%s'.", _path.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < animNum; ++i)
|
||||||
|
{
|
||||||
|
std::string boneName = _bundleReader->readString();
|
||||||
|
unsigned int keyframeNum;
|
||||||
|
if (!_bundleReader->read(&keyframeNum))
|
||||||
|
{
|
||||||
|
CCLOGINFO("Failed to read AnimationData: keyframeNum '%s'.", _path.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int j = 0; j < keyframeNum; ++j)
|
||||||
|
{
|
||||||
|
float keytime;
|
||||||
|
if (!_bundleReader->read(&keytime))
|
||||||
|
{
|
||||||
|
CCLOGINFO("Failed to read AnimationData: keytime '%s'.", _path.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion rotate;
|
||||||
|
if (_bundleReader->read(&rotate, 4, 4) != 4)
|
||||||
|
{
|
||||||
|
CCLOGINFO("Failed to read AnimationData: rotate '%s'.", _path.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
animationdata->_rotationKeys[boneName].push_back(Animation3DData::QuatKey(keytime, rotate));
|
||||||
|
|
||||||
|
Vec3 scale;
|
||||||
|
if (_bundleReader->read(&scale, 4, 3) != 3)
|
||||||
|
{
|
||||||
|
CCLOGINFO("Failed to read AnimationData: scale '%s'.", _path.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
animationdata->_scaleKeys[boneName].push_back(Animation3DData::Vec3Key(keytime, scale));
|
||||||
|
|
||||||
|
Vec3 position;
|
||||||
|
if (_bundleReader->read(&position, 4, 3) != 3)
|
||||||
|
{
|
||||||
|
CCLOGINFO("Failed to read AnimationData: position '%s'.", _path.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
animationdata->_translationKeys[boneName].push_back(Animation3DData::Vec3Key(keytime, position));
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,23 +667,6 @@ GLenum Bundle3D::parseGLType(const std::string& str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Bundle3D::parseGLTypeSize(const std::string& str)
|
|
||||||
{
|
|
||||||
if (str == "GL_FLOAT")
|
|
||||||
{
|
|
||||||
return sizeof(float);
|
|
||||||
}
|
|
||||||
else if (str == "GL_UNSIGNED_INT")
|
|
||||||
{
|
|
||||||
return sizeof(unsigned int);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int Bundle3D::parseGLProgramAttribute(const std::string& str)
|
unsigned int Bundle3D::parseGLProgramAttribute(const std::string& str)
|
||||||
{
|
{
|
||||||
if (str == "VERTEX_ATTRIB_POSITION")
|
if (str == "VERTEX_ATTRIB_POSITION")
|
||||||
|
@ -607,7 +700,7 @@ unsigned int Bundle3D::parseGLProgramAttribute(const std::string& str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bundle3D::getModelPath(const std::string& path)
|
void Bundle3D::getModelRelativePath(const std::string& path)
|
||||||
{
|
{
|
||||||
int index = path.find_last_of('/');
|
int index = path.find_last_of('/');
|
||||||
std::string fullModelPath;
|
std::string fullModelPath;
|
||||||
|
@ -647,21 +740,21 @@ Reference* Bundle3D::seekToFirstType(unsigned int type)
|
||||||
Bundle3D::Bundle3D()
|
Bundle3D::Bundle3D()
|
||||||
:_isBinary(false),
|
:_isBinary(false),
|
||||||
_modelRelativePath(""),
|
_modelRelativePath(""),
|
||||||
_documentBuffer(NULL),
|
_jsonBuffer(NULL),
|
||||||
_path(""),
|
_path(""),
|
||||||
_referenceCount(0),
|
_referenceCount(0),
|
||||||
_bundleReader(NULL),
|
_bundleReader(NULL),
|
||||||
_references(NULL),
|
_references(NULL),
|
||||||
_data(NULL)
|
_binaryBuffer(NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
Bundle3D::~Bundle3D()
|
Bundle3D::~Bundle3D()
|
||||||
{
|
{
|
||||||
CC_SAFE_DELETE_ARRAY(_documentBuffer);
|
CC_SAFE_DELETE_ARRAY(_jsonBuffer);
|
||||||
CC_SAFE_DELETE_ARRAY(_bundleReader);
|
CC_SAFE_DELETE_ARRAY(_bundleReader);
|
||||||
CC_SAFE_DELETE_ARRAY(_references);
|
CC_SAFE_DELETE_ARRAY(_references);
|
||||||
CC_SAFE_DELETE(_data);
|
CC_SAFE_DELETE(_binaryBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_CC_END
|
NS_CC_END
|
||||||
|
|
|
@ -51,6 +51,12 @@ public:
|
||||||
|
|
||||||
static void purgeBundle3D();
|
static void purgeBundle3D();
|
||||||
|
|
||||||
|
void clearBuffer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* load file data include .c3t and .c3b
|
||||||
|
* @param path Model path
|
||||||
|
*/
|
||||||
bool load(const std::string& path);
|
bool load(const std::string& path);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -80,22 +86,71 @@ public:
|
||||||
*/
|
*/
|
||||||
bool loadAnimationData(const std::string& id, Animation3DData* animationdata);
|
bool loadAnimationData(const std::string& id, Animation3DData* animationdata);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool loadJson(const std::string& path);
|
||||||
|
|
||||||
|
bool loadMeshDataJson(MeshData* meshdata);
|
||||||
|
|
||||||
|
bool loadSkinDataJson(SkinData* skindata);
|
||||||
|
|
||||||
|
bool loadMaterialDataJson(MaterialData* materialdata);
|
||||||
|
|
||||||
|
bool loadAnimationDataJson(Animation3DData* animationdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* load data in binary
|
||||||
|
* @param path The c3b file path
|
||||||
|
*/
|
||||||
bool loadBinary(const std::string& path);
|
bool loadBinary(const std::string& path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* load mesh data in binary
|
||||||
|
* @param meshdata The mesh data pointer
|
||||||
|
*/
|
||||||
bool loadMeshDataBinary(MeshData* meshdata);
|
bool loadMeshDataBinary(MeshData* meshdata);
|
||||||
|
|
||||||
bool loadMeshSkin(SkinData* skindata);
|
/**
|
||||||
|
* load skin data in binary
|
||||||
|
* @param skindata The skin data pointer
|
||||||
|
*/
|
||||||
|
bool loadSkinDataBinary(SkinData* skindata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* load material data in binary
|
||||||
|
* @param materialdata The material pointer
|
||||||
|
*/
|
||||||
|
bool loadMaterialDataBinary(MaterialData* materialdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* load animation data in binary
|
||||||
|
* @param animationdata The animation data pointer
|
||||||
|
*/
|
||||||
|
bool loadAnimationDataBinary(Animation3DData* animationdata);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/**
|
||||||
|
* get define data type
|
||||||
|
* @param str The type in string
|
||||||
|
*/
|
||||||
GLenum parseGLType(const std::string& str);
|
GLenum parseGLType(const std::string& str);
|
||||||
|
|
||||||
unsigned int parseGLTypeSize(const std::string& str);
|
/**
|
||||||
|
* get vertex attribute type
|
||||||
|
* @param str The type in string
|
||||||
|
*/
|
||||||
unsigned int parseGLProgramAttribute(const std::string& str);
|
unsigned int parseGLProgramAttribute(const std::string& str);
|
||||||
|
|
||||||
// get model path
|
/*
|
||||||
void getModelPath(const std::string& path);
|
* get model path
|
||||||
|
* @param str Full path of model file
|
||||||
|
*/
|
||||||
|
void getModelRelativePath(const std::string& path);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set the read position in buffer to the target type
|
||||||
|
* @param The data type
|
||||||
|
*/
|
||||||
Reference* seekToFirstType(unsigned int type);
|
Reference* seekToFirstType(unsigned int type);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -106,17 +161,14 @@ protected:
|
||||||
|
|
||||||
std::string _modelRelativePath;
|
std::string _modelRelativePath;
|
||||||
|
|
||||||
char* _documentBuffer;
|
char* _jsonBuffer;
|
||||||
std::string _path;
|
std::string _path;
|
||||||
|
|
||||||
rapidjson::Document _document;
|
rapidjson::Document _document;
|
||||||
|
|
||||||
BundleReader* _bundleReader;
|
BundleReader* _bundleReader;
|
||||||
|
|
||||||
unsigned int _referenceCount;
|
unsigned int _referenceCount;
|
||||||
Reference* _references;
|
Reference* _references;
|
||||||
|
Data* _binaryBuffer;
|
||||||
Data* _data;
|
|
||||||
|
|
||||||
bool _isBinary;
|
bool _isBinary;
|
||||||
};
|
};
|
||||||
|
|
|
@ -115,17 +115,16 @@ struct SkinData
|
||||||
|
|
||||||
int getBoneNameIndex(const std::string& name)const
|
int getBoneNameIndex(const std::string& name)const
|
||||||
{
|
{
|
||||||
std::vector<std::string>::const_iterator iter = boneNames.begin();
|
int i = 0;
|
||||||
for (int i = 0; iter != boneNames.end(); ++iter, ++i)
|
for( const auto &item : boneNames )
|
||||||
{
|
|
||||||
if ((*iter) == name)
|
|
||||||
{
|
{
|
||||||
|
if (item == name)
|
||||||
return i;
|
return i;
|
||||||
}
|
else
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MaterialData
|
struct MaterialData
|
||||||
|
|
|
@ -35,15 +35,25 @@
|
||||||
NS_CC_BEGIN
|
NS_CC_BEGIN
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stream is an interface for reading and writing a sequence of bytes.
|
* BundleReader is an interface for reading sequence of bytes.
|
||||||
*/
|
*/
|
||||||
class BundleReader: public cocos2d::Ref
|
class BundleReader: public cocos2d::Ref
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
~BundleReader();
|
~BundleReader();
|
||||||
|
|
||||||
|
/** creates an BundleReader with lpbuffer and length
|
||||||
|
* @param lpbuffer The pointer to the file data
|
||||||
|
* @param length The size for lpbuffer in bytes
|
||||||
|
*/
|
||||||
static BundleReader* create(char* lpbuffer, unsigned int length);
|
static BundleReader* create(char* lpbuffer, unsigned int length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close and delete buffer
|
||||||
|
*/
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,7 +69,7 @@ public:
|
||||||
size_t read(void* ptr, size_t size, size_t count);
|
size_t read(void* ptr, size_t size, size_t count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a line from the stream.
|
* Reads a line from the buffer.
|
||||||
*/
|
*/
|
||||||
char* readLine(int num, char* line);
|
char* readLine(int num, char* line);
|
||||||
|
|
||||||
|
@ -75,12 +85,12 @@ public:
|
||||||
size_t write(const void* ptr, size_t size, size_t count);
|
size_t write(const void* ptr, size_t size, size_t count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the end of the stream has been reached.
|
* Returns true if the end of the buffer has been reached.
|
||||||
*/
|
*/
|
||||||
bool eof();
|
bool eof();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the length of the stream in bytes.
|
* Returns the length of the buffer in bytes.
|
||||||
*/
|
*/
|
||||||
size_t length();
|
size_t length();
|
||||||
|
|
||||||
|
|
|
@ -541,7 +541,7 @@ std::string Sprite3DWithSkinTest::subtitle() const
|
||||||
|
|
||||||
void Sprite3DWithSkinTest::addNewSpriteWithCoords(Vec2 p)
|
void Sprite3DWithSkinTest::addNewSpriteWithCoords(Vec2 p)
|
||||||
{
|
{
|
||||||
std::string fileName = "Sprite3DTest/girl.c3b";/*"Sprite3DTest/tianguang.c3b"*/
|
std::string fileName = "Sprite3DTest/scene.c3b";
|
||||||
auto sprite = Sprite3D::create(fileName);
|
auto sprite = Sprite3D::create(fileName);
|
||||||
addChild(sprite);
|
addChild(sprite);
|
||||||
sprite->setRotation3D(Vec3(-90.f, 0.f, 0.f));
|
sprite->setRotation3D(Vec3(-90.f, 0.f, 0.f));
|
||||||
|
|
Loading…
Reference in New Issue