Files
scummvm/engines/hpl1/engine/haptic/LowLevelHaptic.cpp
T

264 lines
7.8 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/haptic/LowLevelHaptic.h"
#include "hpl1/engine/haptic/HapticForce.h"
#include "hpl1/engine/haptic/HapticShape.h"
#include "hpl1/engine/haptic/HapticSurface.h"
#include "hpl1/engine/system/low_level_system.h"
#include "hpl1/engine/system/SystemTypes.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/physics/PhysicsBody.h"
#include "hpl1/engine/scene/Camera3D.h"
#include "hpl1/engine/scene/SubMeshEntity.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iLowLevelHaptic::iLowLevelHaptic() {
mpCamera = NULL;
mvCameraOffset = 0;
mvMinMousePos = cVector2f(-50, -50);
mvMaxMousePos = cVector2f(50, 50);
mvScreenSize = cVector2f(800, 600);
mbUpdateShapes = true;
}
//-----------------------------------------------------------------------
iLowLevelHaptic::~iLowLevelHaptic() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iHapticSurface *iLowLevelHaptic::GetSurfaceFromName(const tString &asName) {
tHapticSurfaceMapIt it = m_mapSurfaces.find(asName);
if (it == m_mapSurfaces.end()) {
return NULL;
}
iHapticSurface *pSurface = it->second;
return pSurface;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool iLowLevelHaptic::Init(cResources *apResources) {
mpResources = apResources;
if (InitLowLevel() == false)
return false;
/////////////////////////////////////
// Init variables
mvCurrentHardwarePos = GetHardwarePosition();
mvPreviousHardwarePos = mvCurrentHardwarePos;
mbScreenPosFirstTime = true;
return true;
}
//-----------------------------------------------------------------------
void iLowLevelHaptic::Update(float afTimeStep) {
UpdateLowLevel(afTimeStep);
/////////////////////////////////////
// Hardware position calculations
static bool bHardwareSet = false;
mvPreviousHardwarePos = mvCurrentHardwarePos;
mvCurrentHardwarePos = GetHardwarePosition();
if (bHardwareSet == false) {
mvPreviousHardwarePos = mvCurrentHardwarePos;
bHardwareSet = true;
}
/////////////////////////////////////
// Proxy screen postion calculations
if (mpCamera) {
mvPreviousScreenPos = mvCurrentScreenPos;
cVector3f vProjPos = cMath::MatrixMul(mpCamera->GetViewMatrix(), GetProxyPosition());
vProjPos = cMath::MatrixMulDivideW(mpCamera->GetProjectionMatrix(), vProjPos);
cVector2f vPos2D((vProjPos.x + 1) * 0.5f, (-vProjPos.y + 1) * 0.5f);
mvCurrentScreenPos = vPos2D;
if (mbScreenPosFirstTime) {
mvPreviousScreenPos = mvCurrentScreenPos;
mbScreenPosFirstTime = false;
}
}
/////////////////////////////////////
// Update shape transforms
if (mbUpdateShapes) {
tHapticShapeListIt it = mlstShapes.begin();
for (; it != mlstShapes.end(); ++it) {
iHapticShape *pShape = *it;
// If a body is attached, use it to update shape
if (pShape->GetBody()) {
iPhysicsBody *pBody = pShape->GetBody();
if (pBody->GetTransformUpdateCount() != pShape->GetTransformCount()) {
pShape->SetTransformCount(pBody->GetTransformUpdateCount());
pShape->SetTransform(pBody->GetLocalMatrix());
}
} else if (pShape->GetSubMeshEntity()) {
cSubMeshEntity *pSubEntity = pShape->GetSubMeshEntity();
if (pSubEntity->GetTransformUpdateCount() != pShape->GetTransformCount()) {
pShape->SetTransformCount(pSubEntity->GetTransformUpdateCount());
pShape->SetTransform(pSubEntity->GetWorldMatrix());
}
}
}
}
}
//-----------------------------------------------------------------------
cVector3f iLowLevelHaptic::GetHardwarePosDelta() {
return mvCurrentHardwarePos - mvPreviousHardwarePos;
}
//-----------------------------------------------------------------------
cVector2f iLowLevelHaptic::GetProxyScreenPos(const cVector2f &avScreenSize) {
return mvCurrentScreenPos * avScreenSize;
}
cVector2f iLowLevelHaptic::GetProxyScreenDeltaPos(const cVector2f &avScreenSize) {
return (mvCurrentScreenPos - mvPreviousScreenPos) * avScreenSize;
}
//-----------------------------------------------------------------------
cVector2f iLowLevelHaptic::GetRelativeVirtualMousePos() {
cVector3f vRel = GetHardwarePosDelta();
cVector2f vPos = cVector2f(vRel.x, vRel.y) / (mvMaxMousePos - mvMinMousePos);
vPos.y = -vPos.y;
vPos = vPos * mvScreenSize;
return vPos;
}
//-----------------------------------------------------------------------
cVector2f iLowLevelHaptic::GetVirtualMousePos() {
// Log("Pos: %f %f\n", mvCurrentHardwarePos.x,mvCurrentHardwarePos.y);
cVector2f vPos = (cVector2f(mvCurrentHardwarePos.x, mvCurrentHardwarePos.y) - mvMinMousePos) /
(mvMaxMousePos - mvMinMousePos);
vPos.y = 1 - vPos.y;
vPos = vPos * mvScreenSize;
return vPos;
}
void iLowLevelHaptic::SetVirtualMousePosBounds(const cVector2f &avMin, const cVector2f &avMax,
const cVector2f &avScreenSize) {
mvMinMousePos = avMin;
mvMaxMousePos = avMax;
mvScreenSize = avScreenSize;
}
//-----------------------------------------------------------------------
void iLowLevelHaptic::DestroyShape(iHapticShape *apShape) {
STLFindAndDelete(mlstShapes, apShape);
}
bool iLowLevelHaptic::ShapeExists(iHapticShape *apShape) {
tHapticShapeListIt it = mlstShapes.begin();
for (; it != mlstShapes.end(); ++it) {
if (apShape == *it)
return true;
}
return false;
}
//-----------------------------------------------------------------------
cHapticShapeIterator iLowLevelHaptic::GetShapeIterator() {
return cHapticShapeIterator(&mlstShapes);
}
//-----------------------------------------------------------------------
void iLowLevelHaptic::DestroyForce(iHapticForce *apForce) {
STLFindAndDelete(mlstForces, apForce);
}
//-----------------------------------------------------------------------
void iLowLevelHaptic::StopAllForces() {
tHapticForceListIt it = mlstForces.begin();
for (; it != mlstForces.end(); ++it) {
iHapticForce *pForce = *it;
pForce->SetActive(false);
}
}
//-----------------------------------------------------------------------
void iLowLevelHaptic::DestroyAllShapes() {
STLDeleteAll(mlstShapes);
// Log("Destroying all shapes!\n");
}
void iLowLevelHaptic::DestroyAll() {
STLMapDeleteAll(m_mapSurfaces);
STLDeleteAll(mlstForces);
STLDeleteAll(mlstShapes);
}
//-----------------------------------------------------------------------
} // namespace hpl