void G3CalcNormal (g3sPoint **pointList, CFloatVector *pvNormal) { CFixVector vNormal; if (gameStates.render.nState == 1) // an object polymodel vNormal = CFixVector::Normal (pointList [0]->p3_vec, pointList [1]->p3_vec, pointList [2]->p3_vec); else { short v [4], vSorted [4]; v [0] = pointList [0]->p3_index; v [1] = pointList [1]->p3_index; v [2] = pointList [2]->p3_index; if ((v [0] < 0) || (v [1] < 0) || (v [2] < 0)) { vNormal = CFixVector::Normal (pointList [0]->p3_vec, pointList [1]->p3_vec, pointList [2]->p3_vec); } else { int bFlip = GetVertsForNormal (v [0], v [1], v [2], 32767, vSorted); vNormal = CFixVector::Normal (gameData.segs.vertices [vSorted [0]], gameData.segs.vertices [vSorted [1]], gameData.segs.vertices [vSorted [2]]); if (bFlip) vNormal.Neg (); } } pvNormal->Assign (vNormal); }
//draw a polygon model int DrawPolyModel ( CObject* objP, CFixVector* pos, CFixMatrix* orient, CAngleVector* animAngles, int nModel, int flags, fix light, fix* glowValues, tBitmapIndex altTextures [], tRgbaColorf* colorP) { CPolyModel* modelP; int nTextures, bHires = 0; if ((gameStates.render.nShadowPass == 2) && !ObjectHasShadow (objP)) return 1; if (!(modelP = GetPolyModel (objP, pos, nModel, flags))) { if (!flags && (gameStates.render.nShadowPass != 2) && HaveHiresModel (nModel)) bHires = 1; else return gameStates.render.nShadowPass == 2; } if (gameStates.render.nShadowPass == 2) { if (!bHires) { G3SetModelPoints (gameData.models.polyModelPoints.Buffer ()); G3DrawPolyModelShadow (objP, modelP->Data (), animAngles, nModel); } return 1; } #if 1//def _DEBUG if (nModel == nDbgModel) nDbgModel = nDbgModel; #endif nTextures = bHires ? 0 : modelP->LoadTextures (altTextures); gameStates.ogl.bUseTransform = 1; G3SetModelPoints (gameData.models.polyModelPoints.Buffer ()); gameData.render.vertP = gameData.models.fPolyModelVerts.Buffer (); if (!flags) { //draw entire CObject if (gameStates.app.bNostalgia || !G3RenderModel (objP, nModel, -1, modelP, gameData.models.textures, animAngles, NULL, light, glowValues, colorP)) { if (bHires) { gameStates.ogl.bUseTransform = 0; return 0; } if (objP && (objP->info.nType == OBJ_POWERUP)) { if ((objP->info.nId == POW_SMARTMINE) || (objP->info.nId == POW_PROXMINE)) gameData.models.vScale.Set (I2X (2), I2X (2), I2X (2)); else gameData.models.vScale.Set (I2X (3) / 2, I2X (3) / 2, I2X (3) / 2); } gameStates.ogl.bUseTransform = (gameStates.app.bEndLevelSequence < EL_OUTSIDE) && !(SHOW_DYN_LIGHT && (gameOpts->ogl.bObjLighting || gameOpts->ogl.bLightObjects)); transformation.Begin (*pos, *orient); G3DrawPolyModel (objP, modelP->Data (), gameData.models.textures, animAngles, NULL, light, glowValues, colorP, NULL, nModel); transformation.End (); } } else { CFixVector vOffset; for (int i = 0; flags > 0; flags >>= 1, i++) { if ((flags & 1) && (i < modelP->ModelCount ())) { //if submodel, rotate around its center point, not pivot point vOffset = CFixVector::Avg (modelP->SubModels ().mins [i], modelP->SubModels ().maxs [i]); vOffset.Neg (); if (!G3RenderModel (objP, nModel, i, modelP, gameData.models.textures, animAngles, &vOffset, light, glowValues, colorP)) { if (bHires) { gameStates.ogl.bUseTransform = 0; return 0; } #if DBG G3RenderModel (objP, nModel, i, modelP, gameData.models.textures, animAngles, &vOffset, light, glowValues, colorP); #endif transformation.Begin (vOffset); G3DrawPolyModel (objP, modelP->Data () + modelP->SubModels ().ptrs [i], gameData.models.textures, animAngles, NULL, light, glowValues, colorP, NULL, nModel); transformation.End (); } } } } gameStates.ogl.bUseTransform = 0; gameData.render.vertP = NULL; #if 0 { g3sPoint p0, p1; transformation.Transform (&p0.p3_vec, &objP->info.position.vPos); VmVecSub (&p1.p3_vec, &objP->info.position.vPos, &objP->mType.physInfo.velocity); transformation.Transform (&p1.p3_vec, &p1.p3_vec); glLineWidth (20); glDisable (GL_TEXTURE_2D); glBegin (GL_LINES); glColor4d (1.0, 0.5, 0.0, 0.3); OglVertex3x (p0.p3_vec [X], p0.p3_vec [Y], p0.p3_vec [Z]); glColor4d (1.0, 0.5, 0.0, 0.1); OglVertex3x (p1.p3_vec [X], p1.p3_vec [Y], p1.p3_vec [Z]); glEnd (); glLineWidth (1); } #endif return 1; }
int CCamera::Create (short nId, short srcSeg, short srcSide, short tgtSeg, short tgtSide, CObject *objP, int bShadowMap, int bTeleport) { CAngleVector a; #if 0 short* corners; CFixVector *pv; #endif Init (); m_info.nId = nId; m_info.bShadowMap = bShadowMap; m_info.buffer.SetWidth (Pow2ize (screen.Width () / (2 - gameOpts->render.cameras.bHires))); m_info.buffer.SetHeight (Pow2ize (screen.Height () / (2 - gameOpts->render.cameras.bHires))); m_info.buffer.SetBPP (4); //m_info.buffer.SetRowSize (max (CCanvas::Current ()->Width (), m_info.buffer.Width ())); #if RENDER2TEXTURE if (!CreateBuffer ()) #endif { #if CAMERA_READPIXELS if (!(m_info.buffer.Create (m_info.buffer.Width () * m_info.buffer.Height () * 4))) return 0; if (gameOpts->render.cameras.bFitToWall || m_info.bTeleport) m_info.screenBuf = m_info.buffer.Buffer (); else { m_info.screenBuf = new ubyte [CCanvas::Current ()->Width () * CCanvas::Current ()->Height () * 4]; if (!m_info.screenBuf) { gameOpts->render.cameras.bFitToWall = 1; m_info.screenBuf = m_info.buffer.Buffer (); } } memset (m_info.buffer.Buffer (), 0, m_info.buffer.Width () * m_info.buffer.Height () * 4); #else return 0; #endif } if (objP) { m_info.objP = objP; m_info.orient = objP->info.position.mOrient; m_info.curAngle = m_info.curDelta = 0; m_info.t0 = 0; cameraManager.SetObjectCamera (objP->Index (), nId); } else { m_info.objP = &m_info.obj; if (bTeleport) { CFixVector n = *SEGMENTS [srcSeg].m_sides [srcSide].m_normals; /* n[X] = -n[X]; n[Y] = -n[Y]; */ n.Neg (); a = n.ToAnglesVec (); } else a = SEGMENTS [srcSeg].m_sides [srcSide].m_normals [0].ToAnglesVec (); m_info.obj.info.position.mOrient = CFixMatrix::Create(a); #if 1 if (bTeleport) m_info.obj.info.position.vPos = SEGMENTS [srcSeg].Center (); else m_info.obj.info.position.vPos = SEGMENTS [srcSeg].SideCenter (srcSide); #else corners = SEGMENTS [srcSeg].Corners (srcSide); for (i = 0; i < 4; i++) { pv = gameData.segs.vertices + corners [i]; m_info.obj.info.position.p.vPos.x += pv->x; m_info.obj.info.position.p.vPos.y += pv->y; m_info.obj.info.position.p.vPos.z += pv->z; } m_info.obj.info.position.p.vPos.x /= 4; m_info.obj.info.position.p.vPos.y /= 4; m_info.obj.info.position.p.vPos.z /= 4; #endif m_info.obj.info.nSegment = srcSeg; m_info.bMirror = (tgtSeg == srcSeg) && (tgtSide == srcSide); } //m_info.obj.nSide = srcSide; m_info.nSegment = tgtSeg; m_info.nSide = tgtSide; m_info.bTeleport = (char) bTeleport; return 1; }