Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,375 @@
/* 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/AnimationState.h"
#include "hpl1/engine/graphics/Animation.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/resources/AnimationManager.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cAnimationState::cAnimationState(cAnimation *apAnimation, const tString &asName,
cAnimationManager *apAnimationManager) {
mpAnimation = apAnimation;
mpAnimationManager = apAnimationManager;
mfLength = mpAnimation->GetLength();
msName = asName;
mbActive = false;
mfTimePos = 0;
mfWeight = 1;
mfSpeed = 1.0f;
mfBaseSpeed = 1.0f;
mfTimePos = 0;
mfPrevTimePos = 0;
mbLoop = false;
mbPaused = false;
mfSpecialEventTime = 0;
mfFadeStep = 0;
}
//-----------------------------------------------------------------------
cAnimationState::~cAnimationState() {
STLDeleteAll(mvEvents);
if (mpAnimationManager)
mpAnimationManager->Destroy(mpAnimation);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cAnimationState::Update(float afTimeStep) {
// Update animation
AddTimePosition(afTimeStep);
// Fading
if (mfFadeStep != 0) {
mfWeight += mfFadeStep * afTimeStep;
if (mfFadeStep < 0 && mfWeight <= 0) {
mfWeight = 0;
mbActive = false;
mfFadeStep = 0;
} else if (mfFadeStep > 0 && mfWeight >= 1) {
mfWeight = 1;
mfFadeStep = 0;
}
}
}
//-----------------------------------------------------------------------
bool cAnimationState::IsFading() {
return mfFadeStep != 0;
}
//-----------------------------------------------------------------------
bool cAnimationState::IsOver() {
if (mbLoop)
return false;
return mfTimePos >= mfLength;
}
//-----------------------------------------------------------------------
void cAnimationState::FadeIn(float afTime) {
mfFadeStep = 1.0f / ABS(afTime);
}
void cAnimationState::FadeOut(float afTime) {
mfFadeStep = -1.0f / ABS(afTime);
}
//-----------------------------------------------------------------------
void cAnimationState::SetLength(float afLength) {
mfLength = afLength;
}
float cAnimationState::GetLength() {
return mfLength;
}
//-----------------------------------------------------------------------
void cAnimationState::SetWeight(float afWeight) {
mfWeight = afWeight;
}
float cAnimationState::GetWeight() {
return mfWeight;
}
//-----------------------------------------------------------------------
void cAnimationState::SetSpeed(float afSpeed) {
mfSpeed = afSpeed;
}
float cAnimationState::GetSpeed() {
return mfSpeed;
}
//-----------------------------------------------------------------------
void cAnimationState::SetBaseSpeed(float afSpeed) {
mfBaseSpeed = afSpeed;
}
float cAnimationState::GetBaseSpeed() {
return mfBaseSpeed;
}
//-----------------------------------------------------------------------
void cAnimationState::SetTimePosition(float afPosition) {
if (mbLoop) {
mfTimePos = cMath::Wrap(afPosition, 0, mfLength);
} else {
mfTimePos = cMath::Clamp(afPosition, 0, mfLength);
}
}
float cAnimationState::GetTimePosition() {
return mfTimePos;
}
float cAnimationState::GetPreviousTimePosition() {
return mfPrevTimePos;
}
//-----------------------------------------------------------------------
void cAnimationState::SetRelativeTimePosition(float afPosition) {
SetTimePosition(afPosition * mfLength);
}
float cAnimationState::GetRelativeTimePosition() {
return mfTimePos / mfLength;
}
//-----------------------------------------------------------------------
bool cAnimationState::IsActive() {
return mbActive;
}
void cAnimationState::SetActive(bool abActive) {
if (mbActive == abActive)
return;
mbActive = abActive;
// Should this really be here?
mbPaused = false;
mfFadeStep = 0;
}
//-----------------------------------------------------------------------
bool cAnimationState::IsLooping() {
return mbLoop;
}
void cAnimationState::SetLoop(bool abLoop) {
mbLoop = abLoop;
}
//-----------------------------------------------------------------------
bool cAnimationState::IsPaused() {
return mbPaused;
}
void cAnimationState::SetPaused(bool abPaused) {
mbPaused = abPaused;
}
//-----------------------------------------------------------------------
bool cAnimationState::IsAfterSpecialEvent() {
return mfTimePos > mfSpecialEventTime;
}
bool cAnimationState::IsBeforeSpecialEvent() {
return mfTimePos < mfSpecialEventTime;
}
//-----------------------------------------------------------------------
void cAnimationState::AddTimePosition(float afAdd) {
if (mbPaused)
return;
mfPrevTimePos = mfTimePos;
mfTimePos += afAdd * mfSpeed * mfBaseSpeed;
SetTimePosition(mfTimePos);
}
//-----------------------------------------------------------------------
cAnimation *cAnimationState::GetAnimation() {
return mpAnimation;
}
//-----------------------------------------------------------------------
cAnimationEvent *cAnimationState::CreateEvent() {
cAnimationEvent *pEvent = hplNew(cAnimationEvent, ());
pEvent->mfTime = 0;
pEvent->mType = eAnimationEventType_LastEnum;
pEvent->msValue = "";
mvEvents.push_back(pEvent);
return pEvent;
}
cAnimationEvent *cAnimationState::GetEvent(int alIdx) {
return mvEvents[alIdx];
}
int cAnimationState::GetEventNum() {
return (int)mvEvents.size();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SAVE OBJECT STUFF
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
kBeginSerializeBase(cSaveData_cAnimationState)
kSerializeVar(msName, eSerializeType_String)
kSerializeVar(msAnimationName, eSerializeType_String)
kSerializeVar(mfDefaultSpeed, eSerializeType_Float32)
kSerializeVar(mfLength, eSerializeType_Float32)
kSerializeVar(mfWeight, eSerializeType_Float32)
kSerializeVar(mfSpeed, eSerializeType_Float32)
kSerializeVar(mfTimePos, eSerializeType_Float32)
kSerializeVar(mbActive, eSerializeType_Bool)
kSerializeVar(mbLoop, eSerializeType_Bool)
kSerializeVar(mbPaused, eSerializeType_Bool)
kSerializeVar(mfFadeStep, eSerializeType_Float32)
kEndSerialize()
//-----------------------------------------------------------------------
iSaveObject *cSaveData_cAnimationState::CreateSaveObject(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
return NULL;
}
//-----------------------------------------------------------------------
int cSaveData_cAnimationState::GetSaveCreatePrio() {
return 2;
}
//-----------------------------------------------------------------------
iSaveData *cAnimationState::CreateSaveData() {
return hplNew(cSaveData_cAnimationState, ());
}
//-----------------------------------------------------------------------
void cAnimationState::SaveToSaveData(iSaveData *apSaveData) {
kSaveData_SaveToBegin(cAnimationState);
kSaveData_SaveTo(msName);
pData->msAnimationName = mpAnimation->GetFileName();
kSaveData_SaveTo(mfBaseSpeed);
kSaveData_SaveTo(mfLength);
kSaveData_SaveTo(mfWeight);
kSaveData_SaveTo(mfSpeed);
kSaveData_SaveTo(mfTimePos);
kSaveData_SaveTo(mbActive);
kSaveData_SaveTo(mbLoop);
kSaveData_SaveTo(mbPaused);
kSaveData_SaveTo(mfFadeStep);
}
//-----------------------------------------------------------------------
void cAnimationState::LoadFromSaveData(iSaveData *apSaveData) {
kSaveData_LoadFromBegin(cAnimationState);
kSaveData_LoadFrom(msName);
kSaveData_LoadFrom(mfLength);
kSaveData_LoadFrom(mfWeight);
kSaveData_LoadFrom(mfSpeed);
kSaveData_LoadFrom(mfTimePos);
kSaveData_LoadFrom(mfBaseSpeed);
kSaveData_LoadFrom(mbActive);
kSaveData_LoadFrom(mbLoop);
kSaveData_LoadFrom(mbPaused);
kSaveData_LoadFrom(mfFadeStep);
}
//-----------------------------------------------------------------------
void cAnimationState::SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
kSaveData_SetupBegin(cAnimationState);
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,190 @@
/* 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.
*/
#ifndef HPL_ANIMATION_STATE_H
#define HPL_ANIMATION_STATE_H
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/system/SystemTypes.h"
#include "hpl1/engine/game/SaveGame.h"
namespace hpl {
class cAnimation;
class cAnimationManager;
//---------------------------------------------
class cSaveData_cAnimationState : public iSaveData {
kSaveData_ClassInit(cAnimationState) public : tString msName;
tString msAnimationName;
float mfDefaultSpeed; // Not needed later
float mfLength;
float mfWeight;
float mfSpeed;
float mfTimePos;
float mfBaseSpeed;
bool mbActive;
bool mbLoop;
bool mbPaused;
float mfFadeStep;
float mfSpecialEventTime;
virtual iSaveObject *CreateSaveObject(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
virtual int GetSaveCreatePrio();
};
//---------------------------------------------
class cAnimationEvent {
public:
float mfTime;
eAnimationEventType mType;
tString msValue;
};
//---------------------------------------------
class cAnimationState : public iSaveObject {
typedef iSaveObject super;
public:
cAnimationState(cAnimation *apAnimation, const tString &asName,
cAnimationManager *apAnimationManager);
~cAnimationState();
const char *GetName() { return msName.c_str(); }
void Update(float afTimeStep);
bool IsFading();
/**
* If the animation has reached the end.
*/
bool IsOver();
void FadeIn(float afTime);
void FadeOut(float afTime);
void SetLength(float afLength);
float GetLength();
void SetWeight(float afWeight);
float GetWeight();
void SetSpeed(float afSpeed);
float GetSpeed();
void SetBaseSpeed(float afSpeed);
float GetBaseSpeed();
void SetTimePosition(float afPosition);
float GetTimePosition();
float GetPreviousTimePosition();
/**
* Set the relative position. 0 = start, 1 = end
* \param afPosition
*/
void SetRelativeTimePosition(float afPosition);
/**
* Get the relative position. 0 = start, 1 = end
*/
float GetRelativeTimePosition();
bool IsActive();
void SetActive(bool abActive);
bool IsLooping();
void SetLoop(bool abLoop);
bool IsPaused();
void SetPaused(bool abPaused);
void SetSpecialEventTime(float afT) { mfSpecialEventTime = afT; }
float GetSpecialEventTime() { return mfSpecialEventTime; }
bool IsAfterSpecialEvent();
bool IsBeforeSpecialEvent();
void AddTimePosition(float afAdd);
cAnimation *GetAnimation();
cAnimationEvent *CreateEvent();
cAnimationEvent *GetEvent(int alIdx);
int GetEventNum();
float GetFadeStep() { return mfFadeStep; }
void SetFadeStep(float afX) { mfFadeStep = afX; }
// SaveObject implementation
virtual iSaveData *CreateSaveData();
virtual void SaveToSaveData(iSaveData *apSaveData);
virtual void LoadFromSaveData(iSaveData *apSaveData);
virtual void SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
private:
tString msName;
cAnimationManager *mpAnimationManager;
cAnimation *mpAnimation;
Common::Array<cAnimationEvent *> mvEvents;
// Properties of the animation
float mfLength;
float mfWeight;
float mfSpeed;
float mfTimePos;
float mfPrevTimePos;
float mfBaseSpeed;
float mfSpecialEventTime;
bool mbActive;
bool mbLoop;
bool mbPaused;
// properties for update
float mfFadeStep;
};
} // namespace hpl
#endif // HPL_ANIMATION_STATE_H

View File

@@ -0,0 +1,114 @@
/* 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/Area2D.h"
#include "hpl1/engine/impl/tinyXML/tinyxml.h"
#include "hpl1/engine/physics/Body2D.h"
#include "hpl1/engine/physics/Collider2D.h"
#include "hpl1/engine/system/String.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cArea2D::cArea2D(const tString &asName, const tString &asTypeName, cCollider2D *apCollider)
: iEntity2D(asName) {
UpdateBoundingBox();
msType = asTypeName;
mpCollider = apCollider;
}
//-----------------------------------------------------------------------
cArea2D::~cArea2D() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cArea2D::CheckWorldCollision(tFlag alFlags) {
cRect2f CollideRect = GetBoundingBox();
return mpCollider->CollideRect(CollideRect, alFlags, NULL) != 0 ? true : false;
}
//-----------------------------------------------------------------------
bool cArea2D::CheckBodyCollision(cBody2D *apBody) {
return false;
}
//-----------------------------------------------------------------------
bool cArea2D::LoadData(TiXmlElement *apRootElem) {
mvCustom.x = cString::ToFloat(apRootElem->Attribute("SizeX"), 0);
mvCustom.y = cString::ToFloat(apRootElem->Attribute("SizeY"), 0);
mvCustom.z = cString::ToFloat(apRootElem->Attribute("SizeZ"), 0);
mvSize.x = cString::ToFloat(apRootElem->Attribute("Width"), 0);
mvSize.y = cString::ToFloat(apRootElem->Attribute("Height"), 0);
mbIsActive = cString::ToBool(apRootElem->Attribute("Active"), true);
return true;
}
//-----------------------------------------------------------------------
const cRect2f &cArea2D::GetBoundingBox() {
return mBoundingBox;
}
//-----------------------------------------------------------------------
bool cArea2D::UpdateBoundingBox() {
mBoundingBox = cRect2f(cVector2f(GetWorldPosition().x - mvSize.x / 2,
GetWorldPosition().y - mvSize.y / 2),
mvSize);
return true;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,68 @@
/* 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.
*/
#ifndef HPL_AREA2D_H
#define HPL_AREA2D_H
#include "hpl1/engine/scene/Entity2D.h"
class TiXmlElement;
namespace hpl {
class cBody2D;
class cCollider2D;
class cArea2D : public iEntity2D {
public:
cArea2D(const tString &asName, const tString &asTypeName, cCollider2D *apCollider);
~cArea2D();
tString GetEntityType() { return "Area"; }
const tString &GetType() { return msType; }
const cVector3f &GetCustom() { return mvCustom; }
const cVector2f &GetSize() { return mvSize; }
bool LoadData(TiXmlElement *apRootElem);
bool CheckWorldCollision(tFlag alFlags);
bool CheckBodyCollision(cBody2D *apBody);
const cRect2f &GetBoundingBox();
bool UpdateBoundingBox();
private:
cCollider2D *mpCollider;
tString msType;
cVector2f mvSize;
cVector3f mvCustom;
};
} // namespace hpl
#endif // HPL_AREA2D_H

View File

@@ -0,0 +1,55 @@
/* 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.
*/
#ifndef HPL_CAMERA_H
#define HPL_CAMERA_H
#include "hpl1/engine/math/MathTypes.h"
namespace hpl {
class iLowLevelGraphics;
enum eCameraType {
eCameraType_2D,
eCameraType_3D,
eCameraType_LastEnum
};
class iCamera {
public:
virtual ~iCamera() = default;
virtual void SetModelViewMatrix(iLowLevelGraphics *apLowLevel) = 0;
virtual void SetProjectionMatrix(iLowLevelGraphics *apLowLevel) = 0;
virtual cVector3f GetEyePosition() = 0;
virtual eCameraType GetType() = 0;
};
} // namespace hpl
#endif // HPL_CAMERA_H

View File

@@ -0,0 +1,115 @@
/* 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/Camera2D.h"
#include "hpl1/engine/graphics/LowLevelGraphics.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cCamera2D::cCamera2D(unsigned int alW, unsigned int alH) {
mvPosition = cVector3f(0, 0, 0);
mfAngle = 0;
mvClipArea.x = alW;
mvClipArea.y = alH;
mfZMin = -100;
mfZMax = -100;
mfFOV = 60;
}
//-----------------------------------------------------------------------
cCamera2D::~cCamera2D() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cVector3f cCamera2D::GetEyePosition() {
cVector3f vEyePos = GetPosition();
vEyePos.z = 100;
return vEyePos;
}
//-----------------------------------------------------------------------
void cCamera2D::GetClipRect(cRect2f &aRect) {
float fDiv = 1;
if (mvPosition.z < 0) {
fDiv = 1 - ABS(mvPosition.z / mfZMin);
if (fDiv <= 0)
fDiv = 0.0001f;
} else
fDiv = 1 + ABS(mvPosition.z / mfZMax);
// Transform these depending on z
float lW = ((float)mvClipArea.x) * fDiv;
float lH = ((float)mvClipArea.y) * fDiv;
float lX = mvPosition.x - lW / 2;
float lY = mvPosition.y - lH / 2;
aRect.x = lX;
aRect.y = lY;
aRect.w = lW;
aRect.h = lH;
}
//-----------------------------------------------------------------------
void cCamera2D::SetModelViewMatrix(iLowLevelGraphics *apLowLevel) {
apLowLevel->SetIdentityMatrix(eMatrix_ModelView);
cRect2f ClipRect;
GetClipRect(ClipRect);
cVector2f vVirtSize = apLowLevel->GetVirtualSize();
cVector3f vPos(-(ClipRect.x), -(ClipRect.y), 0);
cVector3f vScale(vVirtSize.x / ClipRect.w, vVirtSize.y / ClipRect.h, 1);
apLowLevel->ScaleMatrix(eMatrix_ModelView, vScale);
apLowLevel->TranslateMatrix(eMatrix_ModelView, vPos);
}
void cCamera2D::SetProjectionMatrix(iLowLevelGraphics *apLowLevel) {
apLowLevel->SetOrthoProjection(apLowLevel->GetVirtualSize(), -1000, 1000);
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,77 @@
/* 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.
*/
#ifndef HPL_CAMERA2D_H
#define HPL_CAMERA2D_H
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/scene/Camera.h"
namespace hpl {
class iLowLevelGraphics;
class cCamera2D : public iCamera {
public:
cCamera2D(unsigned int alW, unsigned int alH);
~cCamera2D();
const cVector3f &GetPosition() const { return mvPosition; }
cVector3f GetEyePosition();
void SetPosition(cVector3f avPos) { mvPosition = avPos; }
void SetXY(cVector2f avPos) {
mvPosition.x = avPos.x;
mvPosition.y = avPos.y;
}
void SetZ(float afZ) { mvPosition.z = afZ; }
void MoveXY(cVector2f avAdd) {
mvPosition.x += avAdd.x;
mvPosition.y += avAdd.y;
}
void MoveZ(float afZ) { mvPosition.z += afZ; }
void GetClipRect(cRect2f &aRect);
void SetModelViewMatrix(iLowLevelGraphics *apLowLevel);
void SetProjectionMatrix(iLowLevelGraphics *apLowLevel);
eCameraType GetType() { return eCameraType_2D; }
private:
cVector3f mvPosition;
float mfAngle;
float mfZMin;
float mfZMax;
float mfFOV;
cVector2l mvClipArea;
};
} // namespace hpl
#endif // HPL_CAMERA2D_H

View 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/Camera3D.h"
#include "hpl1/engine/graphics/LowLevelGraphics.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/scene/Entity3D.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cCamera3D::cCamera3D() {
mvPosition = cVector3f(0);
mfFOV = cMath::ToRad(70.0f);
mfAspect = 4.0f / 3.0f;
mfFarClipPlane = 1000.0f;
mfNearClipPlane = 0.05f;
mfPitch = 0;
mfYaw = 0;
mfRoll = 0;
mRotateMode = eCameraRotateMode_EulerAngles;
mMoveMode = eCameraMoveMode_Fly;
m_mtxView = cMatrixf::Identity;
m_mtxProjection = cMatrixf::Identity;
m_mtxMove = cMatrixf::Identity;
mbViewUpdated = true;
mbProjectionUpdated = true;
mbMoveUpdated = true;
mbInfFarPlane = true;
mvPitchLimits = cVector2f(kPif / 2.0f, -kPif / 2.0f);
mvYawLimits = cVector2f(0, 0);
}
//-----------------------------------------------------------------------
cCamera3D::~cCamera3D() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cCamera3D::SetPosition(const cVector3f &avPos) {
mvPosition = avPos;
mbViewUpdated = true;
mNode.SetPosition(mvPosition);
}
//-----------------------------------------------------------------------
void cCamera3D::SetPitch(float afAngle) {
mfPitch = afAngle;
if (mvPitchLimits.x != 0 || mvPitchLimits.y != 0) {
if (mfPitch > mvPitchLimits.x)
mfPitch = mvPitchLimits.x;
if (mfPitch < mvPitchLimits.y)
mfPitch = mvPitchLimits.y;
}
mbViewUpdated = true;
mbMoveUpdated = true;
}
void cCamera3D::SetYaw(float afAngle) {
mfYaw = afAngle;
if (mvYawLimits.x != 0 || mvYawLimits.y != 0) {
if (mfYaw > mvYawLimits.x)
mfYaw = mvYawLimits.x;
if (mfYaw < mvYawLimits.y)
mfYaw = mvYawLimits.y;
}
mbViewUpdated = true;
mbMoveUpdated = true;
}
void cCamera3D::SetRoll(float afAngle) {
mfRoll = afAngle;
mbViewUpdated = true;
mbMoveUpdated = true;
}
//-----------------------------------------------------------------------
void cCamera3D::AddPitch(float afAngle) {
mfPitch += afAngle;
if (mvPitchLimits.x != 0 || mvPitchLimits.y != 0) {
if (mfPitch > mvPitchLimits.x)
mfPitch = mvPitchLimits.x;
if (mfPitch < mvPitchLimits.y)
mfPitch = mvPitchLimits.y;
}
mbViewUpdated = true;
mbMoveUpdated = true;
}
void cCamera3D::AddYaw(float afAngle) {
mfYaw += afAngle;
if (mvYawLimits.x != 0 || mvYawLimits.y != 0) {
if (mfYaw > mvYawLimits.x)
mfYaw = mvYawLimits.x;
if (mfYaw < mvYawLimits.y)
mfYaw = mvYawLimits.y;
}
mbViewUpdated = true;
mbMoveUpdated = true;
}
void cCamera3D::AddRoll(float afAngle) {
mfRoll += afAngle;
mbViewUpdated = true;
mbMoveUpdated = true;
}
//-----------------------------------------------------------------------
void cCamera3D::MoveForward(float afDist) {
UpdateMoveMatrix();
mvPosition += m_mtxMove.GetForward() * -afDist;
mbViewUpdated = true;
mNode.SetPosition(mvPosition);
}
//-----------------------------------------------------------------------
void cCamera3D::MoveRight(float afDist) {
UpdateMoveMatrix();
mvPosition += m_mtxMove.GetRight() * afDist;
mbViewUpdated = true;
mNode.SetPosition(mvPosition);
}
//-----------------------------------------------------------------------
void cCamera3D::MoveUp(float afDist) {
UpdateMoveMatrix();
mvPosition += m_mtxMove.GetUp() * afDist;
mbViewUpdated = true;
mNode.SetPosition(mvPosition);
}
//-----------------------------------------------------------------------
void cCamera3D::SetRotateMode(eCameraRotateMode aMode) {
mRotateMode = aMode;
mbViewUpdated = true;
mbMoveUpdated = true;
}
//-----------------------------------------------------------------------
void cCamera3D::SetMoveMode(eCameraMoveMode aMode) {
mMoveMode = aMode;
mbMoveUpdated = true;
}
//-----------------------------------------------------------------------
void cCamera3D::ResetRotation() {
mbViewUpdated = false;
mbMoveUpdated = false;
m_mtxMove = cMatrixf::Identity;
m_mtxView = cMatrixf::Identity;
mfRoll = 0;
mfYaw = 0;
mfPitch = 0;
}
//-----------------------------------------------------------------------
cFrustum *cCamera3D::GetFrustum() {
// If the far plane is infinite, still have to use a number on far plane
// to calculate the near plane in the frustm.
bool bWasInf = false;
if (mbInfFarPlane) {
SetInifintiveFarPlane(false);
bWasInf = true;
}
mFrustum.SetViewProjMatrix(GetProjectionMatrix(),
GetViewMatrix(),
GetFarClipPlane(), GetNearClipPlane(),
GetFOV(), GetAspect(), GetPosition(), mbInfFarPlane);
if (bWasInf) {
SetInifintiveFarPlane(true);
}
return &mFrustum;
}
//-----------------------------------------------------------------------
const cMatrixf &cCamera3D::GetViewMatrix() {
if (mbViewUpdated) {
if (mRotateMode == eCameraRotateMode_EulerAngles) {
m_mtxView = cMatrixf::Identity;
m_mtxView = cMath::MatrixMul(cMath::MatrixTranslate(mvPosition * -1), m_mtxView);
m_mtxView = cMath::MatrixMul(cMath::MatrixRotateY(-mfYaw), m_mtxView);
m_mtxView = cMath::MatrixMul(cMath::MatrixRotateX(-mfPitch), m_mtxView);
m_mtxView = cMath::MatrixMul(cMath::MatrixRotateZ(-mfRoll), m_mtxView);
}
mbViewUpdated = false;
}
return m_mtxView;
}
//-----------------------------------------------------------------------
const cMatrixf &cCamera3D::GetProjectionMatrix() {
if (mbProjectionUpdated) {
float fFar = mfFarClipPlane;
float fNear = mfNearClipPlane;
float fTop = tan(mfFOV * 0.5f) * fNear;
float fBottom = -fTop;
float fRight = mfAspect * fTop;
float fLeft = mfAspect * fBottom;
float A = (2.0f * fNear) / (fRight - fLeft);
float B = (2.0f * fNear) / (fTop - fBottom);
float D = -1.0f;
float C, Z;
if (mbInfFarPlane) {
C = -2.0f * fNear;
Z = -1.0f;
} else {
C = -(2.0f * fFar * fNear) / (fFar - fNear);
Z = -(fFar + fNear) / (fFar - fNear);
}
float X = 0; //(fRight + fLeft)/(fRight - fLeft);
float Y = 0; //(fTop + fBottom)/(fTop - fBottom);
m_mtxProjection = cMatrixf(
A, 0, X, 0,
0, B, Y, 0,
0, 0, Z, C,
0, 0, D, 0);
mbProjectionUpdated = false;
}
return m_mtxProjection;
}
//-----------------------------------------------------------------------
const cMatrixf &cCamera3D::GetMoveMatrix() {
UpdateMoveMatrix();
return m_mtxMove;
}
//-----------------------------------------------------------------------
cVector3f cCamera3D::GetEyePosition() {
return mvPosition;
}
//-----------------------------------------------------------------------
void cCamera3D::SetModelViewMatrix(iLowLevelGraphics *apLowLevel) {
}
//-----------------------------------------------------------------------
void cCamera3D::SetProjectionMatrix(iLowLevelGraphics *apLowLevel) {
}
//-----------------------------------------------------------------------
cVector3f cCamera3D::UnProject(const cVector2f &avScreenPos, iLowLevelGraphics *apLowLevel) {
// This code uses math::unproejct which is not working currently
/*cVector3f vPos(avScreenPos.x,avScreenPos.y,-0.1f);
bool bWasInf=false;
if(mbInfFarPlane){
SetInifintiveFarPlane(false);bWasInf=true;
}
cMatrixf mtxViewProj = cMath::MatrixMul(GetProjectionMatrix(), GetViewMatrix());
if(bWasInf){
SetInifintiveFarPlane(true);
}
cVector2f vScreenSize = apLowLevel->GetVirtualSize();
return cMath::Vector3UnProject(vPos, cRect2f(0,0,vScreenSize.x, vScreenSize.y), mtxViewProj);*/
cVector2f vScreenSize = apLowLevel->GetVirtualSize();
cVector2f vNormScreen((avScreenPos.x / vScreenSize.x) - 0.5f,
0.5f - (avScreenPos.y / vScreenSize.y));
float afNormalizedSlope = tan(mfFOV * 0.5f);
cVector2f avViewportToWorld;
avViewportToWorld.y = afNormalizedSlope * mfNearClipPlane * 2.0f;
avViewportToWorld.x = avViewportToWorld.y * mfAspect;
cVector3f vDir(vNormScreen.x * avViewportToWorld.x,
vNormScreen.y * avViewportToWorld.y,
-mfNearClipPlane);
cMatrixf mtxRot = cMath::MatrixInverse(GetViewMatrix().GetRotation());
vDir = cMath::MatrixMul(mtxRot, vDir);
vDir.Normalise();
return vDir;
}
//-----------------------------------------------------------------------
void cCamera3D::AttachEntity(iEntity3D *apEntity) {
mNode.AddEntity(apEntity);
}
void cCamera3D::RemoveEntity(iEntity3D *apEntity) {
mNode.RemoveEntity(apEntity);
}
void cCamera3D::ClearAttachedEntities() {
mNode.ClearEntities();
}
//-----------------------------------------------------------------------
cVector3f cCamera3D::GetForward() {
return GetViewMatrix().GetForward() * -1.0f;
}
cVector3f cCamera3D::GetRight() {
return GetViewMatrix().GetRight();
}
cVector3f cCamera3D::GetUp() {
return GetViewMatrix().GetUp();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cCamera3D::UpdateMoveMatrix() {
if (mbMoveUpdated) {
if (mRotateMode == eCameraRotateMode_EulerAngles) {
m_mtxMove = cMath::MatrixRotateY(-mfYaw);
if (mMoveMode == eCameraMoveMode_Fly) {
m_mtxMove = cMath::MatrixMul(cMath::MatrixRotateX(-mfPitch), m_mtxMove);
}
}
mbMoveUpdated = false;
}
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,243 @@
/* 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.
*/
#ifndef HPL_CAMERA3D_H
#define HPL_CAMERA3D_H
#include "hpl1/engine/math/Frustum.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/scene/Camera.h"
#include "hpl1/engine/scene/Node3D.h"
namespace hpl {
enum eCameraMoveMode {
eCameraMoveMode_Walk,
eCameraMoveMode_Fly,
eCameraMoveMode_LastEnum
};
enum eCameraRotateMode {
eCameraRotateMode_EulerAngles,
eCameraRotateMode_Matrix,
eCameraRotateMode_LastEnum
};
class iLowLevelGraphics;
class iEntity3D;
class cCamera3D : public iCamera {
public:
cCamera3D();
virtual ~cCamera3D();
const cVector3f &GetPosition() const { return mvPosition; }
void SetPosition(const cVector3f &avPos);
/**
* Move forward (or back) according to the move mode.
* \param afDist
*/
void MoveForward(float afDist);
/**
* Move right (or left) according to the move mode.
* \param afDist
*/
void MoveRight(float afDist);
/**
* Move up (or down) according to the move mode.
* \param afDist
*/
void MoveUp(float afDist);
void SetFOV(float afAngle) {
mfFOV = afAngle;
mbProjectionUpdated = true;
}
float GetFOV() { return mfFOV; }
void SetAspect(float afAngle) {
mfAspect = afAngle;
mbProjectionUpdated = true;
}
float GetAspect() { return mfAspect; }
void SetFarClipPlane(float afX) {
mfFarClipPlane = afX;
mbProjectionUpdated = true;
}
float GetFarClipPlane() { return mfFarClipPlane; }
void SetNearClipPlane(float afX) {
mfNearClipPlane = afX;
mbProjectionUpdated = true;
}
float GetNearClipPlane() { return mfNearClipPlane; }
/**
* This sets the far plane so that no far clipping is made.
* The FarClipPlane is still used for creating bounding box and frustum and
* should be set to some value.
*/
void SetInifintiveFarPlane(bool abX) {
mbInfFarPlane = abX;
mbProjectionUpdated = true;
}
bool GetInifintiveFarPlane() { return mbInfFarPlane; }
cFrustum *GetFrustum();
eCameraRotateMode GetRotateMode() { return mRotateMode; }
eCameraMoveMode GetMoveMode() { return mMoveMode; }
/**
* Set the mode to calculate the rotation angles.
* EulerAngles: Yaw, Pitch and Roll are used.
* Matrix: The matrix is changed directly.
*/
void SetRotateMode(eCameraRotateMode aMode);
/**
* Set the mode to calculate movement.
* Walk: only moving in the XZ plane
* Fly: moving in the dir the camera is facing.
*/
void SetMoveMode(eCameraMoveMode aMode);
/**
* Resets all rotation
*/
void ResetRotation();
/**
* Unproject the screen coordinate to world space.
*/
cVector3f UnProject(const cVector2f &avScreenPos, iLowLevelGraphics *apLowLevel);
void AttachEntity(iEntity3D *apEntity);
void RemoveEntity(iEntity3D *apEntity);
cNode3D *GetAttachmentNode() { return &mNode; }
void ClearAttachedEntities();
//////////////////////////////////////////////////
////////// EULER ANGLES ROTATION /////////////////
//////////////////////////////////////////////////
void SetPitch(float afAngle);
void SetYaw(float afAngle);
void SetRoll(float afAngle);
void AddPitch(float afAngle);
void AddYaw(float afAngle);
void AddRoll(float afAngle);
float GetPitch() const { return mfPitch; }
float GetYaw() const { return mfYaw; }
float GetRoll() const { return mfRoll; }
/**
* Set the limits within the pitch can move
* \param avLimits x = high limt and y low.If both are 0 limits are disabled.
*/
void SetPitchLimits(cVector2f avLimits) { mvPitchLimits = avLimits; }
const cVector2f &GetPitchLimits() { return mvPitchLimits; }
/**
* Set the limits within the yaw can move
* \param avLimits x = high limt and y low. If both are 0 limits are disabled.
*/
void SetYawLimits(cVector2f avLimits) { mvYawLimits = avLimits; }
const cVector2f &GetYawLimits() { return mvYawLimits; }
//////////////////////////////////////////////////
////////// EULER ANGLES ROTATION /////////////////
//////////////////////////////////////////////////
const cMatrixf &GetViewMatrix();
const cMatrixf &GetProjectionMatrix();
const cMatrixf &GetMoveMatrix();
// iCamera stuff:
void SetModelViewMatrix(iLowLevelGraphics *apLowLevel);
void SetProjectionMatrix(iLowLevelGraphics *apLowLevel);
cVector3f GetEyePosition();
eCameraType GetType() { return eCameraType_3D; }
cVector3f GetForward();
cVector3f GetRight();
cVector3f GetUp();
//////////////////////////////////////////////////
////////// RENDER SPECIFIC ///////////////////////
//////////////////////////////////////////////////
void SetPrevView(const cMatrixf &a_mtxA) { m_mtxPrevView = a_mtxA; }
void SetPrevProjection(const cMatrixf &a_mtxA) { m_mtxPrevProjection = a_mtxA; }
cMatrixf &GetPrevView() { return m_mtxPrevView; }
cMatrixf &GetPrevProjection() { return m_mtxPrevProjection; }
private:
void UpdateMoveMatrix();
cVector3f mvPosition;
float mfFOV;
float mfAspect;
float mfFarClipPlane;
float mfNearClipPlane;
float mfPitch;
float mfYaw;
float mfRoll;
cVector2f mvPitchLimits;
cVector2f mvYawLimits;
eCameraRotateMode mRotateMode;
eCameraMoveMode mMoveMode;
cMatrixf m_mtxView;
cMatrixf m_mtxProjection;
cMatrixf m_mtxMove;
cMatrixf m_mtxPrevView;
cMatrixf m_mtxPrevProjection;
cNode3D mNode;
cFrustum mFrustum;
bool mbInfFarPlane;
bool mbViewUpdated;
bool mbProjectionUpdated;
bool mbMoveUpdated;
};
} // namespace hpl
#endif // HPL_CAMERA3D_H

View File

@@ -0,0 +1,89 @@
/* 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/ColliderEntity.h"
#include "hpl1/engine/physics/CollideShape.h"
#include "hpl1/engine/physics/PhysicsBody.h"
#include "hpl1/engine/physics/PhysicsWorld.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cColliderEntity::cColliderEntity(const tString &asName, iPhysicsBody *apBody, iPhysicsWorld *apWorld) : iRenderable(asName) {
mpPhysicsWorld = apWorld;
mpBody = apBody;
mBoundingVolume = apBody->GetShape()->GetBoundingVolume();
}
//-----------------------------------------------------------------------
cColliderEntity::~cColliderEntity() {
if (mpBody && mpPhysicsWorld)
mpPhysicsWorld->DestroyBody(mpBody);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cBoundingVolume *cColliderEntity::GetBoundingVolume() {
return &mBoundingVolume;
}
//-----------------------------------------------------------------------
cMatrixf *cColliderEntity::GetModelMatrix(cCamera3D *apCamera) {
return &GetWorldMatrix();
}
//-----------------------------------------------------------------------
int cColliderEntity::GetMatrixUpdateCount() {
return GetTransformUpdateCount();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,73 @@
/* 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.
*/
#ifndef HPL_COLLIDER_ENTITY_H
#define HPL_COLLIDER_ENTITY_H
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/graphics/Renderable.h"
#include "hpl1/engine/math/MathTypes.h"
namespace hpl {
class iPhysicsWorld;
class iPhysicsBody;
class cColliderEntity : public iRenderable {
public:
cColliderEntity(const tString &asName, iPhysicsBody *apBody, iPhysicsWorld *apWorld);
~cColliderEntity();
iMaterial *GetMaterial() { return NULL; }
void UpdateGraphics(cCamera3D *apCamera, float afFrameTime, cRenderList *apRenderList) {}
iVertexBuffer *GetVertexBuffer() { return NULL; }
cBoundingVolume *GetBoundingVolume();
cMatrixf *GetModelMatrix(cCamera3D *apCamera);
int GetMatrixUpdateCount();
eRenderableType GetRenderType() { return eRenderableType_Dummy; }
// Entity implementation
tString GetEntityType() { return "Collider"; }
bool IsVisible() { return false; }
bool IsShadowCaster() { return false; }
void UpdateLogic(float afTimeStep) {}
private:
iPhysicsWorld *mpPhysicsWorld;
iPhysicsBody *mpBody;
};
//-----------------------------------------------------------------------
} // namespace hpl
#endif // HPL_COLLIDER_ENTITY_H

View File

@@ -0,0 +1,99 @@
/* 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/Entity.h"
#include "hpl1/engine/scene/Node.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iEntity::~iEntity() {
if (mpParentNode) {
mpParentNode->RemoveEntity(this);
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SAVE OBJECT STUFF
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
kBeginSerializeVirtual(cSaveData_iEntity, iSaveData)
kSerializeVar(mlParentNodeId, eSerializeType_Int32)
kSerializeVar(msName, eSerializeType_String)
kSerializeVar(mbIsVisible, eSerializeType_Bool)
kSerializeVar(mbIsActive, eSerializeType_Bool)
kEndSerialize()
//-----------------------------------------------------------------------
iSaveData *iEntity::CreateSaveData() {
return NULL;
}
//-----------------------------------------------------------------------
void iEntity::SaveToSaveData(iSaveData *apSaveData) {
kSaveData_SaveToBegin(iEntity);
kSaveData_SaveTo(mbIsActive);
kSaveData_SaveTo(mbIsVisible);
kSaveData_SaveTo(msName);
kSaveData_SaveObject(mpParentNode, mlParentNodeId);
}
//-----------------------------------------------------------------------
void iEntity::LoadFromSaveData(iSaveData *apSaveData) {
kSaveData_LoadFromBegin(iEntity);
kSaveData_LoadFrom(mbIsActive);
kSaveData_LoadFrom(mbIsVisible);
kSaveData_LoadFrom(msName);
}
//-----------------------------------------------------------------------
void iEntity::SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
kSaveData_SetupBegin(iEntity);
// kSaveData_LoadObject(mpParentNode,mlParentNodeId,iNode*);
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,96 @@
/* 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.
*/
#ifndef HPL_ENTITY_H
#define HPL_ENTITY_H
#include "hpl1/engine/game/SaveGame.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/system/SystemTypes.h"
namespace hpl {
class iNode;
//------------------------------------
kSaveData_BaseClass(iEntity) {
kSaveData_ClassInit(iEntity) public : int mlParentNodeId;
tString msName;
bool mbIsVisible;
bool mbIsActive;
};
//------------------------------------
class iEntity : public iSaveObject {
typedef iSaveObject super;
public:
iEntity(tString asName) : msName(asName), mbIsVisible(true),
mbIsActive(true), mpParentNode(NULL) {}
virtual ~iEntity();
virtual tString GetEntityType() = 0;
virtual void UpdateLogic(float afTimeStep) {}
tString &GetName() { return msName; }
void SetName(const tString &asName) { msName = asName; }
iNode *GetParent() { return mpParentNode; }
void SetParent(iNode *apNode) { mpParentNode = apNode; }
bool HasParent() { return mpParentNode != NULL; }
bool IsActive() { return mbIsActive; }
void SetActive(bool abActive) { mbIsActive = abActive; }
virtual bool IsVisible() { return mbIsVisible; }
virtual void SetVisible(bool abVisible) { mbIsVisible = abVisible; }
// SaveObject implementation
virtual iSaveData *CreateSaveData();
virtual void SaveToSaveData(iSaveData *apSaveData);
virtual void LoadFromSaveData(iSaveData *apSaveData);
virtual void SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
protected:
iNode *mpParentNode;
tString msName;
bool mbIsVisible;
bool mbIsActive;
};
typedef Common::List<iEntity *> tEntityList;
typedef tEntityList::iterator tEntityListIt;
typedef cSTLIterator<iEntity *, tEntityList, tEntityListIt> cEntityIterator;
} // namespace hpl
#endif // HPL_ENTITY2D_H

View File

@@ -0,0 +1,117 @@
/* 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/Entity2D.h"
#include "hpl1/engine/scene/GridMap2D.h"
#include "hpl1/engine/scene/Node2D.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iEntity2D::iEntity2D(tString asName) : iEntity(asName), mvPosition(0), mvRotation(0), mvScale(0),
mvLastPosition(0), mvLastRotation(0), mvLastScale(0),
mpGridObject(NULL) {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cVector3f iEntity2D::GetWorldPosition() {
if (mpParentNode) {
cNode2D *pNode2D = static_cast<cNode2D *>(mpParentNode);
return pNode2D->GetPosition() + mvPosition;
} else
return mvPosition;
}
//-----------------------------------------------------------------------
cVector3f iEntity2D::GetWorldRotation() {
if (mpParentNode) {
cNode2D *pNode2D = static_cast<cNode2D *>(mpParentNode);
return pNode2D->GetRotation() + mvRotation;
} else
return mvRotation;
}
//-----------------------------------------------------------------------
cVector3f iEntity2D::GetWorldScale() {
if (mpParentNode) {
cNode2D *pNode2D = static_cast<cNode2D *>(mpParentNode);
return pNode2D->GetScale() + mvScale;
} else
return mvScale;
}
//-----------------------------------------------------------------------
void iEntity2D::SetPosition(const cVector3f &avPos) {
mvLastPosition = mvPosition;
mvPosition = avPos;
if (UpdateBoundingBox())
if (mpGridObject)
mpGridObject->Update(GetBoundingBox());
}
//-----------------------------------------------------------------------
void iEntity2D::SetRotation(const cVector3f &avRot) {
mvLastRotation = mvRotation;
mvRotation = avRot;
if (UpdateBoundingBox())
if (mpGridObject)
mpGridObject->Update(GetBoundingBox());
}
//-----------------------------------------------------------------------
void iEntity2D::SetScale(const cVector3f &avScale) {
mvLastScale = mvScale;
mvScale = avScale;
if (UpdateBoundingBox())
if (mpGridObject)
mpGridObject->Update(GetBoundingBox());
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,82 @@
/* 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.
*/
#ifndef HPL_ENTITY2D_H
#define HPL_ENTITY2D_H
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/scene/Entity.h"
#include "hpl1/engine/system/SystemTypes.h"
namespace hpl {
class cGrid2DObject;
class iEntity2D : public iEntity {
public:
iEntity2D(tString asName);
virtual ~iEntity2D() {}
virtual const cRect2f &GetBoundingBox() = 0;
virtual bool UpdateBoundingBox() = 0;
cVector3f &GetLocalPosition() { return mvPosition; }
cVector3f &GetLocalRotation() { return mvRotation; }
cVector3f &GetLocalScale() { return mvScale; }
cVector3f GetWorldPosition();
cVector3f GetWorldRotation();
cVector3f GetWorldScale();
void SetPosition(const cVector3f &avPos);
void SetRotation(const cVector3f &avRot);
void SetScale(const cVector3f &avScale);
cGrid2DObject *GetGrid2DObject() { return mpGridObject; }
void SetGrid2DObject(cGrid2DObject *apGrid) { mpGridObject = apGrid; }
bool HasGrid2DObject() { return mpGridObject != NULL; }
protected:
cGrid2DObject *mpGridObject;
cVector3f mvPosition;
cVector3f mvRotation;
cVector3f mvScale;
cVector3f mvLastPosition;
cVector3f mvLastRotation;
cVector3f mvLastScale;
cRect2f mBoundingBox;
};
typedef Common::List<iEntity2D *> tEntity2DList;
typedef tEntity2DList::iterator tEntity2DListIt;
} // namespace hpl
#endif // HPL_ENTITY2D_H

View File

@@ -0,0 +1,393 @@
/* 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/Entity3D.h"
#include "hpl1/engine/graphics/RenderList.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/scene/Node3D.h"
#include "hpl1/engine/system/low_level_system.h"
#include "hpl1/engine/scene/PortalContainer.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iEntity3D::iEntity3D(tString asName) : iEntity(asName) {
m_mtxLocalTransform = cMatrixf::Identity;
m_mtxWorldTransform = cMatrixf::Identity;
mbTransformUpdated = true;
mlCount = 0;
mlGlobalRenderCount = cRenderList::GetGlobalRenderCount();
msSourceFile = "";
mbApplyTransformToBV = true;
mbUpdateBoundingVolume = true;
mpParent = NULL;
mlIteratorCount = -1;
mpCurrentSector = NULL;
}
iEntity3D::~iEntity3D() {
if (mpParent)
mpParent->RemoveChild(this);
for (tEntity3DListIt it = mlstChildren.begin(); it != mlstChildren.end(); ++it) {
iEntity3D *pChild = *it;
pChild->mpParent = NULL;
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cVector3f iEntity3D::GetLocalPosition() {
return m_mtxLocalTransform.GetTranslation();
}
//-----------------------------------------------------------------------
cMatrixf &iEntity3D::GetLocalMatrix() {
return m_mtxLocalTransform;
}
//-----------------------------------------------------------------------
cVector3f iEntity3D::GetWorldPosition() {
UpdateWorldTransform();
return m_mtxWorldTransform.GetTranslation();
}
//-----------------------------------------------------------------------
cMatrixf &iEntity3D::GetWorldMatrix() {
UpdateWorldTransform();
return m_mtxWorldTransform;
}
//-----------------------------------------------------------------------
void iEntity3D::SetPosition(const cVector3f &avPos) {
m_mtxLocalTransform.m[0][3] = avPos.x;
m_mtxLocalTransform.m[1][3] = avPos.y;
m_mtxLocalTransform.m[2][3] = avPos.z;
SetTransformUpdated();
}
//-----------------------------------------------------------------------
void iEntity3D::SetMatrix(const cMatrixf &a_mtxTransform) {
m_mtxLocalTransform = a_mtxTransform;
SetTransformUpdated();
}
//-----------------------------------------------------------------------
void iEntity3D::SetWorldPosition(const cVector3f &avWorldPos) {
if (mpParent) {
SetPosition(avWorldPos - mpParent->GetWorldPosition());
} else {
SetPosition(avWorldPos);
}
}
//-----------------------------------------------------------------------
void iEntity3D::SetWorldMatrix(const cMatrixf &a_mtxWorldTransform) {
if (mpParent) {
SetMatrix(cMath::MatrixMul(cMath::MatrixInverse(mpParent->GetWorldMatrix()),
a_mtxWorldTransform));
} else {
SetMatrix(a_mtxWorldTransform);
}
}
//-----------------------------------------------------------------------
void iEntity3D::SetTransformUpdated(bool abUpdateCallbacks) {
mbTransformUpdated = true;
mlCount++;
// Perhaps not update this yet? This is baaaad!
if (mbApplyTransformToBV)
mBoundingVolume.SetTransform(GetWorldMatrix());
mbUpdateBoundingVolume = true;
// Update children
for (tEntity3DListIt EntIt = mlstChildren.begin(); EntIt != mlstChildren.end(); ++EntIt) {
iEntity3D *pChild = *EntIt;
pChild->SetTransformUpdated(true);
}
// Update callbacks
if (mlstCallbacks.empty() || abUpdateCallbacks == false)
return;
tEntityCallbackListIt it = mlstCallbacks.begin();
for (; it != mlstCallbacks.end(); ++it) {
iEntityCallback *pCallback = *it;
pCallback->OnTransformUpdate(this);
}
}
//-----------------------------------------------------------------------
bool iEntity3D::GetTransformUpdated() {
return mbTransformUpdated;
}
//-----------------------------------------------------------------------
int iEntity3D::GetTransformUpdateCount() {
return mlCount;
}
//-----------------------------------------------------------------------
void iEntity3D::AddCallback(iEntityCallback *apCallback) {
mlstCallbacks.push_back(apCallback);
}
//-----------------------------------------------------------------------
void iEntity3D::RemoveCallback(iEntityCallback *apCallback) {
STLFindAndDelete(mlstCallbacks, apCallback);
}
//-----------------------------------------------------------------------
void iEntity3D::AddChild(iEntity3D *apEntity) {
if (apEntity == NULL)
return;
if (apEntity->mpParent != NULL)
return;
mlstChildren.push_back(apEntity);
apEntity->mpParent = this;
apEntity->SetTransformUpdated(true);
}
void iEntity3D::RemoveChild(iEntity3D *apEntity) {
for (tEntity3DListIt it = mlstChildren.begin(); it != mlstChildren.end();) {
iEntity3D *pChild = *it;
if (pChild == apEntity) {
pChild->mpParent = NULL;
it = mlstChildren.erase(it);
} else {
++it;
}
}
}
bool iEntity3D::IsChild(iEntity3D *apEntity) {
for (tEntity3DListIt it = mlstChildren.begin(); it != mlstChildren.end(); ++it) {
iEntity3D *pChild = *it;
if (pChild == apEntity)
return true;
}
return false;
}
iEntity3D *iEntity3D::GetEntityParent() {
return mpParent;
}
//-----------------------------------------------------------------------
bool iEntity3D::IsInSector(cSector *apSector) {
// Log("-- %s --\n",msName.c_str());
// bool bShouldReturnTrue = false;
if (apSector == GetCurrentSector()) {
// Log("Should return true\n");
// bShouldReturnTrue = true;
return true;
}
tRenderContainerDataList *pDataList = GetRenderContainerDataList();
tRenderContainerDataListIt it = pDataList->begin();
for (; it != pDataList->end(); ++it) {
iRenderContainerData *pRenderContainerData = *it;
cSector *pSector = static_cast<cSector *>(pRenderContainerData);
// Log("%s (%d) vs %s (%d)\n",pSector->GetId().c_str(),pSector, apSector->GetId().c_str(),apSector);
if (pSector == apSector) {
// Log("return true!\n");
return true;
}
}
// if(bShouldReturnTrue)Log(" %s should have returned true. Sectors: %d\n",msName.c_str(), mlstRenderContainerData.size());
// Log("return false!\n");
return false;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void iEntity3D::UpdateWorldTransform() {
if (mbTransformUpdated) {
mbTransformUpdated = false;
// first check if there is a node parent
if (mpParentNode) {
cNode3D *pNode3D = static_cast<cNode3D *>(mpParentNode);
m_mtxWorldTransform = cMath::MatrixMul(pNode3D->GetWorldMatrix(), m_mtxLocalTransform);
}
// If there is no node parent check for entity parent
else if (mpParent) {
m_mtxWorldTransform = cMath::MatrixMul(mpParent->GetWorldMatrix(), m_mtxLocalTransform);
} else {
m_mtxWorldTransform = m_mtxLocalTransform;
}
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SAVE OBJECT STUFF
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
kBeginSerializeVirtual(cSaveData_iEntity3D, cSaveData_iEntity)
kSerializeVar(m_mtxLocalTransform, eSerializeType_Matrixf)
kSerializeVar(mBoundingVolume, eSerializeType_Class)
kSerializeVar(msSourceFile, eSerializeType_String)
kSerializeVar(mlParentId, eSerializeType_Int32)
kSerializeVarContainer(mlstChildren, eSerializeType_Int32)
kEndSerialize()
//-----------------------------------------------------------------------
iSaveData *iEntity3D::CreateSaveData() {
return NULL;
}
//-----------------------------------------------------------------------
void iEntity3D::SaveToSaveData(iSaveData *apSaveData) {
kSaveData_SaveToBegin(iEntity3D);
// Log("-------- Saving %s --------------\n",msName.c_str());
kSaveData_SaveTo(m_mtxLocalTransform);
kSaveData_SaveTo(mBoundingVolume);
kSaveData_SaveTo(msSourceFile);
kSaveData_SaveObject(mpParent, mlParentId);
kSaveData_SaveIdList(mlstChildren, tEntity3DListIt, mlstChildren);
/*if(mlstChildren.empty()==false)
{
Log("Children in '%s'/'%s': ",msName.c_str(),GetEntityType().c_str());
for(tEntity3DListIt it=mlstChildren.begin(); it != mlstChildren.end(); ++it)
{
iEntity3D *pEntity = *it;
Log("('%d/%s'/'%s'), ",pEntity->GetSaveObjectId(),pEntity->GetName().c_str(),pEntity->GetEntityType().c_str());
}
Log("\n");
}*/
}
//-----------------------------------------------------------------------
void iEntity3D::LoadFromSaveData(iSaveData *apSaveData) {
kSaveData_LoadFromBegin(iEntity3D);
// Log("-------- Loading %s --------------\n",msName.c_str());
SetMatrix(pData->m_mtxLocalTransform);
// Not sure of this is needed:
kSaveData_LoadFrom(mBoundingVolume);
kSaveData_LoadFrom(msSourceFile);
}
//-----------------------------------------------------------------------
void iEntity3D::SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
kSaveData_SetupBegin(iEntity3D);
// Log("-------- Setup %s --------------\n",msName.c_str());
// kSaveData_LoadObject(mpParent,mlParentId,iEntity3D*);
// kSaveData_LoadIdList(mlstChildren,mlstChildren,iEntity3D*);
if (pData->mlParentId != -1 && mpParent == NULL) {
iEntity3D *pParentEntity = static_cast<iEntity3D *>(apSaveObjectHandler->Get(pData->mlParentId));
if (pParentEntity)
pParentEntity->AddChild(this);
else
Error("Couldn't find parent entity id %d for '%s'\n", pData->mlParentId, GetName().c_str());
}
cContainerListIterator<int> it = pData->mlstChildren.GetIterator();
while (it.HasNext()) {
int mlId = it.Next();
if (mlId != -1) {
iEntity3D *pChildEntity = static_cast<iEntity3D *>(apSaveObjectHandler->Get(mlId));
if (pChildEntity)
AddChild(pChildEntity);
else
Error("Couldn't find child entity id %d for '%s'\n", mlId, GetName().c_str());
}
}
SetTransformUpdated(true);
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,173 @@
/* 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.
*/
#ifndef HPL_ENTITY3D_H
#define HPL_ENTITY3D_H
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/scene/Entity.h"
#include "hpl1/engine/system/Container.h"
#include "hpl1/engine/system/SystemTypes.h"
#include "common/list.h"
#include "hpl1/engine/math/BoundingVolume.h"
namespace hpl {
class iEntity3D;
class cSector;
class iEntityCallback {
public:
virtual ~iEntityCallback() = default;
virtual void OnTransformUpdate(iEntity3D *apEntity) = 0;
};
typedef Common::List<iEntityCallback *> tEntityCallbackList;
typedef tEntityCallbackList::iterator tEntityCallbackListIt;
//------------------------------------
// Used for the render container to add specific data to
// the object.
class iRenderContainerData {
};
typedef Common::List<iRenderContainerData *> tRenderContainerDataList;
typedef tRenderContainerDataList::iterator tRenderContainerDataListIt;
//------------------------------------
kSaveData_ChildClass(iEntity, iEntity3D) {
kSaveData_ClassInit(iEntity3D) public : cMatrixf m_mtxLocalTransform;
cBoundingVolume mBoundingVolume;
tString msSourceFile;
int mlParentId;
cContainerList<int> mlstChildren;
};
//-----------------------------------------
class iEntity3D;
typedef Common::List<iEntity3D *> tEntity3DList;
typedef tEntity3DList::iterator tEntity3DListIt;
class iEntity3D : public iEntity {
typedef iEntity super;
public:
iEntity3D(tString asName);
virtual ~iEntity3D();
cVector3f GetLocalPosition();
cMatrixf &GetLocalMatrix();
cVector3f GetWorldPosition();
cMatrixf &GetWorldMatrix();
void SetPosition(const cVector3f &avPos);
void SetMatrix(const cMatrixf &a_mtxTransform);
void SetWorldPosition(const cVector3f &avWorldPos);
void SetWorldMatrix(const cMatrixf &a_mtxWorldTransform);
void SetTransformUpdated(bool abUpdateCallbacks = true);
bool GetTransformUpdated();
int GetTransformUpdateCount();
void AddCallback(iEntityCallback *apCallback);
void RemoveCallback(iEntityCallback *apCallback);
void SetSourceFile(const tString &asFile) { msSourceFile = asFile; }
const tString &GetSourceFile() { return msSourceFile; }
virtual cBoundingVolume *GetBoundingVolume() { return &mBoundingVolume; }
/**
* The child hierarchy will only work if the child has no node parent.
**/
void AddChild(iEntity3D *apEntity);
void RemoveChild(iEntity3D *apEntity);
bool IsChild(iEntity3D *apEntity);
iEntity3D *GetEntityParent();
virtual tRenderContainerDataList *GetRenderContainerDataList() { return &mlstRenderContainerData; }
inline int GetIteratorCount() { return mlIteratorCount; }
inline void SetIteratorCount(const int alX) { mlIteratorCount = alX; }
inline void SetCurrentSector(cSector *apSetor) { mpCurrentSector = apSetor; }
virtual cSector *GetCurrentSector() const { return mpCurrentSector; }
bool IsInSector(cSector *apSector);
inline int GetGlobalRenderCount() { return mlGlobalRenderCount; }
inline void SetGlobalRenderCount(int alX) { mlGlobalRenderCount = alX; }
// SaveObject implementation
virtual iSaveData *CreateSaveData();
virtual void SaveToSaveData(iSaveData *apSaveData);
virtual void LoadFromSaveData(iSaveData *apSaveData);
virtual void SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
protected:
cMatrixf m_mtxLocalTransform;
cMatrixf m_mtxWorldTransform;
cBoundingVolume mBoundingVolume;
bool mbUpdateBoundingVolume;
bool mbApplyTransformToBV; // Only temp!!
bool mbTransformUpdated;
int mlGlobalRenderCount;
int mlCount;
tString msSourceFile;
tEntityCallbackList mlstCallbacks;
tRenderContainerDataList mlstRenderContainerData;
tEntity3DList mlstChildren;
iEntity3D *mpParent;
cSector *mpCurrentSector;
int mlIteratorCount;
private:
void UpdateWorldTransform();
};
} // namespace hpl
#endif // HPL_ENTITY3D_H

View File

@@ -0,0 +1,502 @@
/* 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/GridMap2D.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/graphics/LowLevelGraphics.h"
#include "hpl1/engine/scene/Entity2D.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cGridMap2D::cGridMap2D(cVector2l avSize, cVector2l avGridSize, cVector2l avMaxGridSpan) {
mvSize = avSize;
mvGridSize = avGridSize;
mvMaxGridSpan = avMaxGridSpan;
mvGridNum = avSize / avGridSize + 1;
mlGlobalCount = 0;
mvGrids.resize(mvGridNum.x * mvGridNum.y);
for (int i = 0; i < (int)mvGrids.size(); i++)
mvGrids[i] = cGrid2D();
}
//-----------------------------------------------------------------------
cGridMap2D::~cGridMap2D() {
for (tGrid2DObjectMapIt it = m_mapAllObjects.begin(); it != m_mapAllObjects.end(); it++) {
it->second->Destroy();
hplDelete(it->second);
}
m_mapAllObjects.clear();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// GRIDMAP PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iGridMap2DIt *cGridMap2D::GetRectIterator(const cRect2f &aRect) {
cVector2l vPos = cVector2l((int)floor(aRect.x / (float)mvGridSize.x),
(int)floor(aRect.y / (float)mvGridSize.y));
cVector2l vSize = cVector2l((int)(aRect.w / (float)mvGridSize.x) + 1,
(int)(aRect.h / (float)mvGridSize.y) + 1);
// Check if we need yet another grid for x and y
if (aRect.x + aRect.w >= (vPos.x + vSize.x) * mvGridSize.x)
vSize.x++;
if (aRect.y + aRect.h >= (vPos.y + vSize.y) * mvGridSize.y)
vSize.y++;
// Log("\nPos: %d:%d\n",vPos.x,vPos.y);
// Log("Size: %d:%d\n\n",vSize.x,vSize.y);
return hplNew(cGridMap2DRectIt, (this, vPos, vSize));
}
//-----------------------------------------------------------------------
bool cGridMap2D::AddEntity(iEntity2D *apEntity) {
cGrid2DObject *pObject = hplNew(cGrid2DObject, (apEntity, this, mlHandleCount));
apEntity->SetGrid2DObject(pObject);
// Insert into the all map.
m_mapAllObjects.insert(tGrid2DObjectMap::value_type(mlHandleCount, pObject));
mlHandleCount++;
return true;
}
//-----------------------------------------------------------------------
bool cGridMap2D::RemoveEntity(iEntity2D *apEntity) {
cGrid2DObject *pObject = apEntity->GetGrid2DObject();
if (pObject == NULL)
return false;
pObject->Destroy();
m_mapAllObjects.erase(pObject->GetHandle());
hplDelete(pObject);
apEntity->SetGrid2DObject(NULL);
return true;
}
//-----------------------------------------------------------------------
cGrid2D *cGridMap2D::GetAt(int alX, int alY) {
if (alX >= mvGridNum.x || alX < 0 || alY >= mvGridNum.y || alY < 0)
return NULL;
return &mvGrids[alX + alY * mvGridNum.x];
}
//-----------------------------------------------------------------------
void cGridMap2D::DrawGrid(iLowLevelGraphics *apLowLevel, float afZ, cColor aCol) {
for (int x = 0; x < mvGridNum.x; x++)
for (int y = 0; y < mvGridNum.y; y++) {
apLowLevel->DrawLineRect2D(cRect2f((float)(x * mvGridSize.x), (float)(y * mvGridSize.y),
(float)(mvGridSize.x), (float)(mvGridSize.y)),
afZ, aCol);
}
}
//-----------------------------------------------------------------------
void cGridMap2D::DrawEntityGrids(iLowLevelGraphics *apLowLevel, cVector2f avWorldPos, float afZ, cColor aCol) {
tGrid2DObjectMapIt it = m_mapAllObjects.begin();
while (it != m_mapAllObjects.end()) {
iEntity2D *pEntity = it->second->GetEntity();
cRect2f Rect = pEntity->GetBoundingBox();
Rect.x -= avWorldPos.x;
Rect.y -= avWorldPos.y;
apLowLevel->DrawLineRect2D(Rect, afZ, aCol);
it++;
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// GRIDMAP PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cGridMap2DRectIt::cGridMap2DRectIt(cGridMap2D *apGridMap, cVector2l avPos, cVector2l avSize) {
mpGridMap = apGridMap;
mvPos = avPos;
mvSize = avSize;
mlType = 0;
mpObject = NULL;
mlGridNum = 0;
mlGridAdd = 0;
mlGridRowCount = 0;
mbUpdated = false;
// Increase the counter so you can load all objects.
mpGridMap->mlGlobalCount++;
mIt = mpGridMap->m_mapGlobalObjects.begin();
}
//-----------------------------------------------------------------------
bool cGridMap2DRectIt::HasNext() {
if (!mbUpdated) {
GetGridObject();
mbUpdated = true;
}
if (mpObject)
return true;
else
return false;
}
//-----------------------------------------------------------------------
iEntity2D *cGridMap2DRectIt::Next() {
iEntity2D *pEntity = NULL;
if (!mbUpdated) {
GetGridObject();
mbUpdated = true;
}
if (mpObject) {
pEntity = mpObject->GetEntity();
mIt++;
mbUpdated = false;
}
return pEntity;
}
//-----------------------------------------------------------------------
/////////////////////////// PRIVATE //////////////////////////////////////
//-----------------------------------------------------------------------
void cGridMap2DRectIt::GetGridObject() {
// bool bEnd = false;
switch (mlType) {
//// GLOBAL OBJECTS //////////////////
case 0: {
// No need to check if the GridObject has been used.
// All objects in globla only occur once
if (mIt == mpGridMap->m_mapGlobalObjects.end()) {
// Log("Reached end of global\n");
mlType = 1;
// Check if the coord is in an outer bound
if (mvPos.x < 0 || mvPos.y < 0 ||
mvPos.x + mvSize.x > mpGridMap->mvGridNum.x ||
mvPos.y + mvSize.y > mpGridMap->mvGridNum.y) {
// Log("Has outer!\n");
mIt = mpGridMap->m_mapOuterObjects.begin();
} else {
// Log("Has NO outer!\n");
mIt = mpGridMap->m_mapOuterObjects.end();
}
// FIXME: fallthrough intended from here?
// fallthrough
} else {
mpObject = mIt->second;
// Log("Found the object in global!\n");
break;
}
}
// FIXME: fallthrough intended?
// fallthrough
//// OUTER OBJECTS //////////////////
case 1: {
// No need to loop this one, since they only occur once and
// no other calls to the objects inside the grid has been made.
if (mIt == mpGridMap->m_mapOuterObjects.end()) {
// Log("End of outer!\n");
// Log("Pos: %d:%d\n",mvPos.x,mvPos.y);
// Log("Size: %d:%d\n",mvSize.x,mvSize.y);
// Log("----------\n");
mlType = 2;
// Check if the rect is outside of the grid map
// If so, we are done
if (mvPos.x >= mpGridMap->mvGridNum.x || mvPos.y >= mpGridMap->mvGridNum.y ||
mvPos.x + mvSize.x - 1 < 0 || mvPos.y + mvSize.y - 1 < 0) {
// Log("Outside Grid!\n");
mpObject = NULL;
mlType = -1;
break;
}
// Remove grids outside of the grid.
// Pos below (0,0):
if (mvPos.x < 0) {
mvSize.x += mvPos.x;
mvPos.x = 0;
}
if (mvPos.y < 0) {
mvSize.y += mvPos.y;
mvPos.y = 0;
}
// Size large than grid map
if (mvPos.x + mvSize.x > mpGridMap->mvGridNum.x) {
mvSize.x -= (mvPos.x + mvSize.x) - (mpGridMap->mvGridNum.x);
}
if (mvPos.y + mvSize.y > mpGridMap->mvGridNum.y) {
mvSize.y -= (mvPos.y + mvSize.y) - (mpGridMap->mvGridNum.y);
}
// Log("Pos: %d:%d\n",mvPos.x,mvPos.y);
// Log("Size: %d:%d\n",mvSize.x,mvSize.y);
// Calculate numbers needed to iterate the grid
mlGridNum = mvPos.x + mvPos.y * mpGridMap->mvGridNum.x;
mlGridAdd = mpGridMap->mvGridNum.x - mvSize.x;
mlGridRowCount = mvSize.y;
mlGridColCount = mvSize.x;
// Log("Num: %d Add: %d Row: %d Col: %d\n",mlGridNum,mlGridAdd,
// mlGridRowCount,mlGridColCount);
// Rect is outsize of map.
if (mvSize.x <= 0 || mvSize.y <= 0) {
mlGridNum = 0;
mIt = mpGridMap->mvGrids[mlGridNum].m_mapObjects.end();
mlGridColCount = 0;
mlGridRowCount = 0;
} else {
mIt = mpGridMap->mvGrids[mlGridNum].m_mapObjects.begin();
}
// FIXME: fallthrough intended from here?
// fallthrough
} else {
// Log("Found the object in outer!\n");
mpObject = mIt->second;
// Set that is object has been used.
mpObject->FirstTime(mpGridMap->mlGlobalCount);
break;
}
}
// FIXME: fallthrough intended?
// fallthrough
//// GRID OBJECTS //////////////////
case 2: {
// Search through the grids til one with GridObjects is found
// or we are at the end
while (true) {
if (mIt == mpGridMap->mvGrids[mlGridNum].m_mapObjects.end()) {
// Log("End of grid[%d] list!\n",mlGridNum);
mlGridNum++;
mlGridColCount--;
if (mlGridColCount <= 0) {
// Log("New row!\n\n");
mlGridColCount = mvSize.x;
mlGridRowCount--;
if (mlGridRowCount <= 0) {
mpObject = NULL;
break;
}
mlGridNum += mlGridAdd;
}
mIt = mpGridMap->mvGrids[mlGridNum].m_mapObjects.begin();
} else {
mpObject = mIt->second;
// Check if object already have been loaded.
if (mpObject->FirstTime(mpGridMap->mlGlobalCount)) {
// Log("Found the object in grid[%d]!\n",mlGridNum);
break;
} else {
// Log("Found OLD object in grid[%d]!\n",mlGridNum);
mIt++;
}
}
}
}
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// GRIDOBJECT PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cGrid2DObject::cGrid2DObject(iEntity2D *apEntity, cGridMap2D *apGridMap, unsigned int alHandle) {
mpEntity = apEntity;
mpGridMap = apGridMap;
mvGridParents.resize(mpGridMap->GetMaxArraySize());
for (int i = 0; i < (int)mvGridParents.size(); i++)
mvGridParents[i] = NULL;
mvPosition = cVector2l(-1000);
mvGridSpan = cVector2l(-1, -1);
mlHandle = alHandle;
mbIsInOuter = false;
mbIsInGLobal = false;
mlCount = 0;
mpEntity->UpdateBoundingBox();
Update(mpEntity->GetBoundingBox());
}
//-----------------------------------------------------------------------
void cGrid2DObject::Destroy() {
// Remove all old grids. This should only remove stuff that are necessary.
for (int x = 0; x < mvGridSpan.x; x++)
for (int y = 0; y < mvGridSpan.y; y++) {
int lNum = x + y * mpGridMap->GetMaxGridSpan().x;
if (mvGridParents[lNum]) {
mvGridParents[lNum]->Erase(mlHandle);
mvGridParents[lNum] = NULL;
}
}
if (mbIsInGLobal) {
mpGridMap->m_mapGlobalObjects.erase(mlHandle);
mbIsInGLobal = false;
} else if (mbIsInOuter) {
mpGridMap->m_mapOuterObjects.erase(mlHandle);
mbIsInOuter = false;
}
}
//-----------------------------------------------------------------------
/**
* \todo This function should be as optimized as possible.
* \param &aRect
*/
void cGrid2DObject::Update(const cRect2f &aRect) {
cVector2f vGSize((float)mpGridMap->GetGridSize().x, (float)mpGridMap->GetGridSize().y);
cVector2l vPos((int)floor(aRect.x / vGSize.x), (int)floor(aRect.y / vGSize.y));
// Calculate the num of extra grids in x,y direction that are needed.
cVector2l vGridSpan((int)(aRect.w / vGSize.x), (int)(aRect.h / vGSize.y));
vGridSpan += 1;
// Log("Rect: %f:%f:%f:%f\n",aRect.x,aRect.y,aRect.w,aRect.h);
// Log("GSize: %f:%f\n",vGSize.x,vGSize.y);
// Log("Pos: %d:%d\n",vPos.x,vPos.y);
// Test if the rect is to large or has negative size.
// If so put it in the global map.
// TODO: this is a long test and it would good to skip it for most stuff
// Fix that!
if (aRect.h < 0 || aRect.w < 0 || vGridSpan.x >= mpGridMap->GetMaxGridSpan().x ||
vGridSpan.y >= mpGridMap->GetMaxGridSpan().y) {
if (mbIsInGLobal == false) {
mbIsInGLobal = true;
// Erase old positions
for (int x = 0; x < mvGridSpan.x; x++)
for (int y = 0; y < mvGridSpan.y; y++) {
int lNum = x + y * mpGridMap->GetMaxGridSpan().x;
if (mvGridParents[lNum]) {
mvGridParents[lNum]->Erase(mlHandle);
mvGridParents[lNum] = NULL;
}
}
mpGridMap->m_mapGlobalObjects.insert(tGrid2DObjectMap::value_type(mlHandle, this));
// Log("Added to global\n");
}
return;
}
// The amount not covered in the span calc above
// Then check if this piece is out side of the last grid.
if (aRect.x + aRect.w >= (vPos.x + vGridSpan.x) * vGSize.x)
vGridSpan.x++;
if (aRect.y + aRect.h >= (vPos.y + vGridSpan.y) * vGSize.y)
vGridSpan.y++;
// Log("GridSpan: %d:%d\n",vGridSpan.x,vGridSpan.y);
if (vPos != mvPosition || vGridSpan != mvGridSpan) {
// Remove all old grids. This should only remove stuff that are necessary.
for (int x = 0; x < mvGridSpan.x; x++)
for (int y = 0; y < mvGridSpan.y; y++) {
int lNum = x + y * mpGridMap->GetMaxGridSpan().x;
if (mvGridParents[lNum] != NULL) {
mvGridParents[lNum]->Erase(mlHandle);
mvGridParents[lNum] = NULL;
}
}
if (mbIsInGLobal) {
mpGridMap->m_mapGlobalObjects.erase(mlHandle);
mbIsInGLobal = false;
} else if (mbIsInOuter) {
mpGridMap->m_mapOuterObjects.erase(mlHandle);
mbIsInOuter = false;
}
mvGridSpan = vGridSpan;
cGrid2D *pGrid = NULL;
for (int x = 0; x < mvGridSpan.x; x++)
for (int y = 0; y < mvGridSpan.y; y++) {
pGrid = mpGridMap->GetAt(vPos.x + x, vPos.y + y);
if (pGrid == NULL) {
if (!mbIsInOuter) {
mpGridMap->m_mapOuterObjects.insert(tGrid2DObjectMap::value_type(
mlHandle, this));
mbIsInOuter = true;
}
} else {
pGrid->Add(this);
mvGridParents[x + y * mpGridMap->GetMaxGridSpan().x] = pGrid;
}
}
}
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,202 @@
/* 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.
*/
#ifndef HPL_GRIDMAP2D_H
#define HPL_GRIDMAP2D_H
#include "common/array.h"
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/math/MathTypes.h"
#include "common/stablemap.h"
namespace hpl {
class iEntity2D;
class iLowLevelGraphics;
/////////// GRID OBJECT ////////////
class cGrid2D;
class cGridMap2D;
typedef Common::Array<cGrid2D *> tGrid2DPtrVec;
typedef tGrid2DPtrVec::iterator tGrid2DPtrVecIt;
class cGrid2DObject {
public:
cGrid2DObject(iEntity2D *apEntity, cGridMap2D *apGridMap, unsigned int alHandle);
void Update(const cRect2f &aRect);
void Destroy();
unsigned int GetHandle() { return mlHandle; }
iEntity2D *GetEntity() { return mpEntity; }
bool FirstTime(unsigned int alGlobalCount) {
if (alGlobalCount < mlCount)
return false;
mlCount = alGlobalCount + 1;
return true;
}
private:
cVector2l mvPosition;
cVector2f mvSize;
cVector2l mvGridSpan;
tGrid2DPtrVec mvGridParents;
iEntity2D *mpEntity;
cGridMap2D *mpGridMap;
bool mbIsInOuter;
bool mbIsInGLobal;
unsigned int mlCount;
int mlHandle;
};
/////////// GRID ////////////
typedef Common::StableMap<int, cGrid2DObject *> tGrid2DObjectMap;
typedef tGrid2DObjectMap::iterator tGrid2DObjectMapIt;
class cGrid2D {
friend class cGridMap2DRectIt;
public:
void Add(cGrid2DObject *pObject) {
m_mapObjects.insert(tGrid2DObjectMap::value_type(
pObject->GetHandle(), pObject));
}
void Erase(unsigned int alHandle) {
m_mapObjects.erase(alHandle);
}
private:
tGrid2DObjectMap m_mapObjects;
};
/////////// GRID MAP ITERATOR ////
class cGridMap2D;
class iGridMap2DIt {
public:
virtual ~iGridMap2DIt() = default;
virtual bool HasNext() = 0;
virtual iEntity2D *Next() = 0;
};
class cGridMap2DRectIt : public iGridMap2DIt {
public:
cGridMap2DRectIt(cGridMap2D *apGridMap, cVector2l avPos, cVector2l avSize);
virtual ~cGridMap2DRectIt() = default;
bool HasNext();
iEntity2D *Next();
private:
cGridMap2D *mpGridMap;
int mlType; // 0=global 1=outer 2=grids
tGrid2DObjectMapIt mIt;
cVector2l mvPos;
cVector2l mvSize;
int mlGridNum;
int mlGridAdd;
int mlGridRowCount;
int mlGridColCount;
bool mbUpdated;
cGrid2DObject *mpObject;
void GetGridObject();
};
/////////// GRID MAP ////////////
typedef Common::Array<cGrid2D> tGrid2DVec;
typedef tGrid2DVec::iterator tGrid2DVecIt;
class cGridMap2D {
friend class cGrid2DObject;
friend class cGridMap2DRectIt;
public:
cGridMap2D(cVector2l avSize, cVector2l avGridSize, cVector2l avMaxGridSpan);
~cGridMap2D();
iGridMap2DIt *GetRectIterator(const cRect2f &aRect);
cGrid2D *GetAt(int alX, int alY);
bool AddEntity(iEntity2D *apEntity);
bool RemoveEntity(iEntity2D *apEntity);
int GetMaxArraySize() { return mvMaxGridSpan.x * mvMaxGridSpan.y; }
const cVector2l &GetMaxGridSpan() { return mvMaxGridSpan; }
const cVector2l &GetGridSize() { return mvGridSize; }
const cVector2l &GetGridNum() { return mvGridNum; }
tGrid2DObjectMap *GetAllMap() { return &m_mapAllObjects; }
void DrawGrid(iLowLevelGraphics *apLowLevel, float afZ = 100, cColor aCol = cColor(1));
void DrawEntityGrids(iLowLevelGraphics *apLowLevel, cVector2f avWorldPos, float afZ = 101, cColor aCol = cColor(1, 0, 1, 1));
private:
// The Grids
tGrid2DVec mvGrids;
// all objects
// This is a list of all objects in the grid.
tGrid2DObjectMap m_mapAllObjects;
// Global Objects
// These are objects that affect the entire map
tGrid2DObjectMap m_mapGlobalObjects;
// Outer Objects
// These are objects outside the bounds of the grid
tGrid2DObjectMap m_mapOuterObjects;
// The count increases every time a fetch on the map is made.
// (all call to GetFirstEntity)
unsigned int mlGlobalCount;
unsigned int mlHandleCount;
cVector2l mvSize;
cVector2l mvGridNum;
cVector2l mvGridSize;
cVector2l mvMaxGridSpan;
};
} // namespace hpl
#endif // HPL_GRIDMAP2D_H

View 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

View File

@@ -0,0 +1,140 @@
/* 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.
*/
#ifndef HPL_IMAGE_ENTITY_H
#define HPL_IMAGE_ENTITY_H
#include "common/array.h"
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/scene/Entity2D.h"
class TiXmlElement;
namespace hpl {
class cResources;
class cGraphics;
class cImageEntityData;
class cImageAnimation;
class cImageEntity : public iEntity2D {
public:
cImageEntity(tString asName, cResources *apResources, cGraphics *apGraphics, bool abAutoDeleteData = true);
~cImageEntity();
const cRect2f &GetBoundingBox();
bool UpdateBoundingBox();
tString GetEntityType() { return "ImageEntity"; }
void Render();
void UpdateLogic(float afTimeStep);
bool LoadData(TiXmlElement *apRootElem);
bool LoadEntityData(tString asDataName, int alAnimNum = 0);
bool LoadEntityData(cImageEntityData *apData, int alAnimNum = 0);
cImageEntityData *GetEntityData() { return mpEntityData; }
///// Animation ////////////////////////
bool SetAnimation(const tString &asName, bool abLoop = true);
const tString &GetCurrentAnimation() const;
bool AnimationIsLooped() { return mbLoopAnimation; }
bool AnimationIsPlaying();
void StopAnimation();
void SetAnimationSpeed(float afSpeed) { mfAnimSpeed = afSpeed; }
float GetAnimationSpeed() { return mfAnimSpeed; }
void SetFrameNum(float afFrame) { mfFrameNum = afFrame; }
float GetFrameNum() { return mfFrameNum; }
int GetMaxFrameNum();
void SetAnimationPaused(bool abX) { mbAnimationPaused = abX; }
bool GetAnimationPaused() { return mbAnimationPaused; }
void SetFlipH(bool abX);
bool GetFlipH() { return mbFlipH; }
void SetFlipV(bool abX);
bool GetFlipV() { return mbFlipV; }
cVector2f GetSize() { return mvSize; }
void SetSize(const cVector2f &avSize);
void SetAlpha(float afX);
float GetAlpha() { return mfAlpha; }
void Flash(float afAdd);
bool IsCollidable() { return mbCollidable; }
private:
cResources *mpResources;
cGraphics *mpGraphics;
cImageEntityData *mpEntityData;
float mfAlpha;
float mfFlashAdd;
bool mbFlashing;
bool mbCollidable;
bool mbAutoDeleteData;
cVector2f mvSize;
bool mbFlipH;
bool mbFlipV;
bool mbRotationHasChanged;
bool mbSizeHasChanged;
float mfCurrentAngle;
cImageAnimation *mpAnimation;
float mfFrameNum;
float mfAnimSpeed;
int mlFrame;
int mlLastFrame;
bool mbAnimationPaused;
bool mbLoopAnimation;
tVertexVec mvBaseVtx;
tVertexVec mvVtx;
tUIntVec mvIdxVec;
cVector3f mvTransform;
tString msTempString;
};
typedef Common::Array<cImageEntity *> tImageEntityVec;
typedef tImageEntityVec::iterator tImageEntityVecIt;
} // namespace hpl
#endif // HPL_IMAGE_ENTITY_H

View File

@@ -0,0 +1,223 @@
/* 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/Light.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/system/low_level_system.h"
#include "hpl1/engine/scene/SoundEntity.h"
#include "hpl1/engine/scene/World3D.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iLight::iLight() : mDiffuseColor(0), mSpecularColor(0), mfIntensity(1),
mbCastShadows(false), mfFarAttenuation(0), mfNearAttenuation(0),
mfSourceRadius(10), mbAffectMaterial(true) {
mfFadeTime = 0;
mbFlickering = false;
mpWorld3D = NULL;
mfFlickerStateLength = 0;
mfFadeTime = 0;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void iLight::SetDiffuseColor(cColor aColor) {
mDiffuseColor = aColor;
OnSetDiffuse();
}
//-----------------------------------------------------------------------
void iLight::UpdateLight(float afTimeStep) {
/////////////////////////////////////////////
// Fade
if (mfFadeTime > 0) {
// Log("Fading: %f / %f\n",afTimeStep,mfFadeTime);
mfFarAttenuation += mfRadiusAdd * afTimeStep;
mDiffuseColor.r += mColAdd.r * afTimeStep;
mDiffuseColor.g += mColAdd.g * afTimeStep;
mDiffuseColor.b += mColAdd.b * afTimeStep;
mDiffuseColor.a += mColAdd.a * afTimeStep;
SetDiffuseColor(mDiffuseColor);
mfFadeTime -= afTimeStep;
// Set the dest values.
if (mfFadeTime <= 0) {
mfFadeTime = 0;
SetDiffuseColor(mDestCol);
mfFarAttenuation = mfDestRadius;
}
}
/////////////////////////////////////////////
// Flickering
if (mbFlickering && mfFadeTime <= 0) {
//////////////////////
// On
if (mbFlickerOn) {
if (mfFlickerTime >= mfFlickerStateLength) {
mbFlickerOn = false;
if (!mbFlickerFade) {
SetDiffuseColor(mFlickerOffColor);
mfFarAttenuation = mfFlickerOffRadius;
} else {
FadeTo(mFlickerOffColor, mfFlickerOffRadius, mfFlickerOffFadeLength);
}
// Sound
if (msFlickerOffSound != "") {
cSoundEntity *pSound = mpWorld3D->CreateSoundEntity("FlickerOff",
msFlickerOffSound, true);
if (pSound)
pSound->SetPosition(GetLightPosition());
}
OnFlickerOff();
mfFlickerTime = 0;
mfFlickerStateLength = cMath::RandRectf(mfFlickerOffMinLength, mfFlickerOffMaxLength);
}
}
//////////////////////
// Off
else {
if (mfFlickerTime >= mfFlickerStateLength) {
mbFlickerOn = true;
if (!mbFlickerFade) {
SetDiffuseColor(mFlickerOnColor);
mfFarAttenuation = mfFlickerOnRadius;
} else {
FadeTo(mFlickerOnColor, mfFlickerOnRadius, mfFlickerOnFadeLength);
}
if (msFlickerOnSound != "") {
cSoundEntity *pSound = mpWorld3D->CreateSoundEntity("FlickerOn",
msFlickerOnSound, true);
if (pSound)
pSound->SetPosition(GetLightPosition());
}
OnFlickerOn();
mfFlickerTime = 0;
mfFlickerStateLength = cMath::RandRectf(mfFlickerOnMinLength, mfFlickerOnMaxLength);
}
}
mfFlickerTime += afTimeStep;
}
/*Log("Time: %f Length: %f FadeTime: %f Color: (%f %f %f %f)\n",mfFlickerTime, mfFlickerStateLength,
mfFadeTime,
mDiffuseColor.r,mDiffuseColor.g,
mDiffuseColor.b,mDiffuseColor.a);*/
}
//-----------------------------------------------------------------------
void iLight::FadeTo(const cColor &aCol, float afRadius, float afTime) {
if (afTime <= 0)
afTime = 0.0001f;
mfFadeTime = afTime;
mColAdd.r = (aCol.r - mDiffuseColor.r) / afTime;
mColAdd.g = (aCol.g - mDiffuseColor.g) / afTime;
mColAdd.b = (aCol.b - mDiffuseColor.b) / afTime;
mColAdd.a = (aCol.a - mDiffuseColor.a) / afTime;
mfRadiusAdd = (afRadius - mfFarAttenuation) / afTime;
mfDestRadius = afRadius;
mDestCol = aCol;
}
bool iLight::IsFading() {
return mfFadeTime != 0;
}
//-----------------------------------------------------------------------
void iLight::SetFlickerActive(bool abX) {
mbFlickering = abX;
}
void iLight::SetFlicker(const cColor &aOffCol, float afOffRadius,
float afOnMinLength, float afOnMaxLength, const tString &asOnSound, const tString &asOnPS,
float afOffMinLength, float afOffMaxLength, const tString &asOffSound, const tString &asOffPS,
bool abFade, float afOnFadeLength, float afOffFadeLength) {
mFlickerOffColor = aOffCol;
mfFlickerOffRadius = afOffRadius;
mfFlickerOnMinLength = afOnMinLength;
mfFlickerOnMaxLength = afOnMaxLength;
msFlickerOnSound = asOnSound;
msFlickerOnPS = asOnPS;
mfFlickerOffMinLength = afOffMinLength;
mfFlickerOffMaxLength = afOffMaxLength;
msFlickerOffSound = asOffSound;
msFlickerOffPS = asOffPS;
mbFlickerFade = abFade;
mfFlickerOnFadeLength = afOnFadeLength;
mfFlickerOffFadeLength = afOffFadeLength;
mFlickerOnColor = mDiffuseColor;
mfFlickerOnRadius = mfFarAttenuation;
mbFlickerOn = true;
mfFlickerTime = 0;
mfFadeTime = 0;
mfFlickerStateLength = cMath::RandRectf(mfFlickerOnMinLength, mfFlickerOnMaxLength);
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,159 @@
/* 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.
*/
#ifndef HPL_LIGHT_H
#define HPL_LIGHT_H
#include "hpl1/engine/graphics/GraphicsTypes.h"
namespace hpl {
class iLowLevelGraphics;
class cWorld3D;
class iLight {
public:
iLight();
virtual ~iLight() = default;
//////////////////////////
// Fading
void FadeTo(const cColor &aCol, float afRadius, float afTime);
bool IsFading();
cColor GetDestColor() { return mDestCol; }
float GetDestRadius() { return mfDestRadius; }
//////////////////////////
// FLickering
void SetFlickerActive(bool abX);
bool GetFlickerActive() { return mbFlickering; }
void SetFlicker(const cColor &aOffCol, float afOffRadius,
float afOnMinLength, float afOnMaxLength, const tString &asOnSound, const tString &asOnPS,
float afOffMinLength, float afOffMaxLength, const tString &asOffSound, const tString &asOffPS,
bool abFade, float afOnFadeLength, float afOffFadeLength);
tString GetFlickerOffSound() { return msFlickerOffSound; }
tString GetFlickerOnSound() { return msFlickerOnSound; }
tString GetFlickerOffPS() { return msFlickerOffPS; }
tString GetFlickerOnPS() { return msFlickerOnPS; }
float GetFlickerOnMinLength() { return mfFlickerOnMinLength; }
float GetFlickerOffMinLength() { return mfFlickerOffMinLength; }
float GetFlickerOnMaxLength() { return mfFlickerOnMaxLength; }
float GetFlickerOffMaxLength() { return mfFlickerOffMaxLength; }
cColor GetFlickerOffColor() { return mFlickerOffColor; }
float GetFlickerOffRadius() { return mfFlickerOffRadius; }
bool GetFlickerFade() { return mbFlickerFade; }
float GetFlickerOnFadeLength() { return mfFlickerOnFadeLength; }
float GetFlickerOffFadeLength() { return mfFlickerOffFadeLength; }
cColor GetFlickerOnColor() { return mFlickerOnColor; }
float GetFlickerOnRadius() { return mfFlickerOnRadius; }
//////////////////////////
// Properties
const cColor &GetDiffuseColor() { return mDiffuseColor; }
void SetDiffuseColor(cColor aColor);
const cColor &GetSpecularColor() { return mSpecularColor; }
void SetSpecularColor(cColor aColor) { mSpecularColor = aColor; }
float GetIntensity() { return mfIntensity; }
void SetIntensity(float afX) { mfIntensity = afX; }
bool GetCastShadows() { return mbCastShadows; }
void SetCastShadows(bool afX) { mbCastShadows = afX; }
bool GetAffectMaterial() { return mbAffectMaterial; }
void SetAffectMaterial(bool afX) { mbAffectMaterial = afX; }
float GetFarAttenuation() { return mfFarAttenuation; }
float GetNearAttenuation() { return mfNearAttenuation; }
virtual void SetFarAttenuation(float afX) = 0;
virtual void SetNearAttenuation(float afX) = 0;
float GetSourceRadius() { return mfSourceRadius; }
void SetSourceRadius(float afX) { mfSourceRadius = afX; }
virtual cVector3f GetLightPosition() = 0;
void UpdateLight(float afTimeStep);
void SetWorld3D(cWorld3D *apWorld) { mpWorld3D = apWorld; }
protected:
virtual void OnFlickerOff() {}
virtual void OnFlickerOn() {}
virtual void OnSetDiffuse() {}
cColor mDiffuseColor;
cColor mSpecularColor;
float mfIntensity;
float mfFarAttenuation;
float mfNearAttenuation;
float mfSourceRadius;
bool mbCastShadows;
bool mbAffectMaterial;
cWorld3D *mpWorld3D;
///////////////////////////
// Fading.
cColor mColAdd;
float mfRadiusAdd;
cColor mDestCol;
float mfDestRadius;
float mfFadeTime;
///////////////////////////
// Flicker
bool mbFlickering;
tString msFlickerOffSound;
tString msFlickerOnSound;
tString msFlickerOffPS;
tString msFlickerOnPS;
float mfFlickerOnMinLength;
float mfFlickerOffMinLength;
float mfFlickerOnMaxLength;
float mfFlickerOffMaxLength;
cColor mFlickerOffColor;
float mfFlickerOffRadius;
bool mbFlickerFade;
float mfFlickerOnFadeLength;
float mfFlickerOffFadeLength;
cColor mFlickerOnColor;
float mfFlickerOnRadius;
bool mbFlickerOn;
float mfFlickerTime;
float mfFlickerStateLength;
};
} // namespace hpl
#endif // HPL_LIGHT_H

View File

@@ -0,0 +1,83 @@
/* 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/Light2D.h"
#include "hpl1/engine/graphics/LowLevelGraphics.h"
#include "hpl1/engine/scene/GridMap2D.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iLight2D::iLight2D(tString asName) : iEntity2D(asName), iLight() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void iLight2D::SetFarAttenuation(float afX) {
mfFarAttenuation = afX;
if (UpdateBoundingBox())
if (mpGridObject)
mpGridObject->Update(GetBoundingBox());
}
//-----------------------------------------------------------------------
void iLight2D::SetNearAttenuation(float afX) {
mfNearAttenuation = afX;
if (mfNearAttenuation > mfFarAttenuation)
SetFarAttenuation(mfNearAttenuation);
}
//-----------------------------------------------------------------------
cVector3f iLight2D::GetLightPosition() {
return GetWorldPosition();
}
//-----------------------------------------------------------------------
void iLight2D::UpdateLogic(float afTimeStep) {
UpdateLight(afTimeStep);
if (mfFadeTime > 0) {
if (UpdateBoundingBox())
mpGridObject->Update(mBoundingBox);
}
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,64 @@
/* 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.
*/
#ifndef HPL_LIGHT2D_H
#define HPL_LIGHT2D_H
#include "common/list.h"
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/scene/Entity2D.h"
#include "hpl1/engine/scene/Light.h"
namespace hpl {
class iLowLevelGraphics;
class iLight2D : public iEntity2D, public iLight {
public:
iLight2D(tString asName);
virtual ~iLight2D() {}
tString GetEntityType() { return "iLight2D"; }
void UpdateLogic(float afTimeStep);
void SetFarAttenuation(float afX);
void SetNearAttenuation(float afX);
cVector3f GetLightPosition();
virtual int Render(iLowLevelGraphics *apLowLevel, int alFirstIndex) = 0;
protected:
};
typedef Common::List<iLight2D *> tLightList;
typedef tLightList::iterator tLightListIt;
} // namespace hpl
#endif // HPL_LIGHT2D_H

View File

@@ -0,0 +1,109 @@
/* 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/Light2DPoint.h"
#include "hpl1/engine/graphics/LowLevelGraphics.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cLight2DPoint::cLight2DPoint(tString asName) : iLight2D(asName) {
UpdateBoundingBox();
}
//-----------------------------------------------------------------------
cLight2DPoint::~cLight2DPoint() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
// TODO: Z might have to be some standard value...
// Has 100 right now, this should be in some global value..
int cLight2DPoint::Render(iLowLevelGraphics *apLowLevel, int alFirstIndex) {
// make the center vetrex:
cVector3f vTex(0);
cVector3f vPos;
cVector3f vLightPos = GetWorldPosition();
vLightPos.z = 100;
float fRadius = GetFarAttenuation();
cColor Col = GetDiffuseColor() * mfIntensity;
Col.a = 0;
cVertex Vtx = cVertex(vLightPos, vTex, Col);
apLowLevel->AddVertexToBatch(Vtx); // index 0!
Col = cColor(0, 0);
int idx = alFirstIndex + 1;
for (float fAngle = 0; fAngle <= k2Pif; fAngle += k2Pif / 32) {
vPos.x = vLightPos.x + fRadius * cos(fAngle); //*0.5;
vPos.y = vLightPos.y + fRadius * sin(fAngle); //*0.5;
vPos.z = 100;
Vtx = cVertex(vPos, vTex, Col);
apLowLevel->AddVertexToBatch(Vtx);
if (idx > 0) {
apLowLevel->AddIndexToBatch(alFirstIndex); // The center
apLowLevel->AddIndexToBatch(idx); // The current point
apLowLevel->AddIndexToBatch(idx - 1); // The previous point
}
idx++;
}
apLowLevel->AddIndexToBatch(alFirstIndex); // The center
apLowLevel->AddIndexToBatch(alFirstIndex + 1); // The current point
apLowLevel->AddIndexToBatch(idx - 1); // The previous point
return idx;
}
//-----------------------------------------------------------------------
const cRect2f &cLight2DPoint::GetBoundingBox() {
return mBoundingBox;
}
//-----------------------------------------------------------------------
bool cLight2DPoint::UpdateBoundingBox() {
mBoundingBox = cRect2f(cVector2f(GetWorldPosition().x, GetWorldPosition().y) - mfFarAttenuation,
cVector2f(mfFarAttenuation * 2));
return true;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,48 @@
/* 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.
*/
#ifndef HPL_LIGHTPOINT2D_H
#define HPL_LIGHTPOINT2D_H
#include "hpl1/engine/scene/Light2D.h"
namespace hpl {
class cLight2DPoint : public iLight2D {
public:
cLight2DPoint(tString asName);
~cLight2DPoint();
const cRect2f &GetBoundingBox();
bool UpdateBoundingBox();
int Render(iLowLevelGraphics *apLowLevel, int alFirstIndex);
};
} // namespace hpl
#endif // HPL_LIGHTPOINT2D_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,228 @@
/* 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.
*/
#ifndef HPL_LIGHT3D_H
#define HPL_LIGHT3D_H
#include "common/list.h"
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/graphics/Renderable.h"
#include "hpl1/engine/scene/Entity3D.h"
#include "hpl1/engine/scene/Light.h"
#include "hpl1/std/set.h"
class TiXmlElement;
namespace hpl {
enum eLight3DType {
eLight3DType_Point,
eLight3DType_Spot,
eLight3DType_LastEnum
};
enum eShadowVolumeType {
eShadowVolumeType_None,
eShadowVolumeType_ZPass,
eShadowVolumeType_ZFail,
eShadowVolumeType_LastEnum,
};
class iLowLevelGraphics;
class cRenderSettings;
class cCamera3D;
class cFrustum;
class iGpuProgram;
class iTexture;
class cTextureManager;
class cResources;
class cFileSearcher;
class cBillboard;
class cSectorVisibilityContainer;
typedef Hpl1::Std::set<iRenderable *> tCasterCacheSet;
typedef tCasterCacheSet::iterator tCasterCacheSetIt;
//------------------------------------------
kSaveData_ChildClass(iRenderable, iLight3D) {
kSaveData_ClassInit(iLight3D) public : tString msFalloffMap;
cContainerList<int> mlstBillboardIds;
cColor mDiffuseColor;
cColor mSpecularColor;
float mfIntensity;
float mfFarAttenuation;
float mfNearAttenuation;
float mfSourceRadius;
bool mbCastShadows;
bool mbAffectMaterial;
cColor mColAdd;
float mfRadiusAdd;
cColor mDestCol;
float mfDestRadius;
float mfFadeTime;
bool mbFlickering;
tString msFlickerOffSound;
tString msFlickerOnSound;
tString msFlickerOffPS;
tString msFlickerOnPS;
float mfFlickerOnMinLength;
float mfFlickerOffMinLength;
float mfFlickerOnMaxLength;
float mfFlickerOffMaxLength;
cColor mFlickerOffColor;
float mfFlickerOffRadius;
bool mbFlickerFade;
float mfFlickerOnFadeLength;
float mfFlickerOffFadeLength;
cColor mFlickerOnColor;
float mfFlickerOnRadius;
bool mbFlickerOn;
float mfFlickerTime;
float mfFlickerStateLength;
};
//------------------------------------------
class iLight3D : public iLight, public iRenderable {
typedef iRenderable super;
public:
iLight3D(tString asName, cResources *apResources);
virtual ~iLight3D();
void UpdateLogic(float afTimeStep);
virtual void SetFarAttenuation(float afX);
virtual void SetNearAttenuation(float afX);
cVector3f GetLightPosition();
virtual bool BeginDraw(cRenderSettings *apRenderSettings, iLowLevelGraphics *apLowLevelGraphics);
virtual void EndDraw(cRenderSettings *apRenderSettings, iLowLevelGraphics *apLowLevelGraphics);
bool CheckObjectIntersection(iRenderable *apObject);
void AddShadowCaster(iRenderable *apObject, cFrustum *apFrustum, bool abStatic, cRenderList *apRenderList);
bool HasStaticCasters();
void ClearCasters(bool abClearStatic);
void SetAllStaticCastersAdded(bool abX) { mbStaticCasterAdded = abX; }
bool AllStaticCastersAdded() { return mbStaticCasterAdded; }
eLight3DType GetLightType() { return mLightType; }
// iEntity implementation
tString GetEntityType() { return "iLight3D"; }
bool IsVisible();
void SetVisible(bool abVisible);
iTexture *GetFalloffMap();
void SetFalloffMap(iTexture *apTexture);
// Renderable implementation:
iMaterial *GetMaterial() { return NULL; }
iVertexBuffer *GetVertexBuffer() { return NULL; }
bool IsShadowCaster() { return false; }
eRenderableType GetRenderType() { return eRenderableType_Light; }
cBoundingVolume *GetBoundingVolume();
int GetMatrixUpdateCount() { return GetTransformUpdateCount(); }
cMatrixf *GetModelMatrix(cCamera3D *apCamera);
inline void RenderShadow(iRenderable *apObject, cRenderSettings *apRenderSettings, iLowLevelGraphics *apLowLevelGraphics);
void LoadXMLProperties(const tString asFile);
void AttachBillboard(cBillboard *apBillboard);
void RemoveBillboard(cBillboard *apBillboard);
Common::Array<cBillboard *> *GetBillboardVec() { return &mvBillboards; }
inline iTexture *GetTempTexture(size_t alIdx) { return mvTempTextures[alIdx]; }
inline void SetTempTexture(size_t alIdx, iTexture *apTex) { mvTempTextures[alIdx] = apTex; }
void SetOnlyAffectInSector(bool abX) { mbOnlyAffectInInSector = abX; }
bool GetOnlyAffectInSector() { return mbOnlyAffectInInSector; }
// SaveObject implementation
virtual iSaveData *CreateSaveData();
virtual void SaveToSaveData(iSaveData *apSaveData);
virtual void LoadFromSaveData(iSaveData *apSaveData);
virtual void SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
protected:
void OnFlickerOff();
void OnFlickerOn();
void OnSetDiffuse();
virtual cSectorVisibilityContainer *CreateSectorVisibility() = 0;
virtual void ExtraXMLProperties(TiXmlElement *apMainElem) {}
virtual void UpdateBoundingVolume() = 0;
virtual bool CreateClipRect(cRect2l &aCliprect, cRenderSettings *apRenderSettings, iLowLevelGraphics *apLowLevelGraphics) = 0;
eLight3DType mLightType;
cTextureManager *mpTextureManager;
cFileSearcher *mpFileSearcher;
iTexture *mpFalloffMap;
iTexture *mvTempTextures[3];
Common::Array<cBillboard *> mvBillboards;
cMatrixf mtxTemp;
tCasterCacheSet m_setStaticCasters;
tCasterCacheSet m_setDynamicCasters;
bool mbStaticCasterAdded;
bool mbOnlyAffectInInSector;
int mlSectorVisibilityCount;
cSectorVisibilityContainer *mpVisSectorCont;
unsigned int *mpIndexArray;
};
typedef Common::List<iLight3D *> tLight3DList;
typedef tLight3DList::iterator tLight3DListIt;
} // namespace hpl
#endif // HPL_LIGHT3D_H

View File

@@ -0,0 +1,138 @@
/* 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/Light3DPoint.h"
#include "hpl1/engine/graphics/LowLevelGraphics.h"
#include "hpl1/engine/graphics/Renderer3D.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/scene/Camera3D.h"
#include "hpl1/engine/game/Game.h"
#include "hpl1/engine/scene/Scene.h"
#include "hpl1/engine/scene/World3D.h"
#include "hpl1/engine/scene/PortalContainer.h"
#include "hpl1/engine/scene/SectorVisibility.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cLight3DPoint::cLight3DPoint(tString asName, cResources *apResources) : iLight3D(asName, apResources) {
mLightType = eLight3DType_Point;
UpdateBoundingVolume();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSectorVisibilityContainer *cLight3DPoint::CreateSectorVisibility() {
return mpWorld3D->GetPortalContainer()->CreateVisibiltyFromBV(GetBoundingVolume());
}
//-----------------------------------------------------------------------
void cLight3DPoint::UpdateBoundingVolume() {
mBoundingVolume.SetSize(mfFarAttenuation * 2);
mBoundingVolume.SetPosition(GetWorldPosition());
}
//-----------------------------------------------------------------------
bool cLight3DPoint::CreateClipRect(cRect2l &aClipRect, cRenderSettings *apRenderSettings,
iLowLevelGraphics *apLowLevelGraphics) {
cVector2f vScreenSize = apLowLevelGraphics->GetScreenSize();
bool bVisible = cMath::GetClipRectFromBV(aClipRect, *GetBoundingVolume(),
apRenderSettings->mpCamera->GetViewMatrix(),
apRenderSettings->mpCamera->GetProjectionMatrix(),
apRenderSettings->mpCamera->GetNearClipPlane(),
cVector2l((int)vScreenSize.x, (int)vScreenSize.y));
return bVisible;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SAVE OBJECT STUFF
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
kBeginSerialize(cSaveData_cLight3DPoint, cSaveData_iLight3D)
kEndSerialize()
//-----------------------------------------------------------------------
iSaveObject *cSaveData_cLight3DPoint::CreateSaveObject(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
cWorld3D *pWorld = apGame->GetScene()->GetWorld3D();
return pWorld->CreateLightPoint(msName);
}
//-----------------------------------------------------------------------
int cSaveData_cLight3DPoint::GetSaveCreatePrio() {
return 3;
}
//-----------------------------------------------------------------------
iSaveData *cLight3DPoint::CreateSaveData() {
return hplNew(cSaveData_cLight3DPoint, ());
}
//-----------------------------------------------------------------------
void cLight3DPoint::SaveToSaveData(iSaveData *apSaveData) {
kSaveData_SaveToBegin(cLight3DPoint);
}
//-----------------------------------------------------------------------
void cLight3DPoint::LoadFromSaveData(iSaveData *apSaveData) {
kSaveData_LoadFromBegin(cLight3DPoint);
}
//-----------------------------------------------------------------------
void cLight3DPoint::SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
kSaveData_SetupBegin(cLight3DPoint);
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,67 @@
/* 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.
*/
#ifndef HPL_LIGHT3D_POINT_H
#define HPL_LIGHT3D_POINT_H
#include "hpl1/engine/scene/Light3D.h"
namespace hpl {
//------------------------------------------
kSaveData_ChildClass(iLight3D, cLight3DPoint) {
kSaveData_ClassInit(cLight3DPoint) public :
virtual iSaveObject *CreateSaveObject(cSaveObjectHandler * apSaveObjectHandler, cGame * apGame);
virtual int GetSaveCreatePrio();
};
//------------------------------------------
class cLight3DPoint : public iLight3D {
typedef iLight3D super;
public:
cLight3DPoint(tString asName, cResources *apResources);
virtual ~cLight3DPoint() = default;
// SaveObject implementation
virtual iSaveData *CreateSaveData();
virtual void SaveToSaveData(iSaveData *apSaveData);
virtual void LoadFromSaveData(iSaveData *apSaveData);
virtual void SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
private:
cSectorVisibilityContainer *CreateSectorVisibility();
void UpdateBoundingVolume();
bool CreateClipRect(cRect2l &aCliprect, cRenderSettings *apRenderSettings, iLowLevelGraphics *apLowLevelGraphics);
};
} // namespace hpl
#endif // HPL_LIGHT3D_POINT_H

View File

@@ -0,0 +1,365 @@
/* 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/Light3DSpot.h"
#include "hpl1/engine/graphics/LowLevelGraphics.h"
#include "hpl1/engine/graphics/Renderer3D.h"
#include "hpl1/engine/impl/tinyXML/tinyxml.h"
#include "hpl1/engine/math/Frustum.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/resources/Resources.h"
#include "hpl1/engine/resources/TextureManager.h"
#include "hpl1/engine/scene/Camera3D.h"
#include "hpl1/engine/game/Game.h"
#include "hpl1/engine/scene/Scene.h"
#include "hpl1/engine/scene/World3D.h"
#include "hpl1/engine/scene/PortalContainer.h"
#include "hpl1/engine/scene/SectorVisibility.h"
namespace hpl {
static constexpr cMatrixf g_mtxTextureUnitFix(0.5f, 0, 0, 0.5f,
0, -0.5f, 0, 0.5f,
0, 0, 0.5f, 0.5f,
0, 0, 0, 1.0f);
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cLight3DSpot::cLight3DSpot(tString asName, cResources *apResources) : iLight3D(asName, apResources) {
mbProjectionUpdated = true;
mbViewProjUpdated = true;
mbFrustumUpdated = true;
mLightType = eLight3DType_Spot;
mpFrustum = hplNew(cFrustum, ());
mlViewProjMatrixCount = -1;
mlViewMatrixCount = -1;
mlFrustumMatrixCount = -1;
mpTexture = NULL;
mfFOV = cMath::ToRad(60.0f);
mfAspect = 1.0f;
mfFarAttenuation = 100.0f;
mfNearClipPlane = 0.1f;
m_mtxView = cMatrixf::Identity;
m_mtxViewProj = cMatrixf::Identity;
m_mtxProjection = cMatrixf::Identity;
UpdateBoundingVolume();
}
cLight3DSpot::~cLight3DSpot() {
if (mpTexture)
mpTextureManager->Destroy(mpTexture);
hplDelete(mpFrustum);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cLight3DSpot::SetTexture(iTexture *apTexture) {
// Destroy any old texture.
if (mpTexture)
mpTextureManager->Destroy(mpTexture);
mpTexture = apTexture;
mpTexture->SetWrapS(eTextureWrap_ClampToBorder);
mpTexture->SetWrapT(eTextureWrap_ClampToBorder);
}
//-----------------------------------------------------------------------
iTexture *cLight3DSpot::GetTexture() {
return mpTexture;
}
//-----------------------------------------------------------------------
void cLight3DSpot::SetFarAttenuation(float afX) {
mfFarAttenuation = afX;
UpdateBoundingVolume();
// This is so that the render container is updated.
SetTransformUpdated();
mbProjectionUpdated = true;
}
//-----------------------------------------------------------------------
void cLight3DSpot::SetNearAttenuation(float afX) {
mfNearAttenuation = afX;
if (mfNearAttenuation > mfFarAttenuation)
SetFarAttenuation(mfNearAttenuation);
}
//-----------------------------------------------------------------------
const cMatrixf &cLight3DSpot::GetViewMatrix() {
if (mlViewMatrixCount != GetTransformUpdateCount()) {
mlViewMatrixCount = GetTransformUpdateCount();
m_mtxView = cMath::MatrixInverse(GetWorldMatrix());
}
return m_mtxView;
}
//-----------------------------------------------------------------------
const cMatrixf &cLight3DSpot::GetProjectionMatrix() {
if (mbProjectionUpdated) {
float fFar = mfFarAttenuation;
float fNear = mfNearClipPlane;
float fTop = tan(mfFOV * 0.5f) * fNear;
float fBottom = -fTop;
float fRight = mfAspect * fTop;
float fLeft = mfAspect * fBottom;
float A = (2.0f * fNear) / (fRight - fLeft);
float B = (2.0f * fNear) / (fTop - fBottom);
float D = -1.0f;
float C = -(2.0f * fFar * fNear) / (fFar - fNear);
float Z = -(fFar + fNear) / (fFar - fNear);
float X = 0;
float Y = 0;
m_mtxProjection = cMatrixf(
A, 0, X, 0,
0, B, Y, 0,
0, 0, Z, C,
0, 0, D, 0);
mbProjectionUpdated = false;
mbViewProjUpdated = true;
mbFrustumUpdated = true;
}
return m_mtxProjection;
}
//-----------------------------------------------------------------------
const cMatrixf &cLight3DSpot::GetViewProjMatrix() {
if (mlViewProjMatrixCount != GetTransformUpdateCount() || mbViewProjUpdated || mbProjectionUpdated) {
m_mtxViewProj = cMath::MatrixMul(GetProjectionMatrix(), GetViewMatrix());
m_mtxViewProj = cMath::MatrixMul(g_mtxTextureUnitFix, m_mtxViewProj);
mlViewProjMatrixCount = GetTransformUpdateCount();
mbViewProjUpdated = false;
}
return m_mtxViewProj;
}
//-----------------------------------------------------------------------
cFrustum *cLight3DSpot::GetFrustum() {
if (mlFrustumMatrixCount != GetTransformUpdateCount() || mbFrustumUpdated || mbProjectionUpdated) {
mpFrustum->SetViewProjMatrix(GetProjectionMatrix(),
GetViewMatrix(),
mfFarAttenuation, mfNearClipPlane,
mfFOV, mfAspect, GetWorldPosition(), false);
mbFrustumUpdated = false;
mlFrustumMatrixCount = GetTransformUpdateCount();
}
return mpFrustum;
}
//-----------------------------------------------------------------------
bool cLight3DSpot::CollidesWithBV(cBoundingVolume *apBV) {
if (cMath::CheckCollisionBV(*GetBoundingVolume(), *apBV) == false)
return false;
return GetFrustum()->CollideBoundingVolume(apBV) != eFrustumCollision_Outside;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSectorVisibilityContainer *cLight3DSpot::CreateSectorVisibility() {
return mpWorld3D->GetPortalContainer()->CreateVisibiltyFromFrustum(mpFrustum);
}
//-----------------------------------------------------------------------
static eTextureAnimMode GetAnimMode(const tString &asType) {
if (cString::ToLowerCase(asType) == "none")
return eTextureAnimMode_None;
else if (cString::ToLowerCase(asType) == "loop")
return eTextureAnimMode_Loop;
else if (cString::ToLowerCase(asType) == "oscillate")
return eTextureAnimMode_Oscillate;
return eTextureAnimMode_None;
}
void cLight3DSpot::ExtraXMLProperties(TiXmlElement *apMainElem) {
tString sTexture = cString::ToString(apMainElem->Attribute("ProjectionImage"), "");
eTextureAnimMode animMode = GetAnimMode(cString::ToString(apMainElem->Attribute("ProjectionAnimMode"), "None"));
float fFrameTime = cString::ToFloat(apMainElem->Attribute("ProjectionFrameTime"), 1.0f);
iTexture *pTex = NULL;
if (animMode != eTextureAnimMode_None) {
pTex = mpTextureManager->CreateAnim2D(sTexture, true);
pTex->SetAnimMode(animMode);
pTex->SetFrameTime(fFrameTime);
} else {
pTex = mpTextureManager->Create2D(sTexture, true);
}
if (pTex) {
SetTexture(pTex);
}
mfAspect = cString::ToFloat(apMainElem->Attribute("Aspect"), mfAspect);
mfNearClipPlane = cString::ToFloat(apMainElem->Attribute("NearClipPlane"), mfNearClipPlane);
}
//-----------------------------------------------------------------------
void cLight3DSpot::UpdateBoundingVolume() {
mBoundingVolume = GetFrustum()->GetBoundingVolume();
}
//-----------------------------------------------------------------------
bool cLight3DSpot::CreateClipRect(cRect2l &aClipRect, cRenderSettings *apRenderSettings,
iLowLevelGraphics *apLowLevelGraphics) {
cVector2f vScreenSize = apLowLevelGraphics->GetScreenSize();
bool bVisible = cMath::GetClipRectFromBV(aClipRect, *GetBoundingVolume(),
apRenderSettings->mpCamera->GetViewMatrix(),
apRenderSettings->mpCamera->GetProjectionMatrix(),
apRenderSettings->mpCamera->GetNearClipPlane(),
cVector2l((int)vScreenSize.x, (int)vScreenSize.y));
return bVisible;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SAVE OBJECT STUFF
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
kBeginSerialize(cSaveData_cLight3DSpot, cSaveData_iLight3D)
kSerializeVar(msTexture, eSerializeType_String)
kSerializeVar(mfFOV, eSerializeType_Float32)
kSerializeVar(mfAspect, eSerializeType_Float32)
kSerializeVar(mfNearClipPlane, eSerializeType_Float32)
kEndSerialize()
//-----------------------------------------------------------------------
iSaveObject *cSaveData_cLight3DSpot::CreateSaveObject(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
cWorld3D *pWorld = apGame->GetScene()->GetWorld3D();
cResources *pResources = apGame->GetResources();
cLight3DSpot *pLight = pWorld->CreateLightSpot(msName);
if (pLight && msTexture != "") {
iTexture *pTex = pResources->GetTextureManager()->Create2D(msTexture, false);
if (pTex)
pLight->SetTexture(pTex);
}
return pLight;
}
//-----------------------------------------------------------------------
int cSaveData_cLight3DSpot::GetSaveCreatePrio() {
return 3;
}
//-----------------------------------------------------------------------
iSaveData *cLight3DSpot::CreateSaveData() {
return hplNew(cSaveData_cLight3DSpot, ());
}
//-----------------------------------------------------------------------
void cLight3DSpot::SaveToSaveData(iSaveData *apSaveData) {
kSaveData_SaveToBegin(cLight3DSpot);
pData->msTexture = mpTexture == NULL ? "" : mpTexture->GetName();
kSaveData_SaveTo(mfFOV);
kSaveData_SaveTo(mfAspect);
kSaveData_SaveTo(mfNearClipPlane);
}
//-----------------------------------------------------------------------
void cLight3DSpot::LoadFromSaveData(iSaveData *apSaveData) {
kSaveData_LoadFromBegin(cLight3DSpot);
kSaveData_LoadFrom(mfFOV);
kSaveData_LoadFrom(mfAspect);
kSaveData_LoadFrom(mfNearClipPlane);
}
//-----------------------------------------------------------------------
void cLight3DSpot::SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
kSaveData_SetupBegin(cLight3DSpot);
// Make sure all is updated.
SetTransformUpdated();
mbProjectionUpdated = true;
mbViewProjUpdated = true;
mbFrustumUpdated = true;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,128 @@
/* 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.
*/
#ifndef HPL_LIGHT3D_SPOT_H
#define HPL_LIGHT3D_SPOT_H
#include "hpl1/engine/scene/Light3D.h"
namespace hpl {
class cResources;
class iTexture;
class cFrustum;
//------------------------------------------
kSaveData_ChildClass(iLight3D, cLight3DSpot) {
kSaveData_ClassInit(cLight3DSpot) public : tString msTexture;
float mfFOV;
float mfAspect;
float mfNearClipPlane;
virtual iSaveObject *CreateSaveObject(cSaveObjectHandler * apSaveObjectHandler, cGame * apGame);
virtual int GetSaveCreatePrio();
};
//------------------------------------------
class cLight3DSpot : public iLight3D {
typedef iLight3D super;
public:
cLight3DSpot(tString asName, cResources *apResources);
~cLight3DSpot();
const cMatrixf &GetViewMatrix();
const cMatrixf &GetProjectionMatrix();
const cMatrixf &GetViewProjMatrix();
void SetTexture(iTexture *apTexture);
iTexture *GetTexture();
void SetFOV(float afAngle) {
mfFOV = afAngle;
mbProjectionUpdated = true;
}
float GetFOV() { return mfFOV; }
void SetAspect(float afAngle) {
mfAspect = afAngle;
mbProjectionUpdated = true;
}
float GetAspect() { return mfAspect; }
void SetNearClipPlane(float afX) {
mfNearClipPlane = afX;
mbProjectionUpdated = true;
}
float GetNearClipPlane() { return mfNearClipPlane; }
void SetFarAttenuation(float afX);
void SetNearAttenuation(float afX);
cFrustum *GetFrustum();
bool CollidesWithBV(cBoundingVolume *apBV);
// SaveObject implementation
virtual iSaveData *CreateSaveData();
virtual void SaveToSaveData(iSaveData *apSaveData);
virtual void LoadFromSaveData(iSaveData *apSaveData);
virtual void SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
private:
cSectorVisibilityContainer *CreateSectorVisibility();
void ExtraXMLProperties(TiXmlElement *apMainElem);
void UpdateBoundingVolume();
bool CreateClipRect(cRect2l &aCliprect, cRenderSettings *apRenderSettings, iLowLevelGraphics *apLowLevelGraphics);
cMatrixf m_mtxProjection;
cMatrixf m_mtxViewProj;
cMatrixf m_mtxView;
cFrustum *mpFrustum;
iTexture *mpTexture;
float mfFOV;
float mfAspect;
float mfNearClipPlane;
bool mbProjectionUpdated;
bool mbViewProjUpdated;
bool mbFrustumUpdated;
int mlViewProjMatrixCount;
int mlViewMatrixCount;
int mlFrustumMatrixCount;
};
} // namespace hpl
#endif // HPL_LIGHT3D_SPOT_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,287 @@
/* 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.
*/
#ifndef HPL_MESH_ENTITY_H
#define HPL_MESH_ENTITY_H
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/graphics/Renderable.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/math/MeshTypes.h"
#include "hpl1/engine/scene/Entity3D.h"
#include "hpl1/engine/system/SystemTypes.h"
#include "hpl1/engine/scene/SubMeshEntity.h"
#include "common/array.h"
#include "hpl1/engine/scene/AnimationState.h"
#include "common/stablemap.h"
namespace hpl {
class cMaterialManager;
class cMeshManager;
class cAnimationManager;
class cMesh;
class cSubMesh;
class cMeshEntity;
class cAnimation;
class cAnimationState;
class cNodeState;
class cBone;
class cNode3D;
class iCollideShape;
class iPhysicsBody;
class iPhysicsWorld;
class cWorld3D;
//-----------------------------------------------------------------------
class cMeshEntityRootNodeUpdate : public iEntityCallback {
public:
void OnTransformUpdate(iEntity3D *apEntity);
};
//------------------------------------------
class cMeshEntityCallback {
public:
virtual ~cMeshEntityCallback() = default;
virtual void AfterAnimationUpdate(cMeshEntity *apMeshEntity, float afTimeStep) = 0;
};
//------------------------------------------
kSaveData_ChildClass(iRenderable, cMeshEntity) {
kSaveData_ClassInit(cMeshEntity) public : tString msMeshName;
bool mbCastShadows;
int mlBodyId;
cContainerVec<cSaveData_cSubMeshEntity> mvSubEntities;
cContainerVec<cSaveData_cAnimationState> mvAnimStates;
virtual iSaveObject *CreateSaveObject(cSaveObjectHandler * apSaveObjectHandler, cGame * apGame);
virtual int GetSaveCreatePrio();
};
//------------------------------------------
class cMeshEntity : public iRenderable {
typedef iRenderable super;
friend class cSubMeshEntity;
friend class cMeshEntityRootNodeUpdate;
friend class cMesh;
public:
cMeshEntity(const tString asName, cMesh *apMesh, cMaterialManager *apMaterialManager,
cMeshManager *apMeshManager, cAnimationManager *apAnimationManager);
~cMeshEntity();
void SetWorld(cWorld3D *apWorld) { mpWorld = apWorld; }
cWorld3D *GetWorld() { return mpWorld; }
void SetCastsShadows(bool abX);
cNode3D *GetRootNode() { return mpRootNode; }
void SetCallback(cMeshEntityCallback *apCallback) { mpCallback = apCallback; }
// Sub mesh entities
cSubMeshEntity *GetSubMeshEntity(unsigned int alIdx);
cSubMeshEntity *GetSubMeshEntityName(const tString &asName);
int GetSubMeshEntityNum();
// Animation states
cAnimationState *AddAnimation(cAnimation *apAnimation, const tString &asName, float afBaseSpeed);
void ClearAnimations();
cAnimationState *GetAnimationState(int alIndex);
int GetAnimationStateIndex(const tString &asName);
cAnimationState *GetAnimationStateFromName(const tString &asName);
int GetAnimationStateNum();
// Animation controller
void Play(int alIndex, bool abLoop, bool bStopPrev);
void PlayName(const tString &asName, bool abLoop, bool bStopPrev);
void Stop();
// Bone states
cBoneState *GetBoneState(int alIndex);
int GetBoneStateIndex(const tString &asName);
cBoneState *GetBoneStateFromName(const tString &asName);
int GetBoneStateNum();
void SetSkeletonPhysicsActive(bool abX);
bool GetSkeletonPhysicsActive();
void SetSkeletonPhysicsCanSleep(bool abX) { mbSkeletonPhysicsCanSleep = abX; }
bool GetSkeletonPhysicsCanSleep() { return mbSkeletonPhysicsCanSleep; }
float GetSkeletonPhysicsWeight();
void SetSkeletonPhysicsWeight(float afX);
void FadeSkeletonPhysicsWeight(float afTime);
void SetSkeletonCollidersActive(bool abX);
bool GetSkeletonCollidersActive();
void AlignBodiesToSkeleton(bool abCalculateSpeed);
cMesh *GetMesh() { return mpMesh; }
/**
* Calculates the transform (and angles and position if wanted) of a mesh based on the position of the root bone.
* This is useful when going from rag doll to mesh.
* \param *apPostion Can be NULL, the position
* \param *apAngles Can be NULL, the angles.
*/
cMatrixf CalculateTransformFromSkeleton(cVector3f *apPostion, cVector3f *apAngles);
/**
* Checks collision with the skeletons collider boides
* \param *apWorld Physics world
* \param *apShape The shape
* \param &a_mtxShape The shapes matrix
* \param *apPosList A list of positions that all contact points are stored in. can be NULL.
* \param *apNumList A list of ints of number of the bone state body hit. can be NULL.
*/
bool CheckColliderShapeCollision(iPhysicsWorld *apWorld,
iCollideShape *apShape, const cMatrixf &a_mtxShape,
tVector3fList *apPosList, tIntList *apNumList);
void ResetGraphicsUpdated();
// Node states
cNode3D *GetNodeState(int alIndex);
int GetNodeStateIndex(const tString &asName);
cNode3D *GetNodeStateFromName(const tString &asName);
int GetNodeStateNum();
bool HasNodes() { return mbHasNodes; }
bool AttachEntityToParent(iEntity3D *apEntity, const tString &asParent);
// Entity implementation
tString GetEntityType() { return "Mesh"; }
bool IsVisible() { return IsRendered(); }
void SetVisible(bool abVisible) { SetRendered(abVisible); }
void UpdateLogic(float afTimeStep);
// Renderable implementation.
void UpdateGraphics(cCamera3D *apCamera, float afFrameTime, cRenderList *apRenderList);
void SetRendered(bool abX);
iMaterial *GetMaterial();
iVertexBuffer *GetVertexBuffer();
bool IsShadowCaster();
cBoundingVolume *GetBoundingVolume();
cMatrixf *GetModelMatrix(cCamera3D *apCamera);
int GetMatrixUpdateCount();
eRenderableType GetRenderType();
void SetBody(iPhysicsBody *apBody) { mpBody = apBody; }
iPhysicsBody *GetBody() { return mpBody; }
// SaveObject implementation
virtual iSaveData *CreateSaveData();
virtual void SaveToSaveData(iSaveData *apSaveData);
virtual void LoadFromSaveData(iSaveData *apSaveData);
virtual void SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
private:
void UpdateNodeMatrixRec(const cMatrixf &a_mtxParentWorld, cNode3D *apNode);
void HandleAnimationEvent(cAnimationEvent *apEvent);
void SetBoneMatrixFromBodyRec(const cMatrixf &a_mtxParentWorld, cBoneState *apBoneState);
void UpdateBVFromSubs();
void BuildBoneStatesRec(cBone *apBone, cNode3D *apParent);
cMaterialManager *mpMaterialManager;
cMeshManager *mpMeshManager;
cAnimationManager *mpAnimationManager;
cWorld3D *mpWorld;
tSubMeshEntityVec mvSubMeshes;
tSubMeshEntityMap m_mapSubMeshes;
tAnimationStateVec mvAnimationStates;
tAnimationStateIndexMap m_mapAnimationStateIndices;
tNodeStateVec mvBoneStates;
tNodeStateIndexMap m_mapBoneStateIndices;
tNodeStateVec mvTempBoneStates;
Common::Array<cMatrixf> mvBoneMatrices;
bool mbSkeletonPhysics;
bool mbSkeletonPhysicsFading;
float mfSkeletonPhysicsFadeSpeed;
float mfSkeletonPhysicsWeight;
bool mbSkeletonPhysicsSleeping;
bool mbSkeletonPhysicsCanSleep;
bool mbSkeletonColliders;
bool mbUpdatedBones;
bool mbHasNodes;
tNodeStateVec mvNodeStates;
tNodeStateIndexMap m_mapNodeStateIndices;
int mlStartSleepCount;
int mlUpdateCount;
float mfTimeStepAccum;
cMesh *mpMesh;
cNode3D *mpRootNode;
cMeshEntityRootNodeUpdate *mpRootCallback;
cMeshEntityCallback *mpCallback;
tEntity3DList mlstAttachedEntities;
cMatrixf mtxTemp;
iPhysicsBody *mpBody;
// Properies:
bool mbCastShadows;
};
//-----------------------------------------------------------------------
} // namespace hpl
#endif // HPL_MESH_ENTITY_H

View File

@@ -0,0 +1,291 @@
/* 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/MultiImageEntity.h"
#include "hpl1/debug.h"
#include "hpl1/engine/scene/Node2D.h"
#include "hpl1/engine/scene/Scene.h"
#include "hpl1/engine/scene/World2D.h"
#include "hpl1/engine/system/String.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cMultiImageEntity::cMultiImageEntity(class cScene *apScene, cNode2D *apNode) {
mpScene = apScene;
mpNode = apNode;
mbFlipH = false;
mbActive = true;
mfAlpha = 1;
mbAnimPaused = false;
}
//-----------------------------------------------------------------------
cMultiImageEntity::~cMultiImageEntity() {
tMultiImagePartMapIt PartIt = m_mapEntityParts.begin();
while (PartIt != m_mapEntityParts.end()) {
for (int i = 0; i < (int)PartIt->second.mvEntity.size(); i++) {
/*Destroy entity*/ // Not really needed since the map will do it..
}
PartIt++;
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cMultiImageEntity::Add(tString asName, tString asFile, cVector3f avLocalPos, tFlag alPartId) {
cImageEntity *pEntity = mpScene->GetWorld2D()->CreateImageEntity(asName, asFile);
if (pEntity == NULL) {
error("Couldn't load image entity '%s'", asFile.c_str());
return false;
}
return Add(asName, pEntity, avLocalPos, alPartId);
}
//-----------------------------------------------------------------------
bool cMultiImageEntity::Add(tString asName, cImageEntity *apEntity, cVector3f avLocalPos, tFlag alPartId) {
apEntity->SetPosition(avLocalPos);
mpNode->AddEntity(apEntity);
tMultiImagePartMapIt PartIt = m_mapEntityParts.find(alPartId);
if (PartIt == m_mapEntityParts.end()) {
cMultiImagePart ImagePart;
ImagePart.mlActiveEntity = 0;
ImagePart.mlId = alPartId;
ImagePart.mlPrio = 0;
ImagePart.mlNextAnimPrio = 0;
ImagePart.msNextAnim = "";
ImagePart.mbSyncFrame = false;
m_mapEntityParts.insert(tMultiImagePartMap::value_type(alPartId, ImagePart));
PartIt = m_mapEntityParts.find(alPartId);
}
PartIt->second.mvEntity.push_back(apEntity);
return true;
}
//-----------------------------------------------------------------------
cImageEntity *cMultiImageEntity::GetEntity(int alPartId) {
tMultiImagePartMapIt PartIt = m_mapEntityParts.find(alPartId);
if (PartIt == m_mapEntityParts.end())
return NULL;
return PartIt->second.mvEntity[PartIt->second.mlActiveEntity];
}
//-----------------------------------------------------------------------
bool cMultiImageEntity::PlayAnim(const tString &asName, tFlag alParts, unsigned int alPrio, bool abLoop, bool abSyncFrame) {
tMultiImagePartMapIt PartIt = m_mapEntityParts.begin();
while (PartIt != m_mapEntityParts.end()) {
// See if the part is among the parts to get the animation.
if ((PartIt->second.mlId & alParts) == 0) {
PartIt++;
continue;
}
cImageEntity *pEntity = PartIt->second.mvEntity[PartIt->second.mlActiveEntity];
if (pEntity->GetCurrentAnimation() == asName) {
PartIt++;
continue;
}
// Check if the prio is lower than current last animation, if so
// check if this animation should be played after and continue.
if (PartIt->second.mlPrio > alPrio) {
if (PartIt->second.mlNextAnimPrio <= alPrio) {
PartIt->second.msNextAnim = asName;
}
PartIt++;
continue;
}
PartIt->second.msNextAnim = pEntity->GetCurrentAnimation();
pEntity->SetAnimation(asName, abLoop);
PartIt->second.mlPrio = alPrio;
PartIt->second.mbSyncFrame = abSyncFrame;
PartIt++;
}
return true;
}
//-----------------------------------------------------------------------
void cMultiImageEntity::UpdateAnim() {
tMultiImagePartMapIt PartIt = m_mapEntityParts.begin();
while (PartIt != m_mapEntityParts.end()) {
cImageEntity *pEntity = PartIt->second.mvEntity[PartIt->second.mlActiveEntity];
if (pEntity->AnimationIsPlaying() == false) {
if (PartIt->second.msNextAnim != "") {
pEntity->SetAnimation(PartIt->second.msNextAnim);
// If chosen, synch with the frame of another entity playing the animation.
if (PartIt->second.mbSyncFrame) {
tMultiImagePartMapIt it = m_mapEntityParts.begin();
while (it != m_mapEntityParts.end()) {
cImageEntity *pTemp = it->second.mvEntity[it->second.mlActiveEntity];
if (pTemp->GetCurrentAnimation() == PartIt->second.msNextAnim) {
pEntity->SetFrameNum(pTemp->GetFrameNum());
break;
}
it++;
}
}
PartIt->second.msNextAnim = "";
PartIt->second.mlPrio = PartIt->second.mlNextAnimPrio;
PartIt->second.mlNextAnimPrio = 0;
PartIt->second.mbSyncFrame = false;
}
}
PartIt++;
}
}
//-----------------------------------------------------------------------
void cMultiImageEntity::SetFlipH(bool abX) {
if (mbFlipH == abX)
return;
mbFlipH = abX;
tMultiImagePartMapIt PartIt = m_mapEntityParts.begin();
while (PartIt != m_mapEntityParts.end()) {
for (int i = 0; i < (int)PartIt->second.mvEntity.size(); i++) {
PartIt->second.mvEntity[i]->SetFlipH(mbFlipH);
cVector3f vPos = PartIt->second.mvEntity[i]->GetLocalPosition();
PartIt->second.mvEntity[i]->SetPosition(cVector3f(-vPos.x, vPos.y, vPos.z));
}
PartIt++;
}
}
//-----------------------------------------------------------------------
void cMultiImageEntity::SetActive(bool abX) {
if (mbActive == abX)
return;
mbActive = abX;
tMultiImagePartMapIt PartIt = m_mapEntityParts.begin();
while (PartIt != m_mapEntityParts.end()) {
for (int i = 0; i < (int)PartIt->second.mvEntity.size(); i++) {
PartIt->second.mvEntity[i]->SetActive(mbActive);
}
PartIt++;
}
}
//-----------------------------------------------------------------------
void cMultiImageEntity::SetAlpha(float afX) {
if (mfAlpha == afX)
return;
mfAlpha = afX;
tMultiImagePartMapIt PartIt = m_mapEntityParts.begin();
while (PartIt != m_mapEntityParts.end()) {
for (int i = 0; i < (int)PartIt->second.mvEntity.size(); i++) {
PartIt->second.mvEntity[i]->SetAlpha(afX);
}
PartIt++;
}
}
//-----------------------------------------------------------------------
void cMultiImageEntity::SetAnimPaused(bool abX) {
if (mbAnimPaused == abX)
return;
mbAnimPaused = abX;
tMultiImagePartMapIt PartIt = m_mapEntityParts.begin();
while (PartIt != m_mapEntityParts.end()) {
for (int i = 0; i < (int)PartIt->second.mvEntity.size(); i++) {
PartIt->second.mvEntity[i]->SetAnimationPaused(abX);
}
PartIt++;
}
}
//-----------------------------------------------------------------------
void cMultiImageEntity::Flash(float afX) {
tMultiImagePartMapIt PartIt = m_mapEntityParts.begin();
while (PartIt != m_mapEntityParts.end()) {
for (int i = 0; i < (int)PartIt->second.mvEntity.size(); i++) {
PartIt->second.mvEntity[i]->Flash(afX);
}
PartIt++;
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,93 @@
/* 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.
*/
#ifndef HPL_MULTI_IMAGE_ENTITY_H
#define HPL_MULTI_IMAGE_ENTITY_H
#include "hpl1/engine/scene/ImageEntity.h"
#include "common/stablemap.h"
namespace hpl {
class cScene;
class cNode2D;
class cMultiImagePart {
public:
tFlag mlId;
int mlActiveEntity;
tImageEntityVec mvEntity;
unsigned int mlPrio;
unsigned int mlNextAnimPrio;
tString msNextAnim;
bool mbSyncFrame;
};
typedef Common::StableMap<unsigned int, cMultiImagePart> tMultiImagePartMap;
typedef tMultiImagePartMap::iterator tMultiImagePartMapIt;
class cMultiImageEntity {
public:
cMultiImageEntity(class cScene *apScene, cNode2D *apNode);
~cMultiImageEntity();
bool Add(tString asName, tString asFile, cVector3f avLocalPos, tFlag alPartId);
bool Add(tString asName, cImageEntity *apEntity, cVector3f avLocalPos, tFlag alPartId);
void SetFlipH(bool abX);
void SetAlpha(float afX);
void Flash(float afX);
void SetActive(bool abX);
bool GetActive() { return mbActive; }
bool PlayAnim(const tString &asName, tFlag alParts, unsigned int alPrio, bool abLoop = true, bool abSyncFrame = false);
void UpdateAnim();
void SetAnimPaused(bool abX);
bool GetAnimPaused() { return mbAnimPaused; }
cImageEntity *GetEntity(int alPartId);
private:
bool mbActive;
float mfAlpha;
bool mbAnimPaused;
cScene *mpScene;
cNode2D *mpNode;
tMultiImagePartMap m_mapEntityParts;
bool mbFlipH;
};
} // namespace hpl
#endif // HPL_MULTI_IMAGE_ENTITY_H

View File

@@ -0,0 +1,150 @@
/* 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/Node.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iNode::~iNode() {
for (tEntityListIt it = mlstEntity.begin(); it != mlstEntity.end(); it++) {
iEntity *pEntity = *it;
pEntity->SetParent(NULL);
}
mlstEntity.clear();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
int iNode::SetVisible(bool abX, bool abCascade) {
int lNum = 0;
for (tEntityListIt it = mlstEntity.begin(); it != mlstEntity.end(); it++) {
(*it)->SetVisible(abX);
lNum++;
}
if (abCascade) {
for (tNodeListIt NIt = mlstNode.begin(); NIt != mlstNode.end(); NIt++) {
(*NIt)->SetVisible(abX, abCascade);
}
}
return lNum;
}
//-----------------------------------------------------------------------
bool iNode::AddEntity(iEntity *apEntity) {
if (apEntity->HasParent())
return false;
mlstEntity.push_back(apEntity);
apEntity->SetParent(this);
return true;
}
//-----------------------------------------------------------------------
bool iNode::RemoveEntity(iEntity *apEntity) {
for (tEntityListIt it = mlstEntity.begin(); it != mlstEntity.end(); it++) {
if (*it == apEntity) {
apEntity->SetParent(NULL);
mlstEntity.erase(it);
return true;
}
}
return false;
}
//-----------------------------------------------------------------------
void iNode::ClearEntities() {
mlstEntity.clear();
}
//-----------------------------------------------------------------------
cNodeIterator iNode::GetChildIterator() {
return cNodeIterator(&mlstNode);
}
cEntityIterator iNode::GetEntityIterator() {
return cEntityIterator(&mlstEntity);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SAVE OBJECT STUFF
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
kBeginSerializeVirtual(cSaveData_iNode, iSaveData)
kSerializeVarContainer(mlstEntities, eSerializeType_Int32)
kSerializeVarContainer(mlstNodes, eSerializeType_Int32)
kEndSerialize()
//-----------------------------------------------------------------------
void iNode::SaveToSaveData(iSaveData *apSaveData) {
kSaveData_SaveToBegin(iNode);
kSaveData_SaveIdList(mlstEntity, tEntityListIt, mlstEntities);
kSaveData_SaveIdList(mlstNode, tNodeListIt, mlstNodes);
}
//-----------------------------------------------------------------------
void iNode::LoadFromSaveData(iSaveData *apSaveData) {
kSaveData_LoadFromBegin(iNode);
}
//-----------------------------------------------------------------------
void iNode::SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
kSaveData_SetupBegin(iNode);
kSaveData_LoadIdList(mlstEntity, mlstEntities, iEntity *);
kSaveData_LoadIdList(mlstNode, mlstNodes, iNode *);
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,90 @@
/* 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.
*/
#ifndef HPL_NODE_H
#define HPL_NODE_H
#include "common/list.h"
#include "hpl1/engine/game/SaveGame.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/scene/Entity.h"
#include "hpl1/engine/system/Container.h"
namespace hpl {
class iNode;
typedef Common::List<iNode *> tNodeList;
typedef tNodeList::iterator tNodeListIt;
typedef cSTLIterator<iNode *, tNodeList, tNodeListIt> cNodeIterator;
//------------------------------------
kSaveData_BaseClass(iNode) {
kSaveData_ClassInit(iNode) public : cContainerList<int> mlstEntities;
cContainerList<int> mlstNodes;
};
//------------------------------------
class iNode : public iSaveObject {
typedef iSaveObject super;
public:
iNode() : mbActive(true) {}
virtual ~iNode();
int SetVisible(bool abX, bool abCascade);
bool AddEntity(iEntity *apEntity);
bool RemoveEntity(iEntity *apEntity);
void ClearEntities();
void SetActive(bool abX) { mbActive = abX; }
bool IsActive() { return mbActive; }
virtual iNode *CreateChild() = 0;
cNodeIterator GetChildIterator();
cEntityIterator GetEntityIterator();
// SaveObject implementation
virtual iSaveData *CreateSaveData() { return NULL; }
virtual void SaveToSaveData(iSaveData *apSaveData);
virtual void LoadFromSaveData(iSaveData *apSaveData);
virtual void SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
protected:
tEntityList mlstEntity;
tNodeList mlstNode;
bool mbActive;
};
} // namespace hpl
#endif // HPL_NODE_H

View File

@@ -0,0 +1,103 @@
/* 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/Node2D.h"
#include "hpl1/engine/scene/Entity2D.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cNode2D::cNode2D() {
mvPosition = cVector3f(0);
}
//-----------------------------------------------------------------------
cNode2D::~cNode2D() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iNode *cNode2D::CreateChild() {
cNode2D *pNode = hplNew(cNode2D, ());
mlstNode.push_back(pNode);
return pNode;
}
//-----------------------------------------------------------------------
cNode2D *cNode2D::CreateChild2D() {
return static_cast<cNode2D *>(CreateChild());
}
//-----------------------------------------------------------------------
void cNode2D::SetPosition(cVector3f avPos) {
cVector3f vPosAdd = avPos - mvPosition;
mvPosition = avPos;
// Update all the entities
for (tEntityListIt it = mlstEntity.begin(); it != mlstEntity.end(); it++) {
iEntity2D *pEntity = static_cast<iEntity2D *>(*it);
pEntity->SetPosition(pEntity->GetLocalPosition());
// call an update??
}
for (tNodeListIt NIt = mlstNode.begin(); NIt != mlstNode.end(); NIt++) {
cNode2D *pNode = static_cast<cNode2D *>(*NIt);
pNode->SetPosition(pNode->mvPosition + vPosAdd);
}
}
//-----------------------------------------------------------------------
void cNode2D::SetRotation(cVector3f avRot) {
}
//-----------------------------------------------------------------------
void cNode2D::SetScale(cVector3f avScale) {
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,61 @@
/* 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.
*/
#ifndef HPL_NODE2D_H
#define HPL_NODE2D_H
#include "common/list.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/scene/Node.h"
namespace hpl {
class cNode2D : public iNode {
public:
cNode2D();
virtual ~cNode2D();
iNode *CreateChild();
cNode2D *CreateChild2D();
cVector3f &GetPosition() { return mvPosition; }
cVector3f &GetRotation() { return mvRotation; }
cVector3f &GetScale() { return mvScale; }
void SetPosition(cVector3f avPos);
void SetRotation(cVector3f avRot);
void SetScale(cVector3f avScale);
private:
cVector3f mvPosition;
cVector3f mvRotation;
cVector3f mvScale;
};
} // namespace hpl
#endif // HPL_NODE2D_H

View File

@@ -0,0 +1,351 @@
/* 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/Node3D.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/scene/Entity3D.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cNode3D::cNode3D(const tString &asName, bool abAutoDeleteChildren) : iNode() {
m_mtxLocalTransform = cMatrixf::Identity;
m_mtxWorldTransform = cMatrixf::Identity;
mvWorldPosition = cVector3f(0, 0, 0);
mbTransformUpdated = true;
mpParent = NULL;
msName = asName;
mbAutoDeleteChildren = abAutoDeleteChildren;
m_mtxRotation = cMatrixf::Identity;
mvScale = cVector3f(1, 1, 1);
mvTranslation = cVector3f(0, 0, 0);
}
//-----------------------------------------------------------------------
cNode3D::~cNode3D() {
if (mbAutoDeleteChildren) {
STLDeleteAll(mlstNode);
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iNode *cNode3D::CreateChild() {
return CreateChild3D();
}
//-----------------------------------------------------------------------
cNode3D *cNode3D::CreateChild3D(const tString &asName, bool abAutoDeleteChildren) {
cNode3D *pNode = hplNew(cNode3D, (asName, abAutoDeleteChildren));
pNode->mpParent = this;
mlstNode.push_back(pNode);
return pNode;
}
//-----------------------------------------------------------------------
cVector3f cNode3D::GetLocalPosition() {
return m_mtxLocalTransform.GetTranslation();
}
//-----------------------------------------------------------------------
cMatrixf &cNode3D::GetLocalMatrix() {
return m_mtxLocalTransform;
}
//-----------------------------------------------------------------------
cVector3f cNode3D::GetWorldPosition() {
UpdateWorldTransform();
return m_mtxWorldTransform.GetTranslation();
}
//-----------------------------------------------------------------------
cMatrixf &cNode3D::GetWorldMatrix() {
UpdateWorldTransform();
return m_mtxWorldTransform;
}
//-----------------------------------------------------------------------
void cNode3D::SetPosition(const cVector3f &avPos) {
m_mtxLocalTransform.m[0][3] = avPos.x;
m_mtxLocalTransform.m[1][3] = avPos.y;
m_mtxLocalTransform.m[2][3] = avPos.z;
SetWorldTransformUpdated();
}
void cNode3D::SetMatrix(const cMatrixf &a_mtxTransform, bool abSetChildrenUpdated) {
m_mtxLocalTransform = a_mtxTransform;
if (abSetChildrenUpdated)
SetWorldTransformUpdated();
else
mbTransformUpdated = true;
}
//-----------------------------------------------------------------------
void cNode3D::SetWorldPosition(const cVector3f &avWorldPos) {
if (mpParent) {
SetPosition(avWorldPos - mpParent->GetWorldPosition());
} else {
SetPosition(avWorldPos);
}
}
//-----------------------------------------------------------------------
void cNode3D::SetWorldMatrix(const cMatrixf &a_mtxWorldTransform) {
if (mpParent) {
SetMatrix(cMath::MatrixMul(cMath::MatrixInverse(mpParent->GetWorldMatrix()),
a_mtxWorldTransform));
} else {
SetMatrix(a_mtxWorldTransform);
}
}
//-----------------------------------------------------------------------
const char *cNode3D::GetName() {
return msName.c_str();
}
//-----------------------------------------------------------------------
cNode3D *cNode3D::GetParent() {
return mpParent;
}
//-----------------------------------------------------------------------
void cNode3D::SetParent(cNode3D *apNode) {
mpParent = apNode;
mpParent->mlstNode.push_back(this);
}
void cNode3D::AddChild(cNode3D *apChild) {
mlstNode.push_back(apChild);
}
//-----------------------------------------------------------------------
void cNode3D::AddRotation(const cVector3f &avRot, eEulerRotationOrder aOrder) {
m_mtxRotation = cMath::MatrixMul(cMath::MatrixRotate(avRot, aOrder), m_mtxRotation);
}
void cNode3D::AddRotation(const cQuaternion &aqRotation) {
// Would be better to have the rotation as a quaternion and
// then just multiply so that it NOT becomes order dependant.
m_mtxRotation = cMath::MatrixMul(cMath::MatrixQuaternion(aqRotation), m_mtxRotation);
}
void cNode3D::AddScale(const cVector3f &avScale) {
mvScale *= avScale;
}
void cNode3D::AddTranslation(const cVector3f &avTrans) {
mvTranslation += avTrans;
}
void cNode3D::UpdateMatrix(bool abSetChildrenUpdated) {
cMatrixf mtxTransform = GetLocalMatrix();
// Save the translation and set it to 0 so that only the rotation is altered.
cVector3f vPos = mtxTransform.GetTranslation();
mtxTransform.SetTranslation(cVector3f(0, 0, 0));
// Log("Startpos: %s",vPos.ToString().c_str());
// Log("World pos: %s\n",GetWorldMatrix().GetTranslation().ToString().c_str());
// The animation rotation is applied before the local.
mtxTransform = cMath::MatrixMul(mtxTransform, m_mtxRotation);
// Skip scale for now.
// mtxTransform = cMath::MatrixMul(cMath::MatrixScale(mvScale), mtxTransform);
mtxTransform.SetTranslation(vPos + mvTranslation);
SetMatrix(mtxTransform, abSetChildrenUpdated);
// Log("World pos: %s\n",GetWorldMatrix().GetTranslation().ToString().c_str());
// Reset values
m_mtxRotation = cMatrixf::Identity;
mvScale = cVector3f(1, 1, 1);
mvTranslation = cVector3f(0, 0, 0);
}
//-----------------------------------------------------------------------
void cNode3D::SetSource(const tString &asSource) {
msSource = asSource;
}
const char *cNode3D::GetSource() {
return msSource.c_str();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cNode3D::UpdateWorldTransform() {
if (mbTransformUpdated) {
// if(msName == "WeaponJoint") LogUpdate(" update world transform!\n");
mbTransformUpdated = false;
if (mpParent) {
m_mtxWorldTransform = cMath::MatrixMul(mpParent->GetWorldMatrix(), m_mtxLocalTransform);
} else {
m_mtxWorldTransform = m_mtxLocalTransform;
}
}
}
//-----------------------------------------------------------------------
void cNode3D::SetWorldTransformUpdated() {
// if(msName == "WeaponJoint") LogUpdate(" setworldtransform updated!\n");
mbTransformUpdated = true;
// Set all entities as updated
tEntityListIt EIt = mlstEntity.begin();
for (; EIt != mlstEntity.end(); ++EIt) {
iEntity3D *pEntity = static_cast<iEntity3D *>(*EIt);
pEntity->SetTransformUpdated();
}
// Set all child nodes as updated
tNodeListIt NIt = mlstNode.begin();
for (; NIt != mlstNode.end(); ++NIt) {
cNode3D *pNode = static_cast<cNode3D *>(*NIt);
pNode->SetWorldTransformUpdated();
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SAVE OBJECT STUFF
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
kBeginSerialize(cSaveData_cNode3D, cSaveData_iNode)
kSerializeVar(msName, eSerializeType_String)
kSerializeVar(msSource, eSerializeType_String)
kSerializeVar(mbAutoDeleteChildren, eSerializeType_Bool)
kSerializeVar(m_mtxLocalTransform, eSerializeType_Matrixf)
kSerializeVar(mlParentId, eSerializeType_Int32)
kEndSerialize()
//-----------------------------------------------------------------------
iSaveObject *cSaveData_cNode3D::CreateSaveObject(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
return hplNew(cNode3D, (msName, mbAutoDeleteChildren));
}
int cSaveData_cNode3D::GetSaveCreatePrio() {
return 0;
}
//-----------------------------------------------------------------------
iSaveData *cNode3D::CreateSaveData() {
return hplNew(cSaveData_cNode3D, ());
}
//-----------------------------------------------------------------------
void cNode3D::SaveToSaveData(iSaveData *apSaveData) {
kSaveData_SaveToBegin(cNode3D);
kSaveData_SaveTo(msName);
kSaveData_SaveTo(msSource);
kSaveData_SaveTo(mbAutoDeleteChildren);
kSaveData_SaveTo(m_mtxLocalTransform);
kSaveData_SaveObject(mpParent, mlParentId);
}
//-----------------------------------------------------------------------
void cNode3D::LoadFromSaveData(iSaveData *apSaveData) {
kSaveData_LoadFromBegin(cNode3D);
kSaveData_LoadFrom(msName);
kSaveData_LoadFrom(msSource);
kSaveData_LoadFrom(mbAutoDeleteChildren);
kSaveData_LoadFrom(m_mtxLocalTransform);
}
//-----------------------------------------------------------------------
void cNode3D::SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
kSaveData_SetupBegin(cNode3D);
kSaveData_LoadObject(mpParent, mlParentId, cNode3D *);
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,128 @@
/* 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.
*/
#ifndef HPL_NODE3D_H
#define HPL_NODE3D_H
#include "common/list.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/scene/Node.h"
namespace hpl {
//------------------------------------
kSaveData_ChildClass(iNode, cNode3D) {
kSaveData_ClassInit(cNode3D) public : tString msName;
tString msSource;
bool mbAutoDeleteChildren;
cMatrixf m_mtxLocalTransform;
int mlParentId;
iSaveObject *CreateSaveObject(cSaveObjectHandler * apSaveObjectHandler, cGame * apGame);
int GetSaveCreatePrio();
};
//------------------------------------
class cNode3D : public iNode {
typedef iNode super;
public:
cNode3D(const tString &asName = "", bool abAutoDeleteChildren = true);
virtual ~cNode3D();
iNode *CreateChild();
cNode3D *CreateChild3D(const tString &asName = "", bool abAutoDeleteChildren = true);
cVector3f GetLocalPosition();
cMatrixf &GetLocalMatrix();
cVector3f GetWorldPosition();
cMatrixf &GetWorldMatrix();
void SetPosition(const cVector3f &avPos);
void SetMatrix(const cMatrixf &a_mtxTransform, bool abSetChildrenUpdated = true);
void SetWorldPosition(const cVector3f &avWorldPos);
void SetWorldMatrix(const cMatrixf &a_mtxWorldTransform);
const char *GetName();
cNode3D *GetParent();
void AddRotation(const cVector3f &avRot, eEulerRotationOrder aOrder);
void AddRotation(const cQuaternion &aqRotation);
void AddScale(const cVector3f &avScale);
void AddTranslation(const cVector3f &avTrans);
void SetSource(const tString &asSource);
const char *GetSource();
/**
* Updates the matrix with the added scales, translations and rotation. It also resets these values.
*/
void UpdateMatrix(bool abSetChildrenUpdated);
// Extra stuff that shouldn't be used externally
void SetParent(cNode3D *apNode);
void AddChild(cNode3D *apChild);
// SaveObject implementation
virtual iSaveData *CreateSaveData();
virtual void SaveToSaveData(iSaveData *apSaveData);
virtual void LoadFromSaveData(iSaveData *apSaveData);
virtual void SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
void UpdateWorldTransform();
void SetWorldTransformUpdated();
private:
tString msName;
tString msSource;
bool mbAutoDeleteChildren;
cMatrixf m_mtxLocalTransform;
cMatrixf m_mtxWorldTransform;
cVector3f mvWorldPosition;
cMatrixf m_mtxRotation;
cVector3f mvScale;
cVector3f mvTranslation;
bool mbTransformUpdated;
cNode3D *mpParent;
};
} // namespace hpl
#endif // HPL_NODE3D_H

View File

@@ -0,0 +1,79 @@
/* 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/NodeState.h"
#include "hpl1/engine/math/Math.h"
//////////////////////////////////////////////////////////////////////////
// WARNING
// THE FOLLOWING CODE IS NOT USED CURRENTLY
// SHOULD BE DELETED SOON IF NOT NEEDED
//////////////////////////////////////////////////////////////////////////
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cNodeState::cNodeState(const tString &asName) {
/*msName = asName;
mpParent = NULL;*/
}
//-----------------------------------------------------------------------
cNodeState::~cNodeState() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
/*void cNodeState::SetWorldTransform(const cMatrixf& a_mtxWorld)
{
m_mtxWorldTransform = a_mtxWorld;
}
//-----------------------------------------------------------------------
cMatrixf& cNodeState::GetWorldTransform()
{
return m_mtxWorldTransform;
}*/
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,47 @@
/* 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.
*/
#ifndef HPL_NODE_STATE_H
#define HPL_NODE_STATE_H
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/scene/Node3D.h"
#include "hpl1/engine/system/SystemTypes.h"
namespace hpl {
class cNodeState {
public:
cNodeState(const tString &asName);
~cNodeState();
private:
};
} // namespace hpl
#endif // HPL_NODE_STATE_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,311 @@
/* 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.
*/
#ifndef HPL_PORTAL_CONTAINER_H
#define HPL_PORTAL_CONTAINER_H
#include "common/list.h"
#include "hpl1/engine/graphics/Renderable.h"
#include "hpl1/engine/math/BoundingVolume.h"
#include "hpl1/engine/scene/RenderableContainer.h"
#include "common/stablemap.h"
#include "hpl1/std/set.h"
namespace hpl {
class iLight3D;
class cSectorVisibilityContainer;
typedef Common::List<iRenderable *> tRenderableList;
typedef Common::List<iRenderable *>::iterator tRenderableListIt;
typedef Hpl1::Std::set<iRenderable *> tRenderableSet;
typedef Hpl1::Std::set<iRenderable *>::iterator tRenderableSetIt;
typedef Hpl1::Std::set<iEntity3D *> tEntity3DSet;
typedef Hpl1::Std::set<iEntity3D *>::iterator tEntity3DSetIt;
//----------------------------------------------------
class cPortalContainer;
class cSector;
//----------------------------------------------------
typedef Common::StableMap<tString, cSector *> tSectorMap;
typedef Common::StableMap<tString, cSector *>::iterator tSectorMapIt;
//----------------------------------------------------
class cPortalContainerEntityIterator {
public:
cPortalContainerEntityIterator(cPortalContainer *apContainer,
cBoundingVolume *apBV);
bool HasNext();
iEntity3D *Next();
private:
cPortalContainer *mpContainer;
cBoundingVolume *mpBV;
tSectorMap *mpSectorMap;
tEntity3DSet *mpEntity3DSet;
tEntity3DSetIt mEntityIt;
tSectorMapIt mSectorIt;
tEntity3DSet mIteratedSet;
int mlIteratorCount;
bool mbGlobal;
};
//----------------------------------------------------
class cPortalContainerCallback : public iEntityCallback {
public:
cPortalContainerCallback(cPortalContainer *apContainer);
void OnTransformUpdate(iEntity3D *apEntity);
private:
cPortalContainer *mpContainer;
};
//----------------------------------------------------
class cPortalContainerEntityCallback : public iEntityCallback {
public:
cPortalContainerEntityCallback(cPortalContainer *apContainer);
void OnTransformUpdate(iEntity3D *apEntity);
private:
cPortalContainer *mpContainer;
};
//----------------------------------------------------
class cSector;
class cPortal;
typedef Common::StableMap<int, cPortal *> tPortalMap;
typedef Common::StableMap<int, cPortal *>::iterator tPortalMapIt;
typedef Common::List<cPortal *> tPortalList;
typedef Common::List<cPortal *>::iterator tPortalListIt;
class cPortal {
friend class cSector;
public:
cPortal(int alId, cPortalContainer *apContainer);
~cPortal();
void SetTargetSector(tString asSectorId);
cSector *GetTargetSector();
cSector *GetSector();
void AddPortalId(int alId);
void SetNormal(const cVector3f &avNormal);
void AddPoint(const cVector3f &avPoint);
void SetTransform(const cMatrixf &a_mtxTrans);
void Compile();
bool IsVisible(cFrustum *apFrustum);
tPortalList *GetPortalList();
// Debug stuffs
cBoundingVolume *GetBV() { return &mBV; }
cVector3f GetNormal() { return mvNormal; }
int GetId() { return mlId; }
cPlanef &GetPlane() { return mPlane; }
bool GetActive() { return mbActive; }
void SetActive(bool abX) { mbActive = abX; }
private:
cPortalContainer *mpContainer;
int mlId;
tString msSectorId;
tString msTargetSectorId;
cSector *mpTargetSector;
cSector *mpSector;
tIntVec mvPortalIds;
tPortalList mlstPortals;
bool mbPortalsNeedUpdate;
bool mbActive;
cVector3f mvNormal;
cPlanef mPlane;
cBoundingVolume mBV;
tVector3fList mlstPoints;
};
//----------------------------------------------------
class cSector : public iRenderContainerData {
friend class cPortalContainer;
friend class cPortalContainerEntityIterator;
public:
cSector(tString asId, cPortalContainer *apContainer);
~cSector();
bool TryToAdd(iRenderable *apObject, bool abStatic);
bool TryToAddEntity(iEntity3D *apEntity);
void AddPortal(cPortal *apPortal);
void GetVisible(cFrustum *apFrustum, cRenderList *apRenderList, cPortal *apStartPortal);
void RemoveDynamic(iRenderable *apObject);
void RemoveEntity(iEntity3D *apEntity);
cPortal *GetPortal(int alId);
void SetAmbientColor(const cColor &aAmbient) { mAmbient = aAmbient; }
const cColor &GetAmbientColor() { return mAmbient; }
// Debug stuffs
cBoundingVolume *GetBV() { return &mBV; }
tPortalList *GetPortalList() { return &mlstPortals; }
tString &GetId() { return msId; }
private:
cPortalContainer *mpContainer;
tString msId;
cBoundingVolume mBV;
int mlVisitCount;
tRenderableSet m_setStaticObjects;
tRenderableSet m_setDynamicObjects;
tEntity3DSet m_setEntities;
tPortalList mlstPortals;
cColor mAmbient;
};
//----------------------------------------------------
class cPortalContainer : public iRenderableContainer {
friend class cPortalContainerCallback;
friend class cPortalContainerEntityCallback;
friend class cPortalContainerEntityIterator;
public:
cPortalContainer();
virtual ~cPortalContainer();
bool AddEntity(iEntity3D *pEntity);
bool RemoveEntity(iEntity3D *pEntity);
bool Add(iRenderable *apRenderable, bool abStatic);
bool Remove(iRenderable *apRenderable);
void AddLightShadowCasters(iLight3D *apLight, cFrustum *apFrustum, cRenderList *apRenderList);
void AddToRenderList(iRenderable *apObject, cFrustum *apFrustum, cRenderList *apRenderList);
void GetVisible(cFrustum *apFrustum, cRenderList *apRenderList);
void Compile();
// Portal Specific Stuff
/**
* Adds a new sector to the container. All sectors must be created before anything else.
*/
void AddSector(tString asSectorId);
/**
* Adds a new renderable to a specific sector.This also recalculates the sector's bounding volume.
* Object must be (and is considered) static!
*/
bool AddToSector(iRenderable *apRenderable, tString asSector);
/*
* Adds a portal to a sector.
*/
bool AddPortal(cPortal *apPortal, tString asSector);
cSector *GetSector(tString asId);
int GetSectorVisitCount() const { return mlSectorVisitCount; }
cPortalContainerEntityIterator GetEntityIterator(cBoundingVolume *apBV);
// Visibility tools
cSectorVisibilityContainer *CreateVisibiltyFromBV(cBoundingVolume *apBV);
cSectorVisibilityContainer *CreateVisibiltyFromFrustum(cFrustum *apFrustum);
// Debug stuff
tSectorMap *GetSectorMap() { return &m_mapSectors; }
tStringList *GetVisibleSectorsList() { return &mlstVisibleSectors; }
tRenderableSet *GetGlobalDynamicObjectSet() { return &m_setGlobalDynamicObjects; }
tRenderableList *GetGlobalStaticObjectList() { return &mlstGlobalStaticObjects; }
private:
void ComputeSectorVisibilty(cSectorVisibilityContainer *apContainer);
tSectorMap m_mapSectors;
int mlSectorVisitCount;
cPortalContainerCallback *mpEntityCallback;
cPortalContainerEntityCallback *mpNormalEntityCallback;
// List with dynamic objects that are not in any sector.
tRenderableSet m_setGlobalDynamicObjects;
// List with static objects that are not in any sector.
tRenderableList mlstGlobalStaticObjects;
// Global dynamic entities
tEntity3DSet m_setGlobalEntities;
tStringList mlstVisibleSectors;
int mlEntityIterateCount;
};
} // namespace hpl
#endif // HPL_PORTAL_CONTAINER_H

View File

@@ -0,0 +1,73 @@
/* 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.
*/
#ifndef HPL_RENDERABLE_CONTAINER_H
#define HPL_RENDERABLE_CONTAINER_H
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/system/SystemTypes.h"
namespace hpl {
class iRenderable;
class cFrustum;
class cRenderList;
class iRenderableContainer {
public:
virtual ~iRenderableContainer() = default;
/**
* Add a new object to the container.
* \param *apRenderable the object
* \param abStatic true if the object will not move, else false.
* \return true if success, else false
*/
virtual bool Add(iRenderable *apRenderable, bool abStatic) = 0;
/**
* Removes the object, only non static are guaranteed to be found.
* \param *apRenderable the object
* \return true if success, else false
*/
virtual bool Remove(iRenderable *apRenderable) = 0;
/**
* Populate the renderlist with all objects visible in a fostrum.
* \param apFostrum
* \param *apRenderList
*/
virtual void GetVisible(cFrustum *apFostrum, cRenderList *apRenderList) = 0;
/**
* Sets up things like octrees so that the container is ready to use.
*/
virtual void Compile() = 0;
};
} // namespace hpl
#endif // RENDERABLE_CONTAINER

View File

@@ -0,0 +1,494 @@
/* 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/Scene.h"
#include "hpl1/engine/game/Updater.h"
#include "hpl1/engine/system/low_level_system.h"
#include "hpl1/engine/graphics/Graphics.h"
#include "hpl1/engine/graphics/GraphicsDrawer.h"
#include "hpl1/engine/graphics/RenderList.h"
#include "hpl1/engine/graphics/Renderer2D.h"
#include "hpl1/engine/graphics/Renderer3D.h"
#include "hpl1/engine/graphics/RendererPostEffects.h"
#include "hpl1/engine/physics/Collider2D.h"
#include "hpl1/engine/resources/Resources.h"
#include "hpl1/engine/resources/ScriptManager.h"
#include "hpl1/engine/scene/Camera2D.h"
#include "hpl1/engine/scene/Camera3D.h"
#include "hpl1/engine/scene/World2D.h"
#include "hpl1/engine/scene/World3D.h"
#include "hpl1/engine/sound/LowLevelSound.h"
#include "hpl1/engine/sound/Sound.h"
#include "hpl1/engine/sound/SoundHandler.h"
#include "hpl1/engine/system/Script.h"
#include "hpl1/engine/physics/Physics.h"
#include "hpl1/engine/resources/FileSearcher.h"
#include "hpl1/engine/resources/MeshLoaderHandler.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cScene::cScene(cGraphics *apGraphics, cResources *apResources, cSound *apSound, cPhysics *apPhysics,
cSystem *apSystem, cAI *apAI)
: iUpdateable("HPL_Scene") {
mpGraphics = apGraphics;
mpResources = apResources;
mpSound = apSound;
mpPhysics = apPhysics;
mpSystem = apSystem;
mpAI = apAI;
mpCollider2D = hplNew(cCollider2D, ());
mpCurrentWorld2D = NULL;
mpCurrentWorld3D = NULL;
mbCameraIsListener = true;
mbDrawScene = true;
mbUpdateMap = true;
mpActiveCamera = NULL;
}
//-----------------------------------------------------------------------
cScene::~cScene() {
Log("Exiting Scene Module\n");
Log("--------------------------------------------------------\n");
STLDeleteAll(mlstWorld3D);
STLDeleteAll(mlstCamera);
hplDelete(mpCollider2D);
Log("--------------------------------------------------------\n\n");
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cCamera2D *cScene::CreateCamera2D(unsigned int alW, unsigned int alH) {
cCamera2D *pCamera = hplNew(cCamera2D, (alW, alH));
// Add Camera to list
mlstCamera.push_back(pCamera);
return pCamera;
}
//-----------------------------------------------------------------------
cCamera3D *cScene::CreateCamera3D(eCameraMoveMode aMoveMode) {
cCamera3D *pCamera = hplNew(cCamera3D, ());
pCamera->SetAspect(mpGraphics->GetLowLevel()->GetScreenSize().x /
mpGraphics->GetLowLevel()->GetScreenSize().y);
// Add Camera to list
mlstCamera.push_back(pCamera);
return pCamera;
}
//-----------------------------------------------------------------------
void cScene::DestroyCamera(iCamera *apCam) {
for (tCameraListIt it = mlstCamera.begin(); it != mlstCamera.end(); it++) {
if (*it == apCam) {
hplDelete(*it);
mlstCamera.erase(it);
break;
}
}
}
//-----------------------------------------------------------------------
void cScene::SetCamera(iCamera *pCam) {
mpActiveCamera = pCam;
if (mbCameraIsListener) {
if (mpActiveCamera->GetType() == eCameraType_2D) {
cCamera2D *pCamera2D = static_cast<cCamera2D *>(mpActiveCamera);
mpSound->GetLowLevel()->SetListenerPosition(pCamera2D->GetPosition());
}
}
}
//-----------------------------------------------------------------------
void cScene::SetCameraPosition(const cVector3f &avPos) {
if (mpActiveCamera->GetType() == eCameraType_2D) {
cCamera2D *pCamera2D = static_cast<cCamera2D *>(mpActiveCamera);
pCamera2D->SetPosition(avPos);
}
if (mbCameraIsListener)
mpSound->GetLowLevel()->SetListenerPosition(avPos);
}
cVector3f cScene::GetCameraPosition() {
if (mpActiveCamera->GetType() == eCameraType_2D) {
cCamera2D *pCamera2D = static_cast<cCamera2D *>(mpActiveCamera);
return pCamera2D->GetPosition();
}
return cVector2f(0);
}
//-----------------------------------------------------------------------
cScriptVar *cScene::CreateLocalVar(const tString &asName) {
cScriptVar *pVar;
pVar = GetLocalVar(asName);
if (pVar == NULL) {
cScriptVar Var;
Var.msName = asName;
m_mapLocalVars.insert(tScriptVarMap::value_type(cString::ToLowerCase(asName), Var));
pVar = GetLocalVar(asName);
if (pVar == NULL)
error("Very strange error when creating script var!");
}
return pVar;
}
//-----------------------------------------------------------------------
cScriptVar *cScene::GetLocalVar(const tString &asName) {
tScriptVarMapIt it = m_mapLocalVars.find(cString::ToLowerCase(asName));
if (it == m_mapLocalVars.end())
return NULL;
return &it->second;
}
//-----------------------------------------------------------------------
tScriptVarMap *cScene::GetLocalVarMap() {
return &m_mapLocalVars;
}
//-----------------------------------------------------------------------
cScriptVar *cScene::CreateGlobalVar(const tString &asName) {
cScriptVar *pVar;
pVar = GetGlobalVar(asName);
if (pVar == NULL) {
cScriptVar Var;
Var.msName = asName;
m_mapGlobalVars.insert(tScriptVarMap::value_type(cString::ToLowerCase(asName), Var));
pVar = GetGlobalVar(asName);
if (pVar == NULL)
error("Very strange error when creating script var!");
}
return pVar;
}
//-----------------------------------------------------------------------
cScriptVar *cScene::GetGlobalVar(const tString &asName) {
tScriptVarMapIt it = m_mapGlobalVars.find(cString::ToLowerCase(asName));
if (it == m_mapGlobalVars.end())
return NULL;
return &it->second;
}
//-----------------------------------------------------------------------
tScriptVarMap *cScene::GetGlobalVarMap() {
return &m_mapGlobalVars;
}
//-----------------------------------------------------------------------
void cScene::UpdateRenderList(float afFrameTime) {
if (mbDrawScene && mpActiveCamera) {
if (mpActiveCamera->GetType() == eCameraType_3D) {
cCamera3D *pCamera3D = static_cast<cCamera3D *>(mpActiveCamera);
if (mpCurrentWorld3D)
mpGraphics->GetRenderer3D()->UpdateRenderList(mpCurrentWorld3D, pCamera3D, afFrameTime);
}
}
}
//-----------------------------------------------------------------------
void cScene::SetDrawScene(bool abX) {
mbDrawScene = abX;
mpGraphics->GetRenderer3D()->GetRenderList()->Clear();
}
//-----------------------------------------------------------------------
void cScene::Render(cUpdater *apUpdater, float afFrameTime) {
if (mbDrawScene && mpActiveCamera) {
if (mpActiveCamera->GetType() == eCameraType_2D) {
cCamera2D *pCamera2D = static_cast<cCamera2D *>(mpActiveCamera);
// pCamera2D->SetModelViewMatrix(mpGraphics->GetLowLevel());
if (mpCurrentWorld2D) {
mpCurrentWorld2D->Render(pCamera2D);
mpGraphics->GetRenderer2D()->RenderObjects(pCamera2D, mpCurrentWorld2D->GetGridMapLights(), mpCurrentWorld2D);
}
} else {
cCamera3D *pCamera3D = static_cast<cCamera3D *>(mpActiveCamera);
if (mpCurrentWorld3D) {
START_TIMING(RenderWorld)
mpGraphics->GetRenderer3D()->RenderWorld(mpCurrentWorld3D, pCamera3D, afFrameTime);
STOP_TIMING(RenderWorld)
}
}
START_TIMING(PostSceneDraw)
apUpdater->OnPostSceneDraw();
STOP_TIMING(PostSceneDraw)
START_TIMING(PostEffects)
mpGraphics->GetRendererPostEffects()->Render();
STOP_TIMING(PostEffects)
} else {
apUpdater->OnPostSceneDraw();
// S
// mpGraphics->GetLowLevel()->SetClearColor(cColor(0,1));
// mpGraphics->GetLowLevel()->ClearScreen();
}
mpGraphics->GetDrawer()->DrawAll();
apUpdater->OnPostGUIDraw();
}
//-----------------------------------------------------------------------
void cScene::Update(float afTimeStep) {
if (mpActiveCamera == NULL)
return;
if (mpActiveCamera->GetType() == eCameraType_2D) {
if (mbUpdateMap && mpCurrentWorld2D) {
mpCurrentWorld2D->Update(afTimeStep);
if (mpCurrentWorld2D->GetScript()) {
mpCurrentWorld2D->GetScript()->Run("OnUpdate()");
}
mpGraphics->GetDrawer()->UpdateBackgrounds();
}
} else {
if (mbCameraIsListener) {
cCamera3D *pCamera3D = static_cast<cCamera3D *>(mpActiveCamera);
mpSound->GetLowLevel()->SetListenerAttributes(
pCamera3D->GetPosition(),
cVector3f(0, 0, 0),
pCamera3D->GetForward() * -1.0f,
pCamera3D->GetUp());
}
if (mbUpdateMap && mpCurrentWorld3D) {
mpCurrentWorld3D->Update(afTimeStep);
if (mpCurrentWorld3D->GetScript()) {
mpCurrentWorld3D->GetScript()->Run("OnUpdate()");
}
}
}
}
//-----------------------------------------------------------------------
void cScene::Reset() {
m_mapLocalVars.clear();
m_mapGlobalVars.clear();
m_setLoadedMaps.clear();
}
//-----------------------------------------------------------------------
void cScene::RenderWorld2D(cCamera2D *apCam, cWorld2D *apWorld) {
if (apWorld) {
apWorld->Render(apCam);
mpGraphics->GetRenderer2D()->RenderObjects(apCam, apWorld->GetGridMapLights(), apWorld);
}
}
//-----------------------------------------------------------------------
cWorld3D *cScene::LoadWorld3D(const tString &asFile, bool abLoadScript, tWorldLoadFlag aFlags) {
// Clear the local script
m_mapLocalVars.clear();
///////////////////////////////////
// Load the map file
tString asPath = mpResources->GetFileSearcher()->GetFilePath(asFile);
if (asPath == "") {
Error("World '%s' doesn't exist\n", asFile.c_str());
return NULL;
}
cWorld3D *pWorld = mpResources->GetMeshLoaderHandler()->LoadWorld(asPath, aFlags);
if (pWorld == NULL) {
Error("Couldn't load world from '%s'\n", asPath.c_str());
return NULL;
}
////////////////////////////////////////////////////////////
// Load the script
iScript *pScript = NULL;
if (abLoadScript) {
tString sScriptFile = cString::SetFileExt(asFile, "hps");
pScript = mpResources->GetScriptManager()->CreateScript(sScriptFile);
if (pScript == NULL) {
Error("Couldn't load script '%s'\n", sScriptFile.c_str());
} else {
pWorld->SetScript(pScript);
}
}
SetWorld3D(pWorld);
////////////////////////////
// Add to loaded maps
tString sName = cString::ToLowerCase(cString::SetFileExt(asFile, ""));
tStringSetIt it = m_setLoadedMaps.find(sName);
if (it == m_setLoadedMaps.end()) {
m_setLoadedMaps.insert(sName);
}
////////////////////////////////////////////////////////////
// Run script start functions
/*if(pScript)
{
//Check if the map has been loaded before, if not run OnStart script.
tString sName = cString::ToLowerCase(cString::SetFileExt(asFile,""));
tStringSetIt it = m_setLoadedMaps.find(sName);
if(it == m_setLoadedMaps.end())
{
m_setLoadedMaps.insert(sName);
pScript->Run("OnStart()");
}
}*/
return pWorld;
}
//-----------------------------------------------------------------------
cWorld3D *cScene::CreateWorld3D(const tString &asName) {
cWorld3D *pWorld = hplNew(cWorld3D, (asName, mpGraphics, mpResources, mpSound, mpPhysics, this,
mpSystem, mpAI));
mlstWorld3D.push_back(pWorld);
return pWorld;
}
//-----------------------------------------------------------------------
void cScene::DestroyWorld3D(cWorld3D *apWorld) {
STLFindAndDelete(mlstWorld3D, apWorld);
}
//-----------------------------------------------------------------------
void cScene::SetWorld3D(cWorld3D *apWorld) {
mpCurrentWorld3D = apWorld;
// Set the world the sound handler uses.
mpSound->GetSoundHandler()->SetWorld3D(mpCurrentWorld3D);
// Set the world for physics.
mpPhysics->SetGameWorld(mpCurrentWorld3D);
}
//-----------------------------------------------------------------------
bool cScene::HasLoadedWorld(const tString &asFile) {
tString sName = cString::ToLowerCase(cString::SetFileExt(asFile, ""));
tStringSetIt it = m_setLoadedMaps.find(sName);
if (it == m_setLoadedMaps.end())
return false;
else
return true;
}
//-----------------------------------------------------------------------
bool cScene::LoadMap2D(tString asFile) {
mpGraphics->GetDrawer()->ClearBackgrounds();
cWorld2D *pTempWorld = NULL;
// temporary save the old map
if (mpCurrentWorld2D) {
pTempWorld = mpCurrentWorld2D;
}
// Clear the local script
m_mapLocalVars.clear();
mpCurrentWorld2D = hplNew(cWorld2D, ("", mpGraphics, mpResources, mpSound, mpCollider2D));
if (mpCurrentWorld2D->CreateFromFile(asFile) == false)
return false;
if (mpCurrentWorld2D->GetScript()) {
// Check if the map has been loaded before, if not run OnStart script.
tString sName = cString::ToLowerCase(cString::SetFileExt(asFile, ""));
tStringSetIt it = m_setLoadedMaps.find(sName);
if (it == m_setLoadedMaps.end()) {
m_setLoadedMaps.insert(sName);
mpCurrentWorld2D->GetScript()->Run("OnStart()");
}
mpCurrentWorld2D->GetScript()->Run("OnLoad()");
}
mpCollider2D->SetWorld(mpCurrentWorld2D);
if (pTempWorld) {
hplDelete(pTempWorld);
}
return true;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,165 @@
/* 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.
*/
#ifndef HPL_SCENE_H
#define HPL_SCENE_H
#include "hpl1/engine/game/GameTypes.h"
#include "hpl1/engine/system/SystemTypes.h"
#include "hpl1/engine/game/Updateable.h"
#include "hpl1/engine/scene/Camera3D.h"
#include "common/list.h"
#include "hpl1/engine/resources/MeshLoader.h"
namespace hpl {
class cAI;
class cGraphics;
class cResources;
class cSystem;
class cSound;
class cPhysics;
class cCollider2D;
class iCamera;
class cCamera2D;
class cUpdater;
class cWorld3D;
class cWorld2D;
typedef Common::List<iCamera *> tCameraList;
typedef tCameraList::iterator tCameraListIt;
typedef Common::List<cWorld3D *> tWorld3DList;
typedef tWorld3DList::iterator tWorld3DListIt;
class cScene : public iUpdateable {
public:
cScene(cGraphics *apGraphics, cResources *apResources, cSound *apSound, cPhysics *apPhysics,
cSystem *apSystem, cAI *apAI);
~cScene();
void Reset();
/**
* Called by cGame
*/
void UpdateRenderList(float afFrameTime);
/**
* Called by cGame
*/
void Render(cUpdater *apUpdater, float afFrameTime);
bool LoadMap2D(tString asFile);
void RenderWorld2D(cCamera2D *apCam, cWorld2D *apWorld);
void Update(float afTimeStep);
void ClearLoadedMaps() { m_setLoadedMaps.clear(); }
tStringSet *GetLoadedMapsSet() { return &m_setLoadedMaps; }
void SetDrawScene(bool abX);
bool GetDrawScene() { return mbDrawScene; }
///// SCRIPT VAR METHODS ////////////////////
cScriptVar *CreateLocalVar(const tString &asName);
cScriptVar *GetLocalVar(const tString &asName);
tScriptVarMap *GetLocalVarMap();
cScriptVar *CreateGlobalVar(const tString &asName);
cScriptVar *GetGlobalVar(const tString &asName);
tScriptVarMap *GetGlobalVarMap();
///// CAMERA 2D METHODS ////////////////////
cCamera2D *CreateCamera2D(unsigned int alW, unsigned int alH);
cCamera3D *CreateCamera3D(eCameraMoveMode aMoveMode);
void DestroyCamera(iCamera *apCam);
/**
* This sets the current camera, depending on this one is 2D or 3D a 2D or 3D world will be rendered.
* \param pCam
*/
void SetCamera(iCamera *pCam);
iCamera *GetCamera() { return mpActiveCamera; }
void SetCameraPosition(const cVector3f &avPos);
cVector3f GetCameraPosition();
void SetCameraIsListener(bool abX) { mbCameraIsListener = abX; }
///// WORLD METHODS ////////////////////
cWorld3D *LoadWorld3D(const tString &asFile, bool abLoadScript, tWorldLoadFlag aFlags);
cWorld3D *CreateWorld3D(const tString &asName);
void DestroyWorld3D(cWorld3D *apWorld);
void SetWorld3D(cWorld3D *apWorld);
cWorld3D *GetWorld3D() { return mpCurrentWorld3D; }
bool HasLoadedWorld(const tString &asFile);
cWorld2D *GetWorld2D() { return mpCurrentWorld2D; }
cCollider2D *GetCollider2D() { return mpCollider2D; }
void SetUpdateMap(bool abX) { mbUpdateMap = abX; }
bool GetUpdateMap() { return mbUpdateMap; }
cSystem *GetSystem() { return mpSystem; }
private:
cGraphics *mpGraphics;
cResources *mpResources;
cSound *mpSound;
cPhysics *mpPhysics;
cSystem *mpSystem;
cAI *mpAI;
cCollider2D *mpCollider2D;
bool mbDrawScene;
bool mbUpdateMap;
tWorld3DList mlstWorld3D;
cWorld3D *mpCurrentWorld3D;
cWorld2D *mpCurrentWorld2D;
tCameraList mlstCamera;
iCamera *mpActiveCamera;
bool mbCameraIsListener;
tScriptVarMap m_mapLocalVars;
tScriptVarMap m_mapGlobalVars;
tStringSet m_setLoadedMaps;
};
} // namespace hpl
#endif // HPL_SCENE_H

View File

@@ -0,0 +1,419 @@
/* 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/SectorVisibility.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/scene/PortalContainer.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// PORTAL VISIBILTY SET
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cPortalVisibility::cPortalVisibility() {
}
//-----------------------------------------------------------------------
cPortalVisibility::~cPortalVisibility() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PORTAL VISIBILTY SET
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cPortalVisibilitySet::cPortalVisibilitySet(cSectorVisibilityContainer *apContainer,
cPortalVisibilitySet *apParent) {
mpParent = apParent;
mpContainer = apContainer;
}
cPortalVisibilitySet::~cPortalVisibilitySet() {
STLDeleteAll(mvVisibility);
}
//-----------------------------------------------------------------------
int cPortalVisibilitySet::AddPortalVisibility(cPortal *apPortal) {
mvVisibility.push_back(hplNew(cPortalVisibility, ()));
size_t lIdx = mvVisibility.size() - 1;
mvVisibility[lIdx]->mpPortal = apPortal;
// Calculate the shadow volume, range is not really need. Just set a high value.
cShadowVolumeBV *pShadow = apPortal->GetBV()->GetShadowVolume(mpContainer->GetOrigin(), 9999.0f, true);
if (pShadow) {
mvVisibility[lIdx]->mShadow = *pShadow;
mvVisibility[lIdx]->mbNullShadow = false;
} else {
mvVisibility[lIdx]->mbNullShadow = true;
}
return (int)lIdx;
}
//-----------------------------------------------------------------------
bool cPortalVisibilitySet::PortalExists(cPortal *apPortal) {
for (size_t i = 0; i < mvVisibility.size(); ++i) {
if (mvVisibility[i]->mpPortal == apPortal)
return true;
}
return false;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SECTOR VISIBILTY
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSectorVisibility::cSectorVisibility(cSectorVisibilityContainer *apContainer) {
mpSector = NULL;
bStart = false;
mpContainer = apContainer;
}
cSectorVisibility::~cSectorVisibility() {
}
//-----------------------------------------------------------------------
cPortalVisibilitySet *cSectorVisibility::GetSetConnectingFromSector(cSector *apSector) {
for (size_t i = 0; i < mvVisibiltySets.size(); ++i) {
if (mvVisibiltySets[i]->GetVisibility(0)->mpPortal->GetSector() == apSector) {
return mvVisibiltySets[i];
}
}
return NULL;
}
//-----------------------------------------------------------------------
void cSectorVisibility::AddVisibilitySet(cPortalVisibilitySet *apSet) {
mvVisibiltySets.push_back(apSet);
}
//-----------------------------------------------------------------------
bool cSectorVisibility::PortalExists(cPortal *apPortal) {
for (size_t i = 0; i < mvVisibiltySets.size(); ++i) {
if (mvVisibiltySets[i]->PortalExists(apPortal))
return true;
}
return false;
}
//-----------------------------------------------------------------------
bool cSectorVisibility::IntersectionBV(cBoundingVolume *apBV) {
if (mvVisibiltySets.empty()) {
// Log("Checking start sector %s\n",mpSector->GetId().c_str());
return mpContainer->IntersectionBV(apBV, NULL);
} else {
// Log("Checking sector %s with %d sets\n", mpSector->GetId().c_str(), mvVisibiltySets.size());
for (size_t i = 0; i < mvVisibiltySets.size(); ++i) {
if (mpContainer->IntersectionBV(apBV, mvVisibiltySets[i])) {
return true;
}
}
return false;
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SECTOR VISIBILTY CONTAINER
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSectorVisibilityContainer::cSectorVisibilityContainer(eSectorVisibilityType aType) {
mType = aType;
mbLog = false;
mlTabs = 0;
}
cSectorVisibilityContainer::~cSectorVisibilityContainer() {
STLMapDeleteAll(m_mapSectors);
STLDeleteAll(mlstPortalVisibilty);
}
//-----------------------------------------------------------------------
cPortalVisibilitySet *cSectorVisibilityContainer::CreatePortalVisibiltySet(cPortalVisibilitySet *apParent) {
cPortalVisibilitySet *pSet = hplNew(cPortalVisibilitySet, (this, apParent));
// Add to visibility list.
mlstPortalVisibilty.push_back(pSet);
return pSet;
}
//-----------------------------------------------------------------------
cSectorVisibility *cSectorVisibilityContainer::GetSectorVisibilty(cSector *apSector) {
// Check if the sector has already been checked.
tSectorVisibilityMapIt it = m_mapSectors.find(apSector);
// The sector has not been added, create visibility and add.
if (it == m_mapSectors.end()) {
if (mbLog)
Log("%sCreating Visibility sector for '%s'!\n", GetTabs().c_str(), apSector->GetId().c_str());
cSectorVisibility *pVisSector = hplNew(cSectorVisibility, (this));
pVisSector->mpSector = apSector;
m_mapSectors.insert(tSectorVisibilityMap::value_type(apSector, pVisSector));
return pVisSector;
}
// The sector exists, return it.
else {
if (mbLog)
Log("%sVisibility sector for '%s' already exist!\n", GetTabs().c_str(), apSector->GetId().c_str());
return it->second;
}
}
//-----------------------------------------------------------------------
void cSectorVisibilityContainer::Compute(cPortalContainer *apContainer) {
/////////////////////////////////////
// Check what sectors the type starts in
// Check the portals in these
tSectorMap *pSectorMap = apContainer->GetSectorMap();
if (mbLog)
Log("Checking for start sectors\n");
// Clear start sectors
m_setStartSectors.clear();
// Get the origin.
if (mType == eSectorVisibilityType_BV)
mvOrigin = mBoundingVolume.GetPosition();
else if (mType == eSectorVisibilityType_Frustum)
mvOrigin = mFrustum.GetOrigin();
///////////////////////////////////
// Check what start start sectors are
tSectorMapIt it = pSectorMap->begin();
for (; it != pSectorMap->end(); ++it) {
cSector *pSector = it->second;
if (cMath::PointBVCollision(mvOrigin, *pSector->GetBV())) {
if (mbLog)
Log("Sector '%s' is a start!\n", pSector->GetId().c_str());
m_setStartSectors.insert(pSector);
}
}
/////////////////////////////////
// Iterate the start sectors
tSectorSetIt startIt = m_setStartSectors.begin();
for (; startIt != m_setStartSectors.end(); ++startIt) {
cSector *pSector = *startIt;
SearchSector(pSector, NULL, 0);
}
if (mbLog)
Log("Done checking start sectors!\n");
}
tSectorVisibilityIterator cSectorVisibilityContainer::GetSectorIterator() {
return tSectorVisibilityIterator(&m_mapSectors);
}
//-----------------------------------------------------------------------
void cSectorVisibilityContainer::SearchSector(cSector *apSector, cPortalVisibilitySet *apParentSet,
int alPortalIndex) {
if (mbLog) {
Log("%s--- Searching sector %s\n%s---------------------------------------\n",
GetTabs().c_str(),
apSector->GetId().c_str(),
GetTabs().c_str());
mlTabs++;
}
cSectorVisibility *pVisSector = GetSectorVisibilty(apSector);
// Save all portals encountered here.
tPortalList lstNewPortals;
//////////////////////////////////
// Go through all portals and see which
tPortalList *pPortalList = NULL;
// Get the portals to search
if (apParentSet) {
if (mbLog)
Log("%sSearching portals from parent portal %d with index %d\n", GetTabs().c_str(), apParentSet->GetVisibility(alPortalIndex)->mpPortal->GetId(), alPortalIndex);
pPortalList = apParentSet->GetVisibility(alPortalIndex)->mpPortal->GetPortalList();
} else {
if (mbLog)
Log("%sNo parent set, searching all portals.\n", GetTabs().c_str());
pPortalList = apSector->GetPortalList();
}
// Iterate the portals
tPortalListIt it = pPortalList->begin();
for (; it != pPortalList->end(); ++it) {
cPortal *pPortal = *it;
cSector *pTargetSector = pPortal->GetTargetSector();
// Check if it is a start sector
if (m_setStartSectors.find(pTargetSector) != m_setStartSectors.end()) {
continue;
}
/////////////////////////////////////////
// Check that the portal that it is intersected and does not already exist
if (pVisSector->PortalExists(pPortal) == false &&
IntersectionBV(pPortal->GetBV(), apParentSet) &&
pPortal->GetActive()) {
if (mbLog)
Log("%sFound new valid portal %d\n", GetTabs().c_str(), pPortal->GetId());
///////////////////////////////////////////////////////
// Check if the portal is facing the right direction
if (cMath::PlaneToPointDist(pPortal->GetPlane(), mvOrigin) < 0.0f) {
continue;
}
cSectorVisibility *pTargetVisSector = GetSectorVisibilty(pTargetSector);
////////////////////////////////////////
// Check if there is another visibility set connecting to the same room
cPortalVisibilitySet *pSet = pTargetVisSector->GetSetConnectingFromSector(pTargetSector);
// If none exist, create new set.
if (pSet == NULL) {
// Create portal visibility and add it to the sector container
pSet = CreatePortalVisibiltySet(apParentSet);
// Add to the specific container
pTargetVisSector->AddVisibilitySet(pSet);
if (mbLog)
Log("%sNo portal connecting from %s to %s, creating new visibility set\n",
GetTabs().c_str(),
apSector->GetId().c_str(),
pTargetSector->GetId().c_str());
}
int lIdx = pSet->AddPortalVisibility(pPortal);
SearchSector(pTargetSector, pSet, lIdx);
} else {
if (mbLog)
Log("%sSkipped unvalid portal %d\n", GetTabs().c_str(), pPortal->GetId());
}
}
if (mbLog) {
mlTabs--;
Log("%s------------------------------------\n%s--- Done searching sector %s!\n",
GetTabs().c_str(),
GetTabs().c_str(),
apSector->GetId().c_str());
}
}
//-----------------------------------------------------------------------
bool cSectorVisibilityContainer::IntersectionBV(cBoundingVolume *apBV, cPortalVisibilitySet *pVisibilitySet) {
///////////////////////////////////////////
// First check with the portal visibility
if (pVisibilitySet) {
cPortalVisibilitySet *pSet = pVisibilitySet;
while (pSet) {
bool bIntersection = false;
size_t lVisibilityNum = pSet->GetVisibilityNum();
for (size_t i = 0; i < lVisibilityNum; ++i) {
if (pSet->GetVisibility(i)->mbNullShadow ||
pSet->GetVisibility(i)->mShadow.CollideBoundingVolume(apBV)) {
bIntersection = true;
break;
}
}
if (bIntersection == false)
return false;
pSet = pSet->GetParent();
}
}
//////////////////////////////////////////
// Check with the type
// BV:
if (mType == eSectorVisibilityType_BV) {
return cMath::CheckCollisionBV(mBoundingVolume, *apBV);
}
// Frustum:
else {
return mFrustum.CollideBoundingVolume(apBV) != eFrustumCollision_Outside;
}
}
//-----------------------------------------------------------------------
tString cSectorVisibilityContainer::GetTabs() {
tString sTabs = "";
for (int i = 0; i < mlTabs; ++i)
sTabs += " ";
return sTabs;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,183 @@
/* 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.
*/
#ifndef HPL_SECTOR_VISIBILTY_H
#define HPL_SECTOR_VISIBILTY_H
#include "hpl1/engine/math/BoundingVolume.h"
#include "hpl1/engine/math/Frustum.h"
namespace hpl {
class cPortal;
class cSector;
class cPortalContainer;
class cSectorVisibilityContainer;
enum eSectorVisibilityType {
eSectorVisibilityType_BV,
eSectorVisibilityType_Frustum,
};
//----------------------------------------------------
/**
* Represent the visibility for one portal
*/
class cPortalVisibility {
public:
cPortalVisibility();
~cPortalVisibility();
cShadowVolumeBV mShadow;
cPortal *mpPortal;
bool mbNullShadow;
};
//----------------------------------------------------
/**
* Represent the visibility from one sector to another
* this may include several portals.
*/
class cPortalVisibilitySet {
friend class cSectorVisibilityContainer;
public:
cPortalVisibilitySet(cSectorVisibilityContainer *apContainer, cPortalVisibilitySet *apParent);
~cPortalVisibilitySet();
cPortalVisibilitySet *GetParent() { return mpParent; }
inline cPortalVisibility *GetVisibility(size_t alIdx) { return mvVisibility[alIdx]; }
inline size_t GetVisibilityNum() { return mvVisibility.size(); }
bool PortalExists(cPortal *apPortal);
int AddPortalVisibility(cPortal *apPortal);
private:
Common::Array<cPortalVisibility *> mvVisibility;
cPortalVisibilitySet *mpParent;
cSectorVisibilityContainer *mpContainer;
};
//----------------------------------------------------
/**
* Represent the visibility of one sector.
*/
class cSectorVisibility {
friend class cSectorVisibilityContainer;
public:
cSectorVisibility(cSectorVisibilityContainer *apContainer);
~cSectorVisibility();
bool PortalExists(cPortal *apPortal);
cPortalVisibilitySet *GetSetConnectingFromSector(cSector *apSector);
void AddVisibilitySet(cPortalVisibilitySet *apSet);
cSector *GetSector() const { return mpSector; }
bool IntersectionBV(cBoundingVolume *apBV);
private:
cSector *mpSector;
Common::Array<cPortalVisibilitySet *> mvVisibiltySets;
bool bStart;
cSectorVisibilityContainer *mpContainer;
};
typedef Common::StableMap<cSector *, cSectorVisibility *> tSectorVisibilityMap;
typedef tSectorVisibilityMap::iterator tSectorVisibilityMapIt;
//----------------------------------------------------
typedef Common::List<cPortalVisibilitySet *> tPortalVisibilitySetList;
typedef tPortalVisibilitySetList::iterator tPortalVisibilitySetListIt;
typedef Hpl1::Std::set<cSector *> tSectorSet;
typedef tSectorSet::iterator tSectorSetIt;
typedef cSTLMapIterator<cSectorVisibility *, tSectorVisibilityMap, tSectorVisibilityMapIt> tSectorVisibilityIterator;
/**
* Container of visibility of all the sectors.
*/
class cSectorVisibilityContainer {
public:
cSectorVisibilityContainer(eSectorVisibilityType aType);
~cSectorVisibilityContainer();
void SetFrustum(const cFrustum &aFrustum) { mFrustum = aFrustum; }
void SetBV(const cBoundingVolume &aBV) { mBoundingVolume = aBV; }
const cVector3f &GetOrigin() { return mvOrigin; }
void Compute(cPortalContainer *apContainer);
cPortalVisibilitySet *CreatePortalVisibiltySet(cPortalVisibilitySet *apParent);
cSectorVisibility *GetSectorVisibilty(cSector *apSector);
tSectorVisibilityIterator GetSectorIterator();
bool IntersectionBV(cBoundingVolume *apBV, cPortalVisibilitySet *apSet);
bool mbLog;
private:
void SearchSector(cSector *apSector, cPortalVisibilitySet *apParentSet, int alPortalIndex);
tString GetTabs();
// cPortalContainer *mpContainer;
tSectorSet m_setStartSectors;
tSectorVisibilityMap m_mapSectors;
eSectorVisibilityType mType;
tPortalVisibilitySetList mlstPortalVisibilty;
cVector3f mvOrigin;
cBoundingVolume mBoundingVolume;
cFrustum mFrustum;
int mlTabs;
};
//----------------------------------------------------
} // namespace hpl
#endif // HPL_SECTOR_VISIBILTY_H

View File

@@ -0,0 +1,609 @@
/* 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/SoundEntity.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/resources/SoundEntityManager.h"
#include "hpl1/engine/sound/LowLevelSound.h"
#include "hpl1/engine/sound/Sound.h"
#include "hpl1/engine/sound/SoundChannel.h"
#include "hpl1/engine/sound/SoundEntityData.h"
#include "hpl1/engine/sound/SoundHandler.h"
#include "hpl1/engine/game/Game.h"
#include "hpl1/engine/scene/Scene.h"
#include "hpl1/engine/scene/World3D.h"
namespace hpl {
tSoundEntityGlobalCallbackList *cSoundEntity::mlstGlobalCallbacks = nullptr;
void cSoundEntity::initGlobalCallbackList() {
cSoundEntity::mlstGlobalCallbacks = new tSoundEntityGlobalCallbackList;
}
void cSoundEntity::finalizeGlobalCallbackList() {
delete cSoundEntity::mlstGlobalCallbacks;
}
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSoundEntity::cSoundEntity(const tString &asName, cSoundEntityData *apData,
cSoundEntityManager *apSoundEntityManager,
cWorld3D *apWorld,
cSoundHandler *apSoundHandler, bool abRemoveWhenOver)
: iEntity3D(asName) {
mbRemoveWhenOver = abRemoveWhenOver;
// Log("Created sound entity '%s'\n",msName.c_str());
mpSoundHandler = apSoundHandler;
mpSoundEntityManager = apSoundEntityManager;
mpWorld = apWorld;
mpData = apData;
mBoundingVolume.SetSize(mpData->GetMaxDistance() * 2);
for (int i = 0; i < 3; i++) {
mvSounds[i] = NULL;
// mvSoundEntries[i] = NULL;
mvSoundId[i] = -1;
}
mfIntervalCount = mpData->GetInterval();
mfVolume = mpData->GetVolume();
mbStopped = false; // If the sound should be stopped
mbStarted = false; // If the sound started playing-
mbSkipStartEnd = false; // If the end and start sounds should be skipped.
mbPrioRemove = false; // If the sounds was removed because too many where playing
mbFadingOut = false; // If the sound is fading out.
mbOutOfRange = false; // If the sound is out of range.
mbLog = false;
mfSleepCount = 0;
mpSoundCallback = hplNew(cSoundEntityChannelCallback, ());
mpSoundCallback->mpEntity = this;
if (mpSoundHandler->GetSilent()) {
mbStarted = true;
mbStopped = true;
mfVolume = 0;
mbSkipStartEnd = true;
mbRemoveWhenOver = true;
}
}
cSoundEntity::~cSoundEntity() {
if (mbLog)
Log("Delete entity start...");
for (int i = 0; i < 3; i++) {
if (mpSoundHandler->IsValid(mvSounds[i])) {
mvSounds[i]->Stop();
}
}
hplDelete(mpSoundCallback);
if (mbLog)
Log("end\n");
// Not sure if this should be here. SOund entities take little memory
// might be better of releasing all of em at exit.
// mpSoundEntityManager->Destroy(mpData);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cSoundEntityChannelCallback::OnPriorityRelease() {
if (mpEntity->mbStopped || mpEntity->mbFadingOut)
return;
mpEntity->mbPrioRemove = true;
}
//-----------------------------------------------------------------------
cSoundEntry *cSoundEntity::GetSoundEntry(eSoundEntityType aType) {
if (mvSounds[aType] == NULL)
return NULL;
// if(mvSoundEntries[aType]==NULL)
//{
// mvSoundEntries[aType] = mpSoundHandler->GetEntryFromSound(mvSounds[aType]);
// }
// return mvSoundEntries[aType];
// if(mpSoundHandler->IsValid(mvSounds[aType])==false) return NULL;
return mpSoundHandler->GetEntryFromSound(mvSounds[aType]);
}
//-----------------------------------------------------------------------
void cSoundEntity::Play(bool abPlayStart) {
if (mpSoundHandler->GetSilent())
return;
if (mbLog)
Log("Play entity start...");
mbStopped = false;
mbOutOfRange = false;
mbFadingOut = false;
if (abPlayStart && mbSkipStartEnd == false) {
if (mpData->GetLoop() && mpData->GetStartSoundName() != "") {
PlaySound(mpData->GetStartSoundName(), false, eSoundEntityType_Start);
mbStarted = false;
}
}
if (mvSounds[eSoundEntityType_Main] == NULL && mvSounds[eSoundEntityType_Start] == NULL && (mpData->GetLoop() == false || mpData->GetInterval() == 0)) {
PlaySound(mpData->GetMainSoundName(), mpData->GetLoop(), eSoundEntityType_Main);
mbStarted = true;
// Log("-- Start playing sound %s\n",msName.c_str());
} else {
/*Log("-- Couldn't play sound %s\n",msName.c_str());
Log("Main: %d Start: %d Loop: %d Interval: %f\n",
(int)mvSounds[eSoundEntityType_Main],
(int)mvSounds[eSoundEntityType_Start],
mpData->GetLoop() ? 1 : 0,
mpData->GetInterval());*/
}
if (mbLog)
Log("end\n");
}
//-----------------------------------------------------------------------
void cSoundEntity::Stop(bool abPlayEnd) {
if (mbStopped)
return;
mbStopped = true;
mbOutOfRange = false;
// mvSoundEntries[eSoundEntityType_Main] = NULL;
if (mvSounds[eSoundEntityType_Main] == NULL)
return;
// Log("entity Stopping %s\n",mpData->GetName().c_str());
if (mbLog)
Log("Stop entity start...");
if (mpData->GetLoop()) {
if (abPlayEnd && mbSkipStartEnd == false) {
PlaySound(mpData->GetStopSoundName(), false, eSoundEntityType_Stop);
}
if (mpSoundHandler->IsValid(mvSounds[eSoundEntityType_Main])) {
mvSounds[eSoundEntityType_Main]->Stop();
}
} else {
if (mpSoundHandler->IsValid(mvSounds[eSoundEntityType_Main])) {
mvSounds[eSoundEntityType_Main]->Stop();
}
}
mvSounds[eSoundEntityType_Main] = NULL;
if (mbLog)
Log("End\n");
}
//-----------------------------------------------------------------------
void cSoundEntity::FadeIn(float afSpeed) {
if (mpSoundHandler->GetSilent())
return;
if (mbLog)
Log("Fade in entity start...");
Play(false);
cSoundEntry *pEntry = GetSoundEntry(eSoundEntityType_Main);
if (pEntry) {
pEntry->mfNormalVolumeMul = 0;
pEntry->mfNormalVolumeFadeDest = 1;
pEntry->mfNormalVolumeFadeSpeed = afSpeed;
if (pEntry->mfNormalVolumeFadeSpeed < 0)
pEntry->mfNormalVolumeFadeSpeed = -pEntry->mfNormalVolumeFadeSpeed;
// Log("Setting speed: %f\n",pEntry->mfNormalVolumeFadeSpeed);
}
if (mbLog)
Log("end\n");
}
void cSoundEntity::FadeOut(float afSpeed) {
mbFadingOut = true;
_fadeSpeed = afSpeed;
if (mpSoundHandler->GetSilent())
return;
if (mbLog)
Log("Fade out entity start...");
if (mvSounds[eSoundEntityType_Main] == NULL) {
mbStopped = true;
return;
}
cSoundEntry *pEntry = GetSoundEntry(eSoundEntityType_Main);
if (pEntry) {
pEntry->mfNormalVolumeFadeDest = 0;
pEntry->mfNormalVolumeFadeSpeed = afSpeed;
if (pEntry->mfNormalVolumeFadeSpeed > 0)
pEntry->mfNormalVolumeFadeSpeed = -pEntry->mfNormalVolumeFadeSpeed;
} else {
mbStopped = true;
}
if (mbLog)
Log("end\n");
}
//-----------------------------------------------------------------------
bool cSoundEntity::IsStopped() {
if (mbStopped && mvSounds[eSoundEntityType_Stop] == NULL) {
return true;
}
return false;
}
bool cSoundEntity::IsFadingOut() {
return mbFadingOut;
}
//-----------------------------------------------------------------------
bool cSoundEntity::GetRemoveWhenOver() {
return mbRemoveWhenOver;
}
//-----------------------------------------------------------------------
void cSoundEntity::UpdateLogic(float afTimeStep) {
if (mpSoundHandler->GetSilent()) {
return;
}
if (mfSleepCount > 0) {
mfSleepCount -= afTimeStep;
return;
}
//////////////////////////////////////////////
// If out of range check if it is inside range.
if (mbOutOfRange && mbStopped == false) {
float fRange = GetListenerSqrLength();
float fMaxRange = mpData->GetMaxDistance();
fMaxRange = fMaxRange * fMaxRange;
if (fRange < fMaxRange) {
Play(false);
mbOutOfRange = false;
} else {
return;
}
}
if (mbLog)
Log("Update entity start...");
/////////////////////////////////////////////////
// Go through all sounds and check if they are playing,
// if so update their positions else remove.
for (int i = 0; i < 3; i++) {
if (mvSounds[i]) {
if (mpSoundHandler->IsValidId(mvSounds[i], mvSoundId[i]) == false) {
mvSounds[i] = NULL;
// mvSoundEntries[i] = NULL;
// if the sound has stopped due to priority try starting again
if (mbPrioRemove && i == (int)eSoundEntityType_Main) {
if (mbStopped == false) {
mbStarted = false;
// mbPrioRemove = false;
mfSleepCount = 0.3f;
} else {
// if(mbLog)Log(" -Sound already stopped..\n");
}
}
// If the sound has already started, stop it.
else if ((mpData->GetInterval() == 0 || mpData->GetLoop() == false) &&
mbStarted) {
// Log("Stopping %s!\n",GetName().c_str());
mbStopped = true;
}
} else {
if (mbPrioRemove) {
// if(mbLog)Log(" -Removed + valid? This is baaaad!\n");
}
if (mvSounds[i] && !mvSounds[i]->GetPositionRelative()) {
mvSounds[i]->SetPosition(GetWorldPosition());
}
}
}
}
//////////////////////////////////////////////
// Check if sound is playing, and if so update it.
if (mbStopped == false) {
/////////////////////////////////////////////////////////////////////////
// Sound is not playing, start it and since it has not been invoked by Play
// no need to play start sound. Only do this if interval is 0 else it might
// be a deliberate pause.
if (mvSounds[eSoundEntityType_Main] == NULL && mvSounds[eSoundEntityType_Start] == NULL && (mpData->GetLoop() == false || mpData->GetInterval() == 0)) {
if (PlaySound(mpData->GetMainSoundName(), mpData->GetLoop(), eSoundEntityType_Main)) {
mbStarted = true;
mbPrioRemove = false;
// Call the callbacks that the sound has started.
tSoundEntityGlobalCallbackListIt it = mlstGlobalCallbacks->begin();
for (; it != mlstGlobalCallbacks->end(); ++it) {
iSoundEntityGlobalCallback *pCallback = *it;
pCallback->OnStart(this);
}
} else if (mbPrioRemove) {
mfSleepCount = 0.3f;
}
}
///////////////////////////////////////////////////////////
// Check if looping and interval is not 0.
// then there needs to be some updating.
if (mpData->GetLoop() && mpData->GetInterval() > 0 && mvSounds[eSoundEntityType_Start] == NULL && mvSounds[eSoundEntityType_Main] == NULL) {
mfIntervalCount += afTimeStep;
// if the interval time has elapsed the sound might be played again.
if (mfIntervalCount >= mpData->GetInterval()) {
// Check random and if rand is right play the sound.
if (cMath::RandRectf(0, 1) <= mpData->GetRandom() ||
mpData->GetRandom() == 0) {
PlaySound(mpData->GetMainSoundName(), false, eSoundEntityType_Main);
}
mfIntervalCount = 0;
}
}
//////////////////////////////////////////////
// If the sound is looped and out of range, stop it
if (mvSounds[eSoundEntityType_Start] == NULL && mpData->GetLoop() && mpData->GetUse3D()) {
float fRange = GetListenerSqrLength();
float fMaxRange = mpData->GetMaxDistance() + 1.0f; // Add one meter to avoid oscillation
fMaxRange = fMaxRange * fMaxRange;
if (fRange > fMaxRange) {
if (mvSounds[eSoundEntityType_Main]) {
if (mpSoundHandler->IsValid(mvSounds[eSoundEntityType_Main])) {
mvSounds[eSoundEntityType_Main]->Stop();
}
mvSounds[eSoundEntityType_Main] = NULL;
if (mbFadingOut)
mbStopped = true;
}
mbOutOfRange = true;
}
}
}
if (mbLog)
Log("end\n");
}
//-----------------------------------------------------------------------
void cSoundEntity::AddGlobalCallback(iSoundEntityGlobalCallback *apCallback) {
mlstGlobalCallbacks->push_back(apCallback);
}
//-----------------------------------------------------------------------
void cSoundEntity::RemoveGlobalCallback(iSoundEntityGlobalCallback *apCallback) {
tSoundEntityGlobalCallbackListIt it = mlstGlobalCallbacks->begin();
for (; it != mlstGlobalCallbacks->end(); ++it) {
if (apCallback == *it) {
mlstGlobalCallbacks->erase(it);
return;
}
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cSoundEntity::PlaySound(const tString &asName, bool abLoop, eSoundEntityType aType) {
if (asName == "")
return false;
if (mpData->GetUse3D()) {
mvSounds[aType] = mpSoundHandler->Play3D(
asName, abLoop,
mfVolume, GetWorldPosition(),
mpData->GetMinDistance(), mpData->GetMaxDistance(),
eSoundDest_World, false, mpData->GetPriority());
} else {
mvSounds[aType] = mpSoundHandler->Play3D(
asName, abLoop,
mfVolume, cVector3f(0, 0, 1),
mpData->GetMinDistance(), mpData->GetMaxDistance(),
eSoundDest_World, true, mpData->GetPriority());
}
if (mvSounds[aType] == NULL) {
if (!mbPrioRemove)
Error("Couldn't play sound '%s' for sound entity %s\n", asName.c_str(), msName.c_str());
if (aType == eSoundEntityType_Main && !mbPrioRemove) {
mbStopped = true;
// mbRemoveWhenOver = true;
}
return false;
} else {
mvSounds[aType]->SetBlockable(mpData->GetBlockable());
mvSounds[aType]->SetBlockVolumeMul(mpData->GetBlockVolumeMul());
mvSounds[aType]->SetPriorityModifier(mpData->GetPriority());
mvSoundId[aType] = mvSounds[aType]->GetId();
if (aType == eSoundEntityType_Main) {
mvSounds[aType]->SetCallBack(mpSoundCallback);
}
}
return true;
// for(int i=0; i<3; ++i) mvSoundEntries[i] = NULL;
}
//-----------------------------------------------------------------------
float cSoundEntity::GetListenerSqrLength() {
cVector3f vListenerPos = mpWorld->GetSound()->GetLowLevel()->GetListenerPosition();
return cMath::Vector3DistSqr(vListenerPos, GetWorldPosition());
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SAVE OBJECT STUFF
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
kBeginSerialize(cSaveData_cSoundEntity, cSaveData_iEntity3D)
kSerializeVar(msData, eSerializeType_String)
kSerializeVar(mbStopped, eSerializeType_Bool)
kSerializeVar(mbRemoveWhenOver, eSerializeType_Bool)
kSerializeVar(mbStarted, eSerializeType_Bool)
kSerializeVar(mbFadingOut, eSerializeType_Bool)
kSerializeVar(mfVolume, eSerializeType_Float32)
kEndSerialize()
//-----------------------------------------------------------------------
iSaveObject *cSaveData_cSoundEntity::CreateSaveObject(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
cWorld3D *pWorld = apGame->GetScene()->GetWorld3D();
if (mbStopped && mbRemoveWhenOver)
return NULL;
// if(mbStopped && mbFadingOut) return NULL;
cSoundEntity *pEntity = pWorld->CreateSoundEntity(msName, msData, mbRemoveWhenOver);
if (mbFadingOut)
pEntity->Stop(false);
return pEntity;
}
//-----------------------------------------------------------------------
int cSaveData_cSoundEntity::GetSaveCreatePrio() {
return 3;
}
//-----------------------------------------------------------------------
iSaveData *cSoundEntity::CreateSaveData() {
return hplNew(cSaveData_cSoundEntity, ());
}
//-----------------------------------------------------------------------
void cSoundEntity::SaveToSaveData(iSaveData *apSaveData) {
kSaveData_SaveToBegin(cSoundEntity);
pData->msData = mpData == NULL ? "" : mpData->GetName();
kSaveData_SaveTo(mbStopped);
kSaveData_SaveTo(mbRemoveWhenOver);
kSaveData_SaveTo(mbStarted);
kSaveData_SaveTo(mbFadingOut);
kSaveData_SaveTo(mfVolume);
}
//-----------------------------------------------------------------------
void cSoundEntity::LoadFromSaveData(iSaveData *apSaveData) {
kSaveData_LoadFromBegin(cSoundEntity);
kSaveData_LoadFrom(mfVolume);
kSaveData_LoadFrom(mbStopped);
kSaveData_LoadFrom(mbRemoveWhenOver);
// kSaveData_LoadFrom(mbStarted);
}
//-----------------------------------------------------------------------
void cSoundEntity::SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
kSaveData_SetupBegin(cSoundEntity);
/*Log("-- %s After setup: Main: %d Start: %d Loop: %d Interval: %f Stopped: %d Started: %d\n",
msName.c_str(),
(int)mvSounds[eSoundEntityType_Main],
(int)mvSounds[eSoundEntityType_Start],
mpData->GetLoop() ? 1 : 0,
mpData->GetInterval(),
mbStopped ? 1 : 0,
mbStarted ? 1 : 0);*/
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,177 @@
/* 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.
*/
#ifndef HPL_SOUND_ENTITY_H
#define HPL_SOUND_ENTITY_H
#include "hpl1/engine/scene/Entity3D.h"
#include "hpl1/engine/sound/SoundChannel.h"
namespace hpl {
class cSoundHandler;
class cSoundEntityData;
class cSoundEntityManager;
class cWorld3D;
class cSoundEntry;
enum eSoundEntityType {
eSoundEntityType_Main,
eSoundEntityType_Start,
eSoundEntityType_Stop,
eSoundEntityType_LastEnum
};
class cSoundEntity;
class cSoundEntityChannelCallback : public iSoundChannelCallback {
public:
virtual ~cSoundEntityChannelCallback() = default;
void OnPriorityRelease();
cSoundEntity *mpEntity;
};
//----------------------------------------
kSaveData_ChildClass(iEntity3D, cSoundEntity) {
kSaveData_ClassInit(cSoundEntity) public : tString msData;
bool mbStopped;
bool mbRemoveWhenOver;
bool mbStarted;
bool mbFadingOut;
float mfVolume;
virtual iSaveObject *CreateSaveObject(cSaveObjectHandler * apSaveObjectHandler, cGame * apGame);
virtual int GetSaveCreatePrio();
};
//------------------------------------------
class iSoundEntityGlobalCallback {
public:
virtual ~iSoundEntityGlobalCallback() = default;
virtual void OnStart(cSoundEntity *apSoundEntity) = 0;
};
typedef Common::List<iSoundEntityGlobalCallback *> tSoundEntityGlobalCallbackList;
typedef tSoundEntityGlobalCallbackList::iterator tSoundEntityGlobalCallbackListIt;
//------------------------------------------
class cSoundEntity : public iEntity3D {
typedef iEntity3D super;
friend class cSoundEntityChannelCallback;
public:
static void initGlobalCallbackList();
static void finalizeGlobalCallbackList();
cSoundEntity(const tString &asName, cSoundEntityData *apData,
cSoundEntityManager *apSoundEntityManager,
cWorld3D *apWorld,
cSoundHandler *apSoundHandler, bool abRemoveWhenOver);
virtual ~cSoundEntity();
void Play(bool abPlayStart = true);
void Stop(bool abPlayEnd = true);
void FadeIn(float afSpeed);
void FadeOut(float afSpeed);
bool IsStopped();
bool IsFadingOut();
float getFadingSpeed() { return _fadeSpeed; }
bool GetRemoveWhenOver();
void SetVolume(float afX) { mfVolume = afX; }
float GetVolume() { return mfVolume; }
iSoundChannel *GetSound(eSoundEntityType aType) { return mvSounds[aType]; }
cSoundEntry *GetSoundEntry(eSoundEntityType aType);
// Entity implementation
void UpdateLogic(float afTimeStep);
tString GetEntityType() { return "SoundEntity"; }
cSoundEntityData *GetData() { return mpData; }
static void AddGlobalCallback(iSoundEntityGlobalCallback *apCallback);
static void RemoveGlobalCallback(iSoundEntityGlobalCallback *apCallback);
// SaveObject implementation
virtual iSaveData *CreateSaveData();
virtual void SaveToSaveData(iSaveData *apSaveData);
virtual void LoadFromSaveData(iSaveData *apSaveData);
virtual void SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
private:
bool PlaySound(const tString &asName, bool abLoop, eSoundEntityType aType);
float GetListenerSqrLength();
cSoundEntityManager *mpSoundEntityManager;
cSoundHandler *mpSoundHandler;
cSoundEntityData *mpData;
cWorld3D *mpWorld;
iSoundChannel *mvSounds[3];
// cSoundEntry *mvSoundEntries[3];
int mvSoundId[3];
bool mbStopped;
bool mbRemoveWhenOver;
bool mbOutOfRange;
float mfIntervalCount;
cSoundEntityChannelCallback *mpSoundCallback;
bool mbStarted;
bool mbFadingOut;
bool mbLog;
float mfVolume;
bool mbPrioRemove;
bool mbSkipStartEnd;
float mfSleepCount;
float _fadeSpeed;
static tSoundEntityGlobalCallbackList *mlstGlobalCallbacks;
};
} // namespace hpl
#endif // HPL_SOUND_ENTITY_H

View File

@@ -0,0 +1,194 @@
/* 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/SoundSource.h"
#include "hpl1/engine/impl/tinyXML/tinyxml.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/sound/Sound.h"
#include "hpl1/engine/sound/SoundChannel.h"
#include "hpl1/engine/sound/SoundHandler.h"
#include "hpl1/engine/system/String.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSoundSource::cSoundSource(const tString &asName, const tString &asSoundName, cSound *apSound, bool abVolatile)
: iEntity2D(asName) {
UpdateBoundingBox();
mpSound = apSound;
msSoundName = asSoundName;
mpSoundChannel = NULL;
mbVolatile = abVolatile;
msSoundName = asSoundName;
mlInterval = 0;
mbLoop = true;
mbRelative = false;
mfMaxDist = 1000;
mfMinDist = 1;
mlRandom = 0;
mfVolume = 1;
mlCounter = 0;
mbPlaying = false;
}
//-----------------------------------------------------------------------
cSoundSource::~cSoundSource() {
Stop();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cSoundSource::UpdateLogic(float afTimeStep) {
if (mbIsActive && !mbPlaying) {
if (mlRandom == 0) {
Play();
} else {
if (mlCounter >= mlInterval) {
if (cMath::RandRectl(0, mlRandom) == 0) {
Play();
mlCounter = 0;
}
} else {
mlCounter++;
}
}
// Update position
if (mbRelative == false) {
if (mpSound->GetSoundHandler()->IsValid(mpSoundChannel)) {
mpSoundChannel->SetPosition(GetWorldPosition());
}
}
}
}
//-----------------------------------------------------------------------
bool cSoundSource::IsDead() {
if (mbVolatile) {
if (mbIsActive == false && mbPlaying == false)
return true;
}
return false;
}
//-----------------------------------------------------------------------
bool cSoundSource::LoadData(TiXmlElement *apRootElem) {
mlInterval = cString::ToInt(apRootElem->Attribute("Interval"), 0);
mbLoop = cString::ToBool(apRootElem->Attribute("Loop"), false);
mbRelative = cString::ToBool(apRootElem->Attribute("Relative"), false);
mfMaxDist = cString::ToFloat(apRootElem->Attribute("MaxDist"), 100);
mfMinDist = cString::ToFloat(apRootElem->Attribute("MinDist"), 100);
mlRandom = cString::ToInt(apRootElem->Attribute("Random"), 100);
mfVolume = cString::ToFloat(apRootElem->Attribute("Volume"), 1);
if (!mbRelative) {
cVector3f vPos;
vPos.x = cString::ToFloat(apRootElem->Attribute("X"), 0);
vPos.y = cString::ToFloat(apRootElem->Attribute("Y"), 0);
vPos.z = cString::ToFloat(apRootElem->Attribute("Z"), 0);
SetPosition(vPos);
} else {
cVector3f vPos;
vPos.x = cString::ToFloat(apRootElem->Attribute("RelX"), 0);
vPos.y = cString::ToFloat(apRootElem->Attribute("RelY"), 0);
vPos.z = cString::ToFloat(apRootElem->Attribute("RelZ"), 0);
SetPosition(vPos);
}
return true;
}
//-----------------------------------------------------------------------
const cRect2f &cSoundSource::GetBoundingBox() {
return mBoundingBox;
}
//-----------------------------------------------------------------------
bool cSoundSource::UpdateBoundingBox() {
return true;
}
//-----------------------------------------------------------------------
void cSoundSource::Stop() {
mpSound->GetSoundHandler()->Stop(msSoundName);
mbIsActive = false;
mbPlaying = false;
mlCounter = 0;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cSoundSource::Play() {
cVector3f vPos;
if (mbRelative)
vPos = GetWorldPosition();
else
vPos = GetLocalPosition();
mpSoundChannel = mpSound->GetSoundHandler()->Play(msSoundName, mbLoop, mfVolume, vPos, mfMinDist, mfMaxDist,
eSoundDest_World, mbRelative);
mbPlaying = true;
if (!mbLoop)
mbIsActive = false;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,96 @@
/* 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.
*/
#ifndef HPL_SOUNDSOURCE_H
#define HPL_SOUNDSOURCE_H
#include "common/list.h"
#include "hpl1/engine/scene/Entity2D.h"
#include "hpl1/engine/system/SystemTypes.h"
class TiXmlElement;
namespace hpl {
class cSound;
class iSoundChannel;
class cSoundSource : public iEntity2D {
public:
cSoundSource(const tString &asName, const tString &asSoundName, cSound *apSound, bool abVolatile);
~cSoundSource();
tString GetEntityType() { return "SoundSource"; }
void UpdateLogic(float afTimeStep);
bool LoadData(TiXmlElement *apRootElem);
bool IsDead();
void SetInterval(int alX) { mlInterval = alX; }
void SetLoop(bool abX) { mbLoop = abX; }
void SetRelative(bool abX) { mbRelative = abX; }
void SetMaxDist(float afX) { mfMaxDist = afX; }
void SetMinDist(float afX) { mfMinDist = afX; }
void SetRandom(int alX) { mlRandom = alX; }
void SetVolume(float afX) { mfVolume = afX; }
iSoundChannel *GetSoundChannel() { return mpSoundChannel; }
const cRect2f &GetBoundingBox();
bool UpdateBoundingBox();
void Stop();
private:
cSound *mpSound;
bool mbVolatile;
int mlInterval;
bool mbLoop;
bool mbRelative;
float mfMaxDist;
float mfMinDist;
int mlRandom;
tString msSoundName;
float mfVolume;
int mlCounter;
bool mbPlaying;
iSoundChannel *mpSoundChannel;
void Play();
};
typedef Common::List<cSoundSource *> tSoundSourceList;
typedef tSoundSourceList::iterator tSoundSourceListIt;
} // namespace hpl
#endif // HPL_SOUNDSOURCE_H

View File

@@ -0,0 +1,523 @@
/* 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/SubMeshEntity.h"
#include "hpl1/engine/scene/MeshEntity.h"
#include "hpl1/engine/graphics/Material.h"
#include "hpl1/engine/graphics/Mesh.h"
#include "hpl1/engine/graphics/SubMesh.h"
#include "hpl1/engine/graphics/VertexBuffer.h"
#include "hpl1/engine/resources/MaterialManager.h"
#include "hpl1/engine/resources/MeshManager.h"
#include "hpl1/engine/graphics/Animation.h"
#include "hpl1/engine/graphics/AnimationTrack.h"
#include "hpl1/engine/graphics/Bone.h"
#include "hpl1/engine/graphics/Skeleton.h"
#include "hpl1/engine/scene/AnimationState.h"
#include "hpl1/engine/scene/NodeState.h"
#include "hpl1/engine/physics/PhysicsBody.h"
#include "hpl1/engine/math/Math.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
cSubMeshEntity::cSubMeshEntity(const tString &asName, cMeshEntity *apMeshEntity, cSubMesh *apSubMesh,
cMaterialManager *apMaterialManager) : iRenderable(asName) {
mpMeshEntity = apMeshEntity;
mpSubMesh = apSubMesh;
mbIsOneSided = mpSubMesh->GetIsOneSided();
mvOneSidedNormal = mpSubMesh->GetOneSidedNormal();
mpMaterialManager = apMaterialManager;
mbCastShadows = false;
mbGraphicsUpdated = false;
mpBody = NULL;
if (mpMeshEntity->GetMesh()->GetSkeleton()) {
mpDynVtxBuffer = mpSubMesh->GetVertexBuffer()->CreateCopy(eVertexBufferUsageType_Dynamic);
mvDynTriangles = *mpSubMesh->GetTriangleVecPtr();
} else {
mpDynVtxBuffer = NULL;
}
mpLocalNode = NULL;
mpEntityCallback = hplNew(cSubMeshEntityBodyUpdate, ());
mbUpdateBody = false;
mpMaterial = NULL;
}
cSubMeshEntity::~cSubMeshEntity() {
hplDelete(mpEntityCallback);
if (mpDynVtxBuffer)
hplDelete(mpDynVtxBuffer);
/* Clear any custom textures here*/
if (mpMaterial)
mpMaterialManager->Destroy(mpMaterial);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// BODY CALLBACK
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cSubMeshEntityBodyUpdate::OnTransformUpdate(iEntity3D *apEntity) {
/*cSubMeshEntity *pSubEntity = static_cast<cSubMeshEntity*>(apEntity);
if(pSubEntity->GetBody())
{
if(apEntity->GetWorldMatrix() != pSubEntity->GetBody()->GetLocalMatrix())
{
Log("Setting matrix on %s from\n",pSubEntity->GetBody()->GetName().c_str());
Log(" %s\n",apEntity->GetWorldMatrix().ToString().c_str());
Log(" %s\n",pSubEntity->GetBody()->GetLocalMatrix().ToString().c_str());
pSubEntity->GetBody()->SetMatrix(apEntity->GetWorldMatrix());
}
}*/
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cSubMeshEntity::UpdateLogic(float afTimeStep) {
if (mbUpdateBody && mpBody) {
mpBody->SetMatrix(GetWorldMatrix());
}
}
//-----------------------------------------------------------------------
iMaterial *cSubMeshEntity::GetMaterial() {
if (mpMaterial == NULL && mpSubMesh->GetMaterial() == NULL) {
Error("Materials for sub entity %s are NULL!\n", GetName().c_str());
}
if (mpMaterial)
return mpMaterial;
else
return mpSubMesh->GetMaterial();
}
//-----------------------------------------------------------------------
// Set Src as private variable to give this a little boost! Or?
static inline void MatrixFloatTransformSet(float *pDest, const cMatrixf &a_mtxA, const float *pSrc, const float fWeight) {
pDest[0] = (a_mtxA.m[0][0] * pSrc[0] + a_mtxA.m[0][1] * pSrc[1] + a_mtxA.m[0][2] * pSrc[2] + a_mtxA.m[0][3]) * fWeight;
pDest[1] = (a_mtxA.m[1][0] * pSrc[0] + a_mtxA.m[1][1] * pSrc[1] + a_mtxA.m[1][2] * pSrc[2] + a_mtxA.m[1][3]) * fWeight;
pDest[2] = (a_mtxA.m[2][0] * pSrc[0] + a_mtxA.m[2][1] * pSrc[1] + a_mtxA.m[2][2] * pSrc[2] + a_mtxA.m[2][3]) * fWeight;
}
static inline void MatrixFloatRotateSet(float *pDest, const cMatrixf &a_mtxA, const float *pSrc, const float fWeight) {
pDest[0] = (a_mtxA.m[0][0] * pSrc[0] + a_mtxA.m[0][1] * pSrc[1] + a_mtxA.m[0][2] * pSrc[2]) * fWeight;
pDest[1] = (a_mtxA.m[1][0] * pSrc[0] + a_mtxA.m[1][1] * pSrc[1] + a_mtxA.m[1][2] * pSrc[2]) * fWeight;
pDest[2] = (a_mtxA.m[2][0] * pSrc[0] + a_mtxA.m[2][1] * pSrc[1] + a_mtxA.m[2][2] * pSrc[2]) * fWeight;
}
////////////////////////////////////////////////////////////
// Set Src as private variable to give this a little boost!Or?
static inline void MatrixFloatTransformAdd(float *pDest, const cMatrixf &a_mtxA, const float *pSrc, const float fWeight) {
pDest[0] += (a_mtxA.m[0][0] * pSrc[0] + a_mtxA.m[0][1] * pSrc[1] + a_mtxA.m[0][2] * pSrc[2] + a_mtxA.m[0][3]) * fWeight;
pDest[1] += (a_mtxA.m[1][0] * pSrc[0] + a_mtxA.m[1][1] * pSrc[1] + a_mtxA.m[1][2] * pSrc[2] + a_mtxA.m[1][3]) * fWeight;
pDest[2] += (a_mtxA.m[2][0] * pSrc[0] + a_mtxA.m[2][1] * pSrc[1] + a_mtxA.m[2][2] * pSrc[2] + a_mtxA.m[2][3]) * fWeight;
}
static inline void MatrixFloatRotateAdd(float *pDest, const cMatrixf &a_mtxA, const float *pSrc, const float fWeight) {
pDest[0] += (a_mtxA.m[0][0] * pSrc[0] + a_mtxA.m[0][1] * pSrc[1] + a_mtxA.m[0][2] * pSrc[2]) * fWeight;
pDest[1] += (a_mtxA.m[1][0] * pSrc[0] + a_mtxA.m[1][1] * pSrc[1] + a_mtxA.m[1][2] * pSrc[2]) * fWeight;
pDest[2] += (a_mtxA.m[2][0] * pSrc[0] + a_mtxA.m[2][1] * pSrc[1] + a_mtxA.m[2][2] * pSrc[2]) * fWeight;
}
////////////////////////////////////////////////////////////
void cSubMeshEntity::UpdateGraphics(cCamera3D *apCamera, float afFrameTime, cRenderList *apRenderList) {
if (mpDynVtxBuffer) {
if (mpMeshEntity->mbSkeletonPhysicsSleeping && mbGraphicsUpdated) {
return;
}
mbGraphicsUpdated = true;
const float *pBindPos = mpSubMesh->GetVertexBuffer()->GetArray(eVertexFlag_Position);
const float *pBindNormal = mpSubMesh->GetVertexBuffer()->GetArray(eVertexFlag_Normal);
const float *pBindTangent = mpSubMesh->GetVertexBuffer()->GetArray(eVertexFlag_Texture1);
float *pSkinPos = mpDynVtxBuffer->GetArray(eVertexFlag_Position);
float *pSkinNormal = mpDynVtxBuffer->GetArray(eVertexFlag_Normal);
float *pSkinTangent = mpDynVtxBuffer->GetArray(eVertexFlag_Texture1);
const int lVtxStride = kvVertexElements[cMath::Log2ToInt(eVertexFlag_Position)];
const int lVtxNum = mpDynVtxBuffer->GetVertexNum();
for (int vtx = 0; vtx < lVtxNum; vtx++) {
// To count the bone bindings
int lCount = 0;
// Get pointer to weights and bone index.
const float *pWeight = &mpSubMesh->mpVertexWeights[vtx * 4];
if (*pWeight == 0)
continue;
const unsigned char *pBoneIdx = &mpSubMesh->mpVertexBones[vtx * 4];
{
const cMatrixf &mtxTransform = mpMeshEntity->mvBoneMatrices[*pBoneIdx];
// Log("Vtx: %d\n",vtx);
// Log("Boneidx: %d Count %d Weight: %f vtx: %d\n",(int)*pBoneIdx,lCount, *pWeight,vtx);
// ATTENTION: Some optimizing might be done by accumulating the matrix instead.
// THIS is really unsure since it seems like it will result in more math, matrix mul = 8*4 calc
// Vertex mul with matrix is 3 * 3 calculations
// this means: vertex= 9*3 = 27, matrix = 32
MatrixFloatTransformSet(pSkinPos, mtxTransform, pBindPos, *pWeight);
MatrixFloatRotateSet(pSkinNormal, mtxTransform, pBindNormal, *pWeight);
MatrixFloatRotateSet(pSkinTangent, mtxTransform, pBindTangent, *pWeight);
++pWeight;
++pBoneIdx;
++lCount;
}
// Iterate weights until 0 is found or count < 4
while (*pWeight != 0 && lCount < 4) {
// Log("Boneidx: %d Count %d Weight: %f\n",(int)*pBoneIdx,lCount, *pWeight);
const cMatrixf &mtxTransform = mpMeshEntity->mvBoneMatrices[*pBoneIdx];
// Transform with the local movement of the bone.
MatrixFloatTransformAdd(pSkinPos, mtxTransform, pBindPos, *pWeight);
MatrixFloatRotateAdd(pSkinNormal, mtxTransform, pBindNormal, *pWeight);
MatrixFloatRotateAdd(pSkinTangent, mtxTransform, pBindTangent, *pWeight);
++pWeight;
++pBoneIdx;
++lCount;
}
pBindPos += lVtxStride;
pSkinPos += lVtxStride;
pBindNormal += 3;
pSkinNormal += 3;
pBindTangent += 4;
pSkinTangent += 4;
}
float *pSkinPosArray = mpDynVtxBuffer->GetArray(eVertexFlag_Position);
if (mpMeshEntity->IsShadowCaster()) {
// Update the shadow double
memcpy(&pSkinPosArray[lVtxStride * lVtxNum], pSkinPosArray, sizeof(float) * lVtxStride * lVtxNum);
for (int vtx = lVtxStride * lVtxNum + lVtxStride - 1; vtx < lVtxStride * lVtxNum * 2; vtx += lVtxStride) {
pSkinPosArray[vtx] = 0;
}
}
// Update buffer
mpDynVtxBuffer->UpdateData(eVertexFlag_Position | eVertexFlag_Normal | eVertexFlag_Texture1, false);
if (mpMeshEntity->IsShadowCaster()) {
// Update triangles
cMath::CreateTriangleData(mvDynTriangles,
mpDynVtxBuffer->GetIndices(), mpDynVtxBuffer->GetIndexNum(),
pSkinPosArray, lVtxStride, lVtxNum);
}
}
/*if(mpDynVtxBuffer)
{
const float *pBindPosArray = mpSubMesh->GetVertexBuffer()->GetArray(eVertexFlag_Position);
const float *pBindNormalArray = mpSubMesh->GetVertexBuffer()->GetArray(eVertexFlag_Normal);
const float *pBindTangentArray = mpSubMesh->GetVertexBuffer()->GetArray(eVertexFlag_Texture1);
float *pSkinPosArray = mpDynVtxBuffer->GetArray(eVertexFlag_Position);
float *pSkinNormalArray = mpDynVtxBuffer->GetArray(eVertexFlag_Normal);
float *pSkinTangentArray = mpDynVtxBuffer->GetArray(eVertexFlag_Texture1);
int lVtxStride = kvVertexElements[cMath::Log2ToInt(eVertexFlag_Position)];
int lVtxNum = mpDynVtxBuffer->GetVertexNum();
memset(pSkinPosArray,0,sizeof(float)*lVtxStride*lVtxNum);
memset(pSkinNormalArray,0,sizeof(float)*3*lVtxNum);
memset(pSkinTangentArray,0,sizeof(float)*4*lVtxNum);
int lSize = mpSubMesh->GetVertexBonePairNum();
for(int i=0; i<lSize; i++)
{
const cVertexBonePair& VBPair = mpSubMesh->GetVertexBonePair(i);
//Log("%d: Vtx: %d Bone: %d\n",i,VBPair.vtxIdx, VBPair.boneIdx);
const float* pBindPos = &pBindPosArray[VBPair.vtxIdx*lVtxStride];
float* pSkinPos = &pSkinPosArray[VBPair.vtxIdx*lVtxStride];
const float* pBindNorm = &pBindNormalArray[VBPair.vtxIdx*3];
float* pSkinNorm = &pSkinNormalArray[VBPair.vtxIdx*3];
const float* pBindTan = &pBindTangentArray[VBPair.vtxIdx*4];
float* pSkinTan = &pSkinTangentArray[VBPair.vtxIdx*4];
const cMatrixf &mtxTransform = mpMeshEntity->mvBoneMatrices[VBPair.boneIdx];
//Transform with the local movement of the bone.
MatrixFloatTransform(pSkinPos,mtxTransform, pBindPos, VBPair.weight);
pSkinPos[3] = 1;
MatrixFloatRotate(pSkinNorm,mtxTransform, pBindNorm, VBPair.weight);
MatrixFloatRotate(pSkinTan,mtxTransform, pBindTan, VBPair.weight);
pSkinTan[3] = pBindTan[3];
//cVector3f vSkin = cMath::MatrixMul(mpMeshEntity->mvBoneMatrices[VBPair.boneIdx],
// cVector3f(pBindPos[0],pBindPos[1],pBindPos[2]));
//pSkinPos[0] += vSkin.x * VBPair.weight;
//pSkinPos[1] += vSkin.y * VBPair.weight;
//pSkinPos[2] += vSkin.z * VBPair.weight;
}
//Update the shadow double
memcpy(&pSkinPosArray[lVtxStride*lVtxNum],pSkinPosArray,sizeof(float)*lVtxStride*lVtxNum);
for(int vtx=lVtxStride*lVtxNum + lVtxStride-1; vtx < lVtxStride*lVtxNum*2; vtx+=lVtxStride)
{
pSkinPosArray[vtx] = 0;
}
//Update buffer
mpDynVtxBuffer->UpdateData(eVertexFlag_Position | eVertexFlag_Normal | eVertexFlag_Texture1,false);
//Update triangles
cMath::CreateTriangleData(mvDynTriangles,
mpDynVtxBuffer->GetIndices(), mpDynVtxBuffer->GetIndexNum(),
pSkinPosArray, lVtxStride, lVtxNum);
}*/
}
iVertexBuffer *cSubMeshEntity::GetVertexBuffer() {
if (mpDynVtxBuffer) {
return mpDynVtxBuffer;
} else {
return mpSubMesh->GetVertexBuffer();
}
}
cBoundingVolume *cSubMeshEntity::GetBoundingVolume() {
return mpMeshEntity->GetBoundingVolume();
}
int cSubMeshEntity::GetMatrixUpdateCount() {
if (mpMeshEntity->HasNodes()) {
return GetTransformUpdateCount();
} else {
return mpMeshEntity->GetMatrixUpdateCount();
}
}
cMatrixf *cSubMeshEntity::GetModelMatrix(cCamera3D *apCamera) {
if (mpMeshEntity->HasNodes()) {
// Log("%s Matrix from local node!\n",msName.c_str());
return &GetWorldMatrix();
} else {
// Log("%s Matrix from mesh!\n",msName.c_str());
if (mpMeshEntity->IsStatic())
return NULL;
return mpMeshEntity->GetModelMatrix(NULL);
}
}
//-----------------------------------------------------------------------
void cSubMeshEntity::SetLocalNode(cNode3D *apNode) {
mpLocalNode = apNode;
mpLocalNode->AddEntity(this);
}
//-----------------------------------------------------------------------
cNode3D *cSubMeshEntity::GetLocalNode() {
return mpLocalNode;
}
//-----------------------------------------------------------------------
tRenderContainerDataList *cSubMeshEntity::GetRenderContainerDataList() {
// Log("Get from parent %s\n",mpMeshEntity->GetName().c_str());
return mpMeshEntity->GetRenderContainerDataList();
}
//-----------------------------------------------------------------------
void cSubMeshEntity::SetUpdateBody(bool abX) {
mbUpdateBody = abX;
/*if(mbUpdateBody)
{
AddCallback(mpEntityCallback);
}
else
{
RemoveCallback(mpEntityCallback);
}*/
}
bool cSubMeshEntity::GetUpdateBody() {
return mbUpdateBody;
}
//-----------------------------------------------------------------------
cTriangleData &cSubMeshEntity::GetTriangle(int alIndex) {
if (mpDynVtxBuffer)
return mvDynTriangles[alIndex];
else
return (*mpSubMesh->GetTriangleVecPtr())[alIndex];
}
int cSubMeshEntity::GetTriangleNum() {
if (mpDynVtxBuffer)
return (int)mvDynTriangles.size();
else
return (int)mpSubMesh->GetTriangleVecPtr()->size();
}
tTriangleDataVec *cSubMeshEntity::GetTriangleVecPtr() {
if (mpDynVtxBuffer)
return &mvDynTriangles;
else
return mpSubMesh->GetTriangleVecPtr();
}
//-----------------------------------------------------------------------
void cSubMeshEntity::SetCustomMaterial(iMaterial *apMaterial, bool abDestroyOldCustom) {
if (abDestroyOldCustom) {
if (mpMaterial)
mpMaterialManager->Destroy(mpMaterial);
}
mpMaterial = apMaterial;
}
//-----------------------------------------------------------------------
cSector *cSubMeshEntity::GetCurrentSector() const {
return mpMeshEntity->GetCurrentSector();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SAVE OBJECT STUFF
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
kBeginSerialize(cSaveData_cSubMeshEntity, cSaveData_iRenderable)
kSerializeVar(msMaterial, eSerializeType_String)
kSerializeVar(mbCastShadows, eSerializeType_Bool)
kSerializeVar(mlBodyId, eSerializeType_Int32)
kSerializeVar(mbUpdateBody, eSerializeType_Bool)
kEndSerialize()
//-----------------------------------------------------------------------
iSaveData *cSubMeshEntity::CreateSaveData() {
return hplNew(cSaveData_cSubMeshEntity, ());
}
//-----------------------------------------------------------------------
void cSubMeshEntity::SaveToSaveData(iSaveData *apSaveData) {
kSaveData_SaveToBegin(cSubMeshEntity);
kSaveData_SaveTo(mbCastShadows);
kSaveData_SaveTo(mbUpdateBody);
pData->msMaterial = mpMaterial == NULL ? "" : mpMaterial->GetName();
kSaveData_SaveObject(mpBody, mlBodyId);
}
//-----------------------------------------------------------------------
void cSubMeshEntity::LoadFromSaveData(iSaveData *apSaveData) {
kSaveData_LoadFromBegin(cSubMeshEntity);
kSaveData_LoadFrom(mbCastShadows);
kSaveData_LoadFrom(mbUpdateBody);
if (pData->msMaterial != "") {
iMaterial *pMat = mpMaterialManager->CreateMaterial(pData->msMaterial);
if (pMat)
SetCustomMaterial(pMat);
}
}
//-----------------------------------------------------------------------
void cSubMeshEntity::SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
kSaveData_SetupBegin(cSubMeshEntity);
kSaveData_LoadObject(mpBody, mlBodyId, iPhysicsBody *);
if (mpBody && mbUpdateBody == false) {
mpBody->CreateNode()->AddEntity(this);
}
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,185 @@
/* 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.
*/
#ifndef HPL_SUB_MESH_ENTITY_H
#define HPL_SUB_MESH_ENTITY_H
#include "common/array.h"
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/graphics/Renderable.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/math/MeshTypes.h"
#include "hpl1/engine/scene/Entity3D.h"
#include "hpl1/engine/scene/SectorVisibility.h"
#include "hpl1/engine/system/SystemTypes.h"
#include "common/stablemap.h"
#include "common/multimap.h"
namespace hpl {
class cMaterialManager;
class cMeshManager;
class cMesh;
class cSubMesh;
class cMeshEntity;
class cAnimationState;
class cNodeState;
class cBone;
class cNode3D;
class iPhysicsBody;
class iMaterial;
class cBoneState;
//-----------------------------------------------------------------------
typedef Common::Array<cAnimationState *> tAnimationStateVec;
typedef tAnimationStateVec::iterator tAnimationStateVecIt;
typedef Common::StableMap<tString, int> tAnimationStateIndexMap;
typedef tAnimationStateIndexMap::iterator tAnimationStateIndexMapIt;
typedef Common::Array<cBoneState *> tNodeStateVec;
typedef tNodeStateVec::iterator tNodeStateVecIt;
typedef Common::StableMap<tString, int> tNodeStateIndexMap;
typedef tNodeStateIndexMap::iterator tNodeStateIndexMapIt;
//-----------------------------------------------------------------------
class cSubMeshEntityBodyUpdate : public iEntityCallback {
public:
void OnTransformUpdate(iEntity3D *apEntity);
};
//-----------------------------------------------------------------------
kSaveData_ChildClass(iRenderable, cSubMeshEntity) {
kSaveData_ClassInit(cSubMeshEntity) public : tString msMaterial;
bool mbCastShadows;
int mlBodyId;
bool mbUpdateBody;
iSaveObject *CreateSaveObject(cSaveObjectHandler * apSaveObjectHandler, cGame * apGame) { return NULL; }
int GetSaveCreatePrio() { return 0; }
};
//-----------------------------------------------------------------------
class cSubMeshEntity : public iRenderable {
typedef iRenderable super;
friend class cMeshEntity;
public:
cSubMeshEntity(const tString &asName, cMeshEntity *apMeshEntity, cSubMesh *apSubMesh, cMaterialManager *apMaterialManager);
virtual ~cSubMeshEntity();
iMaterial *GetMaterial();
void UpdateGraphics(cCamera3D *apCamera, float afFrameTime, cRenderList *apRenderList);
iVertexBuffer *GetVertexBuffer();
void SetCastsShadows(bool abX) { mbCastShadows = abX; }
bool IsShadowCaster() { return mbCastShadows; }
cBoundingVolume *GetBoundingVolume();
cMatrixf *GetModelMatrix(cCamera3D *apCamera);
int GetMatrixUpdateCount();
eRenderableType GetRenderType() { return eRenderableType_Normal; }
cSubMesh *GetSubMesh() const { return mpSubMesh; }
void SetLocalNode(cNode3D *apNode);
cNode3D *GetLocalNode();
tRenderContainerDataList *GetRenderContainerDataList();
// Entity implementation
tString GetEntityType() { return "SubMesh"; }
bool IsVisible() { return IsRendered(); }
void SetVisible(bool abVisible) { SetRendered(abVisible); }
void UpdateLogic(float afTimeStep);
cTriangleData &GetTriangle(int alIndex);
int GetTriangleNum();
tTriangleDataVec *GetTriangleVecPtr();
iPhysicsBody *GetBody() { return mpBody; }
void SetBody(iPhysicsBody *apBody) { mpBody = apBody; }
void SetUpdateBody(bool abX);
bool GetUpdateBody();
void SetCustomMaterial(iMaterial *apMaterial, bool abDestroyOldCustom = true);
iMaterial *GetCustomMaterial() { return mpMaterial; }
cSector *GetCurrentSector() const;
// SaveObject implementation
virtual iSaveData *CreateSaveData();
virtual void SaveToSaveData(iSaveData *apSaveData);
virtual void LoadFromSaveData(iSaveData *apSaveData);
virtual void SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
private:
bool mbCastShadows;
cSubMesh *mpSubMesh;
cMeshEntity *mpMeshEntity;
iMaterial *mpMaterial;
cNode3D *mpLocalNode;
cMaterialManager *mpMaterialManager;
iVertexBuffer *mpDynVtxBuffer;
tTriangleDataVec mvDynTriangles;
cSubMeshEntityBodyUpdate *mpEntityCallback;
bool mbUpdateBody;
bool mbGraphicsUpdated;
iPhysicsBody *mpBody;
};
typedef Common::Array<cSubMeshEntity *> tSubMeshEntityVec;
typedef Common::Array<cSubMeshEntity *>::iterator tSubMeshEntityVecIt;
typedef Common::MultiMap<tString, cSubMeshEntity *> tSubMeshEntityMap;
typedef tSubMeshEntityMap::iterator tSubMeshEntityMapIt;
} // namespace hpl
#endif // HPL_SUB_MESH_ENTITY_H

View File

@@ -0,0 +1,77 @@
/* 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/Tile.h"
#include "hpl1/engine/scene/TileData.h"
#include "hpl1/engine/scene/TileMap.h"
#include "hpl1/engine/scene/TileSet.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cTile::cTile(iTileData *apTileData, eTileRotation aAngle,
const cVector3f &avPos, const cVector2f &avSize, cCollisionMesh2D *apCollMesh) {
mvPosition = avPos + avSize / 2;
mpTileData = NULL;
mAngle = aAngle;
mpCollMesh = apCollMesh;
mlFlags = 0;
// SetTile(apTileData,aAngle,avPos,avSize);
}
//-----------------------------------------------------------------------
cTile::~cTile() {
if (mpCollMesh)
hplDelete(mpCollMesh);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cTile::SetTile(iTileData *apTileData, eTileRotation aAngle,
const cVector3f &avPos, const cVector2f &avSize) {
mpTileData = apTileData;
mAngle = aAngle;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,80 @@
/* 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.
*/
#ifndef HPL_TILE_H
#define HPL_TILE_H
#include "common/list.h"
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/scene/TileData.h"
#include "hpl1/engine/system/SystemTypes.h"
namespace hpl {
#define eTileFlag_Breakable (eFlagBit_0)
class cTile {
public:
cTile(iTileData *apTileData, eTileRotation aAngle,
const cVector3f &avPos, const cVector2f &avSize, cCollisionMesh2D *apCollMesh);
~cTile();
iTileData *GetTileData() { return mpTileData; }
void SetTileData(iTileData *apTileData) { mpTileData = apTileData; }
eTileRotation GetAngle() { return mAngle; }
void SetTile(iTileData *apTileData, eTileRotation aAngle,
const cVector3f &avPos, const cVector2f &avSize);
void SetAngle(eTileRotation aAngle) { mAngle = aAngle; }
const cVector3f &GetPosition() const { return mvPosition; }
cVector3f *GetPositionPtr() { return &mvPosition; }
cCollisionMesh2D *GetCollisionMesh() { return mpCollMesh; }
void SetCollisionMesh(cCollisionMesh2D *apMesh) { mpCollMesh = apMesh; }
tFlag GetFlags() { return mlFlags; }
void SetFlags(tFlag alFlags) { mlFlags = alFlags; }
private:
cCollisionMesh2D *mpCollMesh;
tFlag mlFlags;
iTileData *mpTileData;
cVector3f mvPosition;
eTileRotation mAngle; // 0:normal. 1:90 CW. 2:180. CW 3:270 CW.
// 4: flip horisontally. 5: flip vertically. 6: flip both.
};
typedef Common::List<cTile *> tTileList;
typedef tTileList::iterator tTileListIt;
} // namespace hpl
#endif // HPL_TILE_H

View File

@@ -0,0 +1,157 @@
/* 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/TileData.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cTileDataNormal::cTileDataNormal(cImageManager *apImageManager, cVector2f avTileSize)
{
mpImageManager = apImageManager;
mvImage.resize(eMaterialTexture_LastEnum);
Common::fill(mvImage.begin(), mvImage.end(), nullptr);
mvTileSize = avTileSize;
mCollisionType = eTileCollisionType_Normal;
mpMaterial = NULL;
mpMesh = NULL;
mpCollideMesh = NULL;
}
//-----------------------------------------------------------------------
cTileDataNormal::~cTileDataNormal() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
tVertexVec *cTileDataNormal::GetVertexVec(eTileRotation aRotation) {
return mvVtx[aRotation];
}
//-----------------------------------------------------------------------
tUIntVec *cTileDataNormal::GetIndexVec(eTileRotation aRotation) {
return mvIdx;
}
//-----------------------------------------------------------------------
tVertexVec *cTileDataNormal::GetCollideVertexVec(eTileRotation aRotation) {
return mvCollideVtx[aRotation];
}
//-----------------------------------------------------------------------
tUIntVec *cTileDataNormal::GetCollideIndexVec(eTileRotation aRotation) {
return mvCollideIdx;
}
//-----------------------------------------------------------------------
void cTileDataNormal::Destroy() {
if (mpMaterial)
hplDelete(mpMaterial);
if (mpMesh)
hplDelete(mpMesh);
if (mpCollideMesh)
hplDelete(mpCollideMesh);
}
//-----------------------------------------------------------------------
void cTileDataNormal::SetData(cMesh2D *apMesh, iMaterial *apMaterial) {
SetMaterial(apMaterial);
SetMesh(apMesh); // Note that material must be set before mesh.
}
//-----------------------------------------------------------------------
cMesh2D *cTileDataNormal::GetCollideMesh() {
// if(mpCollideMesh==NULL) return mpMesh;
return mpCollideMesh;
}
//-----------------------------------------------------------------------
void cTileDataNormal::SetCollideMesh(cMesh2D *apCollideMesh) {
mpCollideMesh = apCollideMesh;
for (int i = 0; i < eTileRotation_LastEnum; i++) {
mvCollideVtx[i] = mpCollideMesh->GetVertexVec(cRect2f(0, 0, 1, 1), mvTileSize, (eTileRotation)i);
}
mvCollideIdx = mpCollideMesh->GetIndexVec();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cTileDataNormal::SetMesh(cMesh2D *apMesh) {
mpMesh = apMesh;
mpMesh->CreateTileVertexVec();
if (mpMaterial) {
cRect2f ImageRect = mpMaterial->GetTextureOffset(eMaterialTexture_Diffuse);
for (int i = 0; i < eTileRotation_LastEnum; i++) {
mvVtx[i] = mpMesh->GetVertexVec(ImageRect, mvTileSize, (eTileRotation)i);
}
mvIdx = mpMesh->GetIndexVec();
}
}
//-----------------------------------------------------------------------
void cTileDataNormal::SetMaterial(iMaterial *apMaterial) {
mpMaterial = apMaterial;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,116 @@
/* 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.
*/
#ifndef HPL_TILEDATA_H
#define HPL_TILEDATA_H
#include "hpl1/engine/graphics/Graphics.h"
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/graphics/Material.h"
#include "hpl1/engine/graphics/Mesh2d.h"
#include "hpl1/engine/resources/ImageManager.h"
#include "hpl1/engine/resources/ResourceImage.h"
namespace hpl {
enum eTileCollisionType {
eTileCollisionType_None,
eTileCollisionType_Normal,
eTileCollisionType_OnlyDown,
eTileCollisionType_LastEnum
};
enum eTileDataType {
eTileDataType_Normal,
eTileDataType_LastEnum
};
/////// INTERFACE ///////////////////////
class iTileData {
public:
virtual ~iTileData() {}
virtual void Destroy() = 0;
virtual bool IsSolid() = 0;
virtual eTileDataType GetType() = 0;
/*virtual tVertexVec GetVertexVec(const cVector3f &avPos, const cVector2f &avSize,
unsigned char acAngle)=0;*/
};
/////// IMPLEMENTATIONS OF iTILEDATA ////////////
class cTileDataNormal : public iTileData {
public:
cTileDataNormal(cImageManager *apImageManager, cVector2f avTileSize);
~cTileDataNormal();
void Destroy();
bool IsSolid() { return mbIsSolid; }
void SetIsSolid(bool abIsSolid) { mbIsSolid = abIsSolid; }
eTileCollisionType GetCollisionType() { return mCollisionType; }
void SetCollisionType(eTileCollisionType aCollisionType) { mCollisionType = aCollisionType; }
eTileDataType GetType() { return eTileDataType_Normal; }
tVertexVec *GetVertexVec(eTileRotation aRotation);
tUIntVec *GetIndexVec(eTileRotation aRotation);
tVertexVec *GetCollideVertexVec(eTileRotation aRotation);
tUIntVec *GetCollideIndexVec(eTileRotation aRotation);
iMaterial *GetMaterial() { return mpMaterial; }
cMesh2D *GetMesh() { return mpMesh; }
void SetData(cMesh2D *apMesh, iMaterial *apMaterial);
cMesh2D *GetCollideMesh();
void SetCollideMesh(cMesh2D *apCollideMesh);
private:
cImageManager *mpImageManager;
tResourceImageVec mvImage;
iMaterial *mpMaterial;
tVertexVec *mvVtx[eTileRotation_LastEnum];
tVertexVec *mvCollideVtx[eTileRotation_LastEnum];
tUIntVec *mvIdx;
tUIntVec *mvCollideIdx;
cMesh2D *mpMesh;
cVector2f mvTileSize;
bool mbIsSolid;
eTileCollisionType mCollisionType;
cMesh2D *mpCollideMesh;
void SetMesh(cMesh2D *apMesh);
void SetMaterial(iMaterial *apMaterial);
};
} // namespace hpl
#endif // HPL_TILEDATA_H

View File

@@ -0,0 +1,111 @@
/* 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/TileLayer.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cTileLayer::cTileLayer(unsigned int alW, unsigned int alH, bool abCollision, bool abLit,
eTileLayerType aType, float afZ) {
mvSize = cVector2l(alW, alH);
mbCollision = abCollision;
mbLit = abLit;
mType = aType;
mfZ = afZ;
mvTile.resize(alW * alH);
Common::fill(mvTile.begin(), mvTile.end(), nullptr);
}
//-----------------------------------------------------------------------
cTileLayer::~cTileLayer() {
Log(" Deleting tilelayer.\n");
for (int i = 0; i < (int)mvTile.size(); i++)
if (mvTile[i])
hplDelete(mvTile[i]);
mvTile.clear();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cTileLayer::SetTile(unsigned int alX, unsigned int alY, cTile *aVal) {
int lNum = alY * mvSize.x + alX;
if (lNum >= (int)mvTile.size())
return false;
if (aVal == NULL) {
if (mvTile[lNum])
hplDelete(mvTile[lNum]);
mvTile[lNum] = NULL;
} else {
if (mvTile[lNum] == NULL)
mvTile[lNum] = aVal;
else
*mvTile[lNum] = *aVal;
}
return true;
}
//-----------------------------------------------------------------------
cTile *cTileLayer::GetAt(int alX, int alY) {
if (alX < 0 || alX >= mvSize.x || alY < 0 || alY >= mvSize.y)
return NULL;
int lNum = alY * mvSize.x + alX;
if (lNum >= (int)mvTile.size())
return NULL;
return mvTile[lNum];
}
//-----------------------------------------------------------------------
cTile *cTileLayer::GetAt(int alNum) {
return mvTile[alNum];
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,75 @@
/* 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.
*/
#ifndef HPL_TILELAYER_H
#define HPL_TILELAYER_H
#include "common/array.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/scene/Tile.h"
#include "hpl1/engine/system/SystemTypes.h"
namespace hpl {
enum eTileLayerType {
eTileLayerType_Normal,
eTileLayerType_LastEnum
};
typedef Common::Array<cTile *> tTileVec;
typedef tTileVec::iterator tTileVecIt;
class cTileLayer {
friend class cTileMapRectIt;
friend class cTileMapLineIt;
public:
cTileLayer(unsigned int alW, unsigned int alH, bool abCollision, bool abLit, eTileLayerType aType, float afZ = 0);
~cTileLayer();
bool SetTile(unsigned int alX, unsigned int alY, cTile *aVal);
cTile *GetAt(int alX, int alY);
cTile *GetAt(int alNum);
void SetZ(float afZ) { mfZ = afZ; }
float GetZ() { return mfZ; }
bool HasCollision() { return mbCollision; }
private:
tTileVec mvTile;
cVector2l mvSize;
bool mbCollision;
bool mbLit;
float mfZ;
eTileLayerType mType;
};
} // namespace hpl
#endif // HPL_TILELAYER_H

View File

@@ -0,0 +1,284 @@
/* 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/TileMap.h"
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/graphics/RenderObject2D.h"
#include "hpl1/engine/graphics/Renderer2D.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/resources/ResourceImage.h"
#include "hpl1/engine/resources/Resources.h"
#include "hpl1/engine/resources/TileSetManager.h"
#include "hpl1/engine/scene/TileMapLineIt.h"
#include "hpl1/engine/scene/TileMapRectIt.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cTileMap::cTileMap(cVector2l avSize, float afTileSize, cGraphics *apGraphics, cResources *apResources) {
mfTileSize = 1;
mvSize = avSize;
mfTileSize = afTileSize;
mpGraphics = apGraphics;
mpResources = apResources;
mlShadowLayer = 0;
}
//-----------------------------------------------------------------------
cTileMap::~cTileMap() {
Log(" Deleting tilemap.\n");
for (tTileLayerVecIt it = mvTileLayer.begin(); it != mvTileLayer.end(); it++)
hplDelete(*it);
for (tTileSetVecIt it = mvTileSet.begin(); it != mvTileSet.end(); it++)
mpResources->GetTileSetManager()->Destroy(*it);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cTileMap::Render(cCamera2D *apCam) {
cRect2f Rect;
apCam->GetClipRect(Rect);
iTileMapIt *TileIt = GetRectIterator(Rect, -1);
while (TileIt->HasNext()) {
RenderTileData(TileIt->Next(), TileIt->GetCurrentLayer());
}
hplDelete(TileIt);
}
//-----------------------------------------------------------------------
iTileMapIt *cTileMap::GetRectIterator(const cRect2f &aRect, int alLayer) {
cVector2l vPos = cVector2l((int)floor(aRect.x / mfTileSize),
(int)floor(aRect.y / mfTileSize));
cVector2l vSize = cVector2l((int)(aRect.w / mfTileSize) + 1,
(int)(aRect.h / mfTileSize) + 1);
// Check if we need yet another grid for x and y
if (aRect.x + aRect.w >= (vPos.x + vSize.x) * mfTileSize)
vSize.x++;
if (aRect.y + aRect.h >= (vPos.y + vSize.y) * mfTileSize)
vSize.y++;
// Log("\nPos: %d:%d\n",vPos.x,vPos.y);
// Log("Size: %d:%d\n\n",vSize.x,vSize.y);
return hplNew(cTileMapRectIt, (vPos, vSize, this, alLayer));
}
//-----------------------------------------------------------------------
iTileMapIt *cTileMap::GetLineIterator(const cVector2f &avStart, const cVector2f &avEnd, int alLayer) {
return hplNew(cTileMapLineIt, (avStart, avEnd, this, alLayer));
}
//-----------------------------------------------------------------------
cVector2f cTileMap::GetWorldPos(cVector2f avScreenPos, cCamera2D *apCam) {
cVector2f vWorldPos;
cRect2f Rect;
apCam->GetClipRect(Rect);
cVector2f vVirtSize = mpGraphics->GetLowLevel()->GetVirtualSize();
vWorldPos.x = Rect.x + Rect.w * (avScreenPos.x / ((float)vVirtSize.x));
vWorldPos.y = Rect.y + Rect.h * (avScreenPos.y / ((float)vVirtSize.y));
return vWorldPos;
}
//-----------------------------------------------------------------------
cTile *cTileMap::GetScreenTile(cVector2f avPos, int alLayer, cCamera2D *apCam) {
return GetWorldTile(GetWorldPos(avPos, apCam), alLayer);
}
//-----------------------------------------------------------------------
void cTileMap::SetScreenTileData(cVector2f avPos, int alLayer, cCamera2D *apCam,
int alTileSet, int alTileNum) {
cVector2f vWorldPos = GetWorldPos(avPos, apCam);
cTile *pOldTile = GetWorldTile(vWorldPos, alLayer);
iTileData *pData = NULL;
if (alTileSet >= 0) {
cTileSet *pSet = GetTileSet(alTileSet);
if (pSet == NULL)
return;
pData = pSet->Get(alTileNum);
if (pData == NULL)
return;
}
cVector2l vTilePos = cVector2l((int)floor(vWorldPos.x / mfTileSize), (int)floor(vWorldPos.y / mfTileSize));
if (vTilePos.x < 0 || vTilePos.y < 0 || vTilePos.x >= mvSize.x || vTilePos.y >= mvSize.y)
return;
if (alLayer < 0 || alLayer >= (int)mvTileLayer.size())
return;
cVector3f vTileWorldPos(vTilePos.x * mfTileSize, vTilePos.y * mfTileSize, mvTileLayer[alLayer]->GetZ());
int lAngle = 0;
if (pOldTile)
lAngle = pOldTile->GetAngle();
cTile *pTile = NULL;
if (pData)
pTile = hplNew(cTile, (pData, (eTileRotation)lAngle, vTileWorldPos, mfTileSize, NULL));
mvTileLayer[alLayer]->SetTile(vTilePos.x, vTilePos.y, pTile);
}
//-----------------------------------------------------------------------
void cTileMap::SetScreenTileAngle(cVector2f avPos, int alLayer, cCamera2D *apCam, int alAngle) {
cVector2f vWorldPos = GetWorldPos(avPos, apCam);
cTile *pTile = GetWorldTile(vWorldPos, alLayer);
if (pTile == NULL)
return;
cVector2l vTilePos = cVector2l((int)floor(vWorldPos.x / mfTileSize), (int)floor(vWorldPos.y / mfTileSize));
if (vTilePos.x < 0 || vTilePos.y < 0 || vTilePos.x >= mvSize.x || vTilePos.y >= mvSize.y)
return;
cVector3f vTileWorldPos(vTilePos.x * mfTileSize, vTilePos.y * mfTileSize, mvTileLayer[alLayer]->GetZ());
pTile->SetAngle((eTileRotation)alAngle);
}
//-----------------------------------------------------------------------
cTile *cTileMap::GetWorldTile(cVector2f avPos, int alLayer) {
if (alLayer < 0 || alLayer >= (int)mvTileLayer.size())
return NULL;
return mvTileLayer[alLayer]->GetAt((int)floor(avPos.x / mfTileSize),
(int)floor(avPos.y / mfTileSize));
}
//-----------------------------------------------------------------------
/**
*
* \param alTileNum
* \param alLayer
* \param avDir 0=left, 1=right, 2=up, 3 = down
* \return num of neighbours
*/
int cTileMap::GetTileNeighbours4Dir(int alTileNum, int alLayer, bool *avDir) {
int lCount = 0;
cTileLayer *pLayer = mvTileLayer[alLayer];
int lX = alTileNum % mvSize.x;
int lY = alTileNum / mvSize.x;
/*avDir[0] = pLayer->GetAt(lX-1,lY)!=NULL?true:false;
avDir[1] = pLayer->GetAt(lX+1,lY)!=NULL?true:false;
avDir[2] = pLayer->GetAt(lX,lY-1)!=NULL?true:false;
avDir[3] = pLayer->GetAt(lX,lY+1)!=NULL?true:false;*/
cTile *pTile;
cTileDataNormal *pData;
cVector2l vAdd[4] = {cVector2l(-1, 0), cVector2l(+1, 0), cVector2l(0, -1), cVector2l(0, +1)};
for (int i = 0; i < 4; i++) {
pTile = pLayer->GetAt(lX + vAdd[i].x, lY + vAdd[i].y);
if (pTile != NULL) {
pData = static_cast<cTileDataNormal *>(pTile->GetTileData());
if (pData->IsSolid())
avDir[i] = true;
else
avDir[i] = false;
} else {
avDir[i] = false;
}
}
for (int i = 0; i < 4; i++)
if (avDir[i] == true)
lCount++;
return lCount;
}
//-----------------------------------------------------------------------
void cTileMap::AddTileLayerFront(cTileLayer *apLayer) {
if (mvTileLayer.size() < 1) {
mvTileLayer.push_back(apLayer);
} else {
mvTileLayer.push_back(NULL);
for (int i = (int)mvTileLayer.size() - 2; i >= 0; i--) {
mvTileLayer[i + 1] = mvTileLayer[i];
}
mvTileLayer[0] = apLayer;
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cTileMap::RenderTileData(cTile *apTile, int alLayer) {
cTileDataNormal *pData = static_cast<cTileDataNormal *>(apTile->GetTileData());
if (pData == NULL)
return;
cRect2f _obj = cRect2f(apTile->GetPosition().x - mfTileSize / 2,
apTile->GetPosition().y - mfTileSize / 2, mfTileSize, mfTileSize);
cRenderObject2D _obj2 = cRenderObject2D(pData->GetMaterial(),
pData->GetVertexVec(apTile->GetAngle()),
pData->GetIndexVec(apTile->GetAngle()),
ePrimitiveType_Quad, apTile->GetPosition().z,
_obj,
NULL, apTile->GetPositionPtr());
mpGraphics->GetRenderer2D()->AddObject(_obj2);
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,101 @@
/* 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.
*/
#ifndef HPL_TILEMAP_H
#define HPL_TILEMAP_H
#include "common/array.h"
#include "hpl1/engine/graphics/Graphics.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/scene/Camera2D.h"
#include "hpl1/engine/scene/TileLayer.h"
#include "hpl1/engine/scene/TileMapIt.h"
#include "hpl1/engine/scene/TileSet.h"
namespace hpl {
typedef Common::Array<cTileSet *> tTileSetVec;
typedef tTileSetVec::iterator tTileSetVecIt;
typedef Common::Array<cTileLayer *> tTileLayerVec;
typedef tTileLayerVec::iterator tTileLayerVecIt;
class cTileMap {
friend class cTileMapRectIt;
friend class cTileMapLineIt;
public:
cTileMap(cVector2l avSize, float afTileSize, cGraphics *apGraphics, cResources *apResources);
~cTileMap();
const cVector2l &GetSize() { return mvSize; }
float GetTileSize() { return mfTileSize; }
int GetTileNeighbours4Dir(int alTileNum, int alLayer, bool *avDir);
void AddTileSet(cTileSet *apSet) { mvTileSet.push_back(apSet); }
cTileSet *GetTileSet(int alNum) { return mvTileSet[alNum]; }
void AddTileLayerFront(cTileLayer *apLayer);
void AddTileLayerBack(cTileLayer *apLayer) { mvTileLayer.push_back(apLayer); }
cTileLayer *GetTileLayer(int alNum) { return mvTileLayer[alNum]; }
int GetTileLayerNum() { return (int)mvTileLayer.size(); }
iTileMapIt *GetRectIterator(const cRect2f &aRect, int alLayer);
iTileMapIt *GetLineIterator(const cVector2f &avStart, const cVector2f &avEnd, int alLayer);
void Render(cCamera2D *apCam);
cTile *GetScreenTile(cVector2f avPos, int alLayer, cCamera2D *apCam);
void SetScreenTileData(cVector2f avPos, int alLayer, cCamera2D *apCam, int alTileSet, int alTileNum);
void SetScreenTileAngle(cVector2f avPos, int alLayer, cCamera2D *apCam, int alAngle);
cTile *GetWorldTile(cVector2f avPos, int alLayer);
cVector2f GetWorldPos(cVector2f avScreenPos, cCamera2D *apCam);
void SetShadowLayer(int alShadowLayer) { mlShadowLayer = alShadowLayer; }
int GetShadowLayer() { return mlShadowLayer; }
private:
cGraphics *mpGraphics;
cResources *mpResources;
tTileSetVec mvTileSet;
tTileLayerVec mvTileLayer;
int mlShadowLayer;
cVector2l mvSize;
float mfTileSize;
int mlCurrentLayer;
inline void RenderTileData(cTile *apTile, int alLayer);
};
} // namespace hpl
#endif // HPL_TILEMAP_H

View File

@@ -0,0 +1,48 @@
/* 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.
*/
#ifndef HPL_TILEMAP_IT_H
#define HPL_TILEMAP_IT_H
#include "hpl1/engine/scene/Tile.h"
namespace hpl {
class iTileMapIt {
public:
virtual ~iTileMapIt() {}
virtual bool HasNext() = 0;
virtual cTile *Next() = 0;
virtual cTile *PeekNext() = 0;
virtual int GetNum() = 0;
virtual int GetCurrentLayer() = 0;
};
} // namespace hpl
#endif // HPL_TILEMAP_IT_H

View File

@@ -0,0 +1,270 @@
/* 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/TileMapLineIt.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cTileMapLineIt::cTileMapLineIt(cVector2f avStartPos, cVector2f avEndPos, cTileMap *apTileMap, int alLayer) {
mpTileMap = apTileMap;
mpTile = NULL;
mvPos = avStartPos;
mlLayer = alLayer;
mlLayerCount = 0;
mlCurrentLayer = 0;
mbAtLastTile = false;
mbAddNext = true;
float fAngle = cMath::GetAngleFromPoints2D(avStartPos, avEndPos);
float fDist = sqrt(mpTileMap->GetTileSize() * mpTileMap->GetTileSize());
mvPosAdd = cMath::GetVectorFromAngle2D(fAngle, fDist);
mvPos = avStartPos;
// Get the current tile
mvTilePos = cVector2l((int)floor(avStartPos.x / apTileMap->GetTileSize()),
(int)floor(avStartPos.y / apTileMap->GetTileSize()));
mlTileNum = mvTilePos.x + mvTilePos.y * mpTileMap->mvSize.x;
mvEndPos = cVector2l((int)floor(avEndPos.x / apTileMap->GetTileSize()),
(int)floor(avEndPos.y / apTileMap->GetTileSize()));
if (mvEndPos == mvTilePos)
mbAtLastTile = true;
/*Log("Start: %d %d\n", mvTilePos.x,mvTilePos.y);
Log("End: %d %d\n", mvEndPos.x,mvEndPos.y);
Log("End: %f : %f\n",avEndPos.x,avEndPos.y);
Log("Pos: %s\n",mvPos.ToString().c_str());
Log("Add: %s\n",mvPosAdd.ToString().c_str());
Log("Angle: %f\n\n",(fAngle/k2Pif)*360);
Log("%f : %f\n", mvPosAdd.x / (avEndPos.x - avStartPos.x), mvPosAdd.y / (avEndPos.y - avStartPos.y));
Log("-------------\n");*/
/*Check if the tilepos is outside of the map*/
if (mvTilePos.x < 0 || mvTilePos.y < 0 || mvTilePos.x >= mpTileMap->mvSize.x ||
mvTilePos.y >= mpTileMap->mvSize.y) {
mlLayerCount = (int)mpTileMap->mvTileLayer.size();
}
mbUpdated = false;
}
//-----------------------------------------------------------------------
cTileMapLineIt::~cTileMapLineIt() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cTileMapLineIt::HasNext() {
GetTile();
return mpTile != NULL;
}
//-----------------------------------------------------------------------
cTile *cTileMapLineIt::Next() {
GetTile();
mbUpdated = false;
return mpTile;
}
//-----------------------------------------------------------------------
cTile *cTileMapLineIt::PeekNext() {
GetTile();
return mpTile;
}
//-----------------------------------------------------------------------
int cTileMapLineIt::GetNum() {
return mlTileNum;
}
//-----------------------------------------------------------------------
int cTileMapLineIt::GetCurrentLayer() {
return mlCurrentLayer;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cTileMapLineIt::GetTile() {
if (mbUpdated)
return;
mbUpdated = true;
// We are gonna check till we find a non NULL value or the end.
while (true) {
// Check if end of the this tile pos
if ((mlLayer >= 0 && mlLayerCount > 0) || (mlLayer == -1 && mlLayerCount >= (int)mpTileMap->mvTileLayer.size())) {
if (mbAtLastTile) {
mpTile = NULL;
break;
}
// add pos so we go to the next tile.
if (mbAddNext) {
mvPos += mvPosAdd;
// Get the current tile
cVector2l vLastTilePos = mvTilePos;
mvTilePos = cVector2l((int)floor(mvPos.x / mpTileMap->GetTileSize()),
(int)floor(mvPos.y / mpTileMap->GetTileSize()));
// if there has been a change on both x and y then I tile has been missed
if (mvTilePos.x != vLastTilePos.x && mvTilePos.y != vLastTilePos.y) {
cVector2l vAdd = mvTilePos - vLastTilePos;
// Log("Too big jump!\n");
cVector2f vIntersectX, vIntersectY;
cVector2f vOldPos = mvPos - mvPosAdd;
GetXYIntersection(vOldPos, &vIntersectX, &vIntersectY);
if (cMath::SqrDist2D(vOldPos, vIntersectX) < cMath::SqrDist2D(vOldPos, vIntersectY))
mvTilePos = cVector2l(vLastTilePos.x, vLastTilePos.y + vAdd.y);
else
mvTilePos = cVector2l(vLastTilePos.x + vAdd.x, vLastTilePos.y);
mbAddNext = false;
}
} else {
mbAddNext = true;
mvTilePos = cVector2l((int)floor(mvPos.x / mpTileMap->GetTileSize()),
(int)floor(mvPos.y / mpTileMap->GetTileSize()));
}
/*Check if the tilepos is outside of the map*/
if (mvTilePos.x < 0 || mvTilePos.y < 0 || mvTilePos.x >= mpTileMap->mvSize.x ||
mvTilePos.y >= mpTileMap->mvSize.y) {
mpTile = NULL;
Error("Outside of bounds!\n");
// should just not set mlLayer count to 0. SO that the start can be soutside of the map.
break;
} else {
mlLayerCount = 0;
}
mlTileNum = mvTilePos.x + mvTilePos.y * mpTileMap->mvSize.x;
// Log("Next: %d %d\n", mvTilePos.x,mvTilePos.y);
// Log("Pos: %s\n",mvPos.ToString().c_str());
if (mvTilePos == mvEndPos) {
mbAtLastTile = true;
}
} else {
if (mlLayer < 0) {
mpTile = mpTileMap->mvTileLayer[mlLayerCount]->mvTile[mlTileNum];
mlCurrentLayer = mlLayerCount;
} else {
mpTile = mpTileMap->mvTileLayer[mlLayer]->mvTile[mlTileNum];
mlCurrentLayer = mlLayer;
}
mlLayerCount++;
if (mpTile != NULL) {
iTileData *pData = mpTile->GetTileData();
if (pData && pData->IsSolid()) {
mlLayerCount = (int)mpTileMap->mvTileLayer.size();
}
break;
}
}
}
}
//-----------------------------------------------------------------------
void cTileMapLineIt::GetXYIntersection(const cVector2f &avPosA,
cVector2f *avXIntersect, cVector2f *avYIntersect) {
// Calculate DX
float fDx;
if (mvPosAdd.x > 0)
fDx = ceil(avPosA.x / mpTileMap->GetTileSize()) * mpTileMap->GetTileSize();
else
fDx = floor(avPosA.x / mpTileMap->GetTileSize()) * mpTileMap->GetTileSize();
fDx = fDx - avPosA.x;
// Calculate DY
float fDy;
if (mvPosAdd.y > 0)
fDy = ceil(avPosA.y / mpTileMap->GetTileSize()) * mpTileMap->GetTileSize();
else
fDy = floor(avPosA.y / mpTileMap->GetTileSize()) * mpTileMap->GetTileSize();
fDy = fDy - avPosA.y;
// Get Y Intersection
float fDiv = mvPosAdd.x == 0 ? 0.00001f : mvPosAdd.x; // Handle div by 0
float fInterY = (fDx / fDiv) * mvPosAdd.y;
avYIntersect->x = avPosA.x + fDx;
avYIntersect->y = avPosA.y + fInterY;
// Get X Intersection
fDiv = mvPosAdd.y == 0 ? 0.00001f : mvPosAdd.y; // Handle div by 0
float fInterX = (fDy / fDiv) * mvPosAdd.x;
avXIntersect->y = avPosA.y + fDy;
avXIntersect->x = avPosA.x + fInterX;
// Log("fDx: %0.2f fDy: %0.2f\n",fDx,fDy);
// Log("Intersections: X: %0.2f %0.2f Y: %0.2f %0.2f\n",avXIntersect->x,avXIntersect->y,
// avYIntersect->x,avYIntersect->y);
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,83 @@
/* 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.
*/
#ifndef HPL_TILEMAP_LINE_IT_H
#define HPL_TILEMAP_LINE_IT_H
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/scene/TileMap.h"
#include "hpl1/engine/scene/TileMapIt.h"
namespace hpl {
class cTileMapLineIt : public iTileMapIt {
public:
/**
*
* \param avPos
* \param avSize
* \param apTileMap
* \param alLayer The layer that is to be iterated. -1 = All layers (hiding tiles behind solid ones)
* \return
*/
cTileMapLineIt(cVector2f avStartPos, cVector2f avEndPos, cTileMap *apTileMap, int alLayer);
~cTileMapLineIt();
bool HasNext();
cTile *Next();
cTile *PeekNext();
int GetNum();
int GetCurrentLayer();
private:
cVector2l mvEndPos;
cVector2f mvPos;
cVector2f mvPosAdd;
cVector2l mvTilePos;
int mlLayer;
int mlLayerCount;
int mlCurrentLayer;
int mlTileNum;
bool mbUpdated;
bool mbAtLastTile;
bool mbAddNext;
cTileMap *mpTileMap;
cTile *mpTile;
void GetTile();
void GetXYIntersection(const cVector2f &avPosA, cVector2f *avXIntersect, cVector2f *avYIntersect);
};
} // namespace hpl
#endif // HPL_TILEMAP_LINE_IT_H

View File

@@ -0,0 +1,187 @@
/* 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/TileMapRectIt.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cTileMapRectIt::cTileMapRectIt(cVector2l avPos, cVector2l avSize, cTileMap *apTileMap, int alLayer) {
mpTileMap = apTileMap;
mpTile = NULL;
mvPos = avPos;
mvSize = avSize;
mlLayer = alLayer;
mlLayerCount = 0;
mlCurrentLayer = 0;
//// Clip the pos and size //////
// Pos smaller then (0,0)
if (mvPos.x < 0) {
mvSize.x += mvPos.x;
mvPos.x = 0;
}
if (mvPos.y < 0) {
mvSize.y += mvPos.y;
mvPos.y = 0;
}
// Size large than grid map
if (mvPos.x + mvSize.x > mpTileMap->mvSize.x) {
mvSize.x -= (mvPos.x + mvSize.x) - (mpTileMap->mvSize.x);
}
if (mvPos.y + mvSize.y > mpTileMap->mvSize.y) {
mvSize.y -= (mvPos.y + mvSize.y) - (mpTileMap->mvSize.y);
}
mlTileNum = mvPos.x + mvPos.y * mpTileMap->mvSize.x;
mlTileColAdd = mpTileMap->mvSize.x - mvSize.x;
mlTileRowCount = mvSize.y;
mlTileColCount = mvSize.x;
// The rect is outside of the tilemap
if (mvSize.x <= 0 || mvSize.y <= 0 || mvPos.x >= mpTileMap->mvSize.x || mvPos.y >= mpTileMap->mvSize.y) {
mlTileColCount = 0;
mlTileRowCount = 0;
mlLayerCount = (int)mpTileMap->mvTileLayer.size();
} else {
}
mbUpdated = false;
}
//-----------------------------------------------------------------------
cTileMapRectIt::~cTileMapRectIt() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cTileMapRectIt::HasNext() {
GetTile();
return mpTile != NULL;
}
//-----------------------------------------------------------------------
cTile *cTileMapRectIt::Next() {
GetTile();
mbUpdated = false;
return mpTile;
}
//-----------------------------------------------------------------------
cTile *cTileMapRectIt::PeekNext() {
GetTile();
return mpTile;
}
//-----------------------------------------------------------------------
int cTileMapRectIt::GetNum() {
return mlTileNum;
}
//-----------------------------------------------------------------------
int cTileMapRectIt::GetCurrentLayer() {
return mlCurrentLayer;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cTileMapRectIt::GetTile() {
if (mbUpdated)
return;
mbUpdated = true;
// We are gonna check till we find a non NULL value or the end.
while (true) {
// Check if end of the this tile pos
if ((mlLayer >= 0 && mlLayerCount > 0) || (mlLayer == -1 && mlLayerCount >= (int)mpTileMap->mvTileLayer.size())) {
mlLayerCount = 0;
mlTileNum++;
mlTileColCount--;
if (mlTileColCount <= 0) {
// Log("New row!\n\n");
mlTileColCount = mvSize.x;
mlTileRowCount--;
if (mlTileRowCount <= 0) {
mpTile = NULL;
break;
}
mlTileNum += mlTileColAdd;
}
} else {
if (mlLayer < 0) {
mpTile = mpTileMap->mvTileLayer[mlLayerCount]->mvTile[mlTileNum];
mlCurrentLayer = mlLayerCount;
} else {
mpTile = mpTileMap->mvTileLayer[mlLayer]->mvTile[mlTileNum];
mlCurrentLayer = mlLayer;
}
mlLayerCount++;
if (mpTile != NULL) {
iTileData *pData = mpTile->GetTileData();
if (pData && pData->IsSolid()) {
mlLayerCount = (int)mpTileMap->mvTileLayer.size();
}
break;
}
}
}
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,78 @@
/* 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.
*/
#ifndef HPL_TILEMAP_RECT_IT_H
#define HPL_TILEMAP_RECT_IT_H
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/scene/TileMap.h"
#include "hpl1/engine/scene/TileMapIt.h"
namespace hpl {
class cTileMapRectIt : public iTileMapIt {
public:
/**
*
* \param avPos
* \param avSize
* \param apTileMap
* \param alLayer The layer that is to be iterated. -1 = All layers (hiding tiles behind solid ones)
* \return
*/
cTileMapRectIt(cVector2l avPos, cVector2l avSize, cTileMap *apTileMap, int alLayer);
~cTileMapRectIt();
bool HasNext();
cTile *Next();
cTile *PeekNext();
int GetNum();
int GetCurrentLayer();
private:
cVector2l mvPos;
cVector2l mvSize;
int mlLayer;
int mlLayerCount;
int mlTileNum;
int mlTileColAdd;
int mlTileRowCount;
int mlTileColCount;
int mlCurrentLayer;
bool mbUpdated;
cTileMap *mpTileMap;
cTile *mpTile;
void GetTile();
};
} // namespace hpl
#endif // HPL_TILEMAP_RECT_IT_H

View File

@@ -0,0 +1,220 @@
/* 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/TileSet.h"
#include "hpl1/engine/graphics/MaterialHandler.h"
#include "hpl1/engine/graphics/MeshCreator.h"
#include "hpl1/engine/impl/tinyXML/tinyxml.h"
#include "hpl1/engine/resources/Resources.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cTileSet::cTileSet(tString asName, cGraphics *apGraphics, cResources *apResources)
: iResourceBase(asName, 0) {
mpResources = apResources;
mfTileSize = 0;
mpGraphics = apGraphics;
for (int i = 0; i < eMaterialTexture_LastEnum; i++)
mvImageHandle[i] = -1;
}
//-----------------------------------------------------------------------
cTileSet::~cTileSet() {
Log(" Deleting tileset.\n");
for (tTileDataVecIt it = mvData.begin(); it != mvData.end(); it++) {
(*it)->Destroy();
hplDelete(*it);
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cTileSet::Add(iTileData *apData) {
mvData.push_back(apData);
}
//-----------------------------------------------------------------------
iTileData *cTileSet::Get(int alNum) {
assert(alNum >= 0 && alNum < (int)mvData.size());
return mvData[alNum];
}
//-----------------------------------------------------------------------
bool cTileSet::CreateFromFile(const tString &asFile) {
TiXmlDocument *pDoc = hplNew(TiXmlDocument, (asFile.c_str()));
if (!pDoc->LoadFile()) {
error("Couldn't load tileset '%s'", asFile.c_str());
return false;
}
GetTileNum(pDoc->RootElement()->FirstChildElement());
// Add the resources
mpResources->AddResourceDir(pDoc->RootElement()->Attribute("dir"));
// Get the tiles size
mfTileSize = (float)cString::ToInt(pDoc->RootElement()->Attribute("size"), 0);
// Calculate the best size for the frame:
double x = ceil(log((double)((float)mlNum) * mfTileSize) / log(2.0f));
double y = ceil(log((double)mfTileSize) / log(2.0f));
if (x > kMaxTileFrameWidth) {
y += x - kMaxTileFrameWidth;
x = kMaxTileFrameWidth;
}
mvFrameSize = cVector2l((int)pow(2.0, x), (int)pow(2.0, y));
TiXmlElement *pTileElement = pDoc->RootElement()->FirstChildElement();
while (pTileElement != NULL) {
LoadData(pTileElement);
pTileElement = pTileElement->NextSiblingElement();
}
hplDelete(pDoc);
mpResources->GetImageManager()->FlushAll();
return true;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cTileSet::LoadData(TiXmlElement *pElement) {
tString sName = pElement->Attribute("name");
tString sMaterial = pElement->Attribute("material");
tString sMesh = pElement->Attribute("mesh");
tString sCollideMesh = cString::ToString(pElement->Attribute("collidemesh"), "");
iMaterial *pMaterial = NULL;
cMesh2D *pMesh = NULL;
cMesh2D *pCollideMesh = NULL;
cResourceImage *pImage = NULL;
cTileDataNormal *pTileData = hplNew(cTileDataNormal, (mpResources->GetImageManager(), mfTileSize));
// Log("Tile %s:\n", sName.c_str());
// Log("Creating material: %s\n",sMaterial.c_str());
// Create material
pMaterial = mpGraphics->GetMaterialHandler()->Create(sMaterial, eMaterialPicture_Image);
if (pMaterial == NULL) {
Error("Error creating material '%s' for '%s'!\n", sMaterial.c_str(), sName.c_str());
return false;
}
// Log("Loading images..\n");
// Load the images
tTextureTypeList lstTypes = pMaterial->GetTextureTypes();
for (tTextureTypeListIt it = lstTypes.begin(); it != lstTypes.end(); it++) {
if (mvImageHandle[it->mType] == -1) {
mvImageHandle[it->mType] = mpResources->GetImageManager()->CreateFrame(mvFrameSize);
}
pImage = mpResources->GetImageManager()->CreateImage(sName + it->msSuffix, mvImageHandle[it->mType]);
if (pImage == NULL) {
Error("Can't load texture '%s%s'!\n", sName.c_str(), it->msSuffix.c_str());
return false;
}
pMaterial->SetImage(pImage, it->mType);
}
// Compile material
pMaterial->Compile();
// Create the mesh
pMesh = mpGraphics->GetMeshCreator()->Create2D(sMesh, mfTileSize);
if (pMesh == NULL) {
Error("Error creating mesh for '%s'!\n", sName.c_str());
return false;
}
pTileData->SetData(pMesh, pMaterial);
// Create the collide mesh
if (sCollideMesh != "") {
pCollideMesh = mpGraphics->GetMeshCreator()->Create2D(sCollideMesh, mfTileSize);
if (pCollideMesh == NULL) {
Error("Error creating collide mesh for '%s'!\n", sName.c_str());
return false;
}
pCollideMesh->CreateTileVertexVec();
pTileData->SetCollideMesh(pCollideMesh);
}
// Set the tilesdata properties:
pTileData->SetIsSolid(cString::ToInt(pElement->Attribute("solid"), 1) ? true : false);
eTileCollisionType CType = (eTileCollisionType)cString::ToInt(pElement->Attribute("collision_type"), 1);
pTileData->SetCollisionType(CType);
Add(pTileData);
return true;
}
//-----------------------------------------------------------------------
void cTileSet::GetTileNum(TiXmlElement *apElement) {
mlNum = 0;
while (apElement != NULL) {
mlNum++;
apElement = apElement->NextSiblingElement();
}
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,79 @@
/* 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.
*/
#ifndef HPL_TILESET_H
#define HPL_TILESET_H
#include "common/array.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/resources/ResourceBase.h"
#include "hpl1/engine/scene/TileData.h"
#include "hpl1/engine/system/SystemTypes.h"
class TiXmlElement;
namespace hpl {
#define kMaxTileFrameWidth (9)
typedef Common::Array<iTileData *> tTileDataVec;
typedef tTileDataVec::iterator tTileDataVecIt;
class cResources;
class cTileSet : public iResourceBase {
public:
cTileSet(tString asName, cGraphics *apGraphics, cResources *apResources);
~cTileSet();
// resource stuff:
bool reload() { return false; }
void unload() {}
void destroy() {}
void Add(iTileData *apData);
iTileData *Get(int alNum);
bool CreateFromFile(const tString &asFile);
private:
float mfTileSize;
tTileDataVec mvData;
cResources *mpResources;
cGraphics *mpGraphics;
int mlNum;
int mvImageHandle[eMaterialTexture_LastEnum];
cVector2l mvFrameSize;
bool LoadData(TiXmlElement *pElement);
void GetTileNum(TiXmlElement *apElement);
};
} // namespace hpl
#endif // HPL_TILESET_H

View File

@@ -0,0 +1,816 @@
/* 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/World2D.h"
#include "hpl1/engine/graphics/Graphics.h"
#include "hpl1/engine/graphics/ImageEntityData.h"
#include "hpl1/engine/graphics/Mesh2d.h"
#include "hpl1/engine/impl/tinyXML/tinyxml.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/physics/Body2D.h"
#include "hpl1/engine/physics/Collider2D.h"
#include "hpl1/engine/resources/FileSearcher.h"
#include "hpl1/engine/resources/ParticleManager.h"
#include "hpl1/engine/resources/Resources.h"
#include "hpl1/engine/resources/ScriptManager.h"
#include "hpl1/engine/resources/TileSetManager.h"
#include "hpl1/engine/scene/Area2D.h"
#include "hpl1/engine/scene/Camera.h"
#include "hpl1/engine/scene/GridMap2D.h"
#include "hpl1/engine/scene/ImageEntity.h"
#include "hpl1/engine/scene/Light2DPoint.h"
#include "hpl1/engine/scene/Node2D.h"
#include "hpl1/engine/scene/SoundSource.h"
#include "hpl1/engine/scene/TileMap.h"
#include "hpl1/engine/system/MemoryManager.h"
#include "hpl1/engine/system/Script.h"
#include "hpl1/engine/system/String.h"
#include "hpl1/engine/system/low_level_system.h"
#include "hpl1/engine/graphics/Renderer2D.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cWorld2D::cWorld2D(tString asName, cGraphics *apGraphics, cResources *apResources, cSound *apSound, cCollider2D *apCollider) {
mpGraphics = apGraphics;
mpResources = apResources;
mpSound = apSound;
mpCollider = apCollider;
mpRootNode = hplNew(cNode2D, ());
mpMapLights = NULL;
mpMapImageEntities = NULL;
mpMapBodies = NULL;
mpTileMap = NULL;
mpScript = NULL;
msName = asName;
mfLightZ = 10;
mAmbientColor = cColor(0, 0);
mlBodyIDCount = 0;
}
//-----------------------------------------------------------------------
cWorld2D::~cWorld2D() {
if (mpTileMap)
hplDelete(mpTileMap);
if (mpMapLights)
hplDelete(mpMapLights);
if (mpMapImageEntities)
hplDelete(mpMapImageEntities);
if (mpMapBodies)
hplDelete(mpMapBodies);
if (mpMapParticles)
hplDelete(mpMapParticles);
if (mpMapAreas)
hplDelete(mpMapAreas);
tSoundSourceListIt it = mlstSoundSources.begin();
while (it != mlstSoundSources.end()) {
hplDelete(*it);
it++;
}
mlstSoundSources.clear();
if (mpScript) {
mpResources->GetScriptManager()->Destroy(mpScript);
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cWorld2D::Render(cCamera2D *apCamera) {
mpTileMap->Render(apCamera);
RenderImagesEntities(apCamera);
RenderParticles(apCamera);
}
//-----------------------------------------------------------------------
void cWorld2D::Update(float afTimeStep) {
UpdateEntities();
UpdateBodies();
UpdateParticles();
UpdateSoundSources();
UpdateLights();
}
//-----------------------------------------------------------------------
cLight2DPoint *cWorld2D::CreateLightPoint(tString asName) {
if (mpMapLights == NULL)
return NULL;
cLight2DPoint *pLight = hplNew(cLight2DPoint, (asName));
mpMapLights->AddEntity(pLight);
// Add the light to the base node awell...
return pLight;
}
//-----------------------------------------------------------------------
void cWorld2D::DestroyLight(iLight2D *apLight) {
if (mpMapLights == NULL)
return;
mpMapLights->RemoveEntity(apLight);
hplDelete(apLight);
}
//-----------------------------------------------------------------------
cGridMap2D *cWorld2D::GetGridMapLights() {
return mpMapLights;
}
//-----------------------------------------------------------------------
iLight2D *cWorld2D::GetLight(const tString &asName) {
tGrid2DObjectMap *pGridMap = mpMapLights->GetAllMap();
tGrid2DObjectMapIt it = pGridMap->begin();
for (; it != pGridMap->end(); it++) {
cGrid2DObject *pObj = it->second;
if (pObj->GetEntity()->GetName() == asName) {
return static_cast<iLight2D *>(pObj->GetEntity());
}
}
return NULL;
}
//-----------------------------------------------------------------------
cSoundSource *cWorld2D::CreateSoundSource(const tString &asName, const tString &asSoundName,
bool abVolatile) {
cSoundSource *pSoundSource = hplNew(cSoundSource, (asName, asSoundName, mpSound, abVolatile));
mlstSoundSources.push_back(pSoundSource);
return pSoundSource;
}
//-----------------------------------------------------------------------
void cWorld2D::DestroySoundSource(cSoundSource *apSound) {
mlstSoundSources.remove(apSound);
hplDelete(apSound);
}
//-----------------------------------------------------------------------
cImageEntity *cWorld2D::CreateImageEntity(tString asName, tString asDataName) {
cImageEntity *pEntity = hplNew(cImageEntity, (asName, mpResources, mpGraphics));
if (pEntity == NULL)
return NULL;
if (pEntity->LoadEntityData(asDataName)) {
mpMapImageEntities->AddEntity(pEntity);
} else {
hplDelete(pEntity);
}
return pEntity;
}
//-----------------------------------------------------------------------
void cWorld2D::DestroyImageEntity(cImageEntity *apEntity) {
if (mpMapImageEntities == NULL)
return;
mpMapImageEntities->RemoveEntity(apEntity);
hplDelete(apEntity);
}
//-----------------------------------------------------------------------
cImageEntity *cWorld2D::GetImageEntity(const tString &asName) {
tGrid2DObjectMap *pGridMap = mpMapImageEntities->GetAllMap();
tGrid2DObjectMapIt it = pGridMap->begin();
for (; it != pGridMap->end(); it++) {
cGrid2DObject *pObj = it->second;
if (pObj->GetEntity()->GetName() == asName) {
return static_cast<cImageEntity *>(pObj->GetEntity());
}
}
return NULL;
}
//-----------------------------------------------------------------------
iParticleSystem2D *cWorld2D::CreateParticleSystem(const tString &asName, const cVector3f &avSize) {
/*iParticleSystem2D* pPS = mpResources->GetParticleManager()->CreatePS2D(asName, avSize);
if(pPS == NULL){
Error("Couldn't create particle system '%s'\n",asName.c_str());
}
mpMapParticles->AddEntity(pPS);
return pPS;*/
return NULL;
}
//-----------------------------------------------------------------------
void cWorld2D::DestroyParticleSystem(iParticleSystem2D *apPS) {
/*if(apPS==NULL)return;
mpMapParticles->RemoveEntity(apPS);
hplDelete(apPS);*/
}
//-----------------------------------------------------------------------
cBody2D *cWorld2D::CreateBody2D(const tString &asName, cMesh2D *apMesh, cVector2f avSize) {
cBody2D *pBody = hplNew(cBody2D, (asName, apMesh, avSize, mpCollider, mlBodyIDCount++));
mpMapBodies->AddEntity(pBody);
return pBody;
}
//-----------------------------------------------------------------------
cArea2D *cWorld2D::GetArea(const tString &asName, const tString &asType) {
tGrid2DObjectMap *GridMap = mpMapAreas->GetAllMap();
tGrid2DObjectMapIt it = GridMap->begin();
while (it != GridMap->end()) {
cArea2D *pArea = static_cast<cArea2D *>(it->second->GetEntity());
if (asName == "" || pArea->GetName() == asName) {
if (asType == "" || pArea->GetType() == asType) {
return pArea;
}
}
it++;
}
return NULL;
}
//-----------------------------------------------------------------------
bool cWorld2D::CreateFromFile(tString asFile) {
// Load the document
asFile = cString::SetFileExt(asFile, "hpl");
tString sPath = mpResources->GetFileSearcher()->GetFilePath(asFile);
if (sPath == "") {
error("Couldn't find map '%s'", asFile.c_str());
return false;
}
TiXmlDocument *pDoc = hplNew(TiXmlDocument, (sPath.c_str()));
if (!pDoc->LoadFile()) {
error("Couldn't load map '%s'", asFile.c_str());
return false;
}
// Load the script
asFile = cString::SetFileExt(asFile, "hps");
mpScript = mpResources->GetScriptManager()->CreateScript(asFile);
if (mpScript == NULL) {
Error("Couldn't load script '%s'", asFile.c_str());
}
TiXmlElement *pHplMapElem = pDoc->RootElement();
cVector2l vMapSize;
msMapName = pHplMapElem->Attribute("Name");
vMapSize.x = cString::ToInt(pHplMapElem->Attribute("Width"), 0);
vMapSize.y = cString::ToInt(pHplMapElem->Attribute("Height"), 0);
float fTileSize = (float)cString::ToInt(pHplMapElem->Attribute("TileSize"), 0);
mfLightZ = cString::ToFloat(pHplMapElem->Attribute("LightZ"), 0);
mAmbientColor.r = cString::ToFloat(pHplMapElem->Attribute("AmbColR"), 0) / 255.0f;
mAmbientColor.g = cString::ToFloat(pHplMapElem->Attribute("AmbColG"), 0) / 255.0f;
mAmbientColor.b = cString::ToFloat(pHplMapElem->Attribute("AmbColB"), 0) / 255.0f;
mAmbientColor.a = 0;
// Log("Amb: %f : %f : %f : %f\n",mAmbientColor.r,mAmbientColor.g,mAmbientColor.b,mAmbientColor.a);
mpGraphics->GetRenderer2D()->SetAmbientLight(mAmbientColor);
mpGraphics->GetRenderer2D()->SetShadowZ(mfLightZ);
// Set up data for objects.
cVector2l vWorldSize = vMapSize * (int)fTileSize;
mvWorldSize = cVector2f((float)vWorldSize.x, (float)vWorldSize.y);
mpMapLights = hplNew(cGridMap2D, (vWorldSize, cVector2l(200, 200), cVector2l(5, 5)));
mpMapImageEntities = hplNew(cGridMap2D, (vWorldSize, cVector2l(150, 150), cVector2l(5, 5)));
mpMapBodies = hplNew(cGridMap2D, (vWorldSize, cVector2l(150, 150), cVector2l(5, 5)));
mpMapParticles = hplNew(cGridMap2D, (vWorldSize, cVector2l(300, 300), cVector2l(3, 3)));
mpMapAreas = hplNew(cGridMap2D, (vWorldSize, cVector2l(300, 300), cVector2l(3, 3)));
TiXmlElement *pHplMapChildElem = pHplMapElem->FirstChildElement();
while (pHplMapChildElem) {
tString sChildName = pHplMapChildElem->Value();
/////////////////
/// LIGHTS //////
/////////////////
if (sChildName == "Lights") {
TiXmlElement *pLightChildElem = pHplMapChildElem->FirstChildElement();
while (pLightChildElem) {
cVector3f vPos;
cColor Col(0, 1);
cLight2DPoint *pLight = CreateLightPoint(pLightChildElem->Attribute("Name"));
vPos.x = cString::ToFloat(pLightChildElem->Attribute("X"), 0);
vPos.y = cString::ToFloat(pLightChildElem->Attribute("Y"), 0);
vPos.z = cString::ToFloat(pLightChildElem->Attribute("Z"), 0);
pLight->SetPosition(vPos);
Col.r = cString::ToFloat(pLightChildElem->Attribute("ColR"), 0) / 255.0f;
Col.g = cString::ToFloat(pLightChildElem->Attribute("ColG"), 0) / 255.0f;
Col.b = cString::ToFloat(pLightChildElem->Attribute("ColB"), 0) / 255.0f;
Col.a = cString::ToFloat(pLightChildElem->Attribute("Specular"), 1);
pLight->SetDiffuseColor(Col);
pLight->SetFarAttenuation(cString::ToFloat(pLightChildElem->Attribute("Radius"), 0));
pLight->SetActive(cString::ToBool(pLightChildElem->Attribute("Active"), true));
/*LOad some more stuff*/
pLight->SetAffectMaterial(cString::ToBool(pLightChildElem->Attribute("AffectMaterial"), true));
pLight->SetCastShadows(cString::ToBool(pLightChildElem->Attribute("CastShadows"), true));
pLightChildElem = pLightChildElem->NextSiblingElement();
}
}
////////////////////////
/// ENTITIES ///////////
////////////////////////
else if (sChildName == "Entities") {
TiXmlElement *pEntityElem = pHplMapChildElem->FirstChildElement();
while (pEntityElem) {
tString sRenderType = cString::ToString(pEntityElem->Attribute("RenderType"), "Image");
if (sRenderType == "Image") {
cImageEntity *pEntity = hplNew(cImageEntity, (cString::ToString(
pEntityElem->Attribute("Name"), "Image"),
mpResources, mpGraphics));
// The the main data
cVector3f vPos;
vPos.x = cString::ToFloat(pEntityElem->Attribute("X"), 0);
vPos.y = cString::ToFloat(pEntityElem->Attribute("Y"), 0);
vPos.z = cString::ToFloat(pEntityElem->Attribute("Z"), 0);
pEntity->SetPosition(vPos);
pEntity->SetActive(cString::ToBool(pEntityElem->Attribute("Active"), true));
if (pEntity->LoadData(pEntityElem)) {
mpMapImageEntities->AddEntity(pEntity);
iEntity2DLoader *pLoader = mpResources->GetEntity2DLoader(
pEntity->GetEntityData()->GetType());
if (pLoader) {
pLoader->Load(pEntity);
} else {
/*Maybe delete entity if no type found? */
}
} else {
Error("Couldn't load data for entity '%s'", pEntity->GetName().c_str());
hplDelete(pEntity);
}
} else {
error("No other Render mode for entity exist!!");
}
pEntityElem = pEntityElem->NextSiblingElement();
}
}
/////////////////////////////
/// SOUND SOURCES ///////////
/////////////////////////////
else if (sChildName == "SoundSources") {
TiXmlElement *pSoundElem = pHplMapChildElem->FirstChildElement();
while (pSoundElem) {
cSoundSource *pSound = hplNew(cSoundSource, (
cString::ToString(pSoundElem->Attribute("Name"), ""),
cString::ToString(pSoundElem->Attribute("SoundName"), ""),
mpSound, false));
pSound->LoadData(pSoundElem);
mlstSoundSources.push_back(pSound);
pSoundElem = pSoundElem->NextSiblingElement();
}
}
/////////////////////////////
/// PARTICLE SYSTEMS ///////////
/////////////////////////////
/*else if(sChildName == "ParticleSystems")
{
TiXmlElement* pPartElem = pHplMapChildElem->FirstChildElement();
while(pPartElem)
{
iParticleSystem2D* pPS;
tString sName = cString::ToString(pPartElem->Attribute("Name"),"");
tString sPartName = cString::ToString(pPartElem->Attribute("PartName"),"");
cVector3f vSize;
cVector3f vPos;
vSize.x = cString::ToFloat(pPartElem->Attribute("SizeX"),0);
vSize.y = cString::ToFloat(pPartElem->Attribute("SizeY"),0);
vSize.z = cString::ToFloat(pPartElem->Attribute("SizeZ"),0);
vPos.x = cString::ToFloat(pPartElem->Attribute("X"),0);
vPos.y = cString::ToFloat(pPartElem->Attribute("Y"),0);
vPos.z = cString::ToFloat(pPartElem->Attribute("Z"),0);
pPS = mpResources->GetParticleManager()->CreatePS2D(sPartName,vSize);
if(pPS==NULL){
Error("Couldn't load particle system '%s'!\n",sPartName.c_str());
}
else {
pPS->SetName(sName);
pPS->SetPosition(vPos);
mpMapParticles->AddEntity(pPS);
}
pPartElem = pPartElem->NextSiblingElement();
}
}*/
/////////////////////////////
/// AREAS ///////////////////
/////////////////////////////
else if (sChildName == "Areas") {
TiXmlElement *pAreaElem = pHplMapChildElem->FirstChildElement();
while (pAreaElem) {
cArea2D *pArea;
tString sName = cString::ToString(pAreaElem->Attribute("Name"), "");
tString sAreaType = cString::ToString(pAreaElem->Attribute("AreaType"), "");
cVector3f vPos;
vPos.x = cString::ToFloat(pAreaElem->Attribute("X"), 0);
vPos.y = cString::ToFloat(pAreaElem->Attribute("Y"), 0);
vPos.z = cString::ToFloat(pAreaElem->Attribute("Z"), 0);
pArea = hplNew(cArea2D, (sName, sAreaType, mpCollider));
pArea->LoadData(pAreaElem);
pArea->SetName(sName);
pArea->SetPosition(vPos);
if (pArea->GetType() != "Script") {
iArea2DLoader *pAreaLoader = mpResources->GetArea2DLoader(pArea->GetType());
if (pAreaLoader) {
pAreaLoader->Load(pArea);
}
}
mpMapAreas->AddEntity(pArea);
pAreaElem = pAreaElem->NextSiblingElement();
}
}
/////////////////
/// TILEMAP /////
/////////////////
else if (sChildName == "TileMap") {
mpTileMap = hplNew(cTileMap, (vMapSize, fTileSize, mpGraphics, mpResources));
int lShadowLayer = cString::ToInt(pHplMapChildElem->Attribute("ShadowLayer"), 0);
TiXmlElement *pTileMapChildElem = pHplMapChildElem->FirstChildElement();
while (pTileMapChildElem) {
tString sTileMapChildName = pTileMapChildElem->Value();
// Log("Tilemap: %s\n",sTileMapChildName.c_str());
////////////////////////
/// TILE SETS //////////
////////////////////////
if (sTileMapChildName == "TileSets") {
TiXmlElement *pTileSetChildElem = pTileMapChildElem->FirstChildElement();
while (pTileSetChildElem) {
tString sName = pTileSetChildElem->Attribute("Name");
cTileSet *pTileSet = mpResources->GetTileSetManager()->CreateTileSet(sName);
mpTileMap->AddTileSet(pTileSet);
pTileSetChildElem = pTileSetChildElem->NextSiblingElement();
}
}
////////////////////////
/// TILE LAYERS ////////
///////////////////////
else if (sTileMapChildName == "Layers") {
// Log("Layers\n");
TiXmlElement *pLayerChildElem = pTileMapChildElem->FirstChildElement();
while (pLayerChildElem) {
// Log("Layer Children\n");
if (pLayerChildElem->Attribute("Width") == NULL)
error("Can't Load Width");
int lW = cString::ToInt(pLayerChildElem->Attribute("Width"), 0);
if (pLayerChildElem->Attribute("Height") == NULL)
error("Can't Load Height");
int lH = cString::ToInt(pLayerChildElem->Attribute("Height"), 0);
bool bCollide = cString::ToBool(pLayerChildElem->Attribute("Collide"), true);
bool bLit = cString::ToBool(pLayerChildElem->Attribute("Lit"), true);
float fZ = cString::ToFloat(pLayerChildElem->Attribute("Z"), 0);
cTileLayer *pTileLayer = hplNew(cTileLayer, (lW, lH,
bCollide, bLit, eTileLayerType_Normal));
pTileLayer->SetZ(fZ);
mpTileMap->AddTileLayerFront(pTileLayer);
//// THE TILES ////////
TiXmlElement *pTileRowElem = pLayerChildElem->FirstChildElement();
int lRowCount = 0;
while (pTileRowElem) {
// Log("Tile Row: ");
int lColCount = 0;
tString sData = pTileRowElem->Attribute("Data");
int lDataCount = 0;
while (lDataCount < (int)sData.size()) {
cTile *pTile = hplNew(cTile, (NULL, eTileRotation_0,
cVector3f((float)lColCount * fTileSize, (float)lRowCount * fTileSize, fZ),
cVector2f(fTileSize, fTileSize), NULL));
lDataCount = LoadTileData(pTile, &sData, lDataCount);
if (pTile->GetTileData()) {
// Create the collision mesh
if (pTileLayer->HasCollision()) {
cCollisionMesh2D *pCollMesh = NULL;
cTileDataNormal *pTData;
pTData = static_cast<cTileDataNormal *>(pTile->GetTileData());
if (pTData->GetCollideMesh()) {
pCollMesh = pTData->GetCollideMesh()->CreateCollisonMesh(
cVector2f(pTile->GetPosition().x,
pTile->GetPosition().y),
cVector2f(2),
pTile->GetAngle());
}
pTile->SetCollisionMesh(pCollMesh);
}
// Add tile to the layer
pTileLayer->SetTile(lColCount, lRowCount, pTile);
} else {
hplDelete(pTile);
}
lColCount++;
}
// Log("\n");
lRowCount++;
pTileRowElem = pTileRowElem->NextSiblingElement();
}
pLayerChildElem = pLayerChildElem->NextSiblingElement();
}
}
pTileMapChildElem = pTileMapChildElem->NextSiblingElement();
}
// Set the inverse shadow layer.
mpTileMap->SetShadowLayer(mpTileMap->GetTileLayerNum() - lShadowLayer - 1);
}
pHplMapChildElem = pHplMapChildElem->NextSiblingElement();
}
hplDelete(pDoc);
return true;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cWorld2D::UpdateSoundSources() {
tSoundSourceListIt it = mlstSoundSources.begin();
while (it != mlstSoundSources.end()) {
(*it)->UpdateLogic(0);
if ((*it)->IsDead()) {
it = mlstSoundSources.erase(it);
} else {
it++;
}
}
}
//-----------------------------------------------------------------------
void cWorld2D::UpdateParticles() {
/*tGrid2DObjectMapIt it = mpMapParticles->GetAllMap()->begin();
while(it != mpMapParticles->GetAllMap()->end())
{
iParticleSystem2D *pEntity = static_cast<iParticleSystem2D*>(it->second->GetEntity());
pEntity->UpdateLogic(0);
it++;
//Check if the system is alive, else destroy
if(pEntity->IsDead()){
DestroyParticleSystem(pEntity);
}
}*/
}
//-----------------------------------------------------------------------
void cWorld2D::RenderParticles(cCamera2D *apCamera) {
/*cRect2f ClipRect;
apCamera->GetClipRect(ClipRect);
iGridMap2DIt* pEntityIt = mpMapParticles->GetRectIterator(ClipRect);
while(pEntityIt->HasNext())
{
iParticleSystem2D* pEntity = static_cast<iParticleSystem2D*>(pEntityIt->Next());
pEntity->Render();
}
hplDelete(pEntityIt);*/
}
//-----------------------------------------------------------------------
void cWorld2D::UpdateEntities() {
tGrid2DObjectMapIt it = mpMapImageEntities->GetAllMap()->begin();
while (it != mpMapImageEntities->GetAllMap()->end()) {
iEntity2D *pEntity = static_cast<cImageEntity *>(it->second->GetEntity());
if (pEntity->IsActive())
pEntity->UpdateLogic(0);
it++;
}
}
//-----------------------------------------------------------------------
void cWorld2D::UpdateBodies() {
tGrid2DObjectMapIt it = mpMapBodies->GetAllMap()->begin();
while (it != mpMapBodies->GetAllMap()->end()) {
cBody2D *pBody = static_cast<cBody2D *>(it->second->GetEntity());
if (pBody->IsActive())
pBody->UpdateLogic(0);
it++;
}
}
//-----------------------------------------------------------------------
void cWorld2D::UpdateLights() {
tGrid2DObjectMapIt it = mpMapLights->GetAllMap()->begin();
while (it != mpMapLights->GetAllMap()->end()) {
iLight2D *pLight = static_cast<iLight2D *>(it->second->GetEntity());
if (pLight->IsActive())
pLight->UpdateLogic(0);
it++;
}
}
//-----------------------------------------------------------------------
void cWorld2D::RenderImagesEntities(cCamera2D *apCamera) {
cRect2f ClipRect;
apCamera->GetClipRect(ClipRect);
iGridMap2DIt *pEntityIt = mpMapImageEntities->GetRectIterator(ClipRect);
while (pEntityIt->HasNext()) {
cImageEntity *pEntity = static_cast<cImageEntity *>(pEntityIt->Next());
if (pEntity->IsActive()) {
pEntity->Render();
}
}
hplDelete(pEntityIt);
}
//-----------------------------------------------------------------------
int cWorld2D::LoadTileData(cTile *apTile, tString *asData, int alStart) {
int lCount = alStart;
int lStart = lCount;
int lValType = 0;
int lSet = 0;
int lNum;
while (true) {
if (asData->c_str()[lCount] == ':' || asData->c_str()[lCount] == '|') {
if (lStart != lCount) {
tString sVal = asData->substr(lStart, lCount - lStart);
int lVal = cString::ToInt(sVal.c_str(), -1);
cTileSet *pSet = NULL;
cTileDataNormal *pData = NULL;
switch (lValType) {
case 0:
lSet = lVal;
break;
case 1:
lNum = lVal;
if (lSet < 0)
break;
if (lNum < 0)
break;
pSet = mpTileMap->GetTileSet(lSet);
if (pSet == NULL)
error("Error getting tileset%d", lSet);
pData = static_cast<cTileDataNormal *>(pSet->Get(lNum));
apTile->SetTileData(pData);
break;
case 2:
apTile->SetAngle((eTileRotation)lVal);
break;
case 3:
apTile->SetFlags(eTileFlag_Breakable);
}
lValType++;
}
if (asData->c_str()[lCount] == '|') {
/*if(apTile->GetTileData())
Log("%d,%d,%d|",lSet,lNum,apTile->GetAngle());
else
Log("N|");*/
break;
}
lStart = lCount + 1;
}
lCount++;
}
return lCount + 1;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,179 @@
/* 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.
*/
#ifndef HPL_WORLD2D_H
#define HPL_WORLD2D_H
#include "hpl1/engine/game/GameTypes.h"
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/system/SystemTypes.h"
#include "hpl1/engine/scene/SoundSource.h"
#include "common/stablemap.h"
class TiXmlElement;
namespace hpl {
class cGraphics;
class cResources;
class cSound;
class iCamera;
class cCamera2D;
class cTileMap;
class cTile;
class cNode2D;
class cBody2D;
class cCollider2D;
class cGridMap2D;
class cLight2DPoint;
class iLight2D;
class cImageEntity;
class cParticleManager;
class cArea2D;
class iScript;
class cMesh2D;
class iParticleSystem2D;
class cWorld2D {
friend class cCollider2D;
public:
cWorld2D(tString asName, cGraphics *apGraphics, cResources *apResources, cSound *apSound, cCollider2D *apCollider);
~cWorld2D();
tString GetName() { return msName; }
bool CreateFromFile(tString asFile);
void Render(cCamera2D *apCamera);
void Update(float afTimeStep);
cVector2f GetWorldSize() { return mvWorldSize; }
iScript *GetScript() { return mpScript; }
void ResetBodyIDCount() { mlBodyIDCount = 0; }
///// LIGHT METHODS ////////////////////
cLight2DPoint *CreateLightPoint(tString asName = "");
void DestroyLight(iLight2D *apLight);
cGridMap2D *GetGridMapLights();
iLight2D *GetLight(const tString &asName);
///// BODY METHODS ////////////////////
cBody2D *CreateBody2D(const tString &asName, cMesh2D *apMesh, cVector2f avSize);
cGridMap2D *GetGridMapBodies() { return mpMapBodies; }
///// AREA METHODS ////////////////////
cGridMap2D *GetGridMapAreas() { return mpMapAreas; }
/**
* Gets an area on the map. This does a linear search and very fast.
* \param asName The name, if "" then the first of the correct type is returned
* \param asType The typem if "" then type doesn't matter.
* \return
*/
cArea2D *GetArea(const tString &asName, const tString &asType);
///// SOUNDSOURCE METHODS ////////////////////
cSoundSource *CreateSoundSource(const tString &asName, const tString &asSoundName, bool abVolatile);
void DestroySoundSource(cSoundSource *apSound);
///// ENTITY METHODS ////////////////////
cImageEntity *CreateImageEntity(tString asName, tString asDataName);
cGridMap2D *GetGridMapImageEntities() { return mpMapImageEntities; }
void DestroyImageEntity(cImageEntity *apEntity);
cImageEntity *GetImageEntity(const tString &asName);
///// PARTICLE METHODS ////////////////////
iParticleSystem2D *CreateParticleSystem(const tString &asName, const cVector3f &avSize);
void DestroyParticleSystem(iParticleSystem2D *apPS);
///// TILE METHODS ////////////////////
cTileMap *GetTileMap() { return mpTileMap; }
// Test!
void CreateTileMap();
/// NODE METHODS //////////////////////
cNode2D *GetRootNode() { return mpRootNode; }
private:
tString msName;
cGraphics *mpGraphics;
cSound *mpSound;
cResources *mpResources;
cCollider2D *mpCollider;
cVector2f mvWorldSize;
iScript *mpScript;
cGridMap2D *mpMapLights;
cGridMap2D *mpMapImageEntities;
cGridMap2D *mpMapBodies;
cGridMap2D *mpMapParticles;
cGridMap2D *mpMapAreas;
tSoundSourceList mlstSoundSources;
int mlBodyIDCount;
cTileMap *mpTileMap;
cNode2D *mpRootNode;
tString msMapName;
float mfLightZ;
cColor mAmbientColor;
// Update
void UpdateEntities();
void UpdateBodies();
void UpdateParticles();
void UpdateSoundSources();
void UpdateLights();
// Render
void RenderImagesEntities(cCamera2D *apCamera);
void RenderParticles(cCamera2D *apCamera);
// Load helper
int LoadTileData(cTile *apTile, tString *asData, int alStart);
};
} // namespace hpl
#endif // HPL_WOLRD2D_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,371 @@
/* 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.
*/
#ifndef HPL_WORLD3D_H
#define HPL_WORLD3D_H
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/system/SystemTypes.h"
#include "hpl1/engine/scene/Entity3D.h"
#include "hpl1/engine/scene/SoundSource.h"
#include "hpl1/engine/game/GameTypes.h"
#include "hpl1/engine/game/SaveGame.h"
class TiXmlElement;
namespace hpl {
class cGraphics;
class cResources;
class cSound;
class cPhysics;
class cScene;
class cSystem;
class cAI;
class iCamera;
class cCamera3D;
class cNode3D;
class cLight3DSpot;
class cLight3DPoint;
class iLight3D;
class cImageEntity;
class cParticleManager;
class cParticleSystem3D;
class iScript;
class cPortalContainer;
class iRenderableContainer;
class cMeshEntity;
class cMesh;
class cBillboard;
class cBeam;
class iPhysicsWorld;
class cColliderEntity;
class iPhysicsBody;
class cSoundEntity;
class cAINodeContainer;
class cAStarHandler;
class cAINodeGeneratorParams;
typedef Common::List<iLight3D *> tLight3DList;
typedef Common::List<iLight3D *>::iterator tLight3DListIt;
typedef Common::List<cMeshEntity *> tMeshEntityList;
typedef Common::List<cMeshEntity *>::iterator tMeshEntityListIt;
typedef Common::List<cBillboard *> tBillboardList;
typedef Common::List<cBillboard *>::iterator tBillboardListIt;
typedef Common::List<cBeam *> tBeamList;
typedef Common::List<cBeam *>::iterator tBeamListIt;
typedef Common::List<cParticleSystem3D *> tParticleSystem3DList;
typedef tParticleSystem3DList::iterator tParticleSystem3DListIt;
typedef Common::List<cColliderEntity *> tColliderEntityList;
typedef Common::List<cColliderEntity *>::iterator tColliderEntityListIt;
typedef Common::List<cSoundEntity *> tSoundEntityList;
typedef Common::List<cSoundEntity *>::iterator tSoundEntityListIt;
typedef Common::List<cAINodeContainer *> tAINodeContainerList;
typedef Common::List<cAINodeContainer *>::iterator tAINodeContainerListIt;
typedef Common::List<cAStarHandler *> tAStarHandlerList;
typedef Common::List<cAStarHandler *>::iterator tAStarHandlerIt;
//-------------------------------------------------------------------
typedef cSTLIterator<cMeshEntity *, tMeshEntityList, tMeshEntityListIt> cMeshEntityIterator;
typedef cSTLIterator<cBillboard *, tBillboardList, tBillboardListIt> cBillboardIterator;
typedef cSTLIterator<iLight3D *, tLight3DList, tLight3DListIt> cLight3DListIterator;
typedef cSTLIterator<cParticleSystem3D *, tParticleSystem3DList, tParticleSystem3DListIt> cParticleSystem3DIterator;
typedef cSTLIterator<cSoundEntity *, tSoundEntityList, tSoundEntityListIt> cSoundEntityIterator;
typedef cSTLIterator<cBeam *, tBeamList, tBeamListIt> cBeamIterator;
//-------------------------------------------------------------------
class cTempAiNode {
public:
cTempAiNode(const cVector3f &avPos, const tString &asName) : mvPos(avPos), msName(asName) {}
cVector3f mvPos;
tString msName;
};
typedef Common::List<cTempAiNode> tTempAiNodeList;
typedef Common::List<cTempAiNode>::iterator tTempAiNodeListIt;
class cTempNodeContainer {
public:
tString msName;
tTempAiNodeList mlstNodes;
};
typedef Common::StableMap<tString, cTempNodeContainer *> tTempNodeContainerMap;
typedef Common::StableMap<tString, cTempNodeContainer *>::iterator tTempNodeContainerMapIt;
//-------------------------------------------------------------------
class cAreaEntity : public iSerializable {
kSerializableClassInit(cAreaEntity) public : tString msName;
tString msType;
cMatrixf m_mtxTransform;
cVector3f mvSize;
};
typedef Common::StableMap<tString, cAreaEntity *> tAreaEntityMap;
typedef tAreaEntityMap::iterator tAreaEntityMapIt;
//-------------------------------------------------------------------
class cStartPosEntity : public iSerializable {
kSerializableClassInit(cStartPosEntity) public : cStartPosEntity() {}
cStartPosEntity(const tString &asName) : msName(asName) {}
cMatrixf &GetWorldMatrix() { return m_mtxTransform; }
cMatrixf &GetLocalMatrix() { return m_mtxTransform; }
void SetMatrix(const cMatrixf &a_mtxTrans) { m_mtxTransform = a_mtxTrans; }
tString &GetName() { return msName; }
cMatrixf m_mtxTransform;
tString msName;
};
typedef Common::List<cStartPosEntity *> tStartPosEntityList;
typedef Common::List<cStartPosEntity *>::iterator tStartPosEntityListIt;
//------------------------------------------
kSaveData_BaseClass(cWorld3D) {
kSaveData_ClassInit(cWorld3D) public : cContainerList<cStartPosEntity> mlstStartpos;
cContainerList<cAreaEntity> mlstAreaEntities;
cContainerList<cScriptVar> mlstScriptVars;
virtual iSaveObject *CreateSaveObject(cSaveObjectHandler * apSaveObjectHandler, cGame * apGame);
virtual int GetSaveCreatePrio();
};
//-------------------------------------------------------------------
class cWorld3D {
public:
cWorld3D(tString asName, cGraphics *apGraphics, cResources *apResources, cSound *apSound,
cPhysics *apPhysics, cScene *apScene, cSystem *apSystem, cAI *apAI);
~cWorld3D();
tString GetName() { return msName; }
bool CreateFromFile(tString asFile);
void SetFileName(const tString &asFile) { msFileName = asFile; }
const tString &GetFileName() { return msFileName; }
void Update(float afTimeStep);
void PreUpdate(float afTotalTime, float afTimeStep);
cVector3f GetWorldSize() { return mvWorldSize; }
iScript *GetScript() { return mpScript; }
void SetScript(iScript *apScript) { mpScript = apScript; }
iRenderableContainer *GetRenderContainer();
cPortalContainer *GetPortalContainer();
cPhysics *GetPhysics() { return mpPhysics; }
cResources *GetResources() { return mpResources; }
cSound *GetSound() { return mpSound; }
cSystem *GetSystem() { return mpSystem; }
iEntity3D *CreateEntity(const tString &asName, const cMatrixf &a_mtxTransform,
const tString &asFile, bool abLoadReferences);
/**
* Call this when all things have been added to set up things like physics world size.
**/
void SetUpData();
void AddSaveData(cSaveDataHandler *apHandler);
///// PHYSICS ////////////////////////////////
void SetPhysicsWorld(iPhysicsWorld *apWorld, bool abAutoDelete = true);
iPhysicsWorld *GetPhysicsWorld();
///// AREA ////////////////////////////////
cAreaEntity *CreateAreaEntity(const tString &asName);
cAreaEntity *GetAreaEntity(const tString &asName);
tAreaEntityMap *GetAreaEntityMap() { return &m_mapAreaEntities; }
///// MESH ENTITY METHODS ////////////////////
cMeshEntity *CreateMeshEntity(const tString &asName, cMesh *apMesh, bool abAddToContainer = true);
void DestroyMeshEntity(cMeshEntity *apMesh);
cMeshEntity *GetMeshEntity(const tString &asName);
cMeshEntityIterator GetMeshEntityIterator();
void DrawMeshBoundingBoxes(const cColor &aColor, bool abStatic);
///// LIGHT METHODS ////////////////////
cLight3DPoint *CreateLightPoint(const tString &asName = "", bool abAddToContainer = true);
cLight3DSpot *CreateLightSpot(const tString &asName = "", const tString &asGobo = "",
bool abAddToContainer = true);
void DestroyLight(iLight3D *apLight);
iLight3D *GetLight(const tString &asName);
tLight3DList *GetLightList() { return &mlstLights; }
cLight3DListIterator GetLightIterator() { return cLight3DListIterator(&mlstLights); }
///// BILLBOARD METHODS ////////////////////
cBillboard *CreateBillboard(const tString &asName, const cVector2f &avSize,
const tString &asMaterial = "",
bool abAddToContainer = true, cMatrixf *apTransform = NULL);
void DestroyBillboard(cBillboard *apObject);
cBillboard *GetBillboard(const tString &asName);
cBillboardIterator GetBillboardIterator();
///// BEAM METHODS ////////////////////
cBeam *CreateBeam(const tString &asName);
void DestroyBeam(cBeam *apObject);
cBeam *GetBeam(const tString &asName);
cBeamIterator GetBeamIterator();
///// PARTICLE METHODS ////////////////////
cParticleSystem3D *CreateParticleSystem(const tString &asName, const tString &asType,
const cVector3f &avSize, const cMatrixf &a_mtxTransform);
void DestroyParticleSystem(cParticleSystem3D *apPS);
cParticleSystem3D *GetParticleSystem(const tString &asName);
bool ParticleSystemExists(cParticleSystem3D *apPS);
cParticleSystem3DIterator GetParticleSystemIterator() { return cParticleSystem3DIterator(&mlstParticleSystems); }
///// COllIDER METHODS ////////////////////
cColliderEntity *CreateColliderEntity(const tString &asName, iPhysicsBody *apBody);
void DestroyColliderEntity(cColliderEntity *apCollider);
cColliderEntity *GetColliderEntity(const tString &asName);
///// SOUND ENTITY METHODS ////////////////////
cSoundEntity *CreateSoundEntity(const tString &asName, const tString &asSoundEntity,
bool abRemoveWhenOver);
void DestroySoundEntity(cSoundEntity *apEntity);
cSoundEntity *GetSoundEntity(const tString &asName);
void DestroyAllSoundEntities();
bool SoundEntityExists(cSoundEntity *apEntity);
cSoundEntityIterator GetSoundEntityIterator() { return cSoundEntityIterator(&mlstSoundEntities); }
///// START POS ENTITY METHODS ////////////////
cStartPosEntity *CreateStartPos(const tString &asName);
cStartPosEntity *GetStartPosEntity(const tString &asName);
cStartPosEntity *GetFirstStartPosEntity();
///// AI NODE METHODS ////////////////
void GenerateAINodes(cAINodeGeneratorParams *apParams);
cAINodeContainer *CreateAINodeContainer(const tString &asName,
const tString &asNodeName,
const cVector3f &avSize,
bool abNodeIsAtCenter,
int alMinEdges, int alMaxEdges, float afMaxEdgeDistance,
float afMaxHeight);
cAStarHandler *CreateAStarHandler(cAINodeContainer *apContainer);
void AddAINode(const tString &asName, const tString &asType, const cVector3f &avPosition);
tTempAiNodeList *GetAINodeList(const tString &asType);
/// NODE METHODS //////////////////////
// Remove this for the time being, not need it seems.
// cNode3D* GetRootNode(){ return mpRootNode; }
private:
iSaveData *CreateSaveData();
// Update
void UpdateEntities(float afTimeStep);
void UpdateBodies(float afTimeStep);
void UpdateParticles(float afTimeStep);
void UpdateLights(float afTimeStep);
void UpdateSoundEntities(float afTimeStep);
tString msName;
tString msFileName;
cGraphics *mpGraphics;
cSound *mpSound;
cResources *mpResources;
cPhysics *mpPhysics;
cScene *mpScene;
cSystem *mpSystem;
cAI *mpAI;
iPhysicsWorld *mpPhysicsWorld;
bool mbAutoDeletePhysicsWorld;
cVector3f mvWorldSize;
cPortalContainer *mpPortalContainer;
iScript *mpScript;
tLight3DList mlstLights;
tMeshEntityList mlstMeshEntities;
tBillboardList mlstBillboards;
tBeamList mlstBeams;
tParticleSystem3DList mlstParticleSystems;
tColliderEntityList mlstColliders;
tSoundEntityList mlstSoundEntities;
tStartPosEntityList mlstStartPosEntities;
tAreaEntityMap m_mapAreaEntities;
tAINodeContainerList mlstAINodeContainers;
tAStarHandlerList mlstAStarHandlers;
tTempNodeContainerMap m_mapTempNodes;
cNode3D *mpRootNode;
tString msMapName;
cColor mAmbientColor;
};
} // namespace hpl
#endif // HPL_WOLRD3D_H