bool PlayerCollisionImage::checkTerrain(SimCollisionTerrImage * image, CollisionSurfaceList * list) { // Bounding sphere against terrain, going to do this // in terrain space. Ignores player rotation TMat3F mat,nmat; TMat3F tmp = image->transform; tmp.inverse(); nmat.identity(); nmat.p = transform.p; m_mul(nmat,tmp,&mat); // Point3F center; m_mul(sphere.center,mat,¢er); list->increment(); CollisionSurface& info = list->last(); if (image->gridFile->getSurfaceInfo(center,&info)) { float dist = m_dot(center,info.normal) - m_dot(info.position,info.normal); if (fabs(dist) < sphere.radius) { info.distance = dist; // Pos & normal back to player space list->tLocal = mat; list->tLocal.inverse(); list->tWorld = image->transform; return true; } } list->clear(); return false; }
Point3F& m_mul( const Point3F &p, const QuatF &q, Point3F *r ) { QuatF qq; QuatF qi = q; QuatF qv( p.x, p.y, p.z, 0.0f); qi.inverse(); m_mul(qi, qv, &qq ); m_mul(qq, q, &qv ); r->set(qv.x, qv.y, qv.z); return ( *r ); }
float Player::coverage (Point3F eye) { float total = 0; Point3F foot = getLinearPosition () + collisionImage.sphere.center / 2; Point3F head = foot + collisionImage.sphere.center; Point3F temp; Point3F lshoulder; Point3F rshoulder; temp = getRot (); RMat3F rot (EulerF(temp.x, temp.y, temp.z)); temp.set (collisionImage.bbox.fMin.x / 2, 0, 0); m_mul (temp, rot, &lshoulder); lshoulder += getLinearPosition (); lshoulder.z += collisionImage.sphere.center.z; lshoulder.z += collisionImage.sphere.center.z / 4; temp.set (collisionImage.bbox.fMax.x / 2, 0, 0); m_mul (temp, rot, &rshoulder); rshoulder += getLinearPosition (); rshoulder.z += collisionImage.sphere.center.z; rshoulder.z += collisionImage.sphere.center.z / 4; SimContainerQuery cq; cq.id = getId(); cq.type = -1; cq.mask = SimTerrainObjectType | SimInteriorObjectType | SimPlayerObjectType | StaticObjectType; cq.box.fMin = eye; cq.box.fMax = foot; SimCollisionInfo info; SimContainer* root = findObject(manager,SimRootContainerId,(SimContainer*)0); bool obstructed = root->findLOS (cq, &info); if (!obstructed) total += 0.25; cq.box.fMax = head; obstructed = root->findLOS (cq, &info); if (!obstructed) total += 0.25; cq.box.fMax = lshoulder; obstructed = root->findLOS (cq, &info); if (!obstructed) total += 0.25; cq.box.fMax = rshoulder; obstructed = root->findLOS (cq, &info); if (!obstructed) total += 0.25; return total; }
void Player::getThrowVector(Point3F* pos,Point3F* vec) { RMat3F view,mat; // Add a small upward component to the pitch to // throw the item up a little. float offset = 0.5 * cos(viewPitch); view.set(EulerF(viewPitch + offset,0.0f,0.0f)); m_mul(view,(RMat3F&)getTransform(),&mat); Point3F vv(0,1,0); m_mul(vv,mat,vec); *pos = getBoxCenter(); }
bool tripod::processQuery( SimQuery *q ) { switch (q->type){ case SimCameraQueryType: { // We want this object to be attachable SimCameraQuery * qp = static_cast<SimCameraQuery *>(q); qp->cameraInfo.fov = 0.6f; qp->cameraInfo.nearPlane = 1.0f; qp->cameraInfo.farPlane = 1.0E7f; if (actor) { // ask for actor's position here and use it to fill out tmat const Point3F & pos = *actor->getPos(); const EulerF & rot = *actor->getRot(); TMat3F transMat; EulerF absoluteCamAngle; absoluteCamAngle=mover.getOrbitRot(); if (angleRelative) // just do yaw, at least for now absoluteCamAngle.z += rot.z; // get point to orbit around (use center of object usually) Point3F focusPoint; m_mul(offset,TMat3F(rot,pos),&focusPoint); transMat.set(absoluteCamAngle,focusPoint); if (mover.getOrbitDist()<objectRadius) mover.setOrbitDist(objectRadius); Point3F newPos; m_mul(Point3F(0.0f,-mover.getOrbitDist(),0.0f),transMat,&newPos); transMat.set(absoluteCamAngle,newPos); // apply the offcenter variables to move left/right up/down from object center m_mul(Point3F(objectRadius*Hoffcenter,0,objectRadius*Voffcenter),transMat,&newPos); mover.setPos(newPos); mover.setRot(absoluteCamAngle); } qp->cameraInfo.tmat.set( mover.getRot(), mover.getPos() ); break; } default: return false; } return true; }
Point3F& m_mul( const Point3F &p, const TQuatF &q, Point3F *r ) { //rotate a point by a Quaternion QuatF a; QuatF i = q; QuatF v( p.x, p.y, p.z, 0.0f); i.inverse(); m_mul(i, v, &a ); m_mul(a, q, &v ); v.normalize(); r->set(v.x, v.y, v.z); *r += q.p; return ( *r ); }
// This is like TMat x TMat = Tmat where the first TMat only has translation. TMat3F& m_mul( const Point3F & trans, const TMat3F & b, TMat3F* r ) { AssertWarn( &b != r, "m_mul: dest should not be same as source" ); *r = b; m_mul( trans, b, &r->p ); return *r; }
Box3F& m_mul(const Box3F &b0, const TMat3F &m, Box3F *b1) { m_mul(b0, (RMat3F)m, b1); b1->fMax += m.p; b1->fMin += m.p; return *b1; }
void CelAnimMesh::getPolys(int frameIndex, int matFrameIndex, const TMat3F * meshToShape, unpackedFaceList & fl) const { AssertFatal( fFrames.size() > 0, "Shape must have at least one frame." ); AssertFatal( frameIndex >= 0 && frameIndex < fFrames.size(), "TS::CelAnimMesh: frame index out of range" ); matFrameIndex; // get the frame struct: const Frame *frm = &fFrames[frameIndex]; int fv = frm->fFirstVert; const Point3F *pScale = &frm->fScale; const Point3F *pOrigin = &frm->fOrigin; // int ftv=matFrameIndex*fnTextureVertsPerFrame; int i; Vector<Point3F> & toPoints = fl.fPoints; int startPoint = toPoints.size(); for (i=0;i<fnVertsPerFrame;i++) { toPoints.increment(); Point3F pnt; fVerts[i+fv].getPoint(pnt,*pScale,*pOrigin); if (meshToShape) m_mul(pnt,*meshToShape,&toPoints.last()); else toPoints.last() = pnt; } // Vector<Point2F> & toTextures = fl.fTextures; // int startTexture = toTextures.size(); // for (i=0;i<fnTextureVertsPerFrame;i++) // { // toTextures.increment(); // toTextures.last()=fTextureVerts[i+ftv]; // } for (i=0;i<fFaces.size();i++) { const Face & fromFace = fFaces[i]; fl.fFaces.increment(); TS::Face & toFace = fl.fFaces.last(); toFace.fVIP[0].fVertexIndex=fromFace.fVIP[0].fVertexIndex+startPoint; // toFace.fVIP[0].fTextureIndex=fromFace.fVIP[0].fTextureIndex+startTexture; toFace.fVIP[1].fVertexIndex=fromFace.fVIP[1].fVertexIndex+startPoint; // toFace.fVIP[1].fTextureIndex=fromFace.fVIP[1].fTextureIndex+startTexture; toFace.fVIP[2].fVertexIndex=fromFace.fVIP[2].fVertexIndex+startPoint; // toFace.fVIP[2].fTextureIndex=fromFace.fVIP[2].fTextureIndex+startTexture; // toFace.material=fromFace.fMaterial; } }
bool FlyingCamera::onSimCameraQuery(SimCameraQuery *query) { SimObjectTransformQuery tquery; query->cameraInfo.fov = g_rDefaultFOV; query->cameraInfo.nearPlane = DEFAULT_NEAR_PLANE; query->cameraInfo.farPlane = getFarPlane(); if (objFollow && objFollow->processQuery(&tquery)) { Point3F objPos = tquery.tmat.p; Vector3F x, y, z; RMat3F rmat(EulerF(rotation.x - M_PI / 2, rotation.y, -rotation.z)); tquery.tmat.p += m_mul(Vector3F(0.0f, rDistance, 0.0f), rmat, &y); tquery.tmat.p.z += 2.0f; y.neg(); y.normalize(); m_cross(y, Vector3F(0.0f, 0.0f, 1.0f), &x); x.normalize(); m_cross(x, y, &z); tquery.tmat.setRow(0, x); tquery.tmat.setRow(1, y); tquery.tmat.setRow(2, z); // Set our position findLOSPosition(tquery.tmat, objPos); } query->cameraInfo.tmat = getTransform(); return (true); }
void FlyingCamera::findLOSPosition(TMat3F &tmat, const Point3F &objPos) { Point3F collisionPos; SimContainer *root; SimCollisionInfo info; SimContainerQuery query; query.id = -1; query.type = -1; query.mask = ItemObjectType | SimInteriorObjectType | SimTerrainObjectType | MoveableObjectType | VehicleObjectType; query.box.fMin = objPos; // position of followed object query.box.fMax = tmat.p; // our position root = findObject(manager, SimRootContainerId, root); collisionPos = tmat.p; // Find a line-of-sight from our position to the object we are following if (root->findLOS(query, &info)) { // If LOS collides with something, find the point at which it hits m_mul(info.surfaces[0].position, info.surfaces.tWorld, &collisionPos); } // Move to where the collision occurred tmat.p = collisionPos; setPosition(tmat, true); position = tmat.p; }
bool PlayerCollisionImage::checkInterior(SimCollisionItrImage * image, CollisionSurfaceList * list) { // Bounding box against interior, going to do this // in interior space. Ignores player rotation. TMat3F mat,nmat; TMat3F tmp = image->transform; tmp.inverse(); nmat.identity(); nmat.p = transform.p; m_mul(nmat,tmp,&mat); // ITRCollision & itrColl = image->collision; itrColl.geometry = image->instance->getGeometry(); itrColl.materialList = image->instance->getMaterialList(); itrColl.transform = &mat; itrColl.collisionList = list; if (!itrColl.collide(bbox)) return false; // Pos & normal back to player space // Material, surface & part still refer to the interior list->tLocal = mat; list->tLocal.inverse(); list->tWorld = image->transform; return true; }
// Retorna a^n = b. // Não precisa tratar n=0. M21x21 m_exp(M21x21 a, int n) { M21x21 b; if (n == 1) return a; else if (n % 2 == 0) { b = m_exp(a, n / 2); b = m_mul(b, b); return b; } else { b = m_exp(a, (n - 1) / 2); b = m_mul(b, b); return (m_mul(b, a)); } }
void SimInterior::updateBoundingBox() { if (renderImage.instance) { Box3F box0 = renderImage.instance->getGeometry()->box, box1; m_mul(box0, renderImage.transform, &box1); setBoundingBox(box1); } }
void m_pow (matrix& m, int p) { matrix c; // m0^p = m * (c ^ p) matrix t; m_copy (c, m); m_unit (m); while (p > 0) { if (p & 1) { m_mul (t, m, c); m_copy (m, t); } m_mul (t, c, c); m_copy (c, t); p >>= 1; } }
Box3F& m_mul(const Box3F &b0, const RMat3F &m, Box3F *b1) { Point3F x,y,z; m.getRow(0,&x); m.getRow(1,&y); m.getRow(2,&z); Point3F center,tcenter,radii; center = b0.fMin + b0.fMax; center *= 0.5f; m_mul(center,m,&tcenter); radii = b0.fMax - b0.fMin; radii *= 0.5f; float rx = fabs(x.x) * radii.x + fabs(y.x) * radii.y + fabs(z.x) * radii.z; float ry = fabs(x.y) * radii.x + fabs(y.y) * radii.y + fabs(z.y) * radii.z; float rz = fabs(x.z) * radii.x + fabs(y.z) * radii.y + fabs(z.z) * radii.z; b1->fMin = b1->fMax = tcenter; b1->fMin.x -= rx; b1->fMin.y -= ry; b1->fMin.z -= rz; b1->fMax.x += rx; b1->fMax.y += ry; b1->fMax.z += rz; return *b1; /* Point3F p, u, v, w, z; m_mul(b0.fMin, m, &p); m_mul(Point3F(b0.fMax.x - b0.fMin.x, 0.0f, 0.0f), m, &u); m_mul(Point3F(0.0f, b0.fMax.y - b0.fMin.y, 0.0f), m, &v); m_mul(Point3F(0.0f, 0.0f, b0.fMax.z - b0.fMin.z), m, &w); z.x = u.x + v.x + w.x; z.y = u.y + v.y + w.y; z.z = u.z + v.z + w.z; b1->fMin = u; b1->fMin.setMin(v); b1->fMin.setMin(w); b1->fMin.setMin(z); b1->fMin += p; b1->fMax = u; b1->fMax.setMax(v); b1->fMax.setMax(w); b1->fMax.setMax(z); b1->fMax += p; return *b1; */ }
bool PlayerCollisionImage::checkShape(ShapeCollisionImage * image, CollisionSurfaceList * list) { #if 0 TMat3F mat,tmp = image->transform; tmp.inverse(); m_mul(transform,tmp,&mat); // Shape-box collision routine wants box centered at // origin and wants radii not min/max Point3F radii; Point3F & min = bbox.fMin, & max = bbox.fMax; radii.x = max.x-min.x; radii.y = max.y-min.y; radii.z = max.z-min.z; radii *= 0.5f; // Shift transform so box center at origin Point3F tmpPoint; tmpPoint.x = min.x + radii.x; tmpPoint.y = min.y + radii.y; tmpPoint.z = min.z + radii.z; mat.preTranslate(tmpPoint); return image->shapeInst->collideBox(collisionDetail,radii,&mat,list,false); #else // Sphere against polys in other shape m_mul(image->shapeInst->fRootDeltaTransform, image->transform,&list->tWorld); TMat3F wti = list->tWorld; wti.inverse(); TMat3F mat; m_mul(transform,wti,&mat); if (!image->shapeInst->collideSphere(image->collisionDetail, sphere.center,sphere.radius,&mat,list, image->collisionLevel == CollideFaces)) return false; list->tLocal = mat; list->tLocal.inverse(); return true; #endif }
bool FlyingCamera::onSimFrameEndNotifyEvent(const SimFrameEndNotifyEvent *) { float x = rotation.x; float d = rDistance; // get the move info float speed = atof( CMDConsole::getLocked()->getVariable( "MoveSpeed" ) ); float rot = atof( CMDConsole::getLocked()->getVariable( "PosRotation" ) ) * M_PI * 5; maxLinearSpeed.set( speed, speed, speed ); maxAngularSpeed.set( rot, rot, rot ); // Sample inputs and get new throttles throttle.x = input.linear.x.getInput() * maxLinearSpeed.x; throttle.y = input.linear.y.getInput() * maxLinearSpeed.y; throttle.z = input.linear.z.getInput() * maxLinearSpeed.z; rotation.x += input.angular.x.getInput() * maxAngularSpeed.x; rotation.y += input.angular.y.getInput() * maxAngularSpeed.y; rotation.z += input.angular.z.getInput() * maxAngularSpeed.z; // If we're following we need to keep track of our relative position // and rotation if (objFollow) { if (throttle.y) { rDistance += throttle.y < 0 ? MAX_ATTACHED_SPEED : -MAX_ATTACHED_SPEED; if (rDistance >= MAX_ATTACHED_DISTANCE || rDistance < MIN_ATTACHED_DISTANCE) { rDistance = d; } } if (rotation.x >= MAX_ATTACHED_ROTATION || rotation.x <= MIN_ATTACHED_ROTATION) { rotation.x = x; } } // We only set our own position if we're not following else { Point3F tmp; m_mul(throttle, RMat3F(EulerF(rotation.x, rotation.y, rotation.z)), &tmp); position += tmp; setPosition(TMat3F(EulerF(rotation.x, rotation.y, rotation.z), position), true); } return (true); }
void PlayerCollisionImage::buildImageTransform(SimCollisionImage* image, CollisionSurfaceList* list,TMat3F* mat) { // Transform that goes from image space into the local space. // TMat3F &rootDelta = shapeInst->fRootDeltaTransform; if (rootDelta.flags & (TMat3F::Matrix_HasRotation | TMat3F::Matrix_HasTranslation | TMat3F::Matrix_HasScale)) { // Since this shape has an animation transform, we need // to adjust the collision surface transforms. TMat3F tmp = list->tLocal; m_mul(rootDelta,tmp,&list->tLocal); m_mul(rootDelta,transform,&list->tWorld); } TMat3F wta = list->tWorld; wta.inverse(); m_mul(image->transform,wta,mat); }
bool MissionLighting::collide( void * obj, Point3F & start, Point3F & end, ColorF & col ) { col; MissionLighting * lighter = ( MissionLighting * )obj; bool retVal = false; Point3F a, b; // chekc if lighting the terrain or the interiors ( terrain already did the los check ) if( !lighter->lightingTerrain ) { // translate into world space SimContainer * interior = lighter->m_interiors[ lighter->m_currentInterior ]; TMat3F mat = lighter->getInteriorTransform( *interior ); m_mul( start, mat, &a ); m_mul( end, mat, &b ); // setup for the call to the los function SimCollisionInfo info; SimContainerQuery query; query.id = interior->getId(); query.type = -1; query.box.fMin = a; query.box.fMax = b; #ifdef FEAR query.mask = ( SimInteriorObjectType | SimTerrainObjectType ); #else // StarSiege query.mask = ( StaticInteriorObjectType | SimTerrainObjectType ); #endif // do the collision check SimContainer * root = findObject( lighter->manager, SimRootContainerId, root ); retVal = root->findLOS( query, &info ); } // do the cloud map stuff... if( missionUseCloudMap ) lighter->applyCloudMapIntensity( lighter->lightingTerrain ? end : b, col ); return( retVal ); }
bool ShapeCollisionImage::checkShape(ShapeCollisionImage * image, CollisionSurfaceList * list) { // Sphere against polys in other shape m_mul(image->shapeInst->fRootDeltaTransform, image->transform,&list->tWorld); TMat3F wti = list->tWorld; wti.inverse(); TMat3F mat; m_mul(transform,wti,&mat); if (!image->shapeInst->collideSphere(image->collisionDetail, sphere.center,sphere.radius,&mat,list, image->collisionLevel == CollideFaces)) return false; list->tLocal = mat; list->tLocal.inverse(); return true; }
int main() { char op; int a ,b, c, d; scanf("%d, %d, %c, %d, %d", &a, &b, &op, &c, &d); switch (op) { case '+': m_add(a, b, c, d); break; case '*': m_mul(a, b, c, d); break; case '-': m_sub(a, b, c, d); break; case '/': m_div(a, b, c, d); break; } return 0; }
bool Turret::isTargetable (Player *player, float *minDist, float useRange) { if (player && player->getTeam () != getTeam() && player->getVisibleToTeam (getTeam()) && !player->isDead()) { if (const char* script = scriptName("verifyTarget")) { const char* pRet = Console->evaluatef("%s(%d);", script, player->getId()); if (pRet[0] == 'F' || pRet[0] == 'f') return false; } Point3F playerPos = player->getLeadCenter(); float dist = m_distf (getBoxCenter(), playerPos); if (dist < useRange) targetsTracked++; if (dist < *minDist) { TMat3F invMat; getNodeOffset (&invMat, "dummy muzzle", gunNode); invMat.inverse(); m_mul (Point3F (playerPos.x, playerPos.y, playerPos.z), invMat, &playerPos); float ele = elevation (playerPos.x, playerPos.y, playerPos.z); float rotz = rotation (-playerPos.x, -playerPos.y); if (!inDeadZone (rotz, ele)) { SimContainerQuery collisionQuery; collisionQuery.id = getId(); collisionQuery.type = -1; collisionQuery.mask = SimTerrainObjectType | SimInteriorObjectType; collisionQuery.detail = SimContainerQuery::DefaultDetail; collisionQuery.box.fMin = getBoxCenter(); collisionQuery.box.fMax = player->getLeadCenter(); SimCollisionInfo collisionInfo; SimContainer* root = findObject(manager,SimRootContainerId,root); root->findLOS(collisionQuery, &collisionInfo); if (!collisionInfo.object || collisionInfo.object == player) { *minDist = dist; return true; } } } } return false; }
bool CelAnimMesh::collideShapeBox(int frameIndex, TMat3F & objToOtherShape, objectList &otherOL, objectList &thisOL) const { AssertFatal( fFrames.size() > 0, "Shape must have at least one frame." ); AssertFatal( frameIndex >= 0 && frameIndex < fFrames.size(), "TS::CelAnimMesh: frame index out of range" ); // get the frame struct: const Frame *frm = &fFrames[frameIndex]; int fv = frm->fFirstVert; const Point3F *pScale = &frm->fScale; const Point3F *pOrigin = &frm->fOrigin; // first two verts aren't really verts -- they hold min and max points Point3F radii,min; fVerts[fv+1].getPoint(radii,*pScale,*pOrigin); fVerts[fv].getPoint(min,*pScale,*pOrigin); radii -= min; radii *= 0.5f; // shift transform so box center at origin Point3F tmpPoint = min; tmpPoint += radii; objToOtherShape.preTranslate(tmpPoint); bool gotOne = false; thisOL.increment(); ObjectInfo * poi = &thisOL.last(); for (int i=0;i<otherOL.size();i++) { ObjectInfo & otherOI = otherOL[i]; TMat3F boxTobox; m_mul(objToOtherShape,otherOI.invObjTrans,&boxTobox); if ( otherOI.pObj->collideBoxObj( boxTobox, radii, poi->aOverlap,poi->bOverlap )) { // fill in pointer to other object poi->pObj2=otherOI.pObj; // create another entry on the object list (to be deleted if no more collisions) thisOL.increment(); poi= &thisOL.last(); gotOne = true; } } thisOL.decrement(); return gotOne; }
const TMat3F &Turret::getEyeTransform (void) { static TMat3F ret; TMat3F temp; int node = cameraNode; if (node != -1) { const TMat3F& nmat = image.shape->getTransform(node); temp.set(EulerF(turretElevation, 0, turretRotation), nmat.p); } else temp.identity(); m_mul(temp, getTransform(), &ret); return ret; }
const TMat3F &Player::getEyeTransform() { static TMat3F ret; TMat3F temp; int node = eyeNode; if (node != -1) { const TMat3F& nmat = image.shape->getTransform(node); temp.set(EulerF(viewPitch, 0, 0), nmat.p); } else temp.identity(); m_mul(temp, getTransform(), &ret); return ret; }
bool Turret::getMuzzleTransform(int, TMat3F *transform) { if(!image.shape) return false; image.shape->animate(); int node = gunNode; if(node != -1) { const TMat3F &nodeTrans = image.shape->getTransform(node); TMat3F mat1(EulerF(turretElevation, 0, turretRotation), nodeTrans.p); m_mul(mat1, getTransform(), transform); } else *transform = getTransform(); return true; }
void Turret::getCameraTransform(float camDist, TMat3F *transform) { if(!image.shape) return; image.shape->animate(); int node = cameraNode; if(node != -1) { const TMat3F &nodeTrans = image.shape->getTransform(node); TMat3F mat1(EulerF(turretElevation, 0, turretRotation), nodeTrans.p); m_mul(mat1, getTransform(), transform); validateEyePoint (transform, camDist * 1.3); } else *transform = getTransform(); }
void SimFire::getPosition(Point3F &position) { position = pos; if (onObj) { SimObjectTransformQuery query; if ( onObj->processQuery( &query ) ) { // if matrix has rotation, better multiply through... // assume no scale even if flag set... if ( query.tmat.flags & TMat3F::Matrix_HasRotation ) m_mul(pos,query.tmat,&position); else position += query.tmat.p; } } }
void SimExplosionCloud::makeSound() { if (soundId != EXP_nosound) { Point3F p; if (form==Box) { center = box.fMin; center += box.fMax; center *= 0.5f; } if (hasTransform) m_mul(center,transform,&p); else p = center; Sfx::Manager::PlayAt( manager, soundId, TMat3F(EulerF(0, 0, 0), p), Point3F(0, 0, 0)); } }