static csVector3 FindBiggestHorizontalMovement ( const csBox3& box1, const csReversibleTransform& trans1, const csBox3& box2, const csReversibleTransform& trans2) { // The origin of the second box in the 3D space of the first box. csVector3 o2Tr = trans1.Other2This (trans2.GetOrigin ()); // Transformed bounding box. csBox3 box2Tr; box2Tr.StartBoundingBox (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (0)))); box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (1)))); box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (2)))); box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (3)))); box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (4)))); box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (5)))); box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (6)))); box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (7)))); float xr = o2Tr.x - box1.MaxX () + box2Tr.MinX (); float xl = box1.MinX () - o2Tr.x - box2Tr.MaxX (); float zr = o2Tr.z - box1.MaxZ () + box2Tr.MinZ (); float zl = box1.MinZ () - o2Tr.z - box2Tr.MaxZ (); csVector3 newpos = trans2.GetOrigin (); if (xr >= xl && xr >= zr && xr >= zl) newpos = trans1.This2Other (o2Tr + csVector3 (-xr, 0, -o2Tr.z)); else if (xl >= xr && xl >= zr && xl >= zl) newpos = trans1.This2Other (o2Tr + csVector3 (xl, 0, -o2Tr.z)); else if (zr >= xl && zr >= xr && zr >= zl) newpos = trans1.This2Other (o2Tr + csVector3 (-o2Tr.x, 0, -zr)); else if (zl >= xl && zl >= xr && zl >= zr) newpos = trans1.This2Other (o2Tr + csVector3 (-o2Tr.x, 0, zl)); return newpos; }
int csBox3::Adjacent (const csBox3 &other, float epsilon) const { if (AdjacentX (other, epsilon)) { if (other.MaxX () > MaxX ()) return CS_BOX_SIDE_X; else return CS_BOX_SIDE_x; } if (AdjacentY (other, epsilon)) { if (other.MaxY () > MaxY ()) return CS_BOX_SIDE_Y; else return CS_BOX_SIDE_y; } if (AdjacentZ (other, epsilon)) { if (other.MaxZ () > MaxZ ()) return CS_BOX_SIDE_Z; else return CS_BOX_SIDE_z; } return -1; }
int csBox3::Adjacent (const csBox3& other) const { if (AdjacentX (other)) { if (other.MaxX () > MaxX ()) return BOX_SIDE_X; else return BOX_SIDE_x; } if (AdjacentY (other)) { if (other.MaxY () > MaxY ()) return BOX_SIDE_Y; else return BOX_SIDE_y; } if (AdjacentZ (other)) { if (other.MaxZ () > MaxZ ()) return BOX_SIDE_Z; else return BOX_SIDE_z; } return -1; }
void csMeshWrapper::GetFullBBox (csBox3& box) { box = GetObjectModel ()->GetObjectBoundingBox (); csMovable* mov = &movable; while (mov) { if (!mov->IsTransformIdentity ()) { const csReversibleTransform& trans = mov->GetTransform (); csBox3 b (trans.This2Other (box.GetCorner (0))); b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (1))); b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (2))); b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (3))); b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (4))); b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (5))); b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (6))); b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (7))); box = b; } mov = ((csMovable*)mov)->GetParent (); } }
csBox3 csReversibleTransform::This2Other (const csBox3 &box) const { if (m_t2o.IsIdentity()) { csBox3 newBox (box); newBox.SetCenter (This2Other (box.GetCenter())); return newBox; } else { const csVector3 minA = box.Min (); const csVector3 maxA = box.Max (); csVector3 minB (v_o2t); csVector3 maxB (v_o2t); for (size_t i = 0; i < 3; ++i) { const csVector3 row = m_t2o.Row (i); for (size_t j = 0; j < 3; ++j) { float a = row[j] * minA[j]; float b = row[j] * maxA[j]; if (a < b) { minB[i] += a; maxB[i] += b; } else { minB[i] += b; maxB[i] += a; } } } return csBox3 (minB, maxB); } }
void csMeshOnTexture::ScaleCamera (iMeshWrapper* mesh, int txtw, int txth) { UpdateView (txtw, txth); const csBox3 mesh_box = mesh->GetWorldBoundingBox (); const csVector3 mesh_center = mesh_box.GetCenter (); const iPerspectiveCamera* camera = view->GetPerspectiveCamera (); const float aspect = camera->GetFOV (); const float shift_x = camera->GetShiftX (); const float shift_y = camera->GetShiftY (); int i; float maxz = -100000000.0f; for (i = 0 ; i < 8 ; i++) { csVector3 corner = mesh_box.GetCorner (i) - mesh_center; float z = (corner.x * aspect) / (1.0f - shift_x); if (z < 0) z = (corner.x * aspect) / (float (txtw) - shift_x); z += corner.z; if (z > maxz) maxz = z; z = (corner.y * aspect) / (1.0f - shift_y); if (z < 0) z = (corner.y * aspect) / (float (txth) - shift_y); z += corner.z; if (z > maxz) maxz = z; } csVector3 cam_pos = mesh_center; cam_pos.z -= maxz; for (i = 0 ; i < 8 ; i++) { csVector3 corner = mesh_box.GetCorner (i) - cam_pos; csVector2 p = view->GetCamera()->Perspective (corner); } view->GetCamera()->GetTransform ().Identity (); view->GetCamera()->GetTransform ().SetOrigin (cam_pos); }
bool csBox3::AdjacentZ (const csBox3& other) const { if (ABS (other.MinZ () - MaxZ ()) < SMALL_EPSILON || ABS (other.MaxZ () - MinZ ()) < SMALL_EPSILON) { if (MaxX () < other.MinX () || MinX () > other.MaxX ()) return false; if (MaxY () < other.MinY () || MinY () > other.MaxY ()) return false; return true; } return false; }
bool csBox3::AdjacentZ (const csBox3 &other, float epsilon) const { if ( ABS (other.MinZ () - MaxZ ()) < epsilon || ABS (other.MaxZ () - MinZ ()) < epsilon) { if (MaxX () < other.MinX () || MinX () > other.MaxX ()) return false; if (MaxY () < other.MinY () || MinY () > other.MaxY ()) return false; return true; } return false; }
void csBox3::ManhattanDistance (const csBox3 &other, csVector3 &dist) const { if (other.MinX () >= MaxX ()) dist.x = other.MinX () - MaxX (); else if (MinX () >= other.MaxX ()) dist.x = MinX () - other.MaxX (); else dist.x = 0; if (other.MinY () >= MaxY ()) dist.y = other.MinY () - MaxY (); else if (MinY () >= other.MaxY ()) dist.y = MinY () - other.MaxY (); else dist.y = 0; if (other.MinZ () >= MaxZ ()) dist.z = other.MinZ () - MaxZ (); else if (MinZ () >= other.MaxZ ()) dist.z = MinZ () - other.MaxZ (); else dist.z = 0; }
float csHazeMeshObject::GetScreenBoundingBox (long cameranr, long movablenr, float fov, float sx, float sy, const csReversibleTransform& trans, csBox2& sbox, csBox3& cbox) { csVector2 oneCorner; GetTransformedBoundingBox (cameranr, movablenr, trans, cbox); // if the entire bounding box is behind the camera, we're done if ((cbox.MinZ () < 0) && (cbox.MaxZ () < 0)) { return -1; } // Transform from camera to screen space. if (cbox.MinZ () <= 0) { // Sprite is very close to camera. // Just return a maximum bounding box. sbox.Set (-10000, -10000, 10000, 10000); } else { Perspective (cbox.Max (), oneCorner, fov, sx, sy); sbox.StartBoundingBox (oneCorner); csVector3 v (cbox.MinX (), cbox.MinY (), cbox.MaxZ ()); Perspective (v, oneCorner, fov, sx, sy); sbox.AddBoundingVertexSmart (oneCorner); Perspective (cbox.Min (), oneCorner, fov, sx, sy); sbox.AddBoundingVertexSmart (oneCorner); v.Set (cbox.MaxX (), cbox.MaxY (), cbox.MinZ ()); Perspective (v, oneCorner, fov, sx, sy); sbox.AddBoundingVertexSmart (oneCorner); } return cbox.MaxZ (); }
/* * In order to update the navigation structure, we have to update the navigation meshes for the * affected area, as well as the high level graph. When a navmesh gets updated, a path between * two portals may be closed or opened, and we have to add or remove edges to the graph to * account for this. */ bool celHNavStruct::Update (const csBox3& boundingBox, iSector* sector) { if (!sector) { bool ret; csHash<csRef<iCelNavMesh>, csPtrKey<iSector> >::GlobalIterator it = navMeshes.GetIterator(); csPtrKey<iSector> key; while (it.HasNext()) { csRef<iCelNavMesh> navMesh = it.Next(key); csBox3 navMeshBoundingBox = navMesh->GetBoundingBox(); if (boundingBox.Overlap(navMeshBoundingBox)) { ret = Update(boundingBox, key); if (!ret) { return false; } } } } csPtrKey<iSector> key = sector; csRef<iCelNavMesh> navMesh = navMeshes.Get(key, 0); navMesh->Update(boundingBox); // Update high level graph int nNodes = hlGraph->GetNodeCount(); csArray<csRef<iCelNode> > sameSectorNodes(hlGraph->GetNodeCount()); uint sectorId = sector->QueryObject()->GetID(); int sameSectorSize = 0; for (int i = 0; i < nNodes; ++i) { csRef<iCelNode> node = hlGraph->GetNode(i); uint nodeSectorId = node->GetMapNode()->GetSector()->QueryObject()->GetID(); if (nodeSectorId == sectorId) { sameSectorNodes.Push(node); sameSectorSize++; } } for (int i = 0; i < sameSectorSize; ++i) { csRef<iCelNode> node = sameSectorNodes[i]; // Check edges from the high level graph that are on the updated sector, to update weights and // see if any of them was obstructed. int nEdges = node->GetEdgeCount(); for (int j = nEdges - 1; j > 0; j--) { csRef<iCelEdge> edge = node->GetEdge(j); csRef<iCelNode> node2 = edge->GetSuccessor(); uint edgeSectorId = node2->GetMapNode()->GetSector()->QueryObject()->GetID(); if (edgeSectorId == sectorId) { csRef<iCelNavMeshPath> path = navMesh->ShortestPath(node->GetPosition(), node2->GetPosition(), 256); if (path->GetNodeCount() > 0) { csVector3 last; path->GetLast(last); csVector3 box = parameters->GetPolygonSearchBox(); // Check if last calculated point is within reach of the last given point if (ABS(last[0] - node2->GetPosition()[0]) <= box[0] && ABS(last[1] - node2->GetPosition()[1]) <= box[1] && ABS(last[2] - node2->GetPosition()[2]) <= box[2]) { float length = path->Length(); edge->SetWeight(length); } else { node->RemoveEdge(j); } } else { node->RemoveEdge(j); } } } // Check if any edges need to be added to the high level graph (a path might have opened) for (int j = i + 1; j < sameSectorSize; ++j) { csRef<iCelNode> node2 = sameSectorNodes[j]; bool found = false; for (int k = 0; j < nEdges; ++k) { if (node2 == node->GetEdge(k)->GetSuccessor()) { found = true; break; } } if (!found) { csRef<iCelNavMeshPath> path = navMesh->ShortestPath(node->GetPosition(), node2->GetPosition(), 256); if (path->GetNodeCount() > 0) { csVector3 last; path->GetLast(last); csVector3 box = parameters->GetPolygonSearchBox(); // Check if last calculated point is within reach of the last given point if (ABS(last[0] - node2->GetPosition()[0]) <= box[0] && ABS(last[1] - node2->GetPosition()[1]) <= box[1] && ABS(last[2] - node2->GetPosition()[2]) <= box[2]) { float length = path->Length(); hlGraph->AddEdge(node, node2, true, length); hlGraph->AddEdge(node2, node, true, length); } } } } } return true; }
void HeightMapGen::CreateHeightmap (int heightmap_res, iCollideSystem* cdsys, iSector* sector, csRGBpixel* hmap_dst, float* height_dst, const csBox3& box) { csPrintf ("Creating heightmap...\n"); fflush (stdout); float dx = (box.MaxX () - box.MinX () - 0.2) / float (heightmap_res-1); float dz = (box.MaxZ () - box.MinZ () - 0.2) / float (heightmap_res-1); for (int z = 0 ; z < heightmap_res ; z++) { for (int x = 0 ; x < heightmap_res ; x++) { csVector3 start, end; start.x = box.MinX () + (float)x * dx + 0.1; start.y = box.MaxY () + 10.0; start.z = box.MinZ () + (heightmap_res-z-1) * dz + 0.1; end = start; end.y = box.MinY () - 10.0; csVector3 isect; //mesh->HitBeamObject (start, end, isect, 0, 0); csIntersectingTriangle closest_tri; csColliderHelper::TraceBeam (cdsys, sector, start, end, false, closest_tri, isect); float y = (isect.y - box.MinY ()) / (box.MaxY () - box.MinY ()); if (y < 0) y = 0; else if (y > 0.9999f) y = 0.9999f; *height_dst++ = y; y *= 256.0; hmap_dst->Set (int (y), int (y), int (y)); hmap_dst++; } } }