Initial commit
This commit is contained in:
273
engines/hpl1/engine/graphics/Mesh2d.cpp
Normal file
273
engines/hpl1/engine/graphics/Mesh2d.cpp
Normal file
@@ -0,0 +1,273 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#include "hpl1/engine/graphics/Mesh2d.h"
|
||||
#include "hpl1/engine/math/Math.h"
|
||||
#include "hpl1/engine/math/MathTypes.h"
|
||||
#include "hpl1/engine/system/MemoryManager.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CONSTRUCTORS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cMesh2D::cMesh2D() {
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cMesh2D::~cMesh2D() {
|
||||
mvPos.clear();
|
||||
mvTexCoord.clear();
|
||||
mvColor.clear();
|
||||
mvIndex.clear();
|
||||
|
||||
for (int i = 0; i < eTileRotation_LastEnum; i++)
|
||||
mvVtx[i].clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cMesh2D::AddVertex(cVector2f avPos, cVector2f avTexCoord, cColor aCol) {
|
||||
mvPos.push_back(avPos);
|
||||
mvTexCoord.push_back(avTexCoord);
|
||||
mvColor.push_back(aCol);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cMesh2D::AddIndex(unsigned int alIndex) {
|
||||
mvIndex.push_back(alIndex);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cMesh2D::AddEdgeIndex(unsigned int alIndex) {
|
||||
mvEdgeIndex.push_back(alIndex);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cMesh2D::CreateVertexVec() {
|
||||
for (int i = 0; i < (int)mvPos.size(); i++) {
|
||||
mvVtx[0].push_back(cVertex(cVector3f(mvPos[i].x, mvPos[i].y, 0), mvTexCoord[i], mvColor[i]));
|
||||
}
|
||||
|
||||
CalculateEdges(eTileRotation_0, mvVtx[0], mvEdgeIndex);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cMesh2D::CreateTileVertexVec() {
|
||||
int i;
|
||||
CreateVertexVec();
|
||||
|
||||
for (i = 1; i < eTileRotation_LastEnum; i++) {
|
||||
mvVtx[i] = mvVtx[0];
|
||||
}
|
||||
|
||||
//--- Create the angles;---
|
||||
for (int angle = 1; angle < 4; angle++) {
|
||||
for (i = 0; i < (int)mvVtx[0].size(); i++) {
|
||||
float fAngle = ((float)angle) * kPi2f;
|
||||
mvVtx[angle][i].pos.x = cos(fAngle) * mvVtx[0][i].pos.x -
|
||||
sin(fAngle) * mvVtx[0][i].pos.y;
|
||||
|
||||
mvVtx[angle][i].pos.y = sin(fAngle) * mvVtx[0][i].pos.x +
|
||||
cos(fAngle) * mvVtx[0][i].pos.y;
|
||||
}
|
||||
// Can use same edge index here since order has not changed.
|
||||
CalculateEdges((eTileRotation)angle, mvVtx[angle], mvEdgeIndex);
|
||||
}
|
||||
|
||||
// SKIP THESE FOR NOW
|
||||
// The edges are not calculated correctly..and I din't think they are that needed.
|
||||
/*//--- Flip horizontally ---
|
||||
for(i=0;i<(int)mvVtx[0].size();i++)
|
||||
mvVtx[4][i].pos.x = -mvVtx[0][i].pos.x;
|
||||
CalculateEdges(eTileRotation_FlipH, mvVtx[4], mvEdgeIndex);
|
||||
|
||||
|
||||
//--- Flip vertically ---
|
||||
for(i=0;i<(int)mvVtx[0].size();i++)
|
||||
mvVtx[5][i].pos.y = -mvVtx[0][i].pos.y;
|
||||
CalculateEdges(eTileRotation_FlipV,mvVtx[5],InvEdgeIndex);
|
||||
|
||||
|
||||
//--- Flip vertically and horizontal---
|
||||
for(i=0;i<(int)mvVtx[0].size();i++)
|
||||
{
|
||||
mvVtx[6][i].pos.y = -mvVtx[0][i].pos.y;
|
||||
mvVtx[6][i].pos.x = -mvVtx[0][i].pos.x;
|
||||
|
||||
}
|
||||
//The two flips make it right again. No need to reverse
|
||||
CalculateEdges(eTileRotation_FlipHV,mvVtx[6],mvEdgeIndex);*/
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
tVertexVec *cMesh2D::GetVertexVec(const cRect2f &aImageRect, cVector2f avSize, eTileRotation aRotation) {
|
||||
cVector3f vImageStart(aImageRect.x, aImageRect.y, 0);
|
||||
cVector3f vImageSize(aImageRect.w, aImageRect.h, 0);
|
||||
|
||||
/*Log("ImageStart: %s\n",vImageStart.ToString().c_str());
|
||||
Log("ImageSize: %s\n",vImageSize.ToString().c_str());*/
|
||||
|
||||
for (int j = 0; j < (int)mvVtx[aRotation].size(); j++) {
|
||||
// we want the same texture coords for all angles. therefor 0
|
||||
cVector3f vPos = (mvVtx[0][j].pos + avSize / 2) / avSize;
|
||||
|
||||
mvVtx[aRotation][j].col = 1;
|
||||
mvVtx[aRotation][j].tex = vImageStart + (vPos * vImageSize);
|
||||
switch (aRotation) {
|
||||
case eTileRotation_0:
|
||||
mvVtx[aRotation][j].norm = cVector3f(1, 0, 3);
|
||||
break;
|
||||
case eTileRotation_90:
|
||||
mvVtx[aRotation][j].norm = cVector3f(0, 1, 3);
|
||||
break;
|
||||
case eTileRotation_180:
|
||||
mvVtx[aRotation][j].norm = cVector3f(-1, 0, 3);
|
||||
break;
|
||||
case eTileRotation_270:
|
||||
mvVtx[aRotation][j].norm = cVector3f(0, -1, 3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return &mvVtx[aRotation];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
tUIntVec *cMesh2D::GetIndexVec() {
|
||||
return &mvIndex;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
tMesh2DEdgeVec *cMesh2D::GetEdgeVec(eTileRotation aRotation) {
|
||||
return &mvEdge[aRotation];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cMesh2D::PointIsInside(const cVector2f &avPoint, const cVector2f &avMeshPos, eTileRotation aRotation) {
|
||||
cVector2f vLocalPoint;
|
||||
cVector2f vNormal;
|
||||
|
||||
for (int i = 0; i < (int)mvEdge[aRotation].size(); i++) {
|
||||
vLocalPoint = avPoint - avMeshPos - mvEdge[aRotation][i].mvMidPos;
|
||||
vNormal = mvEdge[aRotation][i].mvNormal;
|
||||
|
||||
if ((vLocalPoint.x * vNormal.x + vLocalPoint.y * vNormal.y) >= 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cCollisionMesh2D *cMesh2D::CreateCollisonMesh(const cVector2f &avPos, const cVector2f &avSizeMul, eTileRotation aRotation) {
|
||||
cCollisionMesh2D *pCollMesh = hplNew(cCollisionMesh2D, ());
|
||||
|
||||
for (int i = 0; i < (int)mvEdgeIndex.size(); i++) {
|
||||
cVector3f vPos = mvVtx[aRotation][mvEdgeIndex[i]].pos;
|
||||
pCollMesh->mvPos.push_back(cVector2f(vPos.x, vPos.y) * (avSizeMul / 2) + avPos);
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)mvEdge[aRotation].size(); i++) {
|
||||
pCollMesh->mvNormal.push_back(mvEdge[aRotation][i].mvNormal);
|
||||
}
|
||||
|
||||
return pCollMesh;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PRIAVTE METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Walks through the positions using the indexes in an Clockwise order and calculates the
|
||||
* normal for every edge (startpos -> endpos).
|
||||
*/
|
||||
void cMesh2D::CalculateEdges(eTileRotation aRotation, tVertexVec &aVtx, tUIntVec &aIdx) {
|
||||
cVector2f vLargest = -100000;
|
||||
cVector2f vSmallest = 1000000;
|
||||
|
||||
for (int i = 0; i < (int)aIdx.size(); i++) {
|
||||
// Do some checks for the BB creation:
|
||||
// X:
|
||||
if (aVtx[aIdx[i]].pos.x > vLargest.x)
|
||||
vLargest.x = aVtx[aIdx[i]].pos.x;
|
||||
else if (aVtx[aIdx[i]].pos.x < vSmallest.x)
|
||||
vSmallest.x = aVtx[aIdx[i]].pos.x;
|
||||
// Y:
|
||||
if (aVtx[aIdx[i]].pos.y > vLargest.y)
|
||||
vLargest.y = aVtx[aIdx[i]].pos.y;
|
||||
else if (aVtx[aIdx[i]].pos.y < vSmallest.y)
|
||||
vSmallest.y = aVtx[aIdx[i]].pos.y;
|
||||
|
||||
int start = i;
|
||||
int end = i + 1 >= (int)aIdx.size() ? 0 : i + 1;
|
||||
cVector2f vNormal;
|
||||
vNormal.x = -(aVtx[aIdx[start]].pos.y - aVtx[aIdx[end]].pos.y);
|
||||
vNormal.y = aVtx[aIdx[start]].pos.x - aVtx[aIdx[end]].pos.x;
|
||||
vNormal.Normalise();
|
||||
|
||||
cVector2f vMidPos;
|
||||
vMidPos.x = (aVtx[aIdx[start]].pos.x + aVtx[aIdx[end]].pos.x) / 2;
|
||||
vMidPos.y = (aVtx[aIdx[start]].pos.y + aVtx[aIdx[end]].pos.y) / 2;
|
||||
|
||||
mvEdge[aRotation].push_back(cMesh2DEdge(vNormal, vMidPos, mvEdgeIndex[start], mvEdgeIndex[end]));
|
||||
}
|
||||
|
||||
// Create the bounding box.
|
||||
mvBoundingBox[aRotation].x = vSmallest.x;
|
||||
mvBoundingBox[aRotation].y = vSmallest.y;
|
||||
mvBoundingBox[aRotation].w = vLargest.x - vSmallest.x;
|
||||
mvBoundingBox[aRotation].h = vLargest.y - vSmallest.y;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
} // namespace hpl
|
||||
Reference in New Issue
Block a user