2019-05-29 00:06:29 +02:00
|
|
|
/* Copyright (C) 2019 Wildfire Games.
|
2012-08-06 23:34:41 +02:00
|
|
|
* This file is part of 0 A.D.
|
|
|
|
*
|
|
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2012-08-06 21:10:47 +02:00
|
|
|
|
|
|
|
#include "precompiled.h"
|
|
|
|
|
2012-08-21 18:40:07 +02:00
|
|
|
#include "renderer/MikktspaceWrap.h"
|
2012-08-06 21:10:47 +02:00
|
|
|
|
2016-11-23 14:02:58 +01:00
|
|
|
MikkTSpace::MikkTSpace(const CModelDefPtr& m, std::vector<float>& v, bool gpuSkinning) : m_Model(m),
|
2012-10-29 14:20:21 +01:00
|
|
|
m_NewVertices(v), m_GpuSkinning(gpuSkinning)
|
2012-08-06 21:10:47 +02:00
|
|
|
{
|
2012-10-29 14:20:21 +01:00
|
|
|
// ensure that m_NewVertices is empty
|
|
|
|
m_NewVertices.clear();
|
2016-11-23 15:09:58 +01:00
|
|
|
|
2012-08-06 21:10:47 +02:00
|
|
|
// set up SMikkTSpaceInterface struct
|
2019-05-29 00:06:29 +02:00
|
|
|
m_Interface.m_getNumFaces = GetNumFaces;
|
|
|
|
m_Interface.m_getNumVerticesOfFace = GetNumVerticesOfFace;
|
|
|
|
m_Interface.m_getPosition = GetPosition;
|
|
|
|
m_Interface.m_getNormal = GetNormal;
|
|
|
|
m_Interface.m_getTexCoord = GetTexCoord;
|
|
|
|
m_Interface.m_setTSpaceBasic = nullptr;
|
|
|
|
m_Interface.m_setTSpace = SetTSpace;
|
2012-08-06 21:10:47 +02:00
|
|
|
|
|
|
|
// set up SMikkTSpaceContext struct
|
2012-10-29 14:20:21 +01:00
|
|
|
m_Context.m_pInterface = &m_Interface;
|
2019-05-29 00:06:29 +02:00
|
|
|
m_Context.m_pUserData = static_cast<void*>(this);
|
2012-08-06 21:10:47 +02:00
|
|
|
}
|
|
|
|
|
2019-05-29 00:06:29 +02:00
|
|
|
void MikkTSpace::Generate()
|
2012-08-06 21:10:47 +02:00
|
|
|
{
|
2012-10-29 14:20:21 +01:00
|
|
|
genTangSpaceDefault(&m_Context);
|
2012-08-06 21:10:47 +02:00
|
|
|
}
|
|
|
|
|
2019-05-31 01:03:01 +02:00
|
|
|
int MikkTSpace::GetNumFaces(const SMikkTSpaceContext* pContext)
|
2012-08-06 21:10:47 +02:00
|
|
|
{
|
2019-05-29 00:06:29 +02:00
|
|
|
return GetUserDataFromContext(pContext)->m_Model->GetNumFaces();
|
2012-08-06 21:10:47 +02:00
|
|
|
}
|
|
|
|
|
2019-05-29 00:06:29 +02:00
|
|
|
int MikkTSpace::GetNumVerticesOfFace(const SMikkTSpaceContext* UNUSED(pContext), const int UNUSED(iFace))
|
2012-08-06 21:10:47 +02:00
|
|
|
{
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
2019-05-31 01:03:01 +02:00
|
|
|
void MikkTSpace::GetPosition(const SMikkTSpaceContext* pContext,
|
|
|
|
float* fvPosOut, const int iFace, const int iVert)
|
2012-08-06 21:10:47 +02:00
|
|
|
{
|
2019-05-29 00:06:29 +02:00
|
|
|
const CVector3D& position = GetVertex(pContext, iFace, iVert).m_Coords;
|
2012-08-06 21:10:47 +02:00
|
|
|
|
2019-05-29 00:06:29 +02:00
|
|
|
fvPosOut[0] = position.X;
|
|
|
|
fvPosOut[1] = position.Y;
|
|
|
|
fvPosOut[2] = position.Z;
|
2012-08-06 21:10:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-05-31 01:03:01 +02:00
|
|
|
void MikkTSpace::GetNormal(const SMikkTSpaceContext* pContext,
|
|
|
|
float* fvNormOut, const int iFace, const int iVert)
|
2012-08-06 21:10:47 +02:00
|
|
|
{
|
2019-05-29 00:06:29 +02:00
|
|
|
const CVector3D& normal = GetVertex(pContext, iFace, iVert).m_Norm;
|
2012-08-06 21:10:47 +02:00
|
|
|
|
2019-05-29 00:06:29 +02:00
|
|
|
fvNormOut[0] = normal.X;
|
|
|
|
fvNormOut[1] = normal.Y;
|
|
|
|
fvNormOut[2] = normal.Z;
|
2012-08-06 21:10:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-05-31 01:03:01 +02:00
|
|
|
void MikkTSpace::GetTexCoord(const SMikkTSpaceContext* pContext,
|
|
|
|
float* fvTexcOut, const int iFace, const int iVert)
|
2012-08-06 21:10:47 +02:00
|
|
|
{
|
2019-05-29 00:06:29 +02:00
|
|
|
const MikkTSpace* userData = GetUserDataFromContext(pContext);
|
|
|
|
const SModelFace& face = userData->m_Model->GetFaces()[iFace];
|
|
|
|
const SModelVertex& v = userData->m_Model->GetVertices()[face.m_Verts[iVert]];
|
2012-08-06 21:10:47 +02:00
|
|
|
|
2019-05-29 00:06:29 +02:00
|
|
|
// The tangents are calculated according to the 'default' UV set
|
2012-08-06 21:10:47 +02:00
|
|
|
fvTexcOut[0] = v.m_UVs[0];
|
2019-05-29 00:06:29 +02:00
|
|
|
fvTexcOut[1] = 1.0 - v.m_UVs[1];
|
2012-08-06 21:10:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-05-31 01:03:01 +02:00
|
|
|
void MikkTSpace::SetTSpace(const SMikkTSpaceContext* pContext, const float* fvTangent,
|
|
|
|
const float* UNUSED(fvBiTangent), const float UNUSED(fMagS), const float UNUSED(fMagT),
|
2019-05-29 00:06:29 +02:00
|
|
|
const tbool bIsOrientationPreserving, const int iFace, const int iVert)
|
2012-08-06 21:10:47 +02:00
|
|
|
{
|
2019-05-29 00:06:29 +02:00
|
|
|
const MikkTSpace* userData = GetUserDataFromContext(pContext);
|
|
|
|
const SModelFace& face = userData->m_Model->GetFaces()[iFace];
|
|
|
|
const SModelVertex& vertex = userData->m_Model->GetVertices()[face.m_Verts[iVert]];
|
|
|
|
|
2019-05-31 01:03:01 +02:00
|
|
|
const CVector3D& p = vertex.m_Coords;
|
2019-05-29 00:06:29 +02:00
|
|
|
userData->m_NewVertices.push_back(p.X);
|
|
|
|
userData->m_NewVertices.push_back(p.Y);
|
|
|
|
userData->m_NewVertices.push_back(p.Z);
|
|
|
|
|
|
|
|
const CVector3D& n = vertex.m_Norm;
|
|
|
|
userData->m_NewVertices.push_back(n.X);
|
|
|
|
userData->m_NewVertices.push_back(n.Y);
|
|
|
|
userData->m_NewVertices.push_back(n.Z);
|
|
|
|
|
|
|
|
userData->m_NewVertices.push_back(fvTangent[0]);
|
|
|
|
userData->m_NewVertices.push_back(fvTangent[1]);
|
|
|
|
userData->m_NewVertices.push_back(fvTangent[2]);
|
|
|
|
userData->m_NewVertices.push_back(bIsOrientationPreserving != 0 ? 1.f : -1.f);
|
|
|
|
|
|
|
|
if (userData->m_GpuSkinning)
|
2012-10-29 14:20:21 +01:00
|
|
|
{
|
2019-05-29 00:06:29 +02:00
|
|
|
for (u8 j = 0; j < 4; ++j)
|
2012-10-29 14:20:21 +01:00
|
|
|
{
|
2019-05-29 00:06:29 +02:00
|
|
|
userData->m_NewVertices.push_back(vertex.m_Blend.m_Bone[j]);
|
|
|
|
userData->m_NewVertices.push_back(255.f * vertex.m_Blend.m_Weight[j]);
|
2012-10-29 14:20:21 +01:00
|
|
|
}
|
|
|
|
}
|
2012-08-06 21:10:47 +02:00
|
|
|
|
2019-05-29 00:06:29 +02:00
|
|
|
size_t numUVsPerVertex = userData->m_Model->GetNumUVsPerVertex();
|
2012-08-06 21:10:47 +02:00
|
|
|
for (size_t UVset = 0; UVset < numUVsPerVertex; ++UVset)
|
|
|
|
{
|
2019-05-29 00:06:29 +02:00
|
|
|
userData->m_NewVertices.push_back(vertex.m_UVs[UVset * 2]);
|
|
|
|
userData->m_NewVertices.push_back(1.f - vertex.m_UVs[UVset * 2 + 1]);
|
2012-08-06 21:10:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-31 01:03:01 +02:00
|
|
|
MikkTSpace* MikkTSpace::GetUserDataFromContext(const SMikkTSpaceContext* pContext)
|
2019-05-29 00:06:29 +02:00
|
|
|
{
|
|
|
|
return static_cast<MikkTSpace*>(pContext->m_pUserData);
|
|
|
|
}
|
2012-08-06 21:10:47 +02:00
|
|
|
|
2019-05-31 01:03:01 +02:00
|
|
|
SModelVertex MikkTSpace::GetVertex(const SMikkTSpaceContext* pContext, const int iFace, const int iVert)
|
2019-05-29 00:06:29 +02:00
|
|
|
{
|
|
|
|
const MikkTSpace* userData = GetUserDataFromContext(pContext);
|
|
|
|
const SModelFace& f = userData->m_Model->GetFaces()[iFace];
|
|
|
|
return userData->m_Model->GetVertices()[f.m_Verts[iVert]];
|
|
|
|
}
|