Exemple #1
0
bool Actor::shouldDrawShadow(int shadowId) {
	Shadow *shadow = &_shadowArray[shadowId];
	if (!shadow->active)
		return false;

	// Don't draw a shadow if the shadow caster and the actor are on different sides
	// of the the shadow plane.
	Sector *sector = shadow->planeList.front().sector;
	Math::Vector3d n = sector->getNormal();
	Math::Vector3d p = sector->getVertices()[0];
	float d = -(n.x() * p.x() + n.y() * p.y() + n.z() * p.z());

	p = getPos();
	// Move the tested point a bit above ground level.
	if (g_grim->getGameType() == GType_MONKEY4)
		p.y() += 0.01;
	else
		p.z() += 0.01;
	bool actorSide = n.x() * p.x() + n.y() * p.y() + n.z() * p.z() + d < 0.f;
	p = shadow->pos;
	bool shadowSide = n.x() * p.x() + n.y() * p.y() + n.z() * p.z() + d < 0.f;

	if (actorSide == shadowSide)
		return true;
	return false;
}
Exemple #2
0
void GfxTinyGL::startActorDraw(Graphics::Vector3d pos, float scale, float yaw, float pitch, float roll) {
	tglEnable(TGL_TEXTURE_2D);
	tglMatrixMode(TGL_MODELVIEW);
	tglPushMatrix();
	if (_currentShadowArray) {
		// TODO find out why shadowMask at device in woods is null
		if (!_currentShadowArray->shadowMask) {
			_currentShadowArray->shadowMask = new byte[_screenWidth * _screenHeight];
			_currentShadowArray->shadowMaskSize = _screenWidth * _screenHeight;
		}
		assert(_currentShadowArray->shadowMask);
		//tglSetShadowColor(255, 255, 255);
		tglSetShadowColor(_shadowColorR, _shadowColorG, _shadowColorB);
		tglSetShadowMaskBuf(_currentShadowArray->shadowMask);
		SectorListType::iterator i = _currentShadowArray->planeList.begin();
		Sector *shadowSector = i->sector;
		tglShadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate);
	}

	tglTranslatef(pos.x(), pos.y(), pos.z());
	tglScalef(scale, scale, scale);
	tglRotatef(yaw, 0, 0, 1);
	tglRotatef(pitch, 1, 0, 0);
	tglRotatef(roll, 0, 1, 0);
}
Exemple #3
0
void Actor::walkForward() {
	float dist = g_grim->getPerSecond(_walkRate);
	// Limit the amount of the movement per frame, otherwise with low fps
	// scripts that use WalkActorForward and proximity may break.
	if ((dist > 0 && dist > _walkRate / 5.f) || (dist < 0 && dist < _walkRate / 5.f))
		dist = _walkRate / 5.f;

	_walking = false;

	if (! _constrain) {
		Math::Vector3d forwardVec(-_moveYaw.getSine() * _pitch.getCosine(),
			_moveYaw.getCosine() * _pitch.getCosine(), _pitch.getSine());

		// EMI: Y is up-down, sectors use an X-Z plane for movement
		if (g_grim->getGameType() == GType_MONKEY4) {
			float temp = forwardVec.z();
			forwardVec.z() = forwardVec.y();
			forwardVec.y() = temp;
		}

		_pos += forwardVec * dist;
		_walkedCur = true;
		return;
	}

	bool backwards = false;
	if (dist < 0) {
		dist = -dist;
		backwards = true;
	}

	int tries = 0;
	while (dist > 0.0f) {
		Math::Vector3d forwardVec(-_moveYaw.getSine() * _pitch.getCosine(),
			_moveYaw.getCosine() * _pitch.getCosine(), _pitch.getSine());

		// EMI: Y is up-down, sectors use an X-Z plane for movement
		if (g_grim->getGameType() == GType_MONKEY4) {
			float temp = forwardVec.z();
			forwardVec.z() = forwardVec.y();
			forwardVec.y() = temp;
		}

		if (backwards)
			forwardVec = -forwardVec;

		Sector *currSector = NULL, *prevSector = NULL, *startSector = NULL;
		Sector::ExitInfo ei;

		g_grim->getCurrSet()->findClosestSector(_pos, &currSector, &_pos);
		if (!currSector) { // Shouldn't happen...
			moveTo(_pos + forwardVec * dist);
			_walkedCur = true;
			return;
		}
		startSector = currSector;

		float oldDist = dist;
		while (currSector) {
			prevSector = currSector;
			Math::Vector3d puckVec = currSector->getProjectionToPuckVector(forwardVec);
			puckVec /= puckVec.getMagnitude();
			currSector->getExitInfo(_pos, puckVec, &ei);
			float exitDist = (ei.exitPoint - _pos).getMagnitude();
			if (dist < exitDist) {
				moveTo(_pos + puckVec * dist);
				_walkedCur = true;
				return;
			}
			_pos = ei.exitPoint;
			dist -= exitDist;
			if (exitDist > 0.0001)
				_walkedCur = true;

			// Check for an adjacent sector which can continue
			// the path
			currSector = g_grim->getCurrSet()->findPointSector(ei.exitPoint + (float)0.0001 * puckVec, Sector::WalkType);

			// EMI: some sectors are significantly higher/lower than others.
			if (currSector && g_grim->getGameType() == GType_MONKEY4) {
				float planeDist = currSector->distanceToPoint(_pos);
				if (fabs(planeDist) < 1.f)
					_pos -= planeDist * currSector->getNormal();
			}

			if (currSector == prevSector || currSector == startSector)
				break;
		}

		int turnDir = 1;
		if (ei.angleWithEdge > 90) {
			ei.angleWithEdge = 180 - ei.angleWithEdge;
			ei.edgeDir = -ei.edgeDir;
			turnDir = -1;
		}
		if (ei.angleWithEdge > _reflectionAngle)
			return;

		ei.angleWithEdge += (float)1.0f;
		turnTo(0, _moveYaw + ei.angleWithEdge * turnDir, 0);

		if (oldDist <= dist + 0.001f) {
			// If we didn't move at all, keep trying a couple more times
			// in case we can move in the new direction.
			tries++;
			if (tries > 3)
				break;
		}
	}
}