open source

This commit is contained in:
lvfulong
2020-11-11 16:17:13 +08:00
parent 4d989f3ecb
commit bc4ca748de
2441 changed files with 623057 additions and 2 deletions
@@ -0,0 +1,63 @@
/**
@file JCFloatArrayKeyframe.h
@brief
@author James
@version 1.0
@date 2018_7_12
*/
#ifndef __JCFloatArrayKeyframe_H__
#define __JCFloatArrayKeyframe_H__
#include <stdio.h>
#include <string>
#include <map>
#include "JCFloatKeyframe.h"
namespace laya
{
class JCFloatArrayKeyframe : public JCKeyFrame
{
public:
struct FloatArrayBuffer
{
char* data;
int byteSize;
FloatArrayBuffer()
{
data = NULL;
byteSize = 0;
}
};
public:
JCFloatArrayKeyframe() {}
virtual ~JCFloatArrayKeyframe() {}
void setTime(float nTime)
{
m_nTime = nTime;
}
float getTime()
{
return m_nTime;
}
public:
FloatArrayBuffer m_nInTangent;
FloatArrayBuffer m_nOutTangent;
FloatArrayBuffer m_nValue;
FloatArrayBuffer m_pData;
};
}
//------------------------------------------------------------------------------
#endif //__JCFloatArrayKeyframe_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,104 @@
/**
@file JCFloatKeyframe.h
@brief
@author James
@version 1.0
@date 2018_7_12
*/
#ifndef __JCFloatKeyframe_H__
#define __JCFloatKeyframe_H__
#include <stdio.h>
#include <string>
#include <map>
namespace laya
{
class JCKeyFrame
{
public:
JCKeyFrame()
{
m_nTime = 0;
}
virtual ~JCKeyFrame()
{
}
float m_nTime;
};
class JCFloatKeyframe : public JCKeyFrame
{
public:
JCFloatKeyframe()
{
m_nInTangent = 0;
m_nOutTangent = 0;
m_nValue = 0;
}
virtual ~JCFloatKeyframe() {}
void setTime(float nTime)
{
m_nTime = nTime;
}
float getTime()
{
return m_nTime;
}
void setInTangent(float nInTangent)
{
m_nInTangent = nInTangent;
}
float getInTangent()
{
return m_nInTangent;
}
void setOutTangent(float nInTangent)
{
m_nOutTangent = nInTangent;
}
float getOutTangent()
{
return m_nOutTangent;
}
void setValue(float nValue)
{
m_nValue = nValue;
}
float getValue()
{
return m_nValue;
}
void _cloneTo(JCFloatKeyframe* pDestObj)
{
pDestObj->m_nTime = m_nTime;
pDestObj->m_nInTangent = m_nInTangent;
pDestObj->m_nOutTangent = m_nOutTangent;
pDestObj->m_nValue = m_nValue;
}
public:
float m_nInTangent;
float m_nOutTangent;
float m_nValue;
};
}
//------------------------------------------------------------------------------
#endif //__JCFloatKeyframe_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,186 @@
/**
@file JCKeyframeNode.h
@brief
@author James
@version 1.0
@date 2018_7_12
*/
#ifndef __JCKeyframeNode_H__
#define __JCKeyframeNode_H__
#include <stdio.h>
#include <string>
#include <map>
#include <vector>
#include "JCFloatKeyframe.h"
#include "JCFloatArrayKeyframe.h"
namespace laya
{
class JCKeyframeNode
{
public:
JCKeyframeNode()
{
m_nIndexInList = 0;
m_nType = 0;
m_nDataType = 0;
m_pDataFloat = 0;
}
virtual ~JCKeyframeNode()
{
m_vOwnerPath.clear();
m_vPropertys.clear();
m_vKeyFrames.clear();
}
int getOwnerPathCount()
{
return m_vOwnerPath.size();
}
int getPropertyCount()
{
return m_vPropertys.size();
}
int getKeyFramesCount()
{
return m_vKeyFrames.size();
}
void _setOwnerPathCount(int value)
{
m_vOwnerPath.resize(value);
}
void _setOwnerPathByIndex(int index, const char* value)
{
m_vOwnerPath[index] = value;
}
const char* _joinOwnerPath(const char* sep)
{
s_sTempString = "";
int nSize = m_vOwnerPath.size() - 1;
for (int i = 0; i < nSize; i++)
{
s_sTempString += m_vOwnerPath[i];
s_sTempString += sep;
}
s_sTempString += m_vOwnerPath[nSize];
return s_sTempString.c_str();
}
void _setPropertyCount(int value)
{
m_vPropertys.resize(value);
}
void _setPropertyByIndex(int index, const char* value)
{
m_vPropertys[index] = value;
}
const char* _joinProperty(const char* sep)
{
s_sTempString = "";
int nSize = m_vPropertys.size() - 1;
for (int i = 0; i < nSize; i++)
{
s_sTempString += m_vPropertys[i];
s_sTempString += sep;
}
s_sTempString += m_vPropertys[nSize];
return s_sTempString.c_str();
}
void _setKeyframeCount(int value)
{
m_vKeyFrames.resize(value);
}
const char* getOwnerPathByIndex(int index)
{
return m_vOwnerPath[index].c_str();
}
const char* getPropertyByIndex(int index)
{
return m_vPropertys[index].c_str();
}
void setIndexInList(int n)
{
m_nIndexInList = n;
}
int getIndexInList()
{
return m_nIndexInList;
}
void setType(int nType)
{
m_nType = nType;
}
int getType()
{
return m_nType;
}
void setFullPath(const char* sPath)
{
m_sFullPath = sPath;
}
const char* getFullPath()
{
return m_sFullPath.c_str();
}
void setPropertyOwner(const char* sBuffer)
{
m_sPropertyOwner = sBuffer;
}
const char* getPropertyOwner()
{
return m_sPropertyOwner.c_str();
}
int getDataType()
{
return m_nDataType;
}
float getFloatData()
{
return m_pDataFloat;
}
public:
static std::string s_sTempString;
std::vector<std::string> m_vOwnerPath;
std::vector<std::string> m_vPropertys;
std::vector<JCKeyFrame*> m_vKeyFrames;
int m_nIndexInList;
int m_nType;
std::string m_sFullPath;
std::string m_sPropertyOwner;
short m_nDataType; //0为float 1为FloatArray
float m_pDataFloat;
JCFloatArrayKeyframe::FloatArrayBuffer m_pDataFloatArray;
};
}
//------------------------------------------------------------------------------
#endif //__JCKeyframeNode_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,265 @@
/**
@file JCKeyframeNodeList.cpp
@brief
@author James
@version 1.0
@date 2018_7_12
*/
#include "JCKeyframeNodeList.h"
#include "../Log.h"
namespace laya
{
//------------------------------------------------------------------------------
JCKeyframeNodeList::JCKeyframeNodeList()
{
}
//------------------------------------------------------------------------------
JCKeyframeNodeList::~JCKeyframeNodeList()
{
m_vNodes.clear();
}
void JCKeyframeNodeList::evaluateClipDatasRealTime(JCKeyframeNodeList* nodes, float playCurTime, short* realTimeCurrentFrameIndexs, int indexSize, bool addtive, bool frontPlay)
{
int nNodeCount = nodes->getCount();
if (nNodeCount != indexSize)
{
LOGE("evaluateClipDatasRealTime error");
return;
}
for (int i = 0; i < nNodeCount; i++) {
JCKeyframeNode* node = nodes->m_vNodes[i];
int type = node->m_nType;
short nextFrameIndex = 0;
std::vector<JCKeyFrame*> keyFrames = node->m_vKeyFrames;
int keyFramesCount = keyFrames.size();
short frameIndex = realTimeCurrentFrameIndexs[i];
if (true)
{
if (frameIndex != -1 && playCurTime < keyFrames[frameIndex]->m_nTime)
{
frameIndex = -1;
realTimeCurrentFrameIndexs[i] = frameIndex;
}
nextFrameIndex = frameIndex + 1;
while (nextFrameIndex < keyFramesCount) {
if (keyFrames[nextFrameIndex]->m_nTime > playCurTime)
break;
frameIndex++;
nextFrameIndex++;
realTimeCurrentFrameIndexs[i] = frameIndex;
}
}
else
{
nextFrameIndex = frameIndex + 1;
if ((nextFrameIndex != keyFramesCount) &&
(playCurTime > keyFrames[nextFrameIndex]->m_nTime))
{
frameIndex = keyFramesCount - 1;
realTimeCurrentFrameIndexs[i] = frameIndex;
}
nextFrameIndex = frameIndex + 1;
while (frameIndex > -1)
{
if (keyFrames[frameIndex]->m_nTime < playCurTime)
break;
frameIndex--;
nextFrameIndex--;
realTimeCurrentFrameIndexs[i] = frameIndex;
}
}
bool isEnd = (nextFrameIndex == keyFramesCount);
switch (type) {
case 0:
{
node->m_nDataType = 0;
JCFloatKeyframe* pKeyframe = (JCFloatKeyframe*)keyFrames[0];
if (frameIndex != -1)
{
JCFloatKeyframe* frame = (JCFloatKeyframe*)keyFrames[frameIndex];
if (isEnd) {//如果nextFrame为空,不修改数据,保持上一帧
node->m_pDataFloat = frame->m_nValue;
}
else {
JCFloatKeyframe* nextFarme = (JCFloatKeyframe*)keyFrames[nextFrameIndex];
float d = nextFarme->m_nTime - frame->m_nTime;
float t;
if (d != 0)
t = (playCurTime - frame->m_nTime) / d;
else
t = 0;
node->m_pDataFloat = _hermiteInterpolate(frame, nextFarme, t, d);
}
}
else {
node->m_pDataFloat = pKeyframe->m_nValue;
}
if (addtive) {
node->m_pDataFloat -= pKeyframe->m_nValue;
}
break;
}
case 1:
case 4:
{
node->m_nDataType = 1;
JCFloatArrayKeyframe::FloatArrayBuffer* clipData = &node->m_pDataFloatArray;
_evaluateFrameNodeArrayDatasRealTime(keyFrames, frameIndex, isEnd, playCurTime, 3, *clipData);
if (addtive) {
JCFloatArrayKeyframe* pKeyframe = (JCFloatArrayKeyframe*)keyFrames[0];
JCFloatArrayKeyframe::FloatArrayBuffer* firstFrameValue = &pKeyframe->m_pData;
float* clipVData = (float*)clipData->data;
float* firstValue = (float*)firstFrameValue->data;
clipVData[0] -= firstValue[6];
clipVData[1] -= firstValue[7];
clipVData[2] -= firstValue[8];
}
break;
}
case 2:
{
node->m_nDataType = 1;
JCFloatArrayKeyframe::FloatArrayBuffer* clipData = &node->m_pDataFloatArray;
_evaluateFrameNodeArrayDatasRealTime(keyFrames, frameIndex, isEnd, playCurTime, 4, *clipData);
if (addtive) {
float temp[4];
JCFloatArrayKeyframe* pKeyframe = (JCFloatArrayKeyframe*)keyFrames[0];
JCFloatArrayKeyframe::FloatArrayBuffer* firstFrameValue = &pKeyframe->m_pData;
quaternionConjugate((float*)firstFrameValue->data,8,temp);
quaternionMultiply(temp, (float*)clipData->data, (float*)clipData->data);
}
break;
}
case 3:
{
node->m_nDataType = 1;
JCFloatArrayKeyframe::FloatArrayBuffer* clipData = &node->m_pDataFloatArray;
_evaluateFrameNodeArrayDatasRealTime(keyFrames, frameIndex, isEnd, playCurTime, 3, *clipData);
if (addtive) {
JCFloatArrayKeyframe* pKeyframe = (JCFloatArrayKeyframe*)keyFrames[0];
JCFloatArrayKeyframe::FloatArrayBuffer* firstFrameValue = &pKeyframe->m_pData;
float* clipVData = (float*)clipData->data;
float* firstValue = (float*)firstFrameValue->data;
clipVData[0] /= firstValue[6];
clipVData[1] /= firstValue[7];
clipVData[2] /= firstValue[8];
}
break;
}
default:
throw "AnimationClip:unknown node type.";
}
}
}
float JCKeyframeNodeList::_hermiteInterpolate(JCFloatKeyframe* frame, JCFloatKeyframe* nextFrame, float t, float dur) {
float t0 = frame->m_nOutTangent, t1 = nextFrame->m_nInTangent;
float t2 = t * t;
float t3 = t2 * t;
float a = (float)(2.0 * t3 - 3.0 * t2 + 1.0);
float b = (float)(t3 - 2.0 * t2 + t);
float c = (float)(t3 - t2);
float d = (float)(-2.0 * t3 + 3.0 * t2);
return a * frame->m_nValue + b * t0 * dur + c * t1 * dur + d * nextFrame->m_nValue;
}
void JCKeyframeNodeList::_evaluateFrameNodeArrayDatasRealTime(std::vector<JCKeyFrame*>& keyFrames, int frameIndex, bool isEnd, float playCurTime, int width, JCFloatArrayKeyframe::FloatArrayBuffer& outDatas)
{
int dataOffset = width * 2;
float* outVData = (float*)outDatas.data;
if (frameIndex != -1)
{
JCFloatArrayKeyframe* frame = (JCFloatArrayKeyframe*)keyFrames[frameIndex];
if (isEnd)
{
float* frameData = (float*)frame->m_pData.data;
for (int j = 0; j < width; j++)
outVData[j] = frameData[dataOffset+j];//不能设为null,会造成跳过当前帧数据
}
else
{
JCFloatArrayKeyframe* nextKeyFrame = (JCFloatArrayKeyframe*)keyFrames[frameIndex + 1];
float t;
float startTime = frame->m_nTime;
float d = nextKeyFrame->m_nTime - startTime;
if (d != 0)
t = (playCurTime - startTime) / d;
else
t = 0;
_hermiteInterpolateArray(frame, nextKeyFrame, t, d, outDatas);
}
}
else
{
JCFloatArrayKeyframe::FloatArrayBuffer* firstFrameDatas = &((JCFloatArrayKeyframe*)keyFrames[0])->m_pData;
float* frameData = (float*)firstFrameDatas->data;
for (int j = 0; j < width; j++)
outVData[j] = frameData[dataOffset+j];
}
}
void JCKeyframeNodeList::_hermiteInterpolateArray(JCFloatArrayKeyframe* frame, JCFloatArrayKeyframe* nextFrame, float t, float dur, JCFloatArrayKeyframe::FloatArrayBuffer& out) {
bool isComputeParams = false;
float a, b, c, d;
float* out_data = (float*)out.data;
float* p0_data = (float*)frame->m_pData.data;
float* p1_data = (float*)nextFrame->m_pData.data;
int nOutTanOffset = out.byteSize / sizeof(float);
int nOffset = nOutTanOffset * 2;
for (int i = 0; i < nOutTanOffset; i++) {
float t0 = p0_data[nOutTanOffset +i], t1 = p1_data[i];
if (!isComputeParams) {
float t2 = t * t;
float t3 = t2 * t;
a = (float)(2.0 * t3 - 3.0 * t2 + 1.0);
b = (float)(t3 - 2.0 * t2 + t);
c = (float)(t3 - t2);
d = (float)(-2.0 * t3 + 3.0 * t2);
isComputeParams = true;
}
out_data[i] = a * p0_data[nOffset+i] + b * t0 * dur + c * t1 * dur + d * p1_data[nOffset+i];
}
}
void JCKeyframeNodeList::quaternionConjugate(float* value,int nOffset, float* result) {
result[0] = -value[nOffset];
result[1] = -value[nOffset+1];
result[2] = -value[nOffset+2];
result[3] = value[nOffset+3];
}
void JCKeyframeNodeList::quaternionMultiply(float* le, float* re, float* oe) {
/*[DISABLE-ADD-VARIABLE-DEFAULT-VALUE]*/
float lx = le[0];
float ly = le[1];
float lz = le[2];
float lw = le[3];
float rx = re[0];
float ry = re[1];
float rz = re[2];
float rw = re[3];
float a = ly * rz - lz * ry;
float b = lz * rx - lx * rz;
float c = lx * ry - ly * rx;
float d = lx * rx + ly * ry + lz * rz;
oe[0] = lx * rw + rx * lw + a;
oe[1] = ly * rw + ry * lw + b;
oe[2] = lz * rw + rz * lw + c;
oe[3] = lw * rw - d;
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,63 @@
/**
@file JCKeyframeNodeList.h
@brief
@author James
@version 1.0
@date 2018_7_12
*/
#ifndef __JCKeyframeNodeList_H__
#define __JCKeyframeNodeList_H__
#include <stdio.h>
#include <string>
#include <map>
#include "JCKeyframeNode.h"
#include <vector>
namespace laya
{
class JCKeyframeNodeList
{
public:
static void evaluateClipDatasRealTime(JCKeyframeNodeList* nodes, float playCurTime, short* realTimeCurrentFrameIndexs,int indexSize, bool addtive, bool frontPlay);
JCKeyframeNodeList();
virtual ~JCKeyframeNodeList();
int getCount()
{
return m_vNodes.size();
}
void setCount(int value)
{
m_vNodes.resize(value);
}
protected:
static float _hermiteInterpolate(JCFloatKeyframe* frame, JCFloatKeyframe* nextFrame, float t, float dur);
static void _evaluateFrameNodeArrayDatasRealTime(std::vector<JCKeyFrame*>& keyFrames, int frameIndex, bool isEnd, float playCurTime, int width, JCFloatArrayKeyframe::FloatArrayBuffer& outDatas);
static void _hermiteInterpolateArray(JCFloatArrayKeyframe* frame, JCFloatArrayKeyframe* nextFrame, float t, float dur, JCFloatArrayKeyframe::FloatArrayBuffer& out);
static void quaternionConjugate(float* value, int offset, float* result);
static void quaternionMultiply(float* le, float* re, float* oe);
public:
std::vector<JCKeyframeNode*> m_vNodes;
};
}
//------------------------------------------------------------------------------
#endif //__JCKeyframeNodeList_H__
//-----------------------------END FILE--------------------------------