Updated lots of things
This commit is contained in:
@@ -6,4 +6,4 @@ target_link_libraries(MorphTargetsResearch OgreBites OgreBullet OgrePaging ${BUL
|
||||
if(OGRE_STATIC)
|
||||
target_link_options(MorphTargetsResearch PRIVATE -static-libstdc++ -static-libgcc)
|
||||
endif()
|
||||
add_dependencies(MorphTargetsResearch stage_files import_vrm)
|
||||
add_dependencies(MorphTargetsResearch stage_files import_vrm import_character_shapes)
|
||||
@@ -3,6 +3,67 @@
|
||||
#include <OgreApplicationContext.h>
|
||||
|
||||
class App;
|
||||
struct Vertex2D {
|
||||
float x, y;
|
||||
Ogre::ColourValue color;
|
||||
|
||||
Vertex2D(float x, float y, const Ogre::ColourValue &color)
|
||||
: x(x)
|
||||
, y(y)
|
||||
, color(color)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static bool calculateBarycentricCoordinates(int px, int py, const Vertex2D &v0,
|
||||
const Vertex2D &v1,
|
||||
const Vertex2D &v2, float &u,
|
||||
float &v, float &w)
|
||||
{
|
||||
float area = 0.5f * ((v1.x - v0.x) * (v2.y - v0.y) -
|
||||
(v2.x - v0.x) * (v1.y - v0.y));
|
||||
if (area == 0)
|
||||
return false; // Degenerate triangle
|
||||
|
||||
u = 0.5f * ((v1.x - px) * (v2.y - py) - (v2.x - px) * (v1.y - py)) /
|
||||
area;
|
||||
v = 0.5f * ((v2.x - px) * (v0.y - py) - (v0.x - px) * (v2.y - py)) /
|
||||
area;
|
||||
w = 1.0f - u - v;
|
||||
|
||||
return u >= 0 && v >= 0 && w >= 0;
|
||||
}
|
||||
|
||||
static void drawColoredTriangle(Ogre::Image &image, const Vertex2D &v0,
|
||||
const Vertex2D &v1, const Vertex2D &v2)
|
||||
{
|
||||
// Determine bounding box of the triangle
|
||||
int minX = std::min({ v0.x, v1.x, v2.x });
|
||||
int minY = std::min({ v0.y, v1.y, v2.y });
|
||||
int maxX = std::max({ v0.x, v1.x, v2.x });
|
||||
int maxY = std::max({ v0.y, v1.y, v2.y });
|
||||
|
||||
// Clamp to image bounds
|
||||
minX = std::max(0, minX);
|
||||
minY = std::max(0, minY);
|
||||
maxX = std::min((int)image.getWidth() - 1, maxX);
|
||||
maxY = std::min((int)image.getHeight() - 1, maxY);
|
||||
|
||||
for (int y = minY; y <= maxY; ++y) {
|
||||
for (int x = minX; x <= maxX; ++x) {
|
||||
float u, v, w;
|
||||
if (calculateBarycentricCoordinates(x, y, v0, v1, v2, u,
|
||||
v, w)) {
|
||||
// Interpolate colors
|
||||
Ogre::ColourValue color = u * v0.color +
|
||||
v * v1.color +
|
||||
w * v2.color;
|
||||
|
||||
image.setColourAt(color, x, y, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void getSubmeshNormals(const Ogre::Mesh *mesh,
|
||||
const Ogre::SubMesh *submesh,
|
||||
@@ -43,6 +104,7 @@ static void getSubmeshUVs(const Ogre::Mesh *mesh, const Ogre::SubMesh *submesh,
|
||||
{
|
||||
int j;
|
||||
float *pReal;
|
||||
uvs.resize(0);
|
||||
Ogre::HardwareVertexBufferSharedPtr vbuf;
|
||||
Ogre::VertexData *vertex_data = submesh->useSharedVertices ?
|
||||
mesh->sharedVertexData :
|
||||
@@ -50,11 +112,7 @@ static void getSubmeshUVs(const Ogre::Mesh *mesh, const Ogre::SubMesh *submesh,
|
||||
const Ogre::VertexElement *uvElem =
|
||||
vertex_data->vertexDeclaration->findElementBySemantic(
|
||||
Ogre::VES_TEXTURE_COORDINATES, index);
|
||||
int vertex_count = 0;
|
||||
if (submesh->useSharedVertices)
|
||||
vertex_count += mesh->sharedVertexData->vertexCount;
|
||||
else
|
||||
vertex_count += submesh->vertexData->vertexCount;
|
||||
int vertex_count = vertex_data->vertexCount;
|
||||
if (!uvElem)
|
||||
return;
|
||||
OgreAssert(uvs.size() == 0 || uvs.size() == vertex_count,
|
||||
@@ -66,6 +124,7 @@ static void getSubmeshUVs(const Ogre::Mesh *mesh, const Ogre::SubMesh *submesh,
|
||||
for (j = 0; j < vertex_data->vertexCount; ++j) {
|
||||
uvElem->baseVertexPointerToElement(uv, &pReal);
|
||||
uvs[j] = Ogre::Vector2(pReal[0], pReal[1]);
|
||||
std::cout << "buffer UV: " << index << ": " << j << " " << uvs[j] << " " << (void *)pReal << " " << (void *)uv << std::endl;
|
||||
uv += vbuf->getVertexSize();
|
||||
}
|
||||
vbuf->unlock();
|
||||
@@ -247,7 +306,9 @@ static void getSubMeshInformation(const Ogre::Mesh *mesh,
|
||||
const Ogre::SubMesh *submesh,
|
||||
struct SubMeshInformation *info)
|
||||
{
|
||||
int i;
|
||||
info->materialName = submesh->getMaterialName();
|
||||
std::cout << "material name: " << info->materialName << std::endl;
|
||||
info->sharedVertices = submesh->useSharedVertices;
|
||||
info->lodFaceList = submesh->mLodFaceList;
|
||||
info->boneList = submesh->getBoneAssignments();
|
||||
@@ -255,21 +316,28 @@ static void getSubMeshInformation(const Ogre::Mesh *mesh,
|
||||
getSubmeshVertices(mesh, submesh, info->vertices);
|
||||
getSubmeshNormals(mesh, submesh, info->normals);
|
||||
getSubmeshUVs(mesh, submesh, info->uvs, 0);
|
||||
std::cout << "UV0: " << info->uvs.size() << std::endl;
|
||||
getSubmeshUVs(mesh, submesh, info->uv2s, 1);
|
||||
std::cout << "UV1: " << info->uv2s.size() << std::endl;
|
||||
for (i = 0; i < info->uvs.size(); i++)
|
||||
std::cout << "UV0: " << i << " " << info->uvs[i] << std::endl;
|
||||
for (i = 0; i < info->uv2s.size(); i++)
|
||||
std::cout << "UV1: " << i << " " << info->uv2s[i] << std::endl;
|
||||
}
|
||||
|
||||
struct MeshInformation {
|
||||
struct MeshMorphTarget {
|
||||
Ogre::SkeletonPtr skelp;
|
||||
struct DataChange {
|
||||
int index;
|
||||
int submesh;
|
||||
Ogre::Vector3 vertex;
|
||||
Ogre::Vector3 normal;
|
||||
};
|
||||
std::vector<DataChange> vertices;
|
||||
float weight;
|
||||
struct MeshMorphTarget {
|
||||
Ogre::SkeletonPtr skelp;
|
||||
Ogre::Image image;
|
||||
struct DataChange {
|
||||
int index;
|
||||
int submesh;
|
||||
Ogre::Vector3 vertex;
|
||||
Ogre::Vector3 normal;
|
||||
};
|
||||
std::vector<DataChange> vertices;
|
||||
float weight;
|
||||
};
|
||||
struct MeshInformation {
|
||||
std::map<Ogre::String, struct MeshMorphTarget> targets;
|
||||
std::vector<struct SubMeshInformation> submesh;
|
||||
Ogre::SkeletonPtr skelp;
|
||||
@@ -287,15 +355,6 @@ struct MeshInformation {
|
||||
getSubMeshInformation(prototype,
|
||||
prototype->getSubMesh(i),
|
||||
&submesh[i]);
|
||||
std::cout << i << " " << "mesh material name: "
|
||||
<< submesh[i].materialName << std::endl;
|
||||
std::cout << i << " "
|
||||
<< "shared: " << submesh[i].sharedVertices
|
||||
<< std::endl;
|
||||
std::cout << i << " " << "vertex_count: "
|
||||
<< submesh[i].vertices.size() << std::endl;
|
||||
std::cout << i << " " << "index_count: "
|
||||
<< submesh[i].indices.size() << std::endl;
|
||||
}
|
||||
}
|
||||
Ogre::MeshPtr create(const Ogre::String &meshName)
|
||||
@@ -362,19 +421,196 @@ struct MeshInformation {
|
||||
max_x, max_y, max_z));
|
||||
return baseMesh;
|
||||
}
|
||||
std::pair<int, int> findVertex(const Ogre::Vector2 &uv)
|
||||
{
|
||||
int i, j;
|
||||
float d = 1.5f;
|
||||
int ret_submesh = -1, ret_index = -1;
|
||||
for (i = 0; i < submesh.size(); i++) {
|
||||
if (submesh[i].uv2s.size() != submesh[i].normals.size())
|
||||
continue;
|
||||
for (j = 0; j < submesh[i].uv2s.size(); j++) {
|
||||
float l =
|
||||
submesh[i].uv2s[j].squaredDistance(uv);
|
||||
if (l < d) {
|
||||
d = l;
|
||||
ret_submesh = i;
|
||||
ret_index = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
OgreAssert(ret_submesh >= 0 && ret_index >= 0,
|
||||
"Vertex not found");
|
||||
return { ret_submesh, ret_index };
|
||||
}
|
||||
void createTarget(const Ogre::String &targetName,
|
||||
const Ogre::Mesh *target)
|
||||
{
|
||||
MeshMorphTarget mtarget;
|
||||
int i, j, k, l;
|
||||
std::vector<SubMeshInformation> targetInfo;
|
||||
std::unordered_map<int, SubMeshInformation> targetInfo;
|
||||
mtarget.skelp = Ogre::SkeletonManager::getSingleton().getByName(
|
||||
target->getSkeletonName(), "Characters");
|
||||
targetInfo.resize(target->getNumSubMeshes());
|
||||
int count = 0;
|
||||
for (i = 0; i < target->getNumSubMeshes(); i++) {
|
||||
SubMeshInformation info;
|
||||
getSubMeshInformation(target, target->getSubMesh(i),
|
||||
&targetInfo[i]);
|
||||
&info);
|
||||
std::cout << "-- processed submesh: " << i << std::endl;
|
||||
std::cout << "-- processed submesh: "
|
||||
<< info.materialName << std::endl;
|
||||
if (info.uv2s.size() == 0)
|
||||
continue;
|
||||
targetInfo[i] = info;
|
||||
count++;
|
||||
}
|
||||
OgreAssert(count > 0, "Bad target mesh count");
|
||||
struct VertexIndex {
|
||||
int base_submesh;
|
||||
int base_index;
|
||||
};
|
||||
std::vector<VertexIndex> indices;
|
||||
Ogre::Image image(Ogre::PF_R8G8B8A8, 512, 512);
|
||||
Ogre::Image image_normals(Ogre::PF_R8G8B8A8, 512, 512);
|
||||
float vertexMul = 0.0f, normalMul = 0.0f;
|
||||
struct DeltaData {
|
||||
std::vector<Ogre::Vector3> vertexDeltas;
|
||||
std::vector<Ogre::Vector3> normalDeltas;
|
||||
std::vector<Ogre::Vector2> uvs;
|
||||
std::vector<unsigned long> indices;
|
||||
};
|
||||
std::vector<DeltaData> deltas;
|
||||
std::cout << "target start " << targetName << "\n";
|
||||
deltas.reserve(targetInfo.size());
|
||||
for (i = 0; i < targetInfo.size(); i++) {
|
||||
if (targetInfo.find(i) == targetInfo.end())
|
||||
continue;
|
||||
std::cout << "submesh: " << i << std::endl;
|
||||
OgreAssert(targetInfo[i].uv2s.size() == targetInfo[i].normals.size(), "bad UV2 count");
|
||||
OgreAssert(targetInfo[i].vertices.size() > 0, "bad vertex count");
|
||||
struct DeltaData dd;
|
||||
dd.vertexDeltas.resize(targetInfo[i].vertices.size());
|
||||
dd.normalDeltas.resize(targetInfo[i].vertices.size());
|
||||
dd.uvs.resize(targetInfo[i].vertices.size());
|
||||
std::cout
|
||||
<< "\tvertices: " << targetInfo[i].vertices.size()
|
||||
<< std::endl;
|
||||
for (j = 0; j < targetInfo[i].vertices.size(); j++) {
|
||||
const Ogre::Vector2 &target_uv =
|
||||
targetInfo[i].uv2s[j];
|
||||
auto ti = findVertex(target_uv);
|
||||
const Ogre::Vector3 &base_v =
|
||||
submesh[ti.first].vertices[ti.second];
|
||||
const Ogre::Vector3 &target_v =
|
||||
targetInfo[i].vertices[j];
|
||||
const Ogre::Vector3 &base_n =
|
||||
submesh[ti.first].normals[ti.second];
|
||||
const Ogre::Vector3 &target_n =
|
||||
targetInfo[i].normals[j];
|
||||
Ogre::Vector3 vertexDelta = target_v - base_v;
|
||||
Ogre::Vector3 normalDelta = target_n - base_n;
|
||||
dd.vertexDeltas[j] = vertexDelta;
|
||||
dd.normalDeltas[j] = normalDelta;
|
||||
dd.uvs[j] = target_uv;
|
||||
std::cout << "UV: " << j << " " << target_uv << " " << ti.second << std::endl;
|
||||
float lv = vertexDelta.length();
|
||||
if (vertexMul < lv)
|
||||
vertexMul = lv;
|
||||
float ln = normalDelta.length();
|
||||
if (normalMul < ln)
|
||||
normalMul = ln;
|
||||
}
|
||||
|
||||
dd.indices = targetInfo[i].indices;
|
||||
std::cout << "indices: " << dd.indices.size() << std::endl;
|
||||
deltas.push_back(dd);
|
||||
}
|
||||
std::cout << "multipliers: " << vertexMul << " " << normalMul
|
||||
<< "\n";
|
||||
OgreAssert(vertexMul > 0.0f && normalMul > 0.0f,
|
||||
"bad multipliers");
|
||||
// normalMul = 1.0f;
|
||||
// vertexMul = 1.0f;
|
||||
for (i = 0; i < deltas.size(); i++) {
|
||||
OgreAssert(deltas[i].normalDeltas.size() == deltas[i].vertexDeltas.size(), "bad delta count");
|
||||
for (j = 0; j < deltas[i].vertexDeltas.size(); j++) {
|
||||
Ogre::Vector3 d =
|
||||
deltas[i].normalDeltas[j] / normalMul *
|
||||
0.5f +
|
||||
Ogre::Vector3(0.5f, 0.5f, 0.5f);
|
||||
d.x = Ogre::Math::Clamp(d.x, 0.0f, 1.0f);
|
||||
d.y = Ogre::Math::Clamp(d.y, 0.0f, 1.0f);
|
||||
d.z = Ogre::Math::Clamp(d.z, 0.0f, 1.0f);
|
||||
deltas[i].normalDeltas[j] = d;
|
||||
d =
|
||||
deltas[i].vertexDeltas[j] / vertexMul *
|
||||
0.5f +
|
||||
Ogre::Vector3(0.5f, 0.5f, 0.5f);
|
||||
d.x = Ogre::Math::Clamp(d.x, 0.0f, 1.0f);
|
||||
d.y = Ogre::Math::Clamp(d.y, 0.0f, 1.0f);
|
||||
d.z = Ogre::Math::Clamp(d.z, 0.0f, 1.0f);
|
||||
deltas[i].vertexDeltas[j] = d;
|
||||
std::cout << " vertex delta: " << deltas[i].vertexDeltas[j];
|
||||
std::cout << " normal delta: " << deltas[i].normalDeltas[j];
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
image.setTo(Ogre::ColourValue(0.5, 0.5, 0.5, 1));
|
||||
image_normals.setTo(Ogre::ColourValue(0.5, 0.5, 0.5, 1));
|
||||
for (i = 0; i < deltas.size(); i++) {
|
||||
for (j = 0; j < deltas[i].indices.size(); j += 3) {
|
||||
int i1 = (int)deltas[i].indices[j];
|
||||
int i2 = (int)deltas[i].indices[j + 1];
|
||||
int i3 = (int)deltas[i].indices[j + 2];
|
||||
Ogre::Vector2 u0 = deltas[i].uvs[i1];
|
||||
Ogre::Vector2 u1 = deltas[i].uvs[i2];
|
||||
Ogre::Vector2 u2 = deltas[i].uvs[i3];
|
||||
Ogre::ColourValue c0(
|
||||
deltas[i].vertexDeltas[i1].x,
|
||||
deltas[i].vertexDeltas[i1].y,
|
||||
deltas[i].vertexDeltas[i1].z, 1.0f);
|
||||
Ogre::ColourValue c1(
|
||||
deltas[i].vertexDeltas[i2].x,
|
||||
deltas[i].vertexDeltas[i2].y,
|
||||
deltas[i].vertexDeltas[i2].z, 1.0f);
|
||||
Ogre::ColourValue c2(
|
||||
deltas[i].vertexDeltas[i3].x,
|
||||
deltas[i].vertexDeltas[i3].y,
|
||||
deltas[i].vertexDeltas[i3].z, 1.0f);
|
||||
Ogre::ColourValue x0(
|
||||
deltas[i].normalDeltas[i1].x,
|
||||
deltas[i].normalDeltas[i1].y,
|
||||
deltas[i].normalDeltas[i1].z, 1.0f);
|
||||
Ogre::ColourValue x1(
|
||||
deltas[i].normalDeltas[i2].x,
|
||||
deltas[i].normalDeltas[i2].y,
|
||||
deltas[i].normalDeltas[i2].z, 1.0f);
|
||||
Ogre::ColourValue x2(
|
||||
deltas[i].normalDeltas[i3].x,
|
||||
deltas[i].normalDeltas[i3].y,
|
||||
deltas[i].normalDeltas[i3].z, 1.0f);
|
||||
Vertex2D v0(u0.x * 512, u0.y * 512, c0);
|
||||
Vertex2D v1(u1.x * 512, u1.y * 512, c1);
|
||||
Vertex2D v2(u2.x * 512, u2.y * 512, c2);
|
||||
Vertex2D xv0(u0.x * 512, u0.y * 512, x0);
|
||||
Vertex2D xv1(u1.x * 512, u1.y * 512, x1);
|
||||
Vertex2D xv2(u2.x * 512, u2.y * 512, x2);
|
||||
std::cout << "triangle: ";
|
||||
std::cout << i1 << " " << i2 << " " << i3 << " ";
|
||||
std::cout << u0 << " " << u1 << " " << u2 << " ";
|
||||
std::cout << "(" << v0.x << ", " << v0.y << ") ";
|
||||
std::cout << "(" << v1.x << ", " << v1.y << ") ";
|
||||
std::cout << "(" << v2.x << ", " << v2.y << ") ";
|
||||
std::cout << std::endl;
|
||||
// SoftwareRenderer2D::drawTriangle(image, v0, v1, v2);
|
||||
drawColoredTriangle(image, v0, v1, v2);
|
||||
drawColoredTriangle(image_normals, xv0, xv1,
|
||||
xv2);
|
||||
}
|
||||
}
|
||||
std::cout << "output image\n";
|
||||
image.save(targetName + "_debug.png");
|
||||
image_normals.save(targetName + "_normals_debug.png");
|
||||
std::vector<Ogre::Vector3> vertices;
|
||||
std::vector<Ogre::Vector3> normals;
|
||||
std::vector<Ogre::Vector2> uvs;
|
||||
@@ -383,8 +619,14 @@ struct MeshInformation {
|
||||
std::vector<Ogre::Vector2> change_uvs;
|
||||
std::vector<MeshMorphTarget::DataChange> changes;
|
||||
for (i = 0; i < targetInfo.size(); i++) {
|
||||
if (targetInfo[i].uv2s.size() !=
|
||||
targetInfo[i].normals.size())
|
||||
continue;
|
||||
OgreAssert(targetInfo[i].normals.size() ==
|
||||
targetInfo[i].uv2s.size(),
|
||||
"UV2 missing");
|
||||
const std::vector<Ogre::Vector2> &puv =
|
||||
targetInfo[i].uvs;
|
||||
targetInfo[i].uv2s;
|
||||
const std::vector<Ogre::Vector3> &pvertices =
|
||||
targetInfo[i].vertices;
|
||||
const std::vector<Ogre::Vector3> &pnormals =
|
||||
@@ -401,9 +643,11 @@ struct MeshInformation {
|
||||
}
|
||||
for (i = 0; i < submesh.size(); i++) {
|
||||
int submesh_id = i;
|
||||
if (submesh[i].uv2s.size() != submesh[i].normals.size())
|
||||
continue;
|
||||
for (j = 0; j < submesh[i].vertices.size(); j++) {
|
||||
int index_id = j;
|
||||
const Ogre::Vector2 &xuv = submesh[i].uvs[j];
|
||||
const Ogre::Vector2 &xuv = submesh[i].uv2s[j];
|
||||
uvs.push_back(xuv);
|
||||
uv_submeshes.push_back(submesh_id);
|
||||
uv_indices.push_back(index_id);
|
||||
@@ -523,6 +767,12 @@ public:
|
||||
void loadResources() override
|
||||
{
|
||||
}
|
||||
Ogre::MeshPtr loadMesh(Ogre::String meshName)
|
||||
{
|
||||
Ogre::MeshPtr ret = Ogre::MeshManager::getSingleton().load(
|
||||
meshName, "Characters");
|
||||
return ret;
|
||||
}
|
||||
void meshProcessing()
|
||||
{
|
||||
int i;
|
||||
@@ -532,11 +782,11 @@ public:
|
||||
std::vector<Ogre::MeshPtr> m_Meshes;
|
||||
|
||||
//define meshes
|
||||
Ogre::MeshPtr base = Ogre::MeshManager::getSingleton().load(
|
||||
"male/normal-male.glb", "Characters");
|
||||
// Ogre::MeshPtr base = Ogre::MeshManager::getSingleton().load(
|
||||
// "male/normal-male.glb", "Characters");
|
||||
Ogre::MeshPtr base = loadMesh("shapes/male/edited-normal-male-base.glb");
|
||||
m_Meshes.push_back(base);
|
||||
Ogre::MeshPtr shape = Ogre::MeshManager::getSingleton().load(
|
||||
"shapes/male/edited-shape-test-male.glb", "Characters");
|
||||
Ogre::MeshPtr shape = loadMesh("shapes/male/edited-shape-test-male.glb");
|
||||
OgreAssert(shape, "no shape");
|
||||
MeshInformation meshinfo(base.get());
|
||||
std::string m_ModelId = "MergedMesh";
|
||||
@@ -554,10 +804,12 @@ public:
|
||||
mScnMgr->getRootSceneNode()->createChildSceneNode();
|
||||
// thisSceneNode->setPosition(100, 100, 100);
|
||||
thisSceneNode->attachObject(ent);
|
||||
#if 0
|
||||
mIdle = ent->getAnimationState("idle");
|
||||
mIdle->setEnabled(true);
|
||||
mIdle->setLoop(true);
|
||||
mIdle->setWeight(1.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
void setup() override
|
||||
@@ -610,6 +862,14 @@ public:
|
||||
characterNode->attachObject(ent_base);
|
||||
#endif
|
||||
addInputListener(OGRE_NEW SimpleListener(this));
|
||||
Ogre::Image image(Ogre::PF_R8G8B8A8, 1024, 1024);
|
||||
image.setTo(Ogre::ColourValue(0, 0, 0, 1));
|
||||
Vertex2D v0(0.0f, 0.0f, Ogre::ColourValue(1, 0, 0, 1));
|
||||
Vertex2D v1(500.0f, 100.0f, Ogre::ColourValue(0, 1, 0, 1));
|
||||
Vertex2D v2(0.0f, 500.0f, Ogre::ColourValue(0, 0, 1, 1));
|
||||
// SoftwareRenderer2D::drawTriangle(image, v0, v1, v2);
|
||||
drawColoredTriangle(image, v0, v1, v2);
|
||||
image.save("checkup.png");
|
||||
}
|
||||
void animationTime(float time)
|
||||
{
|
||||
@@ -623,6 +883,11 @@ private:
|
||||
Ogre::AnimationState *mIdle;
|
||||
};
|
||||
|
||||
void SimpleListener::frameRendered(const Ogre::FrameEvent &evt)
|
||||
{
|
||||
mApp->animationTime(evt.timeSinceLastFrame);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
App ctx;
|
||||
@@ -634,8 +899,3 @@ int main(int argc, char *argv[])
|
||||
ctx.closeApp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SimpleListener::frameRendered(const Ogre::FrameEvent &evt)
|
||||
{
|
||||
mApp->animationTime(evt.timeSinceLastFrame);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user