2014-05-19 05:49:16 +08:00
|
|
|
/****************************************************************************
|
2018-01-29 16:25:32 +08:00
|
|
|
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
2014-05-19 05:49:16 +08:00
|
|
|
|
2022-07-09 01:23:11 +08:00
|
|
|
https://axis-project.github.io/
|
2014-05-19 05:49:16 +08:00
|
|
|
|
|
|
|
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.
|
|
|
|
****************************************************************************/
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
#include "3d/CCMeshRenderer.h"
|
2014-05-19 05:49:16 +08:00
|
|
|
#include "3d/CCObjLoader.h"
|
2014-06-04 18:17:09 +08:00
|
|
|
#include "3d/CCMeshSkin.h"
|
2014-06-05 16:36:01 +08:00
|
|
|
#include "3d/CCBundle3D.h"
|
2022-07-05 14:48:46 +08:00
|
|
|
#include "3d/CCMeshMaterial.h"
|
2014-07-29 10:49:06 +08:00
|
|
|
#include "3d/CCAttachNode.h"
|
2014-08-29 15:39:52 +08:00
|
|
|
#include "3d/CCMesh.h"
|
2014-05-19 05:49:16 +08:00
|
|
|
|
|
|
|
#include "base/CCDirector.h"
|
2014-12-03 17:40:27 +08:00
|
|
|
#include "base/CCAsyncTaskPool.h"
|
2016-06-15 15:01:26 +08:00
|
|
|
#include "base/ccUTF8.h"
|
2019-03-12 16:50:47 +08:00
|
|
|
#include "base/ccUtils.h"
|
2014-10-20 16:25:24 +08:00
|
|
|
#include "2d/CCLight.h"
|
|
|
|
#include "2d/CCCamera.h"
|
2014-05-19 05:49:16 +08:00
|
|
|
#include "base/ccMacros.h"
|
2014-09-28 16:02:12 +08:00
|
|
|
#include "platform/CCPlatformMacros.h"
|
2014-05-19 05:49:16 +08:00
|
|
|
#include "platform/CCFileUtils.h"
|
|
|
|
#include "renderer/CCTextureCache.h"
|
|
|
|
#include "renderer/CCRenderer.h"
|
2015-05-06 04:07:32 +08:00
|
|
|
#include "renderer/CCMaterial.h"
|
|
|
|
#include "renderer/CCTechnique.h"
|
|
|
|
#include "renderer/CCPass.h"
|
2014-05-19 05:49:16 +08:00
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
NS_AX_BEGIN
|
2014-05-19 05:49:16 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
static MeshMaterial* getMeshRendererMaterialForAttribs(MeshVertexData* meshVertexData, bool usesLight);
|
2014-05-19 05:49:16 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
MeshRenderer* MeshRenderer::create()
|
2015-01-14 08:41:24 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
auto mesh = new MeshRenderer();
|
|
|
|
if (mesh->init())
|
2015-01-14 08:41:24 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
mesh->autorelease();
|
|
|
|
return mesh;
|
2015-01-14 08:41:24 +08:00
|
|
|
}
|
2022-07-15 19:17:01 +08:00
|
|
|
AX_SAFE_DELETE(mesh);
|
2015-01-14 08:41:24 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
MeshRenderer* MeshRenderer::create(std::string_view modelPath)
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(modelPath.length() >= 4, "Invalid filename.");
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
auto mesh = new MeshRenderer();
|
|
|
|
if (mesh->initWithFile(modelPath))
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
mesh->_contentSize = mesh->getBoundingBox().size;
|
|
|
|
mesh->autorelease();
|
|
|
|
return mesh;
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
2022-07-15 19:17:01 +08:00
|
|
|
AX_SAFE_DELETE(mesh);
|
2014-05-19 05:49:16 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
2022-07-05 14:48:46 +08:00
|
|
|
MeshRenderer* MeshRenderer::create(std::string_view modelPath, std::string_view texturePath)
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
auto mesh = create(modelPath);
|
|
|
|
if (mesh)
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
mesh->setTexture(texturePath);
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
return mesh;
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::createAsync(std::string_view modelPath,
|
|
|
|
const std::function<void(MeshRenderer*, void*)>& callback,
|
2021-12-25 10:04:45 +08:00
|
|
|
void* callbackparam)
|
2014-12-03 17:40:27 +08:00
|
|
|
{
|
2014-12-05 15:01:30 +08:00
|
|
|
createAsync(modelPath, "", callback, callbackparam);
|
2014-12-03 17:40:27 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::createAsync(std::string_view modelPath,
|
2021-12-26 23:26:34 +08:00
|
|
|
std::string_view texturePath,
|
2022-07-05 14:48:46 +08:00
|
|
|
const std::function<void(MeshRenderer*, void*)>& callback,
|
2021-12-25 10:04:45 +08:00
|
|
|
void* callbackparam)
|
2014-12-03 17:40:27 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
MeshRenderer* mesh = new MeshRenderer();
|
|
|
|
if (mesh->loadFromCache(modelPath))
|
2014-12-03 17:40:27 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
mesh->autorelease();
|
2014-12-03 17:40:27 +08:00
|
|
|
if (!texturePath.empty())
|
2022-07-05 14:48:46 +08:00
|
|
|
mesh->setTexture(texturePath);
|
|
|
|
callback(mesh, callbackparam);
|
2014-12-03 17:40:27 +08:00
|
|
|
return;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
mesh->_asyncLoadParam.afterLoadCallback = callback;
|
|
|
|
mesh->_asyncLoadParam.texPath = texturePath;
|
|
|
|
mesh->_asyncLoadParam.modelPath = modelPath;
|
|
|
|
mesh->_asyncLoadParam.modelFullPath = FileUtils::getInstance()->fullPathForFilename(modelPath);
|
|
|
|
mesh->_asyncLoadParam.callbackParam = callbackparam;
|
|
|
|
mesh->_asyncLoadParam.materialdatas = new MaterialDatas();
|
|
|
|
mesh->_asyncLoadParam.meshdatas = new MeshDatas();
|
|
|
|
mesh->_asyncLoadParam.nodeDatas = new NodeDatas();
|
2021-12-25 10:04:45 +08:00
|
|
|
AsyncTaskPool::getInstance()->enqueue(
|
2022-07-15 19:17:01 +08:00
|
|
|
AsyncTaskPool::TaskType::TASK_IO, AX_CALLBACK_1(MeshRenderer::afterAsyncLoad, mesh),
|
2022-07-05 14:48:46 +08:00
|
|
|
(void*)(&mesh->_asyncLoadParam), [mesh]() {
|
|
|
|
mesh->_asyncLoadParam.result =
|
|
|
|
mesh->loadFromFile(mesh->_asyncLoadParam.modelFullPath, mesh->_asyncLoadParam.nodeDatas,
|
|
|
|
mesh->_asyncLoadParam.meshdatas, mesh->_asyncLoadParam.materialdatas);
|
2021-12-25 10:04:45 +08:00
|
|
|
});
|
2014-12-03 17:40:27 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::afterAsyncLoad(void* param)
|
2014-12-03 17:40:27 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
MeshRenderer::AsyncLoadParam* asyncParam = (MeshRenderer::AsyncLoadParam*)param;
|
2014-12-05 15:01:30 +08:00
|
|
|
autorelease();
|
2014-12-04 18:31:10 +08:00
|
|
|
if (asyncParam)
|
2014-12-03 17:40:27 +08:00
|
|
|
{
|
2014-12-04 18:31:10 +08:00
|
|
|
if (asyncParam->result)
|
2014-12-03 17:40:27 +08:00
|
|
|
{
|
|
|
|
_meshes.clear();
|
|
|
|
_meshVertexDatas.clear();
|
2022-07-15 19:17:01 +08:00
|
|
|
AX_SAFE_RELEASE_NULL(_skeleton);
|
2014-12-03 17:40:27 +08:00
|
|
|
removeAllAttachNode();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
// create in the main thread
|
|
|
|
auto& meshdatas = asyncParam->meshdatas;
|
2014-12-04 18:31:10 +08:00
|
|
|
auto& materialdatas = asyncParam->materialdatas;
|
2021-12-25 10:04:45 +08:00
|
|
|
auto& nodeDatas = asyncParam->nodeDatas;
|
2014-12-03 17:40:27 +08:00
|
|
|
if (initFrom(*nodeDatas, *meshdatas, *materialdatas))
|
|
|
|
{
|
2022-07-12 21:31:54 +08:00
|
|
|
auto meshdata = MeshRendererCache::getInstance()->getMeshRenderData(asyncParam->modelPath);
|
2022-07-05 14:48:46 +08:00
|
|
|
if (meshdata == nullptr)
|
2014-12-05 15:01:30 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
// add to cache
|
2022-07-12 21:31:54 +08:00
|
|
|
auto data = new MeshRendererCache::MeshRenderData();
|
2021-12-25 10:04:45 +08:00
|
|
|
data->materialdatas = materialdatas;
|
|
|
|
data->nodedatas = nodeDatas;
|
2014-12-05 15:01:30 +08:00
|
|
|
data->meshVertexDatas = _meshVertexDatas;
|
2021-12-25 10:04:45 +08:00
|
|
|
for (const auto mesh : _meshes)
|
|
|
|
{
|
2019-01-30 09:35:17 +08:00
|
|
|
data->programStates.pushBack(mesh->getProgramState());
|
2014-12-05 15:01:30 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-12 21:31:54 +08:00
|
|
|
MeshRendererCache::getInstance()->addMeshRenderData(asyncParam->modelPath, data);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-15 19:17:01 +08:00
|
|
|
AX_SAFE_DELETE(meshdatas);
|
2014-12-05 15:01:30 +08:00
|
|
|
materialdatas = nullptr;
|
2021-12-25 10:04:45 +08:00
|
|
|
nodeDatas = nullptr;
|
2014-12-03 17:40:27 +08:00
|
|
|
}
|
|
|
|
}
|
2022-07-15 19:17:01 +08:00
|
|
|
AX_SAFE_DELETE(meshdatas);
|
|
|
|
AX_SAFE_DELETE(materialdatas);
|
|
|
|
AX_SAFE_DELETE(nodeDatas);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2014-12-04 18:31:10 +08:00
|
|
|
if (asyncParam->texPath != "")
|
|
|
|
{
|
|
|
|
setTexture(asyncParam->texPath);
|
|
|
|
}
|
2014-12-03 17:40:27 +08:00
|
|
|
}
|
2014-12-25 17:40:26 +08:00
|
|
|
else
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXLOG("file load failed: %s\n", asyncParam->modelPath.c_str());
|
2014-12-25 17:40:26 +08:00
|
|
|
}
|
2014-12-05 15:01:30 +08:00
|
|
|
asyncParam->afterLoadCallback(this, asyncParam->callbackParam);
|
2014-12-03 17:40:27 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
AABB MeshRenderer::getAABBRecursivelyImp(Node* node)
|
2015-07-09 18:05:47 +08:00
|
|
|
{
|
|
|
|
AABB aabb;
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& iter : node->getChildren())
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
2015-07-09 18:05:47 +08:00
|
|
|
aabb.merge(getAABBRecursivelyImp(iter));
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
MeshRenderer* meshRenderer = dynamic_cast<MeshRenderer*>(node);
|
|
|
|
if (meshRenderer)
|
|
|
|
aabb.merge(meshRenderer->getAABB());
|
2015-07-09 18:05:47 +08:00
|
|
|
|
|
|
|
return aabb;
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
bool MeshRenderer::loadFromCache(std::string_view path)
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2022-07-12 21:31:54 +08:00
|
|
|
auto meshdata = MeshRendererCache::getInstance()->getMeshRenderData(path);
|
2022-07-05 14:48:46 +08:00
|
|
|
if (meshdata)
|
2014-08-19 11:56:09 +08:00
|
|
|
{
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& it : meshdata->meshVertexDatas)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
2014-08-22 13:25:26 +08:00
|
|
|
_meshVertexDatas.pushBack(it);
|
2014-08-19 11:56:09 +08:00
|
|
|
}
|
2022-07-05 14:48:46 +08:00
|
|
|
_skeleton = Skeleton3D::create(meshdata->nodedatas->skeleton);
|
2022-07-15 19:17:01 +08:00
|
|
|
AX_SAFE_RETAIN(_skeleton);
|
2016-10-27 15:10:24 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
const bool singleMesh = (meshdata->nodedatas->nodes.size() == 1);
|
|
|
|
for (const auto& it : meshdata->nodedatas->nodes)
|
2014-08-19 11:56:09 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (it)
|
2014-08-19 11:56:09 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
createNode(it, this, *(meshdata->materialdatas), singleMesh);
|
2014-08-19 11:56:09 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
for (const auto& it : meshdata->nodedatas->skeleton)
|
2014-10-24 15:52:24 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (it)
|
2014-10-24 15:52:24 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
createAttachMeshRendererNode(it, *(meshdata->materialdatas));
|
2014-10-24 15:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
2016-10-27 15:10:24 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
for (ssize_t i = 0, size = _meshes.size(); i < size; ++i)
|
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
// cloning is needed in order to have one state per mesh
|
|
|
|
auto glstate = meshdata->programStates.at(i);
|
2019-01-30 09:35:17 +08:00
|
|
|
_meshes.at(i)->setProgramState(glstate->clone());
|
2014-09-17 13:42:08 +08:00
|
|
|
}
|
2014-08-19 11:56:09 +08:00
|
|
|
return true;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2014-07-29 10:49:06 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
bool MeshRenderer::loadFromFile(std::string_view path,
|
2021-12-25 10:04:45 +08:00
|
|
|
NodeDatas* nodedatas,
|
|
|
|
MeshDatas* meshdatas,
|
|
|
|
MaterialDatas* materialdatas)
|
2014-07-29 10:49:06 +08:00
|
|
|
{
|
|
|
|
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(path);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2015-08-06 03:21:16 +08:00
|
|
|
std::string ext = FileUtils::getInstance()->getFileExtension(path);
|
2014-12-03 17:40:27 +08:00
|
|
|
if (ext == ".obj")
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2014-12-03 17:40:27 +08:00
|
|
|
return Bundle3D::loadObj(*meshdatas, *materialdatas, *nodedatas, fullPath);
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
2014-12-03 17:40:27 +08:00
|
|
|
else if (ext == ".c3b" || ext == ".c3t")
|
2014-08-15 17:46:21 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
// load from .c3b or .c3t
|
2014-12-19 10:21:30 +08:00
|
|
|
auto bundle = Bundle3D::createBundle();
|
2014-12-03 17:40:27 +08:00
|
|
|
if (!bundle->load(fullPath))
|
2014-12-19 10:21:30 +08:00
|
|
|
{
|
|
|
|
Bundle3D::destroyBundle(bundle);
|
2014-12-03 17:40:27 +08:00
|
|
|
return false;
|
2014-09-17 13:42:08 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
auto ret =
|
|
|
|
bundle->loadMeshDatas(*meshdatas) && bundle->loadMaterials(*materialdatas) && bundle->loadNodes(*nodedatas);
|
2014-12-19 10:21:30 +08:00
|
|
|
Bundle3D::destroyBundle(bundle);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2014-12-19 10:21:30 +08:00
|
|
|
return ret;
|
2014-08-15 17:46:21 +08:00
|
|
|
}
|
2014-08-18 14:16:34 +08:00
|
|
|
return false;
|
2014-06-04 18:17:09 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
MeshRenderer::MeshRenderer()
|
2021-12-25 10:04:45 +08:00
|
|
|
: _skeleton(nullptr)
|
|
|
|
, _blend(BlendFunc::ALPHA_NON_PREMULTIPLIED)
|
|
|
|
, _aabbDirty(true)
|
|
|
|
, _lightMask(-1)
|
|
|
|
, _shaderUsingLight(false)
|
|
|
|
, _forceDepthWrite(false)
|
|
|
|
, _usingAutogeneratedGLProgram(true)
|
|
|
|
{}
|
2014-05-19 05:49:16 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
MeshRenderer::~MeshRenderer()
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2014-08-15 20:52:45 +08:00
|
|
|
_meshes.clear();
|
2014-08-22 13:25:26 +08:00
|
|
|
_meshVertexDatas.clear();
|
2022-07-15 19:17:01 +08:00
|
|
|
AX_SAFE_RELEASE_NULL(_skeleton);
|
2014-07-29 10:49:06 +08:00
|
|
|
removeAllAttachNode();
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
bool MeshRenderer::init()
|
2015-01-14 08:41:24 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (Node::init())
|
2015-01-14 08:41:24 +08:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
bool MeshRenderer::initWithFile(std::string_view path)
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2015-11-27 15:53:26 +08:00
|
|
|
_aabbDirty = true;
|
2014-08-18 14:16:34 +08:00
|
|
|
_meshes.clear();
|
2014-08-22 13:25:26 +08:00
|
|
|
_meshVertexDatas.clear();
|
2022-07-15 19:17:01 +08:00
|
|
|
AX_SAFE_RELEASE_NULL(_skeleton);
|
2014-08-18 14:16:34 +08:00
|
|
|
removeAllAttachNode();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2014-07-29 10:49:06 +08:00
|
|
|
if (loadFromCache(path))
|
|
|
|
return true;
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
MeshDatas* meshdatas = new MeshDatas();
|
2021-12-08 00:11:53 +08:00
|
|
|
MaterialDatas* materialdatas = new MaterialDatas();
|
2021-12-25 10:04:45 +08:00
|
|
|
NodeDatas* nodeDatas = new NodeDatas();
|
2014-12-03 17:40:27 +08:00
|
|
|
if (loadFromFile(path, nodeDatas, meshdatas, materialdatas))
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2014-12-03 17:40:27 +08:00
|
|
|
if (initFrom(*nodeDatas, *meshdatas, *materialdatas))
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
// add to cache
|
2022-07-12 21:31:54 +08:00
|
|
|
auto data = new MeshRendererCache::MeshRenderData();
|
2021-12-25 10:04:45 +08:00
|
|
|
data->materialdatas = materialdatas;
|
|
|
|
data->nodedatas = nodeDatas;
|
2014-12-03 17:40:27 +08:00
|
|
|
data->meshVertexDatas = _meshVertexDatas;
|
2021-12-25 10:04:45 +08:00
|
|
|
for (const auto mesh : _meshes)
|
|
|
|
{
|
2019-01-30 09:35:17 +08:00
|
|
|
data->programStates.pushBack(mesh->getProgramState());
|
2014-12-03 17:40:27 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-12 21:31:54 +08:00
|
|
|
MeshRendererCache::getInstance()->addMeshRenderData(path, data);
|
2022-07-15 19:17:01 +08:00
|
|
|
AX_SAFE_DELETE(meshdatas);
|
2015-05-08 15:49:33 +08:00
|
|
|
_contentSize = getBoundingBox().size;
|
2014-12-03 17:40:27 +08:00
|
|
|
return true;
|
|
|
|
}
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
2022-07-15 19:17:01 +08:00
|
|
|
AX_SAFE_DELETE(meshdatas);
|
|
|
|
AX_SAFE_DELETE(materialdatas);
|
|
|
|
AX_SAFE_DELETE(nodeDatas);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2014-06-16 20:58:13 +08:00
|
|
|
return false;
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
bool MeshRenderer::initFrom(const NodeDatas& nodeDatas, const MeshDatas& meshdatas, const MaterialDatas& materialdatas)
|
2014-08-18 14:16:34 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
for (const auto& it : meshdatas.meshDatas)
|
2014-08-18 14:16:34 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (it)
|
2014-08-18 14:16:34 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
// Mesh* mesh = Mesh::create(*it);
|
|
|
|
// _meshes.pushBack(mesh);
|
2014-08-22 13:25:26 +08:00
|
|
|
auto meshvertex = MeshVertexData::create(*it);
|
|
|
|
_meshVertexDatas.pushBack(meshvertex);
|
2014-08-18 14:16:34 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
_skeleton = Skeleton3D::create(nodeDatas.skeleton);
|
2022-07-15 19:17:01 +08:00
|
|
|
AX_SAFE_RETAIN(_skeleton);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2016-10-27 15:10:24 +08:00
|
|
|
auto size = nodeDatas.nodes.size();
|
2021-12-25 10:04:45 +08:00
|
|
|
for (const auto& it : nodeDatas.nodes)
|
2014-08-18 14:16:34 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (it)
|
2014-08-18 14:16:34 +08:00
|
|
|
{
|
2016-10-27 15:10:24 +08:00
|
|
|
createNode(it, this, materialdatas, size == 1);
|
2014-08-18 14:16:34 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
for (const auto& it : nodeDatas.skeleton)
|
2014-08-21 11:23:31 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (it)
|
2014-08-21 11:23:31 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
createAttachMeshRendererNode(it, materialdatas);
|
2014-08-21 11:23:31 +08:00
|
|
|
}
|
|
|
|
}
|
2015-09-17 14:45:16 +08:00
|
|
|
genMaterial();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2014-08-18 14:16:34 +08:00
|
|
|
return true;
|
|
|
|
}
|
2016-10-27 15:10:24 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
MeshRenderer* MeshRenderer::createMeshRendererNode(NodeData* nodedata, ModelData* modeldata, const MaterialDatas& materialdatas)
|
2014-08-21 11:23:31 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
auto meshRenderer = new MeshRenderer();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
meshRenderer->setName(nodedata->id);
|
2021-12-08 00:11:53 +08:00
|
|
|
auto mesh = Mesh::create(nodedata->id, getMeshIndexData(modeldata->subMeshId));
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2021-12-08 00:11:53 +08:00
|
|
|
if (_skeleton && modeldata->bones.size())
|
2014-08-21 11:23:31 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto skin = MeshSkin::create(_skeleton, modeldata->bones, modeldata->invBindPose);
|
|
|
|
mesh->setSkin(skin);
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2021-12-08 00:11:53 +08:00
|
|
|
if (modeldata->materialId == "" && materialdatas.materials.size())
|
|
|
|
{
|
|
|
|
const NTextureData* textureData = materialdatas.materials[0].getTextureData(NTextureData::Usage::Diffuse);
|
|
|
|
mesh->setTexture(textureData->filename);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const NMaterialData* materialData = materialdatas.getMaterialData(modeldata->materialId);
|
2021-12-25 10:04:45 +08:00
|
|
|
if (materialData)
|
2014-08-21 11:23:31 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
const NTextureData* textureData = materialData->getTextureData(NTextureData::Usage::Diffuse);
|
2021-12-25 10:04:45 +08:00
|
|
|
if (textureData)
|
2014-08-21 11:23:31 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
mesh->setTexture(textureData->filename);
|
|
|
|
auto tex = mesh->getTexture();
|
2021-12-25 10:04:45 +08:00
|
|
|
if (tex)
|
2014-08-21 11:23:31 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
Texture2D::TexParams texParams;
|
2021-12-25 10:04:45 +08:00
|
|
|
texParams.minFilter = backend::SamplerFilter::LINEAR;
|
|
|
|
texParams.magFilter = backend::SamplerFilter::LINEAR;
|
2021-12-08 00:11:53 +08:00
|
|
|
texParams.sAddressMode = textureData->wrapS;
|
|
|
|
texParams.tAddressMode = textureData->wrapT;
|
|
|
|
tex->setTexParameters(texParams);
|
|
|
|
mesh->_isTransparent = (materialData->getTextureData(NTextureData::Usage::Transparency) != nullptr);
|
2014-08-21 11:23:31 +08:00
|
|
|
}
|
2021-12-08 00:11:53 +08:00
|
|
|
}
|
|
|
|
textureData = materialData->getTextureData(NTextureData::Usage::Normal);
|
|
|
|
if (textureData)
|
|
|
|
{
|
|
|
|
auto tex = _director->getTextureCache()->addImage(textureData->filename);
|
2021-12-25 10:04:45 +08:00
|
|
|
if (tex)
|
2015-11-25 10:45:03 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
Texture2D::TexParams texParams;
|
2021-12-25 10:04:45 +08:00
|
|
|
texParams.minFilter = backend::SamplerFilter::LINEAR;
|
|
|
|
texParams.magFilter = backend::SamplerFilter::LINEAR;
|
2021-12-08 00:11:53 +08:00
|
|
|
texParams.sAddressMode = textureData->wrapS;
|
|
|
|
texParams.tAddressMode = textureData->wrapT;
|
|
|
|
tex->setTexParameters(texParams);
|
2015-11-25 10:45:03 +08:00
|
|
|
}
|
2021-12-08 00:11:53 +08:00
|
|
|
mesh->setTexture(tex, NTextureData::Usage::Normal);
|
2014-08-21 11:23:31 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-12-08 00:11:53 +08:00
|
|
|
|
|
|
|
// set locale transform
|
|
|
|
Vec3 pos;
|
|
|
|
Quaternion qua;
|
|
|
|
Vec3 scale;
|
|
|
|
nodedata->transform.decompose(&scale, &qua, &pos);
|
2022-07-05 14:48:46 +08:00
|
|
|
meshRenderer->setPosition3D(pos);
|
|
|
|
meshRenderer->setRotationQuat(qua);
|
|
|
|
meshRenderer->setScaleX(scale.x);
|
|
|
|
meshRenderer->setScaleY(scale.y);
|
|
|
|
meshRenderer->setScaleZ(scale.z);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
meshRenderer->addMesh(mesh);
|
|
|
|
meshRenderer->autorelease();
|
|
|
|
meshRenderer->genMaterial();
|
2021-12-08 00:11:53 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
return meshRenderer;
|
2014-08-21 11:23:31 +08:00
|
|
|
}
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::createAttachMeshRendererNode(NodeData* nodedata, const MaterialDatas& materialdatas)
|
2014-08-21 11:23:31 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
for (const auto& it : nodedata->modelNodeDatas)
|
2014-08-21 11:23:31 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (it && getAttachNode(nodedata->id))
|
2014-08-21 11:23:31 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
auto mesh = createMeshRendererNode(nodedata, it, materialdatas);
|
|
|
|
if (mesh)
|
2014-08-21 11:23:31 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
getAttachNode(nodedata->id)->addChild(mesh);
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2014-08-21 11:23:31 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
for (const auto& it : nodedata->children)
|
2014-08-21 11:23:31 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
createAttachMeshRendererNode(it, materialdatas);
|
2014-08-21 11:23:31 +08:00
|
|
|
}
|
|
|
|
}
|
2015-05-06 04:07:32 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::setMaterial(Material* material)
|
2015-05-06 04:07:32 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
setMaterial(material, -1);
|
2015-05-06 04:07:32 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::setMaterial(Material* material, int meshIndex)
|
2015-05-06 04:07:32 +08:00
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(material, "Invalid Material");
|
|
|
|
AXASSERT(meshIndex == -1 || (meshIndex >= 0 && meshIndex < _meshes.size()), "Invalid meshIndex.");
|
2015-05-12 12:31:33 +08:00
|
|
|
|
2015-05-06 04:07:32 +08:00
|
|
|
if (meshIndex == -1)
|
|
|
|
{
|
2016-10-27 15:10:24 +08:00
|
|
|
for (ssize_t i = 0, size = _meshes.size(); i < size; ++i)
|
2015-05-06 04:07:32 +08:00
|
|
|
{
|
2015-12-04 10:54:43 +08:00
|
|
|
_meshes.at(i)->setMaterial(i == 0 ? material : material->clone());
|
2015-05-06 04:07:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-05-12 12:31:33 +08:00
|
|
|
auto mesh = _meshes.at(meshIndex);
|
|
|
|
mesh->setMaterial(material);
|
2015-05-06 04:07:32 +08:00
|
|
|
}
|
2015-05-12 12:31:33 +08:00
|
|
|
|
|
|
|
_usingAutogeneratedGLProgram = false;
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
Material* MeshRenderer::getMaterial(int meshIndex) const
|
2015-05-12 12:31:33 +08:00
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(meshIndex >= 0 && meshIndex < _meshes.size(), "Invalid meshIndex.");
|
2015-05-12 12:31:33 +08:00
|
|
|
return _meshes.at(meshIndex)->getMaterial();
|
2015-05-06 04:07:32 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::genMaterial(bool useLight)
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2014-10-13 15:17:22 +08:00
|
|
|
_shaderUsingLight = useLight;
|
2015-05-12 12:31:33 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
std::unordered_map<const MeshVertexData*, MeshMaterial*> materials;
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& meshVertexData : _meshVertexDatas)
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
auto material = getMeshRendererMaterialForAttribs(meshVertexData, useLight);
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(material, "material should cannot be null.");
|
2015-09-07 13:59:38 +08:00
|
|
|
materials[meshVertexData] = material;
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& mesh : _meshes)
|
2015-05-12 12:31:33 +08:00
|
|
|
{
|
2015-09-07 13:59:38 +08:00
|
|
|
auto material = materials[mesh->getMeshIndexData()->getMeshVertexData()];
|
2021-12-25 10:04:45 +08:00
|
|
|
// keep original state block if exist
|
2015-11-04 11:10:28 +08:00
|
|
|
auto oldmaterial = mesh->getMaterial();
|
|
|
|
if (oldmaterial)
|
|
|
|
{
|
|
|
|
material->setStateBlock(oldmaterial->getStateBlock());
|
|
|
|
}
|
2015-05-06 04:07:32 +08:00
|
|
|
|
2015-09-07 13:59:38 +08:00
|
|
|
if (material->getReferenceCount() == 1)
|
|
|
|
mesh->setMaterial(material);
|
2015-05-06 04:07:32 +08:00
|
|
|
else
|
2015-09-07 13:59:38 +08:00
|
|
|
mesh->setMaterial(material->clone());
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
|
|
|
}
|
2014-08-20 18:20:19 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::createNode(NodeData* nodedata, Node* root, const MaterialDatas& materialdatas, bool singleMesh)
|
2014-08-15 17:46:21 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Node* node = nullptr;
|
|
|
|
for (const auto& it : nodedata->modelNodeDatas)
|
2014-08-15 17:46:21 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (it)
|
2014-08-15 17:46:21 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
if (!it->bones.empty() || singleMesh)
|
2014-08-17 22:49:53 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
if (singleMesh && root != nullptr)
|
2015-04-27 19:12:44 +08:00
|
|
|
root->setName(nodedata->id);
|
2014-08-22 13:25:26 +08:00
|
|
|
auto mesh = Mesh::create(nodedata->id, getMeshIndexData(it->subMeshId));
|
2021-12-25 10:04:45 +08:00
|
|
|
if (mesh)
|
2014-08-18 10:32:23 +08:00
|
|
|
{
|
2014-08-22 13:25:26 +08:00
|
|
|
_meshes.pushBack(mesh);
|
2014-08-20 11:40:04 +08:00
|
|
|
if (_skeleton && it->bones.size())
|
|
|
|
{
|
|
|
|
auto skin = MeshSkin::create(_skeleton, it->bones, it->invBindPose);
|
2014-08-22 13:25:26 +08:00
|
|
|
mesh->setSkin(skin);
|
2014-08-20 11:40:04 +08:00
|
|
|
}
|
2022-07-05 14:48:46 +08:00
|
|
|
mesh->_visibleChanged = std::bind(&MeshRenderer::onAABBDirty, this);
|
2014-08-18 10:32:23 +08:00
|
|
|
|
2017-02-08 09:45:05 +08:00
|
|
|
if (it->materialId == "" && materialdatas.materials.size())
|
2014-08-18 10:32:23 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
const NTextureData* textureData =
|
|
|
|
materialdatas.materials[0].getTextureData(NTextureData::Usage::Diffuse);
|
2014-08-22 13:25:26 +08:00
|
|
|
mesh->setTexture(textureData->filename);
|
2014-08-20 11:40:04 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-02-08 09:45:05 +08:00
|
|
|
const NMaterialData* materialData = materialdatas.getMaterialData(it->materialId);
|
2021-12-25 10:04:45 +08:00
|
|
|
if (materialData)
|
2014-08-18 10:32:23 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
const NTextureData* textureData =
|
|
|
|
materialData->getTextureData(NTextureData::Usage::Diffuse);
|
|
|
|
if (textureData)
|
2014-08-18 10:32:23 +08:00
|
|
|
{
|
2015-07-08 17:00:01 +08:00
|
|
|
mesh->setTexture(textureData->filename);
|
|
|
|
auto tex = mesh->getTexture();
|
2021-12-25 10:04:45 +08:00
|
|
|
if (tex)
|
2014-08-20 11:40:04 +08:00
|
|
|
{
|
2015-05-06 04:07:32 +08:00
|
|
|
Texture2D::TexParams texParams;
|
2021-12-25 10:04:45 +08:00
|
|
|
texParams.minFilter = backend::SamplerFilter::LINEAR;
|
|
|
|
texParams.magFilter = backend::SamplerFilter::LINEAR;
|
2019-06-05 17:58:33 +08:00
|
|
|
texParams.sAddressMode = textureData->wrapS;
|
|
|
|
texParams.tAddressMode = textureData->wrapT;
|
2014-08-20 11:40:04 +08:00
|
|
|
tex->setTexParameters(texParams);
|
2021-12-25 10:04:45 +08:00
|
|
|
mesh->_isTransparent =
|
|
|
|
(materialData->getTextureData(NTextureData::Usage::Transparency) != nullptr);
|
2014-08-20 11:40:04 +08:00
|
|
|
}
|
|
|
|
}
|
2015-11-25 10:45:03 +08:00
|
|
|
textureData = materialData->getTextureData(NTextureData::Usage::Normal);
|
|
|
|
if (textureData)
|
|
|
|
{
|
2021-02-05 23:09:14 +08:00
|
|
|
auto tex = _director->getTextureCache()->addImage(textureData->filename);
|
2015-11-25 10:45:03 +08:00
|
|
|
if (tex)
|
|
|
|
{
|
|
|
|
Texture2D::TexParams texParams;
|
2021-12-25 10:04:45 +08:00
|
|
|
texParams.minFilter = backend::SamplerFilter::LINEAR;
|
|
|
|
texParams.magFilter = backend::SamplerFilter::LINEAR;
|
2019-06-05 17:58:33 +08:00
|
|
|
texParams.sAddressMode = textureData->wrapS;
|
|
|
|
texParams.tAddressMode = textureData->wrapT;
|
2015-11-25 10:45:03 +08:00
|
|
|
tex->setTexParameters(texParams);
|
|
|
|
}
|
2015-12-01 10:37:53 +08:00
|
|
|
mesh->setTexture(tex, NTextureData::Usage::Normal);
|
2015-11-25 10:45:03 +08:00
|
|
|
}
|
2014-08-18 10:32:23 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2015-03-25 10:04:51 +08:00
|
|
|
Vec3 pos;
|
|
|
|
Quaternion qua;
|
|
|
|
Vec3 scale;
|
|
|
|
nodedata->transform.decompose(&scale, &qua, &pos);
|
|
|
|
setPosition3D(pos);
|
|
|
|
setRotationQuat(qua);
|
|
|
|
setScaleX(scale.x);
|
|
|
|
setScaleY(scale.y);
|
|
|
|
setScaleZ(scale.z);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2016-05-09 12:49:29 +08:00
|
|
|
node = this;
|
2014-08-18 10:32:23 +08:00
|
|
|
}
|
2014-08-16 14:49:38 +08:00
|
|
|
}
|
2014-08-20 11:40:04 +08:00
|
|
|
else
|
2014-08-16 10:41:42 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
auto mesh = createMeshRendererNode(nodedata, it, materialdatas);
|
|
|
|
if (mesh)
|
2014-08-18 10:32:23 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (root)
|
2014-08-20 11:40:04 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
root->addChild(mesh);
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2014-08-16 16:56:04 +08:00
|
|
|
}
|
2022-07-05 14:48:46 +08:00
|
|
|
node = mesh;
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2014-08-15 17:46:21 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
if (nodedata->modelNodeDatas.size() == 0)
|
2014-08-15 17:46:21 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
node = Node::create();
|
|
|
|
if (node)
|
2014-08-15 17:46:21 +08:00
|
|
|
{
|
2014-09-03 11:43:42 +08:00
|
|
|
node->setName(nodedata->id);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2015-03-17 13:13:03 +08:00
|
|
|
// set locale transform
|
2015-03-17 12:15:03 +08:00
|
|
|
Vec3 pos;
|
|
|
|
Quaternion qua;
|
|
|
|
Vec3 scale;
|
2015-03-17 15:17:23 +08:00
|
|
|
nodedata->transform.decompose(&scale, &qua, &pos);
|
2015-03-17 12:15:03 +08:00
|
|
|
node->setPosition3D(pos);
|
|
|
|
node->setRotationQuat(qua);
|
|
|
|
node->setScaleX(scale.x);
|
|
|
|
node->setScaleY(scale.y);
|
|
|
|
node->setScaleZ(scale.z);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
if (root)
|
2014-08-15 18:20:37 +08:00
|
|
|
{
|
|
|
|
root->addChild(node);
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2014-08-15 17:46:21 +08:00
|
|
|
}
|
|
|
|
}
|
2016-10-27 15:10:24 +08:00
|
|
|
|
|
|
|
auto size = nodedata->children.size();
|
2021-12-25 10:04:45 +08:00
|
|
|
for (const auto& it : nodedata->children)
|
2014-08-15 17:46:21 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
createNode(it, node, materialdatas, size == 1);
|
2014-08-15 17:46:21 +08:00
|
|
|
}
|
|
|
|
}
|
2014-08-15 20:52:45 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
MeshIndexData* MeshRenderer::getMeshIndexData(std::string_view indexId) const
|
2014-08-15 20:52:45 +08:00
|
|
|
{
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& it : _meshVertexDatas)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
2014-08-22 13:25:26 +08:00
|
|
|
auto index = it->getMeshIndexDataById(indexId);
|
|
|
|
if (index)
|
|
|
|
return index;
|
2014-08-15 20:52:45 +08:00
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::addMesh(Mesh* mesh)
|
2014-08-18 10:32:23 +08:00
|
|
|
{
|
2014-08-22 13:25:26 +08:00
|
|
|
auto meshVertex = mesh->getMeshIndexData()->_vertexData;
|
|
|
|
_meshVertexDatas.pushBack(meshVertex);
|
|
|
|
_meshes.pushBack(mesh);
|
2014-08-18 10:32:23 +08:00
|
|
|
}
|
2014-07-29 10:49:06 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::setTexture(std::string_view texFile)
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2021-02-05 23:09:14 +08:00
|
|
|
auto tex = _director->getTextureCache()->addImage(texFile);
|
2014-06-23 19:08:26 +08:00
|
|
|
setTexture(tex);
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::setTexture(Texture2D* texture)
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& mesh : _meshes)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
2015-06-06 05:53:30 +08:00
|
|
|
mesh->setTexture(texture);
|
2014-08-20 19:01:04 +08:00
|
|
|
}
|
2014-07-29 10:49:06 +08:00
|
|
|
}
|
2022-07-05 14:48:46 +08:00
|
|
|
AttachNode* MeshRenderer::getAttachNode(std::string_view boneName)
|
2014-07-29 10:49:06 +08:00
|
|
|
{
|
|
|
|
auto it = _attachments.find(boneName);
|
|
|
|
if (it != _attachments.end())
|
|
|
|
return it->second;
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2014-08-18 11:13:08 +08:00
|
|
|
if (_skeleton)
|
2014-07-29 10:49:06 +08:00
|
|
|
{
|
2014-08-18 11:13:08 +08:00
|
|
|
auto bone = _skeleton->getBoneByName(boneName);
|
2015-02-04 10:24:29 +08:00
|
|
|
if (bone)
|
2015-02-04 10:36:16 +08:00
|
|
|
{
|
2015-02-04 10:24:29 +08:00
|
|
|
auto attachNode = AttachNode::create(bone);
|
|
|
|
addChild(attachNode);
|
2021-12-26 23:26:34 +08:00
|
|
|
_attachments.emplace(boneName, attachNode); // _attachments[boneName] = attachNode;
|
2015-02-04 10:24:29 +08:00
|
|
|
return attachNode;
|
|
|
|
}
|
2014-07-29 10:49:06 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2014-07-29 10:49:06 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::removeAttachNode(std::string_view boneName)
|
2014-07-29 10:49:06 +08:00
|
|
|
{
|
|
|
|
auto it = _attachments.find(boneName);
|
|
|
|
if (it != _attachments.end())
|
|
|
|
{
|
|
|
|
removeChild(it->second);
|
|
|
|
_attachments.erase(it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::removeAllAttachNode()
|
2014-07-29 10:49:06 +08:00
|
|
|
{
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& it : _attachments)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
2014-07-29 10:49:06 +08:00
|
|
|
removeChild(it.second);
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
2014-07-29 10:49:06 +08:00
|
|
|
_attachments.clear();
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
2015-04-28 23:55:23 +08:00
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
void MeshRenderer::visit(axis::Renderer* renderer, const axis::Mat4& parentTransform, uint32_t parentFlags)
|
2015-01-13 12:06:50 +08:00
|
|
|
{
|
|
|
|
// quick return if not visible. children won't be drawn.
|
|
|
|
if (!_visible)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2015-01-13 12:06:50 +08:00
|
|
|
uint32_t flags = processParentFlags(parentTransform, parentFlags);
|
2015-01-15 08:23:35 +08:00
|
|
|
flags |= FLAGS_RENDER_AS_3D;
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2015-01-13 12:06:50 +08:00
|
|
|
//
|
2021-02-05 23:09:14 +08:00
|
|
|
_director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
|
|
|
|
_director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2015-01-13 12:06:50 +08:00
|
|
|
bool visibleByCamera = isVisitableByVisitingCamera();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2015-01-13 12:06:50 +08:00
|
|
|
int i = 0;
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
if (!_children.empty())
|
2015-01-13 12:06:50 +08:00
|
|
|
{
|
|
|
|
sortAllChildren();
|
|
|
|
// draw children zOrder < 0
|
2021-12-25 10:04:45 +08:00
|
|
|
for (auto size = _children.size(); i < size; i++)
|
2015-01-13 12:06:50 +08:00
|
|
|
{
|
|
|
|
auto node = _children.at(i);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2015-01-13 12:06:50 +08:00
|
|
|
if (node && node->getLocalZOrder() < 0)
|
|
|
|
node->visit(renderer, _modelViewTransform, flags);
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// self draw
|
|
|
|
if (visibleByCamera)
|
|
|
|
this->draw(renderer, _modelViewTransform, flags);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
for (auto it = _children.cbegin() + i, itCend = _children.cend(); it != itCend; ++it)
|
2015-01-13 12:06:50 +08:00
|
|
|
(*it)->visit(renderer, _modelViewTransform, flags);
|
|
|
|
}
|
|
|
|
else if (visibleByCamera)
|
|
|
|
{
|
|
|
|
this->draw(renderer, _modelViewTransform, flags);
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2021-02-05 23:09:14 +08:00
|
|
|
_director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
|
2015-01-13 12:06:50 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::draw(Renderer* renderer, const Mat4& transform, uint32_t flags)
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2022-07-15 19:17:01 +08:00
|
|
|
#if AX_USE_CULLING
|
2021-12-25 10:04:45 +08:00
|
|
|
// TODO new-renderer: interface isVisibleInFrustum removal
|
|
|
|
// camera clipping
|
|
|
|
// if(_children.empty() && Camera::getVisitingCamera() &&
|
|
|
|
// !Camera::getVisitingCamera()->isVisibleInFrustum(&getAABB()))
|
metal support for cocos2d-x (#19305)
* remove deprecated files
* remove some deprecated codes
* remove more deprecated codes
* remove ui deprecated codes
* remove more deprecated codes
* remove deprecated codes in ccmenuitem
* remove more deprecated codes in ui
* remove more deprecated codes in ui
* remove more deprecated codes in ui
* remove more deprecated codes
* remove more deprecated codes
* remove more deprecated codes
* remove vr related codes and ignore some modules
* remove allocator
* remove some config
* 【Feature】add back-end project file
* [Feature] add back-end file
* add pipeline descriptor and shader cache
* [Feature] support sprite for backend
* [Feature] remove unneeded code
* [Feature] according to es2.0 spec, you must use clamp-to-edge as texture wrap mode, and no mipmapping for non-power-of-two texture
* [Feature] set texture wrap mode to clamp-to-edge, and no mipmapping for non-power-of-two texture
* [Feature] remove macro define to .cpp file
* [Feature] add log info
* [Feature] add PipelineDescriptor for TriangleCommand
* [Feature] add PipelineDescriptor object as member of TriangleCommand
* [Feature] add getPipelineDescriptor method
* add renderbackend
* complete pipeline descriptor
* [Feature] add viewport in RenderCommand
* set viewport when rendrering
* [Feature] occur error when using RendererBackend, to be fixed.
* a workaround to fix black screen on macOS 10.14 (#19090)
* add rendererbackend init function
* fix typo
* [Feature] modify testFile
* [BugFix] modify shader path
* [Feature] set default viewport
* fix projection
* [Feature] modify log info
* [BugFix] change viewport data type to int
* [BugFix] add BindGroup to PipelienDescriptor
* [BugFix] change a_position to vec3 in sprite.vert
* [BugFix] set vertexLayout according to V3F_C4B_T2F structure
* [Feature] revert a_position to vec4
* [Feature] renderer should not use gl codes directly
* [Feature] it's better not use default value parameter
* fix depth test setting
* rendererbackend -> renderer
* clear color and depth at begin
* add metal backend
* metal support normalized attribute
* simplify codes
* update external
* add render pass desctriptor in pipeline descriptor
* fix warnings
* fix crash and memeory leak
* refactor Texture2D
* put pipeline descriptor into render command
* simplify codes
* [Feature] update Sprite
* fix crash when closing app
* [Feature] update SpriteBatchNode and TextureAtlas
* support render texture(not finish)
* [Feature] remove unused code
* make tests work on mac
* fix download-deps path error
* make tests work on iOS
* [Feature] support ttf under normal label effect
* refactor triangle command processing
* let renderer handle more common commands
* refactor backend
* make render texture work
* [Feature] refactor backend for GL
* [Feature]Renaming to make it easy to understand
* [Feature] change warp mode to CLAMP_TO_EDGE
* fix ghost
* simplify visit render queue logic
* support progress timer without rial mode
* support partcile system
* Feature/update label (#149)
* [BugFix] fix compile error
* [Feature] support outline effect in ios
* [Feature] add shader file
* [BugFix] fix begin and end RenderPass
* [Feature] update CustomCommand
* [Feature] revert project.pbxproj
* [Feature] simplify codes
* [BugFix] pack AI88 to RGBA8888 only when outline enable
* [Feature] support shadow effect in Label
* [Feature] support BMFont
* [Feature] support glow effect
* [Feature] simplify shader files
* LabelAtlas work
* handle blend function correctly
* support tile map
* don't share buffer in metal
* alloc buffer size as needed
* support more tilemap
* Merge branch 'minggo/metal-support' into feature/updateLabel
* minggo/metal-support:
support tile map
handle blend function correctly
LabelAtlas work
Feature/update label (#149)
support partcile system
# Conflicts:
# cocos/2d/CCLabel.cpp
# cocos/2d/CCSprite.cpp
# cocos/2d/CCSpriteBatchNode.cpp
# cocos/renderer/CCQuadCommand.cpp
# cocos/renderer/CCQuadCommand.h
* render texture work without saving file
* use global viewport
* grid3d works
* remove grabber
* tiled3d works
* [BugFix] fix label bug
* [Feature] add updateSubData for buffer
* [Feature] remove setVertexCount
* support depth test
* add callback command
* [Feature] add UITest
* [Feature] update UITest
* [Feature] remove unneeded codes
* fix custom command issue
* fix layer color blend issue
* [BugFix] fix iOS compile error
* [Feature] remove unneeded codes
* [Feature] fix updateVertexBuffer
* layerradial works
* add draw test back
* fix batch issue
* fix compiling error
* [BugFix] support ETC1
* [BugFix] get the correct pipelineDescriptor
* [BugFix] skip draw when backendTexture nullptr
* clipping node support
* [Feature] add shader files
* fix stencil issue in metal
* [Feature] update UILayoutTest
* [BugFix] skip drawing when vertexCount is zero
* refactor renderer
* add set global z order for stencil manager commands
* fix warnings caused by type
* remove viewport in render command
* [Feature] fix warnings caused by type
* [BugFix] clear vertexCount and indexCount for CustomComand when needed
* [Feature] update clear for CustomCommand
* ios use metal
* fix viewport issue
* fix LayerColorGradient crash
* [cmake] transport to android and windows (#160)
* save point 1
* compile on windows
* run on android
* revert useless change
* android set CC_ENABLE_CACHE_TEXTURE_DATA to 1
* add initGlew
* fix android crash
* add TODO new-renderer
* review update
* revert onGLFWWindowPosCallback
* fix android compiling error
* Impl progress radial (#162)
* progresstimer add radial impl
* default drawType to element
* dec invoke times of createVertexBuffer (#163)
* support depth/stencil format for gl backend
* simplify progress timer codes
* support motionstreak, effect is wrong
* fix motionstreak issue
* [Feature] update Scissor Test (#161)
* [Feature] update Scissor Test
* [Feature] update ScissorTest
* [Feature] rename function
* [Feature] get constant reference if needed
* [Feature] show render status (#164)
* improve performance
* fix depth state
* fill error that triangle vertex/index number bigger than buffer
* fix compiline error in release mode
* fix buffer conflict between CPU and GPU on iOS/macOS
* Renderer refactor (#165)
* use one vertes/index buffer with opengl
* fix error on windows
* custom command support index format config
* CCLayer: compact vertex data structure
* update comment
* fix doc
* support fast tilemap
* pass index format instead
* fix some wrong effect
* fix render texture error
* fix texture per-element size
* fix texture format error
* BlendFunc type refactor, GLenum -> backend::BlendFactor (#167)
* BlendFunc use backend::BlendFactor as inner field
* update comments
* use int to replace GLenum
* update xcode project fiel
* rename to GLBlendConst
* add ccConstants.h
* update xcode project file
* update copyright
* remove primitive command
* remove CCPrimitive.cpp/.h
* remove deprecated files
* remove unneeded files
* remove multiple view support
* remove multiple view support
* remove the usage of frame buffer in camera
* director don't use frame buffer
* remove FrameBuffer
* remove BatchCommand
* add some api reference
* add physics2d back
* fix crash when close app on mac
* improve render texture
* fix rendertexture issue
* fix rendertexture issue
* simplify codes
* CMake support for mac & ios (#169)
* update cmake
* fix compile error
* update 3rd libs version
* remove CCThread.h/.cpp
* remove ccthread
* use audio engine to implement simple audio engine
* remove unneeded codes
* remove deprecated codes
* remove winrt macro
* remove CC_USE_WIC
* set partcile blend function in more elegant way
* remove unneeded codes
* remove unneeded codes
* cmake works on windows
* update project setting
* improve performance
* GLFloat -> float
* sync v3 cmake improvements into metal-support (#172)
* pick: modern cmake, compile definitions improvement (#19139)
* modern cmake, use target_compile_definitions partly
* simplify macro define, remove USE_*
* modern cmake, macro define
* add physics 2d macro define into ccConfig.h
* remove USE_CHIPMUNK macro in build.gradle
* remove CocosSelectModule.cmake
* shrink useless define
* simplify compile options config, re-add if necessary
* update external for tmp CI test
* un-quote target_compile_options value
* add "-g" parameter only when debug mode
* keep single build type when generator Xcode & VS projecy
* update external for tmp CI tes
* add static_cast<char>(-1), fix -Wc++11-narrowing
* simplify win32 compile define
* not modify code, only improve compile options
# Conflicts:
# .gitignore
# cmake/Modules/CocosConfigDepend.cmake
# cocos/CMakeLists.txt
# external/config.json
# tests/cpp-tests/CMakeLists.txt
* modern cmake, improve cmake_compiler_flags (#19145)
* cmake_compiler_flags
* Fix typo
* Fix typo2
* Remove chanages from Android.mk
* correct lua template cmake build (#19149)
* don't add -Wno-deprecated into jsb target
* correct lua template cmake build
* fix win32 lua template compile error
* prevent cmake in-source-build friendly (#19151)
* pick: Copy resources to "Resources/" on win32 like in linux configuration
* add "/Z7" for cpp-tests on windows
* [cmake] fix iOS xcode property setting failed (#19208)
* fix iOS xcode property setting failed
* use search_depend_libs_recursive at dlls collect
* fix typo
* [cmake] add find_host_library into iOS toolchain file (#19230)
* pick: [lua android] use luajit & template cmake update (#19239)
* increase cmake stability , remove tests/CMakeLists.txt (#19261)
* cmake win32 Precompiled header (#19273)
* Precompiled header
* Fix
* Precompiled header for cocos
* Precompiled header jscocos2d
* Fix for COCOS2D_DEBUG is always 1 on Android (#19291)
Related #19289
* little build fix, tests cpp-tests works on mac
* sync v3 build related codes into metal-support (#173)
* strict initialization for std::array
* remove proj.win32 project configs
* modern cmake, cmake_cleanup_remove_unused_variables (#19146)
* Switch travis CI to xenial (#19207)
* Switch travis CI to xenial
* Remove language: android
* Set language: cpp
* Fix java problem
* Update sdkmanager
* Fix sdkmanger
* next sdkmanager fix
* Remove xenial from android
* revert to sdk-tools-{system}-3859397
* Remove linux cmake install
* Update before-install.sh
* Update .travis.yml
* Simplify install-deps-linux.sh, tested on Ubuntu 16.04 (#19212)
* Simplify install-deps-linux.sh
* Cleanup
* pick: install ninja
* update cocos2d-console submodule
* for metal-support alpha release, we only test cpp
* add HelloCpp into project(Cocos2d-x) for tmp test
* update extenal metal-support-4
* update uniform setting
* [Feature] update BindGroup
* [Feature] empty-test
* [Feature] cpp-test
* [Feature] fix GL compiler error
* [Feature] fix GL crash
* [Feature] empty-test
* [Feature] cpp-tests
* [feature] improve frameRate
* [feature] fix opengl compile error
* [feature] fix opengl compile error
* [BugFix] fix compute maxLocation error
* [Feature] update setting unifrom
* [Feature] fix namespace
* [Feature] remove unneeded code
* [Bugfix] fix project file
* [Feature] update review
* [texture2d] impl texture format support (#175)
* texture update
* update
* update texture
* commit
* compile on windows
* ddd
* rename
* rename methods
* no crash
* save gl
* save
* save
* rename
* move out pixel format convert functions
* metal crash
* update
* update android
* support gles compressed texture format
* support more compress format
* add more conversion methods
* ss
* save
* update conversion methods
* add PVRTC format support
* reformat
* add marco linux
* fix GL marcro
* pvrtc supported only by ios 8.0+
* remove unused cmake
* revert change
* refactor Texture2D::initWithData
* fix conversion log
* refactor Texture2D::initWithData
* remove some OpenGL constants for PVRTC
* add todo
* fix typo
* AutoTest works on mac/iOS by disable part cases, sync v3 bug fix (#174)
* review cpp-tests, and fix part issues on start auto test
* sync png format fix: Node:Particle3D abnormal texture effects #19204
* fix cpp-tests SpritePolygon crash, wrong png format (#19170)
* fix wrong png convert format from sRGB to Gray
* erase plist index if all frames was erased
* test_A8.png have I8 format, fix it
* [CCSpriteCache] allow re-add plist & add testcase (#19175)
* allow re-add plist & add testcase
* remove comments/rename method/update testcase
* fix isSpriteFramesWithFileLoaded & add testcase
* remove used variable
* remove unused variable
* fix double free issues when js/lua-tests exit on iOS (#19236)
* disable part cases, AutoTest works without crash on mac
* update cocos2dx files json, to test cocos new next
* fix spritecache plist parsing issue (#19269)
* [linux] Fix FileUtils::getContents with folder (#19157)
* fix FileUtils::getContents on linux/mac
* use stat.st_mode
* simplify
* [CCFileUtils] win32 getFileSize (#19176)
* win32 getFileSize
* fix stat
* [cpp test-Android]20:FileUtils/2 change title (#19197)
* sync #19200
* sync #19231
* [android lua] improve performance of lua loader (#19234)
* [lua] improve performance of lua loader
* remove cache fix
* Revert "fix spritecache plist parsing issue (#19269)"
This reverts commit f3a85ece4307a7b90816c34489d1ed2c8fd11baf.
* remove win32 project files ref in template.json
* add metal framework lnk ref into cpp template
* test on iOS, and disable part cases
* alBufferData instead of alBufferDataStatic for small audio file on Apple (#19227)
* changes AudioCache to use alBufferData instead of alBufferDataStatic
(also makes test 19 faster to trigger openal bugs faster)
The original problem: CrashIfClientProvidedBogusAudioBufferList
https://github.com/cocos2d/cocos2d-x/issues/18948
is not happening anymore, but there's still a not very frequent issue
that makes OpenAL crash with a call stack like this.
AudioCache::readDataTask > alBufferData > CleanUpDeadBufferList
It happes more frequently when the device is "cold", which means after
half an hour of not using the device (locked).
I could not find the actual source code for iOS OpenAL, so I used the
macOS versions:
https://opensource.apple.com/source/OpenAL/OpenAL-48.7/Source/OpenAL/oalImp.cpp.auto.html
They seem to use CAGuard.h to make sure the dead buffer list
has no threading issues. I'm worried because the CAGuard code I found
has macos and win32 define but no iOS, so I'm not sure. I guess the
iOS version is different and has the guard.
I could not find a place in the code that's unprotected by the locks
except the InitializeBufferMap() which should not be called more than
once from cocos, and there's a workaround in AudioEngine-impl for it.
I reduced the occurence of the CleanUpDeadBufferList crash by moving
the guard in ~AudioCache to cover the alDeleteBuffers call.
* remove hack method "setTimeout" on audio
* AutoTest works on iOS
* support set ios deployment target for root project
* enable all texture2d cases, since Jiang have fixed
* add CCTextureUtils to xcode project file (#176)
* add leak cases for SpriteFrameCache (#177)
* re-add SpriteFrameCache cases
* update template file json
* Update SpriteFrameCacheTest.cpp
* fix compiling error
2019-01-18 15:08:25 +08:00
|
|
|
// return;
|
2015-01-14 14:41:10 +08:00
|
|
|
#endif
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2014-08-16 14:16:17 +08:00
|
|
|
if (_skeleton)
|
|
|
|
_skeleton->updateBoneMatrix();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2014-05-19 05:49:16 +08:00
|
|
|
Color4F color(getDisplayedColor());
|
|
|
|
color.a = getDisplayedOpacity() / 255.0f;
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
// check light and determine the shader used
|
2015-03-16 18:04:50 +08:00
|
|
|
const auto& scene = Director::getInstance()->getRunningScene();
|
2015-05-12 12:31:33 +08:00
|
|
|
|
|
|
|
// Don't override GLProgramState if using manually set Material
|
|
|
|
if (_usingAutogeneratedGLProgram && scene)
|
2015-03-16 18:04:50 +08:00
|
|
|
{
|
2015-05-14 08:39:39 +08:00
|
|
|
const auto lights = scene->getLights();
|
2021-12-25 10:04:45 +08:00
|
|
|
bool usingLight = false;
|
|
|
|
for (const auto light : lights)
|
|
|
|
{
|
2016-04-25 09:46:33 +08:00
|
|
|
usingLight = light->isEnabled() && ((static_cast<unsigned int>(light->getLightFlag()) & _lightMask) > 0);
|
2015-03-16 18:04:50 +08:00
|
|
|
if (usingLight)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (usingLight != _shaderUsingLight)
|
2015-05-12 12:31:33 +08:00
|
|
|
{
|
2015-09-17 14:45:16 +08:00
|
|
|
genMaterial(usingLight);
|
2015-05-12 12:31:33 +08:00
|
|
|
}
|
2014-09-25 17:13:46 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& mesh : _meshes)
|
2015-05-06 04:07:32 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
mesh->draw(renderer, _globalZOrder, transform, flags, _lightMask, Vec4(color.r, color.g, color.b, color.a),
|
2015-05-06 04:07:32 +08:00
|
|
|
_forceDepthWrite);
|
2014-06-05 16:36:01 +08:00
|
|
|
}
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
bool MeshRenderer::setProgramState(backend::ProgramState* programState, bool needsRetain)
|
2014-08-20 19:01:04 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (Node::setProgramState(programState, needsRetain))
|
|
|
|
{
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& state : _meshes)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
2020-10-16 16:23:14 +08:00
|
|
|
state->setProgramState(programState);
|
|
|
|
}
|
|
|
|
return true;
|
2014-08-20 19:01:04 +08:00
|
|
|
}
|
2020-10-16 16:23:14 +08:00
|
|
|
return false;
|
2014-08-20 19:01:04 +08:00
|
|
|
}
|
2019-03-13 15:06:30 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::setBlendFunc(const BlendFunc& blendFunc)
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (_blend.src != blendFunc.src || _blend.dst != blendFunc.dst)
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
|
|
|
_blend = blendFunc;
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& mesh : _meshes)
|
2014-08-20 19:01:04 +08:00
|
|
|
{
|
2015-05-06 04:07:32 +08:00
|
|
|
mesh->setBlendFunc(blendFunc);
|
2014-08-20 19:01:04 +08:00
|
|
|
}
|
2014-05-19 05:49:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
const BlendFunc& MeshRenderer::getBlendFunc() const
|
2014-05-19 05:49:16 +08:00
|
|
|
{
|
|
|
|
return _blend;
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
AABB MeshRenderer::getAABBRecursively()
|
2015-04-08 16:40:04 +08:00
|
|
|
{
|
2015-07-09 18:05:47 +08:00
|
|
|
return getAABBRecursivelyImp(this);
|
2015-04-08 16:40:04 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
const AABB& MeshRenderer::getAABB() const
|
2014-08-08 17:54:39 +08:00
|
|
|
{
|
2014-08-12 13:45:06 +08:00
|
|
|
Mat4 nodeToWorldTransform(getNodeToWorldTransform());
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2014-08-12 13:45:06 +08:00
|
|
|
// If nodeToWorldTransform matrix isn't changed, we don't need to transform aabb.
|
2014-08-18 17:02:13 +08:00
|
|
|
if (memcmp(_nodeToWorldTransform.m, nodeToWorldTransform.m, sizeof(Mat4)) == 0 && !_aabbDirty)
|
2014-08-08 17:54:39 +08:00
|
|
|
{
|
2014-08-12 13:45:06 +08:00
|
|
|
return _aabb;
|
2014-08-08 17:54:39 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-08-18 17:02:13 +08:00
|
|
|
_aabb.reset();
|
2015-04-08 16:40:04 +08:00
|
|
|
if (_meshes.size())
|
|
|
|
{
|
|
|
|
Mat4 transform(nodeToWorldTransform);
|
2021-12-25 10:04:45 +08:00
|
|
|
for (const auto& it : _meshes)
|
|
|
|
{
|
2015-04-08 16:40:04 +08:00
|
|
|
if (it->isVisible())
|
|
|
|
_aabb.merge(it->getAABB());
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2015-04-08 16:40:04 +08:00
|
|
|
_aabb.transform(transform);
|
|
|
|
_nodeToWorldTransform = nodeToWorldTransform;
|
2021-12-25 10:04:45 +08:00
|
|
|
_aabbDirty = false;
|
2014-08-18 17:02:13 +08:00
|
|
|
}
|
2014-08-08 17:54:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2014-08-12 13:45:06 +08:00
|
|
|
return _aabb;
|
2014-08-08 17:54:39 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
Action* MeshRenderer::runAction(Action* action)
|
2015-01-28 09:05:51 +08:00
|
|
|
{
|
|
|
|
setForceDepthWrite(true);
|
|
|
|
return Node::runAction(action);
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
Rect MeshRenderer::getBoundingBox() const
|
2014-08-08 17:54:39 +08:00
|
|
|
{
|
|
|
|
AABB aabb = getAABB();
|
|
|
|
Rect ret(aabb._min.x, aabb._min.y, (aabb._max.x - aabb._min.x), (aabb._max.y - aabb._min.y));
|
2021-12-25 10:04:45 +08:00
|
|
|
return ret;
|
2014-08-08 17:54:39 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::setCullFace(CullFaceSide side)
|
2014-08-13 17:38:16 +08:00
|
|
|
{
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& it : _meshes)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
2019-02-15 14:30:10 +08:00
|
|
|
it->getMaterial()->getStateBlock().setCullFaceSide(side);
|
2014-08-13 17:38:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::setCullFaceEnabled(bool enable)
|
2014-08-13 17:38:16 +08:00
|
|
|
{
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& it : _meshes)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
2019-02-15 14:30:10 +08:00
|
|
|
it->getMaterial()->getStateBlock().setCullFace(enable);
|
2014-08-13 17:38:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
Mesh* MeshRenderer::getMeshByIndex(int index) const
|
2014-08-18 11:13:08 +08:00
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(index < _meshes.size(), "Invalid index.");
|
2014-08-22 13:25:26 +08:00
|
|
|
return _meshes.at(index);
|
2014-08-18 11:13:08 +08:00
|
|
|
}
|
|
|
|
|
2014-10-25 12:27:03 +08:00
|
|
|
/**get Mesh by Name */
|
2022-07-05 14:48:46 +08:00
|
|
|
Mesh* MeshRenderer::getMeshByName(std::string_view name) const
|
2014-08-18 11:13:08 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
for (const auto& it : _meshes)
|
|
|
|
{
|
2014-08-18 11:13:08 +08:00
|
|
|
if (it->getName() == name)
|
|
|
|
return it;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
std::vector<Mesh*> MeshRenderer::getMeshArrayByName(std::string_view name) const
|
2014-10-25 12:27:03 +08:00
|
|
|
{
|
|
|
|
std::vector<Mesh*> meshes;
|
2021-12-25 10:04:45 +08:00
|
|
|
for (const auto& it : _meshes)
|
|
|
|
{
|
2014-10-25 12:27:03 +08:00
|
|
|
if (it->getName() == name)
|
|
|
|
meshes.push_back(it);
|
|
|
|
}
|
|
|
|
return meshes;
|
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
Mesh* MeshRenderer::getMesh() const
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
|
|
|
if (_meshes.empty())
|
2016-10-27 15:20:41 +08:00
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
return _meshes.at(0);
|
2016-10-27 15:20:41 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRenderer::setForce2DQueue(bool force2D)
|
2015-07-01 14:24:22 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
for (const auto& mesh : _meshes)
|
|
|
|
{
|
2015-07-01 14:24:22 +08:00
|
|
|
mesh->setForce2DQueue(force2D);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-19 11:56:09 +08:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
2022-07-05 14:48:46 +08:00
|
|
|
MeshRendererCache* MeshRendererCache::_cacheInstance = nullptr;
|
|
|
|
MeshRendererCache* MeshRendererCache::getInstance()
|
2014-08-19 11:56:09 +08:00
|
|
|
{
|
|
|
|
if (_cacheInstance == nullptr)
|
2022-07-05 14:48:46 +08:00
|
|
|
_cacheInstance = new MeshRendererCache();
|
2014-08-19 11:56:09 +08:00
|
|
|
return _cacheInstance;
|
|
|
|
}
|
2022-07-05 14:48:46 +08:00
|
|
|
void MeshRendererCache::destroyInstance()
|
2014-08-19 11:56:09 +08:00
|
|
|
{
|
|
|
|
if (_cacheInstance)
|
|
|
|
{
|
|
|
|
delete _cacheInstance;
|
|
|
|
_cacheInstance = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-12 21:31:54 +08:00
|
|
|
MeshRendererCache::MeshRenderData* MeshRendererCache::getMeshRenderData(std::string_view key) const
|
2014-08-19 11:56:09 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
auto it = _meshDatas.find(key);
|
|
|
|
if (it != _meshDatas.end())
|
2014-08-19 11:56:09 +08:00
|
|
|
return it->second;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-07-12 21:31:54 +08:00
|
|
|
bool MeshRendererCache::addMeshRenderData(std::string_view key, MeshRendererCache::MeshRenderData* meshdata)
|
2014-08-19 11:56:09 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
auto it = _meshDatas.find(key);
|
|
|
|
if (it == _meshDatas.end())
|
2014-08-19 11:56:09 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
_meshDatas.emplace(key, meshdata);
|
2014-08-19 11:56:09 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-07-12 21:31:54 +08:00
|
|
|
void MeshRendererCache::removeMeshRenderData(std::string_view key)
|
2014-08-19 11:56:09 +08:00
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
auto it = _meshDatas.find(key);
|
|
|
|
if (it != _meshDatas.end())
|
2014-08-19 11:56:09 +08:00
|
|
|
{
|
|
|
|
delete it->second;
|
2022-07-05 14:48:46 +08:00
|
|
|
_meshDatas.erase(it);
|
2014-08-19 11:56:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-12 21:31:54 +08:00
|
|
|
void MeshRendererCache::removeAllMeshRenderData()
|
2014-08-19 11:56:09 +08:00
|
|
|
{
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& it : _meshDatas)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
2014-08-19 11:56:09 +08:00
|
|
|
delete it.second;
|
|
|
|
}
|
2022-07-05 14:48:46 +08:00
|
|
|
_meshDatas.clear();
|
2014-08-19 11:56:09 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
MeshRendererCache::MeshRendererCache() {}
|
|
|
|
MeshRendererCache::~MeshRendererCache()
|
2014-08-19 11:56:09 +08:00
|
|
|
{
|
2022-07-12 21:31:54 +08:00
|
|
|
removeAllMeshRenderData();
|
2014-08-19 11:56:09 +08:00
|
|
|
}
|
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
static MeshMaterial* getMeshRendererMaterialForAttribs(MeshVertexData* meshVertexData, bool usesLight)
|
2015-05-12 12:31:33 +08:00
|
|
|
{
|
2019-01-30 09:35:17 +08:00
|
|
|
bool textured = meshVertexData->hasVertexAttrib(shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD);
|
2021-12-25 10:04:45 +08:00
|
|
|
bool hasSkin = meshVertexData->hasVertexAttrib(shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_INDEX) &&
|
|
|
|
meshVertexData->hasVertexAttrib(shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_WEIGHT);
|
|
|
|
bool hasNormal = meshVertexData->hasVertexAttrib(shaderinfos::VertexKey::VERTEX_ATTRIB_NORMAL);
|
|
|
|
bool hasTangentSpace = meshVertexData->hasVertexAttrib(shaderinfos::VertexKey::VERTEX_ATTRIB_TANGENT) &&
|
|
|
|
meshVertexData->hasVertexAttrib(shaderinfos::VertexKey::VERTEX_ATTRIB_BINORMAL);
|
2022-07-05 14:48:46 +08:00
|
|
|
MeshMaterial::MaterialType type;
|
2021-12-25 10:04:45 +08:00
|
|
|
if (textured)
|
2015-05-12 12:31:33 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (hasTangentSpace)
|
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
type = hasNormal && usesLight ? MeshMaterial::MaterialType::BUMPED_DIFFUSE
|
|
|
|
: MeshMaterial::MaterialType::UNLIT;
|
2015-11-25 10:45:03 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
else
|
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
type = hasNormal && usesLight ? MeshMaterial::MaterialType::DIFFUSE
|
|
|
|
: MeshMaterial::MaterialType::UNLIT;
|
2015-11-25 10:45:03 +08:00
|
|
|
}
|
2015-05-12 12:31:33 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-07-05 14:48:46 +08:00
|
|
|
type = hasNormal && usesLight ? MeshMaterial::MaterialType::DIFFUSE_NOTEX
|
|
|
|
: MeshMaterial::MaterialType::UNLIT_NOTEX;
|
2015-05-12 12:31:33 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-05 14:48:46 +08:00
|
|
|
return MeshMaterial::createBuiltInMaterial(type, hasSkin);
|
2015-05-12 12:31:33 +08:00
|
|
|
}
|
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
NS_AX_END
|