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; }
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); }
void GfxTinyGL::drawShadowPlanes() { tglEnable(TGL_SHADOW_MASK_MODE); if (!_currentShadowArray->shadowMask) { _currentShadowArray->shadowMask = new byte[_screenWidth * _screenHeight]; _currentShadowArray->shadowMaskSize = _screenWidth * _screenHeight; } memset(_currentShadowArray->shadowMask, 0, _screenWidth * _screenHeight); tglSetShadowMaskBuf(_currentShadowArray->shadowMask); _currentShadowArray->planeList.begin(); for (SectorListType::iterator i = _currentShadowArray->planeList.begin(); i != _currentShadowArray->planeList.end(); ++i) { Sector *shadowSector = i->sector; tglBegin(TGL_POLYGON); for (int k = 0; k < shadowSector->getNumVertices(); k++) { tglVertex3f(shadowSector->getVertices()[k].x(), shadowSector->getVertices()[k].y(), shadowSector->getVertices()[k].z()); } tglEnd(); } tglSetShadowMaskBuf(NULL); tglDisable(TGL_SHADOW_MASK_MODE); }
void L1_GetSectorOppositeEdge() { lua_Object actorObj = lua_getparam(1); lua_Object nameObj = lua_getparam(2); if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; if (!lua_isstring(nameObj)) { lua_pushnil(); return; } Actor *actor = getactor(actorObj); const char *name = lua_getstring(nameObj); int numSectors = g_grim->getCurrScene()->getSectorCount(); for (int i = 0; i < numSectors; i++) { Sector *sector = g_grim->getCurrScene()->getSectorBase(i); if (strmatch(sector->getName(), name)) { if (sector->getNumVertices() != 4) warning("GetSectorOppositeEdge(): cheat box with %d (!= 4) edges!", sector->getNumVertices()); Graphics::Vector3d* vertices = sector->getVertices(); Sector::ExitInfo e; sector->getExitInfo(actor->getPos(), -actor->getPuckVector(), &e); float frac = (e.exitPoint - vertices[e.edgeVertex + 1]).magnitude() / e.edgeDir.magnitude(); e.edgeVertex -= 2; if (e.edgeVertex < 0) e.edgeVertex += sector->getNumVertices(); Graphics::Vector3d edge = vertices[e.edgeVertex + 1] - vertices[e.edgeVertex]; Graphics::Vector3d p = vertices[e.edgeVertex] + edge * frac; lua_pushnumber(p.x()); lua_pushnumber(p.y()); lua_pushnumber(p.z()); return; } } lua_pushnil(); }