before switch branch save

This commit is contained in:
lvlong 2014-06-19 15:43:02 +08:00
parent c1fd9adebf
commit 8493c4579b
8 changed files with 748 additions and 8 deletions

View File

@ -178,6 +178,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
<ClCompile Include="..\3d\CCAnimate3D.cpp" />
<ClCompile Include="..\3d\CCAnimation3D.cpp" />
<ClCompile Include="..\3d\CCBundle3D.cpp" />
<ClCompile Include="..\3d\CCBundleReader.cpp" />
<ClCompile Include="..\3d\CCMesh.cpp" />
<ClCompile Include="..\3d\CCMeshSkin.cpp" />
<ClCompile Include="..\3d\CCObjLoader.cpp" />
@ -356,6 +357,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
<ClInclude Include="..\3d\CCAnimationCurve.h" />
<ClInclude Include="..\3d\CCBundle3D.h" />
<ClInclude Include="..\3d\CCBundle3DData.h" />
<ClInclude Include="..\3d\CCBundleReader.h" />
<ClInclude Include="..\3d\CCMesh.h" />
<ClInclude Include="..\3d\CCMeshSkin.h" />
<ClInclude Include="..\3d\CCObjLoader.h" />

View File

@ -580,6 +580,9 @@
<ClCompile Include="..\3d\CCSprite3DMaterial.cpp">
<Filter>3d</Filter>
</ClCompile>
<ClCompile Include="..\3d\CCBundleReader.cpp">
<Filter>3d</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\physics\CCPhysicsBody.h">
@ -1180,6 +1183,9 @@
<ClInclude Include="..\3d\CCSprite3DMaterial.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\3d\CCBundleReader.h">
<Filter>3d</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\math\Mat4.inl">

View File

@ -26,8 +26,22 @@
#include "base/ccMacros.h"
#include "platform/CCFileUtils.h"
#include "CCBundleReader.h"
#include "base/CCData.h"
#define BUNDLE_TYPE_SCENE 1
#define BUNDLE_TYPE_NODE 2
#define BUNDLE_TYPE_ANIMATIONS 3
#define BUNDLE_TYPE_ANIMATION 4
#define BUNDLE_TYPE_ANIMATION_CHANNEL 5
#define BUNDLE_TYPE_MODEL 10
#define BUNDLE_TYPE_MATERIAL 16
#define BUNDLE_TYPE_EFFECT 18
#define BUNDLE_TYPE_CAMERA 32
#define BUNDLE_TYPE_LIGHT 33
#define BUNDLE_TYPE_MESH 34
#define BUNDLE_TYPE_MESHPART 35
#define BUNDLE_TYPE_MESHSKIN 36
NS_CC_BEGIN
@ -95,6 +109,8 @@ void Bundle3D::purgeBundle3D()
bool Bundle3D::load(const std::string& path)
{
return loadBinary(path);//
if (_path == path)
return true;
@ -122,6 +138,8 @@ bool Bundle3D::load(const std::string& path)
*/
bool Bundle3D::loadMeshData(const std::string& id, MeshData* meshdata)
{
return loadMeshDataBinary(meshdata);
meshdata->resetData();
assert(_document.HasMember("mesh"));
@ -168,7 +186,7 @@ bool Bundle3D::loadMeshData(const std::string& id, MeshData* meshdata)
meshdata->attribs[i].type = parseGLType(mesh_vertex_attribute_val["type"].GetString());
meshdata->attribs[i].vertexAttrib = parseGLProgramAttribute(mesh_vertex_attribute_val["attribute"].GetString());
}
return true;
}
@ -299,6 +317,229 @@ bool Bundle3D::loadAnimationData(const std::string& id, Animation3DData* animati
return true;
}
bool Bundle3D::loadBinary(const std::string& path)
{
if (_path == path)
return true;
// get file data
CC_SAFE_DELETE(_data);
_data = new Data();
*_data = FileUtils::getInstance()->getDataFromFile(path);
if (_data->isNull())
{
_path = "";
return false;
}
CC_SAFE_DELETE(_bundleReader);
_bundleReader = BundleReader::create((char*)_data->getBytes(), _data->getSize());
char identifier[] = { 'C', '3', 'B', '\0'};
// Read header info
char sig[4];
if (_bundleReader->read(sig, 1, 4) != 4 || memcmp(sig, identifier, 4) != 0)
{
_path = "";
CCLOGINFO(false, "Invalid header: %s", path.c_str());
return false;
}
// Read version
unsigned char ver[2];
if (_bundleReader->read(ver, 1, 2) != 2 || ver[0] != 0 || ver[1] != 1)
{
_path = "";
CCLOGINFO(false, "Unsupported version: (%d, %d)", ver[0], ver[1]);
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
unsigned int refCount;
if (_bundleReader->read(&refCount, 4, 1) != 1)
{
_path = "";
CCLOGINFO("Failed to read ref table size '%s'.", path.c_str());
return false;
}
_referenceCount = refCount;
// Read all refs
CC_SAFE_DELETE_ARRAY(_references);
_references = new Reference[refCount];
for (unsigned int i = 0; i < refCount; ++i)
{
if ((_references[i].id = _bundleReader->readString()).empty() ||
_bundleReader->read(&_references[i].type, 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());
CC_SAFE_DELETE_ARRAY(_references);
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;
}
bool Bundle3D::loadMeshDataBinary(MeshData* meshdata)
{
meshdata->resetData();
// read mesh data
if (_bundleReader->read(&meshdata->attribCount, 4, 1) != 1 || meshdata->attribCount < 1)
return false;
meshdata->attribs.resize(meshdata->attribCount);
for (ssize_t i = 0; i < meshdata->attribCount; i++)
{
unsigned int vUsage, vSize;
if (_bundleReader->read(&vUsage, 4, 1) != 1 || _bundleReader->read(&vSize, 4, 1) != 1)
{
return false;
}
meshdata->attribs[i].size = vSize;
meshdata->attribs[i].attribSizeBytes = meshdata->attribs[i].size * 4;
meshdata->attribs[i].type = GL_FLOAT;
meshdata->attribs[i].vertexAttrib = vUsage;
}
// Read vertex data
if (_bundleReader->read(&meshdata->vertexSizeInFloat, 4, 1) != 1 || meshdata->vertexSizeInFloat == 0)
{
return false;
}
meshdata->vertex.resize(meshdata->vertexSizeInFloat);
if (_bundleReader->read(&meshdata->vertex, 4, meshdata->vertexSizeInFloat) != meshdata->vertexSizeInFloat)
{
return false;
}
// Read index data
unsigned int meshPartCount;
if (_bundleReader->read(&meshPartCount, 4, 1) != 1)
{
return false;
}
for (unsigned int i = 0; i < meshPartCount; ++i)
{
// Read primitive type, index format and index count
unsigned int pType, iFormat, iByteCount;
if (_bundleReader->read(&pType, 4, 1) != 1 ||
_bundleReader->read(&iFormat, 4, 1) != 1 ||
_bundleReader->read(&iByteCount, 4, 1) != 1)
{
return false;
}
meshdata->numIndex = iByteCount / 4;
if (_bundleReader->read(&meshdata->indices, 2, iByteCount) != iByteCount)
{
return false;
}
}
return true;
}
bool Bundle3D::loadMeshSkin(SkinData* skindata)
{
skindata->resetData();
// bind shape
float bindShape[16];
_bundleReader->readMatrix(bindShape);
unsigned int jointCount;
_bundleReader->read(&jointCount);
for (unsigned int i = 0; i < jointCount; i++)
{
skindata->boneNames.push_back(_bundleReader->readString());
}
unsigned int jointsBindPosesCount;
_bundleReader->read(&jointsBindPosesCount);
if (jointsBindPosesCount > 0)
{
assert(jointCount * 16 == jointsBindPosesCount);
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;
}
skindata->inverseBindPoseMatrices.push_back(m);
}
}
skindata->rootBoneIndex = 0;//?????
return true;
}
GLenum Bundle3D::parseGLType(const std::string& str)
{
if (str == "GL_FLOAT")
@ -383,16 +624,44 @@ void Bundle3D::getModelPath(const std::string& path)
}
}
Reference* Bundle3D::seekToFirstType(unsigned int type)
{
// for each Reference
for (unsigned int i = 0; i < _referenceCount; ++i)
{
Reference* ref = &_references[i];
if (ref->type == type)
{
// Found a match
if (_bundleReader->seek(ref->offset, SEEK_SET) == false)
{
CCLOGINFO("Failed to seek to object '%s' in bundle '%s'.", ref->id.c_str(), _path.c_str());
return NULL;
}
return ref;
}
}
return NULL;
}
Bundle3D::Bundle3D()
:_isBinary(false),_modelRelativePath(""),_documentBuffer(NULL),_path("")
:_isBinary(false),
_modelRelativePath(""),
_documentBuffer(NULL),
_path(""),
_referenceCount(0),
_bundleReader(NULL),
_references(NULL),
_data(NULL)
{
}
Bundle3D::~Bundle3D()
{
CC_SAFE_DELETE_ARRAY(_documentBuffer);
CC_SAFE_DELETE_ARRAY(_bundleReader);
CC_SAFE_DELETE_ARRAY(_references);
CC_SAFE_DELETE(_data);
}
NS_CC_END

View File

@ -39,8 +39,10 @@
#include "json/document.h"
NS_CC_BEGIN
class BundleReader;
class Animation3D;
class Data;
class Bundle3D
{
public:
@ -78,6 +80,12 @@ public:
*/
bool loadAnimationData(const std::string& id, Animation3DData* animationdata);
bool loadBinary(const std::string& path);
bool loadMeshDataBinary(MeshData* meshdata);
bool loadMeshSkin(SkinData* skindata);
protected:
GLenum parseGLType(const std::string& str);
@ -88,6 +96,8 @@ protected:
// get model path
void getModelPath(const std::string& path);
Reference* seekToFirstType(unsigned int type);
protected:
Bundle3D();
~Bundle3D();
@ -101,6 +111,13 @@ protected:
rapidjson::Document _document;
BundleReader* _bundleReader;
unsigned int _referenceCount;
Reference* _references;
Data* _data;
bool _isBinary;
};

View File

@ -34,6 +34,26 @@
NS_CC_BEGIN
// vertex usage elements.
enum Vertex_Usage
{
Vertex_Usage_POSITION = 1,
Vertex_Usage_NORMAL = 2,
Vertex_Usage_COLOR = 3,
Vertex_Usage_TANGENT = 4,
Vertex_Usage_BINORMAL = 5,
Vertex_Usage_BLENDWEIGHTS = 6,
Vertex_Usage_BLENDINDICES = 7,
Vertex_Usage_TEXCOORD0 = 8,
Vertex_Usage_TEXCOORD1 = 9,
Vertex_Usage_TEXCOORD2 = 10,
Vertex_Usage_TEXCOORD3 = 11,
Vertex_Usage_TEXCOORD4 = 12,
Vertex_Usage_TEXCOORD5 = 13,
Vertex_Usage_TEXCOORD6 = 14,
Vertex_Usage_TEXCOORD7 = 15
};
//mesh vertex attribute
struct MeshVertexAttrib
{
@ -182,6 +202,17 @@ public:
}
};
class Reference
{
public:
std::string id;
unsigned int type;
unsigned int offset;
Reference(){};
~Reference(){};
};
NS_CC_END
#endif //__CC_BUNDLE_3D_DATA_H__

211
cocos/3d/CCBundleReader.cpp Normal file
View File

@ -0,0 +1,211 @@
#include "CCBundleReader.h"
#include "platform/CCFileUtils.h"
NS_CC_BEGIN
BundleReader::~BundleReader()
{
close();
};
BundleReader* BundleReader::create(char* lpbuffer, unsigned int length)
{
if (lpbuffer)
{
BundleReader* stream = new BundleReader();
stream->init(lpbuffer, length);
return stream;
}
return NULL;
}
void BundleReader::close()
{
CC_SAFE_DELETE(m_buffer);
}
size_t BundleReader::read(void* ptr, size_t size, size_t count)
{
if (!m_buffer || eof())
return 0;
size_t validCount;
size_t validLength = m_length - m_position;
size_t needLength = size*count;
char* ptr1 = (char*)ptr;
if(validLength <= needLength)
{
validCount = validLength/size;
size_t readLength = size*validCount;
memcpy(ptr1,(char*)m_buffer+m_position,readLength);
ptr1 += readLength;
m_position += readLength;
readLength = validLength - readLength;
if(readLength>0)
{
memcpy(ptr1,(char*)m_buffer+m_position,readLength);
m_position += readLength;
validCount+=1;
}
}
else
{
memcpy(ptr1,(char*)m_buffer+m_position,needLength);
m_position += needLength;
validCount = count;
}
//*ptr1 = 0;
return validCount;
}
char* BundleReader::readLine(int num,char* line)
{
if (!m_buffer)
return 0;
//char* str = new char[num];
char* buffer = (char*)m_buffer+m_position;
char* p = line;
char c;
size_t readNum = 0;
while((c=*buffer) != 10 && readNum < (size_t)num && m_position<(long int)m_length)
{
*p = c;
p++;
buffer++;
m_position++;
readNum++;
}
*p = '\0';
return line;
}
size_t BundleReader::write(const void* ptr, size_t size, size_t count)
{
if (!m_buffer)
return 0;
size_t validCount;
size_t validLength = m_length - m_position;
size_t needLength = size*count;
const char* ptr1 = (const char*)ptr;
if (validLength <= needLength)
{
validCount = validLength / size;
size_t readLength = size * validCount;
memcpy((char*)m_buffer + m_position, ptr1, readLength);
ptr1 += readLength;
m_position += readLength;
readLength = validLength - readLength;
if(readLength > 0)
{
memcpy((char*)m_buffer+m_position, ptr1, readLength);
m_position += readLength;
validCount += 1;
}
}
else
{
memcpy((char*)m_buffer + m_position, ptr1, needLength);
m_position += needLength;
validCount = count;
}
return validCount;
}
bool BundleReader::eof()
{
if (!m_buffer)
return true;
return ((size_t)tell()) >= length();
}
size_t BundleReader::length()
{
return m_length;
}
long int BundleReader::tell()
{
if (!m_buffer)
return -1;
return m_position;
}
bool BundleReader::seek(long int offset, int origin)
{
if (!m_buffer)
return false;
if(origin == SEEK_CUR)
{
m_position += offset;
}
else if(origin == SEEK_SET)
{
m_position = offset;
}
else if(origin == SEEK_END)
{
m_position = m_length+offset;
}
else
return false;
return true;
}
bool BundleReader::rewind()
{
if (m_buffer != NULL)
{
m_position = 0;
return true;
}
return false;
}
std::string BundleReader::readString()
{
unsigned int length;
if(read(&length, 4, 1) != 1)
{
return std::string();
}
std::string str;
if (length > 0)
{
str.resize(length);
if (read(&str[0], 1, length) != length)
{
return std::string();
}
}
return str;
}
bool BundleReader::readMatrix(float* m)
{
return (read(m, sizeof(float), 16) == 16);
}
BundleReader::BundleReader()
{
m_buffer = NULL;
m_position = 0;
m_length = 0;
};
void BundleReader::init(char* lpbuffer, unsigned int length)
{
m_position = 0;
m_buffer = lpbuffer;
m_length = length;
}
}

203
cocos/3d/CCBundleReader.h Normal file
View File

@ -0,0 +1,203 @@
/****************************************************************************
Copyright (c) 2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CC_BUNDLE_READER_H__
#define __CC_BUNDLE_READER_H__
#include <string>
#include <vector>
#include "base/CCRef.h"
#include "base/CCPlatformMacros.h"
#include "base/CCConsole.h"
NS_CC_BEGIN
/**
* Stream is an interface for reading and writing a sequence of bytes.
*/
class BundleReader: public cocos2d::Ref
{
public:
~BundleReader();
static BundleReader* create(char* lpbuffer, unsigned int length);
void close();
/**
* Reads an array of elements.
*
* @param ptr The pointer to the memory to copy into.
* The available size should be at least bytes.
* @param size The size of each element to be read, in bytes.
* @param count The number of elements to read.
*
* @return The number of elements read.
*/
size_t read(void* ptr, size_t size, size_t count);
/**
* Reads a line from the stream.
*/
char* readLine(int num,char* line);
/**
* Writes an array of elements.
*
* @param ptr The pointer to the array of elements to be written.
* @param size The size of each element to be written, in bytes.
* @param count The number of elements to write.
*
* @return The number of elements written.
*/
size_t write(const void* ptr, size_t size, size_t count);
/**
* Returns true if the end of the stream has been reached.
*/
bool eof();
/**
* Returns the length of the stream in bytes.
*/
size_t length();
/**
* Returns the position of the file pointer.
*/
long int tell();
/**
* Sets the position of the file pointer.
*/
bool seek(long int offset, int origin);
/**
* Sets the file pointer at the start of the file.
*/
bool rewind();
/**
* read binary typed value.
*/
template<typename T> bool read(T* ptr);
template<typename T> bool readArray(unsigned int* length, std::vector<T>* values);
/**
* first read length, then read string text
*/
std::string readString();
bool readMatrix(float* m);
private:
BundleReader();
void init(char* lpbuffer, unsigned int length);
private:
long int m_position;
size_t m_length;
char* m_buffer;
};
// template read routines
template<typename T>
inline bool BundleReader::read(T *ptr)
{
return (read(ptr, sizeof(T), 1) == 1);
}
/**
* template function to read array of value.
*/
template<typename T>
inline bool BundleReader::readArray(unsigned int *length, std::vector<T> *values)
{
if (!read(length))
{
return false;
}
if (*length > 0 && values)
{
values->resize(*length);
if (read(&(*values)[0], sizeof(T), *length) != *length)
{
return false;
}
}
return true;
}
/**
* specalization for char
*/
template<>
inline bool BundleReader::read<char>(char *ptr)
{
if (read(ptr, sizeof(char), 1) == 1)
{
return true;
}
else
{
*ptr = -1;
return false;
}
}
/**
* specalization for std::string
*/
template<>
inline bool BundleReader::read<std::string>(std::string *ptr)
{
CCLOG("can not read std::string, use readString() instead");
return false;
}
/**
* template function to read array of value.
*/
template<>
inline bool BundleReader::readArray<std::string>(unsigned int *length, std::vector<std::string> *values)
{
if (!read(length))
{
return false;
}
values->clear();
if (*length > 0 && values)
{
for (int i = 0; i < (int)*length; ++i)
{
values->push_back(readString());
}
}
return true;
}
NS_CC_END
#endif

View File

@ -541,12 +541,13 @@ std::string Sprite3DWithSkinTest::subtitle() const
void Sprite3DWithSkinTest::addNewSpriteWithCoords(Vec2 p)
{
auto sprite = Sprite3D::create("Sprite3DTest/girl.c3t");
std::string fileName = "Sprite3DTest/girl.c3b";/*"Sprite3DTest/tianguang.c3b"*/
auto sprite = Sprite3D::create(fileName);
addChild(sprite);
sprite->setRotation3D(Vec3(-90.f, 0.f, 0.f));
sprite->setPosition( Vec2( p.x, p.y) );
auto animation = Animation3D::getOrCreate("Sprite3DTest/girl.c3t");
auto animation = Animation3D::getOrCreate(fileName);
if (animation)
{
auto animate = Animate3D::create(animation);