笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。
CSDN视频网址:http://edu.csdn.net/lecturer/144
继续Cocos2d-x 3.x系列文章的编写,接着Cocos2d-x 3.x 图形学渲染系列二十八的编写工作。
下面以模型Attribute属性给读者展示如下所示:
#ifdef _MSC_VER
#pragma once
#endif
#ifndef MODELDATA_ATTRIBUTES_H
#define MODELDATA_ATTRIBUTES_H
#include "../json/BaseJSONWriter.h"
#include <map>
#define ATTRIBUTE_UNKNOWN 0
#define ATTRIBUTE_POSITION 1
#define ATTRIBUTE_NORMAL 2
#define ATTRIBUTE_COLOR 3
#define ATTRIBUTE_COLORPACKED 4
#define ATTRIBUTE_TANGENT 5
#define ATTRIBUTE_BINORMAL 6
#define ATTRIBUTE_TEXCOORD0 7
#define ATTRIBUTE_TEXCOORD1 8
#define ATTRIBUTE_TEXCOORD2 9
#define ATTRIBUTE_TEXCOORD3 10
#define ATTRIBUTE_TEXCOORD4 11
#define ATTRIBUTE_TEXCOORD5 12
#define ATTRIBUTE_TEXCOORD6 13
#define ATTRIBUTE_TEXCOORD7 14
#define ATTRIBUTE_BLENDWEIGHT0 15
#define ATTRIBUTE_BLENDWEIGHT1 16
#define ATTRIBUTE_BLENDWEIGHT2 17
#define ATTRIBUTE_BLENDWEIGHT3 18
#define ATTRIBUTE_BLENDWEIGHT4 19
#define ATTRIBUTE_BLENDWEIGHT5 20
#define ATTRIBUTE_BLENDWEIGHT6 21
#define ATTRIBUTE_BLENDWEIGHT7 22
#define ATTRIBUTE_COUNT 23
#define ATTRIBUTE_TYPE_SIGNED 0x00
#define ATTRIBUTE_TYPE_UNSIGNED 0x80
#define ATTRIBUTE_TYPE_HEX 0x40
#define ATTRIBUTE_TYPE_FLOAT 0
#define ATTRIBUTE_TYPE_INT 1
#define ATTRIBUTE_TYPE_UINT (ATTRIBUTE_TYPE_INT | ATTRIBUTE_TYPE_UNSIGNED)
#define ATTRIBUTE_TYPE_UINT_HEX (ATTRIBUTE_TYPE_UINT | ATTRIBUTE_TYPE_HEX)
#define INIT_VECTOR(T, A) std::vector<T>(A, A + sizeof(A) / sizeof(*A))
namespace fbxconv {
namespace modeldata {
staticconstchar * AttributeNames[] = {
"UNKNOWN", "VERTEX_ATTRIB_POSITION", "VERTEX_ATTRIB_NORMAL", "VERTEX_ATTRIB_COLOR", "COLORPACKED", "VERTEX_ATTRIB_TANGENT", "VERTEX_ATTRIB_BINORMAL",
"VERTEX_ATTRIB_TEX_COORD", "VERTEX_ATTRIB_TEX_COORD1", "VERTEX_ATTRIB_TEX_COORD2", "VERTEX_ATTRIB_TEX_COORD3", "VERTEX_ATTRIB_TEX_COORD4", "VERTEX_ATTRIB_TEX_COORD5", "VERTEX_ATTRIB_TEX_COORD6", "VERTEX_ATTRIB_TEX_COORD7",
"VERTEX_ATTRIB_BLEND_WEIGHT", "VERTEX_ATTRIB_BLEND_INDEX", "BLENDWEIGHT2", "BLENDWEIGHT3", "BLENDWEIGHT4", "BLENDWEIGHT5", "BLENDWEIGHT6", "BLENDWEIGHT7"
};
staticconstunsignedshort AttributeTypeV2[] = {ATTRIBUTE_TYPE_FLOAT, ATTRIBUTE_TYPE_FLOAT};
staticconstunsignedshort AttributeTypeV4[] = {ATTRIBUTE_TYPE_FLOAT, ATTRIBUTE_TYPE_FLOAT, ATTRIBUTE_TYPE_FLOAT, ATTRIBUTE_TYPE_FLOAT};
staticconstunsignedshort AttributeTypeV3[] = {ATTRIBUTE_TYPE_FLOAT, ATTRIBUTE_TYPE_FLOAT, ATTRIBUTE_TYPE_FLOAT};
staticconstunsignedshort AttributeTypeUIntHex[] = {ATTRIBUTE_TYPE_UINT_HEX};
staticconstunsignedshort AttributeTypeBlend[] = {ATTRIBUTE_TYPE_INT, ATTRIBUTE_TYPE_FLOAT};
staticconststd::vector<unsignedshort> AttributeTypes[] = {
INIT_VECTOR(unsignedshort, AttributeTypeV4), // Unknown
INIT_VECTOR(unsignedshort, AttributeTypeV3), // Position
INIT_VECTOR(unsignedshort, AttributeTypeV3), //
INIT_VECTOR(unsignedshort, AttributeTypeV4), //
INIT_VECTOR(unsignedshort, AttributeTypeUIntHex),// ColorPacked
INIT_VECTOR(unsignedshort, AttributeTypeV3), // Tangent
INIT_VECTOR(unsignedshort, AttributeTypeV3), // Binormal
INIT_VECTOR(unsignedshort, AttributeTypeV2), // Texcoord0
INIT_VECTOR(unsignedshort, AttributeTypeV2), // Texcoord1
INIT_VECTOR(unsignedshort, AttributeTypeV2), // Texcoord2
INIT_VECTOR(unsignedshort, AttributeTypeV2), // Texcoord3
INIT_VECTOR(unsignedshort, AttributeTypeV2), // Texcoord4
INIT_VECTOR(unsignedshort, AttributeTypeV2), // Texcoord5
INIT_VECTOR(unsignedshort, AttributeTypeV2), // Texcoord6
INIT_VECTOR(unsignedshort, AttributeTypeV2), // Texcoord7
INIT_VECTOR(unsignedshort, AttributeTypeBlend), // Blendweight0
INIT_VECTOR(unsignedshort, AttributeTypeBlend), // Blendweight1
INIT_VECTOR(unsignedshort, AttributeTypeBlend), // Blendweight2
INIT_VECTOR(unsignedshort, AttributeTypeBlend), // Blendweight3
INIT_VECTOR(unsignedshort, AttributeTypeBlend), // Blendweight4
INIT_VECTOR(unsignedshort, AttributeTypeBlend), // Blendweight5
INIT_VECTOR(unsignedshort, AttributeTypeBlend), // Blendweight6
INIT_VECTOR(unsignedshort, AttributeTypeBlend) // Blendweight7
};
struct MeshVertexAttrib
{
//属性大小
unsignedint size;
std::string type;
std::string name; };
#define ATTRIBUTE_SIZE(idx) (AttributeTypes[idx].size())
struct Attributes : publicjson::ConstSerializable {
unsignedlong value;
std::map<std::string, MeshVertexAttrib> attributemap;
Attributes() : value(0)
{
MeshVertexAttrib v1;
v1.name = "VERTEX_ATTRIB_POSITION";
v1.size = 3;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_POSITION"]= v1;
v1.name = "VERTEX_ATTRIB_NORMAL";
v1.size = 3;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_NORMAL"]= v1;
v1.name = "VERTEX_ATTRIB_TEX_COORD";
v1.size = 2;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_TEX_COORD"]= v1;
v1.name = "VERTEX_ATTRIB_TEX_COORD1";
v1.size = 2;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_TEX_COORD1"]= v1;
v1.name = "VERTEX_ATTRIB_TEX_COORD2";
v1.size = 2;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_TEX_COORD2"]= v1;
v1.name = "VERTEX_ATTRIB_TEX_COORD3";
v1.size = 2;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_TEX_COORD3"]= v1;
v1.name = "VERTEX_ATTRIB_TEX_COORD4";
v1.size = 2;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_TEX_COORD4"]= v1;
v1.name = "VERTEX_ATTRIB_TEX_COORD5";
v1.size = 2;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_TEX_COORD5"]= v1;
v1.name = "VERTEX_ATTRIB_TEX_COORD6";
v1.size = 2;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_TEX_COORD6"]= v1;
v1.name = "VERTEX_ATTRIB_TEX_COORD7";
v1.size = 2;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_TEX_COORD7"]= v1;
v1.name = "VERTEX_ATTRIB_BLEND_WEIGHT";
v1.size = 4;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_BLEND_WEIGHT"]= v1;
v1.name = "VERTEX_ATTRIB_BLEND_INDEX";
v1.size = 4;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_BLEND_INDEX"]= v1;
v1.name = "VERTEX_ATTRIB_COLOR";
v1.size = 4;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_COLOR"]= v1;
v1.name = "VERTEX_ATTRIB_TANGENT";
v1.size = 3;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_TANGENT"]= v1;
v1.name = "VERTEX_ATTRIB_BINORMAL";
v1.size = 3;
v1.type = "GL_FLOAT";
attributemap["VERTEX_ATTRIB_BINORMAL"]= v1;
}
Attributes(constunsignedlong&v) : value(v) {}
Attributes(constAttributes©From) : value(copyFrom.value) {}
inlinebooloperator==(constAttributes& rhs) const {
returnvalue == rhs.value;
}
unsignedint size() const {
unsignedint result = 0;
for (unsignedint i = 0; i <ATTRIBUTE_COUNT; i++)
if (has(i))
result += (unsignedint)ATTRIBUTE_SIZE(i);
return result;
}
unsignedint length() const {
unsignedint result = 0;
for (unsignedint i = 0; i <ATTRIBUTE_COUNT; i++)
if (has(i))
result++;
return result;
}
constint get(unsignedint index) const {
for (unsignedint i = 0; i <ATTRIBUTE_COUNT; i++)
if (has(i) && index-- <= 0)
return i;
return -1;
}
constchar *name(constunsignedint&index) const {
constint a = get(index);
return a <0 ? 0 : AttributeNames[a];
}
constunsignedshort getType(constunsignedint&v) const {
unsignedint s = 0;
for (unsignedint i = 0; i <ATTRIBUTE_COUNT; i++) {
if (!has(i))
continue;
constunsignedshort is = (unsignedshort)ATTRIBUTE_SIZE(i);
if ((s + is) > v)
returnAttributeTypes[i][v-s];
s+=is;
}
return0;
}
void set(constunsignedint&attribute, constbool&v) {
if (v)
add(attribute);
else
remove(attribute);
}
void add(constunsignedint&attribute) {
value |= (1<< attribute);
}
void remove(constunsignedint&attribute) {
value&= -1 ^ (1<< attribute);
}
inlinebool has(constunsignedint&attribute) const {
return (value& (1<< attribute)) != 0;
}
inlinebool hasPosition() const {
returnhas(ATTRIBUTE_POSITION);
}
void hasPosition(constbool&v) {
set(ATTRIBUTE_POSITION, v);
}
inlinebool hasNormal() const {
returnhas(ATTRIBUTE_NORMAL);
}
void hasNormal(constbool&v) {
set(ATTRIBUTE_NORMAL, v);
}
inlinebool hasColor() const {
returnhas(ATTRIBUTE_COLOR);
}
void hasColor(constbool&v) {
set(ATTRIBUTE_COLOR, v);
}
inlinebool hasColorPacked() const {
returnhas(ATTRIBUTE_COLORPACKED);
}
void hasColorPacked(constbool&v) {
set(ATTRIBUTE_COLORPACKED, v);
}
inlinebool hasTangent() const {
returnhas(ATTRIBUTE_TANGENT);
}
void hasTangent(constbool&v) {
set(ATTRIBUTE_TANGENT, v);
}
inlinebool hasBinormal() const {
returnhas(ATTRIBUTE_BINORMAL);
}
void hasBinormal(constbool&v) {
set(ATTRIBUTE_BINORMAL, v);
}
inlinebool hasUV(constunsignedshort&uv) const {
returnhas(ATTRIBUTE_TEXCOORD0 + uv);
}
void hasUV(constunsignedshort&uv, constbool&v) {
set(ATTRIBUTE_TEXCOORD0 + uv, v);
}
inlinebool hasBlendWeight(constunsignedshort&index) const {
returnhas(ATTRIBUTE_BLENDWEIGHT0 + index);
}
void hasBlendWeight(constunsignedshort&index, constbool&v) {
set(ATTRIBUTE_BLENDWEIGHT0 + index, v);
}
virtualvoid serialize(json::BaseJSONWriter&writer) const;
void writeBinary(FILE* file);
};
} }
#endif
模型所包含的法线,切线,次法线等信息都是通过上述文件定义实现的,最终可从转换后的模型文本文件中显示出来。接下来介绍在Reader模块中的矩阵类实现,模型骨骼动画的播放都会涉及到矩阵的运算,类定义完整代码实现如下:
#ifdef _MSC_VER
#pragma once
#endif //_MSC_VER
#ifndef FBXCONV_READERS_MATRIX3_H
#define FBXCONV_READERS_MATRIX3_H
namespace fbxconv {
namespace readers {
template<class T>struct Matrix3 {
T m[9];
T &x1;
T &x2;
T &x3;
T &y1;
T &y2;
T &y3;
T &z1;
T &z2;
T &z3;
Matrix3() : x1(m[0]), x2(m[1]), x3(m[2]), y1(m[3]), y2(m[4]), y3(m[5]), z1(m[6]), z2(m[7]), z3(m[8]) {
idt();
}
Matrix3(constMatrix3©From) : x1(m[0]), x2(m[1]), x3(m[2]), y1(m[3]), y2(m[4]), y3(m[5]), z1(m[6]), z2(m[7]), z3(m[8]) {
set(copyFrom);
}
inlineMatrix3&operator=(constMatrix3&rhs) {
return set(rhs);
}
inlineMatrix3&operator*=(constMatrix3&rhs) {
return mul(rhs);
}
inlineMatrix3&operator+=(constMatrix3&rhs) {
return add(rhs);
}
Matrix3<T>&idt() {
return set(1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f);
}
Matrix3<T>&set(constMatrix3<T>&rhs) {
return set(rhs.x1, rhs.x2, rhs.x3, rhs.y1, rhs.y2, rhs.y3, rhs.z1, rhs.z2, rhs.z3);
}
Matrix3<T>&set(const T &_x1, const T &_x2, const T &_x3, const T &_y1, const T &_y2, const T &_y3, const T &_z1, const T &_z2, const T &_z3) {
x1 = _x1; x2 = _x2; x3 = _x3;
y1 = _y1; y2 = _y2; y3 = _y3;
z1 = _z1; z2 = _z2; z3 = _z3;
return *this;
}
inlineMatrix3<T>&scale(const T &x = (T)1., const T &y = (T)1., const T &z = (T)1.) {
returnmulr(x, y, z);
}
Matrix3<T>&rotate(const T &radians) {
const T c = cos(radians);
const T s = sin(radians);
return mul(c, -s, s, c);
}
Matrix3<T>&translate(const T &x = (T)0., const T &y = (T)0.) {
return set( x1, x2, x1 * x + x2 * y + x3,
y1, y2, y1 * x + y2 * y + y3,
z1, z2, z1 * x + z2 * y + z3);
}
Matrix3<T>&trn(const T &x = (T)0., const T &y = (T)0.) {
x3 += x;
y3 += y;
return *this;
}
Matrix3<T>&mul(constMatrix3<T>&rhs) {
return mul(rhs.x1, rhs.x2, rhs.x3, rhs.y1, rhs.y2, rhs.y3, rhs.z1, rhs.z2, rhs.z3);
}
Matrix3<T>&mul(const T &_x1, const T &_x2, const T &_x3, const T &_y1, const T &_y2, const T &_y3, const T &_z1, const T &_z2, const T &_z3) {
return set( x1 * _x1 + x2 * _y1 + x3 * _z1, x1 * _x2 + x2 * _y2 + x3 * _z2, x1 * _x3 + x2 * _y3 + x3 * _z3,
y1 * _x1 + y2 * _y1 + y3 * _z1, x2 * _x2 + y2 * _y2 + y3 * _z2, y1 * _x3 + y2 * _y3 + y3 * _z3,
z1 * _x1 + z2 * _y1 + z3 * _z1, x3 * _x2 + z2 * _y2 + z3 * _z2, z1 * _x3 + z2 * _y3 + z3 * _z3);
}
Matrix3<T>&mulr(const T &x = (T)1., const T &y = (T)1., const T &z = (T)1.) {
return set( x1 * x, z2 * y, x3 * z,
y1 * x, y2 * y, y3 * z,
z1 * x, z2 * y, z3 * z);
}
Matrix3<T>&mulc(const T &x = (T)1., const T &y = (T)1., const T &z = (T)1.) {
return set( x1 * x, x2 * x, z3 * x,
y1 * y, y2 * y, y3 * y,
z1 * z, z2 * z, z3 * z);
}
Matrix3<T>&mul(const T &_x1, const T &_x2, const T &_y1, const T &_y2) {
return set( x1 * _x1 + x2 * _y1, x1 * _x2 + x2 * _y2, x3,
y1 * _x1 + y2 * _y1, y1 * _x2 + y2 * _y2, y3,
z1 * _x1 + z2 * _y1, z1 * _x2 + z2 * _y2, z3);
}
Matrix3<T>&add(constMatrix3<T>&rhs) {
return add(rhs.x1, rhs.x2, rhs.x3, rhs.y1, rhs.y2, rhs.y3, rhs.z1, rhs.z2, rhs.z3);
}
Matrix3<T>&add(const T &_x1, const T &_x2, const T &_x3, const T &_y1, const T &_y2, const T &_y3, const T &_z1, const T &_z2, const T &_z3) {
return set(x1 + _x1, x2 + _x2, x3 + _x3, y1 + _y1, y2 + _y2, y3 + _y3, z1 + _z1, z2 + _z2, z3 * _z3);
}
void transform(float&x, float&y) const {
constfloat _x = x, _y = y;
x = x1 * _x + x2 * _y + x3;
y = y1 * _x + y2 * _y + y3;
}
void transform(float&x, float&y, float&z) const {
constfloat _x = x, _y = y, _z = z;
x = x1 * _x + x2 * _y + x3 * _z;
y = y1 * _x + y2 * _y + y3 * _z;
z = z1 * _x + z2 * _y + z3 * _z;
}
};
} }
#endif //FBXCONV_READERS_MATRIX3_H
后续内容敬请期待。。。。。。