173 lines
4.6 KiB
C++
173 lines
4.6 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program 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 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* This file is based on WME.
|
|
* http://dead-code.org/redir.php?target=wme
|
|
* Copyright (c) 2003-2013 Jan Nedoma and contributors
|
|
*/
|
|
|
|
#include "common/file.h"
|
|
|
|
#include "engines/wintermute/base/base_game.h"
|
|
#include "engines/wintermute/base/gfx/3dloader_3ds.h"
|
|
#include "engines/wintermute/base/gfx/3dmesh.h"
|
|
#include "engines/wintermute/dcgf.h"
|
|
|
|
namespace Wintermute {
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
Mesh3DS::Mesh3DS(BaseGame *inGame) : BaseNamedObject(inGame) {
|
|
_vertices = nullptr;
|
|
_faces = nullptr;
|
|
_numFaces = _numVertices = 0;
|
|
_visible = true;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
Mesh3DS::~Mesh3DS() {
|
|
cleanup();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void Mesh3DS::cleanup() {
|
|
SAFE_DELETE_ARRAY(_vertices);
|
|
_numVertices = 0;
|
|
|
|
SAFE_DELETE_ARRAY(_faces);
|
|
_numFaces = 0;
|
|
|
|
_vb.free();
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool Mesh3DS::createVertexBuffer() {
|
|
_vb.free();
|
|
|
|
if (_numFaces == 0)
|
|
return true;
|
|
|
|
int vbSize = _numFaces * sizeof(Mesh3DSVertex) * 3;
|
|
_vb = DXBuffer(vbSize);
|
|
if (_vb.ptr() == nullptr) {
|
|
_game->LOG(0, "Error creating vertex buffer.");
|
|
return false;
|
|
} else
|
|
return true;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool Mesh3DS::fillVertexBuffer(uint32 color) {
|
|
_vb.free();
|
|
|
|
if (_numFaces == 0)
|
|
return true;
|
|
|
|
int vbSize = _numFaces * sizeof(Mesh3DSVertex) * 3;
|
|
_vb = DXBuffer(vbSize);
|
|
if (_vb.ptr() == nullptr) {
|
|
_game->LOG(0, "Error creating vertex buffer.");
|
|
return false;
|
|
}
|
|
|
|
Mesh3DSVertex *verts = (Mesh3DSVertex *)_vb.ptr();
|
|
|
|
for (int i = 0; i < _numFaces; i++) {
|
|
for (int j = 0; j < 3; j++) {
|
|
int outVert = i * 3 + j;
|
|
int vertex = _faces[i]._vertices[j];
|
|
|
|
verts[outVert]._x = _vertices[vertex]._pos._x;
|
|
verts[outVert]._y = _vertices[vertex]._pos._y;
|
|
verts[outVert]._z = _vertices[vertex]._pos._z;
|
|
|
|
verts[outVert]._nx = _faces[i]._normals[j]._x;
|
|
verts[outVert]._ny = _faces[i]._normals[j]._y;
|
|
verts[outVert]._nz = _faces[i]._normals[j]._z;
|
|
|
|
verts[outVert]._r = RGBCOLGetR(color) / 255.0f;
|
|
verts[outVert]._g = RGBCOLGetG(color) / 255.0f;
|
|
verts[outVert]._b = RGBCOLGetB(color) / 255.0f;
|
|
verts[outVert]._a = RGBCOLGetA(color) / 255.0f;
|
|
}
|
|
}
|
|
|
|
fillVertexBuffer();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void Mesh3DS::computeNormals() {
|
|
DXVector3 *normals = new DXVector3[_numVertices];
|
|
for (uint32 i = 0; i < _numVertices; i++) {
|
|
normals[i]._x = 0.0f;
|
|
normals[i]._y = 0.0f;
|
|
normals[i]._z = 0.0f;
|
|
}
|
|
|
|
for (uint32 i = 0; i < _numFaces; i++) {
|
|
uint16 a = _faces[i]._vertices[0];
|
|
uint16 b = _faces[i]._vertices[1];
|
|
uint16 c = _faces[i]._vertices[2];
|
|
|
|
DXVector3 *v1 = &_vertices[a]._pos;
|
|
DXVector3 *v2 = &_vertices[b]._pos;
|
|
DXVector3 *v3 = &_vertices[c]._pos;
|
|
|
|
DXVector3 edge1 = *v2 - *v1;
|
|
DXVector3 edge2 = *v3 - *v2;
|
|
DXVector3 normal;
|
|
DXVec3Cross(&normal, &edge1, &edge2);
|
|
DXVec3Normalize(&normal, &normal);
|
|
|
|
normals[a] += normal;
|
|
normals[b] += normal;
|
|
normals[c] += normal;
|
|
}
|
|
|
|
// Assign the newly computed normals back to the vertices
|
|
for (uint32 i = 0; i < _numFaces; i++) {
|
|
for (uint32 j = 0; j < 3; j++) {
|
|
DXVec3Normalize(&_faces[i]._normals[j], &normals[_faces[i]._vertices[j]]);
|
|
//_faces[i]._normals[j] = normals[_faces[i]._vertices[j]];
|
|
}
|
|
}
|
|
|
|
delete[] normals;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool Mesh3DS::persist(BasePersistenceManager *persistMgr) {
|
|
persistMgr->transferBool(TMEMBER(_visible));
|
|
return true;
|
|
}
|
|
|
|
} // namespace Wintermute
|