1 /* Copyright (C) 2012 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #include "precompiled.h"
20 #include <boost/bind.hpp>
22 #include "graphics/Color.h"
23 #include "graphics/LightEnv.h"
24 #include "graphics/Model.h"
25 #include "graphics/ModelDef.h"
26 #include "graphics/ShaderManager.h"
27 #include "graphics/TextureManager.h"
29 #include "renderer/MikktspaceWrap.h"
31 #include "third_party/mikktspace/mikktspace.h"
35 MikkTSpace::MikkTSpace(const CModelDefPtr
& m
, std::vector
<float>& v
, bool gpuSkinning
) : m_Model(m
),
36 m_NewVertices(v
), m_GpuSkinning(gpuSkinning
)
38 // ensure that m_NewVertices is empty
39 m_NewVertices
.clear();
41 // set up SMikkTSpaceInterface struct
42 m_Interface
.m_getNumFaces
= getNumFaces
;
43 m_Interface
.m_getNumVerticesOfFace
= getNumVerticesOfFace
;
44 m_Interface
.m_getPosition
= getPosition
;
45 m_Interface
.m_getNormal
= getNormal
;
46 m_Interface
.m_getTexCoord
= getTexCoord
;
47 m_Interface
.m_setTSpaceBasic
= NULL
;
48 m_Interface
.m_setTSpace
= setTSpace
;
50 // set up SMikkTSpaceContext struct
51 m_Context
.m_pInterface
= &m_Interface
;
52 m_Context
.m_pUserData
= (void*)this;
55 void MikkTSpace::generate()
57 genTangSpaceDefault(&m_Context
);
61 int MikkTSpace::getNumFaces(const SMikkTSpaceContext
*pContext
)
63 return ((MikkTSpace
*)pContext
->m_pUserData
)->m_Model
->GetNumFaces();
67 int MikkTSpace::getNumVerticesOfFace(const SMikkTSpaceContext
* UNUSED(pContext
), const int UNUSED(iFace
))
73 void MikkTSpace::getPosition(const SMikkTSpaceContext
*pContext
,
74 float fvPosOut
[], const int iFace
, const int iVert
)
76 SModelFace
&face
= ((MikkTSpace
*)pContext
->m_pUserData
)->m_Model
->GetFaces()[iFace
];
77 long i
= face
.m_Verts
[iVert
];
78 const CVector3D
&p
= ((MikkTSpace
*)pContext
->m_pUserData
)->m_Model
->GetVertices()[i
].m_Coords
;
86 void MikkTSpace::getNormal(const SMikkTSpaceContext
*pContext
,
87 float fvNormOut
[], const int iFace
, const int iVert
)
89 SModelFace
&face
= ((MikkTSpace
*)pContext
->m_pUserData
)->m_Model
->GetFaces()[iFace
];
90 long i
= face
.m_Verts
[iVert
];
91 const CVector3D
&n
= ((MikkTSpace
*)pContext
->m_pUserData
)->m_Model
->GetVertices()[i
].m_Norm
;
99 void MikkTSpace::getTexCoord(const SMikkTSpaceContext
*pContext
,
100 float fvTexcOut
[], const int iFace
, const int iVert
)
102 SModelFace
&face
= ((MikkTSpace
*)pContext
->m_pUserData
)->m_Model
->GetFaces()[iFace
];
103 long i
= face
.m_Verts
[iVert
];
104 SModelVertex
&v
= ((MikkTSpace
*)pContext
->m_pUserData
)->m_Model
->GetVertices()[i
];
106 // the tangents are calculated according to the 'default' UV set
107 fvTexcOut
[0] = v
.m_UVs
[0];
108 fvTexcOut
[1] = 1.0-v
.m_UVs
[1];
112 void MikkTSpace::setTSpace(const SMikkTSpaceContext
* pContext
, const float fvTangent
[],
113 const float UNUSED(fvBiTangent
)[], const float UNUSED(fMagS
), const float UNUSED(fMagT
),
114 const tbool bIsOrientationPreserving
, const int iFace
, const int iVert
)
116 SModelFace
&face
= ((MikkTSpace
*)pContext
->m_pUserData
)->m_Model
->GetFaces()[iFace
];
117 long i
= face
.m_Verts
[iVert
];
119 SModelVertex
* vertices
= ((MikkTSpace
*)pContext
->m_pUserData
)->m_Model
->GetVertices();
120 size_t numUVsPerVertex
= ((MikkTSpace
*)pContext
->m_pUserData
)->m_Model
->GetNumUVsPerVertex();
121 std::vector
<float>& m_NewVertices
= ((MikkTSpace
*)pContext
->m_pUserData
)->m_NewVertices
;
123 const CVector3D
&p
= vertices
[i
].m_Coords
;
124 const CVector3D
&n
= vertices
[i
].m_Norm
;
126 m_NewVertices
.push_back(p
.X
);
127 m_NewVertices
.push_back(p
.Y
);
128 m_NewVertices
.push_back(p
.Z
);
130 m_NewVertices
.push_back(n
.X
);
131 m_NewVertices
.push_back(n
.Y
);
132 m_NewVertices
.push_back(n
.Z
);
134 m_NewVertices
.push_back(fvTangent
[0]);
135 m_NewVertices
.push_back(fvTangent
[1]);
136 m_NewVertices
.push_back(fvTangent
[2]);
137 m_NewVertices
.push_back(bIsOrientationPreserving
> 0.5 ? 1.0f
: (-1.0f
));
139 if (((MikkTSpace
*)pContext
->m_pUserData
)->m_GpuSkinning
)
141 for (size_t j
= 0; j
< 4; ++j
)
143 m_NewVertices
.push_back(vertices
[i
].m_Blend
.m_Bone
[j
]);
144 m_NewVertices
.push_back(255.f
* vertices
[i
].m_Blend
.m_Weight
[j
]);
148 for (size_t UVset
= 0; UVset
< numUVsPerVertex
; ++UVset
)
150 m_NewVertices
.push_back(vertices
[i
].m_UVs
[UVset
* 2]);
151 m_NewVertices
.push_back(1.0 - vertices
[i
].m_UVs
[UVset
* 2 + 1]);