Initial commit
This commit is contained in:
413
engines/hpl1/engine/scene/ImageEntity.cpp
Normal file
413
engines/hpl1/engine/scene/ImageEntity.cpp
Normal file
@@ -0,0 +1,413 @@
|
||||
/* 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/scene/ImageEntity.h"
|
||||
#include "hpl1/engine/graphics/Graphics.h"
|
||||
#include "hpl1/engine/graphics/GraphicsTypes.h"
|
||||
#include "hpl1/engine/graphics/ImageEntityData.h"
|
||||
#include "hpl1/engine/graphics/RenderObject2D.h"
|
||||
#include "hpl1/engine/graphics/Renderer2D.h"
|
||||
#include "hpl1/engine/impl/tinyXML/tinyxml.h"
|
||||
#include "hpl1/engine/math/Math.h"
|
||||
#include "hpl1/engine/resources/ImageEntityManager.h"
|
||||
#include "hpl1/engine/resources/Resources.h"
|
||||
#include "hpl1/engine/system/String.h"
|
||||
#include "hpl1/engine/system/low_level_system.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CONSTRUCTORS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cImageEntity::cImageEntity(tString asName, cResources *apResources, cGraphics *apGraphics,
|
||||
bool abAutoDeleteData)
|
||||
: iEntity2D(asName) {
|
||||
mvSize = cVector2f(-1, -1);
|
||||
|
||||
mbFlipH = false;
|
||||
mbFlipV = false;
|
||||
|
||||
mpAnimation = NULL;
|
||||
mfFrameNum = 0;
|
||||
mfAnimSpeed = 0.5f;
|
||||
mlFrame = 0;
|
||||
mlLastFrame = -1;
|
||||
|
||||
mbFlashing = false;
|
||||
|
||||
mfAlpha = 1.0f;
|
||||
|
||||
mpEntityData = NULL;
|
||||
|
||||
mpResources = apResources;
|
||||
mpGraphics = apGraphics;
|
||||
|
||||
UpdateBoundingBox();
|
||||
|
||||
msTempString = "Default";
|
||||
|
||||
mbAnimationPaused = false;
|
||||
mbRotationHasChanged = true;
|
||||
|
||||
mbAutoDeleteData = abAutoDeleteData;
|
||||
|
||||
mbLoopAnimation = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cImageEntity::~cImageEntity() {
|
||||
if (mbAutoDeleteData) {
|
||||
if (mpEntityData)
|
||||
mpResources->GetImageEntityManager()->Destroy(mpEntityData);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
int cImageEntity::GetMaxFrameNum() {
|
||||
if (mpAnimation == NULL)
|
||||
return 0;
|
||||
|
||||
// One for the -1, one for the frame jump, and one because we start with 0.
|
||||
return (int)mpAnimation->mvFrameNums.size() - 3;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cImageEntity::SetAnimation(const tString &asName, bool abLoop) {
|
||||
mbLoopAnimation = abLoop;
|
||||
|
||||
if (mpAnimation->msName == asName)
|
||||
return true;
|
||||
|
||||
cImageAnimation *pAnim = mpEntityData->GetAnimationByName(asName);
|
||||
if (pAnim == NULL)
|
||||
return false;
|
||||
|
||||
mpAnimation = pAnim;
|
||||
mfFrameNum = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const tString &cImageEntity::GetCurrentAnimation() const {
|
||||
if (mpAnimation == NULL) {
|
||||
return msTempString;
|
||||
}
|
||||
|
||||
return mpAnimation->msName;
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cImageEntity::StopAnimation() {
|
||||
for (int i = 0; i < (int)mpAnimation->mvFrameNums.size(); i++) {
|
||||
if (mpAnimation->mvFrameNums[i] == -1) {
|
||||
mlFrame = i;
|
||||
mlLastFrame = i;
|
||||
mfFrameNum = (float)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mbLoopAnimation)
|
||||
mbLoopAnimation = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cImageEntity::SetSize(const cVector2f &avSize) {
|
||||
if (avSize.x == mvSize.x && avSize.y == mvSize.y)
|
||||
return;
|
||||
|
||||
mvSize.x = avSize.x == 0 ? 0.001f : avSize.x;
|
||||
mvSize.y = avSize.y == 0 ? 0.001f : avSize.y;
|
||||
|
||||
mbSizeHasChanged = true;
|
||||
mbRotationHasChanged = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cImageEntity::SetFlipH(bool abX) {
|
||||
if (mbFlipH == abX)
|
||||
return;
|
||||
|
||||
mbFlipH = abX;
|
||||
mbRotationHasChanged = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cImageEntity::SetFlipV(bool abX) {
|
||||
if (mbFlipV == abX)
|
||||
return;
|
||||
|
||||
mbFlipV = abX;
|
||||
mbRotationHasChanged = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cImageEntity::UpdateLogic(float afTimeStep) {
|
||||
if (mbFlashing) {
|
||||
float fAlpha = GetAlpha();
|
||||
if (mfFlashAdd < 0) {
|
||||
fAlpha += mfFlashAdd * 7;
|
||||
if (fAlpha < 0) {
|
||||
fAlpha = 0;
|
||||
mfFlashAdd = -mfFlashAdd;
|
||||
}
|
||||
SetAlpha(fAlpha);
|
||||
} else {
|
||||
fAlpha += mfFlashAdd;
|
||||
if (fAlpha > 1) {
|
||||
fAlpha = 1;
|
||||
mbFlashing = false;
|
||||
}
|
||||
SetAlpha(fAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
if (mpAnimation && !mbAnimationPaused) {
|
||||
if (mpAnimation->mvFrameNums[(int)mfFrameNum] != -1) {
|
||||
mfFrameNum += mfAnimSpeed * mpAnimation->mfSpeed;
|
||||
|
||||
int lFrameNum = (int)mfFrameNum;
|
||||
|
||||
if (mpAnimation->mvFrameNums[lFrameNum] == -1) {
|
||||
if (mbLoopAnimation) {
|
||||
float fTemp = (float)mpAnimation->mvFrameNums[lFrameNum + 1];
|
||||
|
||||
mfFrameNum = fTemp + cMath::GetFraction(mfFrameNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cImageEntity::AnimationIsPlaying() {
|
||||
int lFrameNum = (int)mfFrameNum;
|
||||
return mpAnimation->mvFrameNums[lFrameNum] != -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cImageEntity::Render() {
|
||||
if (!mbIsActive)
|
||||
return;
|
||||
|
||||
/*Update frame stuff if needed here*/
|
||||
|
||||
mvTransform = GetWorldPosition();
|
||||
|
||||
/// Get the frame to be used //////////////
|
||||
if (mpEntityData->GetFrameNum() == 1) {
|
||||
mlFrame = 0;
|
||||
mlLastFrame = 0;
|
||||
} else {
|
||||
mlLastFrame = mlFrame;
|
||||
mlFrame = mpAnimation->mvFrameNums[(int)mfFrameNum];
|
||||
|
||||
if (mlFrame == -1)
|
||||
mlFrame = mpAnimation->mvFrameNums[((int)mfFrameNum) - 1];
|
||||
|
||||
/// If Frame has changed update vertexes
|
||||
if (mlLastFrame != mlFrame) {
|
||||
tVertexVec *pVtx = &mpEntityData->GetImageFrame(mlFrame)->mvVtx;
|
||||
|
||||
for (int i = 0; i < (int)pVtx->size(); i++) {
|
||||
mvVtx[i].tex.x = (*pVtx)[i].tex.x;
|
||||
mvVtx[i].tex.y = (*pVtx)[i].tex.y;
|
||||
mvVtx[i].tex.z = (*pVtx)[i].tex.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mbSizeHasChanged) {
|
||||
for (int i = 0; i < (int)mvBaseVtx.size(); i++) {
|
||||
// Slow as hell!! Change this perhaps?
|
||||
// This also only works on square meshes...
|
||||
mvBaseVtx[i].pos.x = ABS(mvBaseVtx[i].pos.x) / mvBaseVtx[i].pos.x;
|
||||
mvBaseVtx[i].pos.y = ABS(mvBaseVtx[i].pos.y) / mvBaseVtx[i].pos.y;
|
||||
|
||||
mvBaseVtx[i].pos.x *= mvSize.x / 2;
|
||||
mvBaseVtx[i].pos.y *= mvSize.y / 2;
|
||||
mvBaseVtx[i].pos.z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// If rotation or frame has changed, update the vertexes
|
||||
if (mbRotationHasChanged || mfCurrentAngle != GetWorldRotation().z) {
|
||||
mbRotationHasChanged = false;
|
||||
mfCurrentAngle = GetWorldRotation().z;
|
||||
|
||||
float fSin = sin(mfCurrentAngle);
|
||||
float fCos = cos(mfCurrentAngle);
|
||||
|
||||
float fNormZ = 3;
|
||||
if (mbFlipV)
|
||||
fNormZ = 1;
|
||||
if (mbFlipH)
|
||||
fNormZ *= -1;
|
||||
|
||||
for (int i = 0; i < (int)mvVtx.size(); i++) {
|
||||
mvVtx[i].pos.x = mvBaseVtx[i].pos.x * fCos - mvBaseVtx[i].pos.y * fSin;
|
||||
mvVtx[i].pos.y = mvBaseVtx[i].pos.x * fSin + mvBaseVtx[i].pos.y * fCos;
|
||||
|
||||
if (mbFlipH)
|
||||
mvVtx[i].pos.x = -mvVtx[i].pos.x;
|
||||
if (mbFlipV)
|
||||
mvVtx[i].pos.y = -mvVtx[i].pos.y;
|
||||
|
||||
mvVtx[i].norm.x = fCos;
|
||||
mvVtx[i].norm.y = fSin;
|
||||
mvVtx[i].norm.z = fNormZ;
|
||||
}
|
||||
}
|
||||
cRenderObject2D _obj = cRenderObject2D(
|
||||
mpEntityData->GetImageFrame(mlFrame)->mpMaterial,
|
||||
&mvVtx, &mvIdxVec,
|
||||
ePrimitiveType_Quad, GetWorldPosition().z,
|
||||
mBoundingBox, NULL, &mvTransform);
|
||||
// Add the render object.
|
||||
mpGraphics->GetRenderer2D()->AddObject(_obj);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cImageEntity::LoadData(TiXmlElement *apRootElem) {
|
||||
tString sDataName = cString::ToString(apRootElem->Attribute("DataName"), "");
|
||||
|
||||
mbFlipH = cString::ToBool(apRootElem->Attribute("FlipH"), false);
|
||||
mbFlipV = cString::ToBool(apRootElem->Attribute("FlipV"), false);
|
||||
mvRotation.z = cMath::ToRad(cString::ToFloat(apRootElem->Attribute("Angle"), 0));
|
||||
mvSize.x = cString::ToFloat(apRootElem->Attribute("Width"), 2);
|
||||
mvSize.y = cString::ToFloat(apRootElem->Attribute("Height"), 2);
|
||||
int lAnimNum = cString::ToInt(apRootElem->Attribute("AnimNum"), 0);
|
||||
|
||||
return LoadEntityData(sDataName, lAnimNum);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
bool cImageEntity::LoadEntityData(tString asDataName, int alAnimNum) {
|
||||
cImageEntityData *pImageData = mpResources->GetImageEntityManager()->CreateData(asDataName);
|
||||
|
||||
if (pImageData == NULL) {
|
||||
error("Couldn't load Data '%s' for entity '%s'", asDataName.c_str(), msName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return LoadEntityData(pImageData, alAnimNum);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cImageEntity::LoadEntityData(cImageEntityData *apData, int alAnimNum) {
|
||||
mpEntityData = apData;
|
||||
|
||||
if (mpEntityData->GetFrameNum() > 1) {
|
||||
mpAnimation = mpEntityData->GetAnimationByHandle(alAnimNum);
|
||||
mlFrame = mpAnimation->mvFrameNums[0];
|
||||
mlLastFrame = -1;
|
||||
} else {
|
||||
mlFrame = 0;
|
||||
}
|
||||
|
||||
mvBaseVtx = mpEntityData->GetImageFrame(mlFrame)->mvVtx;
|
||||
|
||||
if (mvSize.x < 0 && mvSize.y < 0) {
|
||||
mvSize = mpEntityData->GetImageSize();
|
||||
}
|
||||
|
||||
mvVtx = mvBaseVtx;
|
||||
mvIdxVec = *mpEntityData->GetIndexVec();
|
||||
mbRotationHasChanged = true;
|
||||
mbSizeHasChanged = true;
|
||||
mfCurrentAngle = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const cRect2f &cImageEntity::GetBoundingBox() {
|
||||
return mBoundingBox;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cImageEntity::UpdateBoundingBox() {
|
||||
cVector2f vSize;
|
||||
|
||||
if (mvRotation.z != 0) {
|
||||
// Only Temp...
|
||||
float fMaxSize = sqrt(mvSize.x * mvSize.x + mvSize.y * mvSize.y);
|
||||
|
||||
vSize.x = fMaxSize;
|
||||
vSize.y = fMaxSize;
|
||||
} else {
|
||||
vSize = mvSize;
|
||||
}
|
||||
|
||||
mBoundingBox = cRect2f(cVector2f(GetWorldPosition().x - vSize.x / 2,
|
||||
GetWorldPosition().y - vSize.y / 2),
|
||||
vSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cImageEntity::SetAlpha(float afX) {
|
||||
if (mfAlpha != afX) {
|
||||
mfAlpha = afX;
|
||||
|
||||
for (int i = 0; i < (int)mvVtx.size(); i++) {
|
||||
mvVtx[i].col.a = mfAlpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cImageEntity::Flash(float afAdd) {
|
||||
mbFlashing = true;
|
||||
mfFlashAdd = -ABS(afAdd);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
} // namespace hpl
|
||||
Reference in New Issue
Block a user