[Scummvm-git-logs] scummvm master -> 360014bf08cd56b32457c4f1da38cba500b5e8c0

aquadran noreply at scummvm.org
Sun Oct 13 07:35:14 UTC 2024


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
360014bf08 WINTERMUTE: Removed old mesh loader file. Use mesh internal skinning.


Commit: 360014bf08cd56b32457c4f1da38cba500b5e8c0
    https://github.com/scummvm/scummvm/commit/360014bf08cd56b32457c4f1da38cba500b5e8c0
Author: Paweł Kołodziejski (aquadran at gmail.com)
Date: 2024-10-13T09:35:08+02:00

Commit Message:
WINTERMUTE: Removed old mesh loader file. Use mesh internal skinning.

Changed paths:
  R engines/wintermute/base/gfx/xskinmesh_loader.cpp
  R engines/wintermute/base/gfx/xskinmesh_loader.h
    engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
    engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
    engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
    engines/wintermute/base/gfx/skin_mesh_helper.cpp
    engines/wintermute/base/gfx/skin_mesh_helper.h
    engines/wintermute/base/gfx/xmesh.cpp
    engines/wintermute/base/gfx/xmesh.h
    engines/wintermute/base/gfx/xskinmesh.cpp
    engines/wintermute/base/gfx/xskinmesh.h
    engines/wintermute/module.mk


diff --git a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
index 79c61ff11f6..45d39fe173e 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
@@ -42,6 +42,7 @@
 #include "engines/wintermute/base/gfx/opengl/shadow_volume_opengl.h"
 
 namespace Wintermute {
+
 BaseRenderer3D *makeOpenGL3DRenderer(BaseGame *inGame) {
 	return new BaseRenderOpenGL3D(inGame);
 }
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp b/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
index de3018c16d8..517b6bb4b08 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
@@ -26,7 +26,6 @@
  */
 
 #include "engines/wintermute/base/gfx/xmaterial.h"
-#include "engines/wintermute/base/gfx/xskinmesh_loader.h"
 #include "engines/wintermute/base/gfx/skin_mesh_helper.h"
 
 #include "graphics/opengl/system_headers.h"
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
index af860b47cf2..ad84baa1c4e 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
@@ -26,7 +26,6 @@
  */
 
 #include "engines/wintermute/base/gfx/xmaterial.h"
-#include "engines/wintermute/base/gfx/xskinmesh_loader.h"
 #include "engines/wintermute/base/gfx/skin_mesh_helper.h"
 
 #include "graphics/opengl/system_headers.h"
diff --git a/engines/wintermute/base/gfx/skin_mesh_helper.cpp b/engines/wintermute/base/gfx/skin_mesh_helper.cpp
index a14b23c1f26..8009d5f2930 100644
--- a/engines/wintermute/base/gfx/skin_mesh_helper.cpp
+++ b/engines/wintermute/base/gfx/skin_mesh_helper.cpp
@@ -26,8 +26,8 @@
  */
 
 #include "engines/wintermute/dcgf.h"
+#include "engines/wintermute/coll_templ.h"
 #include "engines/wintermute/base/gfx/skin_mesh_helper.h"
-#include "engines/wintermute/base/gfx/xskinmesh_loader.h"
 #include "engines/wintermute/base/gfx/xskinmesh.h"
 #include "engines/wintermute/base/gfx/xfile_loader.h"
 
@@ -80,6 +80,14 @@ bool SkinMeshHelper::updateSkinnedMesh(const DXMatrix *boneTransforms, DXMesh *m
 	return _skinInfo->updateSkinnedMesh(boneTransforms, sourceVerts, targetVerts);
 }
 
+//////////////////////////////////////////////////////////////////////////
+bool SkinMeshHelper::updateSkinnedMesh(BaseArray<Math::Matrix4> &boneTransforms, DXMesh *mesh) {
+	void *sourceVerts = reinterpret_cast<void *>(_mesh->getVertexBuffer().ptr());
+	void *targetVerts = reinterpret_cast<void *>(mesh->getVertexBuffer().ptr());
+
+	return _skinInfo->updateSkinnedMesh(boneTransforms, sourceVerts, targetVerts);
+}
+
 //////////////////////////////////////////////////////////////////////////
 const char *SkinMeshHelper::getBoneName(uint32 boneIndex) {
 	return _skinInfo->getBoneName(boneIndex);
diff --git a/engines/wintermute/base/gfx/skin_mesh_helper.h b/engines/wintermute/base/gfx/skin_mesh_helper.h
index ed664bcd22a..9df8c56605d 100644
--- a/engines/wintermute/base/gfx/skin_mesh_helper.h
+++ b/engines/wintermute/base/gfx/skin_mesh_helper.h
@@ -57,6 +57,7 @@ public:
 	bool getOriginalMesh(DXMesh **mesh);
 	bool generateSkinnedMesh(Common::Array<uint32> &adjacencyOut, DXMesh **mesh);
 	bool updateSkinnedMesh(const DXMatrix *boneTransforms, DXMesh *mesh);
+	bool updateSkinnedMesh(BaseArray<Math::Matrix4> &boneTransforms, DXMesh *mesh);
 	const char *getBoneName(uint32 boneIndex);
 	DXMatrix *getBoneOffsetMatrix(uint32 boneIndex);
 
diff --git a/engines/wintermute/base/gfx/xmesh.cpp b/engines/wintermute/base/gfx/xmesh.cpp
index 96ec569f0d3..c5c284d3b48 100644
--- a/engines/wintermute/base/gfx/xmesh.cpp
+++ b/engines/wintermute/base/gfx/xmesh.cpp
@@ -28,7 +28,6 @@
 #include "engines/wintermute/base/gfx/3dshadow_volume.h"
 #include "engines/wintermute/base/gfx/xmaterial.h"
 #include "engines/wintermute/base/gfx/xmesh.h"
-#include "engines/wintermute/base/gfx/xskinmesh_loader.h"
 #include "engines/wintermute/base/gfx/skin_mesh_helper.h"
 #include "engines/wintermute/base/gfx/xframe_node.h"
 #include "engines/wintermute/base/gfx/xfile_loader.h"
@@ -81,7 +80,6 @@ bool XMesh::loadFromXData(const Common::String &filename, XFileData *xobj) {
 		return false;
 	}
 
-	XSkinMeshLoader *meshLoader = new XSkinMeshLoader(mesh);
 	auto fvf = mesh->getFVF();
 	uint32 vertexSize = DXGetFVFVertexSize(fvf) / sizeof(float);
 	float *vertexBuffer = (float *)mesh->getVertexBuffer().ptr();
@@ -116,21 +114,15 @@ bool XMesh::loadFromXData(const Common::String &filename, XFileData *xobj) {
 		//_boneMatrices = new DXMatrix*[numBones];
 
 		generateMesh();
-
-		_blendedMesh->_meshLoader = meshLoader;
-		_skinMesh->_mesh->_meshLoader = new XSkinMeshLoader(_skinMesh->_mesh);
 	} else {
 		// no bones are found, blend the mesh and use it as a static mesh
 		_skinMesh->getOriginalMesh(&_staticMesh);
 		_staticMesh->cloneMesh(&_blendedMesh);
 
-		_staticMesh->_meshLoader = new XSkinMeshLoader(_staticMesh);
-
 		delete _skinMesh;
 		_skinMesh = nullptr;
 
 		if (_blendedMesh) {
-			_blendedMesh->_meshLoader = meshLoader;
 			//numFaces = _blendedMesh->getNumFaces();
 			//_adjacency = new uint32[numFaces * 3];
 			_blendedMesh->generateAdjacency(_adjacency);
@@ -162,32 +154,6 @@ bool XMesh::loadFromXData(const Common::String &filename, XFileData *xobj) {
 		}
 	}
 
-	for (uint index = 0; index < numBones; index++) {
-		SkinWeights currSkinWeights;
-		DXBone *bone = skinInfo->getBone(index);
-		currSkinWeights._boneName = bone->_name;
-
-		int weightCount = bone->_numInfluences;
-		currSkinWeights._vertexIndices.resize(weightCount);
-		currSkinWeights._vertexWeights.resize(weightCount);
-
-		for (int i = 0; i < weightCount; ++i) {
-			currSkinWeights._vertexIndices[i] = bone->_vertices[i];
-		}
-
-		for (int i = 0; i < weightCount; ++i) {
-			currSkinWeights._vertexWeights[i] = bone->_weights[i];
-		}
-
-		for (int r = 0; r < 4; ++r) {
-			for (int c = 0; c < 4; ++c) {
-				currSkinWeights._offsetMatrix(c, r) = bone->_transform._m4x4[r * 4 + c];
-			}
-		}
-
-		meshLoader->_skinWeightsList.push_back(currSkinWeights);
-	}
-
 	bufMaterials.free();
 
 	return true;
@@ -218,19 +184,16 @@ bool XMesh::findBones(FrameNode *rootFrame) {
 	if (!_skinMesh)
 		return true;
 
-	auto skinWeightsList = _blendedMesh->_meshLoader->_skinWeightsList;
-
-	_boneMatrices.resize(skinWeightsList.size());
+	_boneMatrices.resize(_skinMesh->getNumBones());
 	// get the buffer with the names of the bones
-	for (uint i = 0; i < skinWeightsList.size(); ++i) {
+	for (uint32 i = 0; i < _skinMesh->getNumBones(); i++) {
 		// find a frame with the same name
-		FrameNode *frame = rootFrame->findFrame(skinWeightsList[i]._boneName.c_str());
-
+		FrameNode *frame = rootFrame->findFrame(_skinMesh->getBoneName(i));
 		if (frame) {
 			// get a *pointer* to its world matrix
 			_boneMatrices[i] = frame->getCombinedMatrix();
 		} else {
-			BaseEngine::LOG(0, "Warning: Cannot find frame '%s'", skinWeightsList[i]._boneName.c_str());
+			BaseEngine::LOG(0, "Warning: Cannot find frame '%s'", _skinMesh->getBoneName(i));
 		}
 	}
 
@@ -242,104 +205,98 @@ bool XMesh::update(FrameNode *parentFrame) {
 	if (!_blendedMesh)
 		return false;
 
-	float *vertexDstData = (float *)_blendedMesh->getVertexBuffer().ptr();
-	if (vertexDstData == nullptr) {
-		return false;
-	}
-	auto fvf = _blendedMesh->getFVF();
-	uint32 vertexSize = DXGetFVFVertexSize(fvf) / sizeof(float);
-	uint32 offset = 0, normalOffset = 0;
-	if (fvf & DXFVF_XYZ) {
-		offset += sizeof(DXVector3) / sizeof(float);
-	}
-	if (fvf & DXFVF_NORMAL) {
-		normalOffset = offset;
-	}
-
-	uint32 vertexCount = _blendedMesh->getNumVertices();
-	auto skinWeightsList = _blendedMesh->_meshLoader->_skinWeightsList;
+	bool res = false;
 
 	// update skinned mesh
 	if (_skinMesh) {
-		float *vertexSrcData = (float *)_skinMesh->_mesh->getVertexBuffer().ptr();
-		BaseArray<Math::Matrix4> finalBoneMatrices;
-		finalBoneMatrices.resize(_boneMatrices.size());
+		int numBones = _skinMesh->getNumBones();
+		BaseArray<Math::Matrix4> boneMatrices;
+		boneMatrices.resize(numBones);
 
 		// prepare final matrices
-		for (uint i = 0; i < skinWeightsList.size(); ++i) {
-			finalBoneMatrices[i] = *_boneMatrices[i] * skinWeightsList[i]._offsetMatrix;
-		}
-
-		// the new vertex coordinates are the weighted sum of the product
-		// of the combined bone transformation matrices and the static pose coordinates
-		// to be able too add the weighted summands together, we reset everything to zero first
-		for (uint32 i = 0; i < vertexCount; ++i) {
-			for (int j = 0; j < 3; ++j) {
-				vertexDstData[i * vertexSize + j] = 0.0f;
-			}
-		}
-
-		for (uint boneIndex = 0; boneIndex < skinWeightsList.size(); ++boneIndex) {
-			// to every vertex which is affected by the bone, we add the product
-			// of the bone transformation with the coordinates of the static pose,
-			// weighted by the weight for the particular vertex
-			// repeating this procedure for all bones gives the new pose
-			for (uint i = 0; i < skinWeightsList[boneIndex]._vertexIndices.size(); ++i) {
-				uint32 vertexIndex = skinWeightsList[boneIndex]._vertexIndices[i];
-				Math::Vector3d pos;
-				pos.setData(vertexSrcData + vertexIndex * vertexSize);
-				finalBoneMatrices[boneIndex].transform(&pos, true);
-				pos *= skinWeightsList[boneIndex]._vertexWeights[i];
-
-				for (uint j = 0; j < 3; ++j) {
-					vertexDstData[vertexIndex * vertexSize + j] += pos.getData()[j];
+		for (int i = 0; i < numBones; ++i) {
+			Math::Matrix4 offsetMatrix;
+			for (int r = 0; r < 4; ++r) {
+				for (int c = 0; c < 4; ++c) {
+					offsetMatrix(c, r) = _skinMesh->getBoneOffsetMatrix(i)->_m4x4[r * 4 + c];
 				}
 			}
+			boneMatrices[i] = *_boneMatrices[i] * offsetMatrix;
 		}
 
-		// now we have to update the vertex normals as well, so prepare the bone transformations
-		for (uint i = 0; i < skinWeightsList.size(); ++i) {
-			finalBoneMatrices[i].transpose();
-			finalBoneMatrices[i].inverse();
+		// generate skinned mesh
+		res = _skinMesh->updateSkinnedMesh(boneMatrices, _blendedMesh);
+
+		if (!res) {
+			BaseEngine::LOG(0, "Error updating skinned mesh");
+			return res;
 		}
 
-		// reset so we can form the weighted sums
-		for (uint32 i = 0; i < vertexCount; ++i) {
-			for (int j = 0; j < 3; ++j) {
-				vertexDstData[i * vertexSize + normalOffset + j] = 0.0f;
+		// update mesh bounding box
+		byte *points = _blendedMesh->getVertexBuffer().ptr();
+
+		DXVector3 BBoxStart = DXVector3(_BBoxStart.x(), _BBoxStart.y(), _BBoxStart.z());
+		DXVector3 BBoxEnd = DXVector3(_BBoxEnd.x(), _BBoxEnd.y(), _BBoxEnd.z());
+		DXComputeBoundingBox((DXVector3 *)points, _blendedMesh->getNumVertices(), DXGetFVFVertexSize(_blendedMesh->getFVF()), &BBoxStart, &BBoxEnd);
+		_BBoxStart = Math::Vector3d(BBoxStart._x, BBoxStart._y, BBoxStart._z);
+		_BBoxEnd = Math::Vector3d(BBoxEnd._x, BBoxEnd._y, BBoxEnd._z);
+		// if you want something done right...
+		if (isnan(_BBoxEnd.x())) {
+			float minX = FLT_MAX;
+			float minY = FLT_MAX;
+			float minZ = FLT_MAX;
+			float maxX = FLT_MIN;
+			float maxY = FLT_MIN;
+			float maxZ = FLT_MIN;
+
+			uint32 fvfSize = _blendedMesh->getFVF();
+
+			byte *vectBuf = points;
+			for (uint32 i = 0; i < _blendedMesh->getNumVertices(); i++) {
+				DXVector3 *vect = (DXVector3 *)vectBuf;
+
+				minX = MIN(minX, vect->_x);
+				minY = MIN(minY, vect->_y);
+				minZ = MIN(minZ, vect->_z);
+
+				maxX = MAX(maxX, vect->_x);
+				maxY = MAX(maxY, vect->_y);
+				maxZ = MAX(maxZ, vect->_z);
+
+				vectBuf += DXGetFVFVertexSize(fvfSize);
 			}
+			_BBoxStart = Math::Vector3d(minX, minY, minZ);
+			_BBoxEnd = Math::Vector3d(maxX, maxY, maxZ);
 		}
+	} else {
+		// update static mesh
+		uint32 fvfSize = DXGetFVFVertexSize(_blendedMesh->getFVF());
+		uint32 numVertices = _blendedMesh->getNumVertices();
 
-		for (uint boneIndex = 0; boneIndex < skinWeightsList.size(); ++boneIndex) {
-			for (uint i = 0; i < skinWeightsList[boneIndex]._vertexIndices.size(); ++i) {
-				uint32 vertexIndex = skinWeightsList[boneIndex]._vertexIndices[i];
-				Math::Vector3d pos;
-				pos.setData(vertexSrcData + vertexIndex * vertexSize + normalOffset);
-				finalBoneMatrices[boneIndex].transform(&pos, true);
-				pos *= skinWeightsList[boneIndex]._vertexWeights[i];
+		// lock static vertex buffer
+		byte *oldPoints = _staticMesh->getVertexBuffer().ptr();
 
-				for (uint j = 0; j < 3; ++j) {
-					vertexDstData[vertexIndex * vertexSize + normalOffset + j] += pos.getData()[j];
-				}
-			}
-		}
+		// lock blended vertex buffer
+		byte *newPoints = _blendedMesh->getVertexBuffer().ptr();
 
-		//updateNormals();
-	} else { // update static
-		for (uint32 i = 0; i < vertexCount; ++i) {
-			float *vertexSrcData = (float *)_staticMesh->getVertexBuffer().ptr();
-			Math::Vector3d pos(vertexSrcData + i * vertexSize);
-			parentFrame->getCombinedMatrix()->transform(&pos, true);
+		for (uint32 i = 0; i < numVertices; i++) {
+			DXVector3 v = *(DXVector3 *)(oldPoints + i * fvfSize);
+			Math::Vector3d newVertex = Math::Vector3d(v._x, v._y, v._z);
+			parentFrame->getCombinedMatrix()->transform(&newVertex, true);
 
-			for (uint j = 0; j < 3; ++j) {
-				vertexDstData[i * vertexSize + j] = pos.getData()[j];
-			}
+			((DXVector3 *)(newPoints + i * fvfSize))->_x = newVertex.x();
+			((DXVector3 *)(newPoints + i * fvfSize))->_y = newVertex.y();
+			((DXVector3 *)(newPoints + i * fvfSize))->_z = newVertex.z();
 		}
-	}
 
-	updateBoundingBox();
-
-	return true;
+		// update bounding box
+		DXVector3 BBoxStart = DXVector3(_BBoxStart.x(), _BBoxStart.y(), _BBoxStart.z());
+		DXVector3 BBoxEnd = DXVector3(_BBoxEnd.x(), _BBoxEnd.y(), _BBoxEnd.z());
+		DXComputeBoundingBox((DXVector3 *)newPoints, _blendedMesh->getNumVertices(), DXGetFVFVertexSize(_blendedMesh->getFVF()), &BBoxStart, &BBoxEnd);
+		_BBoxStart = Math::Vector3d(BBoxStart._x, BBoxStart._y, BBoxStart._z);
+		_BBoxEnd = Math::Vector3d(BBoxEnd._x, BBoxEnd._y, BBoxEnd._z);
+	}
+	return res;
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -524,32 +481,4 @@ bool XMesh::restoreDeviceObjects() {
 	}
 }
 
-void XMesh::updateBoundingBox() {
-	float *vertexData = (float *)_blendedMesh->getVertexBuffer().ptr();
-	if (vertexData == nullptr) {
-		return;
-	}
-	uint32 vertexSize = DXGetFVFVertexSize(_blendedMesh->getFVF()) / sizeof(float);
-	uint32 vertexCount = _blendedMesh->getNumVertices();
-	if (vertexCount == 0) {
-		return;
-	}
-
-	_BBoxStart.setData(&vertexData[0]);
-	_BBoxEnd.setData(&vertexData[0]);
-
-	for (uint16 i = 1; i < vertexCount; ++i) {
-		Math::Vector3d v;
-		v.setData(&vertexData[i * vertexSize]);
-
-		_BBoxStart.x() = MIN(_BBoxStart.x(), v.x());
-		_BBoxStart.y() = MIN(_BBoxStart.y(), v.y());
-		_BBoxStart.z() = MIN(_BBoxStart.z(), v.z());
-
-		_BBoxEnd.x() = MAX(_BBoxEnd.x(), v.x());
-		_BBoxEnd.y() = MAX(_BBoxEnd.y(), v.y());
-		_BBoxEnd.z() = MAX(_BBoxEnd.z(), v.z());
-	}
-}
-
 } // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/xmesh.h b/engines/wintermute/base/gfx/xmesh.h
index 5531235c646..0c293292e11 100644
--- a/engines/wintermute/base/gfx/xmesh.h
+++ b/engines/wintermute/base/gfx/xmesh.h
@@ -73,8 +73,6 @@ public:
 protected:
 	bool generateMesh();
 
-	void updateBoundingBox();
-
 	SkinMeshHelper *_skinMesh;
 	DXMesh *_blendedMesh;
 	DXMesh *_staticMesh;
diff --git a/engines/wintermute/base/gfx/xskinmesh.cpp b/engines/wintermute/base/gfx/xskinmesh.cpp
index 8930f76cd42..28d8d4ec6e4 100644
--- a/engines/wintermute/base/gfx/xskinmesh.cpp
+++ b/engines/wintermute/base/gfx/xskinmesh.cpp
@@ -33,6 +33,9 @@
 #include "engines/wintermute/base/gfx/xskinmesh.h"
 #include "engines/wintermute/base/gfx/xmath.h"
 
+#include "common/array.h"
+#include "math/matrix4.h"
+
 namespace Wintermute {
 
 struct MeshData {
@@ -122,7 +125,7 @@ static bool createMesh(uint32 numFaces, uint32 numVertices, uint32 fvf, DXMesh *
 	return true;
 }
 
-static bool createSkinInfo(uint32 vertexCount, uint32 boneCount, DXSkinInfo **skinInfo) {
+static bool createSkinInfo(uint32 vertexCount, uint32 fvf, uint32 boneCount, DXSkinInfo **skinInfo) {
 	if (!skinInfo)
 		return false;
 
@@ -130,7 +133,7 @@ static bool createSkinInfo(uint32 vertexCount, uint32 boneCount, DXSkinInfo **sk
 	if (!skin)
 		return false;
 
-	if (!skin->create(vertexCount, boneCount)) {
+	if (!skin->create(vertexCount, fvf, boneCount)) {
 		delete skin;
 		return false;
 	}
@@ -411,10 +414,10 @@ static void fillAttributeTable(const uint32 *attribBuffer, uint32 numfaces, cons
 	attribTableSize++;
 }
 
-bool DXSkinInfo::create(uint32 vertexCount, uint32 boneCount) {
+bool DXSkinInfo::create(uint32 vertexCount, uint32 fvf, uint32 boneCount) {
 	_numVertices = vertexCount;
 	_numBones = boneCount;
-	_fvf = 0;
+	_fvf = fvf;
 
 	_bones = new DXBone[boneCount];
 	if (!_bones) {
@@ -429,12 +432,79 @@ void DXSkinInfo::destroy() {
 	_bones = nullptr;
 }
 
+bool DXSkinInfo::updateSkinnedMesh(BaseArray<Math::Matrix4> &boneTransforms, void *srcVertices, void *dstVertices) {
+	uint32 vertexSize = DXGetFVFVertexSize(_fvf);
+	uint32 normalOffset = sizeof(DXVector3);
+	uint32 i, j;
+
+	for (i = 0; i < _numVertices; i++) {
+		DXVector3 *position = (DXVector3 *)((byte *)dstVertices + vertexSize * i);
+		position->_x = 0.0f;
+		position->_y = 0.0f;
+		position->_z = 0.0f;
+	}
+
+	for (i = 0; i < _numBones; i++) {
+		for (j = 0; j < _bones[i]._numInfluences; ++j) {
+			Math::Vector3d position;
+			DXVector3 *positionSrc = (DXVector3 *)((byte *)srcVertices + vertexSize * _bones[i]._vertices[j]);
+			DXVector3 *positionDst = (DXVector3 *)((byte *)dstVertices + vertexSize * _bones[i]._vertices[j]);
+			float weight = _bones[i]._weights[j];
+
+			position.set(positionSrc->_x, positionSrc->_y, positionSrc->_z);
+			boneTransforms[i].transform(&position, true);
+			positionDst->_x += weight * position.x();
+			positionDst->_y += weight * position.y();
+			positionDst->_z += weight * position.z();
+		}
+	}
+
+	if (_fvf & DXFVF_NORMAL) {
+		for (i = 0; i < _numVertices; i++) {
+			DXVector3 *normal = (DXVector3 *)((byte *)dstVertices + vertexSize * i + normalOffset);
+			normal->_x = 0.0f;
+			normal->_y = 0.0f;
+			normal->_z = 0.0f;
+		}
+
+		for (i = 0; i < _numBones; i++) {
+			boneTransforms[i].transpose();
+			boneTransforms[i].inverse();
+		}
+
+		for (i = 0; i < _numBones; i++) {
+			for (j = 0; j < _bones[i]._numInfluences; ++j) {
+				Math::Vector3d normal;
+				DXVector3 *normalSrc = (DXVector3 *)((byte *)srcVertices + vertexSize * _bones[i]._vertices[j] + normalOffset);
+				DXVector3 *normalDst = (DXVector3 *)((byte *)dstVertices + vertexSize * _bones[i]._vertices[j] + normalOffset);
+				float weight = _bones[i]._weights[j];
+
+				normal.set(normalSrc->_x, normalSrc->_y, normalSrc->_z);
+				boneTransforms[i].transform(&normal, true);
+				normalDst->_x += weight * normal.x();
+				normalDst->_y += weight * normal.y();
+				normalDst->_z += weight * normal.z();
+			}
+		}
+
+		for (i = 0; i < _numVertices; i++) {
+			DXVector3 *normalDest = (DXVector3 *)((byte *)dstVertices + (i * vertexSize) + normalOffset);
+			if ((normalDest->_x != 0.0f) && (normalDest->_y != 0.0f) && (normalDest->_z != 0.0f)) {
+				DXVec3Normalize(normalDest, normalDest);
+			}
+		}
+	}
+
+	return true;
+}
+
 bool DXSkinInfo::updateSkinnedMesh(const DXMatrix *boneTransforms, void *srcVertices, void *dstVertices) {
-	uint32 size = DXGetFVFVertexSize(_fvf);
+	uint32 vertexSize = DXGetFVFVertexSize(_fvf);
+	uint32 normalOffset = sizeof(DXVector3);
 	uint32 i, j;
 
 	for (i = 0; i < _numVertices; i++) {
-		DXVector3 *position = (DXVector3 *)((byte *)dstVertices + size * i);
+		DXVector3 *position = (DXVector3 *)((byte *)dstVertices + vertexSize * i);
 		position->_x = 0.0f;
 		position->_y = 0.0f;
 		position->_z = 0.0f;
@@ -449,20 +519,20 @@ bool DXSkinInfo::updateSkinnedMesh(const DXMatrix *boneTransforms, void *srcVert
 
 		for (j = 0; j < _bones[i]._numInfluences; j++) {
 			DXVector3 position;
-			DXVector3 *position_src = (DXVector3 *)((byte *)srcVertices + size * _bones[i]._vertices[j]);
-			DXVector3 *position_dest = (DXVector3 *)((byte *)dstVertices + size * _bones[i]._vertices[j]);
+			DXVector3 *positionSrc = (DXVector3 *)((byte *)srcVertices + vertexSize * _bones[i]._vertices[j]);
+			DXVector3 *positionDst = (DXVector3 *)((byte *)dstVertices + vertexSize * _bones[i]._vertices[j]);
 			float weight = _bones[i]._weights[j];
 
-			DXVec3TransformCoord(&position, position_src, &matrix);
-			position_dest->_x += weight * position._x;
-			position_dest->_y += weight * position._y;
-			position_dest->_z += weight * position._z;
+			DXVec3TransformCoord(&position, positionSrc, &matrix);
+			positionDst->_x += weight * position._x;
+			positionDst->_y += weight * position._y;
+			positionDst->_z += weight * position._z;
 		}
 	}
 
 	if (_fvf & DXFVF_NORMAL) {
 		for (i = 0; i < _numVertices; i++) {
-			DXVector3 *normal = (DXVector3 *)((byte *)dstVertices + size * i + sizeof(DXVector3));
+			DXVector3 *normal = (DXVector3 *)((byte *)dstVertices + vertexSize * i + normalOffset);
 			normal->_x = 0.0f;
 			normal->_y = 0.0f;
 			normal->_z = 0.0f;
@@ -476,20 +546,20 @@ bool DXSkinInfo::updateSkinnedMesh(const DXMatrix *boneTransforms, void *srcVert
 
 			for (j = 0; j < _bones[i]._numInfluences; j++) {
 				DXVector3 normal;
-				DXVector3 *normalSrc = (DXVector3 *)((byte *)srcVertices + size * _bones[i]._vertices[j] + sizeof(DXVector3));
-				DXVector3 *normalDest = (DXVector3 *)((byte *)dstVertices + size * _bones[i]._vertices[j] + sizeof(DXVector3));
+				DXVector3 *normalSrc = (DXVector3 *)((byte *)srcVertices + vertexSize * _bones[i]._vertices[j] + normalOffset);
+				DXVector3 *normalDst = (DXVector3 *)((byte *)dstVertices + vertexSize * _bones[i]._vertices[j] + normalOffset);
 				float weight = _bones[i]._weights[j];
 
 				DXVec3TransformNormal(&normal, normalSrc, &boneInverse);
 				DXVec3TransformNormal(&normal, &normal, &matrix);
-				normalDest->_x += weight * normal._x;
-				normalDest->_y += weight * normal._y;
-				normalDest->_z += weight * normal._z;
+				normalDst->_x += weight * normal._x;
+				normalDst->_y += weight * normal._y;
+				normalDst->_z += weight * normal._z;
 			}
 		}
 
 		for (i = 0; i < _numVertices; i++) {
-			DXVector3 *normalDest = (DXVector3 *)((byte *)dstVertices + (i * size) + sizeof(DXVector3));
+			DXVector3 *normalDest = (DXVector3 *)((byte *)dstVertices + (i * vertexSize) + normalOffset);
 			if ((normalDest->_x != 0.0f) && (normalDest->_y != 0.0f) && (normalDest->_z != 0.0f)) {
 				DXVec3Normalize(normalDest, normalDest);
 			}
@@ -731,7 +801,7 @@ static bool parseSkinMeshHeader(XFileData &fileData, struct MeshData *meshData)
 	}
 
 	meshData->_boneCount = skinMeshHeaderObj->_nBones;
-	return createSkinInfo(meshData->_numVertices, meshData->_boneCount, &meshData->_skinInfo);
+	return createSkinInfo(meshData->_numVertices, meshData->_fvf, meshData->_boneCount, &meshData->_skinInfo);
 }
 
 static bool parseTextureFilename(XFileData &fileData, char *filenameOut) {
@@ -1078,7 +1148,7 @@ static bool parseMesh(XFileData *fileData, struct MeshData *meshData) {
 	}
 
 	if (!meshData->_skinInfo) {
-		result = createSkinInfo(meshData->_numVertices, meshData->_boneCount, &meshData->_skinInfo);
+		result = createSkinInfo(meshData->_numVertices, meshData->_fvf, meshData->_boneCount, &meshData->_skinInfo);
 		if (!result)
 			return false;
 	}
diff --git a/engines/wintermute/base/gfx/xskinmesh.h b/engines/wintermute/base/gfx/xskinmesh.h
index 9e43a6280c0..8d7407bb859 100644
--- a/engines/wintermute/base/gfx/xskinmesh.h
+++ b/engines/wintermute/base/gfx/xskinmesh.h
@@ -33,6 +33,7 @@
 #ifndef WINTERMUTE_XSKINMESH_H
 #define WINTERMUTE_XSKINMESH_H
 
+#include "engines/wintermute/coll_templ.h"
 #include "engines/wintermute/base/gfx/xbuffer.h"
 #include "engines/wintermute/base/gfx/xfile_loader.h"
 #include "engines/wintermute/base/gfx/xmath.h"
@@ -114,7 +115,7 @@ class DXSkinInfo {
 
 public:
 	~DXSkinInfo() { destroy(); }
-	bool create(uint32 vertexCount, uint32 boneCount);
+	bool create(uint32 vertexCount, uint32 fvf, uint32 boneCount);
 	void destroy();
 	uint32 getNumBones() { return _numBones; }
 	bool setBoneName(uint32 boneIdx, const char *name);
@@ -124,6 +125,7 @@ public:
 	bool setBoneOffsetMatrix(uint32 boneIdx, const float *boneTransform);
 	DXMatrix *getBoneOffsetMatrix(uint32 boneIdx) { return &_bones[boneIdx]._transform; }
 	bool updateSkinnedMesh(const DXMatrix *boneTransforms, void *srcVertices, void *dstVertices);
+	bool updateSkinnedMesh(BaseArray<Math::Matrix4> &boneTransforms, void *srcVertices, void *dstVertices);
 };
 
 class DXMesh {
@@ -146,7 +148,6 @@ class DXMesh {
 	bool adjacentEdge(uint32 index1, uint32 index2, uint32 index3, uint32 index4);
 
 public:
-	XSkinMeshLoader *_meshLoader;
 	~DXMesh() { destroy(); }
 	bool create(uint32 numFaces, uint32 numVertices, uint32 fvf);
 	void destroy();
diff --git a/engines/wintermute/base/gfx/xskinmesh_loader.cpp b/engines/wintermute/base/gfx/xskinmesh_loader.cpp
deleted file mode 100644
index d34d5658d2a..00000000000
--- a/engines/wintermute/base/gfx/xskinmesh_loader.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/* 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/>.
- *
- */
-
-#include "engines/wintermute/base/gfx/3dshadow_volume.h"
-#include "engines/wintermute/base/gfx/xmaterial.h"
-#include "engines/wintermute/base/gfx/xskinmesh_loader.h"
-#include "engines/wintermute/base/gfx/xframe_node.h"
-#include "engines/wintermute/base/gfx/xfile_loader.h"
-#include "engines/wintermute/base/gfx/xskinmesh_loader.h"
-#include "engines/wintermute/base/gfx/xskinmesh.h"
-#include "engines/wintermute/base/gfx/xmodel.h"
-#include "engines/wintermute/base/base_engine.h"
-#include "engines/wintermute/math/math_util.h"
-
-namespace Wintermute {
-
-XSkinMeshLoader::XSkinMeshLoader(DXMesh *dxmesh) {
-}
-
-XSkinMeshLoader::~XSkinMeshLoader() {
-}
-
-} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/xskinmesh_loader.h b/engines/wintermute/base/gfx/xskinmesh_loader.h
deleted file mode 100644
index b5ae6009c0e..00000000000
--- a/engines/wintermute/base/gfx/xskinmesh_loader.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* 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/>.
- *
- */
-
-#ifndef WINTERMUTE_XSKINMESH_LOADER_H
-#define WINTERMUTE_XSKINMESH_LOADER_H
-
-#include "engines/wintermute/base/gfx/xmodel.h"
-
-#include "math/matrix4.h"
-#include "math/vector3d.h"
-
-namespace Wintermute {
-
-class Material;
-class XModel;
-class XMesh;
-class ShadowVolume;
-class SkinMeshHelper;
-class VideoTheoraPlayer;
-struct XMeshObject;
-class DXMesh;
-class DXSkinInfo;
-
-struct SkinWeights {
-	Common::String _boneName;
-	Math::Matrix4 _offsetMatrix;
-	BaseArray<uint32> _vertexIndices;
-	BaseArray<float> _vertexWeights;
-};
-
-class XSkinMeshLoader {
-	friend class XMesh;
-	friend class XMeshOpenGL;
-	friend class XMeshOpenGLShader;
-	friend class SkinMeshHelper;
-
-public:
-	XSkinMeshLoader(DXMesh *dxmesh);
-	virtual ~XSkinMeshLoader();
-
-protected:
-
-	BaseArray<Math::Matrix4 *> _boneMatrices;
-	BaseArray<SkinWeights> _skinWeightsList;
-};
-
-} // namespace Wintermute
-
-#endif
diff --git a/engines/wintermute/module.mk b/engines/wintermute/module.mk
index fa1bc028f56..9710e382b73 100644
--- a/engines/wintermute/module.mk
+++ b/engines/wintermute/module.mk
@@ -178,7 +178,6 @@ MODULE_OBJS += \
 	base/gfx/xmesh.o \
 	base/gfx/xmodel.o \
 	base/gfx/xskinmesh.o \
-	base/gfx/xskinmesh_loader.o \
 	base/gfx/opengl/base_surface_opengl3d.o \
 	base/gfx/opengl/base_render_opengl3d.o \
 	base/gfx/opengl/base_render_opengl3d_shader.o \




More information about the Scummvm-git-logs mailing list