void TriggerSetOrient (tObjTransformation *posP, short nSegment, short nSide, int bSetPos, int nStep) { CAngleVector an; CFixVector n; if (nStep <= 0) { n = *SEGMENTS [nSegment].m_sides [nSide].m_normals; n = -n; /* n [Y] = -n [Y]; n [Z] = -n [Z]; */ gameStates.gameplay.vTgtDir = n; if (nStep < 0) nStep = MAX_ORIENT_STEPS; } else n = gameStates.gameplay.vTgtDir; // turn the ship so that it is facing the destination nSide of the destination CSegment // Invert the Normal as it points into the CSegment // compute angles from the Normal an = n.ToAnglesVec (); // create new orientation matrix if (!nStep) posP->mOrient = CFixMatrix::Create (an); if (bSetPos) posP->vPos = SEGMENTS [nSegment].Center (); // rotate the ships vel vector accordingly //StopPlayerMovement (); }
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); }
CFixVector CFace::CalcCenter (CModel* po) { CFloatVector cf; CFixVector c; cf = CalcCenterf (po); c.Assign (cf); return c; }
// Camera is less than size of CPlayerData away from void SetCameraPos (CFixVector *vCameraPos, CObject *objP) { CFixVector vPlayerCameraOffs = *vCameraPos - objP->info.position.vPos; int count = 0; fix xCameraPlayerDist; fix xFarScale; xCameraPlayerDist = vPlayerCameraOffs.Mag(); if (xCameraPlayerDist < xCameraToPlayerDistGoal) { // 2*objP->info.xSize) { // Camera is too close to CPlayerData CObject, so move it away. tFVIQuery fq; tFVIData hit_data; CFixVector local_p1; if (vPlayerCameraOffs.IsZero()) vPlayerCameraOffs[X] += I2X (1)/16; hit_data.hit.nType = HIT_WALL; xFarScale = I2X (1); while ((hit_data.hit.nType != HIT_NONE) && (count++ < 6)) { CFixVector closer_p1; CFixVector::Normalize(vPlayerCameraOffs); vPlayerCameraOffs *= xCameraToPlayerDistGoal; fq.p0 = &objP->info.position.vPos; closer_p1 = objP->info.position.vPos + vPlayerCameraOffs; // This is the actual point we want to put the camera at. vPlayerCameraOffs *= xFarScale; // ...but find a point 50% further away... local_p1 = objP->info.position.vPos + vPlayerCameraOffs; // ...so we won't have to do as many cuts. fq.p1 = &local_p1; fq.startSeg = objP->info.nSegment; fq.radP0 = fq.radP1 = 0; fq.thisObjNum = objP->Index (); fq.ignoreObjList = NULL; fq.flags = 0; fq.bCheckVisibility = false; FindVectorIntersection (&fq, &hit_data); if (hit_data.hit.nType == HIT_NONE) *vCameraPos = closer_p1; else { vPlayerCameraOffs = CFixVector::Random(); xFarScale = I2X (3) / 2; } } } }
fix CheckVectorToHitbox (CFixVector& intersection, CFixVector *p0, CFixVector *p1, CFixVector *vRef, CObject *objP, fix rad, short& nModel) { int iModel, nModels; fix xDist = 0x7fffffff, dMin = 0x7fffffff; CModelHitboxes *pmhb = gameData.models.hitboxes + objP->rType.polyObjInfo.nModel; tBox hb [MAX_HITBOXES + 1]; CFixVector vHit; if (extraGameInfo [IsMultiGame].nHitboxes == 1) { iModel = nModels = 0; } else { iModel = 1; nModels = pmhb->nHitboxes; } if (!vRef) vRef = &OBJPOS (objP)->vPos; intersection.Create (0x7fffffff, 0x7fffffff, 0x7fffffff); TransformHitboxes (objP, vRef, hb); for (; iModel <= nModels; iModel++) { if (FindLineHitboxIntersection (vHit, hb + iModel, p0, p1, p0, rad)) { xDist = RegisterHit (&intersection, &vHit, vRef, dMin); if (dMin > xDist) { dMin = xDist; nModel = iModel; } } } return xDist; }
void DrawOutline (int nVertices, g3sPoint **pointList) { int i; GLint depthFunc; g3sPoint center, Normal; CFixVector n; CFloatVector *nf; #if 1 //!DBG if (gameStates.render.bQueryOcclusion) { tRgbaColorf outlineColor = {1, 1, 0, -1}; G3DrawPolyAlpha (nVertices, pointList, &outlineColor, 1, -1); return; } #endif glGetIntegerv (GL_DEPTH_FUNC, &depthFunc); glDepthFunc (GL_ALWAYS); CCanvas::Current ()->SetColorRGB (255, 255, 255, 255); center.p3_vec.SetZero (); for (i = 0; i < nVertices; i++) { G3DrawLine (pointList [i], pointList [(i + 1) % nVertices]); center.p3_vec += pointList [i]->p3_vec; nf = &pointList [i]->p3_normal.vNormal; /* n[X] = (fix) (nf->x() * 65536.0f); n[Y] = (fix) (nf->y() * 65536.0f); n[Z] = (fix) (nf->z() * 65536.0f); */ n.Assign (*nf); transformation.Rotate(n, n, 0); Normal.p3_vec = pointList[i]->p3_vec + n * (I2X (10)); G3DrawLine (pointList [i], &Normal); } #if 0 VmVecNormal (&Normal.p3_vec, &pointList [0]->p3_vec, &pointList [1]->p3_vec, &pointList [2]->p3_vec); VmVecInc (&Normal.p3_vec, ¢er.p3_vec); VmVecScale (&Normal.p3_vec, I2X (10)); G3DrawLine (¢er, &Normal); #endif glDepthFunc (depthFunc); }
CFixVector *TransformGunPoint (CObject *objP, CFixVector *vGunPoints, int nGun, fix xDelay, ubyte nLaserType, CFixVector *vMuzzle, CFixMatrix *mP) { int bSpectate = SPECTATOR (objP); tObjTransformation* posP = bSpectate ? &gameStates.app.playerPos : &objP->info.position; CFixMatrix m, *viewP; CFixVector v [2]; #if FULL_COCKPIT_OFFS int bLaserOffs = ((gameStates.render.cockpit.nType == CM_FULL_COCKPIT) && (objP->Index () == LOCALPLAYER.nObject)); #else int bLaserOffs = 0; #endif if (nGun < 0) { // use center between gunPoints nGun and nGun + 1 *v = vGunPoints [-nGun] + vGunPoints [-nGun - 1]; // VmVecScale (VmVecAdd (v, vGunPoints - nGun, vGunPoints - nGun - 1), I2X (1) / 2); *v *= (I2X (1) / 2); } else { v [0] = vGunPoints [nGun]; if (bLaserOffs) v [0] += posP->mOrient.UVec () * LASER_OFFS; } if (!mP) mP = &m; if (bSpectate) { viewP = mP; *viewP = posP->mOrient.Transpose (); } else viewP = objP->View (); v[1] = *viewP * v [0]; memcpy (mP, &posP->mOrient, sizeof (CFixMatrix)); if (nGun < 0) v[1] += (*mP).UVec () * (-2 * v->Mag ()); (*vMuzzle) = posP->vPos + v [1]; // If supposed to fire at a delayed time (xDelay), then move this point backwards. if (xDelay) *vMuzzle += mP->FVec () * (-FixMul (xDelay, WI_speed (nLaserType, gameStates.app.nDifficultyLevel))); return vMuzzle; }
int CParticle::Create (CFixVector *vPos, CFixVector *vDir, CFixMatrix *mOrient, short nSegment, int nLife, int nSpeed, char nParticleSystemType, char nClass, float nScale, tRgbaColorf *colorP, int nCurTime, int bBlowUp, float fBrightness, CFixVector *vEmittingFace) { static tRgbaColorf defaultColor = {1,1,1,1}; tRgbaColorf color; CFixVector vDrift; int nRad, nFrames, nType = particleImageManager.GetType (nParticleSystemType); if (nScale < 0) nRad = (int) -nScale; else if (gameOpts->render.particles.bSyncSizes) nRad = (int) PARTICLE_SIZE (gameOpts->render.particles.nSize [0], nScale); else nRad = (int) nScale; if (!nRad) nRad = I2X (1); m_nType = nType; m_bEmissive = (nParticleSystemType == LIGHT_PARTICLES); m_nClass = nClass; m_nSegment = nSegment; m_nBounce = 0; color = colorP ? *colorP : defaultColor; m_color [0] = m_color [1] = color; if ((nType == BULLET_PARTICLES) || (nType == BUBBLE_PARTICLES)) { m_bBright = 0; m_nFade = -1; } else { m_bBright = (nType == SMOKE_PARTICLES) ? (rand () % 50) == 0 : 0; if (colorP) { if (nType != LIGHT_PARTICLES) { m_color [0].red *= RANDOM_FADE; m_color [0].green *= RANDOM_FADE; m_color [0].blue *= RANDOM_FADE; } m_nFade = 0; } else { m_color [0].red = 1.0f; m_color [0].green = 0.5f; m_color [0].blue = 0.0f; m_nFade = 2; } if (m_bEmissive) m_color [0].alpha = (float) (SMOKE_START_ALPHA + 64) / 255.0f; else if (nParticleSystemType != GATLING_PARTICLES) { if (!colorP) m_color [0].alpha = (float) (SMOKE_START_ALPHA + randN (64)) / 255.0f; else { if (colorP->alpha < 0) m_color [0].alpha = -colorP->alpha; else { if (2 == (m_nFade = (char) colorP->alpha)) { m_color [0].red = 1.0f; m_color [0].green = 0.5f; m_color [0].blue = 0.0f; } m_color [0].alpha = (float) (SMOKE_START_ALPHA + randN (64)) / 255.0f; } } } #if 1 if (gameOpts->render.particles.bDisperse && !m_bBright) { fBrightness = 1.0f - fBrightness; m_color [0].alpha += fBrightness * fBrightness / 8.0f; } #endif } //nSpeed = (int) (sqrt (nSpeed) * (float) I2X (1)); nSpeed *= I2X (1); if (vDir) { CAngleVector a; CFixMatrix m; float d; a [PA] = randN (I2X (1) / 4) - I2X (1) / 8; a [BA] = randN (I2X (1) / 4) - I2X (1) / 8; a [HA] = randN (I2X (1) / 4) - I2X (1) / 8; m = CFixMatrix::Create (a); vDrift = m * (*vDir); CFixVector::Normalize (vDrift); d = (float) CFixVector::DeltaAngle (vDrift, *vDir, NULL); if (d) { d = (float) exp ((I2X (1) / 8) / d); nSpeed = (fix) ((float) nSpeed / d); } #if 0 if (!colorP) // hack for static particleSystem w/o user defined color m_color [0].green = m_color [0].blue = 1.0f; #endif vDrift *= nSpeed; if ((nType == SMOKE_PARTICLES) || (nType == BUBBLE_PARTICLES)) m_vDir = *vDir * (I2X (3) / 4 + I2X (randN (16)) / 64); else m_vDir = *vDir; m_bHaveDir = 1; } else { CFixVector vOffs; vDrift [X] = nSpeed - randN (2 * nSpeed); vDrift [Y] = nSpeed - randN (2 * nSpeed); vDrift [Z] = nSpeed - randN (2 * nSpeed); vOffs = vDrift; m_vDir.SetZero (); m_bHaveDir = 1; } m_vDrift = vDrift; if (vEmittingFace) m_vPos = *RandomPointOnQuad (vEmittingFace, vPos); else if (nType != BUBBLE_PARTICLES) m_vPos = *vPos + vDrift * (I2X (1) / 64); else { //m_vPos = *vPos + vDrift * (I2X (1) / 32); nSpeed = vDrift.Mag () / 16; vDrift = CFixVector::Avg ((*mOrient).RVec () * (nSpeed - randN (2 * nSpeed)), (*mOrient).UVec () * (nSpeed - randN (2 * nSpeed))); m_vPos = *vPos + vDrift + (*mOrient).FVec () * (I2X (1) / 2 - randN (I2X (1))); #if 1 m_vDrift.SetZero (); #else CFixVector::Normalize (m_vDrift); m_vDrift *= I2X (32); #endif } if ((nType != BUBBLE_PARTICLES) && mOrient) { CAngleVector vRot; CFixMatrix mRot; vRot [BA] = 0; vRot [PA] = 2048 - ((d_rand () % 9) * 512); vRot [HA] = 2048 - ((d_rand () % 9) * 512); mRot = CFixMatrix::Create (vRot); m_mOrient = *mOrient * mRot; } if (nLife < 0) nLife = -nLife; if (nType == SMOKE_PARTICLES) { if (gameOpts->render.particles.bDisperse) nLife = (nLife * 2) / 3; nLife = nLife / 2 + randN (nLife / 2); } m_nLife = m_nTTL = nLife; m_nMoved = nCurTime; m_nDelay = 0; //bStart ? randN (nLife) : 0; if (nType == SMOKE_PARTICLES) nRad += randN (nRad); else if (nType == BUBBLE_PARTICLES) nRad = nRad / 10 + randN (9 * nRad / 10); else nRad *= 2; if ((m_bBlowUp = bBlowUp)) { m_nRad = nRad / 2; m_nWidth = m_nHeight = m_nRad; m_nRad += m_nRad / bBlowUp; } else { m_nWidth = m_nHeight = nRad; m_nRad = nRad / 2; } nFrames = nParticleFrames [0][nType]; if (nType == BULLET_PARTICLES) { m_nFrame = 0; m_nRotFrame = 0; m_nOrient = 3; } else if (nType == BUBBLE_PARTICLES) { m_nFrame = rand () % (nFrames * nFrames); m_nRotFrame = 0; m_nOrient = 0; } else if (nType == LIGHT_PARTICLES) { m_nFrame = 0; m_nRotFrame = 0; m_nOrient = 0; } else { m_nFrame = rand () % (nFrames * nFrames); m_nRotFrame = m_nFrame / 2; m_nOrient = rand () % 4; } #if 1 if (m_bEmissive) m_color [0].alpha *= ParticleBrightness (colorP); else if (nParticleSystemType == SMOKE_PARTICLES) m_color [0].alpha /= colorP ? color.red + color.green + color.blue + 2 : 2; else if (nParticleSystemType == BUBBLE_PARTICLES) m_color [0].alpha /= 2; else if (nParticleSystemType == LIGHT_PARTICLES) m_color [0].alpha /= 5; # if 0 else if (nParticleSystemType == GATLING_PARTICLES) ;//m_color [0].alpha /= 6; # endif #endif return 1; }
int CTriMeshBuilder::InsertTriangles (void) { tTriangle* triP = &m_triangles [0]; tFaceTriangle* grsTriP = TRIANGLES.Buffer (); CSegFace* m_faceP = NULL; CFixVector vNormal; int h, i, nFace = -1; GLuint nIndex = 0; PrintLog (" inserting new triangles\n"); QSortTriangles (0, m_nTriangles - 1); ResetVertexNormals (); for (h = 0; h < m_nTriangles; h++, triP++, grsTriP++) { grsTriP->nFace = triP->nFace; if (grsTriP->nFace == nFace) m_faceP->nTris++; else { if (m_faceP) m_faceP++; else m_faceP = FACES.faces.Buffer (); nFace = grsTriP->nFace; #if DBG if (m_faceP - FACES.faces != nFace) return 0; #endif m_faceP->nFrame = -1; m_faceP->nIndex = nIndex; m_faceP->nTriIndex = h; m_faceP->nTris = 1; #if USE_RANGE_ELEMENTS m_faceP->vertIndex = FACES.vertIndex + nIndex; #endif } grsTriP->nIndex = nIndex; memcpy (grsTriP->index, triP->index, sizeof (triP->index)); for (i = 0; i < 3; i++) FACES.vertices [nIndex + i].Assign (gameData.segs.fVertices [triP->index [i]]); FACES.normals [nIndex] = CFloatVector3::Normal (FACES.vertices [nIndex], FACES.vertices [nIndex + 1], FACES.vertices [nIndex + 2]); #if DBG if (FACES.normals [nIndex].Mag () == 0) m_faceP = m_faceP; #endif vNormal.Assign (FACES.normals [nIndex]); for (i = 1; i < 3; i++) FACES.normals [nIndex + i] = FACES.normals [nIndex]; memcpy (FACES.texCoord + nIndex, triP->texCoord, sizeof (triP->texCoord)); memcpy (FACES.ovlTexCoord + nIndex, triP->ovlTexCoord, sizeof (triP->ovlTexCoord)); memcpy (FACES.color + nIndex, triP->color, sizeof (triP->color)); #if USE_RANGE_ELEMENTS for (i = 0; i < 3; i++, nIndex++) FACES.vertIndex [nIndex] = nIndex; #else nIndex += 3; #endif } gameData.segs.nTris = m_nTriangles; SetupVertexNormals (); FreeData (); PrintLog (" created %d new triangles and %d new vertices\n", m_nTriangles - m_nTris, gameData.segs.nVertices - m_nVertices); CreateFaceVertLists (); return 1; }
//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; }